operation.go 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800
  1. package opsdev
  2. import (
  3. "context"
  4. "fmt"
  5. "dashoo.cn/common_definition/comm_def"
  6. "dashoo.cn/opms_libary/myerrors"
  7. opsdevdao "dashoo.cn/opms_parent/app/dao/opsdev"
  8. opsdevmodel "dashoo.cn/opms_parent/app/model/opsdev"
  9. "dashoo.cn/opms_parent/app/service"
  10. "github.com/gogf/gf/database/gdb"
  11. "github.com/gogf/gf/frame/g"
  12. "github.com/gogf/gf/os/gtime"
  13. "github.com/gogf/gf/util/gconv"
  14. "github.com/gogf/gf/util/gvalid"
  15. )
  16. type OperationService struct {
  17. *service.ContextService
  18. Dao *opsdevdao.OpsOperationEventDao
  19. RecordDao *opsdevdao.OpsOperationEventRecordDao
  20. AttachmentDao *opsdevdao.OpsOperationEventAttachmentDao
  21. }
  22. func NewOperationService(ctx context.Context) (svc *OperationService, err error) {
  23. svc = new(OperationService)
  24. if svc.ContextService, err = svc.Init(ctx); err != nil {
  25. return nil, err
  26. }
  27. svc.Dao = opsdevdao.NewOpsOperationEventDao(svc.Tenant)
  28. svc.RecordDao = opsdevdao.NewOpsOperationEventRecordDao(svc.Tenant)
  29. svc.AttachmentDao = opsdevdao.NewOpsOperationEventAttachmentDao(svc.Tenant)
  30. return svc, nil
  31. }
  32. // GetList 运维事件列表
  33. func (s *OperationService) GetList(req *opsdevmodel.OpsOperationEventSearchReq) (total int, list []*opsdevmodel.OpsOperationEvent, err error) {
  34. db := s.Dao.FieldsEx(s.Dao.Columns.DeletedTime).Where(s.Dao.Columns.EventStatus+" != ?", opsdevmodel.EventStatusClosed)
  35. if req.EventNo != "" {
  36. db = db.Where(s.Dao.Columns.EventNo, req.EventNo)
  37. }
  38. if req.EventTitle != "" {
  39. db = db.Where(s.Dao.Columns.EventTitle+" like ?", "%"+req.EventTitle+"%")
  40. }
  41. if req.EventStatus != "" {
  42. db = db.Where(s.Dao.Columns.EventStatus, req.EventStatus)
  43. }
  44. if req.EventType != "" {
  45. db = db.Where(s.Dao.Columns.EventType, req.EventType)
  46. }
  47. if req.PriorityLevel != "" {
  48. db = db.Where(s.Dao.Columns.PriorityLevel, req.PriorityLevel)
  49. }
  50. if req.IsBig != "" {
  51. db = db.Where(s.Dao.Columns.IsBig, req.IsBig)
  52. }
  53. if req.IsOps != "" {
  54. db = db.Where(s.Dao.Columns.IsOps, req.IsOps)
  55. }
  56. if req.CustName != "" {
  57. db = db.Where(s.Dao.Columns.CustName+" like ?", "%"+req.CustName+"%")
  58. }
  59. if req.OpsUserName != "" {
  60. db = db.Where(s.Dao.Columns.OpsUserName+" like ?", "%"+req.OpsUserName+"%")
  61. }
  62. if req.ContractName != "" {
  63. db = db.Where(s.Dao.Columns.ContractName+" like ?", "%"+req.ContractName+"%")
  64. }
  65. if req.ProductLine != "" {
  66. db = db.Where(s.Dao.Columns.ProductLine, req.ProductLine)
  67. }
  68. if req.BeginTime != "" {
  69. db = db.Where(s.Dao.Columns.CreatedTime+" >= ?", req.BeginTime)
  70. }
  71. if req.EndTime != "" {
  72. db = db.Where(s.Dao.Columns.CreatedTime+" <= ?", req.EndTime)
  73. }
  74. total, err = db.Count()
  75. if err != nil {
  76. g.Log().Error(err)
  77. return 0, nil, myerrors.DbError("查询运维事件数量失败")
  78. }
  79. pageNum, pageSize := req.GetPage()
  80. err = db.Page(pageNum, pageSize).Order(s.Dao.Columns.CreatedTime + " desc").Scan(&list)
  81. if err != nil {
  82. g.Log().Error(err)
  83. return 0, nil, myerrors.DbError("查询运维事件列表失败")
  84. }
  85. return total, list, nil
  86. }
  87. // GetEntityById 运维事件详情
  88. func (s *OperationService) GetEntityById(req *comm_def.IdReq) (detail *opsdevmodel.OpsOperationEvent, err error) {
  89. if req.Id <= 0 {
  90. return nil, myerrors.ValidError("参数有误!")
  91. }
  92. detail = new(opsdevmodel.OpsOperationEvent)
  93. err = s.Dao.FieldsEx(s.Dao.Columns.DeletedTime).WherePri(s.Dao.Columns.Id, req.Id).Scan(detail)
  94. if err != nil {
  95. g.Log().Error(err)
  96. return nil, myerrors.DbError("查询运维事件详情失败")
  97. }
  98. if detail.Id <= 0 {
  99. return nil, myerrors.TipsError("运维事件不存在")
  100. }
  101. return detail, nil
  102. }
  103. // Create 创建运维事件
  104. func (s *OperationService) Create(req *opsdevmodel.OpsOperationEventReq) (err error) {
  105. if err = gvalid.CheckStruct(s.Ctx, req, nil); err != nil {
  106. return myerrors.ValidError(err.Error())
  107. }
  108. data := gconv.Map(req)
  109. service.SetCreatedInfo(data, s.GetCxtUserId(), s.GetCxtUserName())
  110. data["eventNo"] = generateEventNo()
  111. data["eventStatus"] = opsdevmodel.EventStatusProcessing
  112. data["opsUserId"] = s.GetCxtUserId()
  113. data["opsUserName"] = s.GetCxtUserName()
  114. if v, ok := data["feedbackDate"]; ok && v == "" {
  115. data["feedbackDate"] = gtime.Now()
  116. }
  117. if v, ok := data["assignTime"]; ok && v == "" {
  118. data["assignTime"] = gtime.Now()
  119. }
  120. delete(data, "completeTime")
  121. result, err := s.Dao.Data(data).Insert()
  122. if err != nil {
  123. g.Log().Error(err)
  124. return myerrors.DbError("创建运维事件失败")
  125. }
  126. id, err := result.LastInsertId()
  127. if err != nil {
  128. g.Log().Error(err)
  129. return nil
  130. }
  131. recordData := g.Map{
  132. s.RecordDao.Columns.EventId: id,
  133. s.RecordDao.Columns.HandleUserId: s.GetCxtUserId(),
  134. s.RecordDao.Columns.HandleUserName: s.GetCxtUserName(),
  135. s.RecordDao.Columns.HandleContent: "创建运维事件",
  136. s.RecordDao.Columns.HandleResult: opsdevmodel.HandleResultUnresolved,
  137. s.RecordDao.Columns.HandleDate: gtime.Now(),
  138. s.RecordDao.Columns.OperateType: opsdevmodel.OperateTypeProcess,
  139. }
  140. service.SetCreatedInfo(recordData, s.GetCxtUserId(), s.GetCxtUserName())
  141. _, err = s.RecordDao.Data(recordData).Insert()
  142. if err != nil {
  143. g.Log().Error(err)
  144. }
  145. return nil
  146. }
  147. // UpdateById 更新运维事件
  148. func (s *OperationService) UpdateById(req *opsdevmodel.UpdateOpsOperationEventReq) (err error) {
  149. if err = gvalid.CheckStruct(s.Ctx, req, nil); err != nil {
  150. return myerrors.ValidError(err.Error())
  151. }
  152. event := new(opsdevmodel.OpsOperationEvent)
  153. err = s.Dao.FieldsEx(s.Dao.Columns.DeletedTime).WherePri(s.Dao.Columns.Id, req.Id).Scan(event)
  154. if err != nil {
  155. g.Log().Error(err)
  156. return myerrors.DbError("查询运维事件失败")
  157. }
  158. if event.Id <= 0 {
  159. return myerrors.TipsError("运维事件不存在")
  160. }
  161. if err = s.checkNotClosed(event); err != nil {
  162. return err
  163. }
  164. data := gconv.Map(req.OpsOperationEventReq)
  165. if v, ok := data["feedbackDate"]; ok && v == "" {
  166. delete(data, "feedbackDate")
  167. }
  168. delete(data, "assignTime")
  169. delete(data, "completeTime")
  170. service.SetUpdatedInfo(data, s.GetCxtUserId(), s.GetCxtUserName())
  171. _, err = s.Dao.FieldsEx(service.UpdateFieldEx...).WherePri(s.Dao.Columns.Id, req.Id).Data(data).Update()
  172. if err != nil {
  173. g.Log().Error(err)
  174. return myerrors.DbError("更新运维事件失败")
  175. }
  176. return nil
  177. }
  178. // DeleteByIds 批量删除运维事件
  179. func (s *OperationService) DeleteByIds(req *comm_def.IdsReq) (err error) {
  180. if len(req.Ids) == 0 {
  181. return myerrors.ValidError("参数有误!")
  182. }
  183. _, err = s.Dao.WherePri(req.Ids).Data(g.Map{
  184. s.Dao.Columns.DeletedTime: gtime.Now(),
  185. s.Dao.Columns.UpdatedBy: s.GetCxtUserId(),
  186. s.Dao.Columns.UpdatedName: s.GetCxtUserName(),
  187. }).Update()
  188. if err != nil {
  189. g.Log().Error(err)
  190. return myerrors.DbError("删除运维事件失败")
  191. }
  192. return nil
  193. }
  194. // checkNotClosed 校验事件未关闭,已关闭的事件不允许操作
  195. func (s *OperationService) checkNotClosed(event *opsdevmodel.OpsOperationEvent) error {
  196. if event.EventStatus == opsdevmodel.EventStatusClosed {
  197. return myerrors.TipsError("该事件已关闭,无法进行操作")
  198. }
  199. return nil
  200. }
  201. // Process 处理运维事件
  202. func (s *OperationService) Process(ctx context.Context, req *opsdevmodel.OpsOperationEventProcessReq) error {
  203. if req.Id <= 0 {
  204. return myerrors.TipsError("任务ID不能为空")
  205. }
  206. event := new(opsdevmodel.OpsOperationEvent)
  207. err := s.Dao.FieldsEx(s.Dao.Columns.DeletedTime).WherePri(s.Dao.Columns.Id, req.Id).Scan(event)
  208. if err != nil {
  209. g.Log().Error(err)
  210. return myerrors.DbError("查询运维事件失败")
  211. }
  212. if event.Id <= 0 {
  213. return myerrors.TipsError("运维事件不存在")
  214. }
  215. if err := s.checkNotClosed(event); err != nil {
  216. return err
  217. }
  218. switch req.OperateType {
  219. case opsdevmodel.OperateTypeProcess:
  220. return s.processStart(ctx, event, req)
  221. case opsdevmodel.OperateTypeResume:
  222. return s.processResume(ctx, event, req)
  223. case opsdevmodel.OperateTypeTransfer:
  224. return s.processTransfer(ctx, event, req)
  225. case opsdevmodel.OperateTypeSuspend:
  226. return s.processSuspend(ctx, event, req)
  227. case opsdevmodel.OperateTypeClose:
  228. return s.processClose(ctx, event, req)
  229. default:
  230. return myerrors.TipsError("未知的操作类型")
  231. }
  232. }
  233. func (s *OperationService) processStart(ctx context.Context, event *opsdevmodel.OpsOperationEvent, req *opsdevmodel.OpsOperationEventProcessReq) error {
  234. if event.EventStatus != opsdevmodel.EventStatusPending {
  235. return myerrors.TipsError("当前事件状态不能进行此操作")
  236. }
  237. return s.Dao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
  238. _, err := s.Dao.TX(tx).FieldsEx(service.UpdateFieldEx...).WherePri(s.Dao.Columns.Id, event.Id).Data(g.Map{
  239. s.Dao.Columns.EventStatus: opsdevmodel.EventStatusProcessing,
  240. s.Dao.Columns.OpsUserId: s.GetCxtUserId(),
  241. s.Dao.Columns.OpsUserName: s.GetCxtUserName(),
  242. s.Dao.Columns.AssignTime: gtime.Now(),
  243. s.Dao.Columns.UpdatedBy: s.GetCxtUserId(),
  244. s.Dao.Columns.UpdatedName: s.GetCxtUserName(),
  245. s.Dao.Columns.UpdatedTime: gtime.Now(),
  246. }).Update()
  247. if err != nil {
  248. return err
  249. }
  250. recordData := g.Map{
  251. s.RecordDao.Columns.EventId: event.Id,
  252. s.RecordDao.Columns.HandleUserId: s.GetCxtUserId(),
  253. s.RecordDao.Columns.HandleUserName: s.GetCxtUserName(),
  254. s.RecordDao.Columns.HandleContent: req.HandleContent,
  255. s.RecordDao.Columns.HandleResult: opsdevmodel.HandleResultUnresolved,
  256. s.RecordDao.Columns.HandleDate: gtime.Now(),
  257. s.RecordDao.Columns.OperateType: opsdevmodel.OperateTypeProcess,
  258. }
  259. service.SetCreatedInfo(recordData, s.GetCxtUserId(), s.GetCxtUserName())
  260. _, err = s.RecordDao.TX(tx).Data(recordData).Insert()
  261. if err != nil {
  262. return err
  263. }
  264. return nil
  265. })
  266. }
  267. func (s *OperationService) processClose(ctx context.Context, event *opsdevmodel.OpsOperationEvent, req *opsdevmodel.OpsOperationEventProcessReq) error {
  268. if event.EventStatus == opsdevmodel.EventStatusPending {
  269. return myerrors.TipsError("待处理状态不能直接关闭,请先接收")
  270. }
  271. if event.EventStatus == opsdevmodel.EventStatusSuspended {
  272. return myerrors.TipsError("挂起状态不允许关闭事件,请先转处理")
  273. }
  274. return s.Dao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
  275. _, err := s.Dao.TX(tx).FieldsEx(service.UpdateFieldEx...).WherePri(s.Dao.Columns.Id, event.Id).Data(g.Map{
  276. s.Dao.Columns.EventStatus: opsdevmodel.EventStatusClosed,
  277. s.Dao.Columns.CompleteTime: gtime.Now(),
  278. s.Dao.Columns.CompleteDesc: req.HandleContent,
  279. s.Dao.Columns.UpdatedBy: s.GetCxtUserId(),
  280. s.Dao.Columns.UpdatedName: s.GetCxtUserName(),
  281. s.Dao.Columns.UpdatedTime: gtime.Now(),
  282. }).Update()
  283. if err != nil {
  284. return err
  285. }
  286. recordData := g.Map{
  287. s.RecordDao.Columns.EventId: event.Id,
  288. s.RecordDao.Columns.HandleUserId: s.GetCxtUserId(),
  289. s.RecordDao.Columns.HandleUserName: s.GetCxtUserName(),
  290. s.RecordDao.Columns.HandleContent: req.HandleContent,
  291. s.RecordDao.Columns.HandleResult: req.HandleResult,
  292. s.RecordDao.Columns.HandleDate: gtime.Now(),
  293. s.RecordDao.Columns.OperateType: opsdevmodel.OperateTypeClose,
  294. }
  295. service.SetCreatedInfo(recordData, s.GetCxtUserId(), s.GetCxtUserName())
  296. _, err = s.RecordDao.TX(tx).Data(recordData).Insert()
  297. if err != nil {
  298. return err
  299. }
  300. return nil
  301. })
  302. }
  303. func (s *OperationService) processTransfer(ctx context.Context, event *opsdevmodel.OpsOperationEvent, req *opsdevmodel.OpsOperationEventProcessReq) error {
  304. if event.EventStatus != opsdevmodel.EventStatusProcessing && event.EventStatus != opsdevmodel.EventStatusProcessingNormal {
  305. return myerrors.TipsError("当前事件状态不能转研发")
  306. }
  307. return s.Dao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
  308. _, err := s.Dao.TX(tx).FieldsEx(service.UpdateFieldEx...).WherePri(s.Dao.Columns.Id, event.Id).Data(g.Map{
  309. s.Dao.Columns.EventStatus: opsdevmodel.EventStatusTransfer,
  310. s.Dao.Columns.UpdatedBy: s.GetCxtUserId(),
  311. s.Dao.Columns.UpdatedName: s.GetCxtUserName(),
  312. s.Dao.Columns.UpdatedTime: gtime.Now(),
  313. }).Update()
  314. if err != nil {
  315. return err
  316. }
  317. recordData := g.Map{
  318. s.RecordDao.Columns.EventId: event.Id,
  319. s.RecordDao.Columns.HandleUserId: s.GetCxtUserId(),
  320. s.RecordDao.Columns.HandleUserName: s.GetCxtUserName(),
  321. s.RecordDao.Columns.HandleContent: req.HandleContent,
  322. s.RecordDao.Columns.HandleResult: opsdevmodel.HandleResultUnresolved,
  323. s.RecordDao.Columns.HandleDate: gtime.Now(),
  324. s.RecordDao.Columns.OperateType: opsdevmodel.OperateTypeTransfer,
  325. }
  326. service.SetCreatedInfo(recordData, s.GetCxtUserId(), s.GetCxtUserName())
  327. _, err = s.RecordDao.TX(tx).Data(recordData).Insert()
  328. if err != nil {
  329. return err
  330. }
  331. return nil
  332. })
  333. }
  334. func (s *OperationService) processSuspend(ctx context.Context, event *opsdevmodel.OpsOperationEvent, req *opsdevmodel.OpsOperationEventProcessReq) error {
  335. if event.EventStatus != opsdevmodel.EventStatusProcessing && event.EventStatus != opsdevmodel.EventStatusProcessingNormal && event.EventStatus != opsdevmodel.EventStatusTransfer {
  336. return myerrors.TipsError("当前事件状态不能挂起")
  337. }
  338. return s.Dao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
  339. _, err := s.Dao.TX(tx).FieldsEx(service.UpdateFieldEx...).WherePri(s.Dao.Columns.Id, event.Id).Data(g.Map{
  340. s.Dao.Columns.EventStatus: opsdevmodel.EventStatusSuspended,
  341. s.Dao.Columns.UpdatedBy: s.GetCxtUserId(),
  342. s.Dao.Columns.UpdatedName: s.GetCxtUserName(),
  343. s.Dao.Columns.UpdatedTime: gtime.Now(),
  344. }).Update()
  345. if err != nil {
  346. return err
  347. }
  348. recordData := g.Map{
  349. s.RecordDao.Columns.EventId: event.Id,
  350. s.RecordDao.Columns.HandleUserId: s.GetCxtUserId(),
  351. s.RecordDao.Columns.HandleUserName: s.GetCxtUserName(),
  352. s.RecordDao.Columns.HandleContent: req.HandleContent,
  353. s.RecordDao.Columns.HandleResult: opsdevmodel.HandleResultUnresolved,
  354. s.RecordDao.Columns.HandleDate: gtime.Now(),
  355. s.RecordDao.Columns.OperateType: opsdevmodel.OperateTypeSuspend,
  356. }
  357. service.SetCreatedInfo(recordData, s.GetCxtUserId(), s.GetCxtUserName())
  358. _, err = s.RecordDao.TX(tx).Data(recordData).Insert()
  359. if err != nil {
  360. return err
  361. }
  362. return nil
  363. })
  364. }
  365. func (s *OperationService) processResume(ctx context.Context, event *opsdevmodel.OpsOperationEvent, req *opsdevmodel.OpsOperationEventProcessReq) error {
  366. if event.EventStatus != opsdevmodel.EventStatusSuspended {
  367. return myerrors.TipsError("当前事件状态不能转处理")
  368. }
  369. return s.Dao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
  370. _, err := s.Dao.TX(tx).FieldsEx(service.UpdateFieldEx...).WherePri(s.Dao.Columns.Id, event.Id).Data(g.Map{
  371. s.Dao.Columns.EventStatus: opsdevmodel.EventStatusProcessing,
  372. s.Dao.Columns.UpdatedBy: s.GetCxtUserId(),
  373. s.Dao.Columns.UpdatedName: s.GetCxtUserName(),
  374. s.Dao.Columns.UpdatedTime: gtime.Now(),
  375. }).Update()
  376. if err != nil {
  377. return err
  378. }
  379. recordData := g.Map{
  380. s.RecordDao.Columns.EventId: event.Id,
  381. s.RecordDao.Columns.HandleUserId: s.GetCxtUserId(),
  382. s.RecordDao.Columns.HandleUserName: s.GetCxtUserName(),
  383. s.RecordDao.Columns.HandleContent: req.HandleContent,
  384. s.RecordDao.Columns.HandleResult: opsdevmodel.HandleResultUnresolved,
  385. s.RecordDao.Columns.HandleDate: gtime.Now(),
  386. s.RecordDao.Columns.OperateType: opsdevmodel.OperateTypeResume,
  387. }
  388. service.SetCreatedInfo(recordData, s.GetCxtUserId(), s.GetCxtUserName())
  389. _, err = s.RecordDao.TX(tx).Data(recordData).Insert()
  390. if err != nil {
  391. return err
  392. }
  393. return nil
  394. })
  395. }
  396. // GetRecords 获取运维事件处理记录
  397. func (s *OperationService) GetRecords(req *opsdevmodel.OpsOperationEventRecordSearchReq) (total int, list []*opsdevmodel.OpsOperationEventRecord, err error) {
  398. if req.EventId <= 0 {
  399. return 0, nil, myerrors.ValidError("事件ID不能为空")
  400. }
  401. db := s.RecordDao.FieldsEx(s.RecordDao.Columns.DeletedTime).Where(s.RecordDao.Columns.EventId, req.EventId)
  402. total, err = db.Count()
  403. if err != nil {
  404. g.Log().Error(err)
  405. return 0, nil, myerrors.DbError("查询处理记录数量失败")
  406. }
  407. pageNum, pageSize := req.GetPage()
  408. err = db.Page(pageNum, pageSize).Order(s.RecordDao.Columns.CreatedTime + " desc").Scan(&list)
  409. if err != nil {
  410. g.Log().Error(err)
  411. return 0, nil, myerrors.DbError("查询处理记录列表失败")
  412. }
  413. return total, list, nil
  414. }
  415. // UploadAttachment 上传附件
  416. func (s *OperationService) UploadAttachment(req *opsdevmodel.OpsOperationEventAttachmentReq) (attachment *opsdevmodel.OpsOperationEventAttachment, err error) {
  417. if req.EventId <= 0 {
  418. return nil, myerrors.ValidError("事件ID不能为空")
  419. }
  420. if req.FileName == "" {
  421. return nil, myerrors.ValidError("文件名不能为空")
  422. }
  423. if req.FileUrl == "" {
  424. return nil, myerrors.ValidError("文件地址不能为空")
  425. }
  426. event := new(opsdevmodel.OpsOperationEvent)
  427. err = s.Dao.FieldsEx(s.Dao.Columns.DeletedTime).WherePri(s.Dao.Columns.Id, req.EventId).Scan(event)
  428. if err != nil {
  429. g.Log().Error(err)
  430. return nil, myerrors.DbError("查询运维事件失败")
  431. }
  432. if err := s.checkNotClosed(event); err != nil {
  433. return nil, err
  434. }
  435. data := g.Map{
  436. s.AttachmentDao.Columns.EventId: req.EventId,
  437. s.AttachmentDao.Columns.EventRecordId: req.EventRecordId,
  438. s.AttachmentDao.Columns.FileName: req.FileName,
  439. s.AttachmentDao.Columns.FileUrl: req.FileUrl,
  440. s.AttachmentDao.Columns.FileType: req.FileType,
  441. s.AttachmentDao.Columns.Remark: req.Remark,
  442. }
  443. service.SetCreatedInfo(data, s.GetCxtUserId(), s.GetCxtUserName())
  444. _, err = s.AttachmentDao.Data(data).Insert()
  445. if err != nil {
  446. g.Log().Error(err)
  447. return nil, myerrors.DbError("上传附件失败")
  448. }
  449. // 查询刚插入的记录
  450. attachment = new(opsdevmodel.OpsOperationEventAttachment)
  451. err = s.AttachmentDao.Where(s.AttachmentDao.Columns.EventId, req.EventId).
  452. Order(s.AttachmentDao.Columns.Id + " desc").Scan(attachment)
  453. if err != nil {
  454. g.Log().Error(err)
  455. return nil, myerrors.DbError("查询附件失败")
  456. }
  457. return attachment, nil
  458. }
  459. // GetAttachments 获取事件附件列表
  460. func (s *OperationService) GetAttachments(eventId int) (list []*opsdevmodel.OpsOperationEventAttachment, err error) {
  461. if eventId <= 0 {
  462. return nil, myerrors.ValidError("事件ID不能为空")
  463. }
  464. err = s.AttachmentDao.FieldsEx(s.AttachmentDao.Columns.DeletedTime).
  465. Where(s.AttachmentDao.Columns.EventId, eventId).
  466. Order(s.AttachmentDao.Columns.CreatedTime + " desc").Scan(&list)
  467. if err != nil {
  468. g.Log().Error(err)
  469. return nil, myerrors.DbError("查询附件列表失败")
  470. }
  471. return list, nil
  472. }
  473. // GetStats 运维事件统计
  474. func (s *OperationService) GetStats() (result g.Map, err error) {
  475. result = g.Map{}
  476. statusCounts := []struct {
  477. key string
  478. status string
  479. }{
  480. {"pending", opsdevmodel.EventStatusPending},
  481. {"processingKey", opsdevmodel.EventStatusProcessing},
  482. {"processingNormal", opsdevmodel.EventStatusProcessingNormal},
  483. {"transfer", opsdevmodel.EventStatusTransfer},
  484. {"suspended", opsdevmodel.EventStatusSuspended},
  485. {"closed", opsdevmodel.EventStatusClosed},
  486. }
  487. for _, sc := range statusCounts {
  488. count, err := s.Dao.FieldsEx(s.Dao.Columns.DeletedTime).Where(s.Dao.Columns.EventStatus, sc.status).Count()
  489. if err != nil {
  490. g.Log().Error(err)
  491. return nil, myerrors.DbError("查询运维事件统计失败")
  492. }
  493. result[sc.key] = count
  494. }
  495. today := gtime.Now().Format("Y-m-d")
  496. todayNewCount, err := s.Dao.FieldsEx(s.Dao.Columns.DeletedTime).Where(s.Dao.Columns.CreatedTime+" >= ?", today+" 00:00:00").Count()
  497. if err != nil {
  498. g.Log().Error(err)
  499. return nil, myerrors.DbError("查询今日新增数量失败")
  500. }
  501. result["todayNew"] = todayNewCount
  502. return result, nil
  503. }
  504. // generateEventNo 生成事件编号
  505. func generateEventNo() string {
  506. return fmt.Sprintf("OPS%s", gtime.Now().Format("YmdHis"))
  507. }
  508. // GetKanbanData 看板数据
  509. func (s *OperationService) GetKanbanData(req *opsdevmodel.OpsOperationEventKanbanSearchReq) (result g.Map, err error) {
  510. result = g.Map{}
  511. columns := []struct {
  512. Status string
  513. Name string
  514. Key string
  515. }{
  516. {opsdevmodel.EventStatusPending, "待处理", "10"},
  517. {opsdevmodel.EventStatusProcessing, "处理中(重点)", "20"},
  518. {opsdevmodel.EventStatusProcessingNormal, "处理中(普通)", "30"},
  519. {opsdevmodel.EventStatusTransfer, "转研发", "40"},
  520. {opsdevmodel.EventStatusSuspended, "挂起", "70"},
  521. }
  522. for _, col := range columns {
  523. db := s.Dao.FieldsEx(s.Dao.Columns.DeletedTime).Where(s.Dao.Columns.EventStatus, col.Status)
  524. if req.KeyWords != "" {
  525. switch req.SearchType {
  526. case "custName":
  527. db = db.Where(s.Dao.Columns.CustName+" like ?", "%"+req.KeyWords+"%")
  528. case "feedbackReporter":
  529. db = db.Where(s.Dao.Columns.FeedbackReporter+" like ?", "%"+req.KeyWords+"%")
  530. case "eventNo":
  531. db = db.Where(s.Dao.Columns.EventNo+" like ?", "%"+req.KeyWords+"%")
  532. default:
  533. db = db.Where(s.Dao.Columns.EventTitle+" like ?", "%"+req.KeyWords+"%")
  534. }
  535. }
  536. if req.EventType != "" {
  537. db = db.Where(s.Dao.Columns.EventType, req.EventType)
  538. }
  539. if req.PriorityLevel != "" {
  540. db = db.Where(s.Dao.Columns.PriorityLevel, req.PriorityLevel)
  541. }
  542. count, err := db.Count()
  543. if err != nil {
  544. g.Log().Error(err)
  545. return nil, myerrors.DbError("查询看板数据失败")
  546. }
  547. var list []*opsdevmodel.OpsOperationEvent
  548. err = db.Scan(&list)
  549. if err != nil {
  550. g.Log().Error(err)
  551. return nil, myerrors.DbError("查询看板数据失败")
  552. }
  553. result[col.Key] = g.Map{
  554. "status": col.Key,
  555. "name": col.Name,
  556. "count": count,
  557. "list": list,
  558. }
  559. }
  560. return result, nil
  561. }
  562. // AssignOpsUser 接收/分配运维人员
  563. func (s *OperationService) AssignOpsUser(req *opsdevmodel.AssignOpsUserReq) error {
  564. event := new(opsdevmodel.OpsOperationEvent)
  565. err := s.Dao.FieldsEx(s.Dao.Columns.DeletedTime).WherePri(s.Dao.Columns.Id, req.Id).Scan(event)
  566. if err != nil {
  567. g.Log().Error(err)
  568. return myerrors.DbError("查询运维事件失败")
  569. }
  570. if event.Id <= 0 {
  571. return myerrors.TipsError("运维事件不存在")
  572. }
  573. if err := s.checkNotClosed(event); err != nil {
  574. return err
  575. }
  576. if event.EventStatus != opsdevmodel.EventStatusPending {
  577. return myerrors.TipsError("只有待处理状态的事件才能分配运维人员")
  578. }
  579. opsUserId := req.OpsUserId
  580. opsUserName := req.OpsUserName
  581. if opsUserId <= 0 {
  582. opsUserId = s.GetCxtUserId()
  583. }
  584. if opsUserName == "" {
  585. opsUserName = s.GetCxtUserName()
  586. }
  587. _, err = s.Dao.FieldsEx(service.UpdateFieldEx...).WherePri(s.Dao.Columns.Id, req.Id).Data(g.Map{
  588. s.Dao.Columns.EventStatus: opsdevmodel.EventStatusProcessing,
  589. s.Dao.Columns.OpsUserId: opsUserId,
  590. s.Dao.Columns.OpsUserName: opsUserName,
  591. s.Dao.Columns.AssignTime: gtime.Now(),
  592. s.Dao.Columns.UpdatedBy: s.GetCxtUserId(),
  593. s.Dao.Columns.UpdatedName: s.GetCxtUserName(),
  594. s.Dao.Columns.UpdatedTime: gtime.Now(),
  595. }).Update()
  596. if err != nil {
  597. g.Log().Error(err)
  598. return myerrors.DbError("分配运维人员失败")
  599. }
  600. return nil
  601. }
  602. // AddRecord 添加处理记录
  603. func (s *OperationService) AddRecord(req *opsdevmodel.AddRecordReq) error {
  604. if req.EventId <= 0 {
  605. return myerrors.ValidError("事件ID不能为空")
  606. }
  607. event := new(opsdevmodel.OpsOperationEvent)
  608. err := s.Dao.FieldsEx(s.Dao.Columns.DeletedTime).WherePri(s.Dao.Columns.Id, req.EventId).Scan(event)
  609. if err != nil {
  610. g.Log().Error(err)
  611. return myerrors.DbError("查询运维事件失败")
  612. }
  613. if event.Id <= 0 {
  614. return myerrors.TipsError("运维事件不存在")
  615. }
  616. if err := s.checkNotClosed(event); err != nil {
  617. return err
  618. }
  619. data := g.Map{
  620. s.RecordDao.Columns.EventId: req.EventId,
  621. s.RecordDao.Columns.HandleUserId: s.GetCxtUserId(),
  622. s.RecordDao.Columns.HandleUserName: s.GetCxtUserName(),
  623. s.RecordDao.Columns.HandleContent: req.HandleContent,
  624. s.RecordDao.Columns.HandleResult: req.HandleResult,
  625. s.RecordDao.Columns.HandleDate: gtime.Now(),
  626. s.RecordDao.Columns.OperateType: opsdevmodel.OperateTypeProcess,
  627. }
  628. service.SetCreatedInfo(data, s.GetCxtUserId(), s.GetCxtUserName())
  629. _, err = s.RecordDao.Data(data).Insert()
  630. if err != nil {
  631. g.Log().Error(err)
  632. return myerrors.DbError("添加处理记录失败")
  633. }
  634. return nil
  635. }
  636. // DeleteAttachment 删除附件
  637. func (s *OperationService) DeleteAttachment(req *comm_def.IdReq) error {
  638. if req.Id <= 0 {
  639. return myerrors.ValidError("参数有误!")
  640. }
  641. attachment := new(opsdevmodel.OpsOperationEventAttachment)
  642. err := s.AttachmentDao.WherePri(s.AttachmentDao.Columns.Id, req.Id).Scan(attachment)
  643. if err != nil {
  644. g.Log().Error(err)
  645. return myerrors.DbError("查询附件失败")
  646. }
  647. if attachment.Id <= 0 {
  648. return myerrors.TipsError("附件不存在")
  649. }
  650. _, err = s.AttachmentDao.WherePri(s.AttachmentDao.Columns.Id, req.Id).Data(g.Map{
  651. s.AttachmentDao.Columns.DeletedTime: gtime.Now(),
  652. s.AttachmentDao.Columns.UpdatedBy: s.GetCxtUserId(),
  653. s.AttachmentDao.Columns.UpdatedName: s.GetCxtUserName(),
  654. }).Update()
  655. if err != nil {
  656. g.Log().Error(err)
  657. return myerrors.DbError("删除附件失败")
  658. }
  659. return nil
  660. }
  661. // GetHistoryList 运维历史列表(已关闭事件)
  662. func (s *OperationService) GetHistoryList(req *opsdevmodel.OpsOperationEventHistorySearchReq) (total int, list []*opsdevmodel.OpsOperationEvent, err error) {
  663. db := s.Dao.FieldsEx(s.Dao.Columns.DeletedTime).Where(s.Dao.Columns.EventStatus, opsdevmodel.EventStatusClosed)
  664. if req.ScopeType == "my" {
  665. db = db.Where(s.Dao.Columns.OpsUserId, s.GetCxtUserId())
  666. }
  667. if req.EventTitle != "" {
  668. db = db.Where(s.Dao.Columns.EventTitle+" like ?", "%"+req.EventTitle+"%")
  669. }
  670. if req.CustName != "" {
  671. db = db.Where(s.Dao.Columns.CustName+" like ?", "%"+req.CustName+"%")
  672. }
  673. if req.FeedbackReporter != "" {
  674. db = db.Where(s.Dao.Columns.FeedbackReporter+" like ?", "%"+req.FeedbackReporter+"%")
  675. }
  676. if req.OpsUserName != "" {
  677. db = db.Where(s.Dao.Columns.OpsUserName+" like ?", "%"+req.OpsUserName+"%")
  678. }
  679. if req.BeginTime != "" {
  680. db = db.Where(s.Dao.Columns.FeedbackDate+" >= ?", req.BeginTime)
  681. }
  682. if req.EndTime != "" {
  683. db = db.Where(s.Dao.Columns.FeedbackDate+" <= ?", req.EndTime)
  684. }
  685. total, err = db.Count()
  686. if err != nil {
  687. g.Log().Error(err)
  688. return 0, nil, myerrors.DbError("查询运维历史数量失败")
  689. }
  690. pageNum, pageSize := req.GetPage()
  691. err = db.Page(pageNum, pageSize).Order(s.Dao.Columns.CompleteTime + " desc").Scan(&list)
  692. if err != nil {
  693. g.Log().Error(err)
  694. return 0, nil, myerrors.DbError("查询运维历史列表失败")
  695. }
  696. return total, list, nil
  697. }