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 Distribution *model2.WorkInstanceDistribution `json:"distribution"` Materials []*model.WorkMaterialInfo `json:"materials"` } // InstanceLaunchParams 发起参数信息 InstanceLaunchParams struct { ID uint64 Kind int // 类型 Title string EquipmentID uint64 // 装备ID Breakdowns []uint64 // 故障类型 PlateNumber string // 车牌号 Priority, IsAssist int // 优先级,是否需要上级审批 Remark string // 备注信息 Material []*InstanceLaunchParamsForMaterial Distribution *InstanceLaunchParamsForDistribution } // InstanceLaunchParamsForMaterial 配件信息 InstanceLaunchParamsForMaterial struct { ID uint64 // 器材ID SupplierID uint64 // 供应商ID Number float64 // 需要数量 } // InstanceLaunchParamsForDistribution 配送信息 InstanceLaunchParamsForDistribution struct { Name, Mobile, Address string } ) func (c *Instance) publish(reviewer []string) { utils.TryCatch(func() { for _, v := range reviewer { // Socket通知 service.HubMessage.EmitHandle(&service.HubEmit{ ID: v, Msg: handle.NewWorkNotice("你有一条待办事项"), }) } }) } // List 列表信息 func (c *Instance) List(materialID uint64, kind, page, pageSize int) (*basic.PageDataResponse, error) { mWorkInstance := model.NewWorkInstance() where := make([]*model2.ModelWhere, 0) if materialID > 0 { where = append(where, model2.NewWhere("w.material_id", materialID)) } 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(materialID uint64, kind, page, pageSize int) (*basic.PageDataResponse, error) { mWorkInstance := model.NewWorkInstance() where := make([]*model2.ModelWhere, 0) if materialID > 0 { where = append(where, model2.NewWhere("w.material_id", materialID)) } if kind > 0 { where = append(where, model2.NewWhere("w.kind", kind)) } var count int64 out, err := mWorkInstance.Persons(c.UID, model2.WorkScheduleKindForRepair, 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(materialID uint64, 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 materialID > 0 { where = append(where, model2.NewWhere("w.material_id", materialID)) } if kind > 0 { where = append(where, model2.NewWhere("w.kind", kind)) } var count int64 out := make([]*model.WorkInstanceInfo, 0) if out, err = mWorkInstance.Workbench(&model.WorkbenchCondition{ UID: c.UIDToString(), RoleIDs: roleIDs, }, page, pageSize, &count, where...); err != nil { return nil, err } return &basic.PageDataResponse{Data: out, 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.Distribution = out.WorkInstanceInfo.Distribution out.Distribution = mWorkInstance.GetDistributionAttribute() // 内修才有数据 if out.WorkInstanceInfo.Kind == model2.WorkInstanceKindForWithin { if out.Materials, err = model.NewWorkMaterial().Materials(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.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 // 工单流程信息 mWorkProgress := model.NewWorkProgress() // 工单器材信息 workMaterials := make([]*model2.WorkMaterial, 0) // 内修模块,同步器材库存信息 if mWorkInstance.Kind == model2.WorkInstanceKindForWithin { for _, v := range params.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, }) } } // 查询工单进度流程 // 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 // 下一流程 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 } now := time.Now() 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.ScheduleID = mWorkInstance.Schedule mWorkProgress.Status = model2.WorkProgressStatusForAgree mWorkProgress.Remark = "发起工单" if err = model2.Create(mWorkProgress.WorkProgress, tx); err != nil { return err } // 内修模块,同步器材库存信息 if mWorkInstance.Kind == model2.WorkInstanceKindForWithin && len(workMaterials) > 0 { mManageMaterialSupplier := model.NewManageMaterialSupplier() for _, v := range workMaterials { v.WorkID = mWorkInstance.ID if err = model2.UpdatesWhere(mManageMaterialSupplier.ManageMaterialSupplier, map[string]interface{}{ "frozen_stock": gorm.Expr("frozen_stock + ?", v.MaterialNumber), "updated_at": now, }, nil, tx); err != nil { return err } } mWorkMaterial := model.NewWorkMaterial() if err = model2.Creates(mWorkMaterial.WorkMaterial, &workMaterials, tx); err != nil { return err } } if nextWorkSchedule != nil { // 推送通知 go c.publish(nextWorkSchedule.Reviewer) } return nil }) } // Examine 审核操作 func (c *Instance) Examine(id uint64, status int, remark string, isAssist int) 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", "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("操作错误,无权限审批") } if err = 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 } } // 推送通知 go c.publish(nextScheduleInfo.Reviewer) return nil }); err != nil { return err } 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} } }