package logic4country import ( "asset_assistant/db" "net/http" "strconv" "strings" "time" "fmt" "github.com/gin-gonic/gin" "github.com/google/uuid" "go.uber.org/zap" ) // ReadRequest 读取请求参数结构 type ReadRequest struct { CountryID string `form:"country_id"` // 国家ID,可选 Name string `form:"name"` // 国家名称,可选 Code string `form:"code"` // 国家代码,可选 Page string `form:"page"` // 页码,可选 PageSize string `form:"page_size"` // 每页条数,可选 } // ReadData 读取响应数据结构 type ReadData struct { Total int64 `json:"total"` // 总条数 Page int `json:"page"` // 当前页码 PageSize int `json:"page_size"` // 每页条数 Items []CountryInfoViewItem `json:"items"` // 数据列表 } // CountryInfoViewItem 视图数据项结构 type CountryInfoViewItem struct { CountryID string `json:"country_id"` // 国家ID Name string `json:"name"` // 国家名称 Code string `json:"code"` // 国家代码 } // ReadResponse 读取响应结构 type ReadResponse struct { Success bool `json:"success"` // 操作是否成功 Message string `json:"message"` // 提示信息 Data ReadData `json:"data"` // 响应数据 } // ReadHandler 处理国家信息查询逻辑 func ReadHandler(c *gin.Context) { startTime := time.Now() // 获取或生成请求ID reqID := c.Request.Header.Get("X-ReadRequest-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 ReadRequest if err := c.ShouldBindQuery(&req); err != nil { zap.L().Warn("⚠️ 请求参数解析失败", zap.String("req_id", reqID), zap.Error(err), ) c.JSON(http.StatusBadRequest, ReadResponse{ Success: false, Message: "请求参数格式错误", }) return } // 处理分页参数默认值 page, err := strconv.Atoi(req.Page) if err != nil || page < 1 { page = 1 } pageSize, err := strconv.Atoi(req.PageSize) if err != nil || pageSize < 1 { pageSize = 20 } zap.L().Debug("✅ 请求参数验证通过", zap.String("req_id", reqID), zap.String("country_id", req.CountryID), zap.String("name", req.Name), zap.String("code", req.Code), zap.Int("page", page), zap.Int("page_size", pageSize), ) // 构建查询条件和参数 whereClauses := []string{} args := []interface{}{} paramIndex := 1 if req.CountryID != "" { whereClauses = append(whereClauses, "country_id = $"+strconv.Itoa(paramIndex)) args = append(args, req.CountryID) paramIndex++ } if req.Name != "" { whereClauses = append(whereClauses, "name LIKE $"+strconv.Itoa(paramIndex)) args = append(args, "%"+req.Name+"%") paramIndex++ } if req.Code != "" { whereClauses = append(whereClauses, "code LIKE $"+strconv.Itoa(paramIndex)) args = append(args, "%"+req.Code+"%") paramIndex++ } // 构建基础SQL baseSQL := "SELECT country_id, name, code FROM country_info_view" countSQL := "SELECT COUNT(*) FROM country_info_view" if len(whereClauses) > 0 { whereStr := " WHERE " + strings.Join(whereClauses, " AND ") baseSQL += whereStr countSQL += whereStr } // 计算分页偏移量 offset := (page - 1) * pageSize // 拼接分页SQL(使用fmt.Sprintf更清晰) querySQL := fmt.Sprintf("%s ORDER BY country_id LIMIT $%d OFFSET $%d", baseSQL, paramIndex, paramIndex+1) args = append(args, pageSize, offset) // 查询总条数(修正参数传递方式) var total int64 countArgs := args[:len(args)-2] // 排除分页参数 err = db.DB.QueryRow(countSQL, countArgs...).Scan(&total) if err != nil { zap.L().Error("❌ 查询总条数失败", zap.String("req_id", reqID), zap.Error(err), ) c.JSON(http.StatusInternalServerError, ReadResponse{ Success: false, Message: "查询数据失败,请稍后重试", }) return } // 执行分页查询 rows, err := db.DB.Query(querySQL, args...) if err != nil { zap.L().Error("❌ 分页查询失败", zap.String("req_id", reqID), zap.Error(err), ) c.JSON(http.StatusInternalServerError, ReadResponse{ Success: false, Message: "查询数据失败,请稍后重试", }) return } defer rows.Close() // 处理查询结果 var items []CountryInfoViewItem for rows.Next() { var item CountryInfoViewItem if err := rows.Scan(&item.CountryID, &item.Name, &item.Code); err != nil { zap.L().Error("❌ 解析查询结果失败", zap.String("req_id", reqID), zap.Error(err), ) c.JSON(http.StatusInternalServerError, ReadResponse{ Success: false, Message: "数据处理失败,请稍后重试", }) return } items = append(items, item) } // 检查行迭代过程中是否发生错误 if err := rows.Err(); err != nil { zap.L().Error("❌ 行迭代错误", zap.String("req_id", reqID), zap.Error(err), ) c.JSON(http.StatusInternalServerError, ReadResponse{ Success: false, Message: "查询数据失败,请稍后重试", }) return } // 记录请求处理耗时 duration := time.Since(startTime) zap.L().Info("✅ 国家查询请求处理完成", zap.String("req_id", reqID), zap.Int64("total", total), zap.Int("page", page), zap.Int("page_size", pageSize), zap.Duration("duration", duration), ) // 返回成功响应 c.JSON(http.StatusOK, ReadResponse{ Success: true, Message: "查询成功", Data: ReadData{ Total: total, Page: page, PageSize: pageSize, Items: items, }, }) }