Explorar el Código

docs(api): 添加商户用户信息查询与店铺草稿接口文档

- 编写根据手机号获取商户用户信息接口文档- 编写店铺入住申请草稿接口文档
- 编写基础数据查询接口文档
- 包含接口详情、请求响应示例、业务逻辑说明
- 添加数据库表结构与字段说明
- 提供测试用例与注意事项
- 统一web端商户平台接口文档规范
wxd hace 1 mes
padre
commit
8a087b905c

+ 2 - 1
alien-store-platform/doc/LOGIN_USER_UTIL_README.md

@@ -115,7 +115,7 @@ public class StoreServiceImpl {
 
 ## 详细文档
 
-请查看完整文档:[LOGIN_USER_UTIL_GUIDE.md](LOGIN_USER_UTIL_GUIDE.md)
+请查看完整文档:[LOGIN_USER_UTIL_GUIDE.md](商户登录util)
 
 使用示例代码:[LoginUserUtilExample.java](../src/main/java/shop/alien/storeplatform/example/LoginUserUtilExample.java)
 
@@ -125,3 +125,4 @@ public class StoreServiceImpl {
 **日期**: 2025-11-17  
 **作者**: ssk
 
+

+ 18 - 0
alien-store-platform/src/main/java/shop/alien/storeplatform/controller/MerchantUserController.java

@@ -5,6 +5,7 @@ import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.web.bind.annotation.*;
 import shop.alien.entity.result.R;
+import shop.alien.entity.store.StoreUser;
 import shop.alien.entity.store.vo.StoreUserVo;
 import shop.alien.storeplatform.service.MerchantUserService;
 
@@ -44,6 +45,23 @@ public class MerchantUserController {
             return R.fail(e.getMessage());
         }
     }
+
+    @ApiOperation("修改商户用户信息")
+    @ApiOperationSupport(order = 2)
+    @PostMapping("/updateMerchantUserInfo")
+    public R<Boolean> updateMerchantUserInfo(@RequestBody StoreUser storeUser) {
+        log.info("MerchantUserController.updateMerchantUserInfo?storeUser={}", storeUser);
+        try {
+            boolean success = merchantUserService.updateMerchantUserInfo(storeUser);
+            if (success) {
+                return R.success("修改成功");
+            }
+            return R.fail("修改失败");
+        } catch (Exception e) {
+            log.error("MerchantUserController.updateMerchantUserInfo ERROR: {}", e.getMessage(), e);
+            return R.fail("修改失败:" + e.getMessage());
+        }
+    }
 }
 
 

+ 1 - 0
alien-store-platform/src/main/java/shop/alien/storeplatform/example/LoginUserUtilExample.java

@@ -252,3 +252,4 @@ public class LoginUserUtilExample {
     }
 }
 
+

+ 9 - 0
alien-store-platform/src/main/java/shop/alien/storeplatform/service/MerchantUserService.java

@@ -1,5 +1,6 @@
 package shop.alien.storeplatform.service;
 
+import shop.alien.entity.store.StoreUser;
 import shop.alien.entity.store.vo.StoreUserVo;
 
 /**
@@ -17,6 +18,14 @@ public interface MerchantUserService {
      * @return StoreUserVo
      */
     StoreUserVo getMerchantByPhone(String phone);
+
+    /**
+     * 修改商户用户信息
+     *
+     * @param storeUser 用户信息(包含id和需要修改的字段)
+     * @return 是否修改成功
+     */
+    boolean updateMerchantUserInfo(StoreUser storeUser);
 }
 
 

+ 55 - 0
alien-store-platform/src/main/java/shop/alien/storeplatform/service/impl/MerchantUserServiceImpl.java

@@ -3,6 +3,7 @@ package shop.alien.storeplatform.service.impl;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
 import shop.alien.entity.store.StoreUser;
@@ -90,6 +91,60 @@ public class MerchantUserServiceImpl implements MerchantUserService {
                 phone, user.getId());
         return storeUserVo;
     }
+
+    @Override
+    public boolean updateMerchantUserInfo(StoreUser storeUserParam) {
+        log.info("MerchantUserServiceImpl.updateMerchantUserInfo - 开始修改商户用户信息: userId={}", 
+                storeUserParam.getId());
+
+        if (storeUserParam.getId() == null) {
+            log.warn("MerchantUserServiceImpl.updateMerchantUserInfo - 用户ID为空");
+            throw new RuntimeException("用户ID不能为空");
+        }
+
+        // 构建更新对象(只更新非空字段)
+        StoreUser storeUser = new StoreUser();
+        storeUser.setId(storeUserParam.getId());
+
+        // 昵称
+        if (StringUtils.isNotEmpty(storeUserParam.getNickName())) {
+            storeUser.setNickName(storeUserParam.getNickName());
+            log.debug("MerchantUserServiceImpl.updateMerchantUserInfo - 更新昵称: {}", storeUserParam.getNickName());
+        }
+
+        // 身份证号
+        if (StringUtils.isNotEmpty(storeUserParam.getIdCard())) {
+            storeUser.setIdCard(storeUserParam.getIdCard());
+            log.debug("MerchantUserServiceImpl.updateMerchantUserInfo - 更新身份证号");
+        }
+
+        // 姓名
+        if (StringUtils.isNotEmpty(storeUserParam.getName())) {
+            storeUser.setName(storeUserParam.getName());
+            log.debug("MerchantUserServiceImpl.updateMerchantUserInfo - 更新姓名: {}", storeUserParam.getName());
+        }
+
+        // 账号简介
+        if (StringUtils.isNotEmpty(storeUserParam.getAccountBlurb())) {
+            storeUser.setAccountBlurb(storeUserParam.getAccountBlurb());
+            log.debug("MerchantUserServiceImpl.updateMerchantUserInfo - 更新账号简介");
+        }
+
+        // 头像
+        if (StringUtils.isNotEmpty(storeUserParam.getHeadImg())) {
+            storeUser.setHeadImg(storeUserParam.getHeadImg());
+            log.debug("MerchantUserServiceImpl.updateMerchantUserInfo - 更新头像");
+        }
+
+        // 执行更新
+        int updateResult = storeUserMapper.updateById(storeUser);
+        boolean success = updateResult > 0;
+
+        log.info("MerchantUserServiceImpl.updateMerchantUserInfo - 修改完成: userId={}, success={}", 
+                storeUserParam.getId(), success);
+
+        return success;
+    }
 }
 
 

+ 1 - 0
alien-store-platform/src/main/java/shop/alien/storeplatform/util/LoginUserUtil.java

@@ -244,3 +244,4 @@ public class LoginUserUtil {
     }
 }
 
+

+ 536 - 0
alien-store-platform/接口文档/04-根据手机号获取商户用户信息接口.md

