Reviewed-on: https://git.openi.org.cn/OpenI/aiforge/pulls/2469 Reviewed-by: ychao_1983 <ychao_1983@sina.com>tags/v1.22.7.1
| @@ -29,51 +29,22 @@ | |||||
| } | } | ||||
| .rotation3D__item .scale{ position: absolute; top: 0; width: 100%; height: 100%; } | .rotation3D__item .scale{ position: absolute; top: 0; width: 100%; height: 100%; } | ||||
| .rotation3D__item .cont{ position: relative; z-index: 2; } | .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; } | .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.blue{ color: #01e9fc; } | ||||
| .rotation3D__item.green{ color: #b4b3ca; } | .rotation3D__item.green{ color: #b4b3ca; } | ||||
| .rotation3D__item.yellow{ color: #ffd200; } | .rotation3D__item.yellow{ color: #ffd200; } | ||||
| @@ -90,14 +61,17 @@ | |||||
| ---------------------------*/ | ---------------------------*/ | ||||
| .rotation3D__line{ | .rotation3D__line{ | ||||
| position: absolute; left: 50%; top: 50%; | 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; | padding-top: 60px; color: #fff; font-size: 50px; | ||||
| /*background: #fff;*/ | /*background: #fff;*/ | ||||
| /*原点设置在中间*/ | /*原点设置在中间*/ | ||||
| transform-origin: 50% 0; | transform-origin: 50% 0; | ||||
| transform-style: preserve-3d; | 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 { position: absolute; top: 0; } | ||||
| .rotation3D__line svg path { | .rotation3D__line svg path { | ||||
| stroke: #fff; fill: none; | stroke: #fff; fill: none; | ||||
| @@ -139,8 +113,10 @@ | |||||
| position: absolute; | position: absolute; | ||||
| font-size: 12px; | font-size: 12px; | ||||
| color: #888; | color: #888; | ||||
| transform: rotate(180deg)scale(0.80); | |||||
| } | |||||
| transform:scale(0.80); | |||||
| transform-origin:left; | |||||
| white-space: nowrap; | |||||
| } | |||||
| /*颜色*/ | /*颜色*/ | ||||
| .rotation3D__line.blue { color: #07b2f9; } | .rotation3D__line.blue { color: #07b2f9; } | ||||
| @@ -134,7 +134,7 @@ type Cloudbrain struct { | |||||
| CanDebug bool `xorm:"-"` | CanDebug bool `xorm:"-"` | ||||
| CanDel bool `xorm:"-"` | CanDel bool `xorm:"-"` | ||||
| CanModify bool `xorm:"-"` | CanModify bool `xorm:"-"` | ||||
| Type int | |||||
| Type int `xorm:"INDEX"` | |||||
| BenchmarkTypeID int | BenchmarkTypeID int | ||||
| BenchmarkChildTypeID int | BenchmarkChildTypeID int | ||||
| @@ -2019,3 +2019,30 @@ func GetDatasetInfo(uuidStr string) (map[string]DatasetInfo, string, error) { | |||||
| return datasetInfos, datasetNames, nil | 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 ( | import ( | ||||
| "encoding/base64" | "encoding/base64" | ||||
| "encoding/json" | |||||
| "fmt" | "fmt" | ||||
| "io" | "io" | ||||
| "io/ioutil" | "io/ioutil" | ||||
| @@ -64,7 +65,16 @@ const ( | |||||
| ReCaptcha = "recaptcha" | 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 ( | var ( | ||||
| // AppVer settings | // AppVer settings | ||||
| AppVer string | AppVer string | ||||
| @@ -534,13 +544,16 @@ var ( | |||||
| //grampus config | //grampus config | ||||
| Grampus = struct { | 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 | //elk config | ||||
| ElkUrl string | ElkUrl string | ||||
| ElkUser string | ElkUser string | ||||
| @@ -1423,7 +1436,12 @@ func GetGrampusConfig() { | |||||
| Grampus.UserName = sec.Key("USERNAME").MustString("") | Grampus.UserName = sec.Key("USERNAME").MustString("") | ||||
| Grampus.Password = sec.Key("PASSWORD").MustString("") | Grampus.Password = sec.Key("PASSWORD").MustString("") | ||||
| Grampus.SpecialPools = sec.Key("SPECIAL_POOL").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() { | func SetRadarMapConfig() { | ||||
| @@ -119,7 +119,6 @@ document.onreadystatechange = function () { | |||||
| continue; | continue; | ||||
| } | } | ||||
| } | } | ||||
| refresh3DInfo(record); | |||||
| var recordPrefix = getMsg(record); | var recordPrefix = getMsg(record); | ||||
| if(record.OpType == "6" || record.OpType == "10" || record.OpType == "12" || record.OpType == "13"){ | if(record.OpType == "6" || record.OpType == "10" || record.OpType == "12" || record.OpType == "13"){ | ||||
| html += recordPrefix + actionName; | html += recordPrefix + actionName; | ||||
| @@ -208,29 +207,6 @@ function getTaskLink(record){ | |||||
| return re; | 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){ | function getMsg(record){ | ||||
| var html =""; | var html =""; | ||||
| html += "<div class=\"swiper-slide item\">"; | html += "<div class=\"swiper-slide item\">"; | ||||
| @@ -1057,6 +1057,8 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| m.Post("/prd/event", authentication.AcceptWechatEvent) | m.Post("/prd/event", authentication.AcceptWechatEvent) | ||||
| }) | }) | ||||
| m.Get("/wechat/material", authentication.GetMaterial) | 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()) | }, securityHeaders(), context.APIContexter(), sudo()) | ||||
| } | } | ||||
| @@ -6,6 +6,7 @@ | |||||
| package repo | package repo | ||||
| import ( | import ( | ||||
| "code.gitea.io/gitea/modules/setting" | |||||
| "encoding/json" | "encoding/json" | ||||
| "net/http" | "net/http" | ||||
| "sort" | "sort" | ||||
| @@ -207,3 +208,92 @@ func CloudBrainModelList(ctx *context.APIContext) { | |||||
| "PageIsCloudBrain": true, | "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) | |||||
| copy(ids, idsCloudbrain) | |||||
| 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/vue-2.6.10.min.js"></script> | ||||
| <script src="/rotation3D/rotation3D.js?v={{MD5 AppVer}}"></script> | <script src="/rotation3D/rotation3D.js?v={{MD5 AppVer}}"></script> | ||||
| <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({ | var app = new Vue({ | ||||
| el: "#app", | el: "#app", | ||||
| //数据 blue, green, yellow | //数据 blue, green, yellow | ||||
| data: { | 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 () { | mounted: function () { | ||||
| new Rotation3D({ | new Rotation3D({ | ||||
| @@ -84,6 +124,19 @@ | |||||
| }, | }, | ||||
| methods: {}, | 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> | </script> | ||||
| {{end}} | {{end}} | ||||
| @@ -94,12 +94,6 @@ | |||||
| </div> | </div> | ||||
| <div id="app" v-cloak> | <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> | <div class="rotation3D-baseMap"></div> | ||||
| <!--旋转3D--> | <!--旋转3D--> | ||||
| @@ -129,13 +123,13 @@ | |||||
| <svg width="10" height="400"> | <svg width="10" height="400"> | ||||
| <path id="path2" d="M0 400, 0 0" stroke-dasharray="5,10"/> | <path id="path2" d="M0 400, 0 0" stroke-dasharray="5,10"/> | ||||
| </svg> | </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> | ||||
| <div v-if="item.type=='green'" class="pos"> | <div v-if="item.type=='green'" class="pos"> | ||||
| <svg width="50" height="400"> | <svg width="50" height="400"> | ||||
| <path id="path1" d="M0 400, 0 0" stroke-dasharray="5,10"/> | <path id="path1" d="M0 400, 0 0" stroke-dasharray="5,10"/> | ||||
| </svg> | </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> | </div> | ||||
| </div> | </div> | ||||