| @@ -29,51 +29,22 @@ | |||
| } | |||
| .rotation3D__item .scale{ position: absolute; top: 0; width: 100%; height: 100%; } | |||
| .rotation3D__item .cont{ position: relative; z-index: 2; } | |||
| .rotation3D__item .cont .iconfont { font-size: 28px; margin-top: 30px; margin-bottom: 96px; display: block; } | |||
| .rotation3D__item .cont .iconfont { font-size: 28px; margin-top: 30px; margin-bottom: 96px; display: block; height: 35px;} | |||
| .rotation3D__item .cont p{ color: #101010; } | |||
| .itemList .rotation3D__item .cont p::after{ | |||
| font-size: 12px; | |||
| content: ''; | |||
| position: absolute; | |||
| left: 0; | |||
| right: 0; | |||
| margin-top: 60px; | |||
| color: #101010; | |||
| } | |||
| .itemList .rotation3D__item:nth-child(1) .cont p::after{ | |||
| content: "鹏城云脑一号"; | |||
| } | |||
| .itemList .rotation3D__item:nth-child(2) .cont p::after{ | |||
| content: "鹏城云脑二号"; | |||
| } | |||
| .itemList .rotation3D__item:nth-child(3) .cont p::after{ | |||
| content: "北大人工智能集群系统"; | |||
| } | |||
| .itemList .rotation3D__item:nth-child(4) .cont p::after{ | |||
| content: "合肥类脑智能开放平台"; | |||
| .lineList .rotation3D__line:nth-child(5n+0) .dot{ | |||
| } | |||
| .itemList .rotation3D__item:nth-child(5) .cont p::after{ | |||
| content: "武汉人工智能计算中心"; | |||
| .lineList .rotation3D__line:nth-child(5n+1) .dot{ | |||
| animation-delay: 1s; | |||
| } | |||
| .itemList .rotation3D__item:nth-child(6) .cont p::after{ | |||
| content: "西安未来人工智能计算中心"; | |||
| .lineList .rotation3D__line:nth-child(5n+2) .dot{ | |||
| animation-delay: 3s; | |||
| } | |||
| .itemList .rotation3D__item:nth-child(7) .cont p::after{ | |||
| content: "更多接入中…"; | |||
| .lineList .rotation3D__line:nth-child(5n+3) .dot{ | |||
| animation-delay: 2s; | |||
| } | |||
| .itemList .rotation3D__item:nth-child(8) .cont p::after{ | |||
| content: "中原人工智能计算中心"; | |||
| .lineList .rotation3D__line:nth-child(5n+3) .dot{ | |||
| animation-delay: 4s; | |||
| } | |||
| .itemList .rotation3D__item:nth-child(9) .cont p::after{ | |||
| content: "成都人工智能计算中心"; | |||
| } | |||
| .itemList .rotation3D__item:nth-child(10) .cont p::after{ | |||
| content: "横琴先进智能计算中心"; | |||
| } | |||
| .itemList .rotation3D__item:nth-child(11) .cont p::after{ | |||
| content: "国家超级计算济南中心"; | |||
| } | |||
| .rotation3D__item.blue{ color: #01e9fc; } | |||
| .rotation3D__item.green{ color: #b4b3ca; } | |||
| .rotation3D__item.yellow{ color: #ffd200; } | |||
| @@ -90,14 +61,17 @@ | |||
| ---------------------------*/ | |||
| .rotation3D__line{ | |||
| position: absolute; left: 50%; top: 50%; | |||
| display: block; width: 1px; height: 50%; | |||
| display: block; | |||
| width: 30px; | |||
| height: 50%; | |||
| padding-top: 60px; color: #fff; font-size: 50px; | |||
| /*background: #fff;*/ | |||
| /*原点设置在中间*/ | |||
| transform-origin: 50% 0; | |||
| transform-style: preserve-3d; | |||
| } | |||
| .rotation3D__line .pos{ position: absolute; top: 0; } | |||
| overflow: hidden; | |||
| } | |||
| .rotation3D__line .pos{ position: absolute; top: 0; left: 15px;} | |||
| .rotation3D__line svg { position: absolute; top: 0; } | |||
| .rotation3D__line svg path { | |||
| stroke: #fff; fill: none; | |||
| @@ -139,8 +113,10 @@ | |||
| position: absolute; | |||
| font-size: 12px; | |||
| color: #888; | |||
| transform: rotate(180deg)scale(0.80); | |||
| } | |||
| transform:scale(0.80); | |||
| transform-origin:left; | |||
| white-space: nowrap; | |||
| } | |||
| /*颜色*/ | |||
| .rotation3D__line.blue { color: #07b2f9; } | |||
| @@ -134,7 +134,7 @@ type Cloudbrain struct { | |||
| CanDebug bool `xorm:"-"` | |||
| CanDel bool `xorm:"-"` | |||
| CanModify bool `xorm:"-"` | |||
| Type int | |||
| Type int `xorm:"INDEX"` | |||
| BenchmarkTypeID int | |||
| BenchmarkChildTypeID int | |||
| @@ -2046,3 +2046,30 @@ func GetDatasetInfo(uuidStr string) (map[string]DatasetInfo, string, error) { | |||
| return datasetInfos, datasetNames, nil | |||
| } | |||
| func GetNewestJobsByAiCenter() ([]int64, error) { | |||
| ids := make([]int64, 0) | |||
| return ids, x. | |||
| Select("max(id) as id"). | |||
| Where("type=? and ai_center!='' and ai_center is not null", TypeC2Net). | |||
| GroupBy("ai_center"). | |||
| Table(Cloudbrain{}). | |||
| Find(&ids) | |||
| } | |||
| func GetNewestJobsByType() ([]int64, error) { | |||
| ids := make([]int64, 0) | |||
| return ids, x. | |||
| Select("max(id) as id"). | |||
| In("type", TypeCloudBrainOne, TypeCloudBrainTwo). | |||
| GroupBy("type"). | |||
| Table(Cloudbrain{}). | |||
| Find(&ids) | |||
| } | |||
| func GetCloudbrainByIDs(ids []int64) ([]*Cloudbrain, error) { | |||
| cloudbrains := make([]*Cloudbrain, 0) | |||
| return cloudbrains, x. | |||
| In("id", ids). | |||
| Find(&cloudbrains) | |||
| } | |||
| @@ -7,6 +7,7 @@ package setting | |||
| import ( | |||
| "encoding/base64" | |||
| "encoding/json" | |||
| "fmt" | |||
| "io" | |||
| "io/ioutil" | |||
| @@ -64,7 +65,16 @@ const ( | |||
| ReCaptcha = "recaptcha" | |||
| ) | |||
| // settings | |||
| type C2NetSequenceInfo struct { | |||
| ID int `json:"id"` | |||
| Name string `json:"name"` | |||
| Content string `json:"content"` | |||
| } | |||
| type C2NetSqInfos struct { | |||
| C2NetSqInfo []*C2NetSequenceInfo `json:"sequence"` | |||
| } | |||
| var ( | |||
| // AppVer settings | |||
| AppVer string | |||
| @@ -537,13 +547,16 @@ var ( | |||
| //grampus config | |||
| Grampus = struct { | |||
| Env string | |||
| Host string | |||
| UserName string | |||
| Password string | |||
| SpecialPools string | |||
| Env string | |||
| Host string | |||
| UserName string | |||
| Password string | |||
| SpecialPools string | |||
| C2NetSequence string | |||
| }{} | |||
| C2NetInfos *C2NetSqInfos | |||
| //elk config | |||
| ElkUrl string | |||
| ElkUser string | |||
| @@ -1428,7 +1441,12 @@ func GetGrampusConfig() { | |||
| Grampus.UserName = sec.Key("USERNAME").MustString("") | |||
| Grampus.Password = sec.Key("PASSWORD").MustString("") | |||
| Grampus.SpecialPools = sec.Key("SPECIAL_POOL").MustString("") | |||
| Grampus.C2NetSequence = sec.Key("C2NET_SEQUENCE").MustString("{\"sequence\":[{\"id\":1,\"name\":\"cloudbrain_one\",\"content\":\"鹏城云脑一号\"},{\"id\":2,\"name\":\"cloudbrain_two\",\"content\":\"鹏城云脑二号\"},{\"id\":3,\"name\":\"beida\",\"content\":\"北大人工智能集群系统\"},{\"id\":4,\"name\":\"hefei\",\"content\":\"合肥类脑智能开放平台\"},{\"id\":5,\"name\":\"wuhan\",\"content\":\"武汉人工智能计算中心\"},{\"id\":6,\"name\":\"xian\",\"content\":\"西安未来人工智能计算中心\"},{\"id\":7,\"pclcci\":\"more\",\"content\":\"鹏城云计算所\"},{\"id\":8,\"name\":\"xuchang\",\"content\":\"中原人工智能计算中心\"},{\"id\":9,\"name\":\"chengdu\",\"content\":\"成都人工智能计算中心\"},{\"id\":10,\"name\":\"more\",\"content\":\"横琴先进智能计算中心\"},{\"id\":11,\"name\":\"more\",\"content\":\"国家超级计算济南中心\"}]}") | |||
| if Grampus.C2NetSequence != "" { | |||
| if err := json.Unmarshal([]byte(Grampus.C2NetSequence), &C2NetInfos); err != nil { | |||
| log.Error("Unmarshal(C2NetSequence) failed:%v", err) | |||
| } | |||
| } | |||
| } | |||
| func SetRadarMapConfig() { | |||
| @@ -575,6 +575,8 @@ func GetObsLogFileName(prefix string) (string, error) { | |||
| log.Error("PutObject failed:", err.Error()) | |||
| return "", err | |||
| } | |||
| if output == nil || len(output.Contents) == 0 { | |||
| return "", errors.New("obs log files not exist") | |||
| } | |||
| return output.Contents[0].Key, nil | |||
| } | |||
| @@ -119,7 +119,6 @@ document.onreadystatechange = function () { | |||
| continue; | |||
| } | |||
| } | |||
| refresh3DInfo(record); | |||
| var recordPrefix = getMsg(record); | |||
| if(record.OpType == "6" || record.OpType == "10" || record.OpType == "12" || record.OpType == "13"){ | |||
| html += recordPrefix + actionName; | |||
| @@ -208,29 +207,6 @@ function getTaskLink(record){ | |||
| return re; | |||
| } | |||
| function refresh3DInfo(record){ | |||
| if(record.OpType == "25" || record.OpType == "29" || record.OpType == "31"){ | |||
| //cloudbrain one | |||
| var lines = $('.rotation3D__line'); | |||
| var span = $('.rotation3D__line').find("span")[0]; | |||
| //console.log(span); | |||
| span.innerText =record.RefName; | |||
| //$('.rotation3D__line').find("span").eq(0).text(record.RefName) | |||
| //console.log("cloudbrain one line length=" + lines.length); | |||
| //lines[0].find("span").text(record.RefName); | |||
| }else if(record.OpType == "26" || record.OpType == "27" || record.OpType == "28"){ | |||
| //cloudbrain two | |||
| var lines = $('.rotation3D__line'); | |||
| //console.log("cloudbrain two line length=" + lines.length); | |||
| var span = $('.rotation3D__line').find("span")[1]; | |||
| //console.log(span); | |||
| if(span != null){ | |||
| span.innerText =record.RefName; | |||
| } | |||
| } | |||
| } | |||
| function getMsg(record){ | |||
| var html =""; | |||
| html += "<div class=\"swiper-slide item\">"; | |||
| @@ -1064,6 +1064,8 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| m.Post("/prd/event", authentication.AcceptWechatEvent) | |||
| }) | |||
| m.Get("/wechat/material", authentication.GetMaterial) | |||
| m.Get("/cloudbrain/get_newest_job", repo.GetNewestJobs) | |||
| m.Get("/cloudbrain/get_center_info", repo.GetAICenterInfo) | |||
| }, securityHeaders(), context.APIContexter(), sudo()) | |||
| } | |||
| @@ -6,6 +6,7 @@ | |||
| package repo | |||
| import ( | |||
| "code.gitea.io/gitea/modules/setting" | |||
| "encoding/json" | |||
| "net/http" | |||
| "sort" | |||
| @@ -323,3 +324,94 @@ func CloudBrainModelList(ctx *context.APIContext) { | |||
| "PageIsCloudBrain": true, | |||
| }) | |||
| } | |||
| type JobInfo struct { | |||
| JobName string `json:"job_name"` | |||
| AiCenterId int `json:"ai_center_id"` | |||
| } | |||
| func GetNewestJobs(ctx *context.APIContext) { | |||
| idsC2Net, err := models.GetNewestJobsByAiCenter() | |||
| if err != nil { | |||
| log.Error("GetNewestJobsByAiCenter(%s) failed:%v", err.Error()) | |||
| return | |||
| } | |||
| idsCloudbrain, err := models.GetNewestJobsByType() | |||
| if err != nil { | |||
| log.Error("GetNewestJobsByType(%s) failed:%v", err.Error()) | |||
| return | |||
| } | |||
| ids := make([]int64, len(idsC2Net), cap(idsC2Net)*2) | |||
| copy(ids, idsC2Net) | |||
| for _, id := range idsCloudbrain { | |||
| ids = append(ids, id) | |||
| } | |||
| jobs, err := models.GetCloudbrainByIDs(ids) | |||
| if err != nil { | |||
| log.Error("GetCloudbrainByIDs(%s) failed:%v", err.Error()) | |||
| return | |||
| } | |||
| jobInfos := make([]JobInfo, 0) | |||
| for _, job := range jobs { | |||
| var id int | |||
| var content string | |||
| switch job.Type { | |||
| case models.TypeCloudBrainOne: | |||
| id, content = getAICenterID("cloudbrain_one") | |||
| if content == "" { | |||
| log.Error("job(%s) has no match config info", job.DisplayJobName) | |||
| continue | |||
| } | |||
| case models.TypeCloudBrainTwo: | |||
| id, content = getAICenterID("cloudbrain_two") | |||
| if content == "" { | |||
| log.Error("job(%s) has no match config info", job.DisplayJobName) | |||
| continue | |||
| } | |||
| case models.TypeC2Net: | |||
| centerInfo := strings.Split(job.AiCenter, "+") | |||
| if len(centerInfo) != 2 { | |||
| log.Error("job(%s):ai_center(%s) is wrong", job.DisplayJobName, job.AiCenter) | |||
| continue | |||
| } | |||
| id, content = getAICenterID(centerInfo[0]) | |||
| if content == "" { | |||
| log.Error("job(%s) has no match config info", job.DisplayJobName) | |||
| continue | |||
| } | |||
| default: | |||
| log.Error("no match info") | |||
| continue | |||
| } | |||
| jobInfos = append(jobInfos, JobInfo{ | |||
| JobName: job.DisplayJobName, | |||
| AiCenterId: id, | |||
| }) | |||
| } | |||
| ctx.JSON(http.StatusOK, jobInfos) | |||
| } | |||
| func GetAICenterInfo(ctx *context.APIContext) { | |||
| if setting.C2NetInfos == nil { | |||
| log.Error("C2NET_SEQUENCE is incorrect") | |||
| return | |||
| } | |||
| ctx.JSON(http.StatusOK, setting.C2NetInfos.C2NetSqInfo) | |||
| } | |||
| func getAICenterID(name string) (int, string) { | |||
| for _, info := range setting.C2NetInfos.C2NetSqInfo { | |||
| if name == info.Name { | |||
| return info.ID, info.Content | |||
| } | |||
| } | |||
| return 0, "" | |||
| } | |||
| @@ -51,23 +51,63 @@ | |||
| <script src="/rotation3D/vue-2.6.10.min.js"></script> | |||
| <script src="/rotation3D/rotation3D.js?v={{MD5 AppVer}}"></script> | |||
| <script> | |||
| var jobTask={}; | |||
| function queryAiCenterInfo(){ | |||
| $.ajax({ | |||
| type:"GET", | |||
| url:"/api/v1/cloudbrain/get_newest_job", | |||
| headers: { | |||
| authorization:token, | |||
| }, | |||
| dataType:"json", | |||
| async:false, | |||
| success:function(json){ | |||
| for(var i=0;i < json.length;i++){ | |||
| jobTask[json[i].ai_center_id] =json[i].job_name; | |||
| } | |||
| }, | |||
| error:function(response) { | |||
| console.log("query task info error."); | |||
| } | |||
| }); | |||
| $.ajax({ | |||
| type:"GET", | |||
| url:"/api/v1/cloudbrain/get_center_info", | |||
| headers: { | |||
| authorization:token, | |||
| }, | |||
| dataType:"json", | |||
| async:false, | |||
| success:function(json){ | |||
| displayAiCenterInfo(json); | |||
| }, | |||
| error:function(response) { | |||
| } | |||
| }); | |||
| } | |||
| function displayAiCenterInfo(json){ | |||
| for(var i=0;i<json.length;i++){ | |||
| var tmp ={}; | |||
| tmp["name"]=json[i].name; | |||
| if(jobTask[json[i].id] != null){ | |||
| tmp["type"]="blue"; | |||
| }else{ | |||
| tmp["type"]="green"; | |||
| } | |||
| tmp["icon"]=""; | |||
| tmp["content"]=json[i].content; | |||
| serverItemList.push(tmp); | |||
| } | |||
| } | |||
| var serverItemList=[]; | |||
| queryAiCenterInfo(); | |||
| var app = new Vue({ | |||
| el: "#app", | |||
| //数据 blue, green, yellow | |||
| data: { | |||
| itemList: [ | |||
| { name:'鹏城云脑一号', type:'blue', icon:'', }, | |||
| { name:'鹏城云脑二号', type:'blue', icon:'', }, | |||
| { name:'北大人工智能集群系统', type:'green', icon:'', }, | |||
| { name:'合肥类脑智能开放平台', type:'green', icon:'', }, | |||
| { name:'武汉人工智能计算中心', type:'green', icon:'', }, | |||
| { name:'西安未来人工智能计算中心', type:'green', icon:'', }, | |||
| { name:'……', type:'yellow', icon:'', }, | |||
| { name:'中原人工智能计算中心', type:'green', icon:'', }, | |||
| { name:'成都人工智能计算中心', type:'green', icon:'', }, | |||
| { name:'横琴先进智能计算中心', type:'green', icon:'', }, | |||
| { name:'国家超级计算济南中心', type:'green', icon:'', }, | |||
| ], | |||
| itemList:serverItemList, | |||
| }, | |||
| mounted: function () { | |||
| new Rotation3D({ | |||
| @@ -84,6 +124,19 @@ | |||
| }, | |||
| methods: {}, | |||
| }); | |||
| $(document).ready(function(){ | |||
| var pArrays=$('.itemList').find("p"); | |||
| for(var i=0;i<pArrays.length;i++){ | |||
| var p = pArrays[i]; | |||
| p.innerText=serverItemList[i].content; | |||
| } | |||
| var lines=$('.lineList').find("span"); | |||
| for(var i=0; i< lines.length;i++){ | |||
| if(jobTask[i+1] != null){ | |||
| lines[i].innerText = jobTask[i+1]; | |||
| } | |||
| } | |||
| }); | |||
| </script> | |||
| {{end}} | |||
| @@ -94,12 +94,6 @@ | |||
| </div> | |||
| <div id="app" v-cloak> | |||
| <!--数据 | |||
| <div class="aiData"> | |||
| <p>完成AI任务<br><strong id="completed_task">1716</strong></p> | |||
| <p>运行AI任务<br><strong id="running_task">120</strong></p> | |||
| <p>等待AI任务<br><strong id="wait_task">80</strong></p> | |||
| </div>--> | |||
| <!--底座--> | |||
| <div class="rotation3D-baseMap"></div> | |||
| <!--旋转3D--> | |||
| @@ -129,13 +123,13 @@ | |||
| <svg width="10" height="400"> | |||
| <path id="path2" d="M0 400, 0 0" stroke-dasharray="5,10"/> | |||
| </svg> | |||
| <div class="dot dot2"><i class="el-icon-close"></i></div> | |||
| <div class="dot dot2"><i class="el-icon-close"></i><span></span></div> | |||
| </div> | |||
| <div v-if="item.type=='green'" class="pos"> | |||
| <svg width="50" height="400"> | |||
| <path id="path1" d="M0 400, 0 0" stroke-dasharray="5,10"/> | |||
| </svg> | |||
| <div class="dot dot1 ri-arrow-left-s-line"></div> | |||
| <div class="dot dot1 ri-arrow-left-s-line"><span></span></div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| @@ -213,7 +213,7 @@ td, th { | |||
| <div class="ui pointing secondary menu" style="border-bottom: 1px solid rgba(34,36,38,.15);"> | |||
| <a class="active item" data-tab="first">{{$.i18n.Tr "repo.modelarts.train_job.config"}}</a> | |||
| <a class="item" data-tab="second" onclick="loadLog({{.VersionName}})">{{$.i18n.Tr "repo.modelarts.log"}}</a> | |||
| <a class="item log_bottom" data-tab="second" data-version="{{.VersionName}}">{{$.i18n.Tr "repo.modelarts.log"}}</a> | |||
| <a class="item load-model-file" data-tab="third" data-path="{{$.RepoLink}}/modelarts/inference-job/{{.JobID}}/result_list" data-version="{{.VersionName}}" data-parents="" data-filename="" data-init="init" >{{$.i18n.Tr "repo.model_download"}}</a> | |||
| </div> | |||
| @@ -451,10 +451,10 @@ td, th { | |||
| <div class="ui tab" data-tab="second"> | |||
| <div> | |||
| <a id="{{.VersionName}}-log-down" | |||
| class='{{if eq .Status "KILLED" "FAILED" "START_FAILED" "STOPPED" "COMPLETED" }}ti-download-file{{else}}disabled{{end}}' | |||
| class='{{if and (.CanModify) (eq .Status "KILLED" "FAILED" "START_FAILED" "STOPPED" "COMPLETED") }}ti-download-file{{else}}disabled{{end}}' | |||
| href="{{$.RepoLink}}/modelarts/train-job/{{.JobID}}/download_log_file?version_name={{.VersionName}}"> | |||
| <i class="ri-download-cloud-2-line"></i> | |||
| <span style="margin-left: 0.3rem;">{{$.i18n.Tr "repo.modelarts.download_log"}}</span> | |||
| <span style="margin-left: 0.3rem;">{{$.i18n.Tr "repo.modelarts.download_log"}}</span>{{.CanModify}} | |||
| </a> | |||
| </div> | |||
| @@ -507,6 +507,7 @@ td, th { | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| <script> | |||
| console.log('{{.CanModify}}') | |||
| $(document).ready(function(){ | |||
| $('.secondary.menu .item').tab(); | |||
| }); | |||
| @@ -521,13 +522,5 @@ $(document).ready(function(){ | |||
| repoPath = urlArr.slice(-4)[0] | |||
| jobID = urlArr.slice(-1)[0] | |||
| }) | |||
| function loadLog(version_name){ | |||
| $.get(`/api/v1/repos/${userName}/${repoPath}/modelarts/inference-job/${jobID}/log?version_name=${version_name}&lines=50&order=asc`, (data) => { | |||
| $('input[name=end_line]').val(data.EndLine) | |||
| $('input[name=start_line]').val(data.StartLine) | |||
| $(`#log_file${version_name}`).text(data.Content) | |||
| }).fail(function(err) { | |||
| console.log(err); | |||
| }); | |||
| } | |||
| </script> | |||
| @@ -487,7 +487,7 @@ | |||
| <div class="ui tab" data-tab="second{{$k}}"> | |||
| <div> | |||
| <a id="{{.VersionName}}-log-down" | |||
| class='{{if and ($.CanLogDownload) (eq .Status "KILLED" "FAILED" "START_FAILED" "STOPPED" "COMPLETED") }}ti-download-file{{else}}disabled{{end}}' | |||
| class='{{if and (.CanModify) (eq .Status "KILLED" "FAILED" "START_FAILED" "STOPPED" "COMPLETED") }}ti-download-file{{else}}disabled{{end}}' | |||
| href="{{$.RepoLink}}/modelarts/train-job/{{.JobID}}/download_log_file?version_name={{.VersionName}}"> | |||
| <i class="ri-download-cloud-2-line"></i> | |||
| <span style="margin-left: 0.3rem;">{{$.i18n.Tr "repo.modelarts.download_log"}}</span> | |||
| @@ -508,7 +508,7 @@ | |||
| <div class="ui message message{{.VersionName}}" style="display: none;"> | |||
| <div id="header"></div> | |||
| </div> | |||
| <div class="ui attached log log-scroll" id="log{{.VersionName}}" | |||
| <div class="ui attached log log-scroll" id="log{{.VersionName}}" data-version="{{.VersionName}}" | |||
| style="height: 300px !important; overflow: auto;"> | |||
| <input type="hidden" name="end_line" value> | |||
| <input type="hidden" name="start_line" value> | |||
| @@ -739,7 +739,6 @@ | |||
| $('#' + version_name + '-status').text(data.JobStatus) | |||
| console.log(data) | |||
| if (["KILLED", "FAILED", "START_FAILED", "STOPPED", "COMPLETED"].includes(data.JobStatus)) { | |||
| $(`#${version_name}-log-down`).removeClass('disabled').addClass('ti-download-file') | |||
| $('#' + version_name + '-stop').addClass('disabled') | |||
| } | |||
| @@ -796,6 +795,9 @@ | |||
| $('input[name=end_line]').val(data.EndLine) | |||
| $('input[name=start_line]').val(data.StartLine) | |||
| $(`#log_file${version_name}`).text(data.Content) | |||
| if(!data.CanLogDownload){ | |||
| $(`#${version_name}-log-down`).removeClass('ti-download-file').addClass('disabled') | |||
| } | |||
| }).fail(function (err) { | |||
| console.log(err); | |||
| }); | |||
| @@ -16,6 +16,7 @@ export default async function initCloudrainSow() { | |||
| function logScroll(version_name) { | |||
| let container = document.querySelector(`#log${version_name}`); | |||
| console.log(container); | |||
| let scrollTop = container.scrollTop; | |||
| let scrollHeight = container.scrollHeight; | |||
| let clientHeight = container.clientHeight; | |||