质量模块: - 11 张工艺执行书表:封面、试产、选剥茧(含混茧明细)、试缫与大样、煮茧(含分车间配温、副煮车间)、自动缫(含大样)、后缫 - 10 张样茧试缫表:原料小样/综合样主表 + 选茧、解舒、茧幅、切剖、清洁洁净、茧丝百回纤度 - 服务与接口、主控指针回写(列表 √ 标记)、封面编号自增、报表数据包 - 前端 8 张报表打印版式、7 类工艺单据与 6 类调查录入弹窗、字段驱动表单/表格组件 - 菜单种子新增「质量」目录,样茧子表增加 YjssType 判别列,避免原料小样与综合样自增 Id 重号串数据 报表中心: - 报表模板管理、锐浪 grhtml5 加载与预览、全屏设计面板、数据源 Provider(落丝记录、职工花名册) 其他:同步工作进度 1-11 文档、开发数据库快照、.gitignore 忽略运行日志目录
136 lines
7.5 KiB
Markdown
136 lines
7.5 KiB
Markdown
# 工作进度-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. **无模板版本历史**:画布改坏后只能重新生成模板或用设计器重排。
|