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.

repo_dashbord.go 19 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535
  1. package repo
  2. import (
  3. "fmt"
  4. "net/http"
  5. "net/url"
  6. "strconv"
  7. "time"
  8. "github.com/360EntSecGroup-Skylar/excelize/v2"
  9. "code.gitea.io/gitea/models"
  10. "code.gitea.io/gitea/modules/log"
  11. "code.gitea.io/gitea/modules/context"
  12. "code.gitea.io/gitea/modules/setting"
  13. )
  14. const DEFAULT_PAGE_SIZE = 10
  15. const DATE_FORMAT = "2006-01-02"
  16. const EXCEL_DATE_FORMAT = "20060102"
  17. type ProjectsPeriodData struct {
  18. RecordBeginTime string `json:"recordBeginTime"`
  19. LastUpdatedTime string `json:"lastUpdatedTime"`
  20. PageSize int `json:"pageSize"`
  21. TotalPage int `json:"totalPage"`
  22. TotalCount int64 `json:"totalCount"`
  23. PageRecords []*models.RepoStatistic `json:"pageRecords"`
  24. }
  25. type UserInfo struct {
  26. User string `json:"user"`
  27. Mode int `json:"mode"`
  28. PR int64 `json:"pr"`
  29. Commit int `json:"commit"`
  30. RelAvatarLink string `json:"relAvatarLink"`
  31. Email string `json:"email"`
  32. }
  33. type ProjectLatestData struct {
  34. RecordBeginTime string `json:"recordBeginTime"`
  35. LastUpdatedTime string `json:"lastUpdatedTime"`
  36. CreatTime string `json:"creatTime"`
  37. OpenI float64 `json:"openi"`
  38. Comment int64 `json:"comment"`
  39. View int64 `json:"view"`
  40. Download int64 `json:"download"`
  41. IssueClosedRatio float32 `json:"issueClosedRatio"`
  42. Impact float64 `json:"impact"`
  43. Completeness float64 `json:"completeness"`
  44. Liveness float64 `json:"liveness"`
  45. ProjectHealth float64 `json:"projectHealth"`
  46. TeamHealth float64 `json:"teamHealth"`
  47. Growth float64 `json:"growth"`
  48. Description string `json:"description"`
  49. Top10 []UserInfo `json:"top10"`
  50. }
  51. func RestoreForkNumber(ctx *context.Context) {
  52. repos, err := models.GetAllRepositories()
  53. if err != nil {
  54. log.Error("GetAllRepositories failed: %v", err.Error())
  55. return
  56. }
  57. for _, repo := range repos {
  58. models.RestoreRepoStatFork(int64(repo.NumForks), repo.ID)
  59. }
  60. ctx.JSON(http.StatusOK, struct{}{})
  61. }
  62. func GetAllProjectsPeriodStatistics(ctx *context.Context) {
  63. recordBeginTime, err := getRecordBeginTime()
  64. if err != nil {
  65. log.Error("Can not get record begin time", err)
  66. ctx.Error(http.StatusBadRequest, ctx.Tr("repo.record_begintime_get_err"))
  67. return
  68. }
  69. beginTime, endTime, err := getTimePeroid(ctx, recordBeginTime)
  70. if err != nil {
  71. log.Error("Parameter is wrong", err)
  72. ctx.Error(http.StatusBadRequest, ctx.Tr("repo.parameter_is_wrong"))
  73. return
  74. }
  75. q := ctx.QueryTrim("q")
  76. page := ctx.QueryInt("page")
  77. if page <= 0 {
  78. page = 1
  79. }
  80. pageSize := ctx.QueryInt("pagesize")
  81. if pageSize <= 0 {
  82. pageSize = DEFAULT_PAGE_SIZE
  83. }
  84. orderBy := getOrderBy(ctx)
  85. latestUpdatedTime, latestDate, err := models.GetRepoStatLastUpdatedTime()
  86. if err != nil {
  87. log.Error("Can not query the last updated time.", err)
  88. ctx.Error(http.StatusBadRequest, ctx.Tr("repo.last_update_time_error"))
  89. return
  90. }
  91. countSql := generateCountSql(beginTime, endTime, latestDate, q)
  92. total, err := models.CountRepoStatByRawSql(countSql)
  93. if err != nil {
  94. log.Error("Can not query total count.", err)
  95. ctx.Error(http.StatusBadRequest, ctx.Tr("repo.total_count_get_error"))
  96. return
  97. }
  98. sql := generateSqlByType(ctx, beginTime, endTime, latestDate, q, orderBy, page, pageSize)
  99. projectsPeriodData := ProjectsPeriodData{
  100. RecordBeginTime: recordBeginTime.Format(DATE_FORMAT),
  101. PageSize: pageSize,
  102. TotalPage: getTotalPage(total, pageSize),
  103. TotalCount: total,
  104. LastUpdatedTime: latestUpdatedTime,
  105. PageRecords: models.GetRepoStatisticByRawSql(sql),
  106. }
  107. ctx.JSON(http.StatusOK, projectsPeriodData)
  108. }
  109. func generateSqlByType(ctx *context.Context, beginTime time.Time, endTime time.Time, latestDate string, q string, orderBy string, page int, pageSize int) string {
  110. sql := ""
  111. if ctx.QueryTrim("type") == "all" {
  112. sql = generateTypeAllSql(beginTime, endTime, latestDate, q, orderBy, page, pageSize)
  113. } else {
  114. sql = generatePageSql(beginTime, endTime, latestDate, q, orderBy, page, pageSize)
  115. }
  116. return sql
  117. }
  118. func ServeAllProjectsPeriodStatisticsFile(ctx *context.Context) {
  119. recordBeginTime, err := getRecordBeginTime()
  120. if err != nil {
  121. log.Error("Can not get record begin time", err)
  122. ctx.Error(http.StatusBadRequest, ctx.Tr("repo.record_begintime_get_err"))
  123. return
  124. }
  125. beginTime, endTime, err := getTimePeroid(ctx, recordBeginTime)
  126. if err != nil {
  127. log.Error("Parameter is wrong", err)
  128. ctx.Error(http.StatusBadRequest, ctx.Tr("repo.parameter_is_wrong"))
  129. return
  130. }
  131. q := ctx.QueryTrim("q")
  132. page := ctx.QueryInt("page")
  133. if page <= 0 {
  134. page = 1
  135. }
  136. pageSize := 1000
  137. orderBy := getOrderBy(ctx)
  138. _, latestDate, err := models.GetRepoStatLastUpdatedTime()
  139. if err != nil {
  140. log.Error("Can not query the last updated time.", err)
  141. ctx.Error(http.StatusBadRequest, ctx.Tr("repo.last_update_time_error"))
  142. return
  143. }
  144. countSql := generateCountSql(beginTime, endTime, latestDate, q)
  145. total, err := models.CountRepoStatByRawSql(countSql)
  146. if err != nil {
  147. log.Error("Can not query total count.", err)
  148. ctx.Error(http.StatusBadRequest, ctx.Tr("repo.total_count_get_error"))
  149. return
  150. }
  151. var projectAnalysis = ctx.Tr("repo.repo_stat_inspect")
  152. fileName := getFileName(ctx, beginTime, endTime, projectAnalysis)
  153. totalPage := getTotalPage(total, pageSize)
  154. f := excelize.NewFile()
  155. index := f.NewSheet(projectAnalysis)
  156. f.DeleteSheet("Sheet1")
  157. for k, v := range allProjectsPeroidHeader(ctx) {
  158. f.SetCellValue(projectAnalysis, k, v)
  159. }
  160. var row = 2
  161. for i := 0; i <= totalPage; i++ {
  162. pageRecords := models.GetRepoStatisticByRawSql(generateSqlByType(ctx, beginTime, endTime, latestDate, q, orderBy, i+1, pageSize))
  163. for _, record := range pageRecords {
  164. for k, v := range allProjectsPeroidValues(row, record, ctx) {
  165. f.SetCellValue(projectAnalysis, k, v)
  166. }
  167. row++
  168. }
  169. }
  170. f.SetActiveSheet(index)
  171. ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+url.QueryEscape(fileName))
  172. ctx.Resp.Header().Set("Content-Type", "application/octet-stream")
  173. f.WriteTo(ctx.Resp)
  174. }
  175. func getFileName(ctx *context.Context, beginTime time.Time, endTime time.Time, projectAnalysis string) string {
  176. baseName := projectAnalysis + "_"
  177. if ctx.QueryTrim("q") != "" {
  178. baseName = baseName + ctx.QueryTrim("q") + "_"
  179. }
  180. if ctx.QueryTrim("type") == "all" {
  181. baseName = baseName + ctx.Tr("repo.all")
  182. } else {
  183. baseName = baseName + beginTime.AddDate(0, 0, -1).Format(EXCEL_DATE_FORMAT) + "_" + endTime.AddDate(0, 0, -1).Format(EXCEL_DATE_FORMAT)
  184. }
  185. frontName := baseName + ".xlsx"
  186. return frontName
  187. }
  188. func allProjectsPeroidHeader(ctx *context.Context) map[string]string {
  189. return map[string]string{"A1": ctx.Tr("admin.repos.id"), "B1": ctx.Tr("admin.repos.projectName"), "C1": ctx.Tr("repo.owner"), "D1": ctx.Tr("admin.repos.isPrivate"), "E1": ctx.Tr("admin.repos.openi"), "F1": ctx.Tr("admin.repos.visit"), "G1": ctx.Tr("admin.repos.download"), "H1": ctx.Tr("admin.repos.pr"), "I1": ctx.Tr("admin.repos.commit"),
  190. "J1": ctx.Tr("admin.repos.watches"), "K1": ctx.Tr("admin.repos.stars"), "L1": ctx.Tr("admin.repos.forks"), "M1": ctx.Tr("admin.repos.issues"), "N1": ctx.Tr("admin.repos.closedIssues"), "O1": ctx.Tr("admin.repos.contributor")}
  191. }
  192. func allProjectsPeroidValues(row int, rs *models.RepoStatistic, ctx *context.Context) map[string]string {
  193. return map[string]string{getCellName("A", row): strconv.FormatInt(rs.RepoID, 10), getCellName("B", row): rs.Name, getCellName("C", row): rs.OwnerName, getCellName("D", row): getIsPrivateDisplay(rs.IsPrivate, ctx), getCellName("E", row): strconv.FormatFloat(rs.RadarTotal, 'f', 2, 64),
  194. getCellName("F", row): strconv.FormatInt(rs.NumVisits, 10), getCellName("G", row): strconv.FormatInt(rs.NumDownloads, 10), getCellName("H", row): strconv.FormatInt(rs.NumPulls, 10), getCellName("I", row): strconv.FormatInt(rs.NumCommits, 10),
  195. getCellName("J", row): strconv.FormatInt(rs.NumWatches, 10), getCellName("K", row): strconv.FormatInt(rs.NumStars, 10), getCellName("L", row): strconv.FormatInt(rs.NumForks, 10), getCellName("M", row): strconv.FormatInt(rs.NumIssues, 10),
  196. getCellName("N", row): strconv.FormatInt(rs.NumClosedIssues, 10), getCellName("O", row): strconv.FormatInt(rs.NumContributor, 10),
  197. }
  198. }
  199. func getCellName(col string, row int) string {
  200. return col + strconv.Itoa(row)
  201. }
  202. func getIsPrivateDisplay(private bool, ctx *context.Context) string {
  203. if private {
  204. return ctx.Tr("admin.repos.yes")
  205. } else {
  206. return ctx.Tr("admin.repos.no")
  207. }
  208. }
  209. func GetProjectLatestStatistics(ctx *context.Context) {
  210. repoId := ctx.Params(":id")
  211. recordBeginTime, err := getRecordBeginTime()
  212. if err != nil {
  213. log.Error("Can not get record begin time", err)
  214. ctx.Error(http.StatusBadRequest, ctx.Tr("repo.record_begintime_get_err"))
  215. return
  216. }
  217. latestUpdatedTime, latestDate, err := models.GetRepoStatLastUpdatedTime(repoId)
  218. repoIdInt, _ := strconv.ParseInt(repoId, 10, 64)
  219. repoStat, err := models.GetRepoStatisticByDateAndRepoId(latestDate, repoIdInt)
  220. if err != nil {
  221. log.Error("Can not get the repo statistics "+repoId, err)
  222. ctx.Error(http.StatusBadRequest, ctx.Tr("repo.get_repo_stat_error"))
  223. return
  224. }
  225. repository, err := models.GetRepositoryByID(repoIdInt)
  226. if err != nil {
  227. log.Error("Can not get the repo info "+repoId, err)
  228. ctx.Error(http.StatusBadRequest, ctx.Tr("repo.get_repo_info_error"))
  229. return
  230. }
  231. projectLatestData := ProjectLatestData{
  232. RecordBeginTime: recordBeginTime.Format(DATE_FORMAT),
  233. CreatTime: time.Unix(int64(repository.CreatedUnix), 0).Format(DATE_FORMAT),
  234. LastUpdatedTime: latestUpdatedTime,
  235. OpenI: repoStat.RadarTotal,
  236. Comment: repoStat.NumComments,
  237. View: repoStat.NumVisits,
  238. Download: repoStat.NumDownloads,
  239. IssueClosedRatio: repoStat.IssueFixedRate,
  240. Impact: repoStat.Impact,
  241. Completeness: repoStat.Completeness,
  242. Liveness: repoStat.Liveness,
  243. ProjectHealth: repoStat.ProjectHealth,
  244. TeamHealth: repoStat.TeamHealth,
  245. Growth: repoStat.Growth,
  246. Description: repository.Description,
  247. }
  248. contributors, err := models.GetTop10Contributor(repository.RepoPath())
  249. if err != nil {
  250. log.Error("can not get contributors", err)
  251. }
  252. users := make([]UserInfo, 0)
  253. for _, contributor := range contributors {
  254. mode := repository.GetCollaboratorMode(contributor.UserId)
  255. if mode == -1 {
  256. if contributor.IsAdmin {
  257. mode = int(models.AccessModeAdmin)
  258. }
  259. if contributor.UserId == repository.OwnerID {
  260. mode = int(models.AccessModeOwner)
  261. }
  262. }
  263. pr := models.GetPullCountByUserAndRepoId(repoIdInt, contributor.UserId)
  264. userInfo := UserInfo{
  265. User: contributor.Committer,
  266. Commit: contributor.CommitCnt,
  267. Mode: mode,
  268. PR: pr,
  269. RelAvatarLink: contributor.RelAvatarLink,
  270. Email: contributor.Email,
  271. }
  272. users = append(users, userInfo)
  273. }
  274. projectLatestData.Top10 = users
  275. ctx.JSON(http.StatusOK, projectLatestData)
  276. }
  277. func GetProjectPeriodStatistics(ctx *context.Context) {
  278. repoId := ctx.Params(":id")
  279. recordBeginTime, err := getRecordBeginTime()
  280. if err != nil {
  281. log.Error("Can not get record begin time", err)
  282. ctx.Error(http.StatusBadRequest, ctx.Tr("repo.record_begintime_get_err"))
  283. return
  284. }
  285. repoIdInt, _ := strconv.ParseInt(repoId, 10, 64)
  286. if err != nil {
  287. log.Error("Can not get record begin time", err)
  288. ctx.Error(http.StatusBadRequest, ctx.Tr("repo.record_begintime_get_err"))
  289. return
  290. }
  291. beginTime, endTime, err := getTimePeroid(ctx, recordBeginTime)
  292. isOpenI := ctx.QueryBool("openi")
  293. var repositorys []*models.RepoStatistic
  294. if isOpenI {
  295. repositorys = models.GetRepoStatisticByRawSql(generateRadarSql(beginTime, endTime, repoIdInt))
  296. } else {
  297. repositorys = models.GetRepoStatisticByRawSql(generateTargetSql(beginTime, endTime, repoIdInt))
  298. }
  299. ctx.JSON(http.StatusOK, repositorys)
  300. }
  301. func generateRadarSql(beginTime time.Time, endTime time.Time, repoId int64) string {
  302. sql := "SELECT date, impact, completeness, liveness, project_health, team_health, growth, radar_total FROM repo_statistic" +
  303. " where repo_id=" + strconv.FormatInt(repoId, 10) + " and created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) +
  304. " and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) + " order by created_unix"
  305. return sql
  306. }
  307. func generateTargetSql(beginTime time.Time, endTime time.Time, repoId int64) string {
  308. sql := "SELECT date, num_visits,num_downloads,num_commits FROM repo_statistic" +
  309. " where repo_id=" + strconv.FormatInt(repoId, 10) + " and created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) +
  310. " and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) + " order by created_unix desc"
  311. return sql
  312. }
  313. func generateCountSql(beginTime time.Time, endTime time.Time, latestDate string, q string) string {
  314. countSql := "SELECT count(*) FROM " +
  315. "(SELECT repo_id FROM repo_statistic where created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) +
  316. " and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) + " group by repo_id) A," +
  317. "(SELECT repo_id,name,is_private,radar_total from public.repo_statistic where date='" + latestDate + "') B" +
  318. " where A.repo_id=B.repo_id"
  319. if q != "" {
  320. countSql = countSql + " and B.name like '%" + q + "%'"
  321. }
  322. return countSql
  323. }
  324. func generateTypeAllSql(beginTime time.Time, endTime time.Time, latestDate string, q string, orderBy string, page int, pageSize int) string {
  325. sql := "SELECT A.repo_id,name,owner_name,is_private,radar_total,num_watches,num_visits,num_downloads,num_pulls,num_commits,num_stars,num_forks,num_issues,num_closed_issues,num_contributor FROM " +
  326. "(SELECT repo_id,sum(num_visits) as num_visits " +
  327. " FROM repo_statistic where created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) +
  328. " and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) + " group by repo_id) A," +
  329. "(SELECT repo_id,name,owner_name,is_private,radar_total,num_watches,num_downloads,num_pulls,num_commits,num_stars,num_forks,num_issues,num_closed_issues,num_contributor from public.repo_statistic where date='" + latestDate + "') B" +
  330. " where A.repo_id=B.repo_id"
  331. if q != "" {
  332. sql = sql + " and name like '%" + q + "%'"
  333. }
  334. sql = sql + " order by " + orderBy + " desc,repo_id" + " limit " + strconv.Itoa(pageSize) + " offset " + strconv.Itoa((page-1)*pageSize)
  335. return sql
  336. }
  337. func generatePageSql(beginTime time.Time, endTime time.Time, latestDate string, q string, orderBy string, page int, pageSize int) string {
  338. sql := "SELECT A.repo_id,name,owner_name,is_private,radar_total,num_watches,num_visits,num_downloads,num_pulls,num_commits,num_stars,num_forks,num_issues,num_closed_issues,num_contributor FROM " +
  339. "(SELECT repo_id,sum(num_watches_added) as num_watches,sum(num_visits) as num_visits, sum(num_downloads_added) as num_downloads,sum(num_pulls_added) as num_pulls,sum(num_commits_added) as num_commits,sum(num_stars_added) as num_stars,sum(num_forks_added) num_forks,sum(num_issues_added) as num_issues,sum(num_closed_issues_added) as num_closed_issues,sum(num_contributor_added) as num_contributor " +
  340. " FROM repo_statistic where created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) +
  341. " and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) + " group by repo_id) A," +
  342. "(SELECT repo_id,name,owner_name,is_private,radar_total from public.repo_statistic where date='" + latestDate + "') B" +
  343. " where A.repo_id=B.repo_id"
  344. if q != "" {
  345. sql = sql + " and B.name like '%" + q + "%'"
  346. }
  347. sql = sql + " order by " + orderBy + " desc,A.repo_id" + " limit " + strconv.Itoa(pageSize) + " offset " + strconv.Itoa((page-1)*pageSize)
  348. return sql
  349. }
  350. func getOrderBy(ctx *context.Context) string {
  351. orderBy := ""
  352. switch ctx.Query("sort") {
  353. case "openi":
  354. orderBy = "B.radar_total"
  355. case "view":
  356. orderBy = "A.num_visits"
  357. case "download":
  358. orderBy = "A.num_downloads"
  359. case "pr":
  360. orderBy = "A.num_pulls"
  361. case "commit":
  362. orderBy = "A.num_commits"
  363. case "watch":
  364. orderBy = "A.num_watches"
  365. case "star":
  366. orderBy = "A.num_stars"
  367. case "fork":
  368. orderBy = "A.num_forks"
  369. case "issue":
  370. orderBy = "A.num_issues"
  371. case "issue_closed":
  372. orderBy = "A.num_closed_issues"
  373. case "contributor":
  374. orderBy = "A.num_contributor"
  375. default:
  376. orderBy = "B.radar_total"
  377. }
  378. return orderBy
  379. }
  380. func getTimePeroid(ctx *context.Context, recordBeginTime time.Time) (time.Time, time.Time, error) {
  381. queryType := ctx.QueryTrim("type")
  382. now := time.Now()
  383. recordBeginTimeTemp := recordBeginTime.AddDate(0, 0, 1)
  384. beginTimeStr := ctx.QueryTrim("beginTime")
  385. endTimeStr := ctx.QueryTrim("endTime")
  386. var beginTime time.Time
  387. var endTime time.Time
  388. var err error
  389. if queryType != "" {
  390. if queryType == "all" {
  391. beginTime = recordBeginTimeTemp
  392. endTime = now
  393. } else if queryType == "yesterday" {
  394. endTime = now
  395. beginTime = time.Date(endTime.Year(), endTime.Month(), endTime.Day(), 0, 0, 0, 0, now.Location())
  396. } else if queryType == "current_week" {
  397. beginTime = now.AddDate(0, 0, -int(time.Now().Weekday())+2) //begin from monday
  398. beginTime = time.Date(beginTime.Year(), beginTime.Month(), beginTime.Day(), 0, 0, 0, 0, now.Location())
  399. endTime = now
  400. } else if queryType == "current_month" {
  401. endTime = now
  402. beginTime = time.Date(endTime.Year(), endTime.Month(), 2, 0, 0, 0, 0, now.Location())
  403. } else if queryType == "monthly" {
  404. endTime = now
  405. beginTime = now.AddDate(0, -1, 1)
  406. beginTime = time.Date(beginTime.Year(), beginTime.Month(), beginTime.Day(), 0, 0, 0, 0, now.Location())
  407. } else if queryType == "current_year" {
  408. endTime = now
  409. beginTime = time.Date(endTime.Year(), 1, 2, 0, 0, 0, 0, now.Location())
  410. } else if queryType == "last_month" {
  411. lastMonthTime := now.AddDate(0, -1, 0)
  412. beginTime = time.Date(lastMonthTime.Year(), lastMonthTime.Month(), 2, 0, 0, 0, 0, now.Location())
  413. endTime = time.Date(now.Year(), now.Month(), 2, 0, 0, 0, 0, now.Location())
  414. } else {
  415. return now, now, fmt.Errorf("The value of type parameter is wrong.")
  416. }
  417. } else {
  418. if beginTimeStr == "" || endTimeStr == "" {
  419. //如果查询类型和开始时间结束时间都未设置,按queryType=all处理
  420. beginTime = recordBeginTimeTemp
  421. endTime = now
  422. } else {
  423. beginTime, err = time.ParseInLocation("2006-01-02", beginTimeStr, time.Local)
  424. if err != nil {
  425. return now, now, err
  426. }
  427. endTime, err = time.ParseInLocation("2006-01-02", endTimeStr, time.Local)
  428. if err != nil {
  429. return now, now, err
  430. }
  431. beginTime = beginTime.AddDate(0, 0, 1)
  432. endTime = endTime.AddDate(0, 0, 1)
  433. }
  434. }
  435. if beginTime.Before(recordBeginTimeTemp) {
  436. beginTime = recordBeginTimeTemp
  437. }
  438. return beginTime, endTime, nil
  439. }
  440. func getRecordBeginTime() (time.Time, error) {
  441. return time.ParseInLocation(DATE_FORMAT, setting.RadarMap.RecordBeginTime, time.Local)
  442. }
  443. func getTotalPage(total int64, pageSize int) int {
  444. another := 0
  445. if int(total)%pageSize != 0 {
  446. another = 1
  447. }
  448. return int(total)/pageSize + another
  449. }