# 商户管理 — 前端技术方案

> **依据：** 《商户管理功能需求.md》v1.7、《商户管理技术方案.md》v1.7  
> **前端规范：** `doc/前端设计/前端设计.md`  
> **范围：** 仅 **ruoyi-ui 平台管理端** 列表、添加、编辑、详情；商家端、C 端 **不在 ruoyi-ui 实现**。  
> **实现状态：** 页面与 API 封装已落地，待后端 `/agri/merchant` 联调。

---

## 1. 技术栈与写法约定

| 项 | 说明 |
|----|------|
| 框架 | Vue 2 + Element UI（与 RuoYi-Vue 一致） |
| 请求 | `@/utils/request` 封装的 axios |
| 参考页面 | `ruoyi-ui/src/views/agri/content/banner/index.vue`（双 el-card 列表 + 弹窗） |
| 详情参考 | `ruoyi-ui/src/views/system/user/view.vue`（抽屉只读展示） |
| 布局 | 检索区 `el-card` + 列表区 `el-card` + 表格 `border` |
| 状态字段 | 认证状态 `0/1/2`、主体类型 `1/2`、性别 `0/1`，**不用** Y/N 字典 |

---

## 2. 文件清单

| 类型 | 路径 | 说明 |
|------|------|------|
| 列表页 | `ruoyi-ui/src/views/agri/org/merchant/index.vue` | 列表、添加/编辑弹窗 |
| 详情抽屉 | `ruoyi-ui/src/views/agri/org/merchant/detail.vue` | 详情展示、认证状态调整 |
| API | `ruoyi-ui/src/api/agri/merchant.js` | 列表、详情、增删改、认证、绑定检索 |
| 省市区 | `ruoyi-ui/src/api/agri/region.js` | `getRegionTree` → `GET /agri/region/tree` |

**组件 name（keep-alive）：** `AgriMerchant`

---

## 3. 菜单与路由

若依路由由 **后端菜单** 动态加载，前端需配置：

| 菜单名称 | 组件路径 | 路由 path（建议） | 权限标识 |
|----------|----------|-------------------|----------|
| 商户管理 | `agri/org/merchant/index` | `merchant` | `agri:merchant:list` |

**上级菜单：** 农资管理 → **组织管理**

| 按钮权限 | 标识 |
|----------|------|
| 查看详情 | `agri:merchant:query` |
| 添加商户 | `agri:merchant:add` |
| 编辑商户 | `agri:merchant:edit` |
| 删除商户 | `agri:merchant:remove` |
| 改认证状态 | `agri:merchant:cert` |

---

## 4. 页面结构

```text
商户管理
├── 检索区（el-card）
│   ├── 商户名称 merchantName（模糊）
│   └── 认证状态 certStatus（正常/已冻结/已注销）
├── 列表区（el-card + border 表格）
│   ├── 工具栏：添加商户
│   ├── 列：所属单位、类型、名称、联系人、手机、店铺数、认证状态、认证时间
│   └── 操作：详情、编辑（canEdit）、删除（canDelete）
├── 添加/编辑弹窗（860px · el-tabs）
│   ├── Tab「主体资质」：个人 / 企业字段 + 证件照上传；企业注册地区 el-cascader
│   ├── Tab「商户经营信息」（仅编辑）：名称、经营地区 cascader、联系人、结算等
│   └── Tab「绑定经营账号」（仅新增）：管理员 / 会员远程搜索
└── 详情抽屉（detail.vue · 72% 宽）
    ├── 概要、主体资质、经营信息、关联店铺
    └── 认证状态调整（allowedCertStatuses + 二次确认）
```

---

## 5. 复用组件

| 组件 | 路径 | 用途 |
|------|------|------|
| `Pagination` | 全局注册 | 分页 |
| `RightToolbar` | 全局注册 | 检索区显隐 |
| `ImageUpload` | `@/components/ImageUpload` | 证件照、营业执照上传 |
| `ImagePreview` | `@/components/ImagePreview` | 详情页证照预览 |

**图片上传参数：**

| 属性 | 值 |
|------|-----|
| `limit` | `1` |
| `file-size` | `5`（MB） |
| `file-type` | `['png','jpg','jpeg']` |

**日期区间（`doc/前端设计/前端设计.md` §3.4）：**

| 场景 | 组件 | 提交拆分 |
|------|------|----------|
| 个人证件有效期 | `el-date-picker type="daterange"` → `idValidRange` | `idValidStart` / `idValidEnd` |
| 法人证件有效期 | `el-date-picker type="daterange"` → `legalIdValidRange` | `legalIdValidStart` / `legalIdValidEnd` |
| 企业营业期限 | `el-date-picker type="daterange"` → `licenseValidRange` | `licenseValidStart` / `licenseValidEnd` |
| 长期有效 | `idValidType=2` / `legalIdValidType=2` / `licenseValidType=2`，仅填起始日 | `*ValidEnd` 可为 null |

