@qilitt-mickey/vue3-temp-skill 1.1.74 → 1.1.76
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/SKILL.md +137 -137
- package/mapping/basic/color.json +35 -35
- package/mapping/basic/radius.json +17 -17
- package/mapping/basic/semantic-values.json +72 -72
- package/mapping/basic/spacing.json +21 -21
- package/mapping/basic/typography.json +21 -21
- package/mapping/component/button.json +90 -90
- package/mapping/component/card.json +31 -31
- package/mapping/component/input.json +42 -42
- package/mapping/component/overlay.json +79 -79
- package/mapping/component/pagination.json +34 -34
- package/mapping/component/table.json +42 -42
- package/mapping/component/tag.json +48 -48
- package/mapping/layout/breakpoint.json +20 -20
- package/mapping/scenes/admin/content.json +497 -494
- package/mapping/scenes/admin/layout.json +577 -574
- package/package.json +1 -1
- package/parser/fixtures/changeset-legacy.json +11 -11
- package/parser/fixtures/changeset-neg1.json +8 -8
- package/parser/fixtures/changeset-neg2.json +10 -10
- package/parser/fixtures/changeset-neg3.json +22 -22
- package/parser/fixtures/changeset-neg5-g8-stub.json +26 -26
- package/parser/fixtures/changeset-neg7-g10-dims.json +57 -57
- package/parser/fixtures/changeset-neg9-g6-token-chain.json +34 -0
- package/parser/fixtures/changeset-pos-g6-token-chain.json +35 -0
- package/parser/fixtures/changeset-pos-theme-nometa.json +260 -260
- package/parser/fixtures/changeset-registry-gap.json +29 -29
- package/parser/fixtures/fake-project/src/styles/app.scss +5 -5
- package/parser/fixtures/fake-project/src/views/list.vue +13 -13
- package/parser/fixtures/registry-bad.json +11 -11
- package/parser/fixtures/registry-g6-token-chain.json +10 -0
- package/parser/fixtures/verify/actual-clean.json +35 -35
- package/parser/fixtures/verify/actual.json +33 -33
- package/parser/fixtures/verify/mockup-g6-content.html +12 -0
- package/parser/fixtures/verify/mockup-neutral.html +26 -26
- package/parser/fixtures/verify/mockup-nometa.html +26 -26
- package/parser/fixtures/verify/snapshot-latest.json +102 -102
- package/parser/index.js +32 -1
- package/parser/loader.js +66 -66
- package/parser/validator.js +206 -206
- package/references/auth-pages.md +217 -217
- package/references/base-code-dict.md +56 -56
- package/references/data-compare.md +509 -509
- package/references/data-writeback.md +124 -124
- package/references/design-apply.md +167 -167
- package/references/detail-page.md +119 -119
- package/references/download-export.md +97 -97
- package/references/feedback-loading.md +104 -104
- package/references/feedback-ui.md +134 -134
- package/references/i18n-localization.md +230 -230
- package/references/layout-theme.md +2 -0
- package/references/project-inventory.md +438 -438
- package/references/rich-text.md +94 -94
- package/references/seamless-scroll.md +47 -47
- package/references/steps/step0-preflight.md +58 -58
- package/references/steps/step1-match.md +5 -2
- package/references/steps/step3-style.md +38 -33
- package/references/steps/step3b-shell.md +2 -0
- package/references/steps/step3c-priority.md +26 -26
- package/references/steps/step4-l3.md +14 -14
- package/references/steps/step5-gates.md +65 -63
- package/references/steps/step6-verify.md +77 -77
- package/references/verify-captcha.md +119 -119
- package/scripts/check.mjs +24 -0
- package/scripts/design-audit.mjs +208 -3
|
@@ -1,119 +1,119 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: detail-page
|
|
3
|
-
description: 列表→独立路由详情/编辑/查看。路由 meta、toDetail 写顶部 tag、activePath 保侧栏高亮、initToDetail。
|
|
4
|
-
scope: project
|
|
5
|
-
tags: [vue3, detail, toDetail, useDetail, activePath, showLink, multiTags, keepAlive]
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# 详情页 / 编辑页跳转
|
|
9
|
-
|
|
10
|
-
权威性优先级:模版 `useDetail.ts`、`multiTags`、侧栏 `NavVertical`。列表打开独立路由页时按本文件落地。
|
|
11
|
-
|
|
12
|
-
**反认知偏差(必读)**:`toDetail` 只负责写顶部 tag 并跳转;**侧栏高亮靠 `meta.activePath`,缓存/多开靠 `meta.keepAlive` / `moreTags`**。三者缺一不可,禁止只写 `toDetail`。
|
|
13
|
-
|
|
14
|
-
## 详情三件套(标准样板 · 整段照抄再改名)
|
|
15
|
-
|
|
16
|
-
缺任一段 = 未完成。样板内字段**默认全部写出**(勿改成 `//` 注释再「按需打开」)。仅当业务明确不要缓存/多开时,才删掉对应行。
|
|
17
|
-
|
|
18
|
-
### ① 兄弟路由 meta
|
|
19
|
-
|
|
20
|
-
```typescript
|
|
21
|
-
{
|
|
22
|
-
path: "/customer/detail",
|
|
23
|
-
name: "CustomerDetail",
|
|
24
|
-
component: () => import("@/views/customer/detail/index.vue"),
|
|
25
|
-
meta: {
|
|
26
|
-
title: "客户详情",
|
|
27
|
-
showLink: false,
|
|
28
|
-
activePath: "/customer/list",
|
|
29
|
-
keepAlive: true,
|
|
30
|
-
moreTags: true,
|
|
31
|
-
},
|
|
32
|
-
},
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
### ② 列表页打开
|
|
36
|
-
|
|
37
|
-
```typescript
|
|
38
|
-
import { useDetail } from "@/hooks/useDetail";
|
|
39
|
-
const { toDetail } = useDetail();
|
|
40
|
-
|
|
41
|
-
toDetail("CustomerDetail", { webId: "0" }, "(新增)");
|
|
42
|
-
toDetail(
|
|
43
|
-
"CustomerDetail",
|
|
44
|
-
{ id: row.id, text: row.name, mark: "edit" },
|
|
45
|
-
`(编辑)【${row.name}】`,
|
|
46
|
-
);
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
### ③ 详情页初始化
|
|
50
|
-
|
|
51
|
-
```vue
|
|
52
|
-
<script setup lang="ts">
|
|
53
|
-
import { useDetail } from "@/hooks/useDetail";
|
|
54
|
-
defineOptions({ name: "CustomerDetail" });
|
|
55
|
-
const { initToDetail, getParameter } = useDetail();
|
|
56
|
-
initToDetail("CustomerDetail");
|
|
57
|
-
const { id, mark } = getParameter as DetailParameter;
|
|
58
|
-
</script>
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
### ④ 详情页容器(滚动约定)
|
|
62
|
-
|
|
63
|
-
详情 / 编辑 / 查看页是**长内容页**,滚动交给壳层 `.app-main` 内 `el-scrollbar`。**禁止**根节点使用 `vts-page-fill` / `h-full` / `overflow-hidden`(那是定高画布专用)。
|
|
64
|
-
|
|
65
|
-
```vue
|
|
66
|
-
<template>
|
|
67
|
-
<div
|
|
68
|
-
v-loading.lock="pageLoading"
|
|
69
|
-
class="bg-bg_color p-5"
|
|
70
|
-
:style="{ minHeight: '100%' }"
|
|
71
|
-
>
|
|
72
|
-
<ReHeaderPage />
|
|
73
|
-
<!-- 表单 / 描述 / 版本记录等 -->
|
|
74
|
-
</div>
|
|
75
|
-
</template>
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
| 禁止 | 原因 |
|
|
79
|
-
|------|------|
|
|
80
|
-
| `class="vts-page-fill"` | 触发定高链,内容被裁切、外层滚不动 |
|
|
81
|
-
| `h-full` + `overflow-hidden` | 把超出内容锁死在视口内 |
|
|
82
|
-
| `el-card.vts-page-card` 包整页长表单 | 列表定高卡专用;详情走外层滚动 |
|
|
83
|
-
|
|
84
|
-
完整布局原理见 `layout-theme`「内容区高度与滚动」;列表页见 `crud-pages`。
|
|
85
|
-
|
|
86
|
-
## 概念
|
|
87
|
-
|
|
88
|
-
| 能力 | 字段 / API | 谁负责 |
|
|
89
|
-
|------|------------|--------|
|
|
90
|
-
| 不进左侧菜单 | `meta.showLink: false` | 路由 |
|
|
91
|
-
| 顶部 tag | `toDetail` → `handleTags('push')` | Hook |
|
|
92
|
-
| 侧栏高亮 | `meta.activePath` = 列表 path | 路由 |
|
|
93
|
-
| 页面缓存 / 多开 | `meta.keepAlive` + `moreTags: true` | 路由 |
|
|
94
|
-
|
|
95
|
-
`showLink` 只管侧栏是否显示,不控制顶部 tag。裸 `router.push` 只换路由、不写 tag。
|
|
96
|
-
|
|
97
|
-
| 字段 | 要求 |
|
|
98
|
-
|------|------|
|
|
99
|
-
| `title` | 非空 |
|
|
100
|
-
| `showLink: false` | 必填 |
|
|
101
|
-
| `activePath` | = 列表 path(必填) |
|
|
102
|
-
| `keepAlive` / `moreTags` | 默认 `true`;不要缓存/多开再删 |
|
|
103
|
-
| `name` | = `defineOptions({ name })` |
|
|
104
|
-
|
|
105
|
-
```typescript
|
|
106
|
-
toDetail(name, parameter, title?, model = "query") // model: "query" | "params"
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
写入 tag 时不要把路由上的 `showLink: false` 原样塞进 `handleTags` 的 meta。
|
|
110
|
-
|
|
111
|
-
`initToDetail` 标题:无 id → `(新增)`;`mark==='edit'` → `(编辑)【text】`;`view` → `(查看)【text】`。
|
|
112
|
-
|
|
113
|
-
## Must-do
|
|
114
|
-
|
|
115
|
-
1. 三件套整段落盘(路由 + `toDetail` + `initToDetail`)
|
|
116
|
-
2. `showLink: false` + `activePath` + 非空 `title` + 默认 `keepAlive`/`moreTags`
|
|
117
|
-
3. 列表只用 `toDetail`,禁止裸 `router.push`
|
|
118
|
-
4. 详情页必调 `initToDetail`;`name` 对齐;参数用 `getParameter`
|
|
119
|
-
5. 详情根容器:`min-height: 100%` + `bg-bg_color`;**禁止** `vts-page-fill` / `h-full` / `overflow-hidden`
|
|
1
|
+
---
|
|
2
|
+
name: detail-page
|
|
3
|
+
description: 列表→独立路由详情/编辑/查看。路由 meta、toDetail 写顶部 tag、activePath 保侧栏高亮、initToDetail。
|
|
4
|
+
scope: project
|
|
5
|
+
tags: [vue3, detail, toDetail, useDetail, activePath, showLink, multiTags, keepAlive]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# 详情页 / 编辑页跳转
|
|
9
|
+
|
|
10
|
+
权威性优先级:模版 `useDetail.ts`、`multiTags`、侧栏 `NavVertical`。列表打开独立路由页时按本文件落地。
|
|
11
|
+
|
|
12
|
+
**反认知偏差(必读)**:`toDetail` 只负责写顶部 tag 并跳转;**侧栏高亮靠 `meta.activePath`,缓存/多开靠 `meta.keepAlive` / `moreTags`**。三者缺一不可,禁止只写 `toDetail`。
|
|
13
|
+
|
|
14
|
+
## 详情三件套(标准样板 · 整段照抄再改名)
|
|
15
|
+
|
|
16
|
+
缺任一段 = 未完成。样板内字段**默认全部写出**(勿改成 `//` 注释再「按需打开」)。仅当业务明确不要缓存/多开时,才删掉对应行。
|
|
17
|
+
|
|
18
|
+
### ① 兄弟路由 meta
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
{
|
|
22
|
+
path: "/customer/detail",
|
|
23
|
+
name: "CustomerDetail",
|
|
24
|
+
component: () => import("@/views/customer/detail/index.vue"),
|
|
25
|
+
meta: {
|
|
26
|
+
title: "客户详情",
|
|
27
|
+
showLink: false,
|
|
28
|
+
activePath: "/customer/list",
|
|
29
|
+
keepAlive: true,
|
|
30
|
+
moreTags: true,
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### ② 列表页打开
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
import { useDetail } from "@/hooks/useDetail";
|
|
39
|
+
const { toDetail } = useDetail();
|
|
40
|
+
|
|
41
|
+
toDetail("CustomerDetail", { webId: "0" }, "(新增)");
|
|
42
|
+
toDetail(
|
|
43
|
+
"CustomerDetail",
|
|
44
|
+
{ id: row.id, text: row.name, mark: "edit" },
|
|
45
|
+
`(编辑)【${row.name}】`,
|
|
46
|
+
);
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### ③ 详情页初始化
|
|
50
|
+
|
|
51
|
+
```vue
|
|
52
|
+
<script setup lang="ts">
|
|
53
|
+
import { useDetail } from "@/hooks/useDetail";
|
|
54
|
+
defineOptions({ name: "CustomerDetail" });
|
|
55
|
+
const { initToDetail, getParameter } = useDetail();
|
|
56
|
+
initToDetail("CustomerDetail");
|
|
57
|
+
const { id, mark } = getParameter as DetailParameter;
|
|
58
|
+
</script>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### ④ 详情页容器(滚动约定)
|
|
62
|
+
|
|
63
|
+
详情 / 编辑 / 查看页是**长内容页**,滚动交给壳层 `.app-main` 内 `el-scrollbar`。**禁止**根节点使用 `vts-page-fill` / `h-full` / `overflow-hidden`(那是定高画布专用)。
|
|
64
|
+
|
|
65
|
+
```vue
|
|
66
|
+
<template>
|
|
67
|
+
<div
|
|
68
|
+
v-loading.lock="pageLoading"
|
|
69
|
+
class="bg-bg_color p-5"
|
|
70
|
+
:style="{ minHeight: '100%' }"
|
|
71
|
+
>
|
|
72
|
+
<ReHeaderPage />
|
|
73
|
+
<!-- 表单 / 描述 / 版本记录等 -->
|
|
74
|
+
</div>
|
|
75
|
+
</template>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
| 禁止 | 原因 |
|
|
79
|
+
|------|------|
|
|
80
|
+
| `class="vts-page-fill"` | 触发定高链,内容被裁切、外层滚不动 |
|
|
81
|
+
| `h-full` + `overflow-hidden` | 把超出内容锁死在视口内 |
|
|
82
|
+
| `el-card.vts-page-card` 包整页长表单 | 列表定高卡专用;详情走外层滚动 |
|
|
83
|
+
|
|
84
|
+
完整布局原理见 `layout-theme`「内容区高度与滚动」;列表页见 `crud-pages`。
|
|
85
|
+
|
|
86
|
+
## 概念
|
|
87
|
+
|
|
88
|
+
| 能力 | 字段 / API | 谁负责 |
|
|
89
|
+
|------|------------|--------|
|
|
90
|
+
| 不进左侧菜单 | `meta.showLink: false` | 路由 |
|
|
91
|
+
| 顶部 tag | `toDetail` → `handleTags('push')` | Hook |
|
|
92
|
+
| 侧栏高亮 | `meta.activePath` = 列表 path | 路由 |
|
|
93
|
+
| 页面缓存 / 多开 | `meta.keepAlive` + `moreTags: true` | 路由 |
|
|
94
|
+
|
|
95
|
+
`showLink` 只管侧栏是否显示,不控制顶部 tag。裸 `router.push` 只换路由、不写 tag。
|
|
96
|
+
|
|
97
|
+
| 字段 | 要求 |
|
|
98
|
+
|------|------|
|
|
99
|
+
| `title` | 非空 |
|
|
100
|
+
| `showLink: false` | 必填 |
|
|
101
|
+
| `activePath` | = 列表 path(必填) |
|
|
102
|
+
| `keepAlive` / `moreTags` | 默认 `true`;不要缓存/多开再删 |
|
|
103
|
+
| `name` | = `defineOptions({ name })` |
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
toDetail(name, parameter, title?, model = "query") // model: "query" | "params"
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
写入 tag 时不要把路由上的 `showLink: false` 原样塞进 `handleTags` 的 meta。
|
|
110
|
+
|
|
111
|
+
`initToDetail` 标题:无 id → `(新增)`;`mark==='edit'` → `(编辑)【text】`;`view` → `(查看)【text】`。
|
|
112
|
+
|
|
113
|
+
## Must-do
|
|
114
|
+
|
|
115
|
+
1. 三件套整段落盘(路由 + `toDetail` + `initToDetail`)
|
|
116
|
+
2. `showLink: false` + `activePath` + 非空 `title` + 默认 `keepAlive`/`moreTags`
|
|
117
|
+
3. 列表只用 `toDetail`,禁止裸 `router.push`
|
|
118
|
+
4. 详情页必调 `initToDetail`;`name` 对齐;参数用 `getParameter`
|
|
119
|
+
5. 详情根容器:`min-height: 100%` + `bg-bg_color`;**禁止** `vts-page-fill` / `h-full` / `overflow-hidden`
|
|
@@ -1,97 +1,97 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: download-export
|
|
3
|
-
description: 导出/下载必须带 responseType blob,使用 blobDown 或项目已有下载工具
|
|
4
|
-
scope: project
|
|
5
|
-
tags: [导出, excel, blob, 下载文件, 下载, 导出Excel]
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# 下载与导出
|
|
9
|
-
|
|
10
|
-
> 按本文件示例编写,复用项目已有下载/导出工具与封装,勿另起一套文件流处理。
|
|
11
|
-
|
|
12
|
-
规范文件下载、模板下载、文件流导出与附件预览。在需要下载文件、导出表格或预览附件时参照。
|
|
13
|
-
|
|
14
|
-
**完整性守则**:导出/下载 API **必须**带 `responseType: "blob"`(默认写出,勿当可选项注释掉);前端用 `blobDown` / 项目已有 `download*`,禁止手写 `URL.createObjectURL` 另起一套(除非仓库无封装)。
|
|
15
|
-
|
|
16
|
-
## 强制样板(导出)
|
|
17
|
-
|
|
18
|
-
```typescript
|
|
19
|
-
// api
|
|
20
|
-
export function exportExcel(data: Recordable) {
|
|
21
|
-
return http.request<Result<Blob>>(
|
|
22
|
-
"post",
|
|
23
|
-
`${import.meta.env.VITE_API_BASE_URL}/xxx/export`,
|
|
24
|
-
{ data },
|
|
25
|
-
{ responseType: "blob" },
|
|
26
|
-
);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// 页面
|
|
30
|
-
const res = await exportExcel(params);
|
|
31
|
-
blobDown(res.data, "导出.xlsx", res);
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
## 常用工具
|
|
35
|
-
|
|
36
|
-
项目集成了 `@pureadmin/utils` 与自定义工具:
|
|
37
|
-
|
|
38
|
-
```typescript
|
|
39
|
-
import {
|
|
40
|
-
downloadByBase64,
|
|
41
|
-
downloadByData,
|
|
42
|
-
downloadByOnlineUrl,
|
|
43
|
-
downloadByUrl,
|
|
44
|
-
} from "@pureadmin/utils";
|
|
45
|
-
|
|
46
|
-
import { download, blobDown, downloadAttachment } from "@/utils/utils";
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
## 文件流下载
|
|
50
|
-
|
|
51
|
-
接口返回 Blob 时:
|
|
52
|
-
|
|
53
|
-
```typescript
|
|
54
|
-
import { blobDown } from "@/utils/utils";
|
|
55
|
-
|
|
56
|
-
const res = await exportExcel(params);
|
|
57
|
-
blobDown(res.data, "导出.xlsx", res);
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
若后端在 `content-disposition` 中返回文件名,可自动解析。
|
|
61
|
-
|
|
62
|
-
## 模板下载
|
|
63
|
-
|
|
64
|
-
```typescript
|
|
65
|
-
import { download } from "@/utils/utils";
|
|
66
|
-
|
|
67
|
-
await download("user-template");
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
后端返回 Blob,前端自动下载为 `user-template.xlsx`。
|
|
71
|
-
|
|
72
|
-
## 在线地址/图片下载
|
|
73
|
-
|
|
74
|
-
```typescript
|
|
75
|
-
// 在线图片
|
|
76
|
-
downloadByOnlineUrl("https://xxx.com/a.png", "a.png");
|
|
77
|
-
|
|
78
|
-
// 普通文件
|
|
79
|
-
downloadByUrl("https://xxx.com/file.zip", "file.zip");
|
|
80
|
-
|
|
81
|
-
// base64 图片
|
|
82
|
-
downloadByBase64(base64String, "a.png");
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
## 附件下载
|
|
86
|
-
|
|
87
|
-
```typescript
|
|
88
|
-
import { downloadAttachment } from "@/utils/utils";
|
|
89
|
-
|
|
90
|
-
downloadAttachment("https://xxx.com/file.pdf", "file.pdf");
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
## 关键约定
|
|
94
|
-
|
|
95
|
-
1. 导出文件名优先从响应头解析,其次前端指定。
|
|
96
|
-
2. 大文件导出需显示 loading。
|
|
97
|
-
3. 下载失败时给用户明确提示。
|
|
1
|
+
---
|
|
2
|
+
name: download-export
|
|
3
|
+
description: 导出/下载必须带 responseType blob,使用 blobDown 或项目已有下载工具
|
|
4
|
+
scope: project
|
|
5
|
+
tags: [导出, excel, blob, 下载文件, 下载, 导出Excel]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# 下载与导出
|
|
9
|
+
|
|
10
|
+
> 按本文件示例编写,复用项目已有下载/导出工具与封装,勿另起一套文件流处理。
|
|
11
|
+
|
|
12
|
+
规范文件下载、模板下载、文件流导出与附件预览。在需要下载文件、导出表格或预览附件时参照。
|
|
13
|
+
|
|
14
|
+
**完整性守则**:导出/下载 API **必须**带 `responseType: "blob"`(默认写出,勿当可选项注释掉);前端用 `blobDown` / 项目已有 `download*`,禁止手写 `URL.createObjectURL` 另起一套(除非仓库无封装)。
|
|
15
|
+
|
|
16
|
+
## 强制样板(导出)
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
// api
|
|
20
|
+
export function exportExcel(data: Recordable) {
|
|
21
|
+
return http.request<Result<Blob>>(
|
|
22
|
+
"post",
|
|
23
|
+
`${import.meta.env.VITE_API_BASE_URL}/xxx/export`,
|
|
24
|
+
{ data },
|
|
25
|
+
{ responseType: "blob" },
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// 页面
|
|
30
|
+
const res = await exportExcel(params);
|
|
31
|
+
blobDown(res.data, "导出.xlsx", res);
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## 常用工具
|
|
35
|
+
|
|
36
|
+
项目集成了 `@pureadmin/utils` 与自定义工具:
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
import {
|
|
40
|
+
downloadByBase64,
|
|
41
|
+
downloadByData,
|
|
42
|
+
downloadByOnlineUrl,
|
|
43
|
+
downloadByUrl,
|
|
44
|
+
} from "@pureadmin/utils";
|
|
45
|
+
|
|
46
|
+
import { download, blobDown, downloadAttachment } from "@/utils/utils";
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## 文件流下载
|
|
50
|
+
|
|
51
|
+
接口返回 Blob 时:
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
import { blobDown } from "@/utils/utils";
|
|
55
|
+
|
|
56
|
+
const res = await exportExcel(params);
|
|
57
|
+
blobDown(res.data, "导出.xlsx", res);
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
若后端在 `content-disposition` 中返回文件名,可自动解析。
|
|
61
|
+
|
|
62
|
+
## 模板下载
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
import { download } from "@/utils/utils";
|
|
66
|
+
|
|
67
|
+
await download("user-template");
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
后端返回 Blob,前端自动下载为 `user-template.xlsx`。
|
|
71
|
+
|
|
72
|
+
## 在线地址/图片下载
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
// 在线图片
|
|
76
|
+
downloadByOnlineUrl("https://xxx.com/a.png", "a.png");
|
|
77
|
+
|
|
78
|
+
// 普通文件
|
|
79
|
+
downloadByUrl("https://xxx.com/file.zip", "file.zip");
|
|
80
|
+
|
|
81
|
+
// base64 图片
|
|
82
|
+
downloadByBase64(base64String, "a.png");
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## 附件下载
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
import { downloadAttachment } from "@/utils/utils";
|
|
89
|
+
|
|
90
|
+
downloadAttachment("https://xxx.com/file.pdf", "file.pdf");
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## 关键约定
|
|
94
|
+
|
|
95
|
+
1. 导出文件名优先从响应头解析,其次前端指定。
|
|
96
|
+
2. 大文件导出需显示 loading。
|
|
97
|
+
3. 下载失败时给用户明确提示。
|
|
@@ -1,104 +1,104 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: feedback-loading
|
|
3
|
-
description: Message、Loading、MessageBox、NoticeBar 反馈和加载
|
|
4
|
-
scope: project
|
|
5
|
-
tags: [message, loading, 确认框, 提示, 加载, 操作反馈, 骨架屏, skeleton]
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# 反馈与 Loading
|
|
9
|
-
|
|
10
|
-
> 按本文件示例编写,复用项目已有 Message / Loading / MessageBox 封装,勿另起一套提示方案。
|
|
11
|
-
|
|
12
|
-
规范系统 Loading、Message、MessageBox、NoticeBar 等反馈组件的使用。在需要提示用户或阻塞操作时参照。
|
|
13
|
-
|
|
14
|
-
**完整性守则**:删除/危险操作**默认写出** `ElMessageBox.confirm`;列表请求接 `v-loading`;提交默认 `loading` 防重复。提示文案一律 `$t()`。
|
|
15
|
-
|
|
16
|
-
## 强制样板(删除确认)
|
|
17
|
-
|
|
18
|
-
```typescript
|
|
19
|
-
import { ElMessageBox } from "element-plus";
|
|
20
|
-
import { message } from "@/utils/message";
|
|
21
|
-
|
|
22
|
-
async function onDelete(row: { id: string }) {
|
|
23
|
-
await ElMessageBox.confirm($t("确定删除吗?"), $t("温馨提醒"), {
|
|
24
|
-
confirmButtonText: $t("确定"),
|
|
25
|
-
cancelButtonText: $t("取消"),
|
|
26
|
-
type: "warning",
|
|
27
|
-
});
|
|
28
|
-
// await deleteApi({ id: row.id })
|
|
29
|
-
message($t("删除成功"), { type: "success" });
|
|
30
|
-
}
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
## Loading
|
|
34
|
-
|
|
35
|
-
### 局部 Loading
|
|
36
|
-
|
|
37
|
-
```vue
|
|
38
|
-
<el-card v-loading.lock="loading" :element-loading-spinner="svgLoading">
|
|
39
|
-
<!-- 内容 -->
|
|
40
|
-
</el-card>
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
### 全屏 Loading
|
|
44
|
-
|
|
45
|
-
```vue
|
|
46
|
-
<el-button v-loading.lock.fullscreen="fullLoading" @click="submit">
|
|
47
|
-
保存
|
|
48
|
-
</el-button>
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
### 获取系统统一 Loading SVG
|
|
52
|
-
|
|
53
|
-
```typescript
|
|
54
|
-
import { useApp } from "@/hooks/useApp";
|
|
55
|
-
|
|
56
|
-
const { svgLoading } = useApp();
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
## Message
|
|
60
|
-
|
|
61
|
-
使用 `src/utils/message.ts` 封装函数:
|
|
62
|
-
|
|
63
|
-
```typescript
|
|
64
|
-
import { message, closeAllMessage } from "@/utils/message";
|
|
65
|
-
|
|
66
|
-
message("操作成功", { type: "success" });
|
|
67
|
-
message("警告信息", { type: "warning", duration: 3000 });
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
默认 `duration: 5000`、`grouping: true`、`plain: true`。
|
|
71
|
-
|
|
72
|
-
## MessageBox
|
|
73
|
-
|
|
74
|
-
```typescript
|
|
75
|
-
import { ElMessageBox } from "element-plus";
|
|
76
|
-
|
|
77
|
-
ElMessageBox.confirm($t("确定删除吗?"), $t("温馨提醒"), {
|
|
78
|
-
confirmButtonText: $t("确定"),
|
|
79
|
-
cancelButtonText: $t("取消"),
|
|
80
|
-
type: "warning",
|
|
81
|
-
});
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
## ReNoticeBar 通知栏
|
|
85
|
-
|
|
86
|
-
落点:`src/components/ReNoticeBar`。长文本滚动 / 可关闭提示,用于页内公告条。
|
|
87
|
-
|
|
88
|
-
```vue
|
|
89
|
-
<script setup lang="ts">
|
|
90
|
-
import ReNoticeBar from "@/components/ReNoticeBar";
|
|
91
|
-
</script>
|
|
92
|
-
|
|
93
|
-
<template>
|
|
94
|
-
<ReNoticeBar :text="$t('系统将于今晚维护,请提前保存数据')" />
|
|
95
|
-
</template>
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
Props / 行为以组件源码为准;颜色走主题令牌,禁止业务写死提示条背景 hex。
|
|
99
|
-
|
|
100
|
-
## 关键约定
|
|
101
|
-
|
|
102
|
-
1. 所有提示文案使用 `$t()`。
|
|
103
|
-
2. 长耗时操作显示 loading,避免用户重复点击。
|
|
104
|
-
3. 表单提交失败调用 `checkReeorPosition()` 定位错误项。
|
|
1
|
+
---
|
|
2
|
+
name: feedback-loading
|
|
3
|
+
description: Message、Loading、MessageBox、NoticeBar 反馈和加载
|
|
4
|
+
scope: project
|
|
5
|
+
tags: [message, loading, 确认框, 提示, 加载, 操作反馈, 骨架屏, skeleton]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# 反馈与 Loading
|
|
9
|
+
|
|
10
|
+
> 按本文件示例编写,复用项目已有 Message / Loading / MessageBox 封装,勿另起一套提示方案。
|
|
11
|
+
|
|
12
|
+
规范系统 Loading、Message、MessageBox、NoticeBar 等反馈组件的使用。在需要提示用户或阻塞操作时参照。
|
|
13
|
+
|
|
14
|
+
**完整性守则**:删除/危险操作**默认写出** `ElMessageBox.confirm`;列表请求接 `v-loading`;提交默认 `loading` 防重复。提示文案一律 `$t()`。
|
|
15
|
+
|
|
16
|
+
## 强制样板(删除确认)
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
import { ElMessageBox } from "element-plus";
|
|
20
|
+
import { message } from "@/utils/message";
|
|
21
|
+
|
|
22
|
+
async function onDelete(row: { id: string }) {
|
|
23
|
+
await ElMessageBox.confirm($t("确定删除吗?"), $t("温馨提醒"), {
|
|
24
|
+
confirmButtonText: $t("确定"),
|
|
25
|
+
cancelButtonText: $t("取消"),
|
|
26
|
+
type: "warning",
|
|
27
|
+
});
|
|
28
|
+
// await deleteApi({ id: row.id })
|
|
29
|
+
message($t("删除成功"), { type: "success" });
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Loading
|
|
34
|
+
|
|
35
|
+
### 局部 Loading
|
|
36
|
+
|
|
37
|
+
```vue
|
|
38
|
+
<el-card v-loading.lock="loading" :element-loading-spinner="svgLoading">
|
|
39
|
+
<!-- 内容 -->
|
|
40
|
+
</el-card>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### 全屏 Loading
|
|
44
|
+
|
|
45
|
+
```vue
|
|
46
|
+
<el-button v-loading.lock.fullscreen="fullLoading" @click="submit">
|
|
47
|
+
保存
|
|
48
|
+
</el-button>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### 获取系统统一 Loading SVG
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
import { useApp } from "@/hooks/useApp";
|
|
55
|
+
|
|
56
|
+
const { svgLoading } = useApp();
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Message
|
|
60
|
+
|
|
61
|
+
使用 `src/utils/message.ts` 封装函数:
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
import { message, closeAllMessage } from "@/utils/message";
|
|
65
|
+
|
|
66
|
+
message("操作成功", { type: "success" });
|
|
67
|
+
message("警告信息", { type: "warning", duration: 3000 });
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
默认 `duration: 5000`、`grouping: true`、`plain: true`。
|
|
71
|
+
|
|
72
|
+
## MessageBox
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
import { ElMessageBox } from "element-plus";
|
|
76
|
+
|
|
77
|
+
ElMessageBox.confirm($t("确定删除吗?"), $t("温馨提醒"), {
|
|
78
|
+
confirmButtonText: $t("确定"),
|
|
79
|
+
cancelButtonText: $t("取消"),
|
|
80
|
+
type: "warning",
|
|
81
|
+
});
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## ReNoticeBar 通知栏
|
|
85
|
+
|
|
86
|
+
落点:`src/components/ReNoticeBar`。长文本滚动 / 可关闭提示,用于页内公告条。
|
|
87
|
+
|
|
88
|
+
```vue
|
|
89
|
+
<script setup lang="ts">
|
|
90
|
+
import ReNoticeBar from "@/components/ReNoticeBar";
|
|
91
|
+
</script>
|
|
92
|
+
|
|
93
|
+
<template>
|
|
94
|
+
<ReNoticeBar :text="$t('系统将于今晚维护,请提前保存数据')" />
|
|
95
|
+
</template>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Props / 行为以组件源码为准;颜色走主题令牌,禁止业务写死提示条背景 hex。
|
|
99
|
+
|
|
100
|
+
## 关键约定
|
|
101
|
+
|
|
102
|
+
1. 所有提示文案使用 `$t()`。
|
|
103
|
+
2. 长耗时操作显示 loading,避免用户重复点击。
|
|
104
|
+
3. 表单提交失败调用 `checkReeorPosition()` 定位错误项。
|