# 商户身份验证接口逻辑变更说明

## 变更时间
2025-01-xx

## 变更原因
原有接口 `/alienStore/ali/getIdInfo` 在 alien-store 服务中业务逻辑有修改，需要同步更新到 alien-store-platform 服务中的 `/merchantAuth/verifyIdInfo` 接口。

## 业务逻辑变更对比

### 原逻辑（已废弃）

#### 用户端（appType=0）
```java
// 简单查询 life_user 表
size = lifeUserMapper.selectCount(
    new LambdaQueryWrapper<LifeUser>()
        .eq(LifeUser::getIdCard, idCard)
        .eq(LifeUser::getRealName, name)
);
```

#### 商家端（appType=1）
```java
// 简单查询 store_user 表
size = storeUserMapper.selectCount(
    new LambdaQueryWrapper<StoreUser>()
        .eq(StoreUser::getIdCard, idCard)
        .eq(StoreUser::getName, name)
);
```

---

### 新逻辑（当前使用）

#### 用户端（appType=0）
```java
// 查询未注销的用户（增加 logout_flag=0 条件）
size = lifeUserMapper.selectCount(
    new LambdaQueryWrapper<LifeUser>()
        .eq(LifeUser::getIdCard, idCard)
        .eq(LifeUser::getRealName, name)
        .eq(LifeUser::getLogoutFlag, 0)  // 新增：只查询未注销的用户
);
```

**变更说明：**
- 增加了 `logout_flag = 0` 条件
- 只允许未注销的用户使用该身份证进行认证
- 已注销的用户（logout_flag=1）可以使用相同身份证重新注册

#### 商家端（appType=1）
```java
// 查询已入住或审核中的商家（多步骤查询）
// 1. 根据身份证和姓名查询商户用户
List<StoreUser> storeUserList = storeUserMapper.selectList(
    new LambdaQueryWrapper<StoreUser>()
        .eq(StoreUser::getIdCard, idCard)
        .eq(StoreUser::getName, name)
);

// 2. 获取这些商户用户绑定的店铺ID
List<Integer> storeIds = storeUserList.stream()
        .map(StoreUser::getStoreId)
        .filter(Objects::nonNull)
        .collect(Collectors.toList());

// 3. 查询非审核失败状态的店铺
if (!storeIds.isEmpty()) {
    size = storeInfoMapper.selectCount(
        new LambdaQueryWrapper<StoreInfo>()
            .in(StoreInfo::getId, storeIds)
            .notIn(StoreInfo::getStoreApplicationStatus, 2)  // 排除审核失败的店铺
    );
}
```

**变更说明：**
- 不再直接统计 `store_user` 表记录数
- 改为查询商户用户绑定的店铺信息
- 只统计**非审核失败状态**的店铺（`storeApplicationStatus != 2`）
- 审核失败的店铺（status=2）可以使用相同身份证重新申请

---

## 店铺审核状态说明

| 状态值 | 状态名称 | 说明 | 是否允许重复使用身份证 |
|--------|---------|------|---------------------|
| 0 | 待审核 | 店铺申请已提交，等待审核 | ❌ 不允许 |
| 1 | 审核通过 | 店铺申请审核通过，正常营业 | ❌ 不允许 |
| 2 | 审核失败 | 店铺申请被拒绝 | ✅ **允许** |

---

## 业务场景说明

### 场景1：用户注销后重新注册
**原逻辑问题：**
- 用户注销账号后，身份证仍然被占用
- 无法使用相同身份证重新注册

**新逻辑解决：**
- 查询时只统计未注销的用户（`logout_flag=0`）
- 已注销的用户（`logout_flag=1`）不会被统计
- 用户可以使用相同身份证重新注册

### 场景2：商家审核失败后重新申请
**原逻辑问题：**
- 商家申请被拒绝后，身份证仍然被占用
- 无法使用相同身份证重新申请店铺

**新逻辑解决：**
- 查询时排除审核失败的店铺（`storeApplicationStatus=2`）
- 审核失败的店铺不会阻止重新申请
- 商家可以使用相同身份证重新提交申请

### 场景3：一人一店限制
**业务规则：**
- 一个身份证只能有一个**有效**的店铺
- 有效店铺：待审核（status=0）或审核通过（status=1）
- 审核失败的店铺不算在内

---

## 代码变更详情

### 变更文件
`alien-store-platform/src/main/java/shop/alien/storeplatform/service/impl/MerchantAuthServiceImpl.java`

### 新增依赖
```java
import shop.alien.entity.store.StoreInfo;
import shop.alien.mapper.StoreInfoMapper;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
```

### 关键代码变更

