diff --git a/models/reward_operate_record.go b/models/reward_operate_record.go index 889d291fa..394fba1cf 100644 --- a/models/reward_operate_record.go +++ b/models/reward_operate_record.go @@ -141,18 +141,22 @@ func (r RewardOperateRecord) ToShow() RewardOperateRecordShow { return RewardOperateRecordShow{ SerialNo: r.SerialNo, Date: r.CreatedUnix, - Tittle: r.Tittle, OperateType: r.OperateType, Amount: r.Amount, + Remark: r.Remark, } } type RewardOperateRecordShow struct { SerialNo string Date timeutil.TimeStamp - Tittle string + Status string OperateType string Amount int64 + Action Action + Cloudbrain Cloudbrain + SourceType SourceType + Remark string } func getPointOperateRecord(tl *RewardOperateRecord) (*RewardOperateRecord, error) { @@ -207,15 +211,16 @@ func SumRewardAmountInTaskPeriod(rewardType string, sourceType string, userId in } type RewardOperateContext struct { - SourceType SourceType - SourceId string - Tittle string - Remark string - Reward Reward - TargetUserId int64 - RequestId string - OperateType RewardOperateType - RejectPolicy LimiterRejectPolicy + SourceType SourceType + SourceId string + Tittle string + Remark string + Reward Reward + TargetUserId int64 + RequestId string + OperateType RewardOperateType + RejectPolicy LimiterRejectPolicy + PermittedNegative bool } type Reward struct { diff --git a/routers/reward/point/point.go b/routers/reward/point/point.go index e1a751495..edf41cd72 100644 --- a/routers/reward/point/point.go +++ b/routers/reward/point/point.go @@ -2,6 +2,7 @@ package point import ( "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/routers/response" "code.gitea.io/gitea/services/reward" @@ -9,6 +10,8 @@ import ( "net/http" ) +const tplPoint base.TplName = "/reward/point" + type AccountResponse struct { AccountCode string Balance int64 @@ -24,7 +27,6 @@ func GetPointAccount(ctx *context.Context) { return } res := &AccountResponse{ - AccountCode: a.AccountCode, Balance: a.Balance, TotalEarned: a.TotalEarned, TotalConsumed: a.TotalConsumed, @@ -75,3 +77,7 @@ func OperatePointAccountBalance(ctx *context.Context, req models.AdminRewardOper } ctx.JSON(http.StatusOK, response.Success()) } + +func GetPointPage(ctx *context.Context) { + ctx.HTML(200, tplPoint) +} diff --git a/routers/routes/routes.go b/routers/routes/routes.go index 946f9ddd2..ea2980364 100755 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -595,6 +595,7 @@ func RegisterRoutes(m *macaron.Macaron) { }) m.Group("/reward/point", func() { + m.Get("", point.GetPointPage) m.Get("/limiter/list", point.GetPointLimitConfigList) m.Post("/limiter/add", bindIgnErr(models.LimitConfigVO{}), point.AddPointLimitConfig) m.Post("/limiter/delete", point.DeletePointLimitConfig) diff --git a/services/reward/admin_operate.go b/services/reward/admin_operate.go index 1fdd942d2..b8490a3a8 100644 --- a/services/reward/admin_operate.go +++ b/services/reward/admin_operate.go @@ -32,11 +32,12 @@ func AdminBalanceOperate(req models.AdminRewardOperateReq, doer *models.User) er Amount: req.Amount, Type: req.RewardType, }, - TargetUserId: req.TargetUserId, - RequestId: logId, - OperateType: req.OperateType, - Remark: req.Remark, - RejectPolicy: models.JustReject, + TargetUserId: req.TargetUserId, + RequestId: logId, + OperateType: req.OperateType, + Remark: req.Remark, + RejectPolicy: models.JustReject, + PermittedNegative: true, }) if err != nil { diff --git a/services/reward/period_task.go b/services/reward/period_task.go index 846989652..3fa416dab 100644 --- a/services/reward/period_task.go +++ b/services/reward/period_task.go @@ -63,31 +63,41 @@ func RunRewardTask(t models.RewardPeriodicTask, now time.Time) { log.Info("RunRewardTask. operate record is finished,record=%+v", record) return } - n, nextTime := countExecuteTimes(t, now) + n, _ := countExecuteTimes(t, now) if n == 0 { return } + //get operator operator := GetOperator(models.GetRewardTypeInstance(record.RewardType)) if operator == nil { log.Error("RunRewardTask. operator of reward type is not exist") return } - err = operator.Operate(&models.RewardOperateContext{ - SourceType: models.SourceTypeRunCloudbrainTask, - SourceId: t.OperateSerialNo, - Reward: models.Reward{ - Amount: n * t.Amount, - Type: models.GetRewardTypeInstance(record.RewardType), - }, - TargetUserId: record.UserId, - OperateType: models.GetRewardOperateTypeInstance(record.OperateType), - }) - if err != nil { - log.Error("RunRewardTask.operator operate error.%v", err) - return + nextTime := t.NextExecuteTime + for i := 0; int64(i) <= n; i++ { + err = operator.Operate(&models.RewardOperateContext{ + SourceType: models.SourceTypeRunCloudbrainTask, + SourceId: t.OperateSerialNo, + Reward: models.Reward{ + Amount: t.Amount, + Type: models.GetRewardTypeInstance(record.RewardType), + }, + TargetUserId: record.UserId, + OperateType: models.GetRewardOperateTypeInstance(record.OperateType), + }) + if err != nil { + log.Error("RunRewardTask.operator operate error.%v", err) + if models.IsErrInsufficientPointsBalance(err) { + StopCloudbrainTask(record) + return + } + return + } + models.IncrRewardTaskSuccessCount(t, n, nextTime) + nextTime = timeutil.TimeStamp(int64(nextTime) + t.IntervalSeconds) } - models.IncrRewardTaskSuccessCount(t, n, nextTime) + } func countExecuteTimes(t models.RewardPeriodicTask, now time.Time) (int64, timeutil.TimeStamp) { @@ -101,3 +111,8 @@ func countExecuteTimes(t models.RewardPeriodicTask, now time.Time) (int64, timeu newNextTime := timeutil.TimeStamp(nextTime + n*interval) return n, newNextTime } + +func StopCloudbrainTask(r *models.RewardOperateRecord) { + //todo + +} diff --git a/services/reward/point/point_operate.go b/services/reward/point/point_operate.go index 1a4ff762b..0115c288a 100644 --- a/services/reward/point/point_operate.go +++ b/services/reward/point/point_operate.go @@ -2,6 +2,7 @@ package point import ( "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/redis/redis_client" "code.gitea.io/gitea/modules/redis/redis_key" "code.gitea.io/gitea/modules/redis/redis_lock" @@ -46,6 +47,10 @@ func (operator *PointOperator) Operate(ctx *models.RewardOperateContext) error { if ctx.OperateType == models.OperateTypeIncrease { err = na.Increase(ctx.Reward.Amount, ctx.SourceId) } else if ctx.OperateType == models.OperateTypeDecrease { + if !ctx.PermittedNegative && na.Balance < ctx.Reward.Amount { + log.Info("account balance is not enough,ctx=%v", ctx) + return &models.ErrInsufficientPointsBalance{} + } err = na.Decrease(ctx.Reward.Amount, ctx.SourceId) } if err != nil { diff --git a/services/reward/record.go b/services/reward/record.go index ac28b3565..157e53b53 100644 --- a/services/reward/record.go +++ b/services/reward/record.go @@ -3,8 +3,10 @@ package reward import "code.gitea.io/gitea/models" type RecordResponse struct { - Records []models.RewardOperateRecordShow - Total int64 + Records []models.RewardOperateRecordShow + Total int64 + PageSize int + Page int } func GetRewardRecordList(opts models.RewardRecordListOpts) (*RecordResponse, error) { @@ -16,5 +18,5 @@ func GetRewardRecordList(opts models.RewardRecordListOpts) (*RecordResponse, err for _, v := range l { r = append(r, v.ToShow()) } - return &RecordResponse{Records: r, Total: n}, nil + return &RecordResponse{Records: r, Total: n, Page: opts.Page, PageSize: opts.PageSize}, nil }