mirror of
https://github.com/pure-admin/pure-admin-thin.git
synced 2025-04-24 23:47:17 +08:00
feat: 修改登录界面,登录验证使用后端接口,修改侧边栏
This commit is contained in:
parent
ff27074ebd
commit
a3887dde7a
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@ -25,7 +25,7 @@
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": true
|
||||
"source.fixAll.eslint": "explicit"
|
||||
},
|
||||
"iconify.excludes": ["el"]
|
||||
}
|
||||
|
@ -1,36 +0,0 @@
|
||||
<h1>vue-pure-admin Lite Edition(no i18n version)</h1>
|
||||
|
||||
[](LICENSE)
|
||||
|
||||
**English** | [中文](./README.md)
|
||||
|
||||
## Introduce
|
||||
|
||||
The simplified version is based on the shelf extracted from [vue-pure-admin](https://github.com/pure-admin/vue-pure-admin), which contains main functions and is more suitable for actual project development. The packaged size is introduced globally [element-plus](https://element-plus.org) is still below `2.3MB`, and the full version of the code will be permanently synchronized. After enabling `brotli` compression and `cdn` to replace the local library mode, the package size is less than `350kb`
|
||||
|
||||
## Supporting Video
|
||||
|
||||
- [Click Watch Tutorial](https://www.bilibili.com/video/BV1kg411v7QT)
|
||||
- [Click Watch UI Design](https://www.bilibili.com/video/BV17g411T7rq)
|
||||
|
||||
## Docs
|
||||
|
||||
- [documentation site](https://yiming_chang.gitee.io/pure-admin-doc)
|
||||
|
||||
## Preview
|
||||
|
||||
- [Click me to view the preview station](https://pure-admin-thin.netlify.app/#/login)
|
||||
|
||||
## Maintainer
|
||||
|
||||
[xiaoxian521](https://github.com/xiaoxian521)
|
||||
|
||||
## ⚠️ Attention
|
||||
|
||||
- The Lite version does not accept any issues and prs. If you have any questions, please go to the full version [issues](https://github.com/pure-admin/vue-pure-admin/issues/new/choose) to mention, thank you!
|
||||
|
||||
## License
|
||||
|
||||
In principle, no fees and copyrights are charged, and it is commercially available, but if you need secondary open source (such as using this platform for secondary development and open source, the front-end code must be open source and free), please contact the author for permission! (Free, just take a record)
|
||||
|
||||
[MIT © 2020-present, pure-admin](./LICENSE)
|
53
README.md
53
README.md
@ -1,40 +1,47 @@
|
||||
<h1>vue-pure-admin精简版(非国际化版本)</h1>
|
||||
### 前端(Vue.js)命名规范
|
||||
|
||||
[](LICENSE)
|
||||
#### 变量命名
|
||||
|
||||
**中文** | [English](./README.en-US.md)
|
||||
- 使用驼峰命名法(camelCase)来命名变量,首字母小写。
|
||||
- 示例:`userInfo`, `selectedItem`.
|
||||
|
||||
## 介绍
|
||||
#### 函数命名
|
||||
|
||||
精简版是基于 [vue-pure-admin](https://github.com/pure-admin/vue-pure-admin) 提炼出的架子,包含主体功能,更适合实际项目开发,打包后的大小在全局引入 [element-plus](https://element-plus.org) 的情况下仍然低于 `2.3MB`,并且会永久同步完整版的代码。开启 `brotli` 压缩和 `cdn` 替换本地库模式后,打包大小低于 `350kb`
|
||||
- 同样使用驼峰命名法,以动词开头描述函数的操作。
|
||||
- 示例:`getUserData()`, `updateUserProfile()`.
|
||||
|
||||
## 版本选择
|
||||
#### 组件命名
|
||||
|
||||
当前是非国际化版本,如果您需要国际化版本 [请点击](https://github.com/pure-admin/pure-admin-thin/tree/i18n)
|
||||
- 使用帕斯卡命名法(PascalCase)来命名组件,每个单词的首字母都大写。
|
||||
- 示例:`UserProfile`, `ProductList`.
|
||||
|
||||
## 配套视频
|
||||
#### 文件命名
|
||||
|
||||
- [点我查看教程](https://www.bilibili.com/video/BV1kg411v7QT)
|
||||
- [点我查看 UI 设计](https://www.bilibili.com/video/BV17g411T7rq)
|
||||
- 使用帕斯卡命名法来命名 Vue 组件文件,同时在文件名中体现出组件的用途。
|
||||
- 示例:`UserProfile.vue`, `ProductList.vue`.
|
||||
|
||||
## 配套保姆级文档
|
||||
#### 常量命名
|
||||
|
||||
- [查看文档](https://yiming_chang.gitee.io/pure-admin-doc)
|
||||
- 常量全部大写,多个单词间使用下划线分隔。
|
||||
- 示例:`MAX_ITEMS`, `API_ENDPOINTS`.
|
||||
|
||||
## 预览
|
||||
#### CSS 类名
|
||||
|
||||
- [查看预览](https://pure-admin-thin.netlify.app/#/login)
|
||||
- 使用连字符(kebab-case)来命名类名,保持一致。
|
||||
- 示例:`user-profile`, `product-card`.
|
||||
|
||||
## 维护者
|
||||
#### 路由命名和地址规范
|
||||
|
||||
[xiaoxian521](https://github.com/xiaoxian521)
|
||||
- 使用小写字母和连字符(kebab-case)来命名路由地址。
|
||||
- 示例:`/user-profile`.
|
||||
|
||||
## ⚠️ 注意
|
||||
---
|
||||
|
||||
- 精简版不接受任何 `issues` 和 `pr`,如果有问题请到完整版 [issues](https://github.com/pure-admin/vue-pure-admin/issues/new/choose) 去提,谢谢!
|
||||
### 运行命令:
|
||||
|
||||
## 许可证
|
||||
|
||||
原则上不收取任何费用及版权,可商用,不过如需二次开源(比如用此平台二次开发并开源,要求前端代码必须开源免费)请联系作者获取许可!(免费,走个记录而已)
|
||||
|
||||
[MIT © 2020-present, pure-admin](./LICENSE)
|
||||
```bash
|
||||
npm install -g pnpm # 下载 pnpm
|
||||
pnpm install # 下载配置项
|
||||
pnpm dev # 运行
|
||||
pnpm build # 打包
|
||||
```
|
||||
|
@ -2,7 +2,7 @@ import type { Plugin } from "vite";
|
||||
import dayjs, { Dayjs } from "dayjs";
|
||||
import utils from "@pureadmin/utils";
|
||||
import duration from "dayjs/plugin/duration";
|
||||
import { green, blue, bold } from "picocolors";
|
||||
import { green, bold } from "picocolors";
|
||||
dayjs.extend(duration);
|
||||
|
||||
export function viteBuildInfo(): Plugin {
|
||||
@ -17,15 +17,6 @@ export function viteBuildInfo(): Plugin {
|
||||
outDir = resolvedConfig.build?.outDir ?? "dist";
|
||||
},
|
||||
buildStart() {
|
||||
console.log(
|
||||
bold(
|
||||
green(
|
||||
`👏欢迎使用${blue(
|
||||
"[vue-pure-admin]"
|
||||
)},如果您感觉不错,记得点击后面链接给个star哦💖 https://github.com/pure-admin/vue-pure-admin`
|
||||
)
|
||||
)
|
||||
);
|
||||
if (config.command === "build") {
|
||||
startTime = dayjs(new Date());
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ const permissionRouter = {
|
||||
path: "/permission",
|
||||
meta: {
|
||||
title: "权限管理",
|
||||
icon: "lollipop",
|
||||
icon: "informationLine",
|
||||
rank: 10
|
||||
},
|
||||
children: [
|
||||
|
3572
pnpm-lock.yaml
generated
3572
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
{
|
||||
"Version": "4.5.0",
|
||||
"Title": "PureAdmin",
|
||||
"Title": "Mine processing",
|
||||
"FixedHeader": true,
|
||||
"HiddenSideBar": false,
|
||||
"MultiTagsCache": false,
|
||||
|
1
src/api/qa.ts
Normal file
1
src/api/qa.ts
Normal file
@ -0,0 +1 @@
|
||||
// import { http } from "@/utils/http";
|
@ -1,10 +1,19 @@
|
||||
import { http } from "@/utils/http";
|
||||
|
||||
type Result = {
|
||||
success: boolean;
|
||||
data: Array<any>;
|
||||
// type Result = {
|
||||
// success: boolean;
|
||||
// data: Array<any>;
|
||||
// };
|
||||
|
||||
type HelloMessageResult = {
|
||||
message: string;
|
||||
};
|
||||
|
||||
export const getAsyncRoutes = () => {
|
||||
return http.request<Result>("get", "/getAsyncRoutes");
|
||||
// mock 中的添加路由的接口,用不到注释掉了
|
||||
// export const getAsyncRoutes = () => {
|
||||
// return http.request<Result>("get", "/getAsyncRoutes");
|
||||
// };
|
||||
|
||||
export const getHelloMessage = () => {
|
||||
return http.request<HelloMessageResult>("get", "http://127.0.0.1:5005/hello");
|
||||
};
|
||||
|
@ -28,9 +28,11 @@ export type RefreshTokenResult = {
|
||||
};
|
||||
};
|
||||
|
||||
/** 登录 */
|
||||
/** 登录 使用后端实现,不再使用 mock 中*/
|
||||
export const getLogin = (data?: object) => {
|
||||
return http.request<UserResult>("post", "/login", { data });
|
||||
return http.request<UserResult>("post", "http://127.0.0.1:5005/login", {
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
/** 刷新token */
|
||||
|
BIN
src/assets/login/logo.jpg
Normal file
BIN
src/assets/login/logo.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 34 KiB |
@ -1,36 +0,0 @@
|
||||
export default {
|
||||
path: "/error",
|
||||
redirect: "/error/403",
|
||||
meta: {
|
||||
icon: "informationLine",
|
||||
title: "异常页面",
|
||||
// showLink: false,
|
||||
rank: 9
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "/error/403",
|
||||
name: "403",
|
||||
component: () => import("@/views/error/403.vue"),
|
||||
meta: {
|
||||
title: "403"
|
||||
}
|
||||
},
|
||||
{
|
||||
path: "/error/404",
|
||||
name: "404",
|
||||
component: () => import("@/views/error/404.vue"),
|
||||
meta: {
|
||||
title: "404"
|
||||
}
|
||||
},
|
||||
{
|
||||
path: "/error/500",
|
||||
name: "500",
|
||||
component: () => import("@/views/error/500.vue"),
|
||||
meta: {
|
||||
title: "500"
|
||||
}
|
||||
}
|
||||
]
|
||||
} as RouteConfigsTable;
|
29
src/router/modules/qa.ts
Normal file
29
src/router/modules/qa.ts
Normal file
@ -0,0 +1,29 @@
|
||||
export default {
|
||||
path: "/qa",
|
||||
redirect: "/qa/chat",
|
||||
component: () => import("@/views/qa/index.vue"),
|
||||
meta: {
|
||||
icon: "lollipop",
|
||||
title: "问答系统",
|
||||
// showLink: false,
|
||||
rank: 10
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "/qa/chat",
|
||||
name: "chat",
|
||||
component: () => import("@/views/qa/chat/index.vue"),
|
||||
meta: {
|
||||
title: "对话"
|
||||
}
|
||||
},
|
||||
{
|
||||
path: "/qa/triad",
|
||||
name: "triad",
|
||||
component: () => import("@/views/qa/triad/index.vue"),
|
||||
meta: {
|
||||
title: "三元组"
|
||||
}
|
||||
}
|
||||
]
|
||||
} as RouteConfigsTable;
|
@ -16,7 +16,7 @@ import {
|
||||
storageSession,
|
||||
isIncludeAllChildren
|
||||
} from "@pureadmin/utils";
|
||||
import { getConfig } from "@/config";
|
||||
// import { getConfig } from "@/config";
|
||||
import { menuType } from "@/layout/types";
|
||||
import { buildHierarchyTree } from "@/utils/tree";
|
||||
import { sessionKey, type DataInfo } from "@/utils/auth";
|
||||
@ -27,7 +27,7 @@ const IFrame = () => import("@/layout/frameView.vue");
|
||||
const modulesRoutes = import.meta.glob("/src/views/**/*.{vue,tsx}");
|
||||
|
||||
// 动态路由
|
||||
import { getAsyncRoutes } from "@/api/routes";
|
||||
// import { getAsyncRoutes } from "@/api/routes";
|
||||
|
||||
function handRank(routeInfo: any) {
|
||||
const { name, path, parentId, meta } = routeInfo;
|
||||
@ -181,34 +181,44 @@ function handleAsyncRoutes(routeList) {
|
||||
addPathMatch();
|
||||
}
|
||||
|
||||
/** 初始化路由(`new Promise` 写法防止在异步请求中造成无限循环)*/
|
||||
// function initRouter() {
|
||||
// if (getConfig()?.CachingAsyncRoutes) {
|
||||
// // 开启动态路由缓存本地sessionStorage
|
||||
// const key = "async-routes";
|
||||
// const asyncRouteList = storageSession().getItem(key) as any;
|
||||
// if (asyncRouteList && asyncRouteList?.length > 0) {
|
||||
// return new Promise(resolve => {
|
||||
// handleAsyncRoutes(asyncRouteList);
|
||||
// resolve(router);
|
||||
// });
|
||||
// } else {
|
||||
// return new Promise(resolve => {
|
||||
// getAsyncRoutes().then(({ data }) => {
|
||||
// handleAsyncRoutes(cloneDeep(data));
|
||||
// storageSession().setItem(key, data);
|
||||
// resolve(router);
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
// } else {
|
||||
// return new Promise(resolve => {
|
||||
// getAsyncRoutes().then(({ data }) => {
|
||||
// handleAsyncRoutes(cloneDeep(data));
|
||||
// resolve(router);
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
|
||||
/** 初始化路由(`new Promise` 写法防止在异步请求中造成无限循环)*/
|
||||
function initRouter() {
|
||||
if (getConfig()?.CachingAsyncRoutes) {
|
||||
// 开启动态路由缓存本地sessionStorage
|
||||
const key = "async-routes";
|
||||
const asyncRouteList = storageSession().getItem(key) as any;
|
||||
if (asyncRouteList && asyncRouteList?.length > 0) {
|
||||
return new Promise(resolve => {
|
||||
handleAsyncRoutes(asyncRouteList);
|
||||
// 假设有静态路由配置
|
||||
const staticRoutes = [];
|
||||
handleAsyncRoutes(staticRoutes);
|
||||
resolve(router);
|
||||
});
|
||||
} else {
|
||||
return new Promise(resolve => {
|
||||
getAsyncRoutes().then(({ data }) => {
|
||||
handleAsyncRoutes(cloneDeep(data));
|
||||
storageSession().setItem(key, data);
|
||||
resolve(router);
|
||||
});
|
||||
});
|
||||
}
|
||||
} else {
|
||||
return new Promise(resolve => {
|
||||
getAsyncRoutes().then(({ data }) => {
|
||||
handleAsyncRoutes(cloneDeep(data));
|
||||
resolve(router);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,70 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { useRouter } from "vue-router";
|
||||
import noAccess from "@/assets/status/403.svg?component";
|
||||
|
||||
defineOptions({
|
||||
name: "403"
|
||||
});
|
||||
|
||||
const router = useRouter();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex justify-center items-center h-[640px]">
|
||||
<noAccess />
|
||||
<div class="ml-12">
|
||||
<p
|
||||
class="font-medium text-4xl mb-4 dark:text-white"
|
||||
v-motion
|
||||
:initial="{
|
||||
opacity: 0,
|
||||
y: 100
|
||||
}"
|
||||
:enter="{
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
transition: {
|
||||
delay: 100
|
||||
}
|
||||
}"
|
||||
>
|
||||
403
|
||||
</p>
|
||||
<p
|
||||
class="mb-4 text-gray-500"
|
||||
v-motion
|
||||
:initial="{
|
||||
opacity: 0,
|
||||
y: 100
|
||||
}"
|
||||
:enter="{
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
transition: {
|
||||
delay: 300
|
||||
}
|
||||
}"
|
||||
>
|
||||
抱歉,你无权访问该页面
|
||||
</p>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="router.push('/')"
|
||||
v-motion
|
||||
:initial="{
|
||||
opacity: 0,
|
||||
y: 100
|
||||
}"
|
||||
:enter="{
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
transition: {
|
||||
delay: 500
|
||||
}
|
||||
}"
|
||||
>
|
||||
返回首页
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
@ -1,70 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { useRouter } from "vue-router";
|
||||
import noExist from "@/assets/status/404.svg?component";
|
||||
|
||||
defineOptions({
|
||||
name: "404"
|
||||
});
|
||||
|
||||
const router = useRouter();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex justify-center items-center h-[640px]">
|
||||
<noExist />
|
||||
<div class="ml-12">
|
||||
<p
|
||||
class="font-medium text-4xl mb-4 dark:text-white"
|
||||
v-motion
|
||||
:initial="{
|
||||
opacity: 0,
|
||||
y: 100
|
||||
}"
|
||||
:enter="{
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
transition: {
|
||||
delay: 100
|
||||
}
|
||||
}"
|
||||
>
|
||||
404
|
||||
</p>
|
||||
<p
|
||||
class="mb-4 text-gray-500"
|
||||
v-motion
|
||||
:initial="{
|
||||
opacity: 0,
|
||||
y: 100
|
||||
}"
|
||||
:enter="{
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
transition: {
|
||||
delay: 300
|
||||
}
|
||||
}"
|
||||
>
|
||||
抱歉,你访问的页面不存在
|
||||
</p>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="router.push('/')"
|
||||
v-motion
|
||||
:initial="{
|
||||
opacity: 0,
|
||||
y: 100
|
||||
}"
|
||||
:enter="{
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
transition: {
|
||||
delay: 500
|
||||
}
|
||||
}"
|
||||
>
|
||||
返回首页
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
@ -1,70 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { useRouter } from "vue-router";
|
||||
import noServer from "@/assets/status/500.svg?component";
|
||||
|
||||
defineOptions({
|
||||
name: "500"
|
||||
});
|
||||
|
||||
const router = useRouter();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex justify-center items-center h-[640px]">
|
||||
<noServer />
|
||||
<div class="ml-12">
|
||||
<p
|
||||
class="font-medium text-4xl mb-4 dark:text-white"
|
||||
v-motion
|
||||
:initial="{
|
||||
opacity: 0,
|
||||
y: 100
|
||||
}"
|
||||
:enter="{
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
transition: {
|
||||
delay: 100
|
||||
}
|
||||
}"
|
||||
>
|
||||
500
|
||||
</p>
|
||||
<p
|
||||
class="mb-4 text-gray-500"
|
||||
v-motion
|
||||
:initial="{
|
||||
opacity: 0,
|
||||
y: 100
|
||||
}"
|
||||
:enter="{
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
transition: {
|
||||
delay: 300
|
||||
}
|
||||
}"
|
||||
>
|
||||
抱歉,服务器出错了
|
||||
</p>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="router.push('/')"
|
||||
v-motion
|
||||
:initial="{
|
||||
opacity: 0,
|
||||
y: 100
|
||||
}"
|
||||
:enter="{
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
transition: {
|
||||
delay: 500
|
||||
}
|
||||
}"
|
||||
>
|
||||
返回首页
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
@ -8,7 +8,7 @@ import type { FormInstance } from "element-plus";
|
||||
import { useLayout } from "@/layout/hooks/useLayout";
|
||||
import { useUserStoreHook } from "@/store/modules/user";
|
||||
import { initRouter, getTopMenu } from "@/router/utils";
|
||||
import { bg, avatar, illustration } from "./utils/static";
|
||||
import { bg, illustration } from "./utils/static";
|
||||
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
|
||||
import { ref, reactive, toRaw, onMounted, onBeforeUnmount } from "vue";
|
||||
import { useDataThemeChange } from "@/layout/hooks/useDataThemeChange";
|
||||
@ -33,8 +33,10 @@ dataThemeChange();
|
||||
const { title } = useNav();
|
||||
|
||||
const ruleForm = reactive({
|
||||
username: "admin",
|
||||
password: "admin123"
|
||||
// username: "admin",
|
||||
// password: "admin123"
|
||||
username: "",
|
||||
password: ""
|
||||
});
|
||||
|
||||
const onLogin = async (formEl: FormInstance | undefined) => {
|
||||
@ -43,7 +45,10 @@ const onLogin = async (formEl: FormInstance | undefined) => {
|
||||
await formEl.validate((valid, fields) => {
|
||||
if (valid) {
|
||||
useUserStoreHook()
|
||||
.loginByUsername({ username: ruleForm.username, password: "admin123" })
|
||||
.loginByUsername({
|
||||
username: ruleForm.username,
|
||||
password: ruleForm.password
|
||||
})
|
||||
.then(res => {
|
||||
if (res.success) {
|
||||
// 获取后端路由
|
||||
@ -51,6 +56,12 @@ const onLogin = async (formEl: FormInstance | undefined) => {
|
||||
router.push(getTopMenu(true).path);
|
||||
message("登录成功", { type: "success" });
|
||||
});
|
||||
} else {
|
||||
// TODO: 下面这个不能正确运行
|
||||
// 弹窗显示 "登录失败",并重新返回到登录界面
|
||||
alert("登录失败");
|
||||
loading.value = false;
|
||||
formEl.resetFields(); // 重置表单字段
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@ -95,7 +106,8 @@ onBeforeUnmount(() => {
|
||||
</div>
|
||||
<div class="login-box">
|
||||
<div class="login-form">
|
||||
<avatar class="avatar" />
|
||||
<!-- <avatar class="avatar" /> -->
|
||||
<img src="@/assets/login/logo.jpg" />
|
||||
<Motion>
|
||||
<h2 class="outline-none">{{ title }}</h2>
|
||||
</Motion>
|
||||
|
@ -1,75 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { type CSSProperties, computed } from "vue";
|
||||
import { hasAuth, getAuths } from "@/router/utils";
|
||||
|
||||
defineOptions({
|
||||
name: "PermissionButton"
|
||||
});
|
||||
|
||||
const elStyle = computed((): CSSProperties => {
|
||||
return {
|
||||
width: "85vw",
|
||||
justifyContent: "start"
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-space direction="vertical" size="large">
|
||||
<el-tag :style="elStyle" size="large" effect="dark">
|
||||
当前拥有的code列表:{{ getAuths() }}
|
||||
</el-tag>
|
||||
|
||||
<el-card shadow="never" :style="elStyle">
|
||||
<template #header>
|
||||
<div class="card-header">组件方式判断权限</div>
|
||||
</template>
|
||||
<Auth value="btn_add">
|
||||
<el-button type="success"> 拥有code:'btn_add' 权限可见 </el-button>
|
||||
</Auth>
|
||||
<Auth :value="['btn_edit']">
|
||||
<el-button type="primary"> 拥有code:['btn_edit'] 权限可见 </el-button>
|
||||
</Auth>
|
||||
<Auth :value="['btn_add', 'btn_edit', 'btn_delete']">
|
||||
<el-button type="danger">
|
||||
拥有code:['btn_add', 'btn_edit', 'btn_delete'] 权限可见
|
||||
</el-button>
|
||||
</Auth>
|
||||
</el-card>
|
||||
|
||||
<el-card shadow="never" :style="elStyle">
|
||||
<template #header>
|
||||
<div class="card-header">函数方式判断权限</div>
|
||||
</template>
|
||||
<el-button type="success" v-if="hasAuth('btn_add')">
|
||||
拥有code:'btn_add' 权限可见
|
||||
</el-button>
|
||||
<el-button type="primary" v-if="hasAuth(['btn_edit'])">
|
||||
拥有code:['btn_edit'] 权限可见
|
||||
</el-button>
|
||||
<el-button
|
||||
type="danger"
|
||||
v-if="hasAuth(['btn_add', 'btn_edit', 'btn_delete'])"
|
||||
>
|
||||
拥有code:['btn_add', 'btn_edit', 'btn_delete'] 权限可见
|
||||
</el-button>
|
||||
</el-card>
|
||||
|
||||
<el-card shadow="never" :style="elStyle">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
指令方式判断权限(该方式不能动态修改权限)
|
||||
</div>
|
||||
</template>
|
||||
<el-button type="success" v-auth="'btn_add'">
|
||||
拥有code:'btn_add' 权限可见
|
||||
</el-button>
|
||||
<el-button type="primary" v-auth="['btn_edit']">
|
||||
拥有code:['btn_edit'] 权限可见
|
||||
</el-button>
|
||||
<el-button type="danger" v-auth="['btn_add', 'btn_edit', 'btn_delete']">
|
||||
拥有code:['btn_add', 'btn_edit', 'btn_delete'] 权限可见
|
||||
</el-button>
|
||||
</el-card>
|
||||
</el-space>
|
||||
</template>
|
@ -1,66 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { initRouter } from "@/router/utils";
|
||||
import { storageSession } from "@pureadmin/utils";
|
||||
import { type CSSProperties, ref, computed } from "vue";
|
||||
import { useUserStoreHook } from "@/store/modules/user";
|
||||
import { usePermissionStoreHook } from "@/store/modules/permission";
|
||||
|
||||
defineOptions({
|
||||
name: "PermissionPage"
|
||||
});
|
||||
|
||||
const elStyle = computed((): CSSProperties => {
|
||||
return {
|
||||
width: "85vw",
|
||||
justifyContent: "start"
|
||||
};
|
||||
});
|
||||
|
||||
const username = ref(useUserStoreHook()?.username);
|
||||
|
||||
const options = [
|
||||
{
|
||||
value: "admin",
|
||||
label: "管理员角色"
|
||||
},
|
||||
{
|
||||
value: "common",
|
||||
label: "普通角色"
|
||||
}
|
||||
];
|
||||
|
||||
function onChange() {
|
||||
useUserStoreHook()
|
||||
.loginByUsername({ username: username.value, password: "admin123" })
|
||||
.then(res => {
|
||||
if (res.success) {
|
||||
storageSession().removeItem("async-routes");
|
||||
usePermissionStoreHook().clearAllCachePage();
|
||||
initRouter();
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-space direction="vertical" size="large">
|
||||
<el-tag :style="elStyle" size="large" effect="dark">
|
||||
模拟后台根据不同角色返回对应路由(具体参考完整版pure-admin代码)
|
||||
</el-tag>
|
||||
<el-card shadow="never" :style="elStyle">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>当前角色:{{ username }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-select v-model="username" @change="onChange">
|
||||
<el-option
|
||||
v-for="item in options"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-card>
|
||||
</el-space>
|
||||
</template>
|
9
src/views/qa/chat/index.vue
Normal file
9
src/views/qa/chat/index.vue
Normal file
@ -0,0 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
defineOptions({
|
||||
name: "QAchat"
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h1>问答系统</h1>
|
||||
</template>
|
27
src/views/qa/triad/index.vue
Normal file
27
src/views/qa/triad/index.vue
Normal file
@ -0,0 +1,27 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import { getHelloMessage } from "@/api/routes";
|
||||
|
||||
defineOptions({
|
||||
name: "QAtriad"
|
||||
});
|
||||
|
||||
const message = ref(""); // 响应式变量,用于存储返回的消息
|
||||
|
||||
const handleClick = async () => {
|
||||
try {
|
||||
const response = await getHelloMessage();
|
||||
message.value = response.message; // 更新消息
|
||||
} catch (error) {
|
||||
console.error("Error fetching message:", error);
|
||||
message.value = "Error fetching message";
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h1>三元组管理</h1>
|
||||
<button @click="handleClick">获取消息</button>
|
||||
<p v-if="message">{{ message }}</p>
|
||||
<!-- 显示消息 -->
|
||||
</template>
|
@ -5,5 +5,5 @@ defineOptions({
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h1>Pure-Admin-Thin(非国际化版本)</h1>
|
||||
<h1>首页</h1>
|
||||
</template>
|
||||
|
Loading…
x
Reference in New Issue
Block a user