Some checks failed
Build docker and publish / linux (1.24.5) (push) Failing after 39s
- 新增系统称号模板与效果配置表及相关CRUD接口 - 实现用户称号分配与抽奖效果应用逻辑 - 优化抽奖接口支持用户ID参数以应用称号效果 - 新增称号管理前端页面与分配功能 - 修复Windows时区错误与JSON字段初始化问题 - 移除无用管理接口代码并更新文档说明
178 lines
7.9 KiB
Go
178 lines
7.9 KiB
Go
package admin
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
|
|
"bindbox-game/internal/code"
|
|
"bindbox-game/internal/pkg/core"
|
|
"bindbox-game/internal/repository/mysql/model"
|
|
)
|
|
|
|
type seedDefaultTitlesResponse struct {
|
|
Created int `json:"created"`
|
|
Exists int `json:"exists"`
|
|
IDs []int64 `json:"ids"`
|
|
}
|
|
|
|
// SeedDefaultTitles 内置6个称号与基础效果
|
|
func (h *handler) SeedDefaultTitles() core.HandlerFunc {
|
|
return func(ctx core.Context) {
|
|
// 定义默认称号与效果
|
|
type def struct {
|
|
Name string
|
|
Description string
|
|
EffectType int32
|
|
Params map[string]interface{}
|
|
Stack int32
|
|
CapX1000 int32
|
|
}
|
|
defs := []def{
|
|
{Name: "优惠券使者", Description: "可领取优惠券", EffectType: 1, Params: map[string]interface{}{ "template_id": 0, "frequency": map[string]interface{}{"period": "day", "times": 1}}, Stack: 1, CapX1000: 0},
|
|
{Name: "折扣官", Description: "抽奖购票折扣", EffectType: 2, Params: map[string]interface{}{ "discount_type": "percentage", "value_x1000": 100, "max_discount_x1000": 300}, Stack: 0, CapX1000: 300},
|
|
{Name: "签到达人", Description: "签到双倍积分", EffectType: 3, Params: map[string]interface{}{ "multiplier_x1000": 2000, "daily_cap_points": 0}, Stack: 1, CapX1000: 3000},
|
|
{Name: "卡牌使者", Description: "可领取道具卡", EffectType: 4, Params: map[string]interface{}{ "template_id": 0, "frequency": map[string]interface{}{"period": "week", "times": 2}}, Stack: 1, CapX1000: 0},
|
|
{Name: "幸运加成者", Description: "抽奖概率加成", EffectType: 5, Params: map[string]interface{}{ "target_prize_ids": []int64{}, "boost_x1000": 100, "cap_x1000": 300}, Stack: 1, CapX1000: 300},
|
|
{Name: "双倍之王", Description: "奖品双倍概率", EffectType: 6, Params: map[string]interface{}{ "target_prize_ids": []int64{}, "chance_x1000": 200, "period_cap_times": 1}, Stack: 1, CapX1000: 500},
|
|
}
|
|
created := 0
|
|
exists := 0
|
|
var ids []int64
|
|
for _, d := range defs {
|
|
// 是否存在同名称号
|
|
row, _ := h.readDB.SystemTitles.WithContext(ctx.RequestContext()).Where(h.readDB.SystemTitles.Name.Eq(d.Name)).First()
|
|
if row != nil {
|
|
exists++
|
|
ids = append(ids, row.ID)
|
|
continue
|
|
}
|
|
// 创建称号(使用模型类型)
|
|
newRow := &model.SystemTitles{
|
|
Name: d.Name,
|
|
Description: d.Description,
|
|
Status: 1,
|
|
ObtainRulesJSON: "{}",
|
|
ScopesJSON: "{}",
|
|
}
|
|
if err := h.writeDB.SystemTitles.WithContext(ctx.RequestContext()).Create(newRow); err != nil {
|
|
ctx.AbortWithError(core.Error(http.StatusInternalServerError, code.ServerError, "创建称号失败"))
|
|
return
|
|
}
|
|
// 重新读取ID
|
|
trow, _ := h.readDB.SystemTitles.WithContext(ctx.RequestContext()).Where(h.readDB.SystemTitles.Name.Eq(d.Name)).First()
|
|
if trow == nil {
|
|
ctx.AbortWithError(core.Error(http.StatusInternalServerError, code.ServerError, "创建称号失败(读取)"))
|
|
return
|
|
}
|
|
ids = append(ids, trow.ID)
|
|
created++
|
|
// 创建效果
|
|
paramsBytes, _ := json.Marshal(d.Params)
|
|
eff := &model.SystemTitleEffects{
|
|
TitleID: trow.ID,
|
|
EffectType: d.EffectType,
|
|
ParamsJSON: string(paramsBytes),
|
|
StackingStrategy: d.Stack,
|
|
CapValueX1000: d.CapX1000,
|
|
ScopesJSON: "{}",
|
|
Sort: 1,
|
|
Status: 1,
|
|
}
|
|
if err := h.writeDB.SystemTitleEffects.WithContext(ctx.RequestContext()).Create(eff); err != nil {
|
|
ctx.AbortWithError(core.Error(http.StatusInternalServerError, code.ServerError, "创建称号效果失败"))
|
|
return
|
|
}
|
|
}
|
|
ctx.Payload(&seedDefaultTitlesResponse{Created: created, Exists: exists, IDs: ids})
|
|
}
|
|
}
|
|
|
|
type ensureTitlesMenuResponse struct {
|
|
Ensured bool `json:"ensured"`
|
|
Parent int64 `json:"parent_id"`
|
|
MenuID int64 `json:"menu_id"`
|
|
}
|
|
|
|
// EnsureTitlesMenu 确保运营菜单下存在“称号管理”子菜单
|
|
func (h *handler) EnsureTitlesMenu() core.HandlerFunc {
|
|
return func(ctx core.Context) {
|
|
// 查找运营菜单父节点
|
|
parent, _ := h.readDB.Menus.WithContext(ctx.RequestContext()).Where(h.readDB.Menus.Name.Eq("Operations")).First()
|
|
var parentID int64
|
|
if parent == nil {
|
|
// 创建运营父菜单
|
|
pm := &model.Menus{
|
|
ParentID: 0,
|
|
Path: "/operations",
|
|
Name: "Operations",
|
|
Component: "/index/index",
|
|
Icon: "ri:tools-line",
|
|
Sort: 10,
|
|
Status: true,
|
|
KeepAlive: true,
|
|
IsHide: false,
|
|
IsHideTab: false,
|
|
CreatedUser: "system",
|
|
UpdatedUser: "system",
|
|
}
|
|
if err := h.writeDB.Menus.WithContext(ctx.RequestContext()).Create(pm); err != nil {
|
|
ctx.AbortWithError(core.Error(http.StatusInternalServerError, code.ServerError, "创建运营菜单失败"))
|
|
return
|
|
}
|
|
// 读取
|
|
parent, _ = h.readDB.Menus.WithContext(ctx.RequestContext()).Where(h.readDB.Menus.Name.Eq("Operations")).First()
|
|
if parent == nil {
|
|
ctx.AbortWithError(core.Error(http.StatusInternalServerError, code.ServerError, "创建运营菜单失败(读取)"))
|
|
return
|
|
}
|
|
}
|
|
parentID = parent.ID
|
|
// 查找称号菜单
|
|
titlesMenu, _ := h.readDB.Menus.WithContext(ctx.RequestContext()).Where(h.readDB.Menus.Path.Eq("titles")).Where(h.readDB.Menus.ParentID.Eq(parentID)).First()
|
|
if titlesMenu == nil {
|
|
tm := &struct {
|
|
ParentID int64
|
|
Path string
|
|
Name string
|
|
Component string
|
|
Icon string
|
|
Sort int32
|
|
Status bool
|
|
KeepAlive bool
|
|
IsHide bool
|
|
IsHideTab bool
|
|
}{
|
|
ParentID: parentID,
|
|
Path: "titles",
|
|
Name: "Titles",
|
|
Component: "/operations/titles",
|
|
Icon: "ri:medal-line",
|
|
Sort: 50,
|
|
Status: true,
|
|
KeepAlive: true,
|
|
IsHide: false,
|
|
IsHideTab: false,
|
|
}
|
|
mm := &model.Menus{
|
|
ParentID: tm.ParentID,
|
|
Path: tm.Path,
|
|
Name: tm.Name,
|
|
Component: tm.Component,
|
|
Icon: tm.Icon,
|
|
Sort: tm.Sort,
|
|
Status: tm.Status,
|
|
KeepAlive: tm.KeepAlive,
|
|
IsHide: tm.IsHide,
|
|
IsHideTab: tm.IsHideTab,
|
|
CreatedUser: "system",
|
|
UpdatedUser: "system",
|
|
}
|
|
if err := h.writeDB.Menus.WithContext(ctx.RequestContext()).Create(mm); err != nil {
|
|
ctx.AbortWithError(core.Error(http.StatusInternalServerError, code.ServerError, "创建称号菜单失败"))
|
|
return
|
|
}
|
|
titlesMenu, _ = h.readDB.Menus.WithContext(ctx.RequestContext()).Where(h.readDB.Menus.Path.Eq("titles")).Where(h.readDB.Menus.ParentID.Eq(parentID)).First()
|
|
}
|
|
ctx.Payload(&ensureTitlesMenuResponse{Ensured: true, Parent: parentID, MenuID: titlesMenu.ID})
|
|
}
|
|
} |