Files
2025-09-15 22:08:11 +08:00

78 lines
2.3 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package kills
import (
"context"
"encoding/base64"
"fmt"
"github.com/gin-gonic/gin"
"log"
"math/rand"
"net/http"
"time"
"toutoukan/init/redisInit"
"toutoukan/model/usermodel/userOrder"
"toutoukan/services/order/killOrder/orderMq/mqproducer"
"toutoukan/utill/luaScripts"
)
func GenerateOrderID() string {
timestamp := time.Now().Format("20060102150405")
randomBytes := make([]byte, 8)
_, err := rand.Read(randomBytes)
if err != nil {
return fmt.Sprintf("ORD%s%011d", timestamp, time.Now().UnixNano()%100000000000)
}
randomStr := base64.URLEncoding.EncodeToString(randomBytes)[:11]
return fmt.Sprintf("ORD%s%s", timestamp, randomStr)
}
func Userkill(c *gin.Context) {
var req userOrder.UserRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "请求参数错误", "detail": err.Error()})
return
}
fmt.Printf("用户%d请求购买%s", req.UserID, req.Order)
OrderID := GenerateOrderID()
// 1. Redis扣减库存不变
result, err := redisInit.RedisClient.Eval(context.Background(), luaScripts.Luascript_forkill, []string{req.Order, "mayiming"}, 1, OrderID).Int()
if err != nil {
log.Printf("Redis 脚本执行错误: %v", err)
c.JSON(500, gin.H{"error": "库存操作失败", "detail": err.Error()})
return
}
if result != 1 {
c.JSON(200, gin.H{"result": "库存不足,扣减失败"})
return
}
// 2. 发送MQ消息
msgSent := false
defer func() {
// 若消息未发送成功回滚Redis库存
if !msgSent {
log.Printf("消息发送失败回滚Redis库存商品: %s用户: %d", req.Order, req.UserID)
// 回滚Redis库存+1同时移除可能的订单记录根据Lua脚本逻辑调整
redisInit.RedisClient.Incr(context.Background(), req.Order)
// 若Lua脚本中记录了订单ID如存到set中也需删除
//redisInit.RedisClient.SRem(context.Background(), req.Order, OrderID)
}
}()
// 发送消息(同步发送,确保拿到发送结果)
sendErr := mqproducer.SendNormalMessage(OrderID, req.Order, req.UserID)
if sendErr != nil {
log.Printf("MQ消息发送失败: %v", sendErr)
c.JSON(500, gin.H{"error": "消息发送失败", "detail": sendErr.Error()})
return
}
// 消息发送成功标记为已发送避免defer回滚
msgSent = true
c.JSON(200, gin.H{"result": "库存扣减成功"})
}