feat(frontend): unify attachment management spec and implement fetch+blob download\n\n- Implement forced download via fetch blob, delayed delete etc in repairOrder module\n- Add Attachment Management Unified Standard doctrine to cursorrules-frontend.md so future pages keep consistency\n- Update change log for download preview fix

This commit is contained in:
zlwu committed 2025-07-11 06:36:45 +08:00
1 parent 1540bd1a1b
commit 4ef2208a0c
11 files changed
+1318 -108

No files matched your search

+100
View File
@@ -809,3 +809,103 @@ export default defineConfig({
1. **按钮规范**: 工具栏第一个新增按钮必须使用 `type="primary" plain`,其他按钮使用默认样式
2. **颜色系统**: 使用最新的 Art Design Pro 颜色变量
3. **文档同步**: 代码变更后必须同步更新相关文档
## 4. 附件管理统一规范(强制性)
> 适用范围:所有使用 **Element Plus** + **Vue 3 + TS** 的前端页面(弹窗、新建、编辑、详情、预览等)涉及“附件/文件”功能的模块,必须遵循本规范,以保持 UI 及交互的一致性。
### 4.1 组件结构
| 组件 | 说明 |
|------|------|
| `<el-upload list-type="picture-card">` | 核心上传组件,拖拽 + 点击上传,**单文件最大 10 MB**,**最多 15 个文件** |
| 自定义 `#file` 模板 | 自绘「卡片样式」:缩略图 + 文件名 + 操作按钮组 |
| `<el-button-group>` | 卡片底部操作按钮:下载(success)、删除(danger) |
| 自定义 CSS 类 | `.upload-file-card / thumb / name / actions` 等,详见样式规范 |
### 4.2 功能实现
1. **上传 Upload**
- `auto-upload="true"` + 立即上传
- `accept="image/*,video/*,.pdf,.doc,.docx,.txt"`
- 上传前 (`before-upload`) 校验大小 <10 MB
- 上传成功:
- 新建模式:将返回的 `id` 收集到 `tempAttachmentIds`
- 编辑模式:文件已自动关联到工单
- 上传失败:Element Plus message 提示
2. **下载 Download (强制使用 fetch + blob)**
- 统一函数 `handleDownloadAttachment(file)` / `downloadAttachment(attachment)`
- 流程:`fetch(filePath) → blob → URL.createObjectURL → <a download>`
- 使用 `ElLoading.service()` 显示 *正在下载文件…*
- 下载完成后 `revokeObjectURL` 释放内存
- 解决浏览器对图片/PDF 默认预览导致无法下载的问题
3. **删除 Delete(延迟删除机制)**
- 点击删除 → `proxy.$modal.confirm()` 二次确认
- 已上传文件:只把 `attachment.id` 放入 `pendingDeleteAttachmentIds`,**不立即调用后端**
- 表单保存时统一调用 `deleteAttachment` 批量删除
- 新增未上传文件:直接从 `tempFileList` / `attachmentList` 移除
4. **预览 Preview**
- 判断 `fileType === 'image'` → 使用 `Element Plus ImageViewer` 预览
- 其他类型文件 `window.open(filePath,'_blank')`
- 详情弹窗附件列表同样遵循该预览逻辑
### 4.3 样式规范(SCSS)
```scss
/* 让附件卡片一行展示 4 个 */
:deep(.el-upload-list--picture-card) {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 9px;
margin-top: 12px;
.el-upload-list__item {
width: 166px !important;
min-height: 180px !important;
border-radius: 6px;
overflow: hidden;
}
}
/* 卡片整体布局 */
.upload-file-card {
display: flex;
flex-direction: column;
min-height: 180px;
}
.upload-file-thumb { height: 120px; overflow: hidden; }
.upload-file-name { font-size: 12px; padding: 8px 4px 4px; text-align: center; overflow: hidden; }
.upload-file-card-actions {
padding: 6px 8px;
border-top: 1px solid #f0f0f0;
background: #fafafa;
display: flex; justify-content: center;
}
```
### 4.4 统一变量 & Hook
```ts
const attachmentList = ref<any[]>([]); // el-upload file-list
const tempFileList = ref<File[]>([]); // 新建时未上传的本地文件
const tempAttachmentIds = ref<string[]>([]); // 新建时已上传待关联附件 id
const pendingDeleteAttachmentIds = ref<string[]>([]); // 编辑时标记待删除附件 id
```
### 4.5 集成步骤(页面级)
1. 在 `<script setup>` 引入上述变量 + 上传/下载/删除/预览函数
2. 使用统一的上传组件模板(参考 `web/src/views/hq/pm/repairOrder/index.vue`)
3. 在 *保存/提交* 逻辑中调用 `handlePendingAttachments(orderId)` 处理上传 & 删除
4. 样式直接复制 *样式规范* 中的片段或通过全局样式引入
### 4.6 强制性要求
- **🚨 不得** 在其他页面自定义下载逻辑(必须使用 fetch+blob)
- **🚨 不得** 直接删除附件数据库记录;必须延迟删除
- **🚨 不得** 修改附件卡片 UI 结构及尺寸;需保持一致
- **✅ 必须** 在新页面开发时引用本规范并注明 *附件管理统一规范* 版本
> **版本**: 2025-01-27 附件管理统一规范 v1.0