Files

191 lines
10 KiB
Go

package model
import (
"gorm.io/gorm"
"gorm.io/gorm/clause"
)
const (
DataScopeAll = "all"
DataScopeSelf = "self"
)
var dataScopeModules = []string{"session", "customer", "chat_history", "statistics"}
var predefinedPermissions = []Permission{
{Code: "session.view", Name: "查看会话列表", Module: "工作台", Category: "view", SortOrder: 1},
{Code: "session.reply", Name: "回复访客消息", Module: "工作台", Category: "operate", SortOrder: 2},
{Code: "session.transfer", Name: "转接会话", Module: "工作台", Category: "operate", SortOrder: 3},
{Code: "session.end", Name: "结束会话", Module: "工作台", Category: "operate", SortOrder: 4},
{Code: "session.note", Name: "添加内部备注", Module: "工作台", Category: "operate", SortOrder: 5},
{Code: "session.priority", Name: "标记优先级", Module: "工作台", Category: "operate", SortOrder: 6},
{Code: "customer.view", Name: "查看客户列表", Module: "客户管理", Category: "view", SortOrder: 7},
{Code: "customer.create", Name: "新增客户", Module: "客户管理", Category: "operate", SortOrder: 8},
{Code: "customer.edit", Name: "编辑客户资料", Module: "客户管理", Category: "operate", SortOrder: 9},
{Code: "customer.export", Name: "导出客户", Module: "客户管理", Category: "operate", SortOrder: 10},
{Code: "customer.tag", Name: "管理客户标签", Module: "客户管理", Category: "operate", SortOrder: 11},
{Code: "chat_history.view", Name: "查看对话记录", Module: "对话记录", Category: "view", SortOrder: 12},
{Code: "chat_history.detail", Name: "查看会话详情", Module: "对话记录", Category: "view", SortOrder: 13},
{Code: "chat_history.export", Name: "导出对话记录", Module: "对话记录", Category: "operate", SortOrder: 14},
{Code: "chat_history.batch_archive", Name: "批量归档记录", Module: "对话记录", Category: "operate", SortOrder: 15},
{Code: "knowledge.view", Name: "查看知识库", Module: "知识库", Category: "view", SortOrder: 16},
{Code: "knowledge.create", Name: "新建知识条目", Module: "知识库", Category: "operate", SortOrder: 17},
{Code: "knowledge.edit", Name: "编辑知识条目", Module: "知识库", Category: "operate", SortOrder: 18},
{Code: "knowledge.publish", Name: "发布/下架条目", Module: "知识库", Category: "operate", SortOrder: 19},
{Code: "knowledge.delete", Name: "删除知识条目/分类", Module: "知识库", Category: "operate", SortOrder: 20},
{Code: "quick_reply.view", Name: "查看快捷回复", Module: "快捷回复", Category: "view", SortOrder: 21},
{Code: "quick_reply.team_create", Name: "新建团队快捷回复", Module: "快捷回复", Category: "operate", SortOrder: 22},
{Code: "quick_reply.team_edit", Name: "编辑/删除团队回复", Module: "快捷回复", Category: "operate", SortOrder: 23},
{Code: "quick_reply.personal_manage", Name: "管理我的快捷回复", Module: "快捷回复", Category: "operate", SortOrder: 24},
{Code: "blacklist.view", Name: "查看黑名单", Module: "黑名单", Category: "view", SortOrder: 25},
{Code: "blacklist.create", Name: "拉黑访客/IP/设备", Module: "黑名单", Category: "operate", SortOrder: 26},
{Code: "blacklist.delete", Name: "解除黑名单", Module: "黑名单", Category: "operate", SortOrder: 27},
{Code: "statistics.view", Name: "查看数据统计", Module: "数据统计", Category: "view", SortOrder: 28},
{Code: "statistics.export", Name: "导出报告", Module: "数据统计", Category: "operate", SortOrder: 29},
{Code: "statistics.performance", Name: "查看客服绩效排行", Module: "数据统计", Category: "view", SortOrder: 30},
{Code: "settings.basic", Name: "基本设置", Module: "系统设置", Category: "operate", SortOrder: 31},
{Code: "settings.channel", Name: "渠道管理", Module: "系统设置", Category: "operate", SortOrder: 32},
{Code: "settings.staff", Name: "坐席账号", Module: "系统设置", Category: "operate", SortOrder: 33},
{Code: "settings.assign_rule", Name: "客服分配规则", Module: "系统设置", Category: "operate", SortOrder: 34},
{Code: "settings.customer_tag", Name: "客户标签", Module: "系统设置", Category: "operate", SortOrder: 35},
{Code: "settings.auto_reply", Name: "自动回复", Module: "系统设置", Category: "operate", SortOrder: 36},
{Code: "settings.worktime", Name: "工作时间", Module: "系统设置", Category: "operate", SortOrder: 37},
{Code: "settings.notification", Name: "通知设置", Module: "系统设置", Category: "operate", SortOrder: 38},
{Code: "permission.view", Name: "查看角色列表", Module: "权限控制", Category: "view", SortOrder: 39},
{Code: "permission.create_role", Name: "创建/编辑角色", Module: "权限控制", Category: "operate", SortOrder: 40},
{Code: "permission.delete_role", Name: "删除自定义角色", Module: "权限控制", Category: "operate", SortOrder: 41},
{Code: "permission.assign_role", Name: "给账号分配角色", Module: "权限控制", Category: "operate", SortOrder: 42},
}
// PredefinedPermissions 返回系统所有权限码列表。
func PredefinedPermissions() []Permission {
result := make([]Permission, len(predefinedPermissions))
copy(result, predefinedPermissions)
return result
}
// DataScopeModules 返回支持数据范围配置的业务模块。
func DataScopeModules() []string {
result := make([]string, len(dataScopeModules))
copy(result, dataScopeModules)
return result
}
// DefaultRoleDataScopes 返回角色的默认数据范围。
func DefaultRoleDataScopes(roleCode string) map[string]string {
scope := DataScopeSelf
if roleCode == "admin" || roleCode == "supervisor" {
scope = DataScopeAll
}
result := make(map[string]string, len(dataScopeModules))
for _, module := range dataScopeModules {
result[module] = scope
}
return result
}
// BuiltinRolePermissionCodes 返回内置角色对应的权限码集合。
func BuiltinRolePermissionCodes() map[string][]string {
return map[string][]string{
"admin": {
"session.view", "session.reply", "session.transfer", "session.end", "session.note", "session.priority",
"customer.view", "customer.create", "customer.edit", "customer.export", "customer.tag",
"chat_history.view", "chat_history.detail", "chat_history.export", "chat_history.batch_archive",
"knowledge.view", "knowledge.create", "knowledge.edit", "knowledge.publish", "knowledge.delete",
"quick_reply.view", "quick_reply.team_create", "quick_reply.team_edit", "quick_reply.personal_manage",
"blacklist.view", "blacklist.create", "blacklist.delete",
"statistics.view", "statistics.export", "statistics.performance",
"settings.basic", "settings.channel", "settings.staff", "settings.assign_rule",
"settings.customer_tag", "settings.auto_reply", "settings.worktime", "settings.notification",
"permission.view", "permission.create_role", "permission.delete_role", "permission.assign_role",
},
"supervisor": {
"session.view", "session.reply", "session.transfer", "session.end", "session.note", "session.priority",
"customer.view", "customer.create", "customer.edit", "customer.export", "customer.tag",
"chat_history.view", "chat_history.detail", "chat_history.export", "chat_history.batch_archive",
"knowledge.view", "knowledge.create", "knowledge.edit", "knowledge.publish", "knowledge.delete",
"quick_reply.view", "quick_reply.team_create", "quick_reply.team_edit", "quick_reply.personal_manage",
"blacklist.view", "blacklist.create", "blacklist.delete",
"statistics.view", "statistics.export", "statistics.performance",
"settings.customer_tag", "settings.auto_reply",
},
"agent": {
"session.view", "session.reply", "session.end", "session.note", "session.priority",
"customer.view", "customer.create", "customer.edit", "customer.tag",
"chat_history.view", "chat_history.detail",
"knowledge.view",
"quick_reply.view", "quick_reply.personal_manage",
"statistics.view", "statistics.performance",
},
}
}
// EnsurePermissions 补齐并更新系统权限码,支持后续平滑新增权限项。
func EnsurePermissions() error {
for _, permission := range predefinedPermissions {
if err := DB.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "code"}},
DoUpdates: clause.AssignmentColumns([]string{"name", "module", "category", "sort_order"}),
}).Create(&permission).Error; err != nil {
return err
}
}
return nil
}
// EnsureBuiltinRoles 确保指定租户拥有三个内置角色。
func EnsureBuiltinRoles(tenantID uint) error {
builtins := []struct{ name, code, desc string }{
{"管理员", "admin", "租户最高权限,可管理账号、角色与全部系统设置"},
{"客服主管", "supervisor", "管理一线团队,可查看全部数据并维护知识库、快捷回复、黑名单等"},
{"客服", "agent", "一线接待人员,仅可查看和操作自己相关的会话、客户与个人数据"},
}
permMap := BuiltinRolePermissionCodes()
return DB.Transaction(func(tx *gorm.DB) error {
for _, b := range builtins {
var role Role
created := false
err := tx.Where("tenant_id = ? AND code = ?", tenantID, b.code).First(&role).Error
if err != nil {
if err != gorm.ErrRecordNotFound {
return err
}
role = Role{TenantID: tenantID, Name: b.name, Code: b.code, Type: "builtin", Desc: b.desc}
if err := tx.Create(&role).Error; err != nil {
return err
}
created = true
}
var permissionCount int64
if err := tx.Model(&RolePermission{}).Where("role_id = ?", role.ID).Count(&permissionCount).Error; err != nil {
return err
}
// 新建角色或迁移期空关联才写默认权限,避免覆盖管理员的自定义配置。
if created || permissionCount == 0 {
var permissionIDs []uint
if err := tx.Model(&Permission{}).Where("code IN ?", permMap[b.code]).Pluck("id", &permissionIDs).Error; err != nil {
return err
}
for _, permissionID := range permissionIDs {
if err := tx.Clauses(clause.OnConflict{DoNothing: true}).Create(&RolePermission{
RoleID: role.ID, PermissionID: permissionID,
}).Error; err != nil {
return err
}
}
}
for module, scope := range DefaultRoleDataScopes(b.code) {
if err := tx.Clauses(clause.OnConflict{DoNothing: true}).Create(&RoleDataScope{
RoleID: role.ID, Module: module, Scope: scope,
}).Error; err != nil {
return err
}
}
}
return nil
})
}