add
This commit is contained in:
@@ -18,7 +18,7 @@ log_error() {
|
|||||||
IMAGE_NAME="futures-trading-record-api"
|
IMAGE_NAME="futures-trading-record-api"
|
||||||
IMAGE_TAG="1.0.0"
|
IMAGE_TAG="1.0.0"
|
||||||
FULL_IMAGE="${IMAGE_NAME}:${IMAGE_TAG}"
|
FULL_IMAGE="${IMAGE_NAME}:${IMAGE_TAG}"
|
||||||
COMPOSE_PROJECT_NAME="country_service"
|
COMPOSE_PROJECT_NAME="futures_trading_record_service"
|
||||||
DOCKER_COMPOSE_FILE="./docker-compose.yaml"
|
DOCKER_COMPOSE_FILE="./docker-compose.yaml"
|
||||||
SRC_DIR="./src"
|
SRC_DIR="./src"
|
||||||
DOCKERFILE_PATH="${SRC_DIR}/Dockerfile"
|
DOCKERFILE_PATH="${SRC_DIR}/Dockerfile"
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
docker run -itd --name go_country_dev -v $(pwd)/src:/app -p 20010:80 golang:1.25.0-alpine3.22
|
docker run -itd --name go_futures_trading_record_dev -v $(pwd)/src:/app -p 20010:80 golang:1.25.0-alpine3.22
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
services:
|
services:
|
||||||
postgres:
|
postgres:
|
||||||
image: postgres:17.4-alpine
|
image: postgres:17.4-alpine
|
||||||
container_name: country_db
|
container_name: futures_trading_record_db
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
- 20011:5432
|
- 20011:5432
|
||||||
@@ -13,14 +13,14 @@ services:
|
|||||||
POSTGRES_DB: ${DB_NAME}
|
POSTGRES_DB: ${DB_NAME}
|
||||||
TZ: ${TZ}
|
TZ: ${TZ}
|
||||||
volumes:
|
volumes:
|
||||||
- ./shared_data/country_db:/var/lib/postgresql/data
|
- ./shared_data/futures_trading_record_db:/var/lib/postgresql/data
|
||||||
- ./sql:/docker-entrypoint-initdb.d
|
- ./sql:/docker-entrypoint-initdb.d
|
||||||
- ./scripts:/scripts
|
- ./scripts:/scripts
|
||||||
networks:
|
networks:
|
||||||
- futures-trading-record-network
|
- futures-trading-record-network
|
||||||
country:
|
futures_trading_record:
|
||||||
image: golang:1.25.0-alpine3.22
|
image: golang:1.25.0-alpine3.22
|
||||||
container_name: country_api
|
container_name: futures_trading_record_api
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
- 20010:80
|
- 20010:80
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
services:
|
services:
|
||||||
postgres:
|
postgres:
|
||||||
image: postgres:17.4-alpine
|
image: postgres:17.4-alpine
|
||||||
container_name: country_db
|
container_name: futures_trading_record_db
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
- 20011:5432
|
- 20011:5432
|
||||||
@@ -13,14 +13,14 @@ services:
|
|||||||
POSTGRES_DB: ${DB_NAME}
|
POSTGRES_DB: ${DB_NAME}
|
||||||
TZ: ${TZ}
|
TZ: ${TZ}
|
||||||
volumes:
|
volumes:
|
||||||
- ./shared_data/country_db:/var/lib/postgresql/data
|
- ./shared_data/futures_trading_record_db:/var/lib/postgresql/data
|
||||||
- ./sql:/docker-entrypoint-initdb.d
|
- ./sql:/docker-entrypoint-initdb.d
|
||||||
- ./scripts:/scripts
|
- ./scripts:/scripts
|
||||||
networks:
|
networks:
|
||||||
- futures-trading-record-network
|
- futures-trading-record-network
|
||||||
country:
|
futures_trading_record:
|
||||||
image: futures-trading-record-api:1.0.0
|
image: futures-trading-record-api:1.0.0
|
||||||
container_name: country_api
|
container_name: futures_trading_record_api
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
- 20010:80
|
- 20010:80
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
-- 切换到目标数据库
|
-- 切换到目标数据库
|
||||||
\c postgres;
|
\c postgres;
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION update_country_modified_column()
|
CREATE OR REPLACE FUNCTION update_futures_trading_record_modified_column()
|
||||||
RETURNS TRIGGER AS $$
|
RETURNS TRIGGER AS $$
|
||||||
BEGIN
|
BEGIN
|
||||||
NEW.updated_at = CURRENT_TIMESTAMP;
|
NEW.updated_at = CURRENT_TIMESTAMP;
|
||||||
@@ -11,20 +11,20 @@ $$ LANGUAGE plpgsql VOLATILE;
|
|||||||
|
|
||||||
DO $$
|
DO $$
|
||||||
BEGIN
|
BEGIN
|
||||||
IF NOT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'country') THEN
|
IF NOT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'futures_trading_record') THEN
|
||||||
CREATE TABLE "country" ( -- country是关键字,用双引号包裹
|
CREATE TABLE "futures_trading_record" ( -- futures_trading_record是关键字,用双引号包裹
|
||||||
id UUID DEFAULT gen_random_uuid_v7() PRIMARY KEY NOT NULL,
|
id UUID DEFAULT gen_random_uuid_v7() PRIMARY KEY NOT NULL,
|
||||||
deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||||
);
|
);
|
||||||
CREATE TRIGGER update_country_updated_at
|
CREATE TRIGGER update_futures_trading_record_updated_at
|
||||||
BEFORE UPDATE ON "country"
|
BEFORE UPDATE ON "futures_trading_record"
|
||||||
FOR EACH ROW
|
FOR EACH ROW
|
||||||
EXECUTE FUNCTION update_country_modified_column();
|
EXECUTE FUNCTION update_futures_trading_record_modified_column();
|
||||||
|
|
||||||
RAISE NOTICE 'Created country table and trigger';
|
RAISE NOTICE 'Created futures_trading_record table and trigger';
|
||||||
ELSE
|
ELSE
|
||||||
RAISE NOTICE 'country table already exists';
|
RAISE NOTICE 'futures_trading_record table already exists';
|
||||||
END IF;
|
END IF;
|
||||||
END $$;
|
END $$;
|
||||||
@@ -14,7 +14,7 @@ BEGIN
|
|||||||
IF NOT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'name') THEN
|
IF NOT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'name') THEN
|
||||||
CREATE TABLE name (
|
CREATE TABLE name (
|
||||||
id UUID DEFAULT gen_random_uuid_v7() PRIMARY KEY NOT NULL,
|
id UUID DEFAULT gen_random_uuid_v7() PRIMARY KEY NOT NULL,
|
||||||
country_id UUID NOT NULL,
|
futures_trading_record_id UUID NOT NULL,
|
||||||
name VARCHAR NOT NULL,
|
name VARCHAR NOT NULL,
|
||||||
deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ BEGIN
|
|||||||
IF NOT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'code') THEN
|
IF NOT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'code') THEN
|
||||||
CREATE TABLE code (
|
CREATE TABLE code (
|
||||||
id UUID DEFAULT gen_random_uuid_v7() PRIMARY KEY NOT NULL,
|
id UUID DEFAULT gen_random_uuid_v7() PRIMARY KEY NOT NULL,
|
||||||
country_id UUID NOT NULL,
|
futures_trading_record_id UUID NOT NULL,
|
||||||
code VARCHAR NOT NULL,
|
code VARCHAR NOT NULL,
|
||||||
deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
|||||||
@@ -7,30 +7,30 @@ BEGIN
|
|||||||
-- 检查视图是否已存在
|
-- 检查视图是否已存在
|
||||||
SELECT EXISTS (
|
SELECT EXISTS (
|
||||||
SELECT 1 FROM information_schema.views
|
SELECT 1 FROM information_schema.views
|
||||||
WHERE table_name = 'country_info_view'
|
WHERE table_name = 'futures_trading_record_info_view'
|
||||||
) INTO view_exists;
|
) INTO view_exists;
|
||||||
|
|
||||||
-- 创建或更新视图
|
-- 创建或更新视图
|
||||||
CREATE OR REPLACE VIEW country_info_view AS
|
CREATE OR REPLACE VIEW futures_trading_record_info_view AS
|
||||||
SELECT
|
SELECT
|
||||||
u.id AS country_id,
|
u.id AS futures_trading_record_id,
|
||||||
n.name AS name,
|
n.name AS name,
|
||||||
c.code AS code,
|
c.code AS code,
|
||||||
u.deleted AS deleted
|
u.deleted AS deleted
|
||||||
FROM
|
FROM
|
||||||
"country" u
|
"futures_trading_record" u
|
||||||
JOIN
|
JOIN
|
||||||
name n ON u.id = n.country_id
|
name n ON u.id = n.futures_trading_record_id
|
||||||
JOIN
|
JOIN
|
||||||
code c ON u.id = c.country_id
|
code c ON u.id = c.futures_trading_record_id
|
||||||
WHERE
|
WHERE
|
||||||
u.deleted = FALSE;
|
u.deleted = FALSE;
|
||||||
|
|
||||||
-- 根据视图是否已存在输出不同提示
|
-- 根据视图是否已存在输出不同提示
|
||||||
IF view_exists THEN
|
IF view_exists THEN
|
||||||
RAISE NOTICE '视图 country_info_view 已更新';
|
RAISE NOTICE '视图 futures_trading_record_info_view 已更新';
|
||||||
ELSE
|
ELSE
|
||||||
RAISE NOTICE '视图 country_info_view 已创建';
|
RAISE NOTICE '视图 futures_trading_record_info_view 已创建';
|
||||||
END IF;
|
END IF;
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
WHEN OTHERS THEN
|
WHEN OTHERS THEN
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
module country
|
module futures_trading_record
|
||||||
|
|
||||||
go 1.25.0
|
go 1.25.0
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package logic
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"country/db" // 数据库操作相关包
|
"futures_trading_record/db" // 数据库操作相关包
|
||||||
"time" // 时间处理包
|
"time" // 时间处理包
|
||||||
"github.com/google/uuid" // UUID生成工具
|
"github.com/google/uuid" // UUID生成工具
|
||||||
"github.com/gin-gonic/gin" // Gin框架,用于处理HTTP请求
|
"github.com/gin-gonic/gin" // Gin框架,用于处理HTTP请求
|
||||||
@@ -27,7 +27,7 @@ type CreateResponse struct {
|
|||||||
// CreateData 响应数据结构
|
// CreateData 响应数据结构
|
||||||
// 包含创建成功后的国家ID
|
// 包含创建成功后的国家ID
|
||||||
type CreateData struct {
|
type CreateData struct {
|
||||||
CountryID string `json:"country_id"` // 国家唯一标识ID
|
futures_trading_recordID string `json:"futures_trading_record_id"` // 国家唯一标识ID
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateHandler 处理国家创建逻辑
|
// CreateHandler 处理国家创建逻辑
|
||||||
@@ -106,12 +106,12 @@ func CreateHandler(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// 1. 在country表中创建记录并获取自动生成的ID
|
// 1. 在futures_trading_record表中创建记录并获取自动生成的ID
|
||||||
var countryID string
|
var futures_trading_recordID string
|
||||||
err = tx.QueryRow("INSERT INTO country DEFAULT VALUES RETURNING id").Scan(&countryID)
|
err = tx.QueryRow("INSERT INTO futures_trading_record DEFAULT VALUES RETURNING id").Scan(&futures_trading_recordID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback() // 操作失败,回滚事务
|
tx.Rollback() // 操作失败,回滚事务
|
||||||
zap.L().Error("❌ country表插入失败",
|
zap.L().Error("❌ futures_trading_record表插入失败",
|
||||||
zap.String("req_id", reqID),
|
zap.String("req_id", reqID),
|
||||||
zap.Error(err),
|
zap.Error(err),
|
||||||
)
|
)
|
||||||
@@ -122,18 +122,18 @@ func CreateHandler(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
zap.L().Debug("📝 country表插入成功",
|
zap.L().Debug("📝 futures_trading_record表插入成功",
|
||||||
zap.String("req_id", reqID),
|
zap.String("req_id", reqID),
|
||||||
zap.String("country_id", countryID),
|
zap.String("futures_trading_record_id", futures_trading_recordID),
|
||||||
)
|
)
|
||||||
|
|
||||||
// 2. 插入国家名称到name表(与country_id关联)
|
// 2. 插入国家名称到name表(与futures_trading_record_id关联)
|
||||||
_, err = tx.Exec("INSERT INTO name (country_id, name) VALUES ($1, $2)", countryID, req.Name)
|
_, err = tx.Exec("INSERT INTO name (futures_trading_record_id, name) VALUES ($1, $2)", futures_trading_recordID, req.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback() // 操作失败,回滚事务
|
tx.Rollback() // 操作失败,回滚事务
|
||||||
zap.L().Error("❌ name表插入失败",
|
zap.L().Error("❌ name表插入失败",
|
||||||
zap.String("req_id", reqID),
|
zap.String("req_id", reqID),
|
||||||
zap.String("country_id", countryID),
|
zap.String("futures_trading_record_id", futures_trading_recordID),
|
||||||
zap.Error(err),
|
zap.Error(err),
|
||||||
)
|
)
|
||||||
c.JSON(http.StatusInternalServerError, CreateResponse{
|
c.JSON(http.StatusInternalServerError, CreateResponse{
|
||||||
@@ -143,13 +143,13 @@ func CreateHandler(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 插入国家代码到code表(与country_id关联)
|
// 3. 插入国家代码到code表(与futures_trading_record_id关联)
|
||||||
_, err = tx.Exec("INSERT INTO code (country_id, code) VALUES ($1, $2)", countryID, req.Code)
|
_, err = tx.Exec("INSERT INTO code (futures_trading_record_id, code) VALUES ($1, $2)", futures_trading_recordID, req.Code)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback() // 操作失败,回滚事务
|
tx.Rollback() // 操作失败,回滚事务
|
||||||
zap.L().Error("❌ code表插入失败",
|
zap.L().Error("❌ code表插入失败",
|
||||||
zap.String("req_id", reqID),
|
zap.String("req_id", reqID),
|
||||||
zap.String("country_id", countryID),
|
zap.String("futures_trading_record_id", futures_trading_recordID),
|
||||||
zap.Error(err),
|
zap.Error(err),
|
||||||
)
|
)
|
||||||
c.JSON(http.StatusInternalServerError, CreateResponse{
|
c.JSON(http.StatusInternalServerError, CreateResponse{
|
||||||
@@ -164,7 +164,7 @@ func CreateHandler(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("country_id", countryID),
|
zap.String("futures_trading_record_id", futures_trading_recordID),
|
||||||
zap.Error(err),
|
zap.Error(err),
|
||||||
)
|
)
|
||||||
c.JSON(http.StatusInternalServerError, CreateResponse{
|
c.JSON(http.StatusInternalServerError, CreateResponse{
|
||||||
@@ -178,7 +178,7 @@ 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("country_id", countryID),
|
zap.String("futures_trading_record_id", futures_trading_recordID),
|
||||||
zap.Duration("duration", duration),
|
zap.Duration("duration", duration),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -187,7 +187,7 @@ func CreateHandler(c *gin.Context) {
|
|||||||
Success: true,
|
Success: true,
|
||||||
Message: "创建成功",
|
Message: "创建成功",
|
||||||
Data: CreateData{
|
Data: CreateData{
|
||||||
CountryID: countryID,
|
futures_trading_recordID: futures_trading_recordID,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,7 @@ package logic
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"country/db"
|
"futures_trading_record/db"
|
||||||
"time"
|
"time"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
@@ -11,7 +11,7 @@ import (
|
|||||||
|
|
||||||
// DeleteRequest 删除请求参数结构
|
// DeleteRequest 删除请求参数结构
|
||||||
type DeleteRequest struct {
|
type DeleteRequest struct {
|
||||||
CountryID string `json:"country_id" binding:"required"` // 国家ID,必填
|
futures_trading_recordID string `json:"futures_trading_record_id" binding:"required"` // 国家ID,必填
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteResponse 删除响应结构
|
// DeleteResponse 删除响应结构
|
||||||
@@ -44,14 +44,14 @@ func DeleteHandler(c *gin.Context) {
|
|||||||
)
|
)
|
||||||
c.JSON(http.StatusBadRequest, DeleteResponse{
|
c.JSON(http.StatusBadRequest, DeleteResponse{
|
||||||
Success: false,
|
Success: false,
|
||||||
Message: "请求参数错误:country_id为必填项",
|
Message: "请求参数错误:futures_trading_record_id为必填项",
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
zap.L().Debug("✅ 请求参数验证通过",
|
zap.L().Debug("✅ 请求参数验证通过",
|
||||||
zap.String("req_id", reqID),
|
zap.String("req_id", reqID),
|
||||||
zap.String("country_id", req.CountryID),
|
zap.String("futures_trading_record_id", req.futures_trading_recordID),
|
||||||
)
|
)
|
||||||
|
|
||||||
// 开启数据库事务
|
// 开启数据库事务
|
||||||
@@ -88,13 +88,13 @@ func DeleteHandler(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// 3.1 更新country表
|
// 3.1 更新futures_trading_record表
|
||||||
_, err = tx.Exec("UPDATE country SET deleted = TRUE WHERE id = $1", req.CountryID)
|
_, err = tx.Exec("UPDATE futures_trading_record SET deleted = TRUE WHERE id = $1", req.futures_trading_recordID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
zap.L().Error("❌ country表更新失败",
|
zap.L().Error("❌ futures_trading_record表更新失败",
|
||||||
zap.String("req_id", reqID),
|
zap.String("req_id", reqID),
|
||||||
zap.String("country_id", req.CountryID),
|
zap.String("futures_trading_record_id", req.futures_trading_recordID),
|
||||||
zap.Error(err),
|
zap.Error(err),
|
||||||
)
|
)
|
||||||
c.JSON(http.StatusInternalServerError, DeleteResponse{
|
c.JSON(http.StatusInternalServerError, DeleteResponse{
|
||||||
@@ -105,12 +105,12 @@ func DeleteHandler(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 3.2 更新name表
|
// 3.2 更新name表
|
||||||
_, err = tx.Exec("UPDATE name SET deleted = TRUE WHERE country_id = $1", req.CountryID)
|
_, err = tx.Exec("UPDATE name SET deleted = TRUE WHERE futures_trading_record_id = $1", req.futures_trading_recordID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
zap.L().Error("❌ name表更新失败",
|
zap.L().Error("❌ name表更新失败",
|
||||||
zap.String("req_id", reqID),
|
zap.String("req_id", reqID),
|
||||||
zap.String("country_id", req.CountryID),
|
zap.String("futures_trading_record_id", req.futures_trading_recordID),
|
||||||
zap.Error(err),
|
zap.Error(err),
|
||||||
)
|
)
|
||||||
c.JSON(http.StatusInternalServerError, DeleteResponse{
|
c.JSON(http.StatusInternalServerError, DeleteResponse{
|
||||||
@@ -121,12 +121,12 @@ func DeleteHandler(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 3.3 更新code表
|
// 3.3 更新code表
|
||||||
_, err = tx.Exec("UPDATE code SET deleted = TRUE WHERE country_id = $1", req.CountryID)
|
_, err = tx.Exec("UPDATE code SET deleted = TRUE WHERE futures_trading_record_id = $1", req.futures_trading_recordID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
zap.L().Error("❌ code表更新失败",
|
zap.L().Error("❌ code表更新失败",
|
||||||
zap.String("req_id", reqID),
|
zap.String("req_id", reqID),
|
||||||
zap.String("country_id", req.CountryID),
|
zap.String("futures_trading_record_id", req.futures_trading_recordID),
|
||||||
zap.Error(err),
|
zap.Error(err),
|
||||||
)
|
)
|
||||||
c.JSON(http.StatusInternalServerError, DeleteResponse{
|
c.JSON(http.StatusInternalServerError, DeleteResponse{
|
||||||
@@ -141,7 +141,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("country_id", req.CountryID),
|
zap.String("futures_trading_record_id", req.futures_trading_recordID),
|
||||||
zap.Error(err),
|
zap.Error(err),
|
||||||
)
|
)
|
||||||
c.JSON(http.StatusInternalServerError, DeleteResponse{
|
c.JSON(http.StatusInternalServerError, DeleteResponse{
|
||||||
@@ -155,7 +155,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("country_id", req.CountryID),
|
zap.String("futures_trading_record_id", req.futures_trading_recordID),
|
||||||
zap.Duration("duration", duration),
|
zap.Duration("duration", duration),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package logic
|
package logic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"country/db"
|
"futures_trading_record/db"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
@@ -15,7 +15,7 @@ import (
|
|||||||
|
|
||||||
// ReadRequest 读取请求参数结构
|
// ReadRequest 读取请求参数结构
|
||||||
type ReadRequest struct {
|
type ReadRequest struct {
|
||||||
CountryID string `form:"country_id"` // 国家ID,可选
|
futures_trading_recordID string `form:"futures_trading_record_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"` // 页码,可选
|
||||||
@@ -27,12 +27,12 @@ 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 []futures_trading_recordInfoViewItem `json:"items"` // 数据列表
|
||||||
}
|
}
|
||||||
|
|
||||||
// CountryInfoViewItem 视图数据项结构
|
// futures_trading_recordInfoViewItem 视图数据项结构
|
||||||
type CountryInfoViewItem struct {
|
type futures_trading_recordInfoViewItem struct {
|
||||||
CountryID string `json:"country_id"` // 国家ID
|
futures_trading_recordID string `json:"futures_trading_record_id"` // 国家ID
|
||||||
Name string `json:"name"` // 国家名称
|
Name string `json:"name"` // 国家名称
|
||||||
Code string `json:"code"` // 国家代码
|
Code string `json:"code"` // 国家代码
|
||||||
}
|
}
|
||||||
@@ -76,14 +76,14 @@ func ReadHandler(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 验证查询条件至少有一个不为空
|
// 验证查询条件至少有一个不为空
|
||||||
if req.CountryID == "" && req.Name == "" && req.Code == "" {
|
if req.futures_trading_recordID == "" && req.Name == "" && req.Code == "" {
|
||||||
zap.L().Warn("⚠️ 请求参数验证失败",
|
zap.L().Warn("⚠️ 请求参数验证失败",
|
||||||
zap.String("req_id", reqID),
|
zap.String("req_id", reqID),
|
||||||
zap.String("reason", "country_id、name、code不能同时为空"),
|
zap.String("reason", "futures_trading_record_id、name、code不能同时为空"),
|
||||||
)
|
)
|
||||||
c.JSON(http.StatusBadRequest, ReadResponse{
|
c.JSON(http.StatusBadRequest, ReadResponse{
|
||||||
Success: false,
|
Success: false,
|
||||||
Message: "请求参数错误:country_id、name、code不能同时为空",
|
Message: "请求参数错误:futures_trading_record_id、name、code不能同时为空",
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -100,7 +100,7 @@ func ReadHandler(c *gin.Context) {
|
|||||||
|
|
||||||
zap.L().Debug("✅ 请求参数验证通过",
|
zap.L().Debug("✅ 请求参数验证通过",
|
||||||
zap.String("req_id", reqID),
|
zap.String("req_id", reqID),
|
||||||
zap.String("country_id", req.CountryID),
|
zap.String("futures_trading_record_id", req.futures_trading_recordID),
|
||||||
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),
|
||||||
@@ -112,9 +112,9 @@ func ReadHandler(c *gin.Context) {
|
|||||||
args := []interface{}{}
|
args := []interface{}{}
|
||||||
paramIndex := 1
|
paramIndex := 1
|
||||||
|
|
||||||
if req.CountryID != "" {
|
if req.futures_trading_recordID != "" {
|
||||||
whereClauses = append(whereClauses, "country_id = $"+strconv.Itoa(paramIndex))
|
whereClauses = append(whereClauses, "futures_trading_record_id = $"+strconv.Itoa(paramIndex))
|
||||||
args = append(args, req.CountryID)
|
args = append(args, req.futures_trading_recordID)
|
||||||
paramIndex++
|
paramIndex++
|
||||||
}
|
}
|
||||||
if req.Name != "" {
|
if req.Name != "" {
|
||||||
@@ -129,8 +129,8 @@ func ReadHandler(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 构建基础SQL
|
// 构建基础SQL
|
||||||
baseSQL := "SELECT country_id, name, code FROM country_info_view"
|
baseSQL := "SELECT futures_trading_record_id, name, code FROM futures_trading_record_info_view"
|
||||||
countSQL := "SELECT COUNT(*) FROM country_info_view"
|
countSQL := "SELECT COUNT(*) FROM futures_trading_record_info_view"
|
||||||
if len(whereClauses) > 0 {
|
if len(whereClauses) > 0 {
|
||||||
whereStr := " WHERE " + strings.Join(whereClauses, " AND ")
|
whereStr := " WHERE " + strings.Join(whereClauses, " AND ")
|
||||||
baseSQL += whereStr
|
baseSQL += whereStr
|
||||||
@@ -141,7 +141,7 @@ func ReadHandler(c *gin.Context) {
|
|||||||
offset := (page - 1) * pageSize
|
offset := (page - 1) * pageSize
|
||||||
|
|
||||||
// 拼接分页SQL(使用fmt.Sprintf更清晰)
|
// 拼接分页SQL(使用fmt.Sprintf更清晰)
|
||||||
querySQL := fmt.Sprintf("%s ORDER BY country_id LIMIT $%d OFFSET $%d", baseSQL, paramIndex, paramIndex+1)
|
querySQL := fmt.Sprintf("%s ORDER BY futures_trading_record_id LIMIT $%d OFFSET $%d", baseSQL, paramIndex, paramIndex+1)
|
||||||
args = append(args, pageSize, offset)
|
args = append(args, pageSize, offset)
|
||||||
|
|
||||||
// 查询总条数(修正参数传递方式)
|
// 查询总条数(修正参数传递方式)
|
||||||
@@ -176,10 +176,10 @@ func ReadHandler(c *gin.Context) {
|
|||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
// 处理查询结果
|
// 处理查询结果
|
||||||
var items []CountryInfoViewItem
|
var items []futures_trading_recordInfoViewItem
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var item CountryInfoViewItem
|
var item futures_trading_recordInfoViewItem
|
||||||
if err := rows.Scan(&item.CountryID, &item.Name, &item.Code); err != nil {
|
if err := rows.Scan(&item.futures_trading_recordID, &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),
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package logic
|
package logic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"country/db"
|
"futures_trading_record/db"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@ import (
|
|||||||
|
|
||||||
// UpdateRequest 更新请求参数结构
|
// UpdateRequest 更新请求参数结构
|
||||||
type UpdateRequest struct {
|
type UpdateRequest struct {
|
||||||
CountryID string `json:"country_id" binding:"required"` // 国家ID,必填
|
futures_trading_recordID string `json:"futures_trading_record_id" binding:"required"` // 国家ID,必填
|
||||||
Name string `json:"name"` // 国家名称,可选
|
Name string `json:"name"` // 国家名称,可选
|
||||||
Code string `json:"code"` // 国家代码,可选
|
Code string `json:"code"` // 国家代码,可选
|
||||||
}
|
}
|
||||||
@@ -41,7 +41,7 @@ func UpdateHandler(c *gin.Context) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
var req UpdateRequest
|
var req UpdateRequest
|
||||||
// 绑定并验证请求参数(主要验证country_id必填)
|
// 绑定并验证请求参数(主要验证futures_trading_record_id必填)
|
||||||
if err := c.ShouldBindJSON(&req); err != nil {
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
zap.L().Warn("⚠️ 请求参数验证失败",
|
zap.L().Warn("⚠️ 请求参数验证失败",
|
||||||
zap.String("req_id", reqID),
|
zap.String("req_id", reqID),
|
||||||
@@ -49,7 +49,7 @@ func UpdateHandler(c *gin.Context) {
|
|||||||
)
|
)
|
||||||
c.JSON(http.StatusBadRequest, UpdateResponse{
|
c.JSON(http.StatusBadRequest, UpdateResponse{
|
||||||
Success: false,
|
Success: false,
|
||||||
Message: "请求参数错误:country_id为必填项",
|
Message: "请求参数错误:futures_trading_record_id为必填项",
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -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("country_id", req.CountryID),
|
zap.String("futures_trading_record_id", req.futures_trading_recordID),
|
||||||
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("country_id", req.CountryID),
|
zap.String("futures_trading_record_id", req.futures_trading_recordID),
|
||||||
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 name SET name = $1 WHERE country_id = $2", req.Name, req.CountryID)
|
_, err = tx.Exec("UPDATE name SET name = $1 WHERE futures_trading_record_id = $2", req.Name, req.futures_trading_recordID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
zap.L().Error("❌ name表更新失败",
|
zap.L().Error("❌ name表更新失败",
|
||||||
zap.String("req_id", reqID),
|
zap.String("req_id", reqID),
|
||||||
zap.String("country_id", req.CountryID),
|
zap.String("futures_trading_record_id", req.futures_trading_recordID),
|
||||||
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("country_id", req.CountryID),
|
zap.String("futures_trading_record_id", req.futures_trading_recordID),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果code不为空,更新code表
|
// 如果code不为空,更新code表
|
||||||
if req.Code != "" {
|
if req.Code != "" {
|
||||||
_, err = tx.Exec("UPDATE code SET code = $1 WHERE country_id = $2", req.Code, req.CountryID)
|
_, err = tx.Exec("UPDATE code SET code = $1 WHERE futures_trading_record_id = $2", req.Code, req.futures_trading_recordID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
zap.L().Error("❌ code表更新失败",
|
zap.L().Error("❌ code表更新失败",
|
||||||
zap.String("req_id", reqID),
|
zap.String("req_id", reqID),
|
||||||
zap.String("country_id", req.CountryID),
|
zap.String("futures_trading_record_id", req.futures_trading_recordID),
|
||||||
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("country_id", req.CountryID),
|
zap.String("futures_trading_record_id", req.futures_trading_recordID),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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("country_id", req.CountryID),
|
zap.String("futures_trading_record_id", req.futures_trading_recordID),
|
||||||
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("country_id", req.CountryID),
|
zap.String("futures_trading_record_id", req.futures_trading_recordID),
|
||||||
zap.Duration("duration", duration),
|
zap.Duration("duration", duration),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"country/db" // 数据库相关操作包
|
"futures_trading_record/db" // 数据库相关操作包
|
||||||
"country/logger" // 日志工具包
|
"futures_trading_record/logger" // 日志工具包
|
||||||
"country/logic" // 业务逻辑处理包
|
"futures_trading_record/logic" // 业务逻辑处理包
|
||||||
|
|
||||||
"time"
|
"time"
|
||||||
"github.com/gin-contrib/cors"
|
"github.com/gin-contrib/cors"
|
||||||
@@ -51,20 +51,20 @@ func main() {
|
|||||||
zap.L().Info("✅ 配置跨域中间件完成")
|
zap.L().Info("✅ 配置跨域中间件完成")
|
||||||
|
|
||||||
// 注册创建国家的接口,POST请求,由logic.CreateHandler处理
|
// 注册创建国家的接口,POST请求,由logic.CreateHandler处理
|
||||||
r.POST("/country/create", logic.CreateHandler)
|
r.POST("/futures_trading_record/create", logic.CreateHandler)
|
||||||
zap.L().Info("✅ 创建接口注册完成: POST /country/create")
|
zap.L().Info("✅ 创建接口注册完成: POST /futures_trading_record/create")
|
||||||
|
|
||||||
// 注册读取国家的接口,POST请求,由logic.ReadHandler
|
// 注册读取国家的接口,POST请求,由logic.ReadHandler
|
||||||
r.POST("/country/read", logic.ReadHandler)
|
r.POST("/futures_trading_record/read", logic.ReadHandler)
|
||||||
zap.L().Info("✅ 读取接口注册完成: POST /country/read")
|
zap.L().Info("✅ 读取接口注册完成: POST /futures_trading_record/read")
|
||||||
|
|
||||||
// 注册更新国家的接口,POST请求,由logic.UpdateHandler
|
// 注册更新国家的接口,POST请求,由logic.UpdateHandler
|
||||||
r.POST("/country/update", logic.UpdateHandler)
|
r.POST("/futures_trading_record/update", logic.UpdateHandler)
|
||||||
zap.L().Info("✅ 更新接口注册完成: POST /country/update")
|
zap.L().Info("✅ 更新接口注册完成: POST /futures_trading_record/update")
|
||||||
|
|
||||||
// 注册删除国家的接口,POST请求,由logic.DeleteHandler处理
|
// 注册删除国家的接口,POST请求,由logic.DeleteHandler处理
|
||||||
r.POST("/country/delete", logic.DeleteHandler)
|
r.POST("/futures_trading_record/delete", logic.DeleteHandler)
|
||||||
zap.L().Info("✅ 删除接口注册完成: POST /country/delete")
|
zap.L().Info("✅ 删除接口注册完成: POST /futures_trading_record/delete")
|
||||||
|
|
||||||
// 记录服务启动日志,监听80端口
|
// 记录服务启动日志,监听80端口
|
||||||
zap.L().Info("✅ 服务启动在80端口")
|
zap.L().Info("✅ 服务启动在80端口")
|
||||||
|
|||||||
Reference in New Issue
Block a user