# 操作日志 > 模块编码:audit-log > 端侧:Web专属 > 关联文档:01-模块划分 §3.8 / 02-功能清单-物业公司 §8 / 03-业务流转逻辑-物业公司 §8 / 05-接口规范 §9.2 / 06-项目技术要求 §4.5 > 强制规范遵循 `07-前端界面开发规范.md` ## 功能概览 | 项目 | 说明 | |------|------| | 菜单名称 | 操作日志 | | 子菜单 | 日志时间轴、日志列表、日志详情、日志导出、数据补录日志 | | 功能编号 | PR-AL-01 ~ PR-AL-05 | | 权限编码前缀 | audit-log:list:* / audit-log:supplement:view | --- ## 页面1:日志时间轴页 **页面编号**:PR-AL-01-P01 **端侧归属**:Web专属 **页面路径**:/audit-log/timeline ### 界面布局 ``` ┌──────────────────────────────────────────────────────────────────┐ │ [面包屑] 操作日志 > 日志时间轴 │ ├──────────────────────────────────────────────────────────────────┤ │ [查询条件区] │ │ 模块[▼] 操作人[____] 日期[起始]~[结束] [查询] [重置] │ ├──────────────────────────────────────────────────────────────────┤ │ [时间轴视图] │ │ ┃ 2026-04-16 10:30:25 张三 提交了报修工单 #WX20260416001 │ │ ┃ [查看详情] │ │ ┃ 2026-04-16 10:15:10 李四 审批通过了延期申请 #DQ20260416003 │ │ ┃ [查看详情] │ │ ┃ 2026-04-16 09:45:00 王五 完成了巡检打卡 门诊楼1层 │ │ ┃ [查看详情] │ │ ┃ 2026-04-16 09:00:12 赵六 上班打卡 1号楼大厅 │ │ ▼ [查看详情] │ └──────────────────────────────────────────────────────────────────┘ ``` ### 查询条件 | 字段名 | 控件类型 | 必填 | 默认值 | 说明 | |--------|----------|------|--------|------| | 模块 | 下拉单选 | 否 | 全部 | 报修/巡检/保洁/考勤/评价/组织架构/系统配置 | | 操作人 | 文本输入 | 否 | — | 模糊匹配 | | 日期范围 | 日期范围 | 否 | 今天 | — | ### 操作按钮 | 按钮 | 权限编码 | 位置 | 显示条件 | 说明 | |------|----------|------|----------|------| | 查看详情 | audit-log:list:view | 时间轴节点 | 始终 | 弹窗展示完整信息 | ### API端点 | 页面操作 | API路径 | 方法 | 说明 | |----------|---------|------|------| | 时间轴查询 | /api/v1/audit-logs/timeline | GET | — | ### 交互流程要求 1. **页面加载流程**:进入页面 → 默认日期范围为今天 → 调用时间轴查询API GET /api/v1/audit-logs/timeline → 渲染时间轴视图,按时间倒序排列;同时加载模块下拉选项 2. **查询/筛选交互流程**:选择模块/输入操作人/选择日期范围 → 点击[查询] → 重新加载时间轴数据 → 点击[重置]恢复默认条件(今天/全部模块);支持快捷日期(今天/昨天/近7天) 3. **表单填写与提交流程**:本页无表单提交操作,仅查询展示 4. **弹窗/抽屉交互流程**:点击[查看详情] → 调用详情API GET /api/v1/audit-logs/{id} → 弹窗展示完整日志信息(操作人、时间、IP、模块路径、操作内容、变更前后数据、请求参数、响应状态),宽度700px 5. **行内操作流程**:点击时间轴节点的[查看详情] → 弹窗展示;向下滚动到底部自动加载更多(无限滚动v-infinite-scroll) 6. **异常与错误处理**:时间轴数据加载失败显示"加载失败,点击重试";无数据时显示ElEmpty"暂无日志记录";日期范围超过90天提示"查询时间范围不能超过90天";网络异常提示ElMessage.error 7. **联动/级联交互**:模块筛选影响时间轴数据过滤;日期范围变更后时间轴重新渲染;快捷日期按钮联动日期范围选择器 8. **权限控制交互表现**:无 audit-log:list:view 权限时页面不可见;物业管理员仅查看本公司绑定医院的操作日志 9. **[H1] 防重复请求**:查询按钮点击后立即 disabled + loading 状态,防止重复提交;时间轴无限滚动触发 loadMore 时节流处理(500ms 内不重复请求);查看详情弹窗打开时,当前行操作按钮禁用 10. **[H2] 超时控制**:时间轴查询 API GET /api/v1/audit-logs/timeline 设置超时 15s,超过时提示"查询超时,请稍后重试";详情 API GET /api/v1/audit-logs/{id} 设置超时 15s;请求耗时 >3s 时显示全局 Loading 指示器 11. **[H3] 操作确认**:本页主要为只读展示,暂无删除/停用等危险操作需二次确认 12. **[H8] 反馈机制**:查询成功后静默刷新数据(silent),不弹成功提示;加载失败显示 ElMessage.error("加载失败,请重试",持续显示需手动关闭);详情加载成功 2s 后自动消失的 ElMessage.success 提示 ### 组件规范 | 元素 | 组件 | 配置参数 | |------|------|----------| | 模块筛选 | el-select | clearable, placeholder="全部模块" | | 操作人输入 | el-input | clearable, maxlength=20, placeholder="请输入操作人" | | 日期范围 | el-date-picker | type="daterange", value-format="YYYY-MM-DD", range-separator="至" | | 快捷日期 | el-radio-group + el-radio-button | v-model="quickDate" | | 时间轴 | el-timeline | :reverse=false, v-infinite-scroll="loadMore" | | 时间轴节点 | el-timeline-item | :timestamp="item.time", placement="top" | | 模块标签 | el-tag | type="primary", size="small" | | 查看详情按钮 | el-button | type="primary", link, size="small" | | 详情弹窗 | el-dialog | title="操作日志详情", width="700px" | | 详情展示 | el-descriptions | :column="2", border | | 变更前数据 | el-input | type="textarea", :rows="4", readonly, v-if="beforeData" | | 变更后数据 | el-input | type="textarea", :rows="4", readonly, v-if="afterData" | | 响应状态标签 | el-tag | 成功=success / 失败=danger | ### 校验规则 | 字段 | 规则 | 错误提示 | |------|------|----------| | 操作人 | 非必填,maxlength=20 | — | | 日期范围 | 最多90天 | "查询时间范围不能超过90天" | ### 响应式布局 | 断点 | 布局调整 | |------|----------| | ≥1280px(桌面端) | 查询条件一行;时间轴居中展示(最大宽度900px);详情弹窗700px | | 1024-1279px(Pad横屏) | 查询条件两行;时间轴宽度100%;详情弹窗650px | | 768-1023px(Pad竖屏) | 查询条件竖向堆叠;时间轴全宽;详情弹窗95vw | --- ## 页面2:日志列表页 **页面编号**:PR-AL-02-P01 **端侧归属**:Web专属 **页面路径**:/audit-log/list ### 查询条件 | 字段名 | 控件类型 | 必填 | 默认值 | 说明 | |--------|----------|------|--------|------| | 模块 | 下拉单选 | 否 | 全部 | — | | 操作人 | 文本输入 | 否 | — | 模糊匹配 | | 操作类型 | 下拉多选 | 否 | 全部 | 查看/新增/编辑/删除/审批/导出/分配 | | 日期范围 | 日期范围 | 否 | 今天 | — | ### 列表字段 | 序号 | 字段名 | 列宽 | 支持排序 | 说明 | |------|--------|------|----------|------| | 1 | 操作时间 | 150px | 是 | 默认倒序 | | 2 | 操作人 | 80px | 否 | — | | 3 | 模块 | 80px | 否 | — | | 4 | 操作类型 | 80px | 否 | 彩色标签 | | 5 | 操作内容 | 250px | 否 | — | | 6 | 响应状态 | 80px | 否 | 成功(绿)/失败(红) | | 7 | 操作 | 80px | — | 查看详情 | ### 操作按钮 | 按钮 | 权限编码 | 位置 | 显示条件 | 说明 | |------|----------|------|----------|------| | 查看详情 | audit-log:list:view | 行操作 | 始终 | 弹窗 | ### 日志详情弹窗 ``` ┌──────────────────────────────────────────────────────────────────┐ │ 操作日志详情 [×] │ ├──────────────────────────────────────────────────────────────────┤ │ 操作人:张三(水电维修班) │ │ 操作时间:2026-04-16 10:30:25 │ │ 操作IP:192.168.1.100 │ │ 操作模块:在线报修 → 工单列表 → 工单管理 → 新增 │ │ 操作内容:提交报修工单 #WX20260416001 │ │ 变更前数据:(无,新增操作) │ │ 变更后数据:{ "id": "WX20260416001", "type": "水电", ... } │ │ 请求参数:{ "type": "水电", "description": "3楼灯管不亮", ... } │ │ 响应状态:成功 │ ├──────────────────────────────────────────────────────────────────┤ │ [关闭] │ └──────────────────────────────────────────────────────────────────┘ ``` ### API端点 | 页面操作 | API路径 | 方法 | 说明 | |----------|---------|------|------| | 列表查询 | /api/v1/audit-logs | GET | 分页查询 | | 详情 | /api/v1/audit-logs/{id} | GET | 含完整信息 | ### 交互流程要求 1. **页面加载流程**:进入页面 → 默认日期范围为今天 → 调用列表查询API GET /api/v1/audit-logs → 渲染表格,默认按操作时间倒序排列,每页20条;同时加载模块下拉、操作类型下拉选项 2. **查询/筛选交互流程**:选择模块/输入操作人/选择操作类型(多选,支持全选/反选)/选择日期范围 → 点击[查询] → 重新加载数据 → 点击[重置]恢复默认条件 3. **表单填写与提交流程**:本页无表单提交操作,仅查询展示 4. **弹窗/抽屉交互流程**:点击[查看详情] → 调用详情API GET /api/v1/audit-logs/{id} → 弹窗展示完整日志信息(操作人+班组、操作时间、操作IP、操作模块路径、操作内容、变更前/后数据JSON、请求参数、响应状态),宽度700px 5. **行内操作流程**:点击[查看详情] → 弹窗展示;变更前后数据使用JSON格式化高亮展示 6. **异常与错误处理**:列表数据为空时显示ElEmpty"暂无操作日志";详情加载失败提示"详情加载失败";日期范围超过90天提示"查询时间范围不能超过90天";API请求失败显示ElMessage.error 7. **联动/级联交互**:操作类型多选筛选与模块筛选可组合使用;分页切换保持筛选条件 8. **权限控制交互表现**:无 audit-log:list:view 权限时页面不可见;物业管理员仅查看本公司绑定医院的操作日志 9. **[H1] 防重复请求**:查询按钮点击后 disabled + loading,防止重复提交;分页切换时 abort 前一次未完成的列表请求再发新请求;行内"查看详情"按钮点击后禁用当前行操作,弹窗关闭后恢复 10. **[H2] 超时控制**:列表查询 GET /api/v1/audit-logs 超时 15s;详情 GET /api/v1/audit-logs/{id} 超时 15s;请求 >3s 显示全局 v-loading 全屏遮罩 11. **[H3] 操作确认**:本页为只读列表,暂无删除等危险操作需确认 12. **[H8] 反馈机制**:查询成功静默刷新(silent);失败 ElMessage.error 持续显示手动关闭;详情加载成功 ElMessage.success 2s 自动消失 ### 组件规范 | 元素 | 组件 | 配置参数 | |------|------|----------| | 模块筛选 | el-select | clearable, placeholder="全部模块" | | 操作人输入 | el-input | clearable, maxlength=20, placeholder="请输入操作人" | | 操作类型筛选 | el-select | v-model="query.types", multiple, collapse-tags, collapse-tags-tooltip, filterable, placeholder="全部类型" | | 日期范围 | el-date-picker | type="daterange", value-format="YYYY-MM-DD", range-separator="至" | | 列表 | el-table | stripe, border, :data="tableData", v-loading | | 分页 | el-pagination | layout="total, sizes, prev, pager, next", :page-sizes="[10,20,50,100]" | | 操作类型标签 | el-tag | 查看=info / 新增=success / 编辑=primary / 删除=danger / 审批=warning / 导出=info / 分配=primary | | 响应状态标签 | el-tag | 成功=success / 失败=danger | | 查看详情按钮 | el-button | type="primary", link | | 详情弹窗 | el-dialog | title="操作日志详情", width="700px", :close-on-click-modal="true" | | 详情展示 | el-descriptions | :column="2", border | | 变更前数据 | el-input | type="textarea", :rows="6", readonly, class="json-viewer" | | 变更后数据 | el-input | type="textarea", :rows="6", readonly, class="json-viewer" | | 请求参数 | el-input | type="textarea", :rows="4", readonly | ### 校验规则 | 字段 | 规则 | 错误提示 | |------|------|----------| | 操作人 | 非必填,maxlength=20 | — | | 日期范围 | 最多90天 | "查询时间范围不能超过90天" | ### 响应式布局 | 断点 | 布局调整 | |------|----------| | ≥1280px(桌面端) | 查询条件区水平排列,表格完整展示全部7列,详情弹窗700px | | 1024-1279px(Pad横屏) | 查询条件区换行排列,表格隐藏"模块"列,详情弹窗650px | | 768-1023px(Pad竖屏) | 查询条件区垂直堆叠,表格仅显示操作时间、操作人、操作类型、操作内容、操作列,详情弹窗95vw | --- ## 页面3:日志导出 **页面编号**:PR-AL-04-P01 **端侧归属**:Web专属 **页面路径**:导出弹窗 ### 操作按钮 | 按钮 | 权限编码 | 位置 | 显示条件 | 说明 | |------|----------|------|----------|------| | 导出Excel | audit-log:list:export | 列表页操作栏 | 始终 | 导出当前筛选结果 | ### 交互流程要求 1. **页面加载流程**:日志导出为日志列表页的操作功能,非独立页面;进入日志列表页时加载导出按钮 2. **查询/筛选交互流程**:导出数据范围跟随列表页当前筛选条件 3. **表单填写与提交流程**:在日志列表页点击[导出Excel] → 弹出导出确认弹窗(确认导出当前筛选条件下的数据)→ 确认 → 后端异步生成Excel → 生成完毕自动下载 4. **弹窗/抽屉交互流程**:导出确认弹窗宽度400px,展示当前筛选条件和预估数据量;点击遮罩层可关闭 5. **行内操作流程**:大量数据导出时显示进度条,支持取消操作 6. **异常与错误处理**:导出失败提示"导出失败,请稍后重试";数据量超10万条提示"数据量过大,请缩小查询范围";导出超时提示"导出超时,请缩小查询范围后重试" 7. **联动/级联交互**:导出数据范围与列表页筛选条件联动 8. **权限控制交互表现**:无 audit-log:list:export 权限时导出按钮隐藏 9. **[H1] 防重复请求**:导出按钮点击后 disabled + loading 状态,防止重复点击;导出进行中时禁用查询/筛选等可能改变数据范围的操作 10. **[H2] 超时控制**:导出异步任务超时设置 60s(大文件生成);导出确认弹窗 API 调用超时 15s;>3s 显示全局 Loading 11. **[H3] 操作确认**:导出前必须通过确认弹窗(type=warning),弹窗内容须包含当前筛选条件和预估数据量,用户明确确认后才开始导出 12. **[H8] 反馈机制**:导出成功 ElMessage.success("导出成功",2s 自动消失);导出失败 ElMessage.error 持续显示手动关闭;取消导出不提示 ### 组件规范 | 元素 | 组件 | 配置参数 | |------|------|----------| | 导出按钮 | el-button | type="success", icon="Download", plain, :loading="exportLoading" | | 确认弹窗 | el-message-box | type="warning", confirmButtonText="确认导出", cancelButtonText="取消" | | 导出进度弹窗 | el-dialog | title="导出中", width="400px", :close-on-click-modal="false", :show-close="false" | | 进度条 | el-progress | :percentage="exportProgress", :stroke-width="6" | | 取消导出按钮 | el-button | type="danger", @click="cancelExport" | ### 校验规则 | 字段 | 规则 | 错误提示 | |------|------|----------| | — | — | — | ### 响应式布局 | 断点 | 布局调整 | |------|----------| | ≥1280px(桌面端) | 导出按钮在列表页操作栏展示,弹窗宽度400px | | 1024-1279px(Pad横屏) | 导出按钮缩小为small尺寸 | | 768-1023px(Pad竖屏) | 导出按钮收入"更多"下拉菜单,弹窗宽度90vw | --- ## 页面4:数据补录日志页 **页面编号**:PR-AL-05-P01 **端侧归属**:Web专属 **页面路径**:/audit-log/supplement ### 查询条件 | 字段名 | 控件类型 | 必填 | 默认值 | 说明 | |--------|----------|------|--------|------| | 模块 | 下拉单选 | 否 | 全部 | 巡检/保洁/考勤 | | 补录人 | 文本输入 | 否 | — | 模糊匹配 | | 审核状态 | 下拉单选 | 否 | 全部 | 待审核/通过/驳回 | | 日期范围 | 日期范围 | 否 | — | — | ### 列表字段 | 序号 | 字段名 | 列宽 | 支持排序 | 说明 | |------|--------|------|----------|------| | 1 | 补录时间 | 140px | 是 | 默认倒序 | | 2 | 补录人 | 80px | 否 | — | | 3 | 模块 | 80px | 否 | — | | 4 | 补录原因 | 100px | 否 | 蓝牙故障/系统异常/其他 | | 5 | 审核状态 | 90px | 否 | — | | 6 | 审核人 | 80px | 否 | — | | 7 | 审核时间 | 140px | 否 | — | ### 操作按钮 | 按钮 | 权限编码 | 位置 | 显示条件 | 说明 | |------|----------|------|----------|------| | 查看详情 | audit-log:supplement:view | 行操作 | 始终 | — | ### API端点 | 页面操作 | API路径 | 方法 | 说明 | |----------|---------|------|------| | 补录日志 | /api/v1/audit-logs/supplement | GET | — | ### 交互流程要求 1. **页面加载流程**:进入页面 → 调用API加载补录日志列表 2. **查询交互**:填写条件 → 查询 → 重置到第1页 3. **行内操作**:点击"查看详情"→ 弹窗展示补录详情(补录原因、原始数据、补录后数据、审核信息) 4. **异常处理**:无数据时显示空状态 5. **权限控制**:无 `audit-log:supplement:view` → 页面不可见 6. **[H1] 防重复请求**:查询按钮点击后 disabled + loading,防止重复提交;分页切换时 abort 前次未完成请求;行内"查看详情"点击后禁用当前行,弹窗关闭后恢复 7. **[H2] 超时控制**:列表查询 GET /api/v1/audit-logs/supplement 超时 15s;详情加载超时 15s;>3s 全局 Loading 8. **[H3] 操作确认**:本页为只读查看,暂无删除/停用等危险操作需二次确认 9. **[H8] 反馈机制**:查询成功静默刷新(silent);失败 ElMessage.error 手动关闭;详情加载成功 2s 自动消失提示 ### 组件规范 | 元素 | 组件 | 配置参数 | |------|------|----------| | 列表 | el-table | stripe, border, v-loading | | 审核状态标签 | el-tag | 待审核:type="warning", 通过:type="success", 驳回:type="danger" | | 补录原因标签 | el-tag | type="info", size="small" | | 详情弹窗 | el-dialog | width="600px" | ### 校验规则 | 字段 | 规则 | 错误提示 | |------|------|----------| | 日期范围 | 最多90天 | "查询时间范围不能超过90天" | ### 响应式布局 | 断点 | 布局调整 | |------|----------| | ≥1280px | 查询条件一行;列表完整展示 | | 1024-1279px | 查询条件两行;"审核人""审核时间"列隐藏 | | 768-1023px | 查询条件竖向堆叠;列表仅显示:补录时间、补录人、模块、审核状态、操作 | --- ## 需求追溯 | 功能点编号 | 功能名称 | 文档来源 | 后续服务 | 关联功能 | |------------|----------|----------|----------|----------| | PR-AL-01 | 日志时间轴 | 02-物业公司 §8 / 03-物业公司 §8.2 | — | — | | PR-AL-02 | 日志列表 | 02-物业公司 §8 / 03-物业公司 §8.2 | — | — | | PR-AL-03 | 日志详情 | 02-物业公司 §8 / 03-物业公司 §8.2 | — | — | | PR-AL-04 | 日志导出 | 02-物业公司 §8 | — | — | | PR-AL-05 | 数据补录日志 | 02-物业公司 §8 / 03-物业公司 §8.1 | — | 巡检/保洁/考勤补录审核 | ## 业务规则 1. **日志记录范围**:在线报修/巡检管理/保洁管理/考勤打卡/服务评价/组织架构/系统配置(来源:03-物业公司 §8.1) 2. **自动记录**:所有写操作通过AOP切面统一记录,业务代码无感知(来源:06 §4.5) 3. **记录内容**:操作人、时间、IP、模块、操作类型、变更前后数据快照(来源:06 §4.5 / 03-物业公司 §8.2) 4. **日志保留**:至少保留1年,支持导出(来源:06 §4.5) 5. **物业管理员数据范围**:仅查看本公司绑定医院的操作日志(来源:01 §1.3)