Browse Source

投票功能实现

master
maziyang 1 week ago
parent
commit
ddebf57507
  1. 2
      api/vote_poll/v1/vote_poll.go
  2. 15
      api/vote_poll/vote_poll.go
  3. 48
      api/vote_record/v1/vote_record.go
  4. 17
      api/vote_record/vote_record.go
  5. 7
      internal/cmd/cmd.go
  6. 3
      internal/consts/vote.go
  7. 5
      internal/controller/vote_poll/vote_poll.go
  8. 15
      internal/controller/vote_poll/vote_poll_new.go
  9. 14
      internal/controller/vote_poll/vote_poll_v1_create_vote.go
  10. 5
      internal/controller/vote_record/vote_record.go
  11. 15
      internal/controller/vote_record/vote_record_new.go
  12. 12
      internal/controller/vote_record/vote_record_v1_add_record.go
  13. 12
      internal/controller/vote_record/vote_record_v1_get_index.go
  14. 12
      internal/controller/vote_record/vote_record_v1_get_vote.go
  15. 2
      internal/dao/internal/vote_option.go
  16. 9
      internal/logic/logic.go
  17. 40
      internal/logic/vote_record/add_record.go
  18. 31
      internal/logic/vote_record/get_index.go
  19. 91
      internal/logic/vote_record/get_vote.go
  20. 7
      internal/logic/vote_record/vote_record_logic.go
  21. 1
      internal/model/do/vote_option.go
  22. 1
      internal/model/entity/vote_option.go
  23. 17
      internal/service/vote_record.go
  24. 2
      main.go

2
api/vote_poll/v1/vote_poll.go

