Files
2021-11-19 15:34:22 +08:00

568 lines
17 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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}
}
}