568 lines
17 KiB
Go
568 lines
17 KiB
Go
package work
|
||
|
||
import (
|
||
model2 "ArmedPolice/app/common/model"
|
||
"ArmedPolice/app/controller/basic"
|
||
"ArmedPolice/app/handle"
|
||
"ArmedPolice/app/model"
|
||
"ArmedPolice/app/service"
|
||
"ArmedPolice/lib"
|
||
"ArmedPolice/serve/orm"
|
||
"ArmedPolice/utils"
|
||
"errors"
|
||
"gorm.io/gorm"
|
||
"time"
|
||
)
|
||
|
||
type Instance struct{ *service.Session }
|
||
|
||
type InstanceHandle func(session *service.Session) *Instance
|
||
|
||
type (
|
||
// InstanceInfo 基本信息
|
||
InstanceInfo struct {
|
||
basic.CommonIDString
|
||
*model.WorkInstanceInfo
|
||
}
|
||
// InstanceDetailInfo 详细信息
|
||
InstanceDetailInfo struct {
|
||
basic.CommonIDString
|
||
*model.WorkInstanceInfo
|
||
EquipmentID string `json:"equipment_id"`
|
||
ScheduleID string `json:"schedule_id"`
|
||
Outside struct {
|
||
SupplierName string `json:"supplier_name"`
|
||
} `json:"outside"`
|
||
Within struct {
|
||
Material []*model.WorkMaterialInfo `json:"material"`
|
||
Purchase []*model.WorkPurchaseInfo `json:"purchase"`
|
||
} `json:"within"`
|
||
Distribution *model2.WorkInstanceDistribution `json:"distribution"`
|
||
History []*model.WorkProgressInfo `json:"history"`
|
||
}
|
||
// InstanceLaunchParams 发起参数信息
|
||
InstanceLaunchParams struct {
|
||
ID uint64
|
||
Kind int // 类型
|
||
Title string
|
||
EquipmentID uint64 // 装备ID
|
||
Breakdowns []uint64 // 故障类型
|
||
PlateNumber string // 车牌号
|
||
Priority, IsAssist int // 优先级,是否需要上级审批
|
||
Remark string // 备注信息
|
||
Supplier *InstanceLaunchParamsForSupplier
|
||
Material []*InstanceLaunchParamsForMaterial
|
||
Purchase []*InstanceLaunchParamsForPurchase
|
||
Distribution *InstanceLaunchParamsForDistribution
|
||
}
|
||
// InstanceLaunchParamsForSupplier 供应商信息
|
||
InstanceLaunchParamsForSupplier struct {
|
||
SupplierID uint64 `json:"supplier_id"`
|
||
}
|
||
// InstanceLaunchParamsForMaterial 配件信息
|
||
InstanceLaunchParamsForMaterial struct {
|
||
ID uint64 // 器材ID
|
||
SupplierID uint64 // 供应商ID
|
||
Number float64 // 需要数量
|
||
}
|
||
// InstanceLaunchParamsForPurchase 采购信息
|
||
InstanceLaunchParamsForPurchase struct {
|
||
ID uint64 // 器材ID
|
||
SupplierID uint64 // 供应商ID
|
||
Price float64 // 采购单价
|
||
Number float64 // 采购数量
|
||
}
|
||
// InstanceLaunchParamsForDistribution 配送信息
|
||
InstanceLaunchParamsForDistribution struct {
|
||
Name, Mobile, Address string
|
||
}
|
||
// InstanceExamineParams 审核参数信息
|
||
InstanceExamineParams struct {
|
||
Material []*InstanceLaunchParamsForMaterial
|
||
Purchase []*InstanceLaunchParamsForPurchase
|
||
}
|
||
)
|
||
|
||
func (c *Instance) publish(kind int, reviewer []string) {
|
||
msg := &service.HubEmit{
|
||
Msg: handle.NewWorkNotice("你有一条待办事项", &struct {
|
||
Kind int `json:"kind"`
|
||
}{
|
||
Kind: kind,
|
||
}),
|
||
}
|
||
utils.TryCatch(func() {
|
||
for _, v := range reviewer {
|
||
msg.ID = v
|
||
service.HubMessage.EmitHandle(msg)
|
||
}
|
||
})
|
||
}
|
||
|
||
func (c *Instance) material(tx *gorm.DB, material []*InstanceLaunchParamsForMaterial, workID uint64) error {
|
||
// 工单器材信息
|
||
workMaterials := make([]*model2.WorkMaterial, 0)
|
||
|
||
for _, v := range material {
|
||
if v.ID <= 0 || v.SupplierID <= 0 || v.Number <= 0 {
|
||
return errors.New("操作错误,器材参数不完全")
|
||
}
|
||
workMaterials = append(workMaterials, &model2.WorkMaterial{
|
||
MaterialID: v.ID, MaterialSupplierID: v.SupplierID, MaterialNumber: v.Number,
|
||
})
|
||
}
|
||
// 处理库存信息
|
||
if len(workMaterials) > 0 {
|
||
mManageMaterialSupplier := model.NewManageMaterialSupplier()
|
||
|
||
now := time.Now()
|
||
|
||
for _, v := range workMaterials {
|
||
v.WorkID = workID
|
||
|
||
if err := model2.UpdatesWhere(mManageMaterialSupplier.ManageMaterialSupplier, map[string]interface{}{
|
||
"frozen_stock": gorm.Expr("frozen_stock + ?", v.MaterialNumber), "updated_at": now,
|
||
}, []*model2.ModelWhere{
|
||
model2.NewWhere("material_id", v.MaterialID),
|
||
model2.NewWhere("supplier_id", v.MaterialSupplierID),
|
||
}, tx); err != nil {
|
||
return err
|
||
}
|
||
}
|
||
mWorkMaterial := model.NewWorkMaterial()
|
||
|
||
if err := model2.Creates(mWorkMaterial.WorkMaterial, &workMaterials, tx); err != nil {
|
||
return err
|
||
}
|
||
}
|
||
return nil
|
||
}
|
||
|
||
/// purchase 采购操作
|
||
func (c *Instance) purchase(tx *gorm.DB, purchase []*InstanceLaunchParamsForPurchase, workID uint64) error {
|
||
//mManageMaterialPurchase := model.NewManageMaterialPurchase()
|
||
|
||
//_purchase := make([]*model2.ManageMaterialPurchase, 0)
|
||
|
||
for _, v := range purchase {
|
||
mManageMaterialPurchase := model.NewManageMaterialPurchase()
|
||
|
||
mManageMaterialPurchase.UID = c.UID
|
||
mManageMaterialPurchase.OrderNo = lib.OrderNo()
|
||
mManageMaterialPurchase.MaterialID = v.ID
|
||
mManageMaterialPurchase.SupplierID = v.SupplierID
|
||
mManageMaterialPurchase.Price = v.Price
|
||
mManageMaterialPurchase.Number = v.Number
|
||
mManageMaterialPurchase.Remark = "工单采购"
|
||
|
||
err := model2.Create(mManageMaterialPurchase.ManageMaterialPurchase, tx)
|
||
|
||
if err != nil {
|
||
return err
|
||
}
|
||
mWorkPurchase := model.NewWorkPurchase()
|
||
mWorkPurchase.WorkID = workID
|
||
mWorkPurchase.MaterialPurchaseID = mManageMaterialPurchase.ID
|
||
|
||
if err = model2.Create(mWorkPurchase.WorkPurchase, tx); err != nil {
|
||
return err
|
||
}
|
||
//_purchase = append(_purchase, &model2.ManageMaterialPurchase{
|
||
// UID: c.UID,
|
||
// OrderNo: lib.OrderNo(),
|
||
// MaterialID: v.ID,
|
||
// SupplierID: v.SupplierID,
|
||
// Price: v.Price,
|
||
// Number: v.Number,
|
||
// Remark: "工单采购",
|
||
//})
|
||
}
|
||
//if len(_purchase) > 0 {
|
||
// if err := model2.Creates(mManageMaterialPurchase.ManageMaterialPurchase, _purchase, tx); err != nil {
|
||
// return err
|
||
// }
|
||
//}
|
||
return nil
|
||
}
|
||
|
||
// List 列表信息
|
||
func (c *Instance) List(equipmentCode, equipmentTitle string, kind, page, pageSize int) (*basic.PageDataResponse, error) {
|
||
mWorkInstance := model.NewWorkInstance()
|
||
|
||
where := make([]*model2.ModelWhere, 0)
|
||
|
||
if equipmentCode != "" {
|
||
where = append(where, model2.NewWhereLike("e.code", equipmentCode))
|
||
}
|
||
if equipmentTitle != "" {
|
||
where = append(where, model2.NewWhereLike("e.title", equipmentTitle))
|
||
}
|
||
if kind > 0 {
|
||
where = append(where, model2.NewWhere("w.kind", kind))
|
||
}
|
||
var count int64
|
||
|
||
out, err := mWorkInstance.Instances(page, pageSize, &count, where...)
|
||
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
list := make([]*InstanceInfo, 0)
|
||
|
||
for _, v := range out {
|
||
mWorkInstance.ID = v.ID
|
||
|
||
list = append(list, &InstanceInfo{
|
||
CommonIDString: basic.CommonIDString{ID: mWorkInstance.GetEncodeID()}, WorkInstanceInfo: v,
|
||
})
|
||
}
|
||
return &basic.PageDataResponse{Data: list, Count: count}, nil
|
||
}
|
||
|
||
// Person 个人提交的审核信息
|
||
func (c *Instance) Person(equipmentCode, equipmentTitle string, kind, page, pageSize int) (*basic.PageDataResponse, error) {
|
||
mWorkInstance := model.NewWorkInstance()
|
||
|
||
where := make([]*model2.ModelWhere, 0)
|
||
|
||
if equipmentCode != "" {
|
||
where = append(where, model2.NewWhereLike("e.code", equipmentCode))
|
||
}
|
||
if equipmentTitle != "" {
|
||
where = append(where, model2.NewWhereLike("e.title", equipmentTitle))
|
||
}
|
||
if kind > 0 {
|
||
where = append(where, model2.NewWhere("w.kind", kind))
|
||
}
|
||
var count int64
|
||
|
||
out, err := mWorkInstance.Persons(c.UID, page, pageSize, &count, where...)
|
||
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
list := make([]*InstanceInfo, 0)
|
||
|
||
for _, v := range out {
|
||
mWorkInstance.ID = v.ID
|
||
|
||
list = append(list, &InstanceInfo{
|
||
CommonIDString: basic.CommonIDString{ID: mWorkInstance.GetEncodeID()}, WorkInstanceInfo: v,
|
||
})
|
||
}
|
||
return &basic.PageDataResponse{Data: list, Count: count}, nil
|
||
}
|
||
|
||
// Workbench 工作台
|
||
func (c *Instance) Workbench(equipmentCode, equipmentTitle string, kind, page, pageSize int) (*basic.PageDataResponse, error) {
|
||
// 查询用户角色信息
|
||
mSysUserRole := model.NewSysUserRole()
|
||
roleIDs := make([]string, 0)
|
||
|
||
err := model2.Pluck(mSysUserRole.SysUserRole, "role_id", &roleIDs, model2.NewWhere("uid", c.UID))
|
||
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
mWorkInstance := model.NewWorkInstance()
|
||
|
||
where := make([]*model2.ModelWhere, 0)
|
||
|
||
if equipmentCode != "" {
|
||
where = append(where, model2.NewWhereLike("e.code", equipmentCode))
|
||
}
|
||
if equipmentTitle != "" {
|
||
where = append(where, model2.NewWhereLike("e.title", equipmentTitle))
|
||
}
|
||
if kind > 0 {
|
||
where = append(where, model2.NewWhere("w.kind", kind))
|
||
}
|
||
var count int64
|
||
|
||
out := make([]*model.WorkInstanceInfo, 0)
|
||
|
||
if out, err = mWorkInstance.Workbenchs(&model.WorkbenchCondition{
|
||
UID: c.UIDToString(), RoleIDs: roleIDs,
|
||
}, page, pageSize, &count, where...); err != nil {
|
||
return nil, err
|
||
}
|
||
list := make([]*InstanceInfo, 0)
|
||
|
||
for _, v := range out {
|
||
mWorkInstance.ID = v.ID
|
||
|
||
list = append(list, &InstanceInfo{
|
||
CommonIDString: basic.CommonIDString{ID: mWorkInstance.GetEncodeID()}, WorkInstanceInfo: v,
|
||
})
|
||
}
|
||
return &basic.PageDataResponse{Data: list, Count: count}, nil
|
||
}
|
||
|
||
// Detail 详细信息
|
||
func (c *Instance) Detail(id uint64) (*InstanceDetailInfo, error) {
|
||
out := new(InstanceDetailInfo)
|
||
|
||
var err error
|
||
|
||
mWorkInstance := model.NewWorkInstance()
|
||
// 基本信息
|
||
if out.WorkInstanceInfo, err = mWorkInstance.Detail(id); err != nil {
|
||
return nil, err
|
||
}
|
||
mWorkInstance.SetID(out.WorkInstanceInfo.ID)
|
||
out.CommonIDString = basic.CommonIDString{
|
||
ID: mWorkInstance.GetEncodeID(),
|
||
}
|
||
out.EquipmentID = (&model2.Model{ID: out.WorkInstanceInfo.EquipmentID}).GetEncodeID()
|
||
out.ScheduleID = (&model2.Model{ID: out.WorkInstanceInfo.ScheduleID}).GetEncodeID()
|
||
// 位置信息
|
||
mWorkInstance.Distribution = out.WorkInstanceInfo.Distribution
|
||
|
||
out.Distribution = mWorkInstance.GetDistributionAttribute()
|
||
// 内修才有数据
|
||
if out.WorkInstanceInfo.Kind == model2.WorkInstanceKindForWithin {
|
||
// 器材信息
|
||
materials := make([]*model.WorkMaterialInfo, 0)
|
||
|
||
if materials, err = model.NewWorkMaterial().Materials(id); err != nil {
|
||
return nil, err
|
||
}
|
||
// 采购信息
|
||
purchases := make([]*model.WorkPurchaseInfo, 0)
|
||
|
||
if purchases, err = model.NewWorkPurchase().Purchases(id); err != nil {
|
||
return nil, err
|
||
}
|
||
out.Within = struct {
|
||
Material []*model.WorkMaterialInfo `json:"material"`
|
||
Purchase []*model.WorkPurchaseInfo `json:"purchase"`
|
||
}{Material: materials, Purchase: purchases}
|
||
} else if out.WorkInstanceInfo.Kind == model2.WorkInstanceKindForOutside {
|
||
out.Outside = struct {
|
||
SupplierName string `json:"supplier_name"`
|
||
}{SupplierName: out.WorkInstanceInfo.SupplierName}
|
||
}
|
||
// 工单历史信息
|
||
if out.History, err = model.NewWorkProgress().Progress(id); err != nil {
|
||
return nil, err
|
||
}
|
||
return out, nil
|
||
}
|
||
|
||
// Launch 发起工单申请
|
||
func (c *Instance) Launch(params *InstanceLaunchParams) error {
|
||
// 查询产品信息是否存在
|
||
mManageEquipment := model.NewManageEquipment()
|
||
|
||
var count int64
|
||
|
||
err := model2.Count(mManageEquipment.ManageEquipment, &count, model2.NewWhere("id", params.EquipmentID))
|
||
|
||
if err != nil {
|
||
return err
|
||
} else if count <= 0 {
|
||
return errors.New("操作错误,该装备信息不存在或已被删除")
|
||
}
|
||
// 工单信息
|
||
mWorkInstance := model.NewWorkInstance()
|
||
mWorkInstance.UID = c.UID
|
||
mWorkInstance.OrderNo = lib.OrderNo()
|
||
mWorkInstance.Kind = model2.WorkInstanceKind(params.Kind)
|
||
mWorkInstance.Title = params.Title
|
||
mWorkInstance.EquipmentID = params.EquipmentID
|
||
mWorkInstance.PlateNumber = params.PlateNumber
|
||
mWorkInstance.Priority = model2.WorkInstancePriority(params.Priority)
|
||
mWorkInstance.IsAssist = model2.WorkInstanceAssist(params.IsAssist)
|
||
mWorkInstance.SetBreakdownAttribute(params.Breakdowns)
|
||
mWorkInstance.SetDistributionAttribute(&model2.WorkInstanceDistribution{
|
||
Name: params.Distribution.Name, Mobile: params.Distribution.Mobile, Address: params.Distribution.Address,
|
||
})
|
||
mWorkInstance.Remark = params.Remark
|
||
|
||
if mWorkInstance.Kind == model2.WorkInstanceKindForOutside {
|
||
if params.Supplier.SupplierID <= 0 {
|
||
return errors.New("操作错误,承修单位不存在")
|
||
}
|
||
mWorkInstance.SupplierID = params.Supplier.SupplierID
|
||
}
|
||
// 查询工单进度流程
|
||
// TODO:工单流程
|
||
// 第一阶段:创建工单,默认创建时,直接完成
|
||
mWorkSchedule := model.NewWorkSchedule()
|
||
|
||
isExist := false
|
||
|
||
if isExist, err = mWorkSchedule.FirstSchedule(model2.WorkScheduleKindForRepair); err != nil {
|
||
return err
|
||
} else if !isExist {
|
||
return errors.New("操作错误,无工单流程信息,请先核实数据")
|
||
}
|
||
mWorkInstance.Schedule = mWorkSchedule.ID
|
||
mWorkInstance.Status = model2.WorkInstanceStatusForComplete
|
||
// 工单流程信息
|
||
mWorkProgress := model.NewWorkProgress()
|
||
mWorkProgress.ScheduleID = mWorkInstance.Schedule
|
||
// 下一流程
|
||
nextWorkSchedule := new(model.WorkScheduleInfo)
|
||
|
||
if nextWorkSchedule, err = mWorkSchedule.NextSchedule(mWorkInstance.IsAssist == model2.WorkInstanceAssistForYes); err != nil {
|
||
return err
|
||
}
|
||
if nextWorkSchedule != nil {
|
||
mWorkInstance.Status = model2.WorkInstanceStatusForOngoing
|
||
mWorkInstance.Schedule = nextWorkSchedule.ID
|
||
}
|
||
return orm.GetDB().Transaction(func(tx *gorm.DB) error {
|
||
// 工单信息
|
||
if err = model2.Create(mWorkInstance.WorkInstance, tx); err != nil {
|
||
return err
|
||
}
|
||
// 工单历史
|
||
mWorkProgress.UID = c.UID
|
||
mWorkProgress.WorkID = mWorkInstance.ID
|
||
mWorkProgress.Status = model2.WorkProgressStatusForCreate
|
||
mWorkProgress.Remark = ""
|
||
|
||
if err = model2.Create(mWorkProgress.WorkProgress, tx); err != nil {
|
||
return err
|
||
}
|
||
// 内修模块信息
|
||
if mWorkInstance.Kind == model2.WorkInstanceKindForWithin && params.IsAssist <= 0 {
|
||
// 物料信息
|
||
if err = c.material(tx, params.Material, mWorkInstance.ID); err != nil {
|
||
return err
|
||
}
|
||
// 采购信息
|
||
if err = c.purchase(tx, params.Purchase, mWorkInstance.ID); err != nil {
|
||
return err
|
||
}
|
||
}
|
||
if nextWorkSchedule != nil {
|
||
// 推送通知
|
||
go c.publish(params.Kind, nextWorkSchedule.Reviewer)
|
||
}
|
||
return nil
|
||
})
|
||
}
|
||
|
||
// Examine 审核操作
|
||
func (c *Instance) Examine(id uint64, status int, remark string, isAssist int, params *InstanceExamineParams) error {
|
||
_status := model2.WorkProgressStatus(status)
|
||
|
||
if _status != model2.WorkProgressStatusForAgree && _status != model2.WorkProgressStatusForRefuse {
|
||
return errors.New("操作错误,审核状态异常")
|
||
}
|
||
mWorkInstance := model.NewWorkInstance()
|
||
mWorkInstance.ID = id
|
||
|
||
isExist, err := model2.FirstField(mWorkInstance.WorkInstance, []string{"id", "kind", "schedule", "status"})
|
||
|
||
if err != nil {
|
||
return err
|
||
} else if !isExist {
|
||
return errors.New("操作错误,工单信息不存在")
|
||
} else if mWorkInstance.Status == model2.WorkInstanceStatusForComplete {
|
||
return errors.New("操作错误,当前工单信息已结束")
|
||
}
|
||
// 查询当前工单所在流程的信息
|
||
mWorkSchedule := model.NewWorkSchedule()
|
||
mWorkSchedule.ID = mWorkInstance.Schedule
|
||
|
||
if isExist, err = model2.First(mWorkSchedule.WorkSchedule); err != nil {
|
||
return err
|
||
} else if !isExist {
|
||
return errors.New("操作错误,未知的工单流程")
|
||
}
|
||
// 验证审核权限
|
||
isAuth := false
|
||
|
||
if isAuth, err = mWorkSchedule.ValidateAuth(c.UID); err != nil {
|
||
return err
|
||
} else if !isAuth {
|
||
return errors.New("操作错误,无权限审批")
|
||
}
|
||
return orm.GetDB().Transaction(func(tx *gorm.DB) error {
|
||
// 工单流程记录
|
||
mWorkProgress := model.NewWorkProgress()
|
||
mWorkProgress.UID = c.UID
|
||
mWorkProgress.WorkID = id
|
||
mWorkProgress.ScheduleID = mWorkSchedule.ID
|
||
mWorkProgress.Status = _status
|
||
mWorkProgress.Remark = remark
|
||
|
||
if err = model2.Create(mWorkProgress.WorkProgress, tx); err != nil {
|
||
return err
|
||
}
|
||
workUpdates := map[string]interface{}{
|
||
"status": model2.WorkInstanceStatusForComplete, "updated_at": time.Now(),
|
||
}
|
||
// 下一流程
|
||
nextScheduleInfo := new(model.WorkScheduleInfo)
|
||
|
||
// 拒绝审批,工单直接结束
|
||
if _status == model2.WorkProgressStatusForRefuse {
|
||
goto FINISH
|
||
}
|
||
// 下一流程信息
|
||
if nextScheduleInfo, err = mWorkSchedule.NextSchedule(model2.WorkInstanceAssist(isAssist) == model2.WorkInstanceAssistForYes); err != nil {
|
||
return err
|
||
}
|
||
// 无下一流程,工单直接完成
|
||
if nextScheduleInfo == nil || nextScheduleInfo.ID <= 0 {
|
||
goto FINISH
|
||
}
|
||
workUpdates["status"] = model2.WorkInstanceStatusForOngoing
|
||
workUpdates["schedule"] = nextScheduleInfo.ID
|
||
|
||
if nextScheduleInfo.IsNextStage {
|
||
workUpdates["is_assist"] = isAssist
|
||
}
|
||
FINISH:
|
||
if err = model2.Updates(mWorkInstance.WorkInstance, workUpdates, tx); err != nil {
|
||
return err
|
||
}
|
||
// 完成,创建维修工单
|
||
if workUpdates["status"] == model2.WorkInstanceStatusForComplete {
|
||
// 创建维修工单
|
||
mWorkRepair := model.NewWorkRepair()
|
||
mWorkRepair.OrderNo = lib.OrderNo()
|
||
mWorkRepair.WorkID = mWorkInstance.ID
|
||
// 默认进行中
|
||
mWorkRepair.Status = model2.WorkRepairStatusForOngoing
|
||
|
||
if err = model2.Create(mWorkRepair.WorkRepair, tx); err != nil {
|
||
return err
|
||
}
|
||
}
|
||
// 处理器材信息
|
||
if mWorkInstance.Kind == model2.WorkInstanceKindForWithin && isAssist <= 0 {
|
||
// 物料信息
|
||
if err = c.material(tx, params.Material, id); err != nil {
|
||
return err
|
||
}
|
||
// 采购信息
|
||
if err = c.purchase(tx, params.Purchase, id); err != nil {
|
||
return err
|
||
}
|
||
}
|
||
// 推送通知
|
||
if nextScheduleInfo != nil {
|
||
go c.publish(int(mWorkInstance.Kind), nextScheduleInfo.Reviewer)
|
||
}
|
||
return nil
|
||
})
|
||
}
|
||
|
||
// Delete 删除操作
|
||
func (c *Instance) Delete(id uint64) error {
|
||
mWorkInstance := model.NewWorkInstance()
|
||
mWorkInstance.ID = id
|
||
return model2.Delete(mWorkInstance.WorkInstance)
|
||
}
|
||
|
||
func NewInstance() InstanceHandle {
|
||
return func(session *service.Session) *Instance {
|
||
return &Instance{session}
|
||
}
|
||
}
|