Skip to content

Commit 5b9a418

Browse files
uyarntimi137137
andauthored
feat: add backend dynamic router permission code (#394)
* chore: 大致雏形 * feat: complete permission code * feat: 修复渲染问题并完善权限代码 * chore: release 0.7.0 * chore: 更新依赖 * chore: fix echarts version * feat: upgrade dependencies * chore: mock route map * chore: hash router * chore: concat fixed routers * chore: fix dependencies * feat: optimize * chore: remove roles from get menu process * chore: remain fe permssion code Co-authored-by: 悠静萝莉 <i@mikuhl.cn>
1 parent 56189da commit 5b9a418

24 files changed

Lines changed: 637 additions & 380 deletions

.env

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# 打包路径 根据项目不同按需配置
2-
VITE_BASE_URL = /
2+
VITE_BASE_URL = /

.env.site

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# 打包路径 根据项目不同按需配置
2-
VITE_BASE_URL = https://static.tdesign.tencent.com/starter/vue-next/
2+
VITE_BASE_URL = https://static.tdesign.tencent.com/starter/vue-next/

mock/index.ts

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,4 +144,174 @@ export default [
144144
},
145145
},
146146
},
147+
{
148+
url: '/api/get-menu-list',
149+
method: 'get',
150+
timeout: 2000,
151+
response: {
152+
code: 0,
153+
data: {
154+
...Mock.mock({
155+
list: [
156+
{
157+
path: '/list',
158+
name: 'list',
159+
component: 'LAYOUT',
160+
redirect: '/list/base',
161+
meta: {
162+
title: '列表页',
163+
icon: 'view-list',
164+
},
165+
children: [
166+
{
167+
path: 'base',
168+
name: 'ListBase',
169+
component: '/list/base/index',
170+
meta: {
171+
title: '基础列表页',
172+
},
173+
},
174+
{
175+
path: 'card',
176+
name: 'ListCard',
177+
component: '/list/card/index',
178+
meta: {
179+
title: '卡片列表页',
180+
},
181+
},
182+
{
183+
path: 'filter',
184+
name: 'ListFilter',
185+
component: '/list/filter/index',
186+
meta: {
187+
title: '筛选列表页',
188+
},
189+
},
190+
{
191+
path: 'tree',
192+
name: 'ListTree',
193+
component: '/list/tree/index',
194+
meta: {
195+
title: '树状筛选列表页',
196+
},
197+
},
198+
],
199+
},
200+
{
201+
path: '/form',
202+
name: 'form',
203+
component: 'LAYOUT',
204+
redirect: '/form/base',
205+
meta: {
206+
title: '表单页',
207+
icon: 'edit-1',
208+
},
209+
children: [
210+
{
211+
path: 'base',
212+
name: 'FormBase',
213+
component: '/form/base/index',
214+
meta: {
215+
title: '基础表单页',
216+
},
217+
},
218+
{
219+
path: 'step',
220+
name: 'FormStep',
221+
component: '/form/step/index',
222+
meta: {
223+
title: '分步表单页',
224+
},
225+
},
226+
],
227+
},
228+
{
229+
path: '/detail',
230+
name: 'detail',
231+
component: 'LAYOUT',
232+
redirect: '/detail/base',
233+
meta: {
234+
title: '详情页',
235+
icon: 'layers',
236+
},
237+
children: [
238+
{
239+
path: 'base',
240+
name: 'DetailBase',
241+
component: '/detail/base/index',
242+
meta: {
243+
title: '基础详情页',
244+
},
245+
},
246+
{
247+
path: 'advanced',
248+
name: 'DetailAdvanced',
249+
component: '/detail/advanced/index',
250+
meta: {
251+
title: '多卡片详情页',
252+
},
253+
},
254+
{
255+
path: 'deploy',
256+
name: 'DetailDeploy',
257+
component: '/detail/deploy/index',
258+
meta: {
259+
title: '数据详情页',
260+
},
261+
},
262+
{
263+
path: 'secondary',
264+
name: 'DetailSecondary',
265+
component: '/detail/secondary/index',
266+
meta: {
267+
title: '二级详情页',
268+
},
269+
},
270+
],
271+
},
272+
{
273+
path: '/frame',
274+
name: 'Frame',
275+
component: 'Layout',
276+
redirect: '/frame/doc',
277+
meta: {
278+
icon: 'internet',
279+
title: '外部页面',
280+
},
281+
children: [
282+
{
283+
path: 'doc',
284+
name: 'Doc',
285+
component: 'IFrame',
286+
meta: {
287+
frameSrc: 'https://tdesign.tencent.com/starter/docs/vue-next/get-started',
288+
title: '使用文档(内嵌)',
289+
},
290+
},
291+
{
292+
path: 'TDesign',
293+
name: 'TDesign',
294+
component: 'IFrame',
295+
meta: {
296+
frameSrc: 'https://tdesign.tencent.com/vue-next/getting-started',
297+
title: 'TDesign 文档(内嵌)',
298+
},
299+
},
300+
{
301+
path: 'TDesign2',
302+
name: 'TDesign2',
303+
component: 'IFrame',
304+
meta: {
305+
frameSrc: 'https://tdesign.tencent.com/vue-next/getting-started',
306+
frameBlank: true,
307+
title: 'TDesign 文档(外链)',
308+
},
309+
},
310+
],
311+
},
312+
],
313+
}),
314+
},
315+
},
316+
},
147317
] as MockMethod[];

package.json

Lines changed: 38 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "tdesign-vue-next-starter",
3-
"version": "0.6.1",
3+
"version": "0.7.0",
44
"scripts": {
55
"dev:mock": "vite --open --mode mock",
66
"dev": "vite --open --mode development",
@@ -19,58 +19,59 @@
1919
"test:coverage": "echo \"no test:coverage specified,work in process\""
2020
},
2121
"dependencies": {
22-
"axios": "^1.1.3",
23-
"dayjs": "^1.10.6",
24-
"echarts": "~5.1.2",
22+
"@types/nprogress": "^0.2.0",
23+
"axios": "^1.2.2",
24+
"dayjs": "^1.11.7",
25+
"echarts": "5.1.2",
2526
"lodash": "^4.17.21",
2627
"nprogress": "^0.2.0",
27-
"pinia": "^2.0.11",
28-
"pinia-plugin-persistedstate": "^3.0.1",
29-
"qrcode.vue": "^3.2.2",
30-
"qs": "^6.10.5",
28+
"pinia": "^2.0.28",
29+
"pinia-plugin-persistedstate": "^3.0.2",
30+
"qrcode.vue": "^3.3.3",
31+
"qs": "^6.11.0",
3132
"tdesign-icons-vue-next": "^0.1.7",
3233
"tdesign-vue-next": "^1.0.0",
3334
"tvision-color": "^1.5.0",
34-
"vue": "^3.2.31",
35+
"vue": "^3.2.45",
3536
"vue-clipboard3": "^2.0.0",
36-
"vue-router": "~4.1.5"
37+
"vue-router": "~4.1.6"
3738
},
3839
"devDependencies": {
39-
"@commitlint/cli": "^17.0.3",
40-
"@commitlint/config-conventional": "^17.0.3",
41-
"@types/echarts": "^4.9.10",
42-
"@types/lodash": "^4.14.182",
40+
"@commitlint/cli": "^17.3.0",
41+
"@commitlint/config-conventional": "^17.3.0",
42+
"@types/echarts": "^4.9.16",
43+
"@types/lodash": "^4.14.191",
4344
"@types/qs": "^6.9.7",
44-
"@types/ws": "^8.2.2",
45-
"@typescript-eslint/eslint-plugin": "^4.29.3",
46-
"@typescript-eslint/parser": "^4.29.3",
47-
"@vitejs/plugin-vue": "^2.3.1",
45+
"@types/ws": "^8.5.3",
46+
"@typescript-eslint/eslint-plugin": "^5.47.1",
47+
"@typescript-eslint/parser": "^5.47.1",
48+
"@vitejs/plugin-vue": "^3.2.0",
4849
"@vitejs/plugin-vue-jsx": "^1.1.7",
49-
"@vue/compiler-sfc": "^3.0.5",
50-
"@vue/eslint-config-typescript": "^11.0.0",
50+
"@vue/compiler-sfc": "^3.2.45",
51+
"@vue/eslint-config-typescript": "^11.0.2",
5152
"commitizen": "^4.2.4",
5253
"cz-conventional-changelog": "^3.3.0",
53-
"eslint": "^7.32.0",
54+
"eslint": "^8.30.0",
5455
"eslint-config-airbnb-base": "^15.0.0",
55-
"eslint-config-prettier": "^8.3.0",
56-
"eslint-plugin-import": "^2.24.2",
57-
"eslint-plugin-prettier": "^4.0.0",
58-
"eslint-plugin-vue": "^9.2.0",
56+
"eslint-config-prettier": "^8.5.0",
57+
"eslint-plugin-import": "^2.26.0",
58+
"eslint-plugin-prettier": "^4.2.1",
59+
"eslint-plugin-vue": "^9.8.0",
5960
"eslint-plugin-vue-scoped-css": "^2.2.0",
60-
"husky": "^7.0.4",
61-
"less": "^4.1.1",
62-
"lint-staged": "^12.1.2",
61+
"husky": "^8.0.2",
62+
"less": "^4.1.3",
63+
"lint-staged": "^13.1.0",
6364
"mockjs": "^1.1.0",
64-
"prettier": "^2.4.1",
65-
"stylelint": "~13.13.1",
66-
"stylelint-config-prettier": "~9.0.3",
67-
"stylelint-less": "1.0.1",
68-
"stylelint-order": "~4.1.0",
69-
"typescript": "~4.8.4",
70-
"vite": "^2.7.1",
65+
"prettier": "^2.8.1",
66+
"stylelint": "~14.9.1",
67+
"stylelint-config-prettier": "~9.0.4",
68+
"stylelint-less": "1.0.6",
69+
"stylelint-order": "~6.0.1",
70+
"typescript": "~4.9.4",
71+
"vite": "^3.0.3",
7172
"vite-plugin-mock": "^2.9.6",
72-
"vite-svg-loader": "^3.1.0",
73-
"vue-tsc": "^1.0.8"
73+
"vite-svg-loader": "^4.0.0",
74+
"vue-tsc": "^1.0.19"
7475
},
7576
"config": {
7677
"commitizen": {

src/api/model/permissionModel.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { defineComponent } from 'vue';
2+
3+
export interface MenuListResult {
4+
list: Array<RouteItem>;
5+
}
6+
7+
export type Component<T = any> =
8+
| ReturnType<typeof defineComponent>
9+
| (() => Promise<typeof import('*.vue')>)
10+
| (() => Promise<T>);
11+
12+
export interface RouteItem {
13+
path: string;
14+
name: string;
15+
component?: Component | string;
16+
components?: Component;
17+
redirect?: string;
18+
meta: RouteMeta;
19+
children?: Array<RouteItem>;
20+
}
21+
export interface RouteMeta {
22+
title: string;
23+
icon?: string;
24+
expanded?: boolean;
25+
orderNo?: number;
26+
hidden?: boolean;
27+
hiddenBreadcrumb?: boolean;
28+
single?: boolean;
29+
}

src/api/permission.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { request } from '@/utils/request';
2+
import type { MenuListResult } from '@/api/model/permissionModel';
3+
4+
const Api = {
5+
MenuList: '/get-menu-list',
6+
};
7+
8+
export function getMenuList() {
9+
return request.get<MenuListResult>({
10+
url: Api.MenuList,
11+
});
12+
}

src/constants/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,10 @@ export const NOTIFICATION_TYPES = {
4040
middle: 'warning',
4141
high: 'danger',
4242
};
43+
44+
// 通用请求头
45+
export enum ContentTypeEnum {
46+
Json = 'application/json;charset=UTF-8',
47+
FormURLEncoded = 'application/x-www-form-urlencoded;charset=UTF-8',
48+
FormData = 'multipart/form-data;charset=UTF-8',
49+
}

0 commit comments

Comments
 (0)