go-common/app/job/main/up/service/sign_task_job.go

301 lines
8.5 KiB
Go
Raw Normal View History

2019-04-22 10:49:16 +00:00
package service
import (
"context"
"time"
"go-common/app/admin/main/up/util"
"go-common/app/job/main/up/conf"
"go-common/app/job/main/up/dao/upcrm"
"go-common/app/job/main/up/model/signmodel"
"go-common/app/job/main/up/model/upcrmmodel"
v1 "go-common/app/service/main/archive/api"
"go-common/library/log"
xtime "go-common/library/time"
"github.com/jinzhu/gorm"
)
//CheckTaskJob check task job
func (s *Service) CheckTaskJob(tm time.Time) {
// 今天计算昨天的数据
var yesterday = tm.AddDate(0, 0, -1)
log.Info("start to run CheckTaskJob, date=%s, yesterday=%s", tm, yesterday)
s.CheckTaskFinish(yesterday)
log.Info("finish run CheckTaskJob, date=%s", tm)
}
//Archive data
type Archive struct {
ID int64 `gorm:"column:id"`
}
//CheckTaskFinish check task finish, calculate datas in (-,date]
func (s *Service) CheckTaskFinish(date time.Time) {
// 1.查找所有有效的合同id, begin_date <= date && end _date >= date
// 2.找到所有合同id对应的任务id,
// 3.根据任务类型,日、周、月、累计,计算任务周期[a,b)
// 4.计算完成数量
var crmdb = s.crmdb.GetDb()
var dateStr = date.Format(upcrmmodel.TimeFmtDate)
var offset = 0
var limit = 200
var actualSize = limit
log.Info("start to check task state")
archiveDb, err := gorm.Open("mysql", conf.Conf.ArchiveOrm.DSN)
s.crmdb.StartTask(upcrmmodel.TaskTypeSignTaskCalculate, date)
archiveDb.LogMode(true)
if err != nil {
log.Error("connect archive db fail")
return
}
defer archiveDb.Close()
defer func() {
if err == nil {
s.crmdb.FinishTask(upcrmmodel.TaskTypeSignTaskCalculate, date, upcrmmodel.TaskStateFinish)
} else {
s.crmdb.FinishTask(upcrmmodel.TaskTypeSignTaskCalculate, date, upcrmmodel.TaskStateError)
}
}()
var taskTotalCount = 0
for actualSize == limit {
var signUps []*signmodel.SignUp
var signUpMap = make(map[uint32]*signmodel.SignUp)
// 1
err = crmdb.Table(signmodel.TableNameSignUp).
Select("id, begin_date, end_date").
Where("begin_date <= ? and end_date >= ?", dateStr, dateStr).
Offset(offset).
Limit(limit).
Find(&signUps).Error
offset += limit
if err != nil && err != gorm.ErrRecordNotFound {
log.Error("err get signs, err=%+v", err)
return
}
actualSize = len(signUps)
var signIDs []uint32
for _, v := range signUps {
signUpMap[v.ID] = v
signIDs = append(signIDs, v.ID)
}
// 2
var taskList []*signmodel.SignTask
err = crmdb.Where("sign_id in (?) and state != ? and generate_date<?", signIDs, signmodel.SignTaskStateDelete, dateStr).
Find(&taskList).Error
if err != nil {
log.Error("err get tasks, err=%+v", err)
return
}
// 3
for _, task := range taskList {
taskTotalCount++
if task.Mid == 0 {
log.Error("task's mid is zero, please check! task id=%d", task.ID)
continue
}
var signInfo, ok = signUpMap[task.SignID]
if !ok {
log.Error("sign not found, err=%v", err)
continue
}
// 4 计算数量
err = s.checkSingleTask(task, signInfo, date, archiveDb)
if err != nil {
log.Error("check task err, task_id=%d, err=%v", task.ID, err)
continue
}
}
log.Info("finish to check task state, task total num=%d", taskTotalCount)
}
}
// get task history, if not exist, then will create it
func (s *Service) getOrCreateTaskHistory(task *signmodel.SignTask, generateDate time.Time) (res *signmodel.SignTaskHistory, err error) {
var crmdb = s.crmdb.GetDb()
res = new(signmodel.SignTaskHistory)
err = crmdb.Select("*").Where("task_template_id=? and generate_date=?", task.ID, generateDate).
Find(&res).Error
// 创建一条,如果没找到的话
if err == gorm.ErrRecordNotFound {
res = &signmodel.SignTaskHistory{
Mid: task.Mid,
SignID: task.SignID,
TaskTemplateID: task.ID,
TaskType: task.TaskType,
TaskCondition: task.TaskCondition,
Attribute: task.Attribute,
GenerateDate: xtime.Time(generateDate.Unix()),
State: signmodel.SignTaskStateRunning,
}
err = crmdb.Save(&res).Error
if err != nil {
log.Error("create task history fail, err=%v, task=%v", err, task)
return
}
}
return
}
// check task state
func (s *Service) checkSingleTask(task *signmodel.SignTask, signInfo *signmodel.SignUp, date time.Time, archiveDb *gorm.DB) (err error) {
var taskBegin, taskEnd time.Time
if task.TaskType == signmodel.TaskTypeAccumulate {
taskBegin = signInfo.BeginDate.Time()
taskEnd = signInfo.EndDate.Time()
} else {
taskBegin, taskEnd = upcrm.GetTaskDuration(date, task.TaskType)
}
if task.Mid == 0 {
log.Error("task's mid is zero, please check! task id=%d", task.ID)
return
}
// get task history
// 如果是累计任务这里的taskBegin要设置为0
var tBegin = taskBegin
if task.TaskType == signmodel.TaskTypeAccumulate {
tBegin = time.Time{}
}
taskHistory, err := s.getOrCreateTaskHistory(task, tBegin)
if err != nil {
log.Error("get task history fail, task=%+v, err=%+v", task, err)
return
}
var dateStr = date.Format(upcrmmodel.TimeFmtDate)
switch {
default:
var crmdb = s.crmdb.GetDb()
// 4.去稿件库中查找对应的稿件数量
var archiveCount = 0
var archiveList []*Archive
err = archiveDb.Table("archive").
Where("mid = ? and ctime>= ? and ctime <? and (state >= 0 or state = -6)",
task.Mid, taskBegin, taskEnd).
Select("id").
Find(&archiveList).
Error
if err != nil && err != gorm.ErrRecordNotFound {
log.Error("check archive count fail, taskid=%+v err=%+v", task, err)
break
}
var finalResult []int64
// 5.任务完成度统计时,
// 若录入为不包含商单,
// 则任务完成数=新增稿件数-减去(绿洲/商单报备)稿件数+请假任务数;
// 若录入为包含商单,
// 则任务完成数=新增稿件数+请假任务数;
// 如果没有archive就直接返回
if len(archiveList) != 0 {
// 需要判断商单
if task.IsAttrSet(signmodel.SignTaskAttrBitBusiness) {
var ids []int64
for _, v := range archiveList {
ids = append(ids, v.ID)
}
ids = util.Unique(ids)
// 查询archive服务
archiveResult, e := s.arcRPC.Arcs(context.Background(), &v1.ArcsRequest{Aids: ids})
if e != nil {
err = e
log.Error("get archive result err, err=%+v", err)
break
}
for _, v := range archiveList {
a, ok := archiveResult.Arcs[v.ID]
// 是商单的要排除
if !ok || a.OrderID > 0 {
continue
}
finalResult = append(finalResult, v.ID)
}
} else {
for _, v := range archiveList {
finalResult = append(finalResult, v.ID)
}
}
archiveCount = len(finalResult)
}
// 请假任务数
var absence signmodel.SignTaskAbsence
err = crmdb.Select("sum(absence_count) as absence_count").
Where("task_history_id=? and state!=?", taskHistory.ID, signmodel.SignTaskAbsenceStateDelete).
Find(&absence).Error
if err != nil {
log.Error("get task absence fail, task history=%+v", taskHistory)
return
}
archiveCount += int(absence.AbsenceCount)
log.Info("task count=%d, archive=%d, absence=%d, task=%+v", archiveCount, len(finalResult), absence.AbsenceCount, taskHistory)
// 更新task history的数量
task.TaskCounter = int32(archiveCount)
var tx = crmdb.Begin()
defer func() {
if r := recover(); r != nil || err != nil {
log.Error("roll back task update, task=%+v, r=%+v | err=%+v", task, r, err)
tx.Rollback()
}
}()
err = tx.Table(signmodel.TableNameSignTask).Where("id=?", task.ID).
Updates(map[string]interface{}{
"generate_date": dateStr,
}).Error
if err != nil {
log.Error("update sign task fail, task=%+v, err=%+v", task, err)
return
}
// update history
var state = signmodel.SignTaskStateRunning
if archiveCount >= int(task.TaskCondition) {
state = signmodel.SignTaskStateFinish
}
err = tx.Table(signmodel.TableNameSignTaskHistory).Where("id=?", taskHistory.ID).
Updates(map[string]interface{}{
"task_counter": task.TaskCounter,
"task_condition": task.TaskCondition,
"state": state,
"attribute": task.Attribute,
"task_type": task.TaskType,
}).Error
if err != nil {
log.Error("update sign task history fail, task=%+v, err=%+v", task, err)
return
}
// update sign
err = tx.Table(signmodel.TableNameSignUp).Where("id=?", task.SignID).
Updates(map[string]interface{}{
"task_state": state,
}).Error
if err != nil {
log.Error("update sign up fail, task=%+v, err=%+v", task, err)
return
}
err = tx.Commit().Error
if err != nil {
log.Error("commit err, err=%+v", err)
}
}
return
}