@@ -0,0 +1,536 @@
+# 根据手机号获取商户用户信息接口文档
+
+## 概述
+
+本文档描述了从 `alien-store`(app端商户)迁移到 `alien-store-platform`(web端商户)的根据手机号获取商户用户信息接口。
+
+## 接口详情
+
+### 根据手机号获取商户用户信息
+
+**接口描述**:根据商户手机号查询商户用户的完整信息,包括基本信息、账户状态、余额等,如果用户处于注销中状态,会返回注销倒计时。
+
+#### 原接口
+- **服务**:alien-store(app端商户)
+- **路径**:`GET /alienStore/store/user/getUserByPhone?phone=15242687180`
+- **Controller**:`StoreUserController.getUserByPhone()`
+- **Service**:`StoreUserServiceImpl.getUserByPhone()`
+
+#### 新接口
+- **服务**:alien-store-platform(web端商户)
+- **路径**:`GET /alienStorePlatform/merchantUser/getMerchantByPhone?phone=15242687180`
+- **Controller**:`MerchantUserController.getMerchantByPhone()`
+- **Service**:`MerchantUserServiceImpl.getMerchantByPhone()`
+
+#### 请求参数
+
+**Query 参数**:
+
+| 参数名 | 类型 | 必填 | 说明 |
+|--------|------|------|------|
+| phone | String | 是 | 商户手机号 |
+
+**请求示例**:
+
+```
+GET /alienStorePlatform/merchantUser/getMerchantByPhone?phone=15242687180
+```
+
+#### 响应参数
+
+**成功响应(用户存在)**:
+
+```json
+{
+  "code": 200,
+  "msg": "success",
+  "data": {
+    "id": 123,
+    "phone": "15242687180",
+    "name": "张三",
+    "nickName": "店铺老板",
+    "headImg": "https://example.com/avatar.jpg",
+    "accountBlurb": "这是一家优质店铺",
+    "storeId": 102,
+    "status": 1,
+    "money": 10000,
+    "moneyStr": "100.00",
+    "payPassword": "******",
+    "idCard": "410***********1234",
+    "realName": "张三",
+    "logoutFlag": 0,
+    "logoutTime": null,
+    "logoutReason": null,
+    "countdown": 0,
+    "createdTime": "2024-01-01 10:00:00",
+    "updatedTime": "2025-01-15 14:30:00"
+  },
+  "success": true
+}
+```
+
+**成功响应(用户不存在)**:
+
+```json
+{
+  "code": 500,
+  "msg": "手机号不存在",
+  "data": null,
+  "success": false
+}
+```
+
+**成功响应(用户注销中)**:
+
+```json
+{
+  "code": 200,
+  "msg": "success",
+  "data": {
+    "id": 123,
+    "phone": "15242687180",
+    "name": "张三",
+    "status": -1,
+    "money": 10000,
+    "moneyStr": "100.00",
+    "logoutFlag": 1,
+    "logoutTime": "2025-01-15 10:00:00",
+    "logoutReason": "个人原因",
+    "countdown": 518400000,
+    "createdTime": "2024-01-01 10:00:00",
+    "updatedTime": "2025-01-15 10:00:00"
+  },
+  "success": true
+}
+```
+
+**失败响应(查询错误)**:
+
+```json
+{
+  "code": 500,
+  "msg": "{错误信息}",
+  "data": null,
+  "success": false
+}
+```
+
+#### 响应字段说明
+
+##### 基本信息字段
+
+| 字段名 | 类型 | 说明 |
+|--------|------|------|
+| id | Integer | 商户用户ID |
+| phone | String | 手机号 |
+| name | String | 真实姓名 |
+| nickName | String | 昵称 |
+| headImg | String | 头像URL |
+| accountBlurb | String | 账户简介 |
+| storeId | Integer | 绑定的店铺ID |
+| idCard | String | 身份证号 |
+| realName | String | 实名 |
+
+##### 状态相关字段
+
+| 字段名 | 类型 | 说明 |
+|--------|------|------|
+| status | Integer | 账户状态(-1:注销中, 1:正常, 0:禁用)|
+| logoutFlag | Integer | 注销标记(0:正常, 1:已申请注销)|
+| logoutTime | DateTime | 注销申请时间 |
+| logoutReason | String | 注销原因 |
+| countdown | Long | 注销倒计时(毫秒),仅当status=-1时有值 |
+
+##### 财务相关字段
+
+| 字段名 | 类型 | 说明 |
+|--------|------|------|
+| money | Integer | 账户余额(单位:分)|
+| moneyStr | String | 账户余额(单位:元,格式化后)|
+| payPassword | String | 支付密码(脱敏)|
+
+##### 时间相关字段
+
+| 字段名 | 类型 | 说明 |
+|--------|------|------|
+| createdTime | DateTime | 创建时间 |
+| updatedTime | DateTime | 更新时间 |
+
+#### 业务逻辑
+
+##### 1. 用户查询
+
+```java
+LambdaQueryWrapper<StoreUser> queryWrapper = new LambdaQueryWrapper<>();
+queryWrapper.eq(StoreUser::getPhone, phone);
+StoreUser user = storeUserMapper.selectOne(queryWrapper);
+```
+
+- 根据手机号查询 `store_user` 表
+- 使用 MyBatis-Plus 的 LambdaQueryWrapper
+- 查询条件:`phone` 字段精确匹配
+
+##### 2. 用户不存在处理
+
+```java
+if (user == null) {
+    return new StoreUserVo();  // 返回空对象
+}
+```
+
+- 如果查询结果为空,返回空的 `StoreUserVo` 对象
+- Controller 层判断 `id` 是否为空,返回"手机号不存在"
+
+##### 3. 注销倒计时计算(仅当 status=-1)
+
+```java
+if (user.getStatus() == -1) {
+    // 获取注销申请时间
+    LocalDateTime logoutDateTime = user.getLogoutTime()
+            .toInstant()
+            .atZone(ZoneId.systemDefault())
+            .toLocalDateTime();
+    
+    // 计算7天后的时间(冷静期结束时间)
+    LocalDateTime futureDateTime = logoutDateTime.plusDays(7);
+    
+    // 获取当前时间
+    LocalDateTime nowDateTime = LocalDateTime.now();
+    
+    // 计算剩余时间
+    Duration duration = Duration.between(nowDateTime, futureDateTime);
+    
+    // 转换为毫秒
+    long countdownMillis = duration.toMillis();
+    
+    storeUserVo.setCountdown(countdownMillis);
+}
+```
+
+**注销倒计时说明**:
+- **触发条件**:`status = -1`(账户注销中)
+- **计算逻辑**:
+  - 冷静期:7天
+  - 起始时间:`logoutTime`(注销申请时间)
+  - 结束时间:`logoutTime + 7天`
+  - 倒计时:`结束时间 - 当前时间`
+- **单位**:毫秒(milliseconds)
+- **示例**:
+  - 注销申请时间:2025-01-15 10:00:00
+  - 冷静期结束时间:2025-01-22 10:00:00
+  - 当前时间:2025-01-16 10:00:00
+  - 倒计时:6天 = 518400000毫秒
+
+##### 4. 金额格式转换
+
+```java
+String moneyStr = new BigDecimal(user.getMoney())
+        .divide(new BigDecimal(100), 2, RoundingMode.DOWN)
+        .toString();
+storeUserVo.setMoneyStr(moneyStr);
+```
+
+- **输入**:`money` 字段(单位:分,Integer类型)
+- **输出**:`moneyStr` 字段(单位:元,String类型)
+- **转换规则**:
+  - 除以100转换为元
+  - 保留2位小数
+  - 舍入模式:DOWN(向下舍入)
+- **示例**:
+  - `money = 10000` → `moneyStr = "100.00"`
+  - `money = 12345` → `moneyStr = "123.45"`
+  - `money = 12346` → `moneyStr = "123.46"`
+
+##### 5. 返回结果
+
+- 使用 `BeanUtils.copyProperties()` 复制用户基本信息
+- 设置 `moneyStr` 字段
+- 如果是注销中状态,设置 `countdown` 字段
+- 返回完整的 `StoreUserVo` 对象
+
+---
+
+## 业务场景
+
+### 场景 1:正常用户查询
+
+**请求**:
+```
+GET /alienStorePlatform/merchantUser/getMerchantByPhone?phone=15242687180
+```
+
+**用户状态**:
+- `status = 1`(正常)
+- `logoutFlag = 0`(未申请注销)
+
+**响应特点**:
+- ✅ 返回完整用户信息
+- ✅ `countdown` 为 0(未计算)
+- ✅ `moneyStr` 为格式化后的金额
+
+---
+
+### 场景 2:注销中的用户
+
+**请求**:
+```
+GET /alienStorePlatform/merchantUser/getMerchantByPhone?phone=15242687180
+```
+
+**用户状态**:
+- `status = -1`(注销中)
+- `logoutFlag = 1`(已申请注销)
+- `logoutTime = 2025-01-15 10:00:00`
+
+**响应特点**:
+- ✅ 返回完整用户信息
+- ✅ `countdown` 为剩余冷静期时间(毫秒)
+- ⚠️ 用户在冷静期内可以撤销注销
+- ⚠️ 冷静期结束后账户将被永久注销
+
+---
+
+### 场景 3:用户不存在
+
+**请求**:
+```
+GET /alienStorePlatform/merchantUser/getMerchantByPhone?phone=99999999999
+```
+
+**响应**:
+```json
+{
+  "code": 500,
+  "msg": "手机号不存在",
+  "data": null,
+  "success": false
+}
+```
+
+---
+
+## 数据库表结构
+
+### store_user(商户用户表)
+
+| 字段名 | 类型 | 说明 |
+|--------|------|------|
+| id | INT | 主键,自增 |
+| phone | VARCHAR(11) | 手机号(唯一) |
+| name | VARCHAR(50) | 真实姓名 |
+| nick_name | VARCHAR(50) | 昵称 |
+| head_img | VARCHAR(255) | 头像URL |
+| account_blurb | TEXT | 账户简介 |
+| store_id | INT | 绑定的店铺ID |
+| status | INT | 账户状态(-1:注销中, 0:禁用, 1:正常) |
+| money | INT | 账户余额(单位:分) |
+| pay_password | VARCHAR(100) | 支付密码(加密) |
+| id_card | VARCHAR(18) | 身份证号 |
+| real_name | VARCHAR(50) | 实名 |
+| logout_flag | INT | 注销标记(0:正常, 1:已申请注销) |
+| logout_time | DATETIME | 注销申请时间 |
+| logout_reason | VARCHAR(255) | 注销原因 |
+| delete_flag | INT | 删除标记(0:未删除, 1:已删除) |
+| created_time | DATETIME | 创建时间 |
+| updated_time | DATETIME | 更新时间 |
+
+**重要索引**:
+- PRIMARY KEY (`id`)
+- UNIQUE KEY `uk_phone` (`phone`)
+
+---
+
+## 相关文件
+
+### Controller 层
+- `alien-store-platform/src/main/java/shop/alien/storeplatform/controller/MerchantUserController.java`
+
+### Service 层
+- `alien-store-platform/src/main/java/shop/alien/storeplatform/service/MerchantUserService.java`
+- `alien-store-platform/src/main/java/shop/alien/storeplatform/service/impl/MerchantUserServiceImpl.java`
+
+### Entity/Mapper 层
+- `alien-entity/src/main/java/shop/alien/entity/store/StoreUser.java`
+- `alien-entity/src/main/java/shop/alien/entity/store/vo/StoreUserVo.java`
+- `alien-entity/src/main/java/shop/alien/mapper/StoreUserMapper.java`
+
+---
+
+## 测试建议
+
+### 测试用例 1:查询正常用户
+
+```bash
+curl -X GET "http://localhost:8080/alienStorePlatform/merchantUser/getMerchantByPhone?phone=15242687180"
+```
+
+**期望结果**:
+- 返回完整用户信息
+- `status = 1`
+- `logoutFlag = 0`
+- `countdown = 0`
+- `moneyStr` 格式正确(如:"100.00")
+
+---
+
+### 测试用例 2:查询注销中的用户
+
+**前置条件**:
+- 用户已申请注销
+- `status = -1`
+- `logoutTime` 在过去7天内
+
+```bash
+curl -X GET "http://localhost:8080/alienStorePlatform/merchantUser/getMerchantByPhone?phone=15242687180"
+```
+
+**期望结果**:
+- 返回用户信息
+- `status = -1`
+- `logoutFlag = 1`
+- `countdown > 0`(倒计时为正数)
+- `logoutTime` 和 `logoutReason` 有值
+
+---
+
+### 测试用例 3:查询不存在的用户
+
+```bash
+curl -X GET "http://localhost:8080/alienStorePlatform/merchantUser/getMerchantByPhone?phone=99999999999"
+```
+
+**期望结果**:
+```json
+{
+  "code": 500,
+  "msg": "手机号不存在",
+  "data": null,
+  "success": false
+}
+```
+
+---
+
+### 测试用例 4:金额格式验证
+
+**测试不同金额值的转换**:
+
+| 原始值(分) | 期望值(元) |
+|-------------|-------------|
+| 0 | "0.00" |
+| 100 | "1.00" |
+| 12345 | "123.45" |
+| 99999 | "999.99" |
+
+---
+
+### 测试用例 5:注销倒计时计算
+
+**场景**:用户在不同时间点查询倒计时
+
+| 注销申请时间 | 查询时间 | 期望倒计时 |
+|-------------|---------|----------|
+| 2025-01-15 10:00:00 | 2025-01-16 10:00:00 | 6天 = 518400000ms |
+| 2025-01-15 10:00:00 | 2025-01-22 09:00:00 | 1小时 = 3600000ms |
+| 2025-01-15 10:00:00 | 2025-01-22 10:00:00 | 0ms(冷静期结束) |
+| 2025-01-15 10:00:00 | 2025-01-23 10:00:00 | 负数(已超期) |
+
+---
+
+## 注意事项
+
+### 1. 账户状态说明
+
+| status 值 | 状态 | 说明 |
+|-----------|------|------|
+| -1 | 注销中 | 冷静期内,可撤销注销 |
+| 0 | 禁用 | 账户被管理员禁用 |
+| 1 | 正常 | 账户正常使用 |
+
+### 2. 注销冷静期机制
+
+- ⚠️ **冷静期时长**:7天(从申请注销时间开始计算)
+- ⚠️ **冷静期内**:
+  - 账户 `status = -1`
+  - `logoutFlag = 1`
+  - 用户可以撤销注销申请
+  - 返回 `countdown` 倒计时(毫秒)
+- ⚠️ **冷静期结束后**:
+  - 账户将被永久注销
+  - 所有数据将被清除
+  - 无法恢复
+
+### 3. 金额字段处理
+
+- ⚠️ **存储单位**:分(Integer)
+- ⚠️ **展示单位**:元(String)
+- ⚠️ **转换规则**:
+  - 分 ÷ 100 = 元
+  - 保留2位小数
+  - 向下舍入(RoundingMode.DOWN)
+- ⚠️ **示例**:10000分 = 100.00元
+
+### 4. 手机号查询
+
+- ⚠️ **查询字段**:`phone`(手机号字段)
+- ⚠️ **唯一性**:手机号在数据库中是唯一的
+- ⚠️ **查询结果**:
+  - 如果存在:返回唯一的用户记录
+  - 如果不存在:返回 `null`
+
+### 5. 空对象处理
+
+```java
+if (user == null) {
+    return new StoreUserVo();  // 返回空对象,不是null
+}
+```
+
+- Service 层返回空对象(不是 `null`)
+- Controller 层通过 `id` 字段判断是否为空
+- 避免空指针异常
+
+### 6. 时区处理
+
+```java
+LocalDateTime localDateTime = logoutTime
+    .toInstant()
+    .atZone(ZoneId.systemDefault())
+    .toLocalDateTime();
+```
+
+- 使用系统默认时区
+- 确保时间计算的准确性
+- 避免时区转换错误
+
+---
+
+## 接口对比
+
+| 功能 | 原接口(alien-store) | 新接口(alien-store-platform) |
+|------|----------------------|-------------------------------|
+| 根据手机号查询 | `/alienStore/store/user/getUserByPhone` | `/alienStorePlatform/merchantUser/getMerchantByPhone` |
+| 返回类型 | `R<StoreUser>` | `R<StoreUserVo>` |
+
+**主要变化**:
+- ✅ 接口路径更符合web端命名规范
+- ✅ Controller和Service命名更清晰(`MerchantUser`)
+- ✅ 返回类型统一为 `StoreUserVo`(扩展字段更丰富)
+- ✅ 代码结构更清晰,注释更完善
+
+---
+
+## 版本记录
+
+| 版本 | 日期 | 说明 | 作者 |
+|------|------|------|------|
+| 1.0.0 | 2025-01-xx | 初始版本,迁移商户用户查询功能 | ssk |
+
+---
+
+## 联系方式
+
+如有问题,请联系:
+- 开发团队:Alien Cloud Team
+- 邮箱:dev@alien.shop
+

