Skip to content

Commit

Permalink
feat(controller, poll): create new poll
Browse files Browse the repository at this point in the history
  • Loading branch information
greenhat616 committed Aug 8, 2023
1 parent 761bdd1 commit 80ac1c8
Show file tree
Hide file tree
Showing 15 changed files with 169 additions and 16 deletions.
2 changes: 1 addition & 1 deletion api/admin/v1/modify_sentence.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ type ModifySentenceReq struct {
}

type ModifySentenceRes struct {
model.PollSchema
model.PollElement
}
2 changes: 1 addition & 1 deletion api/poll/v1/cancel.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ type CancelPollReq struct {
}

type CancelPollRes struct {
model.PollSchema
model.PollElement
PollData model.PollData `json:"poll_data" dc:"投票数据"`
}
2 changes: 1 addition & 1 deletion api/poll/v1/detail.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ type GetPollDetailReq struct {
}

type GetPollDetailRes struct {
model.PollSchema
model.PollElement
Records []model.PollRecord `json:"logs" dc:"投票记录"`
}
2 changes: 1 addition & 1 deletion api/poll/v1/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ type GetPollsReq struct {
}

type GetPollsRes []struct {
model.PollSchema
model.PollElement
PollData model.PollData `json:"poll_data" dc:"投票数据"`
}
4 changes: 2 additions & 2 deletions api/poll/v1/new.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ type NewPollReq struct {
}

type NewPollRes struct {
model.PollSchema
RemainPending int `json:"remain_pending" dc:"剩余待处理"`
Poll model.PollElement `json:"poll" dc:"投票内容"`
RemainPending int `json:"remain_pending" dc:"剩余待处理"`
}
2 changes: 1 addition & 1 deletion api/poll/v1/poll.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ type PollReq struct {

// PollRes 成功返回句子的投票记录
type PollRes struct {
model.PollSchema
model.PollElement
PollData model.PollData `json:"poll_data" dc:"投票数据"`
}
4 changes: 4 additions & 0 deletions internal/consts/poll.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package consts

const (
PollMaxOpenPolls = 30 // 最大开放投票数
)

// PollMethod 审核员投票的类型
type PollMethod int

Expand Down
66 changes: 65 additions & 1 deletion internal/controller/poll/poll_v1_new_poll.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,76 @@ package poll
import (
"context"

"github.com/hitokoto-osc/reviewer/internal/model"
"github.com/hitokoto-osc/reviewer/utility/time"

"golang.org/x/sync/errgroup"

"github.com/hitokoto-osc/reviewer/internal/model/entity"

"github.com/hitokoto-osc/reviewer/internal/consts"
"github.com/hitokoto-osc/reviewer/internal/service"

"github.com/gogf/gf/v2/errors/gcode"
"github.com/gogf/gf/v2/errors/gerror"

v1 "github.com/hitokoto-osc/reviewer/api/poll/v1"
)

func (c *ControllerV1) NewPoll(ctx context.Context, req *v1.NewPollReq) (res *v1.NewPollRes, err error) {
return nil, gerror.NewCode(gcode.CodeNotImplemented)
count, err := service.Poll().CountOpenedPoll(ctx)
if err != nil {
return nil, err
}
if count > consts.PollMaxOpenPolls {
return nil, gerror.NewCode(gcode.CodeOperationFailed, "待投票的句子过多,暂时无法创建新投票。")
}

var topPending *entity.Pending
eg, egCtx := errgroup.WithContext(ctx)
eg.Go(func() error {
topPending, err = service.Hitokoto().TopPendingPollNotOpen(egCtx)
return err
})
eg.Go(func() error {
count, err = service.Hitokoto().CountPendingPollNotOpen(egCtx)
return err
})
if err = eg.Wait(); err != nil {
return nil, gerror.Wrap(err, "get top pending failed")
} else if topPending == nil {
return nil, gerror.NewCode(gcode.CodeOperationFailed, "当前无待投票句子。")
}
poll, err := service.Poll().CreatePollByPending(ctx, topPending)
if err != nil {
return nil, gerror.WrapCode(gcode.CodeOperationFailed, err, "创建投票失败")
}
res = &v1.NewPollRes{
Poll: model.PollElement{
SentenceUUID: poll.SentenceUuid,
Sentence: model.HitokotoV1Schema{
ID: uint(topPending.Id),
UUID: topPending.Uuid,
Hitokoto: topPending.Hitokoto,
Type: consts.HitokotoType(topPending.Type),
From: topPending.From,
FromWho: topPending.FromWho,
Creator: topPending.Creator,
CreatorUID: uint(topPending.CreatorUid),
Reviewer: uint(topPending.Reviewer),
Status: consts.HitokotoStatusPending,
PollStatus: consts.PollStatus(poll.Status),
CreatedAt: topPending.CreatedAt,
},
Status: consts.PollStatus(poll.Status),
Accept: poll.Accept,
Reject: poll.Reject,
NeedModify: poll.NeedEdited,
NeedCommonUserPoll: poll.NeedUserPoll,
CreatedAt: (*time.Time)(poll.CreatedAt),
UpdatedAt: (*time.Time)(poll.UpdatedAt),
},
RemainPending: count - 1,
}
return res, nil
}
17 changes: 17 additions & 0 deletions internal/logic/hitokoto/pending.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"context"
"time"

"github.com/hitokoto-osc/reviewer/internal/consts"

"github.com/gogf/gf/v2/database/gdb"
"github.com/hitokoto-osc/reviewer/internal/dao"
"github.com/hitokoto-osc/reviewer/internal/model/do"
Expand All @@ -18,3 +20,18 @@ func (s *sHitokoto) GetPendingByUUID(ctx context.Context, uuid string) (hitokoto
}).Where(do.Pending{Uuid: uuid}).Scan(&hitokoto)
return
}

