bindbox-game/internal/api/user/synthesis_app.go
Zuncle 0a397adf41 feat: 支持批量合成并收口不包邮运费规则
本次提交同时完成碎片批量合成与盒柜发货运费规则改造,减少用户重复操作,并确保不包邮商品在任何件数下都必须支付运费。

- 合成功能:新增批量合成接口与前端一键合成入口,按配方可合成上限批量消耗碎片并生成对应资产,同时补充批量合成测试
- 运费规则:后端新增统一运费判定逻辑,命中 category_id 14/15 的商品时整单强制收取运费,否则继续沿用少于 5 件收运费的旧规则
- 发货流程:新增运费检查接口,前端发货前先向后端确认是否需要支付运费,并根据“件数不足”或“包含不包邮商品”展示不同提示文案
- 接口校验:运费预下单与批量申请发货统一复用后端判定逻辑,避免前端规则被绕过
2026-04-21 02:06:56 +08:00

78 lines
2.3 KiB
Go

package app
import (
"net/http"
"bindbox-game/internal/code"
"bindbox-game/internal/pkg/core"
)
type synthesizeRequest struct {
RecipeID int64 `json:"recipe_id"`
}
type listSynthesisLogsAppRequest struct {
Page int `form:"page"`
PageSize int `form:"page_size"`
}
func (h *handler) ListSynthesisRecipesForUser() core.HandlerFunc {
return func(ctx core.Context) {
userID := int64(ctx.SessionUserInfo().Id)
list, err := h.synthesis.GetAvailableRecipesForUser(ctx.RequestContext(), userID)
if err != nil {
ctx.AbortWithError(core.Error(http.StatusInternalServerError, code.ServerError, err.Error()))
return
}
ctx.Payload(map[string]interface{}{"list": list})
}
}
func (h *handler) DoSynthesis() core.HandlerFunc {
return func(ctx core.Context) {
req := new(synthesizeRequest)
if err := ctx.ShouldBindJSON(req); err != nil || req.RecipeID <= 0 {
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "invalid recipe_id"))
return
}
userID := int64(ctx.SessionUserInfo().Id)
inv, err := h.synthesis.Synthesize(ctx.RequestContext(), userID, req.RecipeID)
if err != nil {
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ServerError, err.Error()))
return
}
ctx.Payload(inv)
}
}
func (h *handler) DoBatchSynthesis() core.HandlerFunc {
return func(ctx core.Context) {
req := new(synthesizeRequest)
if err := ctx.ShouldBindJSON(req); err != nil || req.RecipeID <= 0 {
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "invalid recipe_id"))
return
}
userID := int64(ctx.SessionUserInfo().Id)
result, err := h.synthesis.BatchSynthesize(ctx.RequestContext(), userID, req.RecipeID)
if err != nil {
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ServerError, err.Error()))
return
}
ctx.Payload(result)
}
}
func (h *handler) ListSynthesisLogsForUser() core.HandlerFunc {
return func(ctx core.Context) {
userID := int64(ctx.SessionUserInfo().Id)
req := new(listSynthesisLogsAppRequest)
_ = ctx.ShouldBindForm(req)
list, total, err := h.synthesis.ListLogs(ctx.RequestContext(), req.Page, req.PageSize, &userID)
if err != nil {
ctx.AbortWithError(core.Error(http.StatusInternalServerError, code.ServerError, err.Error()))
return
}
ctx.Payload(map[string]interface{}{"list": list, "total": total})
}
}