+ 398 - 0
alien-store-platform/接口文档/10-店铺草稿接口.md

@@ -0,0 +1,398 @@
+# 店铺入住申请草稿接口文档
+
+## 概述
+
+本文档描述了从 `alien-store`(app端商户)迁移到 `alien-store-platform`(web端商户)的店铺入住申请草稿相关接口。
+
+## 接口列表
+
+### 1. 保存店铺入住申请草稿
+
+**接口描述**:保存商户填写的店铺入住申请草稿信息,支持随时保存,方便商户分多次填写。
+
+#### 原接口
+- **服务**:alien-store(app端商户)
+- **路径**:`POST /alienStore/store/info/saveStoreInfoDraft`
+- **Controller**:`StoreInfoController.saveStoreInfoDraft()`
+- **Service**:`StoreInfoServiceImpl.saveStoreInfoDraft()`
+
+#### 新接口
+- **服务**:alien-store-platform(web端商户)
+- **路径**:`POST /alienStorePlatform/storeManage/saveStoreDraft`
+- **Controller**:`StoreManageController.saveStoreDraft()`
+- **Service**:`StoreManageServiceImpl.saveStoreDraft()`
+
+#### 请求参数
+
+**Content-Type**: `application/json`
+
+**Body 参数**:`StoreInfoDraft` 对象
+
+| 参数名 | 类型 | 必填 | 说明 |
+|--------|------|------|------|
+| storeUserId | Integer | 是 | 商家用户ID(store_user 表 id)|
+| storeName | String | 否 | 门店名称 |
+| businessStatus | Integer | 否 | 营业状态(见字典表 businessStatus)|
+| storeTel | String | 否 | 门店电话 |
+| storeCapacity | Integer | 否 | 容纳人数 |
+| storeArea | Integer | 否 | 门店面积(见字典表 storeArea)|
+| storeAddress | String | 否 | 门店地址 |
+| storeBlurb | String | 否 | 门店简介 |
+| storeType | String | 否 | 门店类型,多选(见字典表 storeType)|
+| isChain | Integer | 否 | 是否连锁(0:否, 1:是)|
+| storePosition | String | 否 | 经度,纬度 |
+| storePass | String | 否 | 门店密码 |
+| passType | Integer | 否 | 密码状态(0:初始密码, 1:已修改)|
+| storeStatus | Integer | 否 | 门店状态(见字典表 storeStatus)|
+| businessSection | Integer | 否 | 经营板块ID(词典表 business_section)|
+| businessSectionName | String | 否 | 经营板块名称 |
+| businessTypes | String | 否 | 经营种类IDs(逗号分隔)|
+| businessTypesName | String | 否 | 经营种类名称(逗号分隔)|
+| queryAddress | String | 否 | 查询经纬度时查询地点存储 |
+| administrativeRegionProvinceName | String | 否 | 行政区域省名称(自动填充)|
+| administrativeRegionProvinceAdcode | String | 否 | 行政区域省adcode |
+| administrativeRegionCityName | String | 否 | 行政区域市名称(自动填充)|
+| administrativeRegionCityAdcode | String | 否 | 行政区域市adcode |
+| administrativeRegionDistrictName | String | 否 | 行政区域区名称(自动填充)|
+| administrativeRegionDistrictAdcode | String | 否 | 行政区域区adcode |
+| businessLicenseUrl | String | 否 | 营业执照地址(JSON字符串)|
+| contractUrl | String | 否 | 合同地址(JSON字符串)|
+| foodLicenceUrl | String | 否 | 经营许可证地址(JSON字符串)|
+
+**请求示例**:
+
+```json
+{
+  "storeUserId": 123,
+  "storeName": "张三的餐厅",
+  "storeTel": "0371-12345678",
+  "storeAddress": "河南省郑州市金水区某某路123号",
+  "administrativeRegionProvinceAdcode": "410000",
+  "administrativeRegionCityAdcode": "410100",
+  "administrativeRegionDistrictAdcode": "410105",
+  "businessSection": 1,
+  "businessTypes": "1,2,3",
+  "storePosition": "113.625368,34.746599",
+  "businessLicenseUrl": "[\"https://example.com/license1.jpg\"]"
+}
+```
+
+#### 响应参数
+
+**成功响应**:
+
+```json
+{
+  "code": 200,
+  "msg": "草稿保存成功",
+  "data": true,
+  "success": true
+}
+```
+
+**失败响应**:
+
+```json
+{
+  "code": 500,
+  "msg": "草稿保存失败",
+  "data": null,
+  "success": false
+}
+```
+
+#### 业务逻辑
+
+1. **行政区域处理**:
+   - 根据省/市/区的 adcode 自动查询并填充对应的名称
+   - 使用 `EssentialCityCodeMapper` 从 `essential_city_code` 表查询
+
+2. **空字段处理**:
+   - 对于 `businessLicenseUrl`、`contractUrl`、`foodLicenceUrl`
+   - 如果为空字符串,则设置为 `null`
+
+3. **数据插入**:
+   - 使用 `StoreInfoDraftMapper` 插入草稿数据
+   - MyBatis-Plus 自动填充 `createdTime`、`updatedTime` 等字段
+
+---
+
+### 2. 查询店铺入住申请草稿
+
+**接口描述**:查询指定商户用户最新保存的店铺入住申请草稿。
+
+#### 原接口
+- **服务**:alien-store(app端商户)
+- **路径**:`GET /alienStore/store/info/selectDraftByUserId`
+- **Controller**:`StoreInfoController.selectDraftByUserId()`
+- **Service**:`StoreInfoServiceImpl.selectDraftByUserId()`
+
+#### 新接口
+- **服务**:alien-store-platform(web端商户)
+- **路径**:`GET /alienStorePlatform/storeManage/getStoreDraft`
+- **Controller**:`StoreManageController.getStoreDraft()`
+- **Service**:`StoreManageServiceImpl.getStoreDraft()`
+
+#### 请求参数
+
+**Query 参数**:
+
+| 参数名 | 类型 | 必填 | 说明 |
+|--------|------|------|------|
+| storeUserId | int | 是 | 商户用户ID |
+
+**请求示例**:
+
+```
+GET /alienStorePlatform/storeManage/getStoreDraft?storeUserId=123
+```
+
+#### 响应参数
+
+**成功响应(有草稿)**:
+
+```json
+{
+  "code": 200,
+  "msg": "success",
+  "data": {
+    "id": 1,
+    "storeUserId": 123,
+    "storeName": "张三的餐厅",
+    "storeTel": "0371-12345678",
+    "storeAddress": "河南省郑州市金水区某某路123号",
+    "administrativeRegionProvinceName": "河南省",
+    "administrativeRegionProvinceAdcode": "410000",
+    "administrativeRegionCityName": "郑州市",
+    "administrativeRegionCityAdcode": "410100",
+    "administrativeRegionDistrictName": "金水区",
+    "administrativeRegionDistrictAdcode": "410105",
+    "businessSection": 1,
+    "businessSectionName": "餐饮",
+    "businessTypes": "1,2,3",
+    "businessTypesName": "中餐,西餐,快餐",
+    "storePosition": "113.625368,34.746599",
+    "businessLicenseUrl": "[\"https://example.com/license1.jpg\"]",
+    "createdTime": "2025-01-15 10:30:00",
+    "updatedTime": "2025-01-15 14:20:00"
+  },
+  "success": true
+}
+```
+
+**成功响应(无草稿)**:
+
+```json
+{
+  "code": 200,
+  "msg": "success",
+  "data": null,
+  "success": true
+}
+```
+
+**失败响应**:
+
+```json
+{
+  "code": 500,
+  "msg": "查询失败: {错误信息}",
+  "data": null,
+  "success": false
+}
+```
+
+#### 业务逻辑
+
+1. **查询条件**:
+   - 根据 `storeUserId` 查询草稿记录
+   - 按 `createdTime` 降序排序
+   - 返回最新的一条记录
+
+2. **数据返回**:
+   - 如果没有草稿记录,返回 `null`
+   - 如果有多条记录,返回最新的一条
+
+3. **软删除处理**:
+   - MyBatis-Plus 自动过滤 `deleteFlag=1` 的记录
+
+---
+
+## 数据库表结构
+
+### store_info_draft(门店草稿表)
+
+| 字段名 | 类型 | 说明 |
+|--------|------|------|
+| id | INT | 主键,自增 |
+| store_user_id | INT | 商家用户ID(store_user 表 id)|
+| store_name | VARCHAR(100) | 门店名称 |
+| business_status | INT | 营业状态 |
+| store_tel | VARCHAR(20) | 门店电话 |
+| store_capacity | INT | 容纳人数 |
+| store_area | INT | 门店面积 |
+| store_address | VARCHAR(255) | 门店地址 |
+| store_blurb | TEXT | 门店简介 |
+| store_type | VARCHAR(50) | 门店类型 |
+| is_chain | INT | 是否连锁 |
+| expiration_time | DATETIME | 到期时间 |
+| store_position | VARCHAR(50) | 经度,纬度 |
+| store_pass | VARCHAR(50) | 门店密码 |
+| pass_type | INT | 密码状态 |
+| store_status | INT | 门店状态 |
+| business_section | INT | 经营板块ID |
+| business_section_name | VARCHAR(50) | 经营板块名称 |
+| business_types | VARCHAR(255) | 经营种类IDs |
+| business_types_name | VARCHAR(255) | 经营种类名称 |
+| store_application_status | INT | 店铺申请审核状态 |
+| query_address | VARCHAR(255) | 查询经纬度时查询地点 |
+| administrative_region_province_name | VARCHAR(50) | 行政区域省名称 |
+| administrative_region_province_adcode | VARCHAR(20) | 行政区域省adcode |
+| administrative_region_city_name | VARCHAR(50) | 行政区域市名称 |
+| administrative_region_city_adcode | VARCHAR(20) | 行政区域市adcode |
+| administrative_region_district_name | VARCHAR(50) | 行政区域区名称 |
+| administrative_region_district_adcode | VARCHAR(20) | 行政区域区adcode |
+| logout_flag | INT | 注销账号(0:正常,1:已注销)|
+| logout_reason | VARCHAR(255) | 注销原因 |
+| logout_time | DATETIME | 注销时间 |
+| business_license_url | TEXT | 营业执照地址(JSON)|
+| contract_url | TEXT | 合同地址(JSON)|
+| food_licence_url | TEXT | 经营许可证地址(JSON)|
+| delete_flag | INT | 删除标记(0:未删除, 1:已删除)|
+| created_time | DATETIME | 创建时间 |
+| created_user_id | INT | 创建人ID |
+| updated_time | DATETIME | 修改时间 |
+| updated_user_id | INT | 修改人ID |
+
+---
+
+## 相关文件
+
+### Controller 层
+- `alien-store-platform/src/main/java/shop/alien/storeplatform/controller/StoreManageController.java`
+
+### Service 层
+- `alien-store-platform/src/main/java/shop/alien/storeplatform/service/StoreManageService.java`
+- `alien-store-platform/src/main/java/shop/alien/storeplatform/service/impl/StoreManageServiceImpl.java`
+
+### Entity 层
+- `alien-entity/src/main/java/shop/alien/entity/store/StoreInfoDraft.java`
+- `alien-entity/src/main/java/shop/alien/mapper/StoreInfoDraftMapper.java`
+
+---
+
+## 测试建议
+
+### 1. 保存草稿接口测试
+
+**测试用例 1:完整信息保存**
+```bash
+curl -X POST http://localhost:8080/alienStorePlatform/storeManage/saveStoreDraft \
+  -H "Content-Type: application/json" \
+  -d '{
+    "storeUserId": 123,
+    "storeName": "测试餐厅",
+    "storeTel": "0371-12345678",
+    "storeAddress": "河南省郑州市金水区测试路123号",
+    "administrativeRegionProvinceAdcode": "410000",
+    "administrativeRegionCityAdcode": "410100",
+    "administrativeRegionDistrictAdcode": "410105",
+    "businessSection": 1,
+    "businessTypes": "1,2",
+    "storePosition": "113.625368,34.746599"
+  }'
+```
+
+**测试用例 2:部分信息保存(草稿功能)**
+```bash
+curl -X POST http://localhost:8080/alienStorePlatform/storeManage/saveStoreDraft \
+  -H "Content-Type: application/json" \
+  -d '{
+    "storeUserId": 123,
+    "storeName": "测试餐厅"
+  }'
+```
+
+**测试用例 3:空字段处理**
+```bash
+curl -X POST http://localhost:8080/alienStorePlatform/storeManage/saveStoreDraft \
+  -H "Content-Type: application/json" \
+  -d '{
+    "storeUserId": 123,
+    "storeName": "测试餐厅",
+    "businessLicenseUrl": "",
+    "contractUrl": "",
+    "foodLicenceUrl": ""
+  }'
+```
+
+### 2. 查询草稿接口测试
+
+**测试用例 1:查询存在的草稿**
+```bash
+curl -X GET http://localhost:8080/alienStorePlatform/storeManage/getStoreDraft?storeUserId=123
+```
+
+**测试用例 2:查询不存在的草稿**
+```bash
+curl -X GET http://localhost:8080/alienStorePlatform/storeManage/getStoreDraft?storeUserId=999999
+```
+
+### 3. 业务流程测试
+
+**场景 1:分步填写**
+1. 第一次保存:仅填写基本信息(storeName, storeTel)
+2. 第二次保存:补充地址信息(storeAddress, 行政区域)
+3. 第三次保存:补充经营信息(businessSection, businessTypes)
+4. 查询草稿:验证最新记录包含所有信息
+
+**场景 2:多次保存覆盖**
+1. 保存草稿 A(基本信息)
+2. 保存草稿 B(完整信息)
+3. 查询草稿:验证返回最新的草稿 B
+
+**场景 3:行政区域自动填充**
+1. 保存草稿时提供 adcode
+2. 查询草稿
+3. 验证省/市/区名称已自动填充
+
+---
+
+## 注意事项
+
+### 1. 字段处理
+- ⚠️ 行政区域名称会根据 adcode 自动查询填充
+- ⚠️ 空字符串的图片URL字段会被设置为 `null`
+- ⚠️ 草稿数据不会进行完整性校验,允许部分字段为空
+
+### 2. 数据查询
+- ⚠️ 查询草稿时按创建时间降序,返回最新的一条
+- ⚠️ 软删除的草稿记录会被自动过滤
+- ⚠️ 如果没有草稿记录,返回 `null` 而不是报错
+
+### 3. 业务场景
+- ⚠️ 草稿可以多次保存,每次保存都会创建新记录
+- ⚠️ 查询时只返回最新的草稿记录
+- ⚠️ 草稿数据不会影响正式的店铺入住申请
+
+### 4. 与正式申请的关系
+- 草稿保存:`saveStoreDraft` - 保存未完成的申请信息
+- 正式申请:`applyStore` - 提交完整的入住申请并进入审核流程
+- 两者使用不同的表:`store_info_draft` vs `store_info`
+
+---
+
+## 版本记录
+
+| 版本 | 日期 | 说明 | 作者 |
+|------|------|------|------|
+| 1.0.0 | 2025-01-xx | 初始版本,迁移草稿功能 | ssk |
+
+---
+
+## 联系方式
+
+如有问题,请联系:
+- 开发团队:Alien Cloud Team
+- 邮箱:dev@alien.shop
+

