package logic4exchange import ( "asset_assistant/db" "net/http" "time" "github.com/gin-gonic/gin" "github.com/google/uuid" "go.uber.org/zap" ) // CreateRequest 注册请求参数结构 // 新增short_name字段,保持必填性与其他核心字段一致 type CreateRequest struct { Name string `json:"name" binding:"required"` // 交易所名称,必填 Code string `json:"code" binding:"required"` // 交易所代码,必填 ShortName string `json:"short_name" binding:"required"` // 交易所短名称,必填 } // CreateResponse 注册响应结构 type CreateResponse struct { Success bool `json:"success"` Message string `json:"message"` Data CreateData `json:"data"` } // CreateData 响应数据结构 type CreateData struct { ExchangeID string `json:"exchange_id"` } // CreateHandler 处理创建逻辑 func CreateHandler(c *gin.Context) { startTime := time.Now() reqID := c.Request.Header.Get("X-RegisterRequest-ID") if reqID == "" { reqID = uuid.New().String() zap.L().Debug("✨ 生成新的请求ID", zap.String("req_id", reqID)) } zap.L().Info("📥 收到交易所创建请求", zap.String("req_id", reqID), zap.String("path", c.Request.URL.Path), zap.String("method", c.Request.Method), ) var req CreateRequest // 绑定参数时会自动验证name、code、short_name三个必填字段 if err := c.ShouldBindJSON(&req); err != nil { zap.L().Warn("⚠️ 请求参数验证失败", zap.String("req_id", reqID), zap.Error(err), zap.Any("request_body", c.Request.Body), ) c.JSON(http.StatusBadRequest, CreateResponse{ Success: false, Message: "请求参数错误:name、code和short_name为必填项", }) return } zap.L().Debug("✅ 请求参数验证通过", zap.String("req_id", reqID), zap.String("name", req.Name), zap.String("code", req.Code), zap.String("short_name", req.ShortName), // 新增短名称日志 ) tx, err := db.DB.Begin() if err != nil { zap.L().Error("❌ 事务开启失败", zap.String("req_id", reqID), zap.Error(err), ) c.JSON(http.StatusInternalServerError, CreateResponse{ Success: false, Message: "系统错误,请稍后重试", }) return } defer func() { if r := recover(); r != nil { if err := tx.Rollback(); err != nil { zap.L().Error("💥 panic后事务回滚失败", zap.String("req_id", reqID), zap.Error(err), ) } zap.L().Error("💥 事务处理发生panic", zap.String("req_id", reqID), zap.Any("recover", r), ) c.JSON(http.StatusInternalServerError, CreateResponse{ Success: false, Message: "系统错误,请稍后重试", }) } }() // 1. 创建exchange主记录 var exchangeID string err = tx.QueryRow("INSERT INTO exchange DEFAULT VALUES RETURNING id").Scan(&exchangeID) if err != nil { tx.Rollback() zap.L().Error("❌ exchange表插入失败", zap.String("req_id", reqID), zap.Error(err), ) c.JSON(http.StatusInternalServerError, CreateResponse{ Success: false, Message: "创建交易所记录失败", }) return } zap.L().Debug("📝 exchange表插入成功", zap.String("req_id", reqID), zap.String("exchange_id", exchangeID), ) // 2. 插入名称信息 _, err = tx.Exec("INSERT INTO exchange_name (exchange_id, name) VALUES ($1, $2)", exchangeID, req.Name) if err != nil { tx.Rollback() zap.L().Error("❌ exchange_name表插入失败", zap.String("req_id", reqID), zap.String("exchange_id", exchangeID), zap.Error(err), ) c.JSON(http.StatusInternalServerError, CreateResponse{ Success: false, Message: "保存名称信息失败", }) return } // 3. 新增:插入短名称信息(对应exchange_short_name表) _, err = tx.Exec("INSERT INTO exchange_short_name (exchange_id, short_name) VALUES ($1, $2)", exchangeID, req.ShortName) if err != nil { tx.Rollback() zap.L().Error("❌ exchange_short_name表插入失败", zap.String("req_id", reqID), zap.String("exchange_id", exchangeID), zap.Error(err), ) c.JSON(http.StatusInternalServerError, CreateResponse{ Success: false, Message: "保存短名称信息失败", }) return } // 4. 插入代码信息 _, err = tx.Exec("INSERT INTO exchange_code (exchange_id, code) VALUES ($1, $2)", exchangeID, req.Code) if err != nil { tx.Rollback() zap.L().Error("❌ exchange_code表插入失败", zap.String("req_id", reqID), zap.String("exchange_id", exchangeID), zap.Error(err), ) c.JSON(http.StatusInternalServerError, CreateResponse{ Success: false, Message: "保存代码信息失败", }) return } // 提交事务 if err := tx.Commit(); err != nil { tx.Rollback() zap.L().Error("❌ 事务提交失败", zap.String("req_id", reqID), zap.String("exchange_id", exchangeID), zap.Error(err), ) c.JSON(http.StatusInternalServerError, CreateResponse{ Success: false, Message: "数据提交失败,请稍后重试", }) return } duration := time.Since(startTime) zap.L().Info("✅ 交易所创建请求处理完成", zap.String("req_id", reqID), zap.String("exchange_id", exchangeID), zap.Duration("duration", duration), ) c.JSON(http.StatusOK, CreateResponse{ Success: true, Message: "创建成功", Data: CreateData{ ExchangeID: exchangeID, }, }) }