package sys import ( "context" "hotgo/internal/consts" "hotgo/internal/dao" "hotgo/internal/library/contexts" "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 sSysImExternalConfig struct{} func NewSysImExternalConfig() *sSysImExternalConfig { return &sSysImExternalConfig{} } func init() { service.RegisterSysImExternalConfig(NewSysImExternalConfig()) } func (s *sSysImExternalConfig) List(ctx context.Context, in *sysin.ImExternalConfigListInp) (list []*sysin.ImExternalConfigListModel, totalCount int, err error) { if err = in.Filter(ctx); err != nil { return } tenant, err := s.resolveTenant(ctx, in.TenantId) if err != nil { return } if err = s.ensureRows(ctx, tenant.Id); err != nil { return } mod := s.model(ctx).Where("tenant_id", tenant.Id) if in.Service != "" { mod = mod.Where("service", in.Service) } if in.Provider != "" { mod = mod.WhereLike("provider", "%"+in.Provider+"%") } if in.Enabled != nil { mod = mod.Where("enabled", *in.Enabled) } mod = mod.Page(in.Page, in.PerPage).OrderAsc("service") if err = mod.ScanAndCount(&list, &totalCount, false); err != nil { err = gerror.Wrap(err, "获取IM外部服务配置失败,请稍后重试!") return } for _, item := range list { item.TenantName = tenant.Name } return } func (s *sSysImExternalConfig) View(ctx context.Context, in *sysin.ImExternalConfigViewInp) (res *sysin.ImExternalConfigViewModel, err error) { if err = in.Filter(ctx); err != nil { return } tenant, err := s.resolveTenant(ctx, in.TenantId) if err != nil { return nil, err } if err = s.ensureRows(ctx, tenant.Id); err != nil { return nil, err } if err = s.model(ctx).Where("tenant_id", tenant.Id).Where("service", in.Service).Scan(&res); err != nil { return nil, gerror.Wrap(err, "获取IM外部服务配置详情失败,请稍后重试!") } if res != nil { res.TenantName = tenant.Name } return } func (s *sSysImExternalConfig) Update(ctx context.Context, in *sysin.ImExternalConfigUpdateInp) (err error) { if err = in.Filter(ctx); err != nil { return } if !s.validService(in.Service) { return gerror.New("服务类型不正确") } tenant, err := s.resolveTenant(ctx, in.TenantId) if err != nil { return err } if err = s.ensureRows(ctx, tenant.Id); err != nil { return err } configJson := "{}" if in.ConfigJson != nil && in.ConfigJson.String() != "" && in.ConfigJson.String() != "null" { configJson = in.ConfigJson.String() } data := g.Map{ "provider": in.Provider, "endpoint": in.Endpoint, "enabled": in.Enabled, "config_json": configJson, "updated_at": gtime.Now(), "updated_by": contexts.GetUserId(ctx), } if in.SecretJson != nil && in.SecretJson.String() != "" && in.SecretJson.String() != "null" && in.SecretJson.String() != "{}" { data["secret_json"] = in.SecretJson.String() } if _, err = imtenant.RegistryDB().Model("im_external_config").Safe().Ctx(ctx). Where("tenant_id", tenant.Id).Where("service", in.Service).Data(data).Update(); err != nil { return gerror.Wrap(err, "更新IM外部服务配置失败,请稍后重试!") } _ = writeImAdminAudit(ctx, tenant.Id, "im_external_config_update", "im_external_config", 0, "success", g.Map{ "service": in.Service, "provider": in.Provider, "enabled": in.Enabled, }) return nil } func (s *sSysImExternalConfig) Check(ctx context.Context, in *sysin.ImExternalConfigCheckInp) (err error) { if err = in.Filter(ctx); err != nil { return } tenant, err := s.resolveTenant(ctx, in.TenantId) if err != nil { return err } if err = s.ensureRows(ctx, tenant.Id); err != nil { return err } var row gdb.Record if row, err = imtenant.RegistryDB().Model("im_external_config").Safe().Ctx(ctx). Where("tenant_id", tenant.Id).Where("service", in.Service).One(); err != nil { return gerror.Wrap(err, "检查IM外部服务配置失败,请稍后重试!") } status := consts.ImExternalConfigStatusConfigured result := "配置完整" if row == nil || row["enabled"].Int() != 1 || row["provider"].String() == "" { status = consts.ImExternalConfigStatusUnconfigured result = "未启用或服务商为空" } if _, err = imtenant.RegistryDB().Model("im_external_config").Safe().Ctx(ctx). Where("tenant_id", tenant.Id).Where("service", in.Service). Data(g.Map{"status": status, "checked_at": gtime.Now(), "check_result": result, "updated_at": gtime.Now()}). Update(); err != nil { return gerror.Wrap(err, "更新IM外部服务检查结果失败,请稍后重试!") } _ = writeImAdminAudit(ctx, tenant.Id, "im_external_config_check", "im_external_config", 0, "success", g.Map{ "service": in.Service, "status": status, }) return nil } func (s *sSysImExternalConfig) model(ctx context.Context) *gdb.Model { return imtenant.RegistryDB().Model("im_external_config").Safe().Ctx(ctx).Fields( "tenant_id", "id", "service", "provider", "endpoint", "enabled", "status", "CAST(config_json AS CHAR) config_json", "CASE WHEN secret_json IS NULL OR CAST(secret_json AS CHAR)='{}' THEN 0 ELSE 1 END has_secret", "checked_at", "check_result", "created_at", "updated_at", ) } func (s *sSysImExternalConfig) resolveTenant(ctx context.Context, selectedTenantId int64) (tenant *entity.ImTenant, err error) { scope, err := resolveImAdminScope(ctx, selectedTenantId) if err != nil { return nil, err } if err = imtenant.RegistryDB().Model(dao.ImTenant.Table()).Safe().Ctx(ctx).WherePri(scope.TenantId).Scan(&tenant); err != nil { return nil, gerror.Wrap(err, "获取IM租户失败") } if tenant == nil { return nil, gerror.New("IM租户不存在") } return tenant, nil } func (s *sSysImExternalConfig) ensureRows(ctx context.Context, tenantId int64) error { services := []string{ consts.ImExternalServiceSms, consts.ImExternalServicePush, consts.ImExternalServiceTurn, consts.ImExternalServiceStorage, consts.ImExternalServiceModeration, } for _, serviceName := range services { count, err := imtenant.RegistryDB().Model("im_external_config").Safe().Ctx(ctx). Where("tenant_id", tenantId).Where("service", serviceName).Count() if err != nil { return gerror.Wrap(err, "初始化IM外部服务配置失败") } if count > 0 { continue } _, err = imtenant.RegistryDB().Exec(ctx, `INSERT INTO im_external_config (tenant_id,service,provider,endpoint,enabled,status,config_json,secret_json,created_by,updated_by) VALUES(?,?,?,?,?,?,CAST(? AS JSON),CAST(? AS JSON),?,?)`, tenantId, serviceName, "", "", 0, consts.ImExternalConfigStatusUnconfigured, "{}", "{}", contexts.GetUserId(ctx), contexts.GetUserId(ctx)) if err != nil { return gerror.Wrap(err, "初始化IM外部服务配置失败") } } return nil } func (s *sSysImExternalConfig) validService(serviceName string) bool { switch serviceName { case consts.ImExternalServiceSms, consts.ImExternalServicePush, consts.ImExternalServiceTurn, consts.ImExternalServiceStorage, consts.ImExternalServiceModeration: return true default: return false } } func externalConfigJson(value string) *gjson.Json { if value == "" { return gjson.New("{}") } return gjson.New(value) }