@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
package/references/auth-pages.md
CHANGED
|
@@ -1,217 +1,217 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: auth-pages
|
|
3
|
-
description: 登录/注册/忘记密码认证流程、API 模式、userStore 集成、路由配置
|
|
4
|
-
scope: project
|
|
5
|
-
tags: [登录, 注册, 忘记密码, 重置密码, 认证, auth, login, register, signup, forgot-password, 找回密码]
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# 认证流程规范(登录 / 注册 / 忘记密码)
|
|
9
|
-
|
|
10
|
-
> **页面设计自由**:认证页面的视觉布局、交互形式、背景效果均由设计主导,本模块仅规范**认证流程、API 模式、Store 集成、路由配置**。勿将此处代码片段当作页面样板整段抄录,仅提取流程模式。
|
|
11
|
-
>
|
|
12
|
-
> **验证码/滑块组件**:见 `verify-captcha` 模块(ReVerify 滑块拼图、ReDragVerify 拖拽验证、ReImageVerify 图片验证码、ReSmsCode 短信倒计时)。本模块不重复其用法。
|
|
13
|
-
|
|
14
|
-
## 涉及文件
|
|
15
|
-
|
|
16
|
-
```
|
|
17
|
-
src/
|
|
18
|
-
├── api/login/index.ts # 认证 API(按后端实际接口调整字段)
|
|
19
|
-
├── store/modules/user.ts # useUserStore:login()、logOut()、token 管理
|
|
20
|
-
├── views/login/ # 登录页(设计自由,仅流程受规范)
|
|
21
|
-
├── utils/rule.ts # 表单校验规则
|
|
22
|
-
└── router/ # 认证页路由(showLink:false)
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
## API 模式
|
|
26
|
-
|
|
27
|
-
> 字段名和接口路径按后端实际定义,以下仅展示结构模式。**勿将字段当作硬约束**。
|
|
28
|
-
|
|
29
|
-
```typescript
|
|
30
|
-
// src/api/login/index.ts
|
|
31
|
-
import { http } from '@/utils/http'
|
|
32
|
-
|
|
33
|
-
// 接口参数类型 — 字段按后端实际定义
|
|
34
|
-
interface LoginParams {
|
|
35
|
-
[key: string]: any // 常见:账号、密码、验证码等,字段名不固定
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// 登录返回 — 结构按后端实际返回
|
|
39
|
-
interface LoginResult {
|
|
40
|
-
[key: string]: any // 常见:token、用户信息等,字段名不固定
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/** 登录 */
|
|
44
|
-
export const getLogin = (data: LoginParams) => {
|
|
45
|
-
return http.request<Result<LoginResult>>('post', '/auth/login', { data })
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/** 发送短信验证码 */
|
|
49
|
-
export const sendSmsCode = (params: Record<string, any>) => {
|
|
50
|
-
return http.request<Result<null>>('post', '/auth/sms-code', { data: params })
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// 注册/忘记密码 API 按需新增,遵循同一模式:
|
|
54
|
-
// 1. 参数类型用 interface 声明,字段按后端定义
|
|
55
|
-
// 2. 返回值用 Result<T> 包裹
|
|
56
|
-
// 3. 方法名语义化(getRegister、sendResetLink、resetPassword)
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
## 认证流程模式
|
|
60
|
-
|
|
61
|
-
> 无论页面长什么样,认证流程必须遵循以下链路。
|
|
62
|
-
|
|
63
|
-
```
|
|
64
|
-
用户输入 → 表单校验 → [验证码校验] → 调用 API → useUserStore 处理 token → initRouter → 跳转首页
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
### 1. Store 集成
|
|
68
|
-
|
|
69
|
-
```typescript
|
|
70
|
-
// store/modules/user.ts — 认证状态管理
|
|
71
|
-
export const useUserStore = defineStore('user', {
|
|
72
|
-
state: () => ({
|
|
73
|
-
token: '',
|
|
74
|
-
userInfo: null as any,
|
|
75
|
-
}),
|
|
76
|
-
actions: {
|
|
77
|
-
// 登录:调用 API → 存 token → 返回结果
|
|
78
|
-
async login(data: Record<string, any>) {
|
|
79
|
-
const res = await getLogin(data)
|
|
80
|
-
if (res.status === 200 && res.data) {
|
|
81
|
-
// token 存储方式按项目实际(localStorage / cookie / pinia 持久化)
|
|
82
|
-
this.token = res.data.accessToken ?? ''
|
|
83
|
-
// 用户信息按后端返回结构存储
|
|
84
|
-
this.userInfo = res.data
|
|
85
|
-
}
|
|
86
|
-
return res
|
|
87
|
-
},
|
|
88
|
-
// 退出
|
|
89
|
-
logOut() {
|
|
90
|
-
this.token = ''
|
|
91
|
-
this.userInfo = null
|
|
92
|
-
// 清除存储、跳转登录
|
|
93
|
-
},
|
|
94
|
-
},
|
|
95
|
-
})
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
### 2. 登录流程
|
|
99
|
-
|
|
100
|
-
```typescript
|
|
101
|
-
// 登录页脚本 — 仅展示流程,页面模板设计自由
|
|
102
|
-
import { useUserStoreHook } from '@/store/modules/user'
|
|
103
|
-
import { getTopMenu, initRouter } from '@/utils/router'
|
|
104
|
-
|
|
105
|
-
const useUserStore = useUserStoreHook()
|
|
106
|
-
const router = useRouter()
|
|
107
|
-
const loading = ref(false)
|
|
108
|
-
|
|
109
|
-
async function handleLogin(formData: Record<string, any>) {
|
|
110
|
-
loading.value = true
|
|
111
|
-
try {
|
|
112
|
-
const res = await useUserStore.login(formData)
|
|
113
|
-
if (res.status === 200) {
|
|
114
|
-
// 初始化路由(动态路由/权限路由)
|
|
115
|
-
await initRouter(router)
|
|
116
|
-
// 跳转到首页或来源页
|
|
117
|
-
router.push(getTopMenu().path)
|
|
118
|
-
}
|
|
119
|
-
} finally {
|
|
120
|
-
loading.value = false
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
### 3. 注册流程
|
|
126
|
-
|
|
127
|
-
```typescript
|
|
128
|
-
// 注册页脚本 — 仅展示流程
|
|
129
|
-
import { getRegister } from '@/api/login'
|
|
130
|
-
|
|
131
|
-
async function handleRegister(formData: Record<string, any>) {
|
|
132
|
-
loading.value = true
|
|
133
|
-
try {
|
|
134
|
-
const res = await getRegister(formData)
|
|
135
|
-
if (res.status === 200) {
|
|
136
|
-
// 注册成功 → 跳转登录或自动登录
|
|
137
|
-
router.push('/login')
|
|
138
|
-
}
|
|
139
|
-
} finally {
|
|
140
|
-
loading.value = false
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
### 4. 忘记密码流程
|
|
146
|
-
|
|
147
|
-
```typescript
|
|
148
|
-
// 忘记密码 — 分步流程,页面交互设计自由
|
|
149
|
-
const step = ref(1) // 步骤数按实际流程定
|
|
150
|
-
|
|
151
|
-
// 步骤 1:验证身份 → 发送重置凭证
|
|
152
|
-
async function handleSendReset(account: string) { /* 调用 API */ }
|
|
153
|
-
|
|
154
|
-
// 步骤 2:重置密码
|
|
155
|
-
async function handleReset(formData: Record<string, any>) { /* 调用 API */ }
|
|
156
|
-
|
|
157
|
-
// 步骤 3:完成 → 跳转登录
|
|
158
|
-
function handleDone() {
|
|
159
|
-
router.push('/login')
|
|
160
|
-
}
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
## 路由配置
|
|
164
|
-
|
|
165
|
-
```typescript
|
|
166
|
-
// 认证页路由统一约定
|
|
167
|
-
{
|
|
168
|
-
path: '/login',
|
|
169
|
-
name: 'Login',
|
|
170
|
-
component: () => import('@/views/login/index.vue'),
|
|
171
|
-
meta: {
|
|
172
|
-
title: '登录',
|
|
173
|
-
showLink: false, // 不在菜单显示
|
|
174
|
-
activePath: '/login', // 高亮路径
|
|
175
|
-
},
|
|
176
|
-
}
|
|
177
|
-
// 注册/忘记密码页同理:showLink: false + activePath
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
## 表单校验模式
|
|
181
|
-
|
|
182
|
-
> 校验规则按业务实际调整,以下为常见模式。
|
|
183
|
-
|
|
184
|
-
```typescript
|
|
185
|
-
import { loginRules } from '@/utils/rule'
|
|
186
|
-
|
|
187
|
-
// 必填校验
|
|
188
|
-
const rules = {
|
|
189
|
-
// 字段名按表单实际定义,不固定
|
|
190
|
-
account: [{ required: true, message: $t('请输入账号'), trigger: 'blur' }],
|
|
191
|
-
password: [{ required: true, message: $t('请输入密码'), trigger: 'blur' }],
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
// 密码确认校验(注册/重置密码场景)
|
|
195
|
-
const confirmPasswordRule = {
|
|
196
|
-
validator: (rule: any, value: string, callback: any) => {
|
|
197
|
-
if (value !== formData.password) {
|
|
198
|
-
callback(new Error($t('两次密码不一致')))
|
|
199
|
-
} else {
|
|
200
|
-
callback()
|
|
201
|
-
}
|
|
202
|
-
},
|
|
203
|
-
trigger: 'blur',
|
|
204
|
-
}
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
## Must-do 清单
|
|
208
|
-
|
|
209
|
-
1. **认证流程链路**:`API → useUserStore.login() → initRouter() → 跳转`,勿另起流程
|
|
210
|
-
2. **页面设计自由**:布局、背景、交互形式由设计主导,本模块不约束视觉
|
|
211
|
-
3. **API 字段动态**:参数和返回值字段按后端实际定义,勿硬编码字段名
|
|
212
|
-
4. **验证码组件**:见 `verify-captcha` 模块,不在本模块重复
|
|
213
|
-
5. **路由约定**:认证页 `showLink: false` 不在菜单显示,`activePath` 指向自身
|
|
214
|
-
6. **路由白名单**:登录/注册/忘记密码页在路由守卫白名单中,无需 token
|
|
215
|
-
7. **国际化**:所有提示文案用 `$t()` 包裹
|
|
216
|
-
8. **密码确认**:注册和重置密码须有确认密码字段 + 自定义校验
|
|
217
|
-
9. **loading 状态**:提交期间禁用按钮,防止重复提交
|
|
1
|
+
---
|
|
2
|
+
name: auth-pages
|
|
3
|
+
description: 登录/注册/忘记密码认证流程、API 模式、userStore 集成、路由配置
|
|
4
|
+
scope: project
|
|
5
|
+
tags: [登录, 注册, 忘记密码, 重置密码, 认证, auth, login, register, signup, forgot-password, 找回密码]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# 认证流程规范(登录 / 注册 / 忘记密码)
|
|
9
|
+
|
|
10
|
+
> **页面设计自由**:认证页面的视觉布局、交互形式、背景效果均由设计主导,本模块仅规范**认证流程、API 模式、Store 集成、路由配置**。勿将此处代码片段当作页面样板整段抄录,仅提取流程模式。
|
|
11
|
+
>
|
|
12
|
+
> **验证码/滑块组件**:见 `verify-captcha` 模块(ReVerify 滑块拼图、ReDragVerify 拖拽验证、ReImageVerify 图片验证码、ReSmsCode 短信倒计时)。本模块不重复其用法。
|
|
13
|
+
|
|
14
|
+
## 涉及文件
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
src/
|
|
18
|
+
├── api/login/index.ts # 认证 API(按后端实际接口调整字段)
|
|
19
|
+
├── store/modules/user.ts # useUserStore:login()、logOut()、token 管理
|
|
20
|
+
├── views/login/ # 登录页(设计自由,仅流程受规范)
|
|
21
|
+
├── utils/rule.ts # 表单校验规则
|
|
22
|
+
└── router/ # 认证页路由(showLink:false)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## API 模式
|
|
26
|
+
|
|
27
|
+
> 字段名和接口路径按后端实际定义,以下仅展示结构模式。**勿将字段当作硬约束**。
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
// src/api/login/index.ts
|
|
31
|
+
import { http } from '@/utils/http'
|
|
32
|
+
|
|
33
|
+
// 接口参数类型 — 字段按后端实际定义
|
|
34
|
+
interface LoginParams {
|
|
35
|
+
[key: string]: any // 常见:账号、密码、验证码等,字段名不固定
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// 登录返回 — 结构按后端实际返回
|
|
39
|
+
interface LoginResult {
|
|
40
|
+
[key: string]: any // 常见:token、用户信息等,字段名不固定
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** 登录 */
|
|
44
|
+
export const getLogin = (data: LoginParams) => {
|
|
45
|
+
return http.request<Result<LoginResult>>('post', '/auth/login', { data })
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** 发送短信验证码 */
|
|
49
|
+
export const sendSmsCode = (params: Record<string, any>) => {
|
|
50
|
+
return http.request<Result<null>>('post', '/auth/sms-code', { data: params })
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// 注册/忘记密码 API 按需新增,遵循同一模式:
|
|
54
|
+
// 1. 参数类型用 interface 声明,字段按后端定义
|
|
55
|
+
// 2. 返回值用 Result<T> 包裹
|
|
56
|
+
// 3. 方法名语义化(getRegister、sendResetLink、resetPassword)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## 认证流程模式
|
|
60
|
+
|
|
61
|
+
> 无论页面长什么样,认证流程必须遵循以下链路。
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
用户输入 → 表单校验 → [验证码校验] → 调用 API → useUserStore 处理 token → initRouter → 跳转首页
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### 1. Store 集成
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
// store/modules/user.ts — 认证状态管理
|
|
71
|
+
export const useUserStore = defineStore('user', {
|
|
72
|
+
state: () => ({
|
|
73
|
+
token: '',
|
|
74
|
+
userInfo: null as any,
|
|
75
|
+
}),
|
|
76
|
+
actions: {
|
|
77
|
+
// 登录:调用 API → 存 token → 返回结果
|
|
78
|
+
async login(data: Record<string, any>) {
|
|
79
|
+
const res = await getLogin(data)
|
|
80
|
+
if (res.status === 200 && res.data) {
|
|
81
|
+
// token 存储方式按项目实际(localStorage / cookie / pinia 持久化)
|
|
82
|
+
this.token = res.data.accessToken ?? ''
|
|
83
|
+
// 用户信息按后端返回结构存储
|
|
84
|
+
this.userInfo = res.data
|
|
85
|
+
}
|
|
86
|
+
return res
|
|
87
|
+
},
|
|
88
|
+
// 退出
|
|
89
|
+
logOut() {
|
|
90
|
+
this.token = ''
|
|
91
|
+
this.userInfo = null
|
|
92
|
+
// 清除存储、跳转登录
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
})
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### 2. 登录流程
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
// 登录页脚本 — 仅展示流程,页面模板设计自由
|
|
102
|
+
import { useUserStoreHook } from '@/store/modules/user'
|
|
103
|
+
import { getTopMenu, initRouter } from '@/utils/router'
|
|
104
|
+
|
|
105
|
+
const useUserStore = useUserStoreHook()
|
|
106
|
+
const router = useRouter()
|
|
107
|
+
const loading = ref(false)
|
|
108
|
+
|
|
109
|
+
async function handleLogin(formData: Record<string, any>) {
|
|
110
|
+
loading.value = true
|
|
111
|
+
try {
|
|
112
|
+
const res = await useUserStore.login(formData)
|
|
113
|
+
if (res.status === 200) {
|
|
114
|
+
// 初始化路由(动态路由/权限路由)
|
|
115
|
+
await initRouter(router)
|
|
116
|
+
// 跳转到首页或来源页
|
|
117
|
+
router.push(getTopMenu().path)
|
|
118
|
+
}
|
|
119
|
+
} finally {
|
|
120
|
+
loading.value = false
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### 3. 注册流程
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
// 注册页脚本 — 仅展示流程
|
|
129
|
+
import { getRegister } from '@/api/login'
|
|
130
|
+
|
|
131
|
+
async function handleRegister(formData: Record<string, any>) {
|
|
132
|
+
loading.value = true
|
|
133
|
+
try {
|
|
134
|
+
const res = await getRegister(formData)
|
|
135
|
+
if (res.status === 200) {
|
|
136
|
+
// 注册成功 → 跳转登录或自动登录
|
|
137
|
+
router.push('/login')
|
|
138
|
+
}
|
|
139
|
+
} finally {
|
|
140
|
+
loading.value = false
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### 4. 忘记密码流程
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
// 忘记密码 — 分步流程,页面交互设计自由
|
|
149
|
+
const step = ref(1) // 步骤数按实际流程定
|
|
150
|
+
|
|
151
|
+
// 步骤 1:验证身份 → 发送重置凭证
|
|
152
|
+
async function handleSendReset(account: string) { /* 调用 API */ }
|
|
153
|
+
|
|
154
|
+
// 步骤 2:重置密码
|
|
155
|
+
async function handleReset(formData: Record<string, any>) { /* 调用 API */ }
|
|
156
|
+
|
|
157
|
+
// 步骤 3:完成 → 跳转登录
|
|
158
|
+
function handleDone() {
|
|
159
|
+
router.push('/login')
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## 路由配置
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
// 认证页路由统一约定
|
|
167
|
+
{
|
|
168
|
+
path: '/login',
|
|
169
|
+
name: 'Login',
|
|
170
|
+
component: () => import('@/views/login/index.vue'),
|
|
171
|
+
meta: {
|
|
172
|
+
title: '登录',
|
|
173
|
+
showLink: false, // 不在菜单显示
|
|
174
|
+
activePath: '/login', // 高亮路径
|
|
175
|
+
},
|
|
176
|
+
}
|
|
177
|
+
// 注册/忘记密码页同理:showLink: false + activePath
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## 表单校验模式
|
|
181
|
+
|
|
182
|
+
> 校验规则按业务实际调整,以下为常见模式。
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
import { loginRules } from '@/utils/rule'
|
|
186
|
+
|
|
187
|
+
// 必填校验
|
|
188
|
+
const rules = {
|
|
189
|
+
// 字段名按表单实际定义,不固定
|
|
190
|
+
account: [{ required: true, message: $t('请输入账号'), trigger: 'blur' }],
|
|
191
|
+
password: [{ required: true, message: $t('请输入密码'), trigger: 'blur' }],
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// 密码确认校验(注册/重置密码场景)
|
|
195
|
+
const confirmPasswordRule = {
|
|
196
|
+
validator: (rule: any, value: string, callback: any) => {
|
|
197
|
+
if (value !== formData.password) {
|
|
198
|
+
callback(new Error($t('两次密码不一致')))
|
|
199
|
+
} else {
|
|
200
|
+
callback()
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
trigger: 'blur',
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## Must-do 清单
|
|
208
|
+
|
|
209
|
+
1. **认证流程链路**:`API → useUserStore.login() → initRouter() → 跳转`,勿另起流程
|
|
210
|
+
2. **页面设计自由**:布局、背景、交互形式由设计主导,本模块不约束视觉
|
|
211
|
+
3. **API 字段动态**:参数和返回值字段按后端实际定义,勿硬编码字段名
|
|
212
|
+
4. **验证码组件**:见 `verify-captcha` 模块,不在本模块重复
|
|
213
|
+
5. **路由约定**:认证页 `showLink: false` 不在菜单显示,`activePath` 指向自身
|
|
214
|
+
6. **路由白名单**:登录/注册/忘记密码页在路由守卫白名单中,无需 token
|
|
215
|
+
7. **国际化**:所有提示文案用 `$t()` 包裹
|
|
216
|
+
8. **密码确认**:注册和重置密码须有确认密码字段 + 自定义校验
|
|
217
|
+
9. **loading 状态**:提交期间禁用按钮,防止重复提交
|
|
@@ -1,56 +1,56 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: base-code-dict
|
|
3
|
-
description: 基础代码字典获取、缓存、useApp().baseCodeGet、filterValue
|
|
4
|
-
scope: project
|
|
5
|
-
tags: [字典, baseCode, 码表, 下拉字典, 数据字典]
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# 基础代码(字典)
|
|
9
|
-
|
|
10
|
-
> 按本文件示例编写,复用 `useApp().baseCodeGet` / `filterValue` 等已有码表能力,勿另起一套字典请求与缓存。
|
|
11
|
-
|
|
12
|
-
规范基础代码(字典)的获取、缓存、映射与使用。在页面需要码表、枚举、下拉数据时参照。
|
|
13
|
-
|
|
14
|
-
## 获取基础代码
|
|
15
|
-
|
|
16
|
-
通过 `useApp().baseCodeGet(codeType)` 获取:
|
|
17
|
-
|
|
18
|
-
```typescript
|
|
19
|
-
import { useApp } from "@/hooks/useApp";
|
|
20
|
-
|
|
21
|
-
const { baseCodeGet, filterValue } = useApp();
|
|
22
|
-
const statusList = baseCodeGet("status");
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
## 特点
|
|
26
|
-
|
|
27
|
-
- 首次调用会自动发起请求并缓存到 `BaseCode` Store。
|
|
28
|
-
- 后续调用直接返回缓存数据。
|
|
29
|
-
- 如需刷新缓存,在 `params` 中传 `refresh: true`。
|
|
30
|
-
|
|
31
|
-
## 映射显示
|
|
32
|
-
|
|
33
|
-
```typescript
|
|
34
|
-
const label = filterValue(code, list, "code", "value");
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
- 默认字段名:`code` / `value`。
|
|
38
|
-
|
|
39
|
-
## 在模板中使用
|
|
40
|
-
|
|
41
|
-
```vue
|
|
42
|
-
<template>
|
|
43
|
-
<span>{{ filterValue(row.status, statusList) }}</span>
|
|
44
|
-
</template>
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
## Store 底层
|
|
48
|
-
|
|
49
|
-
- `src/store/modules/baseCode.ts` 维护 `baseCodeCache`。
|
|
50
|
-
- 接口:`getBaseCode({ codeType })`。
|
|
51
|
-
|
|
52
|
-
## 关键约定
|
|
53
|
-
|
|
54
|
-
1. 码表数据优先使用 `baseCodeGet`,避免重复请求。
|
|
55
|
-
2. 列表中码表回写统一使用 `filterValue`。
|
|
56
|
-
3. 不同模块相同码表使用相同 `codeType`。
|
|
1
|
+
---
|
|
2
|
+
name: base-code-dict
|
|
3
|
+
description: 基础代码字典获取、缓存、useApp().baseCodeGet、filterValue
|
|
4
|
+
scope: project
|
|
5
|
+
tags: [字典, baseCode, 码表, 下拉字典, 数据字典]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# 基础代码(字典)
|
|
9
|
+
|
|
10
|
+
> 按本文件示例编写,复用 `useApp().baseCodeGet` / `filterValue` 等已有码表能力,勿另起一套字典请求与缓存。
|
|
11
|
+
|
|
12
|
+
规范基础代码(字典)的获取、缓存、映射与使用。在页面需要码表、枚举、下拉数据时参照。
|
|
13
|
+
|
|
14
|
+
## 获取基础代码
|
|
15
|
+
|
|
16
|
+
通过 `useApp().baseCodeGet(codeType)` 获取:
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
import { useApp } from "@/hooks/useApp";
|
|
20
|
+
|
|
21
|
+
const { baseCodeGet, filterValue } = useApp();
|
|
22
|
+
const statusList = baseCodeGet("status");
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## 特点
|
|
26
|
+
|
|
27
|
+
- 首次调用会自动发起请求并缓存到 `BaseCode` Store。
|
|
28
|
+
- 后续调用直接返回缓存数据。
|
|
29
|
+
- 如需刷新缓存,在 `params` 中传 `refresh: true`。
|
|
30
|
+
|
|
31
|
+
## 映射显示
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
const label = filterValue(code, list, "code", "value");
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
- 默认字段名:`code` / `value`。
|
|
38
|
+
|
|
39
|
+
## 在模板中使用
|
|
40
|
+
|
|
41
|
+
```vue
|
|
42
|
+
<template>
|
|
43
|
+
<span>{{ filterValue(row.status, statusList) }}</span>
|
|
44
|
+
</template>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Store 底层
|
|
48
|
+
|
|
49
|
+
- `src/store/modules/baseCode.ts` 维护 `baseCodeCache`。
|
|
50
|
+
- 接口:`getBaseCode({ codeType })`。
|
|
51
|
+
|
|
52
|
+
## 关键约定
|
|
53
|
+
|
|
54
|
+
1. 码表数据优先使用 `baseCodeGet`,避免重复请求。
|
|
55
|
+
2. 列表中码表回写统一使用 `filterValue`。
|
|
56
|
+
3. 不同模块相同码表使用相同 `codeType`。
|