You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

reward_operate_record.go 13 kB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
2 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
2 years ago
3 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
2 years ago
3 years ago
3 years ago
2 years ago
3 years ago
3 years ago
2 years ago
3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. package models
  2. import (
  3. "code.gitea.io/gitea/modules/timeutil"
  4. "fmt"
  5. "strconv"
  6. "strings"
  7. "xorm.io/builder"
  8. )
  9. type SourceType string
  10. const (
  11. SourceTypeAccomplishTask SourceType = "ACCOMPLISH_TASK"
  12. SourceTypeAdminOperate SourceType = "ADMIN_OPERATE"
  13. SourceTypeRunCloudbrainTask SourceType = "RUN_CLOUDBRAIN_TASK"
  14. )
  15. func (r SourceType) Name() string {
  16. switch r {
  17. case SourceTypeAccomplishTask:
  18. return "ACCOMPLISH_TASK"
  19. case SourceTypeAdminOperate:
  20. return "ADMIN_OPERATE"
  21. case SourceTypeRunCloudbrainTask:
  22. return "RUN_CLOUDBRAIN_TASK"
  23. default:
  24. return ""
  25. }
  26. }
  27. type RewardType string
  28. const (
  29. RewardTypePoint RewardType = "POINT"
  30. )
  31. func (r RewardType) Name() string {
  32. switch r {
  33. case RewardTypePoint:
  34. return "POINT"
  35. default:
  36. return ""
  37. }
  38. }
  39. func (r RewardType) Show() string {
  40. switch r {
  41. case RewardTypePoint:
  42. return "积分"
  43. default:
  44. return ""
  45. }
  46. }
  47. func GetRewardTypeInstance(s string) RewardType {
  48. switch s {
  49. case RewardTypePoint.Name():
  50. return RewardTypePoint
  51. default:
  52. return ""
  53. }
  54. }
  55. type RewardOperateType string
  56. func (r RewardOperateType) Name() string {
  57. switch r {
  58. case OperateTypeIncrease:
  59. return "INCREASE"
  60. case OperateTypeDecrease:
  61. return "DECREASE"
  62. default:
  63. return ""
  64. }
  65. }
  66. func (r RewardOperateType) Show() string {
  67. switch r {
  68. case OperateTypeIncrease:
  69. return "奖励"
  70. case OperateTypeDecrease:
  71. return "扣减"
  72. default:
  73. return ""
  74. }
  75. }
  76. func GetRewardOperateTypeInstance(s string) RewardOperateType {
  77. switch s {
  78. case OperateTypeIncrease.Name():
  79. return OperateTypeIncrease
  80. case OperateTypeDecrease.Name():
  81. return OperateTypeDecrease
  82. default:
  83. return ""
  84. }
  85. }
  86. const (
  87. OperateTypeIncrease RewardOperateType = "INCREASE"
  88. OperateTypeDecrease RewardOperateType = "DECREASE"
  89. OperateTypeNull RewardOperateType = "NIL"
  90. )
  91. const (
  92. OperateStatusOperating = "OPERATING"
  93. OperateStatusSucceeded = "SUCCEEDED"
  94. OperateStatusFailed = "FAILED"
  95. )
  96. const Semicolon = ";"
  97. type RewardOperateOrderBy string
  98. const (
  99. RewardOrderByIDDesc RewardOperateOrderBy = "reward_operate_record.id desc"
  100. )
  101. type RewardRecordList []*RewardOperateRecord
  102. type RewardRecordShowList []*RewardOperateRecordShow
  103. func (l RewardRecordShowList) loadAttribute(isAdmin bool) {
  104. l.loadAction()
  105. l.loadCloudbrain()
  106. if isAdmin {
  107. l.loadAdminLog()
  108. }
  109. }
  110. func (l RewardRecordShowList) loadAction() error {
  111. if len(l) == 0 {
  112. return nil
  113. }
  114. actionIds := make([]int64, 0)
  115. actionIdMap := make(map[int64]*RewardOperateRecordShow, 0)
  116. for _, r := range l {
  117. if r.SourceType != SourceTypeAccomplishTask.Name() {
  118. continue
  119. }
  120. i, _ := strconv.ParseInt(r.SourceId, 10, 64)
  121. actionIds = append(actionIds, i)
  122. actionIdMap[i] = r
  123. }
  124. actions, err := GetActionByIds(actionIds)
  125. if err != nil {
  126. return err
  127. }
  128. for _, v := range actions {
  129. actionIdMap[v.ID].Action = v.ToShow()
  130. }
  131. return nil
  132. }
  133. func (l RewardRecordShowList) loadCloudbrain() error {
  134. if len(l) == 0 {
  135. return nil
  136. }
  137. cloudbrainIds := make([]int64, 0)
  138. cloudbrainMap := make(map[int64]*RewardOperateRecordShow, 0)
  139. for _, r := range l {
  140. if r.SourceType != SourceTypeRunCloudbrainTask.Name() {
  141. continue
  142. }
  143. i, _ := strconv.ParseInt(r.SourceId, 10, 64)
  144. cloudbrainIds = append(cloudbrainIds, i)
  145. cloudbrainMap[i] = r
  146. }
  147. cloudbrains, err := GetCloudbrainByIds(cloudbrainIds)
  148. if err != nil {
  149. return err
  150. }
  151. var repoIds []int64
  152. var taskIds []int64
  153. for _, task := range cloudbrains {
  154. repoIds = append(repoIds, task.RepoID)
  155. taskIds = append(taskIds, task.ID)
  156. }
  157. repositoryMap, err := GetRepositoriesMapByIDs(repoIds)
  158. specMap, err := GetResourceSpecMapByCloudbrainIDs(taskIds)
  159. if err != nil {
  160. return err
  161. }
  162. for _, v := range cloudbrains {
  163. v.Repo = repositoryMap[v.RepoID]
  164. v.Spec = specMap[v.ID]
  165. cloudbrainMap[v.ID].Cloudbrain = v.ToShow()
  166. }
  167. return nil
  168. }
  169. func (l RewardRecordShowList) loadAdminLog() error {
  170. if len(l) == 0 {
  171. return nil
  172. }
  173. logIds := make([]string, 0)
  174. logMap := make(map[string]*RewardOperateRecordShow, 0)
  175. for _, r := range l {
  176. if r.SourceType != SourceTypeAdminOperate.Name() {
  177. continue
  178. }
  179. logIds = append(logIds, r.SourceId)
  180. logMap[r.SourceId] = r
  181. }
  182. adminLogs, err := GetRewardAdminLogByLogIds(logIds)
  183. if err != nil {
  184. return err
  185. }
  186. for _, v := range adminLogs {
  187. logMap[v.LogId].AdminLog = v.ToShow()
  188. }
  189. return nil
  190. }
  191. type RewardOperateRecord struct {
  192. ID int64 `xorm:"pk autoincr"`
  193. SerialNo string `xorm:"INDEX NOT NULL"`
  194. UserId int64 `xorm:"INDEX NOT NULL"`
  195. Amount int64 `xorm:"NOT NULL"`
  196. LossAmount int64
  197. Title string
  198. RewardType string `xorm:"NOT NULL"`
  199. SourceType string `xorm:"NOT NULL"`
  200. SourceId string `xorm:"INDEX NOT NULL"`
  201. SourceTemplateId string
  202. RequestId string `xorm:"INDEX NOT NULL"`
  203. OperateType string `xorm:"NOT NULL"`
  204. Status string `xorm:"NOT NULL"`
  205. Remark string
  206. CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
  207. UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
  208. LastOperateUnix timeutil.TimeStamp `xorm:"INDEX"`
  209. }
  210. type AdminRewardOperateReq struct {
  211. TargetUserId int64 `binding:"Required"`
  212. OperateType RewardOperateType `binding:"Required"`
  213. Amount int64 `binding:"Required;Range(1,100000)"`
  214. Remark string
  215. RewardType RewardType
  216. }
  217. type RewardOperateRecordShow struct {
  218. SerialNo string
  219. Status string
  220. OperateType string
  221. SourceId string
  222. Amount int64
  223. LossAmount int64
  224. BalanceAfter int64
  225. Remark string
  226. SourceType string
  227. UserName string
  228. LastOperateDate timeutil.TimeStamp
  229. UnitPrice int64
  230. SuccessCount int
  231. Action *ActionShow
  232. Cloudbrain *CloudbrainShow
  233. AdminLog *RewardAdminLogShow
  234. }
  235. func getPointOperateRecord(tl *RewardOperateRecord) (*RewardOperateRecord, error) {
  236. has, err := x.Get(tl)
  237. if err != nil {
  238. return nil, err
  239. } else if !has {
  240. return nil, ErrRecordNotExist{}
  241. }
  242. return tl, nil
  243. }
  244. func GetPointOperateRecordBySourceTypeAndRequestId(sourceType, requestId, operateType string) (*RewardOperateRecord, error) {
  245. t := &RewardOperateRecord{
  246. SourceType: sourceType,
  247. RequestId: requestId,
  248. OperateType: operateType,
  249. }
  250. return getPointOperateRecord(t)
  251. }
  252. func GetPointOperateRecordBySerialNo(serialNo string) (*RewardOperateRecord, error) {
  253. t := &RewardOperateRecord{
  254. SerialNo: serialNo,
  255. }
  256. return getPointOperateRecord(t)
  257. }
  258. func InsertRewardOperateRecord(tl *RewardOperateRecord) (int64, error) {
  259. return x.Insert(tl)
  260. }
  261. func UpdateRewardRecordToFinalStatus(sourceType, requestId, newStatus string) (int64, error) {
  262. r := &RewardOperateRecord{
  263. Status: newStatus,
  264. LastOperateUnix: timeutil.TimeStampNow(),
  265. }
  266. return x.Cols("status", "last_operate_unix").Where("source_type=? and request_id=? and status=?", sourceType, requestId, OperateStatusOperating).Update(r)
  267. }
  268. func SumRewardAmountInTaskPeriod(rewardType string, sourceType string, userId int64, period *PeriodResult) (int64, error) {
  269. var cond = builder.NewCond()
  270. if period != nil {
  271. cond = cond.And(builder.Gte{"created_unix": period.StartTime.Unix()})
  272. cond = cond.And(builder.Lt{"created_unix": period.EndTime.Unix()})
  273. }
  274. if sourceType != "" {
  275. cond = cond.And(builder.Eq{"source_type": sourceType})
  276. }
  277. cond = cond.And(builder.Eq{"reward_type": rewardType})
  278. cond = cond.And(builder.Eq{"user_id": userId})
  279. return x.Where(cond).SumInt(&RewardOperateRecord{}, "amount")
  280. }
  281. type RewardOperateContext struct {
  282. SourceType SourceType
  283. SourceId string
  284. SourceTemplateId string
  285. Title string
  286. Remark string
  287. Reward Reward
  288. TargetUserId int64
  289. RequestId string
  290. OperateType RewardOperateType
  291. RejectPolicy LimiterRejectPolicy
  292. PermittedNegative bool
  293. LossAmount int64
  294. }
  295. type Reward struct {
  296. Amount int64
  297. Type RewardType
  298. }
  299. type UserRewardOperationRedis struct {
  300. UserId int64
  301. Amount int64
  302. RewardType RewardType
  303. OperateType RewardOperateType
  304. }
  305. type UserRewardOperation struct {
  306. UserId int64
  307. Msg string
  308. }
  309. func AppendRemark(remark, appendStr string) string {
  310. return strings.TrimPrefix(remark+Semicolon+appendStr, Semicolon)
  311. }
  312. type RewardRecordListOpts struct {
  313. ListOptions
  314. UserId int64
  315. UserName string
  316. OperateType RewardOperateType
  317. RewardType RewardType
  318. SourceType string
  319. ActionType int
  320. SerialNo string
  321. OrderBy RewardOperateOrderBy
  322. IsAdmin bool
  323. Status string
  324. }
  325. func (opts *RewardRecordListOpts) toCond() builder.Cond {
  326. if opts.Page <= 0 {
  327. opts.Page = 1
  328. }
  329. if len(opts.OrderBy) == 0 {
  330. opts.OrderBy = RewardOrderByIDDesc
  331. }
  332. cond := builder.NewCond()
  333. if opts.UserId > 0 {
  334. cond = cond.And(builder.Eq{"reward_operate_record.user_id": opts.UserId})
  335. }
  336. if opts.OperateType != OperateTypeNull {
  337. cond = cond.And(builder.Eq{"reward_operate_record.operate_type": opts.OperateType.Name()})
  338. }
  339. if opts.SourceType != "" {
  340. cond = cond.And(builder.Eq{"reward_operate_record.source_type": opts.SourceType})
  341. }
  342. if opts.ActionType > 0 {
  343. cond = cond.And(builder.Eq{"reward_operate_record.source_template_id": fmt.Sprint(opts.ActionType)})
  344. }
  345. if opts.SerialNo != "" {
  346. cond = cond.And(builder.Like{"reward_operate_record.serial_no", opts.SerialNo})
  347. }
  348. if opts.Status != "" {
  349. cond = cond.And(builder.Like{"reward_operate_record.status", opts.Status})
  350. }
  351. cond = cond.And(builder.Eq{"reward_operate_record.reward_type": opts.RewardType.Name()})
  352. cond = cond.And(builder.Gt{"reward_operate_record.amount": 0})
  353. return cond
  354. }
  355. type TestTT struct {
  356. SerialNo string
  357. UserId int64
  358. Amount int64
  359. UserName string
  360. }
  361. func GetRewardRecordShowList(opts *RewardRecordListOpts) (RewardRecordShowList, int64, error) {
  362. cond := opts.toCond()
  363. count, err := x.Where(cond).Count(&RewardOperateRecord{})
  364. if err != nil {
  365. return nil, 0, err
  366. }
  367. r := make([]*RewardOperateRecordShow, 0)
  368. err = x.Table("reward_operate_record").Cols("reward_operate_record.source_id", "reward_operate_record.serial_no",
  369. "reward_operate_record.status", "reward_operate_record.operate_type", "reward_operate_record.amount",
  370. "reward_operate_record.loss_amount", "reward_operate_record.remark", "reward_operate_record.source_type",
  371. "reward_operate_record.last_operate_unix as last_operate_date").
  372. Where(cond).Limit(opts.PageSize, (opts.Page-1)*opts.PageSize).OrderBy(string(opts.OrderBy)).Find(&r)
  373. if err != nil {
  374. return nil, 0, err
  375. }
  376. RewardRecordShowList(r).loadAttribute(false)
  377. return r, count, nil
  378. }
  379. func GetAdminRewardRecordShowList(opts *RewardRecordListOpts) (RewardRecordShowList, int64, error) {
  380. cond := opts.toCond()
  381. count, err := x.Where(cond).Count(&RewardOperateRecord{})
  382. if err != nil {
  383. return nil, 0, err
  384. }
  385. r := make([]*RewardOperateRecordShow, 0)
  386. switch opts.OperateType {
  387. case OperateTypeIncrease:
  388. err = x.Table("reward_operate_record").Cols("reward_operate_record.source_id", "reward_operate_record.serial_no",
  389. "reward_operate_record.status", "reward_operate_record.operate_type", "reward_operate_record.amount",
  390. "reward_operate_record.loss_amount", "reward_operate_record.remark", "reward_operate_record.source_type",
  391. "reward_operate_record.last_operate_unix as last_operate_date", "public.user.name as user_name",
  392. "point_account_log.balance_after").
  393. Join("LEFT", "public.user", "reward_operate_record.user_id = public.user.id").
  394. Join("LEFT", "point_account_log", " reward_operate_record.serial_no = point_account_log.source_id").
  395. Where(cond).Limit(opts.PageSize, (opts.Page-1)*opts.PageSize).OrderBy(string(opts.OrderBy)).Find(&r)
  396. case OperateTypeDecrease:
  397. err = x.Table("reward_operate_record").Cols("reward_operate_record.source_id", "reward_operate_record.serial_no",
  398. "reward_operate_record.status", "reward_operate_record.operate_type", "reward_operate_record.amount",
  399. "reward_operate_record.loss_amount", "reward_operate_record.remark", "reward_operate_record.source_type",
  400. "reward_operate_record.last_operate_unix as last_operate_date", "public.user.name as user_name",
  401. "reward_periodic_task.amount as unit_price", "reward_periodic_task.success_count").
  402. Join("LEFT", "public.user", "reward_operate_record.user_id = public.user.id").
  403. Join("LEFT", "reward_periodic_task", "reward_operate_record.serial_no = reward_periodic_task.operate_serial_no").
  404. Where(cond).Limit(opts.PageSize, (opts.Page-1)*opts.PageSize).OrderBy(string(opts.OrderBy)).Find(&r)
  405. }
  406. if err != nil {
  407. return nil, 0, err
  408. }
  409. RewardRecordShowList(r).loadAttribute(true)
  410. return r, count, nil
  411. }