#### 1. 用户端查询
```java
// 旧代码
userWrapper.eq(LifeUser::getIdCard, idCard)
           .eq(LifeUser::getRealName, name);

// 新代码
userWrapper.eq(LifeUser::getIdCard, idCard)
           .eq(LifeUser::getRealName, name)
           .eq(LifeUser::getLogoutFlag, 0);  // 新增
```

#### 2. 商家端查询
```java
// 旧代码（直接查询）
LambdaQueryWrapper<StoreUser> storeWrapper = new LambdaQueryWrapper<>();
storeWrapper.eq(StoreUser::getIdCard, idCard)
           .eq(StoreUser::getName, name);
size = storeUserMapper.selectCount(storeWrapper);

// 新代码（多表联查）
// 第一步：查询商户用户
List<StoreUser> storeUserList = storeUserMapper.selectList(storeUserWrapper);

// 第二步：提取店铺ID
List<Integer> storeIds = storeUserList.stream()
        .map(StoreUser::getStoreId)
        .filter(Objects::nonNull)
        .collect(Collectors.toList());

// 第三步：查询有效店铺
if (!storeIds.isEmpty()) {
    size = storeInfoMapper.selectCount(
        new LambdaQueryWrapper<StoreInfo>()
            .in(StoreInfo::getId, storeIds)
            .notIn(StoreInfo::getStoreApplicationStatus, 2)
    );
}
```

---

## 测试用例

### 测试用例1：用户端 - 未注销用户
```bash
# 场景：用户已注册且未注销
# 期望：返回"该身份证已实名认证过"
curl -X GET "http://localhost:8080/merchantAuth/verifyIdInfo?name=张三&idCard=110101199001011234&appType=0"
```

### 测试用例2：用户端 - 已注销用户
```bash
# 场景：用户已注销（logout_flag=1）
# 期望：可以重新注册，返回"身份验证成功"
curl -X GET "http://localhost:8080/merchantAuth/verifyIdInfo?name=李四&idCard=110101199001011235&appType=0"
```

### 测试用例3：商家端 - 有审核通过的店铺
```bash
# 场景：商家有审核通过的店铺（status=1）
# 期望：返回"该身份证已实名认证过"
curl -X GET "http://localhost:8080/merchantAuth/verifyIdInfo?name=王五&idCard=110101199001011236&appType=1"
```

### 测试用例4：商家端 - 只有审核失败的店铺
```bash
# 场景：商家只有审核失败的店铺（status=2）
# 期望：可以重新申请，返回"身份验证成功"
curl -X GET "http://localhost:8080/merchantAuth/verifyIdInfo?name=赵六&idCard=110101199001011237&appType=1"
```

### 测试用例5：商家端 - 有待审核的店铺
```bash
# 场景：商家有待审核的店铺（status=0）
# 期望：返回"该身份证已实名认证过"
curl -X GET "http://localhost:8080/merchantAuth/verifyIdInfo?name=孙七&idCard=110101199001011238&appType=1"
```

---

## 数据库字段说明

### life_user 表
```sql
-- logout_flag 字段
logout_flag TINYINT DEFAULT 0 COMMENT '注销标记(0:未注销, 1:已注销)'
```

### store_info 表
```sql
-- store_application_status 字段
store_application_status TINYINT DEFAULT 0 COMMENT '店铺申请审核状态(0:待审核, 1:审核通过, 2:审核失败)'
```

---

## 影响范围

### 接口行为变更
1. **用户端**：已注销用户现在可以使用相同身份证重新注册
2. **商家端**：审核失败的商家现在可以使用相同身份证重新申请

### 向后兼容性
- ✅ 接口路径不变
- ✅ 请求参数不变
- ✅ 响应格式不变
- ⚠️ 业务逻辑变更（更宽松的验证规则）

### 潜在风险
- 无风险，变更使业务逻辑更加合理
- 允许用户在注销后重新注册
- 允许商家在审核失败后重新申请

---

## 部署注意事项

1. **数据库检查**
   - 确认 `life_user` 表有 `logout_flag` 字段
   - 确认 `store_info` 表有 `store_application_status` 字段

2. **代码部署**
   - 直接部署即可，无需额外配置
   - 无需数据迁移

3. **测试验证**
   - 验证已注销用户可以重新注册
   - 验证审核失败的商家可以重新申请
   - 验证正常用户和商家仍然被正确拦截

---

## 版本信息

| 版本 | 日期 | 说明 |
|------|------|------|
| v1.0.0 | 2025-01-xx | 初始版本 |
| v1.1.0 | 2025-01-xx | **同步 alien-store 最新业务逻辑** |

---

**变更人员：** AI Assistant  
**审核状态：** 待审核  
**测试状态：** 待测试