@ -12,6 +12,6 @@ type CreateVoteReq struct {
MultiSelection int `v:"required" dc:"支持多选"`
DeadlineTime *gtime.Time `v:"required" dc:"截止时间"`
}
type CreateVoteResp struct {
type CreateVoteRes struct {
Id int64 `json:"id" dc:"投票 id"`
}

15
api/vote_poll/vote_poll.go

@ -0,0 +1,15 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package vote_poll
import (
"context"
"practice_ArticleVote_Go/api/vote_poll/v1"
)
type IVotePollV1 interface {
CreateVote(ctx context.Context, req *v1.CreateVoteReq) (res *v1.CreateVoteRes, err error)
}

48
api/vote_record/v1/vote_record.go

@ -0,0 +1,48 @@
package v1
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
type GetVoteReq struct {
g.Meta `path:"/getVote" method:"get" tags:"<获取文章及投票活动>"`
ArticleId int `json:"articleId" v:"required" dc:"<文章>ID"`
}
type OptionRes struct {
Id int `json:"id" dc:"<选项>ID"`
OptionContent string `json:"optionContent" dc:"选项内容"`
Count int `json:"count" dc:"已投人数"`
}
type GetVoteRes struct {
ArticleTitle string `json:"articleTitle" dc:"文章标题"`
ArticleContent string `json:"articleContent" dc:"文章内容"`
VoteId int `json:"voteId" dc:"投票活动ID"`
VoteStatus int `json:"voteStatus" dc:"是否投票"`
VoteTitle string `json:"voteTitle" dc:"投票标题"`
MultiOption int `json:"multiOption" dc:"是否多选"`
OptionList []OptionRes `json:"optionList" dc:"选项列表"`
Username string `json:"username" dc:"创建者名称"`
DeadlineTime *gtime.Time `json:"deadlineTime" dc:"活动截止时间"`
VotePollStatus int `json:"votePollStatus" dc:"投票活动状态"`
ParticipationNumber int `json:"participationNumber" dc:"参与人数"`
}
type GetIndexReq struct {
g.Meta `path:"/getIndex" method:"get" dc:"获取今天的投票次数"`
UserId int `v:"required" json:"userId" dc:"要投票的用户ID"`
VoteId int `v:"required" json:"voteId" dc:"投票活动的ID"`
}
type GetIndexRes struct {
RemainTimes int `json:"voteIndex" dc:"剩余次数"`
}
type AddRecordReq struct {
g.Meta `path:"/addRecord" method:"post" dc:"<UNK>"`
UserId int `v:"required" json:"userId" dc:"<用户>ID"`
VoteId int `v:"required" json:"voteId" dc:"<投票活动>ID"`
OptionId []int `v:"required" json:"optionId" dc:"<投票选项>ID"`
VoteIndex int `v:"required" json:"voteIndex" dc:"<第几次投票>"`
}
type AddRecordRes struct {
}

17
api/vote_record/vote_record.go

@ -0,0 +1,17 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package vote_record
import (
"context"
"practice_ArticleVote_Go/api/vote_record/v1"
)
type IVoteRecordV1 interface {
GetVote(ctx context.Context, req *v1.GetVoteReq) (res *v1.GetVoteRes, 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)
}

7
internal/cmd/cmd.go

@ -2,12 +2,11 @@ package cmd
import (
"context"
vr "practice_ArticleVote_Go/internal/controller/vote_record"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/os/gcmd"
"practice_ArticleVote_Go/internal/controller/hello"
)
var (
@ -17,10 +16,10 @@ var (
Brief: "start http server",
Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
s := g.Server()
s.Group("/", func(group *ghttp.RouterGroup) {
s.Group("/vote", func(group *ghttp.RouterGroup) {
group.Middleware(ghttp.MiddlewareHandlerResponse)
group.Bind(
hello.NewV1(),
vr.NewV1(),
)
})
s.Run()

3
internal/consts/vote.go

@ -11,3 +11,6 @@ const (
VoteTypeSingle = 0 //单选
VoteTypeMultiple = 1 //多选
)
// 最大投票次数
const MAX_VOTE_TIMES = 3

5
internal/controller/vote_poll/vote_poll.go

@ -0,0 +1,5 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package vote_poll

15
internal/controller/vote_poll/vote_poll_new.go

@ -0,0 +1,15 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package vote_poll
import (
"practice_ArticleVote_Go/api/vote_poll"
)
type ControllerV1 struct{}
func NewV1() vote_poll.IVotePollV1 {
return &ControllerV1{}
}

14
internal/controller/vote_poll/vote_poll_v1_create_vote.go

@ -0,0 +1,14 @@
package vote_poll
import (
"context"
"github.com/gogf/gf/v2/errors/gcode"
"github.com/gogf/gf/v2/errors/gerror"
"practice_ArticleVote_Go/api/vote_poll/v1"
)
func (c *ControllerV1) CreateVote(ctx context.Context, req *v1.CreateVoteReq) (res *v1.CreateVoteRes, err error) {
return nil, gerror.NewCode(gcode.CodeNotImplemented)
}

5
internal/controller/vote_record/vote_record.go

@ -0,0 +1,5 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package vote_record

15
internal/controller/vote_record/vote_record_new.go

@ -0,0 +1,15 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package vote_record
import (
"practice_ArticleVote_Go/api/vote_record"
)
type ControllerV1 struct{}
func NewV1() vote_record.IVoteRecordV1 {
return &ControllerV1{}
}

12
internal/controller/vote_record/vote_record_v1_add_record.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) AddRecord(ctx context.Context, req *v1.AddRecordReq) (res *v1.AddRecordRes, err error) {
return service.NewVoteRecordService().AddRecord(ctx, req)
}

12
internal/controller/vote_record/vote_record_v1_get_index.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) GetIndex(ctx context.Context, req *v1.GetIndexReq) (res *v1.GetIndexRes, err error) {
return service.NewVoteRecordService().GetIndex(ctx, req)
}

12
internal/controller/vote_record/vote_record_v1_get_vote.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) GetVote(ctx context.Context, req *v1.GetVoteReq) (res *v1.GetVoteRes, err error) {
return service.NewVoteRecordService().GetVote(ctx, req)
}

2
internal/dao/internal/vote_option.go

@ -24,6 +24,7 @@ type VoteOptionColumns struct {
Id string //
VoteId string // 投票活动ID
OptionContent string // 选项内容
OptionIndex string // 第几个选项
Status string // 选项状态
CreateTime string //
}
@ -33,6 +34,7 @@ var voteOptionColumns = VoteOptionColumns{
Id: "id",
VoteId: "vote_id",
OptionContent: "option_content",
OptionIndex: "option_index",
Status: "status",
CreateTime: "create_time",
}

9
internal/logic/logic.go

@ -0,0 +1,9 @@
// ==========================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package logic
import (
_ "practice_ArticleVote_Go/internal/logic/vote_record"
)

40
internal/logic/vote_record/add_record.go

@ -0,0 +1,40 @@
package vote_record
import (
"context"
"github.com/gogf/gf/v2/os/gtime"
v1 "practice_ArticleVote_Go/api/vote_record/v1"
"practice_ArticleVote_Go/internal/dao"
"practice_ArticleVote_Go/internal/model/do"
)
func (l *VoteRecordLogic) AddRecord(ctx context.Context, req *v1.AddRecordReq) (res *v1.AddRecordRes, err error) {
now := gtime.Now()
records := make([]do.VoteRecord, 0, len(req.OptionId))
for _, optionId := range req.OptionId {
records = append(records, do.VoteRecord{
UserId: req.UserId,
VoteId: req.VoteId,
OptionId: optionId,
VoteIndex: req.VoteIndex,
CreateTime: now,
UpdateTime: now,
})
}
_, 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
}
res = &v1.AddRecordRes{}
return res, nil
}

31
internal/logic/vote_record/get_index.go

@ -0,0 +1,31 @@
package vote_record
import (
"context"
v1 "practice_ArticleVote_Go/api/vote_record/v1"
"practice_ArticleVote_Go/internal/consts"
"practice_ArticleVote_Go/internal/dao"
"time"
)
func (l *VoteRecordLogic) GetIndex(ctx context.Context, req *v1.GetIndexReq) (res *v1.GetIndexRes, err error) {
today := time.Now().Format("2006-01-02")
record, err := dao.VoteRecord.
Ctx(ctx).
Fields("vote_index").
Where(dao.VoteRecord.Columns().UserId, req.UserId).
Where(dao.VoteRecord.Columns().VoteId, req.VoteId).
Where("DATE("+dao.VoteRecord.Columns().CreateTime+") = ?", today).
OrderDesc(dao.VoteRecord.Columns().VoteIndex).
One()
if err != nil {
return nil, err
}
usedTimes := record["vote_index"].Int()
remainTimes := consts.MAX_VOTE_TIMES - usedTimes
if remainTimes < 0 {
remainTimes = 0
}
return &v1.GetIndexRes{RemainTimes: remainTimes}, nil
}

91
internal/logic/vote_record/get_vote.go

@ -0,0 +1,91 @@
package vote_record
import (
"context"
"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/dao"
)
func (l *VoteRecordLogic) GetVote(ctx context.Context, req *v1.GetVoteReq) (res *v1.GetVoteRes, err error) {
articleRow, err := dao.Article.Ctx(ctx).
Fields(
dao.Article.Columns().ArticleTitle,
dao.Article.Columns().ArticleContent,
dao.Article.Columns().VoteStatus,
dao.User.Columns().Username+" AS username",
).
LeftJoin(dao.User.Table(), dao.Article.Table()+"."+dao.Article.Columns().UserId+" = "+
dao.User.Table()+"."+dao.User.Columns().Id).
Where(dao.Article.Columns().Id, req.ArticleId).
One()
if err != nil {
return nil, err
}
if articleRow == nil {
return nil, gerror.NewCode(gcode.CodeNotFound, "文章不存在")
}
res = &v1.GetVoteRes{
ArticleTitle: articleRow[dao.Article.Columns().ArticleTitle].String(),
ArticleContent: articleRow[dao.Article.Columns().ArticleContent].String(),
VoteStatus: articleRow[dao.Article.Columns().VoteStatus].Int(),
Username: articleRow[dao.User.Columns().Username].String(),
}
if articleRow[dao.Article.Columns().VoteStatus].Int() == 1 {
votePoll, err := dao.VotePoll.Ctx(ctx).
Fields(
dao.VotePoll.Table()+".id AS "+dao.VotePoll.Columns().Id,
dao.VotePoll.Columns().VoteTitle,
dao.VotePoll.Columns().MultiOption,
dao.VotePoll.Columns().Status,
dao.VotePoll.Columns().DeadlineTime,
"( SELECT COUNT(DISTINCT "+dao.VoteRecord.Columns().UserId+") "+
" FROM "+dao.VoteRecord.Table()+
" WHERE "+dao.VoteRecord.Columns().VoteId+" = "+dao.VotePoll.Table()+"."+dao.VotePoll.Columns().Id+
" ) AS totalCount",
).
Where(dao.VotePoll.Columns().ArticleId, req.ArticleId).
One()
if err != nil {
return nil, err
}
res.VoteId = votePoll[dao.VotePoll.Columns().Id].Int()
res.VoteTitle = votePoll[dao.VotePoll.Columns().VoteTitle].String()
res.MultiOption = votePoll[dao.VotePoll.Columns().MultiOption].Int()
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
_, err = dao.VotePoll.Ctx(ctx).Data(g.Map{
dao.VotePoll.Columns().Status: 0,
}).WherePri(res.VoteId).Update()
if err != nil {
return nil, err
}
}
//var optionList []v1.OptionRes
err = dao.VoteOption.Ctx(ctx).
Fields(
dao.VoteOption.Table()+"."+dao.VoteOption.Columns().Id,
dao.VoteOption.Table()+"."+dao.VoteOption.Columns().OptionContent,
" IFNULL(vote_count.count, 0) AS count ",
).
LeftJoin(
" ( "+
"SELECT "+dao.VoteRecord.Columns().OptionId+
", COUNT(*) AS count "+
" FROM "+dao.VoteRecord.Table()+
" GROUP BY "+dao.VoteRecord.Columns().OptionId+
" ) AS vote_count",
dao.VoteOption.Table()+"."+dao.VoteOption.Columns().Id+" = "+"vote_count."+dao.VoteRecord.Columns().OptionId,
).
Where(dao.VoteOption.Table()+"."+dao.VoteOption.Columns().VoteId, votePoll[dao.VotePoll.Columns().Id].Int()).
OrderAsc(dao.VoteOption.Columns().OptionIndex).
Scan(&res.OptionList)
}
return res, nil
}

