ctr_contract_event.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. package service
  2. import (
  3. "context"
  4. "fmt"
  5. contractdao "dashoo.cn/opms_parent/app/dao/contract"
  6. opsdevdao "dashoo.cn/opms_parent/app/dao/opsdev"
  7. contractmodel "dashoo.cn/opms_parent/app/model/contract"
  8. opsdevmodel "dashoo.cn/opms_parent/app/model/opsdev"
  9. "dashoo.cn/opms_parent/app/service"
  10. "dashoo.cn/opms_libary/myerrors"
  11. "github.com/gogf/gf/database/gdb"
  12. "github.com/gogf/gf/frame/g"
  13. "github.com/gogf/gf/os/gtime"
  14. )
  15. type ctrContractEventService struct {
  16. *service.ContextService
  17. Dao *contractdao.CtrContractEventDao
  18. ContractDao *contractdao.CtrContractDao
  19. DeliveryEventDao *opsdevdao.OpsDeliveryProjectEventDao
  20. DeliveryProjectDao *opsdevdao.OpsDeliveryProjectDao
  21. OperationDao *opsdevdao.OpsOperationEventDao
  22. DeliveryAttachmentDao *opsdevdao.OpsDeliveryProjectEventAttachmentDao
  23. OperationAttachmentDao *opsdevdao.OpsOperationEventAttachmentDao
  24. }
  25. func NewCtrContractEventService(ctx context.Context) (*ctrContractEventService, error) {
  26. svc := &ctrContractEventService{}
  27. var err error
  28. if svc.ContextService, err = svc.Init(ctx); err != nil {
  29. return nil, err
  30. }
  31. svc.Dao = contractdao.NewCtrContractEventDao(svc.Tenant)
  32. svc.ContractDao = contractdao.NewCtrContractDao(svc.Tenant)
  33. svc.DeliveryEventDao = opsdevdao.NewOpsDeliveryProjectEventDao(svc.Tenant)
  34. svc.DeliveryProjectDao = opsdevdao.NewOpsDeliveryProjectDao(svc.Tenant)
  35. svc.OperationDao = opsdevdao.NewOpsOperationEventDao(svc.Tenant)
  36. svc.DeliveryAttachmentDao = opsdevdao.NewOpsDeliveryProjectEventAttachmentDao(svc.Tenant)
  37. svc.OperationAttachmentDao = opsdevdao.NewOpsOperationEventAttachmentDao(svc.Tenant)
  38. return svc, nil
  39. }
  40. func (s *ctrContractEventService) GetProjectByContractId(req *contractmodel.CtrContractEventGetProjectReq) (*contractmodel.CtrContractEventProjectRsp, error) {
  41. rsp := &contractmodel.CtrContractEventProjectRsp{}
  42. type projectRow struct {
  43. Id int `orm:"id"`
  44. ProjectStatus string `orm:"project_status"`
  45. }
  46. var project projectRow
  47. count, err := s.DeliveryProjectDao.
  48. Unscoped().
  49. Where("contract_id = ? AND deleted_time IS NULL", req.ContractId).
  50. Count(1)
  51. if err != nil {
  52. g.Log().Error(err)
  53. return nil, myerrors.DbError("查询交付项目失败")
  54. }
  55. if count == 0 {
  56. rsp.Found = false
  57. return rsp, nil
  58. }
  59. err = s.DeliveryProjectDao.
  60. Unscoped().
  61. Fields(s.DeliveryProjectDao.Columns.Id, s.DeliveryProjectDao.Columns.ProjectStatus).
  62. Where("contract_id = ? AND deleted_time IS NULL", req.ContractId).
  63. Limit(1).
  64. Scan(&project)
  65. if err != nil {
  66. g.Log().Error(err)
  67. return nil, myerrors.DbError("查询交付项目详情失败")
  68. }
  69. rsp.Found = true
  70. rsp.ProjectId = project.Id
  71. rsp.ProjectStatus = project.ProjectStatus
  72. if rsp.ProjectStatus == "50" {
  73. rsp.EventType = contractmodel.ContractEventTypeOperation
  74. } else {
  75. rsp.EventType = contractmodel.ContractEventTypeDelivery
  76. }
  77. return rsp, nil
  78. }
  79. func (s *ctrContractEventService) CreateProjectForContract(req *contractmodel.CtrContractEventCreateProjectReq) error {
  80. var contractInfo contractmodel.CtrContract
  81. err := s.ContractDao.WherePri(req.ContractId).Scan(&contractInfo)
  82. if err != nil {
  83. g.Log().Error(err)
  84. return myerrors.DbError("查询合同信息失败")
  85. }
  86. if contractInfo.Id <= 0 {
  87. return myerrors.TipsError("合同不存在")
  88. }
  89. count, err := s.DeliveryProjectDao.
  90. Unscoped().
  91. Where("contract_id = ? AND deleted_time IS NULL", req.ContractId).
  92. Count(1)
  93. if err != nil {
  94. g.Log().Error(err)
  95. return myerrors.DbError("查询交付项目失败")
  96. }
  97. if count > 0 {
  98. return nil
  99. }
  100. data := g.Map{
  101. "project_name": contractInfo.ContractName,
  102. "project_status": "50",
  103. "contract_id": contractInfo.Id,
  104. "contract_no": contractInfo.ContractCode,
  105. "cust_id": contractInfo.CustId,
  106. "cust_name": contractInfo.CustName,
  107. "product_line": contractInfo.ProductLine,
  108. "sales_user_id": contractInfo.InchargeId,
  109. "sales_user_name": contractInfo.InchargeName,
  110. "sales_region_id": contractInfo.CustCityId,
  111. "delivery_node": "05",
  112. }
  113. service.SetCreatedInfo(data, s.GetCxtUserId(), s.GetCxtUserName())
  114. _, err = s.DeliveryProjectDao.Data(data).Insert()
  115. if err != nil {
  116. g.Log().Error(err)
  117. return myerrors.DbError("创建交付项目失败")
  118. }
  119. return nil
  120. }
  121. func (s *ctrContractEventService) GetList(req *contractmodel.CtrContractEventSearchReq) (total int, list []*contractmodel.CtrContractEventRsp, err error) {
  122. baseQuery := s.Dao.DB.Model("ctr_contract_event a").
  123. LeftJoin("ops_delivery_project_event b", "a.event_type='10' AND a.event_id = b.id AND b.deleted_time IS NULL").
  124. LeftJoin("ops_operation_event c", "a.event_type='20' AND a.event_id = c.id AND c.deleted_time IS NULL").
  125. Unscoped().
  126. Where("a.deleted_time IS NULL")
  127. if req.ContractId != 0 {
  128. baseQuery = baseQuery.Where("a.contract_id = ?", req.ContractId)
  129. }
  130. if req.EventType != "" {
  131. baseQuery = baseQuery.Where("a.event_type = ?", req.EventType)
  132. }
  133. if req.EventTitle != "" {
  134. likestr := fmt.Sprintf("%%%s%%", req.EventTitle)
  135. baseQuery = baseQuery.Where("(b.delivery_event_title LIKE ? OR c.event_title LIKE ?)", likestr, likestr)
  136. }
  137. if len(req.EventStatus) > 0 {
  138. baseQuery = baseQuery.Where("COALESCE(b.delivery_event_status, c.event_status) IN (?)", req.EventStatus)
  139. }
  140. if req.FeedbackReporter != "" {
  141. likestr := fmt.Sprintf("%%%s%%", req.FeedbackReporter)
  142. baseQuery = baseQuery.Where("(b.feedback_reporter LIKE ? OR c.feedback_reporter LIKE ?)", likestr, likestr)
  143. }
  144. if req.FeedbackDateStart != "" {
  145. baseQuery = baseQuery.Where("(b.feedback_date >= ? OR c.feedback_date >= ?)", req.FeedbackDateStart, req.FeedbackDateStart)
  146. }
  147. if req.FeedbackDateEnd != "" {
  148. baseQuery = baseQuery.Where("(b.feedback_date <= ? OR c.feedback_date <= ?)", req.FeedbackDateEnd, req.FeedbackDateEnd)
  149. }
  150. if req.OpsUserName != "" {
  151. likestr := fmt.Sprintf("%%%s%%", req.OpsUserName)
  152. baseQuery = baseQuery.Where("(b.ops_user_name LIKE ? OR c.ops_user_name LIKE ?)", likestr, likestr)
  153. }
  154. total, err = baseQuery.Fields("a.id").Count()
  155. if err != nil {
  156. g.Log().Error(err)
  157. return 0, nil, myerrors.DbError("获取合同事件总行数失败")
  158. }
  159. pageSize := req.PageSize
  160. if pageSize <= 0 {
  161. pageSize = 10
  162. }
  163. page := req.GetPage()
  164. err = baseQuery.Fields(
  165. "a.id as ctr_event_id",
  166. "a.event_id",
  167. "a.event_type",
  168. "a.contract_id",
  169. "a.contract_code",
  170. "a.contract_name",
  171. "a.cust_name",
  172. "COALESCE(b.delivery_event_title, c.event_title) as event_title",
  173. "COALESCE(b.delivery_event_no, c.event_no) as event_no",
  174. "COALESCE(b.delivery_event_type, c.event_type) as sub_event_type",
  175. "COALESCE(b.delivery_event_status, c.event_status) as event_status",
  176. "COALESCE(b.ops_user_name, c.ops_user_name) as ops_user_name",
  177. "COALESCE(b.feedback_reporter, c.feedback_reporter) as feedback_reporter",
  178. "COALESCE(b.feedback_date, c.feedback_date) as feedback_date",
  179. "COALESCE(b.complete_time, c.complete_time) as complete_time",
  180. "COALESCE(b.complete_desc, c.complete_desc) as complete_desc",
  181. ).OrderDesc("a.id").Page(page, pageSize).Scan(&list)
  182. if err != nil {
  183. g.Log().Error(err)
  184. return 0, nil, myerrors.DbError("查询合同事件列表失败")
  185. }
  186. return total, list, nil
  187. }
  188. func (s *ctrContractEventService) Create(req *contractmodel.CtrContractEventAddReq) error {
  189. return s.Dao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
  190. var eventId int64
  191. var eventCode string
  192. var err error
  193. switch req.EventType {
  194. case contractmodel.ContractEventTypeOperation:
  195. eventId, eventCode, err = s.createOperationEvent(tx, req)
  196. case contractmodel.ContractEventTypeDelivery:
  197. eventId, eventCode, err = s.createDeliveryEvent(tx, req)
  198. default:
  199. return myerrors.TipsError("未知的事件类型")
  200. }
  201. if err != nil {
  202. return err
  203. }
  204. linkData := g.Map{
  205. "event_id": eventId,
  206. "event_code": eventCode,
  207. "event_type": req.EventType,
  208. "contract_id": req.ContractId,
  209. "contract_code": req.ContractCode,
  210. "contract_name": req.ContractName,
  211. "cust_id": req.CustId,
  212. "cust_name": req.CustName,
  213. "product_line": req.ProductLine,
  214. "is_big": req.IsBig,
  215. "incharge_id": req.InchargeId,
  216. "incharge_name": req.InchargeName,
  217. "remark": req.Remark,
  218. }
  219. service.SetCreatedInfo(linkData, s.GetCxtUserId(), s.GetCxtUserName())
  220. _, err = s.Dao.TX(tx).Data(linkData).Insert()
  221. if err != nil {
  222. g.Log().Error(err)
  223. return myerrors.DbError("新增合同事件关联记录失败")
  224. }
  225. return nil
  226. })
  227. }
  228. func (s *ctrContractEventService) createOperationEvent(tx *gdb.TX, req *contractmodel.CtrContractEventAddReq) (int64, string, error) {
  229. data := g.Map{
  230. "event_title": req.EventTitle,
  231. "event_desc": req.EventDesc,
  232. "event_type": req.SubEventType,
  233. "priority_level": req.PriorityLevel,
  234. "contract_id": req.ContractId,
  235. "contract_name": req.ContractName,
  236. "cust_id": req.CustId,
  237. "cust_name": req.CustName,
  238. "product_line": req.ProductLine,
  239. "is_big": req.IsBig,
  240. "is_ops": "10",
  241. "feedback_reporter": req.FeedbackReporter,
  242. "feedback_source": req.FeedbackSource,
  243. "event_status": opsdevmodel.EventStatusProcessing,
  244. "event_no": generateOperationEventNo(),
  245. "ops_user_id": s.GetCxtUserId(),
  246. "ops_user_name": s.GetCxtUserName(),
  247. }
  248. if req.FeedbackDate == "" {
  249. data["feedback_date"] = gtime.Now()
  250. } else {
  251. data["feedback_date"] = req.FeedbackDate
  252. }
  253. service.SetCreatedInfo(data, s.GetCxtUserId(), s.GetCxtUserName())
  254. result, err := s.OperationDao.TX(tx).Data(data).Insert()
  255. if err != nil {
  256. g.Log().Error(err)
  257. return 0, "", myerrors.DbError("创建运维事件失败")
  258. }
  259. id, _ := result.LastInsertId()
  260. if len(req.Attachments) > 0 {
  261. for _, att := range req.Attachments {
  262. attData := g.Map{
  263. "event_id": id,
  264. "file_name": att.FileName,
  265. "file_url": att.FileUrl,
  266. "file_type": att.FileType,
  267. }
  268. service.SetCreatedInfo(attData, s.GetCxtUserId(), s.GetCxtUserName())
  269. _, _ = s.OperationAttachmentDao.TX(tx).Data(attData).Insert()
  270. }
  271. }
  272. return id, fmt.Sprintf("OPS-%d", id), nil
  273. }
  274. func (s *ctrContractEventService) createDeliveryEvent(tx *gdb.TX, req *contractmodel.CtrContractEventAddReq) (int64, string, error) {
  275. var project opsdevmodel.OpsDeliveryProject
  276. err := s.DeliveryProjectDao.
  277. TX(tx).
  278. Fields(s.DeliveryProjectDao.Columns.Id).
  279. Where("contract_id = ? AND deleted_time IS NULL", req.ContractId).
  280. OrderDesc(s.DeliveryProjectDao.Columns.Id).
  281. Limit(1).
  282. Scan(&project)
  283. if err != nil {
  284. g.Log().Error(err)
  285. return 0, "", myerrors.DbError("查询交付项目失败")
  286. }
  287. if project.Id <= 0 {
  288. return 0, "", myerrors.TipsError("未找到对应交付项目,请先创建项目")
  289. }
  290. data := g.Map{
  291. "project_id": project.Id,
  292. "delivery_event_title": req.EventTitle,
  293. "delivery_event_desc": req.EventDesc,
  294. "delivery_event_type": req.SubEventType,
  295. "feedback_reporter": req.FeedbackReporter,
  296. "feedback_source": req.FeedbackSource,
  297. "delivery_event_status": opsdevmodel.DeliveryEventStatusProcessing,
  298. "delivery_event_no": generateDeliveryEventNo(),
  299. "ops_user_id": s.GetCxtUserId(),
  300. "ops_user_name": s.GetCxtUserName(),
  301. }
  302. if req.FeedbackDate == "" {
  303. data["feedback_date"] = gtime.Now()
  304. } else {
  305. data["feedback_date"] = req.FeedbackDate
  306. }
  307. service.SetCreatedInfo(data, s.GetCxtUserId(), s.GetCxtUserName())
  308. result, err := s.DeliveryEventDao.TX(tx).Data(data).Insert()
  309. if err != nil {
  310. g.Log().Error(err)
  311. return 0, "", myerrors.DbError("创建交付事件失败")
  312. }
  313. id, _ := result.LastInsertId()
  314. if len(req.Attachments) > 0 {
  315. for _, att := range req.Attachments {
  316. attData := g.Map{
  317. "event_id": id,
  318. "file_name": att.FileName,
  319. "file_url": att.FileUrl,
  320. "file_type": att.FileType,
  321. }
  322. service.SetCreatedInfo(attData, s.GetCxtUserId(), s.GetCxtUserName())
  323. _, _ = s.DeliveryAttachmentDao.TX(tx).Data(attData).Insert()
  324. }
  325. }
  326. return id, fmt.Sprintf("DEL-%d", id), nil
  327. }
  328. func generateOperationEventNo() string {
  329. return fmt.Sprintf("OPS%s", gtime.Now().Format("YmdHis"))
  330. }
  331. func generateDeliveryEventNo() string {
  332. return fmt.Sprintf("DEL%s", gtime.Now().Format("YmdHis"))
  333. }
  334. func (s *ctrContractEventService) Cancel(req *contractmodel.CtrContractEventCancelReq) error {
  335. entity, err := s.Dao.WherePri(req.Id).One()
  336. if err != nil {
  337. g.Log().Error(err)
  338. return myerrors.DbError("查询合同事件登记数据失败")
  339. }
  340. if entity == nil {
  341. return myerrors.TipsError("合同事件登记数据不存在")
  342. }
  343. switch req.EventType {
  344. case contractmodel.ContractEventTypeDelivery:
  345. return s.cancelDeliveryEvent(req)
  346. case contractmodel.ContractEventTypeOperation:
  347. return s.cancelOperationEvent(req)
  348. default:
  349. return myerrors.TipsError("未知的事件类型")
  350. }
  351. }
  352. func (s *ctrContractEventService) cancelDeliveryEvent(req *contractmodel.CtrContractEventCancelReq) error {
  353. var event opsdevmodel.OpsDeliveryProjectEvent
  354. err := s.DeliveryEventDao.FieldsEx(s.DeliveryEventDao.Columns.DeletedTime).WherePri(req.EventId).Scan(&event)
  355. if err != nil {
  356. g.Log().Error(err)
  357. return myerrors.DbError("查询交付事件数据失败")
  358. }
  359. if event.Id <= 0 {
  360. return myerrors.TipsError("交付事件不存在")
  361. }
  362. if event.DeliveryEventStatus == opsdevmodel.DeliveryEventStatusClosed {
  363. return myerrors.TipsError("已关闭的事件不能作废")
  364. }
  365. if event.DeliveryEventStatus == opsdevmodel.DeliveryEventStatusCancelled {
  366. return myerrors.TipsError("该事件已作废")
  367. }
  368. return s.DeliveryEventDao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
  369. data := g.Map{
  370. s.DeliveryEventDao.Columns.DeliveryEventStatus: opsdevmodel.DeliveryEventStatusCancelled,
  371. s.DeliveryEventDao.Columns.Remark: req.CancelReason,
  372. }
  373. service.SetUpdatedInfo(data, s.GetCxtUserId(), s.GetCxtUserName())
  374. _, err := s.DeliveryEventDao.TX(tx).FieldsEx(service.UpdateFieldEx...).Data(data).WherePri(req.EventId).Update()
  375. if err != nil {
  376. g.Log().Error(err)
  377. return myerrors.DbError("作废交付事件失败")
  378. }
  379. return nil
  380. })
  381. }
  382. func (s *ctrContractEventService) cancelOperationEvent(req *contractmodel.CtrContractEventCancelReq) error {
  383. var event opsdevmodel.OpsOperationEvent
  384. err := s.OperationDao.FieldsEx(s.OperationDao.Columns.DeletedTime).WherePri(req.EventId).Scan(&event)
  385. if err != nil {
  386. g.Log().Error(err)
  387. return myerrors.DbError("查询运维事件数据失败")
  388. }
  389. if event.Id <= 0 {
  390. return myerrors.TipsError("运维事件不存在")
  391. }
  392. if event.EventStatus == opsdevmodel.EventStatusClosed {
  393. return myerrors.TipsError("已关闭的事件不能作废")
  394. }
  395. data := g.Map{
  396. s.OperationDao.Columns.EventStatus: opsdevmodel.EventStatusClosed,
  397. s.OperationDao.Columns.Remark: req.CancelReason,
  398. }
  399. service.SetUpdatedInfo(data, s.GetCxtUserId(), s.GetCxtUserName())
  400. _, err = s.OperationDao.FieldsEx(service.UpdateFieldEx...).Data(data).WherePri(req.EventId).Update()
  401. if err != nil {
  402. g.Log().Error(err)
  403. return myerrors.DbError("作废运维事件失败")
  404. }
  405. return nil
  406. }