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

124 lines
4.0 KiB

  1. package logic
  2. import (
  3. "VoteManage_Go/api/v1/vote"
  4. "VoteManage_Go/internal/dao"
  5. "VoteManage_Go/internal/model/dto"
  6. "VoteManage_Go/internal/service"
  7. "context"
  8. "fmt"
  9. "github.com/gogf/gf/v2/frame/g"
  10. "github.com/gogf/gf/v2/net/ghttp"
  11. "github.com/gogf/gf/v2/os/gtime"
  12. "github.com/xuri/excelize/v2"
  13. "net/url"
  14. "strconv"
  15. "time"
  16. )
  17. type sVote struct{}
  18. func init() {
  19. service.RegisterVote(New())
  20. }
  21. func New() *sVote {
  22. return &sVote{}
  23. }
  24. func (s *sVote) GetVoteByCondition(ctx context.Context, req *vote.GetVoteDetailListReq) (votes []*dto.VoteDto, total int, err error) {
  25. query := g.Model("vote_records v").LeftJoin("member_info m", "v.jwcode = m.jwcode").
  26. Fields("v.id, m.nickname, v.jwcode, m.dept, v.options_title, v.time").
  27. Where("v.activity_id = ?", req.ActivityId)
  28. // 条件1:jwcode输入(精确匹配)
  29. if req.Jwcode != "" {
  30. query = query.Where("v.jwcode = ?", req.Jwcode)
  31. }
  32. // 条件2:地区dept下拉框(精确匹配)dept是汉字
  33. if req.Dept != "" {
  34. query = query.Where("m.dept = ?", req.Dept)
  35. }
  36. // 条件3:投票日期范围(时间戳转换)
  37. //if req.StartTime != nil && req.EndTime != nil {
  38. // // 将前端日期字符串转为Unix时间戳(示例:2025.04.01 00:00:00 → 时间戳)
  39. // query = query.Where("v.time BETWEEN ? AND ?", req.StartTime.Unix(), req.EndTime.Unix())
  40. //}
  41. if req.StartDate != "" && req.EndDate != "" {
  42. start := gtime.New(req.StartDate + " 00:00:00").Unix()
  43. end := gtime.New(req.EndDate + " 23:59:59").Unix()
  44. query = query.Where("v.time BETWEEN ? AND ?", start, end)
  45. }
  46. // 条件4:分页
  47. query.Page(req.PageNo, req.PageSize).ScanAndCount(&votes, &total, false)
  48. return
  49. }
  50. func (s *sVote) ExportVote(r *ghttp.Request, req *vote.GetVoteDetailListReq) {
  51. votes, _, err := s.GetVoteByCondition(r.Context(), req)
  52. if err != nil {
  53. r.Response.WriteJsonExit(dto.Error("查询失败:" + err.Error()))
  54. return
  55. }
  56. if len(votes) == 0 {
  57. r.Response.WriteJsonExit(dto.Error("查询结果为空"))
  58. return
  59. }
  60. // 内存中创建Excel文件(不落盘)
  61. excelFile := excelize.NewFile()
  62. sheetName := "投票记录"
  63. excelFile.SetSheetName("Sheet1", sheetName)
  64. // 设置表头样式
  65. headers := []string{"序号", "姓名", "精网号", "地区", "投票明细", "投票时间"}
  66. for i, header := range headers {
  67. col := string('A' + i)
  68. excelFile.SetCellValue(sheetName, col+"1", header)
  69. excelFile.SetColWidth(sheetName, col, col, 18) // 列宽调整
  70. }
  71. // 动态写入数据
  72. for rowIdx, vote := range votes {
  73. row := strconv.Itoa(rowIdx + 2)
  74. excelFile.SetCellValue(sheetName, "A"+row, rowIdx+1)
  75. excelFile.SetCellValue(sheetName, "B"+row, vote.Nickname)
  76. excelFile.SetCellValue(sheetName, "C"+row, vote.Jwcode)
  77. excelFile.SetCellValue(sheetName, "D"+row, vote.Dept)
  78. excelFile.SetCellValue(sheetName, "E"+row, vote.OptionsTitle)
  79. excelFile.SetCellValue(sheetName, "F"+row, vote.Time)
  80. }
  81. // 生成唯一文件名并响应流
  82. fileName := fmt.Sprintf("投票记录_%s.xlsx",
  83. time.Now().Format("20060102150405"),
  84. )
  85. r.Response.Header().Set("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
  86. r.Response.Header().Set("Content-Disposition", "attachment; filename*=UTF-8''"+url.QueryEscape(fileName))
  87. // 直接写入HTTP响应流
  88. if buffer, err := excelFile.WriteToBuffer(); err == nil {
  89. r.Response.Write(buffer.Bytes())
  90. } else {
  91. r.Response.WriteJsonExit(dto.Error("文件生成失败:" + err.Error()))
  92. }
  93. }
  94. func (s *sVote) GetActivityList(ctx context.Context, req *vote.GetActivityListReq) (activities []*dto.Activity, total int, err error) {
  95. err = g.DB("live").Model("float_window").Fields("id, title, start, end, created_at").
  96. OrderDesc("id").Page(req.PageNo, req.PageSize).ScanAndCount(&activities, &total, false)
  97. for _, v := range activities {
  98. v.VoteCount, _ = dao.VoteRecords.Ctx(ctx).Where("activity_id", v.Id).Fields("DISTINCT jwcode").Count()
  99. //fmt.Printf(strconv.Itoa(v.VoteCount))
  100. if gtime.Date() < v.Start {
  101. v.Status = 1
  102. } else if gtime.Date() > v.End {
  103. v.Status = 3
  104. } else {
  105. v.Status = 2
  106. }
  107. }
  108. return
  109. }