Files
platforms/docs/操作日志_用户端APP_合同附件下载_20260908.md
czl231 3ef33b531d 已完成用户APP首期功能开发
交付用户端首期页面、配套接口、后台资源及测试文档。用户APP构建、静态分析和三个管理后台构建通过;完整测试仍有2项失败,后端模型注释检查未通过,详见交付记录。
2026-09-13 00:57:32 +08:00

43 lines
5.7 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.
# 合同附件下载开发记录
## 2026-09-08浏览器成功路径补验
新增`backend/api/internal/logic/client/user/gas_contract_download_remote_test.go`:默认跳过,显式设置HEQI_CONTRACT_DOWNLOAD_FIXTURE=1和当前API文件根目录时,为授权测试账号创建一条独立的已终止测试合同及测试PDF,不修改任何既有合同。最长等待5分钟,收到完成标记或超时均清理独立记录与文件;普通单元测试不连接远程。强制终止进程无法保证defer执行,禁止用强杀结束该夹具。
实际验证已通过:浏览器从个人中心进入供气合同,点击“PDF下载验证文件(非业务合同)”的下载按钮,真实鉴权接口返回200,浏览器在Downloads生成619字节PDF。下载文件与服务端原文件SHA-256均为`D5B86BEB045675F863B06D9B75A60FBCEC4E09E8E9CA7543E599672A40AC3820`。PDF经Poppler识别为单页A4、PDF1.4,无JavaScript,已渲染并目视确认“DOWNLOAD TEST ONLY - NOT A BUSINESS CONTRACT”。Poppler报告本机Symbol/ArialUnicode显示字体不可用,但验证页使用Helvetica,文字完整;文件长度以Get-Item和哈希校验为准。
测试夹具运行84.42秒后PASS;再次读取真实接口仅剩原MOCK-CONTRACT-001,测试合同数0,服务端测试PDF不存在。Downloads中的测试副本已转存到验收证据并清理原下载位置。相关Go用户逻辑测试与vet通过,无生产代码改动,无需重建既有App产物。
证据:[实际下载PDF](视觉验收/A1/合同下载_浏览器测试.pdf)、[下载PDF渲染](视觉验收/A1/合同下载_浏览器测试.png)。**Web下载成功路径已验证;Android/iOS系统保存对话框仍待真机验收。** 原业务合同仍缺附件,不能将本测试文件作为其签署附件。以下保留上一轮实施记录。
操作时间:2026-09-08。操作类型:扩展。影响模块:本人合同、受控PDF文件输出及本地保存。
## 行为变化与关键代码
- backend/api/internal/logic/client/user/gas_contract_attachment.go:新增DownloadGasContractAttachment,GET gas/contracts/:identity/attachment限定JWT本人且未归档合同,不接受路径或外部URL。
- backend/api/internal/logic/platform/gasorder/contract_attachment.go:抽取ServeAuthorizedContractPDF供已经完成鉴权的调用方复用,保留平台原入口。继续验证合同存储前缀、根目录边界、文件类型与10MiB限制,响应private/no-store、nosniff、sandbox;不公开存储路径。
- backend/api/internal/routers/client.go及client_test.go:新增受保护附件路由与存在性回归。
- apps/user_app/lib/data/services/api_client.dart:getBytes新增可选Accept参数,旧图片调用兼容。
- apps/user_app/lib/data/repositories/client_repository.dart:gasContractPdf校验会话、缺失、大小及%PDF-文件头,错误JSON不能当PDF保存。
- apps/user_app/lib/ui/features/orders/contract_download_button.dart:读取完成后交给系统保存;防重复点击、文件名清理、取消不报成功、失败可重试。错误原因持续显示在按钮下方并通过liveRegion播报,重试时清除;Web只提示已交给浏览器下载,不声称浏览器已完成落盘。
- gas_contracts_page.dart、gas_order_sections.dart:合同列表与正文均可下载,常规宽度与查看按钮并排,窄屏大字体分行。
- pubspec.yaml/lock:新增file_saver 0.4.0(带dio、dio_web_adapter);保留原依赖约束,使用字节保存,不把鉴权令牌或服务端私有路径传给插件。参考[插件官方文档](https://pub.dev/packages/file_saver)。
## 测试与当前证据
后端gas_contract_attachment_test.go覆盖本人实际文件字节、外部URL拒绝、越界拒绝、文件缺失、非本人合同以及响应头。平台原附件测试、用户逻辑与路由回归通过;Go全量测试、vet及API构建通过。Flutter新增gas_contract_pdf_test.dart与contract_download_button_test.dart,覆盖缺失、错误JSON、迟到会话、失败重试和系统取消。analyze与全量102项测试通过,正文入口增加按钮后两项详情回归通过。
图32的8组布局截图已更新,实际查看390普通截图确认查看与下载按钮并排;窄屏大字体按宽度自动分行。平台资源契约同步及检查48项通过。
Web Release与Android Debug构建通过,新增插件已参与构建;Android仍有既有Kotlin迁移警告,未阻断产物。合同卡片以identity作为稳定Key,筛选或刷新移除卡片时销毁该下载状态,避免迟到请求在另一份合同卡片上继续保存。
远程既有MOCK-CONTRACT-001没有可读取附件,真实GET返回404,匿名请求401。本轮没有修改远程合同、没有生成冒充业务合同的PDF,也没有更改数据库或缓存配置。真实业务PDF成功保存和Android/iOS系统保存对话框仍需有附件的受控测试数据及设备验收,不能用单元测试替代这项结论。
最终浏览器版本已点击真实合同的下载按钮,显示持续错误“合同附件暂不可用,请联系供气单位补充”,按钮恢复可重试。最终Web和Android再次构建通过;持续错误反馈的UI回归通过。当前API进程40192,Web端口18571。
## 维护与风险
服务端导出的ServeAuthorizedContractPDF要求调用者先完成权限校验,禁止直接注册路由。保留10MiB文件上限,避免无界客户端内存下载。系统保存依赖平台支持,取消应保持页面并允许重试;PDF缺失应由供气单位补充,不能从合同正文生成替代签署件。
图32继续部分实现:下载代码已接通,但真实文件保存尚未完成设备验收;签署、家庭共享协议、合同服务和完整视觉仍待补。