bindbox-game/internal/api/admin/douyin_orders_admin.go

202 lines
5.6 KiB
Go

package admin
import (
"bindbox-game/internal/code"
"bindbox-game/internal/pkg/core"
"bindbox-game/internal/pkg/validation"
"bindbox-game/internal/service/douyin"
"fmt"
"net/http"
"strconv"
)
// ---------- 抖店配置 API ----------
type getDouyinConfigResponse struct {
Cookie string `json:"cookie"`
IntervalMinutes int `json:"interval_minutes"`
}
func (h *handler) GetDouyinConfig() core.HandlerFunc {
return func(ctx core.Context) {
cfg, err := h.douyinSvc.GetConfig(ctx.RequestContext())
if err != nil {
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ServerError, validation.Error(err)))
return
}
ctx.Payload(getDouyinConfigResponse{
Cookie: cfg.Cookie,
IntervalMinutes: cfg.IntervalMinutes,
})
}
}
type saveDouyinConfigRequest struct {
Cookie string `json:"cookie"`
IntervalMinutes int `json:"interval_minutes"`
}
func (h *handler) SaveDouyinConfig() core.HandlerFunc {
return func(ctx core.Context) {
req := new(saveDouyinConfigRequest)
if err := ctx.ShouldBindJSON(req); err != nil {
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
return
}
if err := h.douyinSvc.SaveConfig(ctx.RequestContext(), req.Cookie, req.IntervalMinutes); err != nil {
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ServerError, validation.Error(err)))
return
}
ctx.Payload(pcSimpleMessage{Message: "保存成功"})
}
}
// ---------- 抖店订单列表 API ----------
type listDouyinOrdersRequest struct {
Page int `form:"page"`
PageSize int `form:"page_size"`
Status *int `form:"status"`
}
type douyinOrderItem struct {
ID int64 `json:"id"`
ShopOrderID string `json:"shop_order_id"`
OrderStatus int32 `json:"order_status"`
OrderStatusText string `json:"order_status_text"`
DouyinUserID string `json:"douyin_user_id"`
LocalUserID int64 `json:"local_user_id"`
LocalUserNickname string `json:"local_user_nickname"`
ActualReceiveAmount string `json:"actual_receive_amount"`
PayTypeDesc string `json:"pay_type_desc"`
Remark string `json:"remark"`
UserNickname string `json:"user_nickname"`
CreatedAt string `json:"created_at"`
}
type listDouyinOrdersResponse struct {
Page int `json:"page"`
PageSize int `json:"page_size"`
Total int64 `json:"total"`
List []douyinOrderItem `json:"list"`
}
func (h *handler) ListDouyinOrders() core.HandlerFunc {
return func(ctx core.Context) {
req := new(listDouyinOrdersRequest)
if err := ctx.ShouldBindForm(req); err != nil {
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
return
}
orders, total, err := h.douyinSvc.ListOrders(ctx.RequestContext(), req.Page, req.PageSize, req.Status)
if err != nil {
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ServerError, validation.Error(err)))
return
}
// 获取匹配用户的昵称
userNicknameMap := make(map[int64]string)
var userIDs []int64
for _, o := range orders {
if uid, err := strconv.ParseInt(o.LocalUserID, 10, 64); err == nil && uid > 0 {
userIDs = append(userIDs, uid)
}
}
if len(userIDs) > 0 {
var users []struct {
ID int64
Nickname string
}
h.repo.GetDbR().Table("users").Where("id IN ?", userIDs).Select("id, nickname").Find(&users)
for _, u := range users {
userNicknameMap[u.ID] = u.Nickname
}
}
// 构建响应
list := make([]douyinOrderItem, len(orders))
for i, o := range orders {
uid, _ := strconv.ParseInt(o.LocalUserID, 10, 64)
list[i] = douyinOrderItem{
ID: o.ID,
ShopOrderID: o.ShopOrderID,
OrderStatus: o.OrderStatus,
OrderStatusText: getOrderStatusText(o.OrderStatus),
DouyinUserID: o.DouyinUserID,
LocalUserID: uid,
LocalUserNickname: userNicknameMap[uid],
ActualReceiveAmount: formatAmount(o.ActualReceiveAmount),
PayTypeDesc: o.PayTypeDesc,
Remark: o.Remark,
UserNickname: o.UserNickname,
CreatedAt: o.CreatedAt.Format("2006-01-02 15:04:05"),
}
}
ctx.Payload(listDouyinOrdersResponse{
Page: req.Page,
PageSize: req.PageSize,
Total: total,
List: list,
})
}
}
// ---------- 手动同步 API ----------
type syncDouyinOrdersResponse struct {
Message string `json:"message"`
TotalFetched int `json:"total_fetched"`
NewOrders int `json:"new_orders"`
MatchedUsers int `json:"matched_users"`
}
func (h *handler) SyncDouyinOrders() core.HandlerFunc {
return func(ctx core.Context) {
result, err := h.douyinSvc.FetchAndSyncOrders(ctx.RequestContext())
if err != nil {
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ServerError, validation.Error(err)))
return
}
ctx.Payload(syncDouyinOrdersResponse{
Message: "同步成功",
TotalFetched: result.TotalFetched,
NewOrders: result.NewOrders,
MatchedUsers: result.MatchedUsers,
})
}
}
// ---------- 辅助函数 ----------
func getOrderStatusText(status int32) string {
switch status {
case 1:
return "待付款"
case 2:
return "待发货"
case 3:
return "已发货"
case 4:
return "已取消"
case 5:
return "已完成"
default:
return "未知"
}
}
func formatAmount(amountCents int64) string {
yuan := float64(amountCents) / 100.0
return fmt.Sprintf("%.2f", yuan)
}
// SetDouyinService 设置抖店服务 (用于 handler 初始化)
func (h *handler) SetDouyinService(svc douyin.Service) {
h.douyinSvc = svc
}