| @@ -45,7 +45,7 @@ type ImageStar struct { | |||
| } | |||
| type ImageTopic struct { | |||
| ID int64 | |||
| ID int64 `xorm:"pk autoincr"` | |||
| Name string `xorm:"UNIQUE VARCHAR(105)"` | |||
| ImageCount int | |||
| CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | |||
| @@ -468,8 +468,13 @@ func (images ImageList) loadAttributes(e Engine, uid int64) error { | |||
| } | |||
| for i := range images { | |||
| images[i].UserName = users[images[i].UID].Name | |||
| images[i].RelAvatarLink = users[images[i].UID].RelAvatarLink() | |||
| if users[images[i].UID] != nil { | |||
| images[i].UserName = users[images[i].UID].Name | |||
| images[i].RelAvatarLink = users[images[i].UID].RelAvatarLink() | |||
| } else { | |||
| images[i].UserName = "" | |||
| images[i].RelAvatarLink = "" | |||
| } | |||
| if uid == -1 { | |||
| images[i].IsStar = false | |||
| } else { | |||
| @@ -523,17 +523,21 @@ DROP TRIGGER IF EXISTS es_udpate_repository_lang on public.language_stat; | |||
| CREATE OR REPLACE FUNCTION public.udpate_repository_lang() RETURNS trigger AS | |||
| $def$ | |||
| DECLARE | |||
| privateValue bigint; | |||
| BEGIN | |||
| if (TG_OP = 'UPDATE') then | |||
| update public.repository_es SET lang=(select array_to_string(array_agg(language order by percentage desc),',') from public.language_stat where repo_id=NEW.repo_id) where id=NEW.repo_id; | |||
| select into privateValue updated_unix from public.repository where id=NEW.repo_id; | |||
| update public.repository_es SET updated_unix=privateValue,lang=(select array_to_string(array_agg(language order by percentage desc),',') from public.language_stat where repo_id=NEW.repo_id) where id=NEW.repo_id; | |||
| elsif (TG_OP = 'INSERT') then | |||
| update public.repository_es SET lang=(select array_to_string(array_agg(language order by percentage desc),',') from public.language_stat where repo_id=NEW.repo_id) where id=NEW.repo_id; | |||
| select into privateValue updated_unix from public.repository where id=NEW.repo_id; | |||
| update public.repository_es SET updated_unix=privateValue,lang=(select array_to_string(array_agg(language order by percentage desc),',') from public.language_stat where repo_id=NEW.repo_id) where id=NEW.repo_id; | |||
| elsif (TG_OP = 'DELETE') then | |||
| if exists(select 1 from public.repository where id=OLD.repo_id) then | |||
| update public.repository_es SET lang=(select array_to_string(array_agg(language order by percentage desc),',') from public.language_stat where repo_id=OLD.repo_id) where id=OLD.repo_id; | |||
| end if; | |||
| end if; | |||
| return null; | |||
| return NEW; | |||
| END; | |||
| $def$ | |||
| LANGUAGE plpgsql; | |||
| @@ -4,6 +4,7 @@ import ( | |||
| "fmt" | |||
| "sort" | |||
| "strconv" | |||
| "strings" | |||
| "time" | |||
| "code.gitea.io/gitea/modules/log" | |||
| @@ -103,6 +104,8 @@ type UserBusinessAnalysisAll struct { | |||
| CollectImage int `xorm:"NOT NULL DEFAULT 0"` | |||
| CollectedImage int `xorm:"NOT NULL DEFAULT 0"` | |||
| RecommendImage int `xorm:"NOT NULL DEFAULT 0"` | |||
| HasActivity int `xorm:"NOT NULL DEFAULT 0"` | |||
| } | |||
| type UserBusinessAnalysis struct { | |||
| @@ -190,6 +193,8 @@ type UserBusinessAnalysis struct { | |||
| CollectImage int `xorm:"NOT NULL DEFAULT 0"` | |||
| CollectedImage int `xorm:"NOT NULL DEFAULT 0"` | |||
| RecommendImage int `xorm:"NOT NULL DEFAULT 0"` | |||
| HasActivity int `xorm:"NOT NULL DEFAULT 0"` | |||
| } | |||
| type UserBusinessAnalysisQueryOptions struct { | |||
| @@ -227,15 +232,97 @@ func getLastCountDate() int64 { | |||
| return pageStartTime.Unix() | |||
| } | |||
| func QueryMetrics(start int64, end int64) ([]*UserMetrics, int64) { | |||
| func QueryMetricsPage(start int64, end int64, page int, pageSize int) ([]UserMetrics, int64) { | |||
| statictisSess := xStatistic.NewSession() | |||
| defer statictisSess.Close() | |||
| cond := "count_date >" + fmt.Sprint(start) + " and count_date<" + fmt.Sprint(end) | |||
| allCount, err := statictisSess.Where(cond).Count(new(UserMetrics)) | |||
| if err != nil { | |||
| log.Info("query error." + err.Error()) | |||
| return nil, 0 | |||
| } | |||
| userMetricsList := make([]UserMetrics, 0) | |||
| if err := statictisSess.Table(new(UserMetrics)).Where(cond).Limit(pageSize, page*pageSize).OrderBy("count_date desc"). | |||
| Find(&userMetricsList); err != nil { | |||
| return nil, 0 | |||
| } | |||
| return userMetricsList, allCount | |||
| } | |||
| func QueryMetrics(start int64, end int64) ([]UserMetrics, int) { | |||
| statictisSess := xStatistic.NewSession() | |||
| defer statictisSess.Close() | |||
| userMetricsList := make([]*UserMetrics, 0) | |||
| userMetricsList := make([]UserMetrics, 0) | |||
| if err := statictisSess.Table(new(UserMetrics)).Where("count_date >" + fmt.Sprint(start) + " and count_date<" + fmt.Sprint(end)).OrderBy("count_date desc"). | |||
| Find(&userMetricsList); err != nil { | |||
| return nil, 0 | |||
| } | |||
| return userMetricsList, int64(len(userMetricsList)) | |||
| for _, userMetrics := range userMetricsList { | |||
| dateTime := time.Unix(userMetrics.CountDate, 0) | |||
| userMetrics.DisplayDate = dateTime.Format("2006-01-02") | |||
| } | |||
| return userMetricsList, len(userMetricsList) | |||
| } | |||
| func QueryMetricsForAll() []UserMetrics { | |||
| statictisSess := xStatistic.NewSession() | |||
| defer statictisSess.Close() | |||
| userMetricsList := make([]UserMetrics, 0) | |||
| if err := statictisSess.Table(new(UserMetrics)).OrderBy("count_date desc"). | |||
| Find(&userMetricsList); err != nil { | |||
| return nil | |||
| } | |||
| return makeResultForMonth(userMetricsList, len(userMetricsList)) | |||
| } | |||
| func QueryMetricsForYear() []UserMetrics { | |||
| currentTimeNow := time.Now() | |||
| currentYearEndTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 23, 59, 59, 0, currentTimeNow.Location()) | |||
| currentYearStartTime := time.Date(currentTimeNow.Year(), 1, 1, 0, 0, 0, 0, currentTimeNow.Location()) | |||
| allUserInfo, count := QueryMetrics(currentYearStartTime.Unix(), currentYearEndTime.Unix()) | |||
| return makeResultForMonth(allUserInfo, count) | |||
| } | |||
| func makeResultForMonth(allUserInfo []UserMetrics, count int) []UserMetrics { | |||
| monthMap := make(map[string]UserMetrics) | |||
| if count > 0 { | |||
| for _, userMetrics := range allUserInfo { | |||
| dateTime := time.Unix(userMetrics.CountDate, 0) | |||
| month := fmt.Sprint(dateTime.Year()) + "-" + fmt.Sprint(int(dateTime.Month())) | |||
| if _, ok := monthMap[month]; !ok { | |||
| var monthUserMetrics UserMetrics | |||
| monthUserMetrics.DisplayDate = month | |||
| monthUserMetrics.ActivateRegistUser = userMetrics.ActivateRegistUser | |||
| monthUserMetrics.NotActivateRegistUser = userMetrics.NotActivateRegistUser | |||
| monthUserMetrics.TotalUser = userMetrics.TotalUser | |||
| monthUserMetrics.TotalActivateRegistUser = userMetrics.TotalActivateRegistUser | |||
| monthUserMetrics.TotalHasActivityUser = userMetrics.TotalHasActivityUser | |||
| monthUserMetrics.HasActivityUser = userMetrics.HasActivityUser | |||
| monthUserMetrics.DaysForMonth = 1 | |||
| monthMap[month] = monthUserMetrics | |||
| } else { | |||
| value := monthMap[month] | |||
| value.ActivateRegistUser += userMetrics.ActivateRegistUser | |||
| value.NotActivateRegistUser += userMetrics.NotActivateRegistUser | |||
| value.TotalUser += userMetrics.TotalUser | |||
| value.TotalActivateRegistUser += userMetrics.TotalActivateRegistUser | |||
| value.TotalHasActivityUser += userMetrics.TotalHasActivityUser | |||
| value.HasActivityUser += userMetrics.HasActivityUser | |||
| value.DaysForMonth += 1 | |||
| } | |||
| } | |||
| } | |||
| result := make([]UserMetrics, 0) | |||
| for _, value := range monthMap { | |||
| result = append(result, value) | |||
| } | |||
| sort.Slice(result, func(i, j int) bool { | |||
| return strings.Compare(result[i].DisplayDate, result[j].DisplayDate) > 0 | |||
| }) | |||
| return result | |||
| } | |||
| func QueryRankList(key string, tableName string, limit int) ([]*UserBusinessAnalysisAll, int64) { | |||
| @@ -540,6 +627,7 @@ func refreshUserStaticTable(wikiCountMap map[string]int, tableName string, pageS | |||
| if minUserIndex > dateRecordAll.UserIndexPrimitive { | |||
| minUserIndex = dateRecordAll.UserIndexPrimitive | |||
| } | |||
| dateRecordBatch = append(dateRecordBatch, dateRecordAll) | |||
| if len(dateRecordBatch) >= BATCH_INSERT_SIZE { | |||
| insertTable(dateRecordBatch, tableName, statictisSess) | |||
| @@ -695,7 +783,7 @@ func CounDataByDateAndReCount(wikiCountMap map[string]int, startTime time.Time, | |||
| log.Info("query user error. return.") | |||
| return err | |||
| } | |||
| userNewAddActivity := make(map[int64]map[int64]int64) | |||
| ParaWeight := getParaWeight() | |||
| userMetrics := make(map[string]int) | |||
| var indexTotal int64 | |||
| @@ -767,6 +855,9 @@ func CounDataByDateAndReCount(wikiCountMap map[string]int, startTime time.Time, | |||
| dateRecord.UserIndexPrimitive = getUserIndex(dateRecord, ParaWeight) | |||
| setUserMetrics(userMetrics, userRecord, start_unix, end_unix, dateRecord) | |||
| if getUserActivate(dateRecord) > 0 { | |||
| addUserToMap(userNewAddActivity, userRecord.CreatedUnix, dateRecord.ID) | |||
| } | |||
| _, err = statictisSess.Insert(&dateRecord) | |||
| if err != nil { | |||
| log.Info("insert daterecord failed." + err.Error()) | |||
| @@ -789,14 +880,66 @@ func CounDataByDateAndReCount(wikiCountMap map[string]int, startTime time.Time, | |||
| useMetrics.ActivateRegistUser = getMapKeyStringValue("ActivateRegistUser", userMetrics) | |||
| useMetrics.HasActivityUser = getMapKeyStringValue("HasActivityUser", userMetrics) | |||
| useMetrics.RegistActivityUser = 0 | |||
| useMetrics.NotActivateRegistUser = getMapKeyStringValue("NotActivateRegistUser", userMetrics) | |||
| useMetrics.TotalActivateRegistUser = getMapKeyStringValue("TotalActivateRegistUser", userMetrics) | |||
| useMetrics.TotalHasActivityUser = getMapKeyStringValue("TotalHasActivityUser", userMetrics) | |||
| statictisSess.Insert(&useMetrics) | |||
| count, err = sess.Count(new(User)) | |||
| if err != nil { | |||
| log.Info("query user error. return.") | |||
| } | |||
| useMetrics.TotalUser = int(count) | |||
| if useMetrics.ActivateRegistUser+useMetrics.NotActivateRegistUser == 0 { | |||
| useMetrics.ActivateIndex = 0 | |||
| } else { | |||
| useMetrics.ActivateIndex = float64(useMetrics.ActivateRegistUser) / float64(useMetrics.ActivateRegistUser+useMetrics.NotActivateRegistUser) | |||
| } | |||
| statictisSess.Insert(&useMetrics) | |||
| //update new user activity | |||
| updateNewUserAcitivity(userNewAddActivity, statictisSess) | |||
| return nil | |||
| } | |||
| func updateNewUserAcitivity(currentUserActivity map[int64]map[int64]int64, statictisSess *xorm.Session) { | |||
| for key, value := range currentUserActivity { | |||
| useMetrics := &UserMetrics{CountDate: key} | |||
| has, err := statictisSess.Get(useMetrics) | |||
| if err == nil && has { | |||
| userIdArrays := strings.Split(useMetrics.HasActivityUserJson, ",") | |||
| for _, userIdStr := range userIdArrays { | |||
| userIdInt, err := strconv.ParseInt(userIdStr, 10, 64) | |||
| if err == nil { | |||
| value[userIdInt] = userIdInt | |||
| } | |||
| } | |||
| userIdArray := "" | |||
| for _, tmpValue := range value { | |||
| userIdArray += fmt.Sprint(tmpValue) + "," | |||
| } | |||
| useMetrics.HasActivityUser = len(value) | |||
| if len(userIdArray) > 0 { | |||
| useMetrics.HasActivityUserJson = userIdArray[0 : len(userIdArray)-1] | |||
| } | |||
| updateSql := "update public.user_metrics set has_activity_user_json=" + useMetrics.HasActivityUserJson + ",regist_activity_user=" + fmt.Sprint(useMetrics.HasActivityUser) + " where count_date=" + fmt.Sprint(key) | |||
| statictisSess.Exec(updateSql) | |||
| } | |||
| } | |||
| } | |||
| func addUserToMap(currentUserActivity map[int64]map[int64]int64, registDate timeutil.TimeStamp, userId int64) { | |||
| CountDateTime := time.Date(registDate.Year(), registDate.AsTime().Month(), registDate.AsTime().Day(), 0, 1, 0, 0, registDate.AsTime().Location()) | |||
| CountDate := CountDateTime.Unix() | |||
| if _, ok := currentUserActivity[CountDate]; !ok { | |||
| userIdMap := make(map[int64]int64, 0) | |||
| userIdMap[userId] = userId | |||
| currentUserActivity[CountDate] = userIdMap | |||
| } else { | |||
| currentUserActivity[CountDate][userId] = userId | |||
| } | |||
| } | |||
| func setUserMetrics(userMetrics map[string]int, user *User, start_time int64, end_time int64, dateRecord UserBusinessAnalysis) { | |||
| //ActivateRegistUser int `xorm:"NOT NULL DEFAULT 0"` | |||
| //NotActivateRegistUser int `xorm:"NOT NULL DEFAULT 0"` | |||
| @@ -400,10 +400,16 @@ type UserAnalysisPara struct { | |||
| } | |||
| type UserMetrics struct { | |||
| CountDate int64 `xorm:"pk"` | |||
| ActivateRegistUser int `xorm:"NOT NULL DEFAULT 0"` | |||
| NotActivateRegistUser int `xorm:"NOT NULL DEFAULT 0"` | |||
| HasActivityUser int `xorm:"NOT NULL DEFAULT 0"` | |||
| TotalActivateRegistUser int `xorm:"NOT NULL DEFAULT 0"` | |||
| TotalHasActivityUser int `xorm:"NOT NULL DEFAULT 0"` | |||
| CountDate int64 `xorm:"pk"` | |||
| ActivateRegistUser int `xorm:"NOT NULL DEFAULT 0"` | |||
| NotActivateRegistUser int `xorm:"NOT NULL DEFAULT 0"` | |||
| ActivateIndex float64 `xorm:"NOT NULL DEFAULT 0"` | |||
| RegistActivityUser int `xorm:"NOT NULL DEFAULT 0"` | |||
| HasActivityUser int `xorm:"NOT NULL DEFAULT 0"` | |||
| TotalUser int `xorm:"NOT NULL DEFAULT 0"` | |||
| TotalActivateRegistUser int `xorm:"NOT NULL DEFAULT 0"` | |||
| TotalHasActivityUser int `xorm:"NOT NULL DEFAULT 0"` | |||
| DisplayDate string `xorm:"-"` | |||
| DaysForMonth int `xorm:"NOT NULL DEFAULT 0"` | |||
| HasActivityUserJson string `xorm:"text NULL"` | |||
| } | |||
| @@ -525,6 +525,19 @@ static.public.user_business_analysis_last30_day=Last_30_day | |||
| static.public.user_business_analysis_last_month=Last_Month | |||
| static.public.user_business_analysis_yesterday=Yesterday | |||
| static.public.user_business_analysis_all=All | |||
| metrics.sheetname=User Trend Analysis | |||
| metrics.date=Count Date | |||
| metrics.newregistuser=New registered user | |||
| metrics.newregistandactiveuser=New activated | |||
| metrics.hasactivateuser=New contributing activities | |||
| metrics.newregistnotactiveuser=New inactive | |||
| metrics.averageuser=Average new users | |||
| metrics.newuseractiveindex=Activation rate of new users | |||
| metrics.totalregistuser=Cumulative registered users | |||
| metrics.totalactiveduser=Cumulative activated users | |||
| metrics.totalhasactivityuser=Cumulative active users | |||
| [settings] | |||
| profile = Profile | |||
| account = Account | |||
| @@ -530,6 +530,19 @@ static.public.user_business_analysis_last30_day=近30天 | |||
| static.public.user_business_analysis_last_month=上月 | |||
| static.public.user_business_analysis_yesterday=昨天 | |||
| static.public.user_business_analysis_all=所有 | |||
| metrics.sheetname=用户趋势分析 | |||
| metrics.date=日期 | |||
| metrics.newregistuser=新增注册用户 | |||
| metrics.newregistandactiveuser=新增已激活 | |||
| metrics.hasactivateuser=新增有贡献活动 | |||
| metrics.newregistnotactiveuser=新增未激活 | |||
| metrics.averageuser=平均新增用户 | |||
| metrics.newuseractiveindex=新增用户激活率 | |||
| metrics.totalregistuser=累计注册用户 | |||
| metrics.totalactiveduser=累计已激活 | |||
| metrics.totalhasactivityuser=累计有贡献活动 | |||
| [settings] | |||
| profile=个人信息 | |||
| account=账号 | |||
| @@ -550,7 +550,15 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| }) | |||
| }, operationReq) | |||
| m.Get("/query_user_metrics", operationReq, repo_ext.QueryMetrics) | |||
| m.Get("/query_metrics_current_month", operationReq, repo_ext.QueryUserMetricsCurrentMonth) | |||
| m.Get("/query_metrics_current_week", operationReq, repo_ext.QueryUserMetricsCurrentWeek) | |||
| m.Get("/query_metrics_current_year", operationReq, repo_ext.QueryUserMetricsCurrentYear) | |||
| m.Get("/query_metrics_last30_day", operationReq, repo_ext.QueryUserMetricsLast30Day) | |||
| m.Get("/query_metrics_last_month", operationReq, repo_ext.QueryUserMetricsLastMonth) | |||
| m.Get("/query_metrics_yesterday", operationReq, repo_ext.QueryUserMetricsYesterday) | |||
| m.Get("/query_metrics_all", operationReq, repo_ext.QueryUserMetricsAll) | |||
| m.Get("/query_user_metrics_page", operationReq, repo_ext.QueryUserMetricDataPage) | |||
| m.Get("/query_user_rank_list", operationReq, repo_ext.QueryRankingList) | |||
| m.Get("/query_user_static_page", operationReq, repo_ext.QueryUserStaticDataPage) | |||
| m.Get("/query_user_current_month", operationReq, repo_ext.QueryUserStaticCurrentMonth) | |||
| @@ -8,6 +8,7 @@ package routers | |||
| import ( | |||
| "bytes" | |||
| "net/http" | |||
| "strconv" | |||
| "strings" | |||
| "code.gitea.io/gitea/services/repository" | |||
| @@ -641,6 +642,54 @@ func GetRecommendOrg() ([]map[string]interface{}, error) { | |||
| return resultOrg, nil | |||
| } | |||
| func GetRankUser(index string) ([]map[string]interface{}, error) { | |||
| url := setting.RecommentRepoAddr + "user_rank_" + index | |||
| result, err := repository.RecommendFromPromote(url) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| resultOrg := make([]map[string]interface{}, 0) | |||
| for _, userRank := range result { | |||
| tmpIndex := strings.Index(userRank, " ") | |||
| userName := userRank | |||
| score := 0 | |||
| if tmpIndex != -1 { | |||
| userName = userRank[0:tmpIndex] | |||
| tmpScore, err := strconv.Atoi(userRank[tmpIndex+1:]) | |||
| if err != nil { | |||
| log.Info("convert to int error.") | |||
| } | |||
| score = tmpScore | |||
| } | |||
| user, err := models.GetUserByName(userName) | |||
| if err == nil { | |||
| userMap := make(map[string]interface{}) | |||
| userMap["Name"] = user.Name | |||
| userMap["Description"] = user.Description | |||
| userMap["FullName"] = user.FullName | |||
| userMap["HomeLink"] = user.HomeLink() | |||
| userMap["ID"] = user.ID | |||
| userMap["Avatar"] = user.RelAvatarLink() | |||
| userMap["Score"] = score | |||
| resultOrg = append(resultOrg, userMap) | |||
| } else { | |||
| log.Info("query user error," + err.Error()) | |||
| } | |||
| } | |||
| return resultOrg, nil | |||
| } | |||
| func GetUserRankFromPromote(ctx *context.Context) { | |||
| index := ctx.Params("index") | |||
| resultUserRank, err := GetRankUser(index) | |||
| if err != nil { | |||
| ctx.ServerError("500", err) | |||
| return | |||
| } | |||
| ctx.JSON(200, resultUserRank) | |||
| } | |||
| func RecommendOrgFromPromote(ctx *context.Context) { | |||
| resultOrg, err := GetRecommendOrg() | |||
| if err != nil { | |||
| @@ -19,6 +19,57 @@ const ( | |||
| PAGE_SIZE = 2000 | |||
| ) | |||
| func getUserMetricsExcelHeader(ctx *context.Context) map[string]string { | |||
| excelHeader := make([]string, 0) | |||
| excelHeader = append(excelHeader, ctx.Tr("user.metrics.date")) | |||
| excelHeader = append(excelHeader, ctx.Tr("user.metrics.newregistuser")) | |||
| excelHeader = append(excelHeader, ctx.Tr("user.metrics.newregistandactiveuser")) | |||
| excelHeader = append(excelHeader, ctx.Tr("user.metrics.hasactivateuser")) | |||
| excelHeader = append(excelHeader, ctx.Tr("user.metrics.newregistnotactiveuser")) | |||
| excelHeader = append(excelHeader, ctx.Tr("user.metrics.averageuser")) | |||
| excelHeader = append(excelHeader, ctx.Tr("user.metrics.newuseractiveindex")) | |||
| excelHeader = append(excelHeader, ctx.Tr("user.metrics.totalregistuser")) | |||
| excelHeader = append(excelHeader, ctx.Tr("user.metrics.totalactiveduser")) | |||
| excelHeader = append(excelHeader, ctx.Tr("user.metrics.totalhasactivityuser")) | |||
| excelHeaderMap := make(map[string]string, 0) | |||
| var i byte | |||
| i = 0 | |||
| for _, value := range excelHeader { | |||
| excelColumn := getColumn(i) + fmt.Sprint(1) | |||
| excelHeaderMap[excelColumn] = value | |||
| i++ | |||
| } | |||
| return excelHeaderMap | |||
| } | |||
| func writeUserMetricsExcel(row int, xlsx *excelize.File, sheetName string, userMetrics models.UserMetrics) { | |||
| rows := fmt.Sprint(row) | |||
| var tmp byte | |||
| tmp = 0 | |||
| dateTime := time.Unix(userMetrics.CountDate, 0) | |||
| //dateTime.Format("2006-01-02 15:04:05") | |||
| xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, dateTime.Format("2006-01-02 15:04:05")) | |||
| tmp = tmp + 1 | |||
| xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userMetrics.ActivateRegistUser+userMetrics.NotActivateRegistUser) | |||
| tmp = tmp + 1 | |||
| xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userMetrics.ActivateRegistUser) | |||
| tmp = tmp + 1 | |||
| xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userMetrics.RegistActivityUser) | |||
| tmp = tmp + 1 | |||
| xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userMetrics.NotActivateRegistUser) | |||
| tmp = tmp + 1 | |||
| xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, "") | |||
| tmp = tmp + 1 | |||
| xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, fmt.Sprintf("%.2f", userMetrics.ActivateIndex)) | |||
| tmp = tmp + 1 | |||
| xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userMetrics.TotalUser) | |||
| tmp = tmp + 1 | |||
| xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userMetrics.TotalActivateRegistUser) | |||
| tmp = tmp + 1 | |||
| xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userMetrics.TotalHasActivityUser) | |||
| } | |||
| func getExcelHeader(ctx *context.Context) map[string]string { | |||
| excelHeader := make([]string, 0) | |||
| excelHeader = append(excelHeader, ctx.Tr("user.static.id")) | |||
| @@ -200,16 +251,65 @@ func queryUserDataPage(ctx *context.Context, tableName string, queryObj interfac | |||
| } | |||
| } | |||
| func QueryMetrics(ctx *context.Context) { | |||
| func queryMetrics(ctx *context.Context, tableName string) { | |||
| startDate := ctx.Query("startDate") | |||
| endDate := ctx.Query("endDate") | |||
| startTime, _ := time.ParseInLocation("2006-01-02", startDate, time.Local) | |||
| endTime, _ := time.ParseInLocation("2006-01-02", endDate, time.Local) | |||
| result, count := models.QueryMetrics(startTime.Unix(), endTime.Unix()) | |||
| mapInterface := make(map[string]interface{}) | |||
| mapInterface["data"] = result | |||
| mapInterface["count"] = count | |||
| ctx.JSON(http.StatusOK, mapInterface) | |||
| page := ctx.QueryInt("page") | |||
| if page <= 0 { | |||
| page = 1 | |||
| } | |||
| pageSize := ctx.QueryInt("pageSize") | |||
| if pageSize <= 0 { | |||
| pageSize = setting.UI.IssuePagingNum | |||
| } | |||
| IsReturnFile := ctx.QueryBool("IsReturnFile") | |||
| if IsReturnFile { | |||
| //writer exec file. | |||
| xlsx := excelize.NewFile() | |||
| sheetName := ctx.Tr("user.metrics.sheetname") | |||
| index := xlsx.NewSheet(sheetName) | |||
| xlsx.DeleteSheet("Sheet1") | |||
| dataHeader := getUserMetricsExcelHeader(ctx) | |||
| for k, v := range dataHeader { | |||
| //设置单元格的值 | |||
| xlsx.SetCellValue(sheetName, k, v) | |||
| } | |||
| userMetricResult, count := models.QueryMetrics(startTime.Unix(), endTime.Unix()) | |||
| row := 1 | |||
| log.Info("return count=" + fmt.Sprint(count)) | |||
| for _, userRecord := range userMetricResult { | |||
| row++ | |||
| writeUserMetricsExcel(row, xlsx, sheetName, userRecord) | |||
| } | |||
| //设置默认打开的表单 | |||
| xlsx.SetActiveSheet(index) | |||
| filename := sheetName + "_" + ctx.Tr("user.static."+tableName) + ".xlsx" | |||
| ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+url.QueryEscape(filename)) | |||
| ctx.Resp.Header().Set("Content-Type", "application/octet-stream") | |||
| if _, err := xlsx.WriteTo(ctx.Resp); err != nil { | |||
| log.Info("writer exel error." + err.Error()) | |||
| } | |||
| } else { | |||
| var count int64 | |||
| result := make([]models.UserMetrics, 0) | |||
| if tableName == "public.user_business_analysis_current_year" { | |||
| result = models.QueryMetricsForYear() | |||
| count = int64(len(result)) | |||
| } else if tableName == "public.user_business_analysis_all" { | |||
| result = models.QueryMetricsForAll() | |||
| count = int64(len(result)) | |||
| } else { | |||
| result, count = models.QueryMetricsPage(startTime.Unix(), endTime.Unix(), page, pageSize) | |||
| } | |||
| mapInterface := make(map[string]interface{}) | |||
| mapInterface["data"] = result | |||
| mapInterface["count"] = count | |||
| ctx.JSON(http.StatusOK, mapInterface) | |||
| } | |||
| } | |||
| func QueryRankingList(ctx *context.Context) { | |||
| @@ -224,34 +324,71 @@ func QueryRankingList(ctx *context.Context) { | |||
| ctx.JSON(http.StatusOK, mapInterface) | |||
| } | |||
| func QueryUserMetricsCurrentMonth(ctx *context.Context) { | |||
| queryMetrics(ctx, "public.user_business_analysis_current_month") | |||
| } | |||
| func QueryUserStaticCurrentMonth(ctx *context.Context) { | |||
| queryUserDataPage(ctx, "public.user_business_analysis_current_month", new(models.UserBusinessAnalysisCurrentMonth)) | |||
| } | |||
| func QueryUserMetricsCurrentWeek(ctx *context.Context) { | |||
| queryMetrics(ctx, "public.user_business_analysis_current_week") | |||
| } | |||
| func QueryUserStaticCurrentWeek(ctx *context.Context) { | |||
| queryUserDataPage(ctx, "public.user_business_analysis_current_week", new(models.UserBusinessAnalysisCurrentWeek)) | |||
| } | |||
| func QueryUserMetricsCurrentYear(ctx *context.Context) { | |||
| queryMetrics(ctx, "public.user_business_analysis_current_year") | |||
| } | |||
| func QueryUserStaticCurrentYear(ctx *context.Context) { | |||
| queryUserDataPage(ctx, "public.user_business_analysis_current_year", new(models.UserBusinessAnalysisCurrentYear)) | |||
| } | |||
| func QueryUserMetricsLast30Day(ctx *context.Context) { | |||
| queryMetrics(ctx, "public.user_business_analysis_last30_day") | |||
| } | |||
| func QueryUserStaticLast30Day(ctx *context.Context) { | |||
| queryUserDataPage(ctx, "public.user_business_analysis_last30_day", new(models.UserBusinessAnalysisLast30Day)) | |||
| } | |||
| func QueryUserMetricsLastMonth(ctx *context.Context) { | |||
| queryMetrics(ctx, "public.user_business_analysis_last_month") | |||
| } | |||
| func QueryUserStaticLastMonth(ctx *context.Context) { | |||
| queryUserDataPage(ctx, "public.user_business_analysis_last_month", new(models.UserBusinessAnalysisLastMonth)) | |||
| } | |||
| func QueryUserMetricsYesterday(ctx *context.Context) { | |||
| queryMetrics(ctx, "public.user_business_analysis_yesterday") | |||
| } | |||
| func QueryUserStaticYesterday(ctx *context.Context) { | |||
| queryUserDataPage(ctx, "public.user_business_analysis_yesterday", new(models.UserBusinessAnalysisYesterday)) | |||
| } | |||
| func QueryUserMetricsAll(ctx *context.Context) { | |||
| queryMetrics(ctx, "public.user_business_analysis_all") | |||
| } | |||
| func QueryUserStaticAll(ctx *context.Context) { | |||
| queryUserDataPage(ctx, "public.user_business_analysis_all", new(models.UserBusinessAnalysisAll)) | |||
| } | |||
| func QueryUserMetricDataPage(ctx *context.Context) { | |||
| startDate := ctx.Query("startDate") | |||
| endDate := ctx.Query("endDate") | |||
| startTime, _ := time.ParseInLocation("2006-01-02", startDate, time.Local) | |||
| endTime, _ := time.ParseInLocation("2006-01-02", endDate, time.Local) | |||
| page := ctx.QueryInt("page") | |||
| if page <= 0 { | |||
| page = 1 | |||
| } | |||
| pageSize := ctx.QueryInt("pageSize") | |||
| if pageSize <= 0 { | |||
| pageSize = setting.UI.IssuePagingNum | |||
| } | |||
| result, count := models.QueryMetricsPage(startTime.Unix(), endTime.Unix(), page, pageSize) | |||
| mapInterface := make(map[string]interface{}) | |||
| mapInterface["data"] = result | |||
| mapInterface["count"] = count | |||
| ctx.JSON(http.StatusOK, mapInterface) | |||
| } | |||
| func QueryUserStaticDataPage(ctx *context.Context) { | |||
| startDate := ctx.Query("startDate") | |||
| endDate := ctx.Query("endDate") | |||
| @@ -325,6 +325,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| m.Get("/action/notification", routers.ActionNotification) | |||
| m.Get("/recommend/org", routers.RecommendOrgFromPromote) | |||
| m.Get("/recommend/repo", routers.RecommendRepoFromPromote) | |||
| m.Get("/recommend/userrank/:index", routers.GetUserRankFromPromote) | |||
| m.Post("/all/search/", routers.Search) | |||
| m.Get("/all/search/", routers.EmptySearch) | |||
| m.Get("/all/dosearch/", routers.SearchApi) | |||
| @@ -15,7 +15,7 @@ | |||
| <span class="help">{{.i18n.Tr "org.org_name_helper"}}</span> | |||
| </div> | |||
| <div class="inline field {{if .Err_OrgVisibility}}error{{end}}"> | |||
| <!-- <div class="inline field {{if .Err_OrgVisibility}}error{{end}}"> | |||
| <span class="inline required field"><label for="visibility">{{.i18n.Tr "org.settings.visibility"}}</label></span> | |||
| <div class="inline-grouped-list"> | |||
| <div class="ui radio checkbox"> | |||
| @@ -31,7 +31,7 @@ | |||
| <label>{{.i18n.Tr "org.settings.visibility.private"}}</label> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> --> | |||
| <div class="inline field" id="permission_box"> | |||
| <label>{{.i18n.Tr "org.settings.permission"}}</label> | |||
| @@ -43,13 +43,13 @@ | |||
| </div> | |||
| </div> | |||
| <div class="field"> | |||
| <div class="ui radio checkbox"> | |||
| <div class="ui radio disabled checkbox"> | |||
| <input class="hidden enable-system-radio" tabindex="0" name="visibility" type="radio" value="1" {{if eq .CurrentVisibility 1}}checked{{end}}/> | |||
| <label>{{.i18n.Tr "org.settings.visibility.limited"}}</label> | |||
| </div> | |||
| </div> | |||
| <div class="field"> | |||
| <div class="ui radio checkbox"> | |||
| <div class="ui radio disabled checkbox"> | |||
| <input class="hidden enable-system-radio" tabindex="0" name="visibility" type="radio" value="2" {{if eq .CurrentVisibility 2}}checked{{end}}/> | |||
| <label>{{.i18n.Tr "org.settings.visibility.private"}}</label> | |||
| </div> | |||