# 角色管理 — 前端技术方案

> **依据：** 《角色管理功能需求.md》v1.1、《角色管理技术方案.md》v1.1  
> **前端规范：** `doc/前端设计/前端设计.md`  
> **范围：** 仅 **ruoyi-ui 商家端（店铺经营管理端）** 当前店铺员工角色 CRUD、商家端菜单权限树；平台 admin/merchant 角色 **不在本页维护**。  
> **实现状态：** 页面与 API 封装已落地，待后端 `/agri/seller/role` 及 `X-Shop-Id` 联调。

---

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

| 项 | 说明 |
|----|------|
| 框架 | Vue 2 + Element UI（与 RuoYi-Vue 一致） |
| 请求 | `@/utils/request`；商家端接口携带 **`X-Shop-Id`** |
| 参考页面 | `ruoyi-ui/src/views/system/role/index.vue`（权限树交互） |
| 布局 | 检索区 `el-card` + `<br/>` + 列表区 `el-card` + 表格 `border` |
| 状态字典 | `sys_normal_disable`（0 正常 / 1 停用） |

---

## 2. 文件清单

| 类型 | 路径 | 说明 |
|------|------|------|
| 列表页 | `ruoyi-ui/src/views/agri/seller/role/index.vue` | 列表、创建/修改弹窗、权限树 |
| 角色 API | `ruoyi-ui/src/api/agri/seller/role.js` | CRUD、menuTree |
| 店铺上下文 API | `ruoyi-ui/src/api/agri/seller/context.js` | 登录后默认店铺、切换店铺 |
| 店铺上下文工具 | `ruoyi-ui/src/utils/sellerShop.js` | 缓存 shopId、组装 `X-Shop-Id` 请求头 |

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

---

## 3. 菜单与路由

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

| 菜单名称 | 组件路径 | 路由 path（建议） | 权限标识 |
|----------|----------|-------------------|----------|
| 角色管理 | `agri/seller/role/index` | `seller/role` | `agri:seller:role:list` |

**上级菜单：** 店铺经营管理端 → **账号管理**

| 按钮权限 | 标识 |
|----------|------|
| 详情回显 | `agri:seller:role:query` |
| 创建角色 | `agri:seller:role:add` |
| 修改角色 | `agri:seller:role:edit` |
| 删除角色 | `agri:seller:role:remove` |

---

## 4. 页面结构

```text
角色管理
├── 检索区（el-card）
│   └── 角色名称 roleName（模糊，仅此一项）
├── 列表区（el-card + border 表格）
│   ├── 工具栏：创建角色
│   ├── 列：角色名称、角色描述、状态、绑定员工数、创建时间
│   └── 操作：修改角色、删除
└── 创建/修改弹窗（680px）
    ├── 角色名称 roleName（必填）
    ├── 角色描述 roleDesc（选填）
    ├── 状态 status（默认正常）
    └── 功能权限 el-tree（商家端 menuTree；至少 1 项）
```

**不提供：** 权限字符 roleKey、角色顺序（后端自动生成 `seller_s{shopId}_*`）。

---

## 5. 店铺上下文（X-Shop-Id）

| 步骤 | 说明 |
|------|------|
| 页面 `created` | `GET /agri/seller/context` → 缓存 `shopId` / `shopName` |
| 后续请求 | `sellerShop.js` 为 `/agri/seller/role/*` 附加 `X-Shop-Id` |
| 切换店铺 | **仅 Navbar**（`layout/components/Navbar.vue`）→ `PUT /agri/seller/context/shop` → `location.reload()` |

**业务页禁止** 展示店铺名称或选择器（见 `doc/前端设计/前端设计.md` §5）。

---

## 6. API 对接

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

| 前端方法 | HTTP | 路径 | 调用场景 |
|----------|------|------|----------|
| `listSellerRole` | GET | `/list` | 列表、检索、分页 |
| `sellerRoleMenuTree` | GET | `/menuTree` | 创建/编辑权限树 |
| `getSellerRole` | GET | `/{roleId}` | 编辑回显（含 menuIds、bindCount） |
| `addSellerRole` | POST | `/` | 创建角色 |
| `updateSellerRole` | PUT | `/` | 修改角色 |
| `delSellerRole` | DELETE | `/{roleIds}` | 删除 |

**店铺上下文：**

| 前端方法 | HTTP | 路径 |
|----------|------|------|
| `getSellerContext` | GET | `/agri/seller/context` |
| `switchSellerShop` | PUT | `/agri/seller/context/shop` |

### 6.1 列表请求参数

| 字段 | 说明 |
|------|------|
| pageNum, pageSize | 分页 |
| roleName | 角色名称模糊（**仅此检索项**） |

**数据范围：** 后端按 `X-Shop-Id` 过滤当前店铺角色；默认 `create_time DESC`。

### 6.2 列表行字段

| 字段 | 展示规则 |
|------|----------|
| roleName | 主展示列 |
| roleDesc | 空显示「—」 |
| status | `dict-tag` · sys_normal_disable |
| bindCount | 已绑定员工数；辅助删除判断 |
| createTime | `parseTime` |

### 6.3 创建/修改请求体

| 字段 | 表单 | 说明 |
|------|:----:|------|
| roleName | 必填 | 店铺内唯一 |
| roleDesc | 选填 | → remark |
| status | 必填 | 默认 `"0"` |
| menuIds | 必填 | 权限树勾选；至少 1 项 |
| roleId | 编辑 | 修改时必填 |

**权限树交互（对齐 RuoYi system/role）：**

- 展开/折叠、全选/全不选、父子联动
- 提交时合并 **选中 + 半选** 节点 id
- 数据源仅 **商家端** 菜单（`agri:seller:*`）

### 6.4 删除

| 场景 | 前端行为 |
|------|----------|
| 单独删除 | 二次确认；若 `bindCount>0` 提示可能失败 |
| 已绑定员工 | 后端阻断 msg「已分配给员工…」 |
| 批量删除 | **非本期**（需求未要求） |

---

## 7. 交互与校验

| 场景 | 前端行为 |
|------|----------|
| 检索 | 仅 roleName；重置恢复全量 |
| 创建 | 打开前加载 menuTree |
| 编辑 | 并行加载 menuTree + 详情；回显 `menuIds` |
| 未选权限 | 前端 `msgWarning`「请至少选择一项功能权限」 |
| 停用角色 | 表单可选停用；列表仍展示 |
| 权限变更 | 保存后已绑定员工权限由后端即时生效（RM7） |

---

## 8. 权限指令

```html
v-hasPermi="['agri:seller:role:add']"
v-hasPermi="['agri:seller:role:edit']"
v-hasPermi="['agri:seller:role:remove']"
```

---

## 9. 与关联模块边界

| 模块 | 关系 |
|------|------|
| 员工管理 | 本模块定义角色；员工管理 `roleOptions` 选用；停用角色不出现在下拉 |
| 平台角色管理 | **互斥**；不含 admin/merchant |
| 管理员列表 | 平台用户角色维护；与本模块无关 |
| 店铺设置 | 子管理员 **人数** 上限；**不限制** 角色个数 |

---

## 10. 联调检查清单

- [ ] 菜单组件路径 `agri/seller/role/index` 可打开  
- [ ] 登录后 context 写入 `X-Shop-Id`；列表仅当前店铺角色  
- [ ] Navbar 展示当前店铺（经营账号可切换）  
- [ ] roleName 模糊检索  
- [ ] 创建：名称+至少一项权限；店铺内重名后端 msg  
- [ ] 权限树仅商家端菜单  
- [ ] 编辑回显 menuIds；修改成功  
- [ ] 删除已绑定角色后端阻断  
- [ ] 切换店铺后列表范围变化（Navbar reload）  
- [ ] 经营账号外访问后端 msg「仅商户经营账号可管理角色」  

---

## 11. 非本期（前端）

| 项 | 说明 |
|----|------|
| 批量删除 | 需求未列 |
| 列表内状态开关 | 走编辑弹窗改 status |
| 平台端同名页面 | 平台用 RuoYi 系统管理 · 角色管理 |

---

## 12. 修订记录

| 版本 | 日期 | 说明 |
|------|------|------|
| v1.0 | 2026-06 | 首版：商家端角色 CRUD、X-Shop-Id、权限树、前端技术方案 |

---

*文档版本：v1.0 · ruoyi-ui · 关联《角色管理功能需求.md》v1.1 / 《角色管理技术方案.md》v1.1*
