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_business_analysis.go 35 kB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166
  1. package models
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "sort"
  6. "strconv"
  7. "time"
  8. "code.gitea.io/gitea/modules/git"
  9. "code.gitea.io/gitea/modules/log"
  10. "code.gitea.io/gitea/modules/timeutil"
  11. "xorm.io/builder"
  12. )
  13. const (
  14. Page_SIZE = 2000
  15. )
  16. type UserBusinessAnalysisAll struct {
  17. ID int64 `xorm:"pk"`
  18. CountDate int64 `xorm:"pk"`
  19. //action :ActionMergePullRequest // 11
  20. CodeMergeCount int `xorm:"NOT NULL DEFAULT 0"`
  21. //action :ActionCommitRepo // 5
  22. CommitCount int `xorm:"NOT NULL DEFAULT 0"`
  23. //action :ActionCreateIssue // 10
  24. IssueCount int `xorm:"NOT NULL DEFAULT 0"`
  25. //comment table current date
  26. CommentCount int `xorm:"NOT NULL DEFAULT 0"`
  27. //watch table current date
  28. FocusRepoCount int `xorm:"NOT NULL DEFAULT 0"`
  29. //star table current date
  30. StarRepoCount int `xorm:"NOT NULL DEFAULT 0"`
  31. //follow table
  32. WatchedCount int `xorm:"NOT NULL DEFAULT 0"`
  33. // user table
  34. GiteaAgeMonth int `xorm:"NOT NULL DEFAULT 0"`
  35. //
  36. CommitCodeSize int `xorm:"NOT NULL DEFAULT 0"`
  37. //attachement table
  38. CommitDatasetSize int `xorm:"NOT NULL DEFAULT 0"`
  39. //0
  40. CommitModelCount int `xorm:"NOT NULL DEFAULT 0"`
  41. //issue, issueassignees
  42. SolveIssueCount int `xorm:"NOT NULL DEFAULT 0"`
  43. //baike
  44. EncyclopediasCount int `xorm:"NOT NULL DEFAULT 0"`
  45. //user
  46. RegistDate timeutil.TimeStamp `xorm:"NOT NULL"`
  47. //repo
  48. CreateRepoCount int `xorm:"NOT NULL DEFAULT 0"`
  49. //login count, from elk
  50. LoginCount int `xorm:"NOT NULL DEFAULT 0"`
  51. //openi index
  52. OpenIIndex float64 `xorm:"NOT NULL DEFAULT 0"`
  53. //user
  54. Email string `xorm:"NOT NULL"`
  55. //user
  56. Name string `xorm:"NOT NULL"`
  57. DataDate string `xorm:"NULL"`
  58. }
  59. type UserBusinessAnalysis struct {
  60. ID int64 `xorm:"pk"`
  61. CountDate int64 `xorm:"pk"`
  62. //action :ActionMergePullRequest // 11
  63. CodeMergeCount int `xorm:"NOT NULL DEFAULT 0"`
  64. //action :ActionCommitRepo // 5
  65. CommitCount int `xorm:"NOT NULL DEFAULT 0"`
  66. //action :ActionCreateIssue // 6
  67. IssueCount int `xorm:"NOT NULL DEFAULT 0"`
  68. //comment table current date
  69. CommentCount int `xorm:"NOT NULL DEFAULT 0"`
  70. //watch table current date
  71. FocusRepoCount int `xorm:"NOT NULL DEFAULT 0"`
  72. //star table current date
  73. StarRepoCount int `xorm:"NOT NULL DEFAULT 0"`
  74. //follow table
  75. WatchedCount int `xorm:"NOT NULL DEFAULT 0"`
  76. // user table
  77. GiteaAgeMonth int `xorm:"NOT NULL DEFAULT 0"`
  78. //
  79. CommitCodeSize int `xorm:"NOT NULL DEFAULT 0"`
  80. //attachement table
  81. CommitDatasetSize int `xorm:"NOT NULL DEFAULT 0"`
  82. //0
  83. CommitModelCount int `xorm:"NOT NULL DEFAULT 0"`
  84. //issue, issueassignees
  85. SolveIssueCount int `xorm:"NOT NULL DEFAULT 0"`
  86. //baike
  87. EncyclopediasCount int `xorm:"NOT NULL DEFAULT 0"`
  88. //user
  89. RegistDate timeutil.TimeStamp `xorm:"NOT NULL"`
  90. //repo
  91. CreateRepoCount int `xorm:"NOT NULL DEFAULT 0"`
  92. //login count, from elk
  93. LoginCount int `xorm:"NOT NULL DEFAULT 0"`
  94. //openi index
  95. OpenIIndex float64 `xorm:"NOT NULL DEFAULT 0"`
  96. //user
  97. Email string `xorm:"NOT NULL"`
  98. //user
  99. Name string `xorm:"NOT NULL"`
  100. DataDate string `xorm:"NULL"`
  101. }
  102. type UserBusinessAnalysisQueryOptions struct {
  103. ListOptions
  104. UserName string
  105. SortType string
  106. StartTime int64
  107. EndTime int64
  108. IsAll bool
  109. }
  110. type UserBusinessAnalysisList []*UserBusinessAnalysis
  111. func (ulist UserBusinessAnalysisList) Swap(i, j int) { ulist[i], ulist[j] = ulist[j], ulist[i] }
  112. func (ulist UserBusinessAnalysisList) Len() int { return len(ulist) }
  113. func (ulist UserBusinessAnalysisList) Less(i, j int) bool {
  114. return ulist[i].ID > ulist[j].ID
  115. }
  116. type UserBusinessAnalysisAllList []*UserBusinessAnalysisAll
  117. func (ulist UserBusinessAnalysisAllList) Swap(i, j int) { ulist[i], ulist[j] = ulist[j], ulist[i] }
  118. func (ulist UserBusinessAnalysisAllList) Len() int { return len(ulist) }
  119. func (ulist UserBusinessAnalysisAllList) Less(i, j int) bool {
  120. return ulist[i].ID > ulist[j].ID
  121. }
  122. func getLastCountDate() int64 {
  123. statictisSess := xStatistic.NewSession()
  124. defer statictisSess.Close()
  125. statictisSess.Limit(1, 0)
  126. userBusinessAnalysisList := make([]*UserBusinessAnalysis, 0)
  127. if err := statictisSess.Table("user_business_analysis").OrderBy("count_date desc").Limit(1, 0).
  128. Find(&userBusinessAnalysisList); err == nil {
  129. for _, userRecord := range userBusinessAnalysisList {
  130. return userRecord.CountDate - 10000
  131. }
  132. } else {
  133. log.Info("query error." + err.Error())
  134. }
  135. currentTimeNow := time.Now()
  136. pageStartTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 0, 0, 0, currentTimeNow.Location())
  137. return pageStartTime.Unix()
  138. }
  139. func QueryUserStaticDataAll(opts *UserBusinessAnalysisQueryOptions) ([]*UserBusinessAnalysisAll, int64) {
  140. log.Info("query startTime =" + fmt.Sprint(opts.StartTime) + " endTime=" + fmt.Sprint(opts.EndTime) + " isAll=" + fmt.Sprint(opts.IsAll))
  141. statictisSess := xStatistic.NewSession()
  142. defer statictisSess.Close()
  143. allCount, err := statictisSess.Count(new(UserBusinessAnalysisAll))
  144. if err != nil {
  145. log.Info("query error." + err.Error())
  146. return nil, 0
  147. }
  148. log.Info("query return total:" + fmt.Sprint(allCount))
  149. if allCount == 0 {
  150. CommitCodeSizeMap, err := GetAllUserKPIStats()
  151. if err != nil {
  152. log.Info("query commit code errr.")
  153. } else {
  154. log.Info("query commit code size, len=" + fmt.Sprint(len(CommitCodeSizeMap)))
  155. }
  156. RefreshUserStaticAllTabel(make(map[string]int), CommitCodeSizeMap)
  157. }
  158. pageSize := 1000
  159. totalPage := int(allCount) / pageSize
  160. userBusinessAnalysisReturnList := UserBusinessAnalysisAllList{}
  161. for i := 0; i <= int(totalPage); i++ {
  162. userBusinessAnalysisAllList := make([]*UserBusinessAnalysisAll, 0)
  163. if err := statictisSess.Table("user_business_analysis_all").OrderBy("id desc").Limit(pageSize, i*pageSize).
  164. Find(&userBusinessAnalysisAllList); err != nil {
  165. return nil, 0
  166. }
  167. log.Info("query " + fmt.Sprint(i+1) + " result size=" + fmt.Sprint(len(userBusinessAnalysisAllList)))
  168. for _, userRecord := range userBusinessAnalysisAllList {
  169. userBusinessAnalysisReturnList = append(userBusinessAnalysisReturnList, userRecord)
  170. }
  171. }
  172. sort.Sort(userBusinessAnalysisReturnList)
  173. log.Info("return size=" + fmt.Sprint(len(userBusinessAnalysisReturnList)))
  174. return userBusinessAnalysisReturnList, allCount
  175. }
  176. func QueryUserStaticDataPage(opts *UserBusinessAnalysisQueryOptions) ([]*UserBusinessAnalysis, int64) {
  177. log.Info("query startTime =" + fmt.Sprint(opts.StartTime) + " endTime=" + fmt.Sprint(opts.EndTime) + " isAll=" + fmt.Sprint(opts.IsAll))
  178. statictisSess := xStatistic.NewSession()
  179. defer statictisSess.Close()
  180. currentTimeNow := time.Now()
  181. pageStartTime := getLastCountDate()
  182. pageEndTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 23, 59, 59, 0, currentTimeNow.Location()).Unix()
  183. var cond = builder.NewCond()
  184. if len(opts.UserName) > 0 {
  185. cond = cond.And(
  186. builder.Like{"name", opts.UserName},
  187. )
  188. }
  189. cond = cond.And(
  190. builder.Gte{"count_date": pageStartTime},
  191. )
  192. cond = cond.And(
  193. builder.Lte{"count_date": pageEndTime},
  194. )
  195. count, err := statictisSess.Where(cond).Count(new(UserBusinessAnalysis))
  196. if err != nil {
  197. log.Info("query error." + err.Error())
  198. return nil, 0
  199. }
  200. if opts.Page >= 0 && opts.PageSize > 0 {
  201. var start int
  202. if opts.Page == 0 {
  203. start = 0
  204. } else {
  205. start = (opts.Page - 1) * opts.PageSize
  206. }
  207. statictisSess.Limit(opts.PageSize, start)
  208. }
  209. userBusinessAnalysisList := make([]*UserBusinessAnalysis, 0)
  210. if err := statictisSess.Table("user_business_analysis").Where(cond).OrderBy("id desc").
  211. Find(&userBusinessAnalysisList); err != nil {
  212. return nil, 0
  213. }
  214. resultMap := make(map[int64]*UserBusinessAnalysis)
  215. if len(userBusinessAnalysisList) > 0 {
  216. var newAndCond = builder.NewCond()
  217. var newOrCond = builder.NewCond()
  218. for _, userRecord := range userBusinessAnalysisList {
  219. newOrCond = newOrCond.Or(
  220. builder.Eq{"id": userRecord.ID},
  221. )
  222. }
  223. newAndCond = newAndCond.And(
  224. newOrCond,
  225. )
  226. if !opts.IsAll {
  227. newAndCond = newAndCond.And(
  228. builder.Gte{"count_date": opts.StartTime},
  229. )
  230. newAndCond = newAndCond.And(
  231. builder.Lte{"count_date": opts.EndTime},
  232. )
  233. }
  234. allCount, err := statictisSess.Where(newAndCond).Count(new(UserBusinessAnalysis))
  235. if err != nil {
  236. log.Info("query error." + err.Error())
  237. return nil, 0
  238. }
  239. pageSize := 1000
  240. totalPage := int(allCount) / pageSize
  241. for i := 0; i <= int(totalPage); i++ {
  242. userBusinessAnalysisList = make([]*UserBusinessAnalysis, 0)
  243. if err := statictisSess.Table("user_business_analysis").Where(newAndCond).OrderBy("count_date desc").Limit(pageSize, i*pageSize).
  244. Find(&userBusinessAnalysisList); err != nil {
  245. return nil, 0
  246. }
  247. log.Info("query result size=" + fmt.Sprint(len(userBusinessAnalysisList)))
  248. for _, userRecord := range userBusinessAnalysisList {
  249. if _, ok := resultMap[userRecord.ID]; !ok {
  250. resultMap[userRecord.ID] = userRecord
  251. } else {
  252. resultMap[userRecord.ID].CodeMergeCount += userRecord.CodeMergeCount
  253. resultMap[userRecord.ID].CommitCount += userRecord.CommitCount
  254. resultMap[userRecord.ID].IssueCount += userRecord.IssueCount
  255. resultMap[userRecord.ID].CommentCount += userRecord.CommentCount
  256. resultMap[userRecord.ID].FocusRepoCount += userRecord.FocusRepoCount
  257. resultMap[userRecord.ID].StarRepoCount += userRecord.StarRepoCount
  258. resultMap[userRecord.ID].WatchedCount += userRecord.WatchedCount
  259. resultMap[userRecord.ID].CommitCodeSize += userRecord.CommitCodeSize
  260. resultMap[userRecord.ID].CommitDatasetSize += userRecord.CommitDatasetSize
  261. resultMap[userRecord.ID].CommitModelCount += userRecord.CommitModelCount
  262. resultMap[userRecord.ID].SolveIssueCount += userRecord.SolveIssueCount
  263. resultMap[userRecord.ID].EncyclopediasCount += userRecord.EncyclopediasCount
  264. resultMap[userRecord.ID].CreateRepoCount += userRecord.CreateRepoCount
  265. resultMap[userRecord.ID].LoginCount += userRecord.LoginCount
  266. }
  267. }
  268. }
  269. }
  270. userBusinessAnalysisReturnList := UserBusinessAnalysisList{}
  271. for _, v := range resultMap {
  272. userBusinessAnalysisReturnList = append(userBusinessAnalysisReturnList, v)
  273. }
  274. sort.Sort(userBusinessAnalysisReturnList)
  275. log.Info("return size=" + fmt.Sprint(len(userBusinessAnalysisReturnList)))
  276. return userBusinessAnalysisReturnList, count
  277. }
  278. func RefreshUserStaticAllTabel(wikiCountMap map[string]int, CommitCodeSizeMap map[string]*git.UserKPIStats) {
  279. sess := x.NewSession()
  280. defer sess.Close()
  281. statictisSess := xStatistic.NewSession()
  282. defer statictisSess.Close()
  283. log.Info("truncate all data from table: user_business_analysis_all")
  284. statictisSess.Exec("TRUNCATE TABLE user_business_analysis_all")
  285. currentTimeNow := time.Now()
  286. startTime := currentTimeNow.AddDate(0, 0, -1)
  287. pageStartTime := time.Date(2021, 11, 5, 0, 0, 0, 0, currentTimeNow.Location())
  288. log.Info("pageStartTime:" + pageStartTime.Format("2006-01-02 15:04:05"))
  289. pageEndTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 23, 59, 59, 0, currentTimeNow.Location())
  290. log.Info("pageEndTime time:" + pageEndTime.Format("2006-01-02 15:04:05"))
  291. start_unix := pageStartTime.Unix()
  292. end_unix := pageEndTime.Unix()
  293. CodeMergeCountMap := queryPullRequest(start_unix, end_unix)
  294. CommitCountMap := queryCommitAction(start_unix, end_unix, 5)
  295. IssueCountMap := queryAction(start_unix, end_unix, 6)
  296. CommentCountMap := queryComment(start_unix, end_unix)
  297. FocusRepoCountMap := queryWatch(start_unix, end_unix)
  298. StarRepoCountMap := queryStar(start_unix, end_unix)
  299. WatchedCountMap := queryFollow(start_unix, end_unix)
  300. CommitDatasetSizeMap := queryDatasetSize(start_unix, end_unix)
  301. SolveIssueCountMap := querySolveIssue(start_unix, end_unix)
  302. CreateRepoCountMap := queryUserCreateRepo(start_unix, end_unix)
  303. LoginCountMap := queryLoginCount(start_unix, end_unix)
  304. OpenIIndexMap := queryUserRepoOpenIIndex(startTime.Unix(), end_unix)
  305. DataDate := currentTimeNow.Format("2006-01-02")
  306. cond := "type != 1 and is_active=true"
  307. count, err := sess.Where(cond).Count(new(User))
  308. if err != nil {
  309. log.Info("query user error. return.")
  310. return
  311. }
  312. var indexTotal int64
  313. indexTotal = 0
  314. for {
  315. sess.Select("`user`.*").Table("user").Where(cond).Limit(Page_SIZE, int(indexTotal))
  316. userList := make([]*User, 0)
  317. sess.Find(&userList)
  318. for i, userRecord := range userList {
  319. log.Info("insert all static, i=" + fmt.Sprint(i) + " userName=" + userRecord.Name)
  320. var dateRecordAll UserBusinessAnalysisAll
  321. dateRecordAll.ID = userRecord.ID
  322. dateRecordAll.Email = userRecord.Email
  323. dateRecordAll.RegistDate = userRecord.CreatedUnix
  324. dateRecordAll.Name = userRecord.Name
  325. dateRecordAll.GiteaAgeMonth = subMonth(currentTimeNow, userRecord.CreatedUnix.AsTime())
  326. dateRecordAll.DataDate = DataDate
  327. if _, ok := CodeMergeCountMap[dateRecordAll.ID]; !ok {
  328. dateRecordAll.CodeMergeCount = 0
  329. } else {
  330. dateRecordAll.CodeMergeCount = CodeMergeCountMap[dateRecordAll.ID]
  331. }
  332. if _, ok := CommitCountMap[dateRecordAll.ID]; !ok {
  333. dateRecordAll.CommitCount = 0
  334. } else {
  335. dateRecordAll.CommitCount = CommitCountMap[dateRecordAll.ID]
  336. }
  337. if _, ok := IssueCountMap[dateRecordAll.ID]; !ok {
  338. dateRecordAll.IssueCount = 0
  339. } else {
  340. dateRecordAll.IssueCount = IssueCountMap[dateRecordAll.ID]
  341. }
  342. if _, ok := CommentCountMap[dateRecordAll.ID]; !ok {
  343. dateRecordAll.CommentCount = 0
  344. } else {
  345. dateRecordAll.CommentCount = CommentCountMap[dateRecordAll.ID]
  346. }
  347. if _, ok := FocusRepoCountMap[dateRecordAll.ID]; !ok {
  348. dateRecordAll.FocusRepoCount = 0
  349. } else {
  350. dateRecordAll.FocusRepoCount = FocusRepoCountMap[dateRecordAll.ID]
  351. }
  352. if _, ok := StarRepoCountMap[dateRecordAll.ID]; !ok {
  353. dateRecordAll.StarRepoCount = 0
  354. } else {
  355. dateRecordAll.StarRepoCount = StarRepoCountMap[dateRecordAll.ID]
  356. }
  357. if _, ok := WatchedCountMap[dateRecordAll.ID]; !ok {
  358. dateRecordAll.WatchedCount = 0
  359. } else {
  360. dateRecordAll.WatchedCount = WatchedCountMap[dateRecordAll.ID]
  361. }
  362. if _, ok := CommitCodeSizeMap[dateRecordAll.Email]; !ok {
  363. dateRecordAll.CommitCodeSize = 0
  364. } else {
  365. dateRecordAll.CommitCodeSize = int(CommitCodeSizeMap[dateRecordAll.Email].CommitLines)
  366. }
  367. if _, ok := CommitDatasetSizeMap[dateRecordAll.ID]; !ok {
  368. dateRecordAll.CommitDatasetSize = 0
  369. } else {
  370. dateRecordAll.CommitDatasetSize = CommitDatasetSizeMap[dateRecordAll.ID]
  371. }
  372. if _, ok := SolveIssueCountMap[dateRecordAll.ID]; !ok {
  373. dateRecordAll.SolveIssueCount = 0
  374. } else {
  375. dateRecordAll.SolveIssueCount = SolveIssueCountMap[dateRecordAll.ID]
  376. }
  377. if _, ok := wikiCountMap[dateRecordAll.Name]; !ok {
  378. dateRecordAll.EncyclopediasCount = 0
  379. } else {
  380. dateRecordAll.EncyclopediasCount = wikiCountMap[dateRecordAll.Name]
  381. }
  382. if _, ok := CreateRepoCountMap[dateRecordAll.ID]; !ok {
  383. dateRecordAll.CreateRepoCount = 0
  384. } else {
  385. dateRecordAll.CreateRepoCount = CreateRepoCountMap[dateRecordAll.ID]
  386. }
  387. if _, ok := LoginCountMap[dateRecordAll.ID]; !ok {
  388. dateRecordAll.LoginCount = 0
  389. } else {
  390. dateRecordAll.LoginCount = LoginCountMap[dateRecordAll.ID]
  391. }
  392. if _, ok := OpenIIndexMap[dateRecordAll.ID]; !ok {
  393. dateRecordAll.OpenIIndex = 0
  394. } else {
  395. dateRecordAll.OpenIIndex = OpenIIndexMap[dateRecordAll.ID]
  396. }
  397. dateRecordAll.CommitModelCount = 0
  398. _, err = statictisSess.Insert(&dateRecordAll)
  399. if err != nil {
  400. log.Info("insert all data failed." + err.Error())
  401. }
  402. }
  403. indexTotal += Page_SIZE
  404. if indexTotal >= count {
  405. break
  406. }
  407. }
  408. log.Info("refresh all data finished.")
  409. }
  410. func CounDataByDateAndReCount(wikiCountMap map[string]int, startTime time.Time, endTime time.Time, isReCount bool) error {
  411. log.Info("start to count other user info data")
  412. sess := x.NewSession()
  413. defer sess.Close()
  414. currentTimeNow := time.Now()
  415. log.Info("current time:" + currentTimeNow.Format("2006-01-02 15:04:05"))
  416. start_unix := startTime.Unix()
  417. log.Info("DB query time:" + startTime.Format("2006-01-02 15:04:05"))
  418. end_unix := endTime.Unix()
  419. CountDate := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 1, 0, 0, currentTimeNow.Location())
  420. if isReCount {
  421. CountDate = time.Date(startTime.Year(), startTime.Month(), startTime.Day(), 0, 1, 0, 0, currentTimeNow.Location())
  422. }
  423. DataDate := startTime.Format("2006-01-02")
  424. CodeMergeCountMap := queryPullRequest(start_unix, end_unix)
  425. CommitCountMap := queryCommitAction(start_unix, end_unix, 5)
  426. IssueCountMap := queryAction(start_unix, end_unix, 6)
  427. CommentCountMap := queryComment(start_unix, end_unix)
  428. FocusRepoCountMap := queryWatch(start_unix, end_unix)
  429. StarRepoCountMap := queryStar(start_unix, end_unix)
  430. WatchedCountMap := queryFollow(start_unix, end_unix)
  431. CommitCodeSizeMap, err := GetAllUserKPIStats()
  432. if err != nil {
  433. log.Info("query commit code errr.")
  434. } else {
  435. log.Info("query commit code size, len=" + fmt.Sprint(len(CommitCodeSizeMap)))
  436. }
  437. CommitDatasetSizeMap := queryDatasetSize(start_unix, end_unix)
  438. SolveIssueCountMap := querySolveIssue(start_unix, end_unix)
  439. CreateRepoCountMap := queryUserCreateRepo(start_unix, end_unix)
  440. LoginCountMap := queryLoginCount(start_unix, end_unix)
  441. OpenIIndexMap := queryUserRepoOpenIIndex(start_unix, end_unix)
  442. statictisSess := xStatistic.NewSession()
  443. defer statictisSess.Close()
  444. cond := "type != 1 and is_active=true"
  445. count, err := sess.Where(cond).Count(new(User))
  446. if err != nil {
  447. log.Info("query user error. return.")
  448. return err
  449. }
  450. var indexTotal int64
  451. indexTotal = 0
  452. for {
  453. sess.Select("`user`.*").Table("user").Where(cond).Limit(Page_SIZE, int(indexTotal))
  454. userList := make([]*User, 0)
  455. sess.Find(&userList)
  456. for i, userRecord := range userList {
  457. var dateRecord UserBusinessAnalysis
  458. dateRecord.ID = userRecord.ID
  459. log.Info("i=" + fmt.Sprint(i) + " userName=" + userRecord.Name)
  460. dateRecord.CountDate = CountDate.Unix()
  461. statictisSess.Delete(&dateRecord)
  462. dateRecord.Email = userRecord.Email
  463. dateRecord.RegistDate = userRecord.CreatedUnix
  464. dateRecord.Name = userRecord.Name
  465. dateRecord.GiteaAgeMonth = subMonth(currentTimeNow, userRecord.CreatedUnix.AsTime())
  466. dateRecord.DataDate = DataDate
  467. if _, ok := CodeMergeCountMap[dateRecord.ID]; !ok {
  468. dateRecord.CodeMergeCount = 0
  469. } else {
  470. dateRecord.CodeMergeCount = CodeMergeCountMap[dateRecord.ID]
  471. }
  472. if _, ok := CommitCountMap[dateRecord.ID]; !ok {
  473. dateRecord.CommitCount = 0
  474. } else {
  475. dateRecord.CommitCount = CommitCountMap[dateRecord.ID]
  476. }
  477. if _, ok := IssueCountMap[dateRecord.ID]; !ok {
  478. dateRecord.IssueCount = 0
  479. } else {
  480. dateRecord.IssueCount = IssueCountMap[dateRecord.ID]
  481. }
  482. if _, ok := CommentCountMap[dateRecord.ID]; !ok {
  483. dateRecord.CommentCount = 0
  484. } else {
  485. dateRecord.CommentCount = CommentCountMap[dateRecord.ID]
  486. }
  487. if _, ok := FocusRepoCountMap[dateRecord.ID]; !ok {
  488. dateRecord.FocusRepoCount = 0
  489. } else {
  490. dateRecord.FocusRepoCount = FocusRepoCountMap[dateRecord.ID]
  491. }
  492. if _, ok := StarRepoCountMap[dateRecord.ID]; !ok {
  493. dateRecord.StarRepoCount = 0
  494. } else {
  495. dateRecord.StarRepoCount = StarRepoCountMap[dateRecord.ID]
  496. }
  497. if _, ok := WatchedCountMap[dateRecord.ID]; !ok {
  498. dateRecord.WatchedCount = 0
  499. } else {
  500. dateRecord.WatchedCount = WatchedCountMap[dateRecord.ID]
  501. }
  502. if _, ok := CommitCodeSizeMap[dateRecord.Email]; !ok {
  503. dateRecord.CommitCodeSize = 0
  504. } else {
  505. dateRecord.CommitCodeSize = int(CommitCodeSizeMap[dateRecord.Email].CommitLines)
  506. }
  507. if _, ok := CommitDatasetSizeMap[dateRecord.ID]; !ok {
  508. dateRecord.CommitDatasetSize = 0
  509. } else {
  510. dateRecord.CommitDatasetSize = CommitDatasetSizeMap[dateRecord.ID]
  511. }
  512. if _, ok := SolveIssueCountMap[dateRecord.ID]; !ok {
  513. dateRecord.SolveIssueCount = 0
  514. } else {
  515. dateRecord.SolveIssueCount = SolveIssueCountMap[dateRecord.ID]
  516. }
  517. if _, ok := wikiCountMap[dateRecord.Name]; !ok {
  518. dateRecord.EncyclopediasCount = 0
  519. } else {
  520. dateRecord.EncyclopediasCount = wikiCountMap[dateRecord.Name]
  521. }
  522. if _, ok := CreateRepoCountMap[dateRecord.ID]; !ok {
  523. dateRecord.CreateRepoCount = 0
  524. } else {
  525. dateRecord.CreateRepoCount = CreateRepoCountMap[dateRecord.ID]
  526. }
  527. if _, ok := LoginCountMap[dateRecord.ID]; !ok {
  528. dateRecord.LoginCount = 0
  529. } else {
  530. dateRecord.LoginCount = LoginCountMap[dateRecord.ID]
  531. }
  532. if _, ok := OpenIIndexMap[dateRecord.ID]; !ok {
  533. dateRecord.OpenIIndex = 0
  534. } else {
  535. dateRecord.OpenIIndex = OpenIIndexMap[dateRecord.ID]
  536. }
  537. dateRecord.CommitModelCount = 0
  538. _, err = statictisSess.Insert(&dateRecord)
  539. if err != nil {
  540. log.Info("insert daterecord failed." + err.Error())
  541. return err
  542. }
  543. }
  544. indexTotal += Page_SIZE
  545. if indexTotal >= count {
  546. break
  547. }
  548. }
  549. RefreshUserStaticAllTabel(wikiCountMap, CommitCodeSizeMap)
  550. return nil
  551. }
  552. func getInt(str string) int {
  553. re, err := strconv.ParseInt(str, 10, 32)
  554. if err != nil {
  555. return 0
  556. }
  557. return int(re)
  558. }
  559. func CounDataByDate(wikiCountMap map[string]int, startTime time.Time, endTime time.Time) {
  560. CounDataByDateAndReCount(wikiCountMap, startTime, endTime, false)
  561. }
  562. func querySolveIssue(start_unix int64, end_unix int64) map[int64]int {
  563. sess := x.NewSession()
  564. defer sess.Close()
  565. resultMap := make(map[int64]int)
  566. cond := "issue.is_closed=true and issue.closed_unix>=" + fmt.Sprint(start_unix) + " and issue.closed_unix<=" + fmt.Sprint(end_unix)
  567. count, err := sess.Table("issue_assignees").Join("inner", "issue", "issue.id=issue_assignees.issue_id").Where(cond).Count(new(IssueAssignees))
  568. if err != nil {
  569. log.Info("query issue error. return.")
  570. return resultMap
  571. }
  572. var indexTotal int64
  573. indexTotal = 0
  574. for {
  575. issueAssigneesList := make([]*IssueAssignees, 0)
  576. sess.Select("issue_assignees.*").Table("issue_assignees").
  577. Join("inner", "issue", "issue.id=issue_assignees.issue_id").
  578. Where(cond).Limit(Page_SIZE, int(indexTotal))
  579. sess.Find(&issueAssigneesList)
  580. log.Info("query IssueAssignees size=" + fmt.Sprint(len(issueAssigneesList)))
  581. for _, issueAssigneesRecord := range issueAssigneesList {
  582. if _, ok := resultMap[issueAssigneesRecord.AssigneeID]; !ok {
  583. resultMap[issueAssigneesRecord.AssigneeID] = 1
  584. } else {
  585. resultMap[issueAssigneesRecord.AssigneeID] += 1
  586. }
  587. }
  588. indexTotal += Page_SIZE
  589. if indexTotal >= count {
  590. break
  591. }
  592. }
  593. return resultMap
  594. }
  595. func queryPullRequest(start_unix int64, end_unix int64) map[int64]int {
  596. sess := x.NewSession()
  597. defer sess.Close()
  598. resultMap := make(map[int64]int)
  599. cond := "pull_request.merged_unix>=" + fmt.Sprint(start_unix) + " and pull_request.merged_unix<=" + fmt.Sprint(end_unix)
  600. count, err := sess.Table("issue").Join("inner", "pull_request", "issue.id=pull_request.issue_id").Where(cond).Count(new(Issue))
  601. if err != nil {
  602. log.Info("query issue error. return.")
  603. return resultMap
  604. }
  605. var indexTotal int64
  606. indexTotal = 0
  607. for {
  608. issueList := make([]*Issue, 0)
  609. sess.Select("issue.*").Table("issue").Join("inner", "pull_request", "issue.id=pull_request.issue_id").Where(cond).Limit(Page_SIZE, int(indexTotal))
  610. sess.Find(&issueList)
  611. log.Info("query issue(PR) size=" + fmt.Sprint(len(issueList)))
  612. for _, issueRecord := range issueList {
  613. if _, ok := resultMap[issueRecord.PosterID]; !ok {
  614. resultMap[issueRecord.PosterID] = 1
  615. } else {
  616. resultMap[issueRecord.PosterID] += 1
  617. }
  618. }
  619. indexTotal += Page_SIZE
  620. if indexTotal >= count {
  621. break
  622. }
  623. }
  624. return resultMap
  625. }
  626. func queryCommitAction(start_unix int64, end_unix int64, actionType int64) map[int64]int {
  627. sess := x.NewSession()
  628. defer sess.Close()
  629. resultMap := make(map[int64]int)
  630. cond := "user_id=act_user_id and op_type=" + fmt.Sprint(actionType) + " and created_unix>=" + fmt.Sprint(start_unix) + " and created_unix<=" + fmt.Sprint(end_unix)
  631. count, err := sess.Where(cond).Count(new(Action))
  632. if err != nil {
  633. log.Info("query action error. return.")
  634. return resultMap
  635. }
  636. var indexTotal int64
  637. indexTotal = 0
  638. for {
  639. sess.Select("id,user_id,op_type,act_user_id").Table("action").Where(cond).Limit(Page_SIZE, int(indexTotal))
  640. actionList := make([]*Action, 0)
  641. sess.Find(&actionList)
  642. log.Info("query action size=" + fmt.Sprint(len(actionList)))
  643. for _, actionRecord := range actionList {
  644. if _, ok := resultMap[actionRecord.UserID]; !ok {
  645. resultMap[actionRecord.UserID] = 1
  646. } else {
  647. resultMap[actionRecord.UserID] += 1
  648. }
  649. }
  650. indexTotal += Page_SIZE
  651. if indexTotal >= count {
  652. break
  653. }
  654. }
  655. return resultMap
  656. }
  657. func queryAction(start_unix int64, end_unix int64, actionType int64) map[int64]int {
  658. sess := x.NewSession()
  659. defer sess.Close()
  660. resultMap := make(map[int64]int)
  661. cond := "op_type=" + fmt.Sprint(actionType) + " and created_unix>=" + fmt.Sprint(start_unix) + " and created_unix<=" + fmt.Sprint(end_unix)
  662. count, err := sess.Where(cond).Count(new(Action))
  663. if err != nil {
  664. log.Info("query Action error. return.")
  665. return resultMap
  666. }
  667. var indexTotal int64
  668. indexTotal = 0
  669. for {
  670. sess.Select("id,user_id,op_type,act_user_id").Table("action").Where(cond).Limit(Page_SIZE, int(indexTotal))
  671. actionList := make([]*Action, 0)
  672. sess.Find(&actionList)
  673. log.Info("query action size=" + fmt.Sprint(len(actionList)))
  674. for _, actionRecord := range actionList {
  675. if _, ok := resultMap[actionRecord.UserID]; !ok {
  676. resultMap[actionRecord.UserID] = 1
  677. } else {
  678. resultMap[actionRecord.UserID] += 1
  679. }
  680. }
  681. indexTotal += Page_SIZE
  682. if indexTotal >= count {
  683. break
  684. }
  685. }
  686. return resultMap
  687. }
  688. func queryComment(start_unix int64, end_unix int64) map[int64]int {
  689. sess := x.NewSession()
  690. defer sess.Close()
  691. cond := "created_unix>=" + fmt.Sprint(start_unix) + " and created_unix<=" + fmt.Sprint(end_unix)
  692. resultMap := make(map[int64]int)
  693. count, err := sess.Where(cond).Count(new(Comment))
  694. if err != nil {
  695. log.Info("query Comment error. return.")
  696. return resultMap
  697. }
  698. var indexTotal int64
  699. indexTotal = 0
  700. for {
  701. sess.Select("id,type,poster_id").Table("comment").Where(cond).Limit(Page_SIZE, int(indexTotal))
  702. commentList := make([]*Comment, 0)
  703. sess.Find(&commentList)
  704. log.Info("query Comment size=" + fmt.Sprint(len(commentList)))
  705. for _, commentRecord := range commentList {
  706. if _, ok := resultMap[commentRecord.PosterID]; !ok {
  707. resultMap[commentRecord.PosterID] = 1
  708. } else {
  709. resultMap[commentRecord.PosterID] += 1
  710. }
  711. }
  712. indexTotal += Page_SIZE
  713. if indexTotal >= count {
  714. break
  715. }
  716. }
  717. return resultMap
  718. }
  719. func queryWatch(start_unix int64, end_unix int64) map[int64]int {
  720. sess := x.NewSession()
  721. defer sess.Close()
  722. cond := " created_unix>=" + fmt.Sprint(start_unix) + " and created_unix<=" + fmt.Sprint(end_unix)
  723. resultMap := make(map[int64]int)
  724. count, err := sess.Where(cond).Count(new(Watch))
  725. if err != nil {
  726. log.Info("query issue error. return.")
  727. return resultMap
  728. }
  729. var indexTotal int64
  730. indexTotal = 0
  731. for {
  732. watchList := make([]*Watch, 0)
  733. sess.Select("id,user_id,repo_id").Table("watch").Where(cond).Limit(Page_SIZE, int(indexTotal))
  734. sess.Find(&watchList)
  735. log.Info("query Watch size=" + fmt.Sprint(len(watchList)))
  736. for _, watchRecord := range watchList {
  737. if _, ok := resultMap[watchRecord.UserID]; !ok {
  738. resultMap[watchRecord.UserID] = 1
  739. } else {
  740. resultMap[watchRecord.UserID] += 1
  741. }
  742. }
  743. indexTotal += Page_SIZE
  744. if indexTotal >= count {
  745. break
  746. }
  747. }
  748. return resultMap
  749. }
  750. func queryStar(start_unix int64, end_unix int64) map[int64]int {
  751. sess := x.NewSession()
  752. defer sess.Close()
  753. cond := " created_unix>=" + fmt.Sprint(start_unix) + " and created_unix<=" + fmt.Sprint(end_unix)
  754. resultMap := make(map[int64]int)
  755. count, err := sess.Where(cond).Count(new(Star))
  756. if err != nil {
  757. log.Info("query star error. return.")
  758. return resultMap
  759. }
  760. var indexTotal int64
  761. indexTotal = 0
  762. for {
  763. sess.Select("id,uid,repo_id").Table("star").Where(cond).Limit(Page_SIZE, int(indexTotal))
  764. starList := make([]*Star, 0)
  765. sess.Find(&starList)
  766. log.Info("query Star size=" + fmt.Sprint(len(starList)))
  767. for _, starRecord := range starList {
  768. if _, ok := resultMap[starRecord.UID]; !ok {
  769. resultMap[starRecord.UID] = 1
  770. } else {
  771. resultMap[starRecord.UID] += 1
  772. }
  773. }
  774. indexTotal += Page_SIZE
  775. if indexTotal >= count {
  776. break
  777. }
  778. }
  779. return resultMap
  780. }
  781. func queryFollow(start_unix int64, end_unix int64) map[int64]int {
  782. sess := x.NewSession()
  783. defer sess.Close()
  784. resultMap := make(map[int64]int)
  785. cond := " created_unix>=" + fmt.Sprint(start_unix) + " and created_unix<=" + fmt.Sprint(end_unix)
  786. count, err := sess.Where(cond).Count(new(Follow))
  787. if err != nil {
  788. log.Info("query follow error. return.")
  789. return resultMap
  790. }
  791. var indexTotal int64
  792. indexTotal = 0
  793. for {
  794. sess.Select("id,user_id,follow_id").Table("follow").Where(cond).Limit(Page_SIZE, int(indexTotal))
  795. followList := make([]*Follow, 0)
  796. sess.Find(&followList)
  797. log.Info("query Follow size=" + fmt.Sprint(len(followList)))
  798. for _, followRecord := range followList {
  799. if _, ok := resultMap[followRecord.FollowID]; !ok {
  800. resultMap[followRecord.FollowID] = 1
  801. } else {
  802. resultMap[followRecord.FollowID] += 1
  803. }
  804. }
  805. indexTotal += Page_SIZE
  806. if indexTotal >= count {
  807. break
  808. }
  809. }
  810. return resultMap
  811. }
  812. func queryDatasetSize(start_unix int64, end_unix int64) map[int64]int {
  813. sess := x.NewSession()
  814. defer sess.Close()
  815. resultMap := make(map[int64]int)
  816. cond := " created_unix>=" + fmt.Sprint(start_unix) + " and created_unix<=" + fmt.Sprint(end_unix)
  817. count, err := sess.Where(cond).Count(new(Attachment))
  818. if err != nil {
  819. log.Info("query attachment error. return.")
  820. return resultMap
  821. }
  822. var indexTotal int64
  823. indexTotal = 0
  824. for {
  825. sess.Select("id,uploader_id,size").Table("attachment").Where(cond).Limit(Page_SIZE, int(indexTotal))
  826. attachmentList := make([]*Attachment, 0)
  827. sess.Find(&attachmentList)
  828. log.Info("query Attachment size=" + fmt.Sprint(len(attachmentList)))
  829. for _, attachRecord := range attachmentList {
  830. if _, ok := resultMap[attachRecord.UploaderID]; !ok {
  831. resultMap[attachRecord.UploaderID] = int(attachRecord.Size / (1024 * 1024)) //MB
  832. } else {
  833. resultMap[attachRecord.UploaderID] += int(attachRecord.Size / (1024 * 1024)) //MB
  834. }
  835. }
  836. indexTotal += Page_SIZE
  837. if indexTotal >= count {
  838. break
  839. }
  840. }
  841. return resultMap
  842. }
  843. func queryUserCreateRepo(start_unix int64, end_unix int64) map[int64]int {
  844. sess := x.NewSession()
  845. defer sess.Close()
  846. resultMap := make(map[int64]int)
  847. cond := "is_fork=false and created_unix>=" + fmt.Sprint(start_unix) + " and created_unix<=" + fmt.Sprint(end_unix)
  848. count, err := sess.Where(cond).Count(new(Repository))
  849. if err != nil {
  850. log.Info("query Repository error. return.")
  851. return resultMap
  852. }
  853. var indexTotal int64
  854. indexTotal = 0
  855. for {
  856. sess.Select("id,owner_id,name").Table("repository").Where(cond).Limit(Page_SIZE, int(indexTotal))
  857. repoList := make([]*Repository, 0)
  858. sess.Find(&repoList)
  859. log.Info("query Repository size=" + fmt.Sprint(len(repoList)))
  860. for _, repoRecord := range repoList {
  861. if _, ok := resultMap[repoRecord.OwnerID]; !ok {
  862. resultMap[repoRecord.OwnerID] = 1
  863. } else {
  864. resultMap[repoRecord.OwnerID] += 1
  865. }
  866. }
  867. indexTotal += Page_SIZE
  868. if indexTotal >= count {
  869. break
  870. }
  871. }
  872. return resultMap
  873. }
  874. func queryUserRepoOpenIIndex(start_unix int64, end_unix int64) map[int64]float64 {
  875. statictisSess := xStatistic.NewSession()
  876. defer statictisSess.Close()
  877. statictisSess.Select("id,repo_id,radar_total").Table("repo_statistic").Where("created_unix>=" + fmt.Sprint(start_unix) + " and created_unix<=" + fmt.Sprint(end_unix)).OrderBy("id desc")
  878. repoStatisticList := make([]*RepoStatistic, 0)
  879. statictisSess.Find(&repoStatisticList)
  880. repoOpenIIndexMap := make(map[int64]float64)
  881. log.Info("query repo_statistic size=" + fmt.Sprint(len(repoStatisticList)))
  882. for _, repoRecord := range repoStatisticList {
  883. if _, ok := repoOpenIIndexMap[repoRecord.RepoID]; !ok {
  884. repoOpenIIndexMap[repoRecord.RepoID] = repoRecord.RadarTotal
  885. }
  886. }
  887. sess := x.NewSession()
  888. defer sess.Close()
  889. sess.Select("id,owner_id,name").Table("repository").Where("is_fork=false")
  890. repoList := make([]*Repository, 0)
  891. sess.Find(&repoList)
  892. userMap := make(map[int64]float64)
  893. log.Info("query Repository size=" + fmt.Sprint(len(repoList)))
  894. for _, repoRecord := range repoList {
  895. if _, ok := userMap[repoRecord.OwnerID]; !ok {
  896. if _, ok := repoOpenIIndexMap[repoRecord.ID]; ok {
  897. userMap[repoRecord.OwnerID] = repoOpenIIndexMap[repoRecord.ID]
  898. }
  899. }
  900. }
  901. //query collaboration
  902. sess.Select("repo_id,user_id,mode").Table("collaboration")
  903. collaborationList := make([]*Collaboration, 0)
  904. sess.Find(&collaborationList)
  905. log.Info("query collaborationList size=" + fmt.Sprint(len(collaborationList)))
  906. for _, collaborationRecord := range collaborationList {
  907. if _, ok := userMap[collaborationRecord.UserID]; !ok {
  908. if _, ok := repoOpenIIndexMap[collaborationRecord.RepoID]; ok {
  909. userMap[collaborationRecord.UserID] = repoOpenIIndexMap[collaborationRecord.RepoID]
  910. }
  911. } else {
  912. if _, ok := repoOpenIIndexMap[collaborationRecord.RepoID]; ok {
  913. userMap[collaborationRecord.UserID] += repoOpenIIndexMap[collaborationRecord.RepoID]
  914. }
  915. }
  916. }
  917. userMapJson, _ := json.Marshal(userMap)
  918. log.Info("userMapJson=" + string(userMapJson))
  919. return userMap
  920. }
  921. func queryLoginCount(start_unix int64, end_unix int64) map[int64]int {
  922. statictisSess := xStatistic.NewSession()
  923. defer statictisSess.Close()
  924. resultMap := make(map[int64]int)
  925. cond := "created_unix>=" + fmt.Sprint(start_unix) + " and created_unix<=" + fmt.Sprint(end_unix)
  926. count, err := statictisSess.Where(cond).Count(new(UserLoginLog))
  927. if err != nil {
  928. log.Info("query UserLoginLog error. return.")
  929. return resultMap
  930. }
  931. var indexTotal int64
  932. indexTotal = 0
  933. for {
  934. statictisSess.Select("id,u_id").Table("user_login_log").Where(cond).Limit(Page_SIZE, int(indexTotal))
  935. userLoginLogList := make([]*UserLoginLog, 0)
  936. statictisSess.Find(&userLoginLogList)
  937. log.Info("query user login size=" + fmt.Sprint(len(userLoginLogList)))
  938. for _, loginRecord := range userLoginLogList {
  939. if _, ok := resultMap[loginRecord.UId]; !ok {
  940. resultMap[loginRecord.UId] = 1
  941. } else {
  942. resultMap[loginRecord.UId] += 1
  943. }
  944. }
  945. indexTotal += Page_SIZE
  946. if indexTotal >= count {
  947. break
  948. }
  949. }
  950. return resultMap
  951. }
  952. func subMonth(t1, t2 time.Time) (month int) {
  953. y1 := t1.Year()
  954. y2 := t2.Year()
  955. m1 := int(t1.Month())
  956. m2 := int(t2.Month())
  957. d1 := t1.Day()
  958. d2 := t2.Day()
  959. yearInterval := y1 - y2
  960. // 如果 d1的 月-日 小于 d2的 月-日 那么 yearInterval-- 这样就得到了相差的年数
  961. if m1 < m2 || m1 == m2 && d1 < d2 {
  962. yearInterval--
  963. }
  964. // 获取月数差值
  965. monthInterval := (m1 + 12) - m2
  966. if d1 < d2 {
  967. monthInterval--
  968. }
  969. monthInterval %= 12
  970. month = yearInterval*12 + monthInterval
  971. if month == 0 {
  972. month = 1
  973. }
  974. return month
  975. }