feat: add IM file policy and org exports
This commit is contained in:
@@ -0,0 +1,169 @@
|
||||
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: "反馈附件默认策略"},
|
||||
}
|
||||
}
|
||||
@@ -2,16 +2,21 @@ package sys
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"hotgo/internal/consts"
|
||||
"hotgo/internal/model/input/form"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
"hotgo/internal/service"
|
||||
"hotgo/utility/convert"
|
||||
"hotgo/utility/excel"
|
||||
"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/gctx"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"github.com/gogf/gf/v2/util/guid"
|
||||
)
|
||||
|
||||
@@ -58,6 +63,27 @@ func (s *sSysImOrg) DepartmentList(ctx context.Context, in *sysin.ImOrgDepartmen
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sSysImOrg) DepartmentExport(ctx context.Context, in *sysin.ImOrgDepartmentListInp) (err error) {
|
||||
list, totalCount, err := s.DepartmentList(ctx, in)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
tags, err := convert.GetEntityDescTags(sysin.ImOrgDepartmentExportModel{})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var exports []sysin.ImOrgDepartmentExportModel
|
||||
if err = gconv.Scan(list, &exports); err != nil {
|
||||
return
|
||||
}
|
||||
fileName := "导出IM组织部门-" + gctx.CtxId(ctx)
|
||||
sheetName := fmt.Sprintf("索引条件共%v行,共%v页,当前导出是第%v页,本页共%v行", totalCount, form.CalPageCount(totalCount, in.PerPage), in.Page, len(list))
|
||||
if len(list) > 0 {
|
||||
_ = writeImAdminAudit(ctx, list[0].TenantId, "im_org_department_export", "im_org_department", 0, "success", g.Map{"count": len(list)})
|
||||
}
|
||||
return excel.ExportByStructs(ctx, tags, exports, fileName, sheetName)
|
||||
}
|
||||
|
||||
func (s *sSysImOrg) DepartmentEdit(ctx context.Context, in *sysin.ImOrgDepartmentEditInp) (err error) {
|
||||
if err = in.Filter(ctx); err != nil {
|
||||
return
|
||||
@@ -199,6 +225,27 @@ func (s *sSysImOrg) MemberList(ctx context.Context, in *sysin.ImOrgMemberListInp
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sSysImOrg) MemberExport(ctx context.Context, in *sysin.ImOrgMemberListInp) (err error) {
|
||||
list, totalCount, err := s.MemberList(ctx, in)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
tags, err := convert.GetEntityDescTags(sysin.ImOrgMemberExportModel{})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var exports []sysin.ImOrgMemberExportModel
|
||||
if err = gconv.Scan(list, &exports); err != nil {
|
||||
return
|
||||
}
|
||||
fileName := "导出IM组织成员-" + gctx.CtxId(ctx)
|
||||
sheetName := fmt.Sprintf("索引条件共%v行,共%v页,当前导出是第%v页,本页共%v行", totalCount, form.CalPageCount(totalCount, in.PerPage), in.Page, len(list))
|
||||
if len(list) > 0 {
|
||||
_ = writeImAdminAudit(ctx, list[0].TenantId, "im_org_member_export", "im_org_member", 0, "success", g.Map{"count": len(list), "department_id": in.DepartmentId})
|
||||
}
|
||||
return excel.ExportByStructs(ctx, tags, exports, fileName, sheetName)
|
||||
}
|
||||
|
||||
func (s *sSysImOrg) MemberEdit(ctx context.Context, in *sysin.ImOrgMemberEditInp) (err error) {
|
||||
if err = in.Filter(ctx); err != nil {
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user