func (s *sHitokoto) TopPendingPollNotOpen(ctx context.Context) (hitokoto *entity.Pending, err error) {
err = dao.Pending.Ctx(ctx).
Where(dao.Pending.Columns().PollStatus, consts.PollStatusNotOpen).
OrderAsc(dao.Pending.Columns().CreatedAt).
Scan(&hitokoto)
return
}

func (s *sHitokoto) CountPendingPollNotOpen(ctx context.Context) (count int, err error) {
count, err = dao.Pending.Ctx(ctx).
Where(dao.Pending.Columns().PollStatus, consts.PollStatusNotOpen).
Count()
return
}
69 changes: 66 additions & 3 deletions internal/logic/poll/poll.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@ import (
"context"
"time"

"github.com/gogf/gf/v2/os/gtime"

"github.com/google/uuid"

"github.com/gogf/gf/v2/frame/g"

"github.com/gogf/gf/v2/errors/gerror"

"github.com/hitokoto-osc/reviewer/internal/consts"

"github.com/hitokoto-osc/reviewer/internal/service"

"github.com/gogf/gf/v2/database/gdb"
Expand All @@ -22,11 +32,64 @@ func New() service.IPoll {
return &sPoll{}
}

func (s *sPoll) GetPollBySentenceUUID(ctx context.Context, uuid string) (poll *entity.Poll, err error) {
func (s *sPoll) GetPollBySentenceUUID(ctx context.Context, uuidStr string) (poll *entity.Poll, err error) {
err = dao.Poll.Ctx(ctx).Cache(gdb.CacheOption{
Duration: time.Minute * 10,
Name: "poll:uuid:" + uuid,
Name: "poll:uuid:" + uuidStr,
Force: false,
}).Where(do.Poll{SentenceUuid: uuid}).Scan(&poll)
}).Where(do.Poll{SentenceUuid: uuidStr}).Scan(&poll)
return
}

func (s *sPoll) CountOpenedPoll(ctx context.Context) (int, error) {
return dao.Poll.Ctx(ctx).Where(dao.Poll.Columns().Status, consts.PollStatusOpen).Count()
}

func (s *sPoll) CreatePollByPending(ctx context.Context, pending *entity.Pending) (*entity.Poll, error) {
if pending == nil {
return nil, gerror.New("pending is nil")
}
var poll *entity.Poll
err := g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
if pending.Uuid == "" {
uuidInstance, err := uuid.NewRandom()
if err != nil {
return nil
}
pending.Uuid = uuidInstance.String()
}
// 修改 pending 状态
affectedRows, err := dao.Pending.Ctx(ctx).TX(tx).Where(dao.Pending.Columns().Id, pending.Id).Data(g.Map{
dao.Pending.Columns().PollStatus: consts.PollStatusOpen,
dao.Pending.Columns().Uuid: pending.Uuid,
}).UpdateAndGetAffected()
if err != nil {
return err
} else if affectedRows == 0 {
return gerror.New("pending affectedRows is 0")
}
// 创建投票
poll = &entity.Poll{
SentenceUuid: pending.Uuid,
Status: int(consts.PollStatusOpen),
IsExpandedPoll: 0,
Accept: 0,
Reject: 0,
NeedEdited: 0,
NeedUserPoll: 0,
PendingId: pending.Id,
CreatedAt: gtime.Now(),
UpdatedAt: gtime.Now(),
}
insertedID, err := dao.Poll.Ctx(ctx).TX(tx).Data(poll).InsertAndGetId()
if err != nil {
return err
}
poll.Id = int(insertedID)
return nil
})
if err != nil {
return nil, err
}
return poll, nil
}
2 changes: 1 addition & 1 deletion internal/logic/user/poll_log.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ func (s *sUser) GetUserPollLogsWithPollResult(
if e != nil {
return e
}
collections[index].PollInfo = &model.PollSchema{
collections[index].PollInfo = &model.PollElement{
SentenceUUID: poll.SentenceUuid,
Status: consts.PollStatus(poll.Status),
Accept: poll.Accept,
Expand Down
3 changes: 2 additions & 1 deletion internal/model/poll.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ type PollData struct {
Method consts.PollMethod `json:"method" dc:"投票方式"`
}

type PollSchema struct {
type PollElement struct {
SentenceUUID string `json:"sentence_uuid" dc:"句子 UUID"`
Sentence HitokotoV1Schema `json:"sentence" dc:"句子"`
Status consts.PollStatus `json:"status" dc:"投票状态"`
Accept int `json:"accept" dc:"赞同票数"`
Reject int `json:"reject" dc:"反对票数"`
Expand Down
4 changes: 2 additions & 2 deletions internal/model/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ type UserPollLogWithSentence struct {

type UserPollElement struct {
UserPollLogWithSentence
PollInfo *PollSchema `json:"poll_info" dc:"投票信息"`
Marks []int `json:"marks" dc:"投票标记"`
PollInfo *PollElement `json:"poll_info" dc:"投票信息"`
Marks []int `json:"marks" dc:"投票标记"`
}

type UserPollResult struct {
Expand Down
2 changes: 2 additions & 0 deletions internal/service/hitokoto.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion internal/service/poll.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 80ac1c8

Please sign in to comment.