| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- package daily_profit
- import (
- "app/commons/core"
- "app/commons/model/entity"
- "app/commons/services"
- "app/commons/utils"
- "errors"
- "fmt"
- "gorm.io/gorm"
- )
- type Service struct {
- //job *entity.SysJob
- services.CommonService
- }
- func NewService() *Service {
- return &Service{}
- }
- // 每日收益任务
- // nextDay 是否启动下一日任务
- func (s *Service) RunDailyProfitJob(nextDay bool) error {
- var err error
- // 预创建每日任务
- err = s.PreCreationDailyJob()
- if err != nil {
- return err
- }
- dailyJob, err := s.getNextRunDailyJob()
- if err != nil {
- return err
- }
- if dailyJob.JobDate != utils.Today20060102Format() && !nextDay {
- return fmt.Errorf("当前待发放奖励日期:%s 当日:%s 启动失败", dailyJob.JobDate, utils.Today20060102Format())
- }
- // 记录任务状态
- defer func() {
- state := entity.JobFinish
- msg := "每日任务完成"
- if err != nil {
- state = entity.JobFail
- msg = err.Error()
- }
- if err = s.updateJobStateAndDesc(dailyJob, state, msg); err != nil {
- core.JobLog.Errorf(err.Error())
- }
- }()
- if err = s.updateJobStateAndDesc(dailyJob, entity.JobRunning, fmt.Sprintf("天任务开启")); err != nil {
- return err
- }
- // 1 节点收益计算
- if err = s.nodeProfitCal(dailyJob.JobDate); err != nil {
- return err
- }
- // 2 团队业绩排行收益计算
- if err = s.achievementRankingProfitCal(dailyJob.JobDate); err != nil {
- return err
- }
- // 3 个人质押排行收益计算
- if err = s.stakeRankingProfitCal(dailyJob.JobDate); err != nil {
- return err
- }
- return nil
- }
- // 更新任务状态
- func (s *Service) updateJobStateAndDesc(job *entity.SysJob, state, errMsg string) error {
- errMsg = fmt.Sprintf("%s:%s", errMsg, utils.NowTimeSecStr())
- if job.Desc != "" {
- errMsg = fmt.Sprintf("%s\n%s", job.Desc, errMsg)
- }
- return s.DB().Model(&entity.SysJob{}).
- Where("id", job.Id).
- Updates(map[string]interface{}{
- "state": state,
- "desc": errMsg,
- }).Error
- }
- // 获取当前任务
- func (s *Service) getNextRunDailyJob() (*entity.SysJob, error) {
- // 等待状态任务
- firstWaiting, err := s.FirstSysJob(s.DB().Where("state = ?", entity.JobWaiting))
- if err != nil {
- return nil, err
- }
- // 非等待状态任务
- runningOrSuccessOrFailRow, err := s.FirstSysJob(s.DB().Where("state != ?", entity.JobWaiting))
- if err != nil {
- if errors.Is(err, gorm.ErrRecordNotFound) {
- return firstWaiting, nil
- }
- return nil, err
- }
- if runningOrSuccessOrFailRow.State == entity.JobFinish {
- return firstWaiting, nil
- }
- if runningOrSuccessOrFailRow.State == entity.JobRunning {
- return nil, fmt.Errorf("存在运行中天任务:%s", runningOrSuccessOrFailRow.JobDate)
- }
- if runningOrSuccessOrFailRow.State == entity.JobFail {
- return nil, fmt.Errorf("存在运行错误天任务:%s,必须处理错误后才可以正常运行", runningOrSuccessOrFailRow.JobDate)
- }
- return nil, fmt.Errorf("天任务:%s,未知状态错误", runningOrSuccessOrFailRow.JobDate)
- }
- // 预创建3个 每日任务
- func (s *Service) PreCreationDailyJob() error {
- var err error
- firstWaitingJob, err := s.FirstSysJob(s.DB().Where("state", entity.JobWaiting))
- if err != nil {
- // 当不存在等待中 创建一条当日任务
- if errors.Is(err, gorm.ErrRecordNotFound) {
- firstWaitingJob, err = s.newDailyJob(utils.Today20060102Format())
- if err != nil {
- return err
- }
- } else {
- return err
- }
- }
- lastJob, err := s.LastSysJob(s.DB().Where("state", entity.JobWaiting))
- if err != nil {
- return err
- }
- // 计算两天 日期跨度
- n, err := utils.CalculateApartDays(firstWaitingJob.JobDate, lastJob.JobDate)
- if err != nil {
- return err
- }
- // 保持三天任务
- if n < 3 {
- // 目标期
- targetDay, err := utils.ChangeDay(firstWaitingJob.JobDate, 3)
- if err != nil {
- return err
- }
- nowDate := lastJob.JobDate
- for {
- nextDate, err := utils.NextPeriodNo(nowDate)
- if err != nil {
- return err
- }
- if _, err = s.newDailyJob(nextDate); err != nil {
- return err
- }
- if nextDate >= targetDay {
- break
- }
- nowDate = nextDate
- }
- }
- return err
- }
- // 每日任务初始化
- func (s *Service) createJob(nextJob bool) (*entity.SysJob, error) {
- lastJob, err := s.LastSysJob(s.DB())
- if err != nil {
- // 初始化一条记录 当日任务 并返回
- return s.newDailyJob(utils.TimeDate())
- }
- if lastJob.State != entity.JobFinish {
- return nil, fmt.Errorf("%s任务:%s", lastJob.JobDate, entity.JobStateNameById(lastJob.State))
- }
- // 启动下一日任务 -- 用于测试
- if nextJob {
- nextDate, err := utils.AfterOneDay(lastJob.JobDate)
- if err != nil {
- return s.newDailyJob(utils.TimeDate())
- }
- return s.newDailyJob(nextDate)
- } else {
- if lastJob.JobDate == utils.TimeDate() {
- return nil, fmt.Errorf("%s任务:%s", lastJob.JobDate, entity.JobStateNameById(lastJob.State))
- }
- // 创建当日任务
- }
- return s.newDailyJob(utils.TimeDate())
- }
- func (s *Service) newDailyJob(date string) (*entity.SysJob, error) {
- newJob := &entity.SysJob{
- JobDate: date,
- State: entity.JobWaiting,
- Desc: "",
- }
- if err := s.DB().Create(&newJob).Error; err != nil {
- return nil, err
- }
- return newJob, nil
- }
|