This commit is contained in:
vipg
2025-12-22 17:45:23 +08:00
parent 7715886da3
commit 6a74bfdcd4
2 changed files with 19 additions and 10 deletions

View File

@@ -3,10 +3,8 @@
-- =========================================================
\pset pager off
\timing on
-- 切换到目标数据库
\c postgres;
-- 1 保证扩展存在(重复执行无害)
CREATE EXTENSION IF NOT EXISTS "moddatetime" SCHEMA public;
DO $$
@@ -14,7 +12,6 @@ BEGIN
RAISE NOTICE '🚀============ cn_futures_trading_records 部署开始 ============🚀';
END $$;
-- 2 建表(幂等)
DO $$
BEGIN
IF NOT EXISTS (

View File

@@ -7,8 +7,8 @@ import (
"encoding/json"
"fmt"
"net/http"
"reflect"
"strconv"
"strings"
"time"
"github.com/gin-gonic/gin"
@@ -17,7 +17,7 @@ import (
"go.uber.org/zap"
)
/* ---------- 公共 Payload 结构体 ---------- */
/* ---------- 公共 Payload ---------- */
type Payload struct {
Status int `csv:"status" json:"status" binding:"required,min=-1,max=1"`
OpenYear int `csv:"open_year" json:"open_year" binding:"required,min=1900,max=2200"`
@@ -38,7 +38,19 @@ type Payload struct {
TickPrice float64 `csv:"tick_price" json:"tick_price" binding:"required"`
DiffPnL float64 `csv:"diff_pnl" json:"diff_pnl" binding:"required"`
TotalFee float64 `csv:"total_fee" json:"total_fee" binding:"required,min=0"`
ClosePnL float64 `csv:"close_pnl" json:"close_pnl" binding:"required"` // 客户端算好
ClosePnL float64 `csv:"close_pnl" json:"close_pnl" binding:"required"`
}
/* ---------- 包级常量:带 csv 标签的字段个数 ---------- */
var payloadCSVCols int
func init() {
typ := reflect.TypeOf(Payload{})
for i := 0; i < typ.NumField(); i++ {
if _, ok := typ.Field(i).Tag.Lookup("csv"); ok {
payloadCSVCols++
}
}
}
/* ---------- 单条创建 ---------- */
@@ -180,14 +192,14 @@ func CreateBatchHandler(c *gin.Context) {
var recordIDs []string
for idx, row := range req.Rows {
if len(row) != 19 { // 19 列(含 ClosePnL
if len(row) != payloadCSVCols { // ✅ 自动随结构体同步
tx.Rollback()
zap.L().Warn("⚠️ 字段数量不匹配", zap.String("req_id", reqID), zap.Int("row_index", idx), zap.Int("field_count", len(row)))
c.JSON(http.StatusOK, TradingRecordsBatchCreateResponse{Success: false, Message: "第 " + strconv.Itoa(idx+1) + " 行字段数量不足 19 个"})
zap.L().Warn("⚠️ 字段数量不匹配", zap.String("req_id", reqID), zap.Int("row_index", idx), zap.Int("field_count", len(row)), zap.Int("expected", payloadCSVCols))
c.JSON(http.StatusOK, TradingRecordsBatchCreateResponse{Success: false, Message: "第 " + strconv.Itoa(idx+1) + " 行字段数量不足 " + strconv.Itoa(payloadCSVCols) + " 个"})
return
}
// 用 gocsv 一次性映射
// 一次性映射
var p Payload
if err := gocsv.UnmarshalCSV(csv.NewReader(bytes.NewReader([]byte(strings.Join(row, ",")+"\n"))), &p); err != nil {
tx.Rollback()