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