| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110 |
- package opsdev
- import (
- "context"
- "fmt"
- "regexp"
- "strings"
- "dashoo.cn/common_definition/comm_def"
- "dashoo.cn/opms_libary/myerrors"
- opsdevdao "dashoo.cn/opms_parent/app/dao/opsdev"
- opsdevmodel "dashoo.cn/opms_parent/app/model/opsdev"
- "dashoo.cn/opms_parent/app/service"
- "github.com/gogf/gf/database/gdb"
- "github.com/gogf/gf/frame/g"
- "github.com/gogf/gf/os/gtime"
- "github.com/gogf/gf/util/gconv"
- "github.com/gogf/gf/util/gvalid"
- )
- type OperationService struct {
- *service.ContextService
- Dao *opsdevdao.OpsOperationEventDao
- RecordDao *opsdevdao.OpsOperationEventRecordDao
- AttachmentDao *opsdevdao.OpsOperationEventAttachmentDao
- }
- func NewOperationService(ctx context.Context) (svc *OperationService, err error) {
- svc = new(OperationService)
- if svc.ContextService, err = svc.Init(ctx); err != nil {
- return nil, err
- }
- svc.Dao = opsdevdao.NewOpsOperationEventDao(svc.Tenant)
- svc.RecordDao = opsdevdao.NewOpsOperationEventRecordDao(svc.Tenant)
- svc.AttachmentDao = opsdevdao.NewOpsOperationEventAttachmentDao(svc.Tenant)
- return svc, nil
- }
- // GetList 运维事件列表
- func (s *OperationService) GetList(req *opsdevmodel.OpsOperationEventSearchReq) (total int, list []*opsdevmodel.OpsOperationEvent, err error) {
- db := s.Dao.FieldsEx(s.Dao.Columns.DeletedTime).Where(s.Dao.Columns.EventStatus+" != ?", opsdevmodel.EventStatusClosed)
- if req.EventNo != "" {
- db = db.Where(s.Dao.Columns.EventNo, req.EventNo)
- }
- if req.EventTitle != "" {
- db = db.Where(s.Dao.Columns.EventTitle+" like ?", "%"+req.EventTitle+"%")
- }
- if req.EventStatus != "" {
- db = db.Where(s.Dao.Columns.EventStatus, req.EventStatus)
- }
- if req.EventType != "" {
- db = db.Where(s.Dao.Columns.EventType, req.EventType)
- }
- if req.PriorityLevel != "" {
- db = db.Where(s.Dao.Columns.PriorityLevel, req.PriorityLevel)
- }
- if req.IsBig != "" {
- db = db.Where(s.Dao.Columns.IsBig, req.IsBig)
- }
- if req.IsOps != "" {
- db = db.Where(s.Dao.Columns.IsOps, req.IsOps)
- }
- if req.CustName != "" {
- db = db.Where(s.Dao.Columns.CustName+" like ?", "%"+req.CustName+"%")
- }
- if req.OpsUserName != "" {
- db = db.Where(s.Dao.Columns.OpsUserName+" like ?", "%"+req.OpsUserName+"%")
- }
- if req.ContractName != "" {
- db = db.Where(s.Dao.Columns.ContractName+" like ?", "%"+req.ContractName+"%")
- }
- if req.ProductLine != "" {
- db = db.Where(s.Dao.Columns.ProductLine, req.ProductLine)
- }
- if req.BeginTime != "" {
- db = db.Where(s.Dao.Columns.CreatedTime+" >= ?", req.BeginTime)
- }
- if req.EndTime != "" {
- db = db.Where(s.Dao.Columns.CreatedTime+" <= ?", req.EndTime)
- }
- total, err = db.Count()
- if err != nil {
- g.Log().Error(err)
- return 0, nil, myerrors.DbError("查询运维事件数量失败")
- }
- pageNum, pageSize := req.GetPage()
- err = db.Page(pageNum, pageSize).Order(s.Dao.Columns.CreatedTime + " desc").Scan(&list)
- if err != nil {
- g.Log().Error(err)
- return 0, nil, myerrors.DbError("查询运维事件列表失败")
- }
- return total, list, nil
- }
- // GetEntityById 运维事件详情
- func (s *OperationService) GetEntityById(req *comm_def.IdReq) (detail *opsdevmodel.OpsOperationEvent, err error) {
- if req.Id <= 0 {
- return nil, myerrors.ValidError("参数有误!")
- }
- detail = new(opsdevmodel.OpsOperationEvent)
- err = s.Dao.FieldsEx(s.Dao.Columns.DeletedTime).WherePri(s.Dao.Columns.Id, req.Id).Scan(detail)
- if err != nil {
- g.Log().Error(err)
- return nil, myerrors.DbError("查询运维事件详情失败")
- }
- if detail.Id <= 0 {
- return nil, myerrors.TipsError("运维事件不存在")
- }
- return detail, nil
- }
- // Create 创建运维事件
- func (s *OperationService) Create(req *opsdevmodel.OpsOperationEventReq) (err error) {
- if err = gvalid.CheckStruct(s.Ctx, req, nil); err != nil {
- return myerrors.ValidError(err.Error())
- }
- data := gconv.Map(req)
- service.SetCreatedInfo(data, s.GetCxtUserId(), s.GetCxtUserName())
- data["eventNo"] = generateEventNo()
- data["eventStatus"] = opsdevmodel.EventStatusProcessing
- data["opsUserId"] = s.GetCxtUserId()
- data["opsUserName"] = s.GetCxtUserName()
- if v, ok := data["feedbackDate"]; ok && v == "" {
- data["feedbackDate"] = gtime.Now()
- }
- if v, ok := data["assignTime"]; ok && v == "" {
- data["assignTime"] = gtime.Now()
- }
- delete(data, "completeTime")
- result, err := s.Dao.Data(data).Insert()
- if err != nil {
- g.Log().Error(err)
- return myerrors.DbError("创建运维事件失败")
- }
- id, err := result.LastInsertId()
- if err != nil {
- g.Log().Error(err)
- return nil
- }
- recordData := g.Map{
- s.RecordDao.Columns.EventId: id,
- s.RecordDao.Columns.HandleUserId: s.GetCxtUserId(),
- s.RecordDao.Columns.HandleUserName: s.GetCxtUserName(),
- s.RecordDao.Columns.HandleContent: "创建运维事件",
- s.RecordDao.Columns.HandleResult: opsdevmodel.HandleResultUnresolved,
- s.RecordDao.Columns.HandleDate: gtime.Now(),
- s.RecordDao.Columns.OperateType: opsdevmodel.OperateTypeProcess,
- }
- service.SetCreatedInfo(recordData, s.GetCxtUserId(), s.GetCxtUserName())
- _, err = s.RecordDao.Data(recordData).Insert()
- if err != nil {
- g.Log().Error(err)
- }
- return nil
- }
- // UpdateById 更新运维事件
- func (s *OperationService) UpdateById(req *opsdevmodel.UpdateOpsOperationEventReq) (err error) {
- if err = gvalid.CheckStruct(s.Ctx, req, nil); err != nil {
- return myerrors.ValidError(err.Error())
- }
- event := new(opsdevmodel.OpsOperationEvent)
- err = s.Dao.FieldsEx(s.Dao.Columns.DeletedTime).WherePri(s.Dao.Columns.Id, req.Id).Scan(event)
- if err != nil {
- g.Log().Error(err)
- return myerrors.DbError("查询运维事件失败")
- }
- if event.Id <= 0 {
- return myerrors.TipsError("运维事件不存在")
- }
- if err = s.checkNotClosed(event); err != nil {
- return err
- }
- data := gconv.Map(req.OpsOperationEventReq)
- if v, ok := data["feedbackDate"]; ok && v == "" {
- delete(data, "feedbackDate")
- }
- delete(data, "assignTime")
- delete(data, "completeTime")
- service.SetUpdatedInfo(data, s.GetCxtUserId(), s.GetCxtUserName())
- _, err = s.Dao.FieldsEx(service.UpdateFieldEx...).WherePri(s.Dao.Columns.Id, req.Id).Data(data).Update()
- if err != nil {
- g.Log().Error(err)
- return myerrors.DbError("更新运维事件失败")
- }
- return nil
- }
- // DeleteByIds 批量删除运维事件
- func (s *OperationService) DeleteByIds(req *comm_def.IdsReq) (err error) {
- if len(req.Ids) == 0 {
- return myerrors.ValidError("参数有误!")
- }
- _, err = s.Dao.WherePri(req.Ids).Data(g.Map{
- s.Dao.Columns.DeletedTime: gtime.Now(),
- s.Dao.Columns.UpdatedBy: s.GetCxtUserId(),
- s.Dao.Columns.UpdatedName: s.GetCxtUserName(),
- }).Update()
- if err != nil {
- g.Log().Error(err)
- return myerrors.DbError("删除运维事件失败")
- }
- return nil
- }
- // checkNotClosed 校验事件未关闭,已关闭的事件不允许操作
- func (s *OperationService) checkNotClosed(event *opsdevmodel.OpsOperationEvent) error {
- if event.EventStatus == opsdevmodel.EventStatusClosed {
- return myerrors.TipsError("该事件已关闭,无法进行操作")
- }
- return nil
- }
- // Process 处理运维事件
- func (s *OperationService) Process(ctx context.Context, req *opsdevmodel.OpsOperationEventProcessReq) error {
- if req.Id <= 0 {
- return myerrors.TipsError("任务ID不能为空")
- }
- event := new(opsdevmodel.OpsOperationEvent)
- err := s.Dao.FieldsEx(s.Dao.Columns.DeletedTime).WherePri(s.Dao.Columns.Id, req.Id).Scan(event)
- if err != nil {
- g.Log().Error(err)
- return myerrors.DbError("查询运维事件失败")
- }
- if event.Id <= 0 {
- return myerrors.TipsError("运维事件不存在")
- }
- if err := s.checkNotClosed(event); err != nil {
- return err
- }
- switch req.OperateType {
- case opsdevmodel.OperateTypeProcess:
- return s.processStart(ctx, event, req)
- case opsdevmodel.OperateTypeResume:
- return s.processResume(ctx, event, req)
- case opsdevmodel.OperateTypeTransfer:
- return s.processTransfer(ctx, event, req)
- case opsdevmodel.OperateTypeSuspend:
- return s.processSuspend(ctx, event, req)
- case opsdevmodel.OperateTypeClose:
- return s.processClose(ctx, event, req)
- default:
- return myerrors.TipsError("未知的操作类型")
- }
- }
- func (s *OperationService) processStart(ctx context.Context, event *opsdevmodel.OpsOperationEvent, req *opsdevmodel.OpsOperationEventProcessReq) error {
- if event.EventStatus != opsdevmodel.EventStatusPending {
- return myerrors.TipsError("当前事件状态不能进行此操作")
- }
- return s.Dao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
- _, err := s.Dao.TX(tx).FieldsEx(service.UpdateFieldEx...).WherePri(s.Dao.Columns.Id, event.Id).Data(g.Map{
- s.Dao.Columns.EventStatus: opsdevmodel.EventStatusProcessing,
- s.Dao.Columns.OpsUserId: s.GetCxtUserId(),
- s.Dao.Columns.OpsUserName: s.GetCxtUserName(),
- s.Dao.Columns.AssignTime: gtime.Now(),
- s.Dao.Columns.UpdatedBy: s.GetCxtUserId(),
- s.Dao.Columns.UpdatedName: s.GetCxtUserName(),
- s.Dao.Columns.UpdatedTime: gtime.Now(),
- }).Update()
- if err != nil {
- return err
- }
- recordData := g.Map{
- s.RecordDao.Columns.EventId: event.Id,
- s.RecordDao.Columns.HandleUserId: s.GetCxtUserId(),
- s.RecordDao.Columns.HandleUserName: s.GetCxtUserName(),
- s.RecordDao.Columns.HandleContent: req.HandleContent,
- s.RecordDao.Columns.HandleResult: opsdevmodel.HandleResultUnresolved,
- s.RecordDao.Columns.HandleDate: gtime.Now(),
- s.RecordDao.Columns.OperateType: opsdevmodel.OperateTypeProcess,
- }
- service.SetCreatedInfo(recordData, s.GetCxtUserId(), s.GetCxtUserName())
- _, err = s.RecordDao.TX(tx).Data(recordData).Insert()
- if err != nil {
- return err
- }
- return nil
- })
- }
- func (s *OperationService) processClose(ctx context.Context, event *opsdevmodel.OpsOperationEvent, req *opsdevmodel.OpsOperationEventProcessReq) error {
- if event.EventStatus == opsdevmodel.EventStatusPending {
- return myerrors.TipsError("待处理状态不能直接关闭,请先接收")
- }
- if event.EventStatus == opsdevmodel.EventStatusSuspended {
- return myerrors.TipsError("挂起状态不允许关闭事件,请先转处理")
- }
- return s.Dao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
- _, err := s.Dao.TX(tx).FieldsEx(service.UpdateFieldEx...).WherePri(s.Dao.Columns.Id, event.Id).Data(g.Map{
- s.Dao.Columns.EventStatus: opsdevmodel.EventStatusClosed,
- s.Dao.Columns.CompleteTime: gtime.Now(),
- s.Dao.Columns.CompleteDesc: req.HandleContent,
- s.Dao.Columns.UpdatedBy: s.GetCxtUserId(),
- s.Dao.Columns.UpdatedName: s.GetCxtUserName(),
- s.Dao.Columns.UpdatedTime: gtime.Now(),
- }).Update()
- if err != nil {
- return err
- }
- recordData := g.Map{
- s.RecordDao.Columns.EventId: event.Id,
- s.RecordDao.Columns.HandleUserId: s.GetCxtUserId(),
- s.RecordDao.Columns.HandleUserName: s.GetCxtUserName(),
- s.RecordDao.Columns.HandleContent: req.HandleContent,
- s.RecordDao.Columns.HandleResult: req.HandleResult,
- s.RecordDao.Columns.HandleDate: gtime.Now(),
- s.RecordDao.Columns.OperateType: opsdevmodel.OperateTypeClose,
- }
- service.SetCreatedInfo(recordData, s.GetCxtUserId(), s.GetCxtUserName())
- _, err = s.RecordDao.TX(tx).Data(recordData).Insert()
- if err != nil {
- return err
- }
- return nil
- })
- }
- func (s *OperationService) processTransfer(ctx context.Context, event *opsdevmodel.OpsOperationEvent, req *opsdevmodel.OpsOperationEventProcessReq) error {
- if event.EventStatus != opsdevmodel.EventStatusProcessing && event.EventStatus != opsdevmodel.EventStatusProcessingNormal {
- return myerrors.TipsError("当前事件状态不能转研发")
- }
- return s.Dao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
- _, err := s.Dao.TX(tx).FieldsEx(service.UpdateFieldEx...).WherePri(s.Dao.Columns.Id, event.Id).Data(g.Map{
- s.Dao.Columns.EventStatus: opsdevmodel.EventStatusTransfer,
- s.Dao.Columns.UpdatedBy: s.GetCxtUserId(),
- s.Dao.Columns.UpdatedName: s.GetCxtUserName(),
- s.Dao.Columns.UpdatedTime: gtime.Now(),
- }).Update()
- if err != nil {
- return err
- }
- recordData := g.Map{
- s.RecordDao.Columns.EventId: event.Id,
- s.RecordDao.Columns.HandleUserId: s.GetCxtUserId(),
- s.RecordDao.Columns.HandleUserName: s.GetCxtUserName(),
- s.RecordDao.Columns.HandleContent: req.HandleContent,
- s.RecordDao.Columns.HandleResult: opsdevmodel.HandleResultUnresolved,
- s.RecordDao.Columns.HandleDate: gtime.Now(),
- s.RecordDao.Columns.OperateType: opsdevmodel.OperateTypeTransfer,
- }
- service.SetCreatedInfo(recordData, s.GetCxtUserId(), s.GetCxtUserName())
- _, err = s.RecordDao.TX(tx).Data(recordData).Insert()
- if err != nil {
- return err
- }
- return nil
- })
- }
- func (s *OperationService) processSuspend(ctx context.Context, event *opsdevmodel.OpsOperationEvent, req *opsdevmodel.OpsOperationEventProcessReq) error {
- if event.EventStatus != opsdevmodel.EventStatusProcessing && event.EventStatus != opsdevmodel.EventStatusProcessingNormal && event.EventStatus != opsdevmodel.EventStatusTransfer {
- return myerrors.TipsError("当前事件状态不能挂起")
- }
- return s.Dao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
- _, err := s.Dao.TX(tx).FieldsEx(service.UpdateFieldEx...).WherePri(s.Dao.Columns.Id, event.Id).Data(g.Map{
- s.Dao.Columns.EventStatus: opsdevmodel.EventStatusSuspended,
- s.Dao.Columns.UpdatedBy: s.GetCxtUserId(),
- s.Dao.Columns.UpdatedName: s.GetCxtUserName(),
- s.Dao.Columns.UpdatedTime: gtime.Now(),
- }).Update()
- if err != nil {
- return err
- }
- recordData := g.Map{
- s.RecordDao.Columns.EventId: event.Id,
- s.RecordDao.Columns.HandleUserId: s.GetCxtUserId(),
- s.RecordDao.Columns.HandleUserName: s.GetCxtUserName(),
- s.RecordDao.Columns.HandleContent: req.HandleContent,
- s.RecordDao.Columns.HandleResult: opsdevmodel.HandleResultUnresolved,
- s.RecordDao.Columns.HandleDate: gtime.Now(),
- s.RecordDao.Columns.OperateType: opsdevmodel.OperateTypeSuspend,
- }
- service.SetCreatedInfo(recordData, s.GetCxtUserId(), s.GetCxtUserName())
- _, err = s.RecordDao.TX(tx).Data(recordData).Insert()
- if err != nil {
- return err
- }
- return nil
- })
- }
- func (s *OperationService) processResume(ctx context.Context, event *opsdevmodel.OpsOperationEvent, req *opsdevmodel.OpsOperationEventProcessReq) error {
- if event.EventStatus != opsdevmodel.EventStatusSuspended {
- return myerrors.TipsError("当前事件状态不能转处理")
- }
- return s.Dao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
- _, err := s.Dao.TX(tx).FieldsEx(service.UpdateFieldEx...).WherePri(s.Dao.Columns.Id, event.Id).Data(g.Map{
- s.Dao.Columns.EventStatus: opsdevmodel.EventStatusProcessing,
- s.Dao.Columns.UpdatedBy: s.GetCxtUserId(),
- s.Dao.Columns.UpdatedName: s.GetCxtUserName(),
- s.Dao.Columns.UpdatedTime: gtime.Now(),
- }).Update()
- if err != nil {
- return err
- }
- recordData := g.Map{
- s.RecordDao.Columns.EventId: event.Id,
- s.RecordDao.Columns.HandleUserId: s.GetCxtUserId(),
- s.RecordDao.Columns.HandleUserName: s.GetCxtUserName(),
- s.RecordDao.Columns.HandleContent: req.HandleContent,
- s.RecordDao.Columns.HandleResult: opsdevmodel.HandleResultUnresolved,
- s.RecordDao.Columns.HandleDate: gtime.Now(),
- s.RecordDao.Columns.OperateType: opsdevmodel.OperateTypeResume,
- }
- service.SetCreatedInfo(recordData, s.GetCxtUserId(), s.GetCxtUserName())
- _, err = s.RecordDao.TX(tx).Data(recordData).Insert()
- if err != nil {
- return err
- }
- return nil
- })
- }
- // GetRecords 获取运维事件处理记录
- func (s *OperationService) GetRecords(req *opsdevmodel.OpsOperationEventRecordSearchReq) (total int, list []*opsdevmodel.OpsOperationEventRecord, err error) {
- if req.EventId <= 0 {
- return 0, nil, myerrors.ValidError("事件ID不能为空")
- }
- db := s.RecordDao.FieldsEx(s.RecordDao.Columns.DeletedTime).Where(s.RecordDao.Columns.EventId, req.EventId)
- total, err = db.Count()
- if err != nil {
- g.Log().Error(err)
- return 0, nil, myerrors.DbError("查询处理记录数量失败")
- }
- pageNum, pageSize := req.GetPage()
- err = db.Page(pageNum, pageSize).Order(s.RecordDao.Columns.CreatedTime + " desc").Scan(&list)
- if err != nil {
- g.Log().Error(err)
- return 0, nil, myerrors.DbError("查询处理记录列表失败")
- }
- return total, list, nil
- }
- // UploadAttachment 上传附件
- func (s *OperationService) UploadAttachment(req *opsdevmodel.OpsOperationEventAttachmentReq) (attachment *opsdevmodel.OpsOperationEventAttachment, err error) {
- if req.EventId <= 0 {
- return nil, myerrors.ValidError("事件ID不能为空")
- }
- if req.FileName == "" {
- return nil, myerrors.ValidError("文件名不能为空")
- }
- if req.FileUrl == "" {
- return nil, myerrors.ValidError("文件地址不能为空")
- }
- event := new(opsdevmodel.OpsOperationEvent)
- err = s.Dao.FieldsEx(s.Dao.Columns.DeletedTime).WherePri(s.Dao.Columns.Id, req.EventId).Scan(event)
- if err != nil {
- g.Log().Error(err)
- return nil, myerrors.DbError("查询运维事件失败")
- }
- if err := s.checkNotClosed(event); err != nil {
- return nil, err
- }
- data := g.Map{
- s.AttachmentDao.Columns.EventId: req.EventId,
- s.AttachmentDao.Columns.EventRecordId: req.EventRecordId,
- s.AttachmentDao.Columns.FileName: req.FileName,
- s.AttachmentDao.Columns.FileUrl: req.FileUrl,
- s.AttachmentDao.Columns.FileType: req.FileType,
- s.AttachmentDao.Columns.Remark: req.Remark,
- }
- service.SetCreatedInfo(data, s.GetCxtUserId(), s.GetCxtUserName())
- _, err = s.AttachmentDao.Data(data).Insert()
- if err != nil {
- g.Log().Error(err)
- return nil, myerrors.DbError("上传附件失败")
- }
- // 查询刚插入的记录
- attachment = new(opsdevmodel.OpsOperationEventAttachment)
- err = s.AttachmentDao.Where(s.AttachmentDao.Columns.EventId, req.EventId).
- Order(s.AttachmentDao.Columns.Id + " desc").Scan(attachment)
- if err != nil {
- g.Log().Error(err)
- return nil, myerrors.DbError("查询附件失败")
- }
- return attachment, nil
- }
- // GetAttachments 获取事件附件列表
- func (s *OperationService) GetAttachments(eventId int) (list []*opsdevmodel.OpsOperationEventAttachment, err error) {
- if eventId <= 0 {
- return nil, myerrors.ValidError("事件ID不能为空")
- }
- err = s.AttachmentDao.FieldsEx(s.AttachmentDao.Columns.DeletedTime).
- Where(s.AttachmentDao.Columns.EventId, eventId).
- Order(s.AttachmentDao.Columns.CreatedTime + " desc").Scan(&list)
- if err != nil {
- g.Log().Error(err)
- return nil, myerrors.DbError("查询附件列表失败")
- }
- return list, nil
- }
- // GetStats 运维事件统计
- func (s *OperationService) GetStats() (result g.Map, err error) {
- result = g.Map{}
- statusCounts := []struct {
- key string
- status string
- }{
- {"pending", opsdevmodel.EventStatusPending},
- {"processingKey", opsdevmodel.EventStatusProcessing},
- {"processingNormal", opsdevmodel.EventStatusProcessingNormal},
- {"transfer", opsdevmodel.EventStatusTransfer},
- {"suspended", opsdevmodel.EventStatusSuspended},
- {"closed", opsdevmodel.EventStatusClosed},
- }
- for _, sc := range statusCounts {
- count, err := s.Dao.FieldsEx(s.Dao.Columns.DeletedTime).Where(s.Dao.Columns.EventStatus, sc.status).Count()
- if err != nil {
- g.Log().Error(err)
- return nil, myerrors.DbError("查询运维事件统计失败")
- }
- result[sc.key] = count
- }
- today := gtime.Now().Format("Y-m-d")
- todayNewCount, err := s.Dao.FieldsEx(s.Dao.Columns.DeletedTime).Where(s.Dao.Columns.CreatedTime+" >= ?", today+" 00:00:00").Count()
- if err != nil {
- g.Log().Error(err)
- return nil, myerrors.DbError("查询今日新增数量失败")
- }
- result["todayNew"] = todayNewCount
- return result, nil
- }
- // generateEventNo 生成事件编号
- func generateEventNo() string {
- return fmt.Sprintf("OPS%s", gtime.Now().Format("YmdHis"))
- }
- // GetKanbanData 看板数据
- func (s *OperationService) GetKanbanData(req *opsdevmodel.OpsOperationEventKanbanSearchReq) (result g.Map, err error) {
- result = g.Map{}
- columns := []struct {
- Status string
- Name string
- Key string
- }{
- {opsdevmodel.EventStatusPending, "待处理", "10"},
- {opsdevmodel.EventStatusProcessing, "处理中(重点)", "20"},
- {opsdevmodel.EventStatusProcessingNormal, "处理中(普通)", "30"},
- {opsdevmodel.EventStatusTransfer, "转研发", "40"},
- {opsdevmodel.EventStatusSuspended, "挂起", "70"},
- }
- for _, col := range columns {
- db := s.Dao.FieldsEx(s.Dao.Columns.DeletedTime).Where(s.Dao.Columns.EventStatus, col.Status)
- if req.KeyWords != "" {
- switch req.SearchType {
- case "custName":
- db = db.Where(s.Dao.Columns.CustName+" like ?", "%"+req.KeyWords+"%")
- case "feedbackReporter":
- db = db.Where(s.Dao.Columns.FeedbackReporter+" like ?", "%"+req.KeyWords+"%")
- case "eventNo":
- db = db.Where(s.Dao.Columns.EventNo+" like ?", "%"+req.KeyWords+"%")
- default:
- db = db.Where(s.Dao.Columns.EventTitle+" like ?", "%"+req.KeyWords+"%")
- }
- }
- if req.EventType != "" {
- db = db.Where(s.Dao.Columns.EventType, req.EventType)
- }
- if req.PriorityLevel != "" {
- db = db.Where(s.Dao.Columns.PriorityLevel, req.PriorityLevel)
- }
- count, err := db.Count()
- if err != nil {
- g.Log().Error(err)
- return nil, myerrors.DbError("查询看板数据失败")
- }
- var list []*opsdevmodel.OpsOperationEvent
- err = db.Scan(&list)
- if err != nil {
- g.Log().Error(err)
- return nil, myerrors.DbError("查询看板数据失败")
- }
- result[col.Key] = g.Map{
- "status": col.Key,
- "name": col.Name,
- "count": count,
- "list": list,
- }
- }
- return result, nil
- }
- // AssignOpsUser 接收/分配运维人员
- func (s *OperationService) AssignOpsUser(req *opsdevmodel.AssignOpsUserReq) error {
- event := new(opsdevmodel.OpsOperationEvent)
- err := s.Dao.FieldsEx(s.Dao.Columns.DeletedTime).WherePri(s.Dao.Columns.Id, req.Id).Scan(event)
- if err != nil {
- g.Log().Error(err)
- return myerrors.DbError("查询运维事件失败")
- }
- if event.Id <= 0 {
- return myerrors.TipsError("运维事件不存在")
- }
- if err := s.checkNotClosed(event); err != nil {
- return err
- }
- if event.EventStatus != opsdevmodel.EventStatusPending {
- return myerrors.TipsError("只有待处理状态的事件才能分配运维人员")
- }
- opsUserId := req.OpsUserId
- opsUserName := req.OpsUserName
- if opsUserId <= 0 {
- opsUserId = s.GetCxtUserId()
- }
- if opsUserName == "" {
- opsUserName = s.GetCxtUserName()
- }
- _, err = s.Dao.FieldsEx(service.UpdateFieldEx...).WherePri(s.Dao.Columns.Id, req.Id).Data(g.Map{
- s.Dao.Columns.EventStatus: opsdevmodel.EventStatusProcessing,
- s.Dao.Columns.OpsUserId: opsUserId,
- s.Dao.Columns.OpsUserName: opsUserName,
- s.Dao.Columns.AssignTime: gtime.Now(),
- s.Dao.Columns.UpdatedBy: s.GetCxtUserId(),
- s.Dao.Columns.UpdatedName: s.GetCxtUserName(),
- s.Dao.Columns.UpdatedTime: gtime.Now(),
- }).Update()
- if err != nil {
- g.Log().Error(err)
- return myerrors.DbError("分配运维人员失败")
- }
- return nil
- }
- // AddRecord 添加处理记录
- func (s *OperationService) AddRecord(req *opsdevmodel.AddRecordReq) error {
- if req.EventId <= 0 {
- return myerrors.ValidError("事件ID不能为空")
- }
- event := new(opsdevmodel.OpsOperationEvent)
- err := s.Dao.FieldsEx(s.Dao.Columns.DeletedTime).WherePri(s.Dao.Columns.Id, req.EventId).Scan(event)
- if err != nil {
- g.Log().Error(err)
- return myerrors.DbError("查询运维事件失败")
- }
- if event.Id <= 0 {
- return myerrors.TipsError("运维事件不存在")
- }
- if err := s.checkNotClosed(event); err != nil {
- return err
- }
- data := g.Map{
- s.RecordDao.Columns.EventId: req.EventId,
- s.RecordDao.Columns.HandleUserId: s.GetCxtUserId(),
- s.RecordDao.Columns.HandleUserName: s.GetCxtUserName(),
- s.RecordDao.Columns.HandleContent: req.HandleContent,
- s.RecordDao.Columns.HandleResult: req.HandleResult,
- s.RecordDao.Columns.HandleDate: gtime.Now(),
- s.RecordDao.Columns.OperateType: opsdevmodel.OperateTypeProcess,
- }
- service.SetCreatedInfo(data, s.GetCxtUserId(), s.GetCxtUserName())
- _, err = s.RecordDao.Data(data).Insert()
- if err != nil {
- g.Log().Error(err)
- return myerrors.DbError("添加处理记录失败")
- }
- return nil
- }
- // DeleteAttachment 删除附件
- func (s *OperationService) DeleteAttachment(req *comm_def.IdReq) error {
- if req.Id <= 0 {
- return myerrors.ValidError("参数有误!")
- }
- attachment := new(opsdevmodel.OpsOperationEventAttachment)
- err := s.AttachmentDao.WherePri(s.AttachmentDao.Columns.Id, req.Id).Scan(attachment)
- if err != nil {
- g.Log().Error(err)
- return myerrors.DbError("查询附件失败")
- }
- if attachment.Id <= 0 {
- return myerrors.TipsError("附件不存在")
- }
- _, err = s.AttachmentDao.WherePri(s.AttachmentDao.Columns.Id, req.Id).Data(g.Map{
- s.AttachmentDao.Columns.DeletedTime: gtime.Now(),
- s.AttachmentDao.Columns.UpdatedBy: s.GetCxtUserId(),
- s.AttachmentDao.Columns.UpdatedName: s.GetCxtUserName(),
- }).Update()
- if err != nil {
- g.Log().Error(err)
- return myerrors.DbError("删除附件失败")
- }
- return nil
- }
- // GetHistoryList 运维历史列表
- func (s *OperationService) GetHistoryList(req *opsdevmodel.OpsOperationEventHistorySearchReq) (total int, list []*opsdevmodel.OpsOperationEvent, err error) {
- db := s.Dao.FieldsEx(s.Dao.Columns.DeletedTime)
- if !req.IncludeClosed {
- db = db.Where(s.Dao.Columns.EventStatus, opsdevmodel.EventStatusClosed)
- }
- if req.ScopeType == "my" {
- db = db.Where(s.Dao.Columns.OpsUserId, s.GetCxtUserId())
- }
- if req.EventTitle != "" {
- db = db.Where(s.Dao.Columns.EventTitle+" like ?", "%"+req.EventTitle+"%")
- }
- if req.CustName != "" {
- db = db.Where(s.Dao.Columns.CustName+" like ?", "%"+req.CustName+"%")
- }
- if req.FeedbackReporter != "" {
- db = db.Where(s.Dao.Columns.FeedbackReporter+" like ?", "%"+req.FeedbackReporter+"%")
- }
- if req.OpsUserName != "" {
- db = db.Where(s.Dao.Columns.OpsUserName+" like ?", "%"+req.OpsUserName+"%")
- }
- if req.BeginTime != "" {
- db = db.Where(s.Dao.Columns.FeedbackDate+" >= ?", req.BeginTime)
- }
- if req.EndTime != "" {
- db = db.Where(s.Dao.Columns.FeedbackDate+" <= ?", req.EndTime)
- }
- total, err = db.Count()
- if err != nil {
- g.Log().Error(err)
- return 0, nil, myerrors.DbError("查询运维历史数量失败")
- }
- pageNum, pageSize := req.GetPage()
- err = db.Page(pageNum, pageSize).Order(s.Dao.Columns.CompleteTime + " desc").Scan(&list)
- if err != nil {
- g.Log().Error(err)
- return 0, nil, myerrors.DbError("查询运维历史列表失败")
- }
- return total, list, nil
- }
- // Export 导出运维历史
- func (s *OperationService) Export(ctx context.Context, req *opsdevmodel.OpsOperationEventHistoryExport) (content *opsdevmodel.OpsOperationEventHistoryExportContent, err error) {
- db := s.Dao.FieldsEx(s.Dao.Columns.DeletedTime)
- if !req.IncludeClosed {
- db = db.Where(s.Dao.Columns.EventStatus, opsdevmodel.EventStatusClosed)
- }
- if req.ScopeType == "my" {
- db = db.Where(s.Dao.Columns.OpsUserId, s.GetCxtUserId())
- }
- if req.EventTitle != "" {
- db = db.Where(s.Dao.Columns.EventTitle+" like ?", "%"+req.EventTitle+"%")
- }
- if req.CustName != "" {
- db = db.Where(s.Dao.Columns.CustName+" like ?", "%"+req.CustName+"%")
- }
- if req.FeedbackReporter != "" {
- db = db.Where(s.Dao.Columns.FeedbackReporter+" like ?", "%"+req.FeedbackReporter+"%")
- }
- if req.OpsUserName != "" {
- db = db.Where(s.Dao.Columns.OpsUserName+" like ?", "%"+req.OpsUserName+"%")
- }
- if req.BeginTime != "" {
- db = db.Where(s.Dao.Columns.FeedbackDate+" >= ?", req.BeginTime)
- }
- if req.EndTime != "" {
- db = db.Where(s.Dao.Columns.FeedbackDate+" <= ?", req.EndTime)
- }
- var list []*opsdevmodel.OpsOperationEvent
- err = db.Order(s.Dao.Columns.CompleteTime + " desc").Scan(&list)
- if err != nil {
- g.Log().Error(err)
- return nil, myerrors.DbError("查询运维历史失败")
- }
- // 获取所有事件ID
- var eventIds []int
- for _, item := range list {
- eventIds = append(eventIds, item.Id)
- }
- // 获取所有事件的处理记录
- var records []*opsdevmodel.OpsOperationEventRecord
- if len(eventIds) > 0 {
- err = s.RecordDao.WhereIn(s.RecordDao.Columns.EventId, eventIds).Order(s.RecordDao.Columns.HandleDate + " desc").Scan(&records)
- if err != nil {
- g.Log().Error(err)
- return nil, myerrors.DbError("查询处理记录失败")
- }
- }
- // 构建记录Map
- recordMap := make(map[int][]*opsdevmodel.OpsOperationEventRecord)
- for _, record := range records {
- recordMap[record.EventId] = append(recordMap[record.EventId], record)
- }
- // 构建状态Map
- statusMap := map[string]string{
- opsdevmodel.EventStatusPending: "待处理",
- opsdevmodel.EventStatusProcessing: "处理中(重点)",
- opsdevmodel.EventStatusProcessingNormal: "处理中(普通)",
- opsdevmodel.EventStatusTransfer: "转研发",
- opsdevmodel.EventStatusSuspended: "挂起",
- opsdevmodel.EventStatusClosed: "已关闭",
- }
- // 构建操作类型Map
- operateTypeMap := map[string]string{
- opsdevmodel.OperateTypeProcess: "处理",
- opsdevmodel.OperateTypeResume: "转处理",
- opsdevmodel.OperateTypeTransfer: "转研发",
- opsdevmodel.OperateTypeSuspend: "挂起",
- opsdevmodel.OperateTypeClose: "关闭",
- }
- // 构建处理结果Map
- handleResultMap := map[string]string{
- opsdevmodel.HandleResultResolved: "已解决",
- opsdevmodel.HandleResultPartially: "部分解决",
- opsdevmodel.HandleResultUnresolved: "未解决",
- }
- // 构建导出数据
- exportDataList := make([]map[string]interface{}, 0)
- for _, item := range list {
- // 构建处理过程
- processBuilder := ""
- if itemRecords, ok := recordMap[item.Id]; ok && len(itemRecords) > 0 {
- for i, record := range itemRecords {
- // 处理时间(仅年月)
- handleDate := ""
- if record.HandleDate != nil {
- handleDate = record.HandleDate.Format("Y-m-d H:i:s")
- }
- // 操作类型描述
- operateTypeStr := operateTypeMap[record.OperateType]
- if operateTypeStr == "" {
- operateTypeStr = record.OperateType
- }
- // 处理结果描述
- handleResultStr := handleResultMap[record.HandleResult]
- if handleResultStr == "" {
- handleResultStr = record.HandleResult
- }
- // 清理处理内容中的HTML标签
- cleanContent := cleanHtmlTags(record.HandleContent)
- recordStr := fmt.Sprintf("%s-%s-%s-%s-%s", handleDate, record.HandleUserName, operateTypeStr, handleResultStr, cleanContent)
- if i > 0 {
- processBuilder += "\n" + recordStr
- } else {
- processBuilder = recordStr
- }
- }
- }
- closedTime := ""
- if item.CompleteTime != nil {
- closedTime = item.CompleteTime.Format("Y-m-d")
- }
- feedbackDate := ""
- if item.FeedbackDate != nil {
- feedbackDate = item.FeedbackDate.Format("Y-m-d")
- }
- exportData := map[string]interface{}{
- "eventNo": item.EventNo,
- "eventTitle": item.EventTitle,
- "eventStatus": statusMap[item.EventStatus],
- "eventType": item.EventType,
- "custName": item.CustName,
- "opsUserName": item.OpsUserName,
- "feedbackDate": feedbackDate,
- "priorityLevel": item.PriorityLevel,
- "handleProcess": processBuilder,
- "closedTime": closedTime,
- }
- exportDataList = append(exportDataList, exportData)
- }
- // 调用公共导出方法
- exportContent := new(opsdevmodel.OpsOperationEventHistoryExportContent)
- contentBase64, err := service.CommonExportExcel(ctx, "运维历史", opsdevmodel.OpsOperationEventHistoryExportData{}, exportDataList)
- if err != nil {
- g.Log().Error(err)
- return nil, myerrors.DbError("导出运维历史失败")
- }
- exportContent.Content = contentBase64
- return exportContent, nil
- }
- func (s *OperationService) ExportNonClosed(ctx context.Context, req *opsdevmodel.OpsOperationEventExport) (content *opsdevmodel.OpsOperationEventHistoryExportContent, err error) {
- db := s.Dao.FieldsEx(s.Dao.Columns.DeletedTime).Where(s.Dao.Columns.EventStatus+" != ?", opsdevmodel.EventStatusClosed)
- var list []*opsdevmodel.OpsOperationEvent
- err = db.Order(s.Dao.Columns.FeedbackDate + " desc").Scan(&list)
- if err != nil {
- g.Log().Error(err)
- return nil, myerrors.DbError("查询运维事件失败")
- }
- var eventIds []int
- for _, item := range list {
- eventIds = append(eventIds, item.Id)
- }
- var records []*opsdevmodel.OpsOperationEventRecord
- if len(eventIds) > 0 {
- err = s.RecordDao.WhereIn(s.RecordDao.Columns.EventId, eventIds).Order(s.RecordDao.Columns.HandleDate + " desc").Scan(&records)
- if err != nil {
- g.Log().Error(err)
- return nil, myerrors.DbError("查询处理记录失败")
- }
- }
- recordMap := make(map[int][]*opsdevmodel.OpsOperationEventRecord)
- for _, record := range records {
- recordMap[record.EventId] = append(recordMap[record.EventId], record)
- }
- statusMap := map[string]string{
- opsdevmodel.EventStatusPending: "待处理",
- opsdevmodel.EventStatusProcessing: "处理中(重点)",
- opsdevmodel.EventStatusProcessingNormal: "处理中(普通)",
- opsdevmodel.EventStatusTransfer: "转研发",
- opsdevmodel.EventStatusSuspended: "挂起",
- opsdevmodel.EventStatusClosed: "已关闭",
- }
- operateTypeMap := map[string]string{
- opsdevmodel.OperateTypeProcess: "处理",
- opsdevmodel.OperateTypeResume: "转处理",
- opsdevmodel.OperateTypeTransfer: "转研发",
- opsdevmodel.OperateTypeSuspend: "挂起",
- opsdevmodel.OperateTypeClose: "关闭",
- }
- handleResultMap := map[string]string{
- opsdevmodel.HandleResultResolved: "已解决",
- opsdevmodel.HandleResultPartially: "部分解决",
- opsdevmodel.HandleResultUnresolved: "未解决",
- }
- exportDataList := make([]map[string]interface{}, 0)
- for _, item := range list {
- processBuilder := ""
- if itemRecords, ok := recordMap[item.Id]; ok && len(itemRecords) > 0 {
- for i, record := range itemRecords {
- handleDate := ""
- if record.HandleDate != nil {
- handleDate = record.HandleDate.Format("Y-m-d H:i:s")
- }
- operateTypeStr := operateTypeMap[record.OperateType]
- if operateTypeStr == "" {
- operateTypeStr = record.OperateType
- }
- handleResultStr := handleResultMap[record.HandleResult]
- if handleResultStr == "" {
- handleResultStr = record.HandleResult
- }
- cleanContent := cleanHtmlTags(record.HandleContent)
- recordStr := fmt.Sprintf("%s-%s-%s-%s-%s", handleDate, record.HandleUserName, operateTypeStr, handleResultStr, cleanContent)
- if i > 0 {
- processBuilder += "\n" + recordStr
- } else {
- processBuilder = recordStr
- }
- }
- }
- feedbackDate := ""
- if item.FeedbackDate != nil {
- feedbackDate = item.FeedbackDate.Format("Y-m-d")
- }
- exportData := map[string]interface{}{
- "eventNo": item.EventNo,
- "eventTitle": item.EventTitle,
- "eventStatus": statusMap[item.EventStatus],
- "eventType": item.EventType,
- "custName": item.CustName,
- "opsUserName": item.OpsUserName,
- "feedbackDate": feedbackDate,
- "priorityLevel": item.PriorityLevel,
- "handleProcess": processBuilder,
- }
- exportDataList = append(exportDataList, exportData)
- }
- exportContent := new(opsdevmodel.OpsOperationEventHistoryExportContent)
- contentBase64, err := service.CommonExportExcel(ctx, "运维事件", opsdevmodel.OpsOperationEventExportData{}, exportDataList)
- if err != nil {
- g.Log().Error(err)
- return nil, myerrors.DbError("导出运维事件失败")
- }
- exportContent.Content = contentBase64
- return exportContent, nil
- }
- func cleanHtmlTags(content string) string {
- if content == "" {
- return ""
- }
- imgPattern := regexp.MustCompile(`src=["']([^"']+)["']`)
- imgMatches := imgPattern.FindAllStringSubmatch(content, -1)
- seen := make(map[string]bool)
- var imgUrls []string
- for _, match := range imgMatches {
- if len(match) > 1 && !seen[match[1]] {
- seen[match[1]] = true
- imgUrls = append(imgUrls, match[1])
- }
- }
- htmlTagPattern := regexp.MustCompile(`<[^>]*>`)
- result := htmlTagPattern.ReplaceAllString(content, "")
- result = strings.ReplaceAll(result, " ", " ")
- result = strings.ReplaceAll(result, "&", "&")
- result = strings.ReplaceAll(result, "<", "<")
- result = strings.ReplaceAll(result, ">", ">")
- result = strings.ReplaceAll(result, """, "\"")
- result = strings.ReplaceAll(result, "'", "'")
- result = strings.TrimSpace(result)
- if len(imgUrls) > 0 {
- result += "\n图片: "
- for i, url := range imgUrls {
- if i > 0 {
- result += ", "
- }
- result += url
- }
- }
- return result
- }
|