You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

user_data_analysis.go 7.7 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. package repo
  2. import (
  3. "fmt"
  4. "net/http"
  5. "net/url"
  6. "time"
  7. "code.gitea.io/gitea/models"
  8. "code.gitea.io/gitea/modules/context"
  9. "code.gitea.io/gitea/modules/git"
  10. "code.gitea.io/gitea/modules/log"
  11. "code.gitea.io/gitea/modules/setting"
  12. "code.gitea.io/gitea/services/mailer"
  13. "github.com/360EntSecGroup-Skylar/excelize/v2"
  14. )
  15. func QueryUserStaticDataPage(ctx *context.Context) {
  16. startDate := ctx.Query("startDate")
  17. endDate := ctx.Query("endDate")
  18. page := ctx.QueryInt("page")
  19. if page <= 0 {
  20. page = 1
  21. }
  22. pageSize := ctx.QueryInt("pageSize")
  23. if pageSize <= 0 {
  24. pageSize = setting.UI.IssuePagingNum
  25. }
  26. userName := ctx.Query("userName")
  27. IsReturnFile := ctx.QueryBool("IsReturnFile")
  28. log.Info("startDate=" + startDate + " endDate=" + endDate + " userName=" + userName + " page=" + fmt.Sprint(page))
  29. var startTime time.Time
  30. var endTime time.Time
  31. var isAll bool
  32. if startDate == "all" {
  33. isAll = true
  34. startTime = time.Now()
  35. endTime = time.Now()
  36. } else {
  37. startTime, _ = time.ParseInLocation("2006-01-02", startDate, time.Local)
  38. startTime = time.Date(startTime.Year(), startTime.Month(), startTime.Day(), 12, 0, 0, 0, startTime.Location())
  39. settingStartTime, _ := time.Parse("2006-01-02", setting.RadarMap.RecordBeginTime)
  40. if startTime.Unix() < settingStartTime.Unix() {
  41. startTime = settingStartTime
  42. startDate = settingStartTime.Format("2006-01-02")
  43. }
  44. endTime, _ = time.ParseInLocation("2006-01-02", endDate, time.Local)
  45. endTime = endTime.AddDate(0, 0, 1)
  46. endTime = time.Date(endTime.Year(), endTime.Month(), endTime.Day(), 23, 59, 59, 0, startTime.Location())
  47. isAll = false
  48. log.Info("startTime=" + fmt.Sprint(startTime.Unix()) + " endDate=" + fmt.Sprint(endTime.Unix()))
  49. }
  50. if IsReturnFile {
  51. page = -1
  52. pageSize = -1
  53. }
  54. pageOpts := &models.UserBusinessAnalysisQueryOptions{
  55. ListOptions: models.ListOptions{
  56. Page: page,
  57. PageSize: pageSize,
  58. },
  59. UserName: userName,
  60. StartTime: startTime.Unix(),
  61. EndTime: endTime.Unix(),
  62. IsAll: isAll,
  63. }
  64. if IsReturnFile {
  65. re, count := models.QueryUserStaticDataAll(pageOpts)
  66. log.Info("return count=" + fmt.Sprint(count))
  67. //writer exec file.
  68. xlsx := excelize.NewFile()
  69. sheetName := ctx.Tr("user.static.sheetname")
  70. index := xlsx.NewSheet(sheetName)
  71. xlsx.DeleteSheet("Sheet1")
  72. dataHeader := map[string]string{
  73. "A1": ctx.Tr("user.static.id"),
  74. "B1": ctx.Tr("user.static.name"),
  75. "C1": ctx.Tr("user.static.codemergecount"),
  76. "D1": ctx.Tr("user.static.commitcount"),
  77. "E1": ctx.Tr("user.static.issuecount"),
  78. "F1": ctx.Tr("user.static.commentcount"),
  79. "G1": ctx.Tr("user.static.focusrepocount"),
  80. "H1": ctx.Tr("user.static.starrepocount"),
  81. "I1": ctx.Tr("user.static.logincount"),
  82. "J1": ctx.Tr("user.static.watchedcount"),
  83. "K1": ctx.Tr("user.static.commitcodesize"),
  84. "L1": ctx.Tr("user.static.solveissuecount"),
  85. "M1": ctx.Tr("user.static.encyclopediascount"),
  86. "N1": ctx.Tr("user.static.createrepocount"),
  87. "O1": ctx.Tr("user.static.openiindex"),
  88. "P1": ctx.Tr("user.static.registdate"),
  89. "Q1": ctx.Tr("user.static.countdate"),
  90. }
  91. for k, v := range dataHeader {
  92. //设置单元格的值
  93. xlsx.SetCellValue(sheetName, k, v)
  94. }
  95. for i, userRecord := range re {
  96. rows := fmt.Sprint(i + 2)
  97. xlsx.SetCellValue(sheetName, "A"+rows, userRecord.ID)
  98. xlsx.SetCellValue(sheetName, "B"+rows, userRecord.Name)
  99. xlsx.SetCellValue(sheetName, "C"+rows, userRecord.CodeMergeCount)
  100. xlsx.SetCellValue(sheetName, "D"+rows, userRecord.CommitCount)
  101. xlsx.SetCellValue(sheetName, "E"+rows, userRecord.IssueCount)
  102. xlsx.SetCellValue(sheetName, "F"+rows, userRecord.CommentCount)
  103. xlsx.SetCellValue(sheetName, "G"+rows, userRecord.FocusRepoCount)
  104. xlsx.SetCellValue(sheetName, "H"+rows, userRecord.StarRepoCount)
  105. xlsx.SetCellValue(sheetName, "I"+rows, userRecord.LoginCount)
  106. xlsx.SetCellValue(sheetName, "J"+rows, userRecord.WatchedCount)
  107. xlsx.SetCellValue(sheetName, "K"+rows, userRecord.CommitCodeSize)
  108. xlsx.SetCellValue(sheetName, "L"+rows, userRecord.SolveIssueCount)
  109. xlsx.SetCellValue(sheetName, "M"+rows, userRecord.EncyclopediasCount)
  110. xlsx.SetCellValue(sheetName, "N"+rows, userRecord.CreateRepoCount)
  111. xlsx.SetCellValue(sheetName, "O"+rows, fmt.Sprintf("%.2f", userRecord.OpenIIndex))
  112. formatTime := userRecord.RegistDate.Format("2006-01-02 15:04:05")
  113. xlsx.SetCellValue(sheetName, "P"+rows, formatTime[0:len(formatTime)-3])
  114. formatTime = userRecord.DataDate
  115. xlsx.SetCellValue(sheetName, "Q"+rows, formatTime+" 00:01")
  116. }
  117. //设置默认打开的表单
  118. xlsx.SetActiveSheet(index)
  119. filename := sheetName + "_" + ctx.Tr("user.static.all") + ".xlsx"
  120. ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+url.QueryEscape(filename))
  121. ctx.Resp.Header().Set("Content-Type", "application/octet-stream")
  122. if _, err := xlsx.WriteTo(ctx.Resp); err != nil {
  123. log.Info("writer exel error." + err.Error())
  124. }
  125. } else {
  126. mapInterface := make(map[string]interface{})
  127. re, count := models.QueryUserStaticDataPage(pageOpts)
  128. mapInterface["data"] = re
  129. mapInterface["count"] = count
  130. ctx.JSON(http.StatusOK, mapInterface)
  131. }
  132. }
  133. func TimingCountDataByDateAndReCount(date string, isReCount bool) {
  134. if date == "refreshAll" {
  135. models.RefreshUserStaticAllTabel()
  136. return
  137. }
  138. t, _ := time.Parse("2006-01-02", date)
  139. startTime := time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location())
  140. endTime := time.Date(t.Year(), t.Month(), t.Day(), 23, 59, 59, 0, t.Location())
  141. //query wiki data
  142. log.Info("start to time count data")
  143. wikiMap := make(map[string]int)
  144. warnEmailMessage := "用户统计信息入库失败,请尽快定位。"
  145. repoList, err := models.GetAllRepositories()
  146. if err != nil {
  147. log.Error("query repo error." + err.Error())
  148. mailer.SendWarnNotifyMail(setting.Warn_Notify_Mails, warnEmailMessage)
  149. return
  150. }
  151. log.Info("start to query wiki data")
  152. for _, repoRecord := range repoList {
  153. wikiPath := models.WikiPath(repoRecord.OwnerName, repoRecord.Name)
  154. time, err := git.GetLatestCommitTime(wikiPath)
  155. if err == nil {
  156. log.Info("last commit time:" + time.Format("2006-01-02 15:04:05") + " wikiPath=" + wikiPath)
  157. if time.After(startTime) {
  158. wikiRepo, _, err := FindWikiRepoCommitByWikiPath(wikiPath)
  159. if err != nil {
  160. log.Error("wiki not exist. wikiPath=" + wikiPath)
  161. } else {
  162. log.Info("wiki exist, wikiPath=" + wikiPath)
  163. list, err := wikiRepo.GetCommitByPathAndDays(wikiPath, 1)
  164. if err != nil {
  165. log.Info("err,err=v%", err)
  166. } else {
  167. for logEntry := list.Front(); logEntry != nil; logEntry = logEntry.Next() {
  168. commit := logEntry.Value.(*git.Commit)
  169. log.Info("commit msg=" + commit.CommitMessage + " time=" + commit.Committer.When.Format("2006-01-02 15:04:05") + " user=" + commit.Committer.Name)
  170. if _, ok := wikiMap[commit.Committer.Name]; !ok {
  171. wikiMap[commit.Committer.Name] = 1
  172. } else {
  173. wikiMap[commit.Committer.Name] += 1
  174. }
  175. }
  176. }
  177. }
  178. }
  179. }
  180. }
  181. //other user info data
  182. err = models.CounDataByDateAndReCount(wikiMap, startTime, endTime, isReCount)
  183. if err != nil {
  184. log.Error("count user info error." + err.Error())
  185. mailer.SendWarnNotifyMail(setting.Warn_Notify_Mails, warnEmailMessage)
  186. }
  187. if isReCount {
  188. models.RefreshUserStaticAllTabel()
  189. }
  190. }
  191. func TimingCountDataByDate(date string) {
  192. TimingCountDataByDateAndReCount(date, true)
  193. }
  194. func TimingCountData() {
  195. log.Info("start to time count data")
  196. currentTimeNow := time.Now()
  197. log.Info("current time:" + currentTimeNow.Format("2006-01-02 15:04:05"))
  198. startTime := currentTimeNow.AddDate(0, 0, -1).Format("2006-01-02")
  199. TimingCountDataByDateAndReCount(startTime, false)
  200. }