Files
im_manager/server/internal/logic/sys/im_file_policy.go
T

170 lines
5.7 KiB
Go

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/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
type sSysImFilePolicy struct{}
func NewSysImFilePolicy() *sSysImFilePolicy {
return &sSysImFilePolicy{}
}
func init() {
service.RegisterSysImFilePolicy(NewSysImFilePolicy())
}
func (s *sSysImFilePolicy) List(ctx context.Context, in *sysin.ImFilePolicyListInp) (list []*sysin.ImFilePolicyListModel, 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.Purpose != "" {
mod = mod.Where("purpose", in.Purpose)
}
if in.AutoCleanup != nil {
mod = mod.Where("auto_cleanup", *in.AutoCleanup)
}
if in.ScanEnabled != nil {
mod = mod.Where("scan_enabled", *in.ScanEnabled)
}
mod = mod.Page(in.Page, in.PerPage).OrderAsc("id")
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 *sSysImFilePolicy) Update(ctx context.Context, in *sysin.ImFilePolicyUpdateInp) (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
}
allowedMimes := "[]"
if in.AllowedMimes != nil && in.AllowedMimes.String() != "" && in.AllowedMimes.String() != "null" {
allowedMimes = in.AllowedMimes.String()
}
if _, err = imtenant.RegistryDB().Model("im_file_policy").Safe().Ctx(ctx).
Where("tenant_id", tenant.Id).
Where("purpose", in.Purpose).
Data(g.Map{
"max_size": in.MaxSize,
"retention_days": in.RetentionDays,
"allowed_mimes": allowedMimes,
"auto_cleanup": in.AutoCleanup,
"scan_enabled": in.ScanEnabled,
"remark": in.Remark,
"updated_at": gtime.Now(),
"updated_by": contexts.GetUserId(ctx),
}).Update(); err != nil {
return gerror.Wrap(err, "更新IM文件策略失败,请稍后重试!")
}
_ = writeImAdminAudit(ctx, tenant.Id, "im_file_policy_update", "im_file_policy", 0, "success", g.Map{
"purpose": in.Purpose, "auto_cleanup": in.AutoCleanup, "scan_enabled": in.ScanEnabled,
})
return nil
}
func (s *sSysImFilePolicy) model(ctx context.Context) *gdb.Model {
return imtenant.RegistryDB().Model("im_file_policy").Safe().Ctx(ctx).Fields(
"id",
"tenant_id",
"purpose",
"max_size",
"retention_days",
"CAST(allowed_mimes AS CHAR) allowed_mimes",
"auto_cleanup",
"scan_enabled",
"remark",
"updated_at",
)
}
func (s *sSysImFilePolicy) 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 *sSysImFilePolicy) ensureRows(ctx context.Context, tenantId int64) error {
for _, item := range defaultFilePolicies() {
count, err := imtenant.RegistryDB().Model("im_file_policy").Safe().Ctx(ctx).
Where("tenant_id", tenantId).
Where("purpose", item.Purpose).
Count()
if err != nil {
return gerror.Wrap(err, "检查IM文件策略失败")
}
if count > 0 {
continue
}
_, err = imtenant.RegistryDB().Exec(ctx, `INSERT INTO im_file_policy
(tenant_id,purpose,max_size,retention_days,allowed_mimes,auto_cleanup,scan_enabled,remark,created_by,updated_by)
VALUES(?,?,?,?,CAST(? AS JSON),?,?,?,?,?)`,
tenantId, item.Purpose, item.MaxSize, item.RetentionDays, item.AllowedMimes, item.AutoCleanup, item.ScanEnabled, item.Remark, contexts.GetUserId(ctx), contexts.GetUserId(ctx))
if err != nil {
return gerror.Wrap(err, "初始化IM文件策略失败")
}
}
return nil
}
type filePolicySeed struct {
Purpose string
MaxSize int64
RetentionDays int
AllowedMimes string
AutoCleanup int
ScanEnabled int
Remark string
}
func defaultFilePolicies() []*filePolicySeed {
const mb = 1024 * 1024
return []*filePolicySeed{
{Purpose: consts.ImFilePurposeChat, MaxSize: 100 * mb, RetentionDays: 365, AllowedMimes: "[]", AutoCleanup: 0, ScanEnabled: 0, Remark: "聊天附件默认策略"},
{Purpose: consts.ImFilePurposeUserAvatar, MaxSize: 5 * mb, RetentionDays: 0, AllowedMimes: `["image/jpeg","image/png","image/webp"]`, AutoCleanup: 0, ScanEnabled: 0, Remark: "用户头像长期保留"},
{Purpose: consts.ImFilePurposeGroupAvatar, MaxSize: 5 * mb, RetentionDays: 0, AllowedMimes: `["image/jpeg","image/png","image/webp"]`, AutoCleanup: 0, ScanEnabled: 0, Remark: "群头像长期保留"},
{Purpose: consts.ImFilePurposeGroupFile, MaxSize: 200 * mb, RetentionDays: 365, AllowedMimes: "[]", AutoCleanup: 0, ScanEnabled: 0, Remark: "群文件默认策略"},
{Purpose: consts.ImFilePurposeAbuseEvidence, MaxSize: 50 * mb, RetentionDays: 730, AllowedMimes: "[]", AutoCleanup: 0, ScanEnabled: 0, Remark: "举报证据默认策略"},
{Purpose: consts.ImFilePurposeFeedback, MaxSize: 50 * mb, RetentionDays: 365, AllowedMimes: "[]", AutoCleanup: 0, ScanEnabled: 0, Remark: "反馈附件默认策略"},
}
}