218 lines
6.5 KiB
Go
218 lines
6.5 KiB
Go
package logic
|
||
|
||
import (
|
||
"context"
|
||
"strconv"
|
||
|
||
"github.com/gogf/gf/v2/errors/gerror"
|
||
"github.com/gogf/gf/v2/frame/g"
|
||
"github.com/gogf/gf/v2/os/gtime"
|
||
|
||
v1 "tool-api/api/admin/v1"
|
||
"tool-api/internal/consts"
|
||
)
|
||
|
||
// ============================================================================
|
||
// 管理端:额度配置 / 次数包 / 会员套餐 / 额度设置
|
||
// ============================================================================
|
||
|
||
// ===== 次数包档位 =====
|
||
|
||
func AdminQuotaPackList(ctx context.Context) (*v1.QuotaPackListRes, error) {
|
||
records, err := g.Model(consts.TableQuotaPacks).OrderAsc("sort").OrderAsc("times").All()
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
toolNames, err := toolNameMap(ctx)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
list := make([]v1.QuotaPackItem, 0, len(records))
|
||
for _, r := range records {
|
||
toolKey := r["tool_key"].String()
|
||
toolName := ""
|
||
if toolKey != "" {
|
||
toolName = toolNames[toolKey]
|
||
if toolName == "" {
|
||
toolName = toolKey + "(工具不存在)"
|
||
}
|
||
}
|
||
list = append(list, v1.QuotaPackItem{
|
||
Id: r["id"].Int64(),
|
||
PackKey: r["pack_key"].String(),
|
||
Name: r["name"].String(),
|
||
Times: r["times"].Int(),
|
||
PriceCents: r["price_cents"].Int64(),
|
||
ProductId: r["product_id"].String(),
|
||
ValidDays: r["valid_days"].Int(),
|
||
ToolKey: toolKey,
|
||
ToolName: toolName,
|
||
Badge: r["badge"].String(),
|
||
Sort: r["sort"].Int(),
|
||
IsEnabled: r["is_enabled"].Int(),
|
||
Remark: r["remark"].String(),
|
||
})
|
||
}
|
||
return &v1.QuotaPackListRes{List: list}, nil
|
||
}
|
||
|
||
func AdminQuotaPackSave(ctx context.Context, req *v1.QuotaPackSaveReq) (*v1.QuotaPackSaveRes, error) {
|
||
if req.ToolKey != "" {
|
||
count, err := g.Model(consts.TableTools).Where("tool_key", req.ToolKey).Count()
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
if count == 0 {
|
||
return nil, gerror.New("绑定的工具不存在")
|
||
}
|
||
}
|
||
validDays := req.ValidDays
|
||
if validDays <= 0 {
|
||
validDays = 365
|
||
}
|
||
data := g.Map{
|
||
"name": req.Name,
|
||
"times": req.Times,
|
||
"price_cents": req.PriceCents,
|
||
"product_id": req.ProductId,
|
||
"valid_days": validDays,
|
||
"tool_key": req.ToolKey,
|
||
"badge": req.Badge,
|
||
"sort": req.Sort,
|
||
"is_enabled": req.IsEnabled,
|
||
"remark": req.Remark,
|
||
"updated_at": gtime.Now(),
|
||
}
|
||
if req.Id > 0 {
|
||
// 编辑:pack_key 是跨端契约(决定道具),不允许改
|
||
if _, err := g.Model(consts.TableQuotaPacks).Where("id", req.Id).Data(data).Update(); err != nil {
|
||
return nil, err
|
||
}
|
||
return &v1.QuotaPackSaveRes{}, nil
|
||
}
|
||
count, err := g.Model(consts.TableQuotaPacks).Where("pack_key", req.PackKey).Count()
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
if count > 0 {
|
||
return nil, gerror.New("档位标识已存在")
|
||
}
|
||
data["pack_key"] = req.PackKey
|
||
data["created_at"] = gtime.Now()
|
||
if _, err = g.Model(consts.TableQuotaPacks).Data(data).Insert(); err != nil {
|
||
return nil, err
|
||
}
|
||
return &v1.QuotaPackSaveRes{}, nil
|
||
}
|
||
|
||
func AdminQuotaPackToggle(ctx context.Context, id int64, value int) (*v1.QuotaPackToggleRes, error) {
|
||
if _, err := g.Model(consts.TableQuotaPacks).Where("id", id).
|
||
Data(g.Map{"is_enabled": value, "updated_at": gtime.Now()}).Update(); err != nil {
|
||
return nil, err
|
||
}
|
||
return &v1.QuotaPackToggleRes{}, nil
|
||
}
|
||
|
||
// ===== 额度设置 =====
|
||
|
||
func AdminQuotaSettingGet(ctx context.Context) (*v1.QuotaSettingGetRes, error) {
|
||
return &v1.QuotaSettingGetRes{
|
||
PeriodDays: GlobalQuotaPeriodDays(ctx),
|
||
DefaultPeriodDays: consts.DefaultQuotaPeriodDays,
|
||
}, nil
|
||
}
|
||
|
||
func AdminQuotaSettingSave(ctx context.Context, periodDays int) (*v1.QuotaSettingSaveRes, error) {
|
||
if err := settingSave(ctx, consts.SettingQuotaPeriodDays,
|
||
strconv.Itoa(periodDays), "全局默认额度重置周期(天)"); err != nil {
|
||
return nil, err
|
||
}
|
||
return &v1.QuotaSettingSaveRes{}, nil
|
||
}
|
||
|
||
// ===== 会员套餐 =====
|
||
|
||
func AdminPlanList(ctx context.Context) (*v1.PlanListRes, error) {
|
||
records, err := g.Model(consts.TableMemberPlans).OrderAsc("sort").All()
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
levelNames, err := levelNameMap(ctx)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
list := make([]v1.PlanItem, 0, len(records))
|
||
for _, r := range records {
|
||
levelKey := r["level_key"].String()
|
||
list = append(list, v1.PlanItem{
|
||
Id: r["id"].Int64(),
|
||
PlanKey: r["plan_key"].String(),
|
||
Name: r["name"].String(),
|
||
Subtitle: r["subtitle"].String(),
|
||
LevelKey: levelKey,
|
||
LevelName: levelNames[levelKey],
|
||
DurationDays: r["duration_days"].Int(),
|
||
PriceCents: r["price_cents"].Int64(),
|
||
ProductId: r["product_id"].String(),
|
||
Badge: r["badge"].String(),
|
||
QuotaPeriodDays: r["quota_period_days"].Int(),
|
||
Sort: r["sort"].Int(),
|
||
IsEnabled: r["is_enabled"].Int(),
|
||
Remark: r["remark"].String(),
|
||
})
|
||
}
|
||
return &v1.PlanListRes{List: list}, nil
|
||
}
|
||
|
||
// AdminPlanSave 只覆盖运营需要维护的列。
|
||
//
|
||
// 刻意不放开 plan_key / level_key / duration_days:
|
||
// - plan_key 是订单与前端展示的关联键
|
||
// - level_key 必须是 levels 表里真实存在的等级
|
||
// - duration_days 涉及续费顺延语义
|
||
//
|
||
// 这三项仍以 seedMemberPlans 为准,避免后台改出前端不认识的组合。
|
||
func AdminPlanSave(ctx context.Context, req *v1.PlanSaveReq) (*v1.PlanSaveRes, error) {
|
||
record, err := g.Model(consts.TableMemberPlans).Where("id", req.Id).One()
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
if record.IsEmpty() {
|
||
return nil, gerror.New("套餐不存在")
|
||
}
|
||
if _, err = g.Model(consts.TableMemberPlans).Where("id", req.Id).Data(g.Map{
|
||
"name": req.Name,
|
||
"subtitle": req.Subtitle,
|
||
"price_cents": req.PriceCents,
|
||
"product_id": req.ProductId,
|
||
"badge": req.Badge,
|
||
"quota_period_days": req.QuotaPeriodDays,
|
||
"sort": req.Sort,
|
||
"is_enabled": req.IsEnabled,
|
||
"remark": req.Remark,
|
||
"updated_at": gtime.Now(),
|
||
}).Update(); err != nil {
|
||
return nil, err
|
||
}
|
||
return &v1.PlanSaveRes{}, nil
|
||
}
|
||
|
||
// ===== 用户额度周期 =====
|
||
|
||
func AdminUserQuotaPeriod(ctx context.Context, userId int64, periodDays int) (*v1.UserQuotaPeriodRes, error) {
|
||
count, err := g.Model(consts.TableUsers).Where("id", userId).Count()
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
if count == 0 {
|
||
return nil, gerror.New("用户不存在")
|
||
}
|
||
if _, err = g.Model(consts.TableUsers).Where("id", userId).Data(g.Map{
|
||
"quota_period_days": periodDays,
|
||
"updated_at": gtime.Now(),
|
||
}).Update(); err != nil {
|
||
return nil, err
|
||
}
|
||
return &v1.UserQuotaPeriodRes{}, nil
|
||
}
|