fix: 第1批 F1、M12 一资产一号与换货按手机号关联校验

- F1 一个资产同时只能有一个有效手机号关联,他号绑定返回 1192(不含号码),同号幂等
- 登录 need_bind_phone 改看资产是否已有有效关联,新增 asset_phone_bound、asset_phone_is_own;H5 绑定按客户/资产两侧状态分别写入
- 客户换号不再迁移资产关联
- M12 换货新资产有有效手机号关联即拒绝,号码只在 data.phone;换货完成清空旧资产客户绑定并失效旧资产关联(exchange_completed),均不迁移
- OpenSpec Change enforce-single-phone-per-asset:11/16,H5 短信与换货端到端验证待测试部署后完成
This commit is contained in:
邹进
2026-10-12 00:10:41 +09:00
parent 6298a9061f
commit 9ced14fa1b
19 changed files with 568 additions and 451 deletions

View File

@@ -24,6 +24,10 @@ const (
PhoneAssetAssociationInvalidateMethodBackendBatch = "backend_batch"
// PhoneAssetAssociationInvalidateMethodCSVImport 表示 CSV 导入解除。
PhoneAssetAssociationInvalidateMethodCSVImport = "csv_import"
// PhoneAssetAssociationInvalidateMethodExchangeCompleted 表示换货完成时随旧资产一并失效。
PhoneAssetAssociationInvalidateMethodExchangeCompleted = "exchange_completed"
// PhoneAssetAssociationExchangeCompletedReason 换货完成失效旧资产关联的原因。
PhoneAssetAssociationExchangeCompletedReason = "换货完成"
)
// 手机号—资产关联的业务口径常量。
@@ -136,6 +140,8 @@ func PhoneAssetAssociationInvalidateMethodName(method string) string {
return "后台批量解除"
case PhoneAssetAssociationInvalidateMethodCSVImport:
return "CSV导入解除"
case PhoneAssetAssociationInvalidateMethodExchangeCompleted:
return "换货完成失效"
default:
return "未知"
}

View File

@@ -157,6 +157,7 @@ const (
CodeRealnameNotAvailable = 1189 // 请先完成充值或购买套餐后再进行实名认证
CodeOpenAPITimestampInvalid = 1190 // 开放接口时间戳无效
CodeOpenAPINonceReplay = 1191 // 开放接口 nonce 重放
CodeAssetPhoneAlreadyBound = 1192 // 资产已绑定其他手机号(一资产一号)
// 换货相关错误 (1200-1209)
CodeExchangeOrderNotFound = 1200 // 换货单不存在
@@ -328,6 +329,7 @@ var allErrorCodes = []int{
CodeRealnameNotAvailable,
CodeOpenAPITimestampInvalid,
CodeOpenAPINonceReplay,
CodeAssetPhoneAlreadyBound,
CodeExchangeOrderNotFound,
CodeExchangeInProgress,
CodeExchangeStatusInvalid,
@@ -477,6 +479,7 @@ var errorMessages = map[int]string{
CodeSmsSendFailed: "短信发送失败",
CodeVerificationCodeInvalid: "验证码错误或已过期",
CodePhoneAlreadyBound: "手机号已被其他客户绑定",
CodeAssetPhoneAlreadyBound: "该资产已绑定手机号,如需更换请联系管理员",
CodeAlreadyBoundPhone: "当前客户已绑定手机号,不可重复绑定",
CodeOldPhoneMismatch: "旧手机号与当前绑定不匹配",
CodeNeedRealname: "该套餐需实名认证后购买",