基于 opsx-web-lite 框架(Go+Gin+Vue3+Element Plus)构建许可证管理服务器,
业务域参考 Licence 服务器 Web 版。
【后端 - 4层架构】
- 认证:单 Admin 表 + JWT(HS256)
- 核心授权域:Product / Customer / License / Activation
· License 生成/验证/激活/机器绑定/心跳/续期/吊销
· 客户端契约接口:/api/v1/license/{verify,activate,deactivate,heartbeat}
- 定价订单:Plan / Order / 支付网关配置
- 防重复购买:CustomerEntitlement + 幂等支付 webhook + 手动发放
- 分析审计:Dashboard 统计 / Analytics / AuditLog / Setting 管理
【前端】
- Dashboard(ECharts 图表)、产品、客户、License、计划、订单、权益、日志、设置
- 9 个完整 CRUD 业务页面 + 登录/布局
【部署】
- SQLite + 单二进制(//go:embed 嵌入前端)
- 开发:./run.sh start(前端5181/后端9001)
- 生产:./run.sh build && ./run.sh binary start
- 默认账号:admin/admin
Author: Logan.Li
155 lines
4.3 KiB
Go
155 lines
4.3 KiB
Go
package database
|
|
|
|
import (
|
|
"backend/internal/model"
|
|
"backend/utils"
|
|
"log"
|
|
"time"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
const (
|
|
defaultAdminUsername = "admin"
|
|
defaultAdminPassword = "admin"
|
|
)
|
|
|
|
// SeedDefaults 初始化默认数据:管理员账号 + 系统设置 + 示例业务数据 // Logan.Li
|
|
func SeedDefaults(db *gorm.DB) error {
|
|
if err := seedAdmin(db); err != nil {
|
|
return err
|
|
}
|
|
if err := seedSetting(db); err != nil {
|
|
return err
|
|
}
|
|
if err := seedSampleData(db); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// seedAdmin 初始化默认管理员账号(仅在不存在时创建) // Logan.Li
|
|
func seedAdmin(db *gorm.DB) error {
|
|
var count int64
|
|
db.Model(&model.User{}).Where("username = ?", defaultAdminUsername).Count(&count)
|
|
if count > 0 {
|
|
return nil
|
|
}
|
|
|
|
admin := model.User{
|
|
Username: defaultAdminUsername,
|
|
Password: utils.HashPassword(defaultAdminPassword),
|
|
Email: "admin@opsx-licence.local",
|
|
Role: "admin",
|
|
IsActive: true,
|
|
}
|
|
if err := db.Create(&admin).Error; err != nil {
|
|
return err
|
|
}
|
|
log.Printf("[初始化] 已创建默认管理员账号: %s / %s(请尽快修改密码)", defaultAdminUsername, defaultAdminPassword)
|
|
return nil
|
|
}
|
|
|
|
// seedSetting 初始化默认系统设置(仅创建一次) // Logan.Li
|
|
func seedSetting(db *gorm.DB) error {
|
|
var count int64
|
|
db.Model(&model.Setting{}).Count(&count)
|
|
if count > 0 {
|
|
return nil
|
|
}
|
|
|
|
setting := model.Setting{
|
|
SystemName: "opsx-licence",
|
|
DefaultDuration: 365,
|
|
DefaultMaxActivations: 1,
|
|
ExpireReminderDays: 7,
|
|
APIRateLimit: 1000,
|
|
LogRetentionDays: 365,
|
|
}
|
|
if err := db.Create(&setting).Error; err != nil {
|
|
return err
|
|
}
|
|
log.Println("[初始化] 已创建默认系统设置")
|
|
return nil
|
|
}
|
|
|
|
// seedSampleData 初始化示例业务数据(产品/客户/计划/支付网关),便于开发联调 // Logan.Li
|
|
func seedSampleData(db *gorm.DB) error {
|
|
var productCount int64
|
|
db.Model(&model.Product{}).Count(&productCount)
|
|
if productCount > 0 {
|
|
return nil
|
|
}
|
|
|
|
// 示例产品 // Logan.Li
|
|
product := model.Product{
|
|
Name: "OpsX Tools Suite",
|
|
Code: "opsx-tools",
|
|
Version: "1.0.0",
|
|
Description: "OpsX 工具集 - 一站式运维工具箱",
|
|
Features: `["CLI","GUI","Web Console","API"]`,
|
|
Price: 99.00,
|
|
PriceModel: "subscription",
|
|
Status: 1,
|
|
}
|
|
if err := db.Create(&product).Error; err != nil {
|
|
return err
|
|
}
|
|
|
|
// 示例客户 // Logan.Li
|
|
customer := model.Customer{
|
|
Name: "示例客户",
|
|
Company: "Acme Inc.",
|
|
Email: "demo@acme.com",
|
|
Phone: "13800000000",
|
|
Status: 1,
|
|
}
|
|
if err := db.Create(&customer).Error; err != nil {
|
|
return err
|
|
}
|
|
|
|
// 示例定价计划(买断 + 月订阅 + 年订阅) // Logan.Li
|
|
plans := []model.Plan{
|
|
{ProductID: product.ID, Name: "个人永久版", PlanType: "perpetual", Price: 199, Currency: "USD", Duration: 0, MaxDevices: 1, Features: `["全部功能","永久使用","1 设备"]`, SortOrder: 1, Status: 1},
|
|
{ProductID: product.ID, Name: "专业版(月)", PlanType: "monthly", Price: 19, Currency: "USD", Duration: 30, MaxDevices: 3, Features: `["全部功能","按月订阅","3 设备"]`, SortOrder: 2, Status: 1},
|
|
{ProductID: product.ID, Name: "企业版(年)", PlanType: "yearly", Price: 199, Currency: "USD", Duration: 365, MaxDevices: 10, Features: `["全部功能","按年订阅优惠","10 设备","优先支持"]`, SortOrder: 3, Status: 1},
|
|
}
|
|
for i := range plans {
|
|
if err := db.Create(&plans[i]).Error; err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
// 示例 License // Logan.Li
|
|
now := time.Now()
|
|
license := model.License{
|
|
LicenseKey: utils.GenerateLicenseKey(),
|
|
CustomerID: customer.ID,
|
|
ProductID: product.ID,
|
|
Status: model.LicenseStatusActive,
|
|
StartDate: now,
|
|
EndDate: now.AddDate(0, 0, 365),
|
|
Duration: 365,
|
|
MaxActivations: 3,
|
|
Notes: "示例授权,初始化生成",
|
|
}
|
|
if err := db.Create(&license).Error; err != nil {
|
|
return err
|
|
}
|
|
|
|
// 示例支付网关配置(沙箱) // Logan.Li
|
|
gateway := model.PaymentGatewayConfig{
|
|
Gateway: "creem",
|
|
Enabled: true,
|
|
SandboxMode: true,
|
|
Currency: "USD",
|
|
Priority: 1,
|
|
}
|
|
if err := db.Create(&gateway).Error; err != nil {
|
|
return err
|
|
}
|
|
|
|
log.Println("[初始化] 已创建示例产品、客户、计划、License、支付网关")
|
|
return nil
|
|
}
|