+ 484 - 0
alien-store-platform/接口文档/13-基础数据查询接口.md

@@ -0,0 +1,484 @@
+# Web端基础数据查询接口开发文档
+
+## 一、接口概述
+
+本次开发在 `alien-store-platform` 服务中新增了基础数据查询接口,将原 `alien-store` 服务中分散在不同 Controller 的基础数据查询接口统一整合到一个 `BaseDataController` 中,方便 web 端商户平台统一管理和调用。
+
+## 二、接口列表
+
+### 2.1 根据关键词获取地址提示
+
+**接口路径:** `GET /baseData/getAddressPrompt`
+
+**接口说明:** 根据输入的地址关键词,返回高德地图的地址提示列表,支持按城市过滤
+
+**原接口路径:** `/alienStore/gaode/getInputPrompt`
+
+**请求参数:**
+
+| 参数名 | 类型 | 必填 | 说明 | 示例 |
+|--------|------|------|------|------|
+| addressName | String | 是 | 地址关键词 | "中关村" |
+| city | String | 否 | 城市名称 | "北京市" |
+
+**请求示例:**
+```http
+GET /baseData/getAddressPrompt?addressName=中关村&city=北京市
+```
+
+**响应示例:**
+```json
+{
+  "code": 200,
+  "success": true,
+  "msg": "操作成功",
+  "data": {
+    "status": "1",
+    "info": "OK",
+    "infocode": "10000",
+    "count": "10",
+    "tips": [
+      {
+        "id": "B000A8XZL4",
+        "name": "中关村",
+        "district": "北京市海淀区",
+        "adcode": "110108",
+        "location": "116.313676,39.982718",
+        "address": "中关村大街",
+        "typecode": "190301"
+      }
+    ]
+  }
+}
+```
+
+---
+
+### 2.2 获取行政区划数据
+
+**接口路径:** `GET /baseData/getDistrict`
+
+**接口说明:** 根据行政区划代码获取省市区数据,支持级联查询
+
+**原接口路径:** `/alienStore/gaode/getDistrict`
+
+**请求参数:**
+
+| 参数名 | 类型 | 必填 | 说明 | 默认值 | 示例 |
+|--------|------|------|------|--------|------|
+| adCode | String | 否 | 行政区划代码 | 100000 | "100000" |
+
+**行政区划代码说明:**
+- `100000`:中国(返回所有省级数据)
+- `410000`:河南省(返回河南省所有市级数据)
+- `410300`:洛阳市(返回洛阳市所有区县数据)
+
+**请求示例:**
+```http
+# 查询所有省份
+GET /baseData/getDistrict?adCode=100000
+
+# 查询河南省所有城市
+GET /baseData/getDistrict?adCode=410000
+
+# 查询洛阳市所有区县
+GET /baseData/getDistrict?adCode=410300
+```
+
+**响应示例:**
+```json
+{
+  "code": 200,
+  "success": true,
+  "msg": "操作成功",
+  "data": {
+    "status": "1",
+    "info": "OK",
+    "infocode": "10000",
+    "districts": [
+      {
+        "citycode": [],
+        "adcode": "100000",
+        "name": "中华人民共和国",
+        "center": "116.3683244,39.915085",
+        "level": "country",
+        "districts": [
+          {
+            "citycode": "010",
+            "adcode": "110000",
+            "name": "北京市",
+            "center": "116.405285,39.904989",
+            "level": "province"
+          }
+        ]
+      }
+    ]
+  }
+}
+```
+
+---
+
+### 2.3 获取经营板块基础数据
+
+**接口路径:** `GET /baseData/getBusinessSection`
+
+**接口说明:** 获取所有经营板块数据,用于商户选择经营类型
+
+**原接口路径:** `/alienStore/store/info/getBusinessSection`
+
+**请求参数:** 无
+
+**请求示例:**
+```http
+GET /baseData/getBusinessSection
+```
+
+**响应示例:**
+```json
+{
+  "code": 200,
+  "success": true,
+  "msg": "操作成功",
+  "data": [
+    {
+      "id": 1,
+      "typeName": "business_section",
+      "dictId": "1",
+      "dictDetail": "餐饮美食",
+      "parentId": 0
+    },
+    {
+      "id": 2,
+      "typeName": "business_section",
+      "dictId": "2",
+      "dictDetail": "休闲娱乐",
+      "parentId": 0
+    },
+    {
+      "id": 3,
+      "typeName": "business_section",
+      "dictId": "3",
+      "dictDetail": "生活服务",
+      "parentId": 0
+    }
+  ]
+}
+```
+
+---
+
+### 2.4 获取经营种类基础数据
+
+**接口路径:** `GET /baseData/getBusinessTypes`
+
+**接口说明:** 根据经营板块ID获取该板块下的所有经营种类
+
+**原接口路径:** `/alienStore/store/info/getBusinessSectionTypes`
+
+**请求参数:**
+
+| 参数名 | 类型 | 必填 | 说明 | 示例 |
+|--------|------|------|------|------|
+| parentId | String | 是 | 经营板块ID(dictId) | "1" |
+
+**请求示例:**
+```http
+GET /baseData/getBusinessTypes?parentId=1
+```
+
+**响应示例:**
+```json
+{
+  "code": 200,
+  "success": true,
+  "msg": "操作成功",
+  "data": [
+    {
+      "id": 101,
+      "typeName": "business_section",
+      "dictId": "101",
+      "dictDetail": "中餐",
+      "parentId": 1
+    },
+    {
+      "id": 102,
+      "typeName": "business_section",
+      "dictId": "102",
+      "dictDetail": "西餐",
+      "parentId": 1
+    },
+    {
+      "id": 103,
+      "typeName": "business_section",
+      "dictId": "103",
+      "dictDetail": "火锅",
+      "parentId": 1
+    },
+    {
+      "id": 104,
+      "typeName": "business_section",
+      "dictId": "104",
+      "dictDetail": "烧烤",
+      "parentId": 1
+    }
+  ]
+}
+```
+
+---
+
+## 三、业务流程说明
+
+### 3.1 地址搜索流程
+
+```
+用户输入地址关键词
+    ↓
+调用 /baseData/getAddressPrompt 接口
+    ↓
+系统查询城市编码(如果指定城市)
+    ↓
+调用高德地图输入提示接口
+    ↓
+返回地址提示列表
+```
+
+### 3.2 行政区划级联查询流程
+
+```
+1. 查询所有省份
+   GET /baseData/getDistrict?adCode=100000
+   
+2. 用户选择省份(例如:河南省,adCode=410000)
+   GET /baseData/getDistrict?adCode=410000
+   
+3. 用户选择城市(例如:洛阳市,adCode=410300)
+   GET /baseData/getDistrict?adCode=410300
+   
+4. 用户选择区县完成
+```
+
+### 3.3 经营板块和种类选择流程
+
+```
+1. 获取所有经营板块
+   GET /baseData/getBusinessSection
+   
+2. 用户选择经营板块(例如:餐饮美食,dictId=1)
+   GET /baseData/getBusinessTypes?parentId=1
+   
+3. 用户选择经营种类完成
+```
+
+---
+
+## 四、Nacos 配置要求
+
+在 Nacos 配置中心的 `alien-store-platform.yml` 配置文件中,需要添加以下高德地图相关配置:
+
+```yaml
+# 高德地图配置
+gaode:
+  # 高德地图API Key
+  key: your_gaode_api_key_here
+  
+  # 地理编码URL(地址转经纬度)
+  geoUrl: https://restapi.amap.com/v3/geocode/geo?address=%s&key=%s
+  
+  # 输入提示URL
+  geoListUrl: https://restapi.amap.com/v3/assistant/inputtips?keywords=%s&key=%s&city=%s
+  
+  # 行政区划URL
+  getDistrict: https://restapi.amap.com/v3/config/district?key=%s&keywords=%s&subdistrict=1
+  
+  # 距离计算URL
+  distanceUrl: https://restapi.amap.com/v3/direction/driving?origin=%s,%s&destination=%s,%s&key=%s
+  
+  # 直线距离URL
+  distanceTypeUrl: https://restapi.amap.com/v3/direction/driving?origin=%s,%s&destination=%s,%s&key=%s&strategy=%s
+  
+  # 周边搜索URL
+  nearUrl: https://restapi.amap.com/v3/place/around?location=%s,%s&key=%s&radius=%s&offset=%s&page=%s
+  
+  # 地铁站查询URL
+  subwayUrl: https://restapi.amap.com/v3/place/text?key=%s&location=%s,%s&keywords=%s&radius=%s&types=%s
+  
+  # 逆地理编码URL(经纬度转地址)
+  addressUrl: https://restapi.amap.com/v3/geocode/regeo?location=%s,%s&key=%s&radius=%s&extensions=%s
+```
+
+**注意事项:**
+- 需要在高德地图开放平台申请 API Key
+- 配置值可以从 `alien-store` 服务的 Nacos 配置中获取
+- 确保 API Key 有足够的调用额度
+
+---
+
+## 五、数据库依赖
+
+### 5.1 essential_city_code 表
+
+存储城市编码信息,用于地址搜索时的城市过滤。
+
+**表结构:**
+```sql
+CREATE TABLE `essential_city_code` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `area_code` varchar(20) DEFAULT NULL COMMENT '行政区划代码',
+  `area_name` varchar(100) DEFAULT NULL COMMENT '区域名称',
+  `city_code` varchar(20) DEFAULT NULL COMMENT '城市编码',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+```
+
+### 5.2 store_dictionary 表
+
+存储经营板块和经营种类的字典数据。
+
+**表结构:**
+```sql
+CREATE TABLE `store_dictionary` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `type_name` varchar(50) DEFAULT NULL COMMENT '字典类型名称',
+  `dict_id` varchar(20) DEFAULT NULL COMMENT '字典ID',
+  `dict_detail` varchar(200) DEFAULT NULL COMMENT '字典详情',
+  `parent_id` int(11) DEFAULT NULL COMMENT '父节点ID',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+```
+
+**数据说明:**
+- `type_name = 'business_section'` 表示经营板块/经营种类
+- `dict_id = '0'` 表示根节点(不显示)
+- `dict_id != '0' AND parent_id = 根节点ID` 表示经营板块
+- `parent_id = 经营板块ID` 表示经营种类
+
+---
+
+## 六、代码结构
+
+### 6.1 新增文件列表
+
+```
+alien-store-platform/
+├── src/main/java/shop/alien/storeplatform/
+│   ├── controller/
+│   │   └── BaseDataController.java               # 基础数据查询控制器
+│   ├── service/
+│   │   ├── BaseDataService.java                  # 基础数据服务接口
+│   │   └── impl/
+│   │       └── BaseDataServiceImpl.java          # 基础数据服务实现
+│   └── util/
+│       └── GaoDeMapApiUtil.java                  # 高德地图API工具类
+```
+
+### 6.2 核心类说明
+
+**1. BaseDataController**
+- 提供4个基础数据查询接口
+- 统一的接口路径前缀 `/baseData`
+- 完整的 Swagger API 文档
+
+**2. BaseDataService & BaseDataServiceImpl**
+- 实现基础数据查询业务逻辑
+- 调用高德地图API和数据库查询
+- 数据格式转换和封装
+
+**3. GaoDeMapApiUtil**
+- 封装高德地图API调用
+- 支持地址提示和行政区划查询
+- HTTP请求处理和JSON解析
+
+---
+
+## 七、接口对比表
+
+| 功能 | 原接口(alien-store) | 新接口(alien-store-platform) |
+|------|----------------------|-------------------------------|
+| 地址提示 | `/gaode/getInputPrompt` | `/baseData/getAddressPrompt` |
+| 行政区划 | `/gaode/getDistrict` | `/baseData/getDistrict` |
+| 经营板块 | `/store/info/getBusinessSection` | `/baseData/getBusinessSection` |
+| 经营种类 | `/store/info/getBusinessSectionTypes` | `/baseData/getBusinessTypes` |
+
+---
+
+## 八、测试用例
+
+### 8.1 地址提示测试
+
+```bash
+# 测试1:不指定城市
+curl -X GET "http://localhost:8080/baseData/getAddressPrompt?addressName=中关村"
+
+# 测试2:指定城市
+curl -X GET "http://localhost:8080/baseData/getAddressPrompt?addressName=中关村&city=北京市"
+```
+
+### 8.2 行政区划测试
+
+```bash
+# 测试1:查询所有省份
+curl -X GET "http://localhost:8080/baseData/getDistrict?adCode=100000"
+
+# 测试2:查询河南省所有城市
+curl -X GET "http://localhost:8080/baseData/getDistrict?adCode=410000"
+
+# 测试3:查询洛阳市所有区县
+curl -X GET "http://localhost:8080/baseData/getDistrict?adCode=410300"
+```
+
+### 8.3 经营数据测试
+
+```bash
+# 测试1:查询所有经营板块
+curl -X GET "http://localhost:8080/baseData/getBusinessSection"
+
+# 测试2:查询板块ID为1的所有经营种类
+curl -X GET "http://localhost:8080/baseData/getBusinessTypes?parentId=1"
+```
+
+---
+
+## 九、技术亮点
+
+1. **接口统一管理**:将分散的基础数据查询接口统一到一个 Controller 中
+2. **命名规范化**:采用更符合 web 端语义的接口路径命名
+3. **代码复用**:复用原有业务逻辑,保证数据一致性
+4. **服务解耦**:独立的工具类实现,不依赖 alien-store 服务
+5. **文档完整**:提供详细的接口文档和使用说明
+
+---
+
+## 十、部署检查清单
+
+- [ ] 确认 Nacos 配置中已添加高德地图相关配置
+- [ ] 确认高德地图 API Key 有效且有调用额度
+- [ ] 确认数据库中 `essential_city_code` 表数据完整
+- [ ] 确认数据库中 `store_dictionary` 表数据完整
+- [ ] 确认 alien-entity 模块版本一致
+- [ ] 确认接口权限配置正确
+
+---
+
+## 十一、常见问题
+
+### Q1: 高德地图API返回为空怎么办?
+A: 检查以下几点:
+1. API Key 是否有效
+2. 网络连接是否正常
+3. 调用次数是否超限
+4. 请求参数是否正确
+
+### Q2: 行政区划数据查询不准确?
+A: 确保 adCode 参数正确,可以参考高德地图的行政区划代码表
+
+### Q3: 经营种类查询为空?
+A: 检查 parentId 是否正确,确认数据库中该板块下是否有经营种类数据
+
+---
+
+**开发完成时间:** 2025-01-xx  
+**开发人员:** AI Assistant  
+**版本号:** v1.0.0
+

