From 47e9aa27bd6d009c675965b7176fbdae92fdac7e Mon Sep 17 00:00:00 2001 From: vipg Date: Tue, 11 Nov 2025 17:43:03 +0800 Subject: [PATCH] add --- backend/country/sql/03_create_name_table.sql | 6 +- backend/country/sql/04_create_code_table.sql | 6 +- backend/country/src/go.mod | 2 +- backend/country/src/logic/create.go | 115 ++++++++++++++++--- backend/country/src/main.go | 6 +- backend/提示词条.md | 6 + 6 files changed, 118 insertions(+), 23 deletions(-) create mode 100644 backend/提示词条.md diff --git a/backend/country/sql/03_create_name_table.sql b/backend/country/sql/03_create_name_table.sql index 0421712..938798b 100644 --- a/backend/country/sql/03_create_name_table.sql +++ b/backend/country/sql/03_create_name_table.sql @@ -1,7 +1,7 @@ -- 切换到目标数据库 \c postgres; -CREATE OR REPLACE FUNCTION update_account_modified_column() +CREATE OR REPLACE FUNCTION update_name_modified_column() RETURNS TRIGGER AS $$ BEGIN NEW.updated_at = CURRENT_TIMESTAMP; @@ -14,7 +14,7 @@ BEGIN IF NOT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'name') THEN CREATE TABLE name ( id UUID DEFAULT gen_random_uuid_v7() PRIMARY KEY NOT NULL, - user_id UUID NOT NULL, + country_id UUID NOT NULL, name VARCHAR NOT NULL, deleted BOOLEAN NOT NULL DEFAULT FALSE, created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, @@ -23,7 +23,7 @@ BEGIN CREATE TRIGGER update_name_updated_at BEFORE UPDATE ON "name" FOR EACH ROW - EXECUTE FUNCTION update_account_modified_column(); + EXECUTE FUNCTION update_name_modified_column(); RAISE NOTICE 'Created name table and trigger'; ELSE diff --git a/backend/country/sql/04_create_code_table.sql b/backend/country/sql/04_create_code_table.sql index fab118a..08d09a8 100644 --- a/backend/country/sql/04_create_code_table.sql +++ b/backend/country/sql/04_create_code_table.sql @@ -1,7 +1,7 @@ -- 切换到目标数据库 \c postgres; -CREATE OR REPLACE FUNCTION update_password_modified_column() +CREATE OR REPLACE FUNCTION update_code_modified_column() RETURNS TRIGGER AS $$ BEGIN NEW.updated_at = CURRENT_TIMESTAMP; @@ -14,7 +14,7 @@ BEGIN IF NOT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'code') THEN CREATE TABLE code ( id UUID DEFAULT gen_random_uuid_v7() PRIMARY KEY NOT NULL, - user_id UUID NOT NULL, + country_id UUID NOT NULL, code VARCHAR NOT NULL, deleted BOOLEAN NOT NULL DEFAULT FALSE, created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, @@ -23,7 +23,7 @@ BEGIN CREATE TRIGGER update_code_updated_at BEFORE UPDATE ON "code" FOR EACH ROW - EXECUTE FUNCTION update_password_modified_column(); + EXECUTE FUNCTION update_code_modified_column(); RAISE NOTICE 'Created code table and trigger'; ELSE diff --git a/backend/country/src/go.mod b/backend/country/src/go.mod index d31446e..7bb5664 100644 --- a/backend/country/src/go.mod +++ b/backend/country/src/go.mod @@ -1,4 +1,4 @@ -module user +module country go 1.25.0 diff --git a/backend/country/src/logic/create.go b/backend/country/src/logic/create.go index 381dddb..14ef1d4 100644 --- a/backend/country/src/logic/create.go +++ b/backend/country/src/logic/create.go @@ -1,26 +1,115 @@ package logic -// 这里是创建数据逻辑: -// 1、接收 name,code 两个参数。 -// 2、确认提交的 name,code 两个参数不能为空,如果有空,则返回提示。 -// 3、第二步通过后,在 country 表中创建一个 id。 -// 4、通过 3 中的 id,分别保存到 name 和 code 的表中。 +import ( + "net/http" + "country/db" + + "github.com/gin-gonic/gin" + "go.uber.org/zap" +) // CreateRequest 注册请求参数结构 type CreateRequest struct { - + Name string `json:"name" binding:"required"` + Code string `json:"code" binding:"required"` } // CreateResponse 注册响应结构 type CreateResponse struct { - Success bool `json:"success"` - Message string `json:"message"` - Data struct { - - } `json:"data"` + Success bool `json:"success"` + Message string `json:"message"` + Data CreateData `json:"data"` } -// CreateHandler 逻辑 -func CreateHandler(c *gin.Context) { +// CreateData 响应数据结构 +type CreateData struct { + CountryID string `json:"country_id"` +} +// CreateHandler 处理国家创建逻辑 +func CreateHandler(c *gin.Context) { + var req CreateRequest + // 绑定并验证请求参数 + if err := c.ShouldBindJSON(&req); err != nil { + zap.L().Warn("请求参数验证失败", zap.Error(err)) + c.JSON(http.StatusBadRequest, CreateResponse{ + Success: false, + Message: "name和code为必填参数,不能为空", + }) + return + } + + // 在country表中创建记录并获取ID + var countryID string + err := db.DB.QueryRow("INSERT INTO \"country\" DEFAULT VALUES RETURNING id").Scan(&countryID) + if err != nil { + zap.L().Error("插入country表失败", zap.Error(err)) + c.JSON(http.StatusInternalServerError, CreateResponse{ + Success: false, + Message: "创建国家记录失败", + }) + return + } + + // 开启事务 + tx, err := db.DB.Begin() + if err != nil { + zap.L().Error("开启事务失败", zap.Error(err)) + c.JSON(http.StatusInternalServerError, CreateResponse{ + Success: false, + Message: "系统错误,无法开启事务", + }) + return + } + defer func() { + // 发生panic时回滚事务 + if r := recover(); r != nil { + tx.Rollback() + zap.L().Error("事务处理发生panic", zap.Any("recover", r)) + } + }() + + // 插入name表 + _, err = tx.Exec("INSERT INTO name (country_id, name) VALUES ($1, $2)", countryID, req.Name) + if err != nil { + tx.Rollback() + zap.L().Error("插入name表失败", zap.Error(err), zap.String("country_id", countryID)) + c.JSON(http.StatusInternalServerError, CreateResponse{ + Success: false, + Message: "保存名称信息失败", + }) + return + } + + // 插入code表 + _, err = tx.Exec("INSERT INTO code (country_id, code) VALUES ($1, $2)", countryID, req.Code) + if err != nil { + tx.Rollback() + zap.L().Error("插入code表失败", zap.Error(err), zap.String("country_id", countryID)) + c.JSON(http.StatusInternalServerError, CreateResponse{ + Success: false, + Message: "保存代码信息失败", + }) + return + } + + // 提交事务 + if err := tx.Commit(); err != nil { + tx.Rollback() + zap.L().Error("提交事务失败", zap.Error(err), zap.String("country_id", countryID)) + c.JSON(http.StatusInternalServerError, CreateResponse{ + Success: false, + Message: "提交数据失败", + }) + return + } + + // 返回成功响应 + c.JSON(http.StatusOK, CreateResponse{ + Success: true, + Message: "创建成功", + Data: CreateData{ + CountryID: countryID, + }, + }) } \ No newline at end of file diff --git a/backend/country/src/main.go b/backend/country/src/main.go index ed28310..19d130e 100644 --- a/backend/country/src/main.go +++ b/backend/country/src/main.go @@ -1,9 +1,9 @@ package main import ( - "user/db" - "user/logger" - "user/logic" + "country/db" + "country/logger" + "country/logic" "github.com/gin-gonic/gin" _ "github.com/lib/pq" diff --git a/backend/提示词条.md b/backend/提示词条.md new file mode 100644 index 0000000..a71e27c --- /dev/null +++ b/backend/提示词条.md @@ -0,0 +1,6 @@ +分析这个项目,在 create.go 中完成以下需求: + +1、接收 name,code 两个参数。 +2、确认提交的 name,code 两个参数不能为空,如果有空,则返回提示。 +3、第二步通过后,在 country 表中,通过: "INSERT INTO "country" DEFAULT VALUES RETURNING id" 获得ID。 +4、通过 3 中的 id,开启事务保存到 name 和 code 的表中。