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 36 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920
  1. package repo
  2. import (
  3. "fmt"
  4. "net/http"
  5. "net/url"
  6. "os"
  7. "strconv"
  8. "strings"
  9. "time"
  10. "code.gitea.io/gitea/models"
  11. "code.gitea.io/gitea/modules/context"
  12. "code.gitea.io/gitea/modules/git"
  13. "code.gitea.io/gitea/modules/log"
  14. "code.gitea.io/gitea/modules/setting"
  15. "code.gitea.io/gitea/services/mailer"
  16. "github.com/360EntSecGroup-Skylar/excelize/v2"
  17. )
  18. const (
  19. PAGE_SIZE = 2000
  20. Excel_File_Path = "/useranalysis/"
  21. )
  22. func getUserMetricsExcelHeader(ctx *context.Context) map[string]string {
  23. excelHeader := make([]string, 0)
  24. excelHeader = append(excelHeader, ctx.Tr("user.metrics.date"))
  25. excelHeader = append(excelHeader, ctx.Tr("user.metrics.newregistuser"))
  26. excelHeader = append(excelHeader, ctx.Tr("user.metrics.newregistandactiveuser"))
  27. excelHeader = append(excelHeader, ctx.Tr("user.metrics.hasactivateuser"))
  28. excelHeader = append(excelHeader, ctx.Tr("user.metrics.newregistnotactiveuser"))
  29. excelHeader = append(excelHeader, ctx.Tr("user.metrics.newuseractiveindex"))
  30. excelHeader = append(excelHeader, ctx.Tr("user.metrics.currentdayactivity"))
  31. excelHeader = append(excelHeader, ctx.Tr("user.metrics.totalregistuser"))
  32. excelHeader = append(excelHeader, ctx.Tr("user.metrics.totalactiveduser"))
  33. excelHeader = append(excelHeader, ctx.Tr("user.metrics.totalhasactivityuser"))
  34. excelHeaderMap := make(map[string]string, 0)
  35. var i byte
  36. i = 0
  37. for _, value := range excelHeader {
  38. excelColumn := getColumn(i) + fmt.Sprint(1)
  39. excelHeaderMap[excelColumn] = value
  40. i++
  41. }
  42. return excelHeaderMap
  43. }
  44. func writeUserMetricsExcel(row int, xlsx *excelize.File, sheetName string, userMetrics *models.UserMetrics) {
  45. rows := fmt.Sprint(row)
  46. var tmp byte
  47. tmp = 0
  48. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userMetrics.DisplayDate)
  49. tmp = tmp + 1
  50. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userMetrics.ActivateRegistUser+userMetrics.NotActivateRegistUser)
  51. tmp = tmp + 1
  52. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userMetrics.ActivateRegistUser)
  53. tmp = tmp + 1
  54. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userMetrics.RegistActivityUser)
  55. tmp = tmp + 1
  56. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userMetrics.NotActivateRegistUser)
  57. tmp = tmp + 1
  58. t := userMetrics.ActivateIndex * 100
  59. value := "-"
  60. if t < 100 && t > 0 {
  61. value = fmt.Sprintf("%.2f", t) + "%"
  62. } else if t >= 100 {
  63. value = "100%"
  64. }
  65. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, value)
  66. tmp = tmp + 1
  67. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userMetrics.HasActivityUser)
  68. tmp = tmp + 1
  69. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userMetrics.TotalUser)
  70. tmp = tmp + 1
  71. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userMetrics.TotalActivateRegistUser)
  72. tmp = tmp + 1
  73. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userMetrics.TotalHasActivityUser)
  74. }
  75. func getExcelHeader(ctx *context.Context) map[string]string {
  76. excelHeader := make([]string, 0)
  77. excelHeader = append(excelHeader, ctx.Tr("user.static.id"))
  78. excelHeader = append(excelHeader, ctx.Tr("user.static.name"))
  79. excelHeader = append(excelHeader, ctx.Tr("user.static.UserIndex"))
  80. excelHeader = append(excelHeader, ctx.Tr("user.static.UserIndexPrimitive"))
  81. excelHeader = append(excelHeader, ctx.Tr("user.static.codemergecount"))
  82. excelHeader = append(excelHeader, ctx.Tr("user.static.commitcount"))
  83. excelHeader = append(excelHeader, ctx.Tr("user.static.issuecount"))
  84. excelHeader = append(excelHeader, ctx.Tr("user.static.commentcount"))
  85. excelHeader = append(excelHeader, ctx.Tr("user.static.focusrepocount"))
  86. excelHeader = append(excelHeader, ctx.Tr("user.static.starrepocount"))
  87. excelHeader = append(excelHeader, ctx.Tr("user.static.logincount"))
  88. excelHeader = append(excelHeader, ctx.Tr("user.static.watchedcount"))
  89. excelHeader = append(excelHeader, ctx.Tr("user.static.commitcodesize"))
  90. excelHeader = append(excelHeader, ctx.Tr("user.static.solveissuecount"))
  91. excelHeader = append(excelHeader, ctx.Tr("user.static.encyclopediascount"))
  92. excelHeader = append(excelHeader, ctx.Tr("user.static.createrepocount"))
  93. excelHeader = append(excelHeader, ctx.Tr("user.static.openiindex"))
  94. excelHeader = append(excelHeader, ctx.Tr("user.static.CloudBrainTaskNum"))
  95. excelHeader = append(excelHeader, ctx.Tr("user.static.CloudBrainRunTime"))
  96. excelHeader = append(excelHeader, ctx.Tr("user.static.CommitDatasetNum"))
  97. excelHeader = append(excelHeader, ctx.Tr("user.static.CommitModelCount"))
  98. excelHeader = append(excelHeader, ctx.Tr("user.static.ModelConvertCount"))
  99. excelHeader = append(excelHeader, ctx.Tr("user.static.FocusOtherUser"))
  100. excelHeader = append(excelHeader, ctx.Tr("user.static.CollectDataset"))
  101. excelHeader = append(excelHeader, ctx.Tr("user.static.CollectedDataset"))
  102. excelHeader = append(excelHeader, ctx.Tr("user.static.RecommendDataset"))
  103. excelHeader = append(excelHeader, ctx.Tr("user.static.CollectImage"))
  104. excelHeader = append(excelHeader, ctx.Tr("user.static.CollectedImage"))
  105. excelHeader = append(excelHeader, ctx.Tr("user.static.RecommendImage"))
  106. excelHeader = append(excelHeader, ctx.Tr("user.static.email"))
  107. excelHeader = append(excelHeader, ctx.Tr("user.static.phone"))
  108. excelHeader = append(excelHeader, ctx.Tr("user.static.location"))
  109. excelHeader = append(excelHeader, ctx.Tr("user.static.registdate"))
  110. excelHeader = append(excelHeader, ctx.Tr("user.static.countdate"))
  111. excelHeaderMap := make(map[string]string, 0)
  112. var i byte
  113. i = 0
  114. for _, value := range excelHeader {
  115. excelColumn := getColumn(i) + fmt.Sprint(1)
  116. log.Info("excelColumn=" + excelColumn)
  117. excelHeaderMap[excelColumn] = value
  118. i++
  119. }
  120. return excelHeaderMap
  121. }
  122. func writeExcel(row int, xlsx *excelize.File, sheetName string, userRecord *models.UserBusinessAnalysisAll) {
  123. rows := fmt.Sprint(row)
  124. var tmp byte
  125. tmp = 0
  126. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.ID)
  127. tmp = tmp + 1
  128. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.Name)
  129. tmp = tmp + 1
  130. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, fmt.Sprintf("%.2f", userRecord.UserIndex))
  131. tmp = tmp + 1
  132. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, fmt.Sprintf("%.2f", userRecord.UserIndexPrimitive))
  133. tmp = tmp + 1
  134. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.CodeMergeCount)
  135. tmp = tmp + 1
  136. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.CommitCount)
  137. tmp = tmp + 1
  138. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.IssueCount)
  139. tmp = tmp + 1
  140. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.CommentCount)
  141. tmp = tmp + 1
  142. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.FocusRepoCount)
  143. tmp = tmp + 1
  144. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.StarRepoCount)
  145. tmp = tmp + 1
  146. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.LoginCount)
  147. tmp = tmp + 1
  148. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.WatchedCount)
  149. tmp = tmp + 1
  150. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.CommitCodeSize)
  151. tmp = tmp + 1
  152. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.SolveIssueCount)
  153. tmp = tmp + 1
  154. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.EncyclopediasCount)
  155. tmp = tmp + 1
  156. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.CreateRepoCount)
  157. tmp = tmp + 1
  158. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, fmt.Sprintf("%.2f", userRecord.OpenIIndex))
  159. tmp = tmp + 1
  160. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.CloudBrainTaskNum)
  161. tmp = tmp + 1
  162. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, fmt.Sprintf("%.2f", float64(userRecord.CloudBrainRunTime)/3600))
  163. tmp = tmp + 1
  164. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.CommitDatasetNum)
  165. tmp = tmp + 1
  166. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.CommitModelCount)
  167. tmp = tmp + 1
  168. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.ModelConvertCount)
  169. tmp = tmp + 1
  170. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.FocusOtherUser)
  171. tmp = tmp + 1
  172. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.CollectDataset)
  173. tmp = tmp + 1
  174. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.CollectedDataset)
  175. tmp = tmp + 1
  176. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.RecommendDataset)
  177. tmp = tmp + 1
  178. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.CollectImage)
  179. tmp = tmp + 1
  180. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.CollectedImage)
  181. tmp = tmp + 1
  182. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.RecommendImage)
  183. tmp = tmp + 1
  184. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.Email)
  185. tmp = tmp + 1
  186. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.Phone)
  187. tmp = tmp + 1
  188. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.UserLocation)
  189. tmp = tmp + 1
  190. formatTime := userRecord.RegistDate.Format("2006-01-02 15:04:05")
  191. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, formatTime[0:len(formatTime)-3])
  192. tmp = tmp + 1
  193. formatTime = userRecord.DataDate
  194. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, formatTime)
  195. }
  196. func writeExcelPage(row int, xlsx *excelize.File, sheetName string, userRecord *models.UserBusinessAnalysis) {
  197. rows := fmt.Sprint(row)
  198. var tmp byte
  199. tmp = 0
  200. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.ID)
  201. tmp = tmp + 1
  202. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.Name)
  203. tmp = tmp + 1
  204. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, fmt.Sprintf("%.2f", userRecord.UserIndex))
  205. tmp = tmp + 1
  206. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, fmt.Sprintf("%.2f", userRecord.UserIndexPrimitive))
  207. tmp = tmp + 1
  208. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.CodeMergeCount)
  209. tmp = tmp + 1
  210. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.CommitCount)
  211. tmp = tmp + 1
  212. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.IssueCount)
  213. tmp = tmp + 1
  214. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.CommentCount)
  215. tmp = tmp + 1
  216. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.FocusRepoCount)
  217. tmp = tmp + 1
  218. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.StarRepoCount)
  219. tmp = tmp + 1
  220. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.LoginCount)
  221. tmp = tmp + 1
  222. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.WatchedCount)
  223. tmp = tmp + 1
  224. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.CommitCodeSize)
  225. tmp = tmp + 1
  226. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.SolveIssueCount)
  227. tmp = tmp + 1
  228. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.EncyclopediasCount)
  229. tmp = tmp + 1
  230. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.CreateRepoCount)
  231. tmp = tmp + 1
  232. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, fmt.Sprintf("%.2f", userRecord.OpenIIndex))
  233. tmp = tmp + 1
  234. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.CloudBrainTaskNum)
  235. tmp = tmp + 1
  236. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, fmt.Sprintf("%.2f", float64(userRecord.CloudBrainRunTime)/3600))
  237. tmp = tmp + 1
  238. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.CommitDatasetNum)
  239. tmp = tmp + 1
  240. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.CommitModelCount)
  241. tmp = tmp + 1
  242. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.ModelConvertCount)
  243. tmp = tmp + 1
  244. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.FocusOtherUser)
  245. tmp = tmp + 1
  246. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.CollectDataset)
  247. tmp = tmp + 1
  248. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.CollectedDataset)
  249. tmp = tmp + 1
  250. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.RecommendDataset)
  251. tmp = tmp + 1
  252. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.CollectImage)
  253. tmp = tmp + 1
  254. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.CollectedImage)
  255. tmp = tmp + 1
  256. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.RecommendImage)
  257. tmp = tmp + 1
  258. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.Email)
  259. tmp = tmp + 1
  260. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.Phone)
  261. tmp = tmp + 1
  262. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.UserLocation)
  263. tmp = tmp + 1
  264. formatTime := userRecord.RegistDate.Format("2006-01-02 15:04:05")
  265. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, formatTime[0:len(formatTime)-3])
  266. tmp = tmp + 1
  267. formatTime = userRecord.DataDate
  268. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, formatTime)
  269. }
  270. func getColumn(tmp byte) string {
  271. var tmpA byte
  272. tmpA = 'A'
  273. if tmp < 26 {
  274. return string(tmpA + tmp)
  275. } else {
  276. return "A" + string(tmpA+(tmp-26))
  277. }
  278. }
  279. func queryUserDataPage(ctx *context.Context, tableName string, queryObj interface{}) {
  280. page := ctx.QueryInt("page")
  281. if page <= 0 {
  282. page = 1
  283. }
  284. pageSize := ctx.QueryInt("pageSize")
  285. if pageSize <= 0 {
  286. pageSize = setting.UI.IssuePagingNum
  287. }
  288. userName := ctx.Query("userName")
  289. IsReturnFile := ctx.QueryBool("IsReturnFile")
  290. if IsReturnFile {
  291. //writer exec file.
  292. xlsx := excelize.NewFile()
  293. sheetName := ctx.Tr("user.static.sheetname")
  294. index := xlsx.NewSheet(sheetName)
  295. xlsx.DeleteSheet("Sheet1")
  296. dataHeader := getExcelHeader(ctx)
  297. for k, v := range dataHeader {
  298. //设置单元格的值
  299. xlsx.SetCellValue(sheetName, k, v)
  300. }
  301. _, count := models.QueryUserStaticDataByTableName(1, 1, tableName, queryObj, userName)
  302. var indexTotal int64
  303. indexTotal = 0
  304. row := 1
  305. for {
  306. re, _ := models.QueryUserStaticDataByTableName(int(indexTotal), PAGE_SIZE, tableName, queryObj, "")
  307. log.Info("return count=" + fmt.Sprint(count))
  308. for _, userRecord := range re {
  309. row++
  310. writeExcel(row, xlsx, sheetName, userRecord)
  311. }
  312. indexTotal += PAGE_SIZE
  313. if indexTotal >= count {
  314. break
  315. }
  316. }
  317. //设置默认打开的表单
  318. xlsx.SetActiveSheet(index)
  319. filename := sheetName + "_" + ctx.Tr("user.static."+tableName) + ".xlsx"
  320. ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+url.QueryEscape(filename))
  321. ctx.Resp.Header().Set("Content-Type", "application/octet-stream")
  322. if _, err := xlsx.WriteTo(ctx.Resp); err != nil {
  323. log.Info("writer exel error." + err.Error())
  324. }
  325. } else {
  326. re, count := models.QueryUserStaticDataByTableName((page-1)*pageSize, pageSize, tableName, queryObj, userName)
  327. mapInterface := make(map[string]interface{})
  328. mapInterface["data"] = re
  329. mapInterface["count"] = count
  330. ctx.JSON(http.StatusOK, mapInterface)
  331. }
  332. }
  333. func queryMetrics(ctx *context.Context, tableName string, startTime time.Time, endTime time.Time) {
  334. IsReturnFile := ctx.QueryBool("IsReturnFile")
  335. var count int64
  336. result := make([]*models.UserMetrics, 0)
  337. if tableName == "public.user_business_analysis_current_year" {
  338. result = models.QueryMetricsForYear(startTime.Unix(), endTime.Unix())
  339. count = int64(len(result))
  340. } else if tableName == "public.user_business_analysis_all" {
  341. result = models.QueryMetricsForAll(startTime.Unix(), endTime.Unix())
  342. count = int64(len(result))
  343. } else {
  344. result, count = models.QueryMetricsPage(startTime.Unix(), endTime.Unix())
  345. }
  346. if IsReturnFile {
  347. //writer exec file.
  348. xlsx := excelize.NewFile()
  349. sheetName := ctx.Tr("user.metrics.sheetname")
  350. index := xlsx.NewSheet(sheetName)
  351. xlsx.DeleteSheet("Sheet1")
  352. dataHeader := getUserMetricsExcelHeader(ctx)
  353. for k, v := range dataHeader {
  354. //设置单元格的值
  355. xlsx.SetCellValue(sheetName, k, v)
  356. }
  357. row := 1
  358. log.Info("return count=" + fmt.Sprint(count))
  359. for _, userRecord := range result {
  360. row++
  361. writeUserMetricsExcel(row, xlsx, sheetName, userRecord)
  362. }
  363. //设置默认打开的表单
  364. xlsx.SetActiveSheet(index)
  365. filename := sheetName + "_" + ctx.Tr("user.static."+tableName) + ".xlsx"
  366. if tableName == "" {
  367. filename = sheetName + "_" + getTimeFileName(startTime) + "_" + getTimeFileName(endTime) + ".xlsx"
  368. }
  369. ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+url.QueryEscape(filename))
  370. ctx.Resp.Header().Set("Content-Type", "application/octet-stream")
  371. if _, err := xlsx.WriteTo(ctx.Resp); err != nil {
  372. log.Info("writer exel error." + err.Error())
  373. }
  374. } else {
  375. mapInterface := make(map[string]interface{})
  376. mapInterface["data"] = result
  377. mapInterface["count"] = count
  378. if tableName == "public.user_business_analysis_yesterday" {
  379. mapInterface["datarecordbegintime"] = setting.RadarMap.GrowthBeginTime
  380. if len(result) > 0 {
  381. dateTime := time.Unix(result[0].CountDate, 0).AddDate(0, 0, 1)
  382. mapInterface["lastUpdatedTime"] = dateTime.Format("2006-01-02 15:04:05")
  383. } else {
  384. mapInterface["lastUpdatedTime"] = ""
  385. }
  386. }
  387. ctx.JSON(http.StatusOK, mapInterface)
  388. }
  389. }
  390. func getTimeFileName(t time.Time) string {
  391. t = t.Local()
  392. return t.Format("20060102")
  393. }
  394. func QueryRankingList(ctx *context.Context) {
  395. key := ctx.Query("key")
  396. tableName := ctx.Query("tableName")
  397. limit := ctx.QueryInt("limit")
  398. result, count := models.QueryRankList(key, tableName, limit)
  399. mapInterface := make(map[string]interface{})
  400. mapInterface["data"] = result
  401. mapInterface["count"] = count
  402. ctx.JSON(http.StatusOK, mapInterface)
  403. }
  404. func DownloadUserDefineFile(ctx *context.Context) {
  405. filename := ctx.Query("filename")
  406. length := len(filename)
  407. if filename[0:1] == "\"" {
  408. filename = filename[1 : length-1]
  409. }
  410. allFilename := setting.AppDataPath + Excel_File_Path + filename
  411. log.Info("allFilename=" + allFilename)
  412. _, err := os.Stat(allFilename)
  413. if err != nil { //文件不存在
  414. log.Info("file not exist.")
  415. ctx.JSON(http.StatusOK, "File Not Exist.")
  416. } else {
  417. ctx.ServeFile(allFilename, url.QueryEscape(filename))
  418. }
  419. }
  420. func QueryUserMetricsCurrentMonth(ctx *context.Context) {
  421. currentTimeNow := time.Now()
  422. pageEndTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 0, 0, 0, currentTimeNow.Location())
  423. pageStartTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), 1, 0, 0, 0, 0, currentTimeNow.Location())
  424. pageStartTime = getStartTime(pageStartTime)
  425. queryMetrics(ctx, "public.user_business_analysis_current_month", pageStartTime, pageEndTime)
  426. }
  427. func QueryUserStaticCurrentMonth(ctx *context.Context) {
  428. queryUserDataPage(ctx, "public.user_business_analysis_current_month", new(models.UserBusinessAnalysisCurrentMonth))
  429. }
  430. func getStartTime(pageStartTime time.Time) time.Time {
  431. t, _ := time.ParseInLocation("2006-01-02", setting.RadarMap.GrowthBeginTime, time.Local)
  432. t = t.UTC()
  433. if pageStartTime.Before(t) {
  434. pageStartTime = t
  435. }
  436. return pageStartTime
  437. }
  438. func QueryUserMetricsCurrentWeek(ctx *context.Context) {
  439. currentTimeNow := time.Now()
  440. offset := int(time.Monday - currentTimeNow.Weekday())
  441. if offset > 0 {
  442. offset = -6
  443. }
  444. pageStartTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 0, 0, 0, time.Local).AddDate(0, 0, offset)
  445. pageStartTime = getStartTime(pageStartTime)
  446. pageEndTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 0, 0, 0, currentTimeNow.Location())
  447. queryMetrics(ctx, "public.user_business_analysis_current_week", pageStartTime, pageEndTime)
  448. }
  449. func QueryUserStaticCurrentWeek(ctx *context.Context) {
  450. queryUserDataPage(ctx, "public.user_business_analysis_current_week", new(models.UserBusinessAnalysisCurrentWeek))
  451. }
  452. func QueryUserStaticLastWeek(ctx *context.Context) {
  453. queryUserDataPage(ctx, "public.user_business_analysis_last_week", new(models.UserBusinessAnalysisLastWeek))
  454. }
  455. func QueryUserMetricsCurrentYear(ctx *context.Context) {
  456. currentTimeNow := time.Now()
  457. pageStartTime := time.Date(currentTimeNow.Year(), 1, 1, 0, 0, 0, 0, currentTimeNow.Location())
  458. pageStartTime = getStartTime(pageStartTime)
  459. pageEndTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 0, 0, 0, currentTimeNow.Location())
  460. queryMetrics(ctx, "public.user_business_analysis_current_year", pageStartTime, pageEndTime)
  461. }
  462. func QueryUserStaticCurrentYear(ctx *context.Context) {
  463. queryUserDataPage(ctx, "public.user_business_analysis_current_year", new(models.UserBusinessAnalysisCurrentYear))
  464. }
  465. func QueryUserMetricsLast30Day(ctx *context.Context) {
  466. currentTimeNow := time.Now()
  467. pageStartTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 0, 0, 0, time.Local).AddDate(0, 0, -30)
  468. pageStartTime = getStartTime(pageStartTime)
  469. pageEndTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 0, 0, 0, currentTimeNow.Location())
  470. queryMetrics(ctx, "public.user_business_analysis_last30_day", pageStartTime, pageEndTime)
  471. }
  472. func QueryUserStaticLast30Day(ctx *context.Context) {
  473. queryUserDataPage(ctx, "public.user_business_analysis_last30_day", new(models.UserBusinessAnalysisLast30Day))
  474. }
  475. func QueryUserMetricsLastMonth(ctx *context.Context) {
  476. currentTimeNow := time.Now()
  477. thisMonth := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), 1, 0, 0, 0, 0, currentTimeNow.Location())
  478. pageStartTime := thisMonth.AddDate(0, -1, 0)
  479. pageStartTime = getStartTime(pageStartTime)
  480. pageEndTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), 1, 23, 59, 59, 0, currentTimeNow.Location()).AddDate(0, 0, -1)
  481. queryMetrics(ctx, "public.user_business_analysis_last_month", pageStartTime, pageEndTime)
  482. }
  483. func QueryUserStaticLastMonth(ctx *context.Context) {
  484. queryUserDataPage(ctx, "public.user_business_analysis_last_month", new(models.UserBusinessAnalysisLastMonth))
  485. }
  486. func QueryUserMetricsYesterday(ctx *context.Context) {
  487. currentTimeNow := time.Now().AddDate(0, 0, -1)
  488. pageStartTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 0, 0, 0, time.Local)
  489. pageStartTime = getStartTime(pageStartTime)
  490. pageEndTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 23, 59, 59, 0, currentTimeNow.Location())
  491. queryMetrics(ctx, "public.user_business_analysis_yesterday", pageStartTime, pageEndTime)
  492. }
  493. func QueryUserStaticYesterday(ctx *context.Context) {
  494. queryUserDataPage(ctx, "public.user_business_analysis_yesterday", new(models.UserBusinessAnalysisYesterday))
  495. }
  496. func QueryUserMetricsAll(ctx *context.Context) {
  497. currentTimeNow := time.Now()
  498. pageStartTime := time.Date(2022, 4, 5, 0, 0, 0, 0, currentTimeNow.Location())
  499. pageStartTime = getStartTime(pageStartTime)
  500. pageEndTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 0, 0, 0, currentTimeNow.Location())
  501. queryMetrics(ctx, "public.user_business_analysis_all", pageStartTime, pageEndTime)
  502. }
  503. func QueryUserStaticAll(ctx *context.Context) {
  504. queryUserDataPage(ctx, "public.user_business_analysis_all", new(models.UserBusinessAnalysisAll))
  505. }
  506. func QueryUserMetricDataPage(ctx *context.Context) {
  507. startDate := ctx.Query("startDate")
  508. endDate := ctx.Query("endDate")
  509. startTime, _ := time.ParseInLocation("2006-01-02", startDate, time.Local)
  510. startTime = startTime.UTC()
  511. endTime, _ := time.ParseInLocation("2006-01-02", endDate, time.Local)
  512. startTime = getStartTime(startTime)
  513. queryMetrics(ctx, "", startTime, endTime)
  514. }
  515. func QueryUserStaticDataPage(ctx *context.Context) {
  516. startDate := ctx.Query("startDate")
  517. endDate := ctx.Query("endDate")
  518. page := ctx.QueryInt("page")
  519. if page <= 0 {
  520. page = 1
  521. }
  522. pageSize := ctx.QueryInt("pageSize")
  523. if pageSize <= 0 {
  524. pageSize = setting.UI.IssuePagingNum
  525. }
  526. userName := ctx.Query("userName")
  527. IsReturnFile := ctx.QueryBool("IsReturnFile")
  528. log.Info("startDate=" + startDate + " endDate=" + endDate + " userName=" + userName + " page=" + fmt.Sprint(page))
  529. var startTime time.Time
  530. var endTime time.Time
  531. var isAll bool
  532. if startDate == "all" {
  533. isAll = true
  534. startTime = time.Now()
  535. endTime = time.Now()
  536. } else {
  537. startTime, _ = time.ParseInLocation("2006-01-02", startDate, time.Local)
  538. startTime = time.Date(startTime.Year(), startTime.Month(), startTime.Day(), 0, 0, 0, 0, startTime.Location())
  539. settingStartTime, _ := time.Parse("2006-01-02", setting.RadarMap.RecordBeginTime)
  540. if startTime.Unix() < settingStartTime.Unix() {
  541. startTime = settingStartTime
  542. startDate = settingStartTime.Format("2006-01-02")
  543. }
  544. endTime, _ = time.ParseInLocation("2006-01-02", endDate, time.Local)
  545. endTime = time.Date(endTime.Year(), endTime.Month(), endTime.Day(), 23, 59, 59, 0, startTime.Location())
  546. isAll = false
  547. log.Info("startTime=" + fmt.Sprint(startTime.Unix()) + " endDate=" + fmt.Sprint(endTime.Unix()))
  548. }
  549. if IsReturnFile {
  550. page = -1
  551. pageSize = -1
  552. }
  553. pageOpts := &models.UserBusinessAnalysisQueryOptions{
  554. ListOptions: models.ListOptions{
  555. Page: page,
  556. PageSize: pageSize,
  557. },
  558. UserName: userName,
  559. StartTime: startTime.Unix(),
  560. EndTime: endTime.Unix(),
  561. IsAll: isAll,
  562. }
  563. if IsReturnFile {
  564. //re, count := models.QueryUserStaticDataAll(pageOpts)
  565. wikiMap, _ := queryWikiCountMap(startTime, endTime)
  566. re, count := models.QueryUserStaticDataForUserDefine(pageOpts, wikiMap)
  567. sheetName := ctx.Tr("user.static.sheetname")
  568. filename := sheetName + "_" + startDate + "_" + endDate + ".xlsx"
  569. os.Remove(setting.AppDataPath + Excel_File_Path + filename)
  570. go writeFileToDisk(ctx, count, re, filename)
  571. ctx.JSON(http.StatusOK, ctx.Tr("user.static.downloadinfo")+"/api/v1/download_user_define_file?filename="+filename)
  572. } else {
  573. mapInterface := make(map[string]interface{})
  574. key := startTime.Format("2006-01-02") + endTime.Format("2006-01-02")
  575. log.Info("db key =" + key)
  576. re, count := models.QueryDataForUserDefineFromDb(pageOpts, key)
  577. if count == 0 {
  578. wikiMap, _ := queryWikiCountMap(startTime, endTime)
  579. re, count = models.QueryUserStaticDataForUserDefine(pageOpts, wikiMap)
  580. models.WriteDataToDb(re, key)
  581. }
  582. re, count = models.QueryDataForUserDefineFromDb(pageOpts, key)
  583. mapInterface["data"] = re
  584. mapInterface["count"] = count
  585. ctx.JSON(http.StatusOK, mapInterface)
  586. }
  587. }
  588. func writeFileToDisk(ctx *context.Context, count int64, re []*models.UserBusinessAnalysis, filename string) {
  589. log.Info("return count=" + fmt.Sprint(count))
  590. //writer exec file.
  591. xlsx := excelize.NewFile()
  592. sheetName := ctx.Tr("user.static.sheetname")
  593. index := xlsx.NewSheet(sheetName)
  594. xlsx.DeleteSheet("Sheet1")
  595. dataHeader := getExcelHeader(ctx)
  596. for k, v := range dataHeader {
  597. //设置单元格的值
  598. xlsx.SetCellValue(sheetName, k, v)
  599. }
  600. for i, userRecord := range re {
  601. row := i + 2
  602. writeExcelPage(row, xlsx, sheetName, userRecord)
  603. }
  604. //设置默认打开的表单
  605. xlsx.SetActiveSheet(index)
  606. //ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+url.QueryEscape(filename))
  607. //ctx.Resp.Header().Set("Content-Type", "application/octet-stream")
  608. filename = setting.AppDataPath + Excel_File_Path + filename
  609. os.Mkdir(setting.AppDataPath+Excel_File_Path, 0755)
  610. if err := xlsx.SaveAs(filename); err != nil {
  611. log.Info("writer exel error." + err.Error())
  612. } else {
  613. log.Info("write to file succeed, filepath=" + filename)
  614. }
  615. }
  616. func queryWikiCountMap(startTime time.Time, endTime time.Time) (map[string]int, error) {
  617. wikiMap := make(map[string]int)
  618. warnEmailMessage := "用户统计信息入库失败,请尽快定位。"
  619. repoList, err := models.GetAllRepositories()
  620. if err != nil {
  621. log.Error("query repo error." + err.Error())
  622. mailer.SendWarnNotifyMail(setting.Warn_Notify_Mails, warnEmailMessage)
  623. return nil, err
  624. }
  625. log.Info("start to query wiki data")
  626. for _, repoRecord := range repoList {
  627. wikiPath := models.WikiPath(repoRecord.OwnerName, repoRecord.Name)
  628. time, err := git.GetLatestCommitTime(wikiPath)
  629. if err == nil {
  630. log.Info("last commit time:" + time.Format("2006-01-02 15:04:05") + " wikiPath=" + wikiPath)
  631. if time.After(startTime) && time.Before(endTime) {
  632. wikiRepo, _, err := FindWikiRepoCommitByWikiPath(wikiPath)
  633. if err != nil {
  634. log.Error("wiki not exist. wikiPath=" + wikiPath)
  635. } else {
  636. log.Info("wiki exist, wikiPath=" + wikiPath)
  637. list, err := wikiRepo.GetCommitByPathAndDays(wikiPath, 1)
  638. if err != nil {
  639. log.Info("err,err=v%", err)
  640. } else {
  641. for logEntry := list.Front(); logEntry != nil; logEntry = logEntry.Next() {
  642. commit := logEntry.Value.(*git.Commit)
  643. log.Info("commit msg=" + commit.CommitMessage + " time=" + commit.Committer.When.Format("2006-01-02 15:04:05") + " user=" + commit.Committer.Name)
  644. if _, ok := wikiMap[commit.Committer.Name]; !ok {
  645. wikiMap[commit.Committer.Name] = 1
  646. } else {
  647. wikiMap[commit.Committer.Name] += 1
  648. }
  649. }
  650. }
  651. }
  652. }
  653. }
  654. }
  655. return wikiMap, nil
  656. }
  657. func TimingCountDataByDateAndReCount(date string, isReCount bool) {
  658. t, _ := time.Parse("2006-01-02", date)
  659. startTime := time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location())
  660. startTime = startTime.UTC()
  661. endTime := time.Date(t.Year(), t.Month(), t.Day(), 23, 59, 59, 0, t.Location())
  662. endTime = endTime.UTC()
  663. log.Info("startTime time:" + startTime.Format("2006-01-02 15:04:05"))
  664. log.Info("endTime time:" + endTime.Format("2006-01-02 15:04:05"))
  665. warnEmailMessage := "用户统计信息入库失败,请尽快定位。"
  666. //query wiki data
  667. log.Info("start to time count data")
  668. wikiMap, err := queryWikiCountMap(startTime, endTime)
  669. //other user info data
  670. err = models.CounDataByDateAndReCount(wikiMap, startTime, endTime, isReCount)
  671. if err != nil {
  672. log.Error("count user info error." + err.Error())
  673. mailer.SendWarnNotifyMail(setting.Warn_Notify_Mails, warnEmailMessage)
  674. }
  675. log.Info("end to count all user info data")
  676. }
  677. func TimingCountDataByDate(date string) {
  678. TimingCountDataByDateAndReCount(date, true)
  679. }
  680. func TimingCountData() {
  681. log.Info("start to time count data")
  682. currentTimeNow := time.Now()
  683. log.Info("current time:" + currentTimeNow.Format("2006-01-02 15:04:05"))
  684. startTime := currentTimeNow.AddDate(0, 0, -1).Format("2006-01-02")
  685. TimingCountDataByDateAndReCount(startTime, false)
  686. }
  687. func QueryUserActivity(ctx *context.Context) {
  688. startDate := ctx.Query("beginTime")
  689. endDate := ctx.Query("endTime")
  690. t, _ := time.Parse("2006-01-02", startDate)
  691. startTime := time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location())
  692. startTime = startTime.UTC()
  693. t, _ = time.Parse("2006-01-02", endDate)
  694. endTime := time.Date(t.Year(), t.Month(), t.Day(), 23, 59, 59, 0, t.Location())
  695. endTime = endTime.UTC()
  696. sheetName := ctx.Tr("user.static.sheetname")
  697. filename := sheetName + "_" + startDate + "_" + endDate + ".xlsx"
  698. filePath := setting.AppDataPath + Excel_File_Path + filename
  699. os.Remove(setting.AppDataPath + Excel_File_Path + filename)
  700. go writeUserActivityToExcel(startTime, endTime, filePath, ctx)
  701. ctx.JSON(http.StatusOK, ctx.Tr("user.static.downloadinfo")+"/api/v1/download_user_define_file?filename="+filename)
  702. }
  703. func writeUserActivityToExcel(startTime time.Time, endTime time.Time, filePath string, ctx *context.Context) {
  704. re := models.QueryDataForActivity(startTime, endTime)
  705. log.Info("return count=" + fmt.Sprint(len(re)))
  706. //writer exec file.
  707. xlsx := excelize.NewFile()
  708. sheetName := ctx.Tr("user.static.sheetname")
  709. index := xlsx.NewSheet(sheetName)
  710. xlsx.DeleteSheet("Sheet1")
  711. excelHeader := make([]string, 0)
  712. excelHeader = append(excelHeader, ctx.Tr("user.static.id"))
  713. excelHeader = append(excelHeader, ctx.Tr("user.static.name"))
  714. excelHeader = append(excelHeader, ctx.Tr("user.static.codemergecount"))
  715. excelHeader = append(excelHeader, ctx.Tr("user.static.commitcount"))
  716. excelHeader = append(excelHeader, ctx.Tr("user.static.issuecount"))
  717. excelHeader = append(excelHeader, ctx.Tr("user.static.commentcount"))
  718. excelHeader = append(excelHeader, ctx.Tr("user.static.watchedcount"))
  719. excelHeader = append(excelHeader, ctx.Tr("user.static.commitcodesize"))
  720. excelHeader = append(excelHeader, ctx.Tr("user.static.solveissuecount"))
  721. excelHeader = append(excelHeader, ctx.Tr("user.static.CommitDatasetNum"))
  722. excelHeader = append(excelHeader, ctx.Tr("user.static.CommitModelCount"))
  723. excelHeader = append(excelHeader, ctx.Tr("user.static.email"))
  724. excelHeader = append(excelHeader, ctx.Tr("user.static.phone"))
  725. excelHeader = append(excelHeader, ctx.Tr("user.static.registdate"))
  726. excelHeaderMap := make(map[string]string, 0)
  727. var j byte
  728. j = 0
  729. for _, value := range excelHeader {
  730. excelColumn := getColumn(j) + fmt.Sprint(1)
  731. log.Info("excelColumn=" + excelColumn)
  732. excelHeaderMap[excelColumn] = value
  733. j++
  734. }
  735. for k, v := range excelHeaderMap {
  736. //设置单元格的值
  737. xlsx.SetCellValue(sheetName, k, v)
  738. }
  739. for i, userRecord := range re {
  740. row := i + 2
  741. rows := fmt.Sprint(row)
  742. var tmp byte
  743. tmp = 0
  744. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.ID)
  745. tmp = tmp + 1
  746. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.Name)
  747. tmp = tmp + 1
  748. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.CodeMergeCount)
  749. tmp = tmp + 1
  750. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.CommitCount)
  751. tmp = tmp + 1
  752. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.IssueCount)
  753. tmp = tmp + 1
  754. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.CommentCount)
  755. tmp = tmp + 1
  756. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.WatchedCount)
  757. tmp = tmp + 1
  758. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.CommitCodeSize)
  759. tmp = tmp + 1
  760. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.SolveIssueCount)
  761. tmp = tmp + 1
  762. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.CommitDatasetNum)
  763. tmp = tmp + 1
  764. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.CommitModelCount)
  765. tmp = tmp + 1
  766. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.Email)
  767. tmp = tmp + 1
  768. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userRecord.Phone)
  769. tmp = tmp + 1
  770. formatTime := userRecord.RegistDate.Format("2006-01-02 15:04:05")
  771. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, formatTime[0:len(formatTime)-3])
  772. tmp = tmp + 1
  773. }
  774. //设置默认打开的表单
  775. xlsx.SetActiveSheet(index)
  776. os.Mkdir(setting.AppDataPath+Excel_File_Path, 0755)
  777. if err := xlsx.SaveAs(filePath); err != nil {
  778. log.Info("writer exel error." + err.Error())
  779. } else {
  780. log.Info("write to file succeed, filepath=" + filePath)
  781. }
  782. }
  783. // URL: /api/v1/query_user_login?userId=1,2,3,4
  784. func QueryUserLoginInfo(ctx *context.Context) {
  785. userId := ctx.Query("userId")
  786. userIds := strings.Split(userId, ",")
  787. userIdInt := make([]int64, 0)
  788. for _, id := range userIds {
  789. idInt, err := strconv.ParseInt(id, 10, 64)
  790. if err == nil {
  791. userIdInt = append(userIdInt, idInt)
  792. }
  793. }
  794. result := models.QueryUserLoginInfo(userIdInt)
  795. xlsx := excelize.NewFile()
  796. sheetName := ctx.Tr("用户登录信息")
  797. index := xlsx.NewSheet(sheetName)
  798. xlsx.DeleteSheet("Sheet1")
  799. excelHeader := make([]string, 0)
  800. excelHeader = append(excelHeader, "用户ID")
  801. excelHeader = append(excelHeader, "登录IP")
  802. excelHeader = append(excelHeader, "登录时间")
  803. excelHeaderMap := make(map[string]string, 0)
  804. var j byte
  805. j = 0
  806. for _, value := range excelHeader {
  807. excelColumn := getColumn(j) + fmt.Sprint(1)
  808. log.Info("excelColumn=" + excelColumn)
  809. excelHeaderMap[excelColumn] = value
  810. j++
  811. }
  812. for k, v := range excelHeaderMap {
  813. //设置单元格的值
  814. xlsx.SetCellValue(sheetName, k, v)
  815. }
  816. for i, userLogin := range result {
  817. row := i + 2
  818. rows := fmt.Sprint(row)
  819. var tmp byte
  820. tmp = 0
  821. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userLogin.UId)
  822. tmp = tmp + 1
  823. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userLogin.IpAddr)
  824. tmp = tmp + 1
  825. formatTime := userLogin.CreatedUnix.Format("2006-01-02 15:04:05")
  826. xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, formatTime)
  827. }
  828. //设置默认打开的表单
  829. xlsx.SetActiveSheet(index)
  830. filename := sheetName + "_" + time.Now().Format("2006-01-02 15:04:05") + ".xlsx"
  831. ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+url.QueryEscape(filename))
  832. ctx.Resp.Header().Set("Content-Type", "application/octet-stream")
  833. if _, err := xlsx.WriteTo(ctx.Resp); err != nil {
  834. log.Info("writer exel error." + err.Error())
  835. }
  836. }
  837. func QueryUserAnnualReport(ctx *context.Context) {
  838. log.Info("start to QueryUserAnnualReport ")
  839. result := models.QueryUserAnnualReport(ctx.User.ID)
  840. ctx.JSON(http.StatusOK, result)
  841. }