+ 288 - 0
alien-store-platform/接口文档/17-身份验证接口逻辑变更说明.md

@@ -0,0 +1,288 @@
+# 商户身份验证接口逻辑变更说明
+
+## 变更时间
+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  
+**审核状态:** 待审核  
+**测试状态:** 待测试
+

+ 317 - 0
alien-store-platform/接口文档/18-身份验证接口开发总结.md

@@ -0,0 +1,317 @@
+# Web端商户身份验证接口开发总结
+
+## 一、需求说明
+
+将 `alien-store` 服务中 app 端商户的身份信息验证接口 `/alienStore/ali/getIdInfo` 迁移到新的 `alien-store-platform` 服务中,实现 web 端商户的身份证二要素核验功能。
+
+### 原接口信息
+
+- **服务名称**:alien-store(app端商户)
+- **接口路径**:`/alienStore/ali/getIdInfo`
+- **请求参数**:
+  - `name`:姓名
+  - `idCard`:身份证号
+  - `appType`:端区分(0:用户, 1:商家)
+
+### 新接口信息
+
+- **服务名称**:alien-store-platform(web端商户)
+- **接口路径**:`/merchantAuth/verifyIdInfo`
+- **请求参数**:
+  - `name`:姓名
+  - `idCard`:身份证号
+  - `appType`:端区分(0:用户, 1:商家),默认值为1
+
+## 二、实现方案
+
+### 2.1 代码复用策略
+
+采用**业务逻辑复用 + 代码独立**的方式:
+- 复用支付宝身份验证的核心逻辑
+- 创建独立的工具类 `AliApiUtil`,避免依赖 alien-store 服务
+- 使用相同的数据库 Mapper(通过 alien-entity 模块共享)
+
+### 2.2 技术架构
+
+```
+┌─────────────────────────────────────────┐
+│  alien-store-platform (Web端商户平台)   │
+├─────────────────────────────────────────┤
+│  Controller: MerchantAuthController     │
+│    ↓                                     │
+│  Service: MerchantAuthService           │
+│    ↓                                     │
+│  Util: AliApiUtil (支付宝API工具)       │
+│    ↓                                     │
+│  Mapper: LifeUserMapper/StoreUserMapper │
+│    ↓                                     │
+│  Database: MySQL                         │
+└─────────────────────────────────────────┘
+```
+
+### 2.3 核心业务流程
+
+```
+1. 接收请求参数(name, idCard, appType)
+   ↓
+2. 根据 appType 查询数据库
+   ├─ appType=0:查询 life_user 表
+   └─ appType=1:查询 store_user 表
+   ↓
+3. 判断是否已实名认证
+   ├─ 已认证 → 返回"该身份证已实名认证过"
+   └─ 未认证 → 继续下一步
+   ↓
+4. 调用支付宝二要素核验接口
+   ├─ 验证通过 → 返回"身份验证成功"
+   └─ 验证失败 → 返回"身份证号与姓名不一致"
+```
+
+## 三、代码实现
+
+### 3.1 新增文件清单
+
+| 文件路径 | 说明 | 代码行数 |
+|---------|------|---------|
+| `controller/MerchantAuthController.java` | Web端商户身份验证控制器 | ~40行 |
+| `service/MerchantAuthService.java` | 商户身份验证服务接口 | ~20行 |
+| `service/impl/MerchantAuthServiceImpl.java` | 商户身份验证服务实现 | ~60行 |
+| `util/AliApiUtil.java` | 支付宝API工具类 | ~150行 |
+| `README_MERCHANT_AUTH.md` | 接口配置说明文档 | - |
+
+### 3.2 核心代码片段
+
+#### 控制器层
+
+```java
+@GetMapping("/verifyIdInfo")
+public R<String> verifyIdInfo(
+    @RequestParam("name") String name, 
+    @RequestParam("idCard") String idCard, 
+    @RequestParam("appType") Integer appType
+) {
+    log.info("MerchantAuthController.verifyIdInfo?name={}&idCard={}&appType={}", 
+        name, idCard, appType);
+    return merchantAuthService.verifyIdInfo(name, idCard, appType);
+}
+```
+
+#### 服务层
+
+```java
+@Override
+public R<String> verifyIdInfo(String name, String idCard, Integer appType) {
+    // 1. 查询是否已实名认证
+    int size;
+    if (appType == 0) {
+        // 用户端
+        LambdaQueryWrapper<LifeUser> userWrapper = new LambdaQueryWrapper<>();
+        userWrapper.eq(LifeUser::getIdCard, idCard)
+                   .eq(LifeUser::getRealName, name);
+        size = lifeUserMapper.selectCount(userWrapper);
+    } else {
+        // 商家端
+        LambdaQueryWrapper<StoreUser> storeWrapper = new LambdaQueryWrapper<>();
+        storeWrapper.eq(StoreUser::getIdCard, idCard)
+                   .eq(StoreUser::getName, name);
+        size = storeUserMapper.selectCount(storeWrapper);
+    }
+    
+    if (size > 0) {
+        return R.fail("该身份证已实名认证过");
+    }
+    
+    // 2. 调用支付宝身份验证接口
+    if (aliApiUtil.verifyIdCard(name, idCard)) {
+        return R.success("身份验证成功");
+    }
+    
+    return R.fail("身份证号与姓名不一致,请检查后重新填写");
+}
+```
+
+#### 工具类层
+
+```java
+public boolean verifyIdCard(String name, String idCard) {
+    try {
+        AlipayClient alipayClient = new DefaultAlipayClient(setAlipayConfig());
+        DatadigitalFincloudGeneralsaasTwometaCheckRequest request = 
+            new DatadigitalFincloudGeneralsaasTwometaCheckRequest();
+        DatadigitalFincloudGeneralsaasTwometaCheckModel model = 
+            new DatadigitalFincloudGeneralsaasTwometaCheckModel();
+        
+        model.setOuterBizNo("id_" + createOrderNo());
+        model.setCertName(name);
+        model.setCertNo(idCard);
+        model.setCertType("IDENTITY_CARD");
+        
+        request.setBizModel(model);
+        DatadigitalFincloudGeneralsaasTwometaCheckResponse response = 
+            alipayClient.certificateExecute(request);
+        
+        JSONObject jsonObject = JSONObject.parseObject(response.getBody())
+            .getJSONObject("datadigital_fincloud_generalsaas_twometa_check_response");
+        
+        return response.isSuccess() 
+            && "Success".equals(jsonObject.getString("msg")) 
+            && "T".equals(jsonObject.getString("match"));
+    } catch (AlipayApiException e) {
+        log.error("AliApiUtil.verifyIdCard ERROR Msg={}", e.getErrMsg());
+        return false;
+    }
+}
+```
+
+## 四、配置说明
+
+### 4.1 Nacos 配置
+
+需要在 Nacos 配置中心的 `alien-store-platform.yml` 中添加支付宝配置:
+
+```yaml
+app:
+  business:
+    appId: ${your_app_id}
+    appPrivateKey: ${your_private_key}
+    appPublicKey: ${your_public_key}
+    win:
+      appCertPath: D:/certs/appCertPublicKey.crt
+      alipayPublicCertPath: D:/certs/alipayCertPublicKey_RSA2.crt
+      alipayRootCertPath: D:/certs/alipayRootCert.crt
+    linux:
+      appCertPath: /usr/local/certs/appCertPublicKey.crt
+      alipayPublicCertPath: /usr/local/certs/alipayCertPublicKey_RSA2.crt
+      alipayRootCertPath: /usr/local/certs/alipayRootCert.crt
+```
+
+### 4.2 依赖说明
+
+alien-store-platform 已包含的依赖:
+- ✅ `alipay-sdk-java`:支付宝 SDK
+- ✅ `alien-entity`:实体和 Mapper 共享
+- ✅ `alien-util`:工具类共享
+- ✅ `mybatis-plus`:数据库操作
+
+## 五、测试验证
+
+### 5.1 接口测试
+
+**测试用例 1:未认证用户的身份验证**
+
+```bash
+curl -X GET "http://localhost:8080/merchantAuth/verifyIdInfo?name=张三&idCard=110101199001011234&appType=1"
+```
+
+预期响应:
+```json
+{
+  "code": 200,
+  "success": true,
+  "msg": "身份验证成功",
+  "data": "身份验证成功"
+}
+```
+
+**测试用例 2:已认证用户的重复验证**
+
+```bash
+curl -X GET "http://localhost:8080/merchantAuth/verifyIdInfo?name=李四&idCard=110101199001011235&appType=1"
+```
+
+预期响应(假设该用户已认证):
+```json
+{
+  "code": 500,
+  "success": false,
+  "msg": "该身份证已实名认证过",
+  "data": null
+}
+```
+
+**测试用例 3:身份证和姓名不匹配**
+
+```bash
+curl -X GET "http://localhost:8080/merchantAuth/verifyIdInfo?name=王五&idCard=110101199001011236&appType=1"
+```
+
+预期响应:
+```json
+{
+  "code": 500,
+  "success": false,
+  "msg": "身份证号与姓名不一致,请检查后重新填写",
+  "data": null
+}
+```
+
+### 5.2 Swagger 测试
+
+访问 Swagger UI:`http://localhost:8080/doc.html`
+
+在 "web端商户身份验证管理" 分组下找到 "身份证二要素核验" 接口进行测试。
+
+## 六、与原接口的对比
+
+| 对比项 | 原接口(alien-store) | 新接口(alien-store-platform) |
+|-------|---------------------|------------------------------|
+| 接口路径 | `/ali/getIdInfo` | `/merchantAuth/verifyIdInfo` |
+| 服务名称 | alien-store | alien-store-platform |
+| 服务定位 | app端商户 | web端商户 |
+| 业务逻辑 | 完全一致 | 完全一致 |
+| 代码实现 | AliApi.java | AliApiUtil.java |
+| 依赖关系 | 自包含 | 独立实现 |
+| Swagger分组 | 二期-阿里接口 | web端商户身份验证管理 |
+
+## 七、技术亮点
+
+1. **代码复用性**:通过工具类封装,实现核心逻辑复用
+2. **服务独立性**:新服务不依赖 alien-store,保持服务间解耦
+3. **配置灵活性**:支持 Windows 和 Linux 环境自适应
+4. **接口规范性**:遵循 RESTful 规范,使用语义化的接口路径
+5. **文档完整性**:提供详细的配置说明和使用文档
+
+## 八、注意事项
+
+### 8.1 部署前检查
+
+- [ ] 确认 Nacos 配置中已添加支付宝相关配置
+- [ ] 确认支付宝证书文件已上传到服务器
+- [ ] 确认证书文件路径与配置一致
+- [ ] 确认数据库连接正常
+- [ ] 确认 alien-entity 模块版本一致
+
+### 8.2 运行时注意
+
+- 身份证号必须为真实有效的号码(支付宝会实际验证)
+- 测试环境和生产环境使用不同的支付宝配置
+- 接口调用频率受支付宝限制,避免频繁调用
+- 日志中不应记录完整的身份证号(已脱敏处理)
+
+### 8.3 错误处理
+
+| 错误场景 | 返回信息 | 处理建议 |
+|---------|---------|---------|
+| 该身份证已认证 | "该身份证已实名认证过" | 提示用户该身份证已被使用 |
+| 身份证姓名不匹配 | "身份证号与姓名不一致,请检查后重新填写" | 提示用户核对信息 |
+| 支付宝接口异常 | "身份证号与姓名不一致,请检查后重新填写" | 检查支付宝配置和证书 |
+| 数据库连接异常 | 系统异常 | 检查数据库配置 |
+
+## 九、后续优化建议
+
+1. **缓存优化**:对已验证的身份证信息进行短期缓存,减少重复调用
+2. **异步处理**:对于非实时要求的场景,可以采用异步验证
+3. **批量验证**:如果有批量验证需求,可以扩展批量接口
+4. **监控告警**:添加接口调用监控和失败告警
+5. **日志脱敏**:对敏感信息(身份证号、姓名)进行脱敏处理
+
+## 十、总结
+
+本次开发成功将 app 端商户的身份验证接口迁移到 web 端商户平台,实现了业务逻辑的复用和代码的独立性。新接口遵循项目规范,具有良好的可维护性和扩展性。
+
+**开发完成时间**:2025-01-xx  
+**开发人员**:AI Assistant  
+**代码审查状态**:待审查  
+**测试状态**:待测试  
+**部署状态**:待部署
+