package implments
//
//import (
//	"LAPP_ACURA_MOM_BACKEND/common"
//	baseDal "LAPP_ACURA_MOM_BACKEND/dao/base"
//	meDal "LAPP_ACURA_MOM_BACKEND/dao/me"
//	dal "LAPP_ACURA_MOM_BACKEND/dao/om"
//	"LAPP_ACURA_MOM_BACKEND/db"
//	"LAPP_ACURA_MOM_BACKEND/global"
//	"LAPP_ACURA_MOM_BACKEND/grmi"
//	"LAPP_ACURA_MOM_BACKEND/infra/logger"
//	baseMeta "LAPP_ACURA_MOM_BACKEND/meta/base"
//	baseModel "LAPP_ACURA_MOM_BACKEND/models/base"
//	channelModel "LAPP_ACURA_MOM_BACKEND/models/channel"
//	model "LAPP_ACURA_MOM_BACKEND/models/om"
//	"github.com/go-xorm/xorm"
//	uuid "github.com/iris-contrib/go.uuid"
//	"strconv"
//	"strings"
//	"time"
//)
//
//// ExecuteSingleCrossPlantTask 执行跨工厂任务
//func (impl *SerialOrderServiceImplement) ExecuteSingleCrossPlantTask(user *global.User, taskId int) error {
//	engine := db.Eloquent.Master()
//	session := engine.NewSession()
//	defer session.Close()
//	releaseId, err := uuid.NewV4()
//	if err != nil {
//		return nil
//	}
//	log, _ := logger.NewLogger("跨工厂生成计划,id:"+releaseId.String(), "CrossPlant")
//	taskDao := baseDal.NewCrossPlanTaskHeadDAO(session, user.UserId)
//	task, err := taskDao.SelectOne(taskId)
//	if err != nil {
//		log.Error("获取跨工厂任务失败, 任务ID:" + strconv.Itoa(taskId) + ", 错误:" + err.Error())
//		return grmi.NewBusinessError("获取跨工厂任务失败, 任务ID:" + strconv.Itoa(taskId) + ", 错误:" + err.Error())
//	}
//	if task == nil {
//		log.Error("跨工厂任务不存在, 任务ID:" + strconv.Itoa(taskId))
//		return grmi.NewBusinessError("跨工厂任务不存在, 任务ID:" + strconv.Itoa(taskId))
//	}
//	// 校验任务数据合规性
//	projectDao := meDal.NewProjectDAO(session, user.PlantNr, user.UserId)
//	project, err := projectDao.SelectOne(task.ProjectId)
//	if err != nil {
//		task.Status = baseModel.CROSS_TASK_STATUS_ERROR
//		task.ErrorMsg = "查询任务项目失败，错误:" + err.Error()
//		innerErr := taskDao.UpdateOne(task)
//		if innerErr != nil {
//			log.Error("更新任务状态失败, 错误:" + innerErr.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr))
//		}
//		return grmi.NewBusinessError(task.ErrorMsg)
//	}
//	if project == nil {
//		task.Status = baseModel.CROSS_TASK_STATUS_ERROR
//		task.ErrorMsg = "任务项目不存在, 项目ID:" + task.ProjectId
//		innerErr := taskDao.UpdateOne(task)
//		if innerErr != nil {
//			log.Error("更新任务状态失败, 错误:" + innerErr.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr))
//		}
//		return grmi.NewBusinessError(task.ErrorMsg)
//	}
//	// 获取生产的物料，通过;切割
//	productIdLi := strings.Split(task.ArtId, ";")
//	if len(productIdLi) == 0 {
//		task.Status = baseModel.CROSS_TASK_STATUS_ERROR
//		task.ErrorMsg = "任务未包含物料数据"
//		innerErr := taskDao.UpdateOne(task)
//		if innerErr != nil {
//			log.Error("更新任务状态失败, 错误:" + innerErr.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr))
//		}
//		return grmi.NewBusinessError(task.ErrorMsg)
//	}
//	if task.PlanEndTime.Restore().Before(task.PlanStartTime.Restore()) {
//		task.Status = baseModel.CROSS_TASK_STATUS_ERROR
//		task.ErrorMsg = "任务计划结束时间早于开始时间"
//		innerErr := taskDao.UpdateOne(task)
//		if innerErr != nil {
//			log.Error("更新任务状态失败, 错误:" + innerErr.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr))
//		}
//		return grmi.NewBusinessError(task.ErrorMsg)
//	}
//	// 获取每个总成当前派工数量 用于task退出重新启动
//	releaseQtyStrLi := strings.Split(task.ReleaseQty, ";")
//	releaseQtyLi := make([]int, 0, len(productIdLi))
//	if len(releaseQtyStrLi) == 0 {
//		for range productIdLi {
//			releaseQtyStrLi = append(releaseQtyStrLi, "0")
//		}
//	} else if len(releaseQtyStrLi) != len(productIdLi) {
//		task.Status = baseModel.CROSS_TASK_STATUS_ERROR
//		task.ErrorMsg = "派工数量格式错误"
//		innerErr := taskDao.UpdateOne(task)
//		if innerErr != nil {
//			log.Error("更新任务状态失败, 错误:" + innerErr.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr))
//		}
//		return grmi.NewBusinessError(task.ErrorMsg)
//	}
//	// 获取当前总派工的数量
//	var currentQty int
//	for _, releaseQtyStr := range releaseQtyStrLi {
//		qty, err := strconv.Atoi(releaseQtyStr)
//		if err != nil {
//			task.Status = baseModel.CROSS_TASK_STATUS_ERROR
//			task.ErrorMsg = "派工数量格式错误"
//			innerErr := taskDao.UpdateOne(task)
//			if innerErr != nil {
//				log.Error("更新任务状态失败, 错误:" + innerErr.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr))
//			}
//			return grmi.NewBusinessError(task.ErrorMsg)
//		}
//		releaseQtyLi = append(releaseQtyLi, qty)
//		currentQty += qty
//	}
//	// 总时间 / 总数量 = 每个工单消耗的时间
//	subTime := task.PlanEndTime.Restore().Sub(task.PlanStartTime.Restore())
//	totalQty := len(productIdLi) * task.PlanQty
//	perDuration := int(subTime.Seconds()) / totalQty
//	// 调度模式 每一次生成多少个相同物料的工单
//	schedQty, err := strconv.Atoi(task.SchedType)
//	if err != nil || schedQty == 0 {
//		task.Status = baseModel.CROSS_TASK_STATUS_ERROR
//		task.ErrorMsg = "不支持的调度模式"
//		innerErr := taskDao.UpdateOne(task)
//		if innerErr != nil {
//			log.Error("更新任务状态失败, 错误:" + innerErr.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr))
//		}
//		return grmi.NewBusinessError(task.ErrorMsg)
//	}
//	// 生成所有物料的工单工艺
//	productCraftMap := make(map[string]*model.SerialOrder)
//	for _, productId := range productIdLi {
//		serialOrderCraft, err := impl.SingleProductTask(user, session, task, productId)
//		if err != nil {
//			task.Status = baseModel.CROSS_TASK_STATUS_ERROR
//			task.ErrorMsg = "生成工单工艺失败, 错误:" + err.Error()
//			innerErr := taskDao.UpdateOne(task)
//			if innerErr != nil {
//				log.Error("更新任务状态失败, 错误:" + innerErr.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr))
//			}
//			return grmi.NewBusinessError(task.ErrorMsg)
//		}
//		productCraftMap[productId] = serialOrderCraft
//	}
//
//	// 记录生成计划中间的数量
//	type ProductQty struct {
//		ProductId  string // 物料id
//		CurrentQty int    // 当前数量
//	}
//	productQtyCacheLi := make([]ProductQty, 0, len(productIdLi))
//	for _, productId := range productIdLi {
//		productQtyData := ProductQty{
//			ProductId: productId,
//		}
//		productQtyCacheLi = append(productQtyCacheLi, productQtyData)
//	}
//	// 将需要绑定的总成工单通过物料进行聚合
//	taskArtOrderMap := make(map[string][]baseModel.CrossPlanTaskDetail)
//	for _, taskDetail := range task.CrossPlanTaskDetailLi {
//		taskArtOrderMap[taskDetail.ArtId] = append(taskArtOrderMap[taskDetail.ArtId], taskDetail)
//	}
//	taskArtOrderIndexMap := make(map[string]int)
//	for _, productId := range productIdLi {
//		taskArtOrderIndexMap[productId] = 0
//	}
//	for artId, taskDetailLi := range taskArtOrderMap {
//		if len(taskDetailLi) != task.PlanQty {
//			task.Status = baseModel.CROSS_TASK_STATUS_ERROR
//			task.ErrorMsg = "物料绑定的总成工单数量和计划数量不一致, 物料ID:" + artId
//			innerErr := taskDao.UpdateOne(task)
//			if innerErr != nil {
//				log.Error("更新任务状态失败, 错误:" + innerErr.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr))
//			}
//			return grmi.NewBusinessError(task.ErrorMsg)
//		}
//	}
//	// 进行工单及工艺数据生成
//	for {
//		// 派工数量和计划总数相同 退出循环
//		if currentQty == totalQty {
//			break
//		}
//		for index, productQtyCache := range productQtyCacheLi {
//			// 当前总成已达到一次调度数量
//			if productQtyCache.CurrentQty == schedQty {
//				productQtyCache.CurrentQty = 0
//				productQtyCacheLi[index] = productQtyCache
//				continue
//			}
//			// 每一个工单是一次事务
//			if err = session.Begin(); err != nil {
//				task.Status = baseModel.CROSS_TASK_STATUS_ERROR
//				task.ErrorMsg = "开启事务失败, 错误:" + err.Error()
//				innerErr := taskDao.UpdateOne(task)
//				if innerErr != nil {
//					log.Error("更新任务状态失败, 错误:" + innerErr.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr))
//				}
//				return grmi.NewBusinessError(task.ErrorMsg)
//			}
//			orderCraft := productCraftMap[productQtyCache.ProductId]
//			planStartTime := task.PlanStartTime.Restore().Add(time.Duration(currentQty*perDuration) * time.Second)
//			err = impl.SaveBatchOrderData(user, session, orderCraft, planStartTime, perDuration, schedQty, project.SerialOrderSnr)
//			if err != nil {
//				_ = session.Rollback()
//				task.Status = baseModel.CROSS_TASK_STATUS_ERROR
//				task.ErrorMsg = "保存工单工艺失败, 错误:" + err.Error()
//				innerErr := taskDao.UpdateOne(task)
//				if innerErr != nil {
//					log.Error("更新任务状态失败, 错误:" + innerErr.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr))
//				}
//				return grmi.NewBusinessError(task.ErrorMsg)
//			}
//			releaseQtyLi[index] += schedQty
//			var totalReleaseQty string
//			for index, releaseQty := range releaseQtyLi {
//				if index != 0 {
//					totalReleaseQty += ";"
//				}
//				totalReleaseQty += strconv.Itoa(releaseQty)
//			}
//			task.ReleaseQty = totalReleaseQty
//			currentQty += schedQty
//			if currentQty == totalQty {
//				if task.Status == baseModel.CROSS_TASK_STATUS_PLAN {
//					task.StartTime = grmi.DateTime(time.Now())
//				}
//				task.Status = baseModel.CROSS_TASK_STATUS_ACCOMPLISHED
//				task.ActQty = task.PlanQty
//				task.AccomplishTime = grmi.DateTime(time.Now())
//			} else {
//				if task.Status == baseModel.CROSS_TASK_STATUS_PLAN {
//					task.StartTime = grmi.DateTime(time.Now())
//				}
//				task.Status = baseModel.CHECK_STATUS_RUNNING
//			}
//			err = taskDao.UpdateOne(task)
//			if err != nil {
//				_ = session.Rollback()
//				log.Error("更新任务状态失败, 错误:" + err.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr))
//				return err
//			}
//			_ = session.Commit()
//		}
//	}
//	return nil
//}
//
//// SaveBatchOrderData 保存总成的工艺数据
//func (impl *SerialOrderServiceImplement) SaveBatchOrderData(user *global.User, session *xorm.Session, orderCraft *model.SerialOrder, planStartTime time.Time, perDuration, qty int, snrRule string) (err error) {
//	serialOrderDao := dal.NewSerialOrderDAO(session, user.PlantNr, user.UserId)
//	serialOrderStatusDao := dal.NewSerialOrderStatusDAO(session, user.PlantNr, user.UserId)
//	serialOrderPoDao := dal.NewSerialOrderPOLstDAO(session, user.PlantNr, user.UserId)
//	serialOrderStepDao := dal.NewSerialOrderStepLstDAO(session, user.PlantNr, user.UserId)
//	serialOrderOpDetailDao := dal.NewSerialOrderOPDetailDAO(session, user.PlantNr, user.UserId)
//	labelHeadDao := baseDal.NewLabelHeadDAO(session, user.PlantNr, user.UserId)
//	labelDetailDao := baseDal.NewLabelDetailDAO(session, user.PlantNr, user.UserId)
//	snrDao := baseDal.NewSnrDAO(session, user.PlantNr, user.UserId)
//	writeSerialOrderLi := make([]model.SerialOrder, 0)
//	writeSerialOrderStatusLi := make([]model.SerialOrderStatus, 0)
//	writeSerialOrderStepLi := make([]model.SerialOrderStepLst, 0)
//	writeSerialOrderPoLi := make([]model.SerialOrderPOLst, 0)
//	writeSerialOrderOpLi := make([]model.SerialOrderOPDetail, 0)
//	writeLabelHeadLi := make([]baseModel.LabelHead, 0)
//	writeLabelDetailLi := make([]baseModel.LabelDetail, 0)
//	for i := 0; i < qty; i++ {
//		var serialOrder model.SerialOrder
//		serialOrder = *orderCraft
//		serialOrder.PlanStartTime = grmi.DateTime(planStartTime.Add(time.Duration(perDuration*i) * time.Second))
//		serialOrder.PlanEndTime = grmi.DateTime(planStartTime.Add(time.Duration(perDuration*(i+1)) * time.Second))
//		serialOrder.PlanStartDate = grmi.Date(serialOrder.PlanStartTime)
//		serialOrder.PlanEndDate = grmi.Date(serialOrder.PlanEndTime)
//		timeInt, err := strconv.Atoi(planStartTime.Format("060102150405"))
//		if err != nil {
//			return grmi.NewBusinessError("通过时间获取工单调度Key失败, error:" + err.Error())
//		}
//		var dealedSchedKey = int64(timeInt * 100)
//		serialOrder.SchedKey = dealedSchedKey
//		serialNum, err := snrDao.GetNextSnrWithTime(snrRule, serialOrder.PlanStartTime.Restore())
//		if err != nil {
//			return grmi.NewBusinessError("生成工单流水号失败, error:" + err.Error())
//		}
//		serialOrder.SerialOrderPOLstLi = make([]model.SerialOrderPOLst, len(orderCraft.SerialOrderPOLstLi), len(orderCraft.SerialOrderPOLstLi))
//		serialOrder.SerialOrderStepLstLi = make([]model.SerialOrderStepLst, len(orderCraft.SerialOrderStepLstLi), len(orderCraft.SerialOrderStepLstLi))
//		serialOrder.SerialOrderOPDetailLi = make([]model.SerialOrderOPDetail, len(orderCraft.SerialOrderOPDetailLi), len(orderCraft.SerialOrderOPDetailLi))
//		serialOrder.LabelHeadLi = make([]baseModel.LabelHead, len(orderCraft.LabelHeadLi), len(orderCraft.LabelHeadLi))
//		serialOrder.LabelDetailLi = make([]baseModel.LabelDetail, len(orderCraft.LabelDetailLi), len(orderCraft.LabelDetailLi))
//		copy(serialOrder.SerialOrderPOLstLi, orderCraft.SerialOrderPOLstLi)
//		copy(serialOrder.SerialOrderStepLstLi, orderCraft.SerialOrderStepLstLi)
//		copy(serialOrder.SerialOrderOPDetailLi, orderCraft.SerialOrderOPDetailLi)
//		copy(serialOrder.LabelHeadLi, orderCraft.LabelHeadLi)
//		copy(serialOrder.LabelDetailLi, orderCraft.LabelDetailLi)
//		impl.ReplaceData(&serialOrder, serialNum, true)
//		writeSerialOrderLi = append(writeSerialOrderLi, serialOrder)
//		writeSerialOrderStatusLi = append(writeSerialOrderStatusLi, serialOrder.SerialOrderStatus)
//		writeSerialOrderPoLi = append(writeSerialOrderPoLi, serialOrder.SerialOrderPOLstLi...)
//		writeSerialOrderStepLi = append(writeSerialOrderStepLi, serialOrder.SerialOrderStepLstLi...)
//		writeSerialOrderOpLi = append(writeSerialOrderOpLi, serialOrder.SerialOrderOPDetailLi...)
//		writeLabelHeadLi = append(writeLabelHeadLi, serialOrder.LabelHeadLi...)
//		writeLabelDetailLi = append(writeLabelDetailLi, serialOrder.LabelDetailLi...)
//	}
//	// 插入工单
//	num := len(writeSerialOrderLi) / 50
//	remainder := len(writeSerialOrderLi) % 50
//	for i := 0; i < num; i++ {
//		insertLi := writeSerialOrderLi[50*i : (i+1)*50]
//		err = serialOrderDao.Insert(&insertLi)
//		if err != nil {
//			return grmi.NewBusinessError("保存工单失败, 错误:" + err.Error())
//		}
//	}
//	if remainder != 0 {
//		insertLi := writeSerialOrderLi[num*50:]
//		err = serialOrderDao.Insert(&insertLi)
//		if err != nil {
//			return grmi.NewBusinessError("保存工单失败, 错误:" + err.Error())
//		}
//	}
//	// 插入工单状态
//	num = len(writeSerialOrderStatusLi) / 50
//	remainder = len(writeSerialOrderStatusLi) % 50
//	for i := 0; i < num; i++ {
//		insertLi := writeSerialOrderStatusLi[50*i : (i+1)*50]
//		err = serialOrderStatusDao.Insert(&insertLi)
//		if err != nil {
//			return grmi.NewBusinessError("保存工单状态失败, 错误:" + err.Error())
//		}
//	}
//	if remainder != 0 {
//		insertLi := writeSerialOrderStatusLi[num*50:]
//		err = serialOrderStatusDao.Insert(&insertLi)
//		if err != nil {
//			_ = session.Rollback()
//			return grmi.NewBusinessError("保存工单状态失败, 错误:" + err.Error())
//		}
//	}
//	// 插入工单工序数据
//	num = len(writeSerialOrderPoLi) / 50
//	remainder = len(writeSerialOrderPoLi) % 50
//	for i := 0; i < num; i++ {
//		insertLi := writeSerialOrderPoLi[50*i : (i+1)*50]
//		err = serialOrderPoDao.Insert(&insertLi)
//		if err != nil {
//			return grmi.NewBusinessError("保存工单工序失败, 错误:" + err.Error())
//		}
//	}
//	if remainder != 0 {
//		insertLi := writeSerialOrderPoLi[num*50:]
//		err = serialOrderPoDao.Insert(&insertLi)
//		if err != nil {
//			return grmi.NewBusinessError("保存工单工序失败, 错误:" + err.Error())
//		}
//	}
//	// 插入工单工步数据
//	num = len(writeSerialOrderStepLi) / 50
//	remainder = len(writeSerialOrderStepLi) % 50
//	for i := 0; i < num; i++ {
//		insertLi := writeSerialOrderStepLi[50*i : (i+1)*50]
//		err = serialOrderStepDao.Insert(&insertLi)
//		if err != nil {
//			return grmi.NewBusinessError("保存工单工步失败, 错误:" + err.Error())
//		}
//	}
//	if remainder != 0 {
//		insertLi := writeSerialOrderStepLi[num*50:]
//		err = serialOrderStepDao.Insert(&insertLi)
//		if err != nil {
//			return grmi.NewBusinessError("保存工单工步失败, 错误:" + err.Error())
//		}
//	}
//	// 插入工单工艺数据
//	num = len(writeSerialOrderOpLi) / 50
//	remainder = len(writeSerialOrderOpLi) % 50
//	for i := 0; i < num; i++ {
//		insertLi := writeSerialOrderOpLi[50*i : (i+1)*50]
//		err = serialOrderOpDetailDao.Insert(&insertLi)
//		if err != nil {
//			return grmi.NewBusinessError("保存工单工艺失败, 错误:" + err.Error())
//		}
//	}
//	if remainder != 0 {
//		insertLi := writeSerialOrderOpLi[num*50:]
//		err = serialOrderOpDetailDao.Insert(&insertLi)
//		if err != nil {
//			return grmi.NewBusinessError("保存工单工艺失败, 错误:" + err.Error())
//		}
//	}
//	// 写入打印标签数据
//	num = len(writeLabelHeadLi) / 50
//	remainder = len(writeLabelHeadLi) % 50
//	for i := 0; i < num; i++ {
//		insertLi := writeLabelHeadLi[50*i : (i+1)*50]
//		err = labelHeadDao.Insert(&insertLi)
//		if err != nil {
//			return grmi.NewBusinessError("保存标签头部失败, 错误:" + err.Error())
//		}
//	}
//	if remainder != 0 {
//		insertLi := writeLabelHeadLi[num*50:]
//		err = labelHeadDao.Insert(&insertLi)
//		if err != nil {
//			return grmi.NewBusinessError("保存标签头部失败, 错误:" + err.Error())
//		}
//	}
//	num = len(writeLabelDetailLi) / 50
//	remainder = len(writeLabelDetailLi) % 50
//	for i := 0; i < num; i++ {
//		insertLi := writeLabelDetailLi[50*i : (i+1)*50]
//		err = labelDetailDao.Insert(&insertLi)
//		if err != nil {
//			return grmi.NewBusinessError("保存标签详情失败, 错误:" + err.Error())
//		}
//	}
//	if remainder != 0 {
//		insertLi := writeLabelDetailLi[num*50:]
//		err = labelDetailDao.Insert(&insertLi)
//		if err != nil {
//			return grmi.NewBusinessError("保存标签详情失败, 错误:" + err.Error())
//		}
//	}
//	return nil
//}
//
//// SchedCrossPlantTask 调度跨工厂任务
//func (impl *SerialOrderServiceImplement) SchedCrossPlantTask() error {
//	engine := db.Eloquent.Master()
//	session := engine.NewSession()
//	defer session.Close()
//	userId := "MultiPlantTask"
//	plantDao := baseDal.NewPlantDAO(session, userId)
//	plantLi, err := plantDao.Select(nil, nil)
//	if err != nil {
//		return err
//	}
//	for _, plant := range plantLi {
//		user := &global.User{
//			PlantNr: plant.PlantNr,
//			UserId:  userId,
//		}
//		taskDao := baseDal.NewCrossPlanTaskHeadDAO(session, user.UserId)
//		taskLi, err := taskDao.Select([]grmi.Predicate{
//			baseMeta.CrossPlanTaskHead_ToPlantNr.NewPredicate(grmi.Equal, plant.PlantNr),
//			baseMeta.CrossPlanTaskHead_Status.NewPredicate(grmi.LessThen, baseModel.CROSS_TASK_STATUS_ACCOMPLISHED),
//			baseMeta.CrossPlanTaskHead_Status.NewPredicate(grmi.GreaterOrEqual, baseModel.CROSS_TASK_STATUS_PLAN),
//		}, []grmi.Field{baseMeta.CrossPlanTaskHead_Priority, baseMeta.CrossPlanTaskHead_TaskNr})
//		channel, exist := common.ReleaseTaskChannel[user.PlantNr]
//		if !exist {
//			channel = channelModel.NewReleaseChannel()
//			common.ReleaseTaskChannel[user.PlantNr] = channel
//		}
//		for _, task := range taskLi {
//			err = channel.SendData(task)
//			if err != nil {
//				return err
//			}
//		}
//		go func(user *global.User) {
//			impl.ExecuteCrossPlantTask(user)
//		}(user)
//	}
//	return nil
//}
//
//
//// ExecuteCrossPlantTask 执行跨工厂派工
//func (impl *SerialOrderServiceImplement) ExecuteCrossPlantTask(user *global.User) {
//	log, _ := logger.NewLogger("跨工厂任务", "MultiPlantTask")
//	plantNr := user.PlantNr
//	channel, exist := common.ReleaseTaskChannel[plantNr]
//	if !exist {
//		return
//	}
//	for {
//		taskInterface, ok, err := channel.Read()
//		if err != nil {
//			return
//		}
//		if !ok {
//			continue
//		}
//		taskId := taskInterface.(int)
//		err = impl.ExecuteSingleCrossPlantTask(user, taskId)
//		if err != nil {
//			log.Error("派工异常, 错误:" + err.Error())
//			channel.Close()
//			return
//		}
//	}
//}
//
//// ExecuteSingleCrossPlantTask 执行跨工厂任务
//func (impl *SerialOrderServiceImplement) ExecuteSingleCrossPlantTask(user *global.User, taskId int) error {
//	engine := db.Eloquent.Master()
//	session := engine.NewSession()
//	defer session.Close()
//	releaseId, err := uuid.NewV4()
//	if err != nil {
//		return nil
//	}
//	log, _ := logger.NewLogger("跨工厂生成计划,id:"+releaseId.String(), "CrossPlant")
//	taskDao := baseDal.NewCrossPlanTaskHeadDAO(session, user.UserId)
//	task, err := taskDao.SelectOne(taskId)
//	if err != nil {
//		log.Error("获取跨工厂任务失败, 任务ID:" + strconv.Itoa(taskId) + ", 错误:" + err.Error())
//		return grmi.NewBusinessError("获取跨工厂任务失败, 任务ID:" + strconv.Itoa(taskId) + ", 错误:" + err.Error())
//	}
//	if task == nil {
//		log.Error("跨工厂任务不存在, 任务ID:" + strconv.Itoa(taskId))
//		return grmi.NewBusinessError("跨工厂任务不存在, 任务ID:" + strconv.Itoa(taskId))
//	}
//	// 校验任务数据合规性
//	projectDao := meDal.NewProjectDAO(session, user.PlantNr, user.UserId)
//	project, err := projectDao.SelectOne(task.ProjectId)
//	if err != nil {
//		task.Status = baseModel.CROSS_TASK_STATUS_ERROR
//		task.ErrorMsg = "查询任务项目失败，错误:" + err.Error()
//		innerErr := taskDao.UpdateOne(task)
//		if innerErr != nil {
//			log.Error("更新任务状态失败, 错误:" + innerErr.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr))
//		}
//		return grmi.NewBusinessError(task.ErrorMsg)
//	}
//	if project == nil {
//		task.Status = baseModel.CROSS_TASK_STATUS_ERROR
//		task.ErrorMsg = "任务项目不存在, 项目ID:" + task.ProjectId
//		innerErr := taskDao.UpdateOne(task)
//		if innerErr != nil {
//			log.Error("更新任务状态失败, 错误:" + innerErr.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr))
//		}
//		return grmi.NewBusinessError(task.ErrorMsg)
//	}
//	// 获取生产的物料，通过;切割
//	productIdLi := strings.Split(task.ArtId, ";")
//	if len(productIdLi) == 0 {
//		task.Status = baseModel.CROSS_TASK_STATUS_ERROR
//		task.ErrorMsg = "任务未包含物料数据"
//		innerErr := taskDao.UpdateOne(task)
//		if innerErr != nil {
//			log.Error("更新任务状态失败, 错误:" + innerErr.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr))
//		}
//		return grmi.NewBusinessError(task.ErrorMsg)
//	}
//	if task.PlanEndTime.Restore().Before(task.PlanStartTime.Restore()) {
//		task.Status = baseModel.CROSS_TASK_STATUS_ERROR
//		task.ErrorMsg = "任务计划结束时间早于开始时间"
//		innerErr := taskDao.UpdateOne(task)
//		if innerErr != nil {
//			log.Error("更新任务状态失败, 错误:" + innerErr.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr))
//		}
//		return grmi.NewBusinessError(task.ErrorMsg)
//	}
//	// 获取每个总成当前派工数量 用于task退出重新启动
//	releaseQtyStrLi := strings.Split(task.ReleaseQty, ";")
//	releaseQtyLi := make([]int, 0, len(productIdLi))
//	if len(releaseQtyStrLi) == 0 {
//		for range productIdLi {
//			releaseQtyStrLi = append(releaseQtyStrLi, "0")
//		}
//	} else if len(releaseQtyStrLi) != len(productIdLi) {
//		task.Status = baseModel.CROSS_TASK_STATUS_ERROR
//		task.ErrorMsg = "派工数量格式错误"
//		innerErr := taskDao.UpdateOne(task)
//		if innerErr != nil {
//			log.Error("更新任务状态失败, 错误:" + innerErr.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr))
//		}
//		return grmi.NewBusinessError(task.ErrorMsg)
//	}
//	// 获取当前总派工的数量
//	var currentQty int
//	for _, releaseQtyStr := range releaseQtyStrLi {
//		qty, err := strconv.Atoi(releaseQtyStr)
//		if err != nil {
//			task.Status = baseModel.CROSS_TASK_STATUS_ERROR
//			task.ErrorMsg = "派工数量格式错误"
//			innerErr := taskDao.UpdateOne(task)
//			if innerErr != nil {
//				log.Error("更新任务状态失败, 错误:" + innerErr.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr))
//			}
//			return grmi.NewBusinessError(task.ErrorMsg)
//		}
//		releaseQtyLi = append(releaseQtyLi, qty)
//		currentQty += qty
//	}
//	// 总时间 / 总数量 = 每个工单消耗的时间
//	subTime := task.PlanEndTime.Restore().Sub(task.PlanStartTime.Restore())
//	totalQty := len(productIdLi) * task.PlanQty
//	perDuration := int(subTime.Seconds()) / totalQty
//	// 调度模式 每一次生成多少个相同物料的工单
//	schedQty, err := strconv.Atoi(task.SchedType)
//	if err != nil || schedQty == 0 {
//		task.Status = baseModel.CROSS_TASK_STATUS_ERROR
//		task.ErrorMsg = "不支持的调度模式"
//		innerErr := taskDao.UpdateOne(task)
//		if innerErr != nil {
//			log.Error("更新任务状态失败, 错误:" + innerErr.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr))
//		}
//		return grmi.NewBusinessError(task.ErrorMsg)
//	}
//	// 生成所有物料的工单工艺
//	productCraftMap := make(map[string]*model.SerialOrder)
//	for _, productId := range productIdLi {
//		serialOrderCraft, err := impl.SingleProductTask(user, session, task, productId)
//		if err != nil {
//			task.Status = baseModel.CROSS_TASK_STATUS_ERROR
//			task.ErrorMsg = "生成工单工艺失败, 错误:" + err.Error()
//			innerErr := taskDao.UpdateOne(task)
//			if innerErr != nil {
//				log.Error("更新任务状态失败, 错误:" + innerErr.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr))
//			}
//			return grmi.NewBusinessError(task.ErrorMsg)
//		}
//		productCraftMap[productId] = serialOrderCraft
//	}
//
//	// 记录生成计划中间的数量
//	type ProductQty struct {
//		ProductId  string // 物料id
//		CurrentQty int    // 当前数量
//	}
//	productQtyCacheLi := make([]ProductQty, 0, len(productIdLi))
//	for _, productId := range productIdLi {
//		productQtyData := ProductQty{
//			ProductId: productId,
//		}
//		productQtyCacheLi = append(productQtyCacheLi, productQtyData)
//	}
//	// 将需要绑定的总成工单通过物料进行聚合
//	taskArtOrderMap := make(map[string][]baseModel.CrossPlanTaskDetail)
//	for _, taskDetail := range task.CrossPlanTaskDetailLi {
//		taskArtOrderMap[taskDetail.ArtId] = append(taskArtOrderMap[taskDetail.ArtId], taskDetail)
//	}
//	taskArtOrderIndexMap := make(map[string]int)
//	for _, productId := range productIdLi {
//		taskArtOrderIndexMap[productId] = 0
//	}
//	for artId, taskDetailLi := range taskArtOrderMap {
//		if len(taskDetailLi) != task.PlanQty {
//			task.Status = baseModel.CROSS_TASK_STATUS_ERROR
//			task.ErrorMsg = "物料绑定的总成工单数量和计划数量不一致, 物料ID:" + artId
//			innerErr := taskDao.UpdateOne(task)
//			if innerErr != nil {
//				log.Error("更新任务状态失败, 错误:" + innerErr.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr))
//			}
//			return grmi.NewBusinessError(task.ErrorMsg)
//		}
//	}
//	// 进行工单及工艺数据生成
//	for {
//		// 派工数量和计划总数相同 退出循环
//		if currentQty == totalQty {
//			break
//		}
//		for index, productQtyCache := range productQtyCacheLi {
//			// 当前总成已达到一次调度数量
//			if productQtyCache.CurrentQty == schedQty {
//				productQtyCache.CurrentQty = 0
//				productQtyCacheLi[index] = productQtyCache
//				continue
//			}
//			// 每一个工单是一次事务
//			if err = session.Begin(); err != nil {
//				task.Status = baseModel.CROSS_TASK_STATUS_ERROR
//				task.ErrorMsg = "开启事务失败, 错误:" + err.Error()
//				innerErr := taskDao.UpdateOne(task)
//				if innerErr != nil {
//					log.Error("更新任务状态失败, 错误:" + innerErr.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr))
//				}
//				return grmi.NewBusinessError(task.ErrorMsg)
//			}
//			orderCraft := productCraftMap[productQtyCache.ProductId]
//			planStartTime := task.PlanStartTime.Restore().Add(time.Duration(currentQty*perDuration) * time.Second)
//			err = impl.SaveBatchOrderData(user, session, orderCraft, planStartTime, perDuration, schedQty, project.SerialOrderSnr)
//			if err != nil {
//				_ = session.Rollback()
//				task.Status = baseModel.CROSS_TASK_STATUS_ERROR
//				task.ErrorMsg = "保存工单工艺失败, 错误:" + err.Error()
//				innerErr := taskDao.UpdateOne(task)
//				if innerErr != nil {
//					log.Error("更新任务状态失败, 错误:" + innerErr.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr))
//				}
//				return grmi.NewBusinessError(task.ErrorMsg)
//			}
//			releaseQtyLi[index] += schedQty
//			var totalReleaseQty string
//			for index, releaseQty := range releaseQtyLi {
//				if index != 0 {
//					totalReleaseQty += ";"
//				}
//				totalReleaseQty += strconv.Itoa(releaseQty)
//			}
//			task.ReleaseQty = totalReleaseQty
//			currentQty += schedQty
//			if currentQty == totalQty {
//				if task.Status == baseModel.CROSS_TASK_STATUS_PLAN {
//					task.StartTime = grmi.DateTime(time.Now())
//				}
//				task.Status = baseModel.CROSS_TASK_STATUS_ACCOMPLISHED
//				task.ActQty = task.PlanQty
//				task.AccomplishTime = grmi.DateTime(time.Now())
//			} else {
//				if task.Status == baseModel.CROSS_TASK_STATUS_PLAN {
//					task.StartTime = grmi.DateTime(time.Now())
//				}
//				task.Status = baseModel.CHECK_STATUS_RUNNING
//			}
//			err = taskDao.UpdateOne(task)
//			if err != nil {
//				_ = session.Rollback()
//				log.Error("更新任务状态失败, 错误:" + err.Error() + ", 任务ID:" + strconv.Itoa(task.TaskNr))
//				return err
//			}
//			_ = session.Commit()
//		}
//	}
//	return nil
//}