This commit is contained in:
vipg
2025-11-17 18:14:31 +08:00
parent bcd87c3b73
commit fde1929b2c
4 changed files with 52 additions and 52 deletions

View File

@@ -13,8 +13,8 @@ import (
// CreateRequest 注册请求参数结构 // CreateRequest 注册请求参数结构
// 用于接收客户端发送的JSON数据绑定并验证必填字段 // 用于接收客户端发送的JSON数据绑定并验证必填字段
type CreateRequest struct { type CreateRequest struct {
Name string `json:"name" binding:"required"` // 国家名称,必填 Name string `json:"name" binding:"required"` // 货币名称,必填
Code string `json:"code" binding:"required"` // 国家代码,必填 Code string `json:"code" binding:"required"` // 货币代码,必填
} }
// CreateResponse 注册响应结构 // CreateResponse 注册响应结构
@@ -26,12 +26,12 @@ type CreateResponse struct {
} }
// CreateData 响应数据结构 // CreateData 响应数据结构
// 包含创建成功后的国家ID // 包含创建成功后的货币ID
type CreateData struct { type CreateData struct {
CountryID string `json:"currency_id"` // 国家唯一标识ID CurrencyID string `json:"currency_id"` // 货币唯一标识ID
} }
// CreateHandler 处理国家创建逻辑 // CreateHandler 处理货币创建逻辑
// 接收HTTP请求完成参数验证、数据库事务处理并返回响应 // 接收HTTP请求完成参数验证、数据库事务处理并返回响应
func CreateHandler(c *gin.Context) { func CreateHandler(c *gin.Context) {
startTime := time.Now() // 记录请求开始时间,用于统计耗时 startTime := time.Now() // 记录请求开始时间,用于统计耗时
@@ -43,7 +43,7 @@ func CreateHandler(c *gin.Context) {
} }
// 记录请求接收日志,包含关键追踪信息 // 记录请求接收日志,包含关键追踪信息
zap.L().Info("📥 收到国家创建请求", zap.L().Info("📥 收到货币创建请求",
zap.String("req_id", reqID), zap.String("req_id", reqID),
zap.String("path", c.Request.URL.Path), zap.String("path", c.Request.URL.Path),
zap.String("method", c.Request.Method), zap.String("method", c.Request.Method),
@@ -118,7 +118,7 @@ func CreateHandler(c *gin.Context) {
) )
c.JSON(http.StatusInternalServerError, CreateResponse{ c.JSON(http.StatusInternalServerError, CreateResponse{
Success: false, Success: false,
Message: "创建国家记录失败", Message: "创建货币记录失败",
}) })
return return
} }
@@ -128,7 +128,7 @@ func CreateHandler(c *gin.Context) {
zap.String("currency_id", currencyID), zap.String("currency_id", currencyID),
) )
// 2. 插入国家名称到name表与currency_id关联 // 2. 插入货币名称到name表与currency_id关联
_, err = tx.Exec("INSERT INTO currency_name (currency_id, name) VALUES ($1, $2)", currencyID, req.Name) _, err = tx.Exec("INSERT INTO currency_name (currency_id, name) VALUES ($1, $2)", currencyID, req.Name)
if err != nil { if err != nil {
tx.Rollback() // 操作失败,回滚事务 tx.Rollback() // 操作失败,回滚事务
@@ -144,7 +144,7 @@ func CreateHandler(c *gin.Context) {
return return
} }
// 3. 插入国家代码到code表与currency_id关联 // 3. 插入货币代码到code表与currency_id关联
_, err = tx.Exec("INSERT INTO currency_code (currency_id, code) VALUES ($1, $2)", currencyID, req.Code) _, err = tx.Exec("INSERT INTO currency_code (currency_id, code) VALUES ($1, $2)", currencyID, req.Code)
if err != nil { if err != nil {
tx.Rollback() // 操作失败,回滚事务 tx.Rollback() // 操作失败,回滚事务
@@ -177,18 +177,18 @@ func CreateHandler(c *gin.Context) {
// 记录请求处理耗时 // 记录请求处理耗时
duration := time.Since(startTime) duration := time.Since(startTime)
zap.L().Info("✅ 国家创建请求处理完成", zap.L().Info("✅ 货币创建请求处理完成",
zap.String("req_id", reqID), zap.String("req_id", reqID),
zap.String("currency_id", currencyID), zap.String("currency_id", currencyID),
zap.Duration("duration", duration), zap.Duration("duration", duration),
) )
// 返回成功响应,包含创建的国家ID // 返回成功响应,包含创建的货币ID
c.JSON(http.StatusOK, CreateResponse{ c.JSON(http.StatusOK, CreateResponse{
Success: true, Success: true,
Message: "创建成功", Message: "创建成功",
Data: CreateData{ Data: CreateData{
CountryID: currencyID, CurrencyID: currencyID,
}, },
}) })
} }

View File

@@ -12,7 +12,7 @@ import (
// DeleteRequest 删除请求参数结构 // DeleteRequest 删除请求参数结构
type DeleteRequest struct { type DeleteRequest struct {
CountryID string `json:"currency_id" binding:"required"` // 货币ID必填 CurrencyID string `json:"currency_id" binding:"required"` // 货币ID必填
} }
// DeleteResponse 删除响应结构 // DeleteResponse 删除响应结构
@@ -52,7 +52,7 @@ func DeleteHandler(c *gin.Context) {
zap.L().Debug("✅ 请求参数验证通过", zap.L().Debug("✅ 请求参数验证通过",
zap.String("req_id", reqID), zap.String("req_id", reqID),
zap.String("currency_id", req.CountryID), zap.String("currency_id", req.CurrencyID),
) )
// 开启数据库事务 // 开启数据库事务
@@ -90,12 +90,12 @@ func DeleteHandler(c *gin.Context) {
}() }()
// 3.1 更新currency表 // 3.1 更新currency表
_, err = tx.Exec("UPDATE currency SET deleted = TRUE WHERE id = $1", req.CountryID) _, err = tx.Exec("UPDATE currency SET deleted = TRUE WHERE id = $1", req.CurrencyID)
if err != nil { if err != nil {
tx.Rollback() tx.Rollback()
zap.L().Error("❌ currency表更新失败", zap.L().Error("❌ currency表更新失败",
zap.String("req_id", reqID), zap.String("req_id", reqID),
zap.String("currency_id", req.CountryID), zap.String("currency_id", req.CurrencyID),
zap.Error(err), zap.Error(err),
) )
c.JSON(http.StatusInternalServerError, DeleteResponse{ c.JSON(http.StatusInternalServerError, DeleteResponse{
@@ -106,12 +106,12 @@ func DeleteHandler(c *gin.Context) {
} }
// 3.2 更新name表 // 3.2 更新name表
_, err = tx.Exec("UPDATE currency_name SET deleted = TRUE WHERE currency_id = $1", req.CountryID) _, err = tx.Exec("UPDATE currency_name SET deleted = TRUE WHERE currency_id = $1", req.CurrencyID)
if err != nil { if err != nil {
tx.Rollback() tx.Rollback()
zap.L().Error("❌ currency_name表更新失败", zap.L().Error("❌ currency_name表更新失败",
zap.String("req_id", reqID), zap.String("req_id", reqID),
zap.String("currency_id", req.CountryID), zap.String("currency_id", req.CurrencyID),
zap.Error(err), zap.Error(err),
) )
c.JSON(http.StatusInternalServerError, DeleteResponse{ c.JSON(http.StatusInternalServerError, DeleteResponse{
@@ -122,12 +122,12 @@ func DeleteHandler(c *gin.Context) {
} }
// 3.3 更新code表 // 3.3 更新code表
_, err = tx.Exec("UPDATE currency_code SET deleted = TRUE WHERE currency_id = $1", req.CountryID) _, err = tx.Exec("UPDATE currency_code SET deleted = TRUE WHERE currency_id = $1", req.CurrencyID)
if err != nil { if err != nil {
tx.Rollback() tx.Rollback()
zap.L().Error("❌ currency_code表更新失败", zap.L().Error("❌ currency_code表更新失败",
zap.String("req_id", reqID), zap.String("req_id", reqID),
zap.String("currency_id", req.CountryID), zap.String("currency_id", req.CurrencyID),
zap.Error(err), zap.Error(err),
) )
c.JSON(http.StatusInternalServerError, DeleteResponse{ c.JSON(http.StatusInternalServerError, DeleteResponse{
@@ -142,7 +142,7 @@ func DeleteHandler(c *gin.Context) {
tx.Rollback() tx.Rollback()
zap.L().Error("❌ 事务提交失败", zap.L().Error("❌ 事务提交失败",
zap.String("req_id", reqID), zap.String("req_id", reqID),
zap.String("currency_id", req.CountryID), zap.String("currency_id", req.CurrencyID),
zap.Error(err), zap.Error(err),
) )
c.JSON(http.StatusInternalServerError, DeleteResponse{ c.JSON(http.StatusInternalServerError, DeleteResponse{
@@ -156,7 +156,7 @@ func DeleteHandler(c *gin.Context) {
duration := time.Since(startTime) duration := time.Since(startTime)
zap.L().Info("✅ 货币删除请求处理完成", zap.L().Info("✅ 货币删除请求处理完成",
zap.String("req_id", reqID), zap.String("req_id", reqID),
zap.String("currency_id", req.CountryID), zap.String("currency_id", req.CurrencyID),
zap.Duration("duration", duration), zap.Duration("duration", duration),
) )

View File

@@ -16,9 +16,9 @@ import (
// ReadRequest 读取请求参数结构 // ReadRequest 读取请求参数结构
type ReadRequest struct { type ReadRequest struct {
CountryID string `form:"currency_id"` // 国家ID可选 CurrencyID string `form:"currency_id"` // 货币ID可选
Name string `form:"name"` // 国家名称,可选 Name string `form:"name"` // 货币名称,可选
Code string `form:"code"` // 国家代码,可选 Code string `form:"code"` // 货币代码,可选
Page string `form:"page"` // 页码,可选 Page string `form:"page"` // 页码,可选
PageSize string `form:"page_size"` // 每页条数,可选 PageSize string `form:"page_size"` // 每页条数,可选
} }
@@ -28,14 +28,14 @@ type ReadData struct {
Total int64 `json:"total"` // 总条数 Total int64 `json:"total"` // 总条数
Page int `json:"page"` // 当前页码 Page int `json:"page"` // 当前页码
PageSize int `json:"page_size"` // 每页条数 PageSize int `json:"page_size"` // 每页条数
Items []CountryInfoViewItem `json:"items"` // 数据列表 Items []CurrencyInfoViewItem `json:"items"` // 数据列表
} }
// CountryInfoViewItem 视图数据项结构 // CurrencyInfoViewItem 视图数据项结构
type CountryInfoViewItem struct { type CurrencyInfoViewItem struct {
CountryID string `json:"currency_id"` // 国家ID CurrencyID string `json:"currency_id"` // 货币ID
Name string `json:"name"` // 国家名称 Name string `json:"name"` // 货币名称
Code string `json:"code"` // 国家代码 Code string `json:"code"` // 货币代码
} }
// ReadResponse 读取响应结构 // ReadResponse 读取响应结构
@@ -45,7 +45,7 @@ type ReadResponse struct {
Data ReadData `json:"data"` // 响应数据 Data ReadData `json:"data"` // 响应数据
} }
// ReadHandler 处理国家信息查询逻辑 // ReadHandler 处理货币信息查询逻辑
func ReadHandler(c *gin.Context) { func ReadHandler(c *gin.Context) {
startTime := time.Now() startTime := time.Now()
// 获取或生成请求ID // 获取或生成请求ID
@@ -56,7 +56,7 @@ func ReadHandler(c *gin.Context) {
} }
// 记录请求接收日志 // 记录请求接收日志
zap.L().Info("📥 收到国家查询请求", zap.L().Info("📥 收到货币查询请求",
zap.String("req_id", reqID), zap.String("req_id", reqID),
zap.String("path", c.Request.URL.Path), zap.String("path", c.Request.URL.Path),
zap.String("method", c.Request.Method), zap.String("method", c.Request.Method),
@@ -77,7 +77,7 @@ func ReadHandler(c *gin.Context) {
} }
// 验证查询条件至少有一个不为空 // 验证查询条件至少有一个不为空
if req.CountryID == "" && req.Name == "" && req.Code == "" { if req.CurrencyID == "" && req.Name == "" && req.Code == "" {
zap.L().Warn("⚠️ 请求参数验证失败", zap.L().Warn("⚠️ 请求参数验证失败",
zap.String("req_id", reqID), zap.String("req_id", reqID),
zap.String("reason", "currency_id、name、code不能同时为空"), zap.String("reason", "currency_id、name、code不能同时为空"),
@@ -101,7 +101,7 @@ func ReadHandler(c *gin.Context) {
zap.L().Debug("✅ 请求参数验证通过", zap.L().Debug("✅ 请求参数验证通过",
zap.String("req_id", reqID), zap.String("req_id", reqID),
zap.String("currency_id", req.CountryID), zap.String("currency_id", req.CurrencyID),
zap.String("name", req.Name), zap.String("name", req.Name),
zap.String("code", req.Code), zap.String("code", req.Code),
zap.Int("page", page), zap.Int("page", page),
@@ -113,9 +113,9 @@ func ReadHandler(c *gin.Context) {
args := []interface{}{} args := []interface{}{}
paramIndex := 1 paramIndex := 1
if req.CountryID != "" { if req.CurrencyID != "" {
whereClauses = append(whereClauses, "currency_id = $"+strconv.Itoa(paramIndex)) whereClauses = append(whereClauses, "currency_id = $"+strconv.Itoa(paramIndex))
args = append(args, req.CountryID) args = append(args, req.CurrencyID)
paramIndex++ paramIndex++
} }
if req.Name != "" { if req.Name != "" {
@@ -177,10 +177,10 @@ func ReadHandler(c *gin.Context) {
defer rows.Close() defer rows.Close()
// 处理查询结果 // 处理查询结果
var items []CountryInfoViewItem var items []CurrencyInfoViewItem
for rows.Next() { for rows.Next() {
var item CountryInfoViewItem var item CurrencyInfoViewItem
if err := rows.Scan(&item.CountryID, &item.Name, &item.Code); err != nil { if err := rows.Scan(&item.CurrencyID, &item.Name, &item.Code); err != nil {
zap.L().Error("❌ 解析查询结果失败", zap.L().Error("❌ 解析查询结果失败",
zap.String("req_id", reqID), zap.String("req_id", reqID),
zap.Error(err), zap.Error(err),
@@ -209,7 +209,7 @@ func ReadHandler(c *gin.Context) {
// 记录请求处理耗时 // 记录请求处理耗时
duration := time.Since(startTime) duration := time.Since(startTime)
zap.L().Info("✅ 国家查询请求处理完成", zap.L().Info("✅ 货币查询请求处理完成",
zap.String("req_id", reqID), zap.String("req_id", reqID),
zap.Int64("total", total), zap.Int64("total", total),
zap.Int("page", page), zap.Int("page", page),

View File

@@ -12,7 +12,7 @@ import (
// UpdateRequest 更新请求参数结构 // UpdateRequest 更新请求参数结构
type UpdateRequest struct { type UpdateRequest struct {
CountryID string `json:"currency_id" binding:"required"` // 货币ID必填 CurrencyID string `json:"currency_id" binding:"required"` // 货币ID必填
Name string `json:"name"` // 货币名称,可选 Name string `json:"name"` // 货币名称,可选
Code string `json:"code"` // 货币代码,可选 Code string `json:"code"` // 货币代码,可选
} }
@@ -58,7 +58,7 @@ func UpdateHandler(c *gin.Context) {
if req.Name == "" && req.Code == "" { if req.Name == "" && req.Code == "" {
zap.L().Warn("⚠️ 请求参数验证失败", zap.L().Warn("⚠️ 请求参数验证失败",
zap.String("req_id", reqID), zap.String("req_id", reqID),
zap.String("currency_id", req.CountryID), zap.String("currency_id", req.CurrencyID),
zap.String("reason", "name和code不能同时为空"), zap.String("reason", "name和code不能同时为空"),
) )
c.JSON(http.StatusBadRequest, UpdateResponse{ c.JSON(http.StatusBadRequest, UpdateResponse{
@@ -70,7 +70,7 @@ func UpdateHandler(c *gin.Context) {
zap.L().Debug("✅ 请求参数验证通过", zap.L().Debug("✅ 请求参数验证通过",
zap.String("req_id", reqID), zap.String("req_id", reqID),
zap.String("currency_id", req.CountryID), zap.String("currency_id", req.CurrencyID),
zap.String("name", req.Name), zap.String("name", req.Name),
zap.String("code", req.Code), zap.String("code", req.Code),
) )
@@ -111,12 +111,12 @@ func UpdateHandler(c *gin.Context) {
// 如果name不为空更新name表 // 如果name不为空更新name表
if req.Name != "" { if req.Name != "" {
_, err = tx.Exec("UPDATE currency_name SET name = $1 WHERE currency_id = $2", req.Name, req.CountryID) _, err = tx.Exec("UPDATE currency_name SET name = $1 WHERE currency_id = $2", req.Name, req.CurrencyID)
if err != nil { if err != nil {
tx.Rollback() tx.Rollback()
zap.L().Error("❌ currency_name表更新失败", zap.L().Error("❌ currency_name表更新失败",
zap.String("req_id", reqID), zap.String("req_id", reqID),
zap.String("currency_id", req.CountryID), zap.String("currency_id", req.CurrencyID),
zap.Error(err), zap.Error(err),
) )
c.JSON(http.StatusInternalServerError, UpdateResponse{ c.JSON(http.StatusInternalServerError, UpdateResponse{
@@ -127,18 +127,18 @@ func UpdateHandler(c *gin.Context) {
} }
zap.L().Debug("📝 name表更新成功", zap.L().Debug("📝 name表更新成功",
zap.String("req_id", reqID), zap.String("req_id", reqID),
zap.String("currency_id", req.CountryID), zap.String("currency_id", req.CurrencyID),
) )
} }
// 如果code不为空更新code表 // 如果code不为空更新code表
if req.Code != "" { if req.Code != "" {
_, err = tx.Exec("UPDATE currency_code SET code = $1 WHERE currency_id = $2", req.Code, req.CountryID) _, err = tx.Exec("UPDATE currency_code SET code = $1 WHERE currency_id = $2", req.Code, req.CurrencyID)
if err != nil { if err != nil {
tx.Rollback() tx.Rollback()
zap.L().Error("❌ currency_code表更新失败", zap.L().Error("❌ currency_code表更新失败",
zap.String("req_id", reqID), zap.String("req_id", reqID),
zap.String("currency_id", req.CountryID), zap.String("currency_id", req.CurrencyID),
zap.Error(err), zap.Error(err),
) )
c.JSON(http.StatusInternalServerError, UpdateResponse{ c.JSON(http.StatusInternalServerError, UpdateResponse{
@@ -149,7 +149,7 @@ func UpdateHandler(c *gin.Context) {
} }
zap.L().Debug("📝 code表更新成功", zap.L().Debug("📝 code表更新成功",
zap.String("req_id", reqID), zap.String("req_id", reqID),
zap.String("currency_id", req.CountryID), zap.String("currency_id", req.CurrencyID),
) )
} }
@@ -158,7 +158,7 @@ func UpdateHandler(c *gin.Context) {
tx.Rollback() tx.Rollback()
zap.L().Error("❌ 事务提交失败", zap.L().Error("❌ 事务提交失败",
zap.String("req_id", reqID), zap.String("req_id", reqID),
zap.String("currency_id", req.CountryID), zap.String("currency_id", req.CurrencyID),
zap.Error(err), zap.Error(err),
) )
c.JSON(http.StatusInternalServerError, UpdateResponse{ c.JSON(http.StatusInternalServerError, UpdateResponse{
@@ -172,7 +172,7 @@ func UpdateHandler(c *gin.Context) {
duration := time.Since(startTime) duration := time.Since(startTime)
zap.L().Info("✅ 货币更新请求处理完成", zap.L().Info("✅ 货币更新请求处理完成",
zap.String("req_id", reqID), zap.String("req_id", reqID),
zap.String("currency_id", req.CountryID), zap.String("currency_id", req.CurrencyID),
zap.Duration("duration", duration), zap.Duration("duration", duration),
) )