@@ -57,6 +57,7 @@ type LimitConfig struct { | |||
LimitNum int64 `xorm:"NOT NULL"` | |||
LimitCode string | |||
LimitType string `xorm:"NOT NULL"` | |||
RelatedId int64 `xorm:"INDEX"` | |||
CreatorId int64 `xorm:"NOT NULL"` | |||
CreatorName string | |||
DeleterId int64 | |||
@@ -102,9 +103,9 @@ func GetLimitConfigByLimitType(limitType LimitType) ([]LimitConfig, error) { | |||
return r, nil | |||
} | |||
func GetLimitersByLimitTypeWithDeleted(limitType LimitType) ([]LimitConfig, error) { | |||
func GetLimitersByRelatedIdWithDeleted(limitType LimitType) ([]LimitConfig, error) { | |||
r := make([]LimitConfig, 0) | |||
err := x.Unscoped().Where(" limit_type = ?", limitType.Name()).Find(&r) | |||
err := x.Unscoped().Where(" = ?", limitType.Name()).Find(&r) | |||
if err != nil { | |||
return nil, err | |||
} else if len(r) == 0 { | |||
@@ -21,10 +21,13 @@ type TaskConfig struct { | |||
CreatorName string | |||
CreatedUnix timeutil.TimeStamp `xorm:"created"` | |||
DeletedAt timeutil.TimeStamp `xorm:"deleted"` | |||
DeleterId int64 | |||
DeleterName string | |||
} | |||
type TaskConfigWithLimit struct { | |||
TaskCode string `binding:"Required;MaxSize(256)"` | |||
ID int64 | |||
TaskCode string | |||
Tittle string | |||
AwardType string | |||
AwardAmount int64 | |||
@@ -34,6 +37,36 @@ type TaskConfigWithLimit struct { | |||
DeleteAt timeutil.TimeStamp | |||
Limiters []*LimitConfigVO | |||
} | |||
type TaskConfigWithLimitResponse struct { | |||
Records []*TaskConfigWithSingleLimit | |||
Total int64 | |||
PageSize int | |||
Page int | |||
} | |||
type TaskConfigWithSingleLimit struct { | |||
ID int64 | |||
TaskCode string | |||
AwardType string | |||
AwardAmount int64 | |||
Creator string | |||
IsDeleted bool | |||
CreatedUnix timeutil.TimeStamp | |||
DeleteAt timeutil.TimeStamp | |||
RefreshRate string | |||
LimitNum int64 | |||
} | |||
type TaskAndLimiterConfig struct { | |||
TaskConfig TaskConfig `xorm:"extends"` | |||
LimitConfig LimitConfig `xorm:"extends"` | |||
} | |||
func (TaskAndLimiterConfig) TableName() string { | |||
return "task_config" | |||
} | |||
type BatchLimitConfigVO struct { | |||
ConfigList []TaskConfigWithLimit | |||
} | |||
@@ -54,6 +87,14 @@ func GetTaskConfigByTaskCode(taskCode string) (*TaskConfig, error) { | |||
} | |||
return getTaskConfig(t) | |||
} | |||
func GetTaskConfigByID(id int64) (*TaskConfig, error) { | |||
t := &TaskConfig{ | |||
ID: id, | |||
} | |||
return getTaskConfig(t) | |||
} | |||
func GetTaskConfigList() ([]*TaskConfig, error) { | |||
r := make([]*TaskConfig, 0) | |||
err := x.Find(&r) | |||
@@ -65,34 +106,40 @@ func GetTaskConfigList() ([]*TaskConfig, error) { | |||
} | |||
return r, nil | |||
} | |||
func GetTaskConfigPageWithDeleted(opt ListOptions) ([]*TaskConfig, error) { | |||
func GetTaskConfigPageWithDeleted(opt ListOptions) ([]*TaskAndLimiterConfig, int64, error) { | |||
if opt.Page <= 0 { | |||
opt.Page = 1 | |||
} | |||
r := make([]*TaskConfig, 0) | |||
err := x.Unscoped().Limit(opt.PageSize, (opt.Page-1)*opt.PageSize).OrderBy("deleted_at desc,id desc").Find(&r) | |||
n, err := x.Unscoped().Count(&TaskConfig{}) | |||
if err != nil { | |||
return nil, err | |||
return nil, 0, err | |||
} | |||
r := make([]*TaskAndLimiterConfig, 0) | |||
err = x.Join("LEFT", "limit_config", "task_config.id = limit_config.related_id").Unscoped().Limit(opt.PageSize, (opt.Page-1)*opt.PageSize).OrderBy("task_config.deleted_at desc,task_config.id desc").Find(&r) | |||
if len(r) == 0 { | |||
return nil, ErrRecordNotExist{} | |||
return nil, 0, ErrRecordNotExist{} | |||
} | |||
return r, nil | |||
return r, n, nil | |||
} | |||
func AddTaskConfig(config TaskConfigWithLimit, doer *User) error { | |||
func EditTaskConfig(config TaskConfigWithLimit, doer *User) error { | |||
sess := x.NewSession() | |||
defer sess.Close() | |||
//delete old task config | |||
p := &TaskConfig{ | |||
TaskCode: config.TaskCode, | |||
ID: config.ID, | |||
} | |||
_, err := sess.Delete(p) | |||
if err != nil { | |||
sess.Rollback() | |||
return err | |||
} | |||
//update deleter | |||
p.DeleterId = doer.ID | |||
p.DeleterName = doer.Name | |||
sess.Where("id = ?", config.ID).Unscoped().Update(p) | |||
//add new config | |||
t := &TaskConfig{ | |||
@@ -103,7 +150,7 @@ func AddTaskConfig(config TaskConfigWithLimit, doer *User) error { | |||
CreatorId: doer.ID, | |||
CreatorName: doer.Name, | |||
} | |||
_, err = sess.Insert(t) | |||
_, err = sess.InsertOne(t) | |||
if err != nil { | |||
sess.Rollback() | |||
return err | |||
@@ -111,20 +158,69 @@ func AddTaskConfig(config TaskConfigWithLimit, doer *User) error { | |||
//delete old limiter config | |||
lp := &LimitConfig{ | |||
LimitType: LimitTypeTask.Name(), | |||
LimitCode: config.TaskCode, | |||
RelatedId: config.ID, | |||
} | |||
_, err = sess.Delete(lp) | |||
if err != nil { | |||
sess.Rollback() | |||
return err | |||
} | |||
lp.DeleterName = doer.Name | |||
lp.DeleterId = doer.ID | |||
//update deleter | |||
sess.Where("related_id = ?", config.ID).Unscoped().Update(lp) | |||
//add new limiter config | |||
if config.Limiters != nil && len(config.Limiters) > 0 { | |||
for _, v := range config.Limiters { | |||
//add new config | |||
l := &LimitConfig{ | |||
Tittle: v.Tittle, | |||
RefreshRate: v.RefreshRate, | |||
Scope: v.Scope, | |||
LimitNum: v.LimitNum, | |||
LimitCode: config.TaskCode, | |||
LimitType: LimitTypeTask.Name(), | |||
CreatorId: doer.ID, | |||
CreatorName: doer.Name, | |||
RelatedId: t.ID, | |||
} | |||
_, err = sess.Insert(l) | |||
if err != nil { | |||
sess.Rollback() | |||
return err | |||
} | |||
} | |||
} | |||
sess.Commit() | |||
return nil | |||
} | |||
func NewTaskConfig(config TaskConfigWithLimit, doer *User) error { | |||
sess := x.NewSession() | |||
defer sess.Close() | |||
//add new config | |||
t := &TaskConfig{ | |||
TaskCode: config.TaskCode, | |||
Tittle: config.Tittle, | |||
AwardType: config.AwardType, | |||
AwardAmount: config.AwardAmount, | |||
CreatorId: doer.ID, | |||
CreatorName: doer.Name, | |||
} | |||
_, err := sess.InsertOne(t) | |||
if err != nil { | |||
sess.Rollback() | |||
return err | |||
} | |||
//add new limiter config | |||
if config.Limiters != nil && len(config.Limiters) > 0 { | |||
for _, v := range config.Limiters { | |||
//add new config | |||
l := &LimitConfig{ | |||
RelatedId: t.ID, | |||
Tittle: v.Tittle, | |||
RefreshRate: v.RefreshRate, | |||
Scope: v.Scope, | |||
@@ -145,30 +241,36 @@ func AddTaskConfig(config TaskConfigWithLimit, doer *User) error { | |||
return nil | |||
} | |||
func DelTaskConfig(taskCode string) error { | |||
func DelTaskConfig(id int64, doer *User) error { | |||
sess := x.NewSession() | |||
defer sess.Close() | |||
//delete old task config | |||
p := &TaskConfig{ | |||
TaskCode: taskCode, | |||
ID: id, | |||
} | |||
_, err := sess.Delete(p) | |||
if err != nil { | |||
sess.Rollback() | |||
return err | |||
} | |||
//update deleter | |||
p.DeleterId = doer.ID | |||
p.DeleterName = doer.Name | |||
sess.Where("id = ?", id).Unscoped().Update(p) | |||
//delete old limiter config | |||
lp := &LimitConfig{ | |||
LimitType: LimitTypeTask.Name(), | |||
LimitCode: taskCode, | |||
RelatedId: id, | |||
} | |||
_, err = sess.Delete(lp) | |||
if err != nil { | |||
sess.Rollback() | |||
return err | |||
} | |||
lp.DeleterName = doer.Name | |||
lp.DeleterId = doer.ID | |||
//update deleter | |||
sess.Where("related_id = ?", id).Unscoped().Update(lp) | |||
sess.Commit() | |||
return nil | |||
} |
@@ -9,3 +9,6 @@ func TaskAccomplishLock(sourceId string, taskType string) string { | |||
func TaskConfigList() string { | |||
return KeyJoin(TASK_REDIS_PREFIX, "config", "list") | |||
} | |||
func TaskConfigOperateLock(taskCode, rewardType string) string { | |||
return KeyJoin(TASK_REDIS_PREFIX, "config", "operate", "lock") | |||
} |
@@ -35,8 +35,8 @@ func GetPointAccount(ctx *context.Context) { | |||
} | |||
func GetPointRecordList(ctx *context.Context) { | |||
operateType := ctx.Query("operate") | |||
page := ctx.QueryInt("page") | |||
operateType := ctx.Query("Operate") | |||
page := ctx.QueryInt("Page") | |||
var orderBy models.RewardOperateOrderBy | |||
switch ctx.Query("sort") { | |||
default: | |||
@@ -11,7 +11,7 @@ import ( | |||
) | |||
func GetTaskConfigList(ctx *context.Context) { | |||
page := ctx.QueryInt("page") | |||
page := ctx.QueryInt("Page") | |||
r, err := task.GetTaskConfigWithLimitList(models.ListOptions{PageSize: 20, Page: page}) | |||
if err != nil { | |||
ctx.JSON(http.StatusOK, response.ServerError(err.Error())) | |||
@@ -30,7 +30,7 @@ func OperateTaskConfig(ctx *context.Context, config models.TaskConfigWithLimit) | |||
case "new": | |||
err = task.AddTaskConfig(config, ctx.User) | |||
case "del": | |||
err = task.DelTaskConfig(config.TaskCode) | |||
err = task.DelTaskConfig(config.ID, ctx.User) | |||
default: | |||
err = errors.New("action type error") | |||
} | |||
@@ -246,8 +246,8 @@ func GetLimitersByLimitType(limitType models.LimitType) ([]models.LimitConfig, e | |||
return limiters, nil | |||
} | |||
func GetLimitersByLimitTypeWithDeleted(limitType models.LimitType) ([]models.LimitConfig, error) { | |||
limiters, err := models.GetLimitersByLimitTypeWithDeleted(limitType) | |||
func GetLimitersByRelatedIdWithDeleted(limitType models.LimitType) ([]models.LimitConfig, error) { | |||
limiters, err := models.GetLimitersByRelatedIdWithDeleted(limitType) | |||
if err != nil { | |||
if models.IsErrRecordNotExist(err) { | |||
return nil, nil | |||
@@ -5,7 +5,7 @@ import ( | |||
"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/services/reward/limiter" | |||
"code.gitea.io/gitea/modules/redis/redis_lock" | |||
"encoding/json" | |||
"errors" | |||
"time" | |||
@@ -52,58 +52,64 @@ func GetTaskConfigList() ([]*models.TaskConfig, error) { | |||
return config, nil | |||
} | |||
func GetTaskConfigPageWithDeleted(opt models.ListOptions) ([]*models.TaskConfig, error) { | |||
config, err := models.GetTaskConfigPageWithDeleted(opt) | |||
func GetTaskConfigPageWithDeleted(opt models.ListOptions) ([]*models.TaskAndLimiterConfig, int64, error) { | |||
config, count, err := models.GetTaskConfigPageWithDeleted(opt) | |||
if err != nil { | |||
log.Error(" GetTaskConfigPageWithDeleted from model error. %v", err) | |||
if models.IsErrRecordNotExist(err) { | |||
return nil, nil | |||
return nil, 0, nil | |||
} | |||
return nil, err | |||
return nil, 0, err | |||
} | |||
return config, nil | |||
return config, count, nil | |||
} | |||
func GetTaskConfigWithLimitList(opt models.ListOptions) ([]*models.TaskConfigWithLimit, error) { | |||
list, err := GetTaskConfigPageWithDeleted(opt) | |||
func GetTaskConfigWithLimitList(opt models.ListOptions) (*models.TaskConfigWithLimitResponse, error) { | |||
list, n, err := GetTaskConfigPageWithDeleted(opt) | |||
if err != nil { | |||
return nil, err | |||
} | |||
if len(list) == 0 { | |||
return nil, nil | |||
} | |||
r := make([]*models.TaskConfigWithLimit, 0) | |||
l, err := limiter.GetLimitersByLimitTypeWithDeleted(models.LimitTypeTask) | |||
if err != nil { | |||
log.Error(" GetLimitersByLimitType from redis error. %v", err) | |||
return nil, err | |||
} | |||
r := make([]*models.TaskConfigWithSingleLimit, 0) | |||
for i := 0; i < len(list); i++ { | |||
li := list[i] | |||
t := &models.TaskConfigWithLimit{ | |||
TaskCode: li.TaskCode, | |||
Tittle: li.Tittle, | |||
AwardType: li.AwardType, | |||
AwardAmount: li.AwardAmount, | |||
Creator: li.CreatorName, | |||
CreatedUnix: li.CreatedUnix, | |||
IsDeleted: li.DeletedAt > 0, | |||
DeleteAt: li.DeletedAt, | |||
t := &models.TaskConfigWithSingleLimit{ | |||
ID: li.TaskConfig.ID, | |||
TaskCode: li.TaskConfig.TaskCode, | |||
AwardType: li.TaskConfig.AwardType, | |||
AwardAmount: li.TaskConfig.AwardAmount, | |||
Creator: li.TaskConfig.CreatorName, | |||
CreatedUnix: li.TaskConfig.CreatedUnix, | |||
IsDeleted: li.TaskConfig.DeletedAt > 0, | |||
DeleteAt: li.TaskConfig.DeletedAt, | |||
LimitNum: li.LimitConfig.LimitNum, | |||
RefreshRate: li.LimitConfig.RefreshRate, | |||
} | |||
lv := make([]*models.LimitConfigVO, 0) | |||
for j := 0; j < len(l); j++ { | |||
lj := l[j] | |||
if lj.LimitCode == li.TaskCode { | |||
lv = append(lv, lj.ToLimitConfigVO()) | |||
} | |||
} | |||
t.Limiters = lv | |||
r = append(r, t) | |||
} | |||
return r, nil | |||
return &models.TaskConfigWithLimitResponse{ | |||
Records: r, | |||
Page: opt.Page, | |||
PageSize: opt.PageSize, | |||
Total: n, | |||
}, nil | |||
} | |||
func AddTaskConfig(config models.TaskConfigWithLimit, doer *models.User) error { | |||
if config.TaskCode == "" || config.AwardType == "" { | |||
log.Error(" EditTaskConfig param error") | |||
return errors.New("param error") | |||
} | |||
var lock = redis_lock.NewDistributeLock(redis_key.TaskConfigOperateLock(config.TaskCode, config.AwardType)) | |||
isOk, _ := lock.LockWithWait(3*time.Second, 3*time.Second) | |||
if !isOk { | |||
return errors.New("Get lock failed") | |||
} | |||
defer lock.UnLock() | |||
t, err := models.GetTaskConfigByTaskCode(config.TaskCode) | |||
if err != nil && !models.IsErrRecordNotExist(err) { | |||
return err | |||
@@ -112,20 +118,46 @@ func AddTaskConfig(config models.TaskConfigWithLimit, doer *models.User) error { | |||
return errors.New("task config is exist") | |||
} | |||
return EditTaskConfig(config, doer) | |||
for i, l := range config.Limiters { | |||
if l.Scope == "" { | |||
config.Limiters[i].Scope = models.LimitScopeSingleUser.Name() | |||
} | |||
} | |||
err = models.NewTaskConfig(config, doer) | |||
if err != nil { | |||
log.Error("add task config error,config:%v err:%v", config, err) | |||
return err | |||
} | |||
redis_client.Del(redis_key.LimitConfig(models.LimitTypeTask.Name())) | |||
redis_client.Del(redis_key.TaskConfigList()) | |||
return nil | |||
} | |||
func EditTaskConfig(config models.TaskConfigWithLimit, doer *models.User) error { | |||
if config.TaskCode == "" || config.AwardType == "" { | |||
log.Error(" AddTaskConfig param error") | |||
if config.TaskCode == "" || config.AwardType == "" || config.ID <= 0 { | |||
log.Error(" EditTaskConfig param error") | |||
return errors.New("param error") | |||
} | |||
var lock = redis_lock.NewDistributeLock(redis_key.TaskConfigOperateLock(config.TaskCode, config.AwardType)) | |||
isOk, _ := lock.LockWithWait(3*time.Second, 3*time.Second) | |||
if !isOk { | |||
return errors.New("Get lock failed") | |||
} | |||
defer lock.UnLock() | |||
t, err := models.GetTaskConfigByID(config.ID) | |||
if err != nil { | |||
return err | |||
} | |||
if t == nil { | |||
return errors.New("task config is not exist") | |||
} | |||
for i, l := range config.Limiters { | |||
if l.Scope == "" { | |||
config.Limiters[i].Scope = models.LimitScopeSingleUser.Name() | |||
} | |||
} | |||
err := models.AddTaskConfig(config, doer) | |||
err = models.EditTaskConfig(config, doer) | |||
if err != nil { | |||
log.Error("add task config error,config:%v err:%v", config, err) | |||
return err | |||
@@ -135,12 +167,12 @@ func EditTaskConfig(config models.TaskConfigWithLimit, doer *models.User) error | |||
return nil | |||
} | |||
func DelTaskConfig(taskCode string) error { | |||
if taskCode == "" { | |||
log.Error(" AddTaskConfig param error") | |||
func DelTaskConfig(id int64, doer *models.User) error { | |||
if id == 0 { | |||
log.Error(" EditTaskConfig param error") | |||
return errors.New("param error") | |||
} | |||
err := models.DelTaskConfig(taskCode) | |||
err := models.DelTaskConfig(id, doer) | |||
if err != nil { | |||
log.Error("del task config error,err:%v", err) | |||
return err | |||