From 15fc17e54b50f6a055e1a914a30349dad1071067 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E5=BF=A0=E6=9E=97?= <170083662@qq.com> Date: Tue, 20 Jan 2026 17:25:28 +0800 Subject: [PATCH] =?UTF-8?q?fix(credit):=20=E4=BF=AE=E5=A4=8D=E5=80=BA?= =?UTF-8?q?=E5=8A=A1=E4=BA=BA=E5=85=AC=E5=8F=B8ID=E5=8C=B9=E9=85=8D?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将默认更新条件从 companyId 为空改为 companyId=0 - 修改查询条件从 isNull 改为等于 0 的判断 - 更新业务逻辑中对 needUpdate 的判断条件 docs(shop): 添加经销商推荐绑定接口文档 - 新增 SHOP_DEALER_REFEREE_BINDING.md 文档 - 定义 POST /api/shop/shop-dealer-referee 接口规则 - 说明邀请人有效性验证和防止自绑限制 - 描述首次绑定幂等性和溯源字段要求 - 提供数据库唯一索引建议和建表语句 --- docs/SHOP_DEALER_REFEREE_BINDING.md | 26 +++++++++++++++++++ .../CreditJudgmentDebtorController.java | 6 ++--- 2 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 docs/SHOP_DEALER_REFEREE_BINDING.md diff --git a/docs/SHOP_DEALER_REFEREE_BINDING.md b/docs/SHOP_DEALER_REFEREE_BINDING.md new file mode 100644 index 0000000..583bb67 --- /dev/null +++ b/docs/SHOP_DEALER_REFEREE_BINDING.md @@ -0,0 +1,26 @@ +# ShopDealerReferee 绑定接口规则与索引建议 + +接口:`POST /api/shop/shop-dealer-referee` + +## 业务规则(后端) + +- 邀请人(dealerId)必须存在且有效:以 `shop_dealer_user` 记录存在且 `is_delete=0` 为准 +- 当前用户(userId)仅从 token 获取;若 body.userId 存在且与 token 不一致则拒绝 +- 禁止自己绑定自己:`dealerId == userId` +- 仅首次绑定生效:若已存在(同一 tenant、同一 user、`level=1`)则直接返回成功(幂等,不改绑) +- 记录溯源字段:`source`、`scene` + +## 并发幂等(数据库建议) + +建议在 `shop_dealer_referee` 增加溯源字段,并加唯一索引保证并发下不重复写入: + +```sql +ALTER TABLE shop_dealer_referee + ADD COLUMN source VARCHAR(32) NULL COMMENT '来源(如 goods_share)', + ADD COLUMN scene VARCHAR(255) NULL COMMENT '场景参数(溯源统计)'; + +-- 约束:同一 tenant 下,一个用户每个 level 只能有一条推荐关系 +ALTER TABLE shop_dealer_referee + ADD UNIQUE KEY uk_shop_dealer_referee_tenant_user_level (tenant_id, user_id, level); +``` + diff --git a/src/main/java/com/gxwebsoft/credit/controller/CreditJudgmentDebtorController.java b/src/main/java/com/gxwebsoft/credit/controller/CreditJudgmentDebtorController.java index e01569e..4f361a3 100644 --- a/src/main/java/com/gxwebsoft/credit/controller/CreditJudgmentDebtorController.java +++ b/src/main/java/com/gxwebsoft/credit/controller/CreditJudgmentDebtorController.java @@ -151,7 +151,7 @@ public class CreditJudgmentDebtorController extends BaseController { /** * 根据企业名称匹配企业并更新 companyId(匹配 CreditCompany.name / CreditCompany.matchName) * - *
默认仅更新 companyId 为空的记录;如需覆盖更新,传 onlyNull=false。
+ *默认仅更新 companyId=0 的记录;如需覆盖更新,传 onlyNull=false。
*/ @PreAuthorize("hasAuthority('credit:creditJudgmentDebtor:update')") @OperationLog @@ -170,7 +170,7 @@ public class CreditJudgmentDebtorController extends BaseController { .eq(currentTenantId != null, CreditJudgmentDebtor::getTenantId, currentTenantId) .isNotNull(CreditJudgmentDebtor::getName); if (Boolean.TRUE.equals(onlyNull)) { - debtorQuery.isNull(CreditJudgmentDebtor::getCompanyId); + debtorQuery.eq(CreditJudgmentDebtor::getCompanyId, 0); } if (limit != null && limit > 0) { debtorQuery.last("limit " + Math.min(limit, 200000)); @@ -269,7 +269,7 @@ public class CreditJudgmentDebtorController extends BaseController { boolean needUpdate = d.getCompanyId() == null || !companyId.equals(d.getCompanyId()); if (Boolean.TRUE.equals(onlyNull)) { - needUpdate = d.getCompanyId() == null; + needUpdate = d.getCompanyId() != null && d.getCompanyId() == 0; } if (!needUpdate) { continue;