# 银行卡提现功能实施计划

## 一、功能概述

新增银行卡提现功能，与现有支付宝提现功能并行。银行卡提现采用申请-审核模式：
- 用户提交银行卡提现申请（银行卡号、开户支行、提现金额）
- 系统冻结申请金额
- 管理员审核（确认/拒绝）
- 确认后扣除金额，拒绝后解冻金额
- 实际转账由管理员线下手动完成

## 二、数据库变更

### 2.1 修改 `agent_withdrawal` 表

需要新增以下字段：
```sql
ALTER TABLE `agent_withdrawal` 
ADD COLUMN `withdraw_type` TINYINT NOT NULL DEFAULT 1 COMMENT '提现类型:1-支付宝,2-银行卡' AFTER `agent_id`,
ADD COLUMN `bank_card_no` VARCHAR(50) DEFAULT NULL COMMENT '银行卡号' AFTER `payee_account`,
ADD COLUMN `bank_name` VARCHAR(100) DEFAULT NULL COMMENT '开户支行' AFTER `bank_card_no`,
ADD COLUMN `payee_name` VARCHAR(50) DEFAULT NULL COMMENT '收款人姓名' AFTER `bank_name`;
```

**说明：**
- `withdraw_type`: 区分提现类型（1=支付宝，2=银行卡）
- `bank_card_no`: 银行卡号（仅银行卡提现使用）
- `bank_name`: 开户支行（仅银行卡提现使用）
- `payee_name`: 收款人姓名（银行卡提现需要，支付宝提现已有但字段名不同）

### 2.2 新增银行卡信息记录表（可选，用于历史记录）

如果需要保存用户的历史银行卡信息以便自动填充：
```sql
CREATE TABLE `agent_bank_card` (
  `id` BIGINT NOT NULL AUTO_INCREMENT,
  `agent_id` BIGINT NOT NULL COMMENT '代理ID',
  `bank_card_no` VARCHAR(50) NOT NULL COMMENT '银行卡号',
  `bank_name` VARCHAR(100) NOT NULL COMMENT '开户支行',
  `payee_name` VARCHAR(50) NOT NULL COMMENT '收款人姓名',
  `is_default` TINYINT DEFAULT 0 COMMENT '是否默认:0-否,1-是',
  `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `delete_time` DATETIME DEFAULT NULL,
  `del_state` TINYINT DEFAULT 0 COMMENT '删除状态:0-未删除,1-已删除',
  PRIMARY KEY (`id`),
  KEY `idx_agent_id` (`agent_id`),
  KEY `idx_del_state` (`del_state`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='代理银行卡信息表';
```

## 三、后端开发

### 3.1 API接口定义

#### 3.1.1 前端接口（`app/main/api/desc/front/agent.api`）

**新增银行卡提现申请接口：**
```go
// 银行卡提现申请
@handler BankCardWithdrawal
post /withdrawal/bank-card (BankCardWithdrawalReq) returns (WithdrawalResp)

type (
    BankCardWithdrawalReq {
        BankCardNo string  `json:"bank_card_no"` // 银行卡号
        BankName   string  `json:"bank_name"`    // 开户支行
        Amount     float64 `json:"amount"`       // 提现金额
    }
)
```

**新增获取历史银行卡信息接口（可选）：**
```go
// 获取历史银行卡信息
@handler GetBankCardInfo
get /withdrawal/bank-card/info (GetBankCardInfoReq) returns (GetBankCardInfoResp)

type (
    GetBankCardInfoReq  {}
    GetBankCardInfoResp {
        BankCardNo string `json:"bank_card_no"` // 银行卡号
        BankName   string `json:"bank_name"`     // 开户支行
        PayeeName  string `json:"payee_name"`   // 收款人姓名
        IdCard     string `json:"id_card"`      // 身份证号
    }
)
```

#### 3.1.2 管理员接口（`app/main/api/desc/admin/admin_agent.api`）

**新增银行卡提现审核接口：**
```go
// 银行卡提现审核（确认/拒绝）
@handler AdminReviewBankCardWithdrawal
post /agent-withdrawal/bank-card/review (AdminReviewBankCardWithdrawalReq) returns (AdminReviewBankCardWithdrawalResp)

type (
    AdminReviewBankCardWithdrawalReq {
        WithdrawalId int64  `json:"withdrawal_id"` // 提现记录ID
        Action       int64  `json:"action"`        // 操作:1-确认,2-拒绝
        Remark       string `json:"remark"`       // 备注（拒绝时必填）
    }
    
    AdminReviewBankCardWithdrawalResp {
        Success bool `json:"success"`
    }
)
```

**修改现有提现列表接口：**
- 在 `AdminGetAgentWithdrawalListResp` 的 `AgentWithdrawalListItem` 中新增字段：
  - `WithdrawType int64` - 提现类型
  - `BankCardNo string` - 银行卡号
  - `BankName string` - 开户支行
  - `PayeeName string` - 收款人姓名

### 3.2 业务逻辑实现

#### 3.2.1 银行卡提现申请逻辑（`BankCardWithdrawalLogic`）

**文件位置：** `app/main/api/internal/logic/agent/bankcardwithdrawallogic.go`

**核心流程：**
1. 验证用户实名认证状态
2. 验证银行卡信息与实名信息匹配（姓名需一致）
3. 验证可提现金额
4. 计算税费（6%）
5. 冻结资金（事务内）
6. 创建提现记录（状态=申请中，withdraw_type=2）
7. 创建扣税记录（状态=待扣税）
8. 保存银行卡信息到历史记录表（可选）

**关键代码逻辑：**
```go
// 参考 AgentWithdrawalLogic，但：
// 1. 不调用支付宝接口
// 2. 状态直接设为 StatusProcessing（申请中）
// 3. 添加银行卡信息字段
// 4. 验证银行卡号格式
// 5. 验证姓名与实名认证信息一致
```

#### 3.2.2 银行卡提现审核逻辑（`AdminReviewBankCardWithdrawalLogic`）

**文件位置：** `app/main/api/internal/logic/admin_agent/adminreviewbankcardwithdrawallogic.go`

**确认提现流程：**
1. 验证提现记录存在且状态为申请中
2. 验证提现类型为银行卡
3. 事务内操作：
   - 更新提现记录状态为成功
   - 解冻资金并扣除（FrozenBalance -= amount, Balance不变）
   - 更新扣税记录状态为成功
   - 发放提现奖励（如果有）

**拒绝提现流程：**
1. 验证提现记录存在且状态为申请中
2. 验证提现类型为银行卡
3. 事务内操作：
   - 更新提现记录状态为失败，记录拒绝原因
   - 解冻资金（FrozenBalance -= amount, Balance += amount）
   - 更新扣税记录状态为失败

#### 3.2.3 修改现有逻辑

**修改 `AgentWithdrawalLogic`：**
- 在创建提现记录时，设置 `withdraw_type = 1`（支付宝）
- 在 `PayeeAccount` 字段存储支付宝账号

**修改 `AdminGetAgentWithdrawalListLogic`：**
- 查询时关联银行卡信息字段
- 返回时包含提现类型和银行卡信息

### 3.3 数据模型

#### 3.3.1 修改 `AgentWithdrawal` 模型

**文件：** `app/main/model/agentWithdrawalModel_gen.go`（由goctl生成，需重新生成）

**新增字段：**
- `WithdrawType int64` - 提现类型
- `BankCardNo sql.NullString` - 银行卡号
- `BankName sql.NullString` - 开户支行
- `PayeeName sql.NullString` - 收款人姓名

#### 3.3.2 新增 `AgentBankCard` 模型（可选）

如果实现历史记录功能，需要：
1. 创建 `agent_bank_card.sql` 表结构文件
2. 使用 goctl 生成模型：
   ```bash
   goctl model mysql datasource -url="user:password@tcp(host:port)/database" -table="agent_bank_card" -dir="./app/main/model" -cache=true --style=goZero
   ```

### 3.4 状态管理

**提现状态常量：**
```go
const (
    StatusPending   = 1 // 申请中/处理中（支付宝和银行卡共用）
    StatusSuccess   = 2 // 成功
    StatusFailed    = 3 // 失败
)

const (
    WithdrawTypeAlipay   = 1 // 支付宝提现
    WithdrawTypeBankCard = 2 // 银行卡提现
)
```

**银行卡提现状态流转：**
- 申请 → StatusPending（申请中）
- 管理员确认 → StatusSuccess（成功）
- 管理员拒绝 → StatusFailed（失败）

## 四、前端开发

### 4.1 用户端（tydata-webview-v2）

#### 4.1.1 修改提现页面（`src/views/Withdraw.vue`）

**方案A：在同一页面添加切换标签**
- 添加"支付宝提现"和"银行卡提现"两个标签页
- 根据选择的标签显示不同的表单字段

**方案B：创建新的银行卡提现页面**
- 创建 `src/views/BankCardWithdraw.vue`
- 在路由中添加银行卡提现入口

**推荐方案A，用户体验更好**

**银行卡提现表单字段：**
- 银行卡号（必填，格式验证）
- 开户支行（必填）
- 提现金额（必填，验证规则同支付宝）
- 显示实名信息（姓名、身份证号，只读）
- 提示：银行卡信息需与实名信息一致

**功能点：**
1. 页面加载时调用接口获取历史银行卡信息，自动填充
2. 显示用户实名认证信息（姓名、身份证号）
3. 表单验证：
   - 银行卡号格式（16-19位数字）
   - 开户支行不能为空
   - 金额验证（≥50，≤可提现金额）
4. 提交后显示申请成功提示
5. 可在提现记录中查看审核状态

#### 4.1.2 修改提现记录页面（`src/views/WithdrawDetails.vue`）

- 显示提现类型（支付宝/银行卡）
- 银行卡提现显示银行卡号和开户支行
- 显示审核状态（申请中/已确认/已拒绝）

#### 4.1.3 API接口调用

**新增接口调用：**
```javascript
// src/api/withdraw.js 或相应文件
export const bankCardWithdrawal = (data) => {
  return useApiFetch('/agent/withdrawal/bank-card')
    .post(data)
    .json();
};

export const getBankCardInfo = () => {
  return useApiFetch('/agent/withdrawal/bank-card/info')
    .get()
    .json();
};
```

### 4.2 管理端（tydata-admin）

#### 4.2.1 修改提现列表页面（`apps/web-antd/src/views/agent/agent-withdrawal/list.vue`）

**新增功能：**
1. 列表显示提现类型（支付宝/银行卡）
2. 银行卡提现显示银行卡号和开户支行
3. 银行卡提现申请中状态显示"审核"操作按钮
4. 点击审核按钮打开审核弹窗

#### 4.2.2 新增审核弹窗组件

**文件：** `apps/web-antd/src/views/agent/agent-withdrawal/modules/review-modal.vue`

**功能：**
- 显示提现详情（金额、银行卡信息、用户信息等）
- 确认/拒绝操作
- 拒绝时必填拒绝原因
- 提交审核结果

#### 4.2.3 修改列表数据配置（`apps/web-antd/src/views/agent/agent-withdrawal/data.ts`）

**新增列：**
- 提现类型列
- 银行卡号列（仅银行卡提现显示）
- 开户支行列（仅银行卡提现显示）
- 操作列（银行卡申请中状态显示审核按钮）

#### 4.2.4 API接口调用

**新增接口：**
```typescript
// apps/web-antd/src/api/agent.ts
export function reviewBankCardWithdrawal(data: {
  withdrawal_id: number;
  action: 1 | 2; // 1-确认, 2-拒绝
  remark?: string;
}) {
  return request.post('/admin/agent-withdrawal/bank-card/review', data);
}
```

## 五、实施步骤

### 阶段一：数据库准备（1-2天）
1. ✅ 编写数据库变更SQL脚本
2. ✅ 执行SQL脚本更新数据库表结构
3. ✅ 如果实现历史记录功能，创建 `agent_bank_card` 表

### 阶段二：后端开发（3-5天）
1. ✅ 修改API定义文件（`agent.api`、`admin_agent.api`）
2. ✅ 使用goctl重新生成代码（包括模型和类型定义）
3. ✅ 实现银行卡提现申请逻辑（`BankCardWithdrawalLogic`）
4. ✅ 实现银行卡提现审核逻辑（`AdminReviewBankCardWithdrawalLogic`）
5. ✅ 修改现有提现列表逻辑，支持银行卡信息查询
6. ✅ 实现获取历史银行卡信息接口（可选）
7. ✅ 单元测试和接口测试

### 阶段三：前端开发（3-5天）

#### 用户端（tydata-webview-v2）
1. ✅ 修改提现页面，添加银行卡提现选项
2. ✅ 实现银行卡提现表单和验证
3. ✅ 实现历史信息自动填充
4. ✅ 修改提现记录页面，显示银行卡信息
5. ✅ 测试提现流程

#### 管理端（tydata-admin）
1. ✅ 修改提现列表页面，显示银行卡信息
2. ✅ 实现审核弹窗组件
3. ✅ 实现审核操作逻辑
4. ✅ 测试审核流程

### 阶段四：测试与优化（2-3天）
1. ✅ 功能测试（申请、审核、拒绝流程）
2. ✅ 边界测试（金额、状态、并发等）
3. ✅ 性能测试
4. ✅ Bug修复
5. ✅ 代码审查

### 阶段五：部署上线（1天）
1. ✅ 数据库迁移脚本执行
2. ✅ 后端服务部署
3. ✅ 前端应用部署
4. ✅ 生产环境验证

## 六、注意事项

### 6.1 数据兼容性
- 现有支付宝提现记录的 `withdraw_type` 默认为1（支付宝）
- 现有记录的 `bank_card_no`、`bank_name`、`payee_name` 为NULL（正常）

### 6.2 安全性
- 银行卡号需要加密存储（建议使用AES加密）
- 前端传输时使用HTTPS
- 审核操作需要管理员权限验证

### 6.3 业务规则
- 银行卡提现最低金额：50元（与支付宝一致）
- 银行卡提现税率：6%（与支付宝一致）
- 银行卡提现需要实名认证通过
- 银行卡信息需与实名认证姓名一致

### 6.4 用户体验
- 历史银行卡信息自动填充，减少用户输入
- 明确提示银行卡信息需与实名信息一致
- 审核状态及时反馈给用户

### 6.5 错误处理
- 银行卡号格式验证
- 金额不足提示
- 审核操作失败回滚
- 异常情况日志记录

## 七、风险评估

### 7.1 技术风险
- **数据库迁移风险**：表结构变更可能影响现有功能
  - **应对**：先在测试环境验证，做好数据备份
  
- **并发问题**：审核操作可能并发执行
  - **应对**：使用数据库事务和版本号控制

### 7.2 业务风险
- **资金安全**：银行卡提现涉及资金操作
  - **应对**：严格权限控制，操作日志记录
  
- **审核效率**：管理员需要手动审核，可能影响用户体验
  - **应对**：提供审核提醒功能，优化审核流程

## 八、后续优化建议

1. **审核提醒**：管理员审核列表增加待审核数量提醒
2. **批量审核**：支持批量确认/拒绝操作
3. **审核历史**：记录审核操作人和操作时间
4. **银行卡管理**：用户可管理多张银行卡，设置默认卡
5. **提现限额**：银行卡提现可设置不同的限额规则

## 九、文件清单

### 后端文件
- `app/main/api/desc/front/agent.api` - 前端API定义（修改）
- `app/main/api/desc/admin/admin_agent.api` - 管理员API定义（修改）
- `app/main/api/internal/logic/agent/bankcardwithdrawallogic.go` - 银行卡提现申请逻辑（新增）
- `app/main/api/internal/logic/admin_agent/adminreviewbankcardwithdrawallogic.go` - 银行卡提现审核逻辑（新增）
- `app/main/model/agentWithdrawalModel_gen.go` - 提现模型（重新生成）
- `app/main/model/agentBankCardModel.go` - 银行卡信息模型（可选，新增）

### 前端文件（用户端）
- `src/views/Withdraw.vue` - 提现页面（修改）
- `src/views/WithdrawDetails.vue` - 提现记录页面（修改）
- `src/api/withdraw.js` - API接口（修改）

### 前端文件（管理端）
- `apps/web-antd/src/views/agent/agent-withdrawal/list.vue` - 提现列表（修改）
- `apps/web-antd/src/views/agent/agent-withdrawal/modules/review-modal.vue` - 审核弹窗（新增）
- `apps/web-antd/src/views/agent/agent-withdrawal/data.ts` - 列表配置（修改）
- `apps/web-antd/src/api/agent.ts` - API接口（修改）

### 数据库文件
- `deploy/sql/bank_card_withdrawal.sql` - 数据库变更脚本（新增）

---

**预计总工期：10-15个工作日**