**省市区级联（v1.7 · `el-cascader`）：**

| 场景 | 组件 | 数据源 | 落库字段 |
|------|------|--------|----------|
| 企业注册地址 | `form.regRegionCascader` | `getRegionTree()` | `regRegionCode`（区县 `code`）、`regRegionName`（省/市/区县 `/` 连接） |
| 经营地址（编辑 Tab） | `form.bizRegionCascader` | 同上 | `bizRegionCode`、`bizRegionName` |
| 详细地址 | `el-input` | — | `companyDetailAddress` / `bizDetailAddress` |

级联配置：`value: code`、`label: name`、`children: children`、`emitPath: true`；支持 `filterable`、`clearable`。编辑回显按已存 `*RegionCode` 在树中查找路径；提交前剔除 `regRegionCascader` / `bizRegionCascader` 仅 UI 字段。

---

## 6. API 对接

**基路径：** `/agri/merchant`（见 `src/api/agri/merchant.js`）

| 前端方法 | HTTP | 路径 | 调用场景 |
|----------|------|------|----------|
| `listMerchant` | GET | `/list` | 列表、检索、分页 |
| `getMerchant` | GET | `/{merchantId}` | 编辑回显、详情 |
| `addMerchant` | POST | `/` | 添加（主体 + 绑定） |
| `updateMerchant` | PUT | `/` | 编辑（主体 + 经营） |
| `updateMerchantCertStatus` | PUT | `/{merchantId}/certStatus` | 详情改认证 |
| `deleteMerchantCheck` | GET | `/{merchantId}/deleteCheck` | 可选预检 |
| `delMerchant` | DELETE | `/{merchantIds}` | 删除 |
| `selectMerchantList` | GET | `/selectList` | 店铺模块选商户（供 shop 页复用） |
| `adminUserOptions` | GET | `/adminUserOptions` | 新增绑定管理员远程搜索 |
| `memberOptions` | GET | `/memberOptions` | 新增绑定会员远程搜索 |

### 6.1 省市区（v1.7）

**基路径：** `/agri/region`（见 `src/api/agri/region.js`）

| 前端方法 | HTTP | 路径 | 说明 |
|----------|------|------|------|
| `getRegionTree` | GET | `/tree` | 省/市/区县三级树；节点含 `id`、`pid`、`name`、`type`（1省/2市/3区县）、`code`、`children` |

页面 `created` 预加载并缓存；添加/编辑弹窗打开时若未加载则再次请求。落库规则与后端 §9.9 一致：`code` 取选中区县，`name` 为路径名称用 `/` 拼接。

### 6.2 列表请求参数

| 字段 | 说明 |
|------|------|
| pageNum, pageSize | 分页 |
| merchantName | 模糊（名称 / 所属单位） |
| certStatus | `0` 正常 / `1` 冻结 / `2` 注销 |

### 6.3 列表行字段

| 字段 | 展示规则 |
|------|----------|
| unitName | 个人姓名 / 企业名称 |
| merchantName | 空则显示「待完善」 |
| contactName, contactPhone | 未完善显示「—」 |
| canEdit, canDelete | 后端布尔，控制按钮显隐 |

### 6.4 新增请求体要点（v1.5 / v1.6）

- **仅** 主体资质 + `bindType`（`SYS_USER` / `MEMBER`）+ `bindUserId` 或 `bindMemberId`
- **不含** 经营信息字段
- **平台新增最小必填**（`validateSubjectOnInsert`）：
  - 个人：仅 `personName`
  - 企业：仅 `legalName` + `companyName`
- **v1.5 新增主体字段**：`idCardType` / `legalIdCardType`（1 大陆身份证 / 2 来往内地通行证）、`regRegionCode` / `regRegionName`（v1.7 由级联写入）、`corpBankAccount`、法人证件有效期区间等
- **会员绑定（v1.6）**：登录名=会员名称、管理员姓名=会员昵称；密码复制会员 `sys_user.password`；**不传** `sysUserInitPassword`
- **管理员绑定（v1.6）**：检索范围 `role_key=merchant`；登录名=`user_name`、管理员姓名=`nick_name`

### 6.4.1 绑定 Tab UI

| bindType | 远程搜索 | 下拉展示 |
|----------|----------|----------|
| SYS_USER | `adminUserOptions(keyword)` | 昵称 / 用户名 / 手机号 |
| MEMBER | `memberOptions(keyword)` | memberCode / nickName / 脱敏 mobile |

顶部 `el-alert` 说明绑定落库规则；**已移除** 会员「初始密码」输入框。

