From 4e38ee802150c72c663c497e7049197f7443a3ea Mon Sep 17 00:00:00 2001 From: czl231 <3286836406@qq.com> Date: Mon, 10 Aug 2026 12:33:30 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E9=85=8D=E9=80=81=E7=82=B9=E7=BC=96?= =?UTF-8?q?=E7=A0=81=E9=87=8D=E5=A4=8D=E6=97=B6=E8=BF=94=E5=9B=9E=E4=B8=AD?= =?UTF-8?q?=E6=96=87=E6=8F=90=E9=86=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../internal/logic/common/delivery_error.go | 26 +++++++++ .../logic/common/delivery_error_test.go | 44 +++++++++++++++ backend/api/internal/logic/gas/delivery.go | 2 +- .../logic/platform/delivery/delivery.go | 2 +- docs/项目文档_配送点重复编码提醒_v1.0.md | 53 +++++++++++++++++++ 5 files changed, 125 insertions(+), 2 deletions(-) create mode 100644 backend/api/internal/logic/common/delivery_error.go create mode 100644 backend/api/internal/logic/common/delivery_error_test.go create mode 100644 docs/项目文档_配送点重复编码提醒_v1.0.md diff --git a/backend/api/internal/logic/common/delivery_error.go b/backend/api/internal/logic/common/delivery_error.go new file mode 100644 index 0000000..bd6a602 --- /dev/null +++ b/backend/api/internal/logic/common/delivery_error.go @@ -0,0 +1,26 @@ +// 功能描述:转换配送点写入时的数据库错误,避免向客户端泄露数据库实现细节。 +// 版本:v1.0 +package common + +import ( + "errors" + + "github.com/jackc/pgx/v5/pgconn" +) + +const deliveryCodeUniqueConstraint = "idx_delivery_basic_delivery_code" + +var errDeliveryCodeExists = errors.New("配送点编码已存在,请更换后重试") + +// DeliveryCreateError 将配送点创建错误转换为稳定的业务错误。 +// 参数:err 为数据库创建操作返回的原始错误。 +// 返回值:配送点编码冲突时返回中文业务错误,其他错误保持原样。 +func DeliveryCreateError(err error) error { + var postgresError *pgconn.PgError + if errors.As(err, &postgresError) && + postgresError.Code == "23505" && + postgresError.ConstraintName == deliveryCodeUniqueConstraint { + return errDeliveryCodeExists + } + return err +} diff --git a/backend/api/internal/logic/common/delivery_error_test.go b/backend/api/internal/logic/common/delivery_error_test.go new file mode 100644 index 0000000..4cd9237 --- /dev/null +++ b/backend/api/internal/logic/common/delivery_error_test.go @@ -0,0 +1,44 @@ +// 功能描述:验证配送点创建错误的业务化转换规则。 +// 版本:v1.0 +package common + +import ( + "errors" + "testing" + + "github.com/jackc/pgx/v5/pgconn" +) + +// TestDeliveryCreateErrorDeliveryCodeConflict 验证配送点编码唯一冲突会转换为中文提醒。 +// 参数:t 为 Go 测试上下文。 +// 返回值:无。 +func TestDeliveryCreateErrorDeliveryCodeConflict(t *testing.T) { + databaseError := &pgconn.PgError{Code: "23505", ConstraintName: deliveryCodeUniqueConstraint} + + actual := DeliveryCreateError(databaseError) + if actual.Error() != "配送点编码已存在,请更换后重试" { + t.Fatalf("期望中文重复编码提醒,实际为 %q", actual.Error()) + } +} + +// TestDeliveryCreateErrorKeepsOtherErrors 验证非目标约束错误不会被误转换。 +// 参数:t 为 Go 测试上下文。 +// 返回值:无。 +func TestDeliveryCreateErrorKeepsOtherErrors(t *testing.T) { + original := errors.New("database unavailable") + + if actual := DeliveryCreateError(original); actual != original { + t.Fatalf("期望保留原始错误,实际为 %v", actual) + } +} + +// TestDeliveryCreateErrorKeepsOtherUniqueConstraints 验证其他唯一约束冲突不会被误报为配送点编码重复。 +// 参数:t 为 Go 测试上下文。 +// 返回值:无。 +func TestDeliveryCreateErrorKeepsOtherUniqueConstraints(t *testing.T) { + databaseError := &pgconn.PgError{Code: "23505", ConstraintName: "idx_other_unique_constraint"} + + if actual := DeliveryCreateError(databaseError); actual != databaseError { + t.Fatalf("期望保留其他约束错误,实际为 %v", actual) + } +} diff --git a/backend/api/internal/logic/gas/delivery.go b/backend/api/internal/logic/gas/delivery.go index 7bc06b9..cac8e2f 100644 --- a/backend/api/internal/logic/gas/delivery.go +++ b/backend/api/internal/logic/gas/delivery.go @@ -61,7 +61,7 @@ func CreateDelivery(ctx *gin.Context) { Name: request.Name, Principal: request.Principal, Address: request.Address, } if err := impl.DBService.Create(&delivery).Error; err != nil { - infra.Response.Error(ctx, err) + infra.Response.Error(ctx, common.DeliveryCreateError(err)) return } common.RespondCreatedResource(ctx, delivery) diff --git a/backend/api/internal/logic/platform/delivery/delivery.go b/backend/api/internal/logic/platform/delivery/delivery.go index 8e49cb2..055636e 100644 --- a/backend/api/internal/logic/platform/delivery/delivery.go +++ b/backend/api/internal/logic/platform/delivery/delivery.go @@ -106,7 +106,7 @@ func CreateDeliveryBasic(ctx *gin.Context) { } delivery := models.DeliveryBasic{Entity: common.NewEntity(common.StatusDraft), DeliveryCode: request.DeliveryCode, GasBasicID: gasBasicID, Name: request.Name, Principal: request.Principal, Address: request.Address} if err := impl.DBService.Create(&delivery).Error; err != nil { - infra.Response.Error(ctx, err) + infra.Response.Error(ctx, common.DeliveryCreateError(err)) return } common.RespondCreatedResource(ctx, delivery) diff --git a/docs/项目文档_配送点重复编码提醒_v1.0.md b/docs/项目文档_配送点重复编码提醒_v1.0.md new file mode 100644 index 0000000..b248d02 --- /dev/null +++ b/docs/项目文档_配送点重复编码提醒_v1.0.md @@ -0,0 +1,53 @@ +# 配送点重复编码提醒 + +## 项目概述 + +- 功能:新增配送点时,将目标唯一键冲突转换为中文业务提醒。 +- 技术栈:Go、Gin、GORM、PostgreSQL。 +- 运行环境:项目现有 Go 1.26.1 环境。 + +## 目录结构说明 + +```text +platforms/backend/api/internal/logic/ +├── common/ +│ ├── delivery_error.go # 配送点创建错误转换 +│ └── delivery_error_test.go # 错误转换单元测试 +├── gas/delivery.go # 气站端配送点新增入口 +└── platform/delivery/delivery.go # 平台端配送点新增入口 +``` + +## 核心文件说明 + +- `common/delivery_error.go`:精确识别 PostgreSQL `23505` 与约束 `idx_delivery_basic_delivery_code`,返回“配送点编码已存在,请更换后重试”;其他错误保持原样。 +- `platform/delivery/delivery.go`:平台端创建失败时调用公共转换函数。 +- `gas/delivery.go`:气站端创建失败时调用同一公共转换函数。 +- `common/delivery_error_test.go`:覆盖目标约束、普通数据库错误、其他唯一约束三个分支。 + +## 变更记录 + +- 新增配送点重复编码的中文提醒。 +- 平台端和气站端行为保持一致。 +- 保留数据库全局唯一约束、归档占用规则和现有前端顶部提醒。 +- 未新增依赖,未修改公共接口、数据库结构或配送点编码编辑规则。 + +## 维护指南 + +- 若数据库约束名称调整,需要同步更新 `deliveryCodeUniqueConstraint`。 +- 新增其他唯一字段提示时,应按约束名精确映射,不能将全部 `23505` 错误统一解释为配送点编码重复。 +- 验证命令:`go test ./internal/logic/common ./internal/logic/platform/delivery ./internal/logic/gas`。 + +## 操作日志 + +```text +操作时间:2026-08-10 12:24:49 +操作类型:扩展 +影响模块:配送点创建错误处理 + +操作前状态:数据库唯一键原始英文错误直接返回前端,暴露 SQLSTATE 与约束名。 +具体操作:新增精确错误映射并接入平台端、气站端创建入口;新增三个单元测试。 +操作后状态:目标配送点编码冲突返回中文提醒,其他错误行为不变。 +代码变更:delivery_error.go、delivery_error_test.go、platform/delivery/delivery.go、gas/delivery.go。 +验证结果:三个相关 Go 包测试通过。 +风险评估:依赖既有 PostgreSQL 约束名;约束重命名后需同步更新常量。未改变数据库唯一规则。 +```