| @@ -135,7 +135,7 @@ func QueryModelByName(name string, repoId int64) []*AiModelManage { | |||
| sess := x.NewSession() | |||
| defer sess.Close() | |||
| sess.Select("*").Table("ai_model_manage"). | |||
| Where("name='" + name + "' and repo_id=" + fmt.Sprint(repoId)).OrderBy("version desc") | |||
| Where("name='" + name + "' and repo_id=" + fmt.Sprint(repoId)).OrderBy("created_unix desc") | |||
| aiModelManageList := make([]*AiModelManage, 0) | |||
| sess.Find(&aiModelManageList) | |||
| return aiModelManageList | |||
| @@ -1397,6 +1397,8 @@ func getIssueStatsChunk(opts *IssueStatsOptions, issueIDs []int64) (*IssueStats, | |||
| if opts.MilestoneID > 0 { | |||
| sess.And("issue.milestone_id = ?", opts.MilestoneID) | |||
| } else if opts.MilestoneID == -1 { //only search for issues do not have milestone | |||
| sess.And("issue.milestone_id = ?", 0) | |||
| } | |||
| if opts.AssigneeID > 0 { | |||
| @@ -2470,6 +2470,12 @@ func GetBlockChainUnSuccessRepos() ([]*Repository, error) { | |||
| Find(&repos) | |||
| } | |||
| func (repo *Repository) UpdateBlockChain() error { | |||
| _, err := x.Exec("UPDATE `repository` SET block_chain_status = ?, contract_address=? WHERE id = ?", repo.BlockChainStatus, repo.ContractAddress, repo.ID) | |||
| return err | |||
| } | |||
| func (repo *Repository) IncreaseCloneCnt() { | |||
| sess := x.NewSession() | |||
| defer sess.Close() | |||
| @@ -445,8 +445,12 @@ type Contributor struct { | |||
| Email string | |||
| } | |||
| func GetContributors(repoPath string) ([]Contributor, error){ | |||
| cmd := NewCommand("shortlog", "-sne", "--all") | |||
| func GetContributors(repoPath string, branchOrTag ...string) ([]Contributor, error) { | |||
| targetBranchOrTag := "HEAD" | |||
| if len(branchOrTag) > 0 && branchOrTag[0] != "" { | |||
| targetBranchOrTag = branchOrTag[0] | |||
| } | |||
| cmd := NewCommand("shortlog", "-sne", targetBranchOrTag) | |||
| stdout, err := cmd.RunInDir(repoPath) | |||
| if err != nil { | |||
| return nil, err | |||
| @@ -462,9 +466,9 @@ func GetContributors(repoPath string) ([]Contributor, error){ | |||
| } | |||
| number := oneCount[0:strings.Index(oneCount, "\t")] | |||
| commitCnt, _ := strconv.Atoi(number) | |||
| committer := oneCount[strings.Index(oneCount, "\t")+1:strings.LastIndex(oneCount, " ")] | |||
| committer := oneCount[strings.Index(oneCount, "\t")+1 : strings.LastIndex(oneCount, " ")] | |||
| committer = strings.Trim(committer, " ") | |||
| email := oneCount[strings.Index(oneCount, "<")+1:strings.Index(oneCount, ">")] | |||
| email := oneCount[strings.Index(oneCount, "<")+1 : strings.Index(oneCount, ">")] | |||
| contributorsInfo[i] = Contributor{ | |||
| commitCnt, committer, email, | |||
| } | |||
| @@ -778,8 +778,6 @@ datasets = Datasets | |||
| datasets.desc = Enable Dataset | |||
| cloudbrain_helper=Use GPU/NPU resources to open notebooks, model training tasks, etc. | |||
| model_manager = Model | |||
| debug=Debug | |||
| stop=Stop | |||
| delete=Delete | |||
| @@ -897,7 +895,7 @@ model.manage.Accuracy = Accuracy | |||
| model.manage.F1 = F1 | |||
| model.manage.Precision = Precision | |||
| model.manage.Recall = Recall | |||
| model.manage.sava_model = Sava Model | |||
| template.items = Template Items | |||
| template.git_content = Git Content (Default Branch) | |||
| @@ -907,6 +907,7 @@ model.manage.Accuracy = 准确率 | |||
| model.manage.F1 = F1值 | |||
| model.manage.Precision = 精确率 | |||
| model.manage.Recall = 召回率 | |||
| model.manage.sava_model = 保存模型 | |||
| template.items=模板选项 | |||
| template.git_content=Git数据(默认分支) | |||
| @@ -72,7 +72,7 @@ func HandleBlockChainInitNotify(ctx *context.Context) { | |||
| repo.BlockChainStatus = models.RepoBlockChainSuccess | |||
| repo.ContractAddress = req.ContractAddress | |||
| if err = models.UpdateRepositoryCols(repo, "block_chain_status", "contract_address"); err != nil { | |||
| if err = repo.UpdateBlockChain(); err != nil { | |||
| log.Error("UpdateRepositoryCols failed:%v", err.Error(), ctx.Data["msgID"]) | |||
| ctx.JSON(200, map[string]string{ | |||
| "code": "-1", | |||
| @@ -193,6 +193,8 @@ func issues(ctx *context.Context, milestoneID int64, isPullOption util.OptionalB | |||
| var mileIDs []int64 | |||
| if milestoneID > 0 { | |||
| mileIDs = []int64{milestoneID} | |||
| } else if milestoneID == -1 { //only search no milestone | |||
| mileIDs = []int64{0} | |||
| } | |||
| var issues []*models.Issue | |||
| @@ -355,7 +357,7 @@ func Issues(ctx *context.Context) { | |||
| var err error | |||
| // Get milestones. | |||
| ctx.Data["Milestones"], err = models.GetMilestonesByRepoID(ctx.Repo.Repository.ID, api.StateType(ctx.Query("state")), models.ListOptions{}) | |||
| ctx.Data["Milestones"], err = models.GetMilestonesByRepoID(ctx.Repo.Repository.ID, api.StateAll, models.ListOptions{}) | |||
| if err != nil { | |||
| ctx.ServerError("GetAllRepoMilestones", err) | |||
| return | |||
| @@ -605,7 +605,7 @@ func getContributorInfo(contributorInfos []*ContributorInfo, email string) *Cont | |||
| func Home(ctx *context.Context) { | |||
| if len(ctx.Repo.Units) > 0 { | |||
| //get repo contributors info | |||
| contributors, err := git.GetContributors(ctx.Repo.Repository.RepoPath()) | |||
| contributors, err := git.GetContributors(ctx.Repo.Repository.RepoPath(), ctx.Repo.BranchName) | |||
| if err == nil && contributors != nil { | |||
| startTime := time.Now() | |||
| var contributorInfos []*ContributorInfo | |||
| @@ -924,7 +924,9 @@ func ContributorsAPI(ctx *context.Context) { | |||
| count := 0 | |||
| errorCode := 0 | |||
| errorMsg := "" | |||
| contributors, err := git.GetContributors(ctx.Repo.Repository.RepoPath()) | |||
| branchOrTag := ctx.Query("name") | |||
| contributors, err := git.GetContributors(ctx.Repo.Repository.RepoPath(), branchOrTag) | |||
| var contributorInfos []*ContributorInfo | |||
| if err == nil && contributors != nil { | |||
| contributorInfoHash := make(map[string]*ContributorInfo) | |||
| @@ -114,7 +114,7 @@ | |||
| </div> | |||
| <div class="inline field"> | |||
| <label>模型标签</label> | |||
| <input style="width: 83%;margin-left: 7px;" name="Label" maxlength="255" placeholder='{{.i18n.Tr "repo.modelarts.train_job.label_place"}}'> | |||
| <input style="width: 83%;margin-left: 7px;" id="label" name="Label" maxlength="255" placeholder='{{.i18n.Tr "repo.modelarts.train_job.label_place"}}'> | |||
| </div> | |||
| <div class="inline field"> | |||
| <label for="description">模型描述</label> | |||
| @@ -123,7 +123,7 @@ | |||
| <div class="inline field" style="margin-left: 75px;"> | |||
| <button id="submitId" type="button" class="ui create_train_job green button" style="position: absolute;"> | |||
| {{.i18n.Tr "repo.cloudbrain.new"}} | |||
| {{.i18n.Tr "repo.model.manage.sava_model"}} | |||
| </button> | |||
| </div> | |||
| </form> | |||
| @@ -169,6 +169,7 @@ | |||
| $('#choice_model').dropdown('clear') | |||
| $('#choice_version').dropdown('clear') | |||
| $('.ui.dimmer').css({"background-color":""}) | |||
| $('.ui.error.message').text() | |||
| $('.ui.error.message').css('display','none') | |||
| } | |||
| @@ -211,7 +212,6 @@ | |||
| } | |||
| $("#job-name").append(train_html) | |||
| $(".ui.dropdown.selection.search.width83").removeClass("loading") | |||
| $('#choice_model .default.text').text(data[0].JobName) | |||
| $('#choice_model input[name="JobId"]').val(data[0].JobID) | |||
| loadTrainVersion() | |||
| @@ -227,10 +227,13 @@ | |||
| train_html += `<div class="item" data-value="${data[i].VersionName}">${data[i].VersionName}</div>` | |||
| train_html += '</div>' | |||
| } | |||
| $("#job-version").append(train_html) | |||
| $(".ui.dropdown.selection.search.width70").removeClass("loading") | |||
| $('#choice_version .default.text').text(data[0].VersionName) | |||
| $('#choice_version input[name="VersionName"]').val(data[0].VersionName) | |||
| if(data.length){ | |||
| $("#job-version").append(train_html) | |||
| $(".ui.dropdown.selection.search.width70").removeClass("loading") | |||
| $('#choice_version .default.text').text(data[0].VersionName) | |||
| $('#choice_version input[name="VersionName"]').val(data[0].VersionName) | |||
| } | |||
| }) | |||
| } | |||
| </script> | |||
| @@ -221,6 +221,7 @@ function tranSize(value){ | |||
| function editorFn(context){ | |||
| let id= context.dataset.id | |||
| let text = context.dataset.desc | |||
| console.log(id,text) | |||
| $('#edit-td').replaceWith("<div id='edit-div' style='width:80%;display: inline-block;'><textarea id='textarea-value' value='' rows='3' maxlength='255' style='width:80%;' id='edit-text'>"+text+"</textarea><i class='check icon' style='color: #50d4ab;' onclick='editorSure(\"" + text + "\",\"" + id + "\")'></i><i class='times icon' style='color: #f66f6a;' onclick='editorCancel(\"" + text + "\",\"" + id + "\")'></i></div>"); | |||
| } | |||
| @@ -95,8 +95,8 @@ | |||
| min-width="6.75%" | |||
| > | |||
| <template slot-scope="scope"> | |||
| <a :href="'/'+scope.row.UserName" :title="scope.row.UserName"> | |||
| <img class="ui avatar image" :src="scope.row.UserRelAvatarLink"> | |||
| <a :href="!scope.row.UserName? '#':'/'+scope.row.UserName" :title="scope.row.UserName||defaultAvatarName"> | |||
| <img class="ui avatar image" :src="scope.row.UserRelAvatarLink||defaultAvatar"> | |||
| </a> | |||
| </template> | |||
| </el-table-column> | |||
| @@ -104,7 +104,7 @@ | |||
| <el-table-column label="操作" min-width="18%" align="center"> | |||
| <template slot-scope="scope"> | |||
| <div class="space-around"> | |||
| <a :style="{visibility:!scope.row.Children ? 'visible':'hidden'}" :class="{'disabled':!scope.row.IsCanOper}" @click="showcreateVue(scope.row.Name,scope.row.Version)">创建新版本</a> | |||
| <a :style="{visibility:!scope.row.Children ? 'visible':'hidden'}" :class="{'disabled':!scope.row.IsCanOper}" @click="showcreateVue(scope.row.Name,scope.row.Version,scope.row.Label)">创建新版本</a> | |||
| <a :href="loadhref+scope.row.ID" :class="{'disabled':!scope.row.IsCanOper}">下载</a> | |||
| <a :class="{'disabled':!scope.row.IsCanOper}" @click="deleteModel(scope.row.ID,scope.row.cName)">删除</a> | |||
| </div> | |||
| @@ -141,6 +141,7 @@ export default { | |||
| }, | |||
| data() { | |||
| return { | |||
| currentPage:1, | |||
| pageSize:10, | |||
| totalNum:0, | |||
| @@ -149,29 +150,37 @@ export default { | |||
| url:'', | |||
| isLoading:true, | |||
| loadNodeMap:new Map(), | |||
| submitId:{} | |||
| submitId:{}, | |||
| defaultAvatar:'/user/avatar/Ghost/-1', | |||
| defaultAvatarName:'Ghost', | |||
| data:'' | |||
| }; | |||
| }, | |||
| methods: { | |||
| load(tree, treeNode, resolve) { | |||
| this.loadNodeMap.set(tree.cName, {tree,treeNode,resolve}) | |||
| this.$axios.get(this.url+'show_model_child_api',{params:{ | |||
| name:tree.cName | |||
| }}).then((res)=>{ | |||
| let TrainTaskInfo | |||
| let tableData | |||
| tableData= res.data | |||
| for(let i=0;i<tableData.length;i++){ | |||
| TrainTaskInfo = JSON.parse(tableData[i].TrainTaskInfo) | |||
| tableData[i].EngineName = TrainTaskInfo.EngineName.split('-')[0] | |||
| tableData[i].ComputeResource = TrainTaskInfo.ComputeResource | |||
| tableData[i].cName=tableData[i].Name | |||
| tableData[i].Name='' | |||
| tableData[i].VersionCount = '' | |||
| tableData[i].Children = true | |||
| } | |||
| resolve(tableData) | |||
| }) | |||
| try{ | |||
| this.loadNodeMap.set(tree.cName, {tree,treeNode,resolve}) | |||
| this.$axios.get(this.url+'show_model_child_api',{params:{ | |||
| name:tree.cName | |||
| }}).then((res)=>{ | |||
| let TrainTaskInfo | |||
| let tableData | |||
| tableData= res.data | |||
| for(let i=0;i<tableData.length;i++){ | |||
| TrainTaskInfo = JSON.parse(tableData[i].TrainTaskInfo) | |||
| tableData[i].EngineName = TrainTaskInfo.EngineName.split('-')[0] | |||
| tableData[i].ComputeResource = TrainTaskInfo.ComputeResource | |||
| tableData[i].cName=tableData[i].Name | |||
| tableData[i].Name='' | |||
| tableData[i].VersionCount = '' | |||
| tableData[i].Children = true | |||
| } | |||
| resolve(tableData||[]) | |||
| }) | |||
| } | |||
| catch(e){ | |||
| this.loading = false; | |||
| } | |||
| }, | |||
| tableHeaderStyle({row,column,rowIndex,columnIndex}){ | |||
| if(rowIndex===0){ | |||
| @@ -186,26 +195,32 @@ export default { | |||
| this.params.page = val | |||
| this.getModelList() | |||
| }, | |||
| showcreateVue(name,version){ | |||
| showcreateVue(name,version,label){ | |||
| $('.ui.modal.second') | |||
| .modal({ | |||
| centered: false, | |||
| onShow:function(){ | |||
| $('#model_header').text("创建模型新版本") | |||
| $('input[name="Name"]').addClass('model_disabled') | |||
| $('input[name="Name"]').attr('readonly','readonly') | |||
| $('input[name="Version"]').addClass('model_disabled') | |||
| $('.ui.dimmer').css({"background-color":"rgb(136, 136, 136,0.7)"}) | |||
| $("#job-name").empty() | |||
| $('#name').val(name) | |||
| $('#label').val(label) | |||
| let version_string = versionAdd(version) | |||
| $('#version').val(version_string) | |||
| loadTrainList() | |||
| }, | |||
| onHide:function(){ | |||
| document.getElementById("formId").reset(); | |||
| $('input[name="Name"]').removeClass('model_disabled') | |||
| $('input[name="Name"]').removeAttr('readonly') | |||
| $('#choice_model').dropdown('clear') | |||
| $('#choice_version').dropdown('clear') | |||
| $('.ui.dimmer').css({"background-color":""}) | |||
| $('.ui.error.message').text() | |||
| $('.ui.error.message').css('display','none') | |||
| } | |||
| }) | |||
| .modal('show') | |||
| @@ -240,23 +255,22 @@ export default { | |||
| $("#verionname").removeClass("error") | |||
| } | |||
| return true | |||
| }, | |||
| submit(){ | |||
| let context = this | |||
| let flag= this.check() | |||
| if(flag){ | |||
| let data = $("#formId").serialize() | |||
| let cName = $("input[name='Name']").val() | |||
| let row = {cName:cName} | |||
| let version = $("input[name='Version']").val() | |||
| let data = $("#formId").serialize() | |||
| $("#mask").css({"display":"block","z-index":"9999"}) | |||
| $.ajax({ | |||
| url:url_href, | |||
| type:'POST', | |||
| data:data, | |||
| success:function(res){ | |||
| // context.loadrefresh1(row) | |||
| context.getModelList() | |||
| context.loadrefresh(row) | |||
| $('.ui.modal.second').modal('hide') | |||
| }, | |||
| error: function(xhr){ | |||
| @@ -274,20 +288,32 @@ export default { | |||
| } | |||
| }, | |||
| loadrefresh(row){ | |||
| const store = this.$refs.table.store | |||
| if(!this.loadNodeMap.get(row.cName)){ | |||
| return | |||
| const parent = store.states.data | |||
| const index = parent.findIndex(child => child.ID == row.ID) | |||
| parent.splice(index, 1) | |||
| }else{ | |||
| let {tree,treeNode,resolve} = this.loadNodeMap.get(row.cName) | |||
| this.$set( | |||
| this.$refs.table.store.states.lazyTreeNodeMap, | |||
| tree.ID, | |||
| []) | |||
| this.load(tree,treeNode,resolve) | |||
| const keys = Object.keys(store.states.lazyTreeNodeMap); | |||
| if(keys.includes(row.ID)){ | |||
| this.getModelList() | |||
| }else{ | |||
| let parentRow = store.states.data.find(child => child.cName == row.cName); | |||
| let childrenIndex = store.states.lazyTreeNodeMap[parentRow.ID].findIndex(child => child.ID == row.ID) | |||
| parentRow.VersionCount = parentRow.VersionCount-1 | |||
| const parent = store.states.lazyTreeNodeMap[parentRow.ID] | |||
| if(parent.length===1){ | |||
| this.getModelList() | |||
| }else{ | |||
| parent.splice(childrenIndex, 1); | |||
| } | |||
| } | |||
| } | |||
| }, | |||
| deleteModel(id,name){ | |||
| let row={cName:name} | |||
| let row={cName:name,ID:id} | |||
| let _this = this | |||
| let flag=1 | |||
| $('.ui.basic.modal.first') | |||
| @@ -300,8 +326,8 @@ export default { | |||
| params:{ | |||
| ID:id | |||
| }}).then((res)=>{ | |||
| _this.getModelList() | |||
| _this.loadrefresh(row) | |||
| // _this.getModelList() | |||
| }) | |||
| flag = true | |||
| }, | |||
| @@ -315,24 +341,29 @@ export default { | |||
| }) | |||
| .modal('show') | |||
| }, | |||
| getModelList(){ | |||
| this.$axios.get(location.href+'_api',{ | |||
| params:this.params | |||
| }).then((res)=>{ | |||
| $(".ui.grid").removeAttr("style") | |||
| $("#loadContainer").removeClass("loader") | |||
| let TrainTaskInfo | |||
| this.tableData = res.data.data | |||
| for(let i=0;i<this.tableData.length;i++){ | |||
| TrainTaskInfo = JSON.parse(this.tableData[i].TrainTaskInfo) | |||
| this.tableData[i].cName=this.tableData[i].Name | |||
| this.tableData[i].EngineName = TrainTaskInfo.EngineName.split('-')[0] | |||
| this.tableData[i].ComputeResource = TrainTaskInfo.ComputeResource | |||
| this.tableData[i].hasChildren = res.data.data[i].VersionCount===1 ? false : true | |||
| } | |||
| this.totalNum = res.data.count | |||
| }) | |||
| try { | |||
| this.$refs.table.store.states.lazyTreeNodeMap = {} | |||
| this.$axios.get(location.href+'_api',{ | |||
| params:this.params | |||
| }).then((res)=>{ | |||
| $(".ui.grid").removeAttr("style") | |||
| $("#loadContainer").removeClass("loader") | |||
| let TrainTaskInfo | |||
| this.tableData = res.data.data | |||
| for(let i=0;i<this.tableData.length;i++){ | |||
| TrainTaskInfo = JSON.parse(this.tableData[i].TrainTaskInfo) | |||
| this.tableData[i].cName=this.tableData[i].Name | |||
| this.tableData[i].EngineName = TrainTaskInfo.EngineName.split('-')[0] | |||
| this.tableData[i].ComputeResource = TrainTaskInfo.ComputeResource | |||
| this.tableData[i].hasChildren = res.data.data[i].VersionCount===1 ? false : true | |||
| } | |||
| this.totalNum = res.data.count | |||
| }) | |||
| }catch (e) { | |||
| console.log(e) | |||
| } | |||
| }, | |||
| }, | |||
| @@ -369,8 +400,6 @@ export default { | |||
| return size+unitArr[index]; | |||
| } | |||
| } | |||
| }, | |||
| mounted() { | |||
| this.submitId = document.getElementById("submitId") | |||