| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- package period_profit
- import (
- "app/commons/core"
- "app/commons/model/entity"
- "app/commons/services"
- "app/commons/utils"
- "errors"
- "fmt"
- "github.com/shopspring/decimal"
- "gorm.io/gorm"
- )
- type Service struct {
- //job *entity.SysJob
- services.CommonService
- }
- func NewService() *Service {
- return &Service{}
- }
- // 期任务
- // nextPeriod 是否下一期
- func (s *Service) RunPeriodProfit(nextPeriod bool) error {
- var err error
- // 期任务预创建
- if err = s.PreCreationPeriods(); err != nil {
- return err
- }
- // 获取最近一期 运行中或完成任务
- nextPeriodJob, err := s.getNextRunPeriodJob()
- if err != nil {
- return err
- }
- nowPeriodNo := utils.NowPeriodNo()
- // 正常运行当期任务 / 当前开启 nextPeriod 无视时间 运行下一期
- if nextPeriodJob.PeriodNo == nowPeriodNo || nextPeriod {
- if err = s.DB().Model(&entity.StakePeriodJob{}).
- Where("id", nextPeriodJob.Id).
- Update("job_state", entity.PeriodJobStateRunning).Error; err != nil {
- return err
- }
- if err = s.runPeriodTask(nextPeriodJob.PeriodNo); err != nil {
- return err
- }
- }
- err = s.DisProfit()
- if err != nil {
- return err
- }
- return nil
- }
- func (s *Service) runPeriodTask(periodNo string) error {
- err := s.calCurrentStakeProfit(periodNo)
- if err != nil {
- return err
- }
- err = s.calLevelProfit(periodNo)
- if err != nil {
- return err
- }
- updateStm := s.DB().Model(&entity.StakePeriodJob{}).
- Where("period_no", periodNo).
- Where("job_state", entity.PeriodJobStateRunning).
- Updates(map[string]interface{}{
- "level_profit_is_cal": true,
- "job_state": entity.PeriodJobStateSuccess,
- })
- if updateStm.RowsAffected != 1 || updateStm.Error != nil {
- core.JobLog.Errorf("update fail RowsAffected:%d err:%+v", updateStm.RowsAffected, updateStm.Error)
- return err
- }
- return nil
- }
- func (s *Service) getNextRunPeriodJob() (*entity.StakePeriodJob, error) {
- firstWaiting, err := s.FirstStakePeriodJob(s.DB().Where("job_state = ?", entity.PeriodJobStateWaiting))
- if err != nil {
- return nil, err
- }
- runningOrSuccessOrFailRow, err := s.FirstStakePeriodJob(s.DB().Where("job_state != ?", entity.PeriodJobStateWaiting))
- if err != nil {
- if errors.Is(err, gorm.ErrRecordNotFound) {
- return firstWaiting, nil
- }
- return nil, err
- }
- if runningOrSuccessOrFailRow.JobState == entity.PeriodJobStateSuccess {
- return firstWaiting, nil
- }
- if runningOrSuccessOrFailRow.JobState == entity.PeriodJobStateRunning {
- return nil, fmt.Errorf("存在运行中期任务:%s", runningOrSuccessOrFailRow.PeriodNo)
- }
- if runningOrSuccessOrFailRow.JobState == entity.PeriodJobStateFailure {
- return nil, fmt.Errorf("存在运行错误期任务:%s,必须处理错误后才可以正常运行", runningOrSuccessOrFailRow.PeriodNo)
- }
- return nil, fmt.Errorf("期任务:%s,未知状态错误", runningOrSuccessOrFailRow.PeriodNo)
- }
- // 预创建3期任务
- func (s *Service) PreCreationPeriods() error {
- var err error
- firstPeriodJob, err := s.FirstStakePeriodJob(s.DB().Where("job_state", entity.PeriodJobStateWaiting))
- if err != nil {
- // 当无法占到时创建一条
- if errors.Is(err, gorm.ErrRecordNotFound) {
- firstPeriodJob, err = s.newPeriods(utils.NowPeriodNo())
- if err != nil {
- return err
- }
- } else {
- return err
- }
- }
- lastPeriodJob, err := s.LastStakePeriodJob(s.DB().Where("job_state", entity.PeriodJobStateWaiting))
- if err != nil {
- return err
- }
- // 计算两期时间跨度
- n := utils.CalPeriodNosSpan(firstPeriodJob.PeriodNo, lastPeriodJob.PeriodNo)
- // 保持三期创建
- if n < 3 {
- // 目标期
- targetPeriod, err := utils.JumpToPeriodNo(firstPeriodJob.PeriodNo, 3)
- if err != nil {
- return err
- }
- nowPeriod := lastPeriodJob.PeriodNo
- for {
- nextPeriod, err := utils.NextPeriodNo(nowPeriod)
- if err != nil {
- return err
- }
- if _, err = s.newPeriods(nextPeriod); err != nil {
- return err
- }
- if nextPeriod >= targetPeriod {
- break
- }
- nowPeriod = nextPeriod
- }
- }
- return err
- }
- // 创建期任务
- func (s *Service) newPeriods(periodNo string) (*entity.StakePeriodJob, error) {
- newRow := &entity.StakePeriodJob{
- PeriodNo: periodNo,
- JobState: entity.PeriodJobStateWaiting,
- StaticSymbolProfit: decimal.Zero,
- StaticUsdProfit: decimal.Zero,
- Desc: "",
- }
- err := s.DB().Create(&newRow).Error
- return newRow, err
- }
|