| @@ -1999,3 +1999,16 @@ func IsErrJobNotExist(err error) bool { | |||||
| func (err ErrJobNotExist) Error() string { | func (err ErrJobNotExist) Error() string { | ||||
| return fmt.Sprintf("the job does not exist") | return fmt.Sprintf("the job does not exist") | ||||
| } | } | ||||
| type ErrTagNotExist struct { | |||||
| TagID int64 | |||||
| } | |||||
| func (err ErrTagNotExist) Error() string { | |||||
| return fmt.Sprintf("the tag does not exist") | |||||
| } | |||||
| func IsErrTagNotExist(err error) bool { | |||||
| _, ok := err.(ErrTagNotExist) | |||||
| return ok | |||||
| } | |||||
| @@ -134,6 +134,8 @@ func init() { | |||||
| new(BlockChain), | new(BlockChain), | ||||
| new(RecommendOrg), | new(RecommendOrg), | ||||
| new(AiModelManage), | new(AiModelManage), | ||||
| new(OfficialTag), | |||||
| new(OfficialTagRepos), | |||||
| ) | ) | ||||
| tablesStatistic = append(tablesStatistic, | tablesStatistic = append(tablesStatistic, | ||||
| @@ -0,0 +1,165 @@ | |||||
| package models | |||||
| import ( | |||||
| "code.gitea.io/gitea/modules/log" | |||||
| "code.gitea.io/gitea/modules/timeutil" | |||||
| "fmt" | |||||
| ) | |||||
| const DefaultOrgTagLimit = -1 | |||||
| type OfficialTag struct { | |||||
| ID int64 `xorm:"pk autoincr"` | |||||
| Name string `xorm:"NOT NULL"` | |||||
| Code string `xorm:"NOT NULL"` | |||||
| Limit int `xorm:"NOT NULL default(-1)"` | |||||
| Status int `xorm:"NOT NULL default(0)"` | |||||
| CreatedUnix timeutil.TimeStamp `xorm:"created"` | |||||
| UpdatedUnix timeutil.TimeStamp `xorm:"updated"` | |||||
| } | |||||
| type OfficialTagRepos struct { | |||||
| ID int64 `xorm:"pk autoincr"` | |||||
| OrgID int64 `xorm:"NOT NULL INDEX"` | |||||
| TagID int64 `xorm:"NOT NULL"` | |||||
| RepoID int64 `xorm:"NOT NULL INDEX"` | |||||
| CreatedUnix timeutil.TimeStamp `xorm:"created"` | |||||
| UpdatedUnix timeutil.TimeStamp `xorm:"updated"` | |||||
| } | |||||
| type TagReposBrief struct { | |||||
| RepoID int64 | |||||
| RepoName string | |||||
| TagID int64 | |||||
| } | |||||
| type TagReposSelected struct { | |||||
| RepoID int64 | |||||
| RepoName string | |||||
| Selected bool | |||||
| } | |||||
| type TagsDetail struct { | |||||
| TagId int64 | |||||
| TagName string | |||||
| TagLimit int | |||||
| RepoList []Repository | |||||
| } | |||||
| func GetTagByID(id int64) (*OfficialTag, error) { | |||||
| r := &OfficialTag{ | |||||
| ID: id, | |||||
| } | |||||
| has, err := x.Get(r) | |||||
| if err != nil { | |||||
| return nil, err | |||||
| } else if !has { | |||||
| return nil, ErrTagNotExist{0} | |||||
| } | |||||
| return r, nil | |||||
| } | |||||
| func UpdateTagReposByID(tagID, orgID int64, repoIdList []int64) error { | |||||
| sess := x.NewSession() | |||||
| defer sess.Close() | |||||
| if err := sess.Begin(); err != nil { | |||||
| return fmt.Errorf("UpdateTagReposByID[tagId: %d, orgID: %d,error:%v", tagID, orgID, err) | |||||
| } | |||||
| //delete old tag repos | |||||
| r := &OfficialTagRepos{ | |||||
| TagID: tagID, | |||||
| OrgID: orgID, | |||||
| } | |||||
| _, err := sess.Delete(r) | |||||
| if err != nil { | |||||
| return err | |||||
| } | |||||
| if len(repoIdList) == 0 { | |||||
| return sess.Commit() | |||||
| } | |||||
| //add new tag repos | |||||
| data := make([]*OfficialTagRepos, 0) | |||||
| for _, repoId := range repoIdList { | |||||
| data = append(data, &OfficialTagRepos{ | |||||
| OrgID: orgID, | |||||
| TagID: tagID, | |||||
| RepoID: repoId, | |||||
| }) | |||||
| } | |||||
| _, err = sess.Insert(&data) | |||||
| if err != nil { | |||||
| sess.Rollback() | |||||
| return err | |||||
| } | |||||
| return sess.Commit() | |||||
| } | |||||
| func GetTagRepos(tagID, orgID int64) ([]TagReposSelected, error) { | |||||
| t := make([]TagReposBrief, 0) | |||||
| const SQLCmd = "select t1.id as repo_id,t1.name as repo_name,t2.id as tag_id from repository t1 left join official_tag_repos t2 on (t1.id = t2.repo_id and t2.tag_id = ?) where t1.owner_id = ? and t1.is_private = false order by t1.updated_unix desc" | |||||
| if err := x.SQL(SQLCmd, tagID, orgID).Find(&t); err != nil { | |||||
| return nil, err | |||||
| } | |||||
| r := make([]TagReposSelected, 0) | |||||
| for _, v := range t { | |||||
| selected := false | |||||
| if v.TagID > 0 { | |||||
| selected = true | |||||
| } | |||||
| r = append(r, TagReposSelected{ | |||||
| RepoID: v.RepoID, | |||||
| RepoName: v.RepoName, | |||||
| Selected: selected, | |||||
| }) | |||||
| } | |||||
| return r, nil | |||||
| } | |||||
| func GetAllOfficialTagRepos(orgID int64, isOwner bool) ([]TagsDetail, error) { | |||||
| result := make([]TagsDetail, 0) | |||||
| tags, err := GetAllOfficialTags() | |||||
| if err != nil { | |||||
| return nil, err | |||||
| } | |||||
| for _, tag := range tags { | |||||
| repos, err := GetOfficialTagDetail(orgID, tag.ID) | |||||
| if err != nil { | |||||
| return nil, err | |||||
| } | |||||
| if len(repos) == 0 && !isOwner { | |||||
| continue | |||||
| } | |||||
| result = append(result, TagsDetail{ | |||||
| TagId: tag.ID, | |||||
| TagName: tag.Name, | |||||
| TagLimit: tag.Limit, | |||||
| RepoList: repos, | |||||
| }) | |||||
| } | |||||
| return result, nil | |||||
| } | |||||
| func GetOfficialTagDetail(orgID, tagId int64) ([]Repository, error) { | |||||
| t := make([]Repository, 0) | |||||
| const SQLCmd = "select t2.* from official_tag_repos t1 inner join repository t2 on t1.repo_id = t2.id where t1.org_id = ? and t1.tag_id=? order by t2.updated_unix desc" | |||||
| if err := x.SQL(SQLCmd, orgID, tagId).Find(&t); err != nil { | |||||
| return nil, err | |||||
| } | |||||
| return t, nil | |||||
| } | |||||
| func GetAllOfficialTags() ([]OfficialTag, error) { | |||||
| //todo redis? | |||||
| o := make([]OfficialTag, 0) | |||||
| err := x.Where("status = ?", 0).Find(&o) | |||||
| if err != nil { | |||||
| log.Error("GetAllOfficialTags error,%v", err) | |||||
| return nil, err | |||||
| } | |||||
| return o, nil | |||||
| } | |||||
| @@ -70,3 +70,7 @@ type CreateTeamForm struct { | |||||
| func (f *CreateTeamForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | func (f *CreateTeamForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | ||||
| return validate(errs, ctx.Data, f, ctx.Locale) | return validate(errs, ctx.Data, f, ctx.Locale) | ||||
| } | } | ||||
| type SubmitReposOfTagForm struct { | |||||
| RepoList []int64 | |||||
| } | |||||
| @@ -222,6 +222,7 @@ contributors = Contributors | |||||
| [explore] | [explore] | ||||
| repos = Repositories | repos = Repositories | ||||
| select_repos = Select the project | |||||
| users = Users | users = Users | ||||
| organizations = Organizations | organizations = Organizations | ||||
| images = CloudImages | images = CloudImages | ||||
| @@ -234,6 +235,8 @@ org_no_results = No matching organizations found. | |||||
| code_no_results = No source code matching your search term found. | code_no_results = No source code matching your search term found. | ||||
| code_search_results = Search results for '%s' | code_search_results = Search results for '%s' | ||||
| code_last_indexed_at = Last indexed %s | code_last_indexed_at = Last indexed %s | ||||
| save=save | |||||
| cancel=cancel | |||||
| [auth] | [auth] | ||||
| create_new_account = Register Account | create_new_account = Register Account | ||||
| @@ -224,6 +224,7 @@ contributors=贡献者 | |||||
| [explore] | [explore] | ||||
| repos=项目 | repos=项目 | ||||
| select_repos=精选项目 | |||||
| users=用户 | users=用户 | ||||
| organizations=组织 | organizations=组织 | ||||
| images = 云脑镜像 | images = 云脑镜像 | ||||
| @@ -238,6 +239,8 @@ org_no_results=未找到匹配的组织。 | |||||
| code_no_results=未找到与搜索字词匹配的源代码。 | code_no_results=未找到与搜索字词匹配的源代码。 | ||||
| code_search_results=“%s” 的搜索结果是 | code_search_results=“%s” 的搜索结果是 | ||||
| code_last_indexed_at=最后索引于 %s | code_last_indexed_at=最后索引于 %s | ||||
| save=保存 | |||||
| cancel=取消 | |||||
| [auth] | [auth] | ||||
| create_new_account=注册帐号 | create_new_account=注册帐号 | ||||
| @@ -130,5 +130,13 @@ func Home(ctx *context.Context) { | |||||
| pager.SetDefaultParams(ctx) | pager.SetDefaultParams(ctx) | ||||
| ctx.Data["Page"] = pager | ctx.Data["Page"] = pager | ||||
| //find org tag info | |||||
| tags, err := models.GetAllOfficialTagRepos(org.ID, ctx.Org.IsOwner) | |||||
| if err != nil { | |||||
| ctx.ServerError("GetAllOfficialTagRepos", err) | |||||
| return | |||||
| } | |||||
| ctx.Data["tags"] = tags | |||||
| ctx.HTML(200, tplOrgHome) | ctx.HTML(200, tplOrgHome) | ||||
| } | } | ||||
| @@ -0,0 +1,98 @@ | |||||
| // Copyright 2014 The Gogs Authors. All rights reserved. | |||||
| // Copyright 2020 The Gitea Authors. | |||||
| // Use of this source code is governed by a MIT-style | |||||
| // license that can be found in the LICENSE file. | |||||
| package org | |||||
| import ( | |||||
| "code.gitea.io/gitea/models" | |||||
| "code.gitea.io/gitea/modules/auth" | |||||
| "code.gitea.io/gitea/modules/context" | |||||
| "errors" | |||||
| "strconv" | |||||
| ) | |||||
| // SubmitTags submit repos of org tag | |||||
| func SubmitTags(ctx *context.Context, form auth.SubmitReposOfTagForm) { | |||||
| org, tag := getOrgAndTagFromContext(ctx) | |||||
| if ctx.Written() { | |||||
| return | |||||
| } | |||||
| err := models.UpdateTagReposByID(tag.ID, org.ID, form.RepoList) | |||||
| if err != nil { | |||||
| ctx.ServerError("UpdateTagReposByID", err) | |||||
| return | |||||
| } | |||||
| ctx.JSON(200, map[string]interface{}{ | |||||
| "code": "00", | |||||
| "msg": "success", | |||||
| }) | |||||
| } | |||||
| // GetTagRepos get repos under org tag | |||||
| func GetTagRepos(ctx *context.Context) { | |||||
| org, tag := getOrgAndTagFromContext(ctx) | |||||
| if ctx.Written() { | |||||
| return | |||||
| } | |||||
| r, err := models.GetTagRepos(tag.ID, org.ID) | |||||
| if err != nil { | |||||
| ctx.ServerError("GetTagRepos", err) | |||||
| return | |||||
| } | |||||
| ctx.JSON(200, map[string]interface{}{ | |||||
| "code": "00", | |||||
| "msg": "success", | |||||
| "data": r, | |||||
| }) | |||||
| } | |||||
| // getDashboardContextUser finds out dashboard is viewing as which context user. | |||||
| func getOrgAndTagFromContext(ctx *context.Context) (*models.User, *models.OfficialTag) { | |||||
| var org *models.User | |||||
| var tag *models.OfficialTag | |||||
| var err error | |||||
| orgName := ctx.Params(":org") | |||||
| if len(orgName) > 0 { | |||||
| // Organization. | |||||
| org, err = models.GetUserByName(orgName) | |||||
| if err != nil { | |||||
| if models.IsErrUserNotExist(err) { | |||||
| ctx.NotFound("GetUserByName", err) | |||||
| } else { | |||||
| ctx.ServerError("GetUserByName", err) | |||||
| } | |||||
| return nil, nil | |||||
| } | |||||
| if !org.IsOrganization() { | |||||
| ctx.ServerError("GetUserByName", errors.New("it is not an organization")) | |||||
| return nil, nil | |||||
| } | |||||
| } | |||||
| tagIdStr := ctx.Query("tagId") | |||||
| if len(tagIdStr) == 0 { | |||||
| ctx.ServerError("GetTagInfo", errors.New("tag is not exist")) | |||||
| return nil, nil | |||||
| } | |||||
| tagId, _ := strconv.ParseInt(tagIdStr, 10, 32) | |||||
| tag, err = models.GetTagByID(tagId) | |||||
| if err != nil { | |||||
| if models.IsErrTagNotExist(err) { | |||||
| ctx.NotFound("GetTagInfo", err) | |||||
| } else { | |||||
| ctx.ServerError("GetTagInfo", err) | |||||
| } | |||||
| return nil, nil | |||||
| } | |||||
| return org, tag | |||||
| } | |||||
| @@ -627,6 +627,10 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| m.Group("/org", func() { | m.Group("/org", func() { | ||||
| m.Group("/:org", func() { | m.Group("/:org", func() { | ||||
| m.Get("/members", org.Members) | m.Get("/members", org.Members) | ||||
| m.Group("/org_tag", func() { | |||||
| m.Get("/repo_list", org.GetTagRepos) | |||||
| m.Post("/repo_submit", bindIgnErr(auth.SubmitReposOfTagForm{}), org.SubmitTags) | |||||
| }) | |||||
| }, context.OrgAssignment()) | }, context.OrgAssignment()) | ||||
| }) | }) | ||||
| m.Group("/org", func() { | m.Group("/org", func() { | ||||
| @@ -20,10 +20,11 @@ | |||||
| </div> | </div> | ||||
| <div class="ui container"> | <div class="ui container"> | ||||
| <div class="ui stackable grid"> | |||||
| {{template "org/navber" .}} | |||||
| <div class="ui fourteen wide computer column"> | |||||
| {{template "org/navber" .}} | |||||
| {{template "org/select_pro" .}} | |||||
| <div class="ui stackable grid"> | |||||
| <div class="ui sixteen wide computer column"> | |||||
| <div class="ui mobile reversed stackable grid"> | <div class="ui mobile reversed stackable grid"> | ||||
| <div class="ui ten wide tablet eleven wide computer column"> | <div class="ui ten wide tablet eleven wide computer column"> | ||||
| {{if .CanCreateOrgRepo}} | {{if .CanCreateOrgRepo}} | ||||
| @@ -3,10 +3,11 @@ | |||||
| {{template "org/header" .}} | {{template "org/header" .}} | ||||
| <div class="ui container"> | <div class="ui container"> | ||||
| {{template "base/alert" .}} | {{template "base/alert" .}} | ||||
| {{template "org/navber" .}} | |||||
| <div class="ui stackable grid"> | <div class="ui stackable grid"> | ||||
| {{template "org/navber" .}} | |||||
| <div class="ui fourteen wide computer column list"> | |||||
| <div class="ui sixteen wide computer column list"> | |||||
| {{ range .Members}} | {{ range .Members}} | ||||
| <div class="item ui grid"> | <div class="item ui grid"> | ||||
| <div class="ui two wide column"> | <div class="ui two wide column"> | ||||
| @@ -1,4 +1,4 @@ | |||||
| <div class="tablet only mobile only sixteen wide mobile sixteen wide tablet column row"> | |||||
| <!-- <div class="tablet only mobile only sixteen wide mobile sixteen wide tablet column row"> | |||||
| <div class="ui secondary pointing tabular top attached borderless menu navbar"> | <div class="ui secondary pointing tabular top attached borderless menu navbar"> | ||||
| <a class="{{if $.PageIsOrgHome}}active{{end}} item" href="{{.HomeLink}}"> | <a class="{{if $.PageIsOrgHome}}active{{end}} item" href="{{.HomeLink}}"> | ||||
| {{svg "octicon-home" 16}} {{$.i18n.Tr "org.home"}} | {{svg "octicon-home" 16}} {{$.i18n.Tr "org.home"}} | ||||
| @@ -12,10 +12,10 @@ | |||||
| </a> | </a> | ||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| </div> | |||||
| </div> --> | |||||
| <!--平板、移动端--> | <!--平板、移动端--> | ||||
| <div class="computer only two wide computer column"> | |||||
| <!-- <div class="computer only two wide computer column"> | |||||
| <div class="ui grid"> | <div class="ui grid"> | ||||
| <div class="sixteen wide column ui secondary sticky pointing tabular vertical menu"> | <div class="sixteen wide column ui secondary sticky pointing tabular vertical menu"> | ||||
| {{with .Org}} | {{with .Org}} | ||||
| @@ -33,5 +33,37 @@ | |||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | |||||
| <!--电脑、宽屏--> | |||||
| </div> --> | |||||
| <!--电脑、宽屏--> | |||||
| <style> | |||||
| .dis{ | |||||
| margin-bottom: 10px; | |||||
| } | |||||
| .active{ | |||||
| color:#0366D6 !important; | |||||
| } | |||||
| .mleft{ | |||||
| margin-left: 30% !important; | |||||
| } | |||||
| .mbom{ | |||||
| margin-bottom: 10px !important; | |||||
| } | |||||
| </style> | |||||
| <div class="row"> | |||||
| <div class="ui secondary pointing tabular top attached borderless menu navbar mbom"> | |||||
| {{with .Org}} | |||||
| <a class="{{if $.PageIsOrgHome}}active{{end}} item mleft" href="{{.HomeLink}}"> | |||||
| {{svg "octicon-home" 16}} {{$.i18n.Tr "org.home"}} | |||||
| </a> | |||||
| {{end}} | |||||
| <a class="{{if $.PageIsOrgMembers}}active{{end}} item" href="{{$.OrgLink}}/members"> | |||||
| {{svg "octicon-organization" 16}} {{$.i18n.Tr "org.people"}} | |||||
| </a> | |||||
| {{if or ($.IsOrganizationMember) ($.IsOrganizationOwner)}} | |||||
| <a class="{{if $.PageIsOrgTeams}}active{{end}} item" href="{{$.OrgLink}}/teams"> | |||||
| {{svg "octicon-jersey" 16}} {{$.i18n.Tr "org.teams"}} | |||||
| </a> | |||||
| {{end}} | |||||
| </div> | |||||
| </div> | |||||
| @@ -0,0 +1,288 @@ | |||||
| <style> | |||||
| .text-right{ | |||||
| float:right !important; | |||||
| } | |||||
| .header{ | |||||
| font-weight:bold; | |||||
| font-size: 18px; | |||||
| font-family: SourceHanSansSC-medium; | |||||
| } | |||||
| .cor{ | |||||
| color:#0366D6 !important; | |||||
| } | |||||
| .header_card{ | |||||
| /* color:#003A8C !important; */ | |||||
| color:#0366D6 !important; | |||||
| margin: 10px 0; | |||||
| } | |||||
| .marg{ | |||||
| margin: 0 5px !important; | |||||
| } | |||||
| .content_list{ | |||||
| max-height: 200px; | |||||
| overflow: auto; | |||||
| } | |||||
| .Relist{ | |||||
| color:#0366D6 !important; | |||||
| } | |||||
| .descript_height{ | |||||
| color: #101010 !important; | |||||
| height: 40px !important; | |||||
| word-break:break-all; | |||||
| line-height: 20px; | |||||
| overflow: hidden; | |||||
| /* overflow: hidden!important; | |||||
| word-wrap:break-word!important; */ | |||||
| } | |||||
| .tags_height{ | |||||
| height: 30px !important; | |||||
| } | |||||
| .full_height{ | |||||
| height: 100%; | |||||
| } | |||||
| /deep/ ui.checkbox input[type=checkbox]::after{ | |||||
| border: 1px solid #0366D6 !important; | |||||
| } | |||||
| </style> | |||||
| <div class="ui stackable grid"> | |||||
| <div style="width: 100%;margin:15px 0;"> | |||||
| {{if .tags}} | |||||
| <span class="header"> | |||||
| 精选项目 | |||||
| </span> | |||||
| <!-- {{.IsOrganizationOwner}} --> | |||||
| {{if .IsOrganizationOwner}} | |||||
| <a class="text-right" id="model" onclick="showcreate()" >{{svg "octicon-gear" 16}}自定义</a> | |||||
| {{end}} | |||||
| {{end}} | |||||
| </div> | |||||
| <div style="width: 100%;"> | |||||
| {{ range .tags}} | |||||
| {{if eq .TagName "精选项目"}} | |||||
| <div class="ui three cards" style="margin-bottom: 10px;"> | |||||
| {{ range .RepoList}} | |||||
| <div class="card" > | |||||
| <div class="extra full_height" > | |||||
| <div class=" header "> | |||||
| <a class="header_card" href="{{.Link}}"> {{.Name}}</a> | |||||
| </div> | |||||
| <div class='content descript_height'> | |||||
| {{.Description}} | |||||
| </div> | |||||
| <div class="content tags_height" style="margin-top: 5px;"> | |||||
| {{if .Topics }} | |||||
| <div class=" ui tags "> | |||||
| {{range .Topics}} | |||||
| {{if ne . "" }}<a href="{{AppSubUrl}}/explore/repos?q={{.}}&topic={{$.Topic}}"><div class="ui small label topic">{{.}}</div></a>{{end}} | |||||
| {{end}} | |||||
| </div> | |||||
| {{end}} | |||||
| </div> | |||||
| <div class="ui mini right compact marg" > | |||||
| <a class="item marg "> | |||||
| {{svg "octicon-eye" 16}} {{.NumWatches}} | |||||
| </a> | |||||
| <a class="item marg"> | |||||
| {{svg "octicon-star" 16}} {{.NumStars}} | |||||
| </a> | |||||
| <a class="item marg"> | |||||
| {{svg "octicon-git-branch" 16}} {{.NumForks}} | |||||
| </a> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| {{end}} | |||||
| </div> | |||||
| {{end}} | |||||
| {{end}} | |||||
| </div> | |||||
| </div> | |||||
| <div class="ui modal"> | |||||
| <div class="header" style="padding: 1rem;background-color: rgba(240, 240, 240, 100);"> | |||||
| <h4 id="model_header">自定义精选项目</h4> | |||||
| </div> | |||||
| <div class="content content-padding" style="color: black;"> | |||||
| <p>对多可选9个公开项目</p> | |||||
| <div class="ui search" > | |||||
| <div class="ui input" style="width: 100%;"> | |||||
| <input type="text" id = 'search_selectPro' placeholder="Search ..." value = '' oninput="search()"> | |||||
| </div> | |||||
| </div> | |||||
| <div style="margin: 10px ;"> | |||||
| <div id ='org_list' style="margin-bottom: 20px;"class="content_list" > | |||||
| </div> | |||||
| </div> | |||||
| <p id='recommend'></p> | |||||
| <div class="inline field" style="margin-left: 30%;"> | |||||
| <div class="actions"> | |||||
| <button id="submitId" type="button" class="ui create_train_job green deny button" onclick="saveSeletedPro(1)"> | |||||
| {{.i18n.Tr "explore.save"}} | |||||
| </button> | |||||
| <button class="ui button cancel" >{{.i18n.Tr "explore.cancel"}}</button> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <script> | |||||
| var data; | |||||
| var filterData=[]; | |||||
| var num=0; | |||||
| function showcreate(obj){ | |||||
| $('.ui.modal') | |||||
| .modal({ | |||||
| centered: false, | |||||
| onShow:function(){ | |||||
| $("#org_list").empty() | |||||
| getPro(1) | |||||
| }, | |||||
| onHide:function(){ | |||||
| } | |||||
| }) | |||||
| .modal('show') | |||||
| } | |||||
| function getPro(typeTag){ | |||||
| $.ajax({ | |||||
| type:"GET", | |||||
| url:"/org/{{.Org.DisplayName}}/org_tag/repo_list?tagId="+typeTag, | |||||
| dataType:"json", | |||||
| async:false, | |||||
| success:function(json){ | |||||
| data = json.data; | |||||
| var n_length = data.length | |||||
| pro_html = getHTML(data) | |||||
| $("#org_list").append(pro_html) | |||||
| console.log('原始',data) | |||||
| checkedNum() | |||||
| } | |||||
| }); | |||||
| } | |||||
| function getHTML(data){ | |||||
| let pro_html='' | |||||
| for (let i=0;i<data.length;i++){ | |||||
| if (data[i].Selected==true){ | |||||
| console.log("data[i]:",data[i]) | |||||
| pro_html += `<div class="ui checkbox" style="width: 33%;margin-bottom:10px" > <input type="checkbox" checked="" onclick="checkedNum()" class="Relist" name ='select_pro_name' data-repoid="${data[i].RepoID}" data-reponame="${data[i].RepoName}" data-selected=${data[i].Selected} > <label> ${data[i].RepoName} </label></div>` | |||||
| pro_html += '</div>' | |||||
| } | |||||
| else{ | |||||
| pro_html += `<div class="ui checkbox" style="width: 33%;margin-bottom:10px" > <input type="checkbox" onclick="checkedNum()" class="Relist" name ='select_pro_name' data-repoid="${data[i].RepoID}" data-reponame="${data[i].RepoName}" data-selected= ${data[i].Selected}> <label> ${data[i].RepoName} </label></div>` | |||||
| pro_html += '</div>' | |||||
| } | |||||
| } | |||||
| return pro_html | |||||
| } | |||||
| function saveSeletedPro(typeTag){ | |||||
| var saveData=[]; | |||||
| $('input[name="select_pro_name"]:checked').each(function(){ | |||||
| console.log('值',this.dataset.repoid) | |||||
| saveData.push(parseInt(this.dataset.repoid)); | |||||
| }) | |||||
| // saveData = getSelecteDataID(); | |||||
| // console.log("数据:",saveData) | |||||
| $.ajax({ | |||||
| type:"POST", | |||||
| url:"/org/{{.Org.DisplayName}}/org_tag/repo_submit?tagId="+typeTag, | |||||
| contentType:'application/json', | |||||
| dataType:"json", | |||||
| async:false, | |||||
| data:JSON.stringify({'repoList':saveData | |||||
| }), | |||||
| success:function(res){ | |||||
| console.log('保存成功'); | |||||
| location.reload() | |||||
| } | |||||
| }); | |||||
| } | |||||
| function getSelecteData(){ | |||||
| var selectedData=[]; | |||||
| $('input[name="select_pro_name"]:checked').each(function(){ | |||||
| // console.log(this) | |||||
| console.log('值',this.dataset.selected) | |||||
| selectedData.push({"RepoID":parseInt(this.dataset.repoid),"RepoName":this.dataset.reponame,"Selected":JSON.parse(this.dataset.selected)}); | |||||
| }) | |||||
| return selectedData | |||||
| } | |||||
| function search(){ | |||||
| var selectedData = getSelecteData(); | |||||
| var searchValue = document.getElementById("search_selectPro").value; | |||||
| filterData=[]; | |||||
| console.log("searchValue:",searchValue) | |||||
| for (let i=0;i<data.length;i++){ | |||||
| var isInclude=false; | |||||
| if(data[i].RepoName.toLowerCase().includes(searchValue.toLowerCase())){ | |||||
| filterData.push(data[i]) | |||||
| } | |||||
| } | |||||
| console.log("选中的值:",selectedData) | |||||
| console.log("筛选包括选中的值:",filterData) | |||||
| var showData=[]; | |||||
| for(i=0;i<selectedData.length;i++){ | |||||
| filterData =filterData.filter((item)=>{ | |||||
| return item.RepoID!=selectedData[i].RepoID | |||||
| }); | |||||
| } | |||||
| console.log("筛选后不包括选中的值:",filterData) | |||||
| $("#org_list").empty() | |||||
| if(searchValue!=""){ | |||||
| if (filterData.length!=0){ | |||||
| var pro_html = getHTML(selectedData); | |||||
| console.log("selectedData_pro_html:",pro_html) | |||||
| $("#org_list").append(pro_html) | |||||
| pro_html= getHTML(filterData); | |||||
| $("#org_list").append(pro_html) | |||||
| }else{ | |||||
| var pro_html = getHTML(selectedData); | |||||
| $("#org_list").append(pro_html) | |||||
| } | |||||
| }else{ | |||||
| var pro_html = getHTML(data); | |||||
| $("#org_list").append(pro_html) | |||||
| } | |||||
| } | |||||
| function checkedNum(){ | |||||
| num=0; | |||||
| var inputs = document.getElementsByName("select_pro_name") | |||||
| for (var i=0;i<inputs.length;i++){ | |||||
| if(inputs[i].checked){ | |||||
| num++ | |||||
| } | |||||
| } | |||||
| var show_num = 9-num; | |||||
| document.getElementById("recommend").innerHTML="还能推荐"+show_num+"个" | |||||
| } | |||||
| </script> | |||||
| @@ -3,12 +3,12 @@ | |||||
| {{template "org/header" .}} | {{template "org/header" .}} | ||||
| <div class="ui container"> | <div class="ui container"> | ||||
| {{template "base/alert" .}} | {{template "base/alert" .}} | ||||
| {{template "org/navber" .}} | |||||
| <div class="ui stackable grid"> | <div class="ui stackable grid"> | ||||
| {{template "org/navber" .}} | |||||
| <div class="ui fourteen wide computer column list"> | |||||
| <div class="ui sixteen wide computer column list"> | |||||
| <div class="ui two column grid"> | <div class="ui two column grid"> | ||||
| {{range .Teams}} | {{range .Teams}} | ||||
| <div class="column"> | <div class="column"> | ||||