package sys import ( "context" "hotgo/internal/consts" "hotgo/internal/dao" "hotgo/internal/library/imtenant" "hotgo/internal/model/entity" "hotgo/internal/model/input/sysin" "hotgo/internal/service" "github.com/gogf/gf/v2/database/gdb" "github.com/gogf/gf/v2/encoding/gjson" "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/os/gtime" ) type sSysImNotification struct{} func NewSysImNotification() *sSysImNotification { return &sSysImNotification{} } func init() { service.RegisterSysImNotification(NewSysImNotification()) } func (s *sSysImNotification) TemplateList(ctx context.Context, in *sysin.ImNotificationTemplateListInp) (list []*sysin.ImNotificationTemplateListModel, totalCount int, err error) { if err = in.Filter(ctx); err != nil { return } scope, err := resolveImAdminScopeWithAll(ctx, in.TenantId, true) if err != nil { return } tenants, err := s.listTenants(ctx, scope.TenantId, in.TenantId) if err != nil { return } list = []*sysin.ImNotificationTemplateListModel{} for _, tenant := range tenants { if err = s.ensureTemplates(ctx, tenant.Id); err != nil { return } var tenantList []*sysin.ImNotificationTemplateListModel mod := imtenant.RegistryDB().Model("im_notification_template").Safe().Ctx(ctx). Where("tenant_id", tenant.Id) if in.Scene != "" { mod = mod.Where("scene", in.Scene) } if in.Status != nil { mod = mod.Where("status", *in.Status) } if err = mod.OrderAsc("id").Scan(&tenantList); err != nil { return nil, 0, gerror.Wrap(err, "获取IM通知模板失败,请稍后重试!") } for _, item := range tenantList { item.TenantName = tenant.Name if parsed, parseErr := gjson.DecodeToJson(item.PayloadJson); parseErr == nil && parsed != nil { item.PayloadJson = parsed.MustToJsonString() } } list = append(list, tenantList...) } totalCount = len(list) start, end := pageBounds(in.Page, in.PerPage, totalCount) if start >= totalCount { return []*sysin.ImNotificationTemplateListModel{}, totalCount, nil } return list[start:end], totalCount, nil } func (s *sSysImNotification) TemplateUpdate(ctx context.Context, in *sysin.ImNotificationTemplateUpdateInp) (err error) { if err = in.Filter(ctx); err != nil { return } scope, err := resolveImAdminScope(ctx, in.TenantId) if err != nil { return } if err = s.ensureTemplates(ctx, scope.TenantId); err != nil { return } payload := "{}" if in.PayloadJson != nil { payload = in.PayloadJson.MustToJsonString() } if _, err = imtenant.RegistryDB().Model("im_notification_template").Safe().Ctx(ctx). Where("tenant_id", scope.TenantId). Where("scene", in.Scene). Data(g.Map{ "in_app_enabled": in.InAppEnabled, "push_enabled": in.PushEnabled, "sms_enabled": in.SmsEnabled, "status": in.Status, "title_template": in.TitleTemplate, "content_template": in.ContentTemplate, "payload_json": payload, "updated_at": gtime.Now(), }).Update(); err != nil { return gerror.Wrap(err, "更新IM通知模板失败,请稍后重试!") } _ = writeImAdminAudit(ctx, scope.TenantId, "im_notification_template_update", "im_notification_template", 0, "success", g.Map{"scene": in.Scene}) return nil } func (s *sSysImNotification) listTenants(ctx context.Context, scopeTenantId, requestedTenantId int64) (tenants []*entity.ImTenant, err error) { mod := imtenant.RegistryDB().Model(dao.ImTenant.Table()).Safe().Ctx(ctx) if scopeTenantId > 0 { mod = mod.WherePri(scopeTenantId) } else if requestedTenantId > 0 { mod = mod.WherePri(requestedTenantId) } if err = mod.OrderAsc(dao.ImTenant.Columns().Id).Scan(&tenants); err != nil { return nil, gerror.Wrap(err, "获取IM租户失败,请稍后重试!") } return tenants, nil } func (s *sSysImNotification) ensureTemplates(ctx context.Context, tenantId int64) error { for _, item := range defaultNotificationTemplates() { count, err := imtenant.RegistryDB().Model("im_notification_template").Safe().Ctx(ctx). Where("tenant_id", tenantId). Where("scene", item.Scene). Count() if err != nil { return gerror.Wrap(err, "检查IM通知模板失败,请稍后重试!") } if count > 0 { continue } if _, err = imtenant.RegistryDB().Model("im_notification_template").Safe().Ctx(ctx).Data(g.Map{ "tenant_id": tenantId, "scene": item.Scene, "name": item.Name, "in_app_enabled": 1, "push_enabled": item.PushEnabled, "sms_enabled": 0, "status": consts.ImNotificationTemplateEnabled, "title_template": item.Title, "content_template": item.Content, "payload_json": gdb.Raw("CAST('{}' AS JSON)"), "created_at": gtime.Now(), "updated_at": gtime.Now(), }).Insert(); err != nil { return gerror.Wrap(err, "初始化IM通知模板失败,请稍后重试!") } } return nil } type notificationTemplateSeed struct { Scene string Name string Title string Content string PushEnabled int } func defaultNotificationTemplates() []*notificationTemplateSeed { return []*notificationTemplateSeed{ {Scene: consts.ImNotificationSceneAccountSecurity, Name: "账号安全", Title: "账号安全提醒", Content: "你的账号发生安全事件:{{event}}", PushEnabled: 1}, {Scene: consts.ImNotificationSceneFriendRequest, Name: "好友申请", Title: "新的好友申请", Content: "{{user}} 请求添加你为好友", PushEnabled: 1}, {Scene: consts.ImNotificationSceneGroupEvent, Name: "群事件", Title: "群通知", Content: "{{group}} 有新的群事件:{{event}}", PushEnabled: 1}, {Scene: consts.ImNotificationSceneFileEvent, Name: "文件事件", Title: "文件通知", Content: "{{file}} 状态已更新", PushEnabled: 0}, {Scene: consts.ImNotificationSceneMeetingReminder, Name: "会议提醒", Title: "会议提醒", Content: "{{meeting}} 将于 {{time}} 开始", PushEnabled: 1}, {Scene: consts.ImNotificationSceneReportReminder, Name: "日报月报提醒", Title: "填报提醒", Content: "请及时提交 {{report_type}}", PushEnabled: 1}, {Scene: consts.ImNotificationSceneWorkOrder, Name: "工单处理", Title: "工单状态更新", Content: "你的工单 {{ticket}} 已更新", PushEnabled: 1}, } } func pageBounds(page, perPage, total int) (start, end int) { if page <= 0 { page = 1 } if perPage <= 0 { perPage = 10 } start = (page - 1) * perPage end = start + perPage if end > total { end = total } return }