// Package notice 通知模块控制器(绑定 admin 受权限保护组)。 package notice import ( "context" noticev1 "service.xpcool.com/api/notice" "service.xpcool.com/internal/model/dto" "service.xpcool.com/internal/service/notice" ) // Controller 实现通知模块端点。 type Controller struct{} // New 创建通知控制器。 func New() *Controller { return &Controller{} } // ChannelList 通知渠道列表。 func (c *Controller) ChannelList(ctx context.Context, req *noticev1.NoticeChannelListReq) (res *noticev1.NoticeChannelListRes, err error) { list, err := notice.Notice().ChannelList(ctx) if err != nil { return nil, err } out := make([]*noticev1.NoticeChannelItem, 0, len(list)) for i := range list { v := &list[i] out = append(out, ¬icev1.NoticeChannelItem{Id: v.Id, Code: v.Code, Name: v.Name, Enabled: v.Enabled, Config: v.Config, Remark: v.Remark}) } return ¬icev1.NoticeChannelListRes{List: out}, nil } // ChannelSave 保存通知渠道。 func (c *Controller) ChannelSave(ctx context.Context, req *noticev1.NoticeChannelSaveReq) (res *noticev1.NoticeChannelSaveRes, err error) { id, err := notice.Notice().ChannelSave(ctx, dto.NoticeChannelInput{ Id: req.Id, Code: req.Code, Name: req.Name, Enabled: req.Enabled, Config: req.Config, Remark: req.Remark, }) if err != nil { return nil, err } return ¬icev1.NoticeChannelSaveRes{Id: id}, nil } // RuleList 通知规则列表。 func (c *Controller) RuleList(ctx context.Context, req *noticev1.NoticeRuleListReq) (res *noticev1.NoticeRuleListRes, err error) { list, err := notice.Notice().RuleList(ctx, req.EventType) if err != nil { return nil, err } out := make([]*noticev1.NoticeRuleItem, 0, len(list)) for i := range list { v := &list[i] out = append(out, ¬icev1.NoticeRuleItem{ Id: v.Id, Name: v.Name, EventType: v.EventType, ChannelCodes: v.ChannelCodes, UserIds: v.UserIds, TitleTemplate: v.TitleTemplate, BodyTemplate: v.BodyTemplate, Enabled: v.Enabled, }) } return ¬icev1.NoticeRuleListRes{List: out}, nil } // RuleSave 保存通知规则。 func (c *Controller) RuleSave(ctx context.Context, req *noticev1.NoticeRuleSaveReq) (res *noticev1.NoticeRuleSaveRes, err error) { id, err := notice.Notice().RuleSave(ctx, dto.NoticeRuleInput{ Id: req.Id, Name: req.Name, EventType: req.EventType, ChannelCodes: req.ChannelCodes, UserIds: req.UserIds, TitleTemplate: req.TitleTemplate, BodyTemplate: req.BodyTemplate, Enabled: req.Enabled, }) if err != nil { return nil, err } return ¬icev1.NoticeRuleSaveRes{Id: id}, nil } // RuleDelete 删除通知规则。 func (c *Controller) RuleDelete(ctx context.Context, req *noticev1.NoticeRuleDeleteReq) (res *noticev1.NoticeRuleDeleteRes, err error) { if err = notice.Notice().RuleDelete(ctx, req.Id); err != nil { return nil, err } return ¬icev1.NoticeRuleDeleteRes{}, nil } // LogList 通知历史记录分页(含统计概览)。 func (c *Controller) LogList(ctx context.Context, req *noticev1.NoticeLogListReq) (res *noticev1.NoticeLogListRes, err error) { list, total, stats, err := notice.Notice().LogList(ctx, dto.NoticeLogFilter{ Page: req.Page, Size: req.Size, Keyword: req.Keyword, NoticeType: req.NoticeType, Group: req.Group, EventType: req.EventType, ChannelCode: req.ChannelCode, UserId: req.UserId, BatchId: req.BatchId, Status: req.Status, Result: req.Result, DateFrom: req.DateFrom, DateTo: req.DateTo, OrderBy: req.OrderBy, OrderDir: req.OrderDir, }) if err != nil { return nil, err } out := make([]*noticev1.NoticeLogItem, 0, len(list)) for i := range list { out = append(out, toLogItem(&list[i])) } res = ¬icev1.NoticeLogListRes{List: out, Total: total} if stats != nil { res.Stats = ¬icev1.NoticeLogStatsItem{ Total: stats.Total, Success: stats.Success, Failed: stats.Failed, SuccessRate: stats.SuccessRate, } } return res, nil } // LogDetail 通知历史记录详情。 func (c *Controller) LogDetail(ctx context.Context, req *noticev1.NoticeLogDetailReq) (res *noticev1.NoticeLogDetailRes, err error) { vo, err := notice.Notice().LogDetail(ctx, req.Id) if err != nil { return nil, err } return ¬icev1.NoticeLogDetailRes{Item: toLogItem(vo)}, nil } // LogDelete 删除通知历史记录(支持批量)。 func (c *Controller) LogDelete(ctx context.Context, req *noticev1.NoticeLogDeleteReq) (res *noticev1.NoticeLogDeleteRes, err error) { n, err := notice.Notice().LogDelete(ctx, req.Ids) if err != nil { return nil, err } return ¬icev1.NoticeLogDeleteRes{Deleted: n}, nil } // LogClear 清空通知历史记录。 func (c *Controller) LogClear(ctx context.Context, req *noticev1.NoticeLogClearReq) (res *noticev1.NoticeLogClearRes, err error) { n, err := notice.Notice().LogClear(ctx, req.KeepDays, req.DateFrom, req.DateTo) if err != nil { return nil, err } return ¬icev1.NoticeLogClearRes{Deleted: n}, nil } // MetaOptions 通知字典选项(渠道/事件/类型/分组)。 func (c *Controller) MetaOptions(ctx context.Context, req *noticev1.NoticeMetaOptionsReq) (res *noticev1.NoticeMetaOptionsRes, err error) { return ¬icev1.NoticeMetaOptionsRes{ Channels: toMetaItems(dto.NoticeChannelOptions()), Events: toMetaItems(dto.NoticeEventOptions()), Types: toMetaItems(dto.NoticeTypeOptions()), Groups: toMetaItems(dto.NoticeGroupOptions()), }, nil } // Test 测试通知发送。 func (c *Controller) Test(ctx context.Context, req *noticev1.NoticeTestReq) (res *noticev1.NoticeTestRes, err error) { ok, msg, err := notice.Notice().Test(ctx, req.RuleId, req.ChannelCode, req.Target, req.UserIds, req.Title, req.Body) if err != nil { return nil, err } return ¬icev1.NoticeTestRes{Result: ok, Message: msg}, nil } // toLogItem dto → API 契约转换。 func toLogItem(v *dto.NoticeLogVO) *noticev1.NoticeLogItem { return ¬icev1.NoticeLogItem{ Id: v.Id, BatchId: v.BatchId, RuleId: v.RuleId, RuleName: v.RuleName, EventType: v.EventType, EventName: v.EventName, NoticeType: v.NoticeType, TypeName: v.TypeName, Group: v.Group, GroupName: v.GroupName, ChannelCode: v.ChannelCode, ChannelName: v.ChannelName, UserId: v.UserId, UserName: v.UserName, Target: v.Target, Title: v.Title, Body: v.Body, Status: v.Status, StatusName: v.StatusName, Result: v.Result, Error: v.Error, RetryCount: v.RetryCount, DurationMs: v.DurationMs, Source: v.Source, Remark: v.Remark, CreatedAt: v.CreatedAt, } } // toMetaItems dto 字典项 → API 契约转换。 func toMetaItems(list []dto.NoticeMetaItem) []*noticev1.NoticeMetaItem { out := make([]*noticev1.NoticeMetaItem, 0, len(list)) for i := range list { out = append(out, ¬icev1.NoticeMetaItem{Code: list[i].Code, Name: list[i].Name}) } return out }