小程序一些功能更新

This commit is contained in:
李琦
2026-09-29 10:57:01 +08:00
parent 0cb70a7618
commit 3bb7fa8db3
96 changed files with 13890 additions and 213 deletions

View File

@@ -74,10 +74,16 @@ func seedAdmin(ctx context.Context) error {
return err
}
// seedRows 按 uniqueKey 幂等插入(存在即跳过该行)
// seedRows 按 uniqueKey 幂等插入(存在即跳过该行)。
//
// 🔴 存在性判断必须 `.Unscoped()`:GoFrame v2.10 会给 Model 查询自动追加 `deleted_at IS NULL`。
// 若不加,被软删的种子行(当前即 tools)会因"查不到"被判为不存在 → 尝试重新 Insert
// → 撞上**未**墓碑化的唯一键(uk tool_key)→ 每次启动刷屏报错。
// 加 Unscoped 后判"存在"→ 直接跳过,删除继续跨重启保持。
// (对 modules/levels/quota_packs/settings 等无 deleted_at 列的表,Unscoped 是空操作。)
func seedRows(ctx context.Context, table, uniqueKey string, rows []g.Map) error {
for _, row := range rows {
count, err := g.Model(table).Where(uniqueKey, row[uniqueKey]).Count()
count, err := g.Model(table).Unscoped().Where(uniqueKey, row[uniqueKey]).Count()
if err != nil {
return err
}
@@ -96,6 +102,11 @@ func seedRows(ctx context.Context, table, uniqueKey string, rows []g.Map) error
// 与 seedRows 的区别是「已存在的行也会被更新」,适用于配置由代码定义、没有管理端编辑入口的表。
// 有管理端编辑需求的表请继续用 seedRows,避免每次重启覆盖用户在后台的修改。
func upsertRows(ctx context.Context, table, uniqueKey string, rows []g.Map, updateFields []string) error {
// 注意:此处**刻意不加** Unscoped(与上面的 seedRows 不同)。
// upsertRows 目前只服务 member_plans,而该表**没有** deleted_at 列 → 框架不会拼软删条件
// → 加不加 Unscoped 等价(空操作)。
// ⚠️ 若将来给 member_plans 增加软删列:不能盲加 Unscoped —— 那会让下面的 UPDATE 命中
// "已软删"的行,等于把软删数据"复活",未必是想要的语义,需重新评估。
for _, row := range rows {
count, err := g.Model(table).Where(uniqueKey, row[uniqueKey]).Count()
if err != nil {
@@ -169,6 +180,13 @@ func seedTools() []g.Map {
func seedSettings() []g.Map {
return []g.Map{
{"k": consts.SettingQuotaPeriodDays, "v": "7", "remark": "全局默认额度重置周期(天)"},
// ===== 优惠凭证域(迭代-2026-09-20)=====
// 免单道具 ID / 价格:后台可配,**不硬编码**;下单用码/券时改用该道具走支付。
{"k": consts.SettingFreebieProductId, "v": consts.DefaultFreebieProductId,
"remark": "免单道具 ID(须与 MP 后台【虚拟支付 → 道具管理】逐字符一致)"},
{"k": consts.SettingFreebiePriceCents, "v": "1", "remark": "免单道具价格(分)"},
{"k": consts.SettingPromoFailLimitPerMin, "v": "6", "remark": "同一用户 1 分钟内优惠码错误次数上限"},
{"k": consts.SettingCouponLockTtlSeconds, "v": "900", "remark": "免单券下单占用自动释放时长(秒)"},
}
}