# 店铺设置 — 前端技术方案

> **依据：** 《店铺设置功能需求.md》v1.0、《店铺设置技术方案.md》v1.1  
> **前端规范：** `doc/前端设计/前端设计.md`  
> **范围：** 仅 **ruoyi-ui 商家端（店铺经营管理端）** 当前店铺资料展示/编辑、员工数量概览；**不** 维护平台全局策略、**不** 做员工 CRUD。  
> **实现状态：** 页面与 API 封装已落地，待菜单配置及 `/agri/seller/shop` 联调。

---

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

| 项 | 说明 |
|----|------|
| 框架 | Vue 2 + Element UI（与 RuoYi-Vue 一致） |
| 请求 | `@/utils/request` + `sellerShopHeaders()` 携带 **`X-Shop-Id`** |
| 参考页面 | `agri/seller/role/index.vue`（店铺上下文）、`agri/org/shop/index.vue`（店名/电话/头像校验） |
| 布局 | 资料区 `el-card` + `<br/>` + 员工概览 `el-card`（本模块无检索/表格） |
| 图片 | `image-upload` / `image-preview`（头像，5MB，png/jpg/jpeg） |
| 店铺切换 | **仅 Navbar**；业务页 **禁止** 店铺选择器（见 `doc/前端设计/前端设计.md` §5） |

---

## 2. 文件清单

| 类型 | 路径 | 说明 |
|------|------|------|
| 设置页 | `ruoyi-ui/src/views/agri/seller/shop/index.vue` | 资料展示、编辑弹窗、员工概览 |
| 店铺 API | `ruoyi-ui/src/api/agri/seller/shop.js` | 资料 GET/PUT、员工统计 GET |
| 店铺上下文 | `ruoyi-ui/src/api/agri/seller/context.js` | 已有，复用 |
| 店铺工具 | `ruoyi-ui/src/utils/sellerShop.js` | 已有，复用 |

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

---

## 3. 菜单与路由

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

| 菜单名称 | 组件路径 | 路由 path（建议） | 权限标识 |
|----------|----------|-------------------|----------|
| 店铺设置 | `agri/seller/shop/index` | `seller/shop` | `agri:seller:shop:query` |

**上级菜单：** 店铺经营管理端 → **店铺设置**（或同级入口，以运营配置为准）

| 按钮权限 | 标识 | 说明 |
|----------|------|------|
| 查看资料 / 员工概览 | `agri:seller:shop:query` | 页面进入与只读数据 |
| 编辑店铺资料 | `agri:seller:shop:edit` | 「编辑」按钮与 PUT 保存 |

**协作菜单：** 跳转员工管理须 `agri:seller:employee:list`；无权限时「前往员工管理」按钮隐藏。

> **命名区分：** 商家端 **`agri:seller:shop:*`** 与平台 **`agri:shop:setting`**（全局策略）**不可混用**。

---

## 4. 页面结构

```text
店铺设置
├── 区块 A：店铺资料（el-card + el-descriptions border）
│   ├── 工具栏：编辑（v-hasPermi edit）
│   └── 只读展示：
│       ├── 店铺头像、店铺名称
│       ├── 创建时间、店铺状态（开业/停业）
│       ├── 所属商户、客服电话（biz_shop.shop_phone）
│       ├── 负责人姓名、联系电话（商户联系人，后端脱敏）
│       └── 店铺简介
├── <br/>
├── 区块 B：员工概览（el-card）
│   ├── 工具栏：前往员工管理 → /seller/employee
│   └── 指标：
│       ├── 已有员工数 totalCount（当前店，含停用）
│       ├── 停用员工数 disabledCount
│       └── 商户配额 usedCount / maxCount（各店合计 / 平台上限）
└── 编辑弹窗（560px）
    ├── 店铺名称 shopName（必填，≤128）
    ├── 店铺头像 shopAvatar（必填，image-upload）
    ├── 店铺简介 shopDesc（选填，≤1000）
    └── 客服电话 shopPhone（选填，格式校验）
```

**不提供：** 页内店铺选择器、营业状态切换、员工 CRUD、平台全局策略编辑。

---

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

| 步骤 | 说明 |
|------|------|
| 页面 `created` | `GET /agri/seller/context` → `setSellerShopContext(shopId, shopName)` |
| 业务请求 | `sellerShopHeaders()` 注入 `X-Shop-Id` |
| 切换店铺 | Navbar `PUT /agri/seller/context/shop` 成功后 **`location.reload()`**，本页随整页刷新 |
| 数据范围 | 全部接口仅针对 **当前店铺**；切换后不得展示上一店数据 |

---

## 6. API 封装

**模块：** `ruoyi-ui/src/api/agri/seller/shop.js`

| 方法 | HTTP | 路径 | 权限 | 说明 |
|------|------|------|------|------|
| `getSellerShopProfile()` | GET | `/agri/seller/shop` | query | 返回 `SellerShopProfileVO` |
| `updateSellerShopProfile(data)` | PUT | `/agri/seller/shop` | edit | Body：`shopName/shopAvatar/shopDesc/shopPhone` |
| `getSellerShopEmployeeStats()` | GET | `/agri/seller/shop/employeeStats` | query | 返回 `SellerShopEmployeeStatsVO` |

### 6.1 资料 VO 字段映射

| 接口字段 | 界面标签 | 编辑 |
|----------|----------|:----:|
| shopAvatar | 店铺头像 | ✓ |
| shopName | 店铺名称 | ✓ |
| createTime | 创建时间 | ✗ |
| shopStatus | 店铺状态（0 开业 / 1 停业） | ✗ |
| merchantName | 所属商户 | ✗ |
| shopPhone | 客服电话 | ✓ |
| contactName | 负责人姓名 | ✗ |
| contactPhone | 联系电话（脱敏） | ✗ |
| shopDesc | 店铺简介 | ✓ |

### 6.2 员工统计 VO

| 字段 | 界面说明 |
|------|----------|
| totalCount | 当前店已有员工数（正常+停用，不含经营账号） |
| disabledCount | 当前店停用员工数 |
| usedCount | 商户级已占用名额（各店员工合计） |
| maxCount | 平台全局子管理员上限（只读） |

---

## 7. 交互与校验

### 7.1 加载流程

```text
created → loadShopContext
       → 并行 GET /shop + GET /shop/employeeStats
       → 渲染 descriptions + 统计卡片
```

### 7.2 编辑流程

```text
点击「编辑」→ 弹窗预填四字段
           → 校验通过 → PUT /agri/seller/shop
           → msgSuccess → 关闭弹窗 → 重新 GET 资料
```

### 7.3 前端校验规则

| 字段 | 规则 |
|------|------|
| shopName | 必填 |
| shopAvatar | 必填（change 触发） |
| shopDesc | 选填，maxlength 1000 |
| shopPhone | 选填；有值时 `/^[0-9\-+()\s]{5,20}$/`（对齐平台店铺管理） |

后端额外校验（前端透传 msg）：店名全平台唯一、简介过长、无权/无店铺等。

### 7.4 空值展示

未填字段统一显示 **「—」**；联系人未完善不阻断编辑。

### 7.5 跳转员工管理

```javascript
this.$router.push({ path: '/seller/employee' })
```

返回本页时可在 `activated`（若 keep-alive）或用户手动刷新时重新拉 `employeeStats`；Navbar 切店会整页 reload。

---

## 8. 权限与按钮

```html
v-hasPermi="['agri:seller:shop:edit']"      <!-- 编辑 -->
v-hasPermi="['agri:seller:employee:list']"    <!-- 前往员工管理 -->
```

仅有 `query` 无 `edit` 时：可看资料与统计，**无** 编辑按钮。

---

## 9. 与后端 / 平台协作

| 关联 | 说明 |
|------|------|
| 平台 · 店铺管理 | PUT 后 `biz_shop` 同源，平台列表无需同步任务 |
| 平台 · 商户管理 | `contactName/contactPhone` 只读 join |
| 平台 · 店铺设置 | `maxCount` 只读；文案提示联系平台调整 |
| 员工管理 | 统计口径一致；CRUD 在 `/agri/seller/employee` |
| 商品列表等 | 共用 `X-Shop-Id` 与 Navbar 切店行为 |

---

## 10. 联调检查清单

- [ ] 菜单 SQL：`component = agri/seller/shop/index`，perms `agri:seller:shop:query|edit`
- [ ] 经营账号多店：Navbar 切店后资料/统计随店变化
- [ ] 员工账号：固定绑定店，不可切店
- [ ] 保存成功后平台店铺列表名称/头像/简介/电话一致
- [ ] `usedCount/maxCount` 与 `GET /agri/seller/employee/quota` 一致
- [ ] 无 `employee:list` 权限时不展示跳转按钮
- [ ] 店名重复、头像为空、电话格式错误等后端 msg 正常弹出

---

## 11. 修订记录

| 版本 | 说明 |
|------|------|
| **v1.0** | 首版；对齐功能需求 v1.0、后端技术方案 v1.1；实现资料展示/编辑弹窗、员工概览与跳转 |

---

*文档版本：v1.0 · 关联《店铺设置功能需求.md》v1.0、《店铺设置技术方案.md》v1.1*
