package service import ( "context" "fmt" contractdao "dashoo.cn/opms_parent/app/dao/contract" opsdevdao "dashoo.cn/opms_parent/app/dao/opsdev" contractmodel "dashoo.cn/opms_parent/app/model/contract" opsdevmodel "dashoo.cn/opms_parent/app/model/opsdev" "dashoo.cn/opms_parent/app/service" "dashoo.cn/opms_libary/myerrors" "github.com/gogf/gf/database/gdb" "github.com/gogf/gf/frame/g" "github.com/gogf/gf/os/gtime" ) type ctrContractEventService struct { *service.ContextService Dao *contractdao.CtrContractEventDao ContractDao *contractdao.CtrContractDao DeliveryEventDao *opsdevdao.OpsDeliveryProjectEventDao DeliveryProjectDao *opsdevdao.OpsDeliveryProjectDao OperationDao *opsdevdao.OpsOperationEventDao DeliveryAttachmentDao *opsdevdao.OpsDeliveryProjectEventAttachmentDao OperationAttachmentDao *opsdevdao.OpsOperationEventAttachmentDao } func NewCtrContractEventService(ctx context.Context) (*ctrContractEventService, error) { svc := &ctrContractEventService{} var err error if svc.ContextService, err = svc.Init(ctx); err != nil { return nil, err } svc.Dao = contractdao.NewCtrContractEventDao(svc.Tenant) svc.ContractDao = contractdao.NewCtrContractDao(svc.Tenant) svc.DeliveryEventDao = opsdevdao.NewOpsDeliveryProjectEventDao(svc.Tenant) svc.DeliveryProjectDao = opsdevdao.NewOpsDeliveryProjectDao(svc.Tenant) svc.OperationDao = opsdevdao.NewOpsOperationEventDao(svc.Tenant) svc.DeliveryAttachmentDao = opsdevdao.NewOpsDeliveryProjectEventAttachmentDao(svc.Tenant) svc.OperationAttachmentDao = opsdevdao.NewOpsOperationEventAttachmentDao(svc.Tenant) return svc, nil } func (s *ctrContractEventService) GetProjectByContractId(req *contractmodel.CtrContractEventGetProjectReq) (*contractmodel.CtrContractEventProjectRsp, error) { rsp := &contractmodel.CtrContractEventProjectRsp{} type projectRow struct { Id int `orm:"id"` ProjectStatus string `orm:"project_status"` } var project projectRow count, err := s.DeliveryProjectDao. Unscoped(). Where("contract_id = ? AND deleted_time IS NULL", req.ContractId). Count(1) if err != nil { g.Log().Error(err) return nil, myerrors.DbError("查询交付项目失败") } if count == 0 { rsp.Found = false return rsp, nil } err = s.DeliveryProjectDao. Unscoped(). Fields(s.DeliveryProjectDao.Columns.Id, s.DeliveryProjectDao.Columns.ProjectStatus). Where("contract_id = ? AND deleted_time IS NULL", req.ContractId). Limit(1). Scan(&project) if err != nil { g.Log().Error(err) return nil, myerrors.DbError("查询交付项目详情失败") } rsp.Found = true rsp.ProjectId = project.Id rsp.ProjectStatus = project.ProjectStatus if rsp.ProjectStatus == "50" { rsp.EventType = contractmodel.ContractEventTypeOperation } else { rsp.EventType = contractmodel.ContractEventTypeDelivery } return rsp, nil } func (s *ctrContractEventService) CreateProjectForContract(req *contractmodel.CtrContractEventCreateProjectReq) error { var contractInfo contractmodel.CtrContract err := s.ContractDao.WherePri(req.ContractId).Scan(&contractInfo) if err != nil { g.Log().Error(err) return myerrors.DbError("查询合同信息失败") } if contractInfo.Id <= 0 { return myerrors.TipsError("合同不存在") } count, err := s.DeliveryProjectDao. Unscoped(). Where("contract_id = ? AND deleted_time IS NULL", req.ContractId). Count(1) if err != nil { g.Log().Error(err) return myerrors.DbError("查询交付项目失败") } if count > 0 { return nil } data := g.Map{ "project_name": contractInfo.ContractName, "project_status": "50", "contract_id": contractInfo.Id, "contract_no": contractInfo.ContractCode, "cust_id": contractInfo.CustId, "cust_name": contractInfo.CustName, "product_line": contractInfo.ProductLine, "sales_user_id": contractInfo.InchargeId, "sales_user_name": contractInfo.InchargeName, "sales_region_id": contractInfo.CustCityId, "delivery_node": "05", } service.SetCreatedInfo(data, s.GetCxtUserId(), s.GetCxtUserName()) _, err = s.DeliveryProjectDao.Data(data).Insert() if err != nil { g.Log().Error(err) return myerrors.DbError("创建交付项目失败") } return nil } func (s *ctrContractEventService) GetList(req *contractmodel.CtrContractEventSearchReq) (total int, list []*contractmodel.CtrContractEventRsp, err error) { baseQuery := s.Dao.DB.Model("ctr_contract_event a"). LeftJoin("ops_delivery_project_event b", "a.event_type='10' AND a.event_id = b.id AND b.deleted_time IS NULL"). LeftJoin("ops_operation_event c", "a.event_type='20' AND a.event_id = c.id AND c.deleted_time IS NULL"). Unscoped(). Where("a.deleted_time IS NULL") if req.ContractId != 0 { baseQuery = baseQuery.Where("a.contract_id = ?", req.ContractId) } if req.EventType != "" { baseQuery = baseQuery.Where("a.event_type = ?", req.EventType) } if req.EventTitle != "" { likestr := fmt.Sprintf("%%%s%%", req.EventTitle) baseQuery = baseQuery.Where("(b.delivery_event_title LIKE ? OR c.event_title LIKE ?)", likestr, likestr) } if len(req.EventStatus) > 0 { baseQuery = baseQuery.Where("COALESCE(b.delivery_event_status, c.event_status) IN (?)", req.EventStatus) } if req.FeedbackReporter != "" { likestr := fmt.Sprintf("%%%s%%", req.FeedbackReporter) baseQuery = baseQuery.Where("(b.feedback_reporter LIKE ? OR c.feedback_reporter LIKE ?)", likestr, likestr) } if req.FeedbackDateStart != "" { baseQuery = baseQuery.Where("(b.feedback_date >= ? OR c.feedback_date >= ?)", req.FeedbackDateStart, req.FeedbackDateStart) } if req.FeedbackDateEnd != "" { baseQuery = baseQuery.Where("(b.feedback_date <= ? OR c.feedback_date <= ?)", req.FeedbackDateEnd, req.FeedbackDateEnd) } if req.OpsUserName != "" { likestr := fmt.Sprintf("%%%s%%", req.OpsUserName) baseQuery = baseQuery.Where("(b.ops_user_name LIKE ? OR c.ops_user_name LIKE ?)", likestr, likestr) } total, err = baseQuery.Fields("a.id").Count() if err != nil { g.Log().Error(err) return 0, nil, myerrors.DbError("获取合同事件总行数失败") } pageSize := req.PageSize if pageSize <= 0 { pageSize = 10 } page := req.GetPage() err = baseQuery.Fields( "a.id as ctr_event_id", "a.event_id", "a.event_type", "a.contract_id", "a.contract_code", "a.contract_name", "a.cust_name", "COALESCE(b.delivery_event_title, c.event_title) as event_title", "COALESCE(b.delivery_event_no, c.event_no) as event_no", "COALESCE(b.delivery_event_type, c.event_type) as sub_event_type", "COALESCE(b.delivery_event_status, c.event_status) as event_status", "COALESCE(b.ops_user_name, c.ops_user_name) as ops_user_name", "COALESCE(b.feedback_reporter, c.feedback_reporter) as feedback_reporter", "COALESCE(b.feedback_date, c.feedback_date) as feedback_date", "COALESCE(b.complete_time, c.complete_time) as complete_time", "COALESCE(b.complete_desc, c.complete_desc) as complete_desc", ).OrderDesc("a.id").Page(page, pageSize).Scan(&list) if err != nil { g.Log().Error(err) return 0, nil, myerrors.DbError("查询合同事件列表失败") } return total, list, nil } func (s *ctrContractEventService) Create(req *contractmodel.CtrContractEventAddReq) error { return s.Dao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error { var eventId int64 var eventCode string var err error switch req.EventType { case contractmodel.ContractEventTypeOperation: eventId, eventCode, err = s.createOperationEvent(tx, req) case contractmodel.ContractEventTypeDelivery: eventId, eventCode, err = s.createDeliveryEvent(tx, req) default: return myerrors.TipsError("未知的事件类型") } if err != nil { return err } linkData := g.Map{ "event_id": eventId, "event_code": eventCode, "event_type": req.EventType, "contract_id": req.ContractId, "contract_code": req.ContractCode, "contract_name": req.ContractName, "cust_id": req.CustId, "cust_name": req.CustName, "product_line": req.ProductLine, "is_big": req.IsBig, "incharge_id": req.InchargeId, "incharge_name": req.InchargeName, "remark": req.Remark, } service.SetCreatedInfo(linkData, s.GetCxtUserId(), s.GetCxtUserName()) _, err = s.Dao.TX(tx).Data(linkData).Insert() if err != nil { g.Log().Error(err) return myerrors.DbError("新增合同事件关联记录失败") } return nil }) } func (s *ctrContractEventService) createOperationEvent(tx *gdb.TX, req *contractmodel.CtrContractEventAddReq) (int64, string, error) { data := g.Map{ "event_title": req.EventTitle, "event_desc": req.EventDesc, "event_type": req.SubEventType, "priority_level": req.PriorityLevel, "contract_id": req.ContractId, "contract_name": req.ContractName, "cust_id": req.CustId, "cust_name": req.CustName, "product_line": req.ProductLine, "is_big": req.IsBig, "is_ops": "10", "feedback_reporter": req.FeedbackReporter, "feedback_source": req.FeedbackSource, "event_status": opsdevmodel.EventStatusProcessing, "event_no": generateOperationEventNo(), "ops_user_id": s.GetCxtUserId(), "ops_user_name": s.GetCxtUserName(), } if req.FeedbackDate == "" { data["feedback_date"] = gtime.Now() } else { data["feedback_date"] = req.FeedbackDate } service.SetCreatedInfo(data, s.GetCxtUserId(), s.GetCxtUserName()) result, err := s.OperationDao.TX(tx).Data(data).Insert() if err != nil { g.Log().Error(err) return 0, "", myerrors.DbError("创建运维事件失败") } id, _ := result.LastInsertId() if len(req.Attachments) > 0 { for _, att := range req.Attachments { attData := g.Map{ "event_id": id, "file_name": att.FileName, "file_url": att.FileUrl, "file_type": att.FileType, } service.SetCreatedInfo(attData, s.GetCxtUserId(), s.GetCxtUserName()) _, _ = s.OperationAttachmentDao.TX(tx).Data(attData).Insert() } } return id, fmt.Sprintf("OPS-%d", id), nil } func (s *ctrContractEventService) createDeliveryEvent(tx *gdb.TX, req *contractmodel.CtrContractEventAddReq) (int64, string, error) { var project opsdevmodel.OpsDeliveryProject err := s.DeliveryProjectDao. TX(tx). Fields(s.DeliveryProjectDao.Columns.Id). Where("contract_id = ? AND deleted_time IS NULL", req.ContractId). OrderDesc(s.DeliveryProjectDao.Columns.Id). Limit(1). Scan(&project) if err != nil { g.Log().Error(err) return 0, "", myerrors.DbError("查询交付项目失败") } if project.Id <= 0 { return 0, "", myerrors.TipsError("未找到对应交付项目,请先创建项目") } data := g.Map{ "project_id": project.Id, "delivery_event_title": req.EventTitle, "delivery_event_desc": req.EventDesc, "delivery_event_type": req.SubEventType, "feedback_reporter": req.FeedbackReporter, "feedback_source": req.FeedbackSource, "delivery_event_status": opsdevmodel.DeliveryEventStatusProcessing, "delivery_event_no": generateDeliveryEventNo(), "ops_user_id": s.GetCxtUserId(), "ops_user_name": s.GetCxtUserName(), } if req.FeedbackDate == "" { data["feedback_date"] = gtime.Now() } else { data["feedback_date"] = req.FeedbackDate } service.SetCreatedInfo(data, s.GetCxtUserId(), s.GetCxtUserName()) result, err := s.DeliveryEventDao.TX(tx).Data(data).Insert() if err != nil { g.Log().Error(err) return 0, "", myerrors.DbError("创建交付事件失败") } id, _ := result.LastInsertId() if len(req.Attachments) > 0 { for _, att := range req.Attachments { attData := g.Map{ "event_id": id, "file_name": att.FileName, "file_url": att.FileUrl, "file_type": att.FileType, } service.SetCreatedInfo(attData, s.GetCxtUserId(), s.GetCxtUserName()) _, _ = s.DeliveryAttachmentDao.TX(tx).Data(attData).Insert() } } return id, fmt.Sprintf("DEL-%d", id), nil } func generateOperationEventNo() string { return fmt.Sprintf("OPS%s", gtime.Now().Format("YmdHis")) } func generateDeliveryEventNo() string { return fmt.Sprintf("DEL%s", gtime.Now().Format("YmdHis")) } func (s *ctrContractEventService) Cancel(req *contractmodel.CtrContractEventCancelReq) error { entity, err := s.Dao.WherePri(req.Id).One() if err != nil { g.Log().Error(err) return myerrors.DbError("查询合同事件登记数据失败") } if entity == nil { return myerrors.TipsError("合同事件登记数据不存在") } switch req.EventType { case contractmodel.ContractEventTypeDelivery: return s.cancelDeliveryEvent(req) case contractmodel.ContractEventTypeOperation: return s.cancelOperationEvent(req) default: return myerrors.TipsError("未知的事件类型") } } func (s *ctrContractEventService) cancelDeliveryEvent(req *contractmodel.CtrContractEventCancelReq) error { var event opsdevmodel.OpsDeliveryProjectEvent err := s.DeliveryEventDao.FieldsEx(s.DeliveryEventDao.Columns.DeletedTime).WherePri(req.EventId).Scan(&event) if err != nil { g.Log().Error(err) return myerrors.DbError("查询交付事件数据失败") } if event.Id <= 0 { return myerrors.TipsError("交付事件不存在") } if event.DeliveryEventStatus == opsdevmodel.DeliveryEventStatusClosed { return myerrors.TipsError("已关闭的事件不能作废") } if event.DeliveryEventStatus == opsdevmodel.DeliveryEventStatusCancelled { return myerrors.TipsError("该事件已作废") } return s.DeliveryEventDao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error { data := g.Map{ s.DeliveryEventDao.Columns.DeliveryEventStatus: opsdevmodel.DeliveryEventStatusCancelled, s.DeliveryEventDao.Columns.Remark: req.CancelReason, } service.SetUpdatedInfo(data, s.GetCxtUserId(), s.GetCxtUserName()) _, err := s.DeliveryEventDao.TX(tx).FieldsEx(service.UpdateFieldEx...).Data(data).WherePri(req.EventId).Update() if err != nil { g.Log().Error(err) return myerrors.DbError("作废交付事件失败") } return nil }) } func (s *ctrContractEventService) cancelOperationEvent(req *contractmodel.CtrContractEventCancelReq) error { var event opsdevmodel.OpsOperationEvent err := s.OperationDao.FieldsEx(s.OperationDao.Columns.DeletedTime).WherePri(req.EventId).Scan(&event) if err != nil { g.Log().Error(err) return myerrors.DbError("查询运维事件数据失败") } if event.Id <= 0 { return myerrors.TipsError("运维事件不存在") } if event.EventStatus == opsdevmodel.EventStatusClosed { return myerrors.TipsError("已关闭的事件不能作废") } data := g.Map{ s.OperationDao.Columns.EventStatus: opsdevmodel.EventStatusClosed, s.OperationDao.Columns.Remark: req.CancelReason, } service.SetUpdatedInfo(data, s.GetCxtUserId(), s.GetCxtUserName()) _, err = s.OperationDao.FieldsEx(service.UpdateFieldEx...).Data(data).WherePri(req.EventId).Update() if err != nil { g.Log().Error(err) return myerrors.DbError("作废运维事件失败") } return nil }