7
internal/logic/vote_record/vote_record_logic.go

@ -0,0 +1,7 @@
package vote_record
type VoteRecordLogic struct{}
func NewVoteRecordLogic() *VoteRecordLogic {
return &VoteRecordLogic{}
}

1
internal/model/do/vote_option.go

@ -15,6 +15,7 @@ type VoteOption struct {
Id interface{} //
VoteId interface{} // 投票活动ID
OptionContent interface{} // 选项内容
OptionIndex interface{} // 第几个选项
Status interface{} // 选项状态
CreateTime *gtime.Time //
}

1
internal/model/entity/vote_option.go

@ -13,6 +13,7 @@ type VoteOption struct {
Id int64 `json:"id" orm:"id" description:""` //
VoteId int64 `json:"voteId" orm:"vote_id" description:"投票活动ID"` // 投票活动ID
OptionContent string `json:"optionContent" orm:"option_content" description:"选项内容"` // 选项内容
OptionIndex int `json:"optionIndex" orm:"option_index" description:"第几个选项"` // 第几个选项
Status uint `json:"status" orm:"status" description:"选项状态"` // 选项状态
CreateTime *gtime.Time `json:"createTime" orm:"create_time" description:""` //
}

17
internal/service/vote_record.go

@ -0,0 +1,17 @@
package service
import (
"context"
v1 "practice_ArticleVote_Go/api/vote_record/v1"
"practice_ArticleVote_Go/internal/logic/vote_record"
)
type IVoteRecord interface {
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)
}
func NewVoteRecordService() IVoteRecord {
return vote_record.NewVoteRecordLogic()
}

2
main.go

@ -5,6 +5,8 @@ import (
_ "practice_ArticleVote_Go/internal/packed"
_ "practice_ArticleVote_Go/internal/logic"
"github.com/gogf/gf/v2/os/gctx"
"practice_ArticleVote_Go/internal/cmd"

Loading…
Cancel
Save