# 根据手机号获取商户用户信息接口文档 ## 概述 本文档描述了从 `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 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` | `R` | **主要变化**: - ✅ 接口路径更符合web端命名规范 - ✅ Controller和Service命名更清晰(`MerchantUser`) - ✅ 返回类型统一为 `StoreUserVo`(扩展字段更丰富) - ✅ 代码结构更清晰,注释更完善 --- ## 版本记录 | 版本 | 日期 | 说明 | 作者 | |------|------|------|------| | 1.0.0 | 2025-01-xx | 初始版本,迁移商户用户查询功能 | ssk | --- ## 联系方式 如有问题,请联系: - 开发团队:Alien Cloud Team - 邮箱:dev@alien.shop