diff --git a/models/tech_converge_info.go b/models/tech_converge_info.go index 12a315fa2..46aa163f2 100644 --- a/models/tech_converge_info.go +++ b/models/tech_converge_info.go @@ -161,7 +161,7 @@ func GetProjectNames() []string { x.Table("tech_converge_base_info").Distinct("project_name").Find(&names) return names } -func GetRepoIds() []int64 { +func GetSummitRepoIds() []int64 { var ids []int64 x.Table("repo_converge_info").Cols("repo_id").Find(&ids) return ids @@ -169,29 +169,29 @@ func GetRepoIds() []int64 { func GetTechRepoTopics(limit int) []string { - repoIds := GetRepoIds() + repoIds := GetSummitRepoIds() if len(repoIds) == 0 { return []string{} } //select name, repo_count from topic a, repo_topic b //where a.id=b.topic_id and repo_id in (1,3) order by repo_count desc - incondition := "repo_id in (" + inCondition := "repo_id in (" const MaxINItems = 1000 for i := 0; i < len(repoIds); i++ { if i == len(repoIds)-1 { - incondition += strconv.FormatInt(repoIds[i], 10) + inCondition += strconv.FormatInt(repoIds[i], 10) } else if (i+1)%MaxINItems == 0 { - incondition += strconv.FormatInt(repoIds[i], 10) + ") or repo_id in (" + inCondition += strconv.FormatInt(repoIds[i], 10) + ") or repo_id in (" } else { - incondition += strconv.FormatInt(repoIds[i], 10) + "," + inCondition += strconv.FormatInt(repoIds[i], 10) + "," } } - incondition += ")" + inCondition += ")" - sql := "select name, repo_count from topic a, repo_topic b where a.id=b.topic_id and (" + incondition + ") order by repo_count desc" + sql := "select name, repo_count from topic a, repo_topic b where a.id=b.topic_id and (" + inCondition + ") order by repo_count desc" if limit > 0 { sql += "limit " + strconv.Itoa(limit) } @@ -283,6 +283,153 @@ func contains(s []string, e string) bool { return false } +type SearchTechOpt struct { + Q string //科技项目名称 + ProjectType string + Institution string + ApplyYear int + ExecuteYear int + OrderBy string + ListOptions +} + +type SearchRepoOpt struct { + Q string //项目名称,简介 + ProjectName string + Topic string + Institution string + OrderBy string + ListOptions +} + +type RepoWithInstitution struct { + ID int64 `json:"id"` + OwnerID int64 `json:"owner_id"` + OwnerName string `json:"owner_name"` + Name string `json:"name"` + Alias string `json:"alias"` + Topics []string `json:"topics"` + Description string `json:"description"` + Institution string `json:"institution"` + UpdatedUnix timeutil.TimeStamp `json:"updated_unix"` +} + +type TechRepoInfo struct { + ID int64 `json:"id"` + ProjectName string `json:"project_name"` + Institution string `json:"institution"` + Type string `json:"type"` + ApplyYear int `json:"apply_year"` + ExecutePeriod string `json:"execute_period"` + AllInstitution string `json:"all_institution"` + RepoCount int `json:"repo_numer"` + Repos []*RepoWithInstitution +} + +func SearchTechRepoInfo(opt SearchTechOpt) ([]*TechRepoInfo, int64, error) { + + sql := `select a.*,COALESCE(b.count,0) as repo_count, COALESCE(b.max,0) as max from tech_converge_base_info a left join + (select base_info_id,count(id),max(updated_unix) from repo_converge_info where status=2 GROUP BY base_info_id ) b + on a.id=b.base_info_id` + totalSql := "select count(*) from (" + sql + ") c" + buildTechFilterCond(opt) + total, err := x.SQL(totalSql).Count(new(TechConvergeBaseInfo)) + resultList := make([]*TechRepoInfo, 0) + if err != nil { + return resultList, total, err + + } + resultSql := "select id,project_name, institution,type,apply_year,execute_period,all_institution,repo_count from (" + + sql + ") c " + buildTechFilterCond(opt) + opt.OrderBy + " offset " + strconv.Itoa((opt.Page-1)*opt.PageSize) + " limit " + strconv.Itoa(opt.PageSize) + + resultMap, err := x.QueryInterface(resultSql) + if err == nil { + for _, record := range resultMap { + resultList = append(resultList, &TechRepoInfo{ + ID: record["id"].(int64), + ProjectName: record["project_name"].(string), + Institution: record["institution"].(string), + Type: record["type"].(string), + ApplyYear: int(record["apply_year"].(int64)), + ExecutePeriod: record["execute_period"].(string), + AllInstitution: record["all_institution"].(string), + RepoCount: int(record["repo_count"].(int64)), + }) + } + } + + loadRepoInfoForTech(resultList) + + return resultList, total, err + +} + +func buildTechFilterCond(opt SearchTechOpt) string { + + sql := "" + + if opt.Q != "" { + sql += getWherePrefix(sql) + " project_name like '%" + opt.Q + "%'" + + } + if opt.ProjectType != "" { + sql += getWherePrefix(sql) + " type ='" + opt.ProjectType + "'" + } + if opt.ApplyYear != 0 { + sql += getWherePrefix(sql) + " apply_year =" + strconv.Itoa(opt.ApplyYear) + } + if opt.Institution != "" { + sql += getWherePrefix(sql) + " (all_institution like '%" + opt.Institution + ",%'" + " or all_institution like '%," + opt.Institution + "%'" + } + + if opt.ExecuteYear != 0 { + sql += getWherePrefix(sql) + " execute_start_year <=" + strconv.Itoa(opt.ExecuteYear) + " and execute_end_year >=" + strconv.Itoa(opt.ExecuteYear) + } + return sql +} + +func getWherePrefix(sql string) string { + if sql == "" { + return " where " + } + return " and " +} + +func loadRepoInfoForTech(list []*TechRepoInfo) { + + for _, techRepo := range list { + techRepo.Repos = []*RepoWithInstitution{} + if techRepo.RepoCount > 0 { + var repoIds []int64 + x.Table("repo_converge_info").Cols("repo_id").Where("base_info_id=?", techRepo.ID).Desc("updated_unix").Find(&repoIds) + + resultMap, err := GetRepositoriesMapByIDs(repoIds) + + if err == nil { + + for _, repoId := range repoIds { + repo, ok := resultMap[repoId] + if ok { + techRepo.Repos = append(techRepo.Repos, &RepoWithInstitution{ + ID: repo.ID, + Institution: techRepo.Institution, + OwnerID: repo.OwnerID, + OwnerName: repo.OwnerName, + Name: repo.Name, + Alias: repo.Alias, + Topics: repo.Topics, + Description: repo.Description, + UpdatedUnix: repo.UpdatedUnix, + }) + } + + } + + } + } + } + +} + type TechConvergeBrief struct { ProjectNumber string `json:"no"` //项目立项编号 ProjectName string `json:"name"` //科技项目名称 diff --git a/routers/api/v1/tech/tech.go b/routers/api/v1/tech/tech.go index 9b0f7bc93..6576202cf 100644 --- a/routers/api/v1/tech/tech.go +++ b/routers/api/v1/tech/tech.go @@ -51,6 +51,40 @@ func SearchRepoInfo(ctx *context.APIContext) { func SearchTechProjectInfo(ctx *context.APIContext) { + opts := models.SearchTechOpt{} + opts.Q = ctx.Query("name") + opts.ApplyYear = ctx.QueryInt("apply_year") + opts.ExecuteYear = ctx.QueryInt("execute_year") + opts.Institution = ctx.Query("institution_name") + opts.ProjectType = ctx.Query("type_name") + page := ctx.QueryInt("page") + if page <= 0 { + page = 1 + } + opts.Page = page + pageSize := ctx.QueryInt("pageSize") + if pageSize <= 0 { + pageSize = 15 + } + opts.PageSize = pageSize + orderBy := ctx.Query("orderBy") + if orderBy == "" || orderBy == "count" { + opts.OrderBy = "order by repo_count desc, max desc " + } else { + opts.OrderBy = "order by max desc, repo_count desc " + } + + infos, total, err := models.SearchTechRepoInfo(opts) + if err != nil { + + log.Error("search has error", err) + ctx.JSON(http.StatusOK, map[string]interface { + }{"total": 0, "data": []*models.TechRepoInfo{}}) + } else { + ctx.JSON(http.StatusOK, map[string]interface { + }{"total": total, "data": infos}) + } + } func ImportBasicInfo(ctx *context.APIContext) {