店铺商品分类 — 前端技术方案
依据: 《店铺商品分类功能需求.md》v1.0、《店铺商品分类技术方案.md》v1.0
前端规范: doc/前端设计/前端设计.md
范围: 仅 ruoyi-ui 商家端(店铺经营管理端) 当前店铺商品分类 CRUD;平台端商品分类 不在本页维护。
实现状态: 页面与 API 封装已落地,待菜单配置及 /agri/seller/shopCategory 联调。
1. 技术栈与写法约定
| 项 |
说明 |
| 框架 |
Vue 2 + Element UI(与 RuoYi-Vue 一致) |
| 请求 |
@/utils/request;商家端接口携带 X-Shop-Id |
| 参考页面 |
ruoyi-ui/src/views/agri/goods/category/index.vue(两级分类树交互) |
| 商家端参考 |
ruoyi-ui/src/views/agri/seller/role/index.vue(loadShopContext 写 X-Shop-Id) |
| 布局 |
检索区 el-card + <br/> + 列表区 el-card + 表格 border |
2. 与需求文档的差异说明
| 项 |
功能需求 v1.0 |
当前后端实现 |
前端对齐 |
| 数据结构 |
单层 flat 分类 |
biz_goods_category,shop_id 非空,最多 两级 |
对齐 后端 |
| 表单字段 |
名称、排序、是否显示 |
另含 分类图片、是否热门 |
对齐 后端 |
| 删除 |
单条删除 |
支持 批量;失败时返回 data.reasons |
支持单条与批量 |
| 主键字段 |
shopCategoryId |
categoryId |
使用 categoryId |
发品侧「店铺商品分类」下拉可后续对接 GET /level2Options 或 GET /tree;本页以列表 CRUD 为主。
3. 文件清单
| 类型 |
路径 |
说明 |
| 列表页 |
ruoyi-ui/src/views/agri/seller/shopCategory/index.vue |
检索、列表、添加/编辑弹窗、批量删除 |
| 分类 API |
ruoyi-ui/src/api/agri/seller/shopCategory.js |
scope、list、tree、level1/2Options、CRUD |
| 店铺上下文 API |
ruoyi-ui/src/api/agri/seller/context.js |
登录后默认店铺、切换店铺 |
| 店铺上下文工具 |
ruoyi-ui/src/utils/sellerShop.js |
缓存 shopId、组装 X-Shop-Id 请求头 |
组件 name(keep-alive): AgriSellerShopCategory
4. 菜单与路由
若依路由由 后端菜单 动态加载,前端需配置:
| 菜单名称 |
组件路径 |
路由 path(建议) |
权限标识 |
| 店铺商品分类 |
agri/seller/shopCategory/index |
seller/shopCategory |
agri:seller:shopCategory:list |
上级菜单: 店铺经营管理端 → 商品管理
| 按钮权限 |
标识 |
| 详情回显 |
agri:seller:shopCategory:query |
| 添加分类 |
agri:seller:shopCategory:add |
| 编辑分类 |
agri:seller:shopCategory:edit |
| 删除分类 |
agri:seller:shopCategory:remove |
5. 页面结构
店铺商品分类
├── 检索区(el-card)
│ └── 分类名称 keyword(模糊,选填)
├── 列表区(el-card + border 表格)
│ ├── 提示:本店分类与平台分类数据隔离
│ ├── 工具栏:添加一级分类、批量删除
│ ├── 列:分类名称(层级标识)、上级分类、分类图片、是否显示、是否热门、排序
│ └── 操作:添加子分类(一级且 canAddChild)、编辑、删除
└── 添加/编辑弹窗(560px)
├── 分类层级(只读)
├── 上级分类 parentId(二级必填;编辑时不可改上级)
├── 分类名称 categoryName(必填)
├── 分类图片 categoryPic(必填,image-upload)
├── 排序 sortNo(≥0,默认 0)
├── 是否显示 showFlag(默认 1)
└── 是否热门 hotFlag(默认 0)
列表排序: 由后端按 sort_no 升序、create_time 升序;前端不分页内二次排序。
6. 店铺上下文(X-Shop-Id)
| 步骤 |
说明 |
页面 created |
GET /agri/seller/context → setSellerShopContext(shopId, shopName) |
| 每次 API |
sellerShopHeaders() 注入 X-Shop-Id |
| 切换店铺 |
仅 Navbar(merchant 角色)→ PUT /agri/seller/context/shop → location.reload() |
业务页禁止 展示店铺名称或选择器(见 doc/前端设计/前端设计.md §5)。
7. 接口封装
Base URL: /agri/seller/shopCategory
公共请求头: { 'X-Shop-Id': '<当前店铺ID>' }
| 方法 |
路径 |
函数名 |
用途 |
| GET |
/scope |
getShopCategoryScope |
数据范围(shopId、shopName) |
| GET |
/list |
listShopCategory |
分页列表;query:pageNum、pageSize、keyword |
| GET |
/tree |
treeShopCategory |
分类树(本页未用,供发品等复用) |
| GET |
/level1Options |
level1ShopCategoryOptions |
一级下拉(添加二级、编辑回显) |
| GET |
/level2Options |
level2ShopCategoryOptions |
二级下拉(供其他模块) |
| GET |
/{categoryId} |
getShopCategory |
编辑详情回显 |
| POST |
/ |
addShopCategory |
新增 |
| PUT |
/ |
updateShopCategory |
修改 |
| DELETE |
/{categoryIds} |
delShopCategory |
删除;多 ID 逗号分隔 |
7.1 列表行字段(CategoryRowVO)
| 字段 |
说明 |
| categoryId |
主键 |
| categoryName |
分类名称 |
| categoryLevel |
1 一级 / 2 二级 |
| parentId / parentName |
上级(一级为空) |
| categoryPic |
图片 URL |
| showFlag |
1 显示 / 0 隐藏 |
| hotFlag |
1 热门 / 0 否 |
| sortNo |
排序 |
| canAddChild |
是否可添加子分类 |
7.2 提交体(BizGoodsCategory)
| 字段 |
新增 |
编辑 |
说明 |
| categoryLevel |
必填 |
不可改 |
1 / 2 |
| parentId |
二级必填 |
不可改 |
一级传 0 |
| categoryName |
必填 |
必填 |
同店唯一 |
| categoryPic |
必填 |
必填 |
上传组件 |
| sortNo |
必填 |
必填 |
整数 ≥0 |
| showFlag |
必填 |
必填 |
默认 1 |
| hotFlag |
必填 |
必填 |
默认 0 |
| categoryId |
— |
必填 |
编辑时 |
7.3 删除交互
| 场景 |
前端提示 |
| 删除一级 |
「删除一级分类将同时删除其下全部二级分类,是否继续?」 |
| 删除二级 / 批量 |
「确认删除所选分类?分类下存在商品时无法删除」 |
| 后端拒绝 |
拦截器展示 msg;若含 data.reasons 数组,以服务端文案为准 |
8. 权限与按钮
| 操作 |
v-hasPermi |
| 添加一级 / 子分类 |
agri:seller:shopCategory:add |
| 编辑 |
agri:seller:shopCategory:edit |
| 删除 / 批量删除 |
agri:seller:shopCategory:remove |
列表查询依赖菜单权限 agri:seller:shopCategory:list;编辑回显需后端 query 权限。
9. 联调检查清单
10. 后续扩展(非本期)
| 项 |
说明 |
| 发品选分类 |
商品列表页调用 level2ShopCategoryOptions 或 treeShopCategory |
| 单层简化版 |
若产品改回 flat 模型,需后端与前端同步裁剪层级与图片字段 |
| 删除原因明细 |
可在 catch 中解析 data.reasons 用 MessageBox 逐条展示 |