You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

726 lines
40 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 权限管理
> 模块编码permission
> 端侧Web专属仅超级管理员
> 关联文档01-模块划分 §8 / 02-功能清单-超级管理员 §2 / 03-业务流转逻辑-超级管理员 §4~6 / 05-接口规范 §4.2~4.3 / 06-项目技术要求 §4.2
> 强制规范遵循 `07-前端界面开发规范.md`
## 功能概览
| 项目 | 说明 |
|------|------|
| 菜单名称 | 权限管理 |
| 子菜单 | 角色管理、权限配置注册、权限审计日志 |
| 功能编号 | SA-P-01 ~ SA-P-10 |
| 权限编码前缀 | permission:role:* / permission:config:* |
---
## 页面1角色管理列表页
**页面编号**SA-P-01-P01
**端侧归属**Web专属
**页面路径**/permission/roles
### 界面布局
```
┌──────────────────────────────────────────────────────────────────┐
│ [面包屑] 权限管理 > 角色管理 │
├──────────────────────────────────────────────────────────────────┤
│ [查询条件区] │
│ 角色名称[____] 适用范围[▼] 状态[▼] [查询] [重置] │
├──────────────────────────────────────────────────────────────────┤
│ [操作栏] [新增角色] │
├──────────────────────────────────────────────────────────────────┤
│ [列表区] │
│ 序号 | 角色名称 | 适用范围 | 预设模板 | 关联账号数 | 状态 | 操作 │
│ 1 | 医院查看 | 医院 | 是 | 5 | 启用 | 编辑 停用│
│ 2 | 巡检主管 | 物业下属| 否 | 8 | 启用 | 编辑 停用│
│ 3 | 维修员 | 物业下属| 是 | 23 | 启用 | 编辑 停用│
├──────────────────────────────────────────────────────────────────┤
│ [分页] 共15条 每页[20▼] < 1 > │
└──────────────────────────────────────────────────────────────────┘
```
### 查询条件
| 字段名 | 控件类型 | 必填 | 默认值 | 说明 |
|--------|----------|------|--------|------|
| 角色名称 | 文本输入 | 否 | — | 模糊匹配 |
| 适用范围 | 下拉单选 | 否 | 全部 | 医院账号/物业管理员/物业下属 |
| 状态 | 下拉单选 | 否 | 全部 | 启用/停用 |
### 列表字段
| 序号 | 字段名 | 列宽 | 支持排序 | 说明 |
|------|--------|------|----------|------|
| 1 | 序号 | 60px | — | 自增 |
| 2 | 角色名称 | 150px | 是 | — |
| 3 | 适用范围 | 120px | 否 | 医院账号/物业管理员/物业下属 |
| 4 | 预设模板 | 80px | 否 | 是/否标签 |
| 5 | 关联账号数 | 100px | 是 | 点击查看关联账号列表 |
| 6 | 状态 | 80px | 是 | 启用/停用 |
| 7 | 操作 | 220px | — | 编辑/权限预览/停用/删除 |
### 操作按钮
| 按钮 | 权限编码 | 位置 | 显示条件 | 说明 |
|------|----------|------|----------|------|
| 新增角色 | permission:role:create | 操作栏 | 始终 | 跳转新增页 |
| 编辑 | permission:role:update | 行操作 | 始终 | 跳转编辑页 |
| 权限预览 | permission:role:view | 行操作 | 始终 | 弹窗展示完整权限清单 |
| 停用 | permission:role:update | 行操作 | 状态=启用 | 二次确认 |
| 删除 | permission:role:delete | 行操作 | 关联账号数=0 | 二次确认 |
### 角色差异化视图
| 角色 | 可见按钮 | 数据范围 | 备注 |
|------|----------|----------|------|
| 超级管理员 | 全部按钮 | 全部角色 | — |
### API端点
| 页面操作 | API路径 | 方法 | 说明 |
|----------|---------|------|------|
| 列表查询 | /api/v1/roles | GET | 分页查询 |
| 停用角色 | /api/v1/roles/{id}/disable | PUT | — |
| 删除角色 | /api/v1/roles/{id} | DELETE | 仅无关联账号时可删 |
### 交互流程要求
1. **页面加载流程**
- 进入页面 → 调用 `GET /api/v1/roles` 加载列表默认第1页创建时间倒序
- 并行加载下拉选项:适用范围、状态
- 列表为空时显示空状态插图 + "暂无角色"
2. **查询交互流程**
- 填写查询条件 → 点击"查询"→ 调用API → 重置到第1页
- 点击"重置"→ 清空条件 → 重新加载
3. **行内操作流程**
- **编辑**:点击"编辑"→ 路由跳转 `/permission/roles/:id/edit`
- **权限预览**:点击"权限预览"→ 弹窗展示该角色的完整权限清单(调用 `GET /api/v1/roles/{id}/permissions`
- **停用**:二次确认("确认停用角色XX停用后关联账号将失去该角色的权限")→ 调用 `PUT /api/v1/roles/{id}/disable` → 成功提示 → 刷新列表
- **删除**:仅关联账号数=0时显示 → 二次确认("确认删除角色XX此操作不可恢复")→ 调用 `DELETE /api/v1/roles/{id}` → 成功提示 → 刷新列表
4. **联动交互**
- "关联账号数"可点击 → 弹窗展示使用该角色的账号列表
5. **异常处理**
- 删除角色失败(存在关联账号)→ 提示"该角色下存在关联账号,无法删除"
- 停用角色失败 → 提示具体原因
- API失败 → 通用错误提示
6. **权限控制交互**
-`permission:role:create` → "新增角色"按钮不渲染
-`permission:role:update` → "编辑""停用"按钮不渲染
-`permission:role:delete` → "删除"按钮不渲染
-`permission:role:view` → "权限预览"按钮不渲染
7. **[H1]防重复请求**
- 查询/筛选:点击"查询"按钮后立即 disabled=true + 显示loading态API返回后恢复查询期间再次点击无效
- 行内操作(停用/删除等):点击操作按钮后该行所有操作按钮禁用 + 按钮显示loading旋转图标操作完成后恢复
- 分页切换切换页码时取消上一页未完成请求abortController后再发起新请求
- 页面初始化并行请求之间互不阻塞
8. **[H2]超时与加载反馈**
- 列表查询APItimeout=15秒加载中表格区显示v-loading骨架屏遮罩
- 停用/删除等写操作APItimeout=30秒操作按钮:loading态
- 超时处理:自动中断 → ElMessage.error("请求超时,请检查网络后重试") → 按钮恢复可用
- 列表加载超过2秒时显示全局ElLoading进度提示
9. **[H3]操作确认机制**
- 停用角色ElMessageBox.confirm("确定要停用「{角色名}」吗?停用后关联账号将失去该角色的权限", "操作确认", { type: 'warning' })
- 删除角色ElMessageBox.confirm("确定要删除「{角色名}」吗?此操作不可恢复", "删除确认", { type: 'error' })
- 确认弹窗期间底层页面不可点击
10. **[H8]操作结果反馈**
- 成功ElMessage.success(duration=2000ms) → silent刷新列表
- 失败ElMessage.error(duration=0手动关闭)
- 网络异常:提示"网络连接异常"+ 重试按钮
### 组件规范
| 元素 | 组件 | 配置参数 |
|------|------|----------|
| 查询条件区 | el-form | inline, label-width="auto" |
| 适用范围下拉 | el-select | clearable, placeholder="请选择" |
| 状态标签 | el-tag | 启用:type="success", 停用:type="danger" |
| 预设模板标签 | el-tag | 是:type="primary", 否:type="info" |
| 关联账号数 | el-link | type="primary", underline=false, @click="showRelatedAccounts" |
| 操作按钮 | el-button | type="primary", link, size="small" |
| 删除按钮 | el-button | type="danger", link, size="small" |
| 分页 | el-pagination | layout="total, sizes, prev, pager, next" |
### 校验规则
| 字段 | 规则 | 错误提示 |
|------|------|----------|
| 角色名称(查询) | 最大30字符 | — |
### 响应式布局
| 断点 | 布局调整 |
|------|----------|
| ≥1280px桌面端 | 查询条件一行排列;列表完整展示所有列 |
| 1024-1279pxPad横屏 | 查询条件一行排列;"预设模板"列隐藏 |
| 768-1023pxPad竖屏 | 查询条件两行排列;列表仅显示:序号、角色名称、适用范围、状态、操作 |
---
## 页面2角色新增/编辑页
**页面编号**SA-P-01-P02
**端侧归属**Web专属
**页面路径**/permission/roles/create 或 /permission/roles/:id/edit
### 界面布局
```
┌──────────────────────────────────────────────────────────────────┐
│ [面包屑] 权限管理 > 角色管理 > 新增角色 │
├──────────────────────────────────────────────────────────────────┤
│ ── 基本信息 ── │
│ 角色名称:[____________] │
│ 角色描述:[____________________________] │
│ 适用范围:[▼] (医院账号/物业管理员/物业下属) │
│ 选择预设模板:[▼可选] 选择后自动填充权限,可微调 │
├──────────────────────────────────────────────────────────────────┤
│ ── 权限分配(四级树形勾选)── │
│ ☑ 功能菜单:在线报修 │
│ ├── ☑ 页面:工单列表 │
│ │ ├── ☑ 功能点:工单管理 │
│ │ │ ├── ☑ 查看 ☑ 新增 ☑ 编辑 │
│ │ │ ├── ☐ 删除 ☐ 审批 ☑ 导出 ☑ 分配 │
│ │ └── ☑ 功能点:批量操作 │
│ │ ├── ☑ 查看 ☐ 新增 ☐ 编辑 │
│ │ └── ☐ 删除 ☐ 审批 ☐ 导出 ☐ 分配 │
│ ├── ☑ 页面:工单详情 │
│ │ ├── ☑ 功能点:延期审批 │
│ │ │ ├── ☑ 查看 ☐ 新增 ☐ 编辑 │
│ │ │ └── ☐ 删除 ☑ 审批 ☐ 导出 ☐ 分配 │
│ │ └── ☑ 功能点:工单验收 │
│ │ ├── ☑ 查看 ☐ 新增 ☐ 编辑 │
│ │ └── ☐ 删除 ☑ 审批 ☐ 导出 ☐ 分配 │
│ └── ☐ 页面:报修类型管理 │
│ ... │
│ ☐ 功能菜单:巡检管理 │
│ ... │
├──────────────────────────────────────────────────────────────────┤
│ [取消] [权限预览] [保存] │
└──────────────────────────────────────────────────────────────────┘
```
### 表单字段(基本信息)
| 字段名 | 控件类型 | 必填 | 默认值 | 数据来源 | 校验规则 |
|--------|----------|------|--------|----------|----------|
| 角色名称 | 文本输入 | 是 | — | 自填 | 最大30字全局唯一 |
| 角色描述 | 多行文本 | 否 | — | 自填 | 最大200字 |
| 适用范围 | 下拉单选 | 是 | — | 固定选项 | 医院账号/物业管理员/物业下属 |
| 预设模板 | 下拉单选 | 否 | — | 预设模板列表 | 选择后自动填充权限 |
### 预设模板选项
| 模板名称 | 适用对象 | 典型权限 | 文档来源 |
|----------|----------|----------|----------|
| 物业管理员模板 | 物业公司管理员 | 全部日常业务管理权限 | 01 §8.4 |
| 主管模板 | 主管 | 本班组管理+审批+查看+导出 | 01 §8.4 |
| 班组长模板 | 班组长 | 本班组查看+分配+导出 | 01 §8.4 |
| 维修员模板 | 维修人员 | 接单+完工+延期申请 | 01 §8.4 |
| 巡检员模板 | 巡检人员 | 巡检执行+打卡+异常上报 | 01 §8.4 |
| 保洁员模板 | 保洁人员 | 保洁执行+打卡确认 | 01 §8.4 |
| 医院查看模板 | 医院账号 | 全部日常数据查看+合同+招标 | 01 §8.4 |
### 操作按钮
| 按钮 | 权限编码 | 位置 | 显示条件 | 说明 |
|------|----------|------|----------|------|
| 权限预览 | permission:role:view | 底部操作栏 | 始终 | 弹窗展示已勾选的完整权限清单 |
| 保存 | permission:role:create/update | 底部操作栏 | 始终 | 保存后权限审计日志+实时生效 |
### 通知触发
| 触发操作 | 通知对象 | 通知方式 | 消息模板 | 文档来源 |
|----------|----------|----------|----------|----------|
| 权限变更 | 关联账号用户 | Redis Pub/Sub | 毫秒级刷新权限缓存,无需重新登录 | 03-超级管理员 §6 |
| 权限变更 | 关联账号用户 | 小程序 | 下次接口请求时返回新权限集 | 03-超级管理员 §6 |
### API端点
| 页面操作 | API路径 | 方法 | 说明 |
|----------|---------|------|------|
| 新增角色 | /api/v1/roles | POST | — |
| 编辑角色 | /api/v1/roles/{id} | PUT | — |
| 获取权限树 | /api/v1/permissions/tree | GET | 四级权限树结构 |
| 权限预览 | /api/v1/roles/{id}/permissions | GET | 已分配的完整权限列表 |
### 交互流程要求
1. **页面加载流程**
- 新增模式:空白表单 + 调用 `GET /api/v1/permissions/tree` 加载权限树
- 编辑模式:并行调用权限树 + 角色详情(`GET /api/v1/roles/{id}`)→ 回填表单 + 勾选已有权限
- 权限树加载中显示加载动画
2. **表单填写与提交流程**
- 填写基本信息 → 选择预设模板(可选)→ 自动填充权限树勾选 → 微调权限 → 点击"保存"
- 保存前校验:角色名称必填、适用范围必选、至少勾选一个权限项
- 保存成功 → 记录权限审计日志 → 权限实时生效Redis Pub/Sub→ 返回列表页
3. **权限树交互**
- 四级展开:功能菜单→页面→功能点→动作
- 勾选父节点 → 自动勾选所有子节点
- 取消父节点 → 自动取消所有子节点
- 子节点全选 → 父节点自动勾选
- 子节点部分选 → 父节点半选indeterminate
- 支持搜索过滤权限名称
4. **预设模板联动**
- 选择预设模板 → 弹出确认("选择模板将覆盖当前权限配置,是否继续?")→ 确认后自动勾选模板权限
- 模板填充后仍可手动微调
5. **权限预览交互**
- 点击"权限预览"→ 弹窗展示当前已勾选的权限清单(非保存后的,而是实时的)
- 权限预览弹窗同页面3格式
6. **异常处理**
- 角色名称重复 → 提示"该角色名称已存在"
- 权限树加载失败 → 提示"权限配置加载失败",提供"重试"按钮
- 保存失败 → 提示错误信息,表单数据不丢失
7. **权限控制交互**
- 无保存权限 → "保存"按钮禁用
8. **[H1]防重复请求**
- 点击"保存"按钮后::loading=true + 文案"保存中..." + disabledAPI返回后恢复
9. **[H2]超时与加载反馈**
- 提交APIPOST/PUTtimeout=30秒回填APIGETtimeout=15秒
- 超时处理:中断 → 提示"保存超时..." → 按钮恢复
10. **[H3]操作确认机制**
- 选择预设模板时ElMessageBox.confirm("选择模板将覆盖当前权限配置,是否继续?", { type: 'warning' })
11. **[H4]脏数据检测**
- 编辑模式进入时deep clone初始数据为快照
- 修改任意字段→isDirty=true
- 取消/路由离开时isDirty则ElMessageBox.confirm("当前修改尚未保存...")
- beforeRouteLeave导航守卫拦截
- 保存成功后重置快照和isDirty
12. **[H8]操作结果反馈**
- 成功ElMessage.success("保存成功") → 延迟300ms返回列表页
- 失败ElMessage.error(duration=0);表单数据保持不丢失
### 组件规范
| 元素 | 组件 | 配置参数 |
|------|------|----------|
| 表单 | el-form | label-width="100px", :model, :rules |
| 角色名称 | el-input | maxlength=30, show-word-limit, clearable |
| 角色描述 | el-input | type="textarea", maxlength=200, show-word-limit, :rows=3 |
| 适用范围 | el-select | clearable, placeholder="请选择适用范围" |
| 预设模板 | el-select | clearable, placeholder="可选,选择后自动填充权限" |
| 权限树 | el-tree | show-checkbox, check-strictly=false, default-expand-all=false, :data="permissionTree", node-key="code", :filter-node-method |
| 权限搜索 | el-input | placeholder="搜索权限名称", clearable, prefix-icon="Search" |
| 权限预览按钮 | el-button | type="info", plain |
| 保存按钮 | el-button | type="primary", :loading |
### 校验规则
| 字段 | 规则 | 错误提示 |
|------|------|----------|
| 角色名称 | 必填, 2-30字符, 全局唯一 | "请输入角色名称" / "角色名称长度2-30字符" / "该角色名称已存在" |
| 适用范围 | 必填 | "请选择适用范围" |
| 权限勾选 | 至少勾选一个 | "请至少分配一项权限" |
### 响应式布局
| 断点 | 布局调整 |
|------|----------|
| ≥1280px桌面端 | 基本信息两列排列权限树区域宽度100%高度500px可滚动 |
| 1024-1279pxPad横屏 | 基本信息两列排列权限树区域高度400px |
| 768-1023pxPad竖屏 | 基本信息单列排列权限树区域高度350px默认折叠到第二级 |
---
## 页面3权限预览弹窗
**页面编号**SA-P-06-P01
**端侧归属**Web专属
**页面路径**:弹窗形式
### 界面布局
```
┌──────────────────────────────────────────────────────────────────┐
│ 权限预览 — 巡检主管 [×] │
├──────────────────────────────────────────────────────────────────┤
│ ☑ 在线报修 │
│ ├─ ☑ 工单列表 │
│ │ ├─ ☑ 工单管理:查看 ✓ 新增 ✗ 编辑 ✓ 删除 ✗ 审批 ✓ 导出 ✓ 分配 ✗│
│ │ └─ ☐ 批量操作 │
│ ├─ ☑ 工单详情 │
│ │ ├─ ☑ 延期审批:查看 ✓ 审批 ✓ │
│ │ └─ ☑ 工单验收:查看 ✓ 审批 ✓ │
│ └─ ☐ 报修类型管理 │
│ ☑ 巡检管理 │
│ ├─ ☑ 巡检计划:查看 ✓ 新增 ✓ 编辑 ✓ │
│ ... │
├──────────────────────────────────────────────────────────────────┤
│ [关闭] │
└──────────────────────────────────────────────────────────────────┘
```
### 说明
- 展示角色当前已分配的完整权限清单
- 四级展开:功能菜单→页面→功能点→动作
- 每个动作用 ✓/✗ 标识是否有权限
- 支持搜索功能菜单/页面名称
### 交互流程要求
1. **弹窗打开流程**
- 从角色列表页或角色编辑页触发 → 调用 `GET /api/v1/roles/{id}/permissions` 加载权限数据 → 渲染权限树
- 加载中弹窗内显示loading
2. **弹窗内交互**
- 搜索框输入关键词 → 实时过滤权限树,高亮匹配项
- 点击展开/折叠节点
- 只读模式,不可修改勾选状态
3. **弹窗关闭**
- 点击"关闭"按钮或右上角× → 关闭弹窗
- 支持ESC键关闭
4. **[H1]防重复请求**
- 弹窗打开时调用API期间"关闭"按钮禁用 + 弹窗内显示v-loading遮罩数据返回后恢复
5. **[H2]超时与加载反馈**
- 权限查询APIGETtimeout=15秒加载中弹窗内显示loading骨架屏
- 超时处理:中断 → ElMessage.error("权限数据加载超时") → 提供"重试"按钮
6. **[H8]操作结果反馈**
- 加载失败ElMessage.error(duration=0手动关闭) + 弹窗内展示重试按钮
- 网络异常:提示"网络连接异常"+ 重试按钮
### 组件规范
| 元素 | 组件 | 配置参数 |
|------|------|----------|
| 弹窗 | el-dialog | width="600px", :close-on-click-modal=true, title="权限预览" |
| 权限树 | el-tree | :data, default-expand-all, :props, :filter-node-method |
| 搜索框 | el-input | placeholder="搜索权限名称", clearable, prefix-icon="Search" |
| 权限标识 | el-tag | 有权限:type="success", ✓; 无权限:type="info", ✗ |
| 关闭按钮 | el-button | @click="dialogVisible=false" |
### 校验规则
无表单校验(只读展示页)
### 响应式布局
| 断点 | 布局调整 |
|------|----------|
| ≥1280px桌面端 | 弹窗宽度600px |
| 1024-1279pxPad横屏 | 弹窗宽度550px |
| 768-1023pxPad竖屏 | 弹窗宽度90vw最大500px |
---
## 页面4权限配置注册页
**页面编号**SA-P-10-P01
**端侧归属**Web专属
**页面路径**/permission/registry
### 界面布局
```
┌──────────────────────────────────────────────────────────────────┐
│ [面包屑] 权限管理 > 权限配置注册 │
├──────────────────────────────────────────────────────────────────┤
│ [说明] 此页面展示系统自动注册的权限配置来源IModulePlugin
│ 开发新增功能时自动同步,超级管理员可查看但不可手动编辑 │
├──────────────────────────────────────────────────────────────────┤
│ [查询条件区] │
│ 模块名称[____] 页面名称[____] [查询] [重置] │
├──────────────────────────────────────────────────────────────────┤
│ [列表区] │
│ 模块编码 | 模块名称 | 页面编码 | 页面名称 | 功能点 | 可用动作 │
│ repair | 在线报修 | repair_list| 工单列表 | 工单管理 | 查看,新增..│
│ repair | 在线报修 | repair_detail|工单详情| 延期审批| 查看,审批 │
│ ... │
├──────────────────────────────────────────────────────────────────┤
│ [分页] 共120条 每页[20▼] < 1 2 3 ... 6 > │
└──────────────────────────────────────────────────────────────────┘
```
### 查询条件
| 字段名 | 控件类型 | 必填 | 默认值 | 说明 |
|--------|----------|------|--------|------|
| 模块名称 | 文本输入 | 否 | — | 模糊匹配 |
| 页面名称 | 文本输入 | 否 | — | 模糊匹配 |
### 列表字段
| 序号 | 字段名 | 列宽 | 支持排序 | 说明 |
|------|--------|------|----------|------|
| 1 | 模块编码 | 100px | 否 | — |
| 2 | 模块名称 | 100px | 否 | — |
| 3 | 页面编码 | 130px | 否 | — |
| 4 | 页面名称 | 120px | 否 | — |
| 5 | 功能点编码 | 140px | 否 | — |
| 6 | 功能点名称 | 120px | 否 | — |
| 7 | 可用动作 | 200px | 否 | view,create,update,delete,approve,export,assign |
### 操作按钮
| 按钮 | 权限编码 | 位置 | 显示条件 | 说明 |
|------|----------|------|----------|------|
| — | — | — | — | 此页面只读数据由IModulePlugin自动注册 |
### API端点
| 页面操作 | API路径 | 方法 | 说明 |
|----------|---------|------|------|
| 列表查询 | /api/v1/permissions/registry | GET | 查看已注册的权限配置 |
| 刷新 | /api/v1/permissions/registry/refresh | POST | 手动触发权限重新扫描 |
### 交互流程要求
1. **页面加载流程**
- 进入页面 → 调用 `GET /api/v1/permissions/registry` 加载权限配置列表
- 页面顶部显示说明提示条el-alert说明此页面为只读
2. **查询交互流程**
- 填写查询条件 → 点击"查询"→ 筛选列表 → 重置到第1页
3. **操作流程**
- **刷新**:点击"刷新"按钮 → 二次确认("确认重新扫描权限配置?可能需要数秒")→ 调用 `POST /api/v1/permissions/registry/refresh` → 成功提示 → 重新加载列表
- 无其他操作按钮(只读页面)
4. **异常处理**
- 刷新失败 → 提示"权限扫描失败,请稍后重试"
5. **权限控制交互**
- 此页面仅超级管理员可见
6. **[H1]防重复请求**
- 查询/筛选:点击"查询"按钮后立即 disabled=true + 显示loading态API返回后恢复查询期间再次点击无效
- 刷新操作:点击"刷新"按钮后:loading=true + disabledAPI返回后恢复
- 分页切换切换页码时取消上一页未完成请求abortController后再发起新请求
- 页面初始化并行请求之间互不阻塞
7. **[H2]超时与加载反馈**
- 列表查询APItimeout=15秒加载中表格区显示v-loading骨架屏遮罩
- 刷新操作APIPOSTtimeout=30秒操作按钮:loading态
- 超时处理:自动中断 → ElMessage.error("请求超时,请检查网络后重试") → 按钮恢复可用
- 列表加载超过2秒时显示全局ElLoading进度提示
8. **[H3]操作确认机制**
- 刷新权限配置ElMessageBox.confirm("确认重新扫描权限配置?可能需要数秒", "操作确认", { type: 'warning' })
- 确认弹窗期间底层页面不可点击
9. **[H8]操作结果反馈**
- 成功ElMessage.success(duration=2000ms) → silent刷新列表
- 失败ElMessage.error(duration=0手动关闭)
- 网络异常:提示"网络连接异常"+ 重试按钮
### 组件规范
| 元素 | 组件 | 配置参数 |
|------|------|----------|
| 说明提示条 | el-alert | type="info", :closable=false, show-icon |
| 列表 | el-table | stripe, border, v-loading |
| 可用动作 | el-tag | v-for 循环渲染, type="info", size="small" |
| 刷新按钮 | el-button | type="warning", icon="Refresh", plain |
| 分页 | el-pagination | layout="total, sizes, prev, pager, next" |
### 校验规则
无表单校验(只读页面)
### 响应式布局
| 断点 | 布局调整 |
|------|----------|
| ≥1280px桌面端 | 列表完整展示所有列 |
| 1024-1279pxPad横屏 | "功能点编码"列隐藏 |
| 768-1023pxPad竖屏 | 列表仅显示:模块名称、页面名称、功能点名称、可用动作 |
---
## 页面5权限审计日志页
**页面编号**SA-P-08-P01
**端侧归属**Web专属
**页面路径**/permission/audit-log
### 界面布局
```
┌──────────────────────────────────────────────────────────────────┐
│ [面包屑] 权限管理 > 权限审计日志 │
├──────────────────────────────────────────────────────────────────┤
│ [查询条件区] │
│ 操作人[____] 操作类型[▼] 角色[____] 日期[起始]~[结束] [查询] [重置]│
├──────────────────────────────────────────────────────────────────┤
│ [列表区] │
│ 序号 | 操作时间 | 操作人 | 操作类型 | 目标角色 | 变更详情 | 操作 │
│ 1 | 14:00 | admin | 权限修改 | 巡检主管 | [+2项][-1项]| 查看│
│ 2 | 11:30 | admin | 角色创建 | 保洁主管 | — | 查看│
├──────────────────────────────────────────────────────────────────┤
│ [分页] 共80条 每页[20▼] < 1 2 3 4 > │
└──────────────────────────────────────────────────────────────────┘
```
### 查询条件
| 字段名 | 控件类型 | 必填 | 默认值 | 说明 |
|--------|----------|------|--------|------|
| 操作人 | 文本输入 | 否 | — | 模糊匹配 |
| 操作类型 | 下拉单选 | 否 | 全部 | 角色创建/权限修改/角色分配/角色移除 |
| 角色 | 文本输入 | 否 | — | 模糊匹配角色名称 |
| 日期范围 | 日期范围 | 否 | — | 操作时间范围 |
### 列表字段
| 序号 | 字段名 | 列宽 | 支持排序 | 说明 |
|------|--------|------|----------|------|
| 1 | 序号 | 60px | — | 自增 |
| 2 | 操作时间 | 150px | 是 | 默认倒序 |
| 3 | 操作人 | 100px | 否 | — |
| 4 | 操作类型 | 100px | 否 | 标签样式 |
| 5 | 目标角色 | 120px | 否 | — |
| 6 | 变更详情 | 120px | 否 | [+N项][-M项],简洁展示 |
| 7 | 操作 | 80px | — | 查看详情 |
### 操作按钮
| 按钮 | 权限编码 | 位置 | 显示条件 | 说明 |
|------|----------|------|----------|------|
| 查看详情 | audit-log:permission:view | 行操作 | 始终 | 弹窗展示变更前后对比 |
### 审计日志详情弹窗
```
┌──────────────────────────────────────────────────────────────────┐
│ 权限变更详情 [×] │
├──────────────────────────────────────────────────────────────────┤
│ 角色:巡检主管 │
│ 操作人:超级管理员(admin) │
│ 操作时间2026-04-16 14:00:00 │
│ 操作类型:权限修改 │
├──────────────────────────────────────────────────────────────────┤
│ 变更对比: │
│ [+新增] 在线报修 → 工单详情 → 延期审批 → 审批 │
│ [+新增] 在线报修 → 工单列表 → 工单管理 → 导出 │
│ [-移除] 巡检管理 → 巡检计划 → 计划管理 → 删除 │
├──────────────────────────────────────────────────────────────────┤
│ [关闭] │
└──────────────────────────────────────────────────────────────────┘
```
### API端点
| 页面操作 | API路径 | 方法 | 说明 |
|----------|---------|------|------|
| 列表查询 | /api/v1/audit-logs/permission | GET | 分页查询 |
| 详情查询 | /api/v1/audit-logs/permission/{id} | GET | 含变更前后对比 |
### 交互流程要求
1. **页面加载流程**
- 进入页面 → 调用 `GET /api/v1/audit-logs/permission` 加载列表(默认倒序)
- 并行加载下拉选项:操作类型
- 列表为空时显示空状态
2. **查询交互流程**
- 填写条件 → 点击"查询"→ 调用API → 重置到第1页
- 日期范围选择器限制最多查询90天
3. **行内操作流程**
- **查看详情**:点击"查看"→ 弹窗展示变更前后对比(调用 `GET /api/v1/audit-logs/permission/{id}`
- 新增权限用绿色 `[+新增]` 标记,移除权限用红色 `[-移除]` 标记
4. **异常处理**
- 详情加载失败 → 提示错误信息
- 日期范围超限 → 提示"查询时间范围不能超过90天"
5. **权限控制交互**
-`audit-log:permission:view` → 页面不可见
6. **[H1]防重复请求**
- 查询/筛选:点击"查询"按钮后立即 disabled=true + 显示loading态API返回后恢复查询期间再次点击无效
- 行内操作(查看详情):点击"查看"按钮后该行操作按钮禁用 + 按钮显示loading旋转图标弹窗打开后恢复
- 分页切换切换页码时取消上一页未完成请求abortController后再发起新请求
- 页面初始化并行请求之间互不阻塞
7. **[H2]超时与加载反馈**
- 列表查询APItimeout=15秒加载中表格区显示v-loading骨架屏遮罩
- 详情查询APItimeout=15秒加载中弹窗内显示v-loading遮罩
- 超时处理:自动中断 → ElMessage.error("请求超时,请检查网络后重试") → 按钮恢复可用
- 列表加载超过2秒时显示全局ElLoading进度提示
8. **[H8]操作结果反馈**
- 成功ElMessage.success(duration=2000ms) → silent刷新列表
- 失败ElMessage.error(duration=0手动关闭)
- 网络异常:提示"网络连接异常"+ 重试按钮
### 组件规范
| 元素 | 组件 | 配置参数 |
|------|------|----------|
| 日期范围选择 | el-date-picker | type="daterange", value-format="YYYY-MM-DD", :disabled-date |
| 操作类型标签 | el-tag | 角色创建:type="success", 权限修改:type="warning", 角色分配:type="primary", 角色移除:type="danger" |
| 变更摘要 | span | [+N项] color=green, [-M项] color=red |
| 详情弹窗 | el-dialog | width="650px", :close-on-click-modal=false |
| 新增权限 | div | color=var(--el-color-success), 前缀"[+新增]" |
| 移除权限 | div | color=var(--el-color-danger), 前缀"[-移除]" |
| 关闭按钮 | el-button | @click="dialogVisible=false" |
### 校验规则
| 字段 | 规则 | 错误提示 |
|------|------|----------|
| 日期范围 | 最多90天 | "查询时间范围不能超过90天" |
### 响应式布局
| 断点 | 布局调整 |
|------|----------|
| ≥1280px桌面端 | 查询条件一行排列列表完整展示所有列详情弹窗650px |
| 1024-1279pxPad横屏 | 查询条件两行排列;"目标角色"列隐藏详情弹窗600px |
| 768-1023pxPad竖屏 | 查询条件两行排列列表仅显示序号、操作时间、操作人、操作类型、操作详情弹窗90vw |
---
## 需求追溯
| 功能点编号 | 功能名称 | 文档来源 | 后续服务 | 关联功能 |
|------------|----------|----------|----------|----------|
| SA-P-01 | 角色定义 | 02-超级管理员 §2 / 03-超级管理员 §4 | 创建角色→权限分配 | 账号管理(角色绑定) |
| SA-P-02 | 角色权限分配 | 02-超级管理员 §2 / 03-超级管理员 §4 / 01 §8.1 | 权限变更→审计日志+实时生效 | 权限审计日志 / 权限实时生效 |
| SA-P-03 | 角色管理 | 02-超级管理员 §2 | 停用→关联账号权限失效 | 账号管理(角色绑定) |
| SA-P-04 | 权限预设模板 | 02-超级管理员 §2 / 01 §8.4 | 选择模板→自动填充权限 | 角色新增页(模板选择) |
| SA-P-05 | 账号角色绑定 | 02-超级管理员 §2 / 03-超级管理员 §4 | 在账号管理中操作 | 账号管理 / 物业组织架构(下属角色分配) |
| SA-P-06 | 权限预览 | 02-超级管理员 §2 | 预览→确认权限分配 | 角色新增/编辑页 |
| SA-P-07 | 权限自动同步 | 02-超级管理员 §2 / 03-超级管理员 §5 / 01 §8.2 | IModulePlugin注册→权限树自动更新 | 权限配置注册页 |
| SA-P-08 | 权限审计日志 | 02-超级管理员 §2 / 03-超级管理员 §8.2 / 01 §8.5 | 权限变更→自动记录 | 操作日志 |
| SA-P-09 | 权限实时生效 | 02-超级管理员 §2 / 03-超级管理员 §6 / 01 §8.3 | Redis Pub/Sub毫秒级生效 | — |
| SA-P-10 | 权限配置注册 | 02-超级管理员 §2 / 03-超级管理员 §5 | 查看IModulePlugin注册的权限 | 05-接口规范 §4.2 |
## 业务规则
1. **四级权限粒度**功能菜单→页面→功能点→动作7种动作类型view/create/update/delete/approve/export/assign来源01 §8.1 / 06 §4.2
2. **权限自动同步**新模块通过IModulePlugin.getPermissionDefinitions()自动注册权限管理页面自动渲染新可勾选项来源01 §8.2 / 05 §4.2
3. **权限实时生效**权限变更后通过Redis Pub/Sub毫秒级生效无需重新登录来源01 §8.3 / 03-超级管理员 §6 / 06 §3.1
4. **权限审计日志**记录操作人、时间、类型、变更前后对比来源01 §8.5 / 03-超级管理员 §8.2
5. **角色删除条件**仅关联账号数为0时才可删除来源02-超级管理员 SA-P-03
6. **预设模板使用**创建角色时选择模板→系统自动填充权限→管理员微调后保存来源01 §8.4
7. **权限配置表只读**权限配置注册页数据来源于IModulePlugin自动注册超管只可查看不可手动编辑来源03-超级管理员 §5