This commit is contained in:
Austin
2026-09-21 09:28:09 +08:00
28 changed files with 1607 additions and 142 deletions
+17 -1
View File
@@ -30,6 +30,11 @@ func init() {
// Delete 删除
func (s *sSysDictData) Delete(ctx context.Context, in *sysin.DictDataDeleteInp) error {
if count, err := dao.SysDictData.Ctx(ctx).WherePri(in.Id).Where(dao.SysDictData.Columns().Type, consts.ImInternalSecretDictType).Count(); err != nil {
return gerror.Wrap(err, consts.ErrorORM)
} else if count > 0 {
return gerror.New("内部密钥字典禁止通过通用接口操作")
}
_, err := dao.SysDictData.Ctx(ctx).Where("id", in.Id).Delete()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
@@ -42,6 +47,11 @@ func (s *sSysDictData) Delete(ctx context.Context, in *sysin.DictDataDeleteInp)
func (s *sSysDictData) Edit(ctx context.Context, in *sysin.DictDataEditInp) (err error) {
// 修改
if in.Id > 0 {
if count, queryErr := dao.SysDictData.Ctx(ctx).WherePri(in.Id).Where(dao.SysDictData.Columns().Type, consts.ImInternalSecretDictType).Count(); queryErr != nil {
return gerror.Wrap(queryErr, consts.ErrorORM)
} else if count > 0 {
return gerror.New("内部密钥字典禁止通过通用接口操作")
}
_, err = dao.SysDictData.Ctx(ctx).Fields(sysin.DictDataUpdateFields{}).WherePri(in.Id).Data(in).Update()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
@@ -60,6 +70,9 @@ func (s *sSysDictData) Edit(ctx context.Context, in *sysin.DictDataEditInp) (err
if in.Type == "" {
return gerror.Wrap(err, "类型选择无效,请检查")
}
if in.Type == consts.ImInternalSecretDictType {
return gerror.New("内部密钥字典禁止通过通用接口操作")
}
_, err = dao.SysDictData.Ctx(ctx).Fields(sysin.DictDataInsertFields{}).Data(in).OmitEmptyData().Insert()
if err != nil {
@@ -71,7 +84,7 @@ func (s *sSysDictData) Edit(ctx context.Context, in *sysin.DictDataEditInp) (err
// List 获取列表
func (s *sSysDictData) List(ctx context.Context, in *sysin.DictDataListInp) (list []*sysin.DictDataListModel, totalCount int, err error) {
mod := dao.SysDictData.Ctx(ctx)
mod := dao.SysDictData.Ctx(ctx).WhereNot(dao.SysDictData.Columns().Type, consts.ImInternalSecretDictType)
// 类型ID
if in.TypeID > 0 {
types, err := s.GetTypes(ctx, in.TypeID)
@@ -151,6 +164,9 @@ func (s *sSysDictData) GetTypes(ctx context.Context, id int64) (types []string,
// Select 获取列表
func (s *sSysDictData) Select(ctx context.Context, in *sysin.DataSelectInp) (list sysin.DataSelectModel, err error) {
if in.Type == consts.ImInternalSecretDictType {
return nil, gerror.New("内部密钥字典禁止通过通用接口读取")
}
// 优先从内置字典中获取
options, err := dict.GetOptions(ctx, in.Type)
if err == nil {
+17 -2
View File
@@ -31,7 +31,7 @@ func init() {
// Tree 树
func (s *sSysDictType) Tree(ctx context.Context) (list []*sysin.DictTypeTree, err error) {
var (
mod = dao.SysDictType.Ctx(ctx)
mod = dao.SysDictType.Ctx(ctx).WhereNot(dao.SysDictType.Columns().Type, consts.ImInternalSecretDictType)
models []*entity.SysDictType
)
@@ -55,6 +55,9 @@ func (s *sSysDictType) Delete(ctx context.Context, in *sysin.DictTypeDeleteInp)
err = gerror.New("数据不存在或已删除!")
return
}
if models.Type == consts.ImInternalSecretDictType {
return gerror.New("内部密钥字典禁止通过通用接口操作")
}
exist, err := dao.SysDictData.Ctx(ctx).Where("type", models.Type).One()
if err != nil {
@@ -83,6 +86,18 @@ func (s *sSysDictType) Delete(ctx context.Context, in *sysin.DictTypeDeleteInp)
// Edit 修改/新增
func (s *sSysDictType) Edit(ctx context.Context, in *sysin.DictTypeEditInp) (err error) {
if in.Type == consts.ImInternalSecretDictType {
return gerror.New("内部密钥字典禁止通过通用接口操作")
}
if in.Id > 0 {
count, queryErr := dao.SysDictType.Ctx(ctx).WherePri(in.Id).Where(dao.SysDictType.Columns().Type, consts.ImInternalSecretDictType).Count()
if queryErr != nil {
return gerror.Wrap(queryErr, consts.ErrorORM)
}
if count > 0 {
return gerror.New("内部密钥字典禁止通过通用接口操作")
}
}
if err = hgorm.IsUnique(ctx, &dao.SysDictType, g.Map{dao.SysDictType.Columns().Name: in.Name}, "名称已存在", in.Id); err != nil {
return
}
@@ -105,7 +120,7 @@ func (s *sSysDictType) Edit(ctx context.Context, in *sysin.DictTypeEditInp) (err
// TreeSelect 获取类型关系树选项
func (s *sSysDictType) TreeSelect(ctx context.Context, in *sysin.DictTreeSelectInp) (list []*sysin.DictTypeTree, err error) {
var (
mod = dao.SysDictType.Ctx(ctx)
mod = dao.SysDictType.Ctx(ctx).WhereNot(dao.SysDictType.Columns().Type, consts.ImInternalSecretDictType)
models []*entity.SysDictType
)
@@ -71,6 +71,9 @@ func isImPlatformAdmin(ctx context.Context, operatorId int64) bool {
if service.AdminMember().VerifySuperId(ctx, operatorId) {
return true
}
if contexts.GetRoleKey(ctx) == consts.ImPlatformRoleKey {
return true
}
return contexts.IsCompanyDept(ctx) && contexts.GetTenantId(ctx) <= 0
}
@@ -0,0 +1,298 @@
package sys
import (
"context"
"hotgo/internal/consts"
"hotgo/internal/dao"
"hotgo/internal/library/contexts"
"hotgo/internal/library/immessagecrypto"
"hotgo/internal/library/imtenant"
"hotgo/internal/model/entity"
"hotgo/internal/model/input/sysin"
"hotgo/internal/service"
"strings"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
const (
imMessageEncryptionKeyTable = "im_message_encryption_keys"
imTenantMessageEncryptionColumn = "message_encryption_enabled"
)
type sSysImMessageEncryption struct{}
func NewSysImMessageEncryption() *sSysImMessageEncryption { return &sSysImMessageEncryption{} }
func init() {
service.RegisterSysImMessageEncryption(NewSysImMessageEncryption())
}
func (s *sSysImMessageEncryption) List(ctx context.Context, in *sysin.ImMessageEncryptionListInp) (list []*sysin.ImMessageEncryptionListModel, total int, err error) {
if err = in.Filter(ctx); err != nil {
return
}
if err = s.requireSuperAdmin(ctx); err != nil {
return nil, 0, err
}
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",
"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",
"(SELECT MAX(COALESCE(k.activated_at,k.created_at)) FROM "+imMessageEncryptionKeyTable+" k WHERE k.tenant_id=t.id) last_rotated_at",
)
if in.TenantId > 0 {
mod = mod.Where("t.id", in.TenantId)
}
if keyword := strings.TrimSpace(in.Keyword); keyword != "" {
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)
}
if err = mod.Page(in.Page, in.PerPage).OrderAsc("t.id").ScanAndCount(&list, &total, false); err != nil {
return nil, 0, gerror.Wrap(err, "获取商户消息加密配置失败")
}
return
}
func (s *sSysImMessageEncryption) Initialize(ctx context.Context, in *sysin.ImMessageEncryptionActionInp) error {
if err := in.Filter(ctx); err != nil {
return err
}
if err := s.requireSuperAdmin(ctx); err != nil {
return err
}
tenant, err := s.tenantByID(ctx, in.TenantId)
if err != nil {
return err
}
dek, err := immessagecrypto.GenerateDEK()
if err != nil {
return err
}
ciphertext, nonce, err := immessagecrypto.WrapDEK(ctx, tenant.Id, 1, dek)
if err != nil {
return err
}
err = imtenant.RegistryDB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
count, queryErr := tx.Model(imMessageEncryptionKeyTable).Safe().Ctx(ctx).Where("tenant_id", tenant.Id).Count()
if queryErr != nil {
return gerror.Wrap(queryErr, "检查商户消息密钥失败")
}
if count > 0 {
return gerror.New("该商户已经初始化消息密钥")
}
_, insertErr := tx.Model(imMessageEncryptionKeyTable).Safe().Ctx(ctx).Data(g.Map{
"tenant_id": tenant.Id, "key_version": 1, "algorithm": consts.ImMessageKeyAlgorithm,
"encrypted_dek": ciphertext, "dek_nonce": nonce, "status": consts.ImMessageKeyStatusActive,
"created_at": gtime.Now(), "activated_at": gtime.Now(), "created_by": contexts.GetUserId(ctx),
"remark": strings.TrimSpace(in.Remark),
}).Insert()
if insertErr != nil {
return gerror.Wrap(insertErr, "初始化商户消息密钥失败")
}
return nil
})
if err != nil {
return err
}
_ = writeImAdminAudit(ctx, tenant.Id, "message_key_initialize", imMessageEncryptionKeyTable, 0, "success", g.Map{"version": 1})
return publishImPolicyEvent(ctx, tenant.Id, tenant.Code, "message.keys.updated", "message_encryption", 1)
}
func (s *sSysImMessageEncryption) Rotate(ctx context.Context, in *sysin.ImMessageEncryptionActionInp) error {
if err := in.Filter(ctx); err != nil {
return err
}
if err := s.requireSuperAdmin(ctx); err != nil {
return err
}
tenant, err := s.tenantByID(ctx, in.TenantId)
if err != nil {
return err
}
var version uint
err = imtenant.RegistryDB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
pending, queryErr := tx.Model(imMessageEncryptionKeyTable).Safe().Ctx(ctx).
Where("tenant_id", tenant.Id).Where("status", consts.ImMessageKeyStatusPending).Count()
if queryErr != nil {
return gerror.Wrap(queryErr, "检查待激活消息密钥失败")
}
if pending > 0 {
return gerror.New("该商户已有待激活密钥,请等待IM Server确认")
}
value, queryErr := tx.Model(imMessageEncryptionKeyTable).Safe().Ctx(ctx).
Fields("COALESCE(MAX(key_version),0)").Where("tenant_id", tenant.Id).Value()
if queryErr != nil {
return gerror.Wrap(queryErr, "获取消息密钥版本失败")
}
if value.Uint() == 0 {
return gerror.New("请先初始化商户消息密钥")
}
version = value.Uint() + 1
dek, generateErr := immessagecrypto.GenerateDEK()
if generateErr != nil {
return generateErr
}
ciphertext, nonce, wrapErr := immessagecrypto.WrapDEK(ctx, tenant.Id, version, dek)
if wrapErr != nil {
return wrapErr
}
_, insertErr := tx.Model(imMessageEncryptionKeyTable).Safe().Ctx(ctx).Data(g.Map{
"tenant_id": tenant.Id, "key_version": version, "algorithm": consts.ImMessageKeyAlgorithm,
"encrypted_dek": ciphertext, "dek_nonce": nonce, "status": consts.ImMessageKeyStatusPending,
"created_at": gtime.Now(), "created_by": contexts.GetUserId(ctx), "remark": strings.TrimSpace(in.Remark),
}).Insert()
if insertErr != nil {
return gerror.Wrap(insertErr, "创建待激活消息密钥失败")
}
return nil
})
if err != nil {
return err
}
_ = writeImAdminAudit(ctx, tenant.Id, "message_key_rotate", imMessageEncryptionKeyTable, 0, "success", g.Map{"version": version, "status": consts.ImMessageKeyStatusPending})
return publishImPolicyEvent(ctx, tenant.Id, tenant.Code, "message.keys.updated", "message_encryption", version)
}
func (s *sSysImMessageEncryption) Switch(ctx context.Context, in *sysin.ImMessageEncryptionSwitchInp) error {
if err := in.Filter(ctx); err != nil {
return err
}
if err := s.requireSuperAdmin(ctx); err != nil {
return err
}
tenant, err := s.tenantByID(ctx, in.TenantId)
if err != nil {
return err
}
if in.Enabled == 1 {
count, queryErr := imtenant.RegistryDB().Model(imMessageEncryptionKeyTable).Safe().Ctx(ctx).
Where("tenant_id", tenant.Id).Where("status", consts.ImMessageKeyStatusActive).Count()
if queryErr != nil {
return gerror.Wrap(queryErr, "检查商户消息密钥失败")
}
if count == 0 {
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()
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})
return publishImPolicyEvent(ctx, tenant.Id, tenant.Code, "tenant.features.updated", "message_encryption", 0)
}
func (s *sSysImMessageEncryption) GetKey(ctx context.Context, in *sysin.ImMessageKeyGetInp) (*sysin.ImMessageKeyModel, error) {
tenant, err := s.tenantByCode(ctx, in.TenantCode)
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()
if err != nil {
return nil, gerror.Wrap(err, "获取商户消息加密开关失败")
}
mod := imtenant.RegistryDB().Model(imMessageEncryptionKeyTable).Safe().Ctx(ctx).Where("tenant_id", tenant.Id)
if in.Version > 0 {
mod = mod.Where("key_version", in.Version).WhereIn("status", []string{consts.ImMessageKeyStatusPending, consts.ImMessageKeyStatusActive, consts.ImMessageKeyStatusRetired})
} else {
mod = mod.Where("status", consts.ImMessageKeyStatusActive).OrderDesc("key_version")
}
row, err := mod.One()
if err != nil {
return nil, gerror.Wrap(err, "获取商户消息密钥失败")
}
if row.IsEmpty() {
return nil, gerror.New("商户消息密钥不存在")
}
version := row["key_version"].Uint()
dek, err := immessagecrypto.UnwrapDEK(ctx, tenant.Id, version, row["encrypted_dek"].Bytes(), row["dek_nonce"].Bytes())
if err != nil {
return nil, err
}
return &sysin.ImMessageKeyModel{
TenantId: tenant.Id, TenantCode: tenant.Code, Enabled: enabledValue.Int() == 1,
Version: version, Algorithm: row["algorithm"].String(), Status: row["status"].String(), Key: immessagecrypto.EncodeDEK(dek),
}, nil
}
func (s *sSysImMessageEncryption) Ack(ctx context.Context, in *sysin.ImMessageKeyAckInp) error {
tenant, err := s.tenantByCode(ctx, in.TenantCode)
if err != nil {
return err
}
if in.Version == 0 {
return gerror.New("消息密钥版本不能为空")
}
err = imtenant.RegistryDB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
row, queryErr := tx.Model(imMessageEncryptionKeyTable).Safe().Ctx(ctx).
Where("tenant_id", tenant.Id).Where("key_version", in.Version).One()
if queryErr != nil {
return gerror.Wrap(queryErr, "获取待激活消息密钥失败")
}
if row.IsEmpty() || row["status"].String() != consts.ImMessageKeyStatusPending {
return gerror.New("待激活消息密钥不存在")
}
if _, updateErr := tx.Model(imMessageEncryptionKeyTable).Safe().Ctx(ctx).
Where("tenant_id", tenant.Id).Where("status", consts.ImMessageKeyStatusActive).
Data(g.Map{"status": consts.ImMessageKeyStatusRetired, "retired_at": gtime.Now()}).Update(); updateErr != nil {
return gerror.Wrap(updateErr, "退役旧消息密钥失败")
}
if _, updateErr := tx.Model(imMessageEncryptionKeyTable).Safe().Ctx(ctx).
Where("tenant_id", tenant.Id).Where("key_version", in.Version).
Data(g.Map{"status": consts.ImMessageKeyStatusActive, "activated_at": gtime.Now()}).Update(); updateErr != nil {
return gerror.Wrap(updateErr, "激活新消息密钥失败")
}
return nil
})
if err != nil {
return err
}
return publishImPolicyEvent(ctx, tenant.Id, tenant.Code, "message.keys.activated", "message_encryption", in.Version)
}
func (s *sSysImMessageEncryption) requireSuperAdmin(ctx context.Context) error {
if !service.AdminMember().VerifySuperId(ctx, contexts.GetUserId(ctx)) {
return gerror.New("只有最高权限平台管理员可以管理消息密钥")
}
return nil
}
func (s *sSysImMessageEncryption) tenantByID(ctx context.Context, tenantID int64) (*entity.ImTenant, error) {
var tenant *entity.ImTenant
if err := imtenant.RegistryDB().Model(dao.ImTenant.Table()).Safe().Ctx(ctx).WherePri(tenantID).Scan(&tenant); err != nil {
return nil, gerror.Wrap(err, "获取商户失败")
}
if tenant == nil || tenant.Id == 0 {
return nil, gerror.New("商户不存在")
}
return tenant, nil
}
func (s *sSysImMessageEncryption) tenantByCode(ctx context.Context, code string) (*entity.ImTenant, error) {
var tenant *entity.ImTenant
if err := imtenant.RegistryDB().Model(dao.ImTenant.Table()).Safe().Ctx(ctx).
Where(dao.ImTenant.Columns().Code, strings.TrimSpace(code)).Scan(&tenant); err != nil {
return nil, gerror.Wrap(err, "获取商户失败")
}
if tenant == nil || tenant.Id == 0 {
return nil, gerror.New("商户不存在")
}
return tenant, nil
}
+46 -19
View File
@@ -26,18 +26,22 @@ import (
type sSysImTenant struct{}
const (
tenantConfigAliyunModerationEnabled = "aliyun_moderation_enabled"
tenantConfigLocalModerationEnabled = "local_moderation_enabled"
tenantConfigAliyunModerationEnabled = "aliyun_moderation_enabled"
tenantConfigLocalModerationEnabled = "local_moderation_enabled"
tenantConfigMessageEncryptionEnabled = "message_encryption_enabled"
tenantConfigRealnameReviewPolicy = "realname_review_policy"
)
type imTenantConfigModeration struct {
Id int64 `json:"id"`
TenantId int64 `json:"tenant_id"`
MaxUsers uint64 `json:"max_users"`
MaxGroups uint64 `json:"max_groups"`
MaxGroupMembers uint `json:"max_group_members"`
AliyunModerationEnabled int `json:"aliyun_moderation_enabled"`
LocalModerationEnabled int `json:"local_moderation_enabled"`
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 {
@@ -157,6 +161,8 @@ func (s *sSysImTenant) fillListConfig(ctx context.Context, list []*sysin.ImTenan
item.MaxGroupMembers = conf.MaxGroupMembers
item.AliyunModerationEnabled = conf.AliyunModerationEnabled
item.LocalModerationEnabled = conf.LocalModerationEnabled
item.MessageEncryptionEnabled = conf.MessageEncryptionEnabled
item.RealnameReviewPolicy = conf.RealnameReviewPolicy
}
item.DbDsnConfigured = dsnMap[item.Id] != ""
}
@@ -210,7 +216,7 @@ func (s *sSysImTenant) saveTenant(ctx context.Context, in *sysin.ImTenantEditInp
WherePri(in.Id).Data(in).Update(); err != nil {
return gerror.Wrap(err, "修改IM租户失败,请稍后重试!")
}
return s.saveConfig(ctx, in.Id, in.MaxUsers, in.MaxGroups, in.MaxGroupMembers, in.AliyunModerationEnabled, in.LocalModerationEnabled, userId)
return s.saveConfig(ctx, in, userId)
}
in.CreatedBy = userId
@@ -222,7 +228,8 @@ func (s *sSysImTenant) saveTenant(ctx context.Context, in *sysin.ImTenantEditInp
return gerror.Wrap(err, "新增IM租户失败,请稍后重试!")
}
tenantID = id
return s.saveConfig(ctx, id, in.MaxUsers, in.MaxGroups, in.MaxGroupMembers, in.AliyunModerationEnabled, in.LocalModerationEnabled, userId)
in.Id = id
return s.saveConfig(ctx, in, userId)
})
if err != nil {
return err
@@ -246,20 +253,34 @@ func (s *sSysImTenant) checkCodeUnique(ctx context.Context, id int64, code strin
return
}
func (s *sSysImTenant) saveConfig(ctx context.Context, tenantId int64, maxUsers uint64, maxGroups uint64, maxGroupMembers uint, aliyunModerationEnabled, localModerationEnabled int, userId int64) (err error) {
func (s *sSysImTenant) saveConfig(ctx context.Context, in *sysin.ImTenantEditInp, userId int64) (err error) {
if in.MessageEncryptionEnabled == 1 {
count, queryErr := imtenant.RegistryDB().Model(imMessageEncryptionKeyTable).Safe().Ctx(ctx).
Where("tenant_id", in.Id).
Where("status", consts.ImMessageKeyStatusActive).
Count()
if queryErr != nil {
return gerror.Wrap(queryErr, "检查商户消息密钥失败")
}
if count == 0 {
return gerror.New("启用消息加密前必须先在消息密钥管理中初始化有效密钥")
}
}
var conf *entity.ImTenantConfig
if err = s.configModel(ctx).
Where(dao.ImTenantConfig.Columns().TenantId, tenantId).
Where(dao.ImTenantConfig.Columns().TenantId, in.Id).
Scan(&conf); err != nil {
return gerror.Wrap(err, "获取IM租户配置失败,请稍后重试!")
}
data := g.Map{
dao.ImTenantConfig.Columns().MaxUsers: maxUsers,
dao.ImTenantConfig.Columns().MaxGroups: maxGroups,
dao.ImTenantConfig.Columns().MaxGroupMembers: maxGroupMembers,
tenantConfigAliyunModerationEnabled: aliyunModerationEnabled,
tenantConfigLocalModerationEnabled: localModerationEnabled,
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
@@ -270,6 +291,8 @@ func (s *sSysImTenant) saveConfig(ctx context.Context, tenantId int64, maxUsers
dao.ImTenantConfig.Columns().MaxGroupMembers,
tenantConfigAliyunModerationEnabled,
tenantConfigLocalModerationEnabled,
tenantConfigMessageEncryptionEnabled,
tenantConfigRealnameReviewPolicy,
dao.ImTenantConfig.Columns().UpdatedBy,
).
WherePri(conf.Id).Data(data).Update(); err != nil {
@@ -278,7 +301,7 @@ func (s *sSysImTenant) saveConfig(ctx context.Context, tenantId int64, maxUsers
return
}
data[dao.ImTenantConfig.Columns().TenantId] = tenantId
data[dao.ImTenantConfig.Columns().TenantId] = in.Id
data[dao.ImTenantConfig.Columns().CreatedBy] = userId
data[dao.ImTenantConfig.Columns().UpdatedBy] = userId
if _, err = s.configModel(ctx).
@@ -289,6 +312,8 @@ func (s *sSysImTenant) saveConfig(ctx context.Context, tenantId int64, maxUsers
dao.ImTenantConfig.Columns().MaxGroupMembers,
tenantConfigAliyunModerationEnabled,
tenantConfigLocalModerationEnabled,
tenantConfigMessageEncryptionEnabled,
tenantConfigRealnameReviewPolicy,
dao.ImTenantConfig.Columns().CreatedBy,
dao.ImTenantConfig.Columns().UpdatedBy,
).
@@ -324,6 +349,8 @@ func (s *sSysImTenant) View(ctx context.Context, in *sysin.ImTenantViewInp) (res
res.MaxGroupMembers = conf.MaxGroupMembers
res.AliyunModerationEnabled = conf.AliyunModerationEnabled
res.LocalModerationEnabled = conf.LocalModerationEnabled
res.MessageEncryptionEnabled = conf.MessageEncryptionEnabled
res.RealnameReviewPolicy = conf.RealnameReviewPolicy
}
res.DbDsnConfigured = res.DbDsn != ""
return