From 8d6eecc0da0a3a74e9289526a6de794d6e531b95 Mon Sep 17 00:00:00 2001 From: maziyang Date: Tue, 24 Jun 2025 15:23:25 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E6=8A=95=E7=A5=A8=E5=90=8D=E5=8D=95?= =?UTF-8?q?=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/vote_record/v1/vote_record.go | 19 ++++++- api/vote_record/vote_record.go | 1 + hack/config.yaml | 2 +- internal/cmd/cmd.go | 2 +- .../vote_record/vote_record_v1_get_export_file.go | 12 ++++ internal/dao/internal/article.go | 2 +- internal/dao/internal/user.go | 8 ++- internal/dao/internal/vote_poll.go | 4 +- internal/dao/internal/vote_record.go | 10 ++-- internal/logic/vote_record/get_export_file.go | 64 ++++++++++++++++++++++ internal/logic/vote_record/get_index.go | 10 ++++ internal/logic/vote_record/get_vote.go | 6 +- internal/logic/vote_record/get_vote_detail.go | 10 +++- internal/model/do/article.go | 2 +- internal/model/do/user.go | 7 ++- internal/model/do/vote_poll.go | 2 +- internal/model/do/vote_record.go | 8 +-- internal/model/entity/article.go | 2 +- internal/model/entity/user.go | 15 ++--- internal/model/entity/vote_poll.go | 2 +- internal/model/entity/vote_record.go | 14 ++--- internal/service/vote_record.go | 1 + manifest/config/config.yaml | 12 +++- 23 files changed, 167 insertions(+), 48 deletions(-) create mode 100644 internal/controller/vote_record/vote_record_v1_get_export_file.go create mode 100644 internal/logic/vote_record/get_export_file.go diff --git a/api/vote_record/v1/vote_record.go b/api/vote_record/v1/vote_record.go index af81911..5766300 100644 --- a/api/vote_record/v1/vote_record.go +++ b/api/vote_record/v1/vote_record.go @@ -5,9 +5,16 @@ import ( "github.com/gogf/gf/v2/os/gtime" ) -type GetVoteDetailListRes struct { - VoteList []*GetVoteDetailRes `json:"voteList"` - TotalCount int `json:"totalCount"` +type GetExportFileReq struct { + g.Meta `path:"/getExportVoteDetail" method:"get" tags:"获取投票名单列表"` + VoteId int `p:"voteId" v:"required" dc:"投票活动ID"` + Username string `p:"username" dc:"<用户名>"` + Account string `p:"account" dc:"<精网号>"` + Area string `p:"area" dc:"地区"` + OptionContent string `p:"optionContent" dc:"<选项>"` +} +type GetExportFileRes struct { + VoteList []*GetVoteDetailRes `json:"voteList"` } type GetVoteDetailReq struct { g.Meta `path:"/getAllVoteDetail" method:"get" tags:"获取投票名单列表"` @@ -16,6 +23,7 @@ type GetVoteDetailReq struct { Size int `p:"size" dc:"每页数量" default:"50"` Username string `p:"username" dc:"<用户名>"` Account string `p:"account" dc:"<精网号>"` + Area string `p:"area" dc:"地区"` OptionContent string `p:"optionContent" dc:"<选项>"` } @@ -24,9 +32,14 @@ type GetVoteDetailRes struct { Account string `json:"account" dc:"精网号"` //VoteTitle string `json:"voteTitle" dc:"投票标题"` //ArticleTitle string `json:"articleTitle" dc:"文章/视频标题"` + Area string `json:"area" dc:"地区"` OptionContents string `json:"optionContents" dc:"选项名称"` CreateTime *gtime.Time `json:"createTime" dc:"投票时间"` } +type GetVoteDetailListRes struct { + VoteList []*GetVoteDetailRes `json:"voteList"` + TotalCount int `json:"totalCount"` +} type GetVoteReq struct { g.Meta `path:"/getVote" method:"get" tags:"<获取文章及投票活动>"` ArticleId int `p:"articleId" v:"required" dc:"<文章>ID"` diff --git a/api/vote_record/vote_record.go b/api/vote_record/vote_record.go index 7e9e2bc..03f5181 100644 --- a/api/vote_record/vote_record.go +++ b/api/vote_record/vote_record.go @@ -11,6 +11,7 @@ import ( ) type IVoteRecordV1 interface { + GetExportFile(ctx context.Context, req *v1.GetExportFileReq) (res *v1.GetExportFileRes, err error) GetVoteDetail(ctx context.Context, req *v1.GetVoteDetailReq) (res *v1.GetVoteDetailListRes, err error) GetVote(ctx context.Context, req *v1.GetVoteReq) (res *v1.GetVoteRes, err error) GetIndex(ctx context.Context, req *v1.GetIndexReq) (res *v1.GetIndexRes, err error) diff --git a/hack/config.yaml b/hack/config.yaml index 2e1a0e6..5837e80 100644 --- a/hack/config.yaml +++ b/hack/config.yaml @@ -4,7 +4,7 @@ gfcli: gen: dao: - - link: "mysql:root:root@tcp(127.0.0.1:3306)/link_test" + - link: "mysql:root:123456@tcp(127.0.0.1:3306)/link_test" descriptionTag: true docker: diff --git a/internal/cmd/cmd.go b/internal/cmd/cmd.go index 7d4c26e..b83ea14 100644 --- a/internal/cmd/cmd.go +++ b/internal/cmd/cmd.go @@ -29,7 +29,7 @@ var ( s.Group("/", func(group *ghttp.RouterGroup) { group.Middleware(ghttp.MiddlewareHandlerResponse) - group.Bind(article.ArticlecController) + group.Bind(article.ArticleController) }) s.Group("/vote", func(group *ghttp.RouterGroup) { diff --git a/internal/controller/vote_record/vote_record_v1_get_export_file.go b/internal/controller/vote_record/vote_record_v1_get_export_file.go new file mode 100644 index 0000000..8d92b3c --- /dev/null +++ b/internal/controller/vote_record/vote_record_v1_get_export_file.go @@ -0,0 +1,12 @@ +package vote_record + +import ( + "context" + "practice_ArticleVote_Go/internal/service" + + "practice_ArticleVote_Go/api/vote_record/v1" +) + +func (c *ControllerV1) GetExportFile(ctx context.Context, req *v1.GetExportFileReq) (res *v1.GetExportFileRes, err error) { + return service.NewVoteRecordService().ExportVoteDetail(ctx, req) +} diff --git a/internal/dao/internal/article.go b/internal/dao/internal/article.go index e816d09..2cb4956 100644 --- a/internal/dao/internal/article.go +++ b/internal/dao/internal/article.go @@ -22,7 +22,7 @@ type ArticleDao struct { // ArticleColumns defines and stores column names for the table article. type ArticleColumns struct { Id string // - UserId string // 用户ID + UserId string // ArticleTitle string // 文章/视频标题 ArticleContent string // 文章/视频内容 VoteStatus string // 是否发起投票:1发起,0不发起 diff --git a/internal/dao/internal/user.go b/internal/dao/internal/user.go index 278bdd1..fa0d8d5 100644 --- a/internal/dao/internal/user.go +++ b/internal/dao/internal/user.go @@ -22,9 +22,10 @@ type UserDao struct { // UserColumns defines and stores column names for the table user. type UserColumns struct { Id string // - Account string // 精网号 - Password string // 用户密码 - Username string // 用户名 + Account string // + Password string // + Username string // + Area string // Status string // CreateTime string // UpdateTime string // @@ -36,6 +37,7 @@ var userColumns = UserColumns{ Account: "account", Password: "password", Username: "username", + Area: "area", Status: "status", CreateTime: "create_time", UpdateTime: "update_time", diff --git a/internal/dao/internal/vote_poll.go b/internal/dao/internal/vote_poll.go index 396344d..c7005a3 100644 --- a/internal/dao/internal/vote_poll.go +++ b/internal/dao/internal/vote_poll.go @@ -27,8 +27,8 @@ type VotePollColumns struct { MultiOption string // 是否开启多选:1多选,0不多选 DeadlineTime string // 截止时间 CreateTime string // - UpdateTime string // Status string // 投票活动状态:1:进行中,0已结束 + UpdateTime string // } // votePollColumns holds the columns for the table vote_poll. @@ -39,8 +39,8 @@ var votePollColumns = VotePollColumns{ MultiOption: "multi_option", DeadlineTime: "deadline_time", CreateTime: "create_time", - UpdateTime: "update_time", Status: "status", + UpdateTime: "update_time", } // NewVotePollDao creates and returns a new DAO object for table data access. diff --git a/internal/dao/internal/vote_record.go b/internal/dao/internal/vote_record.go index 42d1b04..b7fb7f1 100644 --- a/internal/dao/internal/vote_record.go +++ b/internal/dao/internal/vote_record.go @@ -22,11 +22,11 @@ type VoteRecordDao struct { // VoteRecordColumns defines and stores column names for the table vote_record. type VoteRecordColumns struct { Id string // - UserId string // 用户ID - VoteId string // 投票活动ID - OptionId string // 投票选项ID - VoteIndex string // 已投票次数 + UserId string // + VoteId string // + OptionId string // CreateTime string // + VoteIndex string // UpdateTime string // } @@ -36,8 +36,8 @@ var voteRecordColumns = VoteRecordColumns{ UserId: "user_id", VoteId: "vote_id", OptionId: "option_id", - VoteIndex: "vote_index", CreateTime: "create_time", + VoteIndex: "vote_index", UpdateTime: "update_time", } diff --git a/internal/logic/vote_record/get_export_file.go b/internal/logic/vote_record/get_export_file.go new file mode 100644 index 0000000..eed0e03 --- /dev/null +++ b/internal/logic/vote_record/get_export_file.go @@ -0,0 +1,64 @@ +package vote_record + +import ( + "context" + "github.com/gogf/gf/v2/frame/g" + v1 "practice_ArticleVote_Go/api/vote_record/v1" +) + +func (l *VoteRecordLogic) ExportVoteDetail(ctx context.Context, req *v1.GetExportFileReq) (res *v1.GetExportFileRes, err error) { + query := ` + SELECT + u.username, + u.account, + u.area, + uv.option_contents, + uv.create_time + FROM ( + SELECT + vr.user_id, + vr.vote_index, + DATE(vr.create_time) AS vote_date, + MAX(vr.create_time) AS create_time, + GROUP_CONCAT(o.option_content ORDER BY o.id SEPARATOR ',') AS option_contents + FROM vote_record vr + JOIN vote_option o + ON vr.option_id = o.id + WHERE vr.vote_id = ? + GROUP BY vr.user_id, vr.vote_index, vote_date + ) AS uv + JOIN user u ON u.id = uv.user_id + WHERE 1=1 + ` + + conditions := []interface{}{req.VoteId} + + if req.OptionContent != "" { + query += " AND uv.option_contents LIKE ?" + conditions = append(conditions, "%"+req.OptionContent+"%") + } + if req.Username != "" { + query += " AND u.username LIKE ?" + conditions = append(conditions, "%"+req.Username+"%") + } + if req.Account != "" { + query += " AND u.account LIKE ?" + conditions = append(conditions, "%"+req.Account+"%") + } + if req.Area != "" { + query += " AND u.area LIKE ?" + conditions = append(conditions, "%"+req.Area+"%") + } + query += " ORDER BY uv.create_time DESC " + var voteList []*v1.GetVoteDetailRes + err = g.DB().Ctx(ctx). + Raw(query, conditions...). + Scan(&voteList) + if err != nil { + return nil, err + } + res = &v1.GetExportFileRes{ + VoteList: voteList, + } + return res, err +} diff --git a/internal/logic/vote_record/get_index.go b/internal/logic/vote_record/get_index.go index 387759b..6b09099 100644 --- a/internal/logic/vote_record/get_index.go +++ b/internal/logic/vote_record/get_index.go @@ -2,6 +2,8 @@ package vote_record import ( "context" + "fmt" + "github.com/gogf/gf/v2/frame/g" v1 "practice_ArticleVote_Go/api/vote_record/v1" "practice_ArticleVote_Go/internal/consts" "practice_ArticleVote_Go/internal/dao" @@ -11,6 +13,14 @@ import ( func (l *VoteRecordLogic) GetIndex(ctx context.Context, req *v1.GetIndexReq) (res *v1.GetIndexRes, err error) { today := time.Now().Format("2006-01-02") + redis := g.Redis() + _, err = redis.Set(ctx, "key", "Hello, GoFrame!") + value, err := redis.Get(ctx, "key") + fmt.Println(value) + if err != nil { + fmt.Println("Set error:", err) + return + } record, err := dao.VoteRecord. Ctx(ctx). Fields("vote_index"). diff --git a/internal/logic/vote_record/get_vote.go b/internal/logic/vote_record/get_vote.go index c4827c8..d5b11ce 100644 --- a/internal/logic/vote_record/get_vote.go +++ b/internal/logic/vote_record/get_vote.go @@ -58,10 +58,10 @@ func (l *VoteRecordLogic) GetVote(ctx context.Context, req *v1.GetVoteReq) (res res.DeadlineTime = votePoll[dao.VotePoll.Columns().DeadlineTime].GTime() res.ParticipationNumber = votePoll["totalCount"].Int() res.VotePollStatus = votePoll[dao.VotePoll.Columns().Status].Int() - if res.DeadlineTime.Before(gtime.Now()) && res.VotePollStatus != 0 { - res.VotePollStatus = 0 + if res.DeadlineTime.Before(gtime.Now()) && res.VotePollStatus != 2 { + res.VotePollStatus = 2 _, err = dao.VotePoll.Ctx(ctx).Data(g.Map{ - dao.VotePoll.Columns().Status: 0, + dao.VotePoll.Columns().Status: 2, }).WherePri(res.VoteId).Update() if err != nil { return nil, err diff --git a/internal/logic/vote_record/get_vote_detail.go b/internal/logic/vote_record/get_vote_detail.go index 8afdd34..c30bb8a 100644 --- a/internal/logic/vote_record/get_vote_detail.go +++ b/internal/logic/vote_record/get_vote_detail.go @@ -46,6 +46,7 @@ func (l *VoteRecordLogic) GetVoteDetail(ctx context.Context, req *v1.GetVoteDeta SELECT u.username, u.account, + u.area, uv.option_contents, uv.create_time FROM ( @@ -61,9 +62,8 @@ func (l *VoteRecordLogic) GetVoteDetail(ctx context.Context, req *v1.GetVoteDeta WHERE vr.vote_id = ? GROUP BY vr.user_id, vr.vote_index, vote_date ) AS uv - JOIN ` + "`user`" + ` u - ON u.id = uv.user_id - WHERE 1=1 + JOIN user u ON u.id = uv.user_id + WHERE 1=1 ` conditions := []interface{}{req.VoteId} @@ -80,6 +80,10 @@ func (l *VoteRecordLogic) GetVoteDetail(ctx context.Context, req *v1.GetVoteDeta query += " AND u.account LIKE ?" conditions = append(conditions, "%"+req.Account+"%") } + if req.Area != "" { + query += " AND u.area LIKE ?" + conditions = append(conditions, "%"+req.Area+"%") + } countQuery := "SELECT COUNT(*) AS cnt FROM ( " + query + " ) AS subquery" var cntResult struct{ Cnt int } err = g.DB().Ctx(ctx).Raw(countQuery, conditions...).Scan(&cntResult) diff --git a/internal/model/do/article.go b/internal/model/do/article.go index f34c33c..f4994d7 100644 --- a/internal/model/do/article.go +++ b/internal/model/do/article.go @@ -13,7 +13,7 @@ import ( type Article struct { g.Meta `orm:"table:article, do:true"` Id interface{} // - UserId interface{} // 用户ID + UserId interface{} // ArticleTitle interface{} // 文章/视频标题 ArticleContent interface{} // 文章/视频内容 VoteStatus interface{} // 是否发起投票:1发起,0不发起 diff --git a/internal/model/do/user.go b/internal/model/do/user.go index a2b8e80..d3b7707 100644 --- a/internal/model/do/user.go +++ b/internal/model/do/user.go @@ -13,9 +13,10 @@ import ( type User struct { g.Meta `orm:"table:user, do:true"` Id interface{} // - Account interface{} // 精网号 - Password interface{} // 用户密码 - Username interface{} // 用户名 + Account interface{} // + Password interface{} // + Username interface{} // + Area interface{} // Status interface{} // CreateTime *gtime.Time // UpdateTime *gtime.Time // diff --git a/internal/model/do/vote_poll.go b/internal/model/do/vote_poll.go index 54cb5e5..67ea16b 100644 --- a/internal/model/do/vote_poll.go +++ b/internal/model/do/vote_poll.go @@ -18,6 +18,6 @@ type VotePoll struct { MultiOption interface{} // 是否开启多选:1多选,0不多选 DeadlineTime *gtime.Time // 截止时间 CreateTime *gtime.Time // - UpdateTime *gtime.Time // Status interface{} // 投票活动状态:1:进行中,0已结束 + UpdateTime *gtime.Time // } diff --git a/internal/model/do/vote_record.go b/internal/model/do/vote_record.go index 3b9130e..26a7058 100644 --- a/internal/model/do/vote_record.go +++ b/internal/model/do/vote_record.go @@ -13,10 +13,10 @@ import ( type VoteRecord struct { g.Meta `orm:"table:vote_record, do:true"` Id interface{} // - UserId interface{} // 用户ID - VoteId interface{} // 投票活动ID - OptionId interface{} // 投票选项ID - VoteIndex interface{} // 已投票次数 + UserId interface{} // + VoteId interface{} // + OptionId interface{} // CreateTime *gtime.Time // + VoteIndex interface{} // UpdateTime *gtime.Time // } diff --git a/internal/model/entity/article.go b/internal/model/entity/article.go index 9484a4f..0b7ff15 100644 --- a/internal/model/entity/article.go +++ b/internal/model/entity/article.go @@ -11,7 +11,7 @@ import ( // Article is the golang structure for table article. type Article struct { Id int64 `json:"id" orm:"id" description:""` // - UserId int64 `json:"userId" orm:"user_id" description:"用户ID"` // 用户ID + UserId int64 `json:"userId" orm:"user_id" description:""` // ArticleTitle string `json:"articleTitle" orm:"article_title" description:"文章/视频标题"` // 文章/视频标题 ArticleContent string `json:"articleContent" orm:"article_content" description:"文章/视频内容"` // 文章/视频内容 VoteStatus int `json:"voteStatus" orm:"vote_status" description:"是否发起投票:1发起,0不发起"` // 是否发起投票:1发起,0不发起 diff --git a/internal/model/entity/user.go b/internal/model/entity/user.go index efbde32..7b8bcb6 100644 --- a/internal/model/entity/user.go +++ b/internal/model/entity/user.go @@ -10,11 +10,12 @@ import ( // User is the golang structure for table user. type User struct { - Id int64 `json:"id" orm:"id" description:""` // - Account string `json:"account" orm:"account" description:"精网号"` // 精网号 - Password string `json:"password" orm:"password" description:"用户密码"` // 用户密码 - Username string `json:"username" orm:"username" description:"用户名"` // 用户名 - Status uint `json:"status" orm:"status" description:""` // - CreateTime *gtime.Time `json:"createTime" orm:"create_time" description:""` // - UpdateTime *gtime.Time `json:"updateTime" orm:"update_time" description:""` // + Id int64 `json:"id" orm:"id" description:""` // + Account string `json:"account" orm:"account" description:""` // + Password string `json:"password" orm:"password" description:""` // + Username string `json:"username" orm:"username" description:""` // + Area string `json:"area" orm:"area" description:""` // + Status uint `json:"status" orm:"status" description:""` // + CreateTime *gtime.Time `json:"createTime" orm:"create_time" description:""` // + UpdateTime *gtime.Time `json:"updateTime" orm:"update_time" description:""` // } diff --git a/internal/model/entity/vote_poll.go b/internal/model/entity/vote_poll.go index 43459dc..192d964 100644 --- a/internal/model/entity/vote_poll.go +++ b/internal/model/entity/vote_poll.go @@ -16,6 +16,6 @@ type VotePoll struct { MultiOption int `json:"multiOption" orm:"multi_option" description:"是否开启多选:1多选,0不多选"` // 是否开启多选:1多选,0不多选 DeadlineTime *gtime.Time `json:"deadlineTime" orm:"deadline_time" description:"截止时间"` // 截止时间 CreateTime *gtime.Time `json:"createTime" orm:"create_time" description:""` // - UpdateTime *gtime.Time `json:"updateTime" orm:"update_time" description:""` // Status int `json:"status" orm:"status" description:"投票活动状态:1:进行中,0已结束"` // 投票活动状态:1:进行中,0已结束 + UpdateTime *gtime.Time `json:"updateTime" orm:"update_time" description:""` // } diff --git a/internal/model/entity/vote_record.go b/internal/model/entity/vote_record.go index 056a44e..a11c458 100644 --- a/internal/model/entity/vote_record.go +++ b/internal/model/entity/vote_record.go @@ -10,11 +10,11 @@ import ( // VoteRecord is the golang structure for table vote_record. type VoteRecord struct { - Id int64 `json:"id" orm:"id" description:""` // - UserId int64 `json:"userId" orm:"user_id" description:"用户ID"` // 用户ID - VoteId int64 `json:"voteId" orm:"vote_id" description:"投票活动ID"` // 投票活动ID - OptionId int64 `json:"optionId" orm:"option_id" description:"投票选项ID"` // 投票选项ID - VoteIndex int `json:"voteIndex" orm:"vote_index" description:"已投票次数"` // 已投票次数 - CreateTime *gtime.Time `json:"createTime" orm:"create_time" description:""` // - UpdateTime *gtime.Time `json:"updateTime" orm:"update_time" description:""` // + Id int64 `json:"id" orm:"id" description:""` // + UserId int64 `json:"userId" orm:"user_id" description:""` // + VoteId int64 `json:"voteId" orm:"vote_id" description:""` // + OptionId int64 `json:"optionId" orm:"option_id" description:""` // + CreateTime *gtime.Time `json:"createTime" orm:"create_time" description:""` // + VoteIndex int `json:"voteIndex" orm:"vote_index" description:""` // + UpdateTime *gtime.Time `json:"updateTime" orm:"update_time" description:""` // } diff --git a/internal/service/vote_record.go b/internal/service/vote_record.go index 339b602..3691286 100644 --- a/internal/service/vote_record.go +++ b/internal/service/vote_record.go @@ -7,6 +7,7 @@ import ( ) type IVoteRecord interface { + ExportVoteDetail(ctx context.Context, req *v1.GetExportFileReq) (res *v1.GetExportFileRes, err error) GetIndex(ctx context.Context, req *v1.GetIndexReq) (res *v1.GetIndexRes, err error) AddRecord(ctx context.Context, req *v1.AddRecordReq) (res *v1.AddRecordRes, err error) GetVote(ctx context.Context, req *v1.GetVoteReq) (res *v1.GetVoteRes, err error) diff --git a/manifest/config/config.yaml b/manifest/config/config.yaml index 881daa8..832baf5 100644 --- a/manifest/config/config.yaml +++ b/manifest/config/config.yaml @@ -14,4 +14,14 @@ database: default: link: "mysql:root:123456@tcp(127.0.0.1:3306)/link_test" createdAt: "create_time" - updatedAt: "update_time" \ No newline at end of file + updatedAt: "update_time" + +redis: + default: # 默认实例,用于常规操作 + address: "127.0.0.1:6379" + db: 0 + password: "" + cache: # 缓存专用实例 + address: "127.0.0.1:6379" + db: 1 + password: "" From 60c0d6a7fb807040fee78752b3f41114a374ad16 Mon Sep 17 00:00:00 2001 From: maziyang Date: Wed, 25 Jun 2025 11:43:31 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E4=B8=AD=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0redis?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/consts/consts.go | 11 +++++++ internal/logic/vote_record/add_record.go | 17 +++++----- internal/logic/vote_record/get_export_file.go | 23 ++++++++++++++ internal/logic/vote_record/get_index.go | 10 ------ internal/logic/vote_record/get_vote.go | 24 ++++++++++++++ internal/logic/vote_record/get_vote_detail.go | 26 ++++++++++++++-- internal/utils/cachettl.go | 13 ++++++++ internal/utils/delete_keys.go | 45 +++++++++++++++++++++++++++ main.go | 2 ++ 9 files changed, 149 insertions(+), 22 deletions(-) create mode 100644 internal/utils/cachettl.go create mode 100644 internal/utils/delete_keys.go diff --git a/internal/consts/consts.go b/internal/consts/consts.go index d709a2b..0d60042 100644 --- a/internal/consts/consts.go +++ b/internal/consts/consts.go @@ -1 +1,12 @@ package consts + +const ( + BASE_TTL = 600 + RANDOM_RANGE = 60 +) + +const ( + VOTE_DETAIL = "voteDetail" //投票名单查询 + ARTICLE = "article" //文章查询 + EXPORT_FILE = "exportFile" //导出数据查询 +) diff --git a/internal/logic/vote_record/add_record.go b/internal/logic/vote_record/add_record.go index 3499b32..b94f1c2 100644 --- a/internal/logic/vote_record/add_record.go +++ b/internal/logic/vote_record/add_record.go @@ -2,10 +2,13 @@ package vote_record import ( "context" + "fmt" "github.com/gogf/gf/v2/os/gtime" v1 "practice_ArticleVote_Go/api/vote_record/v1" + "practice_ArticleVote_Go/internal/consts" "practice_ArticleVote_Go/internal/dao" "practice_ArticleVote_Go/internal/model/do" + "practice_ArticleVote_Go/internal/utils" ) func (l *VoteRecordLogic) AddRecord(ctx context.Context, req *v1.AddRecordReq) (res *v1.AddRecordRes, err error) { @@ -22,19 +25,13 @@ func (l *VoteRecordLogic) AddRecord(ctx context.Context, req *v1.AddRecordReq) ( }) } _, err = dao.VoteRecord.Ctx(ctx).Data(records).Insert() - //_, err = dao.VoteRecord. - // Ctx(ctx). - // Data(do.VoteRecord{ - // UserId: req.UserId, - // VoteId: req.VoteId, - // OptionId: req.OptionId, - // VoteIndex: req.VoteIndex, - // CreateTime: gtime.Now(), - // UpdateTime: gtime.Now(), - // }).Insert() if err != nil { return nil, err } + voteDetailpattern := fmt.Sprintf(consts.VOTE_DETAIL+":%d:*", req.VoteId) + _, err = utils.DeleteKeys(ctx, voteDetailpattern) + ExportFilepattern := fmt.Sprintf(consts.EXPORT_FILE+":%d:*", req.VoteId) + _, err = utils.DeleteKeys(ctx, ExportFilepattern) res = &v1.AddRecordRes{} return res, nil } diff --git a/internal/logic/vote_record/get_export_file.go b/internal/logic/vote_record/get_export_file.go index eed0e03..59ad9c2 100644 --- a/internal/logic/vote_record/get_export_file.go +++ b/internal/logic/vote_record/get_export_file.go @@ -2,11 +2,29 @@ package vote_record import ( "context" + "encoding/json" + "fmt" "github.com/gogf/gf/v2/frame/g" v1 "practice_ArticleVote_Go/api/vote_record/v1" + "practice_ArticleVote_Go/internal/consts" + "practice_ArticleVote_Go/internal/utils" ) func (l *VoteRecordLogic) ExportVoteDetail(ctx context.Context, req *v1.GetExportFileReq) (res *v1.GetExportFileRes, err error) { + redis := g.Redis() + cacheKey := fmt.Sprintf( + consts.EXPORT_FILE+":%d:%s:%s:%s:%s", + req.VoteId, req.Username, req.Account, req.Area, req.OptionContent, + ) + data, _ := redis.Get(ctx, cacheKey) + fmt.Println("data", data) + if data != nil { + var cached v1.GetExportFileRes + err = json.Unmarshal([]byte(data.String()), &cached) + if err == nil { + return &cached, nil + } + } query := ` SELECT u.username, @@ -60,5 +78,10 @@ func (l *VoteRecordLogic) ExportVoteDetail(ctx context.Context, req *v1.GetExpor res = &v1.GetExportFileRes{ VoteList: voteList, } + buf, err := json.Marshal(res) + if err == nil { + ttl := utils.GetCacheTTL() + _ = redis.SetEX(ctx, cacheKey, string(buf), int64(ttl)) + } return res, err } diff --git a/internal/logic/vote_record/get_index.go b/internal/logic/vote_record/get_index.go index 6b09099..387759b 100644 --- a/internal/logic/vote_record/get_index.go +++ b/internal/logic/vote_record/get_index.go @@ -2,8 +2,6 @@ package vote_record import ( "context" - "fmt" - "github.com/gogf/gf/v2/frame/g" v1 "practice_ArticleVote_Go/api/vote_record/v1" "practice_ArticleVote_Go/internal/consts" "practice_ArticleVote_Go/internal/dao" @@ -13,14 +11,6 @@ import ( func (l *VoteRecordLogic) GetIndex(ctx context.Context, req *v1.GetIndexReq) (res *v1.GetIndexRes, err error) { today := time.Now().Format("2006-01-02") - redis := g.Redis() - _, err = redis.Set(ctx, "key", "Hello, GoFrame!") - value, err := redis.Get(ctx, "key") - fmt.Println(value) - if err != nil { - fmt.Println("Set error:", err) - return - } record, err := dao.VoteRecord. Ctx(ctx). Fields("vote_index"). diff --git a/internal/logic/vote_record/get_vote.go b/internal/logic/vote_record/get_vote.go index d5b11ce..f6a4397 100644 --- a/internal/logic/vote_record/get_vote.go +++ b/internal/logic/vote_record/get_vote.go @@ -2,15 +2,34 @@ package vote_record import ( "context" + "encoding/json" + "fmt" "github.com/gogf/gf/v2/errors/gcode" "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/os/gtime" v1 "practice_ArticleVote_Go/api/vote_record/v1" + "practice_ArticleVote_Go/internal/consts" "practice_ArticleVote_Go/internal/dao" + "practice_ArticleVote_Go/internal/utils" ) func (l *VoteRecordLogic) GetVote(ctx context.Context, req *v1.GetVoteReq) (res *v1.GetVoteRes, err error) { + redis := g.Redis() + cacheKey := fmt.Sprintf( + consts.ARTICLE+":%d", + req.ArticleId, + ) + fmt.Println(cacheKey) + data, _ := redis.Get(ctx, cacheKey) + fmt.Println("data", data) + if data != nil { + var cached v1.GetVoteRes + err = json.Unmarshal([]byte(data.String()), &cached) + if err == nil { + return &cached, nil + } + } articleRow, err := dao.Article.Ctx(ctx). Fields( dao.Article.Columns().ArticleTitle, @@ -87,5 +106,10 @@ func (l *VoteRecordLogic) GetVote(ctx context.Context, req *v1.GetVoteReq) (res OrderAsc(dao.VoteOption.Columns().OptionIndex). Scan(&res.OptionList) } + buf, err := json.Marshal(res) + if err == nil { + ttl := utils.GetCacheTTL() + _ = redis.SetEX(ctx, cacheKey, string(buf), int64(ttl)) + } return res, nil } diff --git a/internal/logic/vote_record/get_vote_detail.go b/internal/logic/vote_record/get_vote_detail.go index c30bb8a..2ce2f40 100644 --- a/internal/logic/vote_record/get_vote_detail.go +++ b/internal/logic/vote_record/get_vote_detail.go @@ -2,9 +2,12 @@ package vote_record import ( "context" + "encoding/json" "fmt" "github.com/gogf/gf/v2/frame/g" v1 "practice_ArticleVote_Go/api/vote_record/v1" + "practice_ArticleVote_Go/internal/consts" + "practice_ArticleVote_Go/internal/utils" ) func (l *VoteRecordLogic) GetVoteDetail(ctx context.Context, req *v1.GetVoteDetailReq) (res *v1.GetVoteDetailListRes, err error) { @@ -42,6 +45,22 @@ func (l *VoteRecordLogic) GetVoteDetail(ctx context.Context, req *v1.GetVoteDeta // return nil, err //} //return res, nil + redis := g.Redis() + cacheKey := fmt.Sprintf( + consts.VOTE_DETAIL+":%d:%d:%d:%s:%s:%s:%s", + req.VoteId, req.Page, req.Size, + req.Username, req.Account, req.Area, req.OptionContent, + ) + fmt.Println(cacheKey) + data, _ := redis.Get(ctx, cacheKey) + fmt.Println("data", data) + if data != nil { + var cached v1.GetVoteDetailListRes + err = json.Unmarshal([]byte(data.String()), &cached) + if err == nil { + return &cached, nil + } + } query := ` SELECT u.username, @@ -65,9 +84,7 @@ func (l *VoteRecordLogic) GetVoteDetail(ctx context.Context, req *v1.GetVoteDeta JOIN user u ON u.id = uv.user_id WHERE 1=1 ` - conditions := []interface{}{req.VoteId} - if req.OptionContent != "" { query += " AND uv.option_contents LIKE ?" conditions = append(conditions, "%"+req.OptionContent+"%") @@ -102,5 +119,10 @@ func (l *VoteRecordLogic) GetVoteDetail(ctx context.Context, req *v1.GetVoteDeta return nil, err } res.VoteList = voteList + buf, merr := json.Marshal(res) + if merr == nil { + ttl := utils.GetCacheTTL() + _ = redis.SetEX(ctx, cacheKey, string(buf), int64(ttl)) + } return res, nil } diff --git a/internal/utils/cachettl.go b/internal/utils/cachettl.go new file mode 100644 index 0000000..7f7df19 --- /dev/null +++ b/internal/utils/cachettl.go @@ -0,0 +1,13 @@ +package utils + +import ( + "math/rand" + "practice_ArticleVote_Go/internal/consts" + "time" +) + +func GetCacheTTL() time.Duration { + baseTTL := consts.BASE_TTL + randomNumber := rand.Intn(consts.RANDOM_RANGE) + return time.Duration(baseTTL+randomNumber) * time.Second +} diff --git a/internal/utils/delete_keys.go b/internal/utils/delete_keys.go new file mode 100644 index 0000000..d71fdec --- /dev/null +++ b/internal/utils/delete_keys.go @@ -0,0 +1,45 @@ +package utils + +import ( + "context" + "fmt" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/util/gconv" +) + +func DeleteKeys(ctx context.Context, pattern string) (int, error) { + redis := g.Redis() + var ( + cursor uint64 + totalKeys int + batchSize = 100 + ) + g.Log().Debugf(ctx, "开始删除匹配模式 %q 的缓存键", pattern) + for { + result, err := redis.Do(ctx, "SCAN", cursor, "MATCH", pattern, "COUNT", batchSize) + if err != nil { + return totalKeys, fmt.Errorf("SCAN 失败: %v", err) + } + arr := result.Array() + fmt.Println("arr:", arr) + cursor = gconv.Uint64(arr[0]) + rawKeys := gconv.Strings(arr[1]) + var keys []string + for _, k := range rawKeys { + keys = append(keys, k) + } + fmt.Println("keys:", keys) + if len(keys) > 0 { + deleted, err := redis.Del(ctx, keys...) + if err != nil { + g.Log().Warningf(ctx, "缓存删除异常: %v", err) + } + totalKeys += int(deleted) + g.Log().Debugf(ctx, "本次删除 %d/%d 个键", deleted, len(keys)) + } + if cursor == 0 { + break + } + } + return totalKeys, nil +} diff --git a/main.go b/main.go index dcf78da..81c91e5 100644 --- a/main.go +++ b/main.go @@ -9,6 +9,8 @@ import ( "github.com/gogf/gf/v2/os/gctx" + _ "github.com/gogf/gf/contrib/nosql/redis/v2" + "practice_ArticleVote_Go/internal/cmd" ) From 9a0dd6dfe2b012c6c95087b5382d6dca10dcbf16 Mon Sep 17 00:00:00 2001 From: maziyang Date: Wed, 25 Jun 2025 13:38:00 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E4=BD=BF=E7=94=A8redis=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/vote_record/v1/vote_record.go | 1 + internal/logic/vote_record/add_record.go | 12 ++++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/api/vote_record/v1/vote_record.go b/api/vote_record/v1/vote_record.go index 5766300..bb2e5d8 100644 --- a/api/vote_record/v1/vote_record.go +++ b/api/vote_record/v1/vote_record.go @@ -74,6 +74,7 @@ type GetIndexRes struct { type AddRecordReq struct { g.Meta `path:"/addRecord" method:"post" dc:""` + ArticleId int ` v:"required" json:"articleId" dc:"<ID>"` UserId int `v:"required" json:"userId" dc:"<用户>ID"` VoteId int `v:"required" json:"voteId" dc:"<投票活动>ID"` OptionId []int `v:"required" json:"optionId" dc:"<投票选项>ID"` diff --git a/internal/logic/vote_record/add_record.go b/internal/logic/vote_record/add_record.go index b94f1c2..9e41e77 100644 --- a/internal/logic/vote_record/add_record.go +++ b/internal/logic/vote_record/add_record.go @@ -3,6 +3,7 @@ package vote_record import ( "context" "fmt" + "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/os/gtime" v1 "practice_ArticleVote_Go/api/vote_record/v1" "practice_ArticleVote_Go/internal/consts" @@ -28,10 +29,13 @@ func (l *VoteRecordLogic) AddRecord(ctx context.Context, req *v1.AddRecordReq) ( if err != nil { return nil, err } - voteDetailpattern := fmt.Sprintf(consts.VOTE_DETAIL+":%d:*", req.VoteId) - _, err = utils.DeleteKeys(ctx, voteDetailpattern) - ExportFilepattern := fmt.Sprintf(consts.EXPORT_FILE+":%d:*", req.VoteId) - _, err = utils.DeleteKeys(ctx, ExportFilepattern) + voteDetailPattern := fmt.Sprintf(consts.VOTE_DETAIL+":%d:*", req.VoteId) + _, err = utils.DeleteKeys(ctx, voteDetailPattern) + exportFilePattern := fmt.Sprintf(consts.EXPORT_FILE+":%d:*", req.VoteId) + _, err = utils.DeleteKeys(ctx, exportFilePattern) + articleAndVote := fmt.Sprintf(consts.ARTICLE+":%d", req.ArticleId) + redis := g.Redis() + _, err = redis.Del(ctx, articleAndVote) res = &v1.AddRecordRes{} return res, nil }