diff --git a/server/api/admin/imconfiginternal/im_config.go b/server/api/admin/imconfiginternal/im_config.go
index c001eef..15f55f8 100644
--- a/server/api/admin/imconfiginternal/im_config.go
+++ b/server/api/admin/imconfiginternal/im_config.go
@@ -35,8 +35,6 @@ type TenantModel struct {
Code string `json:"code"`
Name string `json:"name"`
TenantDesc *string `json:"tenant_desc,omitempty"`
- DBName string `json:"db_name"`
- DBDSN string `json:"db_dsn"`
State int `json:"state"`
CreatedAt string `json:"created_at"`
CreatedBy int64 `json:"created_by"`
diff --git a/server/internal/controller/internalapi/imconfig/im_config.go b/server/internal/controller/internalapi/imconfig/im_config.go
index 7d8f2c8..8e803d8 100644
--- a/server/internal/controller/internalapi/imconfig/im_config.go
+++ b/server/internal/controller/internalapi/imconfig/im_config.go
@@ -178,17 +178,8 @@ func (c *cConfig) ModerationPolicy(ctx context.Context, req *api.ModerationPolic
return nil, err
}
res = defaultModerationPolicy(tenant)
- var tenantConfig struct {
- AliyunModerationEnabled int `json:"aliyun_moderation_enabled"`
- LocalModerationEnabled int `json:"local_moderation_enabled"`
- }
- if err = imtenant.RegistryDB().Model(dao.ImTenantConfig.Table()).Safe().Ctx(ctx).
- Fields("aliyun_moderation_enabled", "local_moderation_enabled").
- Where(dao.ImTenantConfig.Columns().TenantId, tenant.Id).Scan(&tenantConfig); err != nil {
- return nil, gerror.Wrap(err, "获取商户内容审核开关失败")
- }
- res.AliyunEnabled = tenantConfig.AliyunModerationEnabled == 1
- res.LocalWordsEnabled = tenantConfig.LocalModerationEnabled == 1
+ res.AliyunEnabled = tenant.AliyunModerationEnabled == 1
+ res.LocalWordsEnabled = tenant.LocalModerationEnabled == 1
res.Enabled = res.AliyunEnabled || res.LocalWordsEnabled
columns := dao.ImSecurityPolicy.Columns()
var row struct {
@@ -333,18 +324,7 @@ func (c *cConfig) RealnamePolicy(ctx context.Context, req *api.RealnamePolicyReq
return nil, err
}
res = defaultRealnamePolicy(tenant.Id)
- var row *struct {
- RealnameReviewPolicy int `json:"realname_review_policy"`
- }
- if err = imtenant.RegistryDB().Model(dao.ImTenantConfig.Table()).Safe().Ctx(ctx).
- Fields("realname_review_policy").
- Where(dao.ImTenantConfig.Columns().TenantId, tenant.Id).Scan(&row); err != nil {
- return nil, gerror.Wrap(err, "获取租户实名认证策略失败")
- }
- if row == nil {
- return res, nil
- }
- if row.RealnameReviewPolicy == 1 {
+ if tenant.RealnameReviewPolicy == 1 {
res.RealnameReviewPolicy = 1
}
return res, nil
@@ -553,8 +533,6 @@ func tenantToModel(tenant *entity.ImTenant) *api.TenantModel {
Code: tenant.Code,
Name: tenant.Name,
TenantDesc: &desc,
- DBName: tenant.DbName,
- DBDSN: tenant.DbDsn,
State: tenant.State,
CreatedAt: gtimeToRFC3339(tenant.CreatedAt),
CreatedBy: tenant.CreatedBy,
diff --git a/server/internal/dao/im_tenant_config.go b/server/internal/dao/im_tenant_config.go
deleted file mode 100644
index bb54153..0000000
--- a/server/internal/dao/im_tenant_config.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// =================================================================================
-// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed.
-// =================================================================================
-
-package dao
-
-import (
- "hotgo/internal/dao/internal"
-)
-
-// imTenantConfigDao is the data access object for the table im_tenant_config.
-// You can define custom methods on it to extend its functionality as needed.
-type imTenantConfigDao struct {
- *internal.ImTenantConfigDao
-}
-
-var (
- // ImTenantConfig is a globally accessible object for table im_tenant_config operations.
- ImTenantConfig = imTenantConfigDao{internal.NewImTenantConfigDao()}
-)
-
-// Add your custom methods and functionality below.
diff --git a/server/internal/dao/internal/im_tenant.go b/server/internal/dao/internal/im_tenant.go
index f86ea9a..676156b 100644
--- a/server/internal/dao/internal/im_tenant.go
+++ b/server/internal/dao/internal/im_tenant.go
@@ -21,32 +21,58 @@ type ImTenantDao struct {
// ImTenantColumns defines and stores column names for the table im_tenant.
type ImTenantColumns struct {
- Id string //
- Code string //
- Name string //
- TenantDesc string //
- DbName string //
- DbDsn string //
- State string //
- CreatedAt string //
- CreatedBy string //
- UpdatedAt string //
- UpdatedBy string //
+ Id string //
+ Code string //
+ Name string //
+ TenantDesc string //
+ MaxUsers string // 0表示ä¸é™åˆ¶
+ MaxGroups string // 0表示ä¸é™åˆ¶
+ MaxGroupMembers string // 0表示ä¸é™åˆ¶
+ RealnameReviewPolicy string // 实åå®¡æ ¸ç–略:0自动通过,1è½¬äººå·¥å®¡æ ¸
+ RealnameProviderMode string // 实åè®¤è¯æ¨¡å¼
+ RealnameRequired string // 是å¦å¼ºåˆ¶å®žå
+ RealnameAllowSkip string // 是å¦å…许跳过实å
+ RealnameRemindAfter string // 实åæé†’延迟
+ AliyunModerationEnabled string // 是å¦å¯ç”¨é˜¿é‡Œäº‘å†…å®¹å®¡æ ¸
+ LocalModerationEnabled string // 是å¦å¯ç”¨æœ¬åœ°å†…å®¹å®¡æ ¸
+ MessageEncryptionEnabled string // 是å¦å¯ç”¨æ¶ˆæ¯åР坆
+ DefaultPolicyGroupId string // 默认用户ç–略组
+ SecurityPolicyVersion string // å·²å‘布安全ç–略版本
+ GlobalFriendEnabled string // å…¨å±€åŠ å¥½å‹å¼€å…³
+ MessageCurfewEnabled string // 消æ¯å®µç¦å¼€å…³
+ State string //
+ CreatedAt string //
+ CreatedBy string //
+ UpdatedAt string //
+ UpdatedBy string //
}
// imTenantColumns holds the columns for the table im_tenant.
var imTenantColumns = ImTenantColumns{
- Id: "id",
- Code: "code",
- Name: "name",
- TenantDesc: "tenant_desc",
- DbName: "db_name",
- DbDsn: "db_dsn",
- State: "state",
- CreatedAt: "created_at",
- CreatedBy: "created_by",
- UpdatedAt: "updated_at",
- UpdatedBy: "updated_by",
+ Id: "id",
+ Code: "code",
+ Name: "name",
+ TenantDesc: "tenant_desc",
+ MaxUsers: "max_users",
+ MaxGroups: "max_groups",
+ MaxGroupMembers: "max_group_members",
+ RealnameReviewPolicy: "realname_review_policy",
+ RealnameProviderMode: "realname_provider_mode",
+ RealnameRequired: "realname_required",
+ RealnameAllowSkip: "realname_allow_skip",
+ RealnameRemindAfter: "realname_remind_after",
+ AliyunModerationEnabled: "aliyun_moderation_enabled",
+ LocalModerationEnabled: "local_moderation_enabled",
+ MessageEncryptionEnabled: "message_encryption_enabled",
+ DefaultPolicyGroupId: "default_policy_group_id",
+ SecurityPolicyVersion: "security_policy_version",
+ GlobalFriendEnabled: "global_friend_enabled",
+ MessageCurfewEnabled: "message_curfew_enabled",
+ State: "state",
+ CreatedAt: "created_at",
+ CreatedBy: "created_by",
+ UpdatedAt: "updated_at",
+ UpdatedBy: "updated_by",
}
// NewImTenantDao creates and returns a new DAO object for table data access.
diff --git a/server/internal/dao/internal/im_tenant_config.go b/server/internal/dao/internal/im_tenant_config.go
deleted file mode 100644
index 16bc159..0000000
--- a/server/internal/dao/internal/im_tenant_config.go
+++ /dev/null
@@ -1,103 +0,0 @@
-// ==========================================================================
-// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
-// ==========================================================================
-
-package internal
-
-import (
- "context"
-
- "github.com/gogf/gf/v2/database/gdb"
- "github.com/gogf/gf/v2/frame/g"
-)
-
-// ImTenantConfigDao is the data access object for the table im_tenant_config.
-type ImTenantConfigDao struct {
- table string // table is the underlying table name of the DAO.
- group string // group is the database configuration group name of the current DAO.
- columns ImTenantConfigColumns // columns contains all the column names of Table for convenient usage.
- handlers []gdb.ModelHandler // handlers for customized model modification.
-}
-
-// ImTenantConfigColumns defines and stores column names for the table im_tenant_config.
-type ImTenantConfigColumns struct {
- Id string //
- TenantId string //
- MaxUsers string // 0 means unlimited
- MaxGroups string // 0 means unlimited
- MaxGroupMembers string // 0 means unlimited
- DefaultPolicyGroupId string // Default user policy group
- SecurityPolicyVersion string // Published security policy version
- GlobalFriendEnabled string // Published global friend switch
- MessageCurfewEnabled string // Published message curfew switch
- CreatedAt string //
- CreatedBy string //
- UpdatedAt string //
- UpdatedBy string //
-}
-
-// imTenantConfigColumns holds the columns for the table im_tenant_config.
-var imTenantConfigColumns = ImTenantConfigColumns{
- Id: "id",
- TenantId: "tenant_id",
- MaxUsers: "max_users",
- MaxGroups: "max_groups",
- MaxGroupMembers: "max_group_members",
- DefaultPolicyGroupId: "default_policy_group_id",
- SecurityPolicyVersion: "security_policy_version",
- GlobalFriendEnabled: "global_friend_enabled",
- MessageCurfewEnabled: "message_curfew_enabled",
- CreatedAt: "created_at",
- CreatedBy: "created_by",
- UpdatedAt: "updated_at",
- UpdatedBy: "updated_by",
-}
-
-// NewImTenantConfigDao creates and returns a new DAO object for table data access.
-func NewImTenantConfigDao(handlers ...gdb.ModelHandler) *ImTenantConfigDao {
- return &ImTenantConfigDao{
- group: "default",
- table: "im_tenant_config",
- columns: imTenantConfigColumns,
- handlers: handlers,
- }
-}
-
-// DB retrieves and returns the underlying raw database management object of the current DAO.
-func (dao *ImTenantConfigDao) DB() gdb.DB {
- return g.DB(dao.group)
-}
-
-// Table returns the table name of the current DAO.
-func (dao *ImTenantConfigDao) Table() string {
- return dao.table
-}
-
-// Columns returns all column names of the current DAO.
-func (dao *ImTenantConfigDao) Columns() ImTenantConfigColumns {
- return dao.columns
-}
-
-// Group returns the database configuration group name of the current DAO.
-func (dao *ImTenantConfigDao) Group() string {
- return dao.group
-}
-
-// Ctx creates and returns a Model for the current DAO. It automatically sets the context for the current operation.
-func (dao *ImTenantConfigDao) Ctx(ctx context.Context) *gdb.Model {
- model := dao.DB().Model(dao.table)
- for _, handler := range dao.handlers {
- model = handler(model)
- }
- return model.Safe().Ctx(ctx)
-}
-
-// Transaction wraps the transaction logic using function f.
-// It rolls back the transaction and returns the error if function f returns a non-nil error.
-// It commits the transaction and returns nil if function f returns nil.
-//
-// Note: Do not commit or roll back the transaction in function f,
-// as it is automatically handled by this function.
-func (dao *ImTenantConfigDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
- return dao.Ctx(ctx).Transaction(ctx, f)
-}
diff --git a/server/internal/library/imtenant/db.go b/server/internal/library/imtenant/db.go
index e774f14..6310993 100644
--- a/server/internal/library/imtenant/db.go
+++ b/server/internal/library/imtenant/db.go
@@ -20,6 +20,7 @@ import (
var tenantDbGroups sync.Map
const registryDbGroup = "imRegistry"
+const sharedBusinessDatabase = "meeting_im"
var registryDbGroupOnce sync.Once
@@ -47,19 +48,15 @@ func DB(ctx context.Context, tenantId int64) (db gdb.DB, tenant *entity.ImTenant
// Tenant isolation inside this database is implemented by tenant_id predicates
// and the three tenant-partitioned high-volume table families.
func SharedDB(ctx context.Context) (gdb.DB, error) {
- var sharedTenant *entity.ImTenant
- if err := RegistryDB().Model(dao.ImTenant.Table()).Safe().Ctx(ctx).
- Where(dao.ImTenant.Columns().Code, "default").Scan(&sharedTenant); err != nil {
- return nil, gerror.Wrap(err, "获取共享业务库配置失败")
+ defaultLink := defaultDbLink(ctx)
+ if defaultLink == "" {
+ return nil, gerror.New("默认数据库连接未配置,无法连接共享业务库")
}
- if sharedTenant == nil || sharedTenant.Id <= 0 {
- return nil, gerror.New("默认商户不存在,无法确定共享业务库")
- }
- link, err := tenantLink(ctx, sharedTenant)
+ link, err := replaceMySQLDatabase(defaultLink, sharedBusinessDatabase)
if err != nil {
return nil, err
}
- return dbForLink(link, sharedTenant.Id)
+ return dbForLink(link, 0)
}
func dbForLink(link string, ownerID int64) (gdb.DB, error) {
@@ -111,31 +108,6 @@ func ensureRegistryDBGroup() {
_ = gdb.SetConfigGroup(registryDbGroup, cloned)
}
-func tenantLink(ctx context.Context, tenant *entity.ImTenant) (string, error) {
- if tenant.DbDsn != "" {
- return normalizeMySQLTimeOptions(tenant.DbDsn)
- }
- if tenant.DbName == "" {
- // 未配置独立业务库的商户回落共享默认库
- defaultLink := defaultDbLink(ctx)
- if defaultLink == "" {
- return "", gerror.New("默认数据库连接未配置,无法回落共享业务库")
- }
- return normalizeMySQLTimeOptions(defaultLink)
- }
-
- defaultLink := defaultDbLink(ctx)
- if defaultLink == "" {
- return "", gerror.New("默认数据库连接未配置,无法推导租户业务库连接")
- }
-
- link, err := replaceMySQLDatabase(defaultLink, tenant.DbName)
- if err != nil {
- return "", err
- }
- return link, nil
-}
-
func defaultDbLink(ctx context.Context) string {
if configs, err := gdb.GetConfigGroup("default"); err == nil && len(configs) > 0 {
if configs[0].Link != "" {
diff --git a/server/internal/logic/sys/im_message_encryption.go b/server/internal/logic/sys/im_message_encryption.go
index e0f5710..c99f47b 100644
--- a/server/internal/logic/sys/im_message_encryption.go
+++ b/server/internal/logic/sys/im_message_encryption.go
@@ -40,10 +40,9 @@ func (s *sSysImMessageEncryption) List(ctx context.Context, in *sysin.ImMessageE
}
db := imtenant.RegistryDB()
mod := db.Model(dao.ImTenant.Table()+" t").Safe().Ctx(ctx).
- LeftJoin(dao.ImTenantConfig.Table()+" c", "c.tenant_id=t.id").
Fields(
"t.id tenant_id", "t.code tenant_code", "t.name tenant_name",
- "COALESCE(c."+imTenantMessageEncryptionColumn+",0) message_encryption_enabled",
+ "t."+imTenantMessageEncryptionColumn+" message_encryption_enabled",
"COALESCE((SELECT MAX(k.key_version) FROM "+imMessageEncryptionKeyTable+" k WHERE k.tenant_id=t.id AND k.status='active'),0) active_version",
"COALESCE((SELECT MAX(k.key_version) FROM "+imMessageEncryptionKeyTable+" k WHERE k.tenant_id=t.id AND k.status='pending'),0) pending_version",
"(SELECT COUNT(1) FROM "+imMessageEncryptionKeyTable+" k WHERE k.tenant_id=t.id) key_count",
@@ -56,7 +55,7 @@ func (s *sSysImMessageEncryption) List(ctx context.Context, in *sysin.ImMessageE
mod = mod.Where("t.code LIKE ? OR t.name LIKE ?", "%"+keyword+"%", "%"+keyword+"%")
}
if in.Enabled != nil {
- mod = mod.Where("COALESCE(c."+imTenantMessageEncryptionColumn+",0)=?", *in.Enabled)
+ mod = mod.Where("t."+imTenantMessageEncryptionColumn, *in.Enabled)
}
if err = mod.Page(in.Page, in.PerPage).OrderAsc("t.id").ScanAndCount(&list, &total, false); err != nil {
return nil, 0, gerror.Wrap(err, "获取商户消息加密配置失败")
@@ -185,16 +184,16 @@ func (s *sSysImMessageEncryption) Switch(ctx context.Context, in *sysin.ImMessag
return gerror.New("启用消息加密前必须先初始化有效密钥")
}
}
- result, err := imtenant.RegistryDB().Model(dao.ImTenantConfig.Table()).Safe().Ctx(ctx).
- Where(dao.ImTenantConfig.Columns().TenantId, tenant.Id).
- Data(g.Map{imTenantMessageEncryptionColumn: in.Enabled, dao.ImTenantConfig.Columns().UpdatedBy: contexts.GetUserId(ctx)}).Update()
+ result, err := imtenant.RegistryDB().Model(dao.ImTenant.Table()).Safe().Ctx(ctx).
+ Where(dao.ImTenant.Columns().Id, tenant.Id).
+ Data(g.Map{dao.ImTenant.Columns().MessageEncryptionEnabled: in.Enabled, dao.ImTenant.Columns().UpdatedBy: contexts.GetUserId(ctx)}).Update()
if err != nil {
return gerror.Wrap(err, "更新商户消息加密开关失败")
}
if affected, _ := result.RowsAffected(); affected == 0 {
return gerror.New("商户配置不存在")
}
- _ = writeImAdminAudit(ctx, tenant.Id, "message_encryption_switch", "im_tenant_config", tenant.Id, "success", g.Map{"enabled": in.Enabled})
+ _ = writeImAdminAudit(ctx, tenant.Id, "message_encryption_switch", dao.ImTenant.Table(), tenant.Id, "success", g.Map{"enabled": in.Enabled})
return publishImPolicyEvent(ctx, tenant.Id, tenant.Code, "tenant.features.updated", "message_encryption", 0)
}
@@ -203,8 +202,8 @@ func (s *sSysImMessageEncryption) GetKey(ctx context.Context, in *sysin.ImMessag
if err != nil {
return nil, err
}
- enabledValue, err := imtenant.RegistryDB().Model(dao.ImTenantConfig.Table()).Safe().Ctx(ctx).
- Fields(imTenantMessageEncryptionColumn).Where(dao.ImTenantConfig.Columns().TenantId, tenant.Id).Value()
+ enabledValue, err := imtenant.RegistryDB().Model(dao.ImTenant.Table()).Safe().Ctx(ctx).
+ Fields(dao.ImTenant.Columns().MessageEncryptionEnabled).Where(dao.ImTenant.Columns().Id, tenant.Id).Value()
if err != nil {
return nil, gerror.Wrap(err, "获取商户消息加密开关失败")
}
diff --git a/server/internal/logic/sys/im_security_policy.go b/server/internal/logic/sys/im_security_policy.go
index e4e9920..d30d029 100644
--- a/server/internal/logic/sys/im_security_policy.go
+++ b/server/internal/logic/sys/im_security_policy.go
@@ -207,8 +207,8 @@ func (s *sSysImSecurityPolicy) Publish(ctx context.Context, in *sysin.ImSecurity
return updateErr
}
if tenantID > 0 {
- tc := dao.ImTenantConfig.Columns()
- if _, updateErr := tx.Model(dao.ImTenantConfig.Table()).Safe().Ctx(ctx).Where(tc.TenantId, tenantID).Data(g.Map{tc.SecurityPolicyVersion: row[c.PolicyVersion].Uint(), tc.GlobalFriendEnabled: row[c.GlobalFriendEnabled].Int(), tc.MessageCurfewEnabled: row[c.MessageCurfewEnabled].Int(), tc.UpdatedAt: now, tc.UpdatedBy: operator}).Update(); updateErr != nil {
+ tc := dao.ImTenant.Columns()
+ if _, updateErr := tx.Model(dao.ImTenant.Table()).Safe().Ctx(ctx).Where(tc.Id, tenantID).Data(g.Map{tc.SecurityPolicyVersion: row[c.PolicyVersion].Uint(), tc.GlobalFriendEnabled: row[c.GlobalFriendEnabled].Int(), tc.MessageCurfewEnabled: row[c.MessageCurfewEnabled].Int(), tc.UpdatedAt: now, tc.UpdatedBy: operator}).Update(); updateErr != nil {
return updateErr
}
}
diff --git a/server/internal/logic/sys/im_tenant.go b/server/internal/logic/sys/im_tenant.go
index 442f127..5ab9726 100644
--- a/server/internal/logic/sys/im_tenant.go
+++ b/server/internal/logic/sys/im_tenant.go
@@ -27,28 +27,9 @@ import (
type sSysImTenant struct{}
-const (
- tenantConfigAliyunModerationEnabled = "aliyun_moderation_enabled"
- tenantConfigLocalModerationEnabled = "local_moderation_enabled"
- tenantConfigMessageEncryptionEnabled = "message_encryption_enabled"
- tenantConfigRealnameReviewPolicy = "realname_review_policy"
-)
-
// imManageRoleKey 商户级IM管理员角色标识
const imManageRoleKey = "imManage"
-type imTenantConfigModeration struct {
- Id int64 `json:"id" orm:"id"`
- TenantId int64 `json:"tenant_id" orm:"tenant_id"`
- MaxUsers uint64 `json:"max_users" orm:"max_users"`
- MaxGroups uint64 `json:"max_groups" orm:"max_groups"`
- MaxGroupMembers uint `json:"max_group_members" orm:"max_group_members"`
- AliyunModerationEnabled int `json:"aliyun_moderation_enabled" orm:"aliyun_moderation_enabled"`
- LocalModerationEnabled int `json:"local_moderation_enabled" orm:"local_moderation_enabled"`
- MessageEncryptionEnabled int `json:"message_encryption_enabled" orm:"message_encryption_enabled"`
- RealnameReviewPolicy int `json:"realname_review_policy" orm:"realname_review_policy"`
-}
-
func NewSysImTenant() *sSysImTenant {
return &sSysImTenant{}
}
@@ -62,10 +43,6 @@ func (s *sSysImTenant) Model(ctx context.Context, option ...*handler.Option) *gd
return handler.Model(imtenant.RegistryDB().Model(dao.ImTenant.Table()).Safe().Ctx(ctx), option...)
}
-func (s *sSysImTenant) configModel(ctx context.Context) *gdb.Model {
- return imtenant.RegistryDB().Model(dao.ImTenantConfig.Table()).Safe().Ctx(ctx)
-}
-
// List 获取IM租户列表
func (s *sSysImTenant) List(ctx context.Context, in *sysin.ImTenantListInp) (list []*sysin.ImTenantListModel, totalCount int, err error) {
if err = in.Filter(ctx); err != nil {
@@ -77,7 +54,13 @@ func (s *sSysImTenant) List(ctx context.Context, in *sysin.ImTenantListInp) (lis
dao.ImTenant.Columns().Code,
dao.ImTenant.Columns().Name,
dao.ImTenant.Columns().TenantDesc,
- dao.ImTenant.Columns().DbName,
+ dao.ImTenant.Columns().MaxUsers,
+ dao.ImTenant.Columns().MaxGroups,
+ dao.ImTenant.Columns().MaxGroupMembers,
+ dao.ImTenant.Columns().AliyunModerationEnabled,
+ dao.ImTenant.Columns().LocalModerationEnabled,
+ dao.ImTenant.Columns().MessageEncryptionEnabled,
+ dao.ImTenant.Columns().RealnameReviewPolicy,
dao.ImTenant.Columns().State,
dao.ImTenant.Columns().CreatedBy,
dao.ImTenant.Columns().UpdatedBy,
@@ -102,9 +85,6 @@ func (s *sSysImTenant) List(ctx context.Context, in *sysin.ImTenantListInp) (lis
if in.Name != "" {
mod = mod.WhereLike(dao.ImTenant.Columns().Name, "%"+in.Name+"%")
}
- if in.DbName != "" && isSuperTenantAdmin(ctx) {
- mod = mod.WhereLike(dao.ImTenant.Columns().DbName, "%"+in.DbName+"%")
- }
if in.State != nil {
mod = mod.Where(dao.ImTenant.Columns().State, *in.State)
}
@@ -120,64 +100,6 @@ func (s *sSysImTenant) List(ctx context.Context, in *sysin.ImTenantListInp) (lis
err = gerror.Wrap(err, "获取IM租户列表失败,请稍后重试!")
return
}
- if len(list) == 0 {
- return
- }
-
- if err = s.fillListConfig(ctx, list); err != nil {
- return
- }
- // 业务库名仅超管可见,非超管脱敏返回
- if !isSuperTenantAdmin(ctx) {
- for _, item := range list {
- item.DbName = ""
- }
- }
- return
-}
-
-func (s *sSysImTenant) fillListConfig(ctx context.Context, list []*sysin.ImTenantListModel) (err error) {
- ids := make([]int64, 0, len(list))
- for _, item := range list {
- ids = append(ids, item.Id)
- }
-
- var configs []*imTenantConfigModeration
- if err = s.configModel(ctx).
- WhereIn(dao.ImTenantConfig.Columns().TenantId, ids).
- Scan(&configs); err != nil {
- return gerror.Wrap(err, "获取IM租户配置失败,请稍后重试!")
- }
- configMap := make(map[int64]*imTenantConfigModeration, len(configs))
- for _, item := range configs {
- configMap[item.TenantId] = item
- }
-
- var tenants []*entity.ImTenant
- if err = s.Model(ctx).
- Fields(dao.ImTenant.Columns().Id, dao.ImTenant.Columns().DbDsn).
- WhereIn(dao.ImTenant.Columns().Id, ids).
- Scan(&tenants); err != nil {
- return gerror.Wrap(err, "获取IM租户连接配置失败,请稍后重试!")
- }
- dsnMap := make(map[int64]string, len(tenants))
- for _, item := range tenants {
- dsnMap[item.Id] = item.DbDsn
- }
-
- super := isSuperTenantAdmin(ctx)
- for _, item := range list {
- if conf, ok := configMap[item.Id]; ok {
- item.MaxUsers = conf.MaxUsers
- item.MaxGroups = conf.MaxGroups
- item.MaxGroupMembers = conf.MaxGroupMembers
- item.AliyunModerationEnabled = conf.AliyunModerationEnabled
- item.LocalModerationEnabled = conf.LocalModerationEnabled
- item.MessageEncryptionEnabled = conf.MessageEncryptionEnabled
- item.RealnameReviewPolicy = conf.RealnameReviewPolicy
- }
- item.DbDsnConfigured = super && dsnMap[item.Id] != ""
- }
return
}
@@ -230,14 +152,10 @@ func (s *sSysImTenant) saveTenant(ctx context.Context, in *sysin.ImTenantEditInp
if err = ensureTenantIDSequence(ctx); err != nil {
return err
}
- if in.DbName, in.DbDsn, err = sharedDatabaseConfig(ctx); err != nil {
- return err
- }
in.State = consts.ImTenantStateProvisioning
- } else if !super {
- // 业务库名与独立连接串仅超管可维护,非超管提交一律强制忽略。
- in.DbName = ""
- in.DbDsn = ""
+ }
+ if err = validateTenantMessageEncryption(ctx, in.Id, in.MessageEncryptionEnabled); err != nil {
+ return err
}
err = imtenant.RegistryDB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) (err error) {
if err = s.checkCodeUnique(ctx, in.Id, in.Code); err != nil {
@@ -248,21 +166,24 @@ func (s *sSysImTenant) saveTenant(ctx context.Context, in *sysin.ImTenantEditInp
if in.Id > 0 {
in.UpdatedBy = userId
data := g.Map{
- dao.ImTenant.Columns().Code: in.Code,
- dao.ImTenant.Columns().Name: in.Name,
- dao.ImTenant.Columns().TenantDesc: in.TenantDesc,
- dao.ImTenant.Columns().State: in.State,
- dao.ImTenant.Columns().UpdatedBy: userId,
- }
- if super {
- data[dao.ImTenant.Columns().DbName] = in.DbName
- data[dao.ImTenant.Columns().DbDsn] = in.DbDsn
+ dao.ImTenant.Columns().Code: in.Code,
+ dao.ImTenant.Columns().Name: in.Name,
+ dao.ImTenant.Columns().TenantDesc: in.TenantDesc,
+ dao.ImTenant.Columns().MaxUsers: in.MaxUsers,
+ dao.ImTenant.Columns().MaxGroups: in.MaxGroups,
+ dao.ImTenant.Columns().MaxGroupMembers: in.MaxGroupMembers,
+ dao.ImTenant.Columns().AliyunModerationEnabled: in.AliyunModerationEnabled,
+ dao.ImTenant.Columns().LocalModerationEnabled: in.LocalModerationEnabled,
+ dao.ImTenant.Columns().MessageEncryptionEnabled: in.MessageEncryptionEnabled,
+ dao.ImTenant.Columns().RealnameReviewPolicy: in.RealnameReviewPolicy,
+ dao.ImTenant.Columns().State: in.State,
+ dao.ImTenant.Columns().UpdatedBy: userId,
}
if _, err = s.Model(ctx).
WherePri(in.Id).Data(data).Update(); err != nil {
return gerror.Wrap(err, "修改IM租户失败,请稍后重试!")
}
- return s.saveConfig(ctx, in, userId)
+ return nil
}
in.Id, err = nextTenantID(tx)
@@ -278,7 +199,7 @@ func (s *sSysImTenant) saveTenant(ctx context.Context, in *sysin.ImTenantEditInp
return gerror.Wrap(err, "新增IM租户失败,请稍后重试!")
}
tenantID = in.Id
- return s.saveConfig(ctx, in, userId)
+ return nil
})
if err != nil {
return err
@@ -413,15 +334,7 @@ func (s *sSysImTenant) resetTenantAdminPassword(ctx context.Context, tenantId in
// rollbackTenantCreation 商户创建补偿:删除已写入的商户及配置记录
func (s *sSysImTenant) rollbackTenantCreation(ctx context.Context, tenantId int64) {
- _ = imtenant.RegistryDB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) (err error) {
- if _, err = s.Model(ctx, &handler.Option{FilterAuth: false}).
- WherePri(tenantId).Delete(); err != nil {
- return
- }
- _, err = s.configModel(ctx).
- Where(dao.ImTenantConfig.Columns().TenantId, tenantId).Delete()
- return
- })
+ _, _ = s.Model(ctx, &handler.Option{FilterAuth: false}).WherePri(tenantId).Delete()
}
func (s *sSysImTenant) checkCodeUnique(ctx context.Context, id int64, code string) (err error) {
@@ -439,10 +352,10 @@ func (s *sSysImTenant) checkCodeUnique(ctx context.Context, id int64, code strin
return
}
-func (s *sSysImTenant) saveConfig(ctx context.Context, in *sysin.ImTenantEditInp, userId int64) (err error) {
- if in.MessageEncryptionEnabled == 1 {
+func validateTenantMessageEncryption(ctx context.Context, tenantId int64, enabled int) error {
+ if enabled == 1 {
count, queryErr := imtenant.RegistryDB().Model(imMessageEncryptionKeyTable).Safe().Ctx(ctx).
- Where("tenant_id", in.Id).
+ Where("tenant_id", tenantId).
Where("status", consts.ImMessageKeyStatusActive).
Count()
if queryErr != nil {
@@ -452,61 +365,7 @@ func (s *sSysImTenant) saveConfig(ctx context.Context, in *sysin.ImTenantEditInp
return gerror.New("启用消息加密前必须先在消息密钥管理中初始化有效密钥")
}
}
- var conf *entity.ImTenantConfig
- if err = s.configModel(ctx).
- Where(dao.ImTenantConfig.Columns().TenantId, in.Id).
- Scan(&conf); err != nil {
- return gerror.Wrap(err, "获取IM租户配置失败,请稍后重试!")
- }
-
- data := g.Map{
- dao.ImTenantConfig.Columns().MaxUsers: in.MaxUsers,
- dao.ImTenantConfig.Columns().MaxGroups: in.MaxGroups,
- dao.ImTenantConfig.Columns().MaxGroupMembers: in.MaxGroupMembers,
- tenantConfigAliyunModerationEnabled: in.AliyunModerationEnabled,
- tenantConfigLocalModerationEnabled: in.LocalModerationEnabled,
- tenantConfigMessageEncryptionEnabled: in.MessageEncryptionEnabled,
- tenantConfigRealnameReviewPolicy: in.RealnameReviewPolicy,
- }
- if conf != nil && conf.Id > 0 {
- data[dao.ImTenantConfig.Columns().UpdatedBy] = userId
- if _, err = s.configModel(ctx).
- Fields(
- dao.ImTenantConfig.Columns().MaxUsers,
- dao.ImTenantConfig.Columns().MaxGroups,
- dao.ImTenantConfig.Columns().MaxGroupMembers,
- tenantConfigAliyunModerationEnabled,
- tenantConfigLocalModerationEnabled,
- tenantConfigMessageEncryptionEnabled,
- tenantConfigRealnameReviewPolicy,
- dao.ImTenantConfig.Columns().UpdatedBy,
- ).
- WherePri(conf.Id).Data(data).Update(); err != nil {
- return gerror.Wrap(err, "修改IM租户配置失败,请稍后重试!")
- }
- return
- }
-
- data[dao.ImTenantConfig.Columns().TenantId] = in.Id
- data[dao.ImTenantConfig.Columns().CreatedBy] = userId
- data[dao.ImTenantConfig.Columns().UpdatedBy] = userId
- if _, err = s.configModel(ctx).
- Fields(
- dao.ImTenantConfig.Columns().TenantId,
- dao.ImTenantConfig.Columns().MaxUsers,
- dao.ImTenantConfig.Columns().MaxGroups,
- dao.ImTenantConfig.Columns().MaxGroupMembers,
- tenantConfigAliyunModerationEnabled,
- tenantConfigLocalModerationEnabled,
- tenantConfigMessageEncryptionEnabled,
- tenantConfigRealnameReviewPolicy,
- dao.ImTenantConfig.Columns().CreatedBy,
- dao.ImTenantConfig.Columns().UpdatedBy,
- ).
- Data(data).Insert(); err != nil {
- return gerror.Wrap(err, "新增IM租户配置失败,请稍后重试!")
- }
- return
+ return nil
}
// View 获取IM租户指定信息
@@ -522,23 +381,6 @@ func (s *sSysImTenant) View(ctx context.Context, in *sysin.ImTenantViewInp) (res
return
}
- var conf *imTenantConfigModeration
- if err = s.configModel(ctx).
- Where(dao.ImTenantConfig.Columns().TenantId, in.Id).
- Scan(&conf); err != nil {
- err = gerror.Wrap(err, "获取IM租户配置失败,请稍后重试!")
- return
- }
- if conf != nil {
- res.MaxUsers = conf.MaxUsers
- res.MaxGroups = conf.MaxGroups
- res.MaxGroupMembers = conf.MaxGroupMembers
- res.AliyunModerationEnabled = conf.AliyunModerationEnabled
- res.LocalModerationEnabled = conf.LocalModerationEnabled
- res.MessageEncryptionEnabled = conf.MessageEncryptionEnabled
- res.RealnameReviewPolicy = conf.RealnameReviewPolicy
- }
- res.DbDsnConfigured = res.DbDsn != ""
// 查询商户自动创建的管理员账号(编辑弹窗展示)
roleVal, roleErr := dao.AdminRole.Ctx(ctx).
Fields(dao.AdminRole.Columns().Id).
@@ -558,12 +400,6 @@ func (s *sSysImTenant) View(ctx context.Context, in *sysin.ImTenantViewInp) (res
res.AdminUsername = userVal.String()
}
}
- // 业务库名与独立连接串仅超管可见,非超管全部脱敏
- if !isSuperTenantAdmin(ctx) {
- res.DbName = ""
- res.DbDsn = ""
- res.DbDsnConfigured = false
- }
return
}
@@ -601,17 +437,10 @@ func (s *sSysImTenant) Usage(ctx context.Context, in *sysin.ImTenantUsageInp) (r
}
res = &sysin.ImTenantUsageModel{
- Id: tenant.Id,
- Code: tenant.Code,
- Name: tenant.Name,
- DbName: tenant.DbName,
- DbDsnConfigured: tenant.DbDsn != "",
- Warnings: []string{},
- }
- // 业务库名与连接串信息仅超管可见,非超管全部脱敏
- if !isSuperTenantAdmin(ctx) {
- res.DbName = ""
- res.DbDsnConfigured = false
+ Id: tenant.Id,
+ Code: tenant.Code,
+ Name: tenant.Name,
+ Warnings: []string{},
}
db, _, dbErr := imtenant.DB(ctx, tenant.Id)
diff --git a/server/internal/logic/sys/im_tenant_tables.go b/server/internal/logic/sys/im_tenant_tables.go
index f5fa8b0..a9b83df 100644
--- a/server/internal/logic/sys/im_tenant_tables.go
+++ b/server/internal/logic/sys/im_tenant_tables.go
@@ -12,17 +12,6 @@ import (
const imTenantIDSequenceTable = "im_tenant_id_sequence"
-func sharedDatabaseConfig(ctx context.Context) (dbName, dbDSN string, err error) {
- row, err := imtenant.RegistryDB().GetOne(ctx, "SELECT db_name,db_dsn FROM im_tenant WHERE code='default' LIMIT 1")
- if err != nil {
- return "", "", gerror.Wrap(err, "获取共享业务库配置失败")
- }
- if row.IsEmpty() {
- return "", "", gerror.New("默认商户不存在,无法确定共享业务库")
- }
- return row["db_name"].String(), row["db_dsn"].String(), nil
-}
-
func ensureTenantIDSequence(ctx context.Context) error {
db := imtenant.RegistryDB()
if _, err := db.Exec(ctx, `CREATE TABLE IF NOT EXISTS im_tenant_id_sequence (
diff --git a/server/internal/model/do/im_tenant.go b/server/internal/model/do/im_tenant.go
index 1600c02..e884864 100644
--- a/server/internal/model/do/im_tenant.go
+++ b/server/internal/model/do/im_tenant.go
@@ -11,16 +11,29 @@ import (
// ImTenant is the golang structure of table im_tenant for DAO operations like Where/Data.
type ImTenant struct {
- g.Meta `orm:"table:im_tenant, do:true"`
- Id any //
- Code any //
- Name any //
- TenantDesc any //
- DbName any //
- DbDsn any //
- State any //
- CreatedAt *gtime.Time //
- CreatedBy any //
- UpdatedAt *gtime.Time //
- UpdatedBy any //
+ g.Meta `orm:"table:im_tenant, do:true"`
+ Id any //
+ Code any //
+ Name any //
+ TenantDesc any //
+ MaxUsers any // 0表示ä¸é™åˆ¶
+ MaxGroups any // 0表示ä¸é™åˆ¶
+ MaxGroupMembers any // 0表示ä¸é™åˆ¶
+ RealnameReviewPolicy any // 实åå®¡æ ¸ç–略:0自动通过,1è½¬äººå·¥å®¡æ ¸
+ RealnameProviderMode any // 实åè®¤è¯æ¨¡å¼
+ RealnameRequired any // 是å¦å¼ºåˆ¶å®žå
+ RealnameAllowSkip any // 是å¦å…许跳过实å
+ RealnameRemindAfter any // 实åæé†’延迟
+ AliyunModerationEnabled any // 是å¦å¯ç”¨é˜¿é‡Œäº‘å†…å®¹å®¡æ ¸
+ LocalModerationEnabled any // 是å¦å¯ç”¨æœ¬åœ°å†…å®¹å®¡æ ¸
+ MessageEncryptionEnabled any // 是å¦å¯ç”¨æ¶ˆæ¯åР坆
+ DefaultPolicyGroupId any // 默认用户ç–略组
+ SecurityPolicyVersion any // å·²å‘布安全ç–略版本
+ GlobalFriendEnabled any // å…¨å±€åŠ å¥½å‹å¼€å…³
+ MessageCurfewEnabled any // 消æ¯å®µç¦å¼€å…³
+ State any //
+ CreatedAt *gtime.Time //
+ CreatedBy any //
+ UpdatedAt *gtime.Time //
+ UpdatedBy any //
}
diff --git a/server/internal/model/do/im_tenant_config.go b/server/internal/model/do/im_tenant_config.go
deleted file mode 100644
index 63edd98..0000000
--- a/server/internal/model/do/im_tenant_config.go
+++ /dev/null
@@ -1,28 +0,0 @@
-// =================================================================================
-// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
-// =================================================================================
-
-package do
-
-import (
- "github.com/gogf/gf/v2/frame/g"
- "github.com/gogf/gf/v2/os/gtime"
-)
-
-// ImTenantConfig is the golang structure of table im_tenant_config for DAO operations like Where/Data.
-type ImTenantConfig struct {
- g.Meta `orm:"table:im_tenant_config, do:true"`
- Id any //
- TenantId any //
- MaxUsers any // 0 means unlimited
- MaxGroups any // 0 means unlimited
- MaxGroupMembers any // 0 means unlimited
- DefaultPolicyGroupId any // Default user policy group
- SecurityPolicyVersion any // Published security policy version
- GlobalFriendEnabled any // Published global friend switch
- MessageCurfewEnabled any // Published message curfew switch
- CreatedAt *gtime.Time //
- CreatedBy any //
- UpdatedAt *gtime.Time //
- UpdatedBy any //
-}
diff --git a/server/internal/model/entity/im_tenant.go b/server/internal/model/entity/im_tenant.go
index dc12c0c..8305dc6 100644
--- a/server/internal/model/entity/im_tenant.go
+++ b/server/internal/model/entity/im_tenant.go
@@ -10,15 +10,28 @@ import (
// ImTenant is the golang structure for table im_tenant.
type ImTenant struct {
- Id int64 `json:"id" orm:"id" description:""`
- Code string `json:"code" orm:"code" description:""`
- Name string `json:"name" orm:"name" description:""`
- TenantDesc string `json:"tenantDesc" orm:"tenant_desc" description:""`
- DbName string `json:"dbName" orm:"db_name" description:""`
- DbDsn string `json:"dbDsn" orm:"db_dsn" description:""`
- State int `json:"state" orm:"state" description:""`
- CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:""`
- CreatedBy int64 `json:"createdBy" orm:"created_by" description:""`
- UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:""`
- UpdatedBy int64 `json:"updatedBy" orm:"updated_by" description:""`
+ Id int64 `json:"id" orm:"id" description:""`
+ Code string `json:"code" orm:"code" description:""`
+ Name string `json:"name" orm:"name" description:""`
+ TenantDesc string `json:"tenantDesc" orm:"tenant_desc" description:""`
+ MaxUsers uint64 `json:"maxUsers" orm:"max_users" description:"0表示ä¸é™åˆ¶"`
+ MaxGroups uint64 `json:"maxGroups" orm:"max_groups" description:"0表示ä¸é™åˆ¶"`
+ MaxGroupMembers uint `json:"maxGroupMembers" orm:"max_group_members" description:"0表示ä¸é™åˆ¶"`
+ RealnameReviewPolicy int `json:"realnameReviewPolicy" orm:"realname_review_policy" description:"实åå®¡æ ¸ç–略:0自动通过,1è½¬äººå·¥å®¡æ ¸"`
+ RealnameProviderMode string `json:"realnameProviderMode" orm:"realname_provider_mode" description:"实åè®¤è¯æ¨¡å¼"`
+ RealnameRequired int `json:"realnameRequired" orm:"realname_required" description:"是å¦å¼ºåˆ¶å®žå"`
+ RealnameAllowSkip int `json:"realnameAllowSkip" orm:"realname_allow_skip" description:"是å¦å…许跳过实å"`
+ RealnameRemindAfter string `json:"realnameRemindAfter" orm:"realname_remind_after" description:"实åæé†’延迟"`
+ AliyunModerationEnabled int `json:"aliyunModerationEnabled" orm:"aliyun_moderation_enabled" description:"是å¦å¯ç”¨é˜¿é‡Œäº‘å†…å®¹å®¡æ ¸"`
+ LocalModerationEnabled int `json:"localModerationEnabled" orm:"local_moderation_enabled" description:"是å¦å¯ç”¨æœ¬åœ°å†…å®¹å®¡æ ¸"`
+ MessageEncryptionEnabled int `json:"messageEncryptionEnabled" orm:"message_encryption_enabled" description:"是å¦å¯ç”¨æ¶ˆæ¯åР坆"`
+ DefaultPolicyGroupId int64 `json:"defaultPolicyGroupId" orm:"default_policy_group_id" description:"默认用户ç–略组"`
+ SecurityPolicyVersion uint `json:"securityPolicyVersion" orm:"security_policy_version" description:"å·²å‘布安全ç–略版本"`
+ GlobalFriendEnabled int `json:"globalFriendEnabled" orm:"global_friend_enabled" description:"å…¨å±€åŠ å¥½å‹å¼€å…³"`
+ MessageCurfewEnabled int `json:"messageCurfewEnabled" orm:"message_curfew_enabled" description:"消æ¯å®µç¦å¼€å…³"`
+ State int `json:"state" orm:"state" description:""`
+ CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:""`
+ CreatedBy int64 `json:"createdBy" orm:"created_by" description:""`
+ UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:""`
+ UpdatedBy int64 `json:"updatedBy" orm:"updated_by" description:""`
}
diff --git a/server/internal/model/entity/im_tenant_config.go b/server/internal/model/entity/im_tenant_config.go
deleted file mode 100644
index e8caeb9..0000000
--- a/server/internal/model/entity/im_tenant_config.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// =================================================================================
-// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
-// =================================================================================
-
-package entity
-
-import (
- "github.com/gogf/gf/v2/os/gtime"
-)
-
-// ImTenantConfig is the golang structure for table im_tenant_config.
-type ImTenantConfig struct {
- Id int64 `json:"id" orm:"id" description:""`
- TenantId int64 `json:"tenantId" orm:"tenant_id" description:""`
- MaxUsers uint64 `json:"maxUsers" orm:"max_users" description:"0 means unlimited"`
- MaxGroups uint64 `json:"maxGroups" orm:"max_groups" description:"0 means unlimited"`
- MaxGroupMembers uint `json:"maxGroupMembers" orm:"max_group_members" description:"0 means unlimited"`
- DefaultPolicyGroupId int64 `json:"defaultPolicyGroupId" orm:"default_policy_group_id" description:"Default user policy group"`
- SecurityPolicyVersion uint `json:"securityPolicyVersion" orm:"security_policy_version" description:"Published security policy version"`
- GlobalFriendEnabled int `json:"globalFriendEnabled" orm:"global_friend_enabled" description:"Published global friend switch"`
- MessageCurfewEnabled int `json:"messageCurfewEnabled" orm:"message_curfew_enabled" description:"Published message curfew switch"`
- CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:""`
- CreatedBy int64 `json:"createdBy" orm:"created_by" description:""`
- UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:""`
- UpdatedBy int64 `json:"updatedBy" orm:"updated_by" description:""`
-}
diff --git a/server/internal/model/input/sysin/im_tenant.go b/server/internal/model/input/sysin/im_tenant.go
index f4af04a..6d42fd8 100644
--- a/server/internal/model/input/sysin/im_tenant.go
+++ b/server/internal/model/input/sysin/im_tenant.go
@@ -20,32 +20,10 @@ import (
// ImTenantInsertFields 新增IM租户字段过滤
type ImTenantInsertFields struct {
- Id int64 `json:"id" dc:"商户ID"`
- Code string `json:"code" dc:"租户编码"`
- Name string `json:"name" dc:"租户名称"`
- TenantDesc string `json:"tenantDesc" dc:"租户描述"`
- DbName string `json:"dbName" dc:"业务库名"`
- DbDsn string `json:"dbDsn" dc:"独立连接串"`
- State int `json:"state" dc:"状态"`
- CreatedBy int64 `json:"createdBy" dc:"创建者"`
- UpdatedBy int64 `json:"updatedBy" dc:"更新者"`
-}
-
-// ImTenantConfigUpdateFields 修改IM租户配置字段过滤
-type ImTenantConfigUpdateFields struct {
- MaxUsers uint64 `json:"maxUsers" dc:"最大用户数"`
- MaxGroups uint64 `json:"maxGroups" dc:"最大群组数"`
- MaxGroupMembers uint `json:"maxGroupMembers" dc:"最大群成员数"`
- AliyunModerationEnabled int `json:"aliyunModerationEnabled" dc:"是否启用阿里云内容审核"`
- LocalModerationEnabled int `json:"localModerationEnabled" dc:"是否启用本地内容审核"`
- MessageEncryptionEnabled int `json:"messageEncryptionEnabled" dc:"是否启用消息加密"`
- RealnameReviewPolicy int `json:"realnameReviewPolicy" dc:"实名审核策略"`
- UpdatedBy int64 `json:"updatedBy" dc:"更新者"`
-}
-
-// ImTenantConfigInsertFields 新增IM租户配置字段过滤
-type ImTenantConfigInsertFields struct {
- TenantId int64 `json:"tenantId" dc:"租户ID"`
+ Id int64 `json:"id" dc:"商户ID"`
+ Code string `json:"code" dc:"商户编码"`
+ Name string `json:"name" dc:"商户名称"`
+ TenantDesc string `json:"tenantDesc" dc:"商户描述"`
MaxUsers uint64 `json:"maxUsers" dc:"最大用户数"`
MaxGroups uint64 `json:"maxGroups" dc:"最大群组数"`
MaxGroupMembers uint `json:"maxGroupMembers" dc:"最大群成员数"`
@@ -53,21 +31,16 @@ type ImTenantConfigInsertFields struct {
LocalModerationEnabled int `json:"localModerationEnabled" dc:"是否启用本地内容审核"`
MessageEncryptionEnabled int `json:"messageEncryptionEnabled" dc:"是否启用消息加密"`
RealnameReviewPolicy int `json:"realnameReviewPolicy" dc:"实名审核策略"`
+ State int `json:"state" dc:"状态"`
CreatedBy int64 `json:"createdBy" dc:"创建者"`
+ UpdatedBy int64 `json:"updatedBy" dc:"更新者"`
}
// ImTenantEditInp 修改/新增IM租户
type ImTenantEditInp struct {
entity.ImTenant
- MaxUsers uint64 `json:"maxUsers" dc:"最大用户数"`
- MaxGroups uint64 `json:"maxGroups" dc:"最大群组数"`
- MaxGroupMembers uint `json:"maxGroupMembers" dc:"最大群成员数"`
- AliyunModerationEnabled int `json:"aliyunModerationEnabled" dc:"是否启用阿里云内容审核"`
- LocalModerationEnabled int `json:"localModerationEnabled" dc:"是否启用本地内容审核"`
- MessageEncryptionEnabled int `json:"messageEncryptionEnabled" dc:"是否启用消息加密"`
- RealnameReviewPolicy int `json:"realnameReviewPolicy" dc:"实名审核策略"`
- AdminUsername string `json:"adminUsername" dc:"新增商户时自动创建的后台管理员账号名"`
- AdminPassword string `json:"adminPassword" dc:"新增商户时自动创建的后台管理员初始密码"`
+ AdminUsername string `json:"adminUsername" dc:"新增商户时自动创建的后台管理员账号名"`
+ AdminPassword string `json:"adminPassword" dc:"新增商户时自动创建的后台管理员初始密码"`
}
func (in *ImTenantEditInp) Filter(ctx context.Context) (err error) {
@@ -119,19 +92,9 @@ func (in *ImTenantViewInp) Filter(ctx context.Context) (err error) {
type ImTenantViewModel struct {
entity.ImTenant
- AdminUsername string `json:"adminUsername" dc:"商户管理员账号"`
- MaxUsers uint64 `json:"maxUsers" dc:"最大用户数"`
- MaxGroups uint64 `json:"maxGroups" dc:"最大群组数"`
- MaxGroupMembers uint `json:"maxGroupMembers" dc:"最大群成员数"`
- AliyunModerationEnabled int `json:"aliyunModerationEnabled" dc:"是否启用阿里云内容审核"`
- LocalModerationEnabled int `json:"localModerationEnabled" dc:"是否启用本地内容审核"`
- MessageEncryptionEnabled int `json:"messageEncryptionEnabled" dc:"是否启用消息加密"`
- RealnameReviewPolicy int `json:"realnameReviewPolicy" dc:"实名审核策略"`
- CreatedBySumma *hook.MemberSumma `json:"createdBySumma" dc:"创建者摘要信息"`
- UpdatedBySumma *hook.MemberSumma `json:"updatedBySumma" dc:"更新者摘要信息"`
- DbDsnConfigured bool `json:"dbDsnConfigured" dc:"是否配置独立连接串"`
- TenantDbReachable bool `json:"tenantDbReachable" dc:"业务库是否可达"`
- TenantDbCheckError string `json:"tenantDbCheckError" dc:"业务库检查错误"`
+ AdminUsername string `json:"adminUsername" dc:"商户管理员账号"`
+ CreatedBySumma *hook.MemberSumma `json:"createdBySumma" dc:"创建者摘要信息"`
+ UpdatedBySumma *hook.MemberSumma `json:"updatedBySumma" dc:"更新者摘要信息"`
}
// ImTenantListInp 获取IM租户列表
@@ -140,7 +103,6 @@ type ImTenantListInp struct {
Id int64 `json:"id" dc:"ID"`
Code string `json:"code" dc:"租户编码"`
Name string `json:"name" dc:"租户名称"`
- DbName string `json:"dbName" dc:"业务库名"`
State *int `json:"state" dc:"状态"`
CreatedAt []*gtime.Time `json:"createdAt" dc:"创建时间"`
}
@@ -154,7 +116,6 @@ type ImTenantListModel struct {
Code string `json:"code" dc:"租户编码"`
Name string `json:"name" dc:"租户名称"`
TenantDesc string `json:"tenantDesc" dc:"租户描述"`
- DbName string `json:"dbName" dc:"业务库名"`
State int `json:"state" dc:"状态"`
MaxUsers uint64 `json:"maxUsers" dc:"最大用户数"`
MaxGroups uint64 `json:"maxGroups" dc:"最大群组数"`
@@ -163,7 +124,6 @@ type ImTenantListModel struct {
LocalModerationEnabled int `json:"localModerationEnabled" dc:"是否启用本地内容审核"`
MessageEncryptionEnabled int `json:"messageEncryptionEnabled" dc:"是否启用消息加密"`
RealnameReviewPolicy int `json:"realnameReviewPolicy" dc:"实名审核策略"`
- DbDsnConfigured bool `json:"dbDsnConfigured" dc:"是否配置独立连接串"`
CreatedBy int64 `json:"createdBy" dc:"创建者"`
CreatedBySumma *hook.MemberSumma `json:"createdBySumma" dc:"创建者摘要信息"`
UpdatedBy int64 `json:"updatedBy" dc:"更新者"`
@@ -205,8 +165,6 @@ type ImTenantUsageModel struct {
Id int64 `json:"id" dc:"租户ID"`
Code string `json:"code" dc:"租户编码"`
Name string `json:"name" dc:"租户名称"`
- DbName string `json:"dbName" dc:"业务库名"`
- DbDsnConfigured bool `json:"dbDsnConfigured" dc:"是否配置独立连接串"`
DbReachable bool `json:"dbReachable" dc:"业务库是否可达"`
DbCheckError string `json:"dbCheckError" dc:"业务库检查错误"`
SchemaVersion string `json:"schemaVersion" dc:"Schema版本"`
diff --git a/server/storage/data/generate/im_message_encryption.sql b/server/storage/data/generate/im_message_encryption.sql
index 219690d..9aa3423 100644
--- a/server/storage/data/generate/im_message_encryption.sql
+++ b/server/storage/data/generate/im_message_encryption.sql
@@ -6,9 +6,9 @@ SET @now := NOW();
SET @im_sql = IF(
(SELECT COUNT(*) FROM information_schema.COLUMNS
- WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'im_tenant_config'
+ WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'im_tenant'
AND COLUMN_NAME = 'message_encryption_enabled') = 0,
- 'ALTER TABLE `im_tenant_config` ADD COLUMN `message_encryption_enabled` TINYINT(1) NOT NULL DEFAULT 0 COMMENT ''是否启用消息加密'' AFTER `local_moderation_enabled`',
+ 'ALTER TABLE `im_tenant` ADD COLUMN `message_encryption_enabled` TINYINT(1) NOT NULL DEFAULT 0 COMMENT ''是否启用消息加密'' AFTER `local_moderation_enabled`',
'SELECT 1'
);
PREPARE im_stmt FROM @im_sql;
diff --git a/server/storage/data/generate/im_tenant_merge_config.sql b/server/storage/data/generate/im_tenant_merge_config.sql
new file mode 100644
index 0000000..bb50e95
--- /dev/null
+++ b/server/storage/data/generate/im_tenant_merge_config.sql
@@ -0,0 +1,38 @@
+-- 第一阶段:将商户配置扩展并回填到 im_tenant。
+-- 必须先执行本文件,再发布新版 manager 与 IM Server。
+-- 本阶段保留 im_tenant_config、db_name、db_dsn,确保旧实例在滚动发布期间仍可运行。
+
+ALTER TABLE `im_tenant`
+ ADD COLUMN `max_users` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '0表示不限制' AFTER `tenant_desc`,
+ ADD COLUMN `max_groups` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '0表示不限制' AFTER `max_users`,
+ ADD COLUMN `max_group_members` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '0表示不限制' AFTER `max_groups`,
+ ADD COLUMN `realname_review_policy` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '实名审核策略:0自动通过,1转人工审核' AFTER `max_group_members`,
+ ADD COLUMN `realname_provider_mode` VARCHAR(32) NOT NULL DEFAULT 'id_card_2factor' COMMENT '实名认证模式' AFTER `realname_review_policy`,
+ ADD COLUMN `realname_required` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否强制实名' AFTER `realname_provider_mode`,
+ ADD COLUMN `realname_allow_skip` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否允许跳过实名' AFTER `realname_required`,
+ ADD COLUMN `realname_remind_after` VARCHAR(32) NOT NULL DEFAULT '24h' COMMENT '实名提醒延迟' AFTER `realname_allow_skip`,
+ ADD COLUMN `aliyun_moderation_enabled` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否启用阿里云内容审核' AFTER `realname_remind_after`,
+ ADD COLUMN `local_moderation_enabled` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否启用本地内容审核' AFTER `aliyun_moderation_enabled`,
+ ADD COLUMN `message_encryption_enabled` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否启用消息加密' AFTER `local_moderation_enabled`,
+ ADD COLUMN `default_policy_group_id` BIGINT DEFAULT NULL COMMENT '默认用户策略组' AFTER `message_encryption_enabled`,
+ ADD COLUMN `security_policy_version` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '已发布安全策略版本' AFTER `default_policy_group_id`,
+ ADD COLUMN `global_friend_enabled` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '全局加好友开关' AFTER `security_policy_version`,
+ ADD COLUMN `message_curfew_enabled` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '消息宵禁开关' AFTER `global_friend_enabled`;
+
+UPDATE `im_tenant` t
+INNER JOIN `im_tenant_config` c ON c.`tenant_id`=t.`id`
+SET t.`max_users`=c.`max_users`,
+ t.`max_groups`=c.`max_groups`,
+ t.`max_group_members`=c.`max_group_members`,
+ t.`realname_review_policy`=c.`realname_review_policy`,
+ t.`realname_provider_mode`=c.`realname_provider_mode`,
+ t.`realname_required`=c.`realname_required`,
+ t.`realname_allow_skip`=c.`realname_allow_skip`,
+ t.`realname_remind_after`=c.`realname_remind_after`,
+ t.`aliyun_moderation_enabled`=c.`aliyun_moderation_enabled`,
+ t.`local_moderation_enabled`=c.`local_moderation_enabled`,
+ t.`message_encryption_enabled`=c.`message_encryption_enabled`,
+ t.`default_policy_group_id`=c.`default_policy_group_id`,
+ t.`security_policy_version`=c.`security_policy_version`,
+ t.`global_friend_enabled`=c.`global_friend_enabled`,
+ t.`message_curfew_enabled`=c.`message_curfew_enabled`;
diff --git a/server/storage/data/generate/im_tenant_merge_config_cleanup.sql b/server/storage/data/generate/im_tenant_merge_config_cleanup.sql
new file mode 100644
index 0000000..0099463
--- /dev/null
+++ b/server/storage/data/generate/im_tenant_merge_config_cleanup.sql
@@ -0,0 +1,9 @@
+-- 第二阶段:新版 manager 与 IM Server 全部发布并验证后执行。
+-- 清理已废弃的商户配置表和按商户选库字段。
+
+DROP TABLE `im_tenant_config`;
+
+ALTER TABLE `im_tenant`
+ DROP INDEX `idx_im_tenant_db_name`,
+ DROP COLUMN `db_name`,
+ DROP COLUMN `db_dsn`;
diff --git a/web/src/views/imTenant/edit.vue b/web/src/views/imTenant/edit.vue
index 9aa57fc..ef026fb 100644
--- a/web/src/views/imTenant/edit.vue
+++ b/web/src/views/imTenant/edit.vue
@@ -42,20 +42,6 @@
/>
-
-
-
-
-
-
-
-
-
-
@@ -171,7 +157,7 @@
import { computed, ref, watch } from 'vue';
import { useDictStore } from '@/store/modules/dict';
import { Add, Edit, View } from '@/api/imTenant';
- import { isAdminSuper, newState, rules, State } from './model';
+ import { newState, rules, State } from './model';
import { useProjectSettingStore } from '@/store/modules/projectSetting';
import { useMessage } from 'naive-ui';
import { adaModalWidth } from '@/utils/hotgo';
diff --git a/web/src/views/imTenant/index.vue b/web/src/views/imTenant/index.vue
index c6c1469..4de83f5 100644
--- a/web/src/views/imTenant/index.vue
+++ b/web/src/views/imTenant/index.vue
@@ -52,7 +52,7 @@
import { useDictStore } from '@/store/modules/dict';
import { List, Restore, Status } from '@/api/imTenant';
import { PlusOutlined } from '@vicons/antd';
- import { buildColumns, isAdminSuper, loadOptions, schemas, State } from './model';
+ import { buildColumns, loadOptions, schemas, State } from './model';
import { adaTableScrollX } from '@/utils/hotgo';
import Edit from './edit.vue';
import UsageModal from './usage.vue';
@@ -116,8 +116,7 @@
},
});
- // 业务库名列仅admin超管可见
- const columns = computed(() => buildColumns(isAdminSuper.value));
+ const columns = computed(() => buildColumns());
const scrollX = computed(() => {
return adaTableScrollX(columns.value, actionColumn.width);
@@ -126,8 +125,7 @@
const [register, {}] = useForm({
gridProps: { cols: '1 s:1 m:2 l:3 xl:4 2xl:4' },
labelWidth: 90,
- // 业务库名搜索项仅admin超管可见
- schemas: schemas.value.filter((item) => item.field !== 'dbName' || isAdminSuper.value),
+ schemas: schemas.value,
});
// 加载表格数据
diff --git a/web/src/views/imTenant/model.ts b/web/src/views/imTenant/model.ts
index 5ca2cf4..0c12da3 100644
--- a/web/src/views/imTenant/model.ts
+++ b/web/src/views/imTenant/model.ts
@@ -1,25 +1,18 @@
-import { computed, h, ref } from 'vue';
+import { h, ref } from 'vue';
import { NTag } from 'naive-ui';
import { cloneDeep } from 'lodash-es';
import { FormSchema } from '@/components/Form';
import { defRangeShortcuts } from '@/utils/dateUtil';
import { renderPopoverMemberSumma, MemberSumma } from '@/utils';
import { useDictStore } from '@/store/modules/dict';
-import { useUserStore } from '@/store/modules/user';
const dict = useDictStore();
-const userStore = useUserStore();
-
-// 是否admin超管(业务库名/独立连接串仅超管可见可编辑)
-export const isAdminSuper = computed(() => userStore.getUserInfo?.username === 'admin');
export class State {
public id = 0; // ID
public code = ''; // 商户编码
public name = ''; // 商户名称
public tenantDesc = ''; // 商户描述
- public dbName = ''; // 业务库名
- public dbDsn = ''; // 独立连接串
public adminUsername = ''; // 新增商户时创建的后台管理员账号
public adminPassword = ''; // 新增商户时创建的后台管理员初始密码
public state = 1; // 状态
@@ -30,7 +23,6 @@ export class State {
public localModerationEnabled = 0; // 是否启用本地内容审核
public messageEncryptionEnabled = 0; // 是否启用消息加密
public realnameReviewPolicy = 0; // 实名审核策略
- public dbDsnConfigured = false; // 是否配置独立连接串
public createdBy = 0; // 创建者
public createdBySumma?: null | MemberSumma = null; // 创建者摘要信息
public updatedBy = 0; // 更新者
@@ -49,8 +41,6 @@ export class UsageState {
public id = 0;
public code = '';
public name = '';
- public dbName = '';
- public dbDsnConfigured = false;
public dbReachable = false;
public dbCheckError = '';
public schemaVersion = '';
@@ -126,14 +116,6 @@ export const schemas = ref([
placeholder: '请输入商户名称',
},
},
- {
- field: 'dbName',
- component: 'NInput',
- label: '业务库名',
- componentProps: {
- placeholder: '请输入业务库名',
- },
- },
{
field: 'state',
component: 'NSelect',
@@ -185,25 +167,6 @@ const baseColumns = [
return dict.getLabel('ImTenantStateOptions', row.state);
},
},
- {
- title: '业务库名',
- key: 'dbName',
- align: 'left',
- width: 160,
- },
- {
- title: '独立连接串',
- key: 'dbDsnConfigured',
- align: 'left',
- width: 120,
- render(row: State) {
- return h(
- NTag,
- { type: row.dbDsnConfigured ? 'success' : 'default', bordered: false },
- { default: () => (row.dbDsnConfigured ? '已配置' : '未配置') }
- );
- },
- },
{
title: '最大用户',
key: 'maxUsers',
@@ -297,12 +260,8 @@ const baseColumns = [
},
];
-// 业务库名与独立连接串列仅admin超管可见
-export function buildColumns(isAdmin: boolean) {
- if (isAdmin) {
- return baseColumns;
- }
- return baseColumns.filter((item) => item.key !== 'dbName' && item.key !== 'dbDsnConfigured');
+export function buildColumns() {
+ return baseColumns;
}
// 加载字典数据选项
diff --git a/web/src/views/imTenant/usage.vue b/web/src/views/imTenant/usage.vue
index c1ac175..fbee632 100644
--- a/web/src/views/imTenant/usage.vue
+++ b/web/src/views/imTenant/usage.vue
@@ -11,10 +11,6 @@
{{ usage.name || current.name }}
{{ usage.code || current.code }}
- {{ usage.dbName || '-' }}
-
- {{ usage.dbDsnConfigured ? '已配置' : '未配置' }}
-
{{ usage.dbReachable ? '可达' : '不可达' }}