feat: 新增用户地址更新功能并优化抽奖结果展示,支持显示订单所有抽奖记录
Some checks failed
Build docker and publish / linux (1.24.5) (push) Failing after 15s

This commit is contained in:
邹方成 2025-12-26 12:44:29 +08:00
parent 04791789c9
commit 635924040a
6 changed files with 160 additions and 2 deletions

View File

@ -298,8 +298,9 @@ type resultQueryRequest struct {
}
type resultResponse struct {
Result map[string]any `json:"result"`
Receipt map[string]any `json:"receipt"`
Result map[string]any `json:"result"`
Results []map[string]any `json:"results"`
Receipt map[string]any `json:"receipt"`
}
// GetLotteryResult 抽奖结果查询
@ -377,6 +378,28 @@ func (h *handler) GetLotteryResult() core.HandlerFunc {
}
return ""
}()}
// Also fetch all draw logs for this order to include doubled rewards
if orderID > 0 {
allLogs, _ := h.readDB.ActivityDrawLogs.WithContext(ctx.RequestContext()).Where(h.readDB.ActivityDrawLogs.OrderID.Eq(orderID)).Find()
for _, lg := range allLogs {
rwi, _ := h.readDB.ActivityRewardSettings.WithContext(ctx.RequestContext()).Where(h.readDB.ActivityRewardSettings.ID.Eq(lg.RewardID)).First()
rsp.Results = append(rsp.Results, map[string]any{
"reward_id": lg.RewardID,
"reward_name": func() string {
if rwi != nil {
return rwi.Name
}
return ""
}(),
"image": func() string {
if rwi != nil {
return rwi.Image
}
return ""
}(),
})
}
}
} else if cfgMode == "instant" {
// 即时开奖必须绑定订单且校验归属与支付状态
if orderID == 0 || ord == nil {
@ -496,6 +519,26 @@ func (h *handler) GetLotteryResult() core.HandlerFunc {
}
return ""
}()}
// Fetch all draw logs for this order to include doubled/upgraded rewards
allLogs, _ := h.readDB.ActivityDrawLogs.WithContext(ctx.RequestContext()).Where(h.readDB.ActivityDrawLogs.OrderID.Eq(orderID)).Find()
for _, lg := range allLogs {
rwi, _ := h.readDB.ActivityRewardSettings.WithContext(ctx.RequestContext()).Where(h.readDB.ActivityRewardSettings.ID.Eq(lg.RewardID)).First()
rsp.Results = append(rsp.Results, map[string]any{
"reward_id": lg.RewardID,
"reward_name": func() string {
if rwi != nil {
return rwi.Name
}
return ""
}(),
"image": func() string {
if rwi != nil {
return rwi.Image
}
return ""
}(),
})
}
}
}
}

View File

@ -0,0 +1,71 @@
package app
import (
"net/http"
"strconv"
"bindbox-game/internal/code"
"bindbox-game/internal/pkg/core"
"bindbox-game/internal/pkg/validation"
usersvc "bindbox-game/internal/service/user"
)
type updateAddressRequest struct {
Name string `json:"name"`
Mobile string `json:"mobile"`
Province string `json:"province"`
City string `json:"city"`
District string `json:"district"`
Address string `json:"address"`
IsDefault bool `json:"is_default"`
}
// UpdateUserAddress 更新用户地址
// @Summary 更新用户地址
// @Description 更新当前登录用户的指定收货地址
// @Tags APP端.用户
// @Accept json
// @Produce json
// @Param user_id path integer true "用户ID"
// @Param address_id path integer true "地址ID"
// @Security LoginVerifyToken
// @Param RequestBody body updateAddressRequest true "请求参数"
// @Success 200 {object} okResponse
// @Failure 400 {object} code.Failure "参数错误"
// @Failure 401 {object} code.Failure "未授权"
// @Failure 500 {object} code.Failure "服务器内部错误"
// @Router /api/app/users/{user_id}/addresses/{address_id} [put]
func (h *handler) UpdateUserAddress() core.HandlerFunc {
return func(ctx core.Context) {
req := new(updateAddressRequest)
if err := ctx.ShouldBindJSON(req); err != nil {
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
return
}
if req.Name == "" || req.Mobile == "" || req.Province == "" || req.City == "" || req.District == "" || req.Address == "" {
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "缺少必要参数"))
return
}
userID := int64(ctx.SessionUserInfo().Id)
idStr := ctx.Param("address_id")
addrID, err := strconv.ParseInt(idStr, 10, 64)
if err != nil || addrID <= 0 {
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "地址ID错误"))
return
}
in := usersvc.UpdateAddressInput{
Name: req.Name,
Mobile: req.Mobile,
Province: req.Province,
City: req.City,
District: req.District,
Address: req.Address,
IsDefault: req.IsDefault,
}
if err := h.user.UpdateAddress(ctx.RequestContext(), userID, addrID, in); err != nil {
ctx.AbortWithError(core.Error(http.StatusBadRequest, 10012, err.Error()))
return
}
ctx.Payload(okResponse{Ok: true})
}
}

View File

@ -342,6 +342,7 @@ func NewHTTPMux(logger logger.CustomLogger, db mysql.Repo) (core.Mux, func(), er
appAuthApiRouter.POST("/users/:user_id/addresses", userHandler.AddUserAddress())
appAuthApiRouter.GET("/users/:user_id/addresses", userHandler.ListUserAddresses())
appAuthApiRouter.PUT("/users/:user_id/addresses/:address_id/default", userHandler.SetDefaultUserAddress())
appAuthApiRouter.PUT("/users/:user_id/addresses/:address_id", userHandler.UpdateUserAddress())
appAuthApiRouter.DELETE("/users/:user_id/addresses/:address_id", userHandler.DeleteUserAddress())
appAuthApiRouter.POST("/pay/wechat/jsapi/preorder", userHandler.WechatJSAPIPreorder())

View File

@ -86,3 +86,38 @@ func (s *service) DeleteAddress(ctx context.Context, userID int64, addressID int
_, err := s.writeDB.UserAddresses.WithContext(ctx).Where(s.writeDB.UserAddresses.UserID.Eq(userID), s.writeDB.UserAddresses.ID.Eq(addressID)).Delete(&model.UserAddresses{})
return err
}
type UpdateAddressInput struct {
Name string
Mobile string
Province string
City string
District string
Address string
IsDefault bool
}
func (s *service) UpdateAddress(ctx context.Context, userID int64, addressID int64, in UpdateAddressInput) error {
tx := s.writeDB.Begin()
updates := map[string]interface{}{
"name": in.Name,
"mobile": in.Mobile,
"province": in.Province,
"city": in.City,
"district": in.District,
"address": in.Address,
}
if in.IsDefault {
// 先将其他地址设为非默认
if _, err := tx.UserAddresses.WithContext(ctx).Where(tx.UserAddresses.UserID.Eq(userID), tx.UserAddresses.IsDefault.Eq(1)).Updates(tx.UserAddresses.IsDefault.Value(0)); err != nil {
_ = tx.Rollback()
return err
}
updates["is_default"] = 1
}
if _, err := tx.UserAddresses.WithContext(ctx).Where(tx.UserAddresses.UserID.Eq(userID), tx.UserAddresses.ID.Eq(addressID)).Updates(updates); err != nil {
_ = tx.Rollback()
return err
}
return tx.Commit()
}

View File

@ -40,6 +40,7 @@ type Service interface {
AddAddress(ctx context.Context, userID int64, in AddAddressInput) (*model.UserAddresses, error)
ListAddresses(ctx context.Context, userID int64, page, pageSize int) (items []*model.UserAddresses, total int64, err error)
SetDefaultAddress(ctx context.Context, userID int64, addressID int64) error
UpdateAddress(ctx context.Context, userID int64, addressID int64, in UpdateAddressInput) error
DeleteAddress(ctx context.Context, userID int64, addressID int64) error
CreateUser(ctx context.Context, in CreateUserInput) (*model.Users, error)
DeleteUser(ctx context.Context, userID int64) error

View File

@ -1665,3 +1665,10 @@
{"level":"info","time":"2025-12-26 12:16:02","caller":"logger/logger.go:309","msg":"Processing event","domain":"mini-chat[fat]","type":"order_paid","worker_id":4}
{"level":"info","time":"2025-12-26 12:16:59","caller":"logger/logger.go:309","msg":"Processing event","domain":"mini-chat[fat]","type":"order_paid","worker_id":0}
{"level":"info","time":"2025-12-26 12:17:46","caller":"logger/logger.go:309","msg":"Processing event","domain":"mini-chat[fat]","type":"order_paid","worker_id":4}
{"level":"info","time":"2025-12-26 12:33:31","caller":"logger/logger.go:309","msg":"Connected to Redis","domain":"mini-chat[fat]","addr":"118.25.13.43:8379"}
{"level":"info","time":"2025-12-26 12:33:31","caller":"logger/logger.go:309","msg":"Task center worker started","domain":"mini-chat[fat]"}
{"level":"info","time":"2025-12-26 12:33:31","caller":"logger/logger.go:309","msg":"Worker routine started","domain":"mini-chat[fat]","worker_id":4}
{"level":"info","time":"2025-12-26 12:33:31","caller":"logger/logger.go:309","msg":"Worker routine started","domain":"mini-chat[fat]","worker_id":3}
{"level":"info","time":"2025-12-26 12:33:31","caller":"logger/logger.go:309","msg":"Worker routine started","domain":"mini-chat[fat]","worker_id":2}
{"level":"info","time":"2025-12-26 12:33:31","caller":"logger/logger.go:309","msg":"Worker routine started","domain":"mini-chat[fat]","worker_id":1}
{"level":"info","time":"2025-12-26 12:33:31","caller":"logger/logger.go:309","msg":"Worker routine started","domain":"mini-chat[fat]","worker_id":0}