### 6.5 编辑请求体要点

- 含 `merchantId`、主体字段、经营信息字段；经营 Tab 含 `bizRegionCode` / `bizRegionName` / `bizDetailAddress`
- **不传** `certStatus`（认证仅在详情改）
- 入驻后 `idCardNo`、`creditCode` 前端 disabled，仍随表单提交

### 6.6 认证状态变更

```json
{ "certStatus": "1", "confirm": true }
```

详情页先 `$modal.confirm(confirmMessage)`，再 `confirm: true` 提交。

### 6.7 保存成功扩展

| response.data | 前端行为 |
|---------------|----------|
| `warnExpired` | `msgWarning` 证件/营业期限过期 |
| `bizCompleteChanged` | `msgSuccess`「已可开设店铺」 |
| 新增成功 | 固定提示「请尽快在编辑中完善商户经营信息后再开设店铺」 |

---

## 7. 交互与校验

| 场景 | 前端行为 |
|------|----------|
| 添加 Tab | 默认「主体资质」；切换个人/企业重置 subject 字段 |
| 新增校验 | 个人仅姓名必填；企业仅法人姓名+企业名称必填；证件号/信用代码选填 |
| 绑定搜索 | `el-select` + `remote` + `filterable`；keyword 空不请求 |
| 编辑 Tab | 「主体资质」+「商户经营信息」；无绑定 Tab |
| 注册/经营地址 | 企业主体 Tab 选注册地区；编辑经营 Tab 选经营地区；均为 `el-cascader` + 详细地址输入 |
| 详情跳转店铺 | `$router.push({ path: '/agri/org/shop', query: { merchantName } })` |
| 删除 | 先 `deleteMerchantCheck`；`canDelete=false` 展示 reasons；通过后再二次确认 |
| 列表名称 | `merchantName` 空显示「待完善」 |
| 详情 pendingBizFields | 待完善项中文标签展示 |

---

## 8. 权限指令

```html
v-hasPermi="['agri:merchant:add']"
v-hasPermi="['agri:merchant:edit']"
v-hasPermi="['agri:merchant:remove']"
v-hasPermi="['agri:merchant:query']"
v-hasPermi="['agri:merchant:cert']"
```

---

## 9. 与关联模块边界

| 模块 | 关系 |
|------|------|
| 店铺管理 | 详情可跳转店铺列表；`selectMerchantList` 供开店选商户 |
| 入驻审核 | 审核通过后商户在 **本模块** 维护；申请单不在此列表 |
| 会员管理 | 新增时可选绑定会员；列表 **不展示** 会员列 |

---

## 10. 联调检查清单

- [ ] 新增个人仅填姓名可提交；企业仅法人姓名+企业名称可提交  
- [ ] 绑定会员无初始密码字段；admin/member 远程搜索展示正确  
- [ ] 删除 deleteCheck 阻断并展示 reasons  
- [ ] 详情展示 idCardType、regRegion、bizRegion、corpBankAccount、法人完整字段  
- [ ] 菜单组件路径 `agri/org/merchant/index` 可打开  
- [ ] 列表分页、检索、canEdit/canDelete 正确  
- [ ] 新增仅主体 + 绑定；成功后提示完善经营信息  
- [ ] 编辑补全经营信息后 `bizCompleteChanged`  
- [ ] 详情 `allowedCertStatuses` 流转与二次确认  
- [ ] 证件号/信用代码编辑页 disabled  
- [ ] 删除前置条件后端 msg 正常弹出  
- [ ] `GET /agri/region/tree` 返回三级树；级联选中后 `regRegionCode`/`regRegionName`、`bizRegionCode`/`bizRegionName` 与后端 §9.9 一致  
- [ ] 编辑回显：已存区县 code 能正确还原级联路径  

---

## 11. 非本期（前端）

| 项 | 说明 |
|----|------|
| 商家端登录 | 另端 |
| OCR / 导出 Excel | 不做 |

---

## 12. 修订记录

| 版本 | 日期 | 说明 |
|------|------|------|
| v1.3 | 2026-06 | 接入 `GET /agri/region/tree`；企业注册地址、经营地址改为 `el-cascader`；新增 `api/agri/region.js` |
| v1.2 | 2026-05 | 对齐 v1.6：绑定 Tab、主体扩展字段、deleteCheck |
| v1.1 | 2026-05 | 对齐 v1.6：角色 merchant/member；会员绑定不传初始密码 |
| v1.0 | 2026-05 | 首版：列表 CRUD、详情抽屉、绑定远程搜索 |

---

*文档版本：v1.3 · ruoyi-ui · 关联《商户管理功能需求.md》v1.7 / 《商户管理技术方案.md》v1.7*

