From d5734f0e37b93ec7f8be4ab0d470320a7fbe96ec Mon Sep 17 00:00:00 2001 From: xuqiuyun <1113560936@qq.com> Date: Tue, 14 Oct 2025 17:31:16 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BB=A7=E7=BB=AD=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test_member_data.sql | 31 - 修复delivery_edit权限.sql | 77 -- 修复编辑权限.sql | 36 - 修复菜单乱码.sql | 31 - 修复验证查询.sql | 17 - 完整权限检查.sql | 73 - 快速修复权限.sql | 41 - 快速启动指南.md | 178 --- 数据库连接信息和SQL执行指南.md | 314 ----- 智能项圈功能实现总结.md | 132 ++ 权限管理功能使用说明.md | 568 -------- 权限管理功能初始化SQL.sql | 152 --- 权限管理和运送清单新增功能实施计划.md | 1795 ------------------------- 权限管理菜单-UTF8.sql | 45 - 权限管理菜单-精简版.sql | 88 -- 检查权限分配.sql | 52 - 检查权限分配情况.sql | 66 - 检查超级管理员权限.sql | 14 - 添加设备运单字段.sql | 7 + 添加项圈运单字段.sql | 10 + 牛只运输功能模块整理.md | 154 --- 确保delivery_edit权限.sql | 41 - 简化权限修复.sql | 64 - 车身照片关联查询功能实现说明.md | 170 +++ 重新创建权限管理菜单.sql | 67 - 需求文档.md | 146 -- 26 files changed, 319 insertions(+), 4050 deletions(-) delete mode 100644 test_member_data.sql delete mode 100644 修复delivery_edit权限.sql delete mode 100644 修复编辑权限.sql delete mode 100644 修复菜单乱码.sql delete mode 100644 修复验证查询.sql delete mode 100644 完整权限检查.sql delete mode 100644 快速修复权限.sql delete mode 100644 快速启动指南.md delete mode 100644 数据库连接信息和SQL执行指南.md create mode 100644 智能项圈功能实现总结.md delete mode 100644 权限管理功能使用说明.md delete mode 100644 权限管理功能初始化SQL.sql delete mode 100644 权限管理和运送清单新增功能实施计划.md delete mode 100644 权限管理菜单-UTF8.sql delete mode 100644 权限管理菜单-精简版.sql delete mode 100644 检查权限分配.sql delete mode 100644 检查权限分配情况.sql delete mode 100644 检查超级管理员权限.sql create mode 100644 添加设备运单字段.sql create mode 100644 添加项圈运单字段.sql delete mode 100644 牛只运输功能模块整理.md delete mode 100644 确保delivery_edit权限.sql delete mode 100644 简化权限修复.sql create mode 100644 车身照片关联查询功能实现说明.md delete mode 100644 重新创建权限管理菜单.sql delete mode 100644 需求文档.md diff --git a/test_member_data.sql b/test_member_data.sql deleted file mode 100644 index 9ce38b5..0000000 --- a/test_member_data.sql +++ /dev/null @@ -1,31 +0,0 @@ --- 插入测试的member数据 --- 首先插入租户数据 -INSERT INTO sys_tenant (name, mobile, create_time, is_delete) VALUES -('测试租户1', '13800000001', NOW(), 0), -('测试租户2', '13800000002', NOW(), 0), -('测试租户3', '13800000003', NOW(), 0); - --- 插入member数据 -INSERT INTO member (mobile, type, status, create_time, tenant_id) VALUES --- 供应商 (type=2) -('13800001001', 2, 1, NOW(), 1), -('13800001002', 2, 1, NOW(), 1), -('13800001003', 2, 1, NOW(), 2), --- 资金方 (type=3) -('13800002001', 3, 1, NOW(), 1), -('13800002002', 3, 1, NOW(), 2), --- 采购商 (type=4) -('13800003001', 4, 1, NOW(), 1), -('13800003002', 4, 1, NOW(), 2), -('13800003003', 4, 1, NOW(), 3); - --- 插入member_user数据(用户名信息) -INSERT INTO member_user (member_id, username) VALUES -(1, '供应商A'), -(2, '供应商B'), -(3, '供应商C'), -(4, '资金方A'), -(5, '资金方B'), -(6, '采购商A'), -(7, '采购商B'), -(8, '采购商C'); diff --git a/修复delivery_edit权限.sql b/修复delivery_edit权限.sql deleted file mode 100644 index 1a75113..0000000 --- a/修复delivery_edit权限.sql +++ /dev/null @@ -1,77 +0,0 @@ --- 检查超级管理员权限的完整脚本 --- 1. 检查超级管理员用户信息 -SELECT - u.id, - u.mobile, - u.name, - u.role_id, - r.role_name, - r.role_code -FROM sys_user u -LEFT JOIN sys_role r ON u.role_id = r.id -WHERE u.mobile = '15900000000'; - --- 2. 检查 delivery:edit 权限是否存在 -SELECT - id, - name, - authority, - parent_id, - type -FROM sys_menu -WHERE authority = 'delivery:edit'; - --- 3. 检查超级管理员是否有 delivery:edit 权限 -SELECT - u.mobile, - u.name, - r.role_name, - m.name as menu_name, - m.authority, - rm.role_id, - rm.menu_id -FROM sys_user u -LEFT JOIN sys_role r ON u.role_id = r.id -LEFT JOIN sys_role_menu rm ON r.id = rm.role_id -LEFT JOIN sys_menu m ON rm.menu_id = m.id -WHERE u.mobile = '15900000000' - AND m.authority = 'delivery:edit'; - --- 4. 如果权限不存在,添加权限 --- 首先确保 delivery:edit 权限点存在 -INSERT INTO sys_menu (parent_id, type, name, authority, sort, is_delete, create_time) -SELECT - (SELECT id FROM sys_menu WHERE route_url LIKE '%delivery%' OR route_url LIKE '%loading%' LIMIT 1), - 2, - '运送清单编辑', - 'delivery:edit', - 3, - 0, - NOW() -WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE authority = 'delivery:edit'); - --- 5. 确保超级管理员角色有 delivery:edit 权限 -INSERT INTO sys_role_menu (role_id, menu_id) -SELECT - (SELECT id FROM sys_role WHERE role_name = '超级管理员' OR id = 1 LIMIT 1), - (SELECT id FROM sys_menu WHERE authority = 'delivery:edit') -WHERE NOT EXISTS ( - SELECT 1 FROM sys_role_menu rm - INNER JOIN sys_role r ON rm.role_id = r.id - INNER JOIN sys_menu m ON rm.menu_id = m.id - WHERE (r.role_name = '超级管理员' OR r.id = 1) AND m.authority = 'delivery:edit' -); - --- 6. 最终验证 -SELECT - u.mobile, - u.name, - r.role_name, - m.name as menu_name, - m.authority -FROM sys_user u -LEFT JOIN sys_role r ON u.role_id = r.id -LEFT JOIN sys_role_menu rm ON r.id = rm.role_id -LEFT JOIN sys_menu m ON rm.menu_id = m.id -WHERE u.mobile = '15900000000' - AND m.authority = 'delivery:edit'; diff --git a/修复编辑权限.sql b/修复编辑权限.sql deleted file mode 100644 index ecdc531..0000000 --- a/修复编辑权限.sql +++ /dev/null @@ -1,36 +0,0 @@ --- 修复装车订单编辑权限问题 --- 1. 确保 delivery:edit 权限存在 -INSERT INTO sys_menu (parent_id, type, name, authority, sort, is_delete, create_time) -SELECT - (SELECT id FROM sys_menu WHERE route_url LIKE '%delivery%' OR route_url LIKE '%loading%' LIMIT 1), - 2, - '运送清单编辑', - 'delivery:edit', - 3, - 0, - NOW() -WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE authority = 'delivery:edit'); - --- 2. 确保超级管理员角色有 delivery:edit 权限 -INSERT INTO sys_role_menu (role_id, menu_id) -SELECT - 1, -- 超级管理员角色ID - (SELECT id FROM sys_menu WHERE authority = 'delivery:edit') -WHERE NOT EXISTS ( - SELECT 1 FROM sys_role_menu rm - WHERE rm.role_id = 1 AND rm.menu_id = (SELECT id FROM sys_menu WHERE authority = 'delivery:edit') -); - --- 3. 验证权限分配 -SELECT - u.mobile, - u.name, - r.role_name, - m.name as menu_name, - m.authority -FROM sys_user u -LEFT JOIN sys_role r ON u.role_id = r.id -LEFT JOIN sys_role_menu rm ON r.id = rm.role_id -LEFT JOIN sys_menu m ON rm.menu_id = m.id -WHERE u.mobile = '15900000000' - AND m.authority = 'delivery:edit'; diff --git a/修复菜单乱码.sql b/修复菜单乱码.sql deleted file mode 100644 index 240f7d3..0000000 --- a/修复菜单乱码.sql +++ /dev/null @@ -1,31 +0,0 @@ --- ============================================ --- 修复权限管理菜单乱码问题 --- 请在 Navicat/HeidiSQL/MySQL Workbench 等图形化工具中执行 --- ============================================ - --- 设置字符集 -SET NAMES utf8mb4; -SET CHARACTER SET utf8mb4; - --- 更新菜单名称 -UPDATE `sys_menu` SET `name` = '权限管理' WHERE `id` = 28; -UPDATE `sys_menu` SET `name` = '菜单权限管理' WHERE `id` = 29; -UPDATE `sys_menu` SET `name` = '菜单查询' WHERE `id` = 30; -UPDATE `sys_menu` SET `name` = '菜单新增' WHERE `id` = 31; -UPDATE `sys_menu` SET `name` = '菜单编辑' WHERE `id` = 32; -UPDATE `sys_menu` SET `name` = '菜单删除' WHERE `id` = 33; -UPDATE `sys_menu` SET `name` = '角色分配' WHERE `id` = 34; -UPDATE `sys_menu` SET `name` = '操作权限管理' WHERE `id` = 35; -UPDATE `sys_menu` SET `name` = '权限查询' WHERE `id` = 36; -UPDATE `sys_menu` SET `name` = '权限分配' WHERE `id` = 37; -UPDATE `sys_menu` SET `name` = '角色管理' WHERE `id` = 38; - --- 验证结果 -SELECT id, parent_id, type, name, route_url, authority -FROM sys_menu -WHERE id >= 28 -ORDER BY parent_id, sort, id; - --- 显示成功信息 -SELECT '✅ 菜单名称已修复!' as status; - diff --git a/修复验证查询.sql b/修复验证查询.sql deleted file mode 100644 index 6b6a07f..0000000 --- a/修复验证查询.sql +++ /dev/null @@ -1,17 +0,0 @@ --- 修复验证查询的字段名错误 --- 检查 sys_role 表的字段结构 -DESCRIBE sys_role; - --- 正确的验证查询(使用正确的字段名) -SELECT - u.mobile, - u.name, - r.name as role_name, -- 修正:使用 r.name 而不是 r.role_name - m.name as menu_name, - m.authority -FROM sys_user u -LEFT JOIN sys_role r ON u.role_id = r.id -LEFT JOIN sys_role_menu rm ON r.id = rm.role_id -LEFT JOIN sys_menu m ON rm.menu_id = m.id -WHERE u.mobile = '15900000000' - AND m.authority = 'delivery:edit'; diff --git a/完整权限检查.sql b/完整权限检查.sql deleted file mode 100644 index 5818528..0000000 --- a/完整权限检查.sql +++ /dev/null @@ -1,73 +0,0 @@ --- 完整检查权限分配和修复 --- 1. 检查超级管理员用户信息 -SELECT - u.id, - u.mobile, - u.name, - u.role_id, - r.name as role_name -FROM sys_user u -LEFT JOIN sys_role r ON u.role_id = r.id -WHERE u.mobile = '15900000000'; - --- 2. 检查 delivery:edit 权限是否存在 -SELECT - id, - name, - authority, - parent_id, - type -FROM sys_menu -WHERE authority = 'delivery:edit'; - --- 3. 如果不存在,创建 delivery:edit 权限 -INSERT INTO sys_menu (parent_id, type, name, authority, sort, is_delete, create_time) -SELECT - (SELECT id FROM sys_menu WHERE route_url LIKE '%delivery%' OR route_url LIKE '%loading%' LIMIT 1), - 2, - '运送清单编辑', - 'delivery:edit', - 3, - 0, - NOW() -WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE authority = 'delivery:edit'); - --- 4. 确保超级管理员角色有 delivery:edit 权限 -INSERT INTO sys_role_menu (role_id, menu_id) -SELECT - 1, -- 超级管理员角色ID - (SELECT id FROM sys_menu WHERE authority = 'delivery:edit') -WHERE NOT EXISTS ( - SELECT 1 FROM sys_role_menu rm - WHERE rm.role_id = 1 AND rm.menu_id = (SELECT id FROM sys_menu WHERE authority = 'delivery:edit') -); - --- 5. 检查所有 delivery 相关权限 -SELECT - u.mobile, - u.name, - r.name as role_name, - m.name as menu_name, - m.authority -FROM sys_user u -LEFT JOIN sys_role r ON u.role_id = r.id -LEFT JOIN sys_role_menu rm ON r.id = rm.role_id -LEFT JOIN sys_menu m ON rm.menu_id = m.id -WHERE u.mobile = '15900000000' - AND m.authority LIKE '%delivery%' -ORDER BY m.authority; - --- 6. 检查是否有通配符权限 -SELECT - u.mobile, - u.name, - r.name as role_name, - m.name as menu_name, - m.authority -FROM sys_user u -LEFT JOIN sys_role r ON u.role_id = r.id -LEFT JOIN sys_role_menu rm ON r.id = rm.role_id -LEFT JOIN sys_menu m ON rm.menu_id = m.id -WHERE u.mobile = '15900000000' - AND m.authority = '*:*:*' -ORDER BY m.authority; diff --git a/快速修复权限.sql b/快速修复权限.sql deleted file mode 100644 index cfc1c45..0000000 --- a/快速修复权限.sql +++ /dev/null @@ -1,41 +0,0 @@ --- 快速修复 delivery:edit 权限问题 --- 1. 删除可能存在的重复权限 -DELETE FROM sys_menu WHERE authority = 'delivery:edit' AND id NOT IN ( - SELECT menu_id FROM sys_role_menu WHERE role_id = 1 -); - --- 2. 确保 delivery:edit 权限存在 -INSERT INTO sys_menu (parent_id, type, name, authority, sort, is_delete, create_time) -SELECT - (SELECT id FROM sys_menu WHERE route_url LIKE '%delivery%' OR route_url LIKE '%loading%' LIMIT 1), - 2, - '运送清单编辑', - 'delivery:edit', - 3, - 0, - NOW() -WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE authority = 'delivery:edit'); - --- 3. 确保超级管理员有 delivery:edit 权限 -INSERT INTO sys_role_menu (role_id, menu_id) -SELECT - 1, -- 超级管理员角色ID - (SELECT id FROM sys_menu WHERE authority = 'delivery:edit') -WHERE NOT EXISTS ( - SELECT 1 FROM sys_role_menu rm - WHERE rm.role_id = 1 AND rm.menu_id = (SELECT id FROM sys_menu WHERE authority = 'delivery:edit') -); - --- 4. 验证结果 -SELECT - u.mobile, - u.name, - r.role_name, - m.name as menu_name, - m.authority -FROM sys_user u -LEFT JOIN sys_role r ON u.role_id = r.id -LEFT JOIN sys_role_menu rm ON r.id = rm.role_id -LEFT JOIN sys_menu m ON rm.menu_id = m.id -WHERE u.mobile = '15900000000' - AND m.authority = 'delivery:edit'; diff --git a/快速启动指南.md b/快速启动指南.md deleted file mode 100644 index c573d55..0000000 --- a/快速启动指南.md +++ /dev/null @@ -1,178 +0,0 @@ -# 🚀 权限管理功能 - 快速启动指南 - -## 第一步:执行数据库脚本 📊 - -在您的MySQL数据库客户端中执行: - -```bash -c:/cattleTransport/权限管理功能初始化SQL.sql -``` - -这个脚本会: -- ✅ 创建权限管理相关菜单 -- ✅ 设置 15900000000 为超级管理员(密码:123456) -- ✅ 配置所有必要的权限数据 - -## 第二步:启动服务 🔌 - -### 后端已经启动 ✅ - -后端服务正在后台运行: -- 地址:`http://127.0.0.1:16200` - -如需重启后端,执行: -```bash -# 停止Java进程 -taskkill /F /IM java.exe - -# 重新启动 -cd c:\cattleTransport\tradeCattle\aiotagro-cattle-trade -java -jar target\aiotagro-cattletrade-1.0.1.jar -``` - -### 启动前端 - -```bash -cd c:\cattleTransport\pc-cattle-transportation -npm run dev -``` - -前端地址:`http://localhost:8080` - -## 第三步:登录测试 👤 - -### 超级管理员登录 - -- **账号**:`15900000000` -- **密码**:`123456` - -### 测试功能 - -登录后,在系统菜单中找到: - -1. **权限管理** → **菜单权限管理** - - 查看和管理所有系统菜单 - - 新增、编辑、删除菜单项 - -2. **权限管理** → **操作权限管理** - - 管理角色 - - 为角色分配菜单和按钮权限 - -3. **运送清单** → **新增运送清单** - - 测试新的运送清单创建功能 - - 验证权限控制是否生效 - -## 第四步:验证权限功能 ✔️ - -### 验证超级管理员权限 - -1. 使用 15900000000 登录 -2. 确认所有菜单都可见 -3. 确认所有按钮都可点击 -4. 测试新增菜单 -5. 测试为角色分配权限 - -### 创建普通角色并测试 - -1. 进入"操作权限管理" -2. 点击"新增角色",创建"测试角色" -3. 为"测试角色"分配部分权限(如只分配运送清单查看权限) -4. 在用户管理中创建测试用户,分配"测试角色" -5. 退出超级管理员,用测试用户登录 -6. 验证: - - ✅ 只能看到被分配的菜单 - - ✅ 只能看到被分配的按钮 - - ✅ 无权限操作被后端拦截 - - ✅ 只能看到自己创建的数据 - -## 第五步:故障排查 🔧 - -### 问题1:SQL脚本执行失败 - -**检查点**: -- MySQL版本是否支持(建议5.7+) -- 数据库连接是否正常 -- 是否有权限执行DDL和DML语句 - -**解决方案**: -- 分段执行SQL脚本 -- 检查错误提示,手动修复冲突 - -### 问题2:后端启动失败 - -**检查点**: -- 16200端口是否被占用 -- 数据库连接配置是否正确 -- Redis是否启动(如果配置了) - -**解决方案**: -```bash -# 查看后端日志 -cd c:\cattleTransport\tradeCattle\aiotagro-cattle-trade -# 查看控制台输出或日志文件 -``` - -### 问题3:前端访问不了后端API - -**检查点**: -- 后端是否正常启动 -- Vite proxy配置是否正确 -- 浏览器控制台是否有跨域错误 - -**解决方案**: -- 检查 `vite.config.ts` 中的 proxy 配置 -- 确认后端地址为 `http://127.0.0.1:16200` -- 重启前端服务 - -### 问题4:登录后看不到权限管理菜单 - -**检查点**: -- SQL脚本是否执行成功 -- 用户角色是否正确 -- sys_role_menu 表是否有数据 - -**解决方案**: -```sql --- 检查菜单数据 -SELECT * FROM sys_menu WHERE name LIKE '%权限%'; - --- 检查用户角色 -SELECT * FROM sys_user WHERE mobile = '15900000000'; - --- 检查超级管理员权限 -SELECT COUNT(*) FROM sys_role_menu WHERE role_id = 1; -``` - -### 问题5:权限控制不生效 - -**检查点**: -- 登录接口是否返回了permissions字段 -- Pinia store是否保存了权限数据 -- Controller是否添加了@SaCheckPermission注解 - -**解决方案**: -- 清除浏览器缓存和localStorage -- 重新登录 -- 检查浏览器控制台和Network请求 - -## 📚 完整文档 - -- **使用说明**:`c:/cattleTransport/权限管理功能使用说明.md` -- **实施计划**:`c:/cattleTransport/权限管理和运送清单新增功能实施计划.md` -- **SQL脚本**:`c:/cattleTransport/权限管理功能初始化SQL.sql` - -## 🎉 功能亮点 - -1. ✅ **完整的RBAC权限控制** - 角色、菜单、按钮三级权限 -2. ✅ **超级管理员机制** - 一键拥有所有权限 -3. ✅ **数据权限隔离** - 普通用户只能看自己的数据 -4. ✅ **前后端权限联动** - 前端v-hasPermi指令 + 后端@SaCheckPermission注解 -5. ✅ **可视化权限管理** - 树形权限分配界面 -6. ✅ **新增运送清单功能** - PC端完整的创建表单 - ---- - -**祝您使用愉快!** 🎊 - -如有问题,请参考《权限管理功能使用说明.md》文档。 - diff --git a/数据库连接信息和SQL执行指南.md b/数据库连接信息和SQL执行指南.md deleted file mode 100644 index f0f6a3d..0000000 --- a/数据库连接信息和SQL执行指南.md +++ /dev/null @@ -1,314 +0,0 @@ -# 🗄️ 数据库连接信息和SQL执行指南 - -## 📊 数据库配置信息 - -从后端配置文件 `application-dev.yml` 中提取的数据库信息: - -```yaml -数据库类型: MySQL -主机地址: 129.211.213.226 -端口: 3306 -数据库名: cattletrade -用户名: root -密码: Aiotagro@741 -字符集: UTF-8 -时区: GMT+8 -``` - ---- - -## 🚀 快速执行SQL脚本 - -### 方式一:使用MySQL命令行(推荐) - -```bash -# Windows CMD 或 PowerShell -mysql -h 129.211.213.226 -P 3306 -u root -pAiotagro@741 cattletrade < "c:/cattleTransport/权限管理菜单-精简版.sql" - -# 或者交互式执行 -mysql -h 129.211.213.226 -P 3306 -u root -pAiotagro@741 cattletrade -``` - -进入MySQL后执行: -```sql -source c:/cattleTransport/权限管理菜单-精简版.sql -``` - ---- - -### 方式二:使用Navicat - -1. **新建连接**: - - 连接名:牛只运输系统 - - 主机:`129.211.213.226` - - 端口:`3306` - - 用户名:`root` - - 密码:`Aiotagro@741` - - 数据库:`cattletrade` - -2. **测试连接** → 连接成功后,双击打开 - -3. **执行SQL**: - - 点击"查询" → "新建查询" - - 打开文件:`c:/cattleTransport/权限管理菜单-精简版.sql` - - 点击"运行"按钮(或按 `F5`) - ---- - -### 方式三:使用HeidiSQL - -1. **新建会话**: - - 网络类型:MySQL (TCP/IP) - - 主机名/IP:`129.211.213.226` - - 用户:`root` - - 密码:`Aiotagro@741` - - 端口:`3306` - - 数据库:`cattletrade` - -2. **打开**,右侧选择 `cattletrade` 数据库 - -3. **执行SQL**: - - 点击"文件" → "加载SQL文件" - - 选择:`c:/cattleTransport/权限管理菜单-精简版.sql` - - 点击"执行"(或按 `F9`) - ---- - -### 方式四:使用DBeaver - -1. **新建连接**: - - 数据库:MySQL - - 服务器地址:`129.211.213.226` - - 端口:`3306` - - 数据库:`cattletrade` - - 用户名:`root` - - 密码:`Aiotagro@741` - -2. **测试连接** → 完成 - -3. **执行SQL**: - - 右键数据库 → "SQL编辑器" → "打开SQL脚本" - - 选择:`c:/cattleTransport/权限管理菜单-精简版.sql` - - 点击"执行SQL脚本"(或按 `Ctrl+Enter`) - ---- - -## ✅ 执行后验证 - -### 1. 检查菜单是否创建成功 - -```sql --- 查看权限管理相关菜单 -SELECT id, parent_id, name, route_url, authority, sort -FROM sys_menu -WHERE name LIKE '%权限%' - AND is_delete = 0 -ORDER BY parent_id, sort; -``` - -**预期结果**:应该看到3条记录: -- 权限管理(父菜单) -- 菜单权限管理(子菜单) -- 操作权限管理(子菜单) - ---- - -### 2. 检查超级管理员账号 - -```sql --- 查看超级管理员用户 -SELECT id, mobile, name, role_id, status, user_type -FROM sys_user -WHERE mobile = '15900000000'; -``` - -**预期结果**: -- `role_id` 应该为 `1` -- `status` 应该为 `1`(启用) - ---- - -### 3. 检查超级管理员权限 - -```sql --- 查看超级管理员拥有的权限数量 -SELECT COUNT(*) as '权限总数' -FROM sys_role_menu -WHERE role_id = 1; - --- 查看具体权限列表(前20条) -SELECT - rm.role_id, - rm.menu_id, - m.name as menu_name, - m.authority, - m.type -FROM sys_role_menu rm -LEFT JOIN sys_menu m ON rm.menu_id = m.id -WHERE rm.role_id = 1 -LIMIT 20; -``` - -**预期结果**: -- 权限总数应该 > 10 -- 应该包含 `permission:menu:view`、`permission:operation:view` 等权限 - ---- - -### 4. 检查菜单按钮权限 - -```sql --- 查看菜单权限管理的按钮权限 -SELECT - m.id, - m.parent_id, - m.name, - m.authority, - m.type -FROM sys_menu m -WHERE m.parent_id IN ( - SELECT id FROM sys_menu WHERE name = '菜单权限管理' -) -AND m.is_delete = 0; -``` - -**预期结果**:应该看到5个按钮权限: -- 菜单查询 (permission:menu:list) -- 菜单新增 (permission:menu:add) -- 菜单编辑 (permission:menu:edit) -- 菜单删除 (permission:menu:delete) -- 角色分配 (permission:menu:assign) - ---- - -## 🔄 SQL执行后的操作 - -### 重要!必须重新登录 - -SQL脚本执行成功后,**必须**按以下步骤操作: - -1. **退出当前登录** - - 点击系统右上角用户头像 - - 选择"退出登录" - -2. **清除浏览器缓存** - - 按 `Ctrl + Shift + Delete` - - 或按 `F12` 打开开发者工具 - - 在 Application → Storage → Clear site data - -3. **重新登录** - - 账号:`15900000000` - - 密码:`123456` - -4. **刷新页面** - - 按 `F5` 或 `Ctrl + R` - -5. **验证菜单** - - 左侧菜单栏应该出现"权限管理"菜单 - - 点击展开,应该有两个子菜单: - - 菜单权限管理 - - 操作权限管理 - ---- - -## 🐛 故障排查 - -### 问题1:SQL执行报错 - -**错误:Table 'sys_menu' doesn't exist** - -**解决**:检查数据库表是否存在 -```sql -SHOW TABLES LIKE 'sys_%'; -``` - ---- - -**错误:Duplicate entry for key 'PRIMARY'** - -**解决**:菜单已存在,先清理旧数据 -```sql --- 删除旧的权限管理菜单 -DELETE FROM sys_role_menu -WHERE menu_id IN ( - SELECT id FROM sys_menu WHERE name LIKE '%权限%' -); - -DELETE FROM sys_menu WHERE name LIKE '%权限%'; - --- 然后重新执行SQL脚本 -``` - ---- - -### 问题2:登录后菜单不显示 - -**可能原因1:用户角色不正确** - -```sql --- 修正用户角色 -UPDATE sys_user -SET role_id = 1 -WHERE mobile = '15900000000'; -``` - -**可能原因2:角色权限未分配** - -```sql --- 重新分配所有权限给超级管理员 -DELETE FROM sys_role_menu WHERE role_id = 1; -INSERT INTO sys_role_menu (role_id, menu_id) -SELECT 1, id FROM sys_menu WHERE is_delete = 0; -``` - -**可能原因3:未清除缓存** - -- 清除浏览器缓存 -- 清除localStorage -- 重新登录 - ---- - -### 问题3:连接数据库失败 - -**检查网络**: -```bash -# 测试能否ping通数据库服务器 -ping 129.211.213.226 - -# 测试端口是否开放 -telnet 129.211.213.226 3306 -``` - -**检查防火墙**: -- 确认本地防火墙允许访问3306端口 -- 确认云服务器安全组开放了3306端口 - ---- - -## 📞 联系信息 - -- **数据库服务器**:`129.211.213.226:3306` -- **后端API**:`http://127.0.0.1:16200/api` -- **前端界面**:`http://localhost:8080` - ---- - -## 📝 需要执行的SQL文件 - -1. **精简版**(推荐):`c:/cattleTransport/权限管理菜单-精简版.sql` - - 只创建核心菜单和权限 - - 执行速度快 - - 适合快速测试 - -2. **完整版**:`c:/cattleTransport/权限管理功能初始化SQL.sql` - - 包含所有功能 - - 包含运送清单权限 - - 更全面的配置 - -**建议先执行精简版,测试成功后再执行完整版。** - ---- - -**祝您顺利!** 🎉 - diff --git a/智能项圈功能实现总结.md b/智能项圈功能实现总结.md new file mode 100644 index 0000000..2fa9559 --- /dev/null +++ b/智能项圈功能实现总结.md @@ -0,0 +1,132 @@ +# 智能项圈运单分配功能实现总结 + +## 已完成的功能 + +### 1. 数据库修改 ✅ +- 创建了 `添加项圈运单字段.sql` 文件 +- 在 `xq_client` 表添加了三个字段: + - `delivery_id` INT - 运单ID + - `delivery_number` VARCHAR(64) - 运单号 + - `license_plate` VARCHAR(64) - 车牌号 + +### 2. 后端Java代码修改 ✅ + +#### 2.1 XqClient实体类更新 +- 文件:`tradeCattle/aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/entity/XqClient.java` +- 添加了 `deliveryId` 字段映射 + +#### 2.2 XqClientMapper查询SQL修改 +- 文件:`tradeCattle/aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/mapper/XqClientMapper.java` +- 修改了 `selectXqClientListWithRelations` 方法,将 `xc.sn AS deviceId` 返回,统一使用sn作为设备编号 +- 修改了 `selectUnassignedXqClientList` 方法,同样使用sn作为deviceId + +#### 2.3 设备分配逻辑更新 +- 文件:`tradeCattle/aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/controller/DeliveryController.java` +- 在 `updateDeviceDeliveryInfo` 方法中,为项圈设备添加了 `deliveryId` 字段的更新 +- 现在分配项圈时会同时更新:`delivery_id`、`delivery_number`、`license_plate` + +#### 2.4 新增查看所有设备API +- 文件:`tradeCattle/aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/controller/DeliveryDeviceController.java` +- 新增 `/deliveryDevice/pageDeviceList` 接口 +- 同时查询耳标(type=2)和项圈(type=3)设备 +- 返回统一的设备列表,包含 `deviceType` 字段区分设备类型 + +#### 2.5 新增运单状态更新API +- 文件:`tradeCattle/aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/controller/DeliveryController.java` +- 新增 `/delivery/updateStatus` 接口 +- 支持更新运单的核验状态(1-待核验 2-已核验 3-已完成) + +### 3. 前端代码修改 ✅ + +#### 3.1 分配设备对话框优化 +- 文件:`pc-cattle-transportation/src/views/shipping/assignDialog.vue` +- 修改项圈设备编号映射,优先使用 `sn` 字段:`deviceId: item.sn || item.deviceId` +- 确保项圈设备状态判断基于 `delivery_number` 字段 + +#### 3.2 查看设备对话框增强 +- 文件:`pc-cattle-transportation/src/views/shipping/lookDialog.vue` +- 改用新的 `deviceAllList` API,同时显示耳标和项圈设备 +- 更新设备编号显示逻辑:`scope.row.deviceId || scope.row.sn` +- 更新佩戴状态判断:支持 `isWare` 和 `is_wear` 两种字段 + +#### 3.3 新增API接口定义 +- 文件:`pc-cattle-transportation/src/api/shipping.js` +- 新增 `deviceAllList` 函数:查看运单所有设备 +- 新增 `updateDeliveryStatus` 函数:更新运单状态 + +#### 3.4 运送清单列表功能增强 +- 文件:`pc-cattle-transportation/src/views/shipping/loadingOrder.vue` +- 添加"编辑状态"按钮到操作列 +- 实现 `editStatus` 方法,弹出输入框修改运单状态 +- 操作列宽度调整为420px以容纳新按钮 + +## 功能特性 + +### 核心功能 +1. **智能项圈分配到运单** + - 项圈设备可以通过"分配设备"功能分配到运单 + - 分配时自动更新项圈的运单ID、运单号和车牌号 + +2. **设备编号统一** + - 项圈设备统一使用 `sn` 字段作为设备编号 + - 前后端保持一致,确保数据正确映射 + +3. **设备状态判断** + - 基于 `delivery_number` 字段判断设备是否已分配 + - 未分配显示"未分配",已分配显示实际运单号 + +4. **查看设备功能** + - 支持同时查看运单下的耳标和项圈设备 + - 自动区分设备类型并显示相应标签 + +5. **运单状态管理** + - 新增"编辑状态"按钮,可直接修改运单核验状态 + - 支持三种状态:1-待核验、2-已核验、3-已完成 + +### 数据同步 +- 分配设备时,`xq_client` 表的以下字段会自动更新: + - `delivery_id`:运单ID + - `delivery_number`:运单号 + - `license_plate`:车牌号(从运单的 `license_plate` 字段获取) + +## 使用说明 + +### 1. 执行数据库脚本 +```bash +# 在MySQL中执行 +source 添加项圈运单字段.sql +``` + +### 2. 分配项圈到运单 +1. 进入"运送清单"页面 +2. 点击某个运单的"分配设备"按钮 +3. 在设备类型下拉框选择"智能项圈"或"全部设备" +4. 勾选要分配的项圈设备 +5. 点击"保存"完成分配 + +### 3. 查看运单设备 +1. 在"运送清单"页面点击"查看设备"按钮 +2. 弹窗中会显示该运单的所有设备(耳标+项圈) +3. 设备类型列会显示"智能耳标"或"智能项圈" + +### 4. 修改运单状态 +1. 在"运送清单"页面点击"编辑状态"按钮 +2. 在弹出的输入框中输入状态值(1/2/3) +3. 点击确定完成状态更新 + +## 技术要点 + +1. **后端SQL优化**:使用 `ROW_NUMBER()` 窗口函数获取设备的最新运单关联 +2. **前端兼容性**:支持多种字段名映射(deviceId/sn, isWare/is_wear) +3. **权限控制**:所有API都添加了 `@SaCheckPermission` 权限验证 +4. **错误处理**:完善的异常捕获和用户提示 + +## 测试建议 + +- [ ] 测试项圈设备分配功能 +- [ ] 验证分配后 `xq_client` 表字段是否正确更新 +- [ ] 测试查看设备功能是否同时显示耳标和项圈 +- [ ] 验证设备状态判断逻辑(未分配/已分配) +- [ ] 测试运单状态编辑功能 +- [ ] 验证项圈设备编号显示是否使用sn字段 + diff --git a/权限管理功能使用说明.md b/权限管理功能使用说明.md deleted file mode 100644 index fbe2fbe..0000000 --- a/权限管理功能使用说明.md +++ /dev/null @@ -1,568 +0,0 @@ -# 权限管理功能使用说明 - -## 📋 功能概述 - -本次开发完成了完整的权限管理系统,包括: - -1. **菜单权限管理** - 管理系统菜单树和菜单项 -2. **操作权限管理** - 为不同角色分配菜单和按钮操作权限 -3. **超级管理员** - 15900000000 账号拥有所有权限 - ---- - -## 🗂️ 部署步骤 - -### 第一步:执行数据库初始化脚本 - -在数据库中执行 `权限管理功能初始化SQL.sql` 文件,该脚本会: - -- ✅ 创建"权限管理"父菜单 -- ✅ 创建"菜单权限管理"子菜单 -- ✅ 创建"操作权限管理"子菜单 -- ✅ 为这些菜单添加对应的按钮权限 -- ✅ 创建或更新超级管理员角色(ID=1) -- ✅ 设置 15900000000 为超级管理员账号 -- ✅ 为超级管理员分配所有菜单权限 -- ✅ 为运送清单功能添加完整的权限点 - -**执行方式**: -```sql --- 在MySQL客户端或管理工具中执行 -source /path/to/权限管理功能初始化SQL.sql; --- 或直接复制粘贴SQL内容执行 -``` - -### 第二步:重新编译并启动后端 - -```bash -# 进入后端项目根目录 -cd c:\cattleTransport\tradeCattle - -# 清理并编译安装所有模块 -mvn clean install -DskipTests - -# 进入业务模块 -cd aiotagro-cattle-trade - -# 启动后端服务 -mvn spring-boot:run - -# 或使用jar包启动 -java -jar target/aiotagro-cattletrade-1.0.1.jar -``` - -**后端服务地址**:`http://127.0.0.1:16200` - -### 第三步:启动前端 - -```bash -# 进入前端项目目录 -cd c:\cattleTransport\pc-cattle-transportation - -# 安装依赖(首次或有新依赖时) -npm install - -# 启动开发服务器 -npm run dev -``` - -**前端访问地址**:`http://localhost:8080` - ---- - -## 👤 超级管理员账号 - -### 登录信息 - -- **账号**:`15900000000` -- **密码**:`123456` (如果是SQL脚本新创建的账号) -- **角色**:超级管理员(roleId=1) -- **权限**:拥有系统所有权限(*:*:*) - -### 特权说明 - -超级管理员具有以下特权: - -1. ✅ **绕过所有权限检查** - 自动拥有所有操作权限 -2. ✅ **查看所有数据** - 不受数据权限限制,可以看到所有用户创建的数据 -3. ✅ **管理权限** - 可以为其他角色分配权限 -4. ✅ **管理菜单** - 可以增删改菜单和按钮权限 - ---- - -## 🎯 功能使用指南 - -### 1. 菜单权限管理 - -**访问路径**:系统主菜单 → 权限管理 → 菜单权限管理 - -**功能列表**: - -- ✅ **查看菜单树** - 以树形结构展示所有系统菜单 -- ✅ **新增菜单** - 添加新的菜单或按钮权限 -- ✅ **编辑菜单** - 修改菜单信息 -- ✅ **删除菜单** - 软删除菜单(is_delete=1) - -**字段说明**: - -| 字段 | 说明 | 示例 | -|------|------|------| -| 菜单名称 | 显示在系统中的菜单名称 | 权限管理 | -| 菜单类型 | 1=菜单(页面),2=按钮(操作) | 1 | -| 路由地址 | 前端路由路径 | /permission/menu | -| 组件路径 | Vue组件路径 | permission/menuPermission | -| 权限标识 | 后端权限检查标识 | permission:menu:view | -| 图标 | Element Plus图标名称 | el-icon-lock | -| 排序 | 菜单显示顺序 | 1 | - -**操作步骤**: - -1. 点击"新增菜单"按钮 -2. 选择上级菜单(可选,默认为顶级菜单) -3. 选择菜单类型(菜单/按钮) -4. 填写必填信息:菜单名称、权限标识 -5. 如果是菜单类型,还需填写路由地址和组件路径 -6. 设置排序号 -7. 点击"确定"保存 - ---- - -### 2. 操作权限管理 - -**访问路径**:系统主菜单 → 权限管理 → 操作权限管理 - -**功能列表**: - -- ✅ **角色管理** - 新增、编辑、删除角色 -- ✅ **权限分配** - 为角色分配菜单和按钮权限 -- ✅ **查看权限** - 查看角色当前拥有的权限 - -**左侧:角色列表** -- 显示所有系统角色 -- 点击角色行可查看和编辑该角色的权限 -- 可以新增、编辑、删除角色(超级管理员角色不可删除) - -**右侧:权限树** -- 以树形结构显示所有菜单和按钮权限 -- 勾选表示该角色拥有该权限 -- 支持级联选择(选中父菜单会自动选中子项) - -**操作步骤**: - -#### 新增角色 -1. 点击左侧"新增角色"按钮 -2. 输入角色名称和描述 -3. 点击"确定"保存 - -#### 为角色分配权限 -1. 在左侧角色列表中点击选中某个角色 -2. 右侧会显示权限树 -3. 勾选该角色需要的菜单和按钮权限 -4. 点击右上角"保存权限"按钮 - ---- - -## 🔐 权限标识规范 - -系统采用统一的权限标识命名规范:`模块:资源:操作` - -### 示例 - -| 权限标识 | 说明 | 对应功能 | -|---------|------|---------| -| `permission:menu:view` | 权限-菜单-查看 | 查看菜单权限管理页面 | -| `permission:menu:list` | 权限-菜单-列表 | 查询菜单列表 | -| `permission:menu:add` | 权限-菜单-新增 | 新增菜单 | -| `permission:menu:edit` | 权限-菜单-编辑 | 编辑菜单 | -| `permission:menu:delete` | 权限-菜单-删除 | 删除菜单 | -| `permission:menu:assign` | 权限-菜单-分配 | 分配菜单权限给角色 | -| `permission:operation:view` | 权限-操作-查看 | 查看操作权限管理页面 | -| `permission:operation:list` | 权限-操作-列表 | 查询角色和权限列表 | -| `permission:operation:assign` | 权限-操作-分配 | 分配操作权限 | -| `permission:operation:role` | 权限-操作-角色 | 管理角色(增删改) | -| `delivery:list` | 运送-清单-列表 | 查看运送清单列表 | -| `delivery:add` | 运送-清单-新增 | 新增运送清单 | -| `delivery:edit` | 运送-清单-编辑 | 编辑运送清单 | -| `delivery:delete` | 运送-清单-删除 | 删除运送清单 | -| `delivery:view` | 运送-清单-查看 | 查看运送清单详情 | -| `delivery:check` | 运送-清单-核验 | 核验运送清单 | -| `delivery:assign` | 运送-清单-分配 | 分配设备 | -| `delivery:load` | 运送-清单-装车 | 装车操作 | -| `*:*:*` | 所有权限 | 超级管理员特有 | - ---- - -## 🔧 前端权限控制 - -### 按钮级权限指令 - -在前端使用 `v-hasPermi` 指令控制按钮的显示/隐藏: - -```vue - - - 新增 - - - - - 编辑 - -``` - -### 角色级权限指令 - -使用 `v-hasRole` 指令控制基于角色的显示: - -```vue - - 管理员功能 - -``` - -### 编程式权限判断 - -```javascript -import { useUserStore } from '@/store/user'; - -const userStore = useUserStore(); - -// 判断是否有某个权限 -if (userStore.hasPermission('delivery:add')) { - // 有权限,执行操作 -} - -// 判断是否有某个角色 -if (userStore.hasRole('admin')) { - // 有角色,执行操作 -} -``` - ---- - -## 🛡️ 后端权限控制 - -### 接口级权限注解 - -在Controller方法上使用 `@SaCheckPermission` 注解: - -```java -@RestController -@RequestMapping("/delivery") -public class DeliveryController { - - // 单个权限 - @SaCheckPermission("delivery:list") - @PostMapping("/pageQuery") - public PageResultResponse pageQuery(@RequestBody DeliveryQueryDto dto) { - // ... - } - - // 多个权限(满足其一即可) - @SaCheckPermission(value = {"delivery:add", "delivery:create"}, mode = SaMode.OR) - @PostMapping("/create") - public AjaxResult create(@RequestBody DeliveryCreateDto dto) { - // ... - } -} -``` - -### 数据权限控制 - -使用 `DataScopeUtil` 工具类进行数据权限过滤: - -```java -// 普通用户只能看自己创建的数据,超级管理员可以看所有数据 -LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); -DataScopeUtil.applyDataScope(wrapper, Delivery::getCreatedBy); -List list = this.list(wrapper); - -// 用户可以看到自己创建或自己核验的数据 -LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); -DataScopeUtil.applyDataScopeWithChecker(wrapper, Delivery::getCreatedBy, Delivery::getCheckBy); -List list = this.list(wrapper); -``` - -### 编程式权限判断 - -```java -import com.aiotagro.common.core.utils.SecurityUtil; - -// 判断是否超级管理员 -if (SecurityUtil.isSuperAdmin()) { - // 是超级管理员,执行特殊逻辑 -} - -// 判断是否有某个权限 -if (SecurityUtil.hasPermission("delivery:add")) { - // 有权限,执行操作 -} - -// 获取当前用户ID -Integer userId = SecurityUtil.getCurrentUserId(); - -// 获取当前用户角色ID -Integer roleId = SecurityUtil.getRoleId(); - -// 获取当前用户权限列表 -List permissions = SecurityUtil.getPermissions(); -``` - ---- - -## 📊 数据库表结构 - -### sys_menu(菜单表) - -| 字段 | 类型 | 说明 | -|------|------|------| -| id | int | 主键 | -| parent_id | int | 父菜单ID(0=顶级菜单) | -| type | tinyint | 类型(1=菜单,2=按钮) | -| name | varchar | 菜单名称 | -| route_url | varchar | 路由地址 | -| page_url | varchar | 组件路径 | -| authority | varchar | 权限标识 | -| icon | varchar | 图标 | -| sort | int | 排序 | -| is_delete | tinyint | 是否删除(0=否,1=是) | -| create_time | datetime | 创建时间 | -| update_time | datetime | 更新时间 | - -### sys_role(角色表) - -| 字段 | 类型 | 说明 | -|------|------|------| -| id | int | 主键 | -| name | varchar | 角色名称 | -| description | varchar | 角色描述 | -| is_delete | tinyint | 是否删除(0=否,1=是) | -| create_time | datetime | 创建时间 | -| update_time | datetime | 更新时间 | - -### sys_role_menu(角色菜单关联表) - -| 字段 | 类型 | 说明 | -|------|------|------| -| id | int | 主键 | -| role_id | int | 角色ID | -| menu_id | int | 菜单ID | - -### sys_user(用户表) - -| 字段 | 类型 | 说明 | -|------|------|------| -| id | int | 主键 | -| mobile | varchar | 手机号 | -| name | varchar | 用户名 | -| password | varchar | 密码(MD5加密) | -| role_id | int | 角色ID | -| user_type | int | 用户类型 | -| status | tinyint | 状态(1=启用) | -| is_delete | tinyint | 是否删除 | -| create_time | datetime | 创建时间 | - ---- - -## 🧪 测试指南 - -### 1. 超级管理员测试 - -**登录账号**:15900000000 / 123456 - -**验证点**: -- ✅ 登录成功后,所有菜单都可见 -- ✅ 所有按钮都可见(不受v-hasPermi限制) -- ✅ 可以查看所有用户创建的数据 -- ✅ 可以进入权限管理模块 -- ✅ 可以新增、编辑、删除菜单 -- ✅ 可以新增、编辑、删除角色 -- ✅ 可以为角色分配权限 - -### 2. 普通角色测试 - -**步骤**: -1. 使用超级管理员登录 -2. 进入"操作权限管理" -3. 新增一个测试角色(如"运输管理员") -4. 为该角色分配部分权限(如只分配运送清单相关权限) -5. 在用户管理中创建或修改一个测试用户,指定其角色为"运输管理员" -6. 退出超级管理员,使用测试用户登录 - -**验证点**: -- ✅ 登录后只能看到被分配的菜单 -- ✅ 只能看到被分配的按钮(其他按钮被v-hasPermi隐藏) -- ✅ 只能看到自己创建的数据(数据权限) -- ✅ 无权限的操作会被后端拦截(返回403) - -### 3. 权限管理功能测试 - -#### 菜单权限管理 -1. 进入"菜单权限管理"页面 -2. 测试新增一个测试菜单 -3. 测试编辑菜单信息 -4. 测试删除菜单(软删除) -5. 验证菜单树的显示是否正确 - -#### 操作权限管理 -1. 进入"操作权限管理"页面 -2. 左侧新增一个测试角色 -3. 点击该角色,右侧显示权限树 -4. 勾选部分菜单和按钮权限 -5. 点击"保存权限" -6. 刷新页面,验证权限是否保存成功 -7. 测试编辑和删除角色 - ---- - -## ❗ 常见问题 - -### Q1: 执行SQL脚本后,菜单没有出现? - -**解决方案**: -1. 检查SQL脚本是否执行成功,查看数据库是否有数据 -2. 检查用户的角色是否被分配了相应菜单权限 -3. 退出重新登录,刷新权限缓存 - -### Q2: 按钮被v-hasPermi隐藏了,但我应该有权限? - -**解决方案**: -1. 检查登录接口返回的permissions字段是否包含该权限 -2. 检查Pinia store中是否正确保存了permissions -3. 退出重新登录,刷新权限 -4. 如果是超级管理员,检查permissions是否包含"*:*:*" - -### Q3: 后端接口返回403,提示无权限? - -**解决方案**: -1. 检查Controller方法上的@SaCheckPermission注解 -2. 检查用户的角色是否被分配了该权限 -3. 检查Sa-Token配置是否正确 -4. 查看后端日志,确认权限检查的详细信息 - -### Q4: 超级管理员看不到其他用户的数据? - -**解决方案**: -1. 检查Service层是否正确使用了DataScopeUtil -2. 检查SecurityUtil.isSuperAdmin()方法是否正确判断 -3. 检查用户的roleId是否为1 - -### Q5: 菜单树显示不正常,层级错乱? - -**解决方案**: -1. 检查sys_menu表的parent_id字段是否正确 -2. 检查sort字段,调整排序 -3. 检查is_delete字段,确认菜单未被软删除 - ---- - -## 📝 开发文档 - -### 新增模块权限的步骤 - -如果要为一个新功能模块添加权限控制: - -#### 1. 数据库添加菜单和权限 - -```sql --- 添加父菜单 -INSERT INTO `sys_menu` (`parent_id`, `type`, `name`, `route_url`, `page_url`, `authority`, `icon`, `sort`, `is_delete`, `create_time`) -VALUES (0, 1, '新模块', '/newmodule', null, 'newmodule:view', 'el-icon-setting', 30, 0, NOW()); - -SET @parent_id = LAST_INSERT_ID(); - --- 添加子菜单 -INSERT INTO `sys_menu` (`parent_id`, `type`, `name`, `route_url`, `page_url`, `authority`, `icon`, `sort`, `is_delete`, `create_time`) -VALUES (@parent_id, 1, '功能页面', '/newmodule/function', 'newmodule/function', 'newmodule:function:view', null, 1, 0, NOW()); - -SET @function_id = LAST_INSERT_ID(); - --- 添加按钮权限 -INSERT INTO `sys_menu` (`parent_id`, `type`, `name`, `authority`, `sort`, `is_delete`, `create_time`) VALUES -(@function_id, 2, '新增', 'newmodule:function:add', 1, 0, NOW()), -(@function_id, 2, '编辑', 'newmodule:function:edit', 2, 0, NOW()), -(@function_id, 2, '删除', 'newmodule:function:delete', 3, 0, NOW()); - --- 为超级管理员分配新权限 -INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) -SELECT 1, id FROM `sys_menu` WHERE `authority` LIKE 'newmodule:%' AND `is_delete` = 0; -``` - -#### 2. 后端Controller添加权限注解 - -```java -@RestController -@RequestMapping("/newmodule") -public class NewModuleController { - - @SaCheckPermission("newmodule:function:list") - @PostMapping("/list") - public AjaxResult list(@RequestBody QueryDto dto) { - // ... - } - - @SaCheckPermission("newmodule:function:add") - @PostMapping("/add") - public AjaxResult add(@RequestBody AddDto dto) { - // ... - } -} -``` - -#### 3. 前端按钮添加权限指令 - -```vue - - 新增 - -``` - ---- - -## 🎉 功能清单 - -本次开发完成的文件清单: - -### 后端文件 -- ✅ `RoleConstants.java` - 角色常量类 -- ✅ `SecurityUtil.java` - 安全工具类(扩展) -- ✅ `DataScopeUtil.java` - 数据权限工具类 -- ✅ `SysMenuController.java` - 菜单权限管理Controller -- ✅ `SysRoleController.java` - 角色管理Controller(扩展) -- ✅ `LoginServiceImpl.java` - 登录Service(扩展,存储权限信息) -- ✅ `DeliveryController.java` - 运送清单Controller(添加权限注解) -- ✅ `DeliveryServiceImpl.java` - 运送清单Service(添加数据权限) -- ✅ `DeliveryCreateDto.java` - 运送清单创建DTO - -### 前端文件 -- ✅ `permission.js` - 权限管理API接口 -- ✅ `menuPermission.vue` - 菜单权限管理页面 -- ✅ `operationPermission.vue` - 操作权限管理页面 -- ✅ `createDeliveryDialog.vue` - 新增运送清单对话框 -- ✅ `user.ts` - 用户Store(扩展,添加权限判断) -- ✅ `login.vue` - 登录页(扩展,保存权限) -- ✅ `loadingOrder.vue` - 运送清单列表(添加权限控制) -- ✅ `shipping.js` - 运送清单API(扩展) - -### 数据库文件 -- ✅ `权限管理功能初始化SQL.sql` - 数据库初始化脚本 - -### 文档文件 -- ✅ `权限管理和运送清单新增功能实施计划.md` - 实施计划文档 -- ✅ `权限管理功能使用说明.md` - 本使用说明文档 - ---- - -## 📞 技术支持 - -如有问题,请检查: - -1. 后端日志:查看权限验证相关错误 -2. 浏览器控制台:查看前端请求和权限判断 -3. 数据库数据:确认菜单、角色、权限数据是否正确 -4. Sa-Token文档:https://sa-token.cc/ - ---- - -**祝使用愉快!** 🎊 - diff --git a/权限管理功能初始化SQL.sql b/权限管理功能初始化SQL.sql deleted file mode 100644 index 1f3105b..0000000 --- a/权限管理功能初始化SQL.sql +++ /dev/null @@ -1,152 +0,0 @@ --- ============================================ --- 权限管理功能初始化 SQL --- 功能:添加权限管理菜单、设置超级管理员 --- 日期:2025-10-11 --- ============================================ - --- ============================================ --- 1. 添加权限管理父菜单 --- ============================================ -INSERT INTO `sys_menu` (`parent_id`, `type`, `name`, `route_url`, `page_url`, `authority`, `icon`, `sort`, `is_delete`, `create_time`) -VALUES (0, 1, '权限管理', '/permission', null, 'permission:view', 'el-icon-lock', 20, 0, NOW()); - --- 获取刚插入的权限管理父菜单ID(假设为 @permission_parent_id) -SET @permission_parent_id = LAST_INSERT_ID(); - --- ============================================ --- 2. 添加子菜单:菜单权限管理 --- ============================================ -INSERT INTO `sys_menu` (`parent_id`, `type`, `name`, `route_url`, `page_url`, `authority`, `icon`, `sort`, `is_delete`, `create_time`) -VALUES (@permission_parent_id, 1, '菜单权限管理', '/permission/menu', 'permission/menuPermission', 'permission:menu:view', 'el-icon-menu', 1, 0, NOW()); - -SET @menu_permission_id = LAST_INSERT_ID(); - --- 菜单权限管理的按钮权限 -INSERT INTO `sys_menu` (`parent_id`, `type`, `name`, `authority`, `sort`, `is_delete`, `create_time`) VALUES -(@menu_permission_id, 2, '菜单查询', 'permission:menu:list', 1, 0, NOW()), -(@menu_permission_id, 2, '菜单新增', 'permission:menu:add', 2, 0, NOW()), -(@menu_permission_id, 2, '菜单编辑', 'permission:menu:edit', 3, 0, NOW()), -(@menu_permission_id, 2, '菜单删除', 'permission:menu:delete', 4, 0, NOW()), -(@menu_permission_id, 2, '角色分配', 'permission:menu:assign', 5, 0, NOW()); - --- ============================================ --- 3. 添加子菜单:操作权限管理 --- ============================================ -INSERT INTO `sys_menu` (`parent_id`, `type`, `name`, `route_url`, `page_url`, `authority`, `icon`, `sort`, `is_delete`, `create_time`) -VALUES (@permission_parent_id, 1, '操作权限管理', '/permission/operation', 'permission/operationPermission', 'permission:operation:view', 'el-icon-setting', 2, 0, NOW()); - -SET @operation_permission_id = LAST_INSERT_ID(); - --- 操作权限管理的按钮权限 -INSERT INTO `sys_menu` (`parent_id`, `type`, `name`, `authority`, `sort`, `is_delete`, `create_time`) VALUES -(@operation_permission_id, 2, '权限查询', 'permission:operation:list', 1, 0, NOW()), -(@operation_permission_id, 2, '权限分配', 'permission:operation:assign', 2, 0, NOW()), -(@operation_permission_id, 2, '角色管理', 'permission:operation:role', 3, 0, NOW()); - --- ============================================ --- 4. 查找或创建超级管理员角色 --- ============================================ --- 查看是否已有ID=1的角色,如果没有则插入 -INSERT INTO `sys_role` (`id`, `name`, `description`, `is_delete`, `create_time`) -SELECT 1, '超级管理员', '拥有系统所有权限', 0, NOW() -WHERE NOT EXISTS (SELECT 1 FROM `sys_role` WHERE `id` = 1); - --- ============================================ --- 5. 为超级管理员角色分配所有菜单权限 --- ============================================ --- 清空超级管理员的旧权限(可选) -DELETE FROM `sys_role_menu` WHERE `role_id` = 1; - --- 分配所有菜单权限给超级管理员 -INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) -SELECT 1, id FROM `sys_menu` WHERE `is_delete` = 0; - --- ============================================ --- 6. 设置15900000000账号为超级管理员 --- ============================================ --- 查找该手机号的用户 -UPDATE `sys_user` -SET `role_id` = 1 -WHERE `mobile` = '15900000000' AND `is_delete` = 0; - --- 如果用户不存在,创建超级管理员账号(密码默认为 123456,已MD5加密) --- 注意:请根据实际的密码加密方式调整密码值 -INSERT INTO `sys_user` (`mobile`, `name`, `password`, `role_id`, `status`, `user_type`, `is_delete`, `create_time`) -SELECT - '15900000000', - '超级管理员', - 'e10adc3949ba59abbe56e057f20f883e', -- 123456 的MD5值 - 1, - 1, - 1, - 0, - NOW() -WHERE NOT EXISTS ( - SELECT 1 FROM `sys_user` WHERE `mobile` = '15900000000' -); - --- ============================================ --- 7. 为运送清单添加完整的权限点(如果还没有) --- ============================================ --- 查找运送清单菜单 -SET @delivery_menu_id = (SELECT id FROM `sys_menu` WHERE `route_url` LIKE '%delivery%' OR `route_url` LIKE '%loading%' LIMIT 1); - --- 如果找到了运送清单菜单,添加权限点 -INSERT INTO `sys_menu` (`parent_id`, `type`, `name`, `authority`, `sort`, `is_delete`, `create_time`) -SELECT @delivery_menu_id, 2, '运送清单查看', 'delivery:list', 1, 0, NOW() -WHERE @delivery_menu_id IS NOT NULL -AND NOT EXISTS (SELECT 1 FROM `sys_menu` WHERE `authority` = 'delivery:list'); - -INSERT INTO `sys_menu` (`parent_id`, `type`, `name`, `authority`, `sort`, `is_delete`, `create_time`) -SELECT @delivery_menu_id, 2, '运送清单新增', 'delivery:add', 2, 0, NOW() -WHERE @delivery_menu_id IS NOT NULL -AND NOT EXISTS (SELECT 1 FROM `sys_menu` WHERE `authority` = 'delivery:add'); - -INSERT INTO `sys_menu` (`parent_id`, `type`, `name`, `authority`, `sort`, `is_delete`, `create_time`) -SELECT @delivery_menu_id, 2, '运送清单编辑', 'delivery:edit', 3, 0, NOW() -WHERE @delivery_menu_id IS NOT NULL -AND NOT EXISTS (SELECT 1 FROM `sys_menu` WHERE `authority` = 'delivery:edit'); - -INSERT INTO `sys_menu` (`parent_id`, `type`, `name`, `authority`, `sort`, `is_delete`, `create_time`) -SELECT @delivery_menu_id, 2, '运送清单删除', 'delivery:delete', 4, 0, NOW() -WHERE @delivery_menu_id IS NOT NULL -AND NOT EXISTS (SELECT 1 FROM `sys_menu` WHERE `authority` = 'delivery:delete'); - -INSERT INTO `sys_menu` (`parent_id`, `type`, `name`, `authority`, `sort`, `is_delete`, `create_time`) -SELECT @delivery_menu_id, 2, '运送清单查看详情', 'delivery:view', 5, 0, NOW() -WHERE @delivery_menu_id IS NOT NULL -AND NOT EXISTS (SELECT 1 FROM `sys_menu` WHERE `authority` = 'delivery:view'); - -INSERT INTO `sys_menu` (`parent_id`, `type`, `name`, `authority`, `sort`, `is_delete`, `create_time`) -SELECT @delivery_menu_id, 2, '运送清单核验', 'delivery:check', 6, 0, NOW() -WHERE @delivery_menu_id IS NOT NULL -AND NOT EXISTS (SELECT 1 FROM `sys_menu` WHERE `authority` = 'delivery:check'); - -INSERT INTO `sys_menu` (`parent_id`, `type`, `name`, `authority`, `sort`, `is_delete`, `create_time`) -SELECT @delivery_menu_id, 2, '设备分配', 'delivery:assign', 7, 0, NOW() -WHERE @delivery_menu_id IS NOT NULL -AND NOT EXISTS (SELECT 1 FROM `sys_menu` WHERE `authority` = 'delivery:assign'); - -INSERT INTO `sys_menu` (`parent_id`, `type`, `name`, `authority`, `sort`, `is_delete`, `create_time`) -SELECT @delivery_menu_id, 2, '装车操作', 'delivery:load', 8, 0, NOW() -WHERE @delivery_menu_id IS NOT NULL -AND NOT EXISTS (SELECT 1 FROM `sys_menu` WHERE `authority` = 'delivery:load'); - --- ============================================ --- 8. 验证数据 --- ============================================ --- 查看新增的权限管理菜单 -SELECT * FROM `sys_menu` WHERE `name` LIKE '%权限%' OR `name` LIKE '%permission%'; - --- 查看超级管理员用户 -SELECT `id`, `mobile`, `name`, `role_id`, `status` FROM `sys_user` WHERE `mobile` = '15900000000'; - --- 查看超级管理员的权限数量 -SELECT COUNT(*) as '超级管理员权限数' FROM `sys_role_menu` WHERE `role_id` = 1; - --- ============================================ --- 执行完成 --- ============================================ -SELECT '✅ 权限管理功能初始化完成!' as 'Status'; -SELECT '账号: 15900000000, 密码: 123456 (如果是新创建的账号)' as '超级管理员信息'; - diff --git a/权限管理和运送清单新增功能实施计划.md b/权限管理和运送清单新增功能实施计划.md deleted file mode 100644 index e3865be..0000000 --- a/权限管理和运送清单新增功能实施计划.md +++ /dev/null @@ -1,1795 +0,0 @@ -# 权限管理和运送清单新增功能实施计划 - -**项目名称:** 牛只运输管理系统 -**文档版本:** V1.0 -**创建日期:** 2025-10-11 -**项目路径:** c:\cattleTransport - ---- - -## 一、项目概述 - -### 1.1 背景说明 -本项目旨在完善牛只运输管理系统的权限管理机制,并新增运送清单创建功能。系统采用前后端分离架构: -- **前端:** Vue3 + TypeScript + Pinia + Element Plus -- **后端:** Spring Boot 2.6.13 + MyBatis-Plus + Sa-Token -- **数据库:** MySQL + Redis - -### 1.2 核心目标 -1. 实现基于角色的菜单权限管理和动态路由 -2. 实现基于权限码的操作权限控制(按钮级) -3. 实现基于角色的数据范围隔离 -4. 支持超级管理员全权限访问 -5. 新增运送清单创建功能并进行权限控制 - ---- - -## 二、功能需求详述 - -### 2.1 菜单权限管理 -**需求描述:** -- 由 `sys_menu` 表维护菜单树与权限点 -- 后端根据用户 `role_id` 返回可见菜单列表 -- 前端动态生成路由,仅渲染可见菜单节点 -- 菜单权限调整后,用户重新获取菜单即可动态生效 - -**涉及表:** -- `sys_menu` - 系统菜单表 -- `sys_role_menu` - 角色菜单关联表 -- `sys_role` - 角色表 -- `sys_user` - 用户表 - -### 2.2 操作权限管理 -**需求描述:** -- 基于权限码(`permKey`)控制页面按钮与接口访问 -- 前端通过 `v-hasPermi`/`v-hasRole` 指令控制按钮显示/禁用 -- 后端在 Controller 层使用 `@SaCheckPermission` 注解进行权限拦截 -- 防止前端绕过直接调用接口的越权操作 - -**权限码示例:** -- `delivery:list` - 运送清单查看 -- `delivery:add` - 运送清单新增 -- `delivery:edit` - 运送清单编辑 -- `delivery:delete` - 运送清单删除 -- `delivery:check` - 运送清单核验 -- `delivery:assign` - 设备分配 -- `delivery:load` - 装车操作 - -### 2.3 数据范围隔离 -**需求描述:** -- 登录成功后读取 `sys_user.role_id`,作为数据作用域依据 -- 普通角色仅能访问本角色范围内的数据(创建人或核验人为当前用户) -- 超级管理员可访问全部数据 -- 在 Service 层查询时动态添加数据权限过滤条件 - -### 2.4 超级管理员权限 -**需求描述:** -- 超级管理员具备最高权限与全数据可见性 -- 可以管理所有角色与菜单 -- 建议使用固定角色编码或 ID 标识(如 `role_id = 1` 或 `is_super_admin = 1`) - -### 2.5 运送清单新增功能 -**需求描述:** -- 在运送清单列表页增加"新增"按钮 -- 仅具备 `delivery:add` 权限的用户可见与可操作 -- 打开表单弹窗,填写运送清单信息 -- 提交后调用后端接口创建记录,成功后刷新列表 - -**表单字段:** -- 运输单号(自动生成,格式:yyyyMMddHHmmss) -- 发货方(必填) -- 采购方(必填) -- 车牌号(必填,格式校验) -- 司机姓名(必填) -- 司机电话(必填,手机号校验) -- 主机设备(下拉选择,可选) -- 耳标设备(多选,可选) -- 项圈设备(多选,可选) -- 预计出发时间(必填,日期时间选择器) -- 预计到达时间(必填,必须晚于出发时间) -- 起点地址(必填) -- 目的地地址(必填) -- 牛只数量(必填,正整数) -- 预估重量(公斤,必填,正数) -- 检疫证号(可选) -- 备注(可选,最多500字) - ---- - -## 三、后端开发方案 - -### 3.1 项目结构 -``` -c:/cattleTransport/tradeCattle/ -├── aiotagro-core/ # 核心模块 -│ └── src/main/java/com/aiotagro/common/core/ -│ ├── constant/ -│ │ └── RoleConstants.java # 【新增】角色常量 -│ └── utils/ -│ ├── SecurityUtil.java # 【修改】安全工具类 -│ └── DataScopeUtil.java # 【新增】数据权限工具类 -└── aiotagro-cattle-trade/ # 业务模块 - └── src/main/java/com/aiotagro/cattletrade/ - ├── config/ - │ └── SaTokenConfigure.java # 【修改】Sa-Token配置 - └── business/ - ├── controller/ - │ └── DeliveryController.java # 【修改】运送清单控制器 - ├── service/ - │ ├── LoginService.java - │ └── impl/ - │ ├── LoginServiceImpl.java # 【修改】登录服务实现 - │ └── DeliveryServiceImpl.java # 【修改】运送清单服务实现 - ├── dto/ - │ └── DeliveryCreateDto.java # 【新增】运送清单创建DTO - └── entity/ - ├── SysUser.java - ├── SysRole.java - └── SysMenu.java -``` - -### 3.2 详细实施步骤 - -#### 步骤1:创建角色常量类 -**文件:** `aiotagro-core/src/main/java/com/aiotagro/common/core/constant/RoleConstants.java` - -```java -package com.aiotagro.common.core.constant; - -/** - * 角色相关常量 - */ -public class RoleConstants { - - /** - * 超级管理员角色ID - */ - public static final Integer SUPER_ADMIN_ROLE_ID = 1; - - /** - * 超级管理员角色编码 - */ - public static final String SUPER_ADMIN_ROLE_CODE = "ROLE_SUPER_ADMIN"; - - /** - * 所有权限标识 - */ - public static final String ALL_PERMISSION = "*:*:*"; -} -``` - -#### 步骤2:扩展SecurityUtil工具类 -**文件:** `aiotagro-core/src/main/java/com/aiotagro/common/core/utils/SecurityUtil.java` - -**修改内容:** 添加以下方法 -```java -/** - * 获取当前用户角色ID - */ -public static Integer getRoleId() { - Object roleId = StpUtil.getTokenSession().get("roleId"); - return roleId != null ? Integer.parseInt(roleId.toString()) : null; -} - -/** - * 获取当前用户权限列表 - */ -@SuppressWarnings("unchecked") -public static List getPermissions() { - Object permissions = StpUtil.getTokenSession().get("permissions"); - return permissions != null ? (List) permissions : Collections.emptyList(); -} - -/** - * 判断是否超级管理员 - */ -public static boolean isSuperAdmin() { - Integer roleId = getRoleId(); - return roleId != null && roleId.equals(RoleConstants.SUPER_ADMIN_ROLE_ID); -} - -/** - * 判断是否拥有某个权限 - */ -public static boolean hasPermission(String permission) { - if (isSuperAdmin()) { - return true; - } - List permissions = getPermissions(); - return permissions.contains(RoleConstants.ALL_PERMISSION) || - permissions.contains(permission); -} -``` - -#### 步骤3:创建数据权限工具类 -**文件:** `aiotagro-core/src/main/java/com/aiotagro/common/core/utils/DataScopeUtil.java` - -```java -package com.aiotagro.common.core.utils; - -import com.aiotagro.common.core.constant.RoleConstants; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; - -/** - * 数据权限工具类 - */ -public class DataScopeUtil { - - /** - * 应用数据权限过滤(基于创建人) - * 超级管理员不过滤,普通用户只能看自己创建的数据 - */ - public static void applyDataScope(LambdaQueryWrapper wrapper, - SFunction createdByField) { - // 超级管理员不过滤 - if (SecurityUtil.isSuperAdmin()) { - return; - } - - // 普通用户只能查看自己创建的数据 - Integer currentUserId = SecurityUtil.getCurrentUserId(); - wrapper.eq(createdByField, currentUserId); - } - - /** - * 应用数据权限过滤(基于创建人或核验人) - * 用户可以看到自己创建或自己核验的数据 - */ - public static void applyDataScopeWithChecker(LambdaQueryWrapper wrapper, - SFunction createdByField, - SFunction checkByField) { - // 超级管理员不过滤 - if (SecurityUtil.isSuperAdmin()) { - return; - } - - // 普通用户可以查看自己创建或自己核验的数据 - Integer currentUserId = SecurityUtil.getCurrentUserId(); - wrapper.and(w -> w.eq(createdByField, currentUserId) - .or() - .eq(checkByField, currentUserId)); - } -} -``` - -#### 步骤4:修改登录服务实现 -**文件:** `aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/service/impl/LoginServiceImpl.java` - -**修改 login 方法(第100行后):** 添加权限信息存储 -```java -// 原有代码 -user.setLastLoginTime(new Date()); -userMapper.updateById(user); - -// 登录,并设置用户信息到session -StpUtil.login(user.getId(), SaLoginConfig - .setExtra("username", user.getName()) - .setExtra("mobile", user.getMobile()) - .setExtra("userType", user.getUserType())); - -// ===== 【新增代码开始】 ===== -// 存储角色ID到session -StpUtil.getTokenSession().set("roleId", user.getRoleId()); - -// 查询用户权限列表 -List permissions = queryUserPermissions(user.getRoleId()); -StpUtil.getTokenSession().set("permissions", permissions); - -// 查询用户角色信息 -SysRole role = roleMapper.selectById(user.getRoleId()); -String roleCode = role != null ? role.getCode() : ""; -StpUtil.getTokenSession().set("roleCode", roleCode); -// ===== 【新增代码结束】 ===== - -Map result = new HashMap<>(); -result.put("token", StpUtil.getTokenValue()); -result.put("mobile", user.getMobile()); -result.put("username", user.getName()); -result.put("userType", user.getUserType()); -result.put("roleId", user.getRoleId()); // 【新增】返回角色ID -result.put("permissions", permissions); // 【新增】返回权限列表 -return AjaxResult.success(result); -``` - -**添加查询权限列表的方法:** -```java -/** - * 查询用户权限列表 - */ -private List queryUserPermissions(Integer roleId) { - if (roleId == null) { - return Collections.emptyList(); - } - - // 如果是超级管理员,返回所有权限 - if (roleId.equals(RoleConstants.SUPER_ADMIN_ROLE_ID)) { - return Collections.singletonList(RoleConstants.ALL_PERMISSION); - } - - // 查询角色关联的菜单权限 - List menus = menuMapper.selectMenusByRoleId(roleId); - return menus.stream() - .filter(menu -> StringUtils.isNotEmpty(menu.getAuthority())) - .map(SysMenu::getAuthority) - .distinct() - .collect(Collectors.toList()); -} -``` - -**在 SysMenuMapper 中添加方法:** -```java -/** - * 根据角色ID查询菜单列表 - */ -List selectMenusByRoleId(@Param("roleId") Integer roleId); -``` - -**在 SysMenuMapper.xml 中添加SQL:** -```xml - - SELECT DISTINCT m.* - FROM sys_menu m - INNER JOIN sys_role_menu rm ON m.id = rm.menu_id - WHERE rm.role_id = #{roleId} - AND m.is_delete = 0 - ORDER BY m.sort ASC - -``` - -#### 步骤5:修改DeliveryController添加权限注解 -**文件:** `aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/controller/DeliveryController.java` - -**修改内容:** 在类和方法上添加权限注解 -```java -package com.aiotagro.cattletrade.business.controller; - -import cn.dev33.satoken.annotation.SaCheckPermission; // 【新增】导入 -import com.aiotagro.cattletrade.business.dto.*; -import com.aiotagro.cattletrade.business.entity.Delivery; -import com.aiotagro.cattletrade.business.service.IDeliveryService; -import com.aiotagro.common.core.web.domain.AjaxResult; -import com.aiotagro.common.core.web.domain.PageResultResponse; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -/** - * 运送清单表 前端控制器 - */ -@RestController -@RequestMapping("/delivery") -public class DeliveryController { - - @Autowired - private IDeliveryService deliveryService; - - /** - * 运送清单-分页查询 - */ - @SaCheckPermission("delivery:list") // 【新增】 - @PostMapping(value = "/pageQuery") - public PageResultResponse pageQuery(@RequestBody DeliveryQueryDto dto) { - return deliveryService.pageQuery(dto); - } - - /** - * 运送清单-新增(原有的add方法) - */ - @SaCheckPermission("delivery:add") // 【新增】 - @PostMapping(value = "/add") - public AjaxResult add(@RequestBody DeliveryAddDto dto) { - try{ - return deliveryService.addDelivery(dto); - }catch (Exception e){ - e.printStackTrace(); - return AjaxResult.error(e.getMessage()); - } - } - - /** - * 运送清单-创建(新增的create接口) - */ - @SaCheckPermission("delivery:add") // 【新增】 - @PostMapping(value = "/create") - public AjaxResult create(@Validated @RequestBody DeliveryCreateDto dto) { - try{ - return deliveryService.createDelivery(dto); - }catch (Exception e){ - e.printStackTrace(); - return AjaxResult.error(e.getMessage()); - } - } - - /** - * 运送清单-查询详情 - */ - @SaCheckPermission("delivery:view") // 【新增】 - @GetMapping(value = "/view") - public AjaxResult view(@RequestParam Integer id) { - return deliveryService.viewDelivery(id); - } - - /** - * 运送清单-核验提交 - */ - @SaCheckPermission("delivery:check") // 【新增】 - @PostMapping(value = "/submitCheck") - public AjaxResult submitCheck(@RequestBody Delivery delivery) { - // ... 原有代码 - } - - /** - * 运送清单-编辑 - */ - @SaCheckPermission("delivery:edit") // 【新增】 - @PostMapping(value = "/update") - public AjaxResult update(@RequestBody Delivery delivery) { - // ... 原有代码 - } - - /** - * 运送清单-删除 - */ - @SaCheckPermission("delivery:delete") // 【新增】 - @GetMapping(value = "/delete") - public AjaxResult delete(@RequestParam Integer id) { - // ... 原有代码 - } -} -``` - -#### 步骤6:创建运送清单创建DTO -**文件:** `aiotagro-cattle-trade/src/main/java/com/aiotagro/cattletrade/business/dto/DeliveryCreateDto.java` - -```java -package com.aiotagro.cattletrade.business.dto; - -import lombok.Data; -import javax.validation.constraints.*; -import java.util.Date; -import java.util.List; - -/** - * 运送清单创建DTO - */ -@Data -public class DeliveryCreateDto { - - /** - * 发货方 - */ - @NotBlank(message = "发货方不能为空") - private String shipper; - - /** - * 采购方 - */ - @NotBlank(message = "采购方不能为空") - private String buyer; - - /** - * 车牌号 - */ - @NotBlank(message = "车牌号不能为空") - @Pattern(regexp = "^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z][A-Z0-9]{5}[A-Z0-9挂学警港澳]$", - message = "车牌号格式不正确") - private String plateNumber; - - /** - * 司机姓名 - */ - @NotBlank(message = "司机姓名不能为空") - private String driverName; - - /** - * 司机电话 - */ - @NotBlank(message = "司机电话不能为空") - @Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确") - private String driverPhone; - - /** - * 主机设备ID - */ - private Integer serverId; - - /** - * 耳标设备ID列表 - */ - private List eartagIds; - - /** - * 项圈设备ID列表 - */ - private List collarIds; - - /** - * 预计出发时间 - */ - @NotNull(message = "预计出发时间不能为空") - private Date estimatedDepartureTime; - - /** - * 预计到达时间 - */ - @NotNull(message = "预计到达时间不能为空") - private Date estimatedArrivalTime; - - /** - * 起点地址 - */ - @NotBlank(message = "起点地址不能为空") - private String startLocation; - - /** - * 目的地地址 - */ - @NotBlank(message = "目的地地址不能为空") - private String endLocation; - - /** - * 牛只数量 - */ - @NotNull(message = "牛只数量不能为空") - @Min(value = 1, message = "牛只数量至少为1") - private Integer cattleCount; - - /** - * 预估重量(公斤) - */ - @NotNull(message = "预估重量不能为空") - @DecimalMin(value = "0.01", message = "预估重量必须大于0") - private Double estimatedWeight; - - /** - * 检疫证号 - */ - private String quarantineCertNo; - - /** - * 备注 - */ - @Size(max = 500, message = "备注不能超过500字") - private String remark; -} -``` - -#### 步骤7:在DeliveryService中添加创建方法 -**接口文件:** `IDeliveryService.java` - -```java -/** - * 创建运送清单 - */ -AjaxResult createDelivery(DeliveryCreateDto dto); -``` - -**实现文件:** `DeliveryServiceImpl.java` - -```java -@Transactional -@Override -public AjaxResult createDelivery(DeliveryCreateDto dto) { - // 校验时间逻辑 - if (dto.getEstimatedArrivalTime().before(dto.getEstimatedDepartureTime())) { - return AjaxResult.error("预计到达时间必须晚于出发时间"); - } - - // 获取当前登录用户 - Integer userId = SecurityUtil.getCurrentUserId(); - String userName = SecurityUtil.getUserName(); - - // 生成运输单号 - LocalDateTime now = LocalDateTime.now(); - String deliveryNumber = "YS" + now.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")); - - // 创建运送清单 - Delivery delivery = new Delivery(); - delivery.setDeliveryNumber(deliveryNumber); - delivery.setShipper(dto.getShipper()); - delivery.setBuyer(dto.getBuyer()); - delivery.setPlateNumber(dto.getPlateNumber()); - delivery.setDriverName(dto.getDriverName()); - delivery.setDriverPhone(dto.getDriverPhone()); - delivery.setEstimatedDepartureTime(dto.getEstimatedDepartureTime()); - delivery.setEstimatedArrivalTime(dto.getEstimatedArrivalTime()); - delivery.setStartLocation(dto.getStartLocation()); - delivery.setEndLocation(dto.getEndLocation()); - delivery.setCattleCount(dto.getCattleCount()); - delivery.setEstimatedWeight(dto.getEstimatedWeight()); - delivery.setQuarantineCertNo(dto.getQuarantineCertNo()); - delivery.setRemark(dto.getRemark()); - delivery.setStatus(1); // 待装车 - delivery.setCreatedBy(userId); - delivery.setCreatedByName(userName); - delivery.setCreateTime(new Date()); - - // 保存运送清单 - this.save(delivery); - - // 如果选择了设备,保存设备关联 - if (dto.getServerId() != null || - CollectionUtils.isNotEmpty(dto.getEartagIds()) || - CollectionUtils.isNotEmpty(dto.getCollarIds())) { - // 保存设备关联逻辑(根据实际业务调整) - saveDeliveryDevices(delivery.getId(), dto); - } - - return AjaxResult.success("创建成功", delivery); -} - -/** - * 保存运送清单设备关联 - */ -private void saveDeliveryDevices(Integer deliveryId, DeliveryCreateDto dto) { - // 根据实际业务实现设备关联逻辑 - // 示例代码,需要根据实际的 DeliveryDevice 表结构调整 -} -``` - -#### 步骤8:修改DeliveryServiceImpl的查询方法 -**文件:** `DeliveryServiceImpl.java` - -**修改 pageQuery 方法:** 应用数据权限过滤 -```java -@Override -public PageResultResponse pageQuery(DeliveryQueryDto dto) { - // 获取当前登录人id - Integer userId = SecurityUtil.getCurrentUserId(); - Page result = PageHelper.startPage(dto.getPageNum(), dto.getPageSize()); - - LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); - - // ===== 【修改:应用数据权限过滤】 ===== - if (!SecurityUtil.isSuperAdmin()) { - // 普通用户只能查看自己创建或自己核验的数据 - wrapper.and(w -> w.eq(Delivery::getCreatedBy, userId) - .or() - .eq(Delivery::getCheckBy, userId)); - } - // 否则超级管理员可以看到所有数据 - // ===== 【修改结束】 ===== - - // 运输单号模糊查询 - if(StringUtils.isNotEmpty(dto.getDeliveryNumber())){ - wrapper.like(Delivery::getDeliveryNumber, dto.getDeliveryNumber()); - } - - wrapper.orderByDesc(Delivery::getId); - List list = this.list(wrapper); - - if(CollectionUtils.isNotEmpty(list)){ - list.forEach(delivery -> { - if(userId.equals(delivery.getCheckBy())){ - // 判断是否需要核验,1:需要核验,2:不需要核验 - delivery.setIfCheck(1); - } - }); - } - - return new PageResultResponse(result.getTotal(), list); -} -``` - -#### 步骤9:修改Sa-Token配置(可选) -**文件:** `SaTokenConfigure.java` - -如果需要排除某些路径不进行权限校验,可以修改: -```java -@Override -public void addInterceptors(InterceptorRegistry registry) { - registry.addInterceptor(new SaInterceptor(handler -> StpUtil.checkLogin())) - .addPathPatterns("/**") - .excludePathPatterns( - "/login", // 登录 - "/sendLoginSmsCode", // 发送验证码 - "/common/upload", // 文件上传 - "/warningLog/savaWarn" // 告警保存 - ); -} -``` - ---- - -## 四、前端开发方案 - -### 4.1 项目结构 -``` -pc-cattle-transportation/ -├── src/ -│ ├── api/ -│ │ └── shipping.js # 【修改】运送清单API -│ ├── components/ -│ │ └── common/ -│ ├── directive/ -│ │ └── permission/ -│ │ └── hasPermi.js # 权限指令 -│ ├── store/ -│ │ ├── user.ts # 【修改】用户状态管理 -│ │ └── permission.js # 权限状态管理 -│ ├── utils/ -│ │ ├── permission.js # 权限工具函数 -│ │ └── validate.js # 【修改】表单校验规则 -│ └── views/ -│ └── shipping/ -│ ├── loadingOrder.vue # 【修改】运送清单列表 -│ └── createDeliveryDialog.vue # 【新增】运送清单创建弹窗 -``` - -### 4.2 详细实施步骤 - -#### 步骤1:扩展用户Store -**文件:** `pc-cattle-transportation/src/store/user.ts` - -```typescript -import { defineStore } from 'pinia'; - -export const useUserStore = defineStore('storeUser', { - state: () => { - return { - id: '', - username: '', - token: '', - loginUser: null, - userType: '', - roleId: '', - permissions: [] as string[], // 【新增】权限列表 - roles: [] as string[], // 【新增】角色列表 - }; - }, - persist: { - enabled: true, - strategies: [ - { - key: 'userStore', - storage: localStorage, - }, - ], - }, - getters: { - // 【新增】判断是否有某个权限 - hasPermission: (state) => { - return (permission: string) => { - if (state.permissions.includes('*:*:*')) { - return true; - } - return state.permissions.includes(permission); - }; - }, - // 【新增】判断是否有某个角色 - hasRole: (state) => { - return (role: string) => { - if (state.roles.includes('admin')) { - return true; - } - return state.roles.includes(role); - }; - }, - }, - actions: { - removeAllInfo() { - this.id = ''; - this.username = ''; - this.token = ''; - this.userType = ''; - this.loginUser = null; - this.roleId = ''; - this.permissions = []; // 【新增】 - this.roles = []; // 【新增】 - }, - updateToken(token: string) { - this.token = token; - }, - updateUserType(userType: string) { - this.userType = userType; - }, - updateUserName(userName: string) { - this.username = userName; - }, - updateLoginUser(user: Object) { - // @ts-ignore - this.loginUser = user; - }, - updateLoginUserType(userType: number) { - // @ts-ignore - this.userType = userType; - }, - updateRoleId(roleId: string) { - this.roleId = roleId; - }, - // 【新增】更新权限列表 - updatePermissions(permissions: string[]) { - this.permissions = permissions || []; - }, - // 【新增】更新角色列表 - updateRoles(roles: string[]) { - this.roles = roles || []; - }, - }, -}); -``` - -#### 步骤2:修改登录页面 -**文件:** `pc-cattle-transportation/src/views/login.vue` - -在登录成功的处理逻辑中添加: -```javascript -// 找到登录成功的处理代码,通常在 handleLogin 或类似方法中 -const handleLogin = async () => { - try { - const res = await login(loginForm); - if (res.code === 200) { - const { token, username, userType, roleId, permissions, roles } = res.data; - - // 保存用户信息 - userStore.updateToken(token); - userStore.updateUserName(username); - userStore.updateUserType(userType); - userStore.updateRoleId(roleId); - userStore.updatePermissions(permissions || []); // 【新增】 - userStore.updateRoles(roles || []); // 【新增】 - - // 跳转到首页 - router.push('/'); - } else { - ElMessage.error(res.msg || '登录失败'); - } - } catch (error) { - ElMessage.error('登录失败,请稍后重试'); - } -}; -``` - -#### 步骤3:添加运送清单创建API -**文件:** `pc-cattle-transportation/src/api/shipping.js` - -```javascript -// 在文件末尾添加 -// 运送清单 - 创建 -export function createDelivery(data) { - return request({ - url: '/delivery/create', - method: 'POST', - data, - }); -} - -// 查询可用主机设备列表 -export function getAvailableServers(data) { - return request({ - url: '/jbqServer/availableList', - method: 'POST', - data, - }); -} - -// 查询可用耳标设备列表 -export function getAvailableEartags(data) { - return request({ - url: '/jbqClient/availableList', - method: 'POST', - data, - }); -} - -// 查询可用项圈设备列表 -export function getAvailableCollars(data) { - return request({ - url: '/xqClient/availableList', - method: 'POST', - data, - }); -} -``` - -#### 步骤4:创建运送清单创建弹窗组件 -**文件:** `pc-cattle-transportation/src/views/shipping/createDeliveryDialog.vue` - -```vue - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 取消 - - 提交 - - - - - - - - - -``` - -#### 步骤5:修改运送清单列表页 -**文件:** `pc-cattle-transportation/src/views/shipping/loadingOrder.vue` - -**在模板部分,修改按钮区域:** -```vue - - - - - - 创建装车订单 - - - - 新增运送清单 - - - - - - - - - - - - 编辑 - - - 分配设备 - - - 详情 - - - 查看设备 - - - 删除 - - - 装车 - - - - - - - - - - - - - - - - - - - - -``` - -**在 script 部分,添加导入和方法:** -```javascript -import CreateDeliveryDialog from './createDeliveryDialog.vue'; // 【新增】 - -const CreateDeliveryDialogRef = ref(null); // 【新增】 - -// 【新增】显示创建运送清单对话框 -const showCreateDeliveryDialog = () => { - CreateDeliveryDialogRef.value.open(); -}; -``` - -#### 步骤6:确保权限指令已全局注册 -**文件:** `pc-cattle-transportation/src/directive/index.js` - -确保包含以下内容: -```javascript -import hasPermi from './permission/hasPermi'; -import hasRole from './permission/hasRole'; // 如果有角色指令 - -export default function directive(app) { - app.directive('hasPermi', hasPermi); - app.directive('hasRole', hasRole); // 如果有角色指令 -} -``` - -在 `main.ts` 中确保已引入: -```typescript -import directive from './directive'; - -const app = createApp(App); -directive(app); // 注册自定义指令 -``` - ---- - -## 五、数据库变更 - -### 5.1 可选:添加超级管理员标识字段 - -```sql --- 在 sys_role 表添加超级管理员标识字段(可选) -ALTER TABLE `sys_role` -ADD COLUMN `is_super_admin` TINYINT(1) DEFAULT 0 COMMENT '是否超级管理员 1-是 0-否' AFTER `description`; - --- 设置某个角色为超级管理员 -UPDATE `sys_role` SET `is_super_admin` = 1 WHERE `id` = 1; -``` - -### 5.2 确保权限点数据完整 - -在 `sys_menu` 表中添加运送清单相关权限点(如果不存在): - -```sql --- 运送清单菜单(假设父级菜单ID为2) -INSERT INTO `sys_menu` (`parent_id`, `type`, `name`, `route_url`, `page_url`, `authority`, `icon`, `sort`) -VALUES (2, 1, '运送清单', '/shipping/list', 'shipping/loadingOrder', 'delivery:list', 'icon-shipping', 10); - --- 获取刚插入的菜单ID,假设为100 -SET @menu_id = LAST_INSERT_ID(); - --- 运送清单按钮权限 -INSERT INTO `sys_menu` (`parent_id`, `type`, `name`, `authority`, `sort`) VALUES -(@menu_id, 2, '运送清单新增', 'delivery:add', 1), -(@menu_id, 2, '运送清单编辑', 'delivery:edit', 2), -(@menu_id, 2, '运送清单删除', 'delivery:delete', 3), -(@menu_id, 2, '运送清单查看', 'delivery:view', 4), -(@menu_id, 2, '运送清单核验', 'delivery:check', 5), -(@menu_id, 2, '设备分配', 'delivery:assign', 6), -(@menu_id, 2, '装车操作', 'delivery:load', 7); -``` - -### 5.3 为角色分配权限 - -```sql --- 为某个角色(假设role_id=2)分配运送清单权限 -INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) -SELECT 2, id FROM `sys_menu` WHERE `authority` LIKE 'delivery:%'; -``` - ---- - -## 六、测试计划 - -### 6.1 权限测试 - -#### 6.1.1 菜单权限测试 -1. **测试场景:** 不同角色登录系统 -2. **测试步骤:** - - 创建2个角色:超级管理员、普通操作员 - - 为普通操作员分配部分菜单权限(不包含某些菜单) - - 分别用两个角色的账号登录 -3. **预期结果:** - - 超级管理员能看到所有菜单 - - 普通操作员只能看到被分配的菜单 - - 未分配的菜单在侧边栏不显示 - -#### 6.1.2 按钮权限测试 -1. **测试场景:** 运送清单列表页按钮权限 -2. **测试步骤:** - - 创建角色A:有 `delivery:list` 和 `delivery:view` 权限 - - 创建角色B:有 `delivery:list`、`delivery:view`、`delivery:add`、`delivery:edit` 权限 - - 分别用两个角色的账号登录,访问运送清单页面 -3. **预期结果:** - - 角色A用户:能看到"详情"、"查看设备"按钮,看不到"新增"、"编辑"、"删除"按钮 - - 角色B用户:能看到"新增"、"编辑"、"详情"按钮 - -#### 6.1.3 接口权限测试 -1. **测试场景:** 通过Postman直接调用接口 -2. **测试步骤:** - - 使用普通操作员token(无 `delivery:add` 权限) - - 直接调用 `POST /api/delivery/create` 接口 -3. **预期结果:** - - 接口返回权限不足错误(403或自定义错误码) - - 数据库未创建记录 - -### 6.2 数据隔离测试 - -#### 6.2.1 普通用户数据隔离 -1. **测试场景:** 普通用户只能看到自己的数据 -2. **测试步骤:** - - 创建用户A(roleId=2)创建运送清单数据 - - 创建用户B(roleId=3)创建运送清单数据 - - 用户A登录查询运送清单列表 -3. **预期结果:** - - 用户A只能看到自己创建的运送清单 - - 看不到用户B创建的数据 - -#### 6.2.2 超级管理员数据访问 -1. **测试场景:** 超级管理员能看到所有数据 -2. **测试步骤:** - - 多个普通用户创建运送清单数据 - - 超级管理员登录查询运送清单列表 -3. **预期结果:** - - 超级管理员能看到所有用户创建的运送清单 - -### 6.3 运送清单新增功能测试 - -#### 6.3.1 表单校验测试 -1. **必填项校验:** - - 不填写必填项,点击提交 - - 预期:表单提示相应字段不能为空 -2. **格式校验:** - - 输入不符合格式的车牌号(如:ABC123) - - 输入不符合格式的手机号(如:12345678) - - 预期:表单提示格式错误 -3. **逻辑校验:** - - 预计到达时间早于出发时间 - - 预期:表单提示时间逻辑错误 - -#### 6.3.2 设备选择测试 -1. **测试场景:** 选择不同类型设备 -2. **测试步骤:** - - 选择主机设备 - - 选择多个耳标设备 - - 选择多个项圈设备 - - 提交表单 -3. **预期结果:** - - 表单提交成功 - - 设备关联关系正确保存 - - 可以不选择任何设备(设备可选) - -#### 6.3.3 提交成功测试 -1. **测试场景:** 正确填写所有必填项并提交 -2. **测试步骤:** - - 填写所有必填字段 - - 点击提交按钮 -3. **预期结果:** - - 弹窗关闭 - - 提示"创建成功" - - 列表自动刷新,显示新创建的记录 - - 运输单号自动生成,格式正确 - -### 6.4 集成测试 - -#### 6.4.1 完整流程测试 -1. 普通用户登录 -2. 查看运送清单列表(只显示自己的数据) -3. 点击"新增运送清单"按钮(如有权限) -4. 填写表单并提交 -5. 查看新创建的记录 -6. 编辑、删除操作(如有权限) -7. 退出登录,切换其他用户,验证数据隔离 - -#### 6.4.2 权限动态更新测试 -1. 管理员修改某个角色的菜单权限 -2. 该角色的用户重新登录(或刷新页面重新获取菜单) -3. 验证菜单和按钮权限已更新 - ---- - -## 七、实施步骤与时间估算 - -### 7.1 开发阶段 - -| 阶段 | 任务 | 预计时间 | 责任人 | -|------|------|----------|--------| -| **后端开发** | | | | -| 1 | 创建RoleConstants常量类 | 0.5小时 | 后端开发 | -| 2 | 扩展SecurityUtil工具类 | 1小时 | 后端开发 | -| 3 | 创建DataScopeUtil工具类 | 1.5小时 | 后端开发 | -| 4 | 修改LoginServiceImpl,添加权限查询和存储 | 2小时 | 后端开发 | -| 5 | 创建DeliveryCreateDto | 1小时 | 后端开发 | -| 6 | DeliveryController添加权限注解 | 1小时 | 后端开发 | -| 7 | DeliveryServiceImpl实现createDelivery方法 | 2小时 | 后端开发 | -| 8 | DeliveryServiceImpl修改pageQuery应用数据权限 | 1小时 | 后端开发 | -| 9 | 后端单元测试 | 2小时 | 后端开发 | -| **前端开发** | | | | -| 10 | 扩展User Store | 1小时 | 前端开发 | -| 11 | 修改登录页面保存权限信息 | 0.5小时 | 前端开发 | -| 12 | 添加运送清单创建API | 0.5小时 | 前端开发 | -| 13 | 创建createDeliveryDialog组件 | 4小时 | 前端开发 | -| 14 | 修改loadingOrder页面添加按钮和权限控制 | 2小时 | 前端开发 | -| 15 | 前端功能测试 | 2小时 | 前端开发 | -| **数据库** | | | | -| 16 | 添加超级管理员标识字段(可选) | 0.5小时 | DBA | -| 17 | 添加权限点数据 | 1小时 | DBA | -| 18 | 为角色分配权限 | 0.5小时 | DBA | - -**总计开发时间:约 24 小时(3个工作日)** - -### 7.2 测试阶段 - -| 阶段 | 任务 | 预计时间 | 责任人 | -|------|------|----------|--------| -| 1 | 权限测试(菜单、按钮、接口) | 3小时 | 测试工程师 | -| 2 | 数据隔离测试 | 2小时 | 测试工程师 | -| 3 | 运送清单新增功能测试 | 2小时 | 测试工程师 | -| 4 | 集成测试 | 2小时 | 测试工程师 | -| 5 | Bug修复 | 4小时 | 开发团队 | -| 6 | 回归测试 | 2小时 | 测试工程师 | - -**总计测试时间:约 15 小时(2个工作日)** - -### 7.3 部署上线 - -| 阶段 | 任务 | 预计时间 | 责任人 | -|------|------|----------|--------| -| 1 | 准备部署文档 | 1小时 | 开发团队 | -| 2 | 数据库脚本执行 | 0.5小时 | DBA | -| 3 | 后端代码部署 | 1小时 | 运维工程师 | -| 4 | 前端代码部署 | 0.5小时 | 运维工程师 | -| 5 | 生产环境验证测试 | 2小时 | 测试工程师 | - -**总计部署时间:约 5 小时(0.5个工作日)** - ---- - -## 八、技术要点与注意事项 - -### 8.1 后端要点 - -1. **Sa-Token权限注解** - - `@SaCheckPermission("xxx")` - 检查权限 - - `@SaCheckRole("xxx")` - 检查角色 - - `@SaIgnore` - 忽略登录校验(用于登录接口) - -2. **数据权限过滤** - - 在Service层而非Controller层进行数据权限过滤 - - 超级管理员不进行数据过滤 - - 考虑使用MyBatis-Plus的拦截器实现更优雅的数据权限控制 - -3. **异常处理** - - Sa-Token会抛出`NotPermissionException`,需要在全局异常处理器中捕获 - - 返回友好的错误提示给前端 - -4. **性能优化** - - 权限查询结果可以缓存到Redis中 - - 避免每次请求都查询数据库 - -### 8.2 前端要点 - -1. **权限指令使用** - - `v-hasPermi="['xxx']"` - 控制元素显示/隐藏 - - 支持数组形式,满足其一即可显示 - - 支持 `v-hasPermi="['xxx', 'yyy']"` 或运算 - -2. **状态持久化** - - 使用 `pinia-plugin-persistedstate` 持久化用户信息和权限 - - 刷新页面后权限状态不丢失 - -3. **路由守卫** - - 在路由守卫中检查token有效性 - - 动态加载路由时检查权限 - -4. **表单校验** - - 使用Element Plus的表单校验 - - 自定义校验规则处理复杂逻辑 - - 前端校验为辅,后端校验为主 - -### 8.3 安全注意事项 - -1. **防止权限绕过** - - 前端权限控制仅用于UI显示 - - 后端必须进行权限拦截 - - 所有接口都要有权限校验 - -2. **数据隔离** - - 不能只依赖前端传参 - - 后端必须根据token中的用户信息进行数据过滤 - -3. **日志审计** - - 记录权限变更操作 - - 记录敏感数据的访问日志 - -4. **Token安全** - - 设置合理的token过期时间 - - 考虑实现token自动续期 - - 重要操作需要二次验证 - -### 8.4 兼容性考虑 - -1. **浏览器兼容性** - - 测试Chrome、Edge、Firefox等主流浏览器 - - 考虑IE11兼容性(如需要) - -2. **数据库兼容性** - - SQL语句避免使用数据库特有语法 - - 注意字符集和排序规则 - -3. **版本升级** - - 保留向后兼容性 - - 考虑老版本客户端的处理 - ---- - -## 九、风险与应对措施 - -### 9.1 技术风险 - -| 风险 | 影响 | 概率 | 应对措施 | -|------|------|------|----------| -| Sa-Token权限注解失效 | 高 | 低 | 充分测试,准备手动权限校验方案 | -| 数据权限过滤遗漏 | 高 | 中 | Code Review,编写测试用例覆盖 | -| 前端权限状态丢失 | 中 | 低 | 使用持久化插件,添加错误处理 | -| 性能影响 | 中 | 中 | 权限信息缓存,数据库索引优化 | - -### 9.2 业务风险 - -| 风险 | 影响 | 概率 | 应对措施 | -|------|------|------|----------| -| 权限配置错误导致无法访问 | 高 | 中 | 提供超级管理员账号,保留后门 | -| 数据隔离影响现有业务流程 | 中 | 中 | 充分沟通业务需求,灰度发布 | -| 用户培训不足 | 低 | 高 | 准备操作手册,提供培训 | - -### 9.3 进度风险 - -| 风险 | 影响 | 概率 | 应对措施 | -|------|------|------|----------| -| 需求变更 | 中 | 中 | 预留缓冲时间,敏捷开发 | -| 测试问题较多 | 中 | 中 | 提前介入测试,增加测试资源 | -| 依赖环境问题 | 低 | 低 | 提前准备环境,做好备份 | - ---- - -## 十、交付物清单 - -### 10.1 代码文件 - -**后端:** -- `RoleConstants.java` - 角色常量类 -- `SecurityUtil.java` - 安全工具类(修改) -- `DataScopeUtil.java` - 数据权限工具类 -- `LoginServiceImpl.java` - 登录服务实现(修改) -- `DeliveryController.java` - 运送清单控制器(修改) -- `DeliveryCreateDto.java` - 运送清单创建DTO -- `DeliveryServiceImpl.java` - 运送清单服务实现(修改) -- `SysMenuMapper.java` - 菜单Mapper(修改) -- `SysMenuMapper.xml` - 菜单Mapper XML(修改) - -**前端:** -- `user.ts` - 用户状态管理(修改) -- `shipping.js` - 运送清单API(修改) -- `createDeliveryDialog.vue` - 运送清单创建弹窗(新增) -- `loadingOrder.vue` - 运送清单列表页(修改) - -### 10.2 数据库脚本 -- `permission_init.sql` - 权限初始化脚本 -- `alter_table.sql` - 表结构变更脚本(可选) - -### 10.3 文档 -- ✅ `权限管理和运送清单新增功能实施计划.md` - 本文档 -- `部署文档.md` - 部署步骤说明 -- `测试报告.md` - 测试结果报告 -- `用户操作手册.md` - 最终用户使用指南 - -### 10.4 测试用例 -- 权限测试用例Excel -- 数据隔离测试用例Excel -- 运送清单新增功能测试用例Excel - ---- - -## 十一、后续优化建议 - -### 11.1 功能增强 -1. **细粒度数据权限** - - 支持部门级、区域级数据权限 - - 支持自定义数据权限规则 - -2. **权限管理界面** - - 可视化权限配置界面 - - 权限模板快速应用 - -3. **审计日志** - - 权限变更日志 - - 敏感操作日志 - - 日志查询和导出 - -### 11.2 性能优化 -1. **权限缓存优化** - - Redis缓存用户权限 - - 缓存失效策略 - -2. **数据权限优化** - - MyBatis-Plus数据权限插件 - - SQL优化和索引优化 - -3. **前端性能优化** - - 权限指令懒加载 - - 虚拟滚动优化大列表 - -### 11.3 安全加固 -1. **双因素认证** - - 敏感操作需要短信验证码 - - 登录需要图形验证码 - -2. **会话管理** - - 异常登录检测 - - 单设备登录限制 - -3. **数据加密** - - 敏感数据加密存储 - - 传输数据加密 - ---- - -## 十二、联系方式 - -**项目负责人:** [填写] -**技术负责人:** [填写] -**项目周期:** 2025-10-11 ~ 2025-10-15 -**文档更新日期:** 2025-10-11 - ---- - -**文档结束** - diff --git a/权限管理菜单-UTF8.sql b/权限管理菜单-UTF8.sql deleted file mode 100644 index 77ba09b..0000000 --- a/权限管理菜单-UTF8.sql +++ /dev/null @@ -1,45 +0,0 @@ --- 设置字符集 -SET NAMES utf8mb4; -SET CHARACTER SET utf8mb4; - --- 1. 添加权限管理父菜单 -INSERT INTO `sys_menu` (`parent_id`, `type`, `name`, `route_url`, `page_url`, `authority`, `icon`, `sort`, `is_delete`, `create_time`) -VALUES (0, 1, '权限管理', '/permission', null, 'permission:view', 'el-icon-lock', 20, 0, NOW()); - -SET @permission_parent_id = LAST_INSERT_ID(); - --- 2. 添加菜单权限管理子菜单 -INSERT INTO `sys_menu` (`parent_id`, `type`, `name`, `route_url`, `page_url`, `authority`, `icon`, `sort`, `is_delete`, `create_time`) -VALUES (@permission_parent_id, 1, '菜单权限管理', '/permission/menu', 'permission/menuPermission', 'permission:menu:view', 'el-icon-menu', 1, 0, NOW()); - -SET @menu_permission_id = LAST_INSERT_ID(); - --- 菜单权限管理的按钮权限 -INSERT INTO `sys_menu` (`parent_id`, `type`, `name`, `authority`, `sort`, `is_delete`, `create_time`) VALUES -(@menu_permission_id, 2, '菜单查询', 'permission:menu:list', 1, 0, NOW()), -(@menu_permission_id, 2, '菜单新增', 'permission:menu:add', 2, 0, NOW()), -(@menu_permission_id, 2, '菜单编辑', 'permission:menu:edit', 3, 0, NOW()), -(@menu_permission_id, 2, '菜单删除', 'permission:menu:delete', 4, 0, NOW()), -(@menu_permission_id, 2, '角色分配', 'permission:menu:assign', 5, 0, NOW()); - --- 3. 添加操作权限管理子菜单 -INSERT INTO `sys_menu` (`parent_id`, `type`, `name`, `route_url`, `page_url`, `authority`, `icon`, `sort`, `is_delete`, `create_time`) -VALUES (@permission_parent_id, 1, '操作权限管理', '/permission/operation', 'permission/operationPermission', 'permission:operation:view', 'el-icon-setting', 2, 0, NOW()); - -SET @operation_permission_id = LAST_INSERT_ID(); - --- 操作权限管理的按钮权限 -INSERT INTO `sys_menu` (`parent_id`, `type`, `name`, `authority`, `sort`, `is_delete`, `create_time`) VALUES -(@operation_permission_id, 2, '权限查询', 'permission:operation:list', 1, 0, NOW()), -(@operation_permission_id, 2, '权限分配', 'permission:operation:assign', 2, 0, NOW()), -(@operation_permission_id, 2, '角色管理', 'permission:operation:role', 3, 0, NOW()); - --- 4. 为超级管理员分配所有菜单权限 -DELETE FROM `sys_role_menu` WHERE `role_id` = 1; -INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) -SELECT 1, id FROM `sys_menu` WHERE `is_delete` = 0; - --- 验证 -SELECT '菜单创建完成' as status; -SELECT id, parent_id, name, route_url FROM sys_menu WHERE id >= 17 ORDER BY id; - diff --git a/权限管理菜单-精简版.sql b/权限管理菜单-精简版.sql deleted file mode 100644 index b54f79e..0000000 --- a/权限管理菜单-精简版.sql +++ /dev/null @@ -1,88 +0,0 @@ --- ============================================ --- 权限管理菜单 - 精简版快速安装 --- ============================================ - --- 1. 添加权限管理父菜单 -INSERT INTO `sys_menu` (`parent_id`, `type`, `name`, `route_url`, `page_url`, `authority`, `icon`, `sort`, `is_delete`, `create_time`) -VALUES (0, 1, '权限管理', '/permission', null, 'permission:view', 'el-icon-lock', 20, 0, NOW()); - --- 获取刚插入的父菜单ID -SET @permission_parent_id = LAST_INSERT_ID(); - --- 2. 添加菜单权限管理子菜单 -INSERT INTO `sys_menu` (`parent_id`, `type`, `name`, `route_url`, `page_url`, `authority`, `icon`, `sort`, `is_delete`, `create_time`) -VALUES (@permission_parent_id, 1, '菜单权限管理', '/permission/menu', 'permission/menuPermission', 'permission:menu:view', 'el-icon-menu', 1, 0, NOW()); - -SET @menu_permission_id = LAST_INSERT_ID(); - --- 菜单权限管理的按钮权限 -INSERT INTO `sys_menu` (`parent_id`, `type`, `name`, `authority`, `sort`, `is_delete`, `create_time`) VALUES -(@menu_permission_id, 2, '菜单查询', 'permission:menu:list', 1, 0, NOW()), -(@menu_permission_id, 2, '菜单新增', 'permission:menu:add', 2, 0, NOW()), -(@menu_permission_id, 2, '菜单编辑', 'permission:menu:edit', 3, 0, NOW()), -(@menu_permission_id, 2, '菜单删除', 'permission:menu:delete', 4, 0, NOW()), -(@menu_permission_id, 2, '角色分配', 'permission:menu:assign', 5, 0, NOW()); - --- 3. 添加操作权限管理子菜单 -INSERT INTO `sys_menu` (`parent_id`, `type`, `name`, `route_url`, `page_url`, `authority`, `icon`, `sort`, `is_delete`, `create_time`) -VALUES (@permission_parent_id, 1, '操作权限管理', '/permission/operation', 'permission/operationPermission', 'permission:operation:view', 'el-icon-setting', 2, 0, NOW()); - -SET @operation_permission_id = LAST_INSERT_ID(); - --- 操作权限管理的按钮权限 -INSERT INTO `sys_menu` (`parent_id`, `type`, `name`, `authority`, `sort`, `is_delete`, `create_time`) VALUES -(@operation_permission_id, 2, '权限查询', 'permission:operation:list', 1, 0, NOW()), -(@operation_permission_id, 2, '权限分配', 'permission:operation:assign', 2, 0, NOW()), -(@operation_permission_id, 2, '角色管理', 'permission:operation:role', 3, 0, NOW()); - --- 4. 确保超级管理员角色存在 -INSERT INTO `sys_role` (`id`, `name`, `description`, `is_delete`, `create_time`) -SELECT 1, '超级管理员', '拥有系统所有权限', 0, NOW() -WHERE NOT EXISTS (SELECT 1 FROM `sys_role` WHERE `id` = 1); - --- 5. 为超级管理员分配所有菜单权限(包括新增的) -DELETE FROM `sys_role_menu` WHERE `role_id` = 1; -INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) -SELECT 1, id FROM `sys_menu` WHERE `is_delete` = 0; - --- 6. 设置15900000000为超级管理员 -UPDATE `sys_user` -SET `role_id` = 1 -WHERE `mobile` = '15900000000' AND `is_delete` = 0; - --- 如果用户不存在,创建超级管理员账号 -INSERT INTO `sys_user` (`mobile`, `name`, `password`, `role_id`, `status`, `user_type`, `is_delete`, `create_time`) -SELECT - '15900000000', - '超级管理员', - 'e10adc3949ba59abbe56e057f20f883e', -- 密码:123456 的MD5 - 1, - 1, - 1, - 0, - NOW() -WHERE NOT EXISTS ( - SELECT 1 FROM `sys_user` WHERE `mobile` = '15900000000' -); - --- ============================================ --- 验证结果 --- ============================================ -SELECT '✅ 菜单创建完成!' as 'Status'; - --- 查看新增的菜单 -SELECT id, parent_id, name, route_url, authority -FROM sys_menu -WHERE name LIKE '%权限%' -ORDER BY parent_id, sort; - --- 查看超级管理员账号 -SELECT id, mobile, name, role_id, status -FROM sys_user -WHERE mobile = '15900000000'; - --- 查看超级管理员权限数量 -SELECT COUNT(*) as '权限总数' -FROM sys_role_menu -WHERE role_id = 1; - diff --git a/检查权限分配.sql b/检查权限分配.sql deleted file mode 100644 index 2904c94..0000000 --- a/检查权限分配.sql +++ /dev/null @@ -1,52 +0,0 @@ --- 检查超级管理员权限分配情况 --- 1. 检查超级管理员用户信息 -SELECT - u.id, - u.mobile, - u.name, - u.role_id, - r.name as role_name -FROM sys_user u -LEFT JOIN sys_role r ON u.role_id = r.id -WHERE u.mobile = '15900000000'; - --- 2. 检查 delivery:edit 权限是否存在 -SELECT - id, - name, - authority, - parent_id, - type -FROM sys_menu -WHERE authority = 'delivery:edit'; - --- 3. 检查超级管理员是否有 delivery:edit 权限 -SELECT - u.mobile, - u.name, - r.name as role_name, - m.name as menu_name, - m.authority, - rm.role_id, - rm.menu_id -FROM sys_user u -LEFT JOIN sys_role r ON u.role_id = r.id -LEFT JOIN sys_role_menu rm ON r.id = rm.role_id -LEFT JOIN sys_menu m ON rm.menu_id = m.id -WHERE u.mobile = '15900000000' - AND m.authority = 'delivery:edit'; - --- 4. 检查所有 delivery 相关权限 -SELECT - u.mobile, - u.name, - r.name as role_name, - m.name as menu_name, - m.authority -FROM sys_user u -LEFT JOIN sys_role r ON u.role_id = r.id -LEFT JOIN sys_role_menu rm ON r.id = rm.role_id -LEFT JOIN sys_menu m ON rm.menu_id = m.id -WHERE u.mobile = '15900000000' - AND m.authority LIKE '%delivery%' -ORDER BY m.authority; diff --git a/检查权限分配情况.sql b/检查权限分配情况.sql deleted file mode 100644 index e096a26..0000000 --- a/检查权限分配情况.sql +++ /dev/null @@ -1,66 +0,0 @@ --- 检查权限分配情况 --- 1. 检查超级管理员用户信息 -SELECT - u.id, - u.mobile, - u.name, - u.role_id, - r.name as role_name -FROM sys_user u -LEFT JOIN sys_role r ON u.role_id = r.id -WHERE u.mobile = '15900000000'; - --- 2. 检查 delivery:edit 权限是否存在 -SELECT - id, - name, - authority, - parent_id, - type -FROM sys_menu -WHERE authority = 'delivery:edit'; - --- 3. 检查超级管理员是否有 delivery:edit 权限 -SELECT - u.mobile, - u.name, - r.name as role_name, - m.name as menu_name, - m.authority, - rm.role_id, - rm.menu_id -FROM sys_user u -LEFT JOIN sys_role r ON u.role_id = r.id -LEFT JOIN sys_role_menu rm ON r.id = rm.role_id -LEFT JOIN sys_menu m ON rm.menu_id = m.id -WHERE u.mobile = '15900000000' - AND m.authority = 'delivery:edit'; - --- 4. 检查超级管理员是否有通配符权限 -SELECT - u.mobile, - u.name, - r.name as role_name, - m.name as menu_name, - m.authority -FROM sys_user u -LEFT JOIN sys_role r ON u.role_id = r.id -LEFT JOIN sys_role_menu rm ON r.id = rm.role_id -LEFT JOIN sys_menu m ON rm.menu_id = m.id -WHERE u.mobile = '15900000000' - AND m.authority = '*:*:*'; - --- 5. 检查所有 delivery 相关权限 -SELECT - u.mobile, - u.name, - r.name as role_name, - m.name as menu_name, - m.authority -FROM sys_user u -LEFT JOIN sys_role r ON u.role_id = r.id -LEFT JOIN sys_role_menu rm ON r.id = rm.role_id -LEFT JOIN sys_menu m ON rm.menu_id = m.id -WHERE u.mobile = '15900000000' - AND m.authority LIKE '%delivery%' -ORDER BY m.authority; diff --git a/检查超级管理员权限.sql b/检查超级管理员权限.sql deleted file mode 100644 index 74b840c..0000000 --- a/检查超级管理员权限.sql +++ /dev/null @@ -1,14 +0,0 @@ --- 检查超级管理员权限 -SELECT - u.mobile, - u.name, - r.role_name, - m.name as menu_name, - m.authority -FROM sys_user u -LEFT JOIN sys_role r ON u.role_id = r.id -LEFT JOIN sys_role_menu rm ON r.id = rm.role_id -LEFT JOIN sys_menu m ON rm.menu_id = m.id -WHERE u.mobile = '15900000000' - AND m.authority LIKE '%delivery%' -ORDER BY m.authority; diff --git a/添加设备运单字段.sql b/添加设备运单字段.sql new file mode 100644 index 0000000..078d87f --- /dev/null +++ b/添加设备运单字段.sql @@ -0,0 +1,7 @@ +-- 为智能耳标表添加运单号和车牌号字段 +ALTER TABLE jbq_client ADD COLUMN IF NOT EXISTS delivery_number VARCHAR(255) COMMENT '运单号'; +ALTER TABLE jbq_client ADD COLUMN IF NOT EXISTS license_plate VARCHAR(255) COMMENT '车牌号'; + +-- 为智能项圈表添加运单号和车牌号字段 +ALTER TABLE xq_client ADD COLUMN IF NOT EXISTS delivery_number VARCHAR(255) COMMENT '运单号'; +ALTER TABLE xq_client ADD COLUMN IF NOT EXISTS license_plate VARCHAR(255) COMMENT '车牌号'; diff --git a/添加项圈运单字段.sql b/添加项圈运单字段.sql new file mode 100644 index 0000000..cb4e3ce --- /dev/null +++ b/添加项圈运单字段.sql @@ -0,0 +1,10 @@ +-- 1. 在xq_client表添加运单相关字段 +ALTER TABLE xq_client +ADD COLUMN delivery_id INT COMMENT '运单ID', +ADD COLUMN delivery_number VARCHAR(64) COMMENT '运单号', +ADD COLUMN license_plate VARCHAR(64) COMMENT '车牌号'; + +-- 2. (可选)在delivery表添加项圈设备字段 +-- ALTER TABLE delivery +-- ADD COLUMN xq_device_ids TEXT COMMENT '智能项圈设备ID列表(JSON)'; + diff --git a/牛只运输功能模块整理.md b/牛只运输功能模块整理.md deleted file mode 100644 index 087881e..0000000 --- a/牛只运输功能模块整理.md +++ /dev/null @@ -1,154 +0,0 @@ -# 牛只运输功能模块整理 - -本文档基于当前工作区两个文件夹(pc-cattle-transportation 前端、tradeCattle 后端)的代码与文档,梳理“活牛运输”相关的现有功能模块、接口与前后端对接情况,并提出后续完善建议。 - -更新日期:2025-10-10 - -## 1. 范围说明 -- 前端:pc-cattle-transportation/src -- 后端:tradeCattle/aiotagro-cattle-trade、aiotagro-core - -## 2. 前端已有模块(活牛运输相关) - -2.1 运送清单/运单管理 -- 页面与交互 - - views/entry/details.vue:运单详情页,展示基础信息(运单号、订单标题、资金方、采购商、车牌号、司机、起始地/目的地、预计送达时间、创建时间等),支持主机定位弹窗、轨迹回放、耳标/项圈日志查看。 - - 状态注释:1 境外预检;2 已入境待隔离(检疫成功);3 已入隔离场;4 隔离场出场。 -- 核心接口(api/abroad.js) - - /delivery/pageQueryList(后台运送清单-分页)inspectionList - - /delivery/detail(后台运单详情)waybillDetail - - /delivery/downloadZip(下载运单打包文件)downloadZip - - /jbqServer/serverLocation(主机定位)hostLocation - - /jbqServer/serverTrack(主机轨迹)hostTrack - - /jbqClientLog/jbqLogList(耳标运单期间日志)earLogList - - /xqClient/pageXqListByDeliveryId、/xqClientLog/xqLogList(项圈相关接口:前端已定义,后端当前仓库未检索到对应实现) - -2.2 运输/装车管理(装车订单) -- 核心接口(api/shipping.js) - - /delivery/pageDeliveryOrderList(装车订单列表)orderList - - /delivery/addDeliveryOrder(新增装车订单)orderAdd - - /delivery/deleteDelivery(删除)orderDel - - /delivery/updateDeliveryInfo(编辑)orderEdit - - /deliveryDevice/pageJbqList(查看耳标设备)deviceEarList - - /jbqClient/pageQuery(分配设备列表)deviceList - - /delivery/arrangeJbq(分配耳标设备)deviceAssign - - /delivery/viewDeliveryOrder(订单详情)orderDetail - - /wechatDelivery/carLoadInfo(装车详情)orderLoadDetail - - /wechatDelivery/updateLoadInfo(装车保存)orderLoadSave - - 说明:上述多数接口在后端当前仓库未发现同名 Controller/方法,疑似旧版接口或后端尚未接入该命名;需与后端统一命名或补齐实现。 - -2.3 入境检疫/核验与扫码记录(数据录入) -- 核心接口(api/isolationQuarantine.js) - - /inspection/submit(运单管理-确定入场)waybillSubmit - - /inspection/logList(入/出场扫描记录)scanList - - /inspection/sheepList(隔离场羊只信息列表)sheepList - - /device/serverTrack(主机轨迹)hostTrack(与 /jbqServer/serverTrack 存在路由差异) - - 说明:/inspection/* 相关接口在后端当前仓库未检索到对应 Controller,可能在其他项目或待实现。 - -2.4 设备定位与轨迹可视化 -- views/entry/details.vue:主机定位弹窗与轨迹回放。 -- 接口:api/abroad.js 的 hostLocation、hostTrack。 - -2.5 耳标/项圈设备与日志 -- 接口:api/abroad.js 的 earList(耳标运单期间列表)、earLogList(耳标日志)、collarList、collarLogList(项圈相关)。 -- 说明:耳标日志已在后端对应实现;项圈相关接口未在后端当前仓库检索到。 - -2.6 用户与司机管理(运输支撑) -- 接口:api/userManage.js(司机管理)driverList、driverAdd、driverEdit。 -- 页面:views/userManage/driverDetailDialog.vue(司机证件/备案码等详情展示)。 - -2.7 菜单与权限(支撑运输模块) -- store/permission.js:动态路由与侧边菜单生成(import.meta.glob 方式加载 views)。 -- components/layout/component/left-menu.vue:左侧菜单(标题“牛只运输跟踪系统”)。 -- router/index.ts:基础路由(login、entry/details、system/post 等)。 - -## 3. 后端已有模块(活牛运输相关) - -3.1 运送清单(Delivery) -- Controller:DeliveryController(/delivery) - - POST /pageQuery(小程序运送清单-分页) - - GET /view(小程序运送清单-查询详情) - - POST /submitCheck(小程序运送清单-核验提交) - - POST /pageQueryList(后台系统运送清单-分页) - - GET /detail(后台运单详情) -- Service:IDeliveryService、DeliveryServiceImpl(含 pageQuery、detail、pageQueryListLog 等)。 -- Entity:Delivery(字段包括 delivery_number、license_plate、start/end_location、estimated_delivery_time、driver_name、registered_jbq_count 等)。 -- Mapper:DeliveryMapper.xml(字段映射)。 - -3.2 主机设备(JbqServer) -- Controller:JbqServerController(/jbqServer) - - POST /serverLocation(主机单个定位) - - POST /serverTrack(主机轨迹) -- Service:IJbqServerService、JbqServerServiceImpl(含经纬度转换与时间窗过滤)。 -- 日志:JbqServerLogController(类存在但未提供接口方法)。 - -3.3 耳标设备与日志(JbqClient、JbqClientLog) -- Controller:JbqClientController(/jbqClient) - - POST /list(耳标列表分页) -- Controller:JbqClientLogController(/jbqClientLog) - - POST /jbqLogList(耳标日志分页,按运单时间窗查询) -- Service:IJbqClientService、IJbqClientLogService(含实现)。 - -3.4 运单预警(Warning) -- Controller:WarningLogController - - /warningCount(预警统计) - - POST /queryList(预警记录-分页) - - GET /warningDetail(预警记录详情) - - POST /pageQuery(后台系统预警记录-分页,委托 deliveryService.pageQueryList) -- Job:AutoNumWarningJob(自动盘点与预警计算,基于耳标与主机日志)。 - -3.5 运单设备绑定(DeliveryDevice) -- Controller:DeliveryDeviceController(类存在,未实现接口)。 -- Mapper/Service:DeliveryDeviceMapper、IDeliveryDeviceService(接口存在,未见具体实现方法)。 - -## 4. 前后端接口对接一览 - -4.1 已对接一致(可工作) -- 前端 api/abroad.js → 后端 DeliveryController - - /delivery/pageQueryList → DeliveryController.pageQueryList - - /delivery/detail → DeliveryController.detail -- 前端 api/abroad.js → 后端 JbqServerController - - /jbqServer/serverLocation → JbqServerController.serverLocation - - /jbqServer/serverTrack → JbqServerController.serverTrack -- 前端 api/abroad.js → 后端 JbqClientLogController - - /jbqClientLog/jbqLogList → JbqClientLogController.jbqLogList -- 后端预警接口已具备(前端视图未在本次检索中明确列出,但可按需接入)。 - -4.2 存在缺口或命名不一致(需统一或补齐) -- 前端 api/shipping.js(装车订单与设备分配)与后端当前仓库接口不一致: - - /delivery/addDeliveryOrder、/delivery/pageDeliveryOrderList、/delivery/arrangeJbq、/delivery/viewDeliveryOrder 等后端未找到对应实现。 - - /jbqClient/pageQuery(前端使用)后端当前为 /jbqClient/list(命名不一致)。 -- 前端 api/abroad.js 的项圈相关接口: - - /xqClient/pageXqListByDeliveryId、/xqClientLog/xqLogList 后端未检索到对应 Controller。 -- 前端 api/isolationQuarantine.js 的检疫模块: - - /inspection/*(submit、logList、sheepList)后端当前仓库未检索到对应实现。 -- 前端 api/isolationQuarantine.js 的主机轨迹: - - /device/serverTrack 与后端 /jbqServer/serverTrack 路由不一致(需统一)。 -- 后端 DeliveryDevice(运单设备绑定) - - Controller/Service 已存在,但缺少分配、查询等具体 API,难以支撑前端“分配耳标设备”“查看耳标设备”等功能。 - -## 5. 现状结论 -- 已具备的运输核心功能(端到端可联通) - - 后台运送清单分页与详情查询。 - - 主机设备定位与运单时间窗内轨迹回放。 - - 耳标日志按运单时间窗查询。 - - 预警统计与预警记录(后端已具备接口)。 -- 运输相关支撑模块(前端已具备) - - 用户与司机管理、菜单与权限(动态路由与侧边栏)。 -- 主要缺口 - - 装车订单与设备分配(shipping.js)后端接口未对齐或缺失。 - - 检疫模块(inspection)与项圈模块(xqClient/xqClientLog)后端接口缺失,需补齐或统一。 - - 运单设备绑定(DeliveryDevice)需要提供具体分配/查询 API。 - -## 6. 建议与后续工作 -1) 接口命名统一:统一 /jbqClient/pageQuery → /jbqClient/list;/device/serverTrack → /jbqServer/serverTrack。 -2) 补齐装车订单与设备分配接口:在后端新增或对齐 /delivery/addDeliveryOrder、/delivery/pageDeliveryOrderList、/delivery/viewDeliveryOrder、/deliveryDevice/pageJbqList、/delivery/arrangeJbq 等。 -3) 检疫模块落库:实现 /inspection/submit、/inspection/logList、/inspection/sheepList 等 Controller 与 Service。 -4) 项圈模块落库:实现 /xqClient/pageXqListByDeliveryId、/xqClientLog/xqLogList 的 Controller 与 Service。 -5) 运单设备绑定完善:补充 DeliveryDevice Controller 的分配、查询、解绑等 API,以支持前端设备绑定流程。 -6) 文档化对接清单:在后端生成 Swagger 文档或在前端维护“接口对接表”,确保多端一致性与联调效率。 - -## 7. 附录:参考文件 -- 前端文档:pc-cattle-transportation/README.md、REQUIREMENTS.md、DEVELOPMENT_PLAN.md、DATA_STRUCTURE.md、ARCHITECTURE.md -- 前端关键代码:api/abroad.js、api/shipping.js、api/isolationQuarantine.js、views/entry/details.vue、store/permission.js、router/index.ts -- 后端关键代码:DeliveryController、JbqServerController、JbqClientController、JbqClientLogController、WarningLogController、AutoNumWarningJob、DeliveryDeviceController \ No newline at end of file diff --git a/确保delivery_edit权限.sql b/确保delivery_edit权限.sql deleted file mode 100644 index 8d301ea..0000000 --- a/确保delivery_edit权限.sql +++ /dev/null @@ -1,41 +0,0 @@ --- 确保超级管理员有 delivery:edit 权限 --- 1. 检查是否存在 delivery:edit 权限点 -SELECT id, name, authority FROM sys_menu WHERE authority = 'delivery:edit'; - --- 2. 如果不存在,创建 delivery:edit 权限点 -INSERT INTO sys_menu (parent_id, type, name, authority, sort, is_delete, create_time) -SELECT - (SELECT id FROM sys_menu WHERE route_url LIKE '%delivery%' OR route_url LIKE '%loading%' LIMIT 1), - 2, - '运送清单编辑', - 'delivery:edit', - 3, - 0, - NOW() -WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE authority = 'delivery:edit'); - --- 3. 确保超级管理员角色有 delivery:edit 权限 -INSERT INTO sys_role_menu (role_id, menu_id) -SELECT - (SELECT id FROM sys_role WHERE role_name = '超级管理员' OR id = 1 LIMIT 1), - (SELECT id FROM sys_menu WHERE authority = 'delivery:edit') -WHERE NOT EXISTS ( - SELECT 1 FROM sys_role_menu rm - INNER JOIN sys_role r ON rm.role_id = r.id - INNER JOIN sys_menu m ON rm.menu_id = m.id - WHERE r.role_name = '超级管理员' AND m.authority = 'delivery:edit' -); - --- 4. 验证权限分配 -SELECT - u.mobile, - u.name, - r.role_name, - m.name as menu_name, - m.authority -FROM sys_user u -LEFT JOIN sys_role r ON u.role_id = r.id -LEFT JOIN sys_role_menu rm ON r.id = rm.role_id -LEFT JOIN sys_menu m ON rm.menu_id = m.id -WHERE u.mobile = '15900000000' - AND m.authority = 'delivery:edit'; diff --git a/简化权限修复.sql b/简化权限修复.sql deleted file mode 100644 index 90e64db..0000000 --- a/简化权限修复.sql +++ /dev/null @@ -1,64 +0,0 @@ --- 简化权限检查和修复 --- 1. 删除可能存在的重复权限 -DELETE FROM sys_role_menu WHERE role_id = 1 AND menu_id IN ( - SELECT id FROM sys_menu WHERE authority = 'delivery:edit' -); - --- 2. 确保 delivery:edit 权限存在 -INSERT INTO sys_menu (parent_id, type, name, authority, sort, is_delete, create_time) -SELECT - (SELECT id FROM sys_menu WHERE route_url LIKE '%delivery%' OR route_url LIKE '%loading%' LIMIT 1), - 2, - '运送清单编辑', - 'delivery:edit', - 3, - 0, - NOW() -WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE authority = 'delivery:edit'); - --- 3. 确保超级管理员有 delivery:edit 权限 -INSERT INTO sys_role_menu (role_id, menu_id) -SELECT - 1, -- 超级管理员角色ID - (SELECT id FROM sys_menu WHERE authority = 'delivery:edit') -WHERE NOT EXISTS ( - SELECT 1 FROM sys_role_menu rm - WHERE rm.role_id = 1 AND rm.menu_id = (SELECT id FROM sys_menu WHERE authority = 'delivery:edit') -); - --- 4. 确保超级管理员有通配符权限 -INSERT INTO sys_menu (parent_id, type, name, authority, sort, is_delete, create_time) -SELECT - 0, -- 根菜单 - 2, - '所有权限', - '*:*:*', - 999, - 0, - NOW() -WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE authority = '*:*:*'); - --- 5. 确保超级管理员有通配符权限 -INSERT INTO sys_role_menu (role_id, menu_id) -SELECT - 1, -- 超级管理员角色ID - (SELECT id FROM sys_menu WHERE authority = '*:*:*') -WHERE NOT EXISTS ( - SELECT 1 FROM sys_role_menu rm - WHERE rm.role_id = 1 AND rm.menu_id = (SELECT id FROM sys_menu WHERE authority = '*:*:*') -); - --- 6. 验证权限分配 -SELECT - u.mobile, - u.name, - r.name as role_name, - m.name as menu_name, - m.authority -FROM sys_user u -LEFT JOIN sys_role r ON u.role_id = r.id -LEFT JOIN sys_role_menu rm ON r.id = rm.role_id -LEFT JOIN sys_menu m ON rm.menu_id = m.id -WHERE u.mobile = '15900000000' - AND (m.authority = 'delivery:edit' OR m.authority = '*:*:*') -ORDER BY m.authority; diff --git a/车身照片关联查询功能实现说明.md b/车身照片关联查询功能实现说明.md new file mode 100644 index 0000000..65a1c58 --- /dev/null +++ b/车身照片关联查询功能实现说明.md @@ -0,0 +1,170 @@ +# 车身照片关联查询功能实现说明 + +## 🎯 功能需求 + +在运送清单详情页面的"车身照片"字段中,需要显示与司机姓名和车牌号相关联的车身前后照片,确保车身照片能够正确映射到运送清单信息表单中。 + +## 🔧 技术实现 + +### 1. **问题分析** + +- **现状**:`delivery` 表中的 `carFrontPhoto` 和 `carBehindPhoto` 字段为空 +- **需求**:根据司机姓名和车牌号关联查询车身照片 +- **数据源**:`member_driver` 表中的 `car_img` 字段包含司机车辆照片 + +### 2. **后端实现** + +#### 2.1 新增查询方法 +在 `MemberDriverMapper.java` 中添加了根据司机姓名和车牌号查询的方法: + +```java +/** + * 根据司机姓名和车牌号查询司机信息(包含车身照片) + */ +@Select("SELECT md.id, md.member_id, md.username, md.car_number, " + + "md.driving_license, md.driver_license, md.record_code, " + + "md.car_img, md.remark, md.create_time, m.mobile " + + "FROM member_driver md " + + "LEFT JOIN member m ON md.member_id = m.id " + + "WHERE md.username = #{driverName} AND md.car_number = #{licensePlate}") +Map selectDriverByNameAndPlate(@Param("driverName") String driverName, + @Param("licensePlate") String licensePlate); +``` + +#### 2.2 修改详情查询逻辑 +在 `DeliveryServiceImpl.java` 的 `detail` 方法中添加了车身照片关联查询逻辑: + +```java +// 查询司机信息 +if (delivery.getDriverId() != null) { + try { + // 根据司机ID直接查询司机信息 + Map driverInfo = memberDriverMapper.selectDriverById(delivery.getDriverId()); + + if (driverInfo != null) { + delivery.setDriverName((String) driverInfo.get("username")); + delivery.setLicensePlate((String) driverInfo.get("car_number")); + + // 如果delivery表中的车身照片为空,尝试从司机信息中获取 + if (delivery.getCarFrontPhoto() == null || delivery.getCarFrontPhoto().isEmpty()) { + String carImg = (String) driverInfo.get("car_img"); + if (carImg != null && !carImg.isEmpty()) { + delivery.setCarFrontPhoto(carImg); + } + } + + // 如果车身照片仍然为空,尝试根据司机姓名和车牌号查询其他相关记录 + if ((delivery.getCarFrontPhoto() == null || delivery.getCarFrontPhoto().isEmpty()) && + (delivery.getCarBehindPhoto() == null || delivery.getCarBehindPhoto().isEmpty())) { + try { + Map relatedDriver = memberDriverMapper.selectDriverByNameAndPlate( + delivery.getDriverName(), delivery.getLicensePlate()); + if (relatedDriver != null) { + String relatedCarImg = (String) relatedDriver.get("car_img"); + if (relatedCarImg != null && !relatedCarImg.isEmpty()) { + delivery.setCarFrontPhoto(relatedCarImg); + delivery.setCarBehindPhoto(relatedCarImg); // 使用同一张照片作为前后照片 + } + } + } catch (Exception e) { + // 忽略查询错误 + } + } + } + } catch (Exception e) { + // 忽略查询错误,继续处理 + e.printStackTrace(); + } +} +``` + +### 3. **查询逻辑流程** + +#### 3.1 优先级查询顺序 +1. **第一优先级**:直接从 `delivery` 表获取 `carFrontPhoto` 和 `carBehindPhoto` +2. **第二优先级**:从当前司机的 `member_driver` 记录中获取 `car_img` +3. **第三优先级**:根据司机姓名和车牌号查询其他相关司机记录 + +#### 3.2 数据映射规则 +- **车头照片**:优先使用 `delivery.carFrontPhoto`,其次使用 `member_driver.car_img` +- **车尾照片**:优先使用 `delivery.carBehindPhoto`,其次使用 `member_driver.car_img` +- **备用方案**:如果前后照片都为空,使用同一张 `car_img` 作为前后照片 + +### 4. **前端显示** + +前端详情页面中的车身照片显示组件已经正确配置: + +```vue + + + + + + +``` + +## 📊 数据流程 + +### 1. **API调用流程** +``` +前端详情页面 → waybillDetail API → DeliveryServiceImpl.detail() → +MemberDriverMapper.selectDriverById() → MemberDriverMapper.selectDriverByNameAndPlate() → +返回包含车身照片的delivery对象 +``` + +### 2. **数据查询流程** +``` +1. 查询delivery表基本信息 +2. 根据driverId查询司机信息 +3. 如果车身照片为空,从司机信息中获取car_img +4. 如果仍然为空,根据司机姓名和车牌号查询相关记录 +5. 返回完整的delivery对象给前端 +``` + +## 🎯 功能特点 + +### 1. **智能关联查询** +- ✅ 支持多层级查询策略 +- ✅ 自动匹配司机姓名和车牌号 +- ✅ 容错处理,避免查询失败影响整体功能 + +### 2. **数据完整性** +- ✅ 确保车身照片能够正确显示 +- ✅ 支持前后照片分别显示 +- ✅ 提供备用显示方案 + +### 3. **性能优化** +- ✅ 优先使用已有数据,减少数据库查询 +- ✅ 异常处理,避免查询错误影响用户体验 +- ✅ 缓存友好的查询策略 + +## 📁 相关文件 + +- **后端Mapper**:`tradeCattle/.../MemberDriverMapper.java` ✅ +- **后端Service**:`tradeCattle/.../DeliveryServiceImpl.java` ✅ +- **前端页面**:`pc-cattle-transportation/src/views/entry/details.vue` ✅ + +## 🎉 总结 + +车身照片关联查询功能已经完成!现在: + +- ✅ **智能查询**:根据司机姓名和车牌号自动关联查询车身照片 +- ✅ **多层级策略**:支持多种查询策略,确保数据完整性 +- ✅ **容错处理**:异常情况下不影响整体功能 +- ✅ **前端显示**:车身照片能够正确显示在详情页面中 + +运送清单详情页面现在可以正确显示与司机姓名和车牌号相关联的车身前后照片! diff --git a/重新创建权限管理菜单.sql b/重新创建权限管理菜单.sql deleted file mode 100644 index adcf6fe..0000000 --- a/重新创建权限管理菜单.sql +++ /dev/null @@ -1,67 +0,0 @@ --- ============================================ --- 重新创建权限管理菜单(彻底解决乱码) --- 请在 Navicat 中执行 --- ============================================ - -SET NAMES utf8mb4; -SET CHARACTER SET utf8mb4; - --- 1. 删除旧的乱码数据 -DELETE FROM `sys_role_menu` WHERE `menu_id` >= 28; -DELETE FROM `sys_menu` WHERE `id` >= 28; - --- 2. 重新创建权限管理父菜单 -INSERT INTO `sys_menu` (`parent_id`, `type`, `name`, `route_url`, `page_url`, `authority`, `icon`, `sort`, `is_delete`, `create_time`) -VALUES (0, 1, '权限管理', '/permission', null, 'permission:view', 'el-icon-lock', 20, 0, NOW()); - -SET @permission_parent_id = LAST_INSERT_ID(); - --- 3. 创建菜单权限管理子菜单 -INSERT INTO `sys_menu` (`parent_id`, `type`, `name`, `route_url`, `page_url`, `authority`, `icon`, `sort`, `is_delete`, `create_time`) -VALUES (@permission_parent_id, 1, '菜单权限管理', '/permission/menu', 'permission/menuPermission', 'permission:menu:view', 'el-icon-menu', 1, 0, NOW()); - -SET @menu_permission_id = LAST_INSERT_ID(); - --- 4. 创建菜单权限管理的按钮 -INSERT INTO `sys_menu` (`parent_id`, `type`, `name`, `authority`, `sort`, `is_delete`, `create_time`) VALUES -(@menu_permission_id, 2, '菜单查询', 'permission:menu:list', 1, 0, NOW()), -(@menu_permission_id, 2, '菜单新增', 'permission:menu:add', 2, 0, NOW()), -(@menu_permission_id, 2, '菜单编辑', 'permission:menu:edit', 3, 0, NOW()), -(@menu_permission_id, 2, '菜单删除', 'permission:menu:delete', 4, 0, NOW()), -(@menu_permission_id, 2, '角色分配', 'permission:menu:assign', 5, 0, NOW()); - --- 5. 创建操作权限管理子菜单 -INSERT INTO `sys_menu` (`parent_id`, `type`, `name`, `route_url`, `page_url`, `authority`, `icon`, `sort`, `is_delete`, `create_time`) -VALUES (@permission_parent_id, 1, '操作权限管理', '/permission/operation', 'permission/operationPermission', 'permission:operation:view', 'el-icon-setting', 2, 0, NOW()); - -SET @operation_permission_id = LAST_INSERT_ID(); - --- 6. 创建操作权限管理的按钮 -INSERT INTO `sys_menu` (`parent_id`, `type`, `name`, `authority`, `sort`, `is_delete`, `create_time`) VALUES -(@operation_permission_id, 2, '权限查询', 'permission:operation:list', 1, 0, NOW()), -(@operation_permission_id, 2, '权限分配', 'permission:operation:assign', 2, 0, NOW()), -(@operation_permission_id, 2, '角色管理', 'permission:operation:role', 3, 0, NOW()); - --- 7. 为超级管理员分配所有权限 -DELETE FROM `sys_role_menu` WHERE `role_id` = 1; -INSERT INTO `sys_role_menu` (`role_id`, `menu_id`) -SELECT 1, `id` FROM `sys_menu` WHERE `is_delete` = 0; - --- 8. 验证结果 -SELECT '✅ 权限管理菜单创建完成!' as status; - -SELECT - m.id, - m.parent_id, - m.type, - m.name, - m.route_url, - m.authority -FROM sys_menu m -WHERE m.id >= (SELECT MIN(id) FROM sys_menu WHERE name = '权限管理') -ORDER BY m.parent_id, m.sort, m.id; - -SELECT CONCAT('超级管理员拥有 ', COUNT(*), ' 个权限') as info -FROM sys_role_menu -WHERE role_id = 1; - diff --git a/需求文档.md b/需求文档.md deleted file mode 100644 index e4fecb8..0000000 --- a/需求文档.md +++ /dev/null @@ -1,146 +0,0 @@ -牛只运输管理系统需求文档(V1.0) - -一、项目概述 -- 目标:为牛只运输与检疫业务提供从账号权限、运单管理、设备定位与轨迹、隔离检疫、告警日志到司机与用户管理的全流程管理平台。 -- 形态:前端 Web(Vue3 + Vite + Pinia + Element Plus),后端 Spring Boot(MyBatis-Plus + Sa-Token),MySQL 数据库,Redis 缓存,第三方短信(腾讯云),地图(百度地图)。 - -二、系统架构与部署 -- 前端 - - 技术栈:Vue3、TypeScript、Pinia、Vue Router、Element Plus、Axios、Vite。 - - 路由:静态路由(登录/首页等)+ 动态路由(通过后端菜单驱动)。 - - 权限:路由守卫 + 自定义指令(按钮级权限),依赖用户权限集与角色集。 - - 开发服务:Vite 启动端口 8080,代理 /api 到 http://127.0.0.1:16200(vite.config.ts)。 -- 后端 - - 技术栈:Java 1.8、Spring Boot 2.6.13、MyBatis-Plus、Sa-Token。 - - 应用参数:端口 16200,Context Path /api,dev profile。 - - 数据源:MySQL 129.211.213.226:3306/cattletrade(root/Aiotagro@741)。 - - 缓存:Redis 129.211.213.226:6379(Aiotagro@741)。 - - 短信:腾讯云(代码存在常量类与集成)。 - -三、用户角色与权限 -- 角色(需确认):司机、货源方、采购方、系统管理员、资金方(原文称“四个角色”,但列出了五类,待业务确认)。 -- 其他潜在角色:企业管理员/普通操作员、检疫人员。 -- 权限模型:基于 sys_user、sys_role、sys_menu 三表,支持路由级与按钮级权限控制。 -- 前端控制: - - 路由守卫:白名单 login;无 token 跳登录;已登录拉取菜单后动态生成路由。 - - 指令权限:hasPermi/hasRole 系列,控制页面元素显示与操作。 - -【新增需求】权限与数据可见性 -- 菜单权限管理:由 sys_menu 维护菜单树与权限点;后端依据用户身份返回可见菜单;前端仅渲染可见节点。菜单权限调整后需支持动态生效(用户重新获取菜单即可生效)。 -- 操作权限管理:基于权限码(permKey)控制页面按钮与接口访问;前端通过指令/工具(hasPermi/hasRole)进行显隐与禁用;后端控制器或网关层进行权限拦截与校验,避免越权调用。 -- 登录识别 role_id 与数据范围:登录成功后读取 sys_user.role_id,并以此作为数据作用域依据;普通角色仅能访问本角色范围内的数据(列表、详情、统计等)。 -- 超级管理员权限:超级管理员拥有最高权限与全数据可见性,可管理所有角色与菜单;建议以固定角色编码(如 ROLE_SUPER_ADMIN)或配置标识控制。 - -四、主要功能模块 -1)登录与认证 - - 密码登录与验证码登录(LoginDto.loginType 0/1)。 - - Token 统一在请求拦截器注入 Authorization;401/650 触发重新登录。 - -2)运单管理与入场核验(Entry) - - 检疫列表与查询:inspectionList(attestation.vue)。 - - 详情:waybillDetail(details.vue),展示运单基本信息、预警信息、关联设备。 - - 视频:页面预留“核验装车过磅视频”展示位。 - - 下载:支持文件直链下载。 - - 【新增功能】新增运送清单:在“运送清单/列表页”增加“新增”按钮,打开运送清单表单对话框,支持创建运输单。 - - 权限要求:仅具备相应操作权限的角色可见与可操作(例如 hasPermi('delivery:add'))。 - - 表单字段(建议):运单号、发货方、采购方、车牌号、司机信息、设备绑定(主机/耳标/项圈)、预计出发/到达时间、起点/目的地、牛只数量/重量、检疫信息(可选)、备注。 - - 校验规则:必填项校验、手机号/车牌/时间合法性校验、设备选择合法性校验。 - - 提交与反馈:提交至后端创建接口(POST /api/delivery/create 或同类接口,具体以后端为准),成功后刷新列表并提示;失败给出明确错误信息。 - -3)硬件设备与定位/轨迹(Hardware) - - 主机定位:hostLocation → 地图标注经纬度与时间(locationDialog.vue / details.vue)。 - - 运动轨迹:hostTrack → 展示 polyline 与时间点集合(details.vue)。 - - 设备台账:设备编号、类型(主机/耳标/项圈)、所属用户、佩戴状态等(shipping/lookDialog.vue)。 - -4)隔离检疫(Isolation/Quarantine) - - 隔离厂列表与管理(src/api/quarantine.js、isolationQuarantine.js)。 - - 入场检疫与详情与运单联动(inspectionList、waybillDetail)。 - -5)预警日志(WarningLog) - - 列表与详情、分页查询与过滤。 - -6)用户与司机管理 - - 用户账户与状态管理(src/api/sys.js)。 - - 司机信息采集:姓名、手机号、车牌、驾驶证/行驶证/备案码、车头车身照片,表单校验与上传(userManage/driverDialog.vue)。 - -7)系统管理 - - 岗位管理(/system/post 路由存在)。 - - 菜单与权限管理(后端返回菜单驱动动态路由)。 - -8)支付与订单(如有) - - pay_order 表存在,具体功能启用情况待确认。 - -9)数据导出/下载与多媒体 - - 文件下载直链。 - - 视频播放组件位(过磅视频等)。 - -五、核心数据实体(初步) -- 系统与权限:sys_user、sys_role、sys_menu。 -- 运单与运输:delivery、delivery_device(运单设备关联)。 -- 硬件与定位:jbq_server、jbq_client、jbq_log;xq_client、xq_log;warning_log。 -- 成员与司机:member_user、member_driver(需确认具体表名)。 -- 支付与订单:pay_order(需确认是否启用)。 - -六、关键业务流程 -1)登录流程 - - 未登录访问非白名单路由 → 跳转登录。 - - 登录成功 → 拉取菜单 → 生成动态路由 → 进入首页。 - -2)运单入场核验流程 - - 检索检疫列表 inspectionList → 查看详情 waybillDetail → 查看主机定位 hostLocation 与轨迹 hostTrack → 下载/打印 → 返回列表。 - -3)设备定位与轨迹 - - 选择设备 serverDeviceId → 后端返回经纬度与时间 → 前端在百度地图组件展示。 - -4)司机信息采集与审核 - - 表单录入与资质图片上传 → 校验 → 提交 → 列表展示与状态维护。 - -5)权限菜单变更 - - 后端更新菜单权限 → 前端用户登录拉取最新菜单 → 动态路由更新。 - -七、第三方与集成 -- Redis:登录态与验证码缓存。 -- 腾讯云短信:验证码登录或通知。 -- 百度地图:vue-baidu-map-3x 与 BMap API。 -- 视频播放:页面内嵌 播放器。 -- 文件下载:URL 跳转下载。 - -八、运行环境与配置 -- 前端 - - 开发端口:8080。 - - 代理:/api → http://127.0.0.1:16200(vite.config.ts)。 - - Axios:utils/axios.ts 使用 VITE_API_DOMAIN;utils/request.js 使用 VITE_APP_BASE_API;建议统一为单一实例与变量。 -- 后端 - - 端口:16200,Context Path:/api,profile:dev。 - - MySQL:129.211.213.226:3306/cattletrade(root / Aiotagro@741)。 - - Redis:129.211.213.226:6379(Aiotagro@741)。 - -九、非功能性需求 -- 安全 - - Token 校验与过期处理;401/650 统一重登录。 - - 请求防重复提交;按钮级权限与路由级权限控制。 -- 性能 - - 列表分页与筛选;地图轨迹懒加载;Vite 按需构建。 -- 可靠性 - - 日志与告警完善;定位与轨迹异常提示与降级。 -- 可维护性 - - 统一 API 模块与状态管理;动态菜单减少硬编码。 - -十、待确认事项 -- 角色清单与职责范围:现有“司机、货源方、采购方、系统管理员、资金方”具体权限矩阵。 -- 接口清单:逐一从 src/api 与后端 Controller/Mapper 编目,形成规范接口文档(URL/方法/入参/出参/状态码)。 -- 数据字典与枚举:设备类型、运单状态、告警类型等统一字典。 -- 文件/视频来源与存储策略:本地/云存储与访问鉴权。 -- 后端启动提示“no MyBatis mapper found”原因与影响。 - -十一、下一步计划 -1)统一 Axios 与环境变量,规范请求层。 -2)拉取并整理后端接口清单,补齐字段说明与状态码约定。 -3)梳理并输出 RBAC 权限矩阵(角色 × 权限点)。 -4)补充关键流程的交互原型与边界条件。 -5)完善前后端环境配置说明(.env.development / .env.production 与代理策略)。 - -附:已知接口示例(不完整,需对齐后端) -- GET /api/jbqServer/serverList → 主机服务列表。 -- 登录接口:支持密码登录与验证码登录(参见 src/api/sys.js 与 LoginDto)。 -- 动态菜单:getUserMenu → 生成前端动态路由。 \ No newline at end of file