项目结构更新
This commit is contained in:
77
controllers/kills/kill.go
Normal file
77
controllers/kills/kill.go
Normal file
@@ -0,0 +1,77 @@
|
||||
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消息(关键:发送失败需回滚Redis)
|
||||
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": "库存扣减成功"})
|
||||
}
|
||||
@@ -4,12 +4,12 @@ import (
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"toutoukan/init/redisInit"
|
||||
"toutoukan/utill"
|
||||
"toutoukan/utill/jwt"
|
||||
)
|
||||
|
||||
// 登出功能(从Redis删除令牌)
|
||||
func LogoutHandler(c *gin.Context) {
|
||||
tokenString := utill.ExtractTokenFromHeader(c)
|
||||
tokenString := jwt.ExtractTokenFromHeader(c)
|
||||
if tokenString == "" {
|
||||
c.JSON(400, gin.H{"error": "令牌不存在", "code": "10038"})
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user