新增质量模块(工艺执行书 / 样茧试缫)与报表中心

质量模块:
- 11 张工艺执行书表:封面、试产、选剥茧(含混茧明细)、试缫与大样、煮茧(含分车间配温、副煮车间)、自动缫(含大样)、后缫
- 10 张样茧试缫表:原料小样/综合样主表 + 选茧、解舒、茧幅、切剖、清洁洁净、茧丝百回纤度
- 服务与接口、主控指针回写(列表 √ 标记)、封面编号自增、报表数据包
- 前端 8 张报表打印版式、7 类工艺单据与 6 类调查录入弹窗、字段驱动表单/表格组件
- 菜单种子新增「质量」目录,样茧子表增加 YjssType 判别列,避免原料小样与综合样自增 Id 重号串数据

报表中心:
- 报表模板管理、锐浪 grhtml5 加载与预览、全屏设计面板、数据源 Provider(落丝记录、职工花名册)

其他:同步工作进度 1-11 文档、开发数据库快照、.gitignore 忽略运行日志目录
This commit is contained in:
yanpeng200212
2026-10-22 10:30:37 +08:00
parent 8c4c464362
commit a8890c81e9
92 changed files with 14785 additions and 70 deletions
+135
View File
@@ -0,0 +1,135 @@
# 工作进度-9:报表设计页(可视化画布 + 官方设计器入口 + 本系统保存)
> 时间:2026-10-20(承接工作进度-8)
> 触发:用户希望「做一个页面,嵌入 Grid++Report 7 的设计页面,并加上本系统的保存按钮」
---
## 一、结论:官方设计器无法嵌入网页
先确认事实,避免做出错误承诺:
| 检查项 | 结果 |
|---|---|
| `web/public/grlib/grhtml5-7-min.js` 是否含设计器 API(`insertReportDesigner` 等) | ❌ 无,只有 `insertReportViewer` |
| `D:\GridReport7` 安装目录 | 只有查看器库、`gr7designer64.exe`(Win32 桌面程序)、`gr7webapp64.exe`(打印客户端)、`server\gr7svr*.dll`(服务端生成 DLL) |
| `D:\GridReport7\Samples\Web`(html / vue / asp.net / jsp) | 只有 HTML5 查看器示例,无网页设计器 |
原因:GR7 的设计器是 WinForms/Win32 程序,浏览器无法 iframe 内嵌,也没有 ActiveX/JS 设计器接口。
因此本页提供两条**可用**的设计路径,并在同一页面里放了本系统的「保存模板」按钮:
| 路径 | 排版能力 | 产物格式 | 本页能力 |
|---|---|---|---|
| A. 页面内可视化画布(自研) | 中(页眉/标题/参数行/明细列/页脚/边距/列宽) | JSON(`6.8.5.0`) | 直接编辑 + 保存 |
| B. 唤起本机锐浪 7 设计器 | 强(官方全功能:分组/合计/图表/条码/套打) | `_WR7_` 压缩文本 | 关闭设计器自动回传,本页自动重载 |
> 关键取舍:用官方设计器保存后模板变成 `_WR7_` 压缩文本,**网页画布无法再解析**(只能看真实预览、原样保存、继续用设计器)。页面在唤起设计器前会明确提示这一点。
---
## 二、页面
### 2.1 路由(静态注册,不依赖菜单权限)
`web/src/router/index.js`:
```js
{ path: 'report/design/:id', name: 'ReportDesign',
component: () => import('../views/report/design/index.vue'),
meta: { title: '报表设计', icon: 'Edit' } }
```
入口:
- 报表管理页列表行「设计」
- 报表编辑器顶栏「设计页」
新增文件:`web/src/views/report/design/index.vue`。
### 2.2 页面结构
```
┌ 返回管理 | 报表名 编号 [JSON/_WR7_] [未保存] 撤销 重新载入 真实预览 上传 下载 [锐浪7设计器] [保存模板] ┐
├ 左(画布,自适应缩放 + 10% 档位缩放) │ 右(属性面板) │
│ A4 白纸:页眉 → 报表头(标题/参数行)→ 明细网格 → 页脚 │ 明细列 / 报表标题 / │
│ 表头单元格可点选,右边缘拖拽改列宽(cm 实时写回模板) │ 页眉页脚 / 行高边距 │
└────────────────────────────────────────────────────────────────────┴──────────────────────────┘
```
### 2.3 画布渲染(只读近似 + 真实数据)
- 单位:模板里的 `Left/Top/Width/Height` 是 **cm**,`Font.Size` 是 **1/10000 pt**;画布按 `1cm = 37.795px` 换算,再用 `transform: scale()` 适配容器
- 版块顺序与 GR 一致:`PageHeader` → `ReportHeader[]`(逐节)→ `DetailGrid`(表头 + 数据行)→ `PageFooter`
- 文本替换:
- `[#{报表参数}#]` → `/sys/report/{id}/preview` 返回的 `Parameter[0]` 实际值
- `[#SystemVar(PageNumber)#] / PageCount / CurrentDateTime` → 示例值
- 明细行取 `preview.data.recordset` 前 8 行;无数据时渲染 3 行空行占位,保证排版可见
- 画布上的控件 hover 有虚线框,方便确认位置;真正的字体/边距是否精确以「真实预览」为准
### 2.4 可编辑项(写回模板 JSON)
| 面板 | 修改的节点 | 说明 |
|---|---|---|
| 明细列 · 列标题 | `DetailGrid.ColumnTitle.ColumnTitleCell[].Text` | 缺节点时自动补 |
| 明细列 · 列宽 | `DetailGrid.Column[].Width` | 数字框或画布拖拽,0.4–14cm |
| 明细列 · 添加/删除 | `Recordset.Field` / `Column` / `ColumnContentCell` / `ColumnTitleCell` | 四处同步增删,避免结构不一致 |
| 报表标题 | 报表头第一节里字号最大的文本控件 `Text` + 顶层 `Title` | 找不到控件时给出提示 |
| 标题字号 | 该控件 `Font.Size` | 6–36pt |
| 页眉/页脚 | `PageHeader/PageFooter.Control[].Text` | 逐控件文本框 |
| 页眉/页脚高度 | `PageHeader/PageFooter.Height` | 0–10cm |
| 行高 / 表头高 | `ColumnContent.Height` / `ColumnTitle.Height` | 0.3–4cm |
| 上下边距 | `Printer.TopMargin / BottomMargin` | 0–6cm |
**只改已知且我们已在用、能被 GR 正确识别的键**,不写未知属性(例如单元格对齐、合并、边框),避免模板被 GR 判为损坏。分组、合计、图表、条码等请用官方设计器。
### 2.5 保存
复用工作进度-8 新增的接口,不改后端:
```
PUT /api/sys/report/{id}/template/content { "content": "<JSON 文本>" }
```
- 保存前序列化 `JSON.stringify(doc, null, '\t')`;服务端做 JSON 语法校验后落库
- 有未保存修改时顶栏显示红色「未保存」,离开页面会二次确认
- `撤销修改` = 重新解析已入库文本
### 2.6 真实预览 / 上传下载 / 官方设计器
- **真实预览**:全屏弹窗内用官方 `rubylong.grhtml5.insertReportViewer` 渲染(模板 URL 带 `_t` 时间戳防缓存);有未保存修改时提示「预览的是已保存模板」
- **上传 .grf / 下载 .grf**:复用既有接口
- **锐浪 7 设计器**:
```
f9designer://open?base=<origin>&rid=<id>&token=<jwt>&code=<报表编号>
```
由 `tools/report-designer/F9ReportDesignerHandler.ps1` 处理:下载模板 → 启动 `gr7designer64.exe` → 关闭后自动 `POST /{id}/template` 回传
本页在 `window.focus` 后延迟 2s 自动重新载入模板(也有「重新载入」按钮兜底)
### 2.7 `_WR7_` / 非 JSON 模板兜底
- 检测到 `_WR` 前缀:不渲染画布,显示说明和三个入口(真实预览 / 用设计器修改 / 去模板源码页)
- JSON 解析失败:显示错误 + 引导上传或去源码页修复
---
## 三、验证
| 项 | 结果 |
|---|---|
| Vite 编译 `views/report/design/index.vue`(请求 `http://localhost:5173/src/views/report/design/index.vue`) | ✅ HTTP 200(SFC 编译通过) |
| 同法验证 `ReportEditor.vue` / `manage/index.vue` / `router/index.js` | ✅ HTTP 200 |
| IDE 诊断(4 个改动文件) | ✅ 0 |
| 后端 | 未改动(复用 `PUT /template/content`),无需重新编译 |
| 浏览器实操(登录点一遍) | ⚠ 未执行:当前环境无 node / playwright-cli,无法自动化;Vite 已确认可编译,建议人工点一遍 |
> 保存模板需要后端已重启(工作进度-8 的接口)。
---
## 四、遗留
1. **`_WR7_` 无解码器**:用过官方设计器后画布失效,这是格式决定的;若要两者兼得,需要锐浪的 `decodeWR` 算法或官方提供 JSON 导出。
2. **画布不是 100% 像素级还原**:字体度量、单元格对齐、自动行高与 GR 有差异,最终以「真实预览」为准。
3. **未支持控件级拖拽/属性编辑**:位置 `Left/Top`、边框、颜色、对齐暂不开放,避免写入未经验证的键。
4. **样本数据依赖 `/preview`**:需要参数才能出数的报表会显示空行占位;后续可加「手工填参数再取样本」。
5. **无模板版本历史**:画布改坏后只能重新生成模板或用设计器重排。