Files
affiliate_dash/backend/internal/handler/rock.go
T

270 lines
7.2 KiB
Go

package handler
import (
"errors"
"strconv"
"strings"
"affiliate_dash/internal/pkg/response"
"affiliate_dash/internal/service"
"github.com/gin-gonic/gin"
)
type RockHandler struct {
rockSvc *service.RockService
}
func NewRockHandler(rockSvc *service.RockService) *RockHandler {
return &RockHandler{rockSvc: rockSvc}
}
// GetConfig 获取 Rock 平台配置
func (h *RockHandler) GetConfig(c *gin.Context) {
cfg, err := h.rockSvc.GetConfig(c.Request.Context())
if err != nil {
response.ServerError(c, err.Error())
return
}
response.OK(c, cfg)
}
// UpdateConfig 更新 Rock 平台配置
func (h *RockHandler) UpdateConfig(c *gin.Context) {
var req service.UpdateRockConfigReq
if err := c.ShouldBindJSON(&req); err != nil {
response.BadRequest(c, "参数解析失败")
return
}
cfg, err := h.rockSvc.UpdateConfig(c.Request.Context(), req)
if err != nil {
var validationErr *service.RockConfigValidationError
if errors.As(err, &validationErr) {
response.BadRequest(c, validationErr.Error())
return
}
response.ServerError(c, err.Error())
return
}
response.OK(c, cfg)
}
type testConnReq struct {
BearerToken string `json:"bearer_token"`
}
// TestConnection 测试上游 Token 连通性
func (h *RockHandler) TestConnection(c *gin.Context) {
var req testConnReq
_ = c.ShouldBindJSON(&req)
me, err := h.rockSvc.TestConnection(c.Request.Context(), req.BearerToken)
if err != nil {
response.BadRequest(c, err.Error())
return
}
response.OK(c, me)
}
// GetStats 获取概览数据与库存统计
func (h *RockHandler) GetStats(c *gin.Context) {
stats, err := h.rockSvc.GetStats(c.Request.Context())
if err != nil {
response.ServerError(c, err.Error())
return
}
response.OK(c, stats)
}
// RefreshDashboard 拉取上游 dashboard 并同步最新采购单价。
func (h *RockHandler) RefreshDashboard(c *gin.Context) {
result, err := h.rockSvc.RefreshDashboard(c.Request.Context())
if err != nil {
response.BadRequest(c, err.Error())
return
}
response.OK(c, result)
}
type purchaseReq struct {
Count int `json:"count"`
}
// PurchaseTokens 手动采购并入库 Token
func (h *RockHandler) PurchaseTokens(c *gin.Context) {
var req purchaseReq
if err := c.ShouldBindJSON(&req); err != nil || req.Count <= 0 {
req.Count = 50
}
tokens, err := h.rockSvc.PurchaseTokens(c.Request.Context(), req.Count, false)
if err != nil {
response.BadRequest(c, err.Error())
return
}
response.OK(c, gin.H{
"purchased_count": len(tokens),
"message": "采购成功,已批量入库",
})
}
// ListTokens 分页获取 Token 库存列表
func (h *RockHandler) ListTokens(c *gin.Context) {
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
status := strings.TrimSpace(c.Query("status"))
search := strings.TrimSpace(c.Query("search"))
tokens, total, err := h.rockSvc.ListTokens(c.Request.Context(), page, pageSize, status, search)
if err != nil {
response.ServerError(c, err.Error())
return
}
response.OK(c, gin.H{
"list": tokens,
"total": total,
"page": page,
"page_size": pageSize,
})
}
type correctUIDReq struct {
ExpectedUID string `json:"expected_uid"`
}
// CorrectTokenUID 修改绑定错误订单上买家填写的 UID,不释放提货号。
func (h *RockHandler) CorrectTokenUID(c *gin.Context) {
idUint, err := strconv.ParseUint(c.Param("id"), 10, 64)
if err != nil {
response.BadRequest(c, "无效的 Token ID")
return
}
var req correctUIDReq
if err := c.ShouldBindJSON(&req); err != nil {
response.BadRequest(c, "参数解析失败")
return
}
token, err := h.rockSvc.CorrectMismatchExpectedUID(c.Request.Context(), uint(idUint), req.ExpectedUID)
if err != nil {
response.BadRequest(c, err.Error())
return
}
message := "已更新买家 UID,提货号仍属于原订单"
if token.Status == "bound" {
message = "已改成扫码 UID,绑定阻断已解除,提货号仍属于原订单"
}
response.OK(c, gin.H{
"message": message,
"status": token.Status,
"token": token,
})
}
// ResetToken 客服人工重置 mismatch 状态的 Token
func (h *RockHandler) ResetToken(c *gin.Context) {
idUint, err := strconv.ParseUint(c.Param("id"), 10, 64)
if err != nil {
response.BadRequest(c, "无效的 Token ID")
return
}
if err := h.rockSvc.ResetMismatchToken(c.Request.Context(), uint(idUint)); err != nil {
response.BadRequest(c, err.Error())
return
}
response.OK(c, gin.H{"message": "重置成功,Token 已重新释放至可用库存"})
}
// ReleaseToken 把尚未扫码绑定的使用中链接释放回可用库存
func (h *RockHandler) ReleaseToken(c *gin.Context) {
idUint, err := strconv.ParseUint(c.Param("id"), 10, 64)
if err != nil {
response.BadRequest(c, "无效的 Token ID")
return
}
if err := h.rockSvc.ReleaseUnboundUsingToken(c.Request.Context(), uint(idUint)); err != nil {
response.BadRequest(c, err.Error())
return
}
response.OK(c, gin.H{"message": "已释放回可用库存,该提货链接可以再次分配"})
}
// RefreshBinding 人工刷新指定 Token 的上游绑定状态
func (h *RockHandler) RefreshBinding(c *gin.Context) {
idUint, err := strconv.ParseUint(c.Param("id"), 10, 64)
if err != nil {
response.BadRequest(c, "无效的 Token ID")
return
}
result, err := h.rockSvc.RefreshTokenBinding(c.Request.Context(), uint(idUint))
if err != nil {
response.BadRequest(c, err.Error())
return
}
response.OK(c, result)
}
// TokenPackageLink 返回 Token 所属上游包页面的定位链接
func (h *RockHandler) TokenPackageLink(c *gin.Context) {
idUint, err := strconv.ParseUint(c.Param("id"), 10, 64)
if err != nil {
response.BadRequest(c, "无效的 Token ID")
return
}
result, err := h.rockSvc.TokenPackageLink(c.Request.Context(), uint(idUint))
if err != nil {
response.BadRequest(c, err.Error())
return
}
response.OK(c, result)
}
type updateRemarkReq struct {
Remark string `json:"remark"`
Status string `json:"status"` // 可选:比如 abnormal
}
// UpdateRemark 更新 Token 备注并可联动更新状态
func (h *RockHandler) UpdateRemark(c *gin.Context) {
idUint, err := strconv.ParseUint(c.Param("id"), 10, 64)
if err != nil {
response.BadRequest(c, "无效的 Token ID")
return
}
var req updateRemarkReq
if err := c.ShouldBindJSON(&req); err != nil {
response.BadRequest(c, "参数解析失败")
return
}
token, err := h.rockSvc.UpdateTokenRemark(c.Request.Context(), uint(idUint), req.Remark, req.Status)
if err != nil {
response.BadRequest(c, err.Error())
return
}
response.OK(c, gin.H{
"message": "备注更新成功",
"token": token,
})
}
type markAbnormalReq struct {
Remark string `json:"remark"`
}
// MarkAbnormal 快捷标记为上报失效(作废,不可再用)
func (h *RockHandler) MarkAbnormal(c *gin.Context) {
idUint, err := strconv.ParseUint(c.Param("id"), 10, 64)
if err != nil {
response.BadRequest(c, "无效的 Token ID")
return
}
var req markAbnormalReq
_ = c.ShouldBindJSON(&req)
token, err := h.rockSvc.MarkTokenAbnormal(c.Request.Context(), uint(idUint), req.Remark)
if err != nil {
response.BadRequest(c, err.Error())
return
}
response.OK(c, gin.H{
"message": "已标记为上报失效,该提货链接已作废",
"token": token,
})
}