package cms import ( "fmt" "strings" "time" "git.rosy.net.cn/baseapi/platformapi/jdeclpapi" "git.rosy.net.cn/jx-callback/globals" "git.rosy.net.cn/jx-callback/business/jxstore/financial" "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/jxutils" "git.rosy.net.cn/jx-callback/globals/api" "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" "git.rosy.net.cn/jx-callback/business/model" "git.rosy.net.cn/jx-callback/business/model/dao" ) const ( AcceptMaxCount = 2 CancelMaxCount = 5 ) var ( DayTimeBegin time.Time DayTimeEnd time.Time WeekTimeBegin time.Time WeekTimeEnd time.Time JobTimerMap map[int64]*time.Timer JobAuditTimerMap map[int64]*time.Timer ) func init() { DayTimeBegin = utils.Str2Time(utils.Time2Str(utils.Time2Date(time.Now())) + " 00:00:00") DayTimeEnd = utils.Str2Time(utils.Time2Str(utils.Time2Date(time.Now())) + " 23:59:59") WeekTimeBegin, WeekTimeEnd = getWeekTime() JobTimerMap = make(map[int64]*time.Timer) JobAuditTimerMap = make(map[int64]*time.Timer) } func getWeekTime() (weekTimeBegin, weekTimeEnd time.Time) { offset := int(time.Now().Weekday() - 1) if offset == -1 { offset = -6 } weekTimeBegin = time.Now().AddDate(0, 0, offset) weekTimeEnd = weekTimeBegin.AddDate(0, 0, 7) return weekTimeBegin, weekTimeEnd } func PublishJob(ctx *jxcontext.Context, job *model.Job) (err error) { var ( db = dao.GetDB() ) //需根据任务类型做一些参数判断,比如门店商品链接,地址 // switch job.JobCategoryID { // case 1: // } if ctx.GetUserID() != job.UserID { return fmt.Errorf("用户信息已过期,请重新登录!") } //发布任务要扣除任务总额的保证金,不够扣就要进行充值 userBill, err := dao.GetUserBill(db, job.UserID, "") if userBill == nil { return fmt.Errorf("未查询到该用户的账单!") } job.TotalPrice = job.Count * job.AvgPrice if userBill.AccountBalance < job.TotalPrice { job.Status = model.JobStatusFailed } else { job.Status = model.JobStatusDoing } if job.Count <= 0 { return fmt.Errorf("任务数量不能为0!") } if job.UserID == "" { return fmt.Errorf("任务发起人不能为空!") } jobs, err := dao.GetJobsNoPage(db, []string{job.UserID}, nil, nil, DayTimeBegin, DayTimeEnd, false) if len(jobs) > 0 { members, err := dao.GetUserMember(db, job.UserID, model.MemberTypeNormal) if err != nil { return err } if len(members) <= 0 { return fmt.Errorf("非会员一天只能发布一起任务,请确认!") } } if job.Address != "" && (job.Lng == 0 || job.Lat == 0) { lng, lat, err := api.AutonaviAPI.GetCoordinateFromAddressByPage(job.Address) if err != nil { return err } job.Lng = jxutils.StandardCoordinate2Int(lng) job.Lat = jxutils.StandardCoordinate2Int(lat) } dao.WrapAddIDCULEntity(job, ctx.GetUserName()) dao.Begin(db) defer func() { if r := recover(); r != nil { dao.Rollback(db) panic(r) } }() err = dao.CreateEntity(db, job) for _, v := range job.JobSteps { dao.WrapAddIDCULEntity(v, ctx.GetUserName()) v.JobID = job.ID err = dao.CreateEntity(db, v) } for _, v := range job.JobImgs { dao.WrapAddIDCULEntity(v, ctx.GetUserName()) v.JobID = job.ID err = dao.CreateEntity(db, v) } if err != nil { dao.Rollback(db) } //发布任务要扣除任务总额的保证金,不够扣就要进行充值 if err == nil && job.Status != model.JobStatusFailed { if err = financial.AddExpendUpdateAccount(db, userBill, model.BillTypeDeposit, job.TotalPrice); err != nil { dao.Rollback(db) } } dao.Commit(db) return err } func CancelPublishJob(ctx *jxcontext.Context, jobID int) (err error) { var ( db = dao.GetDB() ) job := &model.Job{} job.ID = jobID err = dao.GetEntity(db, job) if job.UserID == "" || job.Status == model.JobStatusFailed || job.Status == model.JobStatusOverdue || job.FinishedAt.Sub(time.Now()) <= 0 || job.SurplusCount <= 0 || job.LimitCountType <= 0 { return fmt.Errorf("未找到该任务或该任务状态不正常,无法取消!") } //取消已发布的任务 userBill, err := dao.GetUserBill(db, job.UserID, "") if userBill == nil { return fmt.Errorf("未查询到该用户的账单!") } dao.Begin(db) defer func() { if r := recover(); r != nil { dao.Rollback(db) panic(r) } }() if err = financial.AddIncomeUpdateAccount(db, userBill, model.BillTypeJobCancelOverdue, job.SurplusCount*job.AvgPrice); err != nil { dao.Rollback(db) } //3、任务状态被取消 job.Status = model.JobStatusFailed if _, err = dao.UpdateEntity(db, job, "Status"); err != nil { dao.Rollback(db) } dao.Commit(db) return err } func GetJobs(ctx *jxcontext.Context, userIDs []string, categoryIDs, statuss, vendorIDs []int, includeStep bool, fromTime, toTime string, pageSize, offset int) (pagedInfo *model.PagedInfo, err error) { return dao.GetJobs(dao.GetDB(), userIDs, categoryIDs, statuss, vendorIDs, includeStep, utils.Str2Time(fromTime), utils.Str2Time(toTime), pageSize, offset) } func AcceptJob(ctx *jxcontext.Context, jobID int) (errCode string, err error) { var ( db = dao.GetDB() userID = ctx.GetUserID() num int ) job := &model.Job{} job.ID = jobID err = dao.GetEntity(db, job) if job.UserID == "" || job.Status == model.JobStatusFailed || job.Status == model.JobStatusOverdue || job.FinishedAt.Sub(time.Now()) <= 0 || job.SurplusCount <= 0 || job.LimitCountType <= 0 { return errCode, fmt.Errorf("未找到该任务或该任务状态不正常,无法接单!") } num, err = checkJobOrders(db, 0, "<= "+utils.Int2Str(model.JobOrderStatusAccept), userID, utils.ZeroTimeValue, utils.ZeroTimeValue) if num >= AcceptMaxCount { return errCode, fmt.Errorf("每人最多接取" + utils.Int2Str(AcceptMaxCount) + "个任务,请核实!") } num, err = checkJobOrders(db, jobID, "<= "+utils.Int2Str(model.JobOrderStatusWaitAudit), userID, utils.ZeroTimeValue, utils.ZeroTimeValue) if num > 0 { return errCode, fmt.Errorf("您还有此任务未完成,请完成后再接取!") } // num, err = checkJobOrders(db, "= "+utils.Int2Str(model.JobOrderStatusAuditUnPass), userID, utils.ZeroTimeValue, utils.ZeroTimeValue) // if num > 0 { // return fmt.Errorf("您还有此任务未审核通过记录,可直接在未审核中重新提交!") // } switch job.LimitCountType { case model.JobLimitCountTypePO: num, err = checkJobOrders(db, jobID, "<> "+utils.Int2Str(model.JobOrderStatusCancel), userID, utils.ZeroTimeValue, utils.ZeroTimeValue) if num > 0 { return errCode, fmt.Errorf("此任务只支持每人做一次!") } case model.JobLimitCountTypePDO: num, err = checkJobOrders(db, jobID, "<> "+utils.Int2Str(model.JobOrderStatusCancel), userID, DayTimeBegin, DayTimeEnd) if num > 0 { return errCode, fmt.Errorf("此任务只支持每人每天做一次!") } case model.JobLimitCountTypePWO: num, err = checkJobOrders(db, jobID, "<> "+utils.Int2Str(model.JobOrderStatusCancel), userID, WeekTimeBegin, WeekTimeEnd) if num > 0 { return errCode, fmt.Errorf("此任务只支持每人每周做一次!") } case model.JobLimitCountTypeNoLimit: default: return errCode, fmt.Errorf("不支持的任务限次类型!%v", job.LimitCountType) } jobOrder := &model.JobOrder{ JobID: jobID, JobOrderID: jxutils.GenJobOrderNo(), UserID: ctx.GetUserID(), // Status: model.JobOrderStatusAccept, } //美团会员任务 if jobID == model.JobIDMtMembers { jobOrder.Status = model.JobOrderStatusSpec } else { jobOrder.Status = model.JobOrderStatusAccept } dao.Begin(db) defer func() { if r := recover(); r != nil { dao.Rollback(db) panic(r) } }() if err = dao.CreateEntity(db, jobOrder); err != nil { dao.Rollback(db) } //用户接受任务,任务剩余次数-1 job.SurplusCount -= 1 if _, err = dao.UpdateEntity(db, job, "SurplusCount"); err != nil { dao.Rollback(db) } dao.Commit(db) //任务限时完成 defer func() { timer := checkLimitJobOrders(db, job, jobOrder, model.JobTimerTypeAccept) JobTimerMap[jobOrder.JobOrderID] = timer }() //特殊任务,如美团会员,是直接要支付 if jobID == model.JobIDMtMembers { userBill, err := dao.GetUserBill(db, ctx.GetUserID(), "") if err != nil { return errCode, err } if userBill.AccountBalance < job.AvgPrice { return model.ErrCodeAccountBalanceNotEnough, fmt.Errorf("用户余额不足,请充值!") } dao.Begin(db) defer func() { if r := recover(); r != nil { dao.Rollback(db) panic(r) } }() //账户支出 if err = financial.AddExpendUpdateAccount(db, userBill, model.BillTypeSpJob, job.AvgPrice); err != nil { dao.Rollback(db) } dao.Commit(db) } return errCode, err } func CancelAcceptJob(ctx *jxcontext.Context, jobID int, jobOrderID int64) (err error) { var ( db = dao.GetDB() ) jobOrder := &model.JobOrder{} jobOrder.JobOrderID = jobOrderID err = dao.GetEntity(db, jobOrder, "JobOrderID") job := &model.Job{} job.ID = jobID err = dao.GetEntity(db, job) dao.Begin(db) defer func() { if r := recover(); r != nil { dao.Rollback(db) panic(r) } }() //如果当前任务状态正常,剩余数量就加1 if job.Status > 0 { job.SurplusCount += 1 if _, err = dao.UpdateEntity(db, job, "SurplusCount"); err != nil { dao.Rollback(db) } } else { userBill, err := dao.GetUserBill(db, job.UserID, "") if userBill == nil { return fmt.Errorf("未查询到该用户的账单!") } //如果状态不正常(取消或者过期)就要把这一笔退回去 //2、账户收入 if err = financial.AddIncomeUpdateAccount(db, userBill, model.BillTypeJobCancelOverdue, job.AvgPrice); err != nil { dao.Rollback(db) } //3、任务订单状态被取消 jobOrder.Status = model.JobOrderStatusCancel if _, err = dao.UpdateEntity(db, jobOrder, "Status"); err != nil { dao.Rollback(db) } } dao.Commit(db) return err } func checkJobOrders(db *dao.DaoDB, jobID int, statusCompareStr, userID string, fromTime, toTime time.Time) (num int, err error) { jobOrders, err := dao.GetJobOrdersNoPage(db, jobID, 0, userID, statusCompareStr, fromTime, toTime, nil) return len(jobOrders), err } func checkLimitJobOrders(db *dao.DaoDB, job *model.Job, jobOrder *model.JobOrder, jobTimerType int) (timer *time.Timer) { //插到定时任务表里,主要是重启项目后的重启定时器用 jobTimer := &model.JobTimer{ JobID: job.ID, JobOrderID: jobOrder.JobOrderID, Type: jobTimerType, Status: model.JobTimerStatusWait, StartAt: jobOrder.CreatedAt, LimitAt: job.JobLimitAt, } dao.WrapAddIDCULEntity(jobTimer, jxcontext.AdminCtx.GetUserName()) dao.CreateEntity(db, jobTimer) switch jobTimerType { case model.JobTimerTypeAccept: timer = time.NewTimer(time.Hour * time.Duration(job.JobLimitAt)) case model.JobTimerTypeSubmit: timer = time.NewTimer(time.Hour * time.Duration(job.AuditLimitAt)) } utils.CallFuncAsync(func() { select { case <-timer.C: switch jobTimerType { case model.JobTimerTypeAccept: UpdateLimitJobOrders(db, timer, job.ID, jobOrder, jobTimer) case model.JobTimerTypeSubmit: UpdateLimitAuditJobOrders(db, timer, job.ID, jobOrder, jobTimer) } } }) return timer } func UpdateLimitJobOrders(db *dao.DaoDB, timer *time.Timer, jobID int, jobOrder *model.JobOrder, jobTimer *model.JobTimer) { globals.SugarLogger.Debugf("updateLimitJobOrders jobID: %v, jobOrderID: %v", jobID, jobOrder.JobOrderID) defer timer.Stop() if jobOrder.Status > model.JobOrderStatusAccept { return } jobOrder.Status = model.JobOrderStatusCancel if _, err := dao.UpdateEntity(db, jobOrder, "Status"); err == nil { jobTimer.Status = model.JobTimerStatusFinish dao.UpdateEntity(db, jobTimer, "Status") } } func UpdateLimitAuditJobOrders(db *dao.DaoDB, timer *time.Timer, jobID int, jobOrder *model.JobOrder, jobTimer *model.JobTimer) { globals.SugarLogger.Debugf("checkLimitAuditJobOrders jobID: %v, jobOrderID: %v", jobID, jobOrder.JobOrderID) defer timer.Stop() if jobOrder.Status == model.JobOrderStatusWaitAudit { err := AuditJob(jxcontext.AdminCtx, int(jobOrder.JobOrderID), model.JobOrderStatusAuditPass, "超时系统通过") if err != nil { globals.SugarLogger.Debugf("checkLimitAuditJobOrders err: %v jobID: %v, jobOrderID: %v", err, jobID, jobOrder.JobOrderID) } else { jobTimer.Status = model.JobTimerStatusFinish dao.UpdateEntity(db, jobTimer, "Status") } } } func SubmitJob(ctx *jxcontext.Context, jobOrder *model.JobOrder) (err error) { var ( db = dao.GetDB() ) if jobOrder.JobID == 0 || jobOrder.JobOrderID == 0 { return fmt.Errorf("传入数据有误!") } job := &model.Job{} job.ID = jobOrder.JobID err = dao.GetEntity(db, job) jobOrder2 := &model.JobOrder{} jobOrder2.JobOrderID = jobOrder.JobOrderID err = dao.GetEntity(db, jobOrder2, "JobOrderID") if jobOrder2.JobID == 0 { return fmt.Errorf("未查询到相应的任务!") } if jobOrder2.Status >= model.JobOrderStatusWaitAudit { return fmt.Errorf("任务订单状态有误!") } if ctx.GetUserID() != jobOrder2.UserID { return fmt.Errorf("任务订单接收人有误!") } jobOrder2.Img = jobOrder.Img jobOrder2.Content = jobOrder.Content jobOrder2.SubmitAuditAt = time.Now() jobOrder2.Status = model.JobOrderStatusWaitAudit if _, err = dao.UpdateEntity(db, jobOrder2, "Img", "Content", "SubmitAuditAt", "Status"); err == nil { //任务定时器停止 JobTimerMap[jobOrder2.JobOrderID].Stop() //任务定时表状态完成 jobTimer := &model.JobTimer{ JobID: job.ID, JobOrderID: jobOrder2.JobOrderID, Type: model.JobTimerTypeAccept, } if err = dao.GetEntity(db, jobTimer, "JobID", "JobOrderID", "Type"); err == nil { jobTimer.Status = model.JobTimerStatusFinish dao.UpdateEntity(db, jobTimer, "Status") } //审核定时开启 timer := checkLimitJobOrders(db, job, jobOrder2, model.JobTimerTypeSubmit) JobAuditTimerMap[jobOrder2.JobOrderID] = timer } return err } func AuditJob(ctx *jxcontext.Context, jobOrderID, status int, comment string) (err error) { var ( db = dao.GetDB() ) jobOrder := &model.JobOrder{} jobOrder.JobOrderID = int64(jobOrderID) err = dao.GetEntity(db, jobOrder, "JobOrderID") job := &model.Job{} job.ID = jobOrder.JobID err = dao.GetEntity(db, job) if ctx.GetUserID() != job.UserID { return fmt.Errorf("任务发起人才能审核!") } //审核时,若此任务已过期或者已取消,不通过则应将此任务保证金退还给发起人,通过则应将单次任务保证金给接受人 //若此任务未过期,不通过则此任务剩余数量将+1,通过则应将单次任务保证金给接受人 jobOrder.Status = status jobOrder.Comment = comment jobOrder.AuditAt = time.Now() jobOrder.LastOperator = ctx.GetUserName() dao.Begin(db) defer func() { if r := recover(); r != nil { dao.Rollback(db) panic(r) } }() if _, err = dao.UpdateEntity(db, jobOrder, "Status", "Comment", "AuditAt", "LastOperator"); err != nil { dao.Rollback(db) } if status == model.JobOrderStatusAuditPass { //接收人账户收入 userBillJobOrder, err := dao.GetUserBill(db, jobOrder.UserID, "") if err = financial.AddIncomeUpdateAccount(db, userBillJobOrder, model.BillTypeJob, job.AvgPrice); err != nil { dao.Rollback(db) } } else { if job.Status < 0 { userBill, err := dao.GetUserBill(db, job.UserID, "") if err = financial.AddIncomeUpdateAccount(db, userBill, model.BillTypeJobAuditUnPassWithCancelOverdue, job.AvgPrice); err != nil { dao.Rollback(db) } } else { job.SurplusCount += 1 if _, err = dao.UpdateEntity(db, job, "SurplusCount"); err != nil { dao.Rollback(db) } } } dao.Commit(db) //任务定时器停止 JobAuditTimerMap[int64(jobOrderID)].Stop() //任务定时表状态完成 jobTimer := &model.JobTimer{ JobID: job.ID, JobOrderID: jobOrder.JobOrderID, Type: model.JobTimerTypeSubmit, } if err = dao.GetEntity(db, jobTimer, "JobID", "JobOrderID", "Type"); err == nil { jobTimer.Status = model.JobTimerStatusFinish dao.UpdateEntity(db, jobTimer, "Status") } return err } func RefreshJobStatus(ctx *jxcontext.Context) (err error) { var ( db = dao.GetDB() ) globals.SugarLogger.Debugf("RefreshJobStatus begin...") jobs, err := dao.GetJobsNoPage(db, nil, nil, []int{model.JobStatusDoing}, utils.ZeroTimeValue, utils.ZeroTimeValue, false) if err != nil { globals.SugarLogger.Debugf("RefreshJobStatus err :%v", err) return } for _, job := range jobs { if time.Now().Sub(job.FinishedAt) >= 0 { job.Status = model.JobStatusOverdue dao.UpdateEntity(db, job, "Status") } } globals.SugarLogger.Debugf("RefreshJobStatus end...") return err } func ImprotMtMembers(ctx *jxcontext.Context, mtMembers []*model.MtMember) (err error) { var ( db = dao.GetDB() ) for _, v := range mtMembers { v.ShortLink = v.URL[strings.LastIndex(v.URL, "/")+1 : len(v.URL)] dao.WrapAddIDCULDEntity(v, ctx.GetUserName()) } if err = dao.CreateMultiEntities(db, mtMembers); err == nil { job := &model.Job{} job.ID = model.JobIDMtMembers dao.GetEntity(db, job) if job != nil { job.Count += len(mtMembers) dao.UpdateEntity(db, job, "Count") } } return err } func RechargeMtMembers(ctx *jxcontext.Context, phone int) (err error) { var ( db = dao.GetDB() ) mtMember, err := dao.GetMtMember(db) if err != nil { return err } if err = api.MtMemberAPI.RechargeExchange(phone, mtMember.ShortLink); err == nil { mtMember.DeletedAt = time.Now() dao.UpdateEntity(db, mtMember, "DeletedAt") } return err } func SendJdDelivery(ctx *jxcontext.Context, dOrder *model.DeliveryOrder) (errCode string, err error) { var ( db = dao.GetDB() ) sendDeliveryList, _, err := dao.QueryUserDeliveryAddress(db, int64(dOrder.DeliverySendID), nil, 0, 0) receiveDeliveryList, _, err := dao.QueryUserDeliveryAddress(db, int64(dOrder.DeliveryReceiveID), nil, 0, 0) userBill, err := dao.GetUserBill(db, ctx.GetUserID(), "") if err != nil { return errCode, err } if userBill.AccountBalance < dOrder.PayPrice { return model.ErrCodeAccountBalanceNotEnough, fmt.Errorf("用户余额不足,请充值!") } if len(sendDeliveryList) == 0 { return errCode, fmt.Errorf("未找到寄件人地址!") } if len(receiveDeliveryList) == 0 { return errCode, fmt.Errorf("未找到取件人地址!") } dao.WrapAddIDCULEntity(dOrder, ctx.GetUserName()) if vendorWaybillID, err := api.JdEclpAPI.WaybillReceive(&jdeclpapi.WaybillReceiveParam{ SalePlat: jdeclpapi.SalePlatSourceDelivery, CustomerCode: jdeclpapi.CustomerCode, OrderID: utils.Int64ToStr(jxutils.GenOrderNo()), SenderName: sendDeliveryList[0].ConsigneeName, SenderAddress: sendDeliveryList[0].Address + sendDeliveryList[0].DetailAddress, SenderTel: sendDeliveryList[0].ConsigneeMobile, ReceiveName: receiveDeliveryList[0].ConsigneeName, ReceiveAddress: receiveDeliveryList[0].Address + receiveDeliveryList[0].DetailAddress, ReceiveTel: receiveDeliveryList[0].ConsigneeMobile, Weight: dOrder.Weight, Vloumn: dOrder.Vloumn, PackageCount: dOrder.PackageCount, Description: dOrder.Description, Aging: 5, PromiseTimeType: 1, //特惠送 }); err == nil { dOrder.VendorWaybillID = vendorWaybillID } else { return errCode, err } dOrder.Status = model.OrderStatusNew dOrder.UserID = ctx.GetUserID() dao.Begin(db) defer func() { if r := recover(); r != nil { dao.Rollback(db) panic(r) } }() if err = dao.CreateEntity(db, dOrder); err != nil { dao.Rollback(db) } //账户支出明细 if err = financial.AddExpendUpdateAccount(db, userBill, model.BillTypeSpJob, dOrder.PayPrice); err != nil { dao.Rollback(db) } dao.Commit(db) return errCode, err } func CancelJdDelivery(ctx *jxcontext.Context, vendorWaybillID, reason string) (err error) { var ( db = dao.GetDB() dOrder = &model.DeliveryOrder{ VendorWaybillID: vendorWaybillID, } ) err = dao.GetEntity(db, dOrder, "VendorWaybillID") userBill, err := dao.GetUserBill(db, ctx.GetUserID(), "") dOrders, err := dao.GetDeliveryOrdersNoPage(db, []string{ctx.GetUserID()}, []int{model.OrderStatusCanceled}, DayTimeBegin, DayTimeEnd) if err != nil { return err } if len(dOrders) > 0 { return fmt.Errorf("抱歉,您已经在今天取消过京东物流订单!") } if dOrder.ID == 0 { return fmt.Errorf("未找到该运单!") } if err = api.JdEclpAPI.CancelWayBill(&jdeclpapi.CancelWayBillParam{ WaybillCode: vendorWaybillID, CustomerCode: jdeclpapi.CustomerCode, Source: "JOS", CancelReason: reason, OperatorName: ctx.GetUserName(), }); err != nil { return err } dOrder.Status = model.OrderStatusCanceled dOrder.OrderFinishedAt = time.Now() dOrder.Comment = reason dao.Begin(db) defer func() { if r := recover(); r != nil { dao.Rollback(db) panic(r) } }() if _, err = dao.UpdateEntity(db, dOrder, "Status", "OrderFinishedAt", "Comment"); err != nil { dao.Rollback(db) } if err = financial.AddIncomeUpdateAccount(db, userBill, model.BillTypeSpJob, dOrder.PayPrice); err != nil { dao.Rollback(db) } dao.Commit(db) return err } func GetJdDelivery(ctx *jxcontext.Context, status int, fromTime, toTime string, pageSize, offset int) (pagedInfo *model.PagedInfo, err error) { return dao.GetDeliveryOrders(dao.GetDB(), []string{ctx.GetUserID()}, []int{status}, utils.Str2Time(fromTime), utils.Str2Time(toTime), pageSize, offset) } func ResetJobTimers() { var ( db = dao.GetDB() ) jobTimers, err := dao.GetJobTimers(db, model.JobTimerStatusWait) if err != nil { return } task := tasksch.NewParallelTask("ResetJobTimers", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(true), jxcontext.AdminCtx, func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { jobTimer := batchItemList[0].(*model.JobTimer) switch jobTimer.Type { case model.JobTimerTypeAccept: timer := time.NewTimer(jobTimer.StartAt.Add(time.Duration(jobTimer.LimitAt) * time.Hour).Sub(time.Now())) jobOrders, err := dao.GetJobOrdersNoPage(db, jobTimer.JobID, jobTimer.JobOrderID, "", "", utils.ZeroTimeValue, utils.ZeroTimeValue, nil) if err != nil { return retVal, err } utils.CallFuncAsync(func() { select { case <-timer.C: switch jobTimer.Type { case model.JobTimerTypeAccept: UpdateLimitJobOrders(db, timer, jobTimer.JobID, jobOrders[0], jobTimer) case model.JobTimerTypeSubmit: UpdateLimitAuditJobOrders(db, timer, jobTimer.JobID, jobOrders[0], jobTimer) } } }) case model.JobTimerTypeSubmit: default: return retVal, err } return retVal, err }, jobTimers) tasksch.HandleTask(task, nil, true).Run() task.GetID() }