@qilitt-mickey/vue3-temp-skill 1.1.13 → 1.1.15
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 +16 -4
- package/package.json +1 -1
- package/references/api-check.md +2 -0
- package/references/code-quality.md +31 -10
- package/references/core-kernel.md +21 -18
- package/references/crud-pages.md +35 -13
- package/references/data-writeback.md +13 -0
- package/references/design-handoff.md +248 -30
- package/references/design-system.md +73 -29
- package/references/detail-page.md +43 -33
- package/references/download-export.md +20 -0
- package/references/feedback-loading.md +35 -0
- package/references/flowchart-g6.md +1 -2
- package/references/form-advanced.md +5 -2
- package/references/graph-relation.md +2 -2
- package/references/http-api.md +25 -0
- package/references/icons.md +12 -0
- package/references/layout-theme.md +88 -48
- package/references/permission-auth.md +16 -2
- package/references/project-inventory.md +48 -46
- package/references/ui-components.md +43 -141
|
@@ -9,18 +9,13 @@ tags: [vue3, detail, toDetail, useDetail, activePath, showLink, multiTags, keepA
|
|
|
9
9
|
|
|
10
10
|
真相源:模版 `useDetail.ts`、`multiTags`、侧栏 `NavVertical`。列表打开独立路由页时按本文件落地。
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
**反认知偏差(必读)**:`toDetail` 只负责写顶部 tag 并跳转;**侧栏高亮靠 `meta.activePath`,缓存/多开靠 `meta.keepAlive` / `moreTags`**。三者缺一不可,禁止只写 `toDetail`。
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|------|------------|
|
|
16
|
-
| 不进左侧菜单 | 路由 `meta.showLink: false` |
|
|
17
|
-
| 顶部 tag(multiTags) | `useDetail().toDetail` → `handleTags('push')` |
|
|
18
|
-
| 侧栏高亮 | 路由 `meta.activePath` = 列表 path |
|
|
19
|
-
| 页面缓存 | `meta.keepAlive`;多开 tag 再加 `moreTags: true` |
|
|
14
|
+
## 详情三件套(强制完整样板 · 整段照抄再改名)
|
|
20
15
|
|
|
21
|
-
|
|
16
|
+
缺任一段 = 未完成。样板内字段**默认全部写出**(勿改成 `//` 注释再「按需打开」)。仅当业务明确不要缓存/多开时,才删掉对应行。
|
|
22
17
|
|
|
23
|
-
|
|
18
|
+
### ① 兄弟路由 meta
|
|
24
19
|
|
|
25
20
|
```typescript
|
|
26
21
|
{
|
|
@@ -31,36 +26,27 @@ tags: [vue3, detail, toDetail, useDetail, activePath, showLink, multiTags, keepA
|
|
|
31
26
|
title: "客户详情",
|
|
32
27
|
showLink: false,
|
|
33
28
|
activePath: "/customer/list",
|
|
34
|
-
|
|
35
|
-
|
|
29
|
+
keepAlive: true,
|
|
30
|
+
moreTags: true,
|
|
36
31
|
},
|
|
37
32
|
},
|
|
38
33
|
```
|
|
39
34
|
|
|
40
|
-
|
|
41
|
-
|------|------|
|
|
42
|
-
| `title` | 非空 |
|
|
43
|
-
| `showLink: false` | 必填 |
|
|
44
|
-
| `activePath` | = 列表 path |
|
|
45
|
-
| `name` | = `defineOptions({ name })` |
|
|
46
|
-
|
|
47
|
-
## 列表打开
|
|
35
|
+
### ② 列表页打开
|
|
48
36
|
|
|
49
37
|
```typescript
|
|
50
38
|
import { useDetail } from "@/hooks/useDetail";
|
|
51
39
|
const { toDetail } = useDetail();
|
|
52
40
|
|
|
53
41
|
toDetail("CustomerDetail", { webId: "0" }, "(新增)");
|
|
54
|
-
toDetail(
|
|
42
|
+
toDetail(
|
|
43
|
+
"CustomerDetail",
|
|
44
|
+
{ id: row.id, text: row.name, mark: "edit" },
|
|
45
|
+
`(编辑)【${row.name}】`,
|
|
46
|
+
);
|
|
55
47
|
```
|
|
56
48
|
|
|
57
|
-
|
|
58
|
-
toDetail(name, parameter, title?, model = "query") // model: "query" | "params"
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
写入 tag 时不要把路由上的 `showLink: false` 原样塞进 `handleTags` 的 meta。
|
|
62
|
-
|
|
63
|
-
## 详情页
|
|
49
|
+
### ③ 详情页初始化
|
|
64
50
|
|
|
65
51
|
```vue
|
|
66
52
|
<script setup lang="ts">
|
|
@@ -72,12 +58,36 @@ const { id, mark } = getParameter as DetailParameter;
|
|
|
72
58
|
</script>
|
|
73
59
|
```
|
|
74
60
|
|
|
75
|
-
|
|
61
|
+
## 概念
|
|
62
|
+
|
|
63
|
+
| 能力 | 字段 / API | 谁负责 |
|
|
64
|
+
|------|------------|--------|
|
|
65
|
+
| 不进左侧菜单 | `meta.showLink: false` | 路由 |
|
|
66
|
+
| 顶部 tag | `toDetail` → `handleTags('push')` | Hook |
|
|
67
|
+
| 侧栏高亮 | `meta.activePath` = 列表 path | 路由 |
|
|
68
|
+
| 页面缓存 / 多开 | `meta.keepAlive` + `moreTags: true` | 路由 |
|
|
69
|
+
|
|
70
|
+
`showLink` 只管侧栏是否显示,不控制顶部 tag。裸 `router.push` 只换路由、不写 tag。
|
|
71
|
+
|
|
72
|
+
| 字段 | 要求 |
|
|
73
|
+
|------|------|
|
|
74
|
+
| `title` | 非空 |
|
|
75
|
+
| `showLink: false` | 必填 |
|
|
76
|
+
| `activePath` | = 列表 path(必填) |
|
|
77
|
+
| `keepAlive` / `moreTags` | 默认 `true`;不要缓存/多开再删 |
|
|
78
|
+
| `name` | = `defineOptions({ name })` |
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
toDetail(name, parameter, title?, model = "query") // model: "query" | "params"
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
写入 tag 时不要把路由上的 `showLink: false` 原样塞进 `handleTags` 的 meta。
|
|
85
|
+
|
|
86
|
+
`initToDetail` 标题:无 id → `(新增)`;`mark==='edit'` → `(编辑)【text】`;`view` → `(查看)【text】`。
|
|
76
87
|
|
|
77
88
|
## Must-do
|
|
78
89
|
|
|
79
|
-
1.
|
|
80
|
-
2.
|
|
81
|
-
3.
|
|
82
|
-
4.
|
|
83
|
-
5. 需缓存 / 多开时配 `keepAlive` / `moreTags`
|
|
90
|
+
1. 三件套整段落盘(路由 + `toDetail` + `initToDetail`)
|
|
91
|
+
2. `showLink: false` + `activePath` + 非空 `title` + 默认 `keepAlive`/`moreTags`
|
|
92
|
+
3. 列表只用 `toDetail`,禁止裸 `router.push`
|
|
93
|
+
4. 详情页必调 `initToDetail`;`name` 对齐;参数用 `getParameter`
|
|
@@ -4,6 +4,26 @@
|
|
|
4
4
|
|
|
5
5
|
规范文件下载、模板下载、文件流导出与附件预览。在需要下载文件、导出表格或预览附件时参照。
|
|
6
6
|
|
|
7
|
+
**抗略读**:导出/下载 API **必须**带 `responseType: "blob"`(默认写出,勿当可选项注释掉);前端用 `blobDown` / 项目已有 `download*`,禁止手写 `URL.createObjectURL` 另起一套(除非仓库无封装)。
|
|
8
|
+
|
|
9
|
+
## 强制样板(导出)
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
// api
|
|
13
|
+
export function exportExcel(data: Recordable) {
|
|
14
|
+
return http.request<Result<Blob>>(
|
|
15
|
+
"post",
|
|
16
|
+
`${import.meta.env.VITE_API_BASE_URL}/xxx/export`,
|
|
17
|
+
{ data },
|
|
18
|
+
{ responseType: "blob" },
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// 页面
|
|
23
|
+
const res = await exportExcel(params);
|
|
24
|
+
blobDown(res.data, "导出.xlsx", res);
|
|
25
|
+
```
|
|
26
|
+
|
|
7
27
|
## 常用工具
|
|
8
28
|
|
|
9
29
|
项目集成了 `@pureadmin/utils` 与自定义工具:
|
|
@@ -4,6 +4,25 @@
|
|
|
4
4
|
|
|
5
5
|
规范系统 Loading、Message、MessageBox、NoticeBar 等反馈组件的使用。在需要提示用户或阻塞操作时参照。
|
|
6
6
|
|
|
7
|
+
**抗略读**:删除/危险操作**默认写出** `ElMessageBox.confirm`;列表请求接 `v-loading`;提交默认 `loading` 防重复。提示文案一律 `$t()`。
|
|
8
|
+
|
|
9
|
+
## 强制样板(删除确认)
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
import { ElMessageBox } from "element-plus";
|
|
13
|
+
import { message } from "@/utils/message";
|
|
14
|
+
|
|
15
|
+
async function onDelete(row: { id: string }) {
|
|
16
|
+
await ElMessageBox.confirm($t("确定删除吗?"), $t("温馨提醒"), {
|
|
17
|
+
confirmButtonText: $t("确定"),
|
|
18
|
+
cancelButtonText: $t("取消"),
|
|
19
|
+
type: "warning",
|
|
20
|
+
});
|
|
21
|
+
// await deleteApi({ id: row.id })
|
|
22
|
+
message($t("删除成功"), { type: "success" });
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
7
26
|
## Loading
|
|
8
27
|
|
|
9
28
|
### 局部 Loading
|
|
@@ -55,6 +74,22 @@ ElMessageBox.confirm($t("确定删除吗?"), $t("温馨提醒"), {
|
|
|
55
74
|
});
|
|
56
75
|
```
|
|
57
76
|
|
|
77
|
+
## ReNoticeBar 通知栏
|
|
78
|
+
|
|
79
|
+
落点:`src/components/ReNoticeBar`。长文本滚动 / 可关闭提示,用于页内公告条。
|
|
80
|
+
|
|
81
|
+
```vue
|
|
82
|
+
<script setup lang="ts">
|
|
83
|
+
import ReNoticeBar from "@/components/ReNoticeBar";
|
|
84
|
+
</script>
|
|
85
|
+
|
|
86
|
+
<template>
|
|
87
|
+
<ReNoticeBar :text="$t('系统将于今晚维护,请提前保存数据')" />
|
|
88
|
+
</template>
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Props / 行为以组件源码为准;颜色走主题令牌,禁止业务写死提示条背景 hex。
|
|
92
|
+
|
|
58
93
|
## 关键约定
|
|
59
94
|
|
|
60
95
|
1. 所有提示文案使用 `$t()`。
|
|
@@ -231,8 +231,7 @@ defineExpose({ getInstance: () => graph })
|
|
|
231
231
|
```vue
|
|
232
232
|
<!-- g6 页面示例 -->
|
|
233
233
|
<template>
|
|
234
|
-
<div
|
|
235
|
-
class="pos-relative bg-bg_color p-5 overflow-hidden">
|
|
234
|
+
<div class="vts-page-fill h-full pos-relative bg-bg_color p-5 overflow-hidden">
|
|
236
235
|
<div class="toolbar">
|
|
237
236
|
<el-alert title="antv/g6流程图展示" type="info" :closable="false" />
|
|
238
237
|
</div>
|
|
@@ -10,6 +10,8 @@ tags: [form, dialog, ReDialog, ReDialogResize, ReSelectQuery, ReCascader, iconPi
|
|
|
10
10
|
> 核心选择器与 CRUD 列表筛选项高频相关。
|
|
11
11
|
> **弹窗**:业务弹窗统一用 `ReDialog` / `ReDialogResize`,禁止业务页直接堆裸 `el-dialog`(除非用户明确要求)。
|
|
12
12
|
|
|
13
|
+
**抗略读**:弹窗走项目 `ReDialog` 黄金样板(含销毁/禁点遮罩等默认项),勿降级为裸 `el-dialog`。远程下拉用 `ReSelectQuery` 真实 props(`url`/`value`/`label`/`edit-data`),禁止臆造 `:api`。
|
|
14
|
+
|
|
13
15
|
## 依赖(缺则先装)
|
|
14
16
|
|
|
15
17
|
按用到的能力安装(先查 `package.json`):
|
|
@@ -202,7 +204,8 @@ function parseAddress(text: string) {
|
|
|
202
204
|
|
|
203
205
|
## ReDialog 通用弹窗(必用)
|
|
204
206
|
|
|
205
|
-
> 落点:`src/components/ReDialog`。基于 `el-dialog`:居中、可拖拽、`destroy-on-close
|
|
207
|
+
> 落点:`src/components/ReDialog`。基于 `el-dialog`:居中、可拖拽、`destroy-on-close`、默认禁点遮罩关闭、内容区 `el-scrollbar`。
|
|
208
|
+
> **默认值**:`width='50%'`、`maxHeight=500`、`fullscreen=false`(不展示全屏钮)。几何消费 CSS:`--dialog-header-height`(出厂 38)、`--dialog-footer-height`(38)、`--dialog-body-padding`(15)、`--dialog-border-radius`(10);设计落地后按 handoff 回填令牌即可变观感。
|
|
206
209
|
|
|
207
210
|
### Props / 插槽
|
|
208
211
|
|
|
@@ -212,7 +215,7 @@ function parseAddress(text: string) {
|
|
|
212
215
|
| `title` | 标题文案(也可用 `#title` 插槽) |
|
|
213
216
|
| `width` | 默认 `'50%'` |
|
|
214
217
|
| `maxHeight` | 内容区滚动高度,默认 `500`(number 会拼 `px`) |
|
|
215
|
-
| `fullscreen` |
|
|
218
|
+
| `fullscreen` | 是否显示右上角全屏按钮,**默认 `false`**(需要时显式 `:fullscreen="true"`) |
|
|
216
219
|
| 默认插槽 | 内容区(包在 scrollbar 内) |
|
|
217
220
|
| `#footer` | 有则渲染底部操作区 |
|
|
218
221
|
| `#title` | 自定义标题 |
|
|
@@ -24,7 +24,7 @@ import { useApp } from '@/hooks/useApp'
|
|
|
24
24
|
import bgImg from './img/relationBg.png'
|
|
25
25
|
|
|
26
26
|
defineOptions({ name: 'Graph' })
|
|
27
|
-
const {
|
|
27
|
+
const { svgLoading } = useApp()
|
|
28
28
|
const graphRef = ref()
|
|
29
29
|
const loading = ref(false)
|
|
30
30
|
const rootId = ref('')
|
|
@@ -260,6 +260,6 @@ const legendConfig = ref([
|
|
|
260
260
|
|
|
261
261
|
1. 节点/连线类型只需声明项目中实际用到的字段,不必照搬库的完整类型。
|
|
262
262
|
2. 根节点通过 `selfFlag === '1'` 识别,设为 `fixed: true` 固定位置。
|
|
263
|
-
3.
|
|
263
|
+
3. 图谱容器必须有明确高度(定高页用 `vts-page-fill` / `vts-page-card`;内部画布 `height: 100%` 或 `calc(100% - 偏移)`;禁止业务页 `100vh` 减顶栏定高)。
|
|
264
264
|
4. `setJsonData` 的回调中执行居中、缩放、高亮等初始化操作。
|
|
265
265
|
5. 节点自定义样式通过 `#node` 插槽,class 根据 `data` 字段动态绑定。
|
package/references/http-api.md
CHANGED
|
@@ -9,6 +9,31 @@ tags: [axios, http, api, encryption, rsa, aes, download, request]
|
|
|
9
9
|
|
|
10
10
|
> 实现落点:`src/utils/http.ts`、`src/api/**`、全局 `Result<T>`。
|
|
11
11
|
|
|
12
|
+
**抗略读**:接口文件须整段按下方「强制样板」落盘;禁止组件内直接 `axios`/`fetch`。加解密靠 `VITE_ENCODE_SWITCH`,禁止臆造单请求 `crypto: true`。下载接口**默认写出** `responseType: "blob"`(勿注释掉)。
|
|
13
|
+
|
|
14
|
+
## 强制样板(新建 API 照抄)
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
import { http } from "@/utils/http";
|
|
18
|
+
|
|
19
|
+
export function getCustomerList(data: CustomerQuery) {
|
|
20
|
+
return http.request<Result<CustomerPage>>(
|
|
21
|
+
"post",
|
|
22
|
+
`${import.meta.env.VITE_API_BASE_URL}/customer/list`,
|
|
23
|
+
{ data },
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function downloadCustomer(data: Recordable) {
|
|
28
|
+
return http.request<Result<Blob>>(
|
|
29
|
+
"post",
|
|
30
|
+
`${import.meta.env.VITE_API_BASE_URL}/customer/export`,
|
|
31
|
+
{ data },
|
|
32
|
+
{ responseType: "blob" },
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
12
37
|
## Http 封装架构
|
|
13
38
|
|
|
14
39
|
项目使用自定义 `Http` 类封装 Axios,位于 `src/utils/http.ts`。核心特性:
|
package/references/icons.md
CHANGED
|
@@ -11,6 +11,18 @@ tags: [vue3, icon, svg-icon, ReSvgIcon, ReIconPicker, iconify, ep, ri, unocss, m
|
|
|
11
11
|
> **真相源**:`src/components/ReSvgIcon`、`src/components/ReIconPicker`、`src/icons/svg`、`main.ts`、`uno.config.ts`、`build/plugins/SvgSpriteLoader.ts` / `SvgLoader.ts`。
|
|
12
12
|
> 选型表见 `project-inventory`「图标」节;勿另起 IconFont / 未约定的图标库。
|
|
13
13
|
|
|
14
|
+
**抗略读**:新建菜单/父级路由时 **`meta.icon` 默认写出**(如 `ep:user`),禁止交无图标菜单。页面内优先 `<svg-icon name="..." />`,勿散落未约定图标库。
|
|
15
|
+
|
|
16
|
+
## 强制样板(菜单 icon)
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
meta: { title: "客户管理", icon: "ep:user", rank: 10 }
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
```vue
|
|
23
|
+
<svg-icon name="ep:search" />
|
|
24
|
+
```
|
|
25
|
+
|
|
14
26
|
---
|
|
15
27
|
|
|
16
28
|
## 依赖(core,模板已装)
|
|
@@ -189,40 +189,48 @@ html.dark {
|
|
|
189
189
|
|
|
190
190
|
### 4.1 间距
|
|
191
191
|
|
|
192
|
-
|
|
192
|
+
项目内容区内边距走 `--layout-content-padding` → `--vts-margin`(**出厂 8px**;设计 handoff 常覆盖为 24)。UnoCSS `presetRemToPx({ baseFontSize: 4 })` 间距类数字即 px:
|
|
193
193
|
|
|
194
194
|
| UnoCSS 类 | 实际值 | 用途 |
|
|
195
195
|
|-----------|--------|------|
|
|
196
196
|
| `p-1` / `m-1` | 1px | 微调 |
|
|
197
197
|
| `p-2` / `m-2` | 2px | 紧凑间距 |
|
|
198
198
|
| `p-4` / `m-4` | 4px | 小间距 |
|
|
199
|
-
| `p-8` / `m-8` | 8px |
|
|
199
|
+
| `p-8` / `m-8` | 8px | 常等于出厂 `--vts-margin`(handoff 改 margin 后勿再假设恒等于 8) |
|
|
200
200
|
| `p-12` / `m-12` | 12px | 中等间距 |
|
|
201
201
|
| `p-16` / `m-16` | 16px | 大间距 |
|
|
202
202
|
| `p-20` / `m-20` | 20px | 区块间距 |
|
|
203
203
|
|
|
204
|
-
### 4.1.1 弹窗 / MessageBox(design-tokens 定义 · element-plus
|
|
204
|
+
### 4.1.1 弹窗 / MessageBox(design-tokens 定义 · ReDialog / element-plus 执行)
|
|
205
205
|
|
|
206
|
-
| 令牌 |
|
|
206
|
+
| 令牌 | 出厂默认 | 消费位置 |
|
|
207
207
|
|------|---------|---------|
|
|
208
|
-
| `--dialog-header-
|
|
209
|
-
| `--dialog-
|
|
210
|
-
| `--
|
|
211
|
-
| `--dialog-
|
|
212
|
-
| `--
|
|
213
|
-
| `--ds-dialog-bg` | `linear-gradient(primary-bg → component-bg)` | `index.scss` → `--vts-dialog-bg`
|
|
208
|
+
| `--dialog-header-height` | 38px | `.el-dialog__header`(ReDialog) |
|
|
209
|
+
| `--dialog-footer-height` | 38px | `.el-dialog__footer` |
|
|
210
|
+
| `--dialog-body-padding` | 15px | `.el-dialog__body` |
|
|
211
|
+
| `--dialog-border-radius` | 10px | `.el-dialog` |
|
|
212
|
+
| `--message-box-*-padding` | 8px 16px | MessageBox 更紧凑 |
|
|
213
|
+
| `--ds-dialog-bg` | `linear-gradient(primary-bg → component-bg)` | `index.scss` → `--vts-dialog-bg` |
|
|
214
214
|
|
|
215
|
-
> **禁止**写死 `#e5f3fe → #fefefe
|
|
215
|
+
> **禁止**写死 `#e5f3fe → #fefefe`。
|
|
216
|
+
> **出厂**保留上表 ReDialog 默认几何;**设计落地**时按 `design-handoff`「全量令牌核对表 · D. 弹窗」回填(如圆角改 `--radius-lg` / 8px),禁止只改品牌色漏弹窗令牌。
|
|
216
217
|
|
|
217
218
|
### 4.2 字号
|
|
218
219
|
|
|
219
|
-
|
|
220
|
+
**两套并存,勿混用:**
|
|
221
|
+
|
|
222
|
+
| 体系 | 正文基准 | 用途 |
|
|
223
|
+
|------|----------|------|
|
|
224
|
+
| `design-tokens` `--font-size-base` | **14px** | Element Plus / 令牌化组件 |
|
|
225
|
+
| UnoCSS `text-base` | **16px** | 工具类排版(`theme.fontSize` 显式 px) |
|
|
226
|
+
|
|
227
|
+
UnoCSS 其余档:
|
|
220
228
|
|
|
221
229
|
| Token | 大小 | 行高 | 用途 |
|
|
222
230
|
|-------|------|------|------|
|
|
223
231
|
| `text-xs` | 12px | 16px | 辅助文字、标签 |
|
|
224
232
|
| `text-sm` | 14px | 20px | 次要文字、表格 |
|
|
225
|
-
| `text-base` | 16px | 24px |
|
|
233
|
+
| `text-base` | 16px | 24px | Uno 正文类 |
|
|
226
234
|
| `text-lg` | 18px | 28px | 小标题 |
|
|
227
235
|
| `text-xl` | 20px | 28px | 标题 |
|
|
228
236
|
| `text-2xl` | 24px | 32px | 页面标题 |
|
|
@@ -230,12 +238,18 @@ UnoCSS `theme.fontSize` 已显式定义为 px 值(避免被 `presetRemToPx`
|
|
|
230
238
|
|
|
231
239
|
### 4.3 字体
|
|
232
240
|
|
|
233
|
-
|
|
241
|
+
全局字体走令牌 `--font-family`(`design-tokens.scss` 出厂为系统栈)。
|
|
242
|
+
|
|
243
|
+
`index.scss` / `reset.scss` 写法:
|
|
234
244
|
|
|
235
245
|
```css
|
|
236
|
-
font-family: 'Alibaba PuHuiTi 3.0', 'Microsoft YaHei', Arial, sans-serif;
|
|
246
|
+
font-family: var(--font-family, 'Alibaba PuHuiTi 3.0', 'Microsoft YaHei', Arial, sans-serif);
|
|
237
247
|
```
|
|
238
248
|
|
|
249
|
+
- **出厂**:令牌已定义 → 实际为系统栈;PuHui 仅作 fallback
|
|
250
|
+
- **设计落地**:handoff 覆盖 `--font-family` 即全局生效
|
|
251
|
+
- **禁止**再写死 `'Alibaba PuHuiTi 3.0' !important` 通配符覆盖令牌
|
|
252
|
+
|
|
239
253
|
### 4.4 动画时长
|
|
240
254
|
|
|
241
255
|
- 全局过渡时长:`--vts-transition-duration: 0.3s`
|
|
@@ -253,56 +267,68 @@ font-family: 'Alibaba PuHuiTi 3.0', 'Microsoft YaHei', Arial, sans-serif;
|
|
|
253
267
|
|
|
254
268
|
### 4.6 边框圆角
|
|
255
269
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
270
|
+
模版**已定义**全局圆角令牌(`design-tokens`):
|
|
271
|
+
|
|
272
|
+
| 令牌 | 出厂默认 | 用途 |
|
|
273
|
+
|------|----------|------|
|
|
274
|
+
| `--radius-sm` / `--border-radius-sm` | 4px | 小控件、Tag |
|
|
275
|
+
| `--radius-base` / `--border-radius-base` | 6px | 按钮、输入 |
|
|
276
|
+
| `--radius-lg` / `--border-radius-lg` | 8px | 卡片等 |
|
|
277
|
+
| `--dialog-border-radius` | 10px(出厂 ReDialog) | 弹窗;设计落地可改为 `var(--radius-lg)` |
|
|
278
|
+
|
|
279
|
+
设计 handoff 可覆盖上述令牌;业务禁止裸写 `border-radius: 4px`。
|
|
260
280
|
|
|
261
281
|
---
|
|
262
282
|
|
|
263
283
|
## 五、布局系统
|
|
264
284
|
|
|
285
|
+
> **双轨**:下列数字是 **CSS 变量的出厂默认值**,不是组件内写死的常量。设计落地后按 handoff 回填令牌,壳层自动跟随。
|
|
286
|
+
|
|
265
287
|
### 布局模式
|
|
266
288
|
|
|
267
289
|
项目支持三种布局模式,通过布局配置切换:
|
|
268
290
|
|
|
269
|
-
1. **垂直布局(Vertical)** — 侧边栏
|
|
291
|
+
1. **垂直布局(Vertical)** — 侧边栏 `var(--sidebar-width)`(出厂 **208px**)+ 顶部导航。
|
|
270
292
|
2. **水平布局(Horizontal)** — 顶部导航栏,侧边栏宽度为 0。
|
|
271
|
-
3. **混合布局(Mix)** —
|
|
293
|
+
3. **混合布局(Mix)** — 侧边栏同 `--sidebar-width`(一级菜单)+ 顶部导航(二级菜单)。
|
|
272
294
|
|
|
273
295
|
### 布局文件结构
|
|
274
296
|
|
|
275
297
|
```
|
|
276
298
|
src/layout/
|
|
277
|
-
├── index.vue
|
|
299
|
+
├── index.vue
|
|
278
300
|
├── components/
|
|
279
|
-
│ ├── sidebar/
|
|
280
|
-
│ ├── navbar/
|
|
281
|
-
│ ├──
|
|
282
|
-
│
|
|
301
|
+
│ ├── lay-sidebar/ # 侧边栏
|
|
302
|
+
│ ├── lay-navbar/ # 顶部导航
|
|
303
|
+
│ ├── lay-tag/ # 多标签页
|
|
304
|
+
│ ├── lay-content/ # 内容区
|
|
305
|
+
│ ├── lay-header/ # 顶栏容器
|
|
306
|
+
│ └── lay-setting/ # 设置面板
|
|
283
307
|
└── hooks/
|
|
284
|
-
└── useLayout.ts # 布局状态管理
|
|
285
308
|
```
|
|
286
309
|
|
|
287
310
|
### 侧边栏样式架构
|
|
288
311
|
|
|
289
|
-
`src/styles/sidebar.scss` 使用 SCSS mixin `merge-style($sideBarWidth)
|
|
312
|
+
`src/styles/sidebar.scss` 使用 SCSS mixin `merge-style($sideBarWidth)`;宽度传入**令牌**,禁止写死 210:
|
|
290
313
|
|
|
291
314
|
```scss
|
|
292
|
-
|
|
293
|
-
@mixin merge-style($sideBarWidth) {
|
|
294
|
-
// 侧边栏容器、菜单项、子菜单、Logo 等样式
|
|
295
|
-
// $sideBarWidth 控制展开宽度
|
|
296
|
-
}
|
|
315
|
+
$sideBarWidth: var(--sidebar-width, 208px);
|
|
297
316
|
|
|
298
|
-
|
|
299
|
-
.layout-
|
|
300
|
-
// 水平布局
|
|
301
|
-
.layout-horizontal .horizontal-header { @include merge-style(0); }
|
|
302
|
-
// 混合布局
|
|
303
|
-
.layout-mix .sidebar-container { @include merge-style(210px); }
|
|
317
|
+
.layout-vertical .sidebar-container { @include merge-style($sideBarWidth); }
|
|
318
|
+
.layout-mix .sidebar-container { @include merge-style($sideBarWidth); }
|
|
304
319
|
```
|
|
305
320
|
|
|
321
|
+
壳层几何出厂默认(均在 `design-tokens.scss`,可被 handoff 覆盖):
|
|
322
|
+
|
|
323
|
+
| 令牌 | 出厂 | 设计别名 |
|
|
324
|
+
|------|------|----------|
|
|
325
|
+
| `--header-height` | 64px | `--layout-header-height` |
|
|
326
|
+
| `--tabs-height` | 40px | (壳层多标签栏,≠ EP `--tabs-item-height`) |
|
|
327
|
+
| `--sidebar-width` | 208px | `--layout-sider-width` |
|
|
328
|
+
| `--sidebar-collapsed-width` | 64px | `--layout-sider-collapsed-width` |
|
|
329
|
+
| `--layout-content-padding` → `--vts-margin` | 8px | 设计常改 24 |
|
|
330
|
+
| `--layout-footer-height` | 48px | |
|
|
331
|
+
|
|
306
332
|
**修改侧边栏样式时**,必须检查 3 种布局模式下是否都需要调整。
|
|
307
333
|
|
|
308
334
|
### 布局约定
|
|
@@ -310,26 +336,40 @@ src/layout/
|
|
|
310
336
|
1. 页面组件通过 `<router-view>` 嵌套在布局内渲染。
|
|
311
337
|
2. 布局切换通过 store 中的 `layout` 字段控制。
|
|
312
338
|
3. 侧边栏菜单数据来源于路由配置中的 `meta` 信息。
|
|
313
|
-
4. 标签页(TagsView
|
|
339
|
+
4. 标签页(TagsView)三种风格:`smart`(灵动)/ `chrome`(谷歌)/ `card`(卡片·设计规范);由 `configure.showModel` / `platform-config.json` 的 `ShowModel` 控制。设计 handoff 落地时用 `card`。
|
|
340
|
+
|
|
341
|
+
### 页签风格(ShowModel)
|
|
314
342
|
|
|
315
|
-
|
|
343
|
+
| 值 | 设置文案 | 说明 |
|
|
344
|
+
|----|----------|------|
|
|
345
|
+
| `smart` | 灵动 | 底部指示条动画 |
|
|
346
|
+
| `chrome` | 谷歌 | Chrome 梯形页签(模版常见出厂) |
|
|
347
|
+
| `card` | 卡片 | 关闭钮绝对定位不占位;显现时用不透明页签底盖字;再 hover 关闭钮:圆形底 `--layout-bg`/`--bg-layout` + 图标 `--error-6`/`--error-color`=`#F5222D`(勿用 EP `#F56C6C` 偏橘) |
|
|
348
|
+
|
|
349
|
+
设计落地改色/几何时优先改 `--vts-tag-card-*`(见 `index.scss` `:root`),勿再复制一套选择器。
|
|
350
|
+
|
|
351
|
+
### 顶栏 / 页签高度
|
|
316
352
|
|
|
317
353
|
| 环节 | 约定 |
|
|
318
354
|
|------|------|
|
|
319
|
-
|
|
|
320
|
-
|
|
|
321
|
-
|
|
|
355
|
+
| 令牌 | `--header-height` / `--tabs-height` → `--layout-header-offset`;桥接 `--vts-bar-height` / `--vts-tabs-height` / `--vts-layout-header-offset*` |
|
|
356
|
+
| 消费 | `lay-content` 的 `padding-top` 用 `--vts-layout-header-offset*`;定高页用 `.vts-page-card` / `.vts-page-fill` |
|
|
357
|
+
| 禁止 | 业务页用 `100vh` 减顶栏高度;用 JS 测顶栏写 storage;在 `useApp` / `platform-config` 增加顶栏像素字段 |
|
|
358
|
+
|
|
359
|
+
设计落地改顶栏:只改 `--header-height`(或 handoff `geometry.headerHeight`)。
|
|
322
360
|
|
|
323
361
|
### 内容区高度与滚动
|
|
324
362
|
|
|
325
363
|
| 场景 | 卡片 / 高度 | 滚动落点 |
|
|
326
364
|
|------|-------------|----------|
|
|
327
|
-
| 查询列表 | `el-card.vts-page-card
|
|
365
|
+
| 查询列表 | `el-card.vts-page-card`(无 inline `100vh`);表格绑 `useTableSearch().tableHeight` | 仅 `el-table` 体内;分页在表格下方 |
|
|
328
366
|
| 树 + 表分栏 | 同上定高卡;左右并排,高度走 Hook 几何实测 | 同查询列表 |
|
|
329
|
-
|
|
|
330
|
-
|
|
|
367
|
+
| 非 Card 整页填满 | 根节点 `class="vts-page-fill"` + `height: 100%` / `h-full` | 内部区域自管滚动 |
|
|
368
|
+
| 长表单 / 详情 / 说明 | `min-height: 100%`;不绑 `tableHeight` | `.app-main` 内 `el-scrollbar` |
|
|
369
|
+
| Card 内边距 | `--vts-card-padding` → `--card-padding` | 换规范 / `--vts-margin` 只改令牌;列表高度由壳层 + Hook 跟随 |
|
|
331
370
|
|
|
332
|
-
`.vts-page-card
|
|
371
|
+
`.vts-page-card`:flex 填满 `.main-content:has(.vts-page-card)`,`overflow: hidden`,`.el-card__body` 高度 100%。样式在 `element-plus.scss` + `lay-content`。
|
|
372
|
+
`--vts-margin` 可变(模板默认 8px,设计 handoff 可覆盖);壳层对 `.main-content` 使用 **padding**(非 margin)承载该间距,定高链为 `height:100%`,避免「高度+外边距」撑出最外层滚动条。
|
|
333
373
|
|
|
334
374
|
### 混合布局路由结构
|
|
335
375
|
|
|
@@ -7,6 +7,20 @@ tags: [vue3, permission, auth, directive, hooks, v-auth, role, access-control]
|
|
|
7
7
|
|
|
8
8
|
# 权限控制与自定义指令
|
|
9
9
|
|
|
10
|
+
**抗略读**:有权限需求时,`meta.roles` 与 `v-auth`/`ReAuth` **默认写出**(勿注释成可选项)。禁止 `v-if="roles.includes(...)"` 手写角色判断。
|
|
11
|
+
|
|
12
|
+
## 强制样板(页面 + 按钮)
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
// 路由:roles 默认写出
|
|
16
|
+
meta: { title: "用户管理", roles: ["admin", "common"] }
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
```vue
|
|
20
|
+
<el-button v-auth="['admin']" @click="onDelete">{{ $t("删除") }}</el-button>
|
|
21
|
+
<ReAuth :value="['admin']"><!-- 区域级 --></ReAuth>
|
|
22
|
+
```
|
|
23
|
+
|
|
10
24
|
## 权限体系概览
|
|
11
25
|
|
|
12
26
|
项目权限分为三个层级:
|
|
@@ -33,7 +47,7 @@ export default {
|
|
|
33
47
|
component: () => import("@/views/system/user/index.vue"),
|
|
34
48
|
meta: {
|
|
35
49
|
title: "用户管理",
|
|
36
|
-
roles: ["admin", "editor"],
|
|
50
|
+
roles: ["admin", "editor"],
|
|
37
51
|
},
|
|
38
52
|
},
|
|
39
53
|
{
|
|
@@ -42,7 +56,7 @@ export default {
|
|
|
42
56
|
component: () => import("@/views/system/config/index.vue"),
|
|
43
57
|
meta: {
|
|
44
58
|
title: "系统配置",
|
|
45
|
-
roles: ["admin"],
|
|
59
|
+
roles: ["admin"],
|
|
46
60
|
},
|
|
47
61
|
},
|
|
48
62
|
],
|