--- phase: 01-p0 plan: 01 subsystem: realname-status tags: [bug-fix, constants, critical, realname] dependency_graph: requires: [] provides: [CRITICAL-01, CRITICAL-02] affects: [polling_handler, client_order, scheduler, iot_card_service, asset_dto] tech_stack: added: [] patterns: [constants-over-magic-numbers] key_files: created: [] modified: - internal/task/polling_handler.go - internal/model/iot_card.go - internal/model/dto/asset_dto.go - internal/polling/scheduler.go - internal/service/iot_card/service.go - internal/service/client_order/service.go - internal/handler/app/client_realname.go decisions: - 统一使用 constants.RealNameStatusVerified(=1) 替代所有硬编码 1、2 的实名状态判断 - scheduler.go 中 0/1/2 三态判断简化为已实名/未实名两态(符合常量设计) metrics: duration_minutes: 15 completed_date: "2026-03-27" tasks_completed: 2 files_modified: 7 --- # Phase 01 Plan 01: 统一实名状态常量 Summary **一句话总结:** 将全链路 7 处硬编码实名状态值(包括错误的 `return 2`)统一改为 `constants.RealNameStatusVerified(=1)` / `constants.RealNameStatusNotVerified(=0)`,修复 CRITICAL-01 和 CRITICAL-02。 --- ## Objective Achieved 统一实名状态常量(CRITICAL-01),并修复 C 端实名校验(CRITICAL-02)。 实名链路三处不一致(轮询写入 2、常量定义 1、C 端校验 1)造成实名状态链路全面断裂,修复后全链路统一为 `0=未实名、1=已实名`。 --- ## Tasks Completed | Task | Name | Commit | Files | |------|------|--------|-------| | 1 | 修复 polling_handler.go 实名状态写入值(CRITICAL-01) | `1fd0072` | polling_handler.go, iot_card.go, asset_dto.go, scheduler.go, iot_card/service.go | | 2 | 修复 C 端实名校验(CRITICAL-02) | `da50a35` | client_order/service.go, client_realname.go | --- ## Key Changes ### Task 1 — CRITICAL-01 核心修复 **① `internal/task/polling_handler.go` — `parseRealnameStatus`** ```go // 修改前(错误:写入 2 到数据库) func (h *PollingHandler) parseRealnameStatus(realStatus bool) int { if realStatus { return 2 // 已实名 } return 0 // 未实名 } // 修改后(正确:写入常量值 1) func (h *PollingHandler) parseRealnameStatus(realStatus bool) int { if realStatus { return constants.RealNameStatusVerified // = 1,已实名 } return constants.RealNameStatusNotVerified // = 0,未实名 } ``` **② `internal/task/polling_handler.go` — `isFirstRealname`** ```go // 修改前(错误:硬编码 == 2 判断) isFirstRealname := (card.RealNameStatus == 0 || card.RealNameStatus == 1) && newRealnameStatus == 2 // 修改后(正确:使用常量比较,逻辑等价但语义清晰) isFirstRealname := card.RealNameStatus != constants.RealNameStatusVerified && newRealnameStatus == constants.RealNameStatusVerified ``` **③ `internal/model/iot_card.go` — Model gorm comment** ```go // 修改前 RealNameStatus int `gorm:"...comment:实名状态 0-未实名 1-已实名(行业卡可以保持0)" json:"real_name_status"` // 修改后(统一注释,去除误导性括号说明) RealNameStatus int `gorm:"...comment:实名状态 0-未实名 1-已实名" json:"real_name_status"` ``` **④ `internal/model/dto/asset_dto.go` — DTO description** ```go // 修改前(错误:包含 1实名中 2已实名 的旧三态描述) RealNameStatus int `json:"real_name_status" description:"实名状态:0未实名 1实名中 2已实名"` // 修改后(正确:两态) RealNameStatus int `json:"real_name_status" description:"实名状态:0未实名 1已实名"` ``` **⑤ `internal/polling/scheduler.go` — `getCardCondition`** ```go // 修改前(错误:使用硬编码 0/1/2 三态判断) if card.RealNameStatus == 0 || card.RealNameStatus == 1 { return "not_real_name" } if card.RealNameStatus == 2 { // ... } // 修改后(正确:两态常量判断) if card.RealNameStatus != constants.RealNameStatusVerified { return "not_real_name" } if card.RealNameStatus == constants.RealNameStatusVerified { // ... } ``` **⑥ `internal/service/iot_card/service.go` — `parseGatewayRealnameStatus`** ```go // 修改前(错误:返回硬编码 2) // true=已实名(2),false=未实名(0) func parseGatewayRealnameStatus(realStatus bool) int { if realStatus { return 2 } return 0 } // 修改后(正确:返回常量) // true=已实名(1),false=未实名(0) func parseGatewayRealnameStatus(realStatus bool) int { if realStatus { return constants.RealNameStatusVerified } return constants.RealNameStatusNotVerified } ``` --- ### Task 2 — CRITICAL-02 修复 **① `internal/service/client_order/service.go`** ```go // 修改前(硬编码 1,语义不清晰) if packagesNeedRealname(validationResult.Packages) && assetInfo.RealNameStatus != 1 { // 修改后(常量比较,语义明确) if packagesNeedRealname(validationResult.Packages) && assetInfo.RealNameStatus != constants.RealNameStatusVerified { ``` **② `internal/handler/app/client_realname.go`** ```go // 修改前(硬编码 1) if targetCard.RealNameStatus == 1 { // 修改后(常量) if targetCard.RealNameStatus == constants.RealNameStatusVerified { ``` --- ## Verification Results ``` ✅ go build ./... — 编译通过,无错误 ✅ return 2 已消除 — polling_handler.go 中不再有 return 2 ✅ 常量使用确认 — polling_handler.go 和 client_order/service.go 均使用 constants.RealNameStatusVerified ✅ 无遗漏硬编码 — rg 未发现 newRealnameStatus==2 / RealNameStatus==2 / RealNameStatus!=1 ``` --- ## Deviations from Plan ### Auto-fixed Issues **1. [Rule 2 - 缺失修复] 修复 asset_dto.go DTO description** - **Found during:** Task 1 全局搜索 - **Issue:** `asset_dto.go` 的 `RealNameStatus` description 仍含旧三态描述 `1实名中 2已实名` - **Fix:** 更新为 `0未实名 1已实名` - **Files modified:** `internal/model/dto/asset_dto.go` - **Commit:** `1fd0072` **2. [Rule 2 - 缺失修复] 修复 scheduler.go 硬编码三态判断** - **Found during:** Task 1 全局搜索 - **Issue:** `scheduler.go:getCardCondition` 使用 `RealNameStatus == 0 || == 1 || == 2` 硬编码 - **Fix:** 改为 `!= constants.RealNameStatusVerified` / `== constants.RealNameStatusVerified` - **Files modified:** `internal/polling/scheduler.go` - **Commit:** `1fd0072` **3. [Rule 2 - 缺失修复] 修复 iot_card/service.go 另一处 return 2** - **Found during:** Task 1 全局搜索 - **Issue:** `parseGatewayRealnameStatus` 函数也返回硬编码 `2`,与 polling_handler.go 同等问题 - **Fix:** 改为常量返回 - **Files modified:** `internal/service/iot_card/service.go` - **Commit:** `1fd0072` **4. [Rule 2 - 缺失修复] 修复 client_realname.go Handler 层硬编码** - **Found during:** Task 2 全局搜索 - **Issue:** `client_realname.go:128` Handler 层 `== 1` 硬编码实名判断 - **Fix:** 改为 `constants.RealNameStatusVerified` - **Files modified:** `internal/handler/app/client_realname.go` - **Commit:** `da50a35` --- ## Requirements Completed - ✅ **CRITICAL-01**: 实名状态常量统一(DB 写入值 2 vs 常量 1,所有链路断裂)— 已修复 - ✅ **CRITICAL-02**: C 端实名校验修复(依赖 CRITICAL-01)— 已修复 --- ## Self-Check: PASSED - ✅ `internal/task/polling_handler.go` — 已修改并提交 - ✅ `internal/model/iot_card.go` — 已修改并提交 - ✅ `internal/service/client_order/service.go` — 已修改并提交 - ✅ commit `1fd0072` — 存在(Task 1) - ✅ commit `da50a35` — 存在(Task 2)