@qilitt-mickey/vue3-temp-skill 1.0.12 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +66 -214
- package/SKILL.md +165 -527
- package/package.json +2 -2
- package/references/api-check.md +187 -128
- package/references/base-code-dict.md +49 -48
- package/references/chart-echarts.md +61 -0
- package/references/code-quality.md +44 -15
- package/references/core-kernel.md +305 -0
- package/references/crud-pages.md +87 -261
- package/references/data-compare.md +502 -501
- package/references/data-mapping.md +218 -213
- package/references/data-screen.md +94 -79
- package/references/data-writeback.md +104 -104
- package/references/detail-page.md +100 -99
- package/references/directives-advanced.md +27 -4
- package/references/download-export.md +70 -68
- package/references/feedback-loading.md +62 -60
- package/references/feedback-ui.md +125 -111
- package/references/file-management.md +28 -7
- package/references/flowchart-g6.md +249 -244
- package/references/form-advanced.md +264 -26
- package/references/graph-relation.md +12 -7
- package/references/http-api.md +138 -103
- package/references/icons.md +326 -0
- package/references/layout-theme.md +1 -1
- package/references/mobile-h5.md +20 -0
- package/references/particles.md +143 -0
- package/references/permission-auth.md +8 -31
- package/references/project-inventory.md +175 -120
- package/references/qrcode-barcode.md +107 -92
- package/references/rich-text.md +85 -73
- package/references/seamless-scroll.md +40 -38
- package/references/table-vxe.md +114 -0
- package/references/tree-table.md +2 -1
- package/references/ui-components.md +5 -1
- package/references/verify-captcha.md +110 -96
- package/references/websocket-realtime.md +2 -1
- package/references/wechat-js.md +58 -0
- package/references/workflow-bpmn.md +207 -206
- package/references/advanced-ui.md +0 -302
- package/references/build-optim.md +0 -282
- package/references/vue-core.md +0 -209
|
@@ -1,104 +1,104 @@
|
|
|
1
|
-
# 数据回写与编辑
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
|
21
|
-
|
|
22
|
-
| `
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
- [src/
|
|
104
|
-
- [src/
|
|
1
|
+
# 数据回写与编辑
|
|
2
|
+
|
|
3
|
+
> 按本文件示例编写,复用项目已有回显/回填约定与选择器回写方式,勿另起一套表单赋值实现。
|
|
4
|
+
|
|
5
|
+
## 表单回显
|
|
6
|
+
|
|
7
|
+
### 新增/编辑页
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
async function getDetail() {
|
|
11
|
+
const { id } = getParameter.value
|
|
12
|
+
if (!id) return
|
|
13
|
+
const res = await getDetailApi({ id })
|
|
14
|
+
Object.assign(formData, res.data)
|
|
15
|
+
}
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### 选择类组件回填
|
|
19
|
+
|
|
20
|
+
| 组件 | 回填方式 |
|
|
21
|
+
|------|---------|
|
|
22
|
+
| `ReSelectQuery` | 传 `edit-data` 属性 |
|
|
23
|
+
| `el-tree-select` | 传 `:cache-data` 属性 |
|
|
24
|
+
| `ReCascader` | 直接传 `v-model` 数组 |
|
|
25
|
+
|
|
26
|
+
### 表单重置
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
function reset() {
|
|
30
|
+
formRef.value.resetFields()
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## 表格行编辑
|
|
35
|
+
|
|
36
|
+
表格内编辑时维护行状态,支持备份/恢复:
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
const tableData = ref([])
|
|
40
|
+
|
|
41
|
+
function startEdit(row) {
|
|
42
|
+
row._edit = true
|
|
43
|
+
row._backup = { ...row } // 备份原始数据
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function cancelEdit(row) {
|
|
47
|
+
Object.assign(row, row._backup) // 恢复
|
|
48
|
+
row._edit = false
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function saveEdit(row) {
|
|
52
|
+
// 调用保存接口
|
|
53
|
+
saveRowApi(row).then(() => {
|
|
54
|
+
row._edit = false
|
|
55
|
+
delete row._backup
|
|
56
|
+
})
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## 多表单联合校验
|
|
61
|
+
|
|
62
|
+
页面包含多个表单时,使用 `validateForms` 统一校验:
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
import { validateForms } from '@/utils/utils'
|
|
66
|
+
|
|
67
|
+
const formModulesRef = ref([])
|
|
68
|
+
const formModules = [
|
|
69
|
+
{ refName: 'formA' },
|
|
70
|
+
{ refName: 'formB' },
|
|
71
|
+
]
|
|
72
|
+
|
|
73
|
+
async function handleSubmit() {
|
|
74
|
+
const valid = await validateForms(formModulesRef.value, formModules)
|
|
75
|
+
if (!valid) return
|
|
76
|
+
// 所有表单校验通过,提交数据
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## useFormCheck Hook
|
|
81
|
+
|
|
82
|
+
表单校验聚合,适用于需要监听多个字段校验状态的场景:
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
import { useFormCheck } from '@/hooks/useFormCheck'
|
|
86
|
+
|
|
87
|
+
const { validateStatus, onValidate } = useFormCheck(['field1', 'field2'])
|
|
88
|
+
|
|
89
|
+
// 在 el-form 的 @validate 事件中收集
|
|
90
|
+
// validateStatus 响应式记录各字段的校验结果
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## 关键约定
|
|
94
|
+
|
|
95
|
+
1. 回显时只覆盖表单字段,不破坏响应式结构(使用 `Object.assign` 而非重新赋值)。
|
|
96
|
+
2. 编辑前备份数据(`_backup`),取消时恢复。
|
|
97
|
+
3. 选择类组件回填需同时维护 code 与 name 两个字段。
|
|
98
|
+
4. 多表单校验使用 `validateForms`,不要手动逐个调用 `validate()`。
|
|
99
|
+
5. 提交按钮必须有 `loading` 状态防重复提交。
|
|
100
|
+
|
|
101
|
+
## 关联文件
|
|
102
|
+
|
|
103
|
+
- [src/utils/utils.ts](file:///e:/work/vue3-web-temp/src/utils/utils.ts)
|
|
104
|
+
- [src/hooks/useFormCheck.ts](file:///e:/work/vue3-web-temp/src/hooks/useFormCheck.ts)
|
|
@@ -1,99 +1,100 @@
|
|
|
1
|
-
# 详情页开发
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
toDetail('QueryDetail', { mark: '
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
|
27
|
-
|
|
28
|
-
| `
|
|
29
|
-
| `params.
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
|
56
|
-
|
|
57
|
-
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
1
|
+
# 详情页开发
|
|
2
|
+
|
|
3
|
+
> 按本文件示例编写,复用 `useDetail` 等已有详情跳转约定,勿另起一套传参/回显方式。
|
|
4
|
+
|
|
5
|
+
## useDetail Hook
|
|
6
|
+
|
|
7
|
+
用于列表→详情/新增/编辑页的跳转和参数传递。
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
import { useDetail } from '@/hooks/useDetail'
|
|
11
|
+
|
|
12
|
+
const { toDetail, initToDetail, getParameter } = useDetail()
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## 跳转
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
// 从列表跳详情/编辑/新增
|
|
19
|
+
toDetail('QueryDetail', { id: row.id, mark: 'view', text: row.name })
|
|
20
|
+
toDetail('QueryDetail', { id: row.id, mark: 'edit', text: row.name })
|
|
21
|
+
toDetail('QueryDetail', { mark: 'create', text: '新增数据' })
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### 参数说明
|
|
25
|
+
|
|
26
|
+
| 参数 | 说明 |
|
|
27
|
+
|------|------|
|
|
28
|
+
| `routeName` | 目标路由 `name`(必须与路由配置一致) |
|
|
29
|
+
| `params.id` | 数据唯一标识 |
|
|
30
|
+
| `params.mark` | 状态标识:`edit` / `view` / `create` 或自定义 |
|
|
31
|
+
| `params.text` | 用于拼接标签页标题的文本 |
|
|
32
|
+
|
|
33
|
+
> 数字类型参数跳转前需 `toString()`,因为 `vue-router` 解析后全为字符串。
|
|
34
|
+
|
|
35
|
+
## 详情页初始化
|
|
36
|
+
|
|
37
|
+
```vue
|
|
38
|
+
<script setup lang="ts">
|
|
39
|
+
import { useDetail } from '@/hooks/useDetail'
|
|
40
|
+
|
|
41
|
+
defineOptions({ name: 'QueryDetail' }) // 必须与路由 name 一致
|
|
42
|
+
|
|
43
|
+
const { initToDetail, getParameter } = useDetail()
|
|
44
|
+
initToDetail('QueryDetail')
|
|
45
|
+
|
|
46
|
+
// 获取参数
|
|
47
|
+
const { id, mark, text } = getParameter.value
|
|
48
|
+
</script>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### 标签页标题自动生成
|
|
52
|
+
|
|
53
|
+
`initToDetail` 会根据参数自动生成多标签页标题:
|
|
54
|
+
|
|
55
|
+
| 条件 | 标题 |
|
|
56
|
+
|------|------|
|
|
57
|
+
| 无 `id` | `新增` |
|
|
58
|
+
| `mark === 'edit'` | `编辑【xxx】` |
|
|
59
|
+
| `mark === 'view'` | `查看【xxx】` |
|
|
60
|
+
|
|
61
|
+
## 数据回显
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
async function getDetail() {
|
|
65
|
+
const { id } = getParameter.value
|
|
66
|
+
if (!id) return
|
|
67
|
+
const res = await getDetailApi({ id })
|
|
68
|
+
Object.assign(formData, res.data)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
onMounted(() => {
|
|
72
|
+
getDetail()
|
|
73
|
+
})
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## 非多标签页场景
|
|
77
|
+
|
|
78
|
+
普通详情页直接使用 `getParameter` 获取路由参数:
|
|
79
|
+
|
|
80
|
+
```vue
|
|
81
|
+
<script setup lang="ts">
|
|
82
|
+
import { useDetail } from '@/hooks/useDetail'
|
|
83
|
+
|
|
84
|
+
const { getParameter } = useDetail()
|
|
85
|
+
const route = useRoute()
|
|
86
|
+
const id = route.query.id
|
|
87
|
+
</script>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## 关键约定
|
|
91
|
+
|
|
92
|
+
1. 详情页组件 `name` 必须与路由 `name` 一致,否则标签页标题功能异常。
|
|
93
|
+
2. 通过 `getParameter` 获取 `query` 或 `params` 参数,不要直接用 `useRoute()`。
|
|
94
|
+
3. 表单详情页回显:进入页面后调详情接口,用 `Object.assign(formData, data)` 赋值。
|
|
95
|
+
4. `mark` 字段控制页面编辑态:`view` 禁用表单,`edit` 可编辑,`create` 新增。
|
|
96
|
+
5. 选择类组件回填需同时维护 code 与 name(详见 data-writeback 模块)。
|
|
97
|
+
|
|
98
|
+
## 关联文件
|
|
99
|
+
|
|
100
|
+
- [src/hooks/useDetail.ts](file:///e:/work/vue3-web-temp/src/hooks/useDetail.ts)
|
|
@@ -1,9 +1,32 @@
|
|
|
1
|
-
#
|
|
1
|
+
# 高级自定义指令(复制 / 自适应字号)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> 按本文件示例编写,复用项目已有 `v-copy` / `v-auto-font`,勿另起一套复制或字号自适应实现。
|
|
4
|
+
> 本模块**只**覆盖 `v-copy`、`v-auto-font`。
|
|
5
|
+
> `v-auth` → **permission-auth**;`v-compare` 全套 → **data-compare**。
|
|
6
|
+
> **匹配原则**:用户用自然语言描述体验问题即可;**不要求**用户知道指令名或会写代码。指令名仅供 AI 落码时使用。
|
|
4
7
|
|
|
5
|
-
|
|
6
|
-
|
|
8
|
+
## 何时命中
|
|
9
|
+
|
|
10
|
+
用户描述的是**想要的效果**,不是技术名词。AI 根据语义映射到本模块资产。
|
|
11
|
+
|
|
12
|
+
| 用户可能怎么说(自然语言) | 是否命中 | AI 应使用的资产 |
|
|
13
|
+
|----------------------------|----------|-----------------|
|
|
14
|
+
| 「订单号点一下就能复制」「编号太长不好抄,希望能一键复制」 | ✅ | `v-copy` |
|
|
15
|
+
| 「卡片/表头标题太长显示不下,字能不能跟着变小」「文字别被截断,挤得下就行」 | ✅ | `v-auto-font` |
|
|
16
|
+
| 「删除按钮只有管理员能看见」 | ❌ → `permission-auth` | `v-auth` / `ReAuth` |
|
|
17
|
+
| 「编辑时标出改了哪些字段 / 变更汇总」 | ❌ → `data-compare` | `v-compare` 等 |
|
|
18
|
+
| 「把表格导出成 Excel / 下载一份」 | ❌ → `download-export` | 导出下载 |
|
|
19
|
+
| 「帮我加个自定义指令」(没说要干什么) | ❌ 先追问效果 | — |
|
|
20
|
+
|
|
21
|
+
**推荐用户描述(面向业务/产品,无需懂代码)**:
|
|
22
|
+
|
|
23
|
+
```text
|
|
24
|
+
/vue3-temp-skill 表格里的订单号太长不好抄,希望点一下就能复制
|
|
25
|
+
/vue3-temp-skill 卡片标题经常超长显示不全,希望字号能跟着宽度自动变小
|
|
26
|
+
/vue3-temp-skill 邀请码旁边加个复制按钮,点一下复制成功要有提示
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**AI 内部映射(用户无需写出)**:上述第 1、3 条 → `v-copy`;第 2 条 → `v-auto-font`。
|
|
7
30
|
|
|
8
31
|
## v-copy 复制指令
|
|
9
32
|
|
|
@@ -1,68 +1,70 @@
|
|
|
1
|
-
# 下载与导出
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
downloadAttachment
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
1
|
+
# 下载与导出
|
|
2
|
+
|
|
3
|
+
> 按本文件示例编写,复用项目已有下载/导出工具与封装,勿另起一套文件流处理。
|
|
4
|
+
|
|
5
|
+
规范文件下载、模板下载、文件流导出与附件预览。在需要下载文件、导出表格或预览附件时参照。
|
|
6
|
+
|
|
7
|
+
## 常用工具
|
|
8
|
+
|
|
9
|
+
项目集成了 `@pureadmin/utils` 与自定义工具:
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
import {
|
|
13
|
+
downloadByBase64,
|
|
14
|
+
downloadByData,
|
|
15
|
+
downloadByOnlineUrl,
|
|
16
|
+
downloadByUrl,
|
|
17
|
+
} from "@pureadmin/utils";
|
|
18
|
+
|
|
19
|
+
import { download, blobDown, downloadAttachment } from "@/utils/utils";
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## 文件流下载
|
|
23
|
+
|
|
24
|
+
接口返回 Blob 时:
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { blobDown } from "@/utils/utils";
|
|
28
|
+
|
|
29
|
+
const res = await exportExcel(params);
|
|
30
|
+
blobDown(res.data, "导出.xlsx", res);
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
若后端在 `content-disposition` 中返回文件名,可自动解析。
|
|
34
|
+
|
|
35
|
+
## 模板下载
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
import { download } from "@/utils/utils";
|
|
39
|
+
|
|
40
|
+
await download("user-template");
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
后端返回 Blob,前端自动下载为 `user-template.xlsx`。
|
|
44
|
+
|
|
45
|
+
## 在线地址/图片下载
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
// 在线图片
|
|
49
|
+
downloadByOnlineUrl("https://xxx.com/a.png", "a.png");
|
|
50
|
+
|
|
51
|
+
// 普通文件
|
|
52
|
+
downloadByUrl("https://xxx.com/file.zip", "file.zip");
|
|
53
|
+
|
|
54
|
+
// base64 图片
|
|
55
|
+
downloadByBase64(base64String, "a.png");
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## 附件下载
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
import { downloadAttachment } from "@/utils/utils";
|
|
62
|
+
|
|
63
|
+
downloadAttachment("https://xxx.com/file.pdf", "file.pdf");
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## 关键约定
|
|
67
|
+
|
|
68
|
+
1. 导出文件名优先从响应头解析,其次前端指定。
|
|
69
|
+
2. 大文件导出需显示 loading。
|
|
70
|
+
3. 下载失败时给用户明确提示。
|