From f14077bc6fdf9e71acd321d5dc3a63f2276ad42d Mon Sep 17 00:00:00 2001 From: xiaoxian521 <1923740402@qq.com> Date: Tue, 25 Oct 2022 17:51:21 +0800 Subject: [PATCH] release: update `3.6.0` --- locales/en.yaml | 2 +- locales/zh-CN.yaml | 2 +- mock/asyncRoutes.ts | 37 ++++----- mock/login.ts | 36 ++++++++ mock/refreshToken.ts | 27 ++++++ package.json | 2 +- public/serverConfig.json | 2 +- src/api/routes.ts | 8 +- src/api/user.ts | 43 ++++++---- src/components/ReAuth/index.ts | 5 ++ src/components/ReAuth/src/auth.tsx | 20 +++++ src/directives/auth/index.ts | 13 +++ src/directives/index.ts | 2 +- src/directives/permission/index.ts | 18 ---- .../components/search/components/SearchModal.vue | 3 +- src/layout/components/setting/index.vue | 4 +- src/layout/components/sidebar/logo.vue | 6 ++ src/layout/components/sidebar/mixNav.vue | 2 +- src/layout/components/sidebar/vertical.vue | 5 +- src/layout/hooks/useNav.ts | 22 ++--- src/layout/types.ts | 2 +- src/main.ts | 4 + src/router/index.ts | 21 +++-- src/router/modules/error.ts | 2 +- src/router/types.ts | 1 + src/router/utils.ts | 92 +++++++++++++++------ src/store/modules/permission.ts | 37 +-------- src/store/modules/types.ts | 4 +- src/store/modules/user.ts | 88 ++++++++++++-------- src/style/element-plus.scss | 2 +- src/utils/auth.ts | 86 ++++++++++++------- src/utils/http/index.ts | 52 ++++++------ src/views/login/index.vue | 25 +++--- src/views/permission/button/index.vue | 96 ++++++++++++++++------ src/views/permission/page/index.vue | 96 +++++++++++++--------- types/global.d.ts | 1 + types/index.ts | 6 +- 37 files changed, 554 insertions(+), 320 deletions(-) create mode 100644 mock/login.ts create mode 100644 mock/refreshToken.ts create mode 100644 src/components/ReAuth/index.ts create mode 100644 src/components/ReAuth/src/auth.tsx create mode 100644 src/directives/auth/index.ts delete mode 100644 src/directives/permission/index.ts diff --git a/locales/en.yaml b/locales/en.yaml index 9b918ff..5d8c6bf 100644 --- a/locales/en.yaml +++ b/locales/en.yaml @@ -25,7 +25,7 @@ buttons: menus: hshome: Home hslogin: Login - hserror: Error Page + hsabnormal: Abnormal Page hsfourZeroFour: "404" hsfourZeroOne: "403" hsFive: "500" diff --git a/locales/zh-CN.yaml b/locales/zh-CN.yaml index 04edd55..64f52d9 100644 --- a/locales/zh-CN.yaml +++ b/locales/zh-CN.yaml @@ -25,7 +25,7 @@ buttons: menus: hshome: 首页 hslogin: 登录 - hserror: 错误页面 + hsabnormal: 异常页面 hsfourZeroFour: "404" hsfourZeroOne: "403" hsFive: "500" diff --git a/mock/asyncRoutes.ts b/mock/asyncRoutes.ts index 31585b9..2c1e638 100644 --- a/mock/asyncRoutes.ts +++ b/mock/asyncRoutes.ts @@ -1,18 +1,25 @@ -// 根据角色动态生成路由 +// 模拟后端动态生成路由 import { MockMethod } from "vite-plugin-mock"; +/** + * roles:页面级别权限,这里模拟二种 "admin"、"common" + * admin:管理员角色 + * common:普通角色 + */ + const permissionRouter = { path: "/permission", meta: { title: "menus.permission", icon: "lollipop", - rank: 7 + rank: 10 }, children: [ { path: "/permission/page/index", name: "PermissionPage", meta: { + roles: ["admin", "common"], title: "menus.permissionPage" } }, @@ -21,34 +28,22 @@ const permissionRouter = { name: "PermissionButton", meta: { title: "menus.permissionButton", - authority: [] + roles: ["admin", "common"], + auths: ["btn_add", "btn_edit", "btn_delete"] } } ] }; -// 添加不同按钮权限到/permission/button页面中 -function setDifAuthority(authority, routes) { - routes.children[1].meta.authority = [authority]; - return routes; -} - export default [ { url: "/getAsyncRoutes", method: "get", - response: ({ query }) => { - if (query.name === "admin") { - return { - code: 0, - info: [setDifAuthority("v-admin", permissionRouter)] - }; - } else { - return { - code: 0, - info: [setDifAuthority("v-test", permissionRouter)] - }; - } + response: () => { + return { + success: true, + data: [permissionRouter] + }; } } ] as MockMethod[]; diff --git a/mock/login.ts b/mock/login.ts new file mode 100644 index 0000000..cddd4e4 --- /dev/null +++ b/mock/login.ts @@ -0,0 +1,36 @@ +// 根据角色动态生成路由 +import { MockMethod } from "vite-plugin-mock"; + +export default [ + { + url: "/login", + method: "post", + response: ({ body }) => { + if (body.username === "admin") { + return { + success: true, + data: { + username: "admin", + // 一个用户可能有多个角色 + roles: ["admin"], + accessToken: "eyJhbGciOiJIUzUxMiJ9.admin", + refreshToken: "eyJhbGciOiJIUzUxMiJ9.adminRefresh", + expires: "2023/10/30 00:00:00" + } + }; + } else { + return { + success: true, + data: { + username: "common", + // 一个用户可能有多个角色 + roles: ["common"], + accessToken: "eyJhbGciOiJIUzUxMiJ9.common", + refreshToken: "eyJhbGciOiJIUzUxMiJ9.commonRefresh", + expires: "2023/10/30 00:00:00" + } + }; + } + } + } +] as MockMethod[]; diff --git a/mock/refreshToken.ts b/mock/refreshToken.ts new file mode 100644 index 0000000..dfdb711 --- /dev/null +++ b/mock/refreshToken.ts @@ -0,0 +1,27 @@ +import { MockMethod } from "vite-plugin-mock"; + +// 模拟刷新token接口 +export default [ + { + url: "/refreshToken", + method: "post", + response: ({ body }) => { + if (body.refreshToken) { + return { + success: true, + data: { + accessToken: "eyJhbGciOiJIUzUxMiJ9.admin", + refreshToken: "eyJhbGciOiJIUzUxMiJ9.adminRefresh", + // `expires`选择这种日期格式是为了方便调试,后端直接设置时间戳或许更方便(每次都应该递增)。如果后端返回的是时间戳格式,前端开发请来到这个目录`src/utils/auth.ts`,把第`38`行的代码换成expires = data.expires即可。 + expires: "2023/10/30 23:59:59" + } + }; + } else { + return { + success: false, + data: {} + }; + } + } + } +] as MockMethod[]; diff --git a/package.json b/package.json index 9388b96..60adc1d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pure-admin-thin", - "version": "3.5.0", + "version": "3.6.0", "private": true, "scripts": { "dev": "NODE_OPTIONS=--max-old-space-size=4096 vite", diff --git a/public/serverConfig.json b/public/serverConfig.json index e10bdd3..ebf0fd6 100644 --- a/public/serverConfig.json +++ b/public/serverConfig.json @@ -1,5 +1,5 @@ { - "Version": "3.5.0", + "Version": "3.6.0", "Title": "PureAdmin", "FixedHeader": true, "HiddenSideBar": false, diff --git a/src/api/routes.ts b/src/api/routes.ts index 7da04fb..37f5e8f 100644 --- a/src/api/routes.ts +++ b/src/api/routes.ts @@ -1,10 +1,10 @@ import { http } from "../utils/http"; type Result = { - code: number; - info: Array; + success: boolean; + data: Array; }; -export const getAsyncRoutes = (params?: object) => { - return http.request("get", "/getAsyncRoutes", { params }); +export const getAsyncRoutes = () => { + return http.request("get", "/getAsyncRoutes"); }; diff --git a/src/api/user.ts b/src/api/user.ts index 3965ab5..8893dba 100644 --- a/src/api/user.ts +++ b/src/api/user.ts @@ -1,26 +1,39 @@ import { http } from "../utils/http"; -type Result = { - svg?: string; - code?: number; - info?: object; +export type UserResult = { + success: boolean; + data: { + /** 用户名 */ + username: string; + /** 当前登陆用户的角色 */ + roles: Array; + /** `token` */ + accessToken: string; + /** 用于调用刷新`accessToken`的接口时所需的`token` */ + refreshToken: string; + /** `accessToken`的过期时间(格式'xxxx/xx/xx xx:xx:xx') */ + expires: Date; + }; }; -/** 获取验证码 */ -export const getVerify = () => { - return http.request("get", "/captcha"); +export type RefreshTokenResult = { + success: boolean; + data: { + /** `token` */ + accessToken: string; + /** 用于调用刷新`accessToken`的接口时所需的`token` */ + refreshToken: string; + /** `accessToken`的过期时间(格式'xxxx/xx/xx xx:xx:xx') */ + expires: Date; + }; }; /** 登录 */ -export const getLogin = (data: object) => { - return http.request("post", "/login", { data }); +export const getLogin = (data?: object) => { + return http.request("post", "/login", { data }); }; /** 刷新token */ -export const refreshToken = (data: object) => { - return http.request("post", "/refreshToken", { data }); +export const refreshTokenApi = (data?: object) => { + return http.request("post", "/refreshToken", { data }); }; - -// export const searchVague = (data: object) => { -// return http.request("post", "/searchVague", { data }); -// }; diff --git a/src/components/ReAuth/index.ts b/src/components/ReAuth/index.ts new file mode 100644 index 0000000..975ed2c --- /dev/null +++ b/src/components/ReAuth/index.ts @@ -0,0 +1,5 @@ +import auth from "./src/auth"; + +const Auth = auth; + +export { Auth }; diff --git a/src/components/ReAuth/src/auth.tsx b/src/components/ReAuth/src/auth.tsx new file mode 100644 index 0000000..4425658 --- /dev/null +++ b/src/components/ReAuth/src/auth.tsx @@ -0,0 +1,20 @@ +import { defineComponent, Fragment } from "vue"; +import { hasAuth } from "/@/router/utils"; + +export default defineComponent({ + name: "Auth", + props: { + value: { + type: undefined, + default: [] + } + }, + setup(props, { slots }) { + return () => { + if (!slots) return null; + return hasAuth(props.value) ? ( + {slots.default?.()} + ) : null; + }; + } +}); diff --git a/src/directives/auth/index.ts b/src/directives/auth/index.ts new file mode 100644 index 0000000..306dfd3 --- /dev/null +++ b/src/directives/auth/index.ts @@ -0,0 +1,13 @@ +import { hasAuth } from "/@/router/utils"; +import { Directive, type DirectiveBinding } from "vue"; + +export const auth: Directive = { + mounted(el: HTMLElement, binding: DirectiveBinding) { + const { value } = binding; + if (value) { + !hasAuth(value) && el.parentNode.removeChild(el); + } else { + throw new Error("need auths! Like v-auth=\"['btn.add','btn.edit']\""); + } + } +}; diff --git a/src/directives/index.ts b/src/directives/index.ts index ca528d7..d6d6592 100644 --- a/src/directives/index.ts +++ b/src/directives/index.ts @@ -1,2 +1,2 @@ -export * from "./permission"; +export * from "./auth"; export * from "./elResizeDetector"; diff --git a/src/directives/permission/index.ts b/src/directives/permission/index.ts deleted file mode 100644 index c311508..0000000 --- a/src/directives/permission/index.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { usePermissionStoreHook } from "/@/store/modules/permission"; -import { Directive } from "vue"; -import type { DirectiveBinding } from "vue"; - -export const auth: Directive = { - mounted(el: HTMLElement, binding: DirectiveBinding) { - const { value } = binding; - if (value) { - const authRoles = value; - const hasAuth = usePermissionStoreHook().buttonAuth.includes(authRoles); - if (!hasAuth) { - el.parentNode.removeChild(el); - } - } else { - throw new Error("need roles! Like v-auth=\"['admin','test']\""); - } - } -}; diff --git a/src/layout/components/search/components/SearchModal.vue b/src/layout/components/search/components/SearchModal.vue index 593e631..5b6cd24 100644 --- a/src/layout/components/search/components/SearchModal.vue +++ b/src/layout/components/search/components/SearchModal.vue @@ -1,5 +1,6 @@ + + diff --git a/src/views/permission/page/index.vue b/src/views/permission/page/index.vue index 57c5d50..ef084f0 100644 --- a/src/views/permission/page/index.vue +++ b/src/views/permission/page/index.vue @@ -1,53 +1,69 @@ + + diff --git a/types/global.d.ts b/types/global.d.ts index 191f61c..a8caa0e 100644 --- a/types/global.d.ts +++ b/types/global.d.ts @@ -14,6 +14,7 @@ declare module "vue" { IconifyIconOffline: typeof import("../src/components/ReIcon")["IconifyIconOffline"]; IconifyIconOnline: typeof import("../src/components/ReIcon")["IconifyIconOnline"]; FontIcon: typeof import("../src/components/ReIcon")["FontIcon"]; + Auth: typeof import("../src/components/ReAuth")["Auth"]; } } diff --git a/types/index.ts b/types/index.ts index c6d41bb..017550a 100644 --- a/types/index.ts +++ b/types/index.ts @@ -74,8 +74,10 @@ export interface RouteChildrenConfigsTable { showLink?: boolean; /** 是否显示父级菜单 `可选` */ showParent?: boolean; - /** 路由权限设置 `可选` */ - authority?: Array; + /** 页面级别权限设置 `可选` */ + roles?: Array; + /** 按钮级别权限设置 `可选` */ + auths?: Array; /** 路由组件缓存(开启 `true`、关闭 `false`)`可选` */ keepAlive?: boolean; /** 内嵌的`iframe`链接 `可选` */