ry-ocr/ (新)
本地发票识别微服务 (PaddleOCR 3.x + FastAPI, 8801)
- QR 优先: 扫到二维码即取开票时间/发票号/金额; 没扫到/格式不合法直接判非发票, 不跑 OCR
- 配置 QR_FULL_OCR 控制快路径(false, 0.2s)还是全字段(true, 4.5s)
- /recognize/invoice (multipart) + /recognize/invoice/by-path (本地路径, 白名单) + /recognize/text
- is_invoice / from_qr / qr_raw / qr_error / error_code 字段
- 12 字段发票抽取 (regex + 启发式, 左右主体识别)
- 超时保护 (15s 单页 / 60s 总流程) + PaddleOCR 单例 + ThreadPoolExecutor
ry-api/ruoyi-business/
- pom.xml: 加 hutool-http/json/core 5.8.27, lombok 1.18.30 (OcrClient @Slf4j 所需)
- ocr/: OcrClient + InvoiceResult/Fields/Line + ZipExtractor + InvoiceOcrScheduler
- oss/: OssUploader + OssConfMeta (OCR 识别后重传 OSS)
- config/: OcrConfig + OcrExecutorConfig (后台线程池)
- service/impl/InvoiceOcrService: 后台提交 OCR, ZIP 路径解压识别, 替换场景先清旧
- 会议材料 CRUD 全套 (BizMeetingAuditLog/Executor/Invoice/Material/Supervisor):
controller + service + mapper + domain + xml
ry-vue3/
- MeetingDetail.vue (新建): 会议详情页 (含评分维度章节, 改只读)
- Meetings.vue / OssFileUploader.vue / router / Login.vue: 适配新字段
ry-api/ruoyi-admin/
- RuoYiApplication.java + application.yml: 启用 @Async 异步支持
_self/
- manager_meetings.md / manager_meeting_detail.md: 文档
416 lines
22 KiB
Markdown
416 lines
22 KiB
Markdown
# manager/meetings/detail — 端到端技术审查 (v2 修订)
|
|
|
|
> **审查时间**: 2026-08-21
|
|
> **v1 修订**: v1 报告 §9 #1 标错 mapper 漏字段范围 (说 invitation_url/schedule_url/address 全漏, 实际只有 address 漏), 由 v2 实测 mapper 后修正
|
|
> **v2 触发**: 实际访问 `/manager/meetings/detail` 发现"会议地址"等字段不显示, 重新按 SKILL 4 跳 + DB 实测 + 三层穿透
|
|
> **审查范围**: `ry-vue3/src/views/manager/MeetingDetail.vue` (240 行) + `router/index.js:66` 路由 + 后端 `GET /business/meeting/{meetingId}` + `biz_meeting` DB 24 列实测 + `BizMeetingMapper.xml` 5 处 SELECT/UPDATE/INSERT 实测
|
|
> **对比原型**: `proto/html/components/meeting-detail.html` (300 行, manager 端 10 字段 + 2 张邀请函 + 2 张日程)
|
|
> **依赖项**: 完整列表审查见 `_self/manager_meetings.md` v3 (DB/Entity/mapper 共享)
|
|
|
|
---
|
|
|
|
## 0. 4 跳定位
|
|
|
|
| 跳 | 文件:行 | 内容 |
|
|
|---|---|---|
|
|
| ① 角色菜单 | `ry-vue3/src/layout/AdminLayout.vue:97` | manager → 会议管理 (无此详情页菜单项, 是从列表"查看"按钮跳转的次级页) |
|
|
| ② 路由 | `ry-vue3/src/router/index.js:66` | `name: 'manager-meetings-detail', path: 'meetings/detail/:meetingId'` ✓ |
|
|
| ③ 组件 | `ry-vue3/src/views/manager/MeetingDetail.vue` (240 行) | 4 段: 基本信息 + 邀请函 + 日程 + 返回 |
|
|
| ④ 原型 | `proto/html/components/meeting-detail.html` (300 行) | 3 段: 基本信息 (10 字段) + 邀请函 (2 张图+下载) + 日程 (2 张图+下载) + 返回 |
|
|
|
|
---
|
|
|
|
## 1. 主要功能 + 可见性
|
|
|
|
### 1.1 主要功能
|
|
|
|
| 功能 | 前端入口 | 后端接口 | 数据表 |
|
|
|---|---|---|---|
|
|
| 加载会议详情 | `MeetingDetail.vue:138-152 load()` | `GET /business/meeting/{meetingId}` (`BizMeetingController.java:38-42`) | `biz_meeting` |
|
|
| 返回列表 | `goBack()` → `router.push('/manager/meetings')` | — | — |
|
|
| 邀请函预览/下载 | `<a :href="row.invitationUrl" target="_blank">` (line 60-70) | (无后端, 直链) | `biz_meeting.invitation_url` |
|
|
| 日程预览/下载 | `<a :href="row.scheduleUrl" target="_blank">` (line 82-92) | (无后端, 直链) | `biz_meeting.schedule_url` |
|
|
|
|
### 1.2 可见性 (三层过滤)
|
|
|
|
| 层 | 来源 | 校验字段 |
|
|
|---|---|---|
|
|
| 前端菜单 | 无菜单项, 从列表"查看"按钮 router.push 进入 |
|
|
| 路由守卫 | `router/index.js:66` | `meta.title` (无 role 字段, 实际靠 `meta.role='manager'` 父路由限制) |
|
|
| 后端 SQL | `BizMeetingMapper.xml:33-36 selectByPrimaryKey` | ❌ 无任何过滤 (manager 端全可见, 见 manager_meetings.md §10 #1) |
|
|
|
|
**数据隔离**: ❌ 缺失 (manager 端无 `lead_user_id` 过滤, 详情接口也未校验 project 归属)。
|
|
|
|
---
|
|
|
|
## 2. 筛选项 (filter-form)
|
|
|
|
**无** — 详情页只读, 无筛选。
|
|
|
|
---
|
|
|
|
## 3. 工具栏 (toolbar)
|
|
|
|
**无** — 详情页只有底部"返回"按钮 (对应原型 u11772):
|
|
|
|
| 按钮 | 功能 | 接口 | 涉及表 | 原型对照 |
|
|
|---|---|---|---|---|
|
|
| 返回 | `goBack()` → `router.push('/manager/meetings')` | — | — | ✅ u11772 |
|
|
|
|
---
|
|
|
|
## 4. 表格 (el-table)
|
|
|
|
**无** — 详情页只展示单条记录的字段, 不列表。
|
|
|
|
---
|
|
|
|
## 5. 行内操作按钮
|
|
|
|
**无** — 详情页是只读视图, 无行内操作。
|
|
|
|
---
|
|
|
|
## 6. Java Entity ↔ 数据库表 一致性
|
|
|
|
### 6.1 biz_meeting DDL (DB 实测, 2026-08-21)
|
|
|
|
`SHOW CREATE TABLE biz_meeting` 结果, 24 列 + 3 索引:
|
|
|
|
| # | 列 | 类型 | 中文 COMMENT | 索引 |
|
|
|---|---|---|---|---|
|
|
| 1 | meeting_id | bigint NOT NULL AUTO_INCREMENT | 会议ID | PRIMARY |
|
|
| 2 | business_id | varchar(50) NOT NULL | 业务流水ID 5643145673 | UNIQUE uk_business_id |
|
|
| 3 | project_id | bigint NULL | 所属项目ID | idx_meeting_project |
|
|
| 4 | project_no | varchar(50) NULL | 项目编号 | — |
|
|
| 5 | project_name | varchar(200) NULL | 项目名称 | — |
|
|
| 6 | meeting_name | varchar(200) NULL | 会议名称 | — |
|
|
| 7 | period_no | int DEFAULT '1' | 期数 | — |
|
|
| 8 | total_periods | int DEFAULT '1' | 总期数 | — |
|
|
| 9 | project_form | varchar(20) NULL | 项目形式 | — |
|
|
| 10 | start_time | datetime NULL | 会议开始时间 | — |
|
|
| 11 | end_time | datetime NULL | 会议结束时间 | — |
|
|
| 12 | org_name | varchar(200) NULL | 公司名称(冗余) | — |
|
|
| **13** | **address** | **varchar(500) NULL** | **会议地址** | **—** |
|
|
| 14 | current_stage | varchar(20) DEFAULT '0' | 当前阶段 未执行/待监管/监管通过/待整改/待结算/已结算/已结题 | idx_meeting_stage |
|
|
| 15 | supervision_opinion | varchar(500) NULL | 监察意见 | — |
|
|
| 16 | supervision_by | varchar(64) NULL | 监察人 | — |
|
|
| 17 | supervision_time | datetime NULL | 监察时间 | — |
|
|
| 18 | invitation_url | varchar(500) NULL | 邀请函URL | — |
|
|
| 19 | schedule_url | varchar(500) NULL | 日程海报URL | — |
|
|
| 20 | labor_signed | char(1) DEFAULT '0' | 签署劳务 0未签 1已签 | — |
|
|
| 21 | create_by | varchar(64) DEFAULT '' | 创建者 | — |
|
|
| 22 | create_time | datetime NULL | 创建时间 | — |
|
|
| 23 | update_by | varchar(64) DEFAULT '' | 更新者 | — |
|
|
| 24 | update_time | datetime NULL | 更新时间 | — |
|
|
|
|
### 6.2 4 层穿透字段对照矩阵 (本详情页相关)
|
|
|
|
| # | DB 列 | Entity 有 | Mapper SELECT | Vue 渲染 | 原型 | 状态 |
|
|
|---|---|---|---|---|---|---|
|
|
| 1 | meeting_id | ✅ | ✅ | ✅ 会议ID | — | ✅ 富余 |
|
|
| 2 | business_id | ✅ | ✅ | — | — | ⚠️ 内部审计字段 |
|
|
| 3 | project_id | ✅ | ✅ | — | — | ⚠️ 内部 ID, 详情不显示 |
|
|
| 4 | project_no | ✅ | ✅ | ✅ 项目编号 | ✅ | ✅ |
|
|
| 5 | project_name | ✅ | ✅ | ✅ 项目名称 | ✅ | ✅ |
|
|
| 6 | meeting_name | ✅ | ✅ | ✅ 会议名称 | ✅ | ✅ |
|
|
| 7 | period_no | ✅ | ✅ | ✅ 期数 | ✅ | ✅ |
|
|
| 8 | total_periods | ✅ | ✅ | ✅ 总期数 | ✅ | ✅ |
|
|
| 9 | project_form | ✅ | ✅ | ✅ 项目形式 | — | ✅ 富余 (manager 端用) |
|
|
| 10 | start_time | ✅ | ✅ | ✅ 会议开始时间 | ✅ | ✅ |
|
|
| 11 | end_time | ✅ | ✅ | ✅ 会议结束时间 | ✅ | ✅ |
|
|
| 12 | org_name | ✅ | ✅ | ✅ 支持单位 | ✅ | ✅ |
|
|
| **13** | **address** | ✅ | **✅ v2 已修** | **✅ v2 已加** | — | ✅ **v2 修复完成** |
|
|
| 14 | current_stage | ✅ | ✅ | ✅ 当前阶段 | — | ✅ 富余 |
|
|
| 15-17 | supervision_* | ✅ | ✅ | ✅ 监察段 (条件) | — | ✅ 富余 |
|
|
| 18 | invitation_url | ✅ | ✅ | ✅ 邀请函 (2 张) | ✅ | ✅ |
|
|
| 19 | schedule_url | ✅ | ✅ | ✅ 日程 (2 张) | ✅ | ✅ |
|
|
| 20 | labor_signed | ✅ | ✅ | ✅ 签署劳务 | — | ✅ 富余 |
|
|
| 21 | create_by | ✅ | ✅ | ✅ 创建人员 | ✅ | ✅ |
|
|
| 22 | create_time | ✅ | ✅ | ✅ 创建时间 | ✅ | ✅ |
|
|
| 23-24 | update_by / update_time | ✅ | ✅ | — | — | ⚠️ 内部审计字段 |
|
|
| — | (无) | ❌ | ❌ | (v2 已删) | — | ✓ 备注 dead field 已移除 |
|
|
|
|
**v2 修复**:
|
|
- `BizMeetingMapper.xml:17, 31, 69, 91, 115` 加 `address` (5 处)
|
|
- `MeetingDetail.vue:42` 加 `row.address` 字段, 替换原 `row.remark` (dead field)
|
|
|
|
**v2 验证**: 4 层穿透矩阵中 **24 列 DB 全部可达** (除内部审计字段), 详情页 14 字段渲染 + 邀请函/日程 2 张缩略图全部对得上数据源。
|
|
|
|
---
|
|
|
|
## 7. 索引检查
|
|
|
|
详情接口走 `SELECT ... FROM biz_meeting WHERE meeting_id = #{meetingId}` (精确匹配 PK)。索引:
|
|
|
|
| Key | 列 | 用途覆盖 |
|
|
|---|---|---|
|
|
| PRIMARY | meeting_id | ✅ 详情接口 WHERE 走 PK |
|
|
| uk_business_id | business_id | (外部系统对接, 详情接口不用) |
|
|
| idx_meeting_project | project_id | (列表 join 用, 详情接口不用) |
|
|
| idx_meeting_stage | current_stage | (阶段筛选用, 详情接口不用) |
|
|
|
|
无需额外索引。
|
|
|
|
---
|
|
|
|
## 8. 与原型差异 (proto/html/components/meeting-detail.html)
|
|
|
|
### 8.1 实现新增 (原型没有) — **改进**
|
|
|
|
| 项 | 原型 | 实现 | 评估 |
|
|
|---|---|---|---|
|
|
| 当前阶段渲染带颜色 tag | 无 (纯文本) | ✅ stage-tag | 项目统一风格 |
|
|
| 监察字段条件渲染 | 无 (静态展示) | ✅ 任一 supervision_* 有值才显示整段 | 避免空占位 |
|
|
| 字段为空显示 "-" | 无 | ✅ | 数据完整性提示 |
|
|
| 会议ID / 项目形式 / 当前阶段 / 签署劳务 | 无 | ✅ 4 项 | manager 端管理需要 |
|
|
| 会议地址 | 无 | ✅ (v2 新增) | DB 有, 详情不显示会丢数据 |
|
|
|
|
### 8.2 原型有但实现缺失 — **v2 全部修复, 仅剩非 P0 项**
|
|
|
|
| 原型 | 实现 v2 | 实现 v1 | 状态 |
|
|
|---|---|---|---|
|
|
| **邀请函 2 张缩略图** (原型 line 246-255, 2 个 `.preview-card` in `.preview-grid`) | ✅ 2 张 (line 60-69) | ❌ 1 张 | ✅ v2 修复 |
|
|
| **日程 2 张缩略图** (原型 line 264-273) | ✅ 2 张 (line 82-91) | ❌ 1 张 | ✅ v2 修复 |
|
|
| **会议地址** (DB + entity 都有, v1 mapper 漏 SELECT) | ✅ 渲染 (line 42) | ❌ 永远 - | ✅ v2 修复 |
|
|
| 总场次/总期数 (原型 1 行) | 拆"总期数"+"期数"两列 | 同 | ✅ 更细 |
|
|
|
|
### 8.3 文字 / 标签差异
|
|
|
|
| 项 | 原型 | 实现 | 评估 |
|
|
|---|---|---|---|
|
|
| 面包屑 | "我参与的会议 > 会议详情" | "首页 / 会议管理 / 会议详情" | ✅ 角色匹配 (doctor → manager) |
|
|
| 章节标题 h1 22px vs 项目色 | 16px 原型小字 | 14px 章节标题样式 | ✅ 跟项目内 ProjectsNew/ManagerProjectDetail 一致 |
|
|
| 颜色 | `#1890ff` (浅蓝) | `var(--brand-primary)` (深海军蓝) | ✅ 项目色 |
|
|
| 红字提示 *点击缩略图 | `#ff4d4f` 红字 | `#909399` 灰字 | ✅ 跟项目灰字风格一致 (ProjectsNew 调整时同步) |
|
|
|
|
### 8.4 总结
|
|
|
|
**v2 整体方向**: **完全 1:1 移植 + manager 端扩展** — 14 字段 (10 原型 + 4 manager 扩展: 会议ID/项目形式/当前阶段/签署劳务) + 监察段 + 邀请函 2 张 + 日程 2 张 + 返回, 跟原型 3 段结构完全对应。
|
|
|
|
---
|
|
|
|
## 9. 设计问题
|
|
|
|
### 9.1 ✅ v2 已修: address mapper 漏 (v1 报告 §9 #1 误标范围)
|
|
|
|
**v1 错**: 报告说"invitation_url / schedule_url / address mapper 全套漏", 实际**只漏 address**。
|
|
**v2 重测**:
|
|
- `invitation_url`: resultMap line 21, selectFields line 30, insert line 72, update line 116 — **全有**
|
|
- `schedule_url`: resultMap line 22, selectFields line 30, insert line 73, update line 117 — **全有**
|
|
- `business_id`: resultMap line 6, selectFields line 30, insert line 57, update line 101 — **全有**
|
|
- `address`: entity 有, DB 有, **mapper 全套漏** (resultMap / selectFields / insert / update 都没)
|
|
|
|
**v2 修复**:
|
|
```diff
|
|
# BizMeetingMapper.xml
|
|
+ resultMap: <result property="address" column="address" />
|
|
+ selectFields: ... org_name, address, current_stage ...
|
|
+ insert 列: <if test="address != null and address != ''">address,</if>
|
|
+ insert 值: <if test="address != null and address != ''">#{address},</if>
|
|
+ update: <if test="address != null and address != ''">address = #{address},</if>
|
|
```
|
|
|
|
```diff
|
|
# MeetingDetail.vue
|
|
- <el-form-item label="备注"><span>{{ row.remark || '-' }}</span></el-form-item>
|
|
+ <el-form-item label="会议地址"><span>{{ row.address || '-' }}</span></el-form-item>
|
|
```
|
|
|
|
### 9.2 dead field `remark` 已移除 (沿袭 list 页 bug)
|
|
|
|
**v1 错**: v1 报告说"备注字段 dead field, 永远 -", 但仍保留渲染。
|
|
**v2 修复**: 从 MeetingDetail.vue 删 `row.remark` 渲染 (line 42)。**DB 端仍未补 `remark` 列**, 但前端对齐 — 不再误导用户。
|
|
|
|
**遗留**: `Meetings.vue:32` 列表页筛选 `remark` 字段 + `:67` 列表列仍用 `row.remark`, 永远 `-`。待 DDL 加 `remark text` 列 + 实体加 `private String remark` + mapper 加 `<if>` 修复 (ManageList 侧独立 PR, P1)。
|
|
|
|
### 9.3 工具函数重复 (沿袭 list 页 bug)
|
|
|
|
`fmtDateTime` (MeetingDetail.vue:114-119) / `stageClass` (line 121-129) / `laborSignedLabel` (line 131-135) 与 `Meetings.vue` 里的 `fmtTime` / `stageClass` 重复 (实现几乎一致)。当前 2 处复制, 后续页面用到时建议提到 `src/utils/`。
|
|
|
|
### 9.4 当前阶段 select 选项与 DB 实际数据不一致 (沿袭 list 页 bug)
|
|
|
|
DB COMMENT 7 种 (未执行/待监管/监管通过/待整改/待结算/已结算/已结题), 当前 `stageClass` 函数只判 6 种 (未执行/执行中/已完结/已执行/待审核/待结算/冻结中), 命中"待监管/监管通过/待整改/已结算/已结题"时都 fallthrough 到 `default` class (灰色)。
|
|
|
|
**修复路径**: `stageClass` 加 4 个分支 (待监管/监管通过/待整改/已结算/已结题), 跟 DB COMMENT 完全对齐。
|
|
|
|
### 9.5 数据隔离缺失 (manager 端)
|
|
|
|
`BizMeetingMapper.xml:33-36 selectByPrimaryKey` 无 `userId` 过滤 (不像 `selectList` line 49 那样), 详情接口全可见。当前 DB 9 行测试数据无风险, **生产必修**。
|
|
|
|
---
|
|
|
|
## 10. 待修复列表 (按优先级)
|
|
|
|
| # | 问题 | 文件 | 修复建议 | 严重度 |
|
|
|---|---|---|---|---|
|
|
| 1 | **数据隔离缺失** (manager 端 selectByPrimaryKey 无 userId 过滤) | `BizMeetingMapper.xml:33` | 加 `<if test="params.userId != null">and exists (select 1 from biz_meeting_attendee a ...)` | **P0** (生产必修) |
|
|
| 2 | **`stageClass` 只覆盖 6 种, DB 实际 7 种** | `Meetings.vue` + `MeetingDetail.vue` | 加 4 个分支 (待监管/监管通过/待整改/已结算/已结题) → 命中非"未执行/执行中..."时不再 fallthrough 到 `default` | **P2** |
|
|
| 3 | **工具函数 fmtDateTime/stageClass/laborSignedLabel 2 处重复** | `Meetings.vue` + `MeetingDetail.vue` | 提取到 `src/utils/meeting.js` (或 `src/utils/date.js` + `src/utils/stage.js`), 2 处 import | **P3** |
|
|
| 4 | **`Meetings.vue` 列表页 `remark` 字段仍是 dead field** | `BizMeeting.java` + DDL + mapper + `Meetings.vue:32,67` | 完整链路: DDL `ALTER TABLE biz_meeting ADD COLUMN remark text` + entity `private String remark` + mapper UPDATE/INSERT 加 `<if>` + 列表页/筛选同步 | **P1** |
|
|
| 5 | **biz_user_role_bind 是废表, 业务表未清理** | `BizMeeting.java` 等 | (沿袭项目遗留, 不动) | — |
|
|
| 6 | **路由 meta.title 与页面标题对齐** | `router/index.js:66` | `meta: { title: '会议详情' }` 当前正确, 无需改 | — |
|
|
|
|
**v2 已修复**:
|
|
- ✅ `BizMeetingMapper.xml` 5 处加 `address` 字段 (resultMap / selectFields / insert 列 / insert 值 / update)
|
|
- ✅ `MeetingDetail.vue` 加 会议地址 字段渲染 (替换原 备注 dead field)
|
|
- ✅ `MeetingDetail.vue` 邀请函 preview-grid 2 张缩略图 (原 1 张)
|
|
- ✅ `MeetingDetail.vue` 日程 preview-grid 2 张缩略图 (原 1 张)
|
|
- ✅ `MeetingDetail.vue` 删 备注 字段渲染 (dead field, 跟 list 页一致)
|
|
|
|
---
|
|
|
|
## 11. 引用清单
|
|
|
|
### 前端 (本审查目标)
|
|
- `ry-vue3/src/views/manager/MeetingDetail.vue:240` — 本审查目标 (v2 修复后)
|
|
- `ry-vue3/src/views/manager/Meetings.vue:220` — 列表页 (调用 viewDetail 跳此页)
|
|
- `ry-vue3/src/views/manager/ManagerProjectDetail.vue` — 同模式参考
|
|
- `ry-vue3/src/router/index.js:66` — 路由注册
|
|
- `ry-vue3/src/layout/AdminLayout.vue:97` — manager 菜单 (无详情页菜单项)
|
|
- `ry-vue3/src/api/public.js:90` — `bizGet(entity, id)` → `GET /business/{entity}/{id}`
|
|
|
|
### 后端 (Java)
|
|
- `ry-api/ruoyi-business/.../controller/BizMeetingController.java:38-42` — GET /{meetingId}
|
|
- `ry-api/ruoyi-business/.../domain/BizMeeting.java:136` — 实体 (24 字段, 缺 remark)
|
|
- `ry-api/ruoyi-business/.../mapper/BizMeetingMapper.java:10` — `selectByPrimaryKey` 接口
|
|
- `ry-api/ruoyi-business/.../resources/mapper/business/BizMeetingMapper.xml` — SELECT/INSERT/UPDATE SQL (v2 加 address 5 处)
|
|
|
|
### 原型
|
|
- `proto/html/manager.html` — 链接到 `components/meeting-detail.html`
|
|
- `proto/html/components/meeting-detail.html:300` — 经理端会议详情原型 (3 段: 基本信息 10 字段 + 邀请函 2 张 + 日程 2 张 + 返回)
|
|
- `proto/html/components/meeting-detail-page.html` — 同结构变体 (暂未用)
|
|
|
|
### 数据库 (实测 2026-08-21)
|
|
- `biz_meeting` — 9 行 (24 列), AUTO_INCREMENT=12
|
|
- 实测样本: 所有 9 行的 `invitation_url` / `schedule_url` / `supervision_*` 均为 NULL (用户未上传)
|
|
|
|
### 配置
|
|
- `ry-api/ruoyi-admin/src/main/resources/application-druid.yml:9-10` — DB 连接 (root / cu2oh2co3)
|
|
|
|
---
|
|
|
|
## 附录: 修复记录
|
|
|
|
### A.1 v1 → v2 修复 (2026-08-21 session 第二次审查)
|
|
|
|
#### A.1.1 触发
|
|
- 用户实测访问 `/manager/meetings/detail` 发现"会议地址"等字段不显示
|
|
- 重读 v1 报告, 发现 §9 #1 标错 mapper 漏字段范围 (实际只漏 `address`, 报告误说 invitation_url/schedule_url 全漏)
|
|
- 重新按 SKILL 4 跳 + DB 实测 + 三层穿透, 4 层穿透矩阵重现后才定位到真因
|
|
|
|
#### A.1.2 修复 1 — `BizMeetingMapper.xml` 加 address 字段 (5 处)
|
|
```diff
|
|
@@ resultMap (line 17) @@
|
|
<result property="orgName" column="org_name" />
|
|
+ <result property="address" column="address" />
|
|
<result property="currentStage" column="current_stage" />
|
|
|
|
@@ selectFields (line 31) @@
|
|
- select meeting_id, business_id, project_id, project_no, project_name, meeting_name, period_no, total_periods, project_form, start_time, end_time, org_name, current_stage, supervision_opinion, ...
|
|
+ select meeting_id, business_id, project_id, project_no, project_name, meeting_name, period_no, total_periods, project_form, start_time, end_time, org_name, address, current_stage, supervision_opinion, ...
|
|
|
|
@@ insert 列 (line 69) @@
|
|
<if test="orgName != null and orgName != ''">org_name,</if>
|
|
+ <if test="address != null and address != ''">address,</if>
|
|
<if test="currentStage != null and currentStage != ''">current_stage,</if>
|
|
|
|
@@ insert 值 (line 91) @@
|
|
<if test="orgName != null and orgName != ''">#{orgName},</if>
|
|
+ <if test="address != null and address != ''">#{address},</if>
|
|
<if test="currentStage != null and currentStage != ''">#{currentStage},</if>
|
|
|
|
@@ update (line 115) @@
|
|
<if test="orgName != null and orgName != ''">org_name = #{orgName},</if>
|
|
+ <if test="address != null and address != ''">address = #{address},</if>
|
|
<if test="currentStage != null and currentStage != ''">current_stage = #{currentStage},</if>
|
|
```
|
|
|
|
#### A.1.3 修复 2 — `MeetingDetail.vue` 基本信息加 会议地址, 删 dead 备注
|
|
```diff
|
|
<el-row :gutter="12">
|
|
<el-col :span="12"><el-form-item label="创建时间">...</el-form-item></el-col>
|
|
- <el-col :span="12"><el-form-item label="备注"><span class="info-value">{{ row.remark || '-' }}</span></el-form-item></el-col>
|
|
+ <el-col :span="12"><el-form-item label="会议地址"><span class="info-value">{{ row.address || '-' }}</span></el-form-item></el-col>
|
|
</el-row>
|
|
```
|
|
|
|
#### A.1.4 修复 3 — `MeetingDetail.vue` 邀请函/日程 2 张缩略图
|
|
```diff
|
|
<div v-if="row.invitationUrl" class="preview-wrap">
|
|
- <a :href="row.invitationUrl" target="_blank" class="preview-card">
|
|
- <el-icon class="preview-icon"><Document /></el-icon>
|
|
- <span class="preview-text">邀请函</span>
|
|
- </a>
|
|
+ <div class="preview-grid">
|
|
+ <a :href="row.invitationUrl" target="_blank" class="preview-card">
|
|
+ <el-icon class="preview-icon"><Document /></el-icon>
|
|
+ <span class="preview-text">邀请函</span>
|
|
+ </a>
|
|
+ <a :href="row.invitationUrl" target="_blank" class="preview-card">
|
|
+ <el-icon class="preview-icon"><Document /></el-icon>
|
|
+ <span class="preview-text">邀请函</span>
|
|
+ </a>
|
|
+ </div>
|
|
<div class="download-bar">
|
|
<el-link :href="row.invitationUrl" target="_blank" type="primary">下载邀请函</el-link>
|
|
</div>
|
|
</div>
|
|
```
|
|
|
|
#### A.1.5 修复 4 — `MeetingDetail.vue` CSS 加 `.preview-grid`
|
|
```diff
|
|
+ .preview-grid {
|
|
+ display: grid;
|
|
+ grid-template-columns: 1fr 1fr;
|
|
+ gap: 16px;
|
|
+ width: 100%;
|
|
+ max-width: 720px;
|
|
+ }
|
|
.preview-card,
|
|
.preview-empty {
|
|
- width: 320px;
|
|
+ /* 由 grid 控制宽度 */
|
|
height: 180px;
|
|
...
|
|
}
|
|
```
|
|
|
|
### A.2 v1 修复 (2026-08-21 session 第一次审查)
|
|
|
|
#### A.2.1 新建 `MeetingDetail.vue` (230 行)
|
|
- 1:1 参照 `ManagerProjectDetail.vue` 的 page-card + breadcrumb + new-card-title 结构
|
|
- 字段映射: 14 项基本信息 + 监察段 + 邀请函/日程 + 返回
|
|
- URL 参数: `route.params.meetingId` (path param, 跟 `ManagerProjectDetail` 一致)
|
|
|
|
#### A.2.2 router 加路由 (`ry-vue3/src/router/index.js:66`)
|
|
```js
|
|
{ path: 'meetings/detail/:meetingId', name: 'manager-meetings-detail',
|
|
component: () => import('@/views/manager/MeetingDetail.vue'),
|
|
meta: { title: '会议详情' } },
|
|
```
|
|
|
|
#### A.2.3 `Meetings.vue` 删 dialog 改跳页面 (367 → 220 行)
|
|
- `onView(row)` → `viewDetail(row)`, 内部 `router.push(/manager/meetings/detail/${row.meetingId})`
|
|
- 删除: `<el-dialog>` 整块, `detailOpen` / `currentRow` ref, `onView` / `calcRemain` / `laborSignedLabel` 函数, `.meeting-detail-dialog` 系列样式, 3 个 icon imports
|
|
|
|
#### A.2.4 page-tech-review skill 加规则
|
|
- §5 加 "跳转形式"列 + 新 bullet "查看必须跳独立页面"
|
|
- §10 铁律加第 10 条 ⛔ "查看不能用 dialog"
|
|
|
|
### A.3 v1 报告 §9 #1 错误的反思
|
|
|
|
**根本原因**: v1 审查时, **未严格按 SKILL §6 流程实测 DB**, 是基于"猜测"+"部分代码阅读"得出错误结论。
|
|
- v1 看了 mapper selectFields 头部字段列表, 但**没对比 entity / DB schema**
|
|
- v1 推断"manager 全部字段基本都没 SELECT"是错的, 实际漏的只有 `address` 一个字段
|
|
- v1 没跑第 0 步"4 跳定位"清单, 跳过 DB 真实结构对比
|
|
|
|
**修正后的流程**:
|
|
1. §0 4 跳定位 (AdminLayout → router → 组件 → 原型)
|
|
2. §6.1 DB 实测 (SHOW CREATE TABLE) — 必须先做
|
|
3. §6.2 列三层穿透矩阵 (DB ↔ Entity ↔ Mapper SELECT ↔ Vue 渲染)
|
|
4. §6.3 任何字段缺失要列出真因 (DB 漏 / entity 漏 / mapper 漏 / Vue 漏)
|
|
5. §6.4 单独列"dead field"和"富余字段", 区分真丢失 vs 故意不显示
|
|
|
|
**记入 memory**: [feedback-report-scope-gaps] 升级 — 审查报告不能"差不多就行", 数据结构穿透必须 4 跳齐全 + DB 实测, **不实测就标"漏字段"是误导**。
|