# 运费模版 — 前端技术方案

> **依据：** 《运费模版功能需求.md》v1.0、《运费模版技术方案.md》v1.0  
> **前端规范：** `doc/前端设计/前端设计.md`  
> **范围：** 仅 **ruoyi-ui 商家端** 当前店铺运费模版列表、添加/编辑、设为默认、删除；商品列表 **选用** 模版见商品模块。  
> **实现状态：** 页面与 API 封装已落地，待菜单配置及 `/agri/seller/freightTemplate` 联调。

---

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

| 项 | 说明 |
|----|------|
| 框架 | Vue 2 + Element UI |
| 请求 | `@/utils/request` + `sellerShopHeaders()` |
| 参考页面 | `agri/seller/attrTemplate/index.vue`（列表 CRUD + 复杂弹窗） |
| 省份数据 | `GET /agri/region/tree` 顶层节点（`type=1` 省级） |
| 布局 | 检索 `el-card` + `<br/>` + 列表 `el-card` + `border` 表格 |
| 店铺切换 | **仅 Navbar**；业务页不展示店铺选择器 |

---

## 2. 文件清单

| 类型 | 路径 | 说明 |
|------|------|------|
| 列表页 | `ruoyi-ui/src/views/agri/seller/freightTemplate/index.vue` | 检索、列表、添加/编辑弹窗、设默认 |
| 模版 API | `ruoyi-ui/src/api/agri/seller/freightTemplate.js` | list、detail、CRUD、setDefault、options |
| 省份 API | `ruoyi-ui/src/api/agri/region.js` | 指定地区多选 |
| 店铺上下文 | `api/agri/seller/context.js` + `utils/sellerShop.js` | X-Shop-Id |

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

---

## 3. 菜单与路由

| 菜单名称 | 组件路径 | 路由 path（建议） | 权限标识 |
|----------|----------|-------------------|----------|
| 运费模版 | `agri/seller/freightTemplate/index` | `seller/freightTemplate` | `agri:seller:freightTemplate:list` |

**上级菜单：** 店铺经营管理端 → **物流** 或 **商品管理**（与属性模版并列，以运营配置为准）

| 按钮权限 | 标识 |
|----------|------|
| 列表 / 下拉 | `agri:seller:freightTemplate:list` |
| 详情回显 | `agri:seller:freightTemplate:query` |
| 添加 | `agri:seller:freightTemplate:add` |
| 编辑 / 设为默认 | `agri:seller:freightTemplate:edit` |
| 删除 / 批量删除 | `agri:seller:freightTemplate:remove` |

---

## 4. 页面结构

```text
运费模版
├── 检索区（el-card）
│   └── 模版名称 keyword（模糊）
├── 列表区（el-card + border 表格）
│   ├── 工具栏：添加运费模版、批量删除
│   ├── 列：选择框、模版名称（默认标签）、是否包邮、计价方式、发货时间、是否默认
│   └── 操作：设为默认、编辑、删除
└── 添加/编辑弹窗（920px，可滚动）
    ├── 模版名称 templateName *
    ├── 发货时间 shipTime *（预设 + 可输入）
    ├── 设为默认 isDefault（checkbox → '1'/'0'）
    ├── 是否包邮 freeFlag *（1 包邮 / 0 不包邮）
    └── [不包邮时展开]
        ├── 计价方式 pricingType（1 按件数 / 2 按重量）
        ├── 全国默认 defaultRule（首/续计量、首/续费、满免）
        └── 指定地区 regionRules[]（可多行）
            ├── 省份多选 provinceIds（biz_region.id，同模版内不重叠）
            └── 与全国相同的计价字段
```

**列表排序：** 后端 `is_default DESC, create_time DESC`；前端不再二次排序。

---

## 5. 店铺上下文

| 步骤 | 说明 |
|------|------|
| `created` | `getSellerContext` → `setSellerShopContext` |
| 业务请求 | `sellerShopHeaders()` 注入 `X-Shop-Id` |
| Navbar 切店 | `location.reload()` 整页刷新 |

---

## 6. API 封装

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

| 方法 | HTTP | 路径 |
|------|------|------|
| `listFreightTemplate(query)` | GET | `/agri/seller/freightTemplate/list` |
| `getFreightTemplate(id)` | GET | `/agri/seller/freightTemplate/{id}` |
| `addFreightTemplate(data)` | POST | `/agri/seller/freightTemplate` |
| `updateFreightTemplate(data)` | PUT | `/agri/seller/freightTemplate` |
| `setDefaultFreightTemplate(id)` | PUT | `/agri/seller/freightTemplate/default/{id}` |
| `delFreightTemplate(ids)` | DELETE | `/agri/seller/freightTemplate/{ids}` |
| `freightTemplateOptions()` | GET | `/agri/seller/freightTemplate/options` |

### 6.1 列表 Query

`pageNum`、`pageSize`、`keyword`（模版名称模糊）。

### 6.2 保存体 `FreightTemplateSaveDTO`

| 字段 | 说明 |
|------|------|
| templateId | 编辑必填 |
| templateName | 必填 |
| shipTime | 必填 |
| isDefault | `0`/`1` |
| freeFlag | `0` 不包邮 / `1` 包邮 |
| pricingType | `freeFlag=0` 时必填：`1` 按件数 / `2` 按重量 |
| defaultRule | `{ firstUnit, firstFee, addUnit, addFee, freeThreshold? }` |
| regionRules | `[{ provinceIds[], ...rule }]`；包邮时 **不传** |

### 6.3 详情回显

`GET /{id}` → `FreightTemplateDetailVO`：`defaultRule` + `regionRules[].provinceIds`。

---

## 7. 交互与校验

### 7.1 包邮切换

- `freeFlag=1`：**隐藏** 计价区；提交时不带 `pricingType/defaultRule/regionRules`。
- `freeFlag=0`：展开全国默认 + 指定地区。

### 7.2 计价方式标签

| pricingType | 首段 | 续段 | input-number precision |
|-------------|------|------|------------------------|
| `1` 按件数 | 首件数 | 续件数 | 0 |
| `2` 按重量 | 首重(kg) | 续重(kg) | 2 |

### 7.3 指定地区

- 省份来源：`getRegionTree()` **根节点**（省级 `id`/`name`）。
- **同模版内省份不可重复**：其它行已选省份在当前行 `el-option` 上 `disabled`。
- 支持 **新增/删除** 地区规则行；可不配置（仅全国默认）。

### 7.4 前端校验（提交前）

| 项 | 规则 |
|----|------|
| 模版名称 / 发货时间 | Element 表单 required |
| 不包邮 | 须选计价方式；全国默认首/续计量 **>0**，费用 **≥0** |
| 满免 | 选填；有值须 **>0** |
| 地区行 | 若配置了省份，须完整填写规则字段 |

后端另校验：名称唯一、地区重叠、商品引用删除阻断等。

### 7.5 设为默认

- 列表「设为默认」：`PUT /default/{templateId}` + 二次确认。
- 已是默认行 **disabled**。
- 表单勾选「设为默认」：保存时 `isDefault=1`，后端清除其它默认。

### 7.6 删除

- 单条 / 批量：`DELETE /{ids}`（逗号分隔）。
- 二次确认；后端 **整批失败** 时透传 `msg`（及 `data.reasons` 若有）。
- 被商品引用时阻断。

---

## 8. 权限与按钮

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

---

## 9. 与商品列表协作（规划）

| 场景 | 前端 |
|------|------|
| 发品下拉 | `freightTemplateOptions()` 或商品模块封装 |
| 默认预填 | 存在 `isDefault=1` 模版时物流区预填 |
| 保存商品 | `freight_type=2` + `freight_template_id`（商品模块实现） |

本页 **不修改** 商品列表代码；仅提供 `/options` API 封装供后续对接。

---

## 10. 联调检查清单

- [ ] 菜单：`agri/seller/freightTemplate/index`，权限 `agri:seller:freightTemplate:*`
- [ ] 列表默认模版置顶/标签
- [ ] 包邮模版保存后列表计价方式为「—」
- [ ] 不包邮 + 按件/按重量保存与回显
- [ ] 指定地区多省、省际不重叠
- [ ] 设默认后同店仅一条 `isDefault=1`
- [ ] 删除被引用模版失败提示
- [ ] 批量删除部分失败整批不删
- [ ] Navbar 切店后列表随店变化

---

## 11. 修订记录

| 版本 | 说明 |
|------|------|
| **v1.0** | 首版；对齐功能需求 v1.0、后端技术方案 v1.0；列表/复杂表单弹窗/设默认/批量删 |

---

*文档版本：v1.0 · 关联《运费模版功能需求.md》v1.0、《运费模版技术方案.md》v1.0*
