feat(license): Pro 授权机制 — 离线许可码 + 免费版功能闸门
CI / Backend (go vet + test) (push) Canceled after 0s
CI / Frontend (lint + build + test) (push) Canceled after 0s

免费版:日志查询/部署管理/采集/用户管理/LDAP/设置;Pro(¥199 个人单实例永久 / ¥499 团队多实例永久):
日志分析、日志告警、智能运维(AI)、审计日志。
- 后端:HMAC-SHA256 离线许可码(签发 CLI / license --plan --edition --seats --customer --days;
  永久=days 0),GET /system/license + POST activate;RequirePro 闸门挂 metrics/ai/audit;
  过期自动回落免费;测试覆盖签发-校验/篡改/免费拒签
- 前端:菜单 Pro 项带锁标;四个 Pro 页面免费版渲染升级引导卡(功能清单+定价+页内激活);
  设置页新增授权区(版本/席位/到期/激活入口);license 词典中英
- domains 注册提升到 main.tsx 全局(修复 license 命名空间在未引 domains 的页面显示裸键)
This commit is contained in:
opsx committed 2026-10-31 23:08:06 +08:00
1 parent c60b827262
commit 9641503007
26 files changed
+632 -23

No files matched your search

+50
View File
@@ -40,11 +40,61 @@ func fileExists(path string) bool {
// runCLI 提供不依赖 Web 的运维命令(备份 CronJob、恢复、自检都走它)。
//
// lokistack self-check # 打印 JSON 自检结果
func strDefault(v, d string) string {
if strings.TrimSpace(v) == "" {
return d
}
return v
}
func runCLI(args []string) {
switch args[0] {
case "self-check":
out, _ := json.MarshalIndent(services.SelfCheck(), "", " ")
fmt.Println(string(out))
case "license":
// 发行方工具:签发 Pro 许可码(需发行密钥构建;默认密钥仅供开发自测)
flags := map[string]string{}
for _, a := range args[1:] {
if rest, ok := strings.CutPrefix(a, "--"); ok {
if k, v, ok2 := strings.Cut(rest, "="); ok2 {
flags[k] = v
}
}
}
getInt := func(k string, d int) int {
if v := flags[k]; v != "" {
n := 0
for _, ch := range v {
if ch < '0' || ch > '9' {
n = 0
break
}
n = n*10 + int(ch-'0')
}
if n > 0 {
return n
}
}
return d
}
days := getInt("days", 0)
key, err := services.GenerateLicenseKey(
"pro",
strDefault(flags["edition"], "personal"),
strDefault(flags["customer"], "unnamed"),
getInt("seats", 0), getInt("instances", 1), days,
)
if err != nil {
fmt.Fprintln(os.Stderr, "签发失败:", err)
os.Exit(1)
}
expiry := "永久"
if days > 0 {
expiry = fmt.Sprintf("%d 天", days)
}
fmt.Printf("许可码(%s / %s / %s):\n%s\n", strDefault(flags["edition"], "personal"), strDefault(flags["customer"], "unnamed"), expiry, key)
case "version":
fmt.Printf("%s (commit %s, built %s)\n", version, gitCommit, buildTime)
default: