feat: 完成鸽达达后台安全与审计改造
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
package imdashboard
|
||||
|
||||
import (
|
||||
"hotgo/internal/model/input/sysin"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
type OverviewReq struct {
|
||||
g.Meta `path:"/imDashboard/overview" method:"get" tags:"IM数据概览" summary:"获取IM数据概览"`
|
||||
sysin.ImDashboardOverviewInp
|
||||
}
|
||||
|
||||
type OverviewRes struct {
|
||||
*sysin.ImDashboardOverviewModel
|
||||
}
|
||||
|
||||
type TrendsReq struct {
|
||||
g.Meta `path:"/imDashboard/trends" method:"get" tags:"IM数据概览" summary:"获取IM增长趋势"`
|
||||
sysin.ImDashboardTrendsInp
|
||||
}
|
||||
|
||||
type TrendsRes struct {
|
||||
List []*sysin.ImDashboardTrendModel `json:"list" dc:"趋势数据"`
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package imgroupmessage
|
||||
|
||||
import (
|
||||
"hotgo/internal/model/input/form"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
type ListReq struct {
|
||||
g.Meta `path:"/imGroupMessage/list" method:"get" tags:"IM群聊消息" summary:"获取群聊消息列表"`
|
||||
sysin.ImGroupMessageListInp
|
||||
}
|
||||
type ListRes struct {
|
||||
form.PageRes
|
||||
List []*sysin.ImMessageListModel `json:"list" dc:"数据列表"`
|
||||
}
|
||||
type ViewReq struct {
|
||||
g.Meta `path:"/imGroupMessage/view" method:"get" tags:"IM群聊消息" summary:"获取群聊消息详情"`
|
||||
sysin.ImMessageViewInp
|
||||
}
|
||||
type ViewRes struct{ *sysin.ImMessageViewModel }
|
||||
type HideReq struct {
|
||||
g.Meta `path:"/imGroupMessage/hide" method:"post" tags:"IM群聊消息" summary:"隐藏群聊消息"`
|
||||
sysin.ImMessageActionInp
|
||||
}
|
||||
type HideRes struct{ *sysin.ImMessageCommandModel }
|
||||
type DeleteReq struct {
|
||||
g.Meta `path:"/imGroupMessage/delete" method:"post" tags:"IM群聊消息" summary:"删除群聊消息"`
|
||||
sysin.ImMessageActionInp
|
||||
}
|
||||
type DeleteRes struct{ *sysin.ImMessageCommandModel }
|
||||
type ExportReq struct {
|
||||
g.Meta `path:"/imGroupMessage/export" method:"get" tags:"IM群聊消息" summary:"导出群聊消息"`
|
||||
sysin.ImGroupMessageListInp
|
||||
}
|
||||
type ExportRes struct{}
|
||||
@@ -0,0 +1,37 @@
|
||||
package imloginfailurelog
|
||||
|
||||
import (
|
||||
"hotgo/internal/model/input/form"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
type ListReq struct {
|
||||
g.Meta `path:"/imLoginFailureLog/list" method:"get" tags:"IM登录失败日志" summary:"获取登录失败日志"`
|
||||
sysin.ImLoginFailureLogListInp
|
||||
}
|
||||
type ListRes struct {
|
||||
form.PageRes
|
||||
List []*sysin.ImLoginFailureLogModel `json:"list" dc:"数据列表"`
|
||||
}
|
||||
type ViewReq struct {
|
||||
g.Meta `path:"/imLoginFailureLog/view" method:"get" tags:"IM登录失败日志" summary:"获取登录失败详情"`
|
||||
sysin.ImLoginFailureViewInp
|
||||
}
|
||||
type ViewRes struct{ *sysin.ImLoginFailureLogModel }
|
||||
type ExportReq struct {
|
||||
g.Meta `path:"/imLoginFailureLog/export" method:"get" tags:"IM登录失败日志" summary:"导出登录失败日志"`
|
||||
sysin.ImLoginFailureLogListInp
|
||||
}
|
||||
type ExportRes struct{}
|
||||
type AddBlacklistReq struct {
|
||||
g.Meta `path:"/imLoginFailureLog/addBlacklist" method:"post" tags:"IM登录失败日志" summary:"将IP加入黑名单"`
|
||||
sysin.ImLoginFailureAddBlacklistInp
|
||||
}
|
||||
type AddBlacklistRes struct{}
|
||||
type BanUserReq struct {
|
||||
g.Meta `path:"/imLoginFailureLog/banUser" method:"post" tags:"IM登录失败日志" summary:"封禁关联用户"`
|
||||
sysin.ImLoginFailureBanUserInp
|
||||
}
|
||||
type BanUserRes struct{ *sysin.ImUserCommandModel }
|
||||
@@ -0,0 +1,37 @@
|
||||
package imprivatemessage
|
||||
|
||||
import (
|
||||
"hotgo/internal/model/input/form"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
type ListReq struct {
|
||||
g.Meta `path:"/imPrivateMessage/list" method:"get" tags:"IM单聊消息" summary:"获取单聊消息列表"`
|
||||
sysin.ImPrivateMessageListInp
|
||||
}
|
||||
type ListRes struct {
|
||||
form.PageRes
|
||||
List []*sysin.ImMessageListModel `json:"list" dc:"数据列表"`
|
||||
}
|
||||
type ViewReq struct {
|
||||
g.Meta `path:"/imPrivateMessage/view" method:"get" tags:"IM单聊消息" summary:"获取单聊消息详情"`
|
||||
sysin.ImMessageViewInp
|
||||
}
|
||||
type ViewRes struct{ *sysin.ImMessageViewModel }
|
||||
type HideReq struct {
|
||||
g.Meta `path:"/imPrivateMessage/hide" method:"post" tags:"IM单聊消息" summary:"隐藏单聊消息"`
|
||||
sysin.ImMessageActionInp
|
||||
}
|
||||
type HideRes struct{ *sysin.ImMessageCommandModel }
|
||||
type DeleteReq struct {
|
||||
g.Meta `path:"/imPrivateMessage/delete" method:"post" tags:"IM单聊消息" summary:"删除单聊消息"`
|
||||
sysin.ImMessageActionInp
|
||||
}
|
||||
type DeleteRes struct{ *sysin.ImMessageCommandModel }
|
||||
type ExportReq struct {
|
||||
g.Meta `path:"/imPrivateMessage/export" method:"get" tags:"IM单聊消息" summary:"导出单聊消息"`
|
||||
sysin.ImPrivateMessageListInp
|
||||
}
|
||||
type ExportRes struct{}
|
||||
@@ -0,0 +1,59 @@
|
||||
package imsecuritypolicy
|
||||
|
||||
import (
|
||||
"hotgo/internal/model/input/form"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
type ListReq struct {
|
||||
g.Meta `path:"/imSecurityPolicy/list" method:"get" tags:"IM安全策略" summary:"获取安全策略历史"`
|
||||
sysin.ImSecurityPolicyListInp
|
||||
}
|
||||
type ListRes struct {
|
||||
form.PageRes
|
||||
List []*sysin.ImSecurityPolicyModel `json:"list"`
|
||||
}
|
||||
type ViewReq struct {
|
||||
g.Meta `path:"/imSecurityPolicy/view" method:"get" tags:"IM安全策略" summary:"获取安全策略详情"`
|
||||
sysin.ImSecurityPolicyViewInp
|
||||
}
|
||||
type ViewRes struct{ *sysin.ImSecurityPolicyModel }
|
||||
type SaveReq struct {
|
||||
g.Meta `path:"/imSecurityPolicy/save" method:"post" tags:"IM安全策略" summary:"保存安全策略草稿"`
|
||||
sysin.ImSecurityPolicySaveInp
|
||||
}
|
||||
type SaveRes struct {
|
||||
Id int64 `json:"id"`
|
||||
}
|
||||
type PublishReq struct {
|
||||
g.Meta `path:"/imSecurityPolicy/publish" method:"post" tags:"IM安全策略" summary:"发布安全策略"`
|
||||
sysin.ImSecurityPolicyPublishInp
|
||||
}
|
||||
type PublishRes struct{}
|
||||
type RestoreDefaultReq struct {
|
||||
g.Meta `path:"/imSecurityPolicy/restoreDefault" method:"post" tags:"IM安全策略" summary:"恢复默认安全策略"`
|
||||
sysin.ImSecurityPolicyRestoreInp
|
||||
}
|
||||
type RestoreDefaultRes struct {
|
||||
Id int64 `json:"id"`
|
||||
}
|
||||
type IPRuleListReq struct {
|
||||
g.Meta `path:"/imSecurityPolicy/ipRuleList" method:"get" tags:"IM安全策略" summary:"获取IP黑白名单"`
|
||||
sysin.ImSecurityIPRuleListInp
|
||||
}
|
||||
type IPRuleListRes struct {
|
||||
form.PageRes
|
||||
List []*sysin.ImSecurityIPRuleModel `json:"list"`
|
||||
}
|
||||
type IPRuleEditReq struct {
|
||||
g.Meta `path:"/imSecurityPolicy/ipRuleEdit" method:"post" tags:"IM安全策略" summary:"新增或编辑IP规则"`
|
||||
sysin.ImSecurityIPRuleEditInp
|
||||
}
|
||||
type IPRuleEditRes struct{}
|
||||
type IPRuleDeleteReq struct {
|
||||
g.Meta `path:"/imSecurityPolicy/ipRuleDelete" method:"post" tags:"IM安全策略" summary:"删除IP规则"`
|
||||
sysin.ImSecurityIPRuleDeleteInp
|
||||
}
|
||||
type IPRuleDeleteRes struct{}
|
||||
@@ -0,0 +1,51 @@
|
||||
package imsensitiveword
|
||||
|
||||
import (
|
||||
"hotgo/internal/model/input/form"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
type ListReq struct {
|
||||
g.Meta `path:"/imSensitiveWord/list" method:"get" tags:"IM敏感词" summary:"获取敏感词列表"`
|
||||
sysin.ImSensitiveWordListInp
|
||||
}
|
||||
type ListRes struct {
|
||||
form.PageRes
|
||||
List []*sysin.ImSensitiveWordListModel `json:"list"`
|
||||
}
|
||||
type EditReq struct {
|
||||
g.Meta `path:"/imSensitiveWord/edit" method:"post" tags:"IM敏感词" summary:"新增或编辑敏感词"`
|
||||
sysin.ImSensitiveWordEditInp
|
||||
}
|
||||
type EditRes struct{}
|
||||
type DeleteReq struct {
|
||||
g.Meta `path:"/imSensitiveWord/delete" method:"post" tags:"IM敏感词" summary:"删除敏感词"`
|
||||
sysin.ImSensitiveWordDeleteInp
|
||||
}
|
||||
type DeleteRes struct{}
|
||||
type StatusReq struct {
|
||||
g.Meta `path:"/imSensitiveWord/status" method:"post" tags:"IM敏感词" summary:"更新敏感词状态"`
|
||||
sysin.ImSensitiveWordStatusInp
|
||||
}
|
||||
type StatusRes struct{}
|
||||
type BatchImportReq struct {
|
||||
g.Meta `path:"/imSensitiveWord/batchImport" method:"post" tags:"IM敏感词" summary:"批量导入敏感词"`
|
||||
sysin.ImSensitiveWordBatchImportInp
|
||||
}
|
||||
type BatchImportRes struct {
|
||||
*sysin.ImSensitiveWordBatchImportModel
|
||||
}
|
||||
type GroupListReq struct {
|
||||
g.Meta `path:"/imSensitiveWord/groupList" method:"get" tags:"IM敏感词" summary:"获取敏感词分组"`
|
||||
sysin.ImSensitiveWordGroupListInp
|
||||
}
|
||||
type GroupListRes struct {
|
||||
List []*sysin.ImSensitiveWordGroupModel `json:"list"`
|
||||
}
|
||||
type GroupEditReq struct {
|
||||
g.Meta `path:"/imSensitiveWord/groupEdit" method:"post" tags:"IM敏感词" summary:"新增或编辑敏感词分组"`
|
||||
sysin.ImSensitiveWordGroupEditInp
|
||||
}
|
||||
type GroupEditRes struct{}
|
||||
@@ -0,0 +1,22 @@
|
||||
package imuserloginhistory
|
||||
|
||||
import (
|
||||
"hotgo/internal/model/input/form"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
type ListReq struct {
|
||||
g.Meta `path:"/imUserLoginHistory/list" method:"get" tags:"IM用户登录历史" summary:"获取用户登录历史"`
|
||||
sysin.ImUserLoginHistoryListInp
|
||||
}
|
||||
type ListRes struct {
|
||||
form.PageRes
|
||||
List []*sysin.ImUserLoginHistoryModel `json:"list" dc:"数据列表"`
|
||||
}
|
||||
type ExportReq struct {
|
||||
g.Meta `path:"/imUserLoginHistory/export" method:"get" tags:"IM用户登录历史" summary:"导出用户登录历史"`
|
||||
sysin.ImUserLoginHistoryListInp
|
||||
}
|
||||
type ExportRes struct{}
|
||||
@@ -0,0 +1,57 @@
|
||||
package imuserpolicygroup
|
||||
|
||||
import (
|
||||
"hotgo/internal/model/input/form"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
type ListReq struct {
|
||||
g.Meta `path:"/imUserPolicyGroup/list" method:"get" tags:"IM用户策略分组" summary:"获取用户策略分组列表"`
|
||||
sysin.ImUserPolicyGroupListInp
|
||||
}
|
||||
type ListRes struct {
|
||||
form.PageRes
|
||||
List []*sysin.ImUserPolicyGroupListModel `json:"list"`
|
||||
}
|
||||
type ViewReq struct {
|
||||
g.Meta `path:"/imUserPolicyGroup/view" method:"get" tags:"IM用户策略分组" summary:"获取用户策略分组详情"`
|
||||
sysin.ImUserPolicyGroupViewInp
|
||||
}
|
||||
type ViewRes struct {
|
||||
*sysin.ImUserPolicyGroupViewModel
|
||||
}
|
||||
type EditReq struct {
|
||||
g.Meta `path:"/imUserPolicyGroup/edit" method:"post" tags:"IM用户策略分组" summary:"新增或编辑用户策略分组"`
|
||||
sysin.ImUserPolicyGroupEditInp
|
||||
}
|
||||
type EditRes struct{}
|
||||
type DeleteReq struct {
|
||||
g.Meta `path:"/imUserPolicyGroup/delete" method:"post" tags:"IM用户策略分组" summary:"删除用户策略分组"`
|
||||
sysin.ImUserPolicyGroupDeleteInp
|
||||
}
|
||||
type DeleteRes struct{}
|
||||
type StatusReq struct {
|
||||
g.Meta `path:"/imUserPolicyGroup/status" method:"post" tags:"IM用户策略分组" summary:"更新用户策略分组状态"`
|
||||
sysin.ImUserPolicyGroupStatusInp
|
||||
}
|
||||
type StatusRes struct{}
|
||||
type MemberListReq struct {
|
||||
g.Meta `path:"/imUserPolicyGroup/memberList" method:"get" tags:"IM用户策略分组" summary:"获取策略分组成员"`
|
||||
sysin.ImUserPolicyGroupMemberListInp
|
||||
}
|
||||
type MemberListRes struct {
|
||||
form.PageRes
|
||||
List []*sysin.ImUserPolicyGroupMemberModel `json:"list"`
|
||||
}
|
||||
type MemberAddReq struct {
|
||||
g.Meta `path:"/imUserPolicyGroup/memberAdd" method:"post" tags:"IM用户策略分组" summary:"添加策略分组成员"`
|
||||
sysin.ImUserPolicyGroupMemberAddInp
|
||||
}
|
||||
type MemberAddRes struct{}
|
||||
type MemberRemoveReq struct {
|
||||
g.Meta `path:"/imUserPolicyGroup/memberRemove" method:"post" tags:"IM用户策略分组" summary:"移除策略分组成员"`
|
||||
sysin.ImUserPolicyGroupMemberRemoveInp
|
||||
}
|
||||
type MemberRemoveRes struct{}
|
||||
@@ -0,0 +1,84 @@
|
||||
package consts
|
||||
|
||||
import (
|
||||
"hotgo/internal/library/dict"
|
||||
"hotgo/internal/model"
|
||||
)
|
||||
|
||||
const (
|
||||
ImMessageContentText = "text"
|
||||
ImMessageContentImage = "image"
|
||||
ImMessageContentVideo = "video"
|
||||
ImMessageContentAudio = "audio"
|
||||
ImMessageContentVoice = "voice"
|
||||
ImMessageContentFile = "file"
|
||||
ImMessageContentCard = "card"
|
||||
ImMessageContentSystem = "system"
|
||||
|
||||
ImMessageStatusNormal = "normal"
|
||||
ImMessageStatusDeleted = "deleted"
|
||||
ImMessageStatusRecalled = "recalled"
|
||||
ImMessageStatusBlocked = "blocked"
|
||||
ImMessageStatusHidden = "hidden"
|
||||
)
|
||||
|
||||
var ImMessageContentTypeOptions = []*model.Option{
|
||||
dict.GenInfoOption(ImMessageContentText, "文本"),
|
||||
dict.GenPrimaryOption(ImMessageContentImage, "图片"),
|
||||
dict.GenPrimaryOption(ImMessageContentVideo, "视频"),
|
||||
dict.GenPrimaryOption(ImMessageContentAudio, "语音"),
|
||||
dict.GenPrimaryOption(ImMessageContentVoice, "语音"),
|
||||
dict.GenDefaultOption(ImMessageContentFile, "文件"),
|
||||
dict.GenDefaultOption(ImMessageContentCard, "名片"),
|
||||
dict.GenWarningOption(ImMessageContentSystem, "系统"),
|
||||
}
|
||||
|
||||
var ImMessageStatusOptions = []*model.Option{
|
||||
dict.GenSuccessOption(ImMessageStatusNormal, "正常"),
|
||||
dict.GenErrorOption(ImMessageStatusDeleted, "后台删除"),
|
||||
dict.GenWarningOption(ImMessageStatusRecalled, "用户撤回"),
|
||||
dict.GenErrorOption(ImMessageStatusBlocked, "风控拦截"),
|
||||
dict.GenWarningOption(ImMessageStatusHidden, "已隐藏"),
|
||||
}
|
||||
|
||||
var ImLoginTypeOptions = []*model.Option{
|
||||
dict.GenPrimaryOption("password", "密码"),
|
||||
dict.GenPrimaryOption("sms_code", "短信验证码"),
|
||||
dict.GenInfoOption("sso", "单点登录"),
|
||||
dict.GenInfoOption("qr_code", "二维码"),
|
||||
dict.GenDefaultOption("token_refresh", "令牌刷新"),
|
||||
}
|
||||
|
||||
var ImLoginEventTypeOptions = []*model.Option{
|
||||
dict.GenSuccessOption("login", "登录"),
|
||||
dict.GenInfoOption("refresh", "刷新会话"),
|
||||
dict.GenDefaultOption("logout", "主动退出"),
|
||||
dict.GenWarningOption("kicked", "被踢下线"),
|
||||
dict.GenWarningOption("session_expired", "会话过期"),
|
||||
}
|
||||
|
||||
var ImClientPlatformOptions = []*model.Option{
|
||||
dict.GenPrimaryOption("ios", "iOS"),
|
||||
dict.GenSuccessOption("android", "Android"),
|
||||
dict.GenInfoOption("web", "Web"),
|
||||
dict.GenDefaultOption("desktop", "桌面端"),
|
||||
dict.GenDefaultOption("unknown", "未知"),
|
||||
}
|
||||
|
||||
var ImLoginFailureTypeOptions = []*model.Option{
|
||||
dict.GenErrorOption("password_error", "密码错误"),
|
||||
dict.GenErrorOption("code_error", "验证码错误"),
|
||||
dict.GenWarningOption("account_not_found", "账号不存在"),
|
||||
dict.GenErrorOption("account_disabled", "账号已禁用"),
|
||||
dict.GenWarningOption("rate_limited", "访问频率受限"),
|
||||
dict.GenErrorOption("risk_blocked", "风控拦截"),
|
||||
}
|
||||
|
||||
func init() {
|
||||
dict.RegisterEnums("ImMessageContentTypeOptions", "IM消息内容类型选项", ImMessageContentTypeOptions)
|
||||
dict.RegisterEnums("ImMessageStatusOptions", "IM消息状态选项", ImMessageStatusOptions)
|
||||
dict.RegisterEnums("ImLoginTypeOptions", "IM登录方式选项", ImLoginTypeOptions)
|
||||
dict.RegisterEnums("ImLoginEventTypeOptions", "IM登录事件选项", ImLoginEventTypeOptions)
|
||||
dict.RegisterEnums("ImClientPlatformOptions", "IM客户端平台选项", ImClientPlatformOptions)
|
||||
dict.RegisterEnums("ImLoginFailureTypeOptions", "IM登录失败类型选项", ImLoginFailureTypeOptions)
|
||||
}
|
||||
@@ -47,6 +47,8 @@ const (
|
||||
ImAdminCommandUserCancel = "user.account.cancel"
|
||||
ImAdminCommandUserDelete = "user.account.delete"
|
||||
ImAdminCommandUserPasswordReset = "user.password.reset"
|
||||
ImAdminCommandMessageHide = "message.hide"
|
||||
ImAdminCommandMessageDelete = "message.delete"
|
||||
ImAdminCommandKafkaDeadReplay = "kafka.dead_letter.replay"
|
||||
ImAdminCommandKafkaDeadIgnore = "kafka.dead_letter.ignore"
|
||||
ImAdminCommandKafkaDeadResolve = "kafka.dead_letter.resolve"
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
package consts
|
||||
|
||||
import (
|
||||
"hotgo/internal/library/dict"
|
||||
"hotgo/internal/model"
|
||||
)
|
||||
|
||||
const (
|
||||
ImPolicyActionAllow = "allow"
|
||||
ImPolicyActionDeny = "deny"
|
||||
ImPolicyActionChallenge = "challenge"
|
||||
ImPolicyActionAuditOnly = "audit_only"
|
||||
ImSecurityActionBlock = "block"
|
||||
|
||||
ImSensitiveMatchExact = "exact"
|
||||
ImSensitiveMatchContains = "contains"
|
||||
ImSensitiveMatchRegex = "regex"
|
||||
ImSensitiveMatchPinyin = "pinyin"
|
||||
|
||||
ImSensitiveActionReplace = "replace"
|
||||
ImSensitiveActionBlock = "block"
|
||||
ImSensitiveActionAuditOnly = "audit_only"
|
||||
ImSensitiveActionManualReview = "manual_review"
|
||||
|
||||
ImRiskLevelLow = "low"
|
||||
ImRiskLevelMedium = "medium"
|
||||
ImRiskLevelHigh = "high"
|
||||
|
||||
ImSecurityPublishDraft = "draft"
|
||||
ImSecurityPublishPublished = "published"
|
||||
ImSecurityPublishArchived = "archived"
|
||||
ImSecurityPublishFailed = "failed"
|
||||
|
||||
ImCurfewDateDaily = "daily"
|
||||
ImCurfewDateWeekday = "weekday"
|
||||
ImCurfewDateWeekend = "weekend"
|
||||
ImCurfewDateCustom = "custom"
|
||||
|
||||
ImCurfewScopePrivate = "private_message"
|
||||
ImCurfewScopeGroup = "group_message"
|
||||
)
|
||||
|
||||
var (
|
||||
ImPolicyActionOptions = []*model.Option{
|
||||
dict.GenSuccessOption(ImPolicyActionAllow, "放行"),
|
||||
dict.GenErrorOption(ImPolicyActionDeny, "拦截"),
|
||||
dict.GenWarningOption(ImPolicyActionChallenge, "二次验证"),
|
||||
dict.GenInfoOption(ImPolicyActionAuditOnly, "仅审计"),
|
||||
}
|
||||
ImSecurityActionOptions = []*model.Option{
|
||||
dict.GenSuccessOption(ImPolicyActionAllow, "放行"),
|
||||
dict.GenWarningOption(ImPolicyActionChallenge, "二次验证"),
|
||||
dict.GenErrorOption(ImSecurityActionBlock, "阻断"),
|
||||
dict.GenInfoOption(ImPolicyActionAuditOnly, "仅审计"),
|
||||
}
|
||||
ImSensitiveMatchTypeOptions = []*model.Option{
|
||||
dict.GenPrimaryOption(ImSensitiveMatchExact, "精确匹配"),
|
||||
dict.GenDefaultOption(ImSensitiveMatchContains, "包含匹配"),
|
||||
dict.GenWarningOption(ImSensitiveMatchRegex, "正则匹配"),
|
||||
dict.GenInfoOption(ImSensitiveMatchPinyin, "拼音匹配"),
|
||||
}
|
||||
ImSensitiveActionOptions = []*model.Option{
|
||||
dict.GenWarningOption(ImSensitiveActionReplace, "替换"),
|
||||
dict.GenErrorOption(ImSensitiveActionBlock, "拦截"),
|
||||
dict.GenInfoOption(ImSensitiveActionAuditOnly, "仅审计"),
|
||||
dict.GenPrimaryOption(ImSensitiveActionManualReview, "人工审核"),
|
||||
}
|
||||
ImRiskLevelOptions = []*model.Option{
|
||||
dict.GenSuccessOption(ImRiskLevelLow, "低风险"),
|
||||
dict.GenWarningOption(ImRiskLevelMedium, "中风险"),
|
||||
dict.GenErrorOption(ImRiskLevelHigh, "高风险"),
|
||||
}
|
||||
ImSecurityPublishStatusOptions = []*model.Option{
|
||||
dict.GenWarningOption(ImSecurityPublishDraft, "草稿"),
|
||||
dict.GenSuccessOption(ImSecurityPublishPublished, "已发布"),
|
||||
dict.GenDefaultOption(ImSecurityPublishArchived, "已归档"),
|
||||
dict.GenErrorOption(ImSecurityPublishFailed, "发布失败"),
|
||||
}
|
||||
ImCurfewDateTypeOptions = []*model.Option{
|
||||
dict.GenDefaultOption(ImCurfewDateDaily, "每天"),
|
||||
dict.GenPrimaryOption(ImCurfewDateWeekday, "工作日"),
|
||||
dict.GenInfoOption(ImCurfewDateWeekend, "周末"),
|
||||
dict.GenWarningOption(ImCurfewDateCustom, "自定义日期"),
|
||||
}
|
||||
ImCurfewScopeOptions = []*model.Option{
|
||||
dict.GenErrorOption(ImCurfewScopePrivate, "单聊/私聊"),
|
||||
dict.GenWarningOption(ImCurfewScopeGroup, "群聊"),
|
||||
}
|
||||
ImSensitiveSceneOptions = []*model.Option{
|
||||
dict.GenPrimaryOption("private_message", "单聊消息"),
|
||||
dict.GenPrimaryOption("group_message", "群聊消息"),
|
||||
dict.GenInfoOption("user_profile", "用户资料"),
|
||||
dict.GenInfoOption("group_profile", "群资料"),
|
||||
dict.GenWarningOption("feedback", "用户反馈"),
|
||||
dict.GenWarningOption("report", "举报内容"),
|
||||
}
|
||||
ImFriendEntryOptions = []*model.Option{
|
||||
dict.GenDefaultOption("search", "用户搜索"),
|
||||
dict.GenDefaultOption("profile_card", "个人名片"),
|
||||
dict.GenDefaultOption("group_member", "群成员"),
|
||||
dict.GenDefaultOption("qrcode", "二维码"),
|
||||
dict.GenDefaultOption("invite_auto_add", "邀请注册自动添加"),
|
||||
dict.GenDefaultOption("recommendation", "推荐联系人"),
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
dict.RegisterEnums("ImPolicyActionOptions", "IM策略动作", ImPolicyActionOptions)
|
||||
dict.RegisterEnums("ImSecurityActionOptions", "IM安全策略动作", ImSecurityActionOptions)
|
||||
dict.RegisterEnums("ImSensitiveMatchTypeOptions", "IM敏感词匹配类型", ImSensitiveMatchTypeOptions)
|
||||
dict.RegisterEnums("ImSensitiveActionOptions", "IM敏感词动作", ImSensitiveActionOptions)
|
||||
dict.RegisterEnums("ImRiskLevelOptions", "IM风险等级", ImRiskLevelOptions)
|
||||
dict.RegisterEnums("ImSecurityPublishStatusOptions", "IM安全策略发布状态", ImSecurityPublishStatusOptions)
|
||||
dict.RegisterEnums("ImCurfewDateTypeOptions", "IM宵禁日期类型", ImCurfewDateTypeOptions)
|
||||
dict.RegisterEnums("ImCurfewScopeOptions", "IM宵禁范围", ImCurfewScopeOptions)
|
||||
dict.RegisterEnums("ImSensitiveSceneOptions", "IM敏感词场景", ImSensitiveSceneOptions)
|
||||
dict.RegisterEnums("ImFriendEntryOptions", "IM好友入口", ImFriendEntryOptions)
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package sys
|
||||
|
||||
import (
|
||||
"context"
|
||||
"hotgo/api/admin/imdashboard"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
"hotgo/internal/service"
|
||||
)
|
||||
|
||||
var ImDashboard = cImDashboard{}
|
||||
|
||||
type cImDashboard struct{}
|
||||
|
||||
func (c *cImDashboard) Overview(ctx context.Context, req *imdashboard.OverviewReq) (res *imdashboard.OverviewRes, err error) {
|
||||
data, err := service.SysImDashboard().Overview(ctx, &req.ImDashboardOverviewInp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &imdashboard.OverviewRes{ImDashboardOverviewModel: data}, nil
|
||||
}
|
||||
|
||||
func (c *cImDashboard) Trends(ctx context.Context, req *imdashboard.TrendsReq) (res *imdashboard.TrendsRes, err error) {
|
||||
list, err := service.SysImDashboard().Trends(ctx, &req.ImDashboardTrendsInp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if list == nil {
|
||||
list = []*sysin.ImDashboardTrendModel{}
|
||||
}
|
||||
return &imdashboard.TrendsRes{List: list}, nil
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package sys
|
||||
|
||||
import (
|
||||
"context"
|
||||
"hotgo/api/admin/imgroupmessage"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
"hotgo/internal/service"
|
||||
)
|
||||
|
||||
var ImGroupMessage = cImGroupMessage{}
|
||||
|
||||
type cImGroupMessage struct{}
|
||||
|
||||
func (c *cImGroupMessage) List(ctx context.Context, req *imgroupmessage.ListReq) (res *imgroupmessage.ListRes, err error) {
|
||||
list, total, err := service.SysImGroupMessage().List(ctx, &req.ImGroupMessageListInp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if list == nil {
|
||||
list = []*sysin.ImMessageListModel{}
|
||||
}
|
||||
res = &imgroupmessage.ListRes{List: list}
|
||||
res.PageRes.Pack(req, total)
|
||||
return
|
||||
}
|
||||
func (c *cImGroupMessage) View(ctx context.Context, req *imgroupmessage.ViewReq) (*imgroupmessage.ViewRes, error) {
|
||||
data, err := service.SysImGroupMessage().View(ctx, &req.ImMessageViewInp)
|
||||
return &imgroupmessage.ViewRes{ImMessageViewModel: data}, err
|
||||
}
|
||||
func (c *cImGroupMessage) Hide(ctx context.Context, req *imgroupmessage.HideReq) (*imgroupmessage.HideRes, error) {
|
||||
data, err := service.SysImGroupMessage().Hide(ctx, &req.ImMessageActionInp)
|
||||
return &imgroupmessage.HideRes{ImMessageCommandModel: data}, err
|
||||
}
|
||||
func (c *cImGroupMessage) Delete(ctx context.Context, req *imgroupmessage.DeleteReq) (*imgroupmessage.DeleteRes, error) {
|
||||
data, err := service.SysImGroupMessage().Delete(ctx, &req.ImMessageActionInp)
|
||||
return &imgroupmessage.DeleteRes{ImMessageCommandModel: data}, err
|
||||
}
|
||||
func (c *cImGroupMessage) Export(ctx context.Context, req *imgroupmessage.ExportReq) (*imgroupmessage.ExportRes, error) {
|
||||
return &imgroupmessage.ExportRes{}, service.SysImGroupMessage().Export(ctx, &req.ImGroupMessageListInp)
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package sys
|
||||
|
||||
import (
|
||||
"context"
|
||||
"hotgo/api/admin/imloginfailurelog"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
"hotgo/internal/service"
|
||||
)
|
||||
|
||||
var ImLoginFailureLog = cImLoginFailureLog{}
|
||||
|
||||
type cImLoginFailureLog struct{}
|
||||
|
||||
func (c *cImLoginFailureLog) List(ctx context.Context, req *imloginfailurelog.ListReq) (res *imloginfailurelog.ListRes, err error) {
|
||||
list, total, err := service.SysImLoginFailureLog().List(ctx, &req.ImLoginFailureLogListInp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if list == nil {
|
||||
list = []*sysin.ImLoginFailureLogModel{}
|
||||
}
|
||||
res = &imloginfailurelog.ListRes{List: list}
|
||||
res.PageRes.Pack(req, total)
|
||||
return
|
||||
}
|
||||
func (c *cImLoginFailureLog) View(ctx context.Context, req *imloginfailurelog.ViewReq) (*imloginfailurelog.ViewRes, error) {
|
||||
data, err := service.SysImLoginFailureLog().View(ctx, &req.ImLoginFailureViewInp)
|
||||
return &imloginfailurelog.ViewRes{ImLoginFailureLogModel: data}, err
|
||||
}
|
||||
func (c *cImLoginFailureLog) Export(ctx context.Context, req *imloginfailurelog.ExportReq) (*imloginfailurelog.ExportRes, error) {
|
||||
return &imloginfailurelog.ExportRes{}, service.SysImLoginFailureLog().Export(ctx, &req.ImLoginFailureLogListInp)
|
||||
}
|
||||
func (c *cImLoginFailureLog) AddBlacklist(ctx context.Context, req *imloginfailurelog.AddBlacklistReq) (*imloginfailurelog.AddBlacklistRes, error) {
|
||||
return &imloginfailurelog.AddBlacklistRes{}, service.SysImLoginFailureLog().AddBlacklist(ctx, &req.ImLoginFailureAddBlacklistInp)
|
||||
}
|
||||
func (c *cImLoginFailureLog) BanUser(ctx context.Context, req *imloginfailurelog.BanUserReq) (*imloginfailurelog.BanUserRes, error) {
|
||||
data, err := service.SysImLoginFailureLog().BanUser(ctx, &req.ImLoginFailureBanUserInp)
|
||||
return &imloginfailurelog.BanUserRes{ImUserCommandModel: data}, err
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package sys
|
||||
|
||||
import (
|
||||
"context"
|
||||
"hotgo/api/admin/imprivatemessage"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
"hotgo/internal/service"
|
||||
)
|
||||
|
||||
var ImPrivateMessage = cImPrivateMessage{}
|
||||
|
||||
type cImPrivateMessage struct{}
|
||||
|
||||
func (c *cImPrivateMessage) List(ctx context.Context, req *imprivatemessage.ListReq) (res *imprivatemessage.ListRes, err error) {
|
||||
list, total, err := service.SysImPrivateMessage().List(ctx, &req.ImPrivateMessageListInp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if list == nil {
|
||||
list = []*sysin.ImMessageListModel{}
|
||||
}
|
||||
res = &imprivatemessage.ListRes{List: list}
|
||||
res.PageRes.Pack(req, total)
|
||||
return
|
||||
}
|
||||
func (c *cImPrivateMessage) View(ctx context.Context, req *imprivatemessage.ViewReq) (*imprivatemessage.ViewRes, error) {
|
||||
data, err := service.SysImPrivateMessage().View(ctx, &req.ImMessageViewInp)
|
||||
return &imprivatemessage.ViewRes{ImMessageViewModel: data}, err
|
||||
}
|
||||
func (c *cImPrivateMessage) Hide(ctx context.Context, req *imprivatemessage.HideReq) (*imprivatemessage.HideRes, error) {
|
||||
data, err := service.SysImPrivateMessage().Hide(ctx, &req.ImMessageActionInp)
|
||||
return &imprivatemessage.HideRes{ImMessageCommandModel: data}, err
|
||||
}
|
||||
func (c *cImPrivateMessage) Delete(ctx context.Context, req *imprivatemessage.DeleteReq) (*imprivatemessage.DeleteRes, error) {
|
||||
data, err := service.SysImPrivateMessage().Delete(ctx, &req.ImMessageActionInp)
|
||||
return &imprivatemessage.DeleteRes{ImMessageCommandModel: data}, err
|
||||
}
|
||||
func (c *cImPrivateMessage) Export(ctx context.Context, req *imprivatemessage.ExportReq) (*imprivatemessage.ExportRes, error) {
|
||||
return &imprivatemessage.ExportRes{}, service.SysImPrivateMessage().Export(ctx, &req.ImPrivateMessageListInp)
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package sys
|
||||
|
||||
import (
|
||||
"context"
|
||||
"hotgo/api/admin/imsecuritypolicy"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
"hotgo/internal/service"
|
||||
)
|
||||
|
||||
var ImSecurityPolicy = cImSecurityPolicy{}
|
||||
|
||||
type cImSecurityPolicy struct{}
|
||||
|
||||
func (c *cImSecurityPolicy) List(ctx context.Context, req *imsecuritypolicy.ListReq) (res *imsecuritypolicy.ListRes, err error) {
|
||||
list, total, err := service.SysImSecurityPolicy().List(ctx, &req.ImSecurityPolicyListInp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if list == nil {
|
||||
list = []*sysin.ImSecurityPolicyModel{}
|
||||
}
|
||||
res = new(imsecuritypolicy.ListRes)
|
||||
res.List = list
|
||||
res.PageRes.Pack(req, total)
|
||||
return
|
||||
}
|
||||
func (c *cImSecurityPolicy) View(ctx context.Context, req *imsecuritypolicy.ViewReq) (res *imsecuritypolicy.ViewRes, err error) {
|
||||
data, err := service.SysImSecurityPolicy().View(ctx, &req.ImSecurityPolicyViewInp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &imsecuritypolicy.ViewRes{ImSecurityPolicyModel: data}, nil
|
||||
}
|
||||
func (c *cImSecurityPolicy) Save(ctx context.Context, req *imsecuritypolicy.SaveReq) (res *imsecuritypolicy.SaveRes, err error) {
|
||||
id, err := service.SysImSecurityPolicy().Save(ctx, &req.ImSecurityPolicySaveInp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &imsecuritypolicy.SaveRes{Id: id}, nil
|
||||
}
|
||||
func (c *cImSecurityPolicy) Publish(ctx context.Context, req *imsecuritypolicy.PublishReq) (res *imsecuritypolicy.PublishRes, err error) {
|
||||
err = service.SysImSecurityPolicy().Publish(ctx, &req.ImSecurityPolicyPublishInp)
|
||||
return
|
||||
}
|
||||
func (c *cImSecurityPolicy) RestoreDefault(ctx context.Context, req *imsecuritypolicy.RestoreDefaultReq) (res *imsecuritypolicy.RestoreDefaultRes, err error) {
|
||||
id, err := service.SysImSecurityPolicy().RestoreDefault(ctx, &req.ImSecurityPolicyRestoreInp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &imsecuritypolicy.RestoreDefaultRes{Id: id}, nil
|
||||
}
|
||||
func (c *cImSecurityPolicy) IPRuleList(ctx context.Context, req *imsecuritypolicy.IPRuleListReq) (res *imsecuritypolicy.IPRuleListRes, err error) {
|
||||
list, total, err := service.SysImSecurityPolicy().IPRuleList(ctx, &req.ImSecurityIPRuleListInp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if list == nil {
|
||||
list = []*sysin.ImSecurityIPRuleModel{}
|
||||
}
|
||||
res = new(imsecuritypolicy.IPRuleListRes)
|
||||
res.List = list
|
||||
res.PageRes.Pack(req, total)
|
||||
return
|
||||
}
|
||||
func (c *cImSecurityPolicy) IPRuleEdit(ctx context.Context, req *imsecuritypolicy.IPRuleEditReq) (res *imsecuritypolicy.IPRuleEditRes, err error) {
|
||||
err = service.SysImSecurityPolicy().IPRuleEdit(ctx, &req.ImSecurityIPRuleEditInp)
|
||||
return
|
||||
}
|
||||
func (c *cImSecurityPolicy) IPRuleDelete(ctx context.Context, req *imsecuritypolicy.IPRuleDeleteReq) (res *imsecuritypolicy.IPRuleDeleteRes, err error) {
|
||||
err = service.SysImSecurityPolicy().IPRuleDelete(ctx, &req.ImSecurityIPRuleDeleteInp)
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package sys
|
||||
|
||||
import (
|
||||
"context"
|
||||
"hotgo/api/admin/imsensitiveword"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
"hotgo/internal/service"
|
||||
)
|
||||
|
||||
var ImSensitiveWord = cImSensitiveWord{}
|
||||
|
||||
type cImSensitiveWord struct{}
|
||||
|
||||
func (c *cImSensitiveWord) List(ctx context.Context, req *imsensitiveword.ListReq) (res *imsensitiveword.ListRes, err error) {
|
||||
list, total, err := service.SysImSensitiveWord().List(ctx, &req.ImSensitiveWordListInp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if list == nil {
|
||||
list = []*sysin.ImSensitiveWordListModel{}
|
||||
}
|
||||
res = new(imsensitiveword.ListRes)
|
||||
res.List = list
|
||||
res.PageRes.Pack(req, total)
|
||||
return
|
||||
}
|
||||
func (c *cImSensitiveWord) Edit(ctx context.Context, req *imsensitiveword.EditReq) (res *imsensitiveword.EditRes, err error) {
|
||||
err = service.SysImSensitiveWord().Edit(ctx, &req.ImSensitiveWordEditInp)
|
||||
return
|
||||
}
|
||||
func (c *cImSensitiveWord) Delete(ctx context.Context, req *imsensitiveword.DeleteReq) (res *imsensitiveword.DeleteRes, err error) {
|
||||
err = service.SysImSensitiveWord().Delete(ctx, &req.ImSensitiveWordDeleteInp)
|
||||
return
|
||||
}
|
||||
func (c *cImSensitiveWord) Status(ctx context.Context, req *imsensitiveword.StatusReq) (res *imsensitiveword.StatusRes, err error) {
|
||||
err = service.SysImSensitiveWord().Status(ctx, &req.ImSensitiveWordStatusInp)
|
||||
return
|
||||
}
|
||||
func (c *cImSensitiveWord) BatchImport(ctx context.Context, req *imsensitiveword.BatchImportReq) (res *imsensitiveword.BatchImportRes, err error) {
|
||||
data, err := service.SysImSensitiveWord().BatchImport(ctx, &req.ImSensitiveWordBatchImportInp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &imsensitiveword.BatchImportRes{ImSensitiveWordBatchImportModel: data}, nil
|
||||
}
|
||||
func (c *cImSensitiveWord) GroupList(ctx context.Context, req *imsensitiveword.GroupListReq) (res *imsensitiveword.GroupListRes, err error) {
|
||||
list, err := service.SysImSensitiveWord().GroupList(ctx, &req.ImSensitiveWordGroupListInp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if list == nil {
|
||||
list = []*sysin.ImSensitiveWordGroupModel{}
|
||||
}
|
||||
return &imsensitiveword.GroupListRes{List: list}, nil
|
||||
}
|
||||
func (c *cImSensitiveWord) GroupEdit(ctx context.Context, req *imsensitiveword.GroupEditReq) (res *imsensitiveword.GroupEditRes, err error) {
|
||||
err = service.SysImSensitiveWord().GroupEdit(ctx, &req.ImSensitiveWordGroupEditInp)
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package sys
|
||||
|
||||
import (
|
||||
"context"
|
||||
"hotgo/api/admin/imuserloginhistory"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
"hotgo/internal/service"
|
||||
)
|
||||
|
||||
var ImUserLoginHistory = cImUserLoginHistory{}
|
||||
|
||||
type cImUserLoginHistory struct{}
|
||||
|
||||
func (c *cImUserLoginHistory) List(ctx context.Context, req *imuserloginhistory.ListReq) (res *imuserloginhistory.ListRes, err error) {
|
||||
list, total, err := service.SysImUserLoginHistory().List(ctx, &req.ImUserLoginHistoryListInp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if list == nil {
|
||||
list = []*sysin.ImUserLoginHistoryModel{}
|
||||
}
|
||||
res = &imuserloginhistory.ListRes{List: list}
|
||||
res.PageRes.Pack(req, total)
|
||||
return
|
||||
}
|
||||
func (c *cImUserLoginHistory) Export(ctx context.Context, req *imuserloginhistory.ExportReq) (*imuserloginhistory.ExportRes, error) {
|
||||
return &imuserloginhistory.ExportRes{}, service.SysImUserLoginHistory().Export(ctx, &req.ImUserLoginHistoryListInp)
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package sys
|
||||
|
||||
import (
|
||||
"context"
|
||||
"hotgo/api/admin/imuserpolicygroup"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
"hotgo/internal/service"
|
||||
)
|
||||
|
||||
var ImUserPolicyGroup = cImUserPolicyGroup{}
|
||||
|
||||
type cImUserPolicyGroup struct{}
|
||||
|
||||
func (c *cImUserPolicyGroup) List(ctx context.Context, req *imuserpolicygroup.ListReq) (res *imuserpolicygroup.ListRes, err error) {
|
||||
list, total, err := service.SysImUserPolicyGroup().List(ctx, &req.ImUserPolicyGroupListInp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if list == nil {
|
||||
list = []*sysin.ImUserPolicyGroupListModel{}
|
||||
}
|
||||
res = new(imuserpolicygroup.ListRes)
|
||||
res.List = list
|
||||
res.PageRes.Pack(req, total)
|
||||
return
|
||||
}
|
||||
func (c *cImUserPolicyGroup) View(ctx context.Context, req *imuserpolicygroup.ViewReq) (res *imuserpolicygroup.ViewRes, err error) {
|
||||
data, err := service.SysImUserPolicyGroup().View(ctx, &req.ImUserPolicyGroupViewInp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &imuserpolicygroup.ViewRes{ImUserPolicyGroupViewModel: data}, nil
|
||||
}
|
||||
func (c *cImUserPolicyGroup) Edit(ctx context.Context, req *imuserpolicygroup.EditReq) (res *imuserpolicygroup.EditRes, err error) {
|
||||
err = service.SysImUserPolicyGroup().Edit(ctx, &req.ImUserPolicyGroupEditInp)
|
||||
return
|
||||
}
|
||||
func (c *cImUserPolicyGroup) Delete(ctx context.Context, req *imuserpolicygroup.DeleteReq) (res *imuserpolicygroup.DeleteRes, err error) {
|
||||
err = service.SysImUserPolicyGroup().Delete(ctx, &req.ImUserPolicyGroupDeleteInp)
|
||||
return
|
||||
}
|
||||
func (c *cImUserPolicyGroup) Status(ctx context.Context, req *imuserpolicygroup.StatusReq) (res *imuserpolicygroup.StatusRes, err error) {
|
||||
err = service.SysImUserPolicyGroup().Status(ctx, &req.ImUserPolicyGroupStatusInp)
|
||||
return
|
||||
}
|
||||
func (c *cImUserPolicyGroup) MemberList(ctx context.Context, req *imuserpolicygroup.MemberListReq) (res *imuserpolicygroup.MemberListRes, err error) {
|
||||
list, total, err := service.SysImUserPolicyGroup().MemberList(ctx, &req.ImUserPolicyGroupMemberListInp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if list == nil {
|
||||
list = []*sysin.ImUserPolicyGroupMemberModel{}
|
||||
}
|
||||
res = new(imuserpolicygroup.MemberListRes)
|
||||
res.List = list
|
||||
res.PageRes.Pack(req, total)
|
||||
return
|
||||
}
|
||||
func (c *cImUserPolicyGroup) MemberAdd(ctx context.Context, req *imuserpolicygroup.MemberAddReq) (res *imuserpolicygroup.MemberAddRes, err error) {
|
||||
err = service.SysImUserPolicyGroup().MemberAdd(ctx, &req.ImUserPolicyGroupMemberAddInp)
|
||||
return
|
||||
}
|
||||
func (c *cImUserPolicyGroup) MemberRemove(ctx context.Context, req *imuserpolicygroup.MemberRemoveReq) (res *imuserpolicygroup.MemberRemoveRes, err error) {
|
||||
err = service.SysImUserPolicyGroup().MemberRemove(ctx, &req.ImUserPolicyGroupMemberRemoveInp)
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// =================================================================================
|
||||
// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed.
|
||||
// =================================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"hotgo/internal/dao/internal"
|
||||
)
|
||||
|
||||
// imMessageCurfewRulesDao is the data access object for the table im_message_curfew_rules.
|
||||
// You can define custom methods on it to extend its functionality as needed.
|
||||
type imMessageCurfewRulesDao struct {
|
||||
*internal.ImMessageCurfewRulesDao
|
||||
}
|
||||
|
||||
var (
|
||||
// ImMessageCurfewRules is a globally accessible object for table im_message_curfew_rules operations.
|
||||
ImMessageCurfewRules = imMessageCurfewRulesDao{internal.NewImMessageCurfewRulesDao()}
|
||||
)
|
||||
|
||||
// Add your custom methods and functionality below.
|
||||
@@ -0,0 +1,22 @@
|
||||
// =================================================================================
|
||||
// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed.
|
||||
// =================================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"hotgo/internal/dao/internal"
|
||||
)
|
||||
|
||||
// imSecurityIpRulesDao is the data access object for the table im_security_ip_rules.
|
||||
// You can define custom methods on it to extend its functionality as needed.
|
||||
type imSecurityIpRulesDao struct {
|
||||
*internal.ImSecurityIpRulesDao
|
||||
}
|
||||
|
||||
var (
|
||||
// ImSecurityIpRules is a globally accessible object for table im_security_ip_rules operations.
|
||||
ImSecurityIpRules = imSecurityIpRulesDao{internal.NewImSecurityIpRulesDao()}
|
||||
)
|
||||
|
||||
// Add your custom methods and functionality below.
|
||||
@@ -0,0 +1,22 @@
|
||||
// =================================================================================
|
||||
// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed.
|
||||
// =================================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"hotgo/internal/dao/internal"
|
||||
)
|
||||
|
||||
// imSecurityPolicyDao is the data access object for the table im_security_policy.
|
||||
// You can define custom methods on it to extend its functionality as needed.
|
||||
type imSecurityPolicyDao struct {
|
||||
*internal.ImSecurityPolicyDao
|
||||
}
|
||||
|
||||
var (
|
||||
// ImSecurityPolicy is a globally accessible object for table im_security_policy operations.
|
||||
ImSecurityPolicy = imSecurityPolicyDao{internal.NewImSecurityPolicyDao()}
|
||||
)
|
||||
|
||||
// Add your custom methods and functionality below.
|
||||
@@ -0,0 +1,22 @@
|
||||
// =================================================================================
|
||||
// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed.
|
||||
// =================================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"hotgo/internal/dao/internal"
|
||||
)
|
||||
|
||||
// imSensitiveWordGroupsDao is the data access object for the table im_sensitive_word_groups.
|
||||
// You can define custom methods on it to extend its functionality as needed.
|
||||
type imSensitiveWordGroupsDao struct {
|
||||
*internal.ImSensitiveWordGroupsDao
|
||||
}
|
||||
|
||||
var (
|
||||
// ImSensitiveWordGroups is a globally accessible object for table im_sensitive_word_groups operations.
|
||||
ImSensitiveWordGroups = imSensitiveWordGroupsDao{internal.NewImSensitiveWordGroupsDao()}
|
||||
)
|
||||
|
||||
// Add your custom methods and functionality below.
|
||||
@@ -0,0 +1,22 @@
|
||||
// =================================================================================
|
||||
// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed.
|
||||
// =================================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"hotgo/internal/dao/internal"
|
||||
)
|
||||
|
||||
// imSensitiveWordsDao is the data access object for the table im_sensitive_words.
|
||||
// You can define custom methods on it to extend its functionality as needed.
|
||||
type imSensitiveWordsDao struct {
|
||||
*internal.ImSensitiveWordsDao
|
||||
}
|
||||
|
||||
var (
|
||||
// ImSensitiveWords is a globally accessible object for table im_sensitive_words operations.
|
||||
ImSensitiveWords = imSensitiveWordsDao{internal.NewImSensitiveWordsDao()}
|
||||
)
|
||||
|
||||
// Add your custom methods and functionality below.
|
||||
@@ -0,0 +1,22 @@
|
||||
// =================================================================================
|
||||
// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed.
|
||||
// =================================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"hotgo/internal/dao/internal"
|
||||
)
|
||||
|
||||
// imUserPolicyGroupMembersDao is the data access object for the table im_user_policy_group_members.
|
||||
// You can define custom methods on it to extend its functionality as needed.
|
||||
type imUserPolicyGroupMembersDao struct {
|
||||
*internal.ImUserPolicyGroupMembersDao
|
||||
}
|
||||
|
||||
var (
|
||||
// ImUserPolicyGroupMembers is a globally accessible object for table im_user_policy_group_members operations.
|
||||
ImUserPolicyGroupMembers = imUserPolicyGroupMembersDao{internal.NewImUserPolicyGroupMembersDao()}
|
||||
)
|
||||
|
||||
// Add your custom methods and functionality below.
|
||||
@@ -0,0 +1,22 @@
|
||||
// =================================================================================
|
||||
// This file is auto-generated by the GoFrame CLI tool. You may modify it as needed.
|
||||
// =================================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"hotgo/internal/dao/internal"
|
||||
)
|
||||
|
||||
// imUserPolicyGroupsDao is the data access object for the table im_user_policy_groups.
|
||||
// You can define custom methods on it to extend its functionality as needed.
|
||||
type imUserPolicyGroupsDao struct {
|
||||
*internal.ImUserPolicyGroupsDao
|
||||
}
|
||||
|
||||
var (
|
||||
// ImUserPolicyGroups is a globally accessible object for table im_user_policy_groups operations.
|
||||
ImUserPolicyGroups = imUserPolicyGroupsDao{internal.NewImUserPolicyGroupsDao()}
|
||||
)
|
||||
|
||||
// Add your custom methods and functionality below.
|
||||
@@ -0,0 +1,123 @@
|
||||
// ==========================================================================
|
||||
// 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"
|
||||
)
|
||||
|
||||
// ImMessageCurfewRulesDao is the data access object for the table im_message_curfew_rules.
|
||||
type ImMessageCurfewRulesDao 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 ImMessageCurfewRulesColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// ImMessageCurfewRulesColumns defines and stores column names for the table im_message_curfew_rules.
|
||||
type ImMessageCurfewRulesColumns struct {
|
||||
Id string //
|
||||
TenantId string //
|
||||
PolicyId string //
|
||||
RuleCode string //
|
||||
RuleName string //
|
||||
DateType string // daily, weekday, weekend, custom
|
||||
CustomDates string // YYYY-MM-DD values for custom date type
|
||||
Weekdays string // ISO weekdays 1 through 7
|
||||
Timezone string //
|
||||
StartTime string //
|
||||
EndTime string // Less than start_time means crossing midnight
|
||||
Scope string // private_message or group_message
|
||||
WhitelistUserIds string //
|
||||
WhitelistGroupIds string //
|
||||
Message string //
|
||||
Status string // 1 enabled, 2 disabled
|
||||
Sort string //
|
||||
CreatedAt string //
|
||||
CreatedBy string //
|
||||
UpdatedAt string //
|
||||
UpdatedBy string //
|
||||
DeletedAt string //
|
||||
DeletedBy string //
|
||||
}
|
||||
|
||||
// imMessageCurfewRulesColumns holds the columns for the table im_message_curfew_rules.
|
||||
var imMessageCurfewRulesColumns = ImMessageCurfewRulesColumns{
|
||||
Id: "id",
|
||||
TenantId: "tenant_id",
|
||||
PolicyId: "policy_id",
|
||||
RuleCode: "rule_code",
|
||||
RuleName: "rule_name",
|
||||
DateType: "date_type",
|
||||
CustomDates: "custom_dates",
|
||||
Weekdays: "weekdays",
|
||||
Timezone: "timezone",
|
||||
StartTime: "start_time",
|
||||
EndTime: "end_time",
|
||||
Scope: "scope",
|
||||
WhitelistUserIds: "whitelist_user_ids",
|
||||
WhitelistGroupIds: "whitelist_group_ids",
|
||||
Message: "message",
|
||||
Status: "status",
|
||||
Sort: "sort",
|
||||
CreatedAt: "created_at",
|
||||
CreatedBy: "created_by",
|
||||
UpdatedAt: "updated_at",
|
||||
UpdatedBy: "updated_by",
|
||||
DeletedAt: "deleted_at",
|
||||
DeletedBy: "deleted_by",
|
||||
}
|
||||
|
||||
// NewImMessageCurfewRulesDao creates and returns a new DAO object for table data access.
|
||||
func NewImMessageCurfewRulesDao(handlers ...gdb.ModelHandler) *ImMessageCurfewRulesDao {
|
||||
return &ImMessageCurfewRulesDao{
|
||||
group: "default",
|
||||
table: "im_message_curfew_rules",
|
||||
columns: imMessageCurfewRulesColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of the current DAO.
|
||||
func (dao *ImMessageCurfewRulesDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of the current DAO.
|
||||
func (dao *ImMessageCurfewRulesDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of the current DAO.
|
||||
func (dao *ImMessageCurfewRulesDao) Columns() ImMessageCurfewRulesColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the database configuration group name of the current DAO.
|
||||
func (dao *ImMessageCurfewRulesDao) 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 *ImMessageCurfewRulesDao) 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 *ImMessageCurfewRulesDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
// ==========================================================================
|
||||
// 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"
|
||||
)
|
||||
|
||||
// ImSecurityIpRulesDao is the data access object for the table im_security_ip_rules.
|
||||
type ImSecurityIpRulesDao 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 ImSecurityIpRulesColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// ImSecurityIpRulesColumns defines and stores column names for the table im_security_ip_rules.
|
||||
type ImSecurityIpRulesColumns struct {
|
||||
Id string //
|
||||
TenantId string //
|
||||
RuleType string // whitelist or blacklist
|
||||
IpCidr string // IPv4, IPv6 or CIDR
|
||||
Action string // allow, challenge, block, audit_only
|
||||
SceneJson string // login, register, message, upload and other scenes
|
||||
RiskLevel string //
|
||||
Status string // 1 enabled, 2 disabled
|
||||
ExpiresAt string //
|
||||
Remark string //
|
||||
CreatedAt string //
|
||||
CreatedBy string //
|
||||
UpdatedAt string //
|
||||
UpdatedBy string //
|
||||
DeletedAt string //
|
||||
DeletedBy string //
|
||||
}
|
||||
|
||||
// imSecurityIpRulesColumns holds the columns for the table im_security_ip_rules.
|
||||
var imSecurityIpRulesColumns = ImSecurityIpRulesColumns{
|
||||
Id: "id",
|
||||
TenantId: "tenant_id",
|
||||
RuleType: "rule_type",
|
||||
IpCidr: "ip_cidr",
|
||||
Action: "action",
|
||||
SceneJson: "scene_json",
|
||||
RiskLevel: "risk_level",
|
||||
Status: "status",
|
||||
ExpiresAt: "expires_at",
|
||||
Remark: "remark",
|
||||
CreatedAt: "created_at",
|
||||
CreatedBy: "created_by",
|
||||
UpdatedAt: "updated_at",
|
||||
UpdatedBy: "updated_by",
|
||||
DeletedAt: "deleted_at",
|
||||
DeletedBy: "deleted_by",
|
||||
}
|
||||
|
||||
// NewImSecurityIpRulesDao creates and returns a new DAO object for table data access.
|
||||
func NewImSecurityIpRulesDao(handlers ...gdb.ModelHandler) *ImSecurityIpRulesDao {
|
||||
return &ImSecurityIpRulesDao{
|
||||
group: "default",
|
||||
table: "im_security_ip_rules",
|
||||
columns: imSecurityIpRulesColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of the current DAO.
|
||||
func (dao *ImSecurityIpRulesDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of the current DAO.
|
||||
func (dao *ImSecurityIpRulesDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of the current DAO.
|
||||
func (dao *ImSecurityIpRulesDao) Columns() ImSecurityIpRulesColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the database configuration group name of the current DAO.
|
||||
func (dao *ImSecurityIpRulesDao) 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 *ImSecurityIpRulesDao) 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 *ImSecurityIpRulesDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
// ==========================================================================
|
||||
// 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"
|
||||
)
|
||||
|
||||
// ImSecurityPolicyDao is the data access object for the table im_security_policy.
|
||||
type ImSecurityPolicyDao 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 ImSecurityPolicyColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// ImSecurityPolicyColumns defines and stores column names for the table im_security_policy.
|
||||
type ImSecurityPolicyColumns struct {
|
||||
Id string //
|
||||
TenantId string // 0 means global fallback policy
|
||||
PolicyVersion string //
|
||||
PolicyName string //
|
||||
PublishStatus string //
|
||||
PasswordPolicy string //
|
||||
LoginRateLimit string //
|
||||
SensitiveWordPolicy string //
|
||||
FileReviewPolicy string //
|
||||
RealnamePolicy string //
|
||||
RiskChallengePolicy string //
|
||||
GlobalFriendEnabled string // Backend master switch for every add-friend entry
|
||||
FriendDisabledPolicy string // Profile masking, QR and group-member restrictions
|
||||
MessageCurfewEnabled string // Backend master switch for message curfew
|
||||
Remark string //
|
||||
PublishedAt string //
|
||||
PublishedBy string //
|
||||
CreatedAt string //
|
||||
CreatedBy string //
|
||||
UpdatedAt string //
|
||||
UpdatedBy string //
|
||||
DeletedAt string //
|
||||
DeletedBy string //
|
||||
}
|
||||
|
||||
// imSecurityPolicyColumns holds the columns for the table im_security_policy.
|
||||
var imSecurityPolicyColumns = ImSecurityPolicyColumns{
|
||||
Id: "id",
|
||||
TenantId: "tenant_id",
|
||||
PolicyVersion: "policy_version",
|
||||
PolicyName: "policy_name",
|
||||
PublishStatus: "publish_status",
|
||||
PasswordPolicy: "password_policy",
|
||||
LoginRateLimit: "login_rate_limit",
|
||||
SensitiveWordPolicy: "sensitive_word_policy",
|
||||
FileReviewPolicy: "file_review_policy",
|
||||
RealnamePolicy: "realname_policy",
|
||||
RiskChallengePolicy: "risk_challenge_policy",
|
||||
GlobalFriendEnabled: "global_friend_enabled",
|
||||
FriendDisabledPolicy: "friend_disabled_policy",
|
||||
MessageCurfewEnabled: "message_curfew_enabled",
|
||||
Remark: "remark",
|
||||
PublishedAt: "published_at",
|
||||
PublishedBy: "published_by",
|
||||
CreatedAt: "created_at",
|
||||
CreatedBy: "created_by",
|
||||
UpdatedAt: "updated_at",
|
||||
UpdatedBy: "updated_by",
|
||||
DeletedAt: "deleted_at",
|
||||
DeletedBy: "deleted_by",
|
||||
}
|
||||
|
||||
// NewImSecurityPolicyDao creates and returns a new DAO object for table data access.
|
||||
func NewImSecurityPolicyDao(handlers ...gdb.ModelHandler) *ImSecurityPolicyDao {
|
||||
return &ImSecurityPolicyDao{
|
||||
group: "default",
|
||||
table: "im_security_policy",
|
||||
columns: imSecurityPolicyColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of the current DAO.
|
||||
func (dao *ImSecurityPolicyDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of the current DAO.
|
||||
func (dao *ImSecurityPolicyDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of the current DAO.
|
||||
func (dao *ImSecurityPolicyDao) Columns() ImSecurityPolicyColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the database configuration group name of the current DAO.
|
||||
func (dao *ImSecurityPolicyDao) 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 *ImSecurityPolicyDao) 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 *ImSecurityPolicyDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
// ==========================================================================
|
||||
// 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"
|
||||
)
|
||||
|
||||
// ImSensitiveWordGroupsDao is the data access object for the table im_sensitive_word_groups.
|
||||
type ImSensitiveWordGroupsDao 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 ImSensitiveWordGroupsColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// ImSensitiveWordGroupsColumns defines and stores column names for the table im_sensitive_word_groups.
|
||||
type ImSensitiveWordGroupsColumns struct {
|
||||
Id string //
|
||||
TenantId string // 0 means global dictionary
|
||||
GroupCode string //
|
||||
GroupName string //
|
||||
Priority string //
|
||||
Status string // 1 enabled, 2 disabled
|
||||
Remark string //
|
||||
CreatedAt string //
|
||||
CreatedBy string //
|
||||
UpdatedAt string //
|
||||
UpdatedBy string //
|
||||
DeletedAt string //
|
||||
DeletedBy string //
|
||||
}
|
||||
|
||||
// imSensitiveWordGroupsColumns holds the columns for the table im_sensitive_word_groups.
|
||||
var imSensitiveWordGroupsColumns = ImSensitiveWordGroupsColumns{
|
||||
Id: "id",
|
||||
TenantId: "tenant_id",
|
||||
GroupCode: "group_code",
|
||||
GroupName: "group_name",
|
||||
Priority: "priority",
|
||||
Status: "status",
|
||||
Remark: "remark",
|
||||
CreatedAt: "created_at",
|
||||
CreatedBy: "created_by",
|
||||
UpdatedAt: "updated_at",
|
||||
UpdatedBy: "updated_by",
|
||||
DeletedAt: "deleted_at",
|
||||
DeletedBy: "deleted_by",
|
||||
}
|
||||
|
||||
// NewImSensitiveWordGroupsDao creates and returns a new DAO object for table data access.
|
||||
func NewImSensitiveWordGroupsDao(handlers ...gdb.ModelHandler) *ImSensitiveWordGroupsDao {
|
||||
return &ImSensitiveWordGroupsDao{
|
||||
group: "default",
|
||||
table: "im_sensitive_word_groups",
|
||||
columns: imSensitiveWordGroupsColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of the current DAO.
|
||||
func (dao *ImSensitiveWordGroupsDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of the current DAO.
|
||||
func (dao *ImSensitiveWordGroupsDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of the current DAO.
|
||||
func (dao *ImSensitiveWordGroupsDao) Columns() ImSensitiveWordGroupsColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the database configuration group name of the current DAO.
|
||||
func (dao *ImSensitiveWordGroupsDao) 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 *ImSensitiveWordGroupsDao) 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 *ImSensitiveWordGroupsDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
// ==========================================================================
|
||||
// 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"
|
||||
)
|
||||
|
||||
// ImSensitiveWordsDao is the data access object for the table im_sensitive_words.
|
||||
type ImSensitiveWordsDao 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 ImSensitiveWordsColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// ImSensitiveWordsColumns defines and stores column names for the table im_sensitive_words.
|
||||
type ImSensitiveWordsColumns struct {
|
||||
Id string //
|
||||
TenantId string // 0 means global dictionary
|
||||
GroupId string //
|
||||
Word string //
|
||||
WordHash string // SHA-256 of normalized word
|
||||
MatchType string //
|
||||
SceneJson string // Enabled scenes
|
||||
Action string //
|
||||
Replacement string //
|
||||
RiskLevel string //
|
||||
Priority string //
|
||||
Status string // 1 enabled, 2 disabled
|
||||
Remark string //
|
||||
CreatedAt string //
|
||||
CreatedBy string //
|
||||
UpdatedAt string //
|
||||
UpdatedBy string //
|
||||
DeletedAt string //
|
||||
DeletedBy string //
|
||||
}
|
||||
|
||||
// imSensitiveWordsColumns holds the columns for the table im_sensitive_words.
|
||||
var imSensitiveWordsColumns = ImSensitiveWordsColumns{
|
||||
Id: "id",
|
||||
TenantId: "tenant_id",
|
||||
GroupId: "group_id",
|
||||
Word: "word",
|
||||
WordHash: "word_hash",
|
||||
MatchType: "match_type",
|
||||
SceneJson: "scene_json",
|
||||
Action: "action",
|
||||
Replacement: "replacement",
|
||||
RiskLevel: "risk_level",
|
||||
Priority: "priority",
|
||||
Status: "status",
|
||||
Remark: "remark",
|
||||
CreatedAt: "created_at",
|
||||
CreatedBy: "created_by",
|
||||
UpdatedAt: "updated_at",
|
||||
UpdatedBy: "updated_by",
|
||||
DeletedAt: "deleted_at",
|
||||
DeletedBy: "deleted_by",
|
||||
}
|
||||
|
||||
// NewImSensitiveWordsDao creates and returns a new DAO object for table data access.
|
||||
func NewImSensitiveWordsDao(handlers ...gdb.ModelHandler) *ImSensitiveWordsDao {
|
||||
return &ImSensitiveWordsDao{
|
||||
group: "default",
|
||||
table: "im_sensitive_words",
|
||||
columns: imSensitiveWordsColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of the current DAO.
|
||||
func (dao *ImSensitiveWordsDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of the current DAO.
|
||||
func (dao *ImSensitiveWordsDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of the current DAO.
|
||||
func (dao *ImSensitiveWordsDao) Columns() ImSensitiveWordsColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the database configuration group name of the current DAO.
|
||||
func (dao *ImSensitiveWordsDao) 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 *ImSensitiveWordsDao) 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 *ImSensitiveWordsDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
@@ -21,28 +21,36 @@ type ImTenantConfigDao struct {
|
||||
|
||||
// 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
|
||||
CreatedAt string //
|
||||
CreatedBy string //
|
||||
UpdatedAt string //
|
||||
UpdatedBy string //
|
||||
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",
|
||||
CreatedAt: "created_at",
|
||||
CreatedBy: "created_by",
|
||||
UpdatedAt: "updated_at",
|
||||
UpdatedBy: "updated_by",
|
||||
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.
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
// ==========================================================================
|
||||
// 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"
|
||||
)
|
||||
|
||||
// ImUserPolicyGroupMembersDao is the data access object for the table im_user_policy_group_members.
|
||||
type ImUserPolicyGroupMembersDao 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 ImUserPolicyGroupMembersColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// ImUserPolicyGroupMembersColumns defines and stores column names for the table im_user_policy_group_members.
|
||||
type ImUserPolicyGroupMembersColumns struct {
|
||||
Id string //
|
||||
TenantId string //
|
||||
GroupId string //
|
||||
UserId string // User ID in the tenant database
|
||||
Status string // 1 enabled, 2 disabled
|
||||
ValidFrom string //
|
||||
ValidUntil string //
|
||||
Remark string //
|
||||
CreatedAt string //
|
||||
CreatedBy string //
|
||||
UpdatedAt string //
|
||||
UpdatedBy string //
|
||||
DeletedAt string //
|
||||
DeletedBy string //
|
||||
}
|
||||
|
||||
// imUserPolicyGroupMembersColumns holds the columns for the table im_user_policy_group_members.
|
||||
var imUserPolicyGroupMembersColumns = ImUserPolicyGroupMembersColumns{
|
||||
Id: "id",
|
||||
TenantId: "tenant_id",
|
||||
GroupId: "group_id",
|
||||
UserId: "user_id",
|
||||
Status: "status",
|
||||
ValidFrom: "valid_from",
|
||||
ValidUntil: "valid_until",
|
||||
Remark: "remark",
|
||||
CreatedAt: "created_at",
|
||||
CreatedBy: "created_by",
|
||||
UpdatedAt: "updated_at",
|
||||
UpdatedBy: "updated_by",
|
||||
DeletedAt: "deleted_at",
|
||||
DeletedBy: "deleted_by",
|
||||
}
|
||||
|
||||
// NewImUserPolicyGroupMembersDao creates and returns a new DAO object for table data access.
|
||||
func NewImUserPolicyGroupMembersDao(handlers ...gdb.ModelHandler) *ImUserPolicyGroupMembersDao {
|
||||
return &ImUserPolicyGroupMembersDao{
|
||||
group: "default",
|
||||
table: "im_user_policy_group_members",
|
||||
columns: imUserPolicyGroupMembersColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of the current DAO.
|
||||
func (dao *ImUserPolicyGroupMembersDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of the current DAO.
|
||||
func (dao *ImUserPolicyGroupMembersDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of the current DAO.
|
||||
func (dao *ImUserPolicyGroupMembersDao) Columns() ImUserPolicyGroupMembersColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the database configuration group name of the current DAO.
|
||||
func (dao *ImUserPolicyGroupMembersDao) 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 *ImUserPolicyGroupMembersDao) 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 *ImUserPolicyGroupMembersDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
// ==========================================================================
|
||||
// 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"
|
||||
)
|
||||
|
||||
// ImUserPolicyGroupsDao is the data access object for the table im_user_policy_groups.
|
||||
type ImUserPolicyGroupsDao 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 ImUserPolicyGroupsColumns // columns contains all the column names of Table for convenient usage.
|
||||
handlers []gdb.ModelHandler // handlers for customized model modification.
|
||||
}
|
||||
|
||||
// ImUserPolicyGroupsColumns defines and stores column names for the table im_user_policy_groups.
|
||||
type ImUserPolicyGroupsColumns struct {
|
||||
Id string //
|
||||
TenantId string // 0 means global default
|
||||
GroupCode string // Stable policy group code
|
||||
GroupName string // Policy group name
|
||||
Priority string // Higher value has higher priority
|
||||
Status string // 1 enabled, 2 disabled
|
||||
PolicyJson string // Login, friend, message, group and file policies
|
||||
IpWhitelist string // IPv4/IPv6 or CIDR list
|
||||
IpBlacklist string // IPv4/IPv6 or CIDR list
|
||||
Version string // Optimistic-lock/config version
|
||||
Remark string //
|
||||
CreatedAt string //
|
||||
CreatedBy string //
|
||||
UpdatedAt string //
|
||||
UpdatedBy string //
|
||||
DeletedAt string //
|
||||
DeletedBy string //
|
||||
}
|
||||
|
||||
// imUserPolicyGroupsColumns holds the columns for the table im_user_policy_groups.
|
||||
var imUserPolicyGroupsColumns = ImUserPolicyGroupsColumns{
|
||||
Id: "id",
|
||||
TenantId: "tenant_id",
|
||||
GroupCode: "group_code",
|
||||
GroupName: "group_name",
|
||||
Priority: "priority",
|
||||
Status: "status",
|
||||
PolicyJson: "policy_json",
|
||||
IpWhitelist: "ip_whitelist",
|
||||
IpBlacklist: "ip_blacklist",
|
||||
Version: "version",
|
||||
Remark: "remark",
|
||||
CreatedAt: "created_at",
|
||||
CreatedBy: "created_by",
|
||||
UpdatedAt: "updated_at",
|
||||
UpdatedBy: "updated_by",
|
||||
DeletedAt: "deleted_at",
|
||||
DeletedBy: "deleted_by",
|
||||
}
|
||||
|
||||
// NewImUserPolicyGroupsDao creates and returns a new DAO object for table data access.
|
||||
func NewImUserPolicyGroupsDao(handlers ...gdb.ModelHandler) *ImUserPolicyGroupsDao {
|
||||
return &ImUserPolicyGroupsDao{
|
||||
group: "default",
|
||||
table: "im_user_policy_groups",
|
||||
columns: imUserPolicyGroupsColumns,
|
||||
handlers: handlers,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of the current DAO.
|
||||
func (dao *ImUserPolicyGroupsDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of the current DAO.
|
||||
func (dao *ImUserPolicyGroupsDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of the current DAO.
|
||||
func (dao *ImUserPolicyGroupsDao) Columns() ImUserPolicyGroupsColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the database configuration group name of the current DAO.
|
||||
func (dao *ImUserPolicyGroupsDao) 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 *ImUserPolicyGroupsDao) 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 *ImUserPolicyGroupsDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
@@ -1,67 +1,66 @@
|
||||
// Package casbin
|
||||
// @Link https://github.com/bufanyun/hotgo
|
||||
// @Copyright Copyright (c) 2023 HotGo CLI
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||||
package casbin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
casbinv2 "github.com/casbin/casbin/v2"
|
||||
"github.com/casbin/casbin/v2/model"
|
||||
)
|
||||
|
||||
// TestNew description
|
||||
func TestNew(t *testing.T) {
|
||||
const testModel = `
|
||||
[request_definition]
|
||||
r = sub, obj, act
|
||||
|
||||
InitEnforcer(context.TODO())
|
||||
[policy_definition]
|
||||
p = sub, obj, act
|
||||
|
||||
user := "admin"
|
||||
path := "/"
|
||||
method := http.MethodGet
|
||||
t.Logf("\nuser:%v\npath:%v\nmethod:%v", user, path, method)
|
||||
[role_definition]
|
||||
g = _, _
|
||||
|
||||
ok, err := Enforcer.DeletePermissionsForUser(user)
|
||||
[policy_effect]
|
||||
e = some(where (p.eft == allow))
|
||||
|
||||
[matchers]
|
||||
m = g(r.sub, p.sub) && keyMatch(r.obj, p.obj) && regexMatch(r.act, p.act)
|
||||
`
|
||||
|
||||
func TestEnforcerPermissions(t *testing.T) {
|
||||
m, err := model.NewModelFromString(testModel)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
t.Fatalf("创建Casbin测试模型失败: %v", err)
|
||||
}
|
||||
t.Logf("delete user premission:%v", ok)
|
||||
CheckPremission(t, user, path, method)
|
||||
AddPremission(t, user, "*", ActionAll)
|
||||
CheckPremission(t, user, path, method)
|
||||
|
||||
user1 := "user1"
|
||||
path1 := "/api/v1/*"
|
||||
checkPathTrue := "/api/v1/user/list"
|
||||
checkPathFalse := "/api/v2/user/list"
|
||||
AddPremission(t, user1, path1, ActionAll)
|
||||
CheckPremission(t, user1, checkPathTrue, ActionPost)
|
||||
CheckPremission(t, user1, checkPathFalse, http.MethodGet)
|
||||
CheckPremission(t, user1, checkPathTrue, http.MethodGet)
|
||||
CheckPremission(t, user1, "/api/v1/user/list2", http.MethodGet)
|
||||
|
||||
ok, err = Enforcer.DeletePermissionsForUser(user1)
|
||||
enforcer, err := casbinv2.NewEnforcer(m)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
t.Fatalf("创建Casbin测试实例失败: %v", err)
|
||||
}
|
||||
t.Logf("delete user premission:%v", ok)
|
||||
CheckPremission(t, user1, "/api/v1/user1/list", http.MethodGet)
|
||||
|
||||
assertPermission(t, enforcer, "admin", "/", http.MethodGet, false)
|
||||
if ok, addErr := enforcer.AddPolicy("admin", "*", ActionAll); addErr != nil || !ok {
|
||||
t.Fatalf("添加管理员策略失败: ok=%v err=%v", ok, addErr)
|
||||
}
|
||||
assertPermission(t, enforcer, "admin", "/", http.MethodGet, true)
|
||||
|
||||
if ok, addErr := enforcer.AddPolicy("user1", "/api/v1/*", ActionAll); addErr != nil || !ok {
|
||||
t.Fatalf("添加用户策略失败: ok=%v err=%v", ok, addErr)
|
||||
}
|
||||
assertPermission(t, enforcer, "user1", "/api/v1/user/list", http.MethodPost, true)
|
||||
assertPermission(t, enforcer, "user1", "/api/v1/user/list", http.MethodGet, true)
|
||||
assertPermission(t, enforcer, "user1", "/api/v2/user/list", http.MethodGet, false)
|
||||
|
||||
if ok, deleteErr := enforcer.DeletePermissionsForUser("user1"); deleteErr != nil || !ok {
|
||||
t.Fatalf("删除用户策略失败: ok=%v err=%v", ok, deleteErr)
|
||||
}
|
||||
assertPermission(t, enforcer, "user1", "/api/v1/user/list", http.MethodGet, false)
|
||||
}
|
||||
|
||||
// CheckPremission description
|
||||
func CheckPremission(t *testing.T, user string, path string, method string) {
|
||||
ok, err := Enforcer.Enforce(user, path, method)
|
||||
func assertPermission(t *testing.T, enforcer *casbinv2.Enforcer, user, path, method string, expected bool) {
|
||||
t.Helper()
|
||||
actual, err := enforcer.Enforce(user, path, method)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
t.Fatalf("检查权限失败: %v", err)
|
||||
}
|
||||
t.Logf("check \tuser[%s] \tpremission[%s] \tpath[%s] \tallow[%v]", user, method, path, ok)
|
||||
}
|
||||
|
||||
// Add description
|
||||
func AddPremission(t *testing.T, user string, path string, method string) {
|
||||
ok, err := Enforcer.AddPolicy(user, path, method)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
if actual != expected {
|
||||
t.Fatalf("权限结果不符 user=%s path=%s method=%s expected=%v actual=%v", user, path, method, expected, actual)
|
||||
}
|
||||
t.Logf("add \tuser[%s] \tpremission[%s] \tpath[%s] \tresult[%v]", user, method, path, ok)
|
||||
}
|
||||
|
||||
@@ -281,6 +281,8 @@ func (client *Client) handleRoutineTask(ctx context.Context, task func()) {
|
||||
|
||||
// Conn 获取当前连接
|
||||
func (client *Client) Conn() *Conn {
|
||||
client.mutex.Lock()
|
||||
defer client.mutex.Unlock()
|
||||
return client.conn
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,6 @@ func (r *RPC) Request(ctx context.Context, msgId string, send func()) (res inter
|
||||
|
||||
defer func() {
|
||||
isClose.Set(true)
|
||||
close(resCh)
|
||||
r.popCallback(msgId)
|
||||
}()
|
||||
|
||||
@@ -57,8 +56,13 @@ func (r *RPC) Request(ctx context.Context, msgId string, send func()) (res inter
|
||||
|
||||
r.task(ctx, send)
|
||||
|
||||
timer := time.NewTimer(time.Second * RPCTimeout)
|
||||
defer timer.Stop()
|
||||
select {
|
||||
case <-time.After(time.Second * RPCTimeout):
|
||||
case <-ctx.Done():
|
||||
err = gerror.Wrap(ctx.Err(), "RPC request canceled")
|
||||
return
|
||||
case <-timer.C:
|
||||
err = gerror.New("RPC response timeout")
|
||||
return
|
||||
case got := <-resCh:
|
||||
|
||||
@@ -1,21 +1,14 @@
|
||||
// Package tcp_test
|
||||
// @Link https://github.com/bufanyun/hotgo
|
||||
// @Copyright Copyright (c) 2023 HotGo CLI
|
||||
// @Author Ms <133814250@qq.com>
|
||||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||||
package tcp_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/v2/os/gctx"
|
||||
"github.com/gogf/gf/v2/test/gtest"
|
||||
"hotgo/internal/library/network/tcp"
|
||||
"net"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
var T *testing.T // 声明一个全局的 *testing.T 变量
|
||||
"hotgo/internal/library/network/tcp"
|
||||
)
|
||||
|
||||
type TestMsgReq struct {
|
||||
Name string `json:"name"`
|
||||
@@ -33,101 +26,95 @@ type TestRPCMsgRes struct {
|
||||
tcp.ServerRes
|
||||
}
|
||||
|
||||
func onTestMsg(ctx context.Context, req *TestMsgReq) {
|
||||
fmt.Printf("服务器收到消息 ==> onTestMsg:%+v\n", req)
|
||||
conn := tcp.ConnFromCtx(ctx)
|
||||
gtest.C(T, func(t *gtest.T) {
|
||||
t.AssertNE(conn, nil)
|
||||
})
|
||||
|
||||
res := new(TestMsgRes)
|
||||
res.Message = fmt.Sprintf("你的名字:%v", req.Name)
|
||||
conn.Send(ctx, res)
|
||||
}
|
||||
|
||||
func onResponseTestMsg(ctx context.Context, req *TestMsgRes) {
|
||||
fmt.Printf("客户端收到响应消息 ==> TestMsgRes:%+v\n", req)
|
||||
err := req.GetError()
|
||||
gtest.C(T, func(t *gtest.T) {
|
||||
t.AssertNil(err)
|
||||
})
|
||||
}
|
||||
|
||||
func onTestRPCMsg(ctx context.Context, req *TestRPCMsgReq) (res *TestRPCMsgRes, err error) {
|
||||
fmt.Printf("服务器收到消息 ==> onTestRPCMsg:%+v\n", req)
|
||||
res = new(TestRPCMsgRes)
|
||||
res.Message = fmt.Sprintf("你的名字:%v", req.Name)
|
||||
return
|
||||
}
|
||||
|
||||
func startTCPServer() {
|
||||
serv := tcp.NewServer(&tcp.ServerConfig{
|
||||
Name: "hotgo",
|
||||
Addr: ":8002",
|
||||
})
|
||||
|
||||
// 注册路由
|
||||
serv.RegisterRouter(
|
||||
onTestMsg,
|
||||
)
|
||||
|
||||
// 注册RPC路由
|
||||
serv.RegisterRPCRouter(
|
||||
onTestRPCMsg,
|
||||
)
|
||||
|
||||
// 服务监听
|
||||
err := serv.Listen()
|
||||
gtest.C(T, func(t *gtest.T) {
|
||||
t.AssertNil(err)
|
||||
})
|
||||
}
|
||||
|
||||
// 一个基本的消息收发
|
||||
func TestSendMsg(t *testing.T) {
|
||||
T = t
|
||||
go startTCPServer()
|
||||
|
||||
ctx := gctx.New()
|
||||
client := tcp.NewClient(&tcp.ClientConfig{
|
||||
Addr: "127.0.0.1:8002",
|
||||
address := freeTCPAddress(t)
|
||||
messageResponse := make(chan string, 1)
|
||||
server := tcp.NewServer(&tcp.ServerConfig{Name: "hotgo-test", Addr: address})
|
||||
server.RegisterRouter(func(ctx context.Context, req *TestMsgReq) {
|
||||
res := &TestMsgRes{}
|
||||
res.SetMessage(fmt.Sprintf("你的名字:%s", req.Name))
|
||||
if err := tcp.ConnFromCtx(ctx).Send(ctx, res); err != nil {
|
||||
messageResponse <- "send-error:" + err.Error()
|
||||
}
|
||||
})
|
||||
|
||||
// 注册路由
|
||||
client.RegisterRouter(
|
||||
onResponseTestMsg,
|
||||
)
|
||||
|
||||
server.RegisterRPCRouter(func(ctx context.Context, req *TestRPCMsgReq) (*TestRPCMsgRes, error) {
|
||||
res := &TestRPCMsgRes{}
|
||||
res.SetMessage(fmt.Sprintf("你的名字:%s", req.Name))
|
||||
return res, nil
|
||||
})
|
||||
serverErrors := make(chan error, 1)
|
||||
go func() {
|
||||
err := client.Start()
|
||||
gtest.C(T, func(t *gtest.T) {
|
||||
t.AssertNil(err)
|
||||
})
|
||||
serverErrors <- server.Listen()
|
||||
}()
|
||||
defer server.Close()
|
||||
|
||||
// 确保服务都启动完成
|
||||
time.Sleep(time.Second * 1)
|
||||
|
||||
// 拿到客户端的连接
|
||||
conn := client.Conn()
|
||||
gtest.C(T, func(t *gtest.T) {
|
||||
t.AssertNE(conn, nil)
|
||||
client := tcp.NewClient(&tcp.ClientConfig{
|
||||
Addr: address,
|
||||
Timeout: time.Second,
|
||||
ConnectInterval: 10 * time.Millisecond,
|
||||
MaxConnectCount: 100,
|
||||
})
|
||||
|
||||
// 向服务器发送tcp消息,不会阻塞程序执行
|
||||
err := conn.Send(ctx, &TestMsgReq{Name: "Tom"})
|
||||
gtest.C(T, func(t *gtest.T) {
|
||||
t.AssertNil(err)
|
||||
client.RegisterRouter(func(ctx context.Context, res *TestMsgRes) {
|
||||
messageResponse <- res.Message
|
||||
})
|
||||
if err := client.Start(); err != nil {
|
||||
t.Fatalf("启动TCP客户端失败: %v", err)
|
||||
}
|
||||
defer client.Stop()
|
||||
|
||||
// 向服务器发送rpc消息,会等待服务器响应结果,直到拿到结果或响应超时才会继续
|
||||
var res TestRPCMsgRes
|
||||
if err = conn.RequestScan(ctx, &TestRPCMsgReq{Name: "Tony"}, &res); err != nil {
|
||||
gtest.C(T, func(t *gtest.T) {
|
||||
t.AssertNil(err)
|
||||
})
|
||||
conn := waitForConnection(t, client, serverErrors)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
|
||||
defer cancel()
|
||||
if err := conn.Send(ctx, &TestMsgReq{Name: "Tom"}); err != nil {
|
||||
t.Fatalf("发送TCP消息失败: %v", err)
|
||||
}
|
||||
select {
|
||||
case message := <-messageResponse:
|
||||
if message != "你的名字:Tom" {
|
||||
t.Fatalf("TCP响应不符: %s", message)
|
||||
}
|
||||
case <-ctx.Done():
|
||||
t.Fatal("等待TCP响应超时")
|
||||
}
|
||||
|
||||
fmt.Printf("客户端收到RPC消息响应 ==> TestRPCMsgRes:%+v\n", res)
|
||||
time.Sleep(time.Second * 1)
|
||||
var rpcResponse TestRPCMsgRes
|
||||
if err := conn.RequestScan(ctx, &TestRPCMsgReq{Name: "Tony"}, &rpcResponse); err != nil {
|
||||
t.Fatalf("发送RPC消息失败: %v", err)
|
||||
}
|
||||
if rpcResponse.Message != "你的名字:Tony" {
|
||||
t.Fatalf("RPC响应不符: %s", rpcResponse.Message)
|
||||
}
|
||||
}
|
||||
|
||||
func freeTCPAddress(t *testing.T) string {
|
||||
t.Helper()
|
||||
listener, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
if err != nil {
|
||||
t.Fatalf("申请测试端口失败: %v", err)
|
||||
}
|
||||
address := listener.Addr().String()
|
||||
if err = listener.Close(); err != nil {
|
||||
t.Fatalf("释放测试端口失败: %v", err)
|
||||
}
|
||||
return address
|
||||
}
|
||||
|
||||
func waitForConnection(t *testing.T, client *tcp.Client, serverErrors <-chan error) *tcp.Conn {
|
||||
t.Helper()
|
||||
deadline := time.NewTimer(2 * time.Second)
|
||||
defer deadline.Stop()
|
||||
ticker := time.NewTicker(10 * time.Millisecond)
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
select {
|
||||
case err := <-serverErrors:
|
||||
t.Fatalf("TCP服务启动失败: %v", err)
|
||||
case <-deadline.C:
|
||||
t.Fatal("等待TCP连接超时")
|
||||
case <-ticker.C:
|
||||
if conn := client.Conn(); conn != nil {
|
||||
return conn
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/gogf/gf/v2/os/gfile"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
@@ -137,20 +138,53 @@ func (d *LocalDrive) UploadPart(ctx context.Context, in *UploadPartParams) (res
|
||||
|
||||
// MergePartFile 合并分片文件
|
||||
func MergePartFile(srcPath, dstPath string) (err error) {
|
||||
dir, err := os.ReadDir(srcPath)
|
||||
entries, err := os.ReadDir(srcPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sort.Slice(dir, func(i, j int) bool {
|
||||
fiIndex, _ := strconv.Atoi(dir[i].Name())
|
||||
fjIndex, _ := strconv.Atoi(dir[j].Name())
|
||||
return fiIndex < fjIndex
|
||||
type filePart struct {
|
||||
index int
|
||||
path string
|
||||
}
|
||||
parts := make([]filePart, 0, len(entries))
|
||||
for _, entry := range entries {
|
||||
if entry.IsDir() {
|
||||
continue
|
||||
}
|
||||
index, parseErr := strconv.Atoi(entry.Name())
|
||||
if parseErr != nil || index <= 0 {
|
||||
return gerror.Newf("无效的分片文件名:%s", entry.Name())
|
||||
}
|
||||
parts = append(parts, filePart{index: index, path: filepath.Join(srcPath, entry.Name())})
|
||||
}
|
||||
if len(parts) == 0 {
|
||||
return gerror.New("没有可合并的分片文件")
|
||||
}
|
||||
sort.Slice(parts, func(i, j int) bool {
|
||||
return parts[i].index < parts[j].index
|
||||
})
|
||||
for _, file := range dir {
|
||||
filePath := filepath.Join(srcPath, file.Name())
|
||||
if err = gfile.PutBytesAppend(dstPath, gfile.GetBytes(filePath)); err != nil {
|
||||
return err
|
||||
if err = os.MkdirAll(filepath.Dir(dstPath), 0o755); err != nil {
|
||||
return gerror.Wrap(err, "创建目标目录失败")
|
||||
}
|
||||
dstFile, err := os.OpenFile(dstPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0o644)
|
||||
if err != nil {
|
||||
return gerror.Wrap(err, "创建合并文件失败")
|
||||
}
|
||||
defer dstFile.Close()
|
||||
|
||||
for _, part := range parts {
|
||||
srcFile, openErr := os.Open(part.path)
|
||||
if openErr != nil {
|
||||
return gerror.Wrapf(openErr, "打开分片%d失败", part.index)
|
||||
}
|
||||
_, copyErr := io.Copy(dstFile, srcFile)
|
||||
closeErr := srcFile.Close()
|
||||
if copyErr != nil {
|
||||
return gerror.Wrapf(copyErr, "合并分片%d失败", part.index)
|
||||
}
|
||||
if closeErr != nil {
|
||||
return gerror.Wrapf(closeErr, "关闭分片%d失败", part.index)
|
||||
}
|
||||
}
|
||||
return
|
||||
return dstFile.Sync()
|
||||
}
|
||||
|
||||
@@ -1,61 +1,52 @@
|
||||
package storager
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"bytes"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMergePartFile(t *testing.T) {
|
||||
srcFile, _ := os.Open("1.zip")
|
||||
defer srcFile.Close()
|
||||
fileInfo, err := srcFile.Stat()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
tempDir := t.TempDir()
|
||||
partDir := filepath.Join(tempDir, "parts")
|
||||
if err := os.MkdirAll(partDir, 0o755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
hash := md5.New()
|
||||
_, err = io.Copy(hash, srcFile)
|
||||
sum := hash.Sum(nil)
|
||||
fileHash := fmt.Sprintf("%x", sum)
|
||||
|
||||
var singleSize = int64(1024 * 1024 * 100)
|
||||
chunks := int(fileInfo.Size() / singleSize)
|
||||
if fileInfo.Size()%singleSize != 0 {
|
||||
chunks += 1
|
||||
parts := map[string][]byte{
|
||||
"1": []byte("first-"),
|
||||
"2": []byte("second-"),
|
||||
"10": []byte("tenth"),
|
||||
}
|
||||
srcFile.Seek(0, io.SeekStart)
|
||||
for j := 0; j < chunks; j++ {
|
||||
partSize := singleSize
|
||||
if j == chunks-1 {
|
||||
partSize = fileInfo.Size() - int64(j)*singleSize
|
||||
for name, content := range parts {
|
||||
if err := os.WriteFile(filepath.Join(partDir, name), content, 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
partData := make([]byte, partSize)
|
||||
_, err = io.ReadFull(srcFile, partData)
|
||||
pf, _ := os.Create(fmt.Sprintf("tmp/%d", j+1))
|
||||
_, err = pf.Write(partData)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
pf.Close()
|
||||
}
|
||||
|
||||
err = MergePartFile("tmp/", "2.zip")
|
||||
destination := filepath.Join(tempDir, "merged.bin")
|
||||
if err := os.WriteFile(destination, []byte("stale-data"), 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := MergePartFile(partDir, destination); err != nil {
|
||||
t.Fatalf("合并分片失败: %v", err)
|
||||
}
|
||||
|
||||
actual, err := os.ReadFile(destination)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
t.Fatal(err)
|
||||
}
|
||||
expected := []byte("first-second-tenth")
|
||||
if !bytes.Equal(actual, expected) {
|
||||
t.Fatalf("合并内容不符 expected=%q actual=%q", expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
f2, _ := os.Open("2.zip")
|
||||
hash2 := md5.New()
|
||||
_, err = io.Copy(hash2, f2)
|
||||
sum2 := hash.Sum(nil)
|
||||
fileHash2 := fmt.Sprintf("%x", sum2)
|
||||
if fileHash != fileHash2 {
|
||||
t.Error(errors.New("hash mismatch"))
|
||||
func TestMergePartFileRejectsEmptyDirectory(t *testing.T) {
|
||||
partDir := t.TempDir()
|
||||
err := MergePartFile(partDir, filepath.Join(t.TempDir(), "merged.bin"))
|
||||
if err == nil {
|
||||
t.Fatal("空分片目录应返回错误")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ func normalizeImAdminValue(target string, value any) any {
|
||||
parts = append(parts, text)
|
||||
}
|
||||
return strings.Join(parts, ", ")
|
||||
case "profileJson", "trustedJson", "accessJson":
|
||||
case "profileJson", "trustedJson", "accessJson", "head", "content", "metadata", "atUsers":
|
||||
return normalizeImAdminJSONString(value)
|
||||
default:
|
||||
return value
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package sys
|
||||
|
||||
import (
|
||||
"context"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
"hotgo/internal/service"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
type sSysImDashboard struct{}
|
||||
|
||||
func NewSysImDashboard() *sSysImDashboard { return &sSysImDashboard{} }
|
||||
|
||||
func init() { service.RegisterSysImDashboard(NewSysImDashboard()) }
|
||||
|
||||
func (s *sSysImDashboard) Overview(ctx context.Context, in *sysin.ImDashboardOverviewInp) (*sysin.ImDashboardOverviewModel, error) {
|
||||
tenant, err := resolveImAdminTenant(ctx, in.TenantId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return imAdminQueryOne[sysin.ImDashboardOverviewModel](ctx, tenant,
|
||||
"/internal/admin-query/tenants/"+url.PathEscape(tenant.Code)+"/dashboard/overview", nil)
|
||||
}
|
||||
|
||||
func (s *sSysImDashboard) Trends(ctx context.Context, in *sysin.ImDashboardTrendsInp) ([]*sysin.ImDashboardTrendModel, error) {
|
||||
if err := in.Filter(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tenant, err := resolveImAdminTenant(ctx, in.TenantId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
values := addPageQuery(url.Values{}, 1, in.Days)
|
||||
values.Set("days", intToString(in.Days))
|
||||
list, _, err := imAdminQueryList[sysin.ImDashboardTrendModel](ctx, tenant,
|
||||
"/internal/admin-query/tenants/"+url.PathEscape(tenant.Code)+"/dashboard/trends", values, nil)
|
||||
return list, err
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
package sys
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"hotgo/internal/consts"
|
||||
"hotgo/internal/library/contexts"
|
||||
"hotgo/internal/library/imkafka"
|
||||
"hotgo/internal/model/input/form"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
"hotgo/internal/service"
|
||||
"hotgo/utility/convert"
|
||||
"hotgo/utility/excel"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/os/gctx"
|
||||
)
|
||||
|
||||
type sSysImUserLoginHistory struct{}
|
||||
type sSysImLoginFailureLog struct{}
|
||||
|
||||
func NewSysImUserLoginHistory() *sSysImUserLoginHistory { return &sSysImUserLoginHistory{} }
|
||||
func NewSysImLoginFailureLog() *sSysImLoginFailureLog { return &sSysImLoginFailureLog{} }
|
||||
|
||||
func init() {
|
||||
service.RegisterSysImUserLoginHistory(NewSysImUserLoginHistory())
|
||||
service.RegisterSysImLoginFailureLog(NewSysImLoginFailureLog())
|
||||
}
|
||||
|
||||
func (s *sSysImUserLoginHistory) List(ctx context.Context, in *sysin.ImUserLoginHistoryListInp) ([]*sysin.ImUserLoginHistoryModel, int, error) {
|
||||
if err := in.Filter(ctx); err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
tenant, err := resolveImAdminTenant(ctx, in.TenantId)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
values := addPageQuery(url.Values{}, in.Page, in.PerPage)
|
||||
setQuery(values, "user_id", in.UserId)
|
||||
setQuery(values, "account", in.Account)
|
||||
setQuery(values, "login_type", in.LoginType)
|
||||
setQuery(values, "event_type", in.EventType)
|
||||
setQuery(values, "platform", in.Platform)
|
||||
setQuery(values, "ip", in.Ip)
|
||||
addTimeRangeQuery(values, "login_at", in.LoginAt)
|
||||
return imAdminQueryList[sysin.ImUserLoginHistoryModel](ctx, tenant,
|
||||
"/internal/admin-query/tenants/"+url.PathEscape(tenant.Code)+"/user-login-logs", values, nil)
|
||||
}
|
||||
|
||||
func (s *sSysImUserLoginHistory) Export(ctx context.Context, in *sysin.ImUserLoginHistoryListInp) error {
|
||||
list, total, err := s.List(ctx, in)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
exports := make([]sysin.ImLoginAuditExportModel, 0, len(list))
|
||||
for _, item := range list {
|
||||
exports = append(exports, sysin.ImLoginAuditExportModel{Id: item.Id, UserId: item.UserId, AccountMask: item.AccountMask, EventType: item.EventType, Platform: item.Platform, Ip: item.Ip, Region: item.Region, RiskLevel: item.RiskLevel, OccurredAt: item.LoginAt})
|
||||
}
|
||||
return exportLoginAudit(ctx, exports, total, in.Page, in.PerPage, "用户登录历史")
|
||||
}
|
||||
|
||||
func (s *sSysImLoginFailureLog) List(ctx context.Context, in *sysin.ImLoginFailureLogListInp) ([]*sysin.ImLoginFailureLogModel, int, error) {
|
||||
if err := in.Filter(ctx); err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
tenant, err := resolveImAdminTenant(ctx, in.TenantId)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
values := addPageQuery(url.Values{}, in.Page, in.PerPage)
|
||||
setQuery(values, "user_id", in.UserId)
|
||||
setQuery(values, "account", in.Account)
|
||||
setQuery(values, "failure_type", in.FailureType)
|
||||
setQuery(values, "platform", in.Platform)
|
||||
setQuery(values, "ip", in.Ip)
|
||||
addTimeRangeQuery(values, "attempt_at", in.AttemptAt)
|
||||
return imAdminQueryList[sysin.ImLoginFailureLogModel](ctx, tenant,
|
||||
"/internal/admin-query/tenants/"+url.PathEscape(tenant.Code)+"/login-failure-logs", values, nil)
|
||||
}
|
||||
|
||||
func (s *sSysImLoginFailureLog) View(ctx context.Context, in *sysin.ImLoginFailureViewInp) (*sysin.ImLoginFailureLogModel, error) {
|
||||
if err := in.Filter(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tenant, err := resolveImAdminTenant(ctx, in.TenantId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return imAdminQueryOne[sysin.ImLoginFailureLogModel](ctx, tenant,
|
||||
"/internal/admin-query/tenants/"+url.PathEscape(tenant.Code)+"/login-failure-logs/"+strconv.FormatInt(in.Id, 10), nil)
|
||||
}
|
||||
|
||||
func (s *sSysImLoginFailureLog) Export(ctx context.Context, in *sysin.ImLoginFailureLogListInp) error {
|
||||
list, total, err := s.List(ctx, in)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
exports := make([]sysin.ImLoginAuditExportModel, 0, len(list))
|
||||
for _, item := range list {
|
||||
exports = append(exports, sysin.ImLoginAuditExportModel{Id: item.Id, UserId: item.UserId, AccountMask: item.AccountMask, EventType: item.FailureType, Platform: item.Platform, Ip: item.Ip, Region: item.Region, RiskLevel: item.RiskLevel, Reason: item.Reason, OccurredAt: item.AttemptAt})
|
||||
}
|
||||
return exportLoginAudit(ctx, exports, total, in.Page, in.PerPage, "登录失败日志")
|
||||
}
|
||||
|
||||
func exportLoginAudit(ctx context.Context, exports []sysin.ImLoginAuditExportModel, total int, page int, perPage int, label string) error {
|
||||
tags, err := convert.GetEntityDescTags(sysin.ImLoginAuditExportModel{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fileName := "导出" + label + "-" + gctx.CtxId(ctx)
|
||||
sheetName := fmt.Sprintf("索引条件共%v行,共%v页,当前导出是第%v页,本页共%v行", total, form.CalPageCount(total, perPage), page, len(exports))
|
||||
return excel.ExportByStructs(ctx, tags, exports, fileName, sheetName)
|
||||
}
|
||||
|
||||
func (s *sSysImLoginFailureLog) AddBlacklist(ctx context.Context, in *sysin.ImLoginFailureAddBlacklistInp) error {
|
||||
if err := in.Filter(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
remark := in.Remark
|
||||
if remark == "" {
|
||||
remark = "由登录失败日志加入"
|
||||
}
|
||||
return service.SysImSecurityPolicy().IPRuleEdit(ctx, &sysin.ImSecurityIPRuleEditInp{
|
||||
TenantId: in.TenantId, RuleType: "blacklist", IpCidr: in.Ip, Action: "deny",
|
||||
SceneJson: gjson.New([]string{"login"}), RiskLevel: "high", Status: consts.StatusEnabled, Remark: remark,
|
||||
})
|
||||
}
|
||||
|
||||
func (s *sSysImLoginFailureLog) BanUser(ctx context.Context, in *sysin.ImLoginFailureBanUserInp) (*sysin.ImUserCommandModel, error) {
|
||||
if err := in.Filter(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tenant, err := resolveImAdminTenant(ctx, in.TenantId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
user := contexts.GetUser(ctx)
|
||||
actorName := ""
|
||||
if user != nil {
|
||||
actorName = user.RealName
|
||||
}
|
||||
command, err := imkafka.PublishAdminCommand(ctx, imkafka.AdminCommandInput{
|
||||
TenantID: tenant.Id, TenantCode: tenant.Code, EventType: consts.ImAdminCommandUserBan,
|
||||
BizType: "user", BizID: strconv.FormatInt(in.UserId, 10),
|
||||
Actor: &imkafka.Actor{Type: "admin", ID: strconv.FormatInt(contexts.GetUserId(ctx), 10), DisplayName: actorName},
|
||||
Payload: map[string]any{"user_id": strconv.FormatInt(in.UserId, 10), "target_user_id": strconv.FormatInt(in.UserId, 10), "reason": in.Reason},
|
||||
CreatedBy: contexts.GetUserId(ctx),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &sysin.ImUserCommandModel{CommandID: command.CommandID, EventID: command.EventID, Status: command.Status, TenantID: command.TenantID, TenantCode: command.TenantCode, EventType: command.EventType, IdempotencyKey: command.IdempotencyKey}, nil
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
package sys
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"hotgo/internal/consts"
|
||||
"hotgo/internal/library/contexts"
|
||||
"hotgo/internal/library/imkafka"
|
||||
"hotgo/internal/model/input/form"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
"hotgo/internal/service"
|
||||
"hotgo/utility/convert"
|
||||
"hotgo/utility/excel"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/gogf/gf/v2/os/gctx"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
)
|
||||
|
||||
type sSysImPrivateMessage struct{}
|
||||
type sSysImGroupMessage struct{}
|
||||
|
||||
func NewSysImPrivateMessage() *sSysImPrivateMessage { return &sSysImPrivateMessage{} }
|
||||
func NewSysImGroupMessage() *sSysImGroupMessage { return &sSysImGroupMessage{} }
|
||||
|
||||
func init() {
|
||||
service.RegisterSysImPrivateMessage(NewSysImPrivateMessage())
|
||||
service.RegisterSysImGroupMessage(NewSysImGroupMessage())
|
||||
}
|
||||
|
||||
func (s *sSysImPrivateMessage) List(ctx context.Context, in *sysin.ImPrivateMessageListInp) ([]*sysin.ImMessageListModel, int, error) {
|
||||
if err := in.Filter(ctx); err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
values := addPageQuery(url.Values{}, in.Page, in.PerPage)
|
||||
setQuery(values, "topic", in.Topic)
|
||||
setQuery(values, "from_user_id", in.FromUserId)
|
||||
setQuery(values, "to_user_id", in.ToUserId)
|
||||
setQuery(values, "content_type", in.ContentType)
|
||||
setQuery(values, "status", in.Status)
|
||||
setQuery(values, "keyword", in.Keyword)
|
||||
addTimeRangeQuery(values, "created_at", in.CreatedAt)
|
||||
return queryImMessages(ctx, in.TenantId, "private-messages", values)
|
||||
}
|
||||
|
||||
func (s *sSysImGroupMessage) List(ctx context.Context, in *sysin.ImGroupMessageListInp) ([]*sysin.ImMessageListModel, int, error) {
|
||||
if err := in.Filter(ctx); err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
values := addPageQuery(url.Values{}, in.Page, in.PerPage)
|
||||
setQuery(values, "topic", in.Topic)
|
||||
setQuery(values, "sender_user_id", in.SenderUserId)
|
||||
setQuery(values, "content_type", in.ContentType)
|
||||
setQuery(values, "status", in.Status)
|
||||
setQuery(values, "keyword", in.Keyword)
|
||||
addTimeRangeQuery(values, "created_at", in.CreatedAt)
|
||||
return queryImMessages(ctx, in.TenantId, "group-messages", values)
|
||||
}
|
||||
|
||||
func queryImMessages(ctx context.Context, tenantId int64, resource string, values url.Values) ([]*sysin.ImMessageListModel, int, error) {
|
||||
tenant, err := resolveImAdminTenant(ctx, tenantId)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return imAdminQueryList[sysin.ImMessageListModel](ctx, tenant,
|
||||
"/internal/admin-query/tenants/"+url.PathEscape(tenant.Code)+"/"+resource, values,
|
||||
map[string]string{"sender_user_id": "fromUserId", "sent_at": "createdAt", "message_type": "contentType", "content_summary": "contentExcerpt"})
|
||||
}
|
||||
|
||||
func (s *sSysImPrivateMessage) View(ctx context.Context, in *sysin.ImMessageViewInp) (*sysin.ImMessageViewModel, error) {
|
||||
return viewImMessage(ctx, in)
|
||||
}
|
||||
|
||||
func (s *sSysImGroupMessage) View(ctx context.Context, in *sysin.ImMessageViewInp) (*sysin.ImMessageViewModel, error) {
|
||||
return viewImMessage(ctx, in)
|
||||
}
|
||||
|
||||
func viewImMessage(ctx context.Context, in *sysin.ImMessageViewInp) (*sysin.ImMessageViewModel, error) {
|
||||
if err := in.Filter(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tenant, err := resolveImAdminTenant(ctx, in.TenantId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
path := "/internal/admin-query/tenants/" + url.PathEscape(tenant.Code) + "/messages/" + url.PathEscape(in.Topic) + "/" + strconv.FormatInt(in.SeqId, 10)
|
||||
return imAdminQueryOne[sysin.ImMessageViewModel](ctx, tenant, path,
|
||||
map[string]string{"sender_user_id": "fromUserId", "sent_at": "createdAt", "message_type": "contentType"})
|
||||
}
|
||||
|
||||
func (s *sSysImPrivateMessage) Hide(ctx context.Context, in *sysin.ImMessageActionInp) (*sysin.ImMessageCommandModel, error) {
|
||||
return publishMessageCommand(ctx, in, "private", consts.ImAdminCommandMessageHide)
|
||||
}
|
||||
|
||||
func (s *sSysImPrivateMessage) Delete(ctx context.Context, in *sysin.ImMessageActionInp) (*sysin.ImMessageCommandModel, error) {
|
||||
return publishMessageCommand(ctx, in, "private", consts.ImAdminCommandMessageDelete)
|
||||
}
|
||||
|
||||
func (s *sSysImGroupMessage) Hide(ctx context.Context, in *sysin.ImMessageActionInp) (*sysin.ImMessageCommandModel, error) {
|
||||
return publishMessageCommand(ctx, in, "group", consts.ImAdminCommandMessageHide)
|
||||
}
|
||||
|
||||
func (s *sSysImGroupMessage) Delete(ctx context.Context, in *sysin.ImMessageActionInp) (*sysin.ImMessageCommandModel, error) {
|
||||
return publishMessageCommand(ctx, in, "group", consts.ImAdminCommandMessageDelete)
|
||||
}
|
||||
|
||||
func publishMessageCommand(ctx context.Context, in *sysin.ImMessageActionInp, conversationType string, eventType string) (*sysin.ImMessageCommandModel, error) {
|
||||
if err := in.Filter(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tenant, err := resolveImAdminTenant(ctx, in.TenantId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
user := contexts.GetUser(ctx)
|
||||
actorName := ""
|
||||
if user != nil {
|
||||
actorName = user.RealName
|
||||
}
|
||||
bizId := in.Topic + ":" + strconv.FormatInt(in.SeqId, 10)
|
||||
command, err := imkafka.PublishAdminCommand(ctx, imkafka.AdminCommandInput{
|
||||
TenantID: tenant.Id, TenantCode: tenant.Code, EventType: eventType, BizType: "message", BizID: bizId,
|
||||
Actor: &imkafka.Actor{Type: "admin", ID: strconv.FormatInt(contexts.GetUserId(ctx), 10), DisplayName: actorName},
|
||||
Payload: map[string]any{"conversation_type": conversationType, "topic": in.Topic, "seq_id": in.SeqId, "reason": in.Reason},
|
||||
CreatedBy: contexts.GetUserId(ctx),
|
||||
})
|
||||
result := "success"
|
||||
if err != nil {
|
||||
result = "failed"
|
||||
}
|
||||
_ = writeImAdminAudit(ctx, tenant.Id, eventType, "message", in.SeqId, result, map[string]any{"conversation_type": conversationType, "topic": in.Topic, "reason": in.Reason})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &sysin.ImMessageCommandModel{CommandId: command.CommandID, EventId: command.EventID, Status: command.Status}, nil
|
||||
}
|
||||
|
||||
func (s *sSysImPrivateMessage) Export(ctx context.Context, in *sysin.ImPrivateMessageListInp) error {
|
||||
list, total, err := s.List(ctx, in)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return exportImMessages(ctx, list, total, in.Page, in.PerPage, "单聊消息")
|
||||
}
|
||||
|
||||
func (s *sSysImGroupMessage) Export(ctx context.Context, in *sysin.ImGroupMessageListInp) error {
|
||||
list, total, err := s.List(ctx, in)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return exportImMessages(ctx, list, total, in.Page, in.PerPage, "群聊消息")
|
||||
}
|
||||
|
||||
func exportImMessages(ctx context.Context, list []*sysin.ImMessageListModel, total int, page int, perPage int, label string) error {
|
||||
tags, err := convert.GetEntityDescTags(sysin.ImMessageExportModel{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var exports []sysin.ImMessageExportModel
|
||||
if err = gconv.Scan(list, &exports); err != nil {
|
||||
return err
|
||||
}
|
||||
fileName := "导出" + label + "-" + gctx.CtxId(ctx)
|
||||
sheetName := fmt.Sprintf("索引条件共%v行,共%v页,当前导出是第%v页,本页共%v行", total, form.CalPageCount(total, perPage), page, len(list))
|
||||
return excel.ExportByStructs(ctx, tags, exports, fileName, sheetName)
|
||||
}
|
||||
|
||||
func setQuery(values url.Values, key string, value string) {
|
||||
if value != "" {
|
||||
values.Set(key, value)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package sys
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"hotgo/internal/dao"
|
||||
"hotgo/internal/library/contexts"
|
||||
"hotgo/internal/library/imkafka"
|
||||
"hotgo/internal/library/imtenant"
|
||||
"hotgo/internal/model/entity"
|
||||
"hotgo/internal/service"
|
||||
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
)
|
||||
|
||||
func resolveImPolicyTenant(ctx context.Context, selectedTenantID int64) (tenantID int64, tenantCode string, err error) {
|
||||
operatorID := contexts.GetUserId(ctx)
|
||||
if service.AdminMember().VerifySuperId(ctx, operatorID) && selectedTenantID == 0 {
|
||||
return 0, "*", nil
|
||||
}
|
||||
scope, err := resolveImAdminScope(ctx, selectedTenantID)
|
||||
if err != nil {
|
||||
return 0, "", err
|
||||
}
|
||||
var tenant *entity.ImTenant
|
||||
if err = imtenant.RegistryDB().Model(dao.ImTenant.Table()).Safe().Ctx(ctx).
|
||||
Where(dao.ImTenant.Columns().Id, scope.TenantId).Scan(&tenant); err != nil {
|
||||
return 0, "", gerror.Wrap(err, "获取IM租户失败")
|
||||
}
|
||||
if tenant == nil {
|
||||
return 0, "", gerror.New("IM租户不存在")
|
||||
}
|
||||
return tenant.Id, tenant.Code, nil
|
||||
}
|
||||
|
||||
func policyJSON(value *gjson.Json, fallback string) string {
|
||||
if value == nil || value.String() == "" || value.String() == "null" {
|
||||
return fallback
|
||||
}
|
||||
return value.String()
|
||||
}
|
||||
|
||||
func publishImPolicyEvent(ctx context.Context, tenantID int64, tenantCode, eventType, group string, version uint) error {
|
||||
return imkafka.PublishConfigEvent(ctx, imkafka.ConfigEventInput{
|
||||
TenantID: tenantID,
|
||||
TenantCode: tenantCode,
|
||||
EventType: eventType,
|
||||
Group: group,
|
||||
Keys: []string{"version", "payload"},
|
||||
BizID: fmt.Sprintf("%s:%d:%d", group, tenantID, version),
|
||||
Actor: &imkafka.Actor{
|
||||
Type: "admin",
|
||||
ID: strconv.FormatInt(contexts.GetUserId(ctx), 10),
|
||||
},
|
||||
CreatedBy: contexts.GetUserId(ctx),
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,331 @@
|
||||
package sys
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
|
||||
"hotgo/internal/consts"
|
||||
"hotgo/internal/dao"
|
||||
"hotgo/internal/library/contexts"
|
||||
"hotgo/internal/library/imtenant"
|
||||
"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 sSysImSecurityPolicy struct{}
|
||||
|
||||
func NewSysImSecurityPolicy() *sSysImSecurityPolicy { return &sSysImSecurityPolicy{} }
|
||||
func init() { service.RegisterSysImSecurityPolicy(NewSysImSecurityPolicy()) }
|
||||
|
||||
func securityPolicyFields(alias string) []any {
|
||||
c := dao.ImSecurityPolicy.Columns()
|
||||
p := alias
|
||||
if p != "" {
|
||||
p += "."
|
||||
}
|
||||
return []any{p + c.Id, p + c.TenantId, p + c.PolicyVersion, p + c.PolicyName, p + c.PublishStatus, "CAST(" + p + c.PasswordPolicy + " AS CHAR) password_policy", "CAST(" + p + c.LoginRateLimit + " AS CHAR) login_rate_limit", "CAST(" + p + c.SensitiveWordPolicy + " AS CHAR) sensitive_word_policy", "CAST(" + p + c.FileReviewPolicy + " AS CHAR) file_review_policy", "CAST(" + p + c.RealnamePolicy + " AS CHAR) realname_policy", "CAST(" + p + c.RiskChallengePolicy + " AS CHAR) risk_challenge_policy", p + c.GlobalFriendEnabled, "CAST(" + p + c.FriendDisabledPolicy + " AS CHAR) friend_disabled_policy", p + c.MessageCurfewEnabled, p + c.Remark, p + c.PublishedAt, p + c.PublishedBy, p + c.CreatedAt, p + c.UpdatedAt}
|
||||
}
|
||||
|
||||
func (s *sSysImSecurityPolicy) List(ctx context.Context, in *sysin.ImSecurityPolicyListInp) (list []*sysin.ImSecurityPolicyModel, total int, err error) {
|
||||
if err = in.Filter(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
tenantID, _, err := resolveImPolicyTenant(ctx, in.TenantId)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
c := dao.ImSecurityPolicy.Columns()
|
||||
model := imtenant.RegistryDB().Model(dao.ImSecurityPolicy.Table()).Safe().Ctx(ctx).Fields(securityPolicyFields("")...).Where(c.TenantId, tenantID).WhereNull(c.DeletedAt)
|
||||
if in.PublishStatus != "" {
|
||||
model = model.Where(c.PublishStatus, in.PublishStatus)
|
||||
}
|
||||
err = model.Page(in.Page, in.PerPage).OrderDesc(c.PolicyVersion).ScanAndCount(&list, &total, false)
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sSysImSecurityPolicy) View(ctx context.Context, in *sysin.ImSecurityPolicyViewInp) (res *sysin.ImSecurityPolicyModel, err error) {
|
||||
if err = in.Filter(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
c := dao.ImSecurityPolicy.Columns()
|
||||
baseModel := imtenant.RegistryDB().Model(dao.ImSecurityPolicy.Table()).Safe().Ctx(ctx).Fields(securityPolicyFields("")...).WhereNull(c.DeletedAt)
|
||||
if in.Id > 0 {
|
||||
err = baseModel.Where(c.Id, in.Id).Scan(&res)
|
||||
} else {
|
||||
tenantID, _, resolveErr := resolveImPolicyTenant(ctx, in.TenantId)
|
||||
if resolveErr != nil {
|
||||
return nil, resolveErr
|
||||
}
|
||||
err = baseModel.Where(c.TenantId, tenantID).
|
||||
Where(c.PublishStatus, consts.ImSecurityPublishPublished).
|
||||
OrderDesc(c.PolicyVersion).Scan(&res)
|
||||
if err == nil && res == nil {
|
||||
err = baseModel.Where(c.TenantId, tenantID).OrderDesc(c.PolicyVersion).Scan(&res)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return nil, gerror.Wrap(err, "获取安全策略失败")
|
||||
}
|
||||
if res == nil {
|
||||
return nil, gerror.New("安全策略不存在")
|
||||
}
|
||||
if _, _, err = resolveImPolicyTenant(ctx, res.TenantId); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res.CurfewRules, err = s.curfewRules(ctx, res.Id)
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sSysImSecurityPolicy) curfewRules(ctx context.Context, policyID int64) (list []*sysin.ImMessageCurfewRuleModel, err error) {
|
||||
c := dao.ImMessageCurfewRules.Columns()
|
||||
err = imtenant.RegistryDB().Model(dao.ImMessageCurfewRules.Table()).Safe().Ctx(ctx).Fields(c.Id, c.RuleCode, c.RuleName, c.DateType, "CAST("+c.CustomDates+" AS CHAR) custom_dates", "CAST("+c.Weekdays+" AS CHAR) weekdays", c.Timezone, "TIME_FORMAT("+c.StartTime+",'%H:%i') start_time", "TIME_FORMAT("+c.EndTime+",'%H:%i') end_time", c.Scope, "CAST("+c.WhitelistUserIds+" AS CHAR) whitelist_user_ids", "CAST("+c.WhitelistGroupIds+" AS CHAR) whitelist_group_ids", c.Message, c.Status, c.Sort).Where(c.PolicyId, policyID).WhereNull(c.DeletedAt).OrderAsc(c.Sort).OrderAsc(c.Id).Scan(&list)
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sSysImSecurityPolicy) Save(ctx context.Context, in *sysin.ImSecurityPolicySaveInp) (id int64, err error) {
|
||||
if err = in.Filter(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
tenantID, _, err := resolveImPolicyTenant(ctx, in.TenantId)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
db := imtenant.RegistryDB()
|
||||
c := dao.ImSecurityPolicy.Columns()
|
||||
rc := dao.ImMessageCurfewRules.Columns()
|
||||
operator := contexts.GetUserId(ctx)
|
||||
now := gtime.Now()
|
||||
err = db.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
|
||||
version := uint(0)
|
||||
if in.Id > 0 {
|
||||
current, readErr := tx.Model(dao.ImSecurityPolicy.Table()).Safe().Ctx(ctx).Where(c.Id, in.Id).WhereNull(c.DeletedAt).One()
|
||||
if readErr != nil {
|
||||
return readErr
|
||||
}
|
||||
if current.IsEmpty() || current[c.TenantId].Int64() != tenantID {
|
||||
return gerror.New("安全策略不存在")
|
||||
}
|
||||
if current[c.PublishStatus].String() != consts.ImSecurityPublishDraft {
|
||||
return gerror.New("只有草稿状态的安全策略可以编辑")
|
||||
}
|
||||
version = current[c.PolicyVersion].Uint()
|
||||
id = in.Id
|
||||
} else {
|
||||
maxValue, maxErr := tx.Model(dao.ImSecurityPolicy.Table()).Safe().Ctx(ctx).Where(c.TenantId, tenantID).Max(c.PolicyVersion)
|
||||
if maxErr != nil {
|
||||
return maxErr
|
||||
}
|
||||
version = uint(maxValue) + 1
|
||||
}
|
||||
data := g.Map{c.TenantId: tenantID, c.PolicyVersion: version, c.PolicyName: in.PolicyName, c.PublishStatus: consts.ImSecurityPublishDraft, c.PasswordPolicy: policyJSON(in.PasswordPolicy, "{}"), c.LoginRateLimit: policyJSON(in.LoginRateLimit, "{}"), c.SensitiveWordPolicy: policyJSON(in.SensitiveWordPolicy, "{}"), c.FileReviewPolicy: policyJSON(in.FileReviewPolicy, "{}"), c.RealnamePolicy: policyJSON(in.RealnamePolicy, "{}"), c.RiskChallengePolicy: policyJSON(in.RiskChallengePolicy, "{}"), c.GlobalFriendEnabled: in.GlobalFriendEnabled, c.FriendDisabledPolicy: policyJSON(in.FriendDisabledPolicy, `{"hide_profile":true,"block_qrcode":true,"block_group_member_entry":true,"blocked_entries":["search","profile_card","group_member","qrcode","invite_auto_add","recommendation"],"message":"当前时段暂不允许添加好友"}`), c.MessageCurfewEnabled: in.MessageCurfewEnabled, c.Remark: in.Remark, c.UpdatedAt: now, c.UpdatedBy: operator}
|
||||
if in.Id > 0 {
|
||||
if _, updateErr := tx.Model(dao.ImSecurityPolicy.Table()).Safe().Ctx(ctx).Where(c.Id, in.Id).Data(data).Update(); updateErr != nil {
|
||||
return updateErr
|
||||
}
|
||||
} else {
|
||||
data[c.CreatedAt] = now
|
||||
data[c.CreatedBy] = operator
|
||||
result, insertErr := tx.Model(dao.ImSecurityPolicy.Table()).Safe().Ctx(ctx).Data(data).Insert()
|
||||
if insertErr != nil {
|
||||
return insertErr
|
||||
}
|
||||
id, insertErr = result.LastInsertId()
|
||||
if insertErr != nil {
|
||||
return insertErr
|
||||
}
|
||||
}
|
||||
if _, deleteErr := tx.Model(dao.ImMessageCurfewRules.Table()).Safe().Ctx(ctx).Where(rc.PolicyId, id).Delete(); deleteErr != nil {
|
||||
return deleteErr
|
||||
}
|
||||
for _, rule := range in.CurfewRules {
|
||||
_, insertErr := tx.Model(dao.ImMessageCurfewRules.Table()).Safe().Ctx(ctx).Data(g.Map{rc.TenantId: tenantID, rc.PolicyId: id, rc.RuleCode: rule.RuleCode, rc.RuleName: rule.RuleName, rc.DateType: rule.DateType, rc.CustomDates: policyJSON(rule.CustomDates, "[]"), rc.Weekdays: policyJSON(rule.Weekdays, "[]"), rc.Timezone: rule.Timezone, rc.StartTime: rule.StartTime, rc.EndTime: rule.EndTime, rc.Scope: rule.Scope, rc.WhitelistUserIds: policyJSON(rule.WhitelistUserIds, "[]"), rc.WhitelistGroupIds: policyJSON(rule.WhitelistGroupIds, "[]"), rc.Message: rule.Message, rc.Status: rule.Status, rc.Sort: rule.Sort, rc.CreatedAt: now, rc.CreatedBy: operator, rc.UpdatedAt: now, rc.UpdatedBy: operator}).Insert()
|
||||
if insertErr != nil {
|
||||
return insertErr
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return 0, gerror.Wrap(err, "保存安全策略草稿失败")
|
||||
}
|
||||
_ = writeImAdminAudit(ctx, tenantID, "im_security_policy_save", "im_security_policy", id, "success", g.Map{"global_friend_enabled": in.GlobalFriendEnabled, "message_curfew_enabled": in.MessageCurfewEnabled})
|
||||
return id, nil
|
||||
}
|
||||
|
||||
func (s *sSysImSecurityPolicy) Publish(ctx context.Context, in *sysin.ImSecurityPolicyPublishInp) error {
|
||||
if err := in.Filter(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
db := imtenant.RegistryDB()
|
||||
c := dao.ImSecurityPolicy.Columns()
|
||||
var row gdb.Record
|
||||
var err error
|
||||
if row, err = db.Model(dao.ImSecurityPolicy.Table()).Safe().Ctx(ctx).Where(c.Id, in.Id).WhereNull(c.DeletedAt).One(); err != nil {
|
||||
return err
|
||||
}
|
||||
if row.IsEmpty() {
|
||||
return gerror.New("安全策略不存在")
|
||||
}
|
||||
if row[c.PublishStatus].String() != consts.ImSecurityPublishDraft {
|
||||
return gerror.New("只有草稿状态可以发布")
|
||||
}
|
||||
tenantID, tenantCode, err := resolveImPolicyTenant(ctx, row[c.TenantId].Int64())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
operator := contexts.GetUserId(ctx)
|
||||
now := gtime.Now()
|
||||
err = db.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
|
||||
if _, updateErr := tx.Model(dao.ImSecurityPolicy.Table()).Safe().Ctx(ctx).Where(c.TenantId, tenantID).Where(c.PublishStatus, consts.ImSecurityPublishPublished).WhereNot(c.Id, in.Id).WhereNull(c.DeletedAt).Data(g.Map{c.PublishStatus: consts.ImSecurityPublishArchived, c.UpdatedAt: now, c.UpdatedBy: operator}).Update(); updateErr != nil {
|
||||
return updateErr
|
||||
}
|
||||
if _, updateErr := tx.Model(dao.ImSecurityPolicy.Table()).Safe().Ctx(ctx).Where(c.Id, in.Id).Data(g.Map{c.PublishStatus: consts.ImSecurityPublishPublished, c.PublishedAt: now, c.PublishedBy: operator, c.UpdatedAt: now, c.UpdatedBy: operator}).Update(); updateErr != nil {
|
||||
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 {
|
||||
return updateErr
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return gerror.Wrap(err, "发布安全策略失败")
|
||||
}
|
||||
_ = writeImAdminAudit(ctx, tenantID, "im_security_policy_publish", "im_security_policy", in.Id, "success", g.Map{"reason": in.Reason, "version": row[c.PolicyVersion].Uint()})
|
||||
return publishImPolicyEvent(ctx, tenantID, tenantCode, "security.policy.updated", "security_policy", row[c.PolicyVersion].Uint())
|
||||
}
|
||||
|
||||
func (s *sSysImSecurityPolicy) RestoreDefault(ctx context.Context, in *sysin.ImSecurityPolicyRestoreInp) (int64, error) {
|
||||
if err := in.Filter(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
tenantID, _, err := resolveImPolicyTenant(ctx, in.TenantId)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
c := dao.ImSecurityPolicy.Columns()
|
||||
var source *sysin.ImSecurityPolicyModel
|
||||
err = imtenant.RegistryDB().Model(dao.ImSecurityPolicy.Table()).Safe().Ctx(ctx).
|
||||
Fields(securityPolicyFields("")...).Where(c.TenantId, 0).
|
||||
Where(c.PublishStatus, consts.ImSecurityPublishPublished).WhereNull(c.DeletedAt).
|
||||
OrderDesc(c.PolicyVersion).Scan(&source)
|
||||
if err != nil {
|
||||
return 0, gerror.Wrap(err, "读取全局默认安全策略失败")
|
||||
}
|
||||
if source == nil {
|
||||
return 0, gerror.New("全局默认安全策略不存在")
|
||||
}
|
||||
source.CurfewRules, err = s.curfewRules(ctx, source.Id)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
rules := make([]*sysin.ImMessageCurfewRuleInp, 0, len(source.CurfewRules))
|
||||
for _, rule := range source.CurfewRules {
|
||||
rules = append(rules, &sysin.ImMessageCurfewRuleInp{RuleCode: rule.RuleCode, RuleName: rule.RuleName, DateType: rule.DateType, CustomDates: gjson.New(rule.CustomDates), Weekdays: gjson.New(rule.Weekdays), Timezone: rule.Timezone, StartTime: rule.StartTime, EndTime: rule.EndTime, Scope: rule.Scope, WhitelistUserIds: gjson.New(rule.WhitelistUserIds), WhitelistGroupIds: gjson.New(rule.WhitelistGroupIds), Message: rule.Message, Status: rule.Status, Sort: rule.Sort})
|
||||
}
|
||||
id, err := s.Save(ctx, &sysin.ImSecurityPolicySaveInp{TenantId: tenantID, PolicyName: "恢复默认安全策略", PasswordPolicy: gjson.New(source.PasswordPolicy), LoginRateLimit: gjson.New(source.LoginRateLimit), SensitiveWordPolicy: gjson.New(source.SensitiveWordPolicy), FileReviewPolicy: gjson.New(source.FileReviewPolicy), RealnamePolicy: gjson.New(source.RealnamePolicy), RiskChallengePolicy: gjson.New(source.RiskChallengePolicy), GlobalFriendEnabled: source.GlobalFriendEnabled, FriendDisabledPolicy: gjson.New(source.FriendDisabledPolicy), MessageCurfewEnabled: source.MessageCurfewEnabled, Remark: in.Reason, CurfewRules: rules})
|
||||
if err == nil {
|
||||
_ = writeImAdminAudit(ctx, tenantID, "im_security_policy_restore_default", "im_security_policy", id, "success", g.Map{"reason": in.Reason})
|
||||
}
|
||||
return id, err
|
||||
}
|
||||
|
||||
func (s *sSysImSecurityPolicy) IPRuleList(ctx context.Context, in *sysin.ImSecurityIPRuleListInp) (list []*sysin.ImSecurityIPRuleModel, total int, err error) {
|
||||
if err = in.Filter(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
tenantID, _, err := resolveImPolicyTenant(ctx, in.TenantId)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
c := dao.ImSecurityIpRules.Columns()
|
||||
model := imtenant.RegistryDB().Model(dao.ImSecurityIpRules.Table()).Safe().Ctx(ctx).Fields(c.Id, c.TenantId, c.RuleType, c.IpCidr, c.Action, "CAST("+c.SceneJson+" AS CHAR) scene_json", c.RiskLevel, c.Status, c.ExpiresAt, c.Remark, c.CreatedAt, c.UpdatedAt).Where(c.TenantId, tenantID).WhereNull(c.DeletedAt)
|
||||
if in.RuleType != "" {
|
||||
model = model.Where(c.RuleType, in.RuleType)
|
||||
}
|
||||
if in.IpCidr != "" {
|
||||
model = model.WhereLike(c.IpCidr, "%"+in.IpCidr+"%")
|
||||
}
|
||||
if in.Status != 0 {
|
||||
model = model.Where(c.Status, in.Status)
|
||||
}
|
||||
err = model.Page(in.Page, in.PerPage).OrderDesc(c.Id).ScanAndCount(&list, &total, false)
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sSysImSecurityPolicy) IPRuleEdit(ctx context.Context, in *sysin.ImSecurityIPRuleEditInp) error {
|
||||
if err := in.Filter(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if net.ParseIP(in.IpCidr) == nil {
|
||||
if _, _, err := net.ParseCIDR(in.IpCidr); err != nil {
|
||||
return gerror.New("IP或CIDR格式不合法")
|
||||
}
|
||||
}
|
||||
tenantID, tenantCode, err := resolveImPolicyTenant(ctx, in.TenantId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c := dao.ImSecurityIpRules.Columns()
|
||||
db := imtenant.RegistryDB()
|
||||
now := gtime.Now()
|
||||
data := g.Map{c.TenantId: tenantID, c.RuleType: in.RuleType, c.IpCidr: in.IpCidr, c.Action: in.Action, c.SceneJson: policyJSON(in.SceneJson, "[]"), c.RiskLevel: in.RiskLevel, c.Status: in.Status, c.ExpiresAt: in.ExpiresAt, c.Remark: in.Remark, c.UpdatedAt: now, c.UpdatedBy: contexts.GetUserId(ctx)}
|
||||
targetID := in.Id
|
||||
if in.Id > 0 {
|
||||
var row gdb.Record
|
||||
if row, err = db.Model(dao.ImSecurityIpRules.Table()).Safe().Ctx(ctx).Where(c.Id, in.Id).WhereNull(c.DeletedAt).One(); err != nil {
|
||||
return err
|
||||
}
|
||||
if row.IsEmpty() || row[c.TenantId].Int64() != tenantID {
|
||||
return gerror.New("IP规则不存在")
|
||||
}
|
||||
_, err = db.Model(dao.ImSecurityIpRules.Table()).Safe().Ctx(ctx).Where(c.Id, in.Id).Data(data).Update()
|
||||
} else {
|
||||
data[c.CreatedAt] = now
|
||||
data[c.CreatedBy] = contexts.GetUserId(ctx)
|
||||
result, insertErr := db.Model(dao.ImSecurityIpRules.Table()).Safe().Ctx(ctx).Data(data).Insert()
|
||||
err = insertErr
|
||||
if err == nil {
|
||||
targetID, err = result.LastInsertId()
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return gerror.Wrap(err, "保存IP规则失败")
|
||||
}
|
||||
_ = writeImAdminAudit(ctx, tenantID, "im_security_ip_rule_edit", "im_security_ip_rule", targetID, "success", g.Map{"ip_cidr": in.IpCidr, "rule_type": in.RuleType})
|
||||
return publishImPolicyEvent(ctx, tenantID, tenantCode, "security.policy.updated", "security_policy", uint(targetID))
|
||||
}
|
||||
|
||||
func (s *sSysImSecurityPolicy) IPRuleDelete(ctx context.Context, in *sysin.ImSecurityIPRuleDeleteInp) error {
|
||||
if err := in.Filter(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
c := dao.ImSecurityIpRules.Columns()
|
||||
db := imtenant.RegistryDB()
|
||||
var row gdb.Record
|
||||
var err error
|
||||
if row, err = db.Model(dao.ImSecurityIpRules.Table()).Safe().Ctx(ctx).Where(c.Id, in.Id).WhereNull(c.DeletedAt).One(); err != nil {
|
||||
return err
|
||||
}
|
||||
if row.IsEmpty() {
|
||||
return gerror.New("IP规则不存在")
|
||||
}
|
||||
tenantID, tenantCode, err := resolveImPolicyTenant(ctx, row[c.TenantId].Int64())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = db.Model(dao.ImSecurityIpRules.Table()).Safe().Ctx(ctx).Where(c.Id, in.Id).Data(g.Map{c.Status: consts.StatusDisable, c.DeletedAt: gtime.Now(), c.DeletedBy: contexts.GetUserId(ctx), c.UpdatedAt: gtime.Now(), c.UpdatedBy: contexts.GetUserId(ctx)}).Update()
|
||||
if err != nil {
|
||||
return gerror.Wrap(err, "删除IP规则失败")
|
||||
}
|
||||
_ = writeImAdminAudit(ctx, tenantID, "im_security_ip_rule_delete", "im_security_ip_rule", in.Id, "success", nil)
|
||||
return publishImPolicyEvent(ctx, tenantID, tenantCode, "security.policy.updated", "security_policy", uint(in.Id))
|
||||
}
|
||||
@@ -0,0 +1,266 @@
|
||||
package sys
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"strings"
|
||||
|
||||
"hotgo/internal/consts"
|
||||
"hotgo/internal/dao"
|
||||
"hotgo/internal/library/contexts"
|
||||
"hotgo/internal/library/imtenant"
|
||||
"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 sSysImSensitiveWord struct{}
|
||||
|
||||
func NewSysImSensitiveWord() *sSysImSensitiveWord { return &sSysImSensitiveWord{} }
|
||||
func init() { service.RegisterSysImSensitiveWord(NewSysImSensitiveWord()) }
|
||||
|
||||
func normalizedSensitiveWord(value string) (string, string) {
|
||||
normalized := strings.ToLower(strings.TrimSpace(value))
|
||||
sum := sha256.Sum256([]byte(normalized))
|
||||
return normalized, hex.EncodeToString(sum[:])
|
||||
}
|
||||
|
||||
func (s *sSysImSensitiveWord) List(ctx context.Context, in *sysin.ImSensitiveWordListInp) (list []*sysin.ImSensitiveWordListModel, total int, err error) {
|
||||
if err = in.Filter(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
tenantID, _, err := resolveImPolicyTenant(ctx, in.TenantId)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
c := dao.ImSensitiveWords.Columns()
|
||||
gc := dao.ImSensitiveWordGroups.Columns()
|
||||
model := imtenant.RegistryDB().Model(dao.ImSensitiveWords.Table()+" w").Safe().Ctx(ctx).LeftJoin(dao.ImSensitiveWordGroups.Table()+" g", "g."+gc.Id+"=w."+c.GroupId).Fields("w."+c.Id, "w."+c.TenantId, "w."+c.GroupId, "g."+gc.GroupName, "w."+c.Word, "w."+c.MatchType, "CAST(w."+c.SceneJson+" AS CHAR) scene_json", "w."+c.Action, "w."+c.Replacement, "w."+c.RiskLevel, "w."+c.Priority, "w."+c.Status, "w."+c.Remark, "w."+c.CreatedAt, "w."+c.UpdatedAt).Where("w."+c.TenantId, tenantID).WhereNull("w." + c.DeletedAt)
|
||||
if in.GroupId > 0 {
|
||||
model = model.Where("w."+c.GroupId, in.GroupId)
|
||||
}
|
||||
if in.Word != "" {
|
||||
model = model.WhereLike("w."+c.Word, "%"+in.Word+"%")
|
||||
}
|
||||
if in.MatchType != "" {
|
||||
model = model.Where("w."+c.MatchType, in.MatchType)
|
||||
}
|
||||
if in.Action != "" {
|
||||
model = model.Where("w."+c.Action, in.Action)
|
||||
}
|
||||
if in.RiskLevel != "" {
|
||||
model = model.Where("w."+c.RiskLevel, in.RiskLevel)
|
||||
}
|
||||
if in.Status != 0 {
|
||||
model = model.Where("w."+c.Status, in.Status)
|
||||
}
|
||||
err = model.Page(in.Page, in.PerPage).OrderDesc("w."+c.Priority).OrderDesc("w."+c.Id).ScanAndCount(&list, &total, false)
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, "获取敏感词列表失败")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sSysImSensitiveWord) Edit(ctx context.Context, in *sysin.ImSensitiveWordEditInp) error {
|
||||
if err := in.Filter(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
tenantID, tenantCode, err := resolveImPolicyTenant(ctx, in.TenantId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = validateSensitiveWordGroup(ctx, tenantID, in.GroupId); err != nil {
|
||||
return err
|
||||
}
|
||||
_, hash := normalizedSensitiveWord(in.Word)
|
||||
c := dao.ImSensitiveWords.Columns()
|
||||
db := imtenant.RegistryDB()
|
||||
now := gtime.Now()
|
||||
data := g.Map{c.TenantId: tenantID, c.GroupId: in.GroupId, c.Word: in.Word, c.WordHash: hash, c.MatchType: in.MatchType, c.SceneJson: policyJSON(in.SceneJson, "[]"), c.Action: in.Action, c.Replacement: in.Replacement, c.RiskLevel: in.RiskLevel, c.Priority: in.Priority, c.Status: in.Status, c.Remark: in.Remark, c.UpdatedAt: now, c.UpdatedBy: contexts.GetUserId(ctx)}
|
||||
targetID := in.Id
|
||||
if in.Id > 0 {
|
||||
var row gdb.Record
|
||||
if row, err = db.Model(dao.ImSensitiveWords.Table()).Safe().Ctx(ctx).Where(c.Id, in.Id).WhereNull(c.DeletedAt).One(); err != nil {
|
||||
return err
|
||||
}
|
||||
if row.IsEmpty() || row[c.TenantId].Int64() != tenantID {
|
||||
return gerror.New("敏感词不存在")
|
||||
}
|
||||
_, err = db.Model(dao.ImSensitiveWords.Table()).Safe().Ctx(ctx).Where(c.Id, in.Id).Data(data).Update()
|
||||
} else {
|
||||
data[c.CreatedAt] = now
|
||||
data[c.CreatedBy] = contexts.GetUserId(ctx)
|
||||
result, insertErr := db.Model(dao.ImSensitiveWords.Table()).Safe().Ctx(ctx).Data(data).Insert()
|
||||
err = insertErr
|
||||
if err == nil {
|
||||
targetID, err = result.LastInsertId()
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return gerror.Wrap(err, "保存敏感词失败,请检查是否重复")
|
||||
}
|
||||
_ = writeImAdminAudit(ctx, tenantID, "im_sensitive_word_edit", "im_sensitive_word", targetID, "success", g.Map{"group_id": in.GroupId, "action": in.Action})
|
||||
return publishImPolicyEvent(ctx, tenantID, tenantCode, "sensitive_words.updated", "sensitive_words", uint(targetID))
|
||||
}
|
||||
|
||||
func (s *sSysImSensitiveWord) Delete(ctx context.Context, in *sysin.ImSensitiveWordDeleteInp) error {
|
||||
if err := in.Filter(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return s.updateWordState(ctx, in.Id, consts.StatusDisable, true, "im_sensitive_word_delete")
|
||||
}
|
||||
func (s *sSysImSensitiveWord) Status(ctx context.Context, in *sysin.ImSensitiveWordStatusInp) error {
|
||||
if err := in.Filter(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return s.updateWordState(ctx, in.Id, in.Status, false, "im_sensitive_word_status")
|
||||
}
|
||||
func (s *sSysImSensitiveWord) updateWordState(ctx context.Context, id int64, status int, deleted bool, action string) error {
|
||||
c := dao.ImSensitiveWords.Columns()
|
||||
db := imtenant.RegistryDB()
|
||||
var row gdb.Record
|
||||
var err error
|
||||
if row, err = db.Model(dao.ImSensitiveWords.Table()).Safe().Ctx(ctx).Where(c.Id, id).WhereNull(c.DeletedAt).One(); err != nil {
|
||||
return err
|
||||
}
|
||||
if row.IsEmpty() {
|
||||
return gerror.New("敏感词不存在")
|
||||
}
|
||||
tenantID, tenantCode, err := resolveImPolicyTenant(ctx, row[c.TenantId].Int64())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
data := g.Map{c.Status: status, c.UpdatedAt: gtime.Now(), c.UpdatedBy: contexts.GetUserId(ctx)}
|
||||
if deleted {
|
||||
data[c.DeletedAt] = gtime.Now()
|
||||
data[c.DeletedBy] = contexts.GetUserId(ctx)
|
||||
}
|
||||
if _, err = db.Model(dao.ImSensitiveWords.Table()).Safe().Ctx(ctx).Where(c.Id, id).Data(data).Update(); err != nil {
|
||||
return gerror.Wrap(err, "更新敏感词失败")
|
||||
}
|
||||
_ = writeImAdminAudit(ctx, tenantID, action, "im_sensitive_word", id, "success", g.Map{"status": status})
|
||||
return publishImPolicyEvent(ctx, tenantID, tenantCode, "sensitive_words.updated", "sensitive_words", uint(id))
|
||||
}
|
||||
|
||||
func (s *sSysImSensitiveWord) BatchImport(ctx context.Context, in *sysin.ImSensitiveWordBatchImportInp) (res *sysin.ImSensitiveWordBatchImportModel, err error) {
|
||||
if err = in.Filter(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
tenantID, tenantCode, err := resolveImPolicyTenant(ctx, in.TenantId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = validateSensitiveWordGroup(ctx, tenantID, in.GroupId); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res = &sysin.ImSensitiveWordBatchImportModel{}
|
||||
db := imtenant.RegistryDB()
|
||||
c := dao.ImSensitiveWords.Columns()
|
||||
seen := map[string]struct{}{}
|
||||
err = db.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
|
||||
for _, raw := range in.Words {
|
||||
word, hash := normalizedSensitiveWord(raw)
|
||||
if word == "" {
|
||||
res.Skipped++
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[hash]; ok {
|
||||
res.Skipped++
|
||||
continue
|
||||
}
|
||||
seen[hash] = struct{}{}
|
||||
count, countErr := tx.Model(dao.ImSensitiveWords.Table()).Safe().Ctx(ctx).Where(c.TenantId, tenantID).Where(c.GroupId, in.GroupId).Where(c.WordHash, hash).WhereNull(c.DeletedAt).Count()
|
||||
if countErr != nil {
|
||||
return countErr
|
||||
}
|
||||
if count > 0 {
|
||||
res.Skipped++
|
||||
continue
|
||||
}
|
||||
now := gtime.Now()
|
||||
_, insertErr := tx.Model(dao.ImSensitiveWords.Table()).Safe().Ctx(ctx).Data(g.Map{c.TenantId: tenantID, c.GroupId: in.GroupId, c.Word: strings.TrimSpace(raw), c.WordHash: hash, c.MatchType: in.MatchType, c.SceneJson: policyJSON(in.SceneJson, "[]"), c.Action: in.Action, c.Replacement: in.Replacement, c.RiskLevel: in.RiskLevel, c.Status: consts.StatusEnabled, c.CreatedAt: now, c.CreatedBy: contexts.GetUserId(ctx), c.UpdatedAt: now, c.UpdatedBy: contexts.GetUserId(ctx)}).Insert()
|
||||
if insertErr != nil {
|
||||
return insertErr
|
||||
}
|
||||
res.Inserted++
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, gerror.Wrap(err, "批量导入敏感词失败")
|
||||
}
|
||||
_ = writeImAdminAudit(ctx, tenantID, "im_sensitive_word_batch_import", "im_sensitive_word", 0, "success", g.Map{"inserted": res.Inserted, "skipped": res.Skipped})
|
||||
err = publishImPolicyEvent(ctx, tenantID, tenantCode, "sensitive_words.updated", "sensitive_words", uint(res.Inserted))
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sSysImSensitiveWord) GroupList(ctx context.Context, in *sysin.ImSensitiveWordGroupListInp) (list []*sysin.ImSensitiveWordGroupModel, err error) {
|
||||
if err = in.Filter(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
tenantID, _, err := resolveImPolicyTenant(ctx, in.TenantId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c := dao.ImSensitiveWordGroups.Columns()
|
||||
err = imtenant.RegistryDB().Model(dao.ImSensitiveWordGroups.Table()).Safe().Ctx(ctx).Fields(c.Id, c.TenantId, c.GroupCode, c.GroupName, c.Priority, c.Status, c.Remark, c.CreatedAt).Where(c.TenantId, tenantID).WhereNull(c.DeletedAt).OrderDesc(c.Priority).OrderAsc(c.GroupName).Scan(&list)
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sSysImSensitiveWord) GroupEdit(ctx context.Context, in *sysin.ImSensitiveWordGroupEditInp) error {
|
||||
if err := in.Filter(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
tenantID, tenantCode, err := resolveImPolicyTenant(ctx, in.TenantId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c := dao.ImSensitiveWordGroups.Columns()
|
||||
db := imtenant.RegistryDB()
|
||||
now := gtime.Now()
|
||||
data := g.Map{c.TenantId: tenantID, c.GroupCode: in.GroupCode, c.GroupName: in.GroupName, c.Priority: in.Priority, c.Status: in.Status, c.Remark: in.Remark, c.UpdatedAt: now, c.UpdatedBy: contexts.GetUserId(ctx)}
|
||||
targetID := in.Id
|
||||
if in.Id > 0 {
|
||||
var row gdb.Record
|
||||
if row, err = db.Model(dao.ImSensitiveWordGroups.Table()).Safe().Ctx(ctx).Where(c.Id, in.Id).WhereNull(c.DeletedAt).One(); err != nil {
|
||||
return err
|
||||
}
|
||||
if row.IsEmpty() || row[c.TenantId].Int64() != tenantID {
|
||||
return gerror.New("敏感词分组不存在")
|
||||
}
|
||||
if row[c.GroupCode].String() != in.GroupCode {
|
||||
return gerror.New("分组编码创建后不能修改")
|
||||
}
|
||||
_, err = db.Model(dao.ImSensitiveWordGroups.Table()).Safe().Ctx(ctx).Where(c.Id, in.Id).Data(data).Update()
|
||||
} else {
|
||||
data[c.CreatedAt] = now
|
||||
data[c.CreatedBy] = contexts.GetUserId(ctx)
|
||||
result, insertErr := db.Model(dao.ImSensitiveWordGroups.Table()).Safe().Ctx(ctx).Data(data).Insert()
|
||||
err = insertErr
|
||||
if err == nil {
|
||||
targetID, err = result.LastInsertId()
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return gerror.Wrap(err, "保存敏感词分组失败")
|
||||
}
|
||||
_ = writeImAdminAudit(ctx, tenantID, "im_sensitive_word_group_edit", "im_sensitive_word_group", targetID, "success", nil)
|
||||
return publishImPolicyEvent(ctx, tenantID, tenantCode, "sensitive_words.updated", "sensitive_words", uint(targetID))
|
||||
}
|
||||
|
||||
func validateSensitiveWordGroup(ctx context.Context, tenantID, groupID int64) error {
|
||||
c := dao.ImSensitiveWordGroups.Columns()
|
||||
count, err := imtenant.RegistryDB().Model(dao.ImSensitiveWordGroups.Table()).Safe().Ctx(ctx).Where(c.Id, groupID).Where(c.TenantId, tenantID).WhereNull(c.DeletedAt).Count()
|
||||
if err != nil {
|
||||
return gerror.Wrap(err, "检查敏感词分组失败")
|
||||
}
|
||||
if count == 0 {
|
||||
return gerror.New("敏感词分组不存在")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,290 @@
|
||||
package sys
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"hotgo/internal/consts"
|
||||
"hotgo/internal/dao"
|
||||
"hotgo/internal/library/contexts"
|
||||
"hotgo/internal/library/imtenant"
|
||||
"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 sSysImUserPolicyGroup struct{}
|
||||
|
||||
func NewSysImUserPolicyGroup() *sSysImUserPolicyGroup { return &sSysImUserPolicyGroup{} }
|
||||
func init() { service.RegisterSysImUserPolicyGroup(NewSysImUserPolicyGroup()) }
|
||||
|
||||
func (s *sSysImUserPolicyGroup) List(ctx context.Context, in *sysin.ImUserPolicyGroupListInp) (list []*sysin.ImUserPolicyGroupListModel, total int, err error) {
|
||||
if err = in.Filter(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
tenantID, _, err := resolveImPolicyTenant(ctx, in.TenantId)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
c := dao.ImUserPolicyGroups.Columns()
|
||||
mc := dao.ImUserPolicyGroupMembers.Columns()
|
||||
model := imtenant.RegistryDB().Model(dao.ImUserPolicyGroups.Table()+" p").Safe().Ctx(ctx).
|
||||
Fields("p."+c.Id, "p."+c.TenantId, "p."+c.GroupCode, "p."+c.GroupName, "p."+c.Priority, "p."+c.Status,
|
||||
"CAST(p."+c.PolicyJson+" AS CHAR) policy_json", "CAST(p."+c.IpWhitelist+" AS CHAR) ip_whitelist",
|
||||
"CAST(p."+c.IpBlacklist+" AS CHAR) ip_blacklist", "p."+c.Version, "p."+c.Remark, "p."+c.CreatedAt, "p."+c.UpdatedAt,
|
||||
"(SELECT COUNT(*) FROM "+dao.ImUserPolicyGroupMembers.Table()+" m WHERE m."+mc.GroupId+"=p."+c.Id+" AND m."+mc.Status+"=1 AND m."+mc.DeletedAt+" IS NULL) member_count").
|
||||
Where("p."+c.TenantId, tenantID).WhereNull("p." + c.DeletedAt)
|
||||
if in.Keyword != "" {
|
||||
keyword := "%" + in.Keyword + "%"
|
||||
model = model.Where("(p."+c.GroupCode+" LIKE ? OR p."+c.GroupName+" LIKE ?)", keyword, keyword)
|
||||
}
|
||||
if in.Status != 0 {
|
||||
model = model.Where("p."+c.Status, in.Status)
|
||||
}
|
||||
err = model.Page(in.Page, in.PerPage).OrderDesc("p."+c.Priority).OrderDesc("p."+c.Id).ScanAndCount(&list, &total, false)
|
||||
if err != nil {
|
||||
err = gerror.Wrap(err, "获取用户策略分组失败")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sSysImUserPolicyGroup) View(ctx context.Context, in *sysin.ImUserPolicyGroupViewInp) (res *sysin.ImUserPolicyGroupViewModel, err error) {
|
||||
if err = in.Filter(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
c := dao.ImUserPolicyGroups.Columns()
|
||||
var row *sysin.ImUserPolicyGroupListModel
|
||||
err = imtenant.RegistryDB().Model(dao.ImUserPolicyGroups.Table()).Safe().Ctx(ctx).
|
||||
Fields(c.Id, c.TenantId, c.GroupCode, c.GroupName, c.Priority, c.Status, "CAST("+c.PolicyJson+" AS CHAR) policy_json", "CAST("+c.IpWhitelist+" AS CHAR) ip_whitelist", "CAST("+c.IpBlacklist+" AS CHAR) ip_blacklist", c.Version, c.Remark, c.CreatedAt, c.UpdatedAt).
|
||||
Where(c.Id, in.Id).WhereNull(c.DeletedAt).Scan(&row)
|
||||
if err != nil {
|
||||
return nil, gerror.Wrap(err, "获取用户策略分组详情失败")
|
||||
}
|
||||
if row == nil {
|
||||
return nil, gerror.New("用户策略分组不存在")
|
||||
}
|
||||
if _, _, err = resolveImPolicyTenant(ctx, row.TenantId); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &sysin.ImUserPolicyGroupViewModel{ImUserPolicyGroupListModel: *row}, nil
|
||||
}
|
||||
|
||||
func (s *sSysImUserPolicyGroup) Edit(ctx context.Context, in *sysin.ImUserPolicyGroupEditInp) error {
|
||||
if err := in.Filter(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
tenantID, tenantCode, err := resolveImPolicyTenant(ctx, in.TenantId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c := dao.ImUserPolicyGroups.Columns()
|
||||
db := imtenant.RegistryDB()
|
||||
now := gtime.Now()
|
||||
operator := contexts.GetUserId(ctx)
|
||||
data := g.Map{c.GroupName: in.GroupName, c.Priority: in.Priority, c.Status: in.Status, c.PolicyJson: policyJSON(in.PolicyJson, "{}"), c.IpWhitelist: policyJSON(in.IpWhitelist, "[]"), c.IpBlacklist: policyJSON(in.IpBlacklist, "[]"), c.Remark: in.Remark, c.UpdatedAt: now, c.UpdatedBy: operator}
|
||||
var targetID int64
|
||||
if in.Id > 0 {
|
||||
var current gdb.Record
|
||||
if current, err = db.Model(dao.ImUserPolicyGroups.Table()).Safe().Ctx(ctx).Where(c.Id, in.Id).WhereNull(c.DeletedAt).One(); err != nil {
|
||||
return gerror.Wrap(err, "读取用户策略分组失败")
|
||||
}
|
||||
if current.IsEmpty() || current[c.TenantId].Int64() != tenantID {
|
||||
return gerror.New("用户策略分组不存在")
|
||||
}
|
||||
if current[c.GroupCode].String() != in.GroupCode {
|
||||
return gerror.New("分组编码创建后不能修改")
|
||||
}
|
||||
data[c.Version] = gdb.Raw("version+1")
|
||||
if _, err = db.Model(dao.ImUserPolicyGroups.Table()).Safe().Ctx(ctx).Where(c.Id, in.Id).Data(data).Update(); err != nil {
|
||||
return gerror.Wrap(err, "更新用户策略分组失败")
|
||||
}
|
||||
targetID = in.Id
|
||||
} else {
|
||||
data[c.TenantId] = tenantID
|
||||
data[c.GroupCode] = in.GroupCode
|
||||
data[c.Version] = 1
|
||||
data[c.CreatedAt] = now
|
||||
data[c.CreatedBy] = operator
|
||||
result, insertErr := db.Model(dao.ImUserPolicyGroups.Table()).Safe().Ctx(ctx).Data(data).Insert()
|
||||
if insertErr != nil {
|
||||
return gerror.Wrap(insertErr, "新增用户策略分组失败")
|
||||
}
|
||||
targetID, err = result.LastInsertId()
|
||||
if err != nil {
|
||||
return gerror.Wrap(err, "获取用户策略分组ID失败")
|
||||
}
|
||||
}
|
||||
_ = writeImAdminAudit(ctx, tenantID, "im_user_policy_group_edit", "im_user_policy_group", targetID, "success", g.Map{"group_code": in.GroupCode})
|
||||
return publishImPolicyEvent(ctx, tenantID, tenantCode, "user_policy_group.updated", "user_policy_groups", uint(targetID))
|
||||
}
|
||||
|
||||
func (s *sSysImUserPolicyGroup) Delete(ctx context.Context, in *sysin.ImUserPolicyGroupDeleteInp) error {
|
||||
if err := in.Filter(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
c := dao.ImUserPolicyGroups.Columns()
|
||||
mc := dao.ImUserPolicyGroupMembers.Columns()
|
||||
db := imtenant.RegistryDB()
|
||||
var row gdb.Record
|
||||
var err error
|
||||
if row, err = db.Model(dao.ImUserPolicyGroups.Table()).Safe().Ctx(ctx).Where(c.Id, in.Id).WhereNull(c.DeletedAt).One(); err != nil {
|
||||
return gerror.Wrap(err, "读取用户策略分组失败")
|
||||
}
|
||||
if row.IsEmpty() {
|
||||
return gerror.New("用户策略分组不存在")
|
||||
}
|
||||
tenantID, tenantCode, err := resolveImPolicyTenant(ctx, row[c.TenantId].Int64())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
count, err := db.Model(dao.ImUserPolicyGroupMembers.Table()).Safe().Ctx(ctx).Where(mc.GroupId, in.Id).Where(mc.Status, consts.StatusEnabled).WhereNull(mc.DeletedAt).Count()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if count > 0 {
|
||||
return gerror.New("请先移除分组内成员")
|
||||
}
|
||||
now := gtime.Now()
|
||||
_, err = db.Model(dao.ImUserPolicyGroups.Table()).Safe().Ctx(ctx).Where(c.Id, in.Id).Data(g.Map{c.DeletedAt: now, c.DeletedBy: contexts.GetUserId(ctx), c.Status: consts.StatusDisable}).Update()
|
||||
if err != nil {
|
||||
return gerror.Wrap(err, "删除用户策略分组失败")
|
||||
}
|
||||
_ = writeImAdminAudit(ctx, tenantID, "im_user_policy_group_delete", "im_user_policy_group", in.Id, "success", nil)
|
||||
return publishImPolicyEvent(ctx, tenantID, tenantCode, "user_policy_group.deleted", "user_policy_groups", uint(in.Id))
|
||||
}
|
||||
|
||||
func (s *sSysImUserPolicyGroup) Status(ctx context.Context, in *sysin.ImUserPolicyGroupStatusInp) error {
|
||||
if err := in.Filter(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
c := dao.ImUserPolicyGroups.Columns()
|
||||
db := imtenant.RegistryDB()
|
||||
var row gdb.Record
|
||||
var err error
|
||||
if row, err = db.Model(dao.ImUserPolicyGroups.Table()).Safe().Ctx(ctx).Where(c.Id, in.Id).WhereNull(c.DeletedAt).One(); err != nil {
|
||||
return err
|
||||
}
|
||||
if row.IsEmpty() {
|
||||
return gerror.New("用户策略分组不存在")
|
||||
}
|
||||
tenantID, tenantCode, err := resolveImPolicyTenant(ctx, row[c.TenantId].Int64())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = db.Model(dao.ImUserPolicyGroups.Table()).Safe().Ctx(ctx).Where(c.Id, in.Id).Data(g.Map{c.Status: in.Status, c.Version: gdb.Raw("version+1"), c.UpdatedBy: contexts.GetUserId(ctx), c.UpdatedAt: gtime.Now()}).Update()
|
||||
if err != nil {
|
||||
return gerror.Wrap(err, "更新用户策略分组状态失败")
|
||||
}
|
||||
_ = writeImAdminAudit(ctx, tenantID, "im_user_policy_group_status", "im_user_policy_group", in.Id, "success", g.Map{"status": in.Status})
|
||||
return publishImPolicyEvent(ctx, tenantID, tenantCode, "user_policy_group.updated", "user_policy_groups", uint(in.Id))
|
||||
}
|
||||
|
||||
func (s *sSysImUserPolicyGroup) MemberList(ctx context.Context, in *sysin.ImUserPolicyGroupMemberListInp) (list []*sysin.ImUserPolicyGroupMemberModel, total int, err error) {
|
||||
if err = in.Filter(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
gc := dao.ImUserPolicyGroups.Columns()
|
||||
mc := dao.ImUserPolicyGroupMembers.Columns()
|
||||
var group gdb.Record
|
||||
if group, err = imtenant.RegistryDB().Model(dao.ImUserPolicyGroups.Table()).Safe().Ctx(ctx).Where(gc.Id, in.GroupId).WhereNull(gc.DeletedAt).One(); err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
if group.IsEmpty() {
|
||||
return nil, 0, gerror.New("用户策略分组不存在")
|
||||
}
|
||||
if _, _, err = resolveImPolicyTenant(ctx, group[gc.TenantId].Int64()); err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
model := imtenant.RegistryDB().Model(dao.ImUserPolicyGroupMembers.Table()).Safe().Ctx(ctx).Fields(mc.Id, mc.GroupId, mc.TenantId, mc.UserId, mc.Status, mc.ValidFrom, mc.ValidUntil, mc.Remark, mc.CreatedAt).Where(mc.GroupId, in.GroupId).WhereNull(mc.DeletedAt)
|
||||
if in.UserId > 0 {
|
||||
model = model.Where(mc.UserId, in.UserId)
|
||||
}
|
||||
err = model.Page(in.Page, in.PerPage).OrderDesc(mc.Id).ScanAndCount(&list, &total, false)
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sSysImUserPolicyGroup) MemberAdd(ctx context.Context, in *sysin.ImUserPolicyGroupMemberAddInp) error {
|
||||
if err := in.Filter(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
gc := dao.ImUserPolicyGroups.Columns()
|
||||
mc := dao.ImUserPolicyGroupMembers.Columns()
|
||||
db := imtenant.RegistryDB()
|
||||
var group gdb.Record
|
||||
var err error
|
||||
if group, err = db.Model(dao.ImUserPolicyGroups.Table()).Safe().Ctx(ctx).Where(gc.Id, in.GroupId).WhereNull(gc.DeletedAt).One(); err != nil {
|
||||
return err
|
||||
}
|
||||
if group.IsEmpty() {
|
||||
return gerror.New("用户策略分组不存在")
|
||||
}
|
||||
tenantID, tenantCode, err := resolveImPolicyTenant(ctx, group[gc.TenantId].Int64())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if tenantID == 0 {
|
||||
return gerror.New("全局默认分组不能添加成员,请先选择具体租户")
|
||||
}
|
||||
tenantDB, _, err := imtenant.DB(ctx, tenantID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
userCount, err := tenantDB.Model("im_users").Safe().Ctx(ctx).Where("id", in.UserId).Count()
|
||||
if err != nil {
|
||||
return gerror.Wrap(err, "检查租户用户失败")
|
||||
}
|
||||
if userCount == 0 {
|
||||
return gerror.New("用户不存在或不属于当前租户")
|
||||
}
|
||||
var current gdb.Record
|
||||
current, err = db.Model(dao.ImUserPolicyGroupMembers.Table()).Safe().Ctx(ctx).Where(mc.GroupId, in.GroupId).Where(mc.UserId, in.UserId).One()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
now := gtime.Now()
|
||||
data := g.Map{mc.TenantId: tenantID, mc.Status: consts.StatusEnabled, mc.ValidFrom: in.ValidFrom, mc.ValidUntil: in.ValidUntil, mc.Remark: in.Remark, mc.DeletedAt: nil, mc.DeletedBy: nil, mc.UpdatedAt: now, mc.UpdatedBy: contexts.GetUserId(ctx)}
|
||||
if current.IsEmpty() {
|
||||
data[mc.GroupId] = in.GroupId
|
||||
data[mc.UserId] = in.UserId
|
||||
data[mc.CreatedAt] = now
|
||||
data[mc.CreatedBy] = contexts.GetUserId(ctx)
|
||||
_, err = db.Model(dao.ImUserPolicyGroupMembers.Table()).Safe().Ctx(ctx).Data(data).Insert()
|
||||
} else {
|
||||
_, err = db.Model(dao.ImUserPolicyGroupMembers.Table()).Safe().Ctx(ctx).Where(mc.Id, current[mc.Id]).Data(data).Update()
|
||||
}
|
||||
if err != nil {
|
||||
return gerror.Wrap(err, "添加策略分组成员失败")
|
||||
}
|
||||
_ = writeImAdminAudit(ctx, tenantID, "im_user_policy_group_member_add", "im_user_policy_group", in.GroupId, "success", g.Map{"user_id": in.UserId})
|
||||
return publishImPolicyEvent(ctx, tenantID, tenantCode, "user_policy_group.updated", "user_policy_groups", uint(in.GroupId))
|
||||
}
|
||||
|
||||
func (s *sSysImUserPolicyGroup) MemberRemove(ctx context.Context, in *sysin.ImUserPolicyGroupMemberRemoveInp) error {
|
||||
if err := in.Filter(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
mc := dao.ImUserPolicyGroupMembers.Columns()
|
||||
db := imtenant.RegistryDB()
|
||||
var row gdb.Record
|
||||
var err error
|
||||
if row, err = db.Model(dao.ImUserPolicyGroupMembers.Table()).Safe().Ctx(ctx).Where(mc.Id, in.Id).WhereNull(mc.DeletedAt).One(); err != nil {
|
||||
return err
|
||||
}
|
||||
if row.IsEmpty() {
|
||||
return gerror.New("策略分组成员不存在")
|
||||
}
|
||||
tenantID, tenantCode, err := resolveImPolicyTenant(ctx, row[mc.TenantId].Int64())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = db.Model(dao.ImUserPolicyGroupMembers.Table()).Safe().Ctx(ctx).Where(mc.Id, in.Id).Data(g.Map{mc.Status: consts.StatusDisable, mc.DeletedAt: gtime.Now(), mc.DeletedBy: contexts.GetUserId(ctx), mc.UpdatedAt: gtime.Now(), mc.UpdatedBy: contexts.GetUserId(ctx)}).Update()
|
||||
if err != nil {
|
||||
return gerror.Wrap(err, "移除策略分组成员失败")
|
||||
}
|
||||
groupID := row[mc.GroupId].Int64()
|
||||
_ = writeImAdminAudit(ctx, tenantID, "im_user_policy_group_member_remove", "im_user_policy_group", groupID, "success", g.Map{"user_id": row[mc.UserId].Int64()})
|
||||
return publishImPolicyEvent(ctx, tenantID, tenantCode, "user_policy_group.updated", "user_policy_groups", uint(groupID))
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
// =================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package do
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// ImMessageCurfewRules is the golang structure of table im_message_curfew_rules for DAO operations like Where/Data.
|
||||
type ImMessageCurfewRules struct {
|
||||
g.Meta `orm:"table:im_message_curfew_rules, do:true"`
|
||||
Id any //
|
||||
TenantId any //
|
||||
PolicyId any //
|
||||
RuleCode any //
|
||||
RuleName any //
|
||||
DateType any // daily, weekday, weekend, custom
|
||||
CustomDates *gjson.Json // YYYY-MM-DD values for custom date type
|
||||
Weekdays *gjson.Json // ISO weekdays 1 through 7
|
||||
Timezone any //
|
||||
StartTime *gtime.Time //
|
||||
EndTime *gtime.Time // Less than start_time means crossing midnight
|
||||
Scope any // private_message or group_message
|
||||
WhitelistUserIds *gjson.Json //
|
||||
WhitelistGroupIds *gjson.Json //
|
||||
Message any //
|
||||
Status any // 1 enabled, 2 disabled
|
||||
Sort any //
|
||||
CreatedAt *gtime.Time //
|
||||
CreatedBy any //
|
||||
UpdatedAt *gtime.Time //
|
||||
UpdatedBy any //
|
||||
DeletedAt *gtime.Time //
|
||||
DeletedBy any //
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// =================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package do
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// ImSecurityIpRules is the golang structure of table im_security_ip_rules for DAO operations like Where/Data.
|
||||
type ImSecurityIpRules struct {
|
||||
g.Meta `orm:"table:im_security_ip_rules, do:true"`
|
||||
Id any //
|
||||
TenantId any //
|
||||
RuleType any // whitelist or blacklist
|
||||
IpCidr any // IPv4, IPv6 or CIDR
|
||||
Action any // allow, challenge, block, audit_only
|
||||
SceneJson *gjson.Json // login, register, message, upload and other scenes
|
||||
RiskLevel any //
|
||||
Status any // 1 enabled, 2 disabled
|
||||
ExpiresAt *gtime.Time //
|
||||
Remark any //
|
||||
CreatedAt *gtime.Time //
|
||||
CreatedBy any //
|
||||
UpdatedAt *gtime.Time //
|
||||
UpdatedBy any //
|
||||
DeletedAt *gtime.Time //
|
||||
DeletedBy any //
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
// =================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package do
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// ImSecurityPolicy is the golang structure of table im_security_policy for DAO operations like Where/Data.
|
||||
type ImSecurityPolicy struct {
|
||||
g.Meta `orm:"table:im_security_policy, do:true"`
|
||||
Id any //
|
||||
TenantId any // 0 means global fallback policy
|
||||
PolicyVersion any //
|
||||
PolicyName any //
|
||||
PublishStatus any //
|
||||
PasswordPolicy *gjson.Json //
|
||||
LoginRateLimit *gjson.Json //
|
||||
SensitiveWordPolicy *gjson.Json //
|
||||
FileReviewPolicy *gjson.Json //
|
||||
RealnamePolicy *gjson.Json //
|
||||
RiskChallengePolicy *gjson.Json //
|
||||
GlobalFriendEnabled any // Backend master switch for every add-friend entry
|
||||
FriendDisabledPolicy *gjson.Json // Profile masking, QR and group-member restrictions
|
||||
MessageCurfewEnabled any // Backend master switch for message curfew
|
||||
Remark any //
|
||||
PublishedAt *gtime.Time //
|
||||
PublishedBy any //
|
||||
CreatedAt *gtime.Time //
|
||||
CreatedBy any //
|
||||
UpdatedAt *gtime.Time //
|
||||
UpdatedBy any //
|
||||
DeletedAt *gtime.Time //
|
||||
DeletedBy any //
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// =================================================================================
|
||||
// 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"
|
||||
)
|
||||
|
||||
// ImSensitiveWordGroups is the golang structure of table im_sensitive_word_groups for DAO operations like Where/Data.
|
||||
type ImSensitiveWordGroups struct {
|
||||
g.Meta `orm:"table:im_sensitive_word_groups, do:true"`
|
||||
Id any //
|
||||
TenantId any // 0 means global dictionary
|
||||
GroupCode any //
|
||||
GroupName any //
|
||||
Priority any //
|
||||
Status any // 1 enabled, 2 disabled
|
||||
Remark any //
|
||||
CreatedAt *gtime.Time //
|
||||
CreatedBy any //
|
||||
UpdatedAt *gtime.Time //
|
||||
UpdatedBy any //
|
||||
DeletedAt *gtime.Time //
|
||||
DeletedBy any //
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// =================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package do
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// ImSensitiveWords is the golang structure of table im_sensitive_words for DAO operations like Where/Data.
|
||||
type ImSensitiveWords struct {
|
||||
g.Meta `orm:"table:im_sensitive_words, do:true"`
|
||||
Id any //
|
||||
TenantId any // 0 means global dictionary
|
||||
GroupId any //
|
||||
Word any //
|
||||
WordHash any // SHA-256 of normalized word
|
||||
MatchType any //
|
||||
SceneJson *gjson.Json // Enabled scenes
|
||||
Action any //
|
||||
Replacement any //
|
||||
RiskLevel any //
|
||||
Priority any //
|
||||
Status any // 1 enabled, 2 disabled
|
||||
Remark any //
|
||||
CreatedAt *gtime.Time //
|
||||
CreatedBy any //
|
||||
UpdatedAt *gtime.Time //
|
||||
UpdatedBy any //
|
||||
DeletedAt *gtime.Time //
|
||||
DeletedBy any //
|
||||
}
|
||||
@@ -11,14 +11,18 @@ import (
|
||||
|
||||
// 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
|
||||
CreatedAt *gtime.Time //
|
||||
CreatedBy any //
|
||||
UpdatedAt *gtime.Time //
|
||||
UpdatedBy any //
|
||||
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 //
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
// =================================================================================
|
||||
// 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"
|
||||
)
|
||||
|
||||
// ImUserPolicyGroupMembers is the golang structure of table im_user_policy_group_members for DAO operations like Where/Data.
|
||||
type ImUserPolicyGroupMembers struct {
|
||||
g.Meta `orm:"table:im_user_policy_group_members, do:true"`
|
||||
Id any //
|
||||
TenantId any //
|
||||
GroupId any //
|
||||
UserId any // User ID in the tenant database
|
||||
Status any // 1 enabled, 2 disabled
|
||||
ValidFrom *gtime.Time //
|
||||
ValidUntil *gtime.Time //
|
||||
Remark any //
|
||||
CreatedAt *gtime.Time //
|
||||
CreatedBy any //
|
||||
UpdatedAt *gtime.Time //
|
||||
UpdatedBy any //
|
||||
DeletedAt *gtime.Time //
|
||||
DeletedBy any //
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// =================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package do
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// ImUserPolicyGroups is the golang structure of table im_user_policy_groups for DAO operations like Where/Data.
|
||||
type ImUserPolicyGroups struct {
|
||||
g.Meta `orm:"table:im_user_policy_groups, do:true"`
|
||||
Id any //
|
||||
TenantId any // 0 means global default
|
||||
GroupCode any // Stable policy group code
|
||||
GroupName any // Policy group name
|
||||
Priority any // Higher value has higher priority
|
||||
Status any // 1 enabled, 2 disabled
|
||||
PolicyJson *gjson.Json // Login, friend, message, group and file policies
|
||||
IpWhitelist *gjson.Json // IPv4/IPv6 or CIDR list
|
||||
IpBlacklist *gjson.Json // IPv4/IPv6 or CIDR list
|
||||
Version any // Optimistic-lock/config version
|
||||
Remark any //
|
||||
CreatedAt *gtime.Time //
|
||||
CreatedBy any //
|
||||
UpdatedAt *gtime.Time //
|
||||
UpdatedBy any //
|
||||
DeletedAt *gtime.Time //
|
||||
DeletedBy any //
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
// =================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package entity
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// ImMessageCurfewRules is the golang structure for table im_message_curfew_rules.
|
||||
type ImMessageCurfewRules struct {
|
||||
Id int64 `json:"id" orm:"id" description:""`
|
||||
TenantId int64 `json:"tenantId" orm:"tenant_id" description:""`
|
||||
PolicyId int64 `json:"policyId" orm:"policy_id" description:""`
|
||||
RuleCode string `json:"ruleCode" orm:"rule_code" description:""`
|
||||
RuleName string `json:"ruleName" orm:"rule_name" description:""`
|
||||
DateType string `json:"dateType" orm:"date_type" description:"daily, weekday, weekend, custom"`
|
||||
CustomDates *gjson.Json `json:"customDates" orm:"custom_dates" description:"YYYY-MM-DD values for custom date type"`
|
||||
Weekdays *gjson.Json `json:"weekdays" orm:"weekdays" description:"ISO weekdays 1 through 7"`
|
||||
Timezone string `json:"timezone" orm:"timezone" description:""`
|
||||
StartTime *gtime.Time `json:"startTime" orm:"start_time" description:""`
|
||||
EndTime *gtime.Time `json:"endTime" orm:"end_time" description:"Less than start_time means crossing midnight"`
|
||||
Scope string `json:"scope" orm:"scope" description:"private_message or group_message"`
|
||||
WhitelistUserIds *gjson.Json `json:"whitelistUserIds" orm:"whitelist_user_ids" description:""`
|
||||
WhitelistGroupIds *gjson.Json `json:"whitelistGroupIds" orm:"whitelist_group_ids" description:""`
|
||||
Message string `json:"message" orm:"message" description:""`
|
||||
Status int `json:"status" orm:"status" description:"1 enabled, 2 disabled"`
|
||||
Sort int `json:"sort" orm:"sort" 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:""`
|
||||
DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:""`
|
||||
DeletedBy int64 `json:"deletedBy" orm:"deleted_by" description:""`
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// =================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package entity
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// ImSecurityIpRules is the golang structure for table im_security_ip_rules.
|
||||
type ImSecurityIpRules struct {
|
||||
Id int64 `json:"id" orm:"id" description:""`
|
||||
TenantId int64 `json:"tenantId" orm:"tenant_id" description:""`
|
||||
RuleType string `json:"ruleType" orm:"rule_type" description:"whitelist or blacklist"`
|
||||
IpCidr string `json:"ipCidr" orm:"ip_cidr" description:"IPv4, IPv6 or CIDR"`
|
||||
Action string `json:"action" orm:"action" description:"allow, challenge, block, audit_only"`
|
||||
SceneJson *gjson.Json `json:"sceneJson" orm:"scene_json" description:"login, register, message, upload and other scenes"`
|
||||
RiskLevel string `json:"riskLevel" orm:"risk_level" description:""`
|
||||
Status int `json:"status" orm:"status" description:"1 enabled, 2 disabled"`
|
||||
ExpiresAt *gtime.Time `json:"expiresAt" orm:"expires_at" description:""`
|
||||
Remark string `json:"remark" orm:"remark" 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:""`
|
||||
DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:""`
|
||||
DeletedBy int64 `json:"deletedBy" orm:"deleted_by" description:""`
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
// =================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package entity
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// ImSecurityPolicy is the golang structure for table im_security_policy.
|
||||
type ImSecurityPolicy struct {
|
||||
Id int64 `json:"id" orm:"id" description:""`
|
||||
TenantId int64 `json:"tenantId" orm:"tenant_id" description:"0 means global fallback policy"`
|
||||
PolicyVersion uint `json:"policyVersion" orm:"policy_version" description:""`
|
||||
PolicyName string `json:"policyName" orm:"policy_name" description:""`
|
||||
PublishStatus string `json:"publishStatus" orm:"publish_status" description:""`
|
||||
PasswordPolicy *gjson.Json `json:"passwordPolicy" orm:"password_policy" description:""`
|
||||
LoginRateLimit *gjson.Json `json:"loginRateLimit" orm:"login_rate_limit" description:""`
|
||||
SensitiveWordPolicy *gjson.Json `json:"sensitiveWordPolicy" orm:"sensitive_word_policy" description:""`
|
||||
FileReviewPolicy *gjson.Json `json:"fileReviewPolicy" orm:"file_review_policy" description:""`
|
||||
RealnamePolicy *gjson.Json `json:"realnamePolicy" orm:"realname_policy" description:""`
|
||||
RiskChallengePolicy *gjson.Json `json:"riskChallengePolicy" orm:"risk_challenge_policy" description:""`
|
||||
GlobalFriendEnabled int `json:"globalFriendEnabled" orm:"global_friend_enabled" description:"Backend master switch for every add-friend entry"`
|
||||
FriendDisabledPolicy *gjson.Json `json:"friendDisabledPolicy" orm:"friend_disabled_policy" description:"Profile masking, QR and group-member restrictions"`
|
||||
MessageCurfewEnabled int `json:"messageCurfewEnabled" orm:"message_curfew_enabled" description:"Backend master switch for message curfew"`
|
||||
Remark string `json:"remark" orm:"remark" description:""`
|
||||
PublishedAt *gtime.Time `json:"publishedAt" orm:"published_at" description:""`
|
||||
PublishedBy int64 `json:"publishedBy" orm:"published_by" 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:""`
|
||||
DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:""`
|
||||
DeletedBy int64 `json:"deletedBy" orm:"deleted_by" description:""`
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// =================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package entity
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// ImSensitiveWordGroups is the golang structure for table im_sensitive_word_groups.
|
||||
type ImSensitiveWordGroups struct {
|
||||
Id int64 `json:"id" orm:"id" description:""`
|
||||
TenantId int64 `json:"tenantId" orm:"tenant_id" description:"0 means global dictionary"`
|
||||
GroupCode string `json:"groupCode" orm:"group_code" description:""`
|
||||
GroupName string `json:"groupName" orm:"group_name" description:""`
|
||||
Priority int `json:"priority" orm:"priority" description:""`
|
||||
Status int `json:"status" orm:"status" description:"1 enabled, 2 disabled"`
|
||||
Remark string `json:"remark" orm:"remark" 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:""`
|
||||
DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:""`
|
||||
DeletedBy int64 `json:"deletedBy" orm:"deleted_by" description:""`
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// =================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package entity
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// ImSensitiveWords is the golang structure for table im_sensitive_words.
|
||||
type ImSensitiveWords struct {
|
||||
Id int64 `json:"id" orm:"id" description:""`
|
||||
TenantId int64 `json:"tenantId" orm:"tenant_id" description:"0 means global dictionary"`
|
||||
GroupId int64 `json:"groupId" orm:"group_id" description:""`
|
||||
Word string `json:"word" orm:"word" description:""`
|
||||
WordHash string `json:"wordHash" orm:"word_hash" description:"SHA-256 of normalized word"`
|
||||
MatchType string `json:"matchType" orm:"match_type" description:""`
|
||||
SceneJson *gjson.Json `json:"sceneJson" orm:"scene_json" description:"Enabled scenes"`
|
||||
Action string `json:"action" orm:"action" description:""`
|
||||
Replacement string `json:"replacement" orm:"replacement" description:""`
|
||||
RiskLevel string `json:"riskLevel" orm:"risk_level" description:""`
|
||||
Priority int `json:"priority" orm:"priority" description:""`
|
||||
Status int `json:"status" orm:"status" description:"1 enabled, 2 disabled"`
|
||||
Remark string `json:"remark" orm:"remark" 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:""`
|
||||
DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:""`
|
||||
DeletedBy int64 `json:"deletedBy" orm:"deleted_by" description:""`
|
||||
}
|
||||
@@ -10,13 +10,17 @@ import (
|
||||
|
||||
// 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"`
|
||||
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:""`
|
||||
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:""`
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
// =================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package entity
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// ImUserPolicyGroupMembers is the golang structure for table im_user_policy_group_members.
|
||||
type ImUserPolicyGroupMembers struct {
|
||||
Id int64 `json:"id" orm:"id" description:""`
|
||||
TenantId int64 `json:"tenantId" orm:"tenant_id" description:""`
|
||||
GroupId int64 `json:"groupId" orm:"group_id" description:""`
|
||||
UserId int64 `json:"userId" orm:"user_id" description:"User ID in the tenant database"`
|
||||
Status int `json:"status" orm:"status" description:"1 enabled, 2 disabled"`
|
||||
ValidFrom *gtime.Time `json:"validFrom" orm:"valid_from" description:""`
|
||||
ValidUntil *gtime.Time `json:"validUntil" orm:"valid_until" description:""`
|
||||
Remark string `json:"remark" orm:"remark" 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:""`
|
||||
DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:""`
|
||||
DeletedBy int64 `json:"deletedBy" orm:"deleted_by" description:""`
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// =================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package entity
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// ImUserPolicyGroups is the golang structure for table im_user_policy_groups.
|
||||
type ImUserPolicyGroups struct {
|
||||
Id int64 `json:"id" orm:"id" description:""`
|
||||
TenantId int64 `json:"tenantId" orm:"tenant_id" description:"0 means global default"`
|
||||
GroupCode string `json:"groupCode" orm:"group_code" description:"Stable policy group code"`
|
||||
GroupName string `json:"groupName" orm:"group_name" description:"Policy group name"`
|
||||
Priority int `json:"priority" orm:"priority" description:"Higher value has higher priority"`
|
||||
Status int `json:"status" orm:"status" description:"1 enabled, 2 disabled"`
|
||||
PolicyJson *gjson.Json `json:"policyJson" orm:"policy_json" description:"Login, friend, message, group and file policies"`
|
||||
IpWhitelist *gjson.Json `json:"ipWhitelist" orm:"ip_whitelist" description:"IPv4/IPv6 or CIDR list"`
|
||||
IpBlacklist *gjson.Json `json:"ipBlacklist" orm:"ip_blacklist" description:"IPv4/IPv6 or CIDR list"`
|
||||
Version uint `json:"version" orm:"version" description:"Optimistic-lock/config version"`
|
||||
Remark string `json:"remark" orm:"remark" 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:""`
|
||||
DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:""`
|
||||
DeletedBy int64 `json:"deletedBy" orm:"deleted_by" description:""`
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package sysin
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
type ImDashboardOverviewInp struct {
|
||||
TenantId int64 `json:"tenantId" dc:"租户ID"`
|
||||
}
|
||||
|
||||
type ImDashboardOverviewModel struct {
|
||||
TenantId int64 `json:"tenantId" dc:"租户ID"`
|
||||
TenantName string `json:"tenantName" dc:"租户名称"`
|
||||
TotalUsers int64 `json:"totalUsers" dc:"总用户数"`
|
||||
ActiveUsers int64 `json:"activeUsers" dc:"活跃用户数"`
|
||||
TotalGroups int64 `json:"totalGroups" dc:"总群组数"`
|
||||
TotalConversations int64 `json:"totalConversations" dc:"总会话数"`
|
||||
TotalMessages int64 `json:"totalMessages" dc:"总消息数"`
|
||||
TodayMessages int64 `json:"todayMessages" dc:"今日消息数"`
|
||||
}
|
||||
|
||||
type ImDashboardTrendsInp struct {
|
||||
TenantId int64 `json:"tenantId" dc:"租户ID"`
|
||||
Days int `json:"days" dc:"统计天数"`
|
||||
}
|
||||
|
||||
func (in *ImDashboardTrendsInp) Filter(ctx context.Context) error {
|
||||
if in.Days == 0 {
|
||||
in.Days = 7
|
||||
}
|
||||
if in.Days < 1 || in.Days > 31 {
|
||||
return gerror.New("统计天数必须在1到31天之间")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ImDashboardTrendModel struct {
|
||||
Date *gtime.Time `json:"date" dc:"日期"`
|
||||
UserCount int64 `json:"userCount" dc:"新增用户数"`
|
||||
MessageCount int64 `json:"messageCount" dc:"新增消息数"`
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
package sysin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"hotgo/internal/model/input/form"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
type ImUserLoginHistoryListInp struct {
|
||||
form.PageReq
|
||||
TenantId int64 `json:"tenantId" dc:"租户ID"`
|
||||
UserId string `json:"userId" dc:"用户ID"`
|
||||
Account string `json:"account" dc:"脱敏账号"`
|
||||
LoginType string `json:"loginType" dc:"登录方式"`
|
||||
EventType string `json:"eventType" dc:"事件类型"`
|
||||
Platform string `json:"platform" dc:"客户端平台"`
|
||||
Ip string `json:"ip" dc:"IP地址"`
|
||||
LoginAt []*gtime.Time `json:"loginAt" dc:"登录时间"`
|
||||
}
|
||||
|
||||
func (in *ImUserLoginHistoryListInp) Filter(ctx context.Context) error {
|
||||
in.Account = strings.TrimSpace(in.Account)
|
||||
in.Ip = strings.TrimSpace(in.Ip)
|
||||
return filterImAuditPage(&in.PageReq)
|
||||
}
|
||||
|
||||
type ImUserLoginHistoryModel struct {
|
||||
TenantId int64 `json:"tenantId" dc:"租户ID"`
|
||||
TenantName string `json:"tenantName" dc:"租户名称"`
|
||||
Id int64 `json:"id" dc:"ID"`
|
||||
UserId string `json:"userId" dc:"用户ID"`
|
||||
Username string `json:"username" dc:"用户名"`
|
||||
AccountType string `json:"accountType" dc:"账号类型"`
|
||||
AccountMask string `json:"accountMask" dc:"脱敏账号"`
|
||||
LoginType string `json:"loginType" dc:"登录方式"`
|
||||
EventType string `json:"eventType" dc:"事件类型"`
|
||||
SessionId string `json:"sessionId" dc:"会话ID"`
|
||||
DeviceId string `json:"deviceId" dc:"设备ID"`
|
||||
Platform string `json:"platform" dc:"客户端平台"`
|
||||
AppVersion string `json:"appVersion" dc:"客户端版本"`
|
||||
Ip string `json:"ip" dc:"IP地址"`
|
||||
Region string `json:"region" dc:"地区"`
|
||||
UserAgent string `json:"userAgent" dc:"客户端标识"`
|
||||
RiskLevel string `json:"riskLevel" dc:"风险等级"`
|
||||
RequestId string `json:"requestId" dc:"请求ID"`
|
||||
LoginAt *gtime.Time `json:"loginAt" dc:"登录时间"`
|
||||
LogoutAt *gtime.Time `json:"logoutAt" dc:"登出时间"`
|
||||
Metadata string `json:"metadata" dc:"元数据"`
|
||||
}
|
||||
|
||||
type ImLoginFailureLogListInp struct {
|
||||
form.PageReq
|
||||
TenantId int64 `json:"tenantId" dc:"租户ID"`
|
||||
UserId string `json:"userId" dc:"用户ID"`
|
||||
Account string `json:"account" dc:"脱敏账号"`
|
||||
FailureType string `json:"failureType" dc:"失败类型"`
|
||||
Platform string `json:"platform" dc:"客户端平台"`
|
||||
Ip string `json:"ip" dc:"IP地址"`
|
||||
AttemptAt []*gtime.Time `json:"attemptAt" dc:"尝试时间"`
|
||||
}
|
||||
|
||||
func (in *ImLoginFailureLogListInp) Filter(ctx context.Context) error {
|
||||
in.Account = strings.TrimSpace(in.Account)
|
||||
in.Ip = strings.TrimSpace(in.Ip)
|
||||
return filterImAuditPage(&in.PageReq)
|
||||
}
|
||||
|
||||
func filterImAuditPage(page *form.PageReq) error {
|
||||
if page.Page <= 0 {
|
||||
page.Page = 1
|
||||
}
|
||||
if page.PerPage <= 0 {
|
||||
page.PerPage = 20
|
||||
}
|
||||
if page.PerPage > 200 {
|
||||
return gerror.New("每页数量不能超过200")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ImLoginFailureLogModel struct {
|
||||
TenantId int64 `json:"tenantId" dc:"租户ID"`
|
||||
TenantName string `json:"tenantName" dc:"租户名称"`
|
||||
Id int64 `json:"id" dc:"ID"`
|
||||
UserId string `json:"userId" dc:"用户ID"`
|
||||
AccountType string `json:"accountType" dc:"账号类型"`
|
||||
AccountMask string `json:"accountMask" dc:"脱敏账号"`
|
||||
FailureType string `json:"failureType" dc:"失败类型"`
|
||||
Reason string `json:"reason" dc:"原因码"`
|
||||
Detail string `json:"detail" dc:"失败详情"`
|
||||
Ip string `json:"ip" dc:"IP地址"`
|
||||
Region string `json:"region" dc:"地区"`
|
||||
DeviceId string `json:"deviceId" dc:"设备ID"`
|
||||
Platform string `json:"platform" dc:"客户端平台"`
|
||||
AppVersion string `json:"appVersion" dc:"客户端版本"`
|
||||
UserAgent string `json:"userAgent" dc:"客户端标识"`
|
||||
RiskLevel string `json:"riskLevel" dc:"风险等级"`
|
||||
RiskAction string `json:"riskAction" dc:"风控动作"`
|
||||
RequestId string `json:"requestId" dc:"请求ID"`
|
||||
AttemptAt *gtime.Time `json:"attemptAt" dc:"尝试时间"`
|
||||
Metadata string `json:"metadata" dc:"元数据"`
|
||||
}
|
||||
|
||||
type ImLoginFailureViewInp struct {
|
||||
TenantId int64 `json:"tenantId" dc:"租户ID"`
|
||||
Id int64 `json:"id" dc:"日志ID"`
|
||||
}
|
||||
|
||||
func (in *ImLoginFailureViewInp) Filter(ctx context.Context) error {
|
||||
if in.Id <= 0 {
|
||||
return gerror.New("日志ID不能为空")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ImLoginFailureAddBlacklistInp struct {
|
||||
TenantId int64 `json:"tenantId" dc:"租户ID"`
|
||||
Ip string `json:"ip" dc:"IP地址"`
|
||||
Remark string `json:"remark" dc:"备注"`
|
||||
}
|
||||
|
||||
func (in *ImLoginFailureAddBlacklistInp) Filter(ctx context.Context) error {
|
||||
in.Ip = strings.TrimSpace(in.Ip)
|
||||
if in.Ip == "" {
|
||||
return gerror.New("IP地址不能为空")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ImLoginFailureBanUserInp struct {
|
||||
TenantId int64 `json:"tenantId" dc:"租户ID"`
|
||||
UserId int64 `json:"userId" dc:"用户ID"`
|
||||
Reason string `json:"reason" dc:"封禁原因"`
|
||||
}
|
||||
|
||||
func (in *ImLoginFailureBanUserInp) Filter(ctx context.Context) error {
|
||||
in.Reason = strings.TrimSpace(in.Reason)
|
||||
if in.UserId <= 0 {
|
||||
return gerror.New("用户ID不能为空")
|
||||
}
|
||||
if in.Reason == "" {
|
||||
return gerror.New("封禁原因不能为空")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ImLoginAuditExportModel struct {
|
||||
Id int64 `json:"id" dc:"ID"`
|
||||
UserId string `json:"userId" dc:"用户ID"`
|
||||
AccountMask string `json:"accountMask" dc:"脱敏账号"`
|
||||
EventType string `json:"eventType" dc:"事件/失败类型"`
|
||||
Platform string `json:"platform" dc:"客户端平台"`
|
||||
Ip string `json:"ip" dc:"IP地址"`
|
||||
Region string `json:"region" dc:"地区"`
|
||||
RiskLevel string `json:"riskLevel" dc:"风险等级"`
|
||||
Reason string `json:"reason" dc:"原因"`
|
||||
OccurredAt *gtime.Time `json:"occurredAt" dc:"发生时间"`
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
package sysin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"hotgo/internal/consts"
|
||||
"hotgo/internal/library/dict"
|
||||
"hotgo/internal/model/input/form"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
type ImPrivateMessageListInp struct {
|
||||
form.PageReq
|
||||
TenantId int64 `json:"tenantId" dc:"租户ID"`
|
||||
Topic string `json:"topic" dc:"会话Topic"`
|
||||
FromUserId string `json:"fromUserId" dc:"发送用户ID"`
|
||||
ToUserId string `json:"toUserId" dc:"接收用户ID"`
|
||||
ContentType string `json:"contentType" dc:"内容类型"`
|
||||
Status string `json:"status" dc:"状态"`
|
||||
Keyword string `json:"keyword" dc:"内容关键词"`
|
||||
CreatedAt []*gtime.Time `json:"createdAt" dc:"发送时间"`
|
||||
}
|
||||
|
||||
func (in *ImPrivateMessageListInp) Filter(ctx context.Context) error {
|
||||
return filterImMessageList(&in.PageReq, &in.Topic, &in.Keyword, in.ContentType, in.Status)
|
||||
}
|
||||
|
||||
type ImGroupMessageListInp struct {
|
||||
form.PageReq
|
||||
TenantId int64 `json:"tenantId" dc:"租户ID"`
|
||||
Topic string `json:"topic" dc:"群Topic"`
|
||||
SenderUserId string `json:"senderUserId" dc:"发送用户ID"`
|
||||
ContentType string `json:"contentType" dc:"内容类型"`
|
||||
Status string `json:"status" dc:"状态"`
|
||||
Keyword string `json:"keyword" dc:"内容关键词"`
|
||||
CreatedAt []*gtime.Time `json:"createdAt" dc:"发送时间"`
|
||||
}
|
||||
|
||||
func (in *ImGroupMessageListInp) Filter(ctx context.Context) error {
|
||||
return filterImMessageList(&in.PageReq, &in.Topic, &in.Keyword, in.ContentType, in.Status)
|
||||
}
|
||||
|
||||
func filterImMessageList(page *form.PageReq, topic *string, keyword *string, contentType string, status string) error {
|
||||
*topic = strings.TrimSpace(*topic)
|
||||
*keyword = strings.TrimSpace(*keyword)
|
||||
if page.Page <= 0 {
|
||||
page.Page = 1
|
||||
}
|
||||
if page.PerPage <= 0 {
|
||||
page.PerPage = 20
|
||||
}
|
||||
if page.PerPage > 200 {
|
||||
return gerror.New("每页数量不能超过200")
|
||||
}
|
||||
if contentType != "" && !dict.HasOptionKey(consts.ImMessageContentTypeOptions, contentType) {
|
||||
return gerror.New("消息类型不合法")
|
||||
}
|
||||
if status != "" && !dict.HasOptionKey(consts.ImMessageStatusOptions, status) {
|
||||
return gerror.New("消息状态不合法")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ImMessageListModel struct {
|
||||
TenantId int64 `json:"tenantId" dc:"租户ID"`
|
||||
TenantName string `json:"tenantName" dc:"租户名称"`
|
||||
Topic string `json:"topic" dc:"会话Topic"`
|
||||
SeqId int64 `json:"seqId" dc:"消息序号"`
|
||||
FromUserId string `json:"fromUserId" dc:"发送用户ID"`
|
||||
SenderUsername string `json:"senderUsername" dc:"发送人用户名"`
|
||||
SenderNickname string `json:"senderNickname" dc:"发送人昵称"`
|
||||
ToUserId string `json:"toUserId" dc:"接收用户ID"`
|
||||
ReceiverUsername string `json:"receiverUsername" dc:"接收人用户名"`
|
||||
ReceiverNickname string `json:"receiverNickname" dc:"接收人昵称"`
|
||||
GroupName string `json:"groupName" dc:"群名称"`
|
||||
GroupNo string `json:"groupNo" dc:"群号"`
|
||||
ContentType string `json:"contentType" dc:"消息类型"`
|
||||
ContentExcerpt string `json:"contentExcerpt" dc:"内容摘要"`
|
||||
Status string `json:"status" dc:"状态"`
|
||||
ReplyToSeq int64 `json:"replyToSeq" dc:"回复消息序号"`
|
||||
AtUsers string `json:"atUsers" dc:"@用户"`
|
||||
CreatedAt *gtime.Time `json:"createdAt" dc:"发送时间"`
|
||||
UpdatedAt *gtime.Time `json:"updatedAt" dc:"更新时间"`
|
||||
}
|
||||
|
||||
type ImMessageViewInp struct {
|
||||
TenantId int64 `json:"tenantId" dc:"租户ID"`
|
||||
Topic string `json:"topic" dc:"会话Topic"`
|
||||
SeqId int64 `json:"seqId" dc:"消息序号"`
|
||||
}
|
||||
|
||||
func (in *ImMessageViewInp) Filter(ctx context.Context) error {
|
||||
in.Topic = strings.TrimSpace(in.Topic)
|
||||
if in.Topic == "" || in.SeqId <= 0 {
|
||||
return gerror.New("消息Topic和序号不能为空")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ImMessageViewModel struct {
|
||||
ImMessageListModel
|
||||
Head string `json:"head" dc:"消息头"`
|
||||
Content string `json:"content" dc:"完整消息内容"`
|
||||
Metadata string `json:"metadata" dc:"扩展数据"`
|
||||
}
|
||||
|
||||
type ImMessageActionInp struct {
|
||||
TenantId int64 `json:"tenantId" dc:"租户ID"`
|
||||
Topic string `json:"topic" dc:"会话Topic"`
|
||||
SeqId int64 `json:"seqId" dc:"消息序号"`
|
||||
Reason string `json:"reason" dc:"处置原因"`
|
||||
}
|
||||
|
||||
func (in *ImMessageActionInp) Filter(ctx context.Context) error {
|
||||
in.Topic = strings.TrimSpace(in.Topic)
|
||||
in.Reason = strings.TrimSpace(in.Reason)
|
||||
if in.Topic == "" || in.SeqId <= 0 {
|
||||
return gerror.New("消息Topic和序号不能为空")
|
||||
}
|
||||
if in.Reason == "" {
|
||||
return gerror.New("处置原因不能为空")
|
||||
}
|
||||
if len([]rune(in.Reason)) > 500 {
|
||||
return gerror.New("处置原因不能超过500个字符")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ImMessageCommandModel struct {
|
||||
CommandId string `json:"commandId" dc:"命令ID"`
|
||||
EventId string `json:"eventId" dc:"事件ID"`
|
||||
Status string `json:"status" dc:"命令状态"`
|
||||
}
|
||||
|
||||
type ImMessageExportModel struct {
|
||||
Topic string `json:"topic" dc:"Topic"`
|
||||
SeqId int64 `json:"seqId" dc:"消息序号"`
|
||||
FromUserId string `json:"fromUserId" dc:"发送用户ID"`
|
||||
ToUserId string `json:"toUserId" dc:"接收用户ID"`
|
||||
GroupName string `json:"groupName" dc:"群名称"`
|
||||
ContentType string `json:"contentType" dc:"消息类型"`
|
||||
ContentExcerpt string `json:"contentExcerpt" dc:"内容摘要"`
|
||||
Status string `json:"status" dc:"状态"`
|
||||
CreatedAt *gtime.Time `json:"createdAt" dc:"发送时间"`
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
package sysin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"hotgo/internal/consts"
|
||||
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
)
|
||||
|
||||
func TestImMessageCurfewRuleFilter(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
valid := &ImMessageCurfewRuleInp{
|
||||
RuleCode: "after_work",
|
||||
RuleName: "下班时段",
|
||||
DateType: consts.ImCurfewDateWeekday,
|
||||
StartTime: "18:00",
|
||||
EndTime: "09:00",
|
||||
Scope: consts.ImCurfewScopePrivate,
|
||||
}
|
||||
if err := valid.Filter(ctx); err != nil {
|
||||
t.Fatalf("跨午夜宵禁规则应合法: %v", err)
|
||||
}
|
||||
if valid.Timezone != "Asia/Shanghai" || valid.Status != consts.StatusEnabled {
|
||||
t.Fatalf("默认值未补齐: timezone=%s status=%d", valid.Timezone, valid.Status)
|
||||
}
|
||||
|
||||
invalidTime := *valid
|
||||
invalidTime.StartTime = "25:00"
|
||||
if err := invalidTime.Filter(ctx); err == nil {
|
||||
t.Fatal("非法宵禁时间应被拒绝")
|
||||
}
|
||||
}
|
||||
|
||||
func TestImSecurityPolicySaveFilterRequiresCurfewRule(t *testing.T) {
|
||||
in := &ImSecurityPolicySaveInp{
|
||||
PolicyName: "默认策略",
|
||||
GlobalFriendEnabled: 1,
|
||||
MessageCurfewEnabled: 1,
|
||||
}
|
||||
if err := in.Filter(context.Background()); err == nil {
|
||||
t.Fatal("启用宵禁但未配置规则应被拒绝")
|
||||
}
|
||||
in.CurfewRules = []*ImMessageCurfewRuleInp{{
|
||||
RuleCode: "group_only",
|
||||
RuleName: "仅群聊",
|
||||
DateType: consts.ImCurfewDateDaily,
|
||||
StartTime: "18:00",
|
||||
EndTime: "09:00",
|
||||
Scope: consts.ImCurfewScopeGroup,
|
||||
}}
|
||||
if err := in.Filter(context.Background()); err == nil {
|
||||
t.Fatal("宵禁仅配置群聊规则时应被拒绝")
|
||||
}
|
||||
}
|
||||
|
||||
func TestImSecurityPolicySaveFilterForcesEveryFriendEntryOff(t *testing.T) {
|
||||
in := &ImSecurityPolicySaveInp{
|
||||
PolicyName: "下班策略",
|
||||
GlobalFriendEnabled: 0,
|
||||
MessageCurfewEnabled: 0,
|
||||
FriendDisabledPolicy: gjson.New(map[string]interface{}{
|
||||
"hide_profile": false,
|
||||
"blocked_entries": []string{"search"},
|
||||
}),
|
||||
}
|
||||
if err := in.Filter(context.Background()); err != nil {
|
||||
t.Fatalf("关闭全局好友功能的策略应合法: %v", err)
|
||||
}
|
||||
policy := in.FriendDisabledPolicy.Map()
|
||||
if hide, ok := policy["hide_profile"].(bool); !ok || !hide {
|
||||
t.Fatal("关闭全局好友功能时必须强制隐藏个人资料")
|
||||
}
|
||||
entries := in.FriendDisabledPolicy.Get("blocked_entries").Array()
|
||||
if len(entries) != 6 {
|
||||
t.Fatalf("关闭全局好友功能时必须禁用全部6个入口: %#v", policy["blocked_entries"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestImSecurityPolicyPublishFilter(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
if err := (&ImSecurityPolicyPublishInp{Id: 1, Reason: " "}).Filter(ctx); err == nil {
|
||||
t.Fatal("空发布原因应被拒绝")
|
||||
}
|
||||
if err := (&ImSecurityPolicyPublishInp{Id: 1, Reason: "管理员发布"}).Filter(ctx); err != nil {
|
||||
t.Fatalf("合法发布参数不应报错: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestImSecurityIPRuleEditFilter(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
valid := &ImSecurityIPRuleEditInp{
|
||||
RuleType: "blacklist",
|
||||
IpCidr: "192.0.2.0/24",
|
||||
Action: consts.ImSecurityActionBlock,
|
||||
SceneJson: gjson.New([]string{"login"}),
|
||||
RiskLevel: consts.ImRiskLevelHigh,
|
||||
}
|
||||
if err := valid.Filter(ctx); err != nil {
|
||||
t.Fatalf("合法IP阻断规则不应报错: %v", err)
|
||||
}
|
||||
|
||||
invalidAction := *valid
|
||||
invalidAction.Action = consts.ImPolicyActionDeny
|
||||
if err := invalidAction.Filter(ctx); err == nil {
|
||||
t.Fatal("数据库枚举不支持的deny动作应被拒绝")
|
||||
}
|
||||
}
|
||||
|
||||
func TestImSensitiveWordEditFilter(t *testing.T) {
|
||||
in := &ImSensitiveWordEditInp{
|
||||
GroupId: 1,
|
||||
Word: "测试词",
|
||||
MatchType: consts.ImSensitiveMatchContains,
|
||||
SceneJson: gjson.New([]string{"private_message"}),
|
||||
Action: consts.ImSensitiveActionReplace,
|
||||
RiskLevel: consts.ImRiskLevelMedium,
|
||||
}
|
||||
if err := in.Filter(context.Background()); err == nil {
|
||||
t.Fatal("替换动作未填写替换文本应被拒绝")
|
||||
}
|
||||
}
|
||||
|
||||
func TestImSensitiveWordGroupEditFilter(t *testing.T) {
|
||||
in := &ImSensitiveWordGroupEditInp{GroupCode: "default", GroupName: " "}
|
||||
if err := in.Filter(context.Background()); err == nil {
|
||||
t.Fatal("空分组名称应被拒绝")
|
||||
}
|
||||
}
|
||||
|
||||
func TestImUserPolicyGroupInputFilter(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
group := &ImUserPolicyGroupEditInp{
|
||||
GroupCode: "staff",
|
||||
GroupName: " ",
|
||||
PolicyJson: gjson.New(map[string]interface{}{}),
|
||||
}
|
||||
if err := group.Filter(ctx); err == nil {
|
||||
t.Fatal("空用户策略分组名称应被拒绝")
|
||||
}
|
||||
if err := (&ImUserPolicyGroupMemberAddInp{GroupId: 1, UserId: 0}).Filter(ctx); err == nil {
|
||||
t.Fatal("无效用户ID应被拒绝")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,324 @@
|
||||
package sysin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"hotgo/internal/consts"
|
||||
"hotgo/internal/library/dict"
|
||||
"hotgo/internal/model/input/form"
|
||||
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
type ImSecurityPolicyListInp struct {
|
||||
form.PageReq
|
||||
TenantId int64 `json:"tenantId"`
|
||||
PublishStatus string `json:"publishStatus"`
|
||||
}
|
||||
|
||||
func (in *ImSecurityPolicyListInp) Filter(ctx context.Context) error {
|
||||
if in.PublishStatus != "" && !dict.HasOptionKey(consts.ImSecurityPublishStatusOptions, in.PublishStatus) {
|
||||
return gerror.New("发布状态不合法")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ImMessageCurfewRuleModel struct {
|
||||
Id int64 `json:"id"`
|
||||
RuleCode string `json:"ruleCode"`
|
||||
RuleName string `json:"ruleName"`
|
||||
DateType string `json:"dateType"`
|
||||
CustomDates string `json:"customDates"`
|
||||
Weekdays string `json:"weekdays"`
|
||||
Timezone string `json:"timezone"`
|
||||
StartTime string `json:"startTime"`
|
||||
EndTime string `json:"endTime"`
|
||||
Scope string `json:"scope"`
|
||||
WhitelistUserIds string `json:"whitelistUserIds"`
|
||||
WhitelistGroupIds string `json:"whitelistGroupIds"`
|
||||
Message string `json:"message"`
|
||||
Status int `json:"status"`
|
||||
Sort int `json:"sort"`
|
||||
}
|
||||
|
||||
type ImSecurityPolicyModel struct {
|
||||
Id int64 `json:"id"`
|
||||
TenantId int64 `json:"tenantId"`
|
||||
PolicyVersion uint `json:"policyVersion"`
|
||||
PolicyName string `json:"policyName"`
|
||||
PublishStatus string `json:"publishStatus"`
|
||||
PasswordPolicy string `json:"passwordPolicy"`
|
||||
LoginRateLimit string `json:"loginRateLimit"`
|
||||
SensitiveWordPolicy string `json:"sensitiveWordPolicy"`
|
||||
FileReviewPolicy string `json:"fileReviewPolicy"`
|
||||
RealnamePolicy string `json:"realnamePolicy"`
|
||||
RiskChallengePolicy string `json:"riskChallengePolicy"`
|
||||
GlobalFriendEnabled int `json:"globalFriendEnabled"`
|
||||
FriendDisabledPolicy string `json:"friendDisabledPolicy"`
|
||||
MessageCurfewEnabled int `json:"messageCurfewEnabled"`
|
||||
Remark string `json:"remark"`
|
||||
PublishedAt *gtime.Time `json:"publishedAt"`
|
||||
PublishedBy int64 `json:"publishedBy"`
|
||||
CreatedAt *gtime.Time `json:"createdAt"`
|
||||
UpdatedAt *gtime.Time `json:"updatedAt"`
|
||||
CurfewRules []*ImMessageCurfewRuleModel `json:"curfewRules"`
|
||||
}
|
||||
|
||||
type ImSecurityPolicyViewInp struct {
|
||||
Id int64 `json:"id"`
|
||||
TenantId int64 `json:"tenantId"`
|
||||
}
|
||||
|
||||
func (in *ImSecurityPolicyViewInp) Filter(ctx context.Context) error {
|
||||
if in.Id <= 0 && in.TenantId < 0 {
|
||||
return gerror.New("策略ID或租户ID不合法")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ImMessageCurfewRuleInp struct {
|
||||
RuleCode string `json:"ruleCode"`
|
||||
RuleName string `json:"ruleName"`
|
||||
DateType string `json:"dateType"`
|
||||
CustomDates *gjson.Json `json:"customDates"`
|
||||
Weekdays *gjson.Json `json:"weekdays"`
|
||||
Timezone string `json:"timezone"`
|
||||
StartTime string `json:"startTime"`
|
||||
EndTime string `json:"endTime"`
|
||||
Scope string `json:"scope"`
|
||||
WhitelistUserIds *gjson.Json `json:"whitelistUserIds"`
|
||||
WhitelistGroupIds *gjson.Json `json:"whitelistGroupIds"`
|
||||
Message string `json:"message"`
|
||||
Status int `json:"status"`
|
||||
Sort int `json:"sort"`
|
||||
}
|
||||
|
||||
func (in *ImMessageCurfewRuleInp) Filter(ctx context.Context) error {
|
||||
in.RuleCode = strings.TrimSpace(in.RuleCode)
|
||||
in.RuleName = strings.TrimSpace(in.RuleName)
|
||||
in.Timezone = strings.TrimSpace(in.Timezone)
|
||||
in.Message = strings.TrimSpace(in.Message)
|
||||
if !imPolicyGroupCodePattern.MatchString(in.RuleCode) {
|
||||
return gerror.New("宵禁规则编码格式不合法")
|
||||
}
|
||||
if in.RuleName == "" {
|
||||
return gerror.New("宵禁规则名称不能为空")
|
||||
}
|
||||
if !dict.HasOptionKey(consts.ImCurfewDateTypeOptions, in.DateType) {
|
||||
return gerror.New("宵禁日期类型不合法")
|
||||
}
|
||||
if !dict.HasOptionKey(consts.ImCurfewScopeOptions, in.Scope) {
|
||||
return gerror.New("宵禁范围不合法")
|
||||
}
|
||||
if len(in.StartTime) != 5 || len(in.EndTime) != 5 {
|
||||
return gerror.New("宵禁时间必须使用HH:mm格式")
|
||||
}
|
||||
if _, err := time.Parse("15:04", in.StartTime); err != nil {
|
||||
return gerror.New("宵禁开始时间不合法")
|
||||
}
|
||||
if _, err := time.Parse("15:04", in.EndTime); err != nil {
|
||||
return gerror.New("宵禁结束时间不合法")
|
||||
}
|
||||
if in.Timezone == "" {
|
||||
in.Timezone = "Asia/Shanghai"
|
||||
}
|
||||
if in.Message == "" {
|
||||
in.Message = "当前时段暂不能发送消息"
|
||||
}
|
||||
if in.Status == 0 {
|
||||
in.Status = consts.StatusEnabled
|
||||
}
|
||||
if in.Status != consts.StatusEnabled && in.Status != consts.StatusDisable {
|
||||
return gerror.New("宵禁规则状态不合法")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ImSecurityPolicySaveInp struct {
|
||||
Id int64 `json:"id"`
|
||||
TenantId int64 `json:"tenantId"`
|
||||
PolicyName string `json:"policyName" v:"required#策略名称不能为空"`
|
||||
PasswordPolicy *gjson.Json `json:"passwordPolicy"`
|
||||
LoginRateLimit *gjson.Json `json:"loginRateLimit"`
|
||||
SensitiveWordPolicy *gjson.Json `json:"sensitiveWordPolicy"`
|
||||
FileReviewPolicy *gjson.Json `json:"fileReviewPolicy"`
|
||||
RealnamePolicy *gjson.Json `json:"realnamePolicy"`
|
||||
RiskChallengePolicy *gjson.Json `json:"riskChallengePolicy"`
|
||||
GlobalFriendEnabled int `json:"globalFriendEnabled"`
|
||||
FriendDisabledPolicy *gjson.Json `json:"friendDisabledPolicy"`
|
||||
MessageCurfewEnabled int `json:"messageCurfewEnabled"`
|
||||
Remark string `json:"remark"`
|
||||
CurfewRules []*ImMessageCurfewRuleInp `json:"curfewRules"`
|
||||
}
|
||||
|
||||
func (in *ImSecurityPolicySaveInp) Filter(ctx context.Context) error {
|
||||
in.PolicyName = strings.TrimSpace(in.PolicyName)
|
||||
in.Remark = strings.TrimSpace(in.Remark)
|
||||
if in.PolicyName == "" || len([]rune(in.PolicyName)) > 128 {
|
||||
return gerror.New("策略名称长度必须为1至128个字符")
|
||||
}
|
||||
if in.GlobalFriendEnabled != 0 && in.GlobalFriendEnabled != 1 {
|
||||
return gerror.New("全局好友开关不合法")
|
||||
}
|
||||
if in.MessageCurfewEnabled != 0 && in.MessageCurfewEnabled != 1 {
|
||||
return gerror.New("宵禁开关不合法")
|
||||
}
|
||||
if in.GlobalFriendEnabled == 0 {
|
||||
policy := make(map[string]interface{})
|
||||
if in.FriendDisabledPolicy != nil {
|
||||
policy = in.FriendDisabledPolicy.Map()
|
||||
}
|
||||
policy["hide_profile"] = true
|
||||
policy["block_qrcode"] = true
|
||||
policy["block_group_member_entry"] = true
|
||||
policy["blocked_entries"] = []string{
|
||||
"search", "profile_card", "group_member", "qrcode", "invite_auto_add", "recommendation",
|
||||
}
|
||||
message, ok := policy["message"].(string)
|
||||
if !ok || strings.TrimSpace(message) == "" {
|
||||
policy["message"] = "当前时段暂不允许添加好友"
|
||||
}
|
||||
in.FriendDisabledPolicy = gjson.New(policy)
|
||||
}
|
||||
if in.MessageCurfewEnabled == 1 && len(in.CurfewRules) == 0 {
|
||||
return gerror.New("启用宵禁时至少配置一条宵禁规则")
|
||||
}
|
||||
seen := make(map[string]struct{}, len(in.CurfewRules))
|
||||
hasPrivateMessageRule := false
|
||||
for _, rule := range in.CurfewRules {
|
||||
if rule == nil {
|
||||
return gerror.New("宵禁规则不能为空")
|
||||
}
|
||||
if err := rule.Filter(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, ok := seen[rule.RuleCode]; ok {
|
||||
return gerror.New("宵禁规则编码不能重复")
|
||||
}
|
||||
seen[rule.RuleCode] = struct{}{}
|
||||
if rule.Scope == consts.ImCurfewScopePrivate && rule.Status == consts.StatusEnabled {
|
||||
hasPrivateMessageRule = true
|
||||
}
|
||||
}
|
||||
if in.MessageCurfewEnabled == 1 && !hasPrivateMessageRule {
|
||||
return gerror.New("启用宵禁时至少配置一条启用的单聊/私聊规则")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ImSecurityPolicyPublishInp struct {
|
||||
Id int64 `json:"id" v:"required|min:1#策略ID不能为空|策略ID不合法"`
|
||||
Reason string `json:"reason" v:"required#发布原因不能为空"`
|
||||
}
|
||||
|
||||
func (in *ImSecurityPolicyPublishInp) Filter(ctx context.Context) error {
|
||||
in.Reason = strings.TrimSpace(in.Reason)
|
||||
if in.Id <= 0 {
|
||||
return gerror.New("策略ID不合法")
|
||||
}
|
||||
if in.Reason == "" {
|
||||
return gerror.New("发布原因不能为空")
|
||||
}
|
||||
if len([]rune(in.Reason)) > 500 {
|
||||
return gerror.New("发布原因不能超过500个字符")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ImSecurityPolicyRestoreInp struct {
|
||||
TenantId int64 `json:"tenantId"`
|
||||
Reason string `json:"reason" v:"required#恢复原因不能为空"`
|
||||
}
|
||||
|
||||
func (in *ImSecurityPolicyRestoreInp) Filter(ctx context.Context) error {
|
||||
in.Reason = strings.TrimSpace(in.Reason)
|
||||
if in.TenantId < 0 {
|
||||
return gerror.New("租户ID不合法")
|
||||
}
|
||||
if in.Reason == "" {
|
||||
return gerror.New("恢复原因不能为空")
|
||||
}
|
||||
if len([]rune(in.Reason)) > 500 {
|
||||
return gerror.New("恢复原因不能超过500个字符")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ImSecurityIPRuleListInp struct {
|
||||
form.PageReq
|
||||
TenantId int64 `json:"tenantId"`
|
||||
RuleType string `json:"ruleType"`
|
||||
IpCidr string `json:"ipCidr"`
|
||||
Status int `json:"status"`
|
||||
}
|
||||
|
||||
func (in *ImSecurityIPRuleListInp) Filter(ctx context.Context) error {
|
||||
in.IpCidr = strings.TrimSpace(in.IpCidr)
|
||||
if in.RuleType != "" && in.RuleType != "whitelist" && in.RuleType != "blacklist" {
|
||||
return gerror.New("IP规则类型不合法")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ImSecurityIPRuleModel struct {
|
||||
Id int64 `json:"id"`
|
||||
TenantId int64 `json:"tenantId"`
|
||||
RuleType string `json:"ruleType"`
|
||||
IpCidr string `json:"ipCidr"`
|
||||
Action string `json:"action"`
|
||||
SceneJson string `json:"sceneJson"`
|
||||
RiskLevel string `json:"riskLevel"`
|
||||
Status int `json:"status"`
|
||||
ExpiresAt *gtime.Time `json:"expiresAt"`
|
||||
Remark string `json:"remark"`
|
||||
CreatedAt *gtime.Time `json:"createdAt"`
|
||||
UpdatedAt *gtime.Time `json:"updatedAt"`
|
||||
}
|
||||
type ImSecurityIPRuleEditInp struct {
|
||||
Id int64 `json:"id"`
|
||||
TenantId int64 `json:"tenantId"`
|
||||
RuleType string `json:"ruleType"`
|
||||
IpCidr string `json:"ipCidr"`
|
||||
Action string `json:"action"`
|
||||
SceneJson *gjson.Json `json:"sceneJson"`
|
||||
RiskLevel string `json:"riskLevel"`
|
||||
Status int `json:"status"`
|
||||
ExpiresAt *gtime.Time `json:"expiresAt"`
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
|
||||
func (in *ImSecurityIPRuleEditInp) Filter(ctx context.Context) error {
|
||||
in.IpCidr = strings.TrimSpace(in.IpCidr)
|
||||
if in.RuleType != "whitelist" && in.RuleType != "blacklist" {
|
||||
return gerror.New("IP规则类型不合法")
|
||||
}
|
||||
if in.IpCidr == "" {
|
||||
return gerror.New("IP或CIDR不能为空")
|
||||
}
|
||||
if !dict.HasOptionKey(consts.ImSecurityActionOptions, in.Action) {
|
||||
return gerror.New("规则动作不合法")
|
||||
}
|
||||
if !dict.HasOptionKey(consts.ImRiskLevelOptions, in.RiskLevel) {
|
||||
return gerror.New("风险等级不合法")
|
||||
}
|
||||
if in.Status == 0 {
|
||||
in.Status = consts.StatusEnabled
|
||||
}
|
||||
if in.Status != consts.StatusEnabled && in.Status != consts.StatusDisable {
|
||||
return gerror.New("状态不合法")
|
||||
}
|
||||
if in.SceneJson == nil || in.SceneJson.String() == "" || in.SceneJson.String() == "null" {
|
||||
return gerror.New("生效场景不能为空")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ImSecurityIPRuleDeleteInp struct {
|
||||
Id int64 `json:"id" v:"required|min:1#IP规则ID不能为空|IP规则ID不合法"`
|
||||
}
|
||||
|
||||
func (in *ImSecurityIPRuleDeleteInp) Filter(ctx context.Context) error { return nil }
|
||||
@@ -0,0 +1,190 @@
|
||||
package sysin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"hotgo/internal/consts"
|
||||
"hotgo/internal/library/dict"
|
||||
"hotgo/internal/model/input/form"
|
||||
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
type ImSensitiveWordListInp struct {
|
||||
form.PageReq
|
||||
TenantId int64 `json:"tenantId"`
|
||||
GroupId int64 `json:"groupId"`
|
||||
Word string `json:"word"`
|
||||
MatchType string `json:"matchType"`
|
||||
Action string `json:"action"`
|
||||
RiskLevel string `json:"riskLevel"`
|
||||
Status int `json:"status"`
|
||||
}
|
||||
|
||||
func (in *ImSensitiveWordListInp) Filter(ctx context.Context) error {
|
||||
in.Word = strings.TrimSpace(in.Word)
|
||||
if in.MatchType != "" && !dict.HasOptionKey(consts.ImSensitiveMatchTypeOptions, in.MatchType) {
|
||||
return gerror.New("匹配类型不合法")
|
||||
}
|
||||
if in.Action != "" && !dict.HasOptionKey(consts.ImSensitiveActionOptions, in.Action) {
|
||||
return gerror.New("命中动作不合法")
|
||||
}
|
||||
if in.RiskLevel != "" && !dict.HasOptionKey(consts.ImRiskLevelOptions, in.RiskLevel) {
|
||||
return gerror.New("风险等级不合法")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ImSensitiveWordListModel struct {
|
||||
Id int64 `json:"id"`
|
||||
TenantId int64 `json:"tenantId"`
|
||||
GroupId int64 `json:"groupId"`
|
||||
GroupName string `json:"groupName"`
|
||||
Word string `json:"word"`
|
||||
MatchType string `json:"matchType"`
|
||||
SceneJson string `json:"sceneJson"`
|
||||
Action string `json:"action"`
|
||||
Replacement string `json:"replacement"`
|
||||
RiskLevel string `json:"riskLevel"`
|
||||
Priority int `json:"priority"`
|
||||
Status int `json:"status"`
|
||||
Remark string `json:"remark"`
|
||||
CreatedAt *gtime.Time `json:"createdAt"`
|
||||
UpdatedAt *gtime.Time `json:"updatedAt"`
|
||||
}
|
||||
|
||||
type ImSensitiveWordEditInp struct {
|
||||
Id int64 `json:"id"`
|
||||
TenantId int64 `json:"tenantId"`
|
||||
GroupId int64 `json:"groupId" v:"required|min:1#敏感词分组不能为空|敏感词分组不合法"`
|
||||
Word string `json:"word" v:"required#敏感词不能为空"`
|
||||
MatchType string `json:"matchType"`
|
||||
SceneJson *gjson.Json `json:"sceneJson" v:"required#生效场景不能为空"`
|
||||
Action string `json:"action"`
|
||||
Replacement string `json:"replacement"`
|
||||
RiskLevel string `json:"riskLevel"`
|
||||
Priority int `json:"priority"`
|
||||
Status int `json:"status"`
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
|
||||
func (in *ImSensitiveWordEditInp) Filter(ctx context.Context) error {
|
||||
in.Word = strings.TrimSpace(in.Word)
|
||||
in.Replacement = strings.TrimSpace(in.Replacement)
|
||||
in.Remark = strings.TrimSpace(in.Remark)
|
||||
if in.Word == "" || len([]rune(in.Word)) > 255 {
|
||||
return gerror.New("敏感词长度必须为1至255个字符")
|
||||
}
|
||||
if !dict.HasOptionKey(consts.ImSensitiveMatchTypeOptions, in.MatchType) {
|
||||
return gerror.New("匹配类型不合法")
|
||||
}
|
||||
if !dict.HasOptionKey(consts.ImSensitiveActionOptions, in.Action) {
|
||||
return gerror.New("命中动作不合法")
|
||||
}
|
||||
if !dict.HasOptionKey(consts.ImRiskLevelOptions, in.RiskLevel) {
|
||||
return gerror.New("风险等级不合法")
|
||||
}
|
||||
if in.Status == 0 {
|
||||
in.Status = consts.StatusEnabled
|
||||
}
|
||||
if in.Status != consts.StatusEnabled && in.Status != consts.StatusDisable {
|
||||
return gerror.New("状态不合法")
|
||||
}
|
||||
if in.SceneJson == nil || in.SceneJson.String() == "" || in.SceneJson.String() == "null" {
|
||||
return gerror.New("生效场景不能为空")
|
||||
}
|
||||
if in.Action == consts.ImSensitiveActionReplace && in.Replacement == "" {
|
||||
return gerror.New("替换动作必须填写替换文本")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ImSensitiveWordDeleteInp struct {
|
||||
Id int64 `json:"id" v:"required|min:1#敏感词ID不能为空|敏感词ID不合法"`
|
||||
}
|
||||
|
||||
func (in *ImSensitiveWordDeleteInp) Filter(ctx context.Context) error { return nil }
|
||||
|
||||
type ImSensitiveWordStatusInp struct {
|
||||
Id int64 `json:"id" v:"required|min:1#敏感词ID不能为空|敏感词ID不合法"`
|
||||
Status int `json:"status" v:"required#状态不能为空"`
|
||||
}
|
||||
|
||||
func (in *ImSensitiveWordStatusInp) Filter(ctx context.Context) error {
|
||||
if in.Status != consts.StatusEnabled && in.Status != consts.StatusDisable {
|
||||
return gerror.New("状态不合法")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ImSensitiveWordBatchImportInp struct {
|
||||
TenantId int64 `json:"tenantId"`
|
||||
GroupId int64 `json:"groupId" v:"required|min:1#敏感词分组不能为空|敏感词分组不合法"`
|
||||
Words []string `json:"words" v:"required#敏感词列表不能为空"`
|
||||
MatchType string `json:"matchType"`
|
||||
SceneJson *gjson.Json `json:"sceneJson"`
|
||||
Action string `json:"action"`
|
||||
Replacement string `json:"replacement"`
|
||||
RiskLevel string `json:"riskLevel"`
|
||||
}
|
||||
|
||||
func (in *ImSensitiveWordBatchImportInp) Filter(ctx context.Context) error {
|
||||
if len(in.Words) == 0 || len(in.Words) > 5000 {
|
||||
return gerror.New("每次导入1至5000个敏感词")
|
||||
}
|
||||
base := ImSensitiveWordEditInp{GroupId: in.GroupId, Word: "validate", MatchType: in.MatchType, SceneJson: in.SceneJson, Action: in.Action, Replacement: in.Replacement, RiskLevel: in.RiskLevel, Status: consts.StatusEnabled}
|
||||
return base.Filter(ctx)
|
||||
}
|
||||
|
||||
type ImSensitiveWordBatchImportModel struct {
|
||||
Inserted int `json:"inserted"`
|
||||
Skipped int `json:"skipped"`
|
||||
}
|
||||
|
||||
type ImSensitiveWordGroupListInp struct {
|
||||
TenantId int64 `json:"tenantId"`
|
||||
}
|
||||
|
||||
func (in *ImSensitiveWordGroupListInp) Filter(ctx context.Context) error { return nil }
|
||||
|
||||
type ImSensitiveWordGroupModel struct {
|
||||
Id int64 `json:"id"`
|
||||
TenantId int64 `json:"tenantId"`
|
||||
GroupCode string `json:"groupCode"`
|
||||
GroupName string `json:"groupName"`
|
||||
Priority int `json:"priority"`
|
||||
Status int `json:"status"`
|
||||
Remark string `json:"remark"`
|
||||
CreatedAt *gtime.Time `json:"createdAt"`
|
||||
}
|
||||
type ImSensitiveWordGroupEditInp struct {
|
||||
Id int64 `json:"id"`
|
||||
TenantId int64 `json:"tenantId"`
|
||||
GroupCode string `json:"groupCode" v:"required#分组编码不能为空"`
|
||||
GroupName string `json:"groupName" v:"required#分组名称不能为空"`
|
||||
Priority int `json:"priority"`
|
||||
Status int `json:"status"`
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
|
||||
func (in *ImSensitiveWordGroupEditInp) Filter(ctx context.Context) error {
|
||||
in.GroupCode = strings.TrimSpace(in.GroupCode)
|
||||
in.GroupName = strings.TrimSpace(in.GroupName)
|
||||
in.Remark = strings.TrimSpace(in.Remark)
|
||||
if !imPolicyGroupCodePattern.MatchString(in.GroupCode) {
|
||||
return gerror.New("分组编码格式不合法")
|
||||
}
|
||||
if in.GroupName == "" || len([]rune(in.GroupName)) > 128 {
|
||||
return gerror.New("分组名称长度必须为1至128个字符")
|
||||
}
|
||||
if in.Status == 0 {
|
||||
in.Status = consts.StatusEnabled
|
||||
}
|
||||
if in.Status != consts.StatusEnabled && in.Status != consts.StatusDisable {
|
||||
return gerror.New("状态不合法")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
package sysin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"hotgo/internal/consts"
|
||||
"hotgo/internal/model/input/form"
|
||||
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
var imPolicyGroupCodePattern = regexp.MustCompile(`^[A-Za-z][A-Za-z0-9_-]{1,63}$`)
|
||||
|
||||
type ImUserPolicyGroupListInp struct {
|
||||
form.PageReq
|
||||
TenantId int64 `json:"tenantId" dc:"租户ID,0为全局默认"`
|
||||
Keyword string `json:"keyword" dc:"编码或名称"`
|
||||
Status int `json:"status" dc:"状态"`
|
||||
}
|
||||
|
||||
func (in *ImUserPolicyGroupListInp) Filter(ctx context.Context) error {
|
||||
in.Keyword = strings.TrimSpace(in.Keyword)
|
||||
if in.Status != 0 && in.Status != consts.StatusEnabled && in.Status != consts.StatusDisable {
|
||||
return gerror.New("状态不合法")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ImUserPolicyGroupListModel struct {
|
||||
Id int64 `json:"id"`
|
||||
TenantId int64 `json:"tenantId"`
|
||||
GroupCode string `json:"groupCode"`
|
||||
GroupName string `json:"groupName"`
|
||||
Priority int `json:"priority"`
|
||||
Status int `json:"status"`
|
||||
PolicyJson string `json:"policyJson"`
|
||||
IpWhitelist string `json:"ipWhitelist"`
|
||||
IpBlacklist string `json:"ipBlacklist"`
|
||||
Version uint `json:"version"`
|
||||
Remark string `json:"remark"`
|
||||
MemberCount int `json:"memberCount"`
|
||||
CreatedAt *gtime.Time `json:"createdAt"`
|
||||
UpdatedAt *gtime.Time `json:"updatedAt"`
|
||||
}
|
||||
|
||||
type ImUserPolicyGroupViewInp struct {
|
||||
Id int64 `json:"id" v:"required|min:1#策略分组ID不能为空|策略分组ID不合法"`
|
||||
}
|
||||
|
||||
func (in *ImUserPolicyGroupViewInp) Filter(ctx context.Context) error { return nil }
|
||||
|
||||
type ImUserPolicyGroupViewModel struct{ ImUserPolicyGroupListModel }
|
||||
|
||||
type ImUserPolicyGroupEditInp struct {
|
||||
Id int64 `json:"id"`
|
||||
TenantId int64 `json:"tenantId" dc:"租户ID,0为全局默认"`
|
||||
GroupCode string `json:"groupCode" v:"required#分组编码不能为空"`
|
||||
GroupName string `json:"groupName" v:"required#分组名称不能为空"`
|
||||
Priority int `json:"priority"`
|
||||
Status int `json:"status"`
|
||||
PolicyJson *gjson.Json `json:"policyJson" v:"required#策略配置不能为空"`
|
||||
IpWhitelist *gjson.Json `json:"ipWhitelist"`
|
||||
IpBlacklist *gjson.Json `json:"ipBlacklist"`
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
|
||||
func (in *ImUserPolicyGroupEditInp) Filter(ctx context.Context) error {
|
||||
in.GroupCode = strings.TrimSpace(in.GroupCode)
|
||||
in.GroupName = strings.TrimSpace(in.GroupName)
|
||||
in.Remark = strings.TrimSpace(in.Remark)
|
||||
if !imPolicyGroupCodePattern.MatchString(in.GroupCode) {
|
||||
return gerror.New("分组编码必须以字母开头,只能包含字母、数字、下划线和中划线")
|
||||
}
|
||||
if in.GroupName == "" || len([]rune(in.GroupName)) > 128 {
|
||||
return gerror.New("分组名称长度必须为1至128个字符")
|
||||
}
|
||||
if in.Status == 0 {
|
||||
in.Status = consts.StatusEnabled
|
||||
}
|
||||
if in.Status != consts.StatusEnabled && in.Status != consts.StatusDisable {
|
||||
return gerror.New("状态不合法")
|
||||
}
|
||||
if in.PolicyJson == nil || in.PolicyJson.String() == "null" {
|
||||
return gerror.New("策略配置不能为空")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ImUserPolicyGroupDeleteInp struct {
|
||||
Id int64 `json:"id" v:"required|min:1#策略分组ID不能为空|策略分组ID不合法"`
|
||||
}
|
||||
|
||||
func (in *ImUserPolicyGroupDeleteInp) Filter(ctx context.Context) error { return nil }
|
||||
|
||||
type ImUserPolicyGroupStatusInp struct {
|
||||
Id int64 `json:"id" v:"required|min:1#策略分组ID不能为空|策略分组ID不合法"`
|
||||
Status int `json:"status" v:"required#状态不能为空"`
|
||||
}
|
||||
|
||||
func (in *ImUserPolicyGroupStatusInp) Filter(ctx context.Context) error {
|
||||
if in.Status != consts.StatusEnabled && in.Status != consts.StatusDisable {
|
||||
return gerror.New("状态不合法")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ImUserPolicyGroupMemberListInp struct {
|
||||
form.PageReq
|
||||
GroupId int64 `json:"groupId" v:"required|min:1#策略分组ID不能为空|策略分组ID不合法"`
|
||||
UserId int64 `json:"userId"`
|
||||
}
|
||||
|
||||
func (in *ImUserPolicyGroupMemberListInp) Filter(ctx context.Context) error { return nil }
|
||||
|
||||
type ImUserPolicyGroupMemberModel struct {
|
||||
Id int64 `json:"id"`
|
||||
GroupId int64 `json:"groupId"`
|
||||
TenantId int64 `json:"tenantId"`
|
||||
UserId int64 `json:"userId"`
|
||||
Status int `json:"status"`
|
||||
ValidFrom *gtime.Time `json:"validFrom"`
|
||||
ValidUntil *gtime.Time `json:"validUntil"`
|
||||
Remark string `json:"remark"`
|
||||
CreatedAt *gtime.Time `json:"createdAt"`
|
||||
}
|
||||
|
||||
type ImUserPolicyGroupMemberAddInp struct {
|
||||
GroupId int64 `json:"groupId" v:"required|min:1#策略分组ID不能为空|策略分组ID不合法"`
|
||||
UserId int64 `json:"userId" v:"required|min:1#用户ID不能为空|用户ID不合法"`
|
||||
ValidFrom *gtime.Time `json:"validFrom"`
|
||||
ValidUntil *gtime.Time `json:"validUntil"`
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
|
||||
func (in *ImUserPolicyGroupMemberAddInp) Filter(ctx context.Context) error {
|
||||
in.Remark = strings.TrimSpace(in.Remark)
|
||||
if in.GroupId <= 0 {
|
||||
return gerror.New("策略分组ID不合法")
|
||||
}
|
||||
if in.UserId <= 0 {
|
||||
return gerror.New("用户ID不合法")
|
||||
}
|
||||
if in.ValidFrom != nil && in.ValidUntil != nil && in.ValidUntil.Before(in.ValidFrom) {
|
||||
return gerror.New("有效结束时间不能早于开始时间")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ImUserPolicyGroupMemberRemoveInp struct {
|
||||
Id int64 `json:"id" v:"required|min:1#成员关系ID不能为空|成员关系ID不合法"`
|
||||
}
|
||||
|
||||
func (in *ImUserPolicyGroupMemberRemoveInp) Filter(ctx context.Context) error { return nil }
|
||||
@@ -0,0 +1,5 @@
|
||||
package genrouter
|
||||
|
||||
import "hotgo/internal/controller/admin/sys"
|
||||
|
||||
func init() { LoginRequiredRouter = append(LoginRequiredRouter, sys.ImDashboard) }
|
||||
@@ -0,0 +1,5 @@
|
||||
package genrouter
|
||||
|
||||
import "hotgo/internal/controller/admin/sys"
|
||||
|
||||
func init() { LoginRequiredRouter = append(LoginRequiredRouter, sys.ImGroupMessage) }
|
||||
@@ -0,0 +1,5 @@
|
||||
package genrouter
|
||||
|
||||
import "hotgo/internal/controller/admin/sys"
|
||||
|
||||
func init() { LoginRequiredRouter = append(LoginRequiredRouter, sys.ImLoginFailureLog) }
|
||||
@@ -0,0 +1,5 @@
|
||||
package genrouter
|
||||
|
||||
import "hotgo/internal/controller/admin/sys"
|
||||
|
||||
func init() { LoginRequiredRouter = append(LoginRequiredRouter, sys.ImPrivateMessage) }
|
||||
@@ -0,0 +1,5 @@
|
||||
package genrouter
|
||||
|
||||
import "hotgo/internal/controller/admin/sys"
|
||||
|
||||
func init() { LoginRequiredRouter = append(LoginRequiredRouter, sys.ImSecurityPolicy) }
|
||||
@@ -0,0 +1,5 @@
|
||||
package genrouter
|
||||
|
||||
import "hotgo/internal/controller/admin/sys"
|
||||
|
||||
func init() { LoginRequiredRouter = append(LoginRequiredRouter, sys.ImSensitiveWord) }
|
||||
@@ -0,0 +1,5 @@
|
||||
package genrouter
|
||||
|
||||
import "hotgo/internal/controller/admin/sys"
|
||||
|
||||
func init() { LoginRequiredRouter = append(LoginRequiredRouter, sys.ImUserLoginHistory) }
|
||||
@@ -0,0 +1,5 @@
|
||||
package genrouter
|
||||
|
||||
import "hotgo/internal/controller/admin/sys"
|
||||
|
||||
func init() { LoginRequiredRouter = append(LoginRequiredRouter, sys.ImUserPolicyGroup) }
|
||||
+182
-44
@@ -359,6 +359,64 @@ type (
|
||||
// Update 更新IM文件策略
|
||||
Update(ctx context.Context, in *sysin.ImFilePolicyUpdateInp) (err error)
|
||||
}
|
||||
ISysImUserPolicyGroup interface {
|
||||
List(ctx context.Context, in *sysin.ImUserPolicyGroupListInp) (list []*sysin.ImUserPolicyGroupListModel, totalCount int, err error)
|
||||
View(ctx context.Context, in *sysin.ImUserPolicyGroupViewInp) (res *sysin.ImUserPolicyGroupViewModel, err error)
|
||||
Edit(ctx context.Context, in *sysin.ImUserPolicyGroupEditInp) (err error)
|
||||
Delete(ctx context.Context, in *sysin.ImUserPolicyGroupDeleteInp) (err error)
|
||||
Status(ctx context.Context, in *sysin.ImUserPolicyGroupStatusInp) (err error)
|
||||
MemberList(ctx context.Context, in *sysin.ImUserPolicyGroupMemberListInp) (list []*sysin.ImUserPolicyGroupMemberModel, totalCount int, err error)
|
||||
MemberAdd(ctx context.Context, in *sysin.ImUserPolicyGroupMemberAddInp) (err error)
|
||||
MemberRemove(ctx context.Context, in *sysin.ImUserPolicyGroupMemberRemoveInp) (err error)
|
||||
}
|
||||
ISysImSensitiveWord interface {
|
||||
List(ctx context.Context, in *sysin.ImSensitiveWordListInp) (list []*sysin.ImSensitiveWordListModel, totalCount int, err error)
|
||||
Edit(ctx context.Context, in *sysin.ImSensitiveWordEditInp) (err error)
|
||||
Delete(ctx context.Context, in *sysin.ImSensitiveWordDeleteInp) (err error)
|
||||
Status(ctx context.Context, in *sysin.ImSensitiveWordStatusInp) (err error)
|
||||
BatchImport(ctx context.Context, in *sysin.ImSensitiveWordBatchImportInp) (res *sysin.ImSensitiveWordBatchImportModel, err error)
|
||||
GroupList(ctx context.Context, in *sysin.ImSensitiveWordGroupListInp) (list []*sysin.ImSensitiveWordGroupModel, err error)
|
||||
GroupEdit(ctx context.Context, in *sysin.ImSensitiveWordGroupEditInp) (err error)
|
||||
}
|
||||
ISysImSecurityPolicy interface {
|
||||
List(ctx context.Context, in *sysin.ImSecurityPolicyListInp) (list []*sysin.ImSecurityPolicyModel, totalCount int, err error)
|
||||
View(ctx context.Context, in *sysin.ImSecurityPolicyViewInp) (res *sysin.ImSecurityPolicyModel, err error)
|
||||
Save(ctx context.Context, in *sysin.ImSecurityPolicySaveInp) (id int64, err error)
|
||||
Publish(ctx context.Context, in *sysin.ImSecurityPolicyPublishInp) (err error)
|
||||
RestoreDefault(ctx context.Context, in *sysin.ImSecurityPolicyRestoreInp) (id int64, err error)
|
||||
IPRuleList(ctx context.Context, in *sysin.ImSecurityIPRuleListInp) (list []*sysin.ImSecurityIPRuleModel, totalCount int, err error)
|
||||
IPRuleEdit(ctx context.Context, in *sysin.ImSecurityIPRuleEditInp) (err error)
|
||||
IPRuleDelete(ctx context.Context, in *sysin.ImSecurityIPRuleDeleteInp) (err error)
|
||||
}
|
||||
ISysImDashboard interface {
|
||||
Overview(ctx context.Context, in *sysin.ImDashboardOverviewInp) (res *sysin.ImDashboardOverviewModel, err error)
|
||||
Trends(ctx context.Context, in *sysin.ImDashboardTrendsInp) (list []*sysin.ImDashboardTrendModel, err error)
|
||||
}
|
||||
ISysImPrivateMessage interface {
|
||||
List(ctx context.Context, in *sysin.ImPrivateMessageListInp) (list []*sysin.ImMessageListModel, totalCount int, err error)
|
||||
View(ctx context.Context, in *sysin.ImMessageViewInp) (res *sysin.ImMessageViewModel, err error)
|
||||
Hide(ctx context.Context, in *sysin.ImMessageActionInp) (res *sysin.ImMessageCommandModel, err error)
|
||||
Delete(ctx context.Context, in *sysin.ImMessageActionInp) (res *sysin.ImMessageCommandModel, err error)
|
||||
Export(ctx context.Context, in *sysin.ImPrivateMessageListInp) (err error)
|
||||
}
|
||||
ISysImGroupMessage interface {
|
||||
List(ctx context.Context, in *sysin.ImGroupMessageListInp) (list []*sysin.ImMessageListModel, totalCount int, err error)
|
||||
View(ctx context.Context, in *sysin.ImMessageViewInp) (res *sysin.ImMessageViewModel, err error)
|
||||
Hide(ctx context.Context, in *sysin.ImMessageActionInp) (res *sysin.ImMessageCommandModel, err error)
|
||||
Delete(ctx context.Context, in *sysin.ImMessageActionInp) (res *sysin.ImMessageCommandModel, err error)
|
||||
Export(ctx context.Context, in *sysin.ImGroupMessageListInp) (err error)
|
||||
}
|
||||
ISysImUserLoginHistory interface {
|
||||
List(ctx context.Context, in *sysin.ImUserLoginHistoryListInp) (list []*sysin.ImUserLoginHistoryModel, totalCount int, err error)
|
||||
Export(ctx context.Context, in *sysin.ImUserLoginHistoryListInp) (err error)
|
||||
}
|
||||
ISysImLoginFailureLog interface {
|
||||
List(ctx context.Context, in *sysin.ImLoginFailureLogListInp) (list []*sysin.ImLoginFailureLogModel, totalCount int, err error)
|
||||
View(ctx context.Context, in *sysin.ImLoginFailureViewInp) (res *sysin.ImLoginFailureLogModel, err error)
|
||||
Export(ctx context.Context, in *sysin.ImLoginFailureLogListInp) (err error)
|
||||
AddBlacklist(ctx context.Context, in *sysin.ImLoginFailureAddBlacklistInp) (err error)
|
||||
BanUser(ctx context.Context, in *sysin.ImLoginFailureBanUserInp) (res *sysin.ImUserCommandModel, err error)
|
||||
}
|
||||
ISysImExternalConfig interface {
|
||||
// List 获取IM外部服务配置列表
|
||||
List(ctx context.Context, in *sysin.ImExternalConfigListInp) (list []*sysin.ImExternalConfigListModel, totalCount int, err error)
|
||||
@@ -686,50 +744,58 @@ type (
|
||||
)
|
||||
|
||||
var (
|
||||
localSysAddons ISysAddons
|
||||
localSysAddonsConfig ISysAddonsConfig
|
||||
localSysAttachment ISysAttachment
|
||||
localSysBlacklist ISysBlacklist
|
||||
localSysConfig ISysConfig
|
||||
localSysCron ISysCron
|
||||
localSysCronGroup ISysCronGroup
|
||||
localSysCurdDemo ISysCurdDemo
|
||||
localSysImTenant ISysImTenant
|
||||
localSysImRegistration ISysImRegistration
|
||||
localSysImInvite ISysImInvite
|
||||
localSysImUser ISysImUser
|
||||
localSysImGroup ISysImGroup
|
||||
localSysImRealname ISysImRealname
|
||||
localSysImWorkOrder ISysImWorkOrder
|
||||
localSysImOutbox ISysImOutbox
|
||||
localSysImOrg ISysImOrg
|
||||
localSysImFile ISysImFile
|
||||
localSysImFilePolicy ISysImFilePolicy
|
||||
localSysImExternalConfig ISysImExternalConfig
|
||||
localSysImNotification ISysImNotification
|
||||
localSysImAppRelease ISysImAppRelease
|
||||
localSysImAbuseReason ISysImAbuseReason
|
||||
localSysImMailboxConfig ISysImMailboxConfig
|
||||
localSysImFeedbackConfig ISysImFeedbackConfig
|
||||
localSysImWorkbench ISysImWorkbench
|
||||
localSysImTaskDashboard ISysImTaskDashboard
|
||||
localSysImAuditLog ISysImAuditLog
|
||||
localSysImKafkaAudit ISysImKafkaAudit
|
||||
localSysImKafkaCommand ISysImKafkaCommand
|
||||
localSysImDeadLetter ISysImDeadLetter
|
||||
localSysDictData ISysDictData
|
||||
localSysDictType ISysDictType
|
||||
localSysEmsLog ISysEmsLog
|
||||
localSysGenCodes ISysGenCodes
|
||||
localSysLog ISysLog
|
||||
localSysLoginLog ISysLoginLog
|
||||
localSysNormalTreeDemo ISysNormalTreeDemo
|
||||
localSysOptionTreeDemo ISysOptionTreeDemo
|
||||
localSysProvinces ISysProvinces
|
||||
localSysServeLicense ISysServeLicense
|
||||
localSysServeLog ISysServeLog
|
||||
localSysSmsLog ISysSmsLog
|
||||
localSysTestCategory ISysTestCategory
|
||||
localSysAddons ISysAddons
|
||||
localSysAddonsConfig ISysAddonsConfig
|
||||
localSysAttachment ISysAttachment
|
||||
localSysBlacklist ISysBlacklist
|
||||
localSysConfig ISysConfig
|
||||
localSysCron ISysCron
|
||||
localSysCronGroup ISysCronGroup
|
||||
localSysCurdDemo ISysCurdDemo
|
||||
localSysImTenant ISysImTenant
|
||||
localSysImRegistration ISysImRegistration
|
||||
localSysImInvite ISysImInvite
|
||||
localSysImUser ISysImUser
|
||||
localSysImGroup ISysImGroup
|
||||
localSysImRealname ISysImRealname
|
||||
localSysImWorkOrder ISysImWorkOrder
|
||||
localSysImOutbox ISysImOutbox
|
||||
localSysImOrg ISysImOrg
|
||||
localSysImFile ISysImFile
|
||||
localSysImFilePolicy ISysImFilePolicy
|
||||
localSysImUserPolicyGroup ISysImUserPolicyGroup
|
||||
localSysImSensitiveWord ISysImSensitiveWord
|
||||
localSysImSecurityPolicy ISysImSecurityPolicy
|
||||
localSysImDashboard ISysImDashboard
|
||||
localSysImPrivateMessage ISysImPrivateMessage
|
||||
localSysImGroupMessage ISysImGroupMessage
|
||||
localSysImUserLoginHistory ISysImUserLoginHistory
|
||||
localSysImLoginFailureLog ISysImLoginFailureLog
|
||||
localSysImExternalConfig ISysImExternalConfig
|
||||
localSysImNotification ISysImNotification
|
||||
localSysImAppRelease ISysImAppRelease
|
||||
localSysImAbuseReason ISysImAbuseReason
|
||||
localSysImMailboxConfig ISysImMailboxConfig
|
||||
localSysImFeedbackConfig ISysImFeedbackConfig
|
||||
localSysImWorkbench ISysImWorkbench
|
||||
localSysImTaskDashboard ISysImTaskDashboard
|
||||
localSysImAuditLog ISysImAuditLog
|
||||
localSysImKafkaAudit ISysImKafkaAudit
|
||||
localSysImKafkaCommand ISysImKafkaCommand
|
||||
localSysImDeadLetter ISysImDeadLetter
|
||||
localSysDictData ISysDictData
|
||||
localSysDictType ISysDictType
|
||||
localSysEmsLog ISysEmsLog
|
||||
localSysGenCodes ISysGenCodes
|
||||
localSysLog ISysLog
|
||||
localSysLoginLog ISysLoginLog
|
||||
localSysNormalTreeDemo ISysNormalTreeDemo
|
||||
localSysOptionTreeDemo ISysOptionTreeDemo
|
||||
localSysProvinces ISysProvinces
|
||||
localSysServeLicense ISysServeLicense
|
||||
localSysServeLog ISysServeLog
|
||||
localSysSmsLog ISysSmsLog
|
||||
localSysTestCategory ISysTestCategory
|
||||
)
|
||||
|
||||
func SysAddons() ISysAddons {
|
||||
@@ -941,6 +1007,78 @@ func RegisterSysImFilePolicy(i ISysImFilePolicy) {
|
||||
localSysImFilePolicy = i
|
||||
}
|
||||
|
||||
func SysImUserPolicyGroup() ISysImUserPolicyGroup {
|
||||
if localSysImUserPolicyGroup == nil {
|
||||
panic("implement not found for interface ISysImUserPolicyGroup, forgot register?")
|
||||
}
|
||||
return localSysImUserPolicyGroup
|
||||
}
|
||||
|
||||
func RegisterSysImUserPolicyGroup(i ISysImUserPolicyGroup) { localSysImUserPolicyGroup = i }
|
||||
|
||||
func SysImSensitiveWord() ISysImSensitiveWord {
|
||||
if localSysImSensitiveWord == nil {
|
||||
panic("implement not found for interface ISysImSensitiveWord, forgot register?")
|
||||
}
|
||||
return localSysImSensitiveWord
|
||||
}
|
||||
|
||||
func RegisterSysImSensitiveWord(i ISysImSensitiveWord) { localSysImSensitiveWord = i }
|
||||
|
||||
func SysImSecurityPolicy() ISysImSecurityPolicy {
|
||||
if localSysImSecurityPolicy == nil {
|
||||
panic("implement not found for interface ISysImSecurityPolicy, forgot register?")
|
||||
}
|
||||
return localSysImSecurityPolicy
|
||||
}
|
||||
|
||||
func RegisterSysImSecurityPolicy(i ISysImSecurityPolicy) { localSysImSecurityPolicy = i }
|
||||
|
||||
func SysImDashboard() ISysImDashboard {
|
||||
if localSysImDashboard == nil {
|
||||
panic("implement not found for interface ISysImDashboard, forgot register?")
|
||||
}
|
||||
return localSysImDashboard
|
||||
}
|
||||
|
||||
func RegisterSysImDashboard(i ISysImDashboard) { localSysImDashboard = i }
|
||||
|
||||
func SysImPrivateMessage() ISysImPrivateMessage {
|
||||
if localSysImPrivateMessage == nil {
|
||||
panic("implement not found for interface ISysImPrivateMessage, forgot register?")
|
||||
}
|
||||
return localSysImPrivateMessage
|
||||
}
|
||||
|
||||
func RegisterSysImPrivateMessage(i ISysImPrivateMessage) { localSysImPrivateMessage = i }
|
||||
|
||||
func SysImGroupMessage() ISysImGroupMessage {
|
||||
if localSysImGroupMessage == nil {
|
||||
panic("implement not found for interface ISysImGroupMessage, forgot register?")
|
||||
}
|
||||
return localSysImGroupMessage
|
||||
}
|
||||
|
||||
func RegisterSysImGroupMessage(i ISysImGroupMessage) { localSysImGroupMessage = i }
|
||||
|
||||
func SysImUserLoginHistory() ISysImUserLoginHistory {
|
||||
if localSysImUserLoginHistory == nil {
|
||||
panic("implement not found for interface ISysImUserLoginHistory, forgot register?")
|
||||
}
|
||||
return localSysImUserLoginHistory
|
||||
}
|
||||
|
||||
func RegisterSysImUserLoginHistory(i ISysImUserLoginHistory) { localSysImUserLoginHistory = i }
|
||||
|
||||
func SysImLoginFailureLog() ISysImLoginFailureLog {
|
||||
if localSysImLoginFailureLog == nil {
|
||||
panic("implement not found for interface ISysImLoginFailureLog, forgot register?")
|
||||
}
|
||||
return localSysImLoginFailureLog
|
||||
}
|
||||
|
||||
func RegisterSysImLoginFailureLog(i ISysImLoginFailureLog) { localSysImLoginFailureLog = i }
|
||||
|
||||
func SysImExternalConfig() ISysImExternalConfig {
|
||||
if localSysImExternalConfig == nil {
|
||||
panic("implement not found for interface ISysImExternalConfig, forgot register?")
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
SET @now := NOW();
|
||||
SET @imRootId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'imManager' LIMIT 1);
|
||||
|
||||
INSERT INTO `hg_admin_menu` (`id`,`pid`,`title`,`name`,`path`,`icon`,`type`,`redirect`,`permissions`,`permission_name`,`component`,`always_show`,`active_menu`,`is_root`,`is_frame`,`frame_src`,`keep_alive`,`hidden`,`affix`,`level`,`tree`,`sort`,`remark`,`status`,`created_at`,`updated_at`)
|
||||
SELECT NULL,@imRootId,p.title,p.name,p.path,'','2','',p.permissions,'',p.component,'1','imManager','0','0','','0','0','0','2',CONCAT('tr_',@imRootId,' '),p.sort,'','1',@now,@now
|
||||
FROM (
|
||||
SELECT '数据概览' title,'imDashboardIndex' name,'dashboard/index' path,'/imDashboard/overview' permissions,'/imDashboard/index' component,5 sort UNION ALL
|
||||
SELECT '单聊消息','imPrivateMessageIndex','private-message/index','/imPrivateMessage/list','/imPrivateMessage/index',40 UNION ALL
|
||||
SELECT '群聊消息','imGroupMessageIndex','group-message/index','/imGroupMessage/list','/imGroupMessage/index',45 UNION ALL
|
||||
SELECT '用户登录历史','imUserLoginHistoryIndex','user-login-history/index','/imUserLoginHistory/list','/imUserLoginHistory/index',50 UNION ALL
|
||||
SELECT '登录失败日志','imLoginFailureLogIndex','login-failure-log/index','/imLoginFailureLog/list','/imLoginFailureLog/index',55
|
||||
) p WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` m WHERE m.`name`=p.name);
|
||||
|
||||
SET @dashboardId := (SELECT `id` FROM `hg_admin_menu` WHERE `name`='imDashboardIndex' LIMIT 1);
|
||||
SET @privateMessageId := (SELECT `id` FROM `hg_admin_menu` WHERE `name`='imPrivateMessageIndex' LIMIT 1);
|
||||
SET @groupMessageId := (SELECT `id` FROM `hg_admin_menu` WHERE `name`='imGroupMessageIndex' LIMIT 1);
|
||||
SET @userLoginId := (SELECT `id` FROM `hg_admin_menu` WHERE `name`='imUserLoginHistoryIndex' LIMIT 1);
|
||||
SET @loginFailureId := (SELECT `id` FROM `hg_admin_menu` WHERE `name`='imLoginFailureLogIndex' LIMIT 1);
|
||||
|
||||
INSERT INTO `hg_admin_menu` (`id`,`pid`,`title`,`name`,`path`,`icon`,`type`,`redirect`,`permissions`,`permission_name`,`component`,`always_show`,`active_menu`,`is_root`,`is_frame`,`frame_src`,`keep_alive`,`hidden`,`affix`,`level`,`tree`,`sort`,`remark`,`status`,`created_at`,`updated_at`)
|
||||
SELECT NULL,x.pid,x.title,x.name,'','','3','',x.permissions,'','','1','','0','0','','0','0','0','3',CONCAT('tr_',@imRootId,' tr_',x.pid,' '),x.sort,'','1',@now,@now
|
||||
FROM (
|
||||
SELECT @dashboardId pid,'查看概览' title,'imDashboardOverview' name,'/imDashboard/overview' permissions,10 sort UNION ALL
|
||||
SELECT @dashboardId,'查看趋势','imDashboardTrends','/imDashboard/trends',20 UNION ALL
|
||||
SELECT @privateMessageId,'消息详情','imPrivateMessageView','/imPrivateMessage/view',10 UNION ALL
|
||||
SELECT @privateMessageId,'隐藏消息','imPrivateMessageHide','/imPrivateMessage/hide',20 UNION ALL
|
||||
SELECT @privateMessageId,'删除消息','imPrivateMessageDelete','/imPrivateMessage/delete',30 UNION ALL
|
||||
SELECT @privateMessageId,'导出消息','imPrivateMessageExport','/imPrivateMessage/export',40 UNION ALL
|
||||
SELECT @groupMessageId,'消息详情','imGroupMessageView','/imGroupMessage/view',10 UNION ALL
|
||||
SELECT @groupMessageId,'隐藏消息','imGroupMessageHide','/imGroupMessage/hide',20 UNION ALL
|
||||
SELECT @groupMessageId,'删除消息','imGroupMessageDelete','/imGroupMessage/delete',30 UNION ALL
|
||||
SELECT @groupMessageId,'导出消息','imGroupMessageExport','/imGroupMessage/export',40 UNION ALL
|
||||
SELECT @userLoginId,'导出登录历史','imUserLoginHistoryExport','/imUserLoginHistory/export',10 UNION ALL
|
||||
SELECT @loginFailureId,'失败详情','imLoginFailureLogView','/imLoginFailureLog/view',10 UNION ALL
|
||||
SELECT @loginFailureId,'导出失败日志','imLoginFailureLogExport','/imLoginFailureLog/export',20 UNION ALL
|
||||
SELECT @loginFailureId,'加入IP黑名单','imLoginFailureLogAddBlacklist','/imLoginFailureLog/addBlacklist',30 UNION ALL
|
||||
SELECT @loginFailureId,'封禁关联用户','imLoginFailureLogBanUser','/imLoginFailureLog/banUser',40
|
||||
) x WHERE x.pid IS NOT NULL AND NOT EXISTS (SELECT 1 FROM `hg_admin_menu` m WHERE m.`name`=x.name);
|
||||
@@ -0,0 +1,52 @@
|
||||
SET @now := NOW();
|
||||
SET @imRootId := (SELECT `id` FROM `hg_admin_menu` WHERE `name` = 'imManager' LIMIT 1);
|
||||
|
||||
INSERT INTO `hg_admin_menu` (`id`,`pid`,`title`,`name`,`path`,`icon`,`type`,`redirect`,`permissions`,`permission_name`,`component`,`always_show`,`active_menu`,`is_root`,`is_frame`,`frame_src`,`keep_alive`,`hidden`,`affix`,`level`,`tree`,`sort`,`remark`,`status`,`created_at`,`updated_at`)
|
||||
SELECT NULL,@imRootId,'用户分组','imUserPolicyGroupIndex','user-policy-group/index','','2','','/imUserPolicyGroup/list','','/imUserPolicyGroup/index','1','imManager','0','0','','0','0','0','2',CONCAT('tr_',@imRootId,' '),'25','','1',@now,@now
|
||||
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name`='imUserPolicyGroupIndex');
|
||||
SET @policyGroupId := (SELECT `id` FROM `hg_admin_menu` WHERE `name`='imUserPolicyGroupIndex' LIMIT 1);
|
||||
|
||||
INSERT INTO `hg_admin_menu` (`id`,`pid`,`title`,`name`,`path`,`icon`,`type`,`redirect`,`permissions`,`permission_name`,`component`,`always_show`,`active_menu`,`is_root`,`is_frame`,`frame_src`,`keep_alive`,`hidden`,`affix`,`level`,`tree`,`sort`,`remark`,`status`,`created_at`,`updated_at`)
|
||||
SELECT NULL,@policyGroupId,p.title,p.name,'','','3','',p.permissions,'','','1','','0','0','','0','0','0','3',CONCAT('tr_',@imRootId,' tr_',@policyGroupId,' '),p.sort,'','1',@now,@now
|
||||
FROM (
|
||||
SELECT '分组详情' title,'imUserPolicyGroupView' name,'/imUserPolicyGroup/view' permissions,10 sort UNION ALL
|
||||
SELECT '分组编辑','imUserPolicyGroupEdit','/imUserPolicyGroup/edit',20 UNION ALL
|
||||
SELECT '分组删除','imUserPolicyGroupDelete','/imUserPolicyGroup/delete',30 UNION ALL
|
||||
SELECT '状态更新','imUserPolicyGroupStatus','/imUserPolicyGroup/status',40 UNION ALL
|
||||
SELECT '成员列表','imUserPolicyGroupMemberList','/imUserPolicyGroup/memberList',50 UNION ALL
|
||||
SELECT '添加成员','imUserPolicyGroupMemberAdd','/imUserPolicyGroup/memberAdd',60 UNION ALL
|
||||
SELECT '移除成员','imUserPolicyGroupMemberRemove','/imUserPolicyGroup/memberRemove',70
|
||||
) p WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` m WHERE m.`name`=p.name);
|
||||
|
||||
INSERT INTO `hg_admin_menu` (`id`,`pid`,`title`,`name`,`path`,`icon`,`type`,`redirect`,`permissions`,`permission_name`,`component`,`always_show`,`active_menu`,`is_root`,`is_frame`,`frame_src`,`keep_alive`,`hidden`,`affix`,`level`,`tree`,`sort`,`remark`,`status`,`created_at`,`updated_at`)
|
||||
SELECT NULL,@imRootId,'敏感词库','imSensitiveWordIndex','sensitive-word/index','','2','','/imSensitiveWord/list','','/imSensitiveWord/index','1','imManager','0','0','','0','0','0','2',CONCAT('tr_',@imRootId,' '),'90','','1',@now,@now
|
||||
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name`='imSensitiveWordIndex');
|
||||
SET @sensitiveWordId := (SELECT `id` FROM `hg_admin_menu` WHERE `name`='imSensitiveWordIndex' LIMIT 1);
|
||||
|
||||
INSERT INTO `hg_admin_menu` (`id`,`pid`,`title`,`name`,`path`,`icon`,`type`,`redirect`,`permissions`,`permission_name`,`component`,`always_show`,`active_menu`,`is_root`,`is_frame`,`frame_src`,`keep_alive`,`hidden`,`affix`,`level`,`tree`,`sort`,`remark`,`status`,`created_at`,`updated_at`)
|
||||
SELECT NULL,@sensitiveWordId,p.title,p.name,'','','3','',p.permissions,'','','1','','0','0','','0','0','0','3',CONCAT('tr_',@imRootId,' tr_',@sensitiveWordId,' '),p.sort,'','1',@now,@now
|
||||
FROM (
|
||||
SELECT '敏感词编辑' title,'imSensitiveWordEdit' name,'/imSensitiveWord/edit' permissions,10 sort UNION ALL
|
||||
SELECT '敏感词删除','imSensitiveWordDelete','/imSensitiveWord/delete',20 UNION ALL
|
||||
SELECT '状态更新','imSensitiveWordStatus','/imSensitiveWord/status',30 UNION ALL
|
||||
SELECT '批量导入','imSensitiveWordBatchImport','/imSensitiveWord/batchImport',40 UNION ALL
|
||||
SELECT '分组列表','imSensitiveWordGroupList','/imSensitiveWord/groupList',50 UNION ALL
|
||||
SELECT '分组编辑','imSensitiveWordGroupEdit','/imSensitiveWord/groupEdit',60
|
||||
) p WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` m WHERE m.`name`=p.name);
|
||||
|
||||
INSERT INTO `hg_admin_menu` (`id`,`pid`,`title`,`name`,`path`,`icon`,`type`,`redirect`,`permissions`,`permission_name`,`component`,`always_show`,`active_menu`,`is_root`,`is_frame`,`frame_src`,`keep_alive`,`hidden`,`affix`,`level`,`tree`,`sort`,`remark`,`status`,`created_at`,`updated_at`)
|
||||
SELECT NULL,@imRootId,'安全策略','imSecurityPolicyIndex','security-policy/index','','2','','/imSecurityPolicy/list','','/imSecurityPolicy/index','1','imManager','0','0','','0','0','0','2',CONCAT('tr_',@imRootId,' '),'95','','1',@now,@now
|
||||
WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` WHERE `name`='imSecurityPolicyIndex');
|
||||
SET @securityPolicyId := (SELECT `id` FROM `hg_admin_menu` WHERE `name`='imSecurityPolicyIndex' LIMIT 1);
|
||||
|
||||
INSERT INTO `hg_admin_menu` (`id`,`pid`,`title`,`name`,`path`,`icon`,`type`,`redirect`,`permissions`,`permission_name`,`component`,`always_show`,`active_menu`,`is_root`,`is_frame`,`frame_src`,`keep_alive`,`hidden`,`affix`,`level`,`tree`,`sort`,`remark`,`status`,`created_at`,`updated_at`)
|
||||
SELECT NULL,@securityPolicyId,p.title,p.name,'','','3','',p.permissions,'','','1','','0','0','','0','0','0','3',CONCAT('tr_',@imRootId,' tr_',@securityPolicyId,' '),p.sort,'','1',@now,@now
|
||||
FROM (
|
||||
SELECT '策略详情' title,'imSecurityPolicyView' name,'/imSecurityPolicy/view' permissions,10 sort UNION ALL
|
||||
SELECT '保存草稿','imSecurityPolicySave','/imSecurityPolicy/save',20 UNION ALL
|
||||
SELECT '发布策略','imSecurityPolicyPublish','/imSecurityPolicy/publish',30 UNION ALL
|
||||
SELECT '恢复默认','imSecurityPolicyRestoreDefault','/imSecurityPolicy/restoreDefault',40 UNION ALL
|
||||
SELECT 'IP规则列表','imSecurityPolicyIpRuleList','/imSecurityPolicy/ipRuleList',50 UNION ALL
|
||||
SELECT 'IP规则编辑','imSecurityPolicyIpRuleEdit','/imSecurityPolicy/ipRuleEdit',60 UNION ALL
|
||||
SELECT 'IP规则删除','imSecurityPolicyIpRuleDelete','/imSecurityPolicy/ipRuleDelete',70
|
||||
) p WHERE NOT EXISTS (SELECT 1 FROM `hg_admin_menu` m WHERE m.`name`=p.name);
|
||||
Reference in New Issue
Block a user