Files
F9Web/AI开发日志/2026-08-15.md
T

136 lines
12 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.
# F9 智慧缫丝系统 —— CodeBuddy 持续工作存档
> 本文件为 CodeBuddy 开发日志归档(每日一份),归档日期:2026-08-15。
> 新对话开始后:先读本文件 + `功能清单` + `项目说明`,按「任务状态」继续推进,无需重新调研。
最后更新:2026-08-15
---
## 一、任务状态总览(按用户约定的优先级 1→2→3)
| 序号 | 任务 | 状态 | 说明 |
|---|---|---|---|
| 1 | 通用打印接入主前端 | 🔄 **进行中(方案已定,代码未写)** | 三步:后端取行数据接口 → openprint 外部打印模式 → web 打印按钮 |
| 2 | 简易工作流(采购/领料审批闭环) | ⏳ 待做 | 4 张表已有,缺服务+API+前端审批 UI |
| 3 | 专业业务逻辑(自动定级/能耗分摊/成本盈亏/断料预警) | ⏳ 待做 | 依赖任务 1/2 部分能力 |
已完成的里程碑:
- ✅ 动态 CRUD 体系(后端 EntityCatalog + CrudService + DataController,前端 CrudPage + table-map 配置驱动)
- ✅ openprint 打印设计器全链路(模板设计→数据源内省→预览/打印,推 PDF 到本地客户端)
- ✅ 工作台接真实数据(WorkBenchController + workbench/index.vue 重写)
---
## 二、项目架构速查
### 2.1 三端结构
| 端 | 目录 | 技术栈 | 端口 | 说明 |
|---|---|---|---|---|
| PC 前端 | `web/` | Vue3 + Element Plus + ECharts + Pinia | vite dev 5173 | 代理 `/api` → localhost:5136 |
| 后端 | `server/` | .NET 10 + FreeSql (v3.5.311) | 5136 | MySQL 云库 `f9web`116.198.221.105 |
| 打印设计器 | `openprint/` | Vue3 + Naive UI + Vite | 5227 | 对接 F9 的 `PrintApiController`,推 PDF(base64) 到本地客户端 `127.0.0.1:18888` |
| 电视大屏 / 小程序 | — | — | — | 未开始(按项目说明先完成 PC 端) |
### 2.2 后端关键约定
- **表命名**:模块前缀 + 下划线,如 `CRM_Customer``RawMaterial_Instock``Common_Workflow``RepCenter_ReportDesign`;实体类同前缀,如 `RawMaterial_Instock`
- **默认字段**`id``flag`0=删除,>0 有效,<0 无效,-1=作废)、`addtime``adder``updatetime``updater``memo`
- **序列化**`Program.cs` 全局 CamelCase + 忽略 null(即 C# 属性 `OrderNo` → JSON `orderNo`)。
- **响应信封**:普通 API 用 `ApiResult`**`PrintApiController``api/print`)返回裸 JSON** `{items,total}`openprint 的 http-client 已按此解析,主前端 axios 也可透传)。
- **动态查询**`DataController``EntityCatalog`(表名→实体 Type 反射映射)+ `CrudService<T>` 泛型反射调用,`GetList/GetById/Add/Update/Delete` 等通用接口。
- **工作流表**(已有,未做服务):`Common_Workflow`(流程定义)/ `Common_WorkflowNode`(节点)/ `Common_WorkflowInstance`(实例)/ `Common_WorkflowTask`(任务,`Status==0` 待办、`UserId` 当前处理人)。
### 2.3 web 前端关键约定
- **Token 存储**localStorage key = **`f9mes_token`**`web/src/stores/user.js``TOKEN_KEY`)。
- **API 封装**`web/src/api/request.js`axios 拦截器注入 Bearer);`web/src/api/index.js` 集中导出(含已新增的 `getWorkBenchSummary`)。
- **配置驱动 CRUD**`web/src/config/table-map.js` 定义每张表的列/表单配置,`web/src/components/CrudPage.vue` 是通用页面组件,菜单由 `InitDataService` 生成。
### 2.4 openprint 关键约定
- **对接开关**`openprint/src/main.ts` 仅当配置 `VITE_OPENPRINT_API_BASE` 时才切换云端仓库(HttpRepository/HttpDataSource);`.env` 中配 `VITE_OPENPRINT_API_BASE` + `VITE_OPENPRINT_API_TOKEN`
- **HttpClient token**:构造时静态传入(`http-client.ts``HttpOptions.token`),**构造后不可变**;若改运行时 token 需改构造时机或加 setter。
- **绑定 Path 约定**:后端 `PrintService.BuildFields` 生成 `Path = "{TableId}.{PropName}"`(如 `RawMaterial_Instock.OrderNo`);openprint 的 `expression.ts`/`data-binder.ts` 按路径取值。**注意**:序列化后 JSON 为 camelCase,而 Path 是 PascalCase,取值器需兼容(大小写不敏感取 key 或按 camelCase 注入)。
- **打印出口**`PrintDialog.vue``doPrint()``store.buildTemplate()` + `buildPreviewData(dsStore.activeFields)``buildPrintPayload({template, data})` → 推本地客户端(POST `/print``127.0.0.1:18888`)。**当前用假数据**,是接入真实数据的关键改造点。
- **数据源内省**`PrintApiController``data-sources`/`fields``PrintService` 按实体类前缀分组(ModuleNames 字典),字段缓存 TTL 10 分钟。
---
## 三、任务 1:通用打印接入主前端(进行中)
### 3.1 目标
表单通用打印:主前端任意 CRUD 列表 → 选中一行 → 选打印模板 → 打开 openprint 用**该行真实数据**打印(针式/A4 均支持,设计器已具备)。
### 3.2 已锁定的三步方案(代码未写,按序实施)
**Step A — 后端:取行数据接口**
- 位置:`PrintApiController.cs` 新增(或新 controller),路由建议 `GET api/print/data/{table}/{id}`
- 实现:基于 `EntityCatalog` 动态取实体 Type → FreeSql 按 `id` 查询单行 → 输出结构匹配绑定 Path:`{ "<TableId>": { "<camelCaseProp>": value, ... } }`(如 `{ "rawMaterial_Instock": { "orderNo": "...", ... } }` 或 PascalCase 表名,需与 PrintService.BuildFields 生成的 Path 前缀一致,建议直接复用 BuildFields 的 TableId)。
- 返回裸 JSON(同 PrintApiController 风格,走 openprint http-client 的 json() 直接拿对象)。
**Step B — openprint:外部打印模式**
- 解析 URL 参数:`?print=1&template=<templateId>&table=<tableId>&row=<rowId>&token=<token>`
- 启动流程(main.ts 或 App.vue):检测 `print=1` 时 → 用 URL 的 token(或 localStorage)替换 HttpClient 的 token → 加载模板(designer store `loadTemplate`)→ 调 `api/print/data/{table}/{row}` 拉真实数据 → 注入到 dataSource store 供 `doPrint` 使用(如新增 `externalData` 状态,`PrintDialog.doPrint()` 优先用它替代 `buildPreviewData`)→ 自动打开打印弹窗。
- 注意:`designer.ts``loadTemplate({id,name,data})`/`buildTemplate()`/`setRepository()`/`restoreLastTemplate()``dataSource.ts``activeFields` 决定字段列表;只读模式下应隐藏设计工具栏(TopToolbar 需加 `readonly`/`external` 模式判断)。
- token:主前端 web 存于 localStorage `f9mes_token`openprint 与 web 同源部署时可直接读;跨端口时用 URL 传 token 更稳(注意 URL 长度与泄露,内网 MES 可接受)。
**Step C — webCrudPage 打印按钮**
- `CrudPage.vue` 工具栏加「打印」按钮(选中一行时可用)→ 弹窗列出该表可用模板(调 `api/print/templates``tableId` 过滤)→ 确认后 `window.open` openprint 打印 URL`http://localhost:5227/?print=1&template={id}&table={tableName}&row={rowId}&token={token}`
- 需要后端提供"按表过滤模板"的能力(`PrintApiController.templates` 若支持 tableId 查询则直接用,否则加参数)。
### 3.3 关键文件清单
- 后端:`server/src/F9MES.Api/Controllers/PrintApiController.cs``server/src/F9MES.Application/Print/PrintService.cs``server/src/F9MES.Api/Common/EntityCatalog.cs``server/src/F9MES.Api/Controllers/DataController.cs`
- openprint`src/main.ts``src/App.vue``src/config/backend.ts``src/repository/http-client.ts`token 构造点)、`src/design/stores/designer.ts`loadTemplate)、`src/design/stores/dataSource.ts``src/design/modals/PrintDialog.vue`doPrint)、`src/design/toolbar/TopToolbar.vue`showPrint 挂载)、`src/design/preview/preview-data.ts`buildPreviewData)、`src/core/layout-engine/expression.ts` + `data-binder.ts`(取值)
- web`src/components/CrudPage.vue``src/api/index.js``src/config/table-map.js``src/stores/user.js`token
---
## 四、任务 2:简易工作流(待做)
- 现状:4 张表(Common_Workflow/Node/Instance/Task)已有,`WorkBenchController` 已统计 `Common_WorkflowTask`Status==0 && UserId==当前用户)为待办。
- 要做:
1. 后端:工作流服务(流程定义 CRUD、节点配置、发起实例、提交/审批/驳回/撤回流转)、API(建议 `api/workflow/...`)。
2. 前端:审批中心页面(我的待办、我发起的、流程配置);在采购单、领料申请等表单接审批。
3. 关联:任务 1 打印对审批单据同样适用。
---
## 五、任务 3:专业业务逻辑(待做)
按优先级从高到低建议:
1. **断料预警**(原料库存超期/不足,工作台预警列表已预留位置)
2. **自动定级**(Lims 检验数据 → 调用定级标准自动判定生丝等级,标准表需先建/已有则复用)
3. **能耗分摊**(Enms 抄表 → 按投料量/产量/机台时长分摊到庄口 → 推成本)
4. **成本盈亏**(BizBoss 生产成本分摊 + 分庄口盈亏统计)
---
## 六、工程实践与坑位(必读)
1. **编译锁定**:后端进程运行时 DLL 被锁,`dotnet build` 会报 MSB3027/MSB3021 → 用 `dotnet build -o build_tmp` 验证编译,完成后删临时目录;**改动后端必须重启服务才生效**。
2. **FreeSql 陷阱**:非空 DateTime 没有 `.HasValue`;空集合时 `.Where(x => ids.Contains(...))` 会生成非法 SQL,需先 `if (list.Count > 0)` 守卫。
3. **JSON 大小写**:后端全局 camelCaseopenprint 绑定 Path 是 PascalCase,取值需兼容。
4. **openprint 是独立应用**:改动它用 `npm run dev`(端口 5227)独立调试;主前端 web 是 vite dev5173)。
5. 数据库连接(项目说明):MySQL `116.198.221.105``f9web` 用户 `f9web`;阿里云 OSSbbit-f9-web);天气用 Open-Meteo。
6. 项目要求:类/文件命名带模块前缀、各模块类放各自文件夹、公共类放 Common;界面 MES 风格、高可配置、表单必须支持打印、表单带简易工作流。
---
## 七、本轮对话已完成的工作(2026-08 中旬)
### 7.1 工作台真实数据(已完成 ✅)
- 新增 `server/src/F9MES.Api/Controllers/WorkBenchController.cs``GET api/workbench/summary`,聚合统计卡(今日产丝=ProHou_Daily.OutputWeight 合计、在线机组=ProQian_Machine 启用且运行、待办=工单+工作流待办、预警数)+ 近 30 天趋势 + 庄口占比 + 待办列表(工单/审批)+ 预警列表。
- `web/src/api/index.js`:新增 `getWorkBenchSummary`
- `web/src/views/workbench/index.vue`:重写,4 统计卡/趋势折线/庄口占比饼图/待办与预警列表全部接真实数据,无数据时占位,保留天气+快捷入口。
- 已用 `-o build_tmp` 验证编译通过;**需重启后端生效**。
### 7.2 openprint 全链路调研(已完成,结论见第三节)
已通读:PrintApiController / PrintService / EntityCatalog / DataController / http-repo / http-datasource / http-client / backend.ts / main.ts / App.vue / TopToolbar / PrintDialog / designer store / dataSource store / preview-data / expression / data-binder / CrudPage / table-map / request.js / user store / 两端 vite 配置。结论已沉淀到第三节。
---
## 八、下一步行动(新对话从这里开始)
1. 先读本文件 + `功能清单` + `项目说明`(若工作区未加载)。
2.**3.2 的 Step A → B → C** 依次实施任务 1(打印接入),每步完成后用 `dotnet build -o build_tmp` / `npm run build` 验证,openprint 与 web 可分别 `npm run dev` 联调。
3. 完成后再推进任务 2(简易工作流)。
4. 任何大改动前更新本文件「最后更新」日期与任务状态。