143 lines
8.1 KiB
Go
143 lines
8.1 KiB
Go
package main
|
|
|
|
import (
|
|
"log"
|
|
"time"
|
|
|
|
"golang.org/x/crypto/bcrypt"
|
|
|
|
"kefu-cloud/server/internal/config"
|
|
"kefu-cloud/server/internal/model"
|
|
)
|
|
|
|
func main() {
|
|
cfg := config.Load()
|
|
model.InitDB(cfg.Database.DSN())
|
|
|
|
seed()
|
|
log.Println("种子数据填充完成")
|
|
}
|
|
|
|
func seed() {
|
|
hash, _ := bcrypt.GenerateFromPassword([]byte("kefu_admin123"), bcrypt.DefaultCost)
|
|
pwd := string(hash)
|
|
|
|
model.EnsurePermissions()
|
|
|
|
// Plans
|
|
plans := []model.Plan{
|
|
{Name: "基础版", PriceMonthly: 299, Seats: 2, StorageDays: 30, KBLimit: 50, Status: "active", Features: `{"stats":"basic","api":false,"channels":["web"],"brand":false}`},
|
|
{Name: "专业版", PriceMonthly: 699, Seats: 10, StorageDays: 180, KBLimit: 500, Status: "active", Features: `{"stats":"advanced","api":true,"channels":["web","wechat","app"],"brand":true}`},
|
|
{Name: "企业版", PriceMonthly: 1999, Seats: 50, StorageDays: 0, KBLimit: 0, Status: "active", Features: `{"stats":"custom","api":true,"channels":["all"],"brand":true,"dedicated":true}`},
|
|
}
|
|
model.DB.Create(&plans)
|
|
|
|
// Tenants
|
|
now := time.Now()
|
|
tenants := []model.Tenant{
|
|
{Name: "赵六科技", PlanID: &plans[2].ID, SeatCount: 30, ExpireAt: now.AddDate(1, 0, 0), Status: "normal", ContactName: "赵总", ContactPhone: "13800001111", ContactEmail: "zhao@tech.com"},
|
|
{Name: "李四商贸", PlanID: &plans[1].ID, SeatCount: 10, ExpireAt: now.AddDate(0, 6, 0), Status: "normal", ContactName: "李经理", ContactPhone: "13900002222", ContactEmail: "li@trade.com"},
|
|
{Name: "王五集团", PlanID: &plans[2].ID, SeatCount: 50, ExpireAt: now.AddDate(0, 0, 7), Status: "expiring", ContactName: "王总", ContactPhone: "13700003333", ContactEmail: "wang@group.com"},
|
|
{Name: "孙八信息", PlanID: &plans[0].ID, SeatCount: 2, ExpireAt: now.AddDate(1, 0, 0), Status: "suspended", ContactName: "孙经理", ContactPhone: "13600004444", ContactEmail: "sun@info.com"},
|
|
{Name: "周九科技", PlanID: &plans[1].ID, SeatCount: 8, ExpireAt: now.AddDate(0, -1, 0), Status: "expired", ContactName: "周总", ContactPhone: "13500005555", ContactEmail: "zhou@tech.com"},
|
|
}
|
|
model.DB.Create(&tenants)
|
|
|
|
// 为每个租户创建内置角色及默认权限
|
|
for _, t := range tenants {
|
|
model.EnsureBuiltinRoles(t.ID)
|
|
}
|
|
|
|
// Platform admin
|
|
model.DB.Create(&model.User{
|
|
TenantID: 0, Role: "platform_admin", Username: "platform_admin", PasswordHash: pwd, Nickname: "平台管理员", Status: "online",
|
|
})
|
|
|
|
// Tenant 1 users
|
|
model.DB.Create(&model.User{
|
|
TenantID: tenants[0].ID, Role: "admin", Username: "kefu_admin", PasswordHash: pwd, Nickname: "赵总(管理员)", Status: "online",
|
|
})
|
|
model.DB.Create(&model.User{
|
|
TenantID: tenants[0].ID, Role: "supervisor", Username: "supervisor", PasswordHash: pwd, Nickname: "客服主管", Status: "online",
|
|
})
|
|
agent1 := model.User{TenantID: tenants[0].ID, Role: "agent", Username: "agent1", PasswordHash: pwd, Nickname: "客服小王", Status: "online"}
|
|
agent2 := model.User{TenantID: tenants[0].ID, Role: "agent", Username: "agent2", PasswordHash: pwd, Nickname: "客服小李", Status: "online"}
|
|
agent3 := model.User{TenantID: tenants[0].ID, Role: "agent", Username: "agent3", PasswordHash: pwd, Nickname: "客服小张", Status: "online"}
|
|
model.DB.Create(&[]model.User{agent1, agent2, agent3})
|
|
|
|
// Tenant 2 users
|
|
model.DB.Create(&model.User{
|
|
TenantID: tenants[1].ID, Role: "admin", Username: "litrade_admin", PasswordHash: pwd, Nickname: "李经理", Status: "online",
|
|
})
|
|
model.DB.Create(&model.User{
|
|
TenantID: tenants[1].ID, Role: "agent", Username: "litrade_agent1", PasswordHash: pwd, Nickname: "客服小李2", Status: "online",
|
|
})
|
|
|
|
// Channels for Tenant 1
|
|
channels := []model.Channel{
|
|
{TenantID: tenants[0].ID, Type: "web", Name: "网页聊天", Status: "enabled", ScriptCode: `<script src="/widget.js" data-id="WK_8a3f2e"></script>`},
|
|
{TenantID: tenants[0].ID, Type: "wechat", Name: "微信公众号", Status: "enabled"},
|
|
{TenantID: tenants[0].ID, Type: "app", Name: "APP内嵌", Status: "disabled"},
|
|
}
|
|
model.DB.Create(&channels)
|
|
|
|
// Knowledge categories(两级树,对齐设计稿)
|
|
tid := tenants[0].ID
|
|
rootFAQ := model.Category{TenantID: tid, Name: "产品常见问题"}
|
|
rootAfter := model.Category{TenantID: tid, Name: "售后服务"}
|
|
rootTech := model.Category{TenantID: tid, Name: "技术支持"}
|
|
rootPolicy := model.Category{TenantID: tid, Name: "政策条款"}
|
|
rootQuick := model.Category{TenantID: tid, Name: "快捷回复模板"}
|
|
model.DB.Create(&rootFAQ)
|
|
model.DB.Create(&rootAfter)
|
|
model.DB.Create(&rootTech)
|
|
model.DB.Create(&rootPolicy)
|
|
model.DB.Create(&rootQuick)
|
|
subAccount := model.Category{TenantID: tid, Name: "账户相关", ParentID: &rootFAQ.ID}
|
|
subFeature := model.Category{TenantID: tid, Name: "功能使用", ParentID: &rootFAQ.ID}
|
|
subBilling := model.Category{TenantID: tid, Name: "计费问题", ParentID: &rootFAQ.ID}
|
|
model.DB.Create(&subAccount)
|
|
model.DB.Create(&subFeature)
|
|
model.DB.Create(&subBilling)
|
|
entries := []model.KnowledgeEntry{
|
|
{TenantID: tid, CategoryID: subAccount.ID, Title: "如何修改登录密码", Content: "登录后在右上角头像→个人设置→修改密码。也可通过手机验证码或邮箱链接重置。", Status: "published", UsageCount: 156},
|
|
{TenantID: tid, CategoryID: subBilling.ID, Title: "支持哪些支付方式", Content: "支持微信支付、支付宝、银行转账", Status: "published", UsageCount: 98},
|
|
{TenantID: tid, CategoryID: subFeature.ID, Title: "如何升级为高级会员", Content: "进入账户设置页面,选择会员升级选项,支持月付和年付两种方式,年付享8折优惠", Status: "published", UsageCount: 88},
|
|
{TenantID: tid, CategoryID: rootAfter.ID, Title: "退货流程说明", Content: "在线申请→审核→寄回→退款,全程3-5个工作日", Status: "published", UsageCount: 45},
|
|
{TenantID: tid, CategoryID: rootTech.ID, Title: "API接口文档", Content: "开发者文档请访问 docs.example.com/api", Status: "draft", UsageCount: 0},
|
|
{TenantID: tid, CategoryID: rootPolicy.ID, Title: "隐私政策更新说明", Content: "我们会定期更新隐私政策,重大变更将通过站内信通知", Status: "published", UsageCount: 12},
|
|
{TenantID: tid, CategoryID: rootQuick.ID, Title: "欢迎语模板", Content: "您好!欢迎来到客服云,请问有什么可以帮您的?", Status: "published", UsageCount: 230},
|
|
}
|
|
model.DB.Create(&entries)
|
|
|
|
// 客户标签库(管理员维护,坐席选择)
|
|
customerTags := []model.CustomerTag{
|
|
{TenantID: tid, Name: "VIP客户", Color: "amber", SortOrder: 0},
|
|
{TenantID: tid, Name: "新客户", Color: "green", SortOrder: 1},
|
|
{TenantID: tid, Name: "活跃", Color: "blue", SortOrder: 2},
|
|
{TenantID: tid, Name: "沉默", Color: "orange", SortOrder: 3},
|
|
{TenantID: tid, Name: "企业客户", Color: "cyan", SortOrder: 4},
|
|
}
|
|
model.DB.Create(&customerTags)
|
|
|
|
// 团队快捷回复(独立模块;知识库「快捷回复模板」分类可逐步弃用)
|
|
quickReplies := []model.QuickReply{
|
|
{TenantID: tid, Scope: "team", Title: "打招呼", Content: "您好!欢迎来到客服云,请问有什么可以帮您的?", Shortcut: "nh", GroupName: "通用", Status: "published", UsageCount: 120},
|
|
{TenantID: tid, Scope: "team", Title: "稍等查询", Content: "您好,正在为您查询,请稍候。", Shortcut: "sd", GroupName: "通用", Status: "published", UsageCount: 80},
|
|
{TenantID: tid, Scope: "team", Title: "提供订单号", Content: "为更快处理,请您提供订单号或相关截图,谢谢。", Shortcut: "ddh", GroupName: "售后", Status: "published", UsageCount: 56},
|
|
{TenantID: tid, Scope: "team", Title: "结束语", Content: "感谢您的咨询,祝您生活愉快!如有其它问题随时联系我们。", Shortcut: "js", GroupName: "通用", Status: "draft", UsageCount: 0},
|
|
}
|
|
model.DB.Create(&quickReplies)
|
|
|
|
// Announcements
|
|
model.DB.Create(&[]model.Announcement{
|
|
{Title: "系统维护通知", Content: "平台将于7月20日 02:00-04:00 进行例行维护", Status: "published"},
|
|
{Title: "新功能上线", Content: "知识库批量导入功能已上线", Status: "published"},
|
|
})
|
|
|
|
log.Println("默认租户管理员: kefu_admin / kefu_admin123")
|
|
log.Println("其它种子账号密码均为: kefu_admin123")
|
|
}
|
|
|
|
func ptr[T any](v T) *T { return &v }
|