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

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

其他:同步工作进度 1-11 文档、开发数据库快照、.gitignore 忽略运行日志目录
2026-10-22 10:30:37 +08:00

134 lines
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 工作进度-8:模板源码在线编辑(免下载 / 上传)
> 时间:2026-10-20(承接工作进度-7)
> 触发:用户提出「能不能直接编辑对应报表的模板文件然后保存,而不是下载 → 改 → 上传 → 保存」
---
## 一、结论
可以。模板本来就以文本存在库里(`sys_report_files.design_content`,TEXT),
之前只是没有「写回文本」的入口,只能整文件上传。本次新增:
- 后端一个接口:`PUT /api/sys/report/{id}/template/content`,请求体 `{ "content": "<模板全文>" }`
- 前端「模板源码」由**只读**改为**可编辑**,配「保存模板 / 格式化 / 撤销修改 / 放大编辑」
原来的「上传 .grf / 下载 .grf」保留不动(用于本机设计器排版、外部模板导入)。
---
## 二、方案取舍
| 方案 | 说明 | 结论 |
|---|---|---|
| 现状:下载 → 本地改 → 上传 | 需要本地装锐浪设计器或文本编辑器,来回一次文件 | 保留,不再作为主路径 |
| **在线编辑模板源码 + 保存** | 文本表单直接改 `.grf` 内容,保存即入库,刷新预览立即生效 | ✅ 本次实现 |
| 内嵌可视化设计器(拖控件、改属性) | 需要对 `.grf` 全量解析 / 回写;GR7 设计器格式是 `_WR` 压缩文本,无解码器 | 不做(见工作进度-5 遗留) |
---
## 三、后端
### 3.1 DTO(`ReportDtos.cs`)
```csharp
public class ReportTemplateContentDto { public string? Content { get; set; } }
```
### 3.2 Service(`IReportService` / `ReportService.SaveTemplateContentAsync`)
```csharp
public async Task<int> SaveTemplateContentAsync(long id, string content)
{
var entity = ... ?? throw new F9NotFoundException("报表不存在");
var text = NormalizeTemplateContent(content); // 去 BOM / trim,空内容拦截
if (head.StartsWith('{') || head.StartsWith('['))
JsonDocument.Parse(text); // JSON 语法校验,失败抛 F9OperationException
await SaveTemplateAsync(entity, text); // 复用「有则更新 ReportFile,无则新建并绑定」
...
return text.Length;
}
```
- 与上传接口走同一套落库逻辑(`SaveTemplateAsync`),因此「新建 / 更新 / 绑定 `report_file_id`」行为一致
- 校验规则:
| 内容形态 | 服务端行为 |
|---|---|
| `{...}` / `[...]`(GR6 JSON 模板) | 语法校验,不合法直接 400「模板 JSON 不合法:…」 |
| `_WR...`(GR7 设计器压缩文本) | 原样保存(无法在服务端校验) |
| 空 / 仅空白 | 400「报表模板内容为空」 |
### 3.3 接口(`SysReportController`)
```
PUT /api/sys/report/{id}/template/content
Body: { "content": "..." }
200 → { code: 200, data: { id, size, hasTemplate: true }, message: "模板已保存" }
404 → 报表不存在 400 → 内容为空 / JSON 不合法
```
与已有接口的关系:
| 方法 | 路由 | 用途 |
|---|---|---|
| GET | `/{id}/template` | 渲染库 / 前端读模板 |
| POST | `/{id}/template` | 上传 .grf 文件(设计器回传) |
| **PUT** | **`/{id}/template/content`** | **在线编辑后保存文本(本次新增)** |
| GET | `/{id}/template/download` | 下载 .grf 给本机设计器 |
---
## 四、前端
### 4.1 `ReportEditor.vue` —— 「模板源码」页
- 去掉 `readonly`;`v-model="templateSource"` 直接编辑
- 新增状态:`templateSaved`(已入库内容,用于判定「未保存」)、`templateSaving`、`wrUnlocked`、`sourceMaximized`
- 工具条:
| 按钮 / 标签 | 行为 |
|---|---|
| `JSON 模板` / `_WR 压缩模板` | 当前模板形态提示 |
| `未保存` | `templateSource !== templateSaved` 时显示 |
| 格式化 | `JSON.parse` + `JSON.stringify(…, '\t')`;非 JSON 禁用 |
| 撤销修改 | 确认后恢复为上次保存内容 |
| 放大编辑 | 整屏弹窗编辑同一份文本(同一 v-model) |
| 保存模板 | 前端先校验 JSON,再 `PUT /sys/report/{id}/template/content` |
- 保存成功后:重新拉取模板 → `hasTemplate = true` → 重置预览(提示点「刷新预览」)→ `emit('saved')`
- 「保存报表」时若模板源码有未保存修改,会先弹确认:`先保存模板` / `忽略模板修改`,避免手改内容被静默丢弃
- `_WR` 压缩模板默认**只读**,需勾「允许编辑」才可改,保存前再二次确认(无本地校验能力)
- 报表未保存时提示「请先保存报表,再编辑模板源码」;已保存但无模板时也可以直接粘贴 JSON 保存(相当于无文件新建模板)
### 4.2 预览缓存
`grhtml5` 拉模板是普通 GET,容易被浏览器缓存。预览 URL 追加 `_t=Date.now()`(编辑器与报表中心都加),保证改完模板点「刷新预览」能看到新内容。
### 4.3 `views/report/manage/index.vue` —— 列表页入口
- 每行新增「编辑模板」:选中该报表并让右侧工作台**直接打开「模板源码」页**(`ReportEditor` 新增 `openSource` prop,配合 `designerKey` 强制重载)
- 「上传模板 / 下载模板」保留
---
## 五、验证
| 项 | 结果 |
|---|---|
| 后端 `dotnet build`(输出到独立目录避开运行中进程锁定) | ✅ 0 错误 |
| `IReportService` / `ReportService` / DTO / Controller 改动 | ✅ 编译通过 |
| 前端 IDE 诊断(`ReportEditor.vue`、`manage/index.vue`、`center/index.vue`) | ✅ 0 诊断 |
| 前端 `npm run build` | ⚠ 当前环境无 node/npm,未执行;需在本机 `cd web && npm run build` 复核 |
> 运行中的 `F9WebAiTest.Api` 仍在用旧程序集,**需重启后端**后新接口才生效。
---
## 六、遗留
1. **无语法高亮 / 行号**:目前是 `el-input textarea`,后续可换 CodeMirror / Monaco(需新增前端依赖)。
2. **无模板历史版本**:手工改坏后无法一键回滚,只能重新「生成模板」或重新上传;建议后续给 `sys_report_files` 加版本表。
3. **`_WR` 仍不能结构化编辑**:需要锐浪的解码 / 编码算法,暂以「允许编辑 + 风险提示」兜底。
4. **保存模板不刷新明细字段 / 报表参数页签**:手改 `DetailGrid.Recordset.Field` 后,左栏字段列表仍是旧值(点「识别明细列与报表参数」可同步)。