# Web端商户快速提现申请接口文档 ## 模块概述 本模块提供商户快速提现功能,与普通提现(需审核)不同,此接口创建的提现记录直接标记为"已通过"状态(paymentStatus=3),无需人工审核,与app端 `applyCashOut` 接口保持一致。 --- ## 接口信息 ### 快速提现申请(免审核) #### 接口详情 - **接口名称**: 快速提现申请(免审核) - **接口路径**: `POST /incomeManage/applyFastCashOut` - **请求方式**: POST - **接口描述**: 为当前登录的商户提交快速提现申请,直接创建为"已通过"状态,无需审核流程 - **登录验证**: ✅ 需要(通过 JWT token 自动获取storeId) --- ## 与普通提现的区别 | 项目 | 普通提现 (/cashOut) | 快速提现 (/applyFastCashOut) | |------|-------------------|----------------------------| | 提现状态 | paymentStatus = 1(待审核) | paymentStatus = 3(已通过) | | 审核流程 | 需要人工审核 | 免审核,直接通过 | | 账户扣款 | 提交时扣款 | 提交时不扣款 | | 适用场景 | Web端常规提现 | 与app端保持一致的快速提现 | | 后续流程 | 需管理员审核后打款 | 可直接进入打款流程 | --- ## 请求参数 ### 请求体(Request Body) 使用 `CashOutDTO` 对象作为请求体(JSON格式): | 参数名 | 类型 | 必填 | 说明 | 示例值 | |--------|------|------|------|--------| | payPassword | String | 是 | 支付密码 | 123456 | | withdrawalMoney | Integer | 是 | 提现金额(单位:分) | 50000 | ### 参数说明 #### payPassword(支付密码) - **用途**: 验证用户身份 - **格式**: 用户设置的支付密码 - **验证**: 必须与数据库中的支付密码匹配 - **安全**: 建议前端加密后传输 #### withdrawalMoney(提现金额) - **单位**: 分(1元 = 100分) - **最小值**: 10分(0.1元) - **最大值**: 不能超过账户余额 - **示例**: - 提现100元 → `withdrawalMoney = 10000` - 提现50元 → `withdrawalMoney = 5000` - 提现0.1元 → `withdrawalMoney = 10` **注意**: `storeId` 从登录用户的 JWT Token 中自动获取,不需要在请求中传递。 --- ## 请求示例 ### 示例1: 提现500元 ```http POST /incomeManage/applyFastCashOut Content-Type: application/json Authorization: Bearer YOUR_JWT_TOKEN { "payPassword": "123456", "withdrawalMoney": 50000 } ``` ```bash curl -X POST "http://localhost:8080/incomeManage/applyFastCashOut" \ -H "Authorization: Bearer YOUR_JWT_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "payPassword": "123456", "withdrawalMoney": 50000 }' ``` --- ### 示例2: 提现全部余额 假设账户余额为1000元(100000分): ```http POST /incomeManage/applyFastCashOut Content-Type: application/json Authorization: Bearer YOUR_JWT_TOKEN { "payPassword": "123456", "withdrawalMoney": 100000 } ``` --- ## 响应参数 ### 成功响应 ```json { "code": 200, "success": true, "data": { "id": 1001, "storeId": 103, "storeUserId": 114, "money": 50000, "commission": null, "cashOutType": 0, "paymentStatus": 3, "orderNo": null, "aliOrderNo": null, "paymentDate": null, "payDate": null, "failReason": null, "incomeStartTime": "2025-11-20 14:30:00", "incomeEndTime": "2025-11-20 14:30:00", "deleteFlag": 0, "createdTime": "2025-11-20 14:30:00", "updatedTime": "2025-11-20 14:30:00" }, "msg": "操作成功" } ``` ### 响应字段说明 #### 外层字段 | 字段名 | 类型 | 说明 | |--------|------|------| | code | Integer | 状态码(200-成功) | | success | Boolean | 是否成功 | | data | Object | 提现记录对象(StoreCashOutRecord) | | msg | String | 提示信息 | #### data 字段(StoreCashOutRecord) | 字段名 | 类型 | 说明 | |--------|------|------| | id | Long | 提现记录ID | | storeId | Integer | 门店ID | | storeUserId | Integer | 用户ID | | money | Integer | 提现金额(单位:分) | | commission | Integer | 手续费(单位:分,可为null) | | cashOutType | Integer | 提现类型(0-全部提现) | | paymentStatus | Integer | ⚠️ 提现状态(3-已通过) | | orderNo | String | 提现订单号(初始为null) | | aliOrderNo | String | 支付宝订单号(初始为null) | | paymentDate | Date | 申请时间(初始为null) | | payDate | Date | 打款时间(初始为null) | | failReason | String | 失败原因(初始为null) | | incomeStartTime | Date | 收入开始时间 | | incomeEndTime | Date | 收入结束时间 | | deleteFlag | Integer | 删除标识(0-未删除) | | createdTime | Date | 创建时间 | | updatedTime | Date | 更新时间 | **重要说明**: - 🔔 `paymentStatus = 3` 表示"已通过",区别于普通提现的"待审核" - 🔔 订单号、支付宝订单号等字段需要在打款时填充 --- ### 失败响应 #### 1. 支付密码错误 ```json { "code": 500, "success": false, "data": null, "msg": "支付密码错误" } ``` #### 2. 余额不足 ```json { "code": 500, "success": false, "data": null, "msg": "余额不足" } ``` #### 3. 提现金额过小 ```json { "code": 500, "success": false, "data": null, "msg": "金额不能小于0.1元" } ``` #### 4. 未登录或token无效 ```json { "code": 500, "success": false, "data": null, "msg": "请先登录" } ``` #### 5. 系统异常 ```json { "code": 500, "success": false, "data": null, "msg": "快速提现失败:{异常信息}" } ``` --- ## 业务逻辑说明 ### 快速提现流程 ``` ┌─────────────────────────────────────────────┐ │ 1. 接收请求(从DTO获取参数) │ │ - payPassword (必填,从DTO) │ │ - withdrawalMoney (必填,单位:分,从DTO) │ │ - JWT token (自动获取storeId) │ └─────────────────┬───────────────────────────┘ ↓ ┌─────────────────────────────────────────────┐ │ 2. 从 JWT token 中解析门店ID │ │ storeId = LoginUserUtil.getCurrentStoreId()│ └─────────────────┬───────────────────────────┘ ↓ ┌─────────────────────────────────────────────┐ │ 3. 验证支付密码 │ │ SELECT * FROM store_user │ │ WHERE store_id = ? AND pay_password = ? │ │ IF user == null │ │ 返回错误: "支付密码错误" │ └─────────────────┬───────────────────────────┘ ↓ ┌─────────────────────────────────────────────┐ │ 4. 验证账户余额 │ │ IF user.money <= withdrawalMoney │ │ 返回错误: "余额不足" │ └─────────────────┬───────────────────────────┘ ↓ ┌─────────────────────────────────────────────┐ │ 5. 验证提现金额 │ │ amountInYuan = withdrawalMoney ÷ 100 │ │ IF amountInYuan < 0.1 │ │ 返回错误: "金额不能小于0.1元" │ └─────────────────┬───────────────────────────┘ ↓ ┌─────────────────────────────────────────────┐ │ 6. 创建提现记录 │ │ StoreCashOutRecord record = new ... │ │ record.paymentStatus = 3 // 已通过 │ │ INSERT INTO store_cash_out_record │ └─────────────────┬───────────────────────────┘ ↓ ┌─────────────────────────────────────────────┐ │ 7. 返回结果 │ │ 返回 StoreCashOutRecord 对象 │ └─────────────────────────────────────────────┘ ``` ### 与原接口的对比 #### 原接口(app端) ```java @GetMapping("/applyCashOut") public R applyCashOut(Integer storeId, String payPassword, Integer withdrawalMoney) ``` - 使用 GET 请求 - 需要手动传递 storeId - URL: `/storeIncomeDetailsRecord/applyCashOut?storeId=103&payPassword=123456&withdrawalMoney=50000` #### 新接口(web端) ```java @PostMapping("/applyFastCashOut") public R> applyFastCashOut(@RequestBody CashOutDTO cashOutDTO) ``` - 使用 POST 请求(更安全) - 从 JWT token 自动获取 storeId - 使用 DTO 接收 JSON 请求体 - URL: `/incomeManage/applyFastCashOut` **核心逻辑一致性**: - ✅ 支付密码验证逻辑相同 - ✅ 余额验证逻辑相同(`money <= withdrawalMoney`) - ✅ 最小金额验证相同(0.1元) - ✅ 提现状态相同(paymentStatus = 3) - ✅ 返回数据格式相同(StoreCashOutRecord对象) --- ## 数据库操作 ### 查询用户SQL ```sql SELECT * FROM store_user WHERE store_id = ? AND pay_password = ? LIMIT 1 ``` ### 插入提现记录SQL ```sql INSERT INTO store_cash_out_record ( store_id, money, cash_out_type, payment_status, delete_flag, income_start_time, income_end_time, store_user_id, created_time, updated_time ) VALUES ( ?, -- storeId ?, -- withdrawalMoney 0, -- cashOutType (0-全部提现) 3, -- paymentStatus (3-已通过) 0, -- deleteFlag NOW(), -- incomeStartTime NOW(), -- incomeEndTime ?, -- storeUserId NOW(), -- createdTime NOW() -- updatedTime ) ``` --- ## 业务场景 ### 场景 1: 正常快速提现 **前置条件**: - 账户余额: 1000元(100000分) - 支付密码: 123456 **请求**: ```http POST /incomeManage/applyFastCashOut Content-Type: application/json Authorization: Bearer VALID_TOKEN { "payPassword": "123456", "withdrawalMoney": 50000 } ``` **响应**: ```json { "code": 200, "success": true, "data": { "id": 1001, "storeId": 103, "money": 50000, "paymentStatus": 3, ... }, "msg": "操作成功" } ``` **数据库变化**: - ✅ 新增一条提现记录(paymentStatus=3) - ❌ 账户余额不变(与普通提现不同) --- ### 场景 2: 支付密码错误 **请求**: ```http POST /incomeManage/applyFastCashOut Content-Type: application/json { "payPassword": "wrong_password", "withdrawalMoney": 50000 } ``` **响应**: ```json { "code": 500, "success": false, "data": null, "msg": "支付密码错误" } ``` --- ### 场景 3: 余额不足 **前置条件**: 账户余额 100元(10000分) **请求**: ```http POST /incomeManage/applyFastCashOut Content-Type: application/json { "payPassword": "123456", "withdrawalMoney": 20000 } ``` **响应**: ```json { "code": 500, "success": false, "data": null, "msg": "余额不足" } ``` --- ### 场景 4: 提现金额过小 **请求**: ```http POST /incomeManage/applyFastCashOut Content-Type: application/json { "payPassword": "123456", "withdrawalMoney": 5 } ``` **响应**: ```json { "code": 500, "success": false, "data": null, "msg": "金额不能小于0.1元" } ``` --- ## 前端集成示例 ### Vue.js 示例 ```javascript export default { data() { return { payPassword: '', withdrawalMoney: '', // 用户输入的元金额 loading: false }; }, methods: { async applyFastCashOut() { // 1. 验证输入 if (!this.payPassword) { this.$message.error('请输入支付密码'); return; } if (!this.withdrawalMoney || this.withdrawalMoney < 0.1) { this.$message.error('提现金额不能小于0.1元'); return; } // 2. 转换金额单位(元转分) const withdrawalMoneyInCents = Math.floor(this.withdrawalMoney * 100); // 3. 发送请求(使用JSON Body) this.loading = true; try { const response = await this.$axios.post('/incomeManage/applyFastCashOut', { payPassword: this.payPassword, withdrawalMoney: withdrawalMoneyInCents }); if (response.data.success) { const cashOutRecord = response.data.data; this.$message.success('快速提现申请成功'); console.log('提现记录ID:', cashOutRecord.id); console.log('提现状态:', cashOutRecord.paymentStatus); // 3-已通过 // 刷新列表或跳转 this.$router.push('/cashout-list'); } else { this.$message.error(response.data.msg); } } catch (error) { console.error('快速提现失败:', error); this.$message.error('快速提现失败,请稍后重试'); } finally { this.loading = false; } } } } ``` --- ### React 示例 ```javascript import { useState } from 'react'; import axios from 'axios'; function FastCashOut() { const [payPassword, setPayPassword] = useState(''); const [withdrawalMoney, setWithdrawalMoney] = useState(''); const [loading, setLoading] = useState(false); const handleSubmit = async () => { // 1. 验证输入 if (!payPassword) { alert('请输入支付密码'); return; } const amount = parseFloat(withdrawalMoney); if (!amount || amount < 0.1) { alert('提现金额不能小于0.1元'); return; } // 2. 转换金额单位(元转分) const withdrawalMoneyInCents = Math.floor(amount * 100); // 3. 发送请求(使用JSON Body) setLoading(true); try { const response = await axios.post('/incomeManage/applyFastCashOut', { payPassword, withdrawalMoney: withdrawalMoneyInCents }); if (response.data.success) { const cashOutRecord = response.data.data; alert('快速提现申请成功'); console.log('提现记录:', cashOutRecord); // 跳转或刷新 } else { alert(response.data.msg); } } catch (error) { console.error('快速提现失败:', error); alert('快速提现失败,请稍后重试'); } finally { setLoading(false); } }; return (
⚠️ 快速提现无需审核,提现记录将直接标记为"已通过"状态