'admin-21.06.19:修复诸多问题,具体查看CHANGELOG.md文件1.04更新日志'
This commit is contained in:
parent
1ade90a114
commit
9a43e1d6c7
|
|
@ -57,5 +57,6 @@ module.exports = {
|
|||
'no-unused-vars': 'error',
|
||||
'no-v-model-argument': 'off',
|
||||
'no-case-declarations': 'off',
|
||||
'no-console': 'error',
|
||||
},
|
||||
};
|
||||
|
|
|
|||
20
CHANGELOG.md
20
CHANGELOG.md
|
|
@ -2,13 +2,31 @@
|
|||
|
||||
🎉🎉🔥 `vue-next-admin` 基于 vue3.x 、Typescript、vite、Element plus 等,适配手机、平板、pc 的后台开源免费模板库(vue2.x 请切换 vue-prev-admin 分支)
|
||||
|
||||
## 1.0.4
|
||||
|
||||
`2021.06.19`
|
||||
|
||||
- 🌟 更新 依赖更新最新版本("vite": "^2.3.7")热更新无问题
|
||||
- 🎉 新增 深克隆工具,方便开发,感谢<a href="https://gitee.com/kangert" target="_blank">@kangert</a>(<a href="https://gitee.com/lyt-top/vue-next-admin/pulls/6" target="_blank">#6</a>)
|
||||
- 🎯 优化 类型定义提高编码体验,修复不能将类型“string | undefined”分配给类型“string”的问题。感谢<a href="https://gitee.com/kangert" target="_blank">@kangert</a>(<a href="https://gitee.com/lyt-top/vue-next-admin/pulls/5" target="_blank">#5</a>)
|
||||
- 🎯 优化 `layout` 文件夹移动到与 `views` 文件夹同级(改动较大,`/@/views/layout` 变成 `/@/layout`)
|
||||
- 🎯 优化 页面有 `console.log` 时 `eslint` 不生效问题
|
||||
- 🎯 优化 页面、ts 中 `any` 类型问题(改动较大)
|
||||
- 🎯 优化 登录页在手机上显示的效果
|
||||
- 🎯 优化 多行注释信息,鼠标放到方法名即可查看,更加直观的知道方法参数等。引入方法时需去掉以 `.ts` 结尾的后缀(改动较大)
|
||||
- 🎯 优化 移除 `utils/storage.ts` 下的旧写法(改动较大)
|
||||
- 🎯 优化 拆分 `router` 下内容,路由、前端、后端控制分开写,方便理解
|
||||
- 🐞 修复 鼠标移入顶部用户信息栏 `开/关全屏` 文字反向问题
|
||||
- 🐞 修复 热更新时,NextLoading(界面 loading) 不消失问题 `window.nextLoading === undefined`
|
||||
- 🐞 修复 vuex 中不可以使用 `/@/api/xxx` 下的接口调用问题
|
||||
|
||||
## 1.0.3
|
||||
|
||||
`2021.06.02`
|
||||
|
||||
- ❄️ 删除 G6 思维导图界面
|
||||
- 🌟 更新 手动更新 vue、vue-router、vuex 到最近最多人使用的版本,出现不可预测的问题请降低版本。版本查看:<a href="https://www.npmjs.com/package/vue" target="_blank">vue 版本查看</a>
|
||||
- 🐞 修复 开启后端控制路由`isRequestRoutes`在非首页刷新页面后,回到首页的问题,感谢群友@伯牙已遇钟子期
|
||||
- 🐞 修复 开启后端控制路由 `isRequestRoutes` 在非首页刷新页面后,回到首页的问题,感谢群友@伯牙已遇钟子期
|
||||
|
||||
## 1.0.2
|
||||
|
||||
|
|
|
|||
32
package.json
32
package.json
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "vue-next-admin",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.4",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
|
|
@ -10,10 +10,10 @@
|
|||
"axios": "^0.21.1",
|
||||
"clipboard": "^2.0.8",
|
||||
"countup.js": "^2.0.7",
|
||||
"cropperjs": "^1.5.11",
|
||||
"echarts": "^5.1.1",
|
||||
"cropperjs": "^1.5.12",
|
||||
"echarts": "^5.1.2",
|
||||
"echarts-wordcloud": "^2.0.0",
|
||||
"element-plus": "^1.0.2-beta.45",
|
||||
"element-plus": "^1.0.2-beta.48",
|
||||
"mitt": "^2.1.0",
|
||||
"nprogress": "^0.2.0",
|
||||
"print-js": "^1.6.0",
|
||||
|
|
@ -27,26 +27,26 @@
|
|||
"vue-router": "^4.0.8",
|
||||
"vue-web-screen-shot": "^1.2.0",
|
||||
"vuex": "^4.0.1",
|
||||
"wangeditor": "^4.7.1"
|
||||
"wangeditor": "^4.7.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/axios": "^0.14.0",
|
||||
"@types/clipboard": "^2.0.1",
|
||||
"@types/node": "^15.6.1",
|
||||
"@types/node": "^15.12.4",
|
||||
"@types/nprogress": "^0.2.0",
|
||||
"@types/sortablejs": "^1.10.6",
|
||||
"@typescript-eslint/eslint-plugin": "^4.26.0",
|
||||
"@typescript-eslint/parser": "^4.26.0",
|
||||
"@typescript-eslint/eslint-plugin": "^4.27.0",
|
||||
"@typescript-eslint/parser": "^4.27.0",
|
||||
"@vitejs/plugin-vue": "^1.2.3",
|
||||
"@vue/compiler-sfc": "^3.0.11",
|
||||
"@vue/compiler-sfc": "^3.1.1",
|
||||
"dotenv": "^10.0.0",
|
||||
"eslint": "^7.27.0",
|
||||
"eslint-plugin-vue": "^7.10.0",
|
||||
"prettier": "^2.3.0",
|
||||
"sass": "^1.34.0",
|
||||
"sass-loader": "^11.1.1",
|
||||
"typescript": "^4.3.2",
|
||||
"vite": "^2.3.5",
|
||||
"eslint": "^7.29.0",
|
||||
"eslint-plugin-vue": "^7.11.1",
|
||||
"prettier": "^2.3.1",
|
||||
"sass": "^1.35.1",
|
||||
"sass-loader": "^12.1.0",
|
||||
"typescript": "^4.3.4",
|
||||
"vite": "^2.3.7",
|
||||
"vue-eslint-parser": "^7.6.0"
|
||||
},
|
||||
"browserslist": [
|
||||
|
|
|
|||
|
|
@ -1,6 +1,13 @@
|
|||
/* eslint-disable */
|
||||
|
||||
// 声明文件,*.vue 后缀的文件交给 vue 模块来处理
|
||||
declare module '*.vue' {
|
||||
import type { DefineComponent } from 'vue';
|
||||
const component: DefineComponent<{}, {}, any>;
|
||||
export default component;
|
||||
}
|
||||
|
||||
// 声明文件,定义全局变量。其它 app.config.globalProperties.xxx,使用 getCurrentInstance() 来获取
|
||||
interface Window {
|
||||
nextLoading: boolean;
|
||||
}
|
||||
|
|
|
|||
22
src/App.vue
22
src/App.vue
|
|
@ -8,11 +8,11 @@
|
|||
import { computed, ref, getCurrentInstance, onBeforeMount, onMounted, onUnmounted, nextTick, defineComponent, watch } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useStore } from '/@/store/index.ts';
|
||||
import { getLocal } from '/@/utils/storage.ts';
|
||||
import setIntroduction from '/@/utils/setIconfont.ts';
|
||||
import LockScreen from '/@/views/layout/lockScreen/index.vue';
|
||||
import Setings from '/@/views/layout/navBars/breadcrumb/setings.vue';
|
||||
import { useStore } from '/@/store/index';
|
||||
import { Local } from '/@/utils/storage';
|
||||
import setIntroduction from '/@/utils/setIconfont';
|
||||
import LockScreen from '/@/layout/lockScreen/index.vue';
|
||||
import Setings from '/@/layout/navBars/breadcrumb/setings.vue';
|
||||
export default defineComponent({
|
||||
name: 'app',
|
||||
components: { LockScreen, Setings },
|
||||
|
|
@ -45,9 +45,9 @@ export default defineComponent({
|
|||
openSetingsDrawer();
|
||||
});
|
||||
// 获取缓存中的布局配置
|
||||
if (getLocal('themeConfig')) {
|
||||
store.dispatch('themeConfig/setThemeConfig', getLocal('themeConfig'));
|
||||
document.documentElement.style.cssText = getLocal('themeConfigStyle');
|
||||
if (Local.get('themeConfig')) {
|
||||
store.dispatch('themeConfig/setThemeConfig', Local.get('themeConfig'));
|
||||
document.documentElement.style.cssText = Local.get('themeConfigStyle');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
@ -60,9 +60,9 @@ export default defineComponent({
|
|||
() => route.path,
|
||||
() => {
|
||||
nextTick(() => {
|
||||
let webTitle = '';
|
||||
route.path === '/login' ? (webTitle = route.meta.title) : (webTitle = t(route.meta.title));
|
||||
document.title = `${webTitle} - ${getThemeConfig.value.globalTitle}` || getThemeConfig.value.globalTitle;
|
||||
// let webTitle = '';
|
||||
// route.path === '/login' ? (webTitle = route.meta.title) : (webTitle = t(route.meta.title));
|
||||
// document.title = `${webTitle} - ${getThemeConfig.value.globalTitle}` || getThemeConfig.value.globalTitle;
|
||||
});
|
||||
}
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
import request from '/@/utils/request.ts';
|
||||
import request from '/@/utils/request';
|
||||
|
||||
// 用户登录
|
||||
/**
|
||||
* 用户登录
|
||||
* @param params 要传的参数值
|
||||
* @returns 返回接口数据
|
||||
*/
|
||||
export function signIn(params: object) {
|
||||
return request({
|
||||
url: '/user/signIn',
|
||||
|
|
@ -9,7 +13,11 @@ export function signIn(params: object) {
|
|||
});
|
||||
}
|
||||
|
||||
// 用户退出登录
|
||||
/**
|
||||
* 用户退出登录
|
||||
* @param params 要传的参数值
|
||||
* @returns 返回接口数据
|
||||
*/
|
||||
export function signOut(params: object) {
|
||||
return request({
|
||||
url: '/user/signOut',
|
||||
|
|
|
|||
|
|
@ -1,10 +1,16 @@
|
|||
import request from '/@/utils/request.ts';
|
||||
import request from '/@/utils/request';
|
||||
|
||||
/**
|
||||
* 后端控制菜单模拟json,路径在 https://gitee.com/lyt-top/vue-next-admin-images/tree/master/menu
|
||||
* 后端控制路由,isRequestRoutes 为 true,则开启后端控制路由
|
||||
*/
|
||||
// 获取后端动态路由菜单(admin)
|
||||
|
||||
/**
|
||||
* 获取后端动态路由菜单(admin)
|
||||
* @link 参考:https://gitee.com/lyt-top/vue-next-admin-images/tree/master/menu
|
||||
* @param params 要传的参数值,非必传
|
||||
* @returns 返回接口数据
|
||||
*/
|
||||
export function getMenuAdmin(params?: object) {
|
||||
return request({
|
||||
url: '/gitee/lyt-top/vue-next-admin-images/raw/master/menu/adminMenu.json',
|
||||
|
|
@ -13,7 +19,12 @@ export function getMenuAdmin(params?: object) {
|
|||
});
|
||||
}
|
||||
|
||||
// 获取后端动态路由菜单(test)
|
||||
/**
|
||||
* 获取后端动态路由菜单(test)
|
||||
* @link 参考:https://gitee.com/lyt-top/vue-next-admin-images/tree/master/menu
|
||||
* @param params 要传的参数值,非必传
|
||||
* @returns 返回接口数据
|
||||
*/
|
||||
export function getMenuTest(params?: object) {
|
||||
return request({
|
||||
url: '/gitee/lyt-top/vue-next-admin-images/raw/master/menu/testMenu.json',
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
<script lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { useStore } from '/@/store/index.ts';
|
||||
import { useStore } from '/@/store/index';
|
||||
export default {
|
||||
name: 'auth',
|
||||
props: {
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
<script lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { useStore } from '/@/store/index.ts';
|
||||
import { judementSameArr } from '/@/utils/arrayOperation.ts';
|
||||
import { useStore } from '/@/store/index';
|
||||
import { judementSameArr } from '/@/utils/arrayOperation';
|
||||
export default {
|
||||
name: 'authAll',
|
||||
props: {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
<script lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { useStore } from '/@/store/index.ts';
|
||||
import { useStore } from '/@/store/index';
|
||||
export default {
|
||||
name: 'auths',
|
||||
props: {
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@
|
|||
|
||||
<script lang="ts">
|
||||
import { ref, toRefs, reactive, onMounted, nextTick, computed } from 'vue';
|
||||
import initIconfont from '/@/utils/getStyleSheets.ts';
|
||||
import initIconfont from '/@/utils/getStyleSheets';
|
||||
export default {
|
||||
name: 'iconSelector',
|
||||
props: {
|
||||
|
|
|
|||
|
|
@ -2,18 +2,18 @@ import { createI18n } from 'vue-i18n';
|
|||
import zhcnLocale from 'element-plus/lib/locale/lang/zh-cn';
|
||||
import enLocale from 'element-plus/lib/locale/lang/en';
|
||||
import zhtwLocale from 'element-plus/lib/locale/lang/zh-tw';
|
||||
import { store } from '/@/store/index.ts';
|
||||
import { store } from '/@/store/index';
|
||||
|
||||
import nextZhcn from '/@/i18n/lang/zh-cn.ts';
|
||||
import nextEn from '/@/i18n/lang/en.ts';
|
||||
import nextZhtw from '/@/i18n/lang/zh-tw.ts';
|
||||
import nextZhcn from '/@/i18n/lang/zh-cn';
|
||||
import nextEn from '/@/i18n/lang/en';
|
||||
import nextZhtw from '/@/i18n/lang/zh-tw';
|
||||
|
||||
import pagesHomeZhcn from '/@/i18n/pages/home/zh-cn.ts';
|
||||
import pagesHomeEn from '/@/i18n/pages/home/en.ts';
|
||||
import pagesHomeZhtw from '/@/i18n/pages/home/zh-tw.ts';
|
||||
import pagesLoginZhcn from '/@/i18n/pages/login/zh-cn.ts';
|
||||
import pagesLoginEn from '/@/i18n/pages/login/en.ts';
|
||||
import pagesLoginZhtw from '/@/i18n/pages/login/zh-tw.ts';
|
||||
import pagesHomeZhcn from '/@/i18n/pages/home/zh-cn';
|
||||
import pagesHomeEn from '/@/i18n/pages/home/en';
|
||||
import pagesHomeZhtw from '/@/i18n/pages/home/zh-tw';
|
||||
import pagesLoginZhcn from '/@/i18n/pages/login/zh-cn';
|
||||
import pagesLoginEn from '/@/i18n/pages/login/en';
|
||||
import pagesLoginZhtw from '/@/i18n/pages/login/zh-tw';
|
||||
|
||||
// 定义语言国际化内容
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ export default {
|
|||
dropdown3: '404',
|
||||
dropdown4: '401',
|
||||
dropdown5: 'Log out',
|
||||
dropdown6: 'Code warehouse',
|
||||
searchPlaceholder: 'Menu search: support Chinese, routing path',
|
||||
newTitle: 'notice',
|
||||
newBtn: 'All read',
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ export default {
|
|||
dropdown3: '404',
|
||||
dropdown4: '401',
|
||||
dropdown5: '退出登录',
|
||||
dropdown6: '代码仓库',
|
||||
searchPlaceholder: '菜单搜索:支持中文、路由路径',
|
||||
newTitle: '通知',
|
||||
newBtn: '全部已读',
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ export default {
|
|||
dropdown3: '404',
|
||||
dropdown4: '401',
|
||||
dropdown5: '登出',
|
||||
dropdown6: '程式碼倉庫',
|
||||
searchPlaceholder: '選單蒐索:支援中文、路由路徑',
|
||||
newTitle: '通知',
|
||||
newBtn: '全部已讀',
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@
|
|||
|
||||
<script lang="ts">
|
||||
import { toRefs, reactive, computed, watch, getCurrentInstance, onBeforeMount, onUnmounted } from 'vue';
|
||||
import { useStore } from '/@/store/index.ts';
|
||||
import Logo from '/@/views/layout/logo/index.vue';
|
||||
import Vertical from '/@/views/layout/navMenu/vertical.vue';
|
||||
import { useStore } from '/@/store/index';
|
||||
import Logo from '/@/layout/logo/index.vue';
|
||||
import Vertical from '/@/layout/navMenu/vertical.vue';
|
||||
export default {
|
||||
name: 'layoutAside',
|
||||
components: { Logo, Vertical },
|
||||
|
|
@ -46,7 +46,7 @@
|
|||
<script lang="ts">
|
||||
import { reactive, toRefs, ref, computed, onMounted, nextTick, getCurrentInstance, watch } from 'vue';
|
||||
import { useRoute, useRouter, onBeforeRouteUpdate } from 'vue-router';
|
||||
import { useStore } from '/@/store/index.ts';
|
||||
import { useStore } from '/@/store/index';
|
||||
export default {
|
||||
name: 'layoutColumnsAside',
|
||||
setup() {
|
||||
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
<script lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { useStore } from '/@/store/index.ts';
|
||||
import NavBarsIndex from '/@/views/layout/navBars/index.vue';
|
||||
import { useStore } from '/@/store/index';
|
||||
import NavBarsIndex from '/@/layout/navBars/index.vue';
|
||||
export default {
|
||||
name: 'layoutHeader',
|
||||
components: { NavBarsIndex },
|
||||
|
|
@ -22,11 +22,11 @@
|
|||
<script lang="ts">
|
||||
import { computed, defineComponent, toRefs, reactive, getCurrentInstance, watch, onBeforeMount } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useStore } from '/@/store/index.ts';
|
||||
import LayoutParentView from '/@/views/layout/routerView/parent.vue';
|
||||
import Footer from '/@/views/layout/footer/index.vue';
|
||||
import Link from '/@/views/layout/routerView/link.vue';
|
||||
import Iframes from '/@/views/layout/routerView/iframes.vue';
|
||||
import { useStore } from '/@/store/index';
|
||||
import LayoutParentView from '/@/layout/routerView/parent.vue';
|
||||
import Footer from '/@/layout/footer/index.vue';
|
||||
import Link from '/@/layout/routerView/link.vue';
|
||||
import Iframes from '/@/layout/routerView/iframes.vue';
|
||||
export default defineComponent({
|
||||
name: 'layoutMain',
|
||||
components: { LayoutParentView, Footer, Link, Iframes },
|
||||
|
|
@ -7,12 +7,12 @@
|
|||
|
||||
<script lang="ts">
|
||||
import { computed, onBeforeMount, onUnmounted, getCurrentInstance } from 'vue';
|
||||
import { useStore } from '/@/store/index.ts';
|
||||
import { getLocal, setLocal } from '/@/utils/storage.ts';
|
||||
import Defaults from '/@/views/layout/main/defaults.vue';
|
||||
import Classic from '/@/views/layout/main/classic.vue';
|
||||
import Transverse from '/@/views/layout/main/transverse.vue';
|
||||
import Columns from '/@/views/layout/main/columns.vue';
|
||||
import { useStore } from '/@/store/index';
|
||||
import { Local } from '/@/utils/storage';
|
||||
import Defaults from '/@/layout/main/defaults.vue';
|
||||
import Classic from '/@/layout/main/classic.vue';
|
||||
import Transverse from '/@/layout/main/transverse.vue';
|
||||
import Columns from '/@/layout/main/columns.vue';
|
||||
export default {
|
||||
name: 'layout',
|
||||
components: { Defaults, Classic, Transverse, Columns },
|
||||
|
|
@ -25,7 +25,7 @@ export default {
|
|||
});
|
||||
// 窗口大小改变时(适配移动端)
|
||||
const onLayoutResize = () => {
|
||||
if (!getLocal('oldLayout')) setLocal('oldLayout', getThemeConfig.value.layout);
|
||||
if (!Local.get('oldLayout')) Local.set('oldLayout', getThemeConfig.value.layout);
|
||||
const clientWidth = document.body.clientWidth;
|
||||
if (clientWidth < 1000) {
|
||||
getThemeConfig.value.isCollapse = false;
|
||||
|
|
@ -35,7 +35,7 @@ export default {
|
|||
});
|
||||
} else {
|
||||
proxy.mittBus.emit('layoutMobileResize', {
|
||||
layout: getLocal('oldLayout') ? getLocal('oldLayout') : getThemeConfig.value.layout,
|
||||
layout: Local.get('oldLayout') ? Local.get('oldLayout') : getThemeConfig.value.layout,
|
||||
clientWidth,
|
||||
});
|
||||
}
|
||||
|
|
@ -53,9 +53,9 @@
|
|||
|
||||
<script lang="ts">
|
||||
import { nextTick, onMounted, reactive, toRefs, ref, onUnmounted, getCurrentInstance } from 'vue';
|
||||
import { useStore } from '/@/store/index.ts';
|
||||
import { formatDate } from '/@/utils/formatTime.ts';
|
||||
import { setLocal } from '/@/utils/storage.ts';
|
||||
import { useStore } from '/@/store/index';
|
||||
import { formatDate } from '/@/utils/formatTime';
|
||||
import { Local } from '/@/utils/storage';
|
||||
export default {
|
||||
name: 'layoutLockScreen',
|
||||
setup() {
|
||||
|
|
@ -154,7 +154,7 @@ export default {
|
|||
// 存储布局配置
|
||||
const setLocalThemeConfig = () => {
|
||||
store.state.themeConfig.themeConfig.isDrawer = false;
|
||||
setLocal('themeConfig', store.state.themeConfig.themeConfig);
|
||||
Local.set('themeConfig', store.state.themeConfig.themeConfig);
|
||||
};
|
||||
// 密码输入点击事件
|
||||
const onLockScreenSubmit = () => {
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
<script lang="ts">
|
||||
import { computed, getCurrentInstance } from 'vue';
|
||||
import { useStore } from '/@/store/index.ts';
|
||||
import { useStore } from '/@/store/index';
|
||||
export default {
|
||||
name: 'layoutLogo',
|
||||
setup() {
|
||||
|
|
@ -14,11 +14,11 @@
|
|||
|
||||
<script lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { useStore } from '/@/store/index.ts';
|
||||
import Aside from '/@/views/layout/component/aside.vue';
|
||||
import Header from '/@/views/layout/component/header.vue';
|
||||
import Main from '/@/views/layout/component/main.vue';
|
||||
import TagsView from '/@/views/layout/navBars/tagsView/tagsView.vue';
|
||||
import { useStore } from '/@/store/index';
|
||||
import Aside from '/@/layout/component/aside.vue';
|
||||
import Header from '/@/layout/component/header.vue';
|
||||
import Main from '/@/layout/component/main.vue';
|
||||
import TagsView from '/@/layout/navBars/tagsView/tagsView.vue';
|
||||
export default {
|
||||
name: 'layoutClassic',
|
||||
components: { Aside, Header, Main, TagsView },
|
||||
|
|
@ -17,11 +17,11 @@
|
|||
|
||||
<script lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { useStore } from '/@/store/index.ts';
|
||||
import Aside from '/@/views/layout/component/aside.vue';
|
||||
import Header from '/@/views/layout/component/header.vue';
|
||||
import Main from '/@/views/layout/component/main.vue';
|
||||
import ColumnsAside from '/@/views/layout/component/columnsAside.vue';
|
||||
import { useStore } from '/@/store/index';
|
||||
import Aside from '/@/layout/component/aside.vue';
|
||||
import Header from '/@/layout/component/header.vue';
|
||||
import Main from '/@/layout/component/main.vue';
|
||||
import ColumnsAside from '/@/layout/component/columnsAside.vue';
|
||||
export default {
|
||||
name: 'layoutColumns',
|
||||
components: { Aside, Header, Main, ColumnsAside },
|
||||
|
|
@ -15,10 +15,10 @@
|
|||
<script lang="ts">
|
||||
import { computed, getCurrentInstance, watch } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useStore } from '/@/store/index.ts';
|
||||
import Aside from '/@/views/layout/component/aside.vue';
|
||||
import Header from '/@/views/layout/component/header.vue';
|
||||
import Main from '/@/views/layout/component/main.vue';
|
||||
import { useStore } from '/@/store/index';
|
||||
import Aside from '/@/layout/component/aside.vue';
|
||||
import Header from '/@/layout/component/header.vue';
|
||||
import Main from '/@/layout/component/main.vue';
|
||||
export default {
|
||||
name: 'layoutDefaults',
|
||||
components: { Aside, Header, Main },
|
||||
|
|
@ -7,8 +7,8 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Header from '/@/views/layout/component/header.vue';
|
||||
import Main from '/@/views/layout/component/main.vue';
|
||||
import Header from '/@/layout/component/header.vue';
|
||||
import Main from '/@/layout/component/main.vue';
|
||||
export default {
|
||||
name: 'layoutTransverse',
|
||||
components: { Header, Main },
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
<script lang="ts">
|
||||
import { toRefs, reactive, computed, getCurrentInstance, onMounted } from 'vue';
|
||||
import { onBeforeRouteUpdate, useRoute, useRouter } from 'vue-router';
|
||||
import { useStore } from '/@/store/index.ts';
|
||||
import { useStore } from '/@/store/index';
|
||||
export default {
|
||||
name: 'layoutBreadcrumb',
|
||||
setup() {
|
||||
|
|
@ -10,11 +10,11 @@
|
|||
<script lang="ts">
|
||||
import { computed, reactive, toRefs, onMounted, onUnmounted, getCurrentInstance } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useStore } from '/@/store/index.ts';
|
||||
import Breadcrumb from '/@/views/layout/navBars/breadcrumb/breadcrumb.vue';
|
||||
import User from '/@/views/layout/navBars/breadcrumb/user.vue';
|
||||
import Logo from '/@/views/layout/logo/index.vue';
|
||||
import Horizontal from '/@/views/layout/navMenu/horizontal.vue';
|
||||
import { useStore } from '/@/store/index';
|
||||
import Breadcrumb from '/@/layout/navBars/breadcrumb/breadcrumb.vue';
|
||||
import User from '/@/layout/navBars/breadcrumb/user.vue';
|
||||
import Logo from '/@/layout/logo/index.vue';
|
||||
import Horizontal from '/@/layout/navMenu/horizontal.vue';
|
||||
export default {
|
||||
name: 'layoutBreadcrumbIndex',
|
||||
components: { Breadcrumb, User, Logo, Horizontal },
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
import { reactive, toRefs, defineComponent, ref, nextTick } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useStore } from '/@/store/index.ts';
|
||||
import { useStore } from '/@/store/index';
|
||||
export default defineComponent({
|
||||
name: 'layoutBreadcrumbSearch',
|
||||
setup() {
|
||||
|
|
@ -370,11 +370,11 @@ import { nextTick, onUnmounted, onMounted, getCurrentInstance, defineComponent,
|
|||
import { ElMessage } from 'element-plus';
|
||||
import ClipboardJS from 'clipboard';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useStore } from '/@/store/index.ts';
|
||||
import { getLightColor } from '/@/utils/theme.ts';
|
||||
import Watermark from '/@/utils/wartermark.ts';
|
||||
import { verifyAndSpace } from '/@/utils/toolsValidate.ts';
|
||||
import { setLocal, getLocal, removeLocal } from '/@/utils/storage.ts';
|
||||
import { useStore } from '/@/store/index';
|
||||
import { getLightColor } from '/@/utils/theme';
|
||||
import Watermark from '/@/utils/wartermark';
|
||||
import { verifyAndSpace } from '/@/utils/toolsValidate';
|
||||
import { Local } from '/@/utils/storage';
|
||||
export default defineComponent({
|
||||
name: 'layoutBreadcrumbSeting',
|
||||
setup() {
|
||||
|
|
@ -438,7 +438,7 @@ export default defineComponent({
|
|||
if (getThemeConfig.value.isMenuBarColorHighlight) {
|
||||
elsItems.forEach((el: any) => el.setAttribute('id', ``));
|
||||
elActive.setAttribute('id', `add-is-active`);
|
||||
setLocal('menuBarHighlightId', elActive.getAttribute('id'));
|
||||
Local.set('menuBarHighlightId', elActive.getAttribute('id'));
|
||||
} else {
|
||||
elActive.setAttribute('id', ``);
|
||||
}
|
||||
|
|
@ -506,7 +506,7 @@ export default defineComponent({
|
|||
};
|
||||
// 5、布局切换
|
||||
const onSetLayout = (layout: string) => {
|
||||
setLocal('oldLayout', layout);
|
||||
Local.set('oldLayout', layout);
|
||||
if (getThemeConfig.value.layout === layout) return false;
|
||||
getThemeConfig.value.layout = layout;
|
||||
getThemeConfig.value.isDrawer = false;
|
||||
|
|
@ -569,16 +569,16 @@ export default defineComponent({
|
|||
};
|
||||
// 存储布局配置
|
||||
const setLocalThemeConfig = () => {
|
||||
removeLocal('themeConfig');
|
||||
setLocal('themeConfig', getThemeConfig.value);
|
||||
Local.remove('themeConfig');
|
||||
Local.set('themeConfig', getThemeConfig.value);
|
||||
};
|
||||
// 存储布局配置全局主题样式(html根标签)
|
||||
const setLocalThemeConfigStyle = () => {
|
||||
setLocal('themeConfigStyle', document.documentElement.style.cssText);
|
||||
Local.set('themeConfigStyle', document.documentElement.style.cssText);
|
||||
};
|
||||
// 一键复制配置
|
||||
const onCopyConfigClick = (target: any) => {
|
||||
let copyThemeConfig = getLocal('themeConfig');
|
||||
let copyThemeConfig = Local.get('themeConfig');
|
||||
copyThemeConfig.isDrawer = false;
|
||||
const clipboard = new ClipboardJS(target, {
|
||||
text: () => JSON.stringify(copyThemeConfig),
|
||||
|
|
@ -609,8 +609,8 @@ export default defineComponent({
|
|||
onMounted(() => {
|
||||
nextTick(() => {
|
||||
// 判断当前布局是否不相同,不相同则初始化当前布局的样式,防止监听窗口大小改变时,布局配置logo、菜单背景等部分布局失效问题
|
||||
if (!getLocal('frequency')) initSetLayoutChange();
|
||||
setLocal('frequency', 1);
|
||||
if (!Local.get('frequency')) initSetLayoutChange();
|
||||
Local.set('frequency', 1);
|
||||
// 修复防止退出登录再进入界面时,需要刷新样式才生效的问题,初始化布局样式等(登录的时候触发,目前方案)
|
||||
proxy.mittBus.on('onSignInClick', () => {
|
||||
initSetStyle();
|
||||
|
|
@ -627,7 +627,7 @@ export default defineComponent({
|
|||
initSetLayoutChange();
|
||||
onMenuBarHighlightChange();
|
||||
});
|
||||
window.addEventListener('load', () => {
|
||||
setTimeout(() => {
|
||||
// 修复防止退出登录再进入界面时,需要刷新样式才生效的问题,初始化布局样式等(登录的时候触发,目前方案)
|
||||
initSetStyle();
|
||||
// 灰色模式
|
||||
|
|
@ -637,8 +637,8 @@ export default defineComponent({
|
|||
// 开启水印
|
||||
onWartermarkChange();
|
||||
// 语言国际化
|
||||
if (getLocal('themeConfig')) proxy.$i18n.locale = getLocal('themeConfig').globalI18n;
|
||||
});
|
||||
if (Local.get('themeConfig')) proxy.$i18n.locale = Local.get('themeConfig').globalI18n;
|
||||
}, 100);
|
||||
});
|
||||
});
|
||||
onUnmounted(() => {
|
||||
|
|
@ -46,7 +46,7 @@
|
|||
<div class="layout-navbars-breadcrumb-user-icon mr10" @click="onScreenfullClick">
|
||||
<i
|
||||
class="iconfont"
|
||||
:title="isScreenfull ? $t('message.user.title5') : $t('message.user.title6')"
|
||||
:title="isScreenfull ? $t('message.user.title6') : $t('message.user.title5')"
|
||||
:class="!isScreenfull ? 'icon-fullscreen' : 'icon-tuichuquanping'"
|
||||
></i>
|
||||
</div>
|
||||
|
|
@ -59,6 +59,7 @@
|
|||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item command="/home">{{ $t('message.user.dropdown1') }}</el-dropdown-item>
|
||||
<el-dropdown-item command="wareHouse">{{ $t('message.user.dropdown6') }}</el-dropdown-item>
|
||||
<el-dropdown-item command="/personal">{{ $t('message.user.dropdown2') }}</el-dropdown-item>
|
||||
<el-dropdown-item command="/404">{{ $t('message.user.dropdown3') }}</el-dropdown-item>
|
||||
<el-dropdown-item command="/401">{{ $t('message.user.dropdown4') }}</el-dropdown-item>
|
||||
|
|
@ -76,11 +77,11 @@ import { useRouter } from 'vue-router';
|
|||
import { ElMessageBox, ElMessage } from 'element-plus';
|
||||
import screenfull from 'screenfull';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { resetRoute } from '/@/router/index.ts';
|
||||
import { useStore } from '/@/store/index.ts';
|
||||
import { clearSession, setLocal, getLocal, removeLocal } from '/@/utils/storage.ts';
|
||||
import UserNews from '/@/views/layout/navBars/breadcrumb/userNews.vue';
|
||||
import Search from '/@/views/layout/navBars/breadcrumb/search.vue';
|
||||
import { resetRoute } from '/@/router/index';
|
||||
import { useStore } from '/@/store/index';
|
||||
import { Session, Local } from '/@/utils/storage';
|
||||
import UserNews from '/@/layout/navBars/breadcrumb/userNews.vue';
|
||||
import Search from '/@/layout/navBars/breadcrumb/search.vue';
|
||||
export default {
|
||||
name: 'layoutBreadcrumbUser',
|
||||
components: { UserNews, Search },
|
||||
|
|
@ -152,7 +153,7 @@ export default {
|
|||
},
|
||||
})
|
||||
.then(() => {
|
||||
clearSession(); // 清除缓存/token等
|
||||
Session.clear(); // 清除缓存/token等
|
||||
resetRoute(); // 删除/重置路由
|
||||
router.push('/login');
|
||||
setTimeout(() => {
|
||||
|
|
@ -160,6 +161,8 @@ export default {
|
|||
}, 300);
|
||||
})
|
||||
.catch(() => {});
|
||||
} else if (path === 'wareHouse') {
|
||||
window.open('https://gitee.com/lyt-top/vue-next-admin');
|
||||
} else {
|
||||
router.push(path);
|
||||
}
|
||||
|
|
@ -170,24 +173,24 @@ export default {
|
|||
};
|
||||
// 组件大小改变
|
||||
const onComponentSizeChange = (size: string) => {
|
||||
removeLocal('themeConfig');
|
||||
Local.remove('themeConfig');
|
||||
getThemeConfig.value.globalComponentSize = size;
|
||||
setLocal('themeConfig', getThemeConfig.value);
|
||||
Local.set('themeConfig', getThemeConfig.value);
|
||||
proxy.$ELEMENT.size = size;
|
||||
initComponentSize();
|
||||
window.location.reload();
|
||||
};
|
||||
// 语言切换
|
||||
const onLanguageChange = (lang: string) => {
|
||||
removeLocal('themeConfig');
|
||||
Local.remove('themeConfig');
|
||||
getThemeConfig.value.globalI18n = lang;
|
||||
setLocal('themeConfig', getThemeConfig.value);
|
||||
Local.set('themeConfig', getThemeConfig.value);
|
||||
proxy.$i18n.locale = lang;
|
||||
initI18n();
|
||||
};
|
||||
// 初始化言语国际化
|
||||
const initI18n = () => {
|
||||
switch (getLocal('themeConfig').globalI18n) {
|
||||
switch (Local.get('themeConfig').globalI18n) {
|
||||
case 'zh-cn':
|
||||
state.disabledI18n = 'zh-cn';
|
||||
break;
|
||||
|
|
@ -201,7 +204,7 @@ export default {
|
|||
};
|
||||
// 初始化全局组件大小
|
||||
const initComponentSize = () => {
|
||||
switch (getLocal('themeConfig').globalComponentSize) {
|
||||
switch (Local.get('themeConfig').globalComponentSize) {
|
||||
case '':
|
||||
state.disabledSize = '';
|
||||
break;
|
||||
|
|
@ -218,7 +221,7 @@ export default {
|
|||
};
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
if (getLocal('themeConfig')) {
|
||||
if (Local.get('themeConfig')) {
|
||||
initI18n();
|
||||
initComponentSize();
|
||||
}
|
||||
|
|
@ -7,9 +7,9 @@
|
|||
|
||||
<script lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { useStore } from '/@/store/index.ts';
|
||||
import BreadcrumbIndex from '/@/views/layout/navBars/breadcrumb/index.vue';
|
||||
import TagsView from '/@/views/layout/navBars/tagsView/tagsView.vue';
|
||||
import { useStore } from '/@/store/index';
|
||||
import BreadcrumbIndex from '/@/layout/navBars/breadcrumb/index.vue';
|
||||
import TagsView from '/@/layout/navBars/tagsView/tagsView.vue';
|
||||
export default {
|
||||
name: 'layoutNavBars',
|
||||
components: { BreadcrumbIndex, TagsView },
|
||||
|
|
@ -43,10 +43,10 @@
|
|||
import { toRefs, reactive, onMounted, computed, ref, nextTick, onBeforeUpdate, onBeforeMount, onUnmounted, getCurrentInstance, watch } from 'vue';
|
||||
import { useRoute, useRouter, onBeforeRouteUpdate } from 'vue-router';
|
||||
import screenfull from 'screenfull';
|
||||
import { useStore } from '/@/store/index.ts';
|
||||
import { setSession, getSession, removeSession } from '/@/utils/storage.ts';
|
||||
import { useStore } from '/@/store/index';
|
||||
import { Session } from '/@/utils/storage';
|
||||
import Sortable from 'sortablejs';
|
||||
import Contextmenu from '/@/views/layout/navBars/tagsView/contextmenu.vue';
|
||||
import Contextmenu from '/@/layout/navBars/tagsView/contextmenu.vue';
|
||||
export default {
|
||||
name: 'layoutTagsView',
|
||||
components: { Contextmenu },
|
||||
|
|
@ -77,20 +77,20 @@ export default {
|
|||
});
|
||||
// 存储 tagsViewList 到浏览器临时缓存中,页面刷新时,保留记录
|
||||
const addBrowserSetSession = (tagsViewList: Array<object>) => {
|
||||
setSession('tagsViewList', tagsViewList);
|
||||
Session.set('tagsViewList', tagsViewList);
|
||||
};
|
||||
// 获取 vuex 中的 tagsViewRoutes 列表
|
||||
const getTagsViewRoutes = () => {
|
||||
state.routePath = route.path;
|
||||
state.tagsViewList = [];
|
||||
if (!store.state.themeConfig.themeConfig.isCacheTagsView) removeSession('tagsViewList');
|
||||
if (!store.state.themeConfig.themeConfig.isCacheTagsView) Session.remove('tagsViewList');
|
||||
state.tagsViewRoutesList = store.state.tagsViewRoutes.tagsViewRoutes;
|
||||
initTagsView();
|
||||
};
|
||||
// vuex 中获取路由信息:如果是设置了固定的(isAffix),进行初始化显示
|
||||
const initTagsView = () => {
|
||||
if (getSession('tagsViewList') && store.state.themeConfig.themeConfig.isCacheTagsView) {
|
||||
state.tagsViewList = getSession('tagsViewList');
|
||||
if (Session.get('tagsViewList') && store.state.themeConfig.themeConfig.isCacheTagsView) {
|
||||
state.tagsViewList = Session.get('tagsViewList');
|
||||
} else {
|
||||
state.tagsViewRoutesList.map((v: any) => {
|
||||
if (v.meta.isAffix && !v.meta.isHide) state.tagsViewList.push({ ...v });
|
||||
|
|
@ -31,8 +31,8 @@
|
|||
<script lang="ts">
|
||||
import { toRefs, reactive, computed, defineComponent, getCurrentInstance, onMounted, nextTick } from 'vue';
|
||||
import { useRoute, onBeforeRouteUpdate } from 'vue-router';
|
||||
import { useStore } from '/@/store/index.ts';
|
||||
import SubItem from '/@/views/layout/navMenu/subItem.vue';
|
||||
import { useStore } from '/@/store/index';
|
||||
import SubItem from '/@/layout/navMenu/subItem.vue';
|
||||
export default defineComponent({
|
||||
name: 'navMenuHorizontal',
|
||||
components: { SubItem },
|
||||
|
|
@ -31,8 +31,8 @@
|
|||
<script lang="ts">
|
||||
import { toRefs, reactive, computed, defineComponent, getCurrentInstance } from 'vue';
|
||||
import { useRoute, onBeforeRouteUpdate } from 'vue-router';
|
||||
import { useStore } from '/@/store/index.ts';
|
||||
import SubItem from '/@/views/layout/navMenu/subItem.vue';
|
||||
import { useStore } from '/@/store/index';
|
||||
import SubItem from '/@/layout/navMenu/subItem.vue';
|
||||
export default defineComponent({
|
||||
name: 'navMenuVertical',
|
||||
components: { SubItem },
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
<script lang="ts">
|
||||
import { computed, defineComponent, toRefs, reactive, getCurrentInstance, onBeforeMount, onUnmounted, nextTick } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useStore } from '/@/store/index.ts';
|
||||
import { useStore } from '/@/store/index';
|
||||
export default defineComponent({
|
||||
name: 'layoutParentView',
|
||||
setup() {
|
||||
|
|
@ -2,9 +2,9 @@ import { createApp } from 'vue';
|
|||
import App from './App.vue';
|
||||
import router from './router';
|
||||
import { store, key } from './store';
|
||||
import { directive } from '/@/utils/directive.ts';
|
||||
import { i18n } from '/@/i18n/index.ts';
|
||||
import { globalComponentSize } from '/@/utils/componentSize.ts';
|
||||
import { directive } from '/@/utils/directive';
|
||||
import { i18n } from '/@/i18n/index';
|
||||
import { globalComponentSize } from '/@/utils/componentSize';
|
||||
|
||||
import ElementPlus from 'element-plus';
|
||||
import 'element-plus/lib/theme-chalk/index.css';
|
||||
|
|
|
|||
|
|
@ -0,0 +1,98 @@
|
|||
import { store } from '/@/store/index.ts';
|
||||
import { Session } from '/@/utils/storage';
|
||||
import { NextLoading } from '/@/utils/loading';
|
||||
import { setAddRoute, setFilterMenuAndCacheTagsViewRoutes } from '/@/router/index';
|
||||
import { dynamicRoutes } from '/@/router/route';
|
||||
import { getMenuAdmin, getMenuTest } from '/@/api/menu/index';
|
||||
|
||||
/**
|
||||
* 获取目录下的 .vue、.tsx 全部文件
|
||||
* @method import.meta.glob
|
||||
* @link 参考:https://cn.vitejs.dev/guide/features.html#json
|
||||
*/
|
||||
const dynamicViewsModules: Record<string, Function> = import.meta.glob('../views/**/*.{vue,tsx}');
|
||||
|
||||
/**
|
||||
* 后端控制路由:初始化方法,防止刷新时路由丢失
|
||||
* @method NextLoading 界面 loading 动画开始执行
|
||||
* @method store.dispatch('userInfos/setUserInfos') 触发初始化用户信息
|
||||
* @method store.dispatch('requestOldRoutes/setBackEndControlRoutes') 存储接口原始路由(未处理component),根据需求选择使用
|
||||
* @method setAddRoute 添加动态路由
|
||||
* @method setFilterMenuAndCacheTagsViewRoutes 设置递归过滤有权限的路由到 vuex routesList 中(已处理成多级嵌套路由)及缓存多级嵌套数组处理后的一维数组
|
||||
*/
|
||||
export async function initBackEndControlRoutes() {
|
||||
// 界面 loading 动画开始执行
|
||||
if (window.nextLoading === undefined) NextLoading.start();
|
||||
// 无 token 停止执行下一步
|
||||
if (!Session.get('token')) return false;
|
||||
// 触发初始化用户信息
|
||||
store.dispatch('userInfos/setUserInfos');
|
||||
// 获取路由菜单数据
|
||||
const res = await getBackEndControlRoutes();
|
||||
// 存储接口原始路由(未处理component),根据需求选择使用
|
||||
store.dispatch('requestOldRoutes/setBackEndControlRoutes', JSON.parse(JSON.stringify(res.data)));
|
||||
// 处理路由(component),替换 dynamicRoutes(/@/router/route)第一个顶级 children 的路由
|
||||
dynamicRoutes[0].children = await backEndComponent(res.data);
|
||||
// 添加动态路由
|
||||
await setAddRoute();
|
||||
// 设置递归过滤有权限的路由到 vuex routesList 中(已处理成多级嵌套路由)及缓存多级嵌套数组处理后的一维数组
|
||||
setFilterMenuAndCacheTagsViewRoutes();
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求后端路由菜单接口
|
||||
* @description isRequestRoutes 为 true,则开启后端控制路由
|
||||
* @returns 返回后端路由菜单数据
|
||||
*/
|
||||
export function getBackEndControlRoutes() {
|
||||
// 模拟 admin 与 test
|
||||
const auth = store.state.userInfos.userInfos.authPageList[0];
|
||||
// 管理员 admin
|
||||
if (auth === 'admin') return getMenuAdmin();
|
||||
// 其它用户 test
|
||||
else return getMenuTest();
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新请求后端路由菜单接口
|
||||
* @description 用于菜单管理界面刷新菜单(未进行测试)
|
||||
* @description 路径:/src/views/system/menu/component/addMenu.vue
|
||||
*/
|
||||
export function setBackEndControlRefreshRoutes() {
|
||||
getBackEndControlRoutes();
|
||||
}
|
||||
|
||||
/**
|
||||
* 后端路由 component 转换
|
||||
* @param routes 后端返回的路由表数组
|
||||
* @returns 返回处理成函数后的 component
|
||||
*/
|
||||
export function backEndComponent(routes: any) {
|
||||
if (!routes) return;
|
||||
return routes.map((item: any) => {
|
||||
if (item.component) item.component = dynamicImport(dynamicViewsModules, item.component as string);
|
||||
item.children && backEndComponent(item.children);
|
||||
return item;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 后端路由 component 转换函数
|
||||
* @param dynamicViewsModules 获取目录下的 .vue、.tsx 全部文件
|
||||
* @param component 当前要处理项 component
|
||||
* @returns 返回处理成函数后的 component
|
||||
*/
|
||||
export function dynamicImport(dynamicViewsModules: Record<string, Function>, component: string) {
|
||||
const keys = Object.keys(dynamicViewsModules);
|
||||
const matchKeys = keys.filter((key) => {
|
||||
const k = key.replace('../views', '');
|
||||
return k.startsWith(`${component}`) || k.startsWith(`/${component}`);
|
||||
});
|
||||
if (matchKeys?.length === 1) {
|
||||
const matchKey = matchKeys[0];
|
||||
return dynamicViewsModules[matchKey];
|
||||
}
|
||||
if (matchKeys?.length > 1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
import { store } from '/@/store/index';
|
||||
import { Session } from '/@/utils/storage';
|
||||
import { NextLoading } from '/@/utils/loading';
|
||||
import { setAddRoute, setFilterMenuAndCacheTagsViewRoutes } from '/@/router/index';
|
||||
|
||||
/**
|
||||
* 前端控制路由:初始化方法,防止刷新时路由丢失
|
||||
* @method NextLoading 界面 loading 动画开始执行
|
||||
* @method store.dispatch('userInfos/setUserInfos') 触发初始化用户信息
|
||||
* @method setAddRoute 添加动态路由
|
||||
* @method setFilterMenuAndCacheTagsViewRoutes 设置递归过滤有权限的路由到 vuex routesList 中(已处理成多级嵌套路由)及缓存多级嵌套数组处理后的一维数组
|
||||
*/
|
||||
export async function initFrontEndControlRoutes() {
|
||||
// 界面 loading 动画开始执行
|
||||
if (window.nextLoading === undefined) NextLoading.start();
|
||||
// 无 token 停止执行下一步
|
||||
if (!Session.get('token')) return false;
|
||||
// 触发初始化用户信息
|
||||
store.dispatch('userInfos/setUserInfos');
|
||||
// 添加动态路由
|
||||
await setAddRoute();
|
||||
// 设置递归过滤有权限的路由到 vuex routesList 中(已处理成多级嵌套路由)及缓存多级嵌套数组处理后的一维数组
|
||||
setFilterMenuAndCacheTagsViewRoutes();
|
||||
}
|
||||
1047
src/router/index.ts
1047
src/router/index.ts
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,869 @@
|
|||
import { RouteRecordRaw } from 'vue-router';
|
||||
|
||||
/**
|
||||
* 路由meta对象参数说明
|
||||
* meta: {
|
||||
* title: 菜单栏及 tagsView 栏、菜单搜索名称(国际化)
|
||||
* isLink: 是否超链接菜单,开启外链条件,`1、isLink:true 2、链接地址不为空`
|
||||
* isHide: 是否隐藏此路由
|
||||
* isKeepAlive: 是否缓存组件状态
|
||||
* isAffix: 是否固定在 tagsView 栏上
|
||||
* isIframe: 是否内嵌窗口,,开启条件,`1、isIframe:true 2、链接地址不为空`
|
||||
* auth: 当前路由权限标识(多个请用逗号隔开),最后转成数组格式,用于与当前用户权限进行对比,控制路由显示、隐藏
|
||||
* icon: 菜单、tagsView 图标,阿里:加 `iconfont xxx`,fontawesome:加 `fa xxx`
|
||||
* }
|
||||
*/
|
||||
|
||||
/**
|
||||
* 定义动态路由
|
||||
* @description 未开启 isRequestRoutes 为 true 时使用(前端控制路由),开启时第一个顶级 children 的路由将被替换成接口请求回来的路由数据
|
||||
* @description 各字段请查看 `/@/views/system/menu/component/addMenu.vue 下的 ruleForm`
|
||||
* @returns 返回路由菜单数据
|
||||
*/
|
||||
export const dynamicRoutes: Array<RouteRecordRaw> = [
|
||||
{
|
||||
path: '/',
|
||||
name: '/',
|
||||
component: () => import('/@/layout/index.vue'),
|
||||
redirect: '/home',
|
||||
meta: {
|
||||
isKeepAlive: true,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: '/home',
|
||||
name: 'home',
|
||||
component: () => import('/@/views/home/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.home',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: true,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'iconfont icon-shouye',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/system',
|
||||
name: 'system',
|
||||
component: () => import('/@/layout/routerView/parent.vue'),
|
||||
redirect: '/system/menu',
|
||||
meta: {
|
||||
title: 'message.router.system',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin'],
|
||||
icon: 'iconfont icon-xitongshezhi',
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: '/system/menu',
|
||||
name: 'systemMenu',
|
||||
component: () => import('/@/views/system/menu/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.systemMenu',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin'],
|
||||
icon: 'iconfont icon-caidan',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/system/user',
|
||||
name: 'systemUser',
|
||||
component: () => import('/@/views/system/user/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.systemUser',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin'],
|
||||
icon: 'iconfont icon-icon-',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
path: '/limits',
|
||||
name: 'limits',
|
||||
component: () => import('/@/layout/routerView/parent.vue'),
|
||||
redirect: '/limits/frontEnd',
|
||||
meta: {
|
||||
title: 'message.router.limits',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'iconfont icon-quanxian',
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: '/limits/frontEnd',
|
||||
name: 'limitsFrontEnd',
|
||||
component: () => import('/@/layout/routerView/parent.vue'),
|
||||
redirect: '/limits/frontEnd/page',
|
||||
meta: {
|
||||
title: 'message.router.limitsFrontEnd',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: '/limits/frontEnd/page',
|
||||
name: 'limitsFrontEndPage',
|
||||
component: () => import('/@/views/limits/frontEnd/page/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.limitsFrontEndPage',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/limits/frontEnd/btn',
|
||||
name: 'limitsFrontEndBtn',
|
||||
component: () => import('/@/views/limits/frontEnd/btn/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.limitsFrontEndBtn',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/limits/backEnd',
|
||||
name: 'limitsBackEnd',
|
||||
component: () => import('/@/layout/routerView/parent.vue'),
|
||||
meta: {
|
||||
title: 'message.router.limitsBackEnd',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: '/limits/backEnd/page',
|
||||
name: 'limitsBackEndEndPage',
|
||||
component: () => import('/@/views/limits/backEnd/page/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.limitsBackEndEndPage',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/menu',
|
||||
name: 'menu',
|
||||
component: () => import('/@/layout/routerView/parent.vue'),
|
||||
redirect: '/menu/menu1',
|
||||
meta: {
|
||||
title: 'message.router.menu',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'iconfont icon-caidan',
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: '/menu/menu1',
|
||||
name: 'menu1',
|
||||
component: () => import('/@/layout/routerView/parent.vue'),
|
||||
redirect: '/menu/menu1/menu11',
|
||||
meta: {
|
||||
title: 'message.router.menu1',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'iconfont icon-caidan',
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: '/menu/menu1/menu11',
|
||||
name: 'menu11',
|
||||
component: () => import('/@/views/menu/menu1/menu11/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.menu11',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'iconfont icon-caidan',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/menu/menu1/menu12',
|
||||
name: 'menu12',
|
||||
component: () => import('/@/layout/routerView/parent.vue'),
|
||||
redirect: '/menu/menu1/menu12/menu121',
|
||||
meta: {
|
||||
title: 'message.router.menu12',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'iconfont icon-caidan',
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: '/menu/menu1/menu12/menu121',
|
||||
name: 'menu121',
|
||||
component: () => import('/@/views/menu/menu1/menu12/menu121/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.menu121',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'iconfont icon-caidan',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/menu/menu1/menu12/menu122',
|
||||
name: 'menu122',
|
||||
component: () => import('/@/views/menu/menu1/menu12/menu122/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.menu122',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'iconfont icon-caidan',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/menu/menu1/menu13',
|
||||
name: 'menu13',
|
||||
component: () => import('/@/views/menu/menu1/menu13/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.menu13',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'iconfont icon-caidan',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/menu/menu2',
|
||||
name: 'menu2',
|
||||
component: () => import('/@/views/menu/menu2/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.menu2',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'iconfont icon-caidan',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/fun',
|
||||
name: 'funIndex',
|
||||
component: () => import('/@/layout/routerView/parent.vue'),
|
||||
redirect: '/fun/tagsView',
|
||||
meta: {
|
||||
title: 'message.router.funIndex',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'iconfont icon-crew_feature',
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: '/fun/tagsView',
|
||||
name: 'funTagsView',
|
||||
component: () => import('/@/views/fun/tagsView/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.funTagsView',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'el-icon-thumb',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/fun/countup',
|
||||
name: 'funCountup',
|
||||
component: () => import('/@/views/fun/countup/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.funCountup',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'el-icon-odometer',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/fun/echartsTree',
|
||||
name: 'funEchartsTree',
|
||||
component: () => import('/@/views/fun/tree/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.funEchartsTree',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'el-icon-connection',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/fun/selector',
|
||||
name: 'funSelector',
|
||||
component: () => import('/@/views/fun/selector/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.funSelector',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'iconfont icon-xuanzeqi',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/fun/wangEditor',
|
||||
name: 'funWangEditor',
|
||||
component: () => import('/@/views/fun/wangEditor/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.funWangEditor',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'iconfont icon-fuwenbenkuang',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/fun/cropper',
|
||||
name: 'funCropper',
|
||||
component: () => import('/@/views/fun/cropper/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.funCropper',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'iconfont icon-caijian',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/fun/qrcode',
|
||||
name: 'funQrcode',
|
||||
component: () => import('/@/views/fun/qrcode/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.funQrcode',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'iconfont icon-ico',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/fun/echartsMap',
|
||||
name: 'funEchartsMap',
|
||||
component: () => import('/@/views/fun/echartsMap/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.funEchartsMap',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'iconfont icon-ditu',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/fun/printJs',
|
||||
name: 'funPrintJs',
|
||||
component: () => import('/@/views/fun/printJs/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.funPrintJs',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'el-icon-printer',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/fun/clipboard',
|
||||
name: 'funClipboard',
|
||||
component: () => import('/@/views/fun/clipboard/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.funClipboard',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'el-icon-document-copy',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/fun/screenShort',
|
||||
name: 'funScreenShort',
|
||||
component: () => import('/@/views/fun/screenShort/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.funScreenShort',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'el-icon-crop',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/fun/gridLayout',
|
||||
name: 'funGridLayout',
|
||||
component: () => import('/@/views/fun/gridLayout/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.funGridLayout',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'iconfont icon-tuodong',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/fun/splitpanes',
|
||||
name: 'funSplitpanes',
|
||||
component: () => import('/@/views/fun/splitpanes/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.funSplitpanes',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'iconfont icon--chaifenlie',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/pages',
|
||||
name: 'pagesIndex',
|
||||
component: () => import('/@/layout/routerView/parent.vue'),
|
||||
redirect: '/pages/filtering',
|
||||
meta: {
|
||||
title: 'message.router.pagesIndex',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'iconfont icon-fuzhiyemian',
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: '/pages/filtering',
|
||||
name: 'pagesFiltering',
|
||||
component: () => import('/@/views/pages/filtering/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.pagesFiltering',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'el-icon-sell',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/pages/filteringDetails',
|
||||
name: 'pagesFilteringDetails',
|
||||
component: () => import('/@/views/pages/filtering/details.vue'),
|
||||
meta: {
|
||||
title: 'message.router.pagesFilteringDetails',
|
||||
isLink: '',
|
||||
isHide: true,
|
||||
isKeepAlive: false,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'el-icon-s-order',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/pages/filteringDetails1',
|
||||
name: 'pagesFilteringDetails1',
|
||||
component: () => import('/@/views/pages/filtering/details1.vue'),
|
||||
meta: {
|
||||
title: 'message.router.pagesFilteringDetails1',
|
||||
isLink: '',
|
||||
isHide: true,
|
||||
isKeepAlive: false,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'el-icon-s-order',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/pages/iocnfont',
|
||||
name: 'pagesIocnfont',
|
||||
component: () => import('/@/views/pages/iocnfont/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.pagesIocnfont',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'el-icon-present',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/pages/element',
|
||||
name: 'pagesElement',
|
||||
component: () => import('/@/views/pages/element/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.pagesElement',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'el-icon-platform-eleme',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/pages/awesome',
|
||||
name: 'pagesAwesome',
|
||||
component: () => import('/@/views/pages/awesome/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.pagesAwesome',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'el-icon-set-up',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/pages/cityLinkage',
|
||||
name: 'pagesCityLinkage',
|
||||
component: () => import('/@/views/pages/cityLinkage/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.pagesCityLinkage',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'iconfont icon-jiliandongxuanzeqi',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/pages/formAdapt',
|
||||
name: 'pagesFormAdapt',
|
||||
component: () => import('/@/views/pages/formAdapt/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.pagesFormAdapt',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'iconfont icon-biaodan',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/pages/listAdapt',
|
||||
name: 'pagesListAdapt',
|
||||
component: () => import('/@/views/pages/listAdapt/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.pagesListAdapt',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'iconfont icon-chazhaobiaodanliebiao',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/pages/waterfall',
|
||||
name: 'pagesWaterfall',
|
||||
component: () => import('/@/views/pages/waterfall/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.pagesWaterfall',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'iconfont icon-zidingyibuju',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/pages/steps',
|
||||
name: 'pagesSteps',
|
||||
component: () => import('/@/views/pages/steps/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.pagesSteps',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'iconfont icon-step',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/pages/preview',
|
||||
name: 'pagesPreview',
|
||||
component: () => import('/@/views/pages/preview/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.pagesPreview',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'iconfont icon-15tupianyulan',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/pages/waves',
|
||||
name: 'pagesWaves',
|
||||
component: () => import('/@/views/pages/waves/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.pagesWaves',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'iconfont icon-bolangneng',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/pages/tree',
|
||||
name: 'pagesTree',
|
||||
component: () => import('/@/views/pages/tree/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.pagesTree',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'iconfont icon-shuxingtu',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/chart',
|
||||
name: 'chartIndex',
|
||||
component: () => import('/@/views/chart/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.chartIndex',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'iconfont icon-ico_shuju',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/personal',
|
||||
name: 'personal',
|
||||
component: () => import('/@/views/personal/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.personal',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'iconfont icon-gerenzhongxin',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/tools',
|
||||
name: 'tools',
|
||||
component: () => import('/@/views/tools/index.vue'),
|
||||
meta: {
|
||||
title: 'message.router.tools',
|
||||
isLink: '',
|
||||
isHide: false,
|
||||
isKeepAlive: true,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin', 'test'],
|
||||
icon: 'iconfont icon-gongju',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/link',
|
||||
name: 'layoutLinkView',
|
||||
component: () => import('/@/layout/routerView/parent.vue'),
|
||||
meta: {
|
||||
title: 'message.router.layoutLinkView',
|
||||
isLink: 'https://element-plus.gitee.io/#/zh-CN/component/installation',
|
||||
isHide: false,
|
||||
isKeepAlive: false,
|
||||
isAffix: false,
|
||||
isIframe: false,
|
||||
auth: ['admin'],
|
||||
icon: 'iconfont icon-caozuo-wailian',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/iframes',
|
||||
name: 'layoutIfameView',
|
||||
component: () => import('/@/layout/routerView/parent.vue'),
|
||||
meta: {
|
||||
title: 'message.router.layoutIfameView',
|
||||
isLink: 'https://gitee.com/lyt-top/vue-next-admin',
|
||||
isHide: false,
|
||||
isKeepAlive: false,
|
||||
isAffix: true,
|
||||
isIframe: true,
|
||||
auth: ['admin'],
|
||||
icon: 'iconfont icon-neiqianshujuchucun',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* 定义静态路由
|
||||
* @description 前端控制直接改 dynamicRoutes 中的路由,后端控制不需要修改,请求接口路由数据时,会覆盖 dynamicRoutes 第一个顶级 children 的内容(全屏,不包含 layout 中的路由出口)
|
||||
* @returns 返回路由菜单数据
|
||||
*/
|
||||
export const staticRoutes: Array<RouteRecordRaw> = [
|
||||
{
|
||||
path: '/login',
|
||||
name: 'login',
|
||||
component: () => import('/@/views/login/index.vue'),
|
||||
meta: {
|
||||
title: '登陆',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/404',
|
||||
name: 'notFound',
|
||||
component: () => import('/@/views/error/404.vue'),
|
||||
meta: {
|
||||
title: '找不到此页面',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/401',
|
||||
name: 'noPower',
|
||||
component: () => import('/@/views/error/401.vue'),
|
||||
meta: {
|
||||
title: '没有权限',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
|
@ -1,19 +1,36 @@
|
|||
import { InjectionKey } from 'vue';
|
||||
import { createStore, useStore as baseUseStore, Store, ModuleTree } from 'vuex';
|
||||
import { createStore, useStore as baseUseStore, Store } from 'vuex';
|
||||
import { RootStateTypes } from '/@/store/interface/index';
|
||||
import themeConfig from '/@/store/modules/themeConfig.ts';
|
||||
import routesList from '/@/store/modules/routesList.ts';
|
||||
import keepAliveNames from '/@/store/modules/keepAliveNames.ts';
|
||||
import tagsViewRoutes from '/@/store/modules/tagsViewRoutes.ts';
|
||||
import userInfos from '/@/store/modules/userInfos.ts';
|
||||
import requestOldRoutes from '/@/store/modules/requestOldRoutes.ts';
|
||||
|
||||
let modules: ModuleTree<object> = {}
|
||||
const modulesFiles: Record<string, Function> = import.meta.glob('./modules/*.ts')
|
||||
for (const path in modulesFiles) {
|
||||
const moduleName: string = path.replace(/(.*\/)*([^.]+).*/gi, '$2')
|
||||
let module: ModuleTree<object> = await modulesFiles[path]()
|
||||
modules = { ...modules, [moduleName]:module.default}
|
||||
}
|
||||
// const modulesFiles: Record<string, Function> = import.meta.glob('./modules/*.ts');
|
||||
|
||||
// npm run build
|
||||
// https://github.com/vitejs/vite/issues/3035
|
||||
// Top-level await is not available in the configured target environment ("chrome87", "edge88", "es2019", "firefox78", "safari13.1")
|
||||
// let modules: ModuleTree<object> = {};
|
||||
// for (const path in modulesFiles) {
|
||||
// const moduleName: string = path.replace(/(.*\/)*([^.]+).*/gi, '$2');
|
||||
// let module: ModuleTree<object> = await modulesFiles[path]();
|
||||
// modules = { ...modules, [moduleName]: module.default };
|
||||
// }
|
||||
|
||||
export const key: InjectionKey<Store<RootStateTypes>> = Symbol();
|
||||
|
||||
export const store = createStore<RootStateTypes>({
|
||||
modules
|
||||
modules: {
|
||||
themeConfig,
|
||||
routesList,
|
||||
keepAliveNames,
|
||||
tagsViewRoutes,
|
||||
userInfos,
|
||||
requestOldRoutes,
|
||||
},
|
||||
});
|
||||
|
||||
export function useStore() {
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ const themeConfigModule: Module<ThemeConfigState, RootStateTypes> = {
|
|||
|
||||
/**
|
||||
* 菜单 / 顶栏
|
||||
* 注意:为了演示,切换布局时,颜色会被还原成默认,代码位置:/@/views/layout/navBars/breadcrumb/setings.vue
|
||||
* 注意:为了演示,切换布局时,颜色会被还原成默认,代码位置:/@/layout/navBars/breadcrumb/setings.vue
|
||||
* 中的 `initSetLayoutChange(设置布局切换,重置主题样式)` 方法
|
||||
*/
|
||||
// 默认顶栏导航背景颜色,请注意:需要同时修改 `/@/theme/common/var.scss` 对应的值
|
||||
|
|
@ -116,7 +116,7 @@ const themeConfigModule: Module<ThemeConfigState, RootStateTypes> = {
|
|||
|
||||
/**
|
||||
* 布局切换
|
||||
* 注意:为了演示,切换布局时,颜色会被还原成默认,代码位置:/@/views/layout/navBars/breadcrumb/setings.vue
|
||||
* 注意:为了演示,切换布局时,颜色会被还原成默认,代码位置:/@/layout/navBars/breadcrumb/setings.vue
|
||||
* 中的 `initSetLayoutChange(设置布局切换,重置主题样式)` 方法
|
||||
*/
|
||||
// 布局切换:可选值"<defaults|classic|transverse|columns>",默认 defaults
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { Module } from 'vuex';
|
||||
import { getSession } from '/@/utils/storage.ts';
|
||||
import { Session } from '/@/utils/storage.ts';
|
||||
// 此处加上 `.ts` 后缀报错,具体原因不详
|
||||
import { UserInfosState, RootStateTypes } from '/@/store/interface/index';
|
||||
|
||||
|
|
@ -20,7 +20,7 @@ const userInfosModule: Module<UserInfosState, RootStateTypes> = {
|
|||
if (data) {
|
||||
commit('getUserInfos', data);
|
||||
} else {
|
||||
if (getSession('userInfo')) commit('getUserInfos', getSession('userInfo'));
|
||||
if (Session.get('userInfo')) commit('getUserInfos', Session.get('userInfo'));
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -4,18 +4,19 @@
|
|||
------------------------------- */
|
||||
@media screen and (max-width: $xs) {
|
||||
.login-container {
|
||||
.login-content {
|
||||
width: 90% !important;
|
||||
padding: 20px 0 !important;
|
||||
background: none !important;
|
||||
.login-logo {
|
||||
display: none;
|
||||
}
|
||||
.login-content-form-btn {
|
||||
.login-content {
|
||||
width: 100% !important;
|
||||
padding: 12px 0 !important;
|
||||
height: 100% !important;
|
||||
padding: 20px 0 !important;
|
||||
border-radius: 0 !important;
|
||||
box-shadow: unset !important;
|
||||
}
|
||||
.login-copyright {
|
||||
.login-copyright-msg {
|
||||
white-space: unset !important;
|
||||
}
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
// 判断两数组是否相同
|
||||
export function judementSameArr(news: Array<string>, old: Array<string>) {
|
||||
/**
|
||||
* 判断两数组是否相同
|
||||
* @param news 新数据
|
||||
* @param old 源数据
|
||||
* @returns 两数组相同返回 `true`,反之则反
|
||||
*/
|
||||
export function judementSameArr(news: Array<string>, old: Array<string>): boolean {
|
||||
let count = 0;
|
||||
const leng = old.length;
|
||||
for (let i in old) {
|
||||
|
|
|
|||
|
|
@ -1,21 +1,26 @@
|
|||
import type { App } from 'vue';
|
||||
import { store } from '/@/store/index.ts';
|
||||
import { judementSameArr } from '/@/utils/arrayOperation.ts';
|
||||
import { judementSameArr } from '/@/utils/arrayOperation';
|
||||
|
||||
// 用户权限指令
|
||||
/**
|
||||
* 用户权限指令
|
||||
* @directive 单个权限验证(v-auth="xxx")
|
||||
* @directive 多个权限验证,满足一个则显示(v-auths="[xxx,xxx]")
|
||||
* @directive 多个权限验证,全部满足则显示(v-auth-all="[xxx,xxx]")
|
||||
*/
|
||||
export function authDirective(app: App) {
|
||||
// 单个权限验证(v-auth="xxx")
|
||||
app.directive('auth', {
|
||||
mounted(el, binding) {
|
||||
if (!store.state.userInfos.userInfos.authBtnList.some((v: any) => v === binding.value)) el.parentNode.removeChild(el);
|
||||
if (!store.state.userInfos.userInfos.authBtnList.some((v: string) => v === binding.value)) el.parentNode.removeChild(el);
|
||||
},
|
||||
});
|
||||
// 多个权限验证,满足一个则显示(v-auths="[xxx,xxx]")
|
||||
app.directive('auths', {
|
||||
mounted(el, binding) {
|
||||
let flag = false;
|
||||
store.state.userInfos.userInfos.authBtnList.map((val: any) => {
|
||||
binding.value.map((v: any) => {
|
||||
store.state.userInfos.userInfos.authBtnList.map((val: string) => {
|
||||
binding.value.map((v: string) => {
|
||||
if (val === v) flag = true;
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,23 +1,35 @@
|
|||
import { store } from '/@/store/index.ts';
|
||||
import { judementSameArr } from '/@/utils/arrayOperation.ts';
|
||||
import { judementSameArr } from '/@/utils/arrayOperation';
|
||||
|
||||
// 单个权限验证
|
||||
export function auth(value: string) {
|
||||
return store.state.userInfos.userInfos.authBtnList.some((v: any) => v === value);
|
||||
/**
|
||||
* 单个权限验证
|
||||
* @param value 权限值
|
||||
* @returns 有权限,返回 `true`,反之则反
|
||||
*/
|
||||
export function auth(value: string): boolean {
|
||||
return store.state.userInfos.userInfos.authBtnList.some((v: string) => v === value);
|
||||
}
|
||||
|
||||
// 多个权限验证,满足一个则为 true
|
||||
export function auths(value: Array<string>) {
|
||||
/**
|
||||
* 多个权限验证,满足一个则为 true
|
||||
* @param value 权限值
|
||||
* @returns 有权限,返回 `true`,反之则反
|
||||
*/
|
||||
export function auths(value: Array<string>): boolean {
|
||||
let flag = false;
|
||||
store.state.userInfos.userInfos.authBtnList.map((val: any) => {
|
||||
value.map((v: any) => {
|
||||
store.state.userInfos.userInfos.authBtnList.map((val: string) => {
|
||||
value.map((v: string) => {
|
||||
if (val === v) flag = true;
|
||||
});
|
||||
});
|
||||
return flag;
|
||||
}
|
||||
|
||||
// 多个权限验证,全部满足则为 true
|
||||
export function authAll(value: Array<string>) {
|
||||
/**
|
||||
* 多个权限验证,全部满足则为 true
|
||||
* @param value 权限值
|
||||
* @returns 有权限,返回 `true`,反之则反
|
||||
*/
|
||||
export function authAll(value: Array<string>): boolean {
|
||||
return judementSameArr(value, store.state.userInfos.userInfos.authBtnList);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
import { getLocal } from '/@/utils/storage.ts';
|
||||
import { Local } from '/@/utils/storage';
|
||||
|
||||
// 全局组件大小
|
||||
export const globalComponentSize = getLocal('themeConfig')?.globalComponentSize;
|
||||
/**
|
||||
* 全局组件大小
|
||||
* @returns 返回 `window.localStorage` 中读取的缓存值 `globalComponentSize`
|
||||
*/
|
||||
export const globalComponentSize: string = Local.get('themeConfig')?.globalComponentSize;
|
||||
|
|
|
|||
|
|
@ -1,19 +1,23 @@
|
|||
import type { App } from 'vue';
|
||||
|
||||
// 按钮波浪指令
|
||||
/**
|
||||
* 按钮波浪指令
|
||||
* @directive 默认方式:v-waves,如 `<div v-waves></div>`
|
||||
* @directive 参数方式:v-waves=" |light|red|orange|purple|green|teal",如 `<div v-waves="'light'"></div>`
|
||||
*/
|
||||
export function wavesDirective(app: App) {
|
||||
app.directive('waves', {
|
||||
mounted(el, binding) {
|
||||
el.classList.add('waves-effect');
|
||||
binding.value && el.classList.add(`waves-${binding.value}`);
|
||||
function setConvertStyle(obj: any) {
|
||||
function setConvertStyle(obj: { [key: string]: unknown }) {
|
||||
let style: string = '';
|
||||
for (let i in obj) {
|
||||
if (obj.hasOwnProperty(i)) style += `${i}:${obj[i]};`;
|
||||
}
|
||||
return style;
|
||||
}
|
||||
function onCurrentClick(e: any) {
|
||||
function onCurrentClick(e: { [key: string]: unknown }) {
|
||||
let elDiv = document.createElement('div');
|
||||
elDiv.classList.add('waves-ripple');
|
||||
el.appendChild(elDiv);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
/**
|
||||
* 对象深克隆
|
||||
* @param obj 源对象
|
||||
* @returns 克隆后的对象
|
||||
*/
|
||||
export function deepClone(obj: any) {
|
||||
let newObj: any;
|
||||
try {
|
||||
newObj = obj.push ? [] : {};
|
||||
} catch (error) {
|
||||
newObj = {};
|
||||
}
|
||||
for (let attr in obj) {
|
||||
if (typeof obj[attr] === 'object') {
|
||||
newObj[attr] = deepClone(obj[attr]);
|
||||
} else {
|
||||
newObj[attr] = obj[attr];
|
||||
}
|
||||
}
|
||||
return newObj;
|
||||
}
|
||||
|
|
@ -1,8 +1,12 @@
|
|||
import type { App } from 'vue';
|
||||
import { authDirective } from '/@/utils/authDirective.ts';
|
||||
import { wavesDirective } from '/@/utils/customDirective.ts';
|
||||
import { authDirective } from '/@/utils/authDirective';
|
||||
import { wavesDirective } from '/@/utils/customDirective';
|
||||
|
||||
// 导出指令方法
|
||||
/**
|
||||
* 导出指令方法:v-xxx
|
||||
* @methods authDirective 用户权限指令,用法:v-auth
|
||||
* @methods wavesDirective 按钮波浪指令,用法:v-waves
|
||||
*/
|
||||
export function directive(app: App) {
|
||||
// 用户权限指令
|
||||
authDirective(app);
|
||||
|
|
|
|||
|
|
@ -1,20 +1,17 @@
|
|||
/*
|
||||
* 年(Y) 可用1-4个占位符
|
||||
* 月(m)、日(d)、小时(H)、分(M)、秒(S) 可用1-2个占位符
|
||||
* 星期(W) 可用1-3个占位符
|
||||
* 季度(q为阿拉伯数字,Q为中文数字)可用1或4个占位符
|
||||
*
|
||||
* let date = new Date()
|
||||
* formatDate(date, "YYYY-mm-dd HH:MM:SS") // 2020-02-09 14:04:23
|
||||
* formatDate(date, "YYYY-mm-dd HH:MM:SS Q") // 2020-02-09 14:09:03 一
|
||||
* formatDate(date, "YYYY-mm-dd HH:MM:SS WWW") // 2020-02-09 14:45:12 星期日
|
||||
* formatDate(date, "YYYY-mm-dd HH:MM:SS QQQQ") // 2020-02-09 14:09:36 第一季度
|
||||
* formatDate(date, "YYYY-mm-dd HH:MM:SS WWW QQQQ") // 2020-02-09 14:46:12 星期日 第一季度
|
||||
/**
|
||||
* 时间日期转换
|
||||
* @param date 当前时间,new Date() 格式
|
||||
* @param format 需要转换的时间格式字符串
|
||||
* @description format 字符串随意,如 `YYYY-mm、YYYY-mm-dd`
|
||||
* @description format 季度:"YYYY-mm-dd HH:MM:SS QQQQ"
|
||||
* @description format 星期:"YYYY-mm-dd HH:MM:SS WWW"
|
||||
* @description format 季度 + 星期:"YYYY-mm-dd HH:MM:SS WWW QQQQ"
|
||||
* @returns 返回拼接后的时间字符串
|
||||
*/
|
||||
export function formatDate(date: Date, format: string) {
|
||||
export function formatDate(date: Date, format: string): string {
|
||||
let we = date.getDay(); // 星期
|
||||
let qut = Math.floor((date.getMonth() + 3) / 3).toString(); // 季度
|
||||
const opt: any = {
|
||||
const opt: { [key: string]: string } = {
|
||||
'Y+': date.getFullYear().toString(), // 年
|
||||
'm+': (date.getMonth() + 1).toString(), // 月(月份从0开始,要+1)
|
||||
'd+': date.getDate().toString(), // 日
|
||||
|
|
@ -24,7 +21,7 @@ export function formatDate(date: Date, format: string) {
|
|||
'q+': qut, // 季度
|
||||
};
|
||||
// 中文数字 (星期)
|
||||
const week: any = {
|
||||
const week: { [key: string]: string } = {
|
||||
'0': '日',
|
||||
'1': '一',
|
||||
'2': '二',
|
||||
|
|
@ -34,7 +31,7 @@ export function formatDate(date: Date, format: string) {
|
|||
'6': '六',
|
||||
};
|
||||
// 中文数字(季度)
|
||||
const quarter: any = {
|
||||
const quarter: { [key: string]: string } = {
|
||||
'1': '一',
|
||||
'2': '二',
|
||||
'3': '三',
|
||||
|
|
@ -52,27 +49,21 @@ export function formatDate(date: Date, format: string) {
|
|||
}
|
||||
|
||||
/**
|
||||
* 10秒: 10 * 1000
|
||||
* 1分: 60 * 1000
|
||||
* 1小时: 60 * 60 * 1000
|
||||
* 24小时:60 * 60 * 24 * 1000
|
||||
* 3天: 60 * 60* 24 * 1000 * 3
|
||||
*
|
||||
* let data = new Date()
|
||||
* formatPast(data) // 刚刚
|
||||
* formatPast(data - 11 * 1000) // 11秒前
|
||||
* formatPast(data - 2 * 60 * 1000) // 2分钟前
|
||||
* formatPast(data - 60 * 60 * 2 * 1000) // 2小时前
|
||||
* formatPast(data - 60 * 60 * 2 * 1000) // 2小时前
|
||||
* formatPast(data - 60 * 60 * 71 * 1000) // 2天前
|
||||
* formatPast("2020-06-01") // 2020-06-01
|
||||
* formatPast("2020-06-01", "YYYY-mm-dd HH:MM:SS WWW QQQQ") // 2020-06-01 08:00:00 星期一 第二季度
|
||||
* 将时间转换为 `几秒前`、`几分钟前`、`几小时前`、`几天前`
|
||||
* @param param 当前时间,new Date() 格式或者字符串时间格式
|
||||
* @param format 需要转换的时间格式字符串
|
||||
* @description param 10秒: 10 * 1000
|
||||
* @description param 1分: 60 * 1000
|
||||
* @description param 1小时: 60 * 60 * 1000
|
||||
* @description param 24小时:60 * 60 * 24 * 1000
|
||||
* @description param 3天: 60 * 60* 24 * 1000 * 3
|
||||
* @returns 返回拼接后的时间字符串
|
||||
*/
|
||||
export function formatPast(param: any, format: string = 'YYYY-mm-dd') {
|
||||
export function formatPast(param: string | Date, format: string = 'YYYY-mm-dd'): string {
|
||||
// 传入格式处理、存储转换值
|
||||
let t: any, s: any;
|
||||
let t: any, s: number;
|
||||
// 获取js 时间戳
|
||||
let time: any = new Date().getTime();
|
||||
let time: number = new Date().getTime();
|
||||
// 是否是对象
|
||||
typeof param === 'string' || 'object' ? (t = new Date(param).getTime()) : (t = param);
|
||||
// 当前时间戳 - 传入时间戳
|
||||
|
|
@ -104,9 +95,12 @@ export function formatPast(param: any, format: string = 'YYYY-mm-dd') {
|
|||
}
|
||||
|
||||
/**
|
||||
* formatAxis(new Date()) // 上午好
|
||||
* 时间问候语
|
||||
* @param param 当前时间,new Date() 格式
|
||||
* @description param 调用 `formatAxis(new Date())` 输出 `上午好`
|
||||
* @returns 返回拼接后的时间字符串
|
||||
*/
|
||||
export function formatAxis(param: any) {
|
||||
export function formatAxis(param: Date): string {
|
||||
let hour: number = new Date(param).getHours();
|
||||
if (hour < 6) return '凌晨好';
|
||||
else if (hour < 9) return '早上好';
|
||||
|
|
|
|||
|
|
@ -79,7 +79,12 @@ const getAwesomeIconfont = () => {
|
|||
});
|
||||
};
|
||||
|
||||
// 定义导出方法集合
|
||||
/**
|
||||
* 获取字体图标 `document.styleSheets`
|
||||
* @method ali 获取阿里字体图标 `<i class="iconfont 图标类名"></i>`
|
||||
* @method ele 获取 element plus 自带图标 `<i class="图标类名"></i>`
|
||||
* @method ali 获取 fontawesome 的图标 `<i class="fa 图标类名"></i>`
|
||||
*/
|
||||
const initIconfont = {
|
||||
// iconfont
|
||||
ali: () => {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,12 @@
|
|||
import { nextTick } from 'vue';
|
||||
import loadingCss from '/@/theme/loading.scss';
|
||||
|
||||
// 定义方法
|
||||
/**
|
||||
* 页面全局 Loading
|
||||
* @method setCss 载入 css
|
||||
* @method start 创建 loading
|
||||
* @method done 移除 loading
|
||||
*/
|
||||
export const NextLoading = {
|
||||
// 载入 css
|
||||
setCss: () => {
|
||||
|
|
@ -13,7 +18,7 @@ export const NextLoading = {
|
|||
},
|
||||
// 创建 loading
|
||||
start: () => {
|
||||
const bodys: any = document.body;
|
||||
const bodys: Element = document.body;
|
||||
const div = document.createElement('div');
|
||||
div.setAttribute('class', 'loading-next');
|
||||
const htmls = `
|
||||
|
|
@ -33,11 +38,13 @@ export const NextLoading = {
|
|||
`;
|
||||
div.innerHTML = htmls;
|
||||
bodys.insertBefore(div, bodys.childNodes[0]);
|
||||
window.nextLoading = true;
|
||||
},
|
||||
// 移除 loading
|
||||
done: () => {
|
||||
nextTick(() => {
|
||||
setTimeout(() => {
|
||||
window.nextLoading = false;
|
||||
const el = document.querySelector('.loading-next');
|
||||
el && el.parentNode?.removeChild(el);
|
||||
}, 1000);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import axios from 'axios';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import { clearSession, getSession } from '/@/utils/storage.ts';
|
||||
import router, { resetRoute } from '/@/router/index.ts';
|
||||
import { Session } from '/@/utils/storage';
|
||||
|
||||
// 配置新建一个 axios 实例
|
||||
const service = axios.create({
|
||||
|
|
@ -14,8 +13,8 @@ const service = axios.create({
|
|||
service.interceptors.request.use(
|
||||
(config) => {
|
||||
// 在发送请求之前做些什么 token
|
||||
if (getSession('token')) {
|
||||
config.headers.common['Authorization'] = `${getSession('token')}`;
|
||||
if (Session.get('token')) {
|
||||
config.headers.common['Authorization'] = `${Session.get('token')}`;
|
||||
}
|
||||
return config;
|
||||
},
|
||||
|
|
@ -33,9 +32,8 @@ service.interceptors.response.use(
|
|||
if (res.code && res.code !== 0) {
|
||||
// `token` 过期或者账号已在别处登录
|
||||
if (res.code === 401 || res.code === 4001) {
|
||||
clearSession(); // 清除浏览器全部临时缓存
|
||||
router.push('/login'); // 去登录页面
|
||||
resetRoute(); // 删除/重置路由
|
||||
Session.clear(); // 清除浏览器全部临时缓存
|
||||
window.location.href = '/'; // 去登录页
|
||||
ElMessageBox.alert('你已被登出,请重新登录', '提示', {})
|
||||
.then(() => {})
|
||||
.catch(() => {});
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ const cssCdnUrlList: Array<string> = [
|
|||
// 第三方 js url
|
||||
const jsCdnUrlList: Array<string> = [];
|
||||
|
||||
// 动态设置字体图标
|
||||
// 动态批量设置字体图标
|
||||
export function setCssCdn() {
|
||||
if (cssCdnUrlList.length <= 0) return false;
|
||||
cssCdnUrlList.map((v) => {
|
||||
|
|
@ -18,7 +18,7 @@ export function setCssCdn() {
|
|||
});
|
||||
}
|
||||
|
||||
// 批量设置第三方js
|
||||
// 动态批量设置第三方js
|
||||
export function setJsCdn() {
|
||||
if (jsCdnUrlList.length <= 0) return false;
|
||||
jsCdnUrlList.map((v) => {
|
||||
|
|
@ -28,11 +28,17 @@ export function setJsCdn() {
|
|||
});
|
||||
}
|
||||
|
||||
// 设置执行函数
|
||||
/**
|
||||
* 批量设置字体图标、动态js
|
||||
* @method cssCdn 动态批量设置字体图标
|
||||
* @method jsCdn 动态批量设置第三方js
|
||||
*/
|
||||
const setIntroduction = {
|
||||
// 设置css
|
||||
cssCdn: () => {
|
||||
setCssCdn();
|
||||
},
|
||||
// 设置js
|
||||
jsCdn: () => {
|
||||
setJsCdn();
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,43 +1,10 @@
|
|||
// 1. localStorage
|
||||
// 设置永久缓存
|
||||
export function setLocal(key: string, val: any) {
|
||||
window.localStorage.setItem(key, JSON.stringify(val));
|
||||
}
|
||||
// 获取永久缓存
|
||||
export function getLocal(key: string) {
|
||||
let json: any = window.localStorage.getItem(key);
|
||||
return JSON.parse(json);
|
||||
}
|
||||
// 移除永久缓存
|
||||
export function removeLocal(key: string) {
|
||||
window.localStorage.removeItem(key);
|
||||
}
|
||||
// 移除全部永久缓存
|
||||
export function clearLocal() {
|
||||
window.localStorage.clear();
|
||||
}
|
||||
|
||||
// 2. sessionStorage
|
||||
// 设置临时缓存
|
||||
export function setSession(key: string, val: any) {
|
||||
window.sessionStorage.setItem(key, JSON.stringify(val));
|
||||
}
|
||||
// 获取临时缓存
|
||||
export function getSession(key: string) {
|
||||
let json: any = window.sessionStorage.getItem(key);
|
||||
return JSON.parse(json);
|
||||
}
|
||||
// 移除临时缓存
|
||||
export function removeSession(key: string) {
|
||||
window.sessionStorage.removeItem(key);
|
||||
}
|
||||
// 移除全部临时缓存
|
||||
export function clearSession() {
|
||||
window.sessionStorage.clear();
|
||||
}
|
||||
|
||||
// 新写法,简单易记,建议使用
|
||||
// 1、window.localStorage 浏览器永久缓存
|
||||
/**
|
||||
* window.localStorage 浏览器永久缓存
|
||||
* @method set 设置永久缓存
|
||||
* @method get 获取永久缓存
|
||||
* @method remove 移除永久缓存
|
||||
* @method clear 移除全部永久缓存
|
||||
*/
|
||||
export const Local = {
|
||||
// 设置永久缓存
|
||||
set(key: string, val: any) {
|
||||
|
|
@ -58,7 +25,13 @@ export const Local = {
|
|||
},
|
||||
};
|
||||
|
||||
// 2、window.sessionStorage 浏览器临时缓存
|
||||
/**
|
||||
* window.sessionStorage 浏览器临时缓存
|
||||
* @method set 设置临时缓存
|
||||
* @method get 获取临时缓存
|
||||
* @method remove 移除临时缓存
|
||||
* @method clear 移除全部临时缓存
|
||||
*/
|
||||
export const Session = {
|
||||
// 设置临时缓存
|
||||
set(key: string, val: any) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
import { ElMessage } from 'element-plus';
|
||||
|
||||
// hex颜色转rgb颜色
|
||||
/**
|
||||
* hex颜色转rgb颜色
|
||||
* @param str 颜色值字符串
|
||||
* @returns 返回处理后的颜色值
|
||||
*/
|
||||
export function hexToRgb(str: any) {
|
||||
let hexs: any = '';
|
||||
let reg = /^\#?[0-9A-Fa-f]{6}$/;
|
||||
|
|
@ -11,7 +15,13 @@ export function hexToRgb(str: any) {
|
|||
return hexs;
|
||||
}
|
||||
|
||||
// rgb颜色转Hex颜色
|
||||
/**
|
||||
* rgb颜色转Hex颜色
|
||||
* @param r 代表红色
|
||||
* @param g 代表绿色
|
||||
* @param b 代表蓝色
|
||||
* @returns 返回处理后的颜色值
|
||||
*/
|
||||
export function rgbToHex(r: any, g: any, b: any) {
|
||||
let reg = /^\d{1,3}$/;
|
||||
if (!reg.test(r) || !reg.test(g) || !reg.test(b)) return ElMessage({ type: 'warning', message: '输入错误的rgb颜色值' });
|
||||
|
|
@ -20,7 +30,12 @@ export function rgbToHex(r: any, g: any, b: any) {
|
|||
return `#${hexs.join('')}`;
|
||||
}
|
||||
|
||||
// 加深颜色值,level为加深的程度,限0-1之间
|
||||
/**
|
||||
* 加深颜色值
|
||||
* @param color 颜色值字符串
|
||||
* @param level 加深的程度,限0-1之间
|
||||
* @returns 返回处理后的颜色值
|
||||
*/
|
||||
export function getDarkColor(color: any, level: number) {
|
||||
let reg = /^\#?[0-9A-Fa-f]{6}$/;
|
||||
if (!reg.test(color)) return ElMessage({ type: 'warning', message: '输入错误的hex颜色值' });
|
||||
|
|
@ -29,7 +44,12 @@ export function getDarkColor(color: any, level: number) {
|
|||
return rgbToHex(rgb[0], rgb[1], rgb[2]);
|
||||
}
|
||||
|
||||
// 变浅颜色值,level为加深的程度,限0-1之间
|
||||
/**
|
||||
* 变浅颜色值
|
||||
* @param color 颜色值字符串
|
||||
* @param level 加深的程度,限0-1之间
|
||||
* @returns 返回处理后的颜色值
|
||||
*/
|
||||
export function getLightColor(color: any, level: number) {
|
||||
let reg = /^\#?[0-9A-Fa-f]{6}$/;
|
||||
if (!reg.test(color)) return ElMessage({ type: 'warning', message: '输入错误的hex颜色值' });
|
||||
|
|
|
|||
|
|
@ -1,9 +1,14 @@
|
|||
/**
|
||||
* 2020.11.29 lyt 整理
|
||||
* 工具类集合,适用于平时开发
|
||||
* 新增多行注释信息,鼠标放到方法名即可查看
|
||||
*/
|
||||
|
||||
// 小数或整数(不可以负数)
|
||||
/**
|
||||
* 小数或整数(不可以负数)
|
||||
* @param val 当前值字符串
|
||||
* @returns 返回处理后的字符串
|
||||
*/
|
||||
export function verifyNumberIntegerAndFloat(val: string) {
|
||||
// 匹配空格
|
||||
let v = val.replace(/(^\s*)|(\s*$)/g, '');
|
||||
|
|
@ -21,7 +26,11 @@ export function verifyNumberIntegerAndFloat(val: string) {
|
|||
return v;
|
||||
}
|
||||
|
||||
// 正整数验证
|
||||
/**
|
||||
* 正整数验证
|
||||
* @param val 当前值字符串
|
||||
* @returns 返回处理后的字符串
|
||||
*/
|
||||
export function verifiyNumberInteger(val: string) {
|
||||
// 匹配空格
|
||||
let v = val.replace(/(^\s*)|(\s*$)/g, '');
|
||||
|
|
@ -37,7 +46,11 @@ export function verifiyNumberInteger(val: string) {
|
|||
return v;
|
||||
}
|
||||
|
||||
// 去掉中文及空格
|
||||
/**
|
||||
* 去掉中文及空格
|
||||
* @param val 当前值字符串
|
||||
* @returns 返回处理后的字符串
|
||||
*/
|
||||
export function verifyCnAndSpace(val: string) {
|
||||
// 匹配中文与空格
|
||||
let v = val.replace(/[\u4e00-\u9fa5\s]+/g, '');
|
||||
|
|
@ -47,7 +60,11 @@ export function verifyCnAndSpace(val: string) {
|
|||
return v;
|
||||
}
|
||||
|
||||
// 去掉英文及空格
|
||||
/**
|
||||
* 去掉英文及空格
|
||||
* @param val 当前值字符串
|
||||
* @returns 返回处理后的字符串
|
||||
*/
|
||||
export function verifyEnAndSpace(val: string) {
|
||||
// 匹配英文与空格
|
||||
let v = val.replace(/[a-zA-Z]+/g, '');
|
||||
|
|
@ -57,7 +74,11 @@ export function verifyEnAndSpace(val: string) {
|
|||
return v;
|
||||
}
|
||||
|
||||
// 禁止输入空格
|
||||
/**
|
||||
* 禁止输入空格
|
||||
* @param val 当前值字符串
|
||||
* @returns 返回处理后的字符串
|
||||
*/
|
||||
export function verifyAndSpace(val: string) {
|
||||
// 匹配空格
|
||||
let v = val.replace(/(^\s*)|(\s*$)/g, '');
|
||||
|
|
@ -65,7 +86,11 @@ export function verifyAndSpace(val: string) {
|
|||
return v;
|
||||
}
|
||||
|
||||
// 金额用 `,` 区分开
|
||||
/**
|
||||
* 金额用 `,` 区分开
|
||||
* @param val 当前值字符串
|
||||
* @returns 返回处理后的字符串
|
||||
*/
|
||||
export function verifyNumberComma(val: string) {
|
||||
// 调用小数或整数(不可以负数)方法
|
||||
let v: any = verifyNumberIntegerAndFloat(val);
|
||||
|
|
@ -79,7 +104,13 @@ export function verifyNumberComma(val: string) {
|
|||
return v;
|
||||
}
|
||||
|
||||
// 匹配文字变色(搜索时)
|
||||
/**
|
||||
* 匹配文字变色(搜索时)
|
||||
* @param val 当前值字符串
|
||||
* @param text 要处理的字符串值
|
||||
* @param color 搜索到时字体高亮颜色
|
||||
* @returns 返回处理后的字符串
|
||||
*/
|
||||
export function verifyTextColor(val: string, text = '', color = 'red') {
|
||||
// 返回内容,添加颜色
|
||||
let v = text.replace(new RegExp(val, 'gi'), `<span style='color: ${color}'>${val}</span>`);
|
||||
|
|
@ -87,7 +118,12 @@ export function verifyTextColor(val: string, text = '', color = 'red') {
|
|||
return v;
|
||||
}
|
||||
|
||||
// 数字转中文大写
|
||||
/**
|
||||
* 数字转中文大写
|
||||
* @param val 当前值字符串
|
||||
* @param unit 默认:仟佰拾亿仟佰拾万仟佰拾元角分
|
||||
* @returns 返回处理后的字符串
|
||||
*/
|
||||
export function verifyNumberCnUppercase(val: any, unit = '仟佰拾亿仟佰拾万仟佰拾元角分', v = '') {
|
||||
// 当前内容字符串添加 2个0,为什么??
|
||||
val += '00';
|
||||
|
|
@ -114,7 +150,11 @@ export function verifyNumberCnUppercase(val: any, unit = '仟佰拾亿仟佰拾
|
|||
return v;
|
||||
}
|
||||
|
||||
// 手机号码
|
||||
/**
|
||||
* 手机号码
|
||||
* @param val 当前值字符串
|
||||
* @returns 返回 true: 手机号码正确
|
||||
*/
|
||||
export function verifyPhone(val: string) {
|
||||
// false: 手机号码不正确
|
||||
if (!/^((12[0-9])|(13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0,5-9]))\d{8}$/.test(val)) return false;
|
||||
|
|
@ -122,7 +162,11 @@ export function verifyPhone(val: string) {
|
|||
else return true;
|
||||
}
|
||||
|
||||
// 国内电话号码
|
||||
/**
|
||||
* 国内电话号码
|
||||
* @param val 当前值字符串
|
||||
* @returns 返回 true: 国内电话号码正确
|
||||
*/
|
||||
export function verifyTelPhone(val: string) {
|
||||
// false: 国内电话号码不正确
|
||||
if (!/\d{3}-\d{8}|\d{4}-\d{7}/.test(val)) return false;
|
||||
|
|
@ -130,7 +174,11 @@ export function verifyTelPhone(val: string) {
|
|||
else return true;
|
||||
}
|
||||
|
||||
// 登录账号 (字母开头,允许5-16字节,允许字母数字下划线)
|
||||
/**
|
||||
* 登录账号 (字母开头,允许5-16字节,允许字母数字下划线)
|
||||
* @param val 当前值字符串
|
||||
* @returns 返回 true: 登录账号正确
|
||||
*/
|
||||
export function verifyAccount(val: string) {
|
||||
// false: 登录账号不正确
|
||||
if (!/^[a-zA-Z][a-zA-Z0-9_]{4,15}$/.test(val)) return false;
|
||||
|
|
@ -138,7 +186,11 @@ export function verifyAccount(val: string) {
|
|||
else return true;
|
||||
}
|
||||
|
||||
// 密码 (以字母开头,长度在6~16之间,只能包含字母、数字和下划线)
|
||||
/**
|
||||
* 密码 (以字母开头,长度在6~16之间,只能包含字母、数字和下划线)
|
||||
* @param val 当前值字符串
|
||||
* @returns 返回 true: 密码正确
|
||||
*/
|
||||
export function verifyPassword(val: string) {
|
||||
// false: 密码不正确
|
||||
if (!/^[a-zA-Z]\w{5,15}$/.test(val)) return false;
|
||||
|
|
@ -146,7 +198,11 @@ export function verifyPassword(val: string) {
|
|||
else return true;
|
||||
}
|
||||
|
||||
// 强密码 (字母+数字+特殊字符,长度在6-16之间)
|
||||
/**
|
||||
* 强密码 (字母+数字+特殊字符,长度在6-16之间)
|
||||
* @param val 当前值字符串
|
||||
* @returns 返回 true: 强密码正确
|
||||
*/
|
||||
export function verifyPasswordPowerful(val: string) {
|
||||
// false: 强密码不正确
|
||||
if (!/^(?![a-zA-z]+$)(?!\d+$)(?![!@#$%^&\.*]+$)(?![a-zA-z\d]+$)(?![a-zA-z!@#$%^&\.*]+$)(?![\d!@#$%^&\.*]+$)[a-zA-Z\d!@#$%^&\.*]{6,16}$/.test(val))
|
||||
|
|
@ -155,7 +211,14 @@ export function verifyPasswordPowerful(val: string) {
|
|||
else return true;
|
||||
}
|
||||
|
||||
// 密码强度
|
||||
/**
|
||||
* 密码强度
|
||||
* @param val 当前值字符串
|
||||
* @description 弱:纯数字,纯字母,纯特殊字符
|
||||
* @description 中:字母+数字,字母+特殊字符,数字+特殊字符
|
||||
* @description 强:字母+数字+特殊字符
|
||||
* @returns 返回处理后的字符串:弱、中、强
|
||||
*/
|
||||
export function verifyPasswordStrength(val: string) {
|
||||
let v = '';
|
||||
// 弱:纯数字,纯字母,纯特殊字符
|
||||
|
|
@ -169,7 +232,11 @@ export function verifyPasswordStrength(val: string) {
|
|||
return v;
|
||||
}
|
||||
|
||||
// IP地址
|
||||
/**
|
||||
* IP地址
|
||||
* @param val 当前值字符串
|
||||
* @returns 返回 true: IP地址正确
|
||||
*/
|
||||
export function verifyIPAddress(val: string) {
|
||||
// false: IP地址不正确
|
||||
if (
|
||||
|
|
@ -182,7 +249,11 @@ export function verifyIPAddress(val: string) {
|
|||
else return true;
|
||||
}
|
||||
|
||||
// 邮箱
|
||||
/**
|
||||
* 邮箱
|
||||
* @param val 当前值字符串
|
||||
* @returns 返回 true: 邮箱正确
|
||||
*/
|
||||
export function verifyEmail(val: string) {
|
||||
// false: 邮箱不正确
|
||||
if (
|
||||
|
|
@ -195,7 +266,11 @@ export function verifyEmail(val: string) {
|
|||
else return true;
|
||||
}
|
||||
|
||||
// 身份证
|
||||
/**
|
||||
* 身份证
|
||||
* @param val 当前值字符串
|
||||
* @returns 返回 true: 身份证正确
|
||||
*/
|
||||
export function verifyIdCard(val: string) {
|
||||
// false: 身份证不正确
|
||||
if (!/^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/.test(val)) return false;
|
||||
|
|
@ -203,7 +278,11 @@ export function verifyIdCard(val: string) {
|
|||
else return true;
|
||||
}
|
||||
|
||||
// 姓名
|
||||
/**
|
||||
* 姓名
|
||||
* @param val 当前值字符串
|
||||
* @returns 返回 true: 姓名正确
|
||||
*/
|
||||
export function verifyFullName(val: string) {
|
||||
// false: 姓名不正确
|
||||
if (!/^[\u4e00-\u9fa5]{1,6}(·[\u4e00-\u9fa5]{1,6}){0,2}$/.test(val)) return false;
|
||||
|
|
@ -211,7 +290,11 @@ export function verifyFullName(val: string) {
|
|||
else return true;
|
||||
}
|
||||
|
||||
// 邮政编码
|
||||
/**
|
||||
* 邮政编码
|
||||
* @param val 当前值字符串
|
||||
* @returns 返回 true: 邮政编码正确
|
||||
*/
|
||||
export function verifyPostalCode(val: string) {
|
||||
// false: 邮政编码不正确
|
||||
if (!/^[1-9][0-9]{5}$/.test(val)) return false;
|
||||
|
|
@ -219,7 +302,11 @@ export function verifyPostalCode(val: string) {
|
|||
else return true;
|
||||
}
|
||||
|
||||
// url
|
||||
/**
|
||||
* url 处理
|
||||
* @param val 当前值字符串
|
||||
* @returns 返回 true: url 正确
|
||||
*/
|
||||
export function verifyUrl(val: string) {
|
||||
// false: url不正确
|
||||
if (
|
||||
|
|
@ -232,7 +319,11 @@ export function verifyUrl(val: string) {
|
|||
else return true;
|
||||
}
|
||||
|
||||
// 车牌号
|
||||
/**
|
||||
* 车牌号
|
||||
* @param val 当前值字符串
|
||||
* @returns 返回 true:车牌号正确
|
||||
*/
|
||||
export function verifyCarNum(val: string) {
|
||||
// false: 车牌号不正确
|
||||
if (
|
||||
|
|
|
|||
|
|
@ -1,20 +1,25 @@
|
|||
// vite 打包相关
|
||||
import dotenv from 'dotenv';
|
||||
|
||||
// 定义接口类型声明
|
||||
export interface ViteEnv {
|
||||
VITE_PORT: number;
|
||||
VITE_OPEN: boolean;
|
||||
VITE_PUBLIC_PATH: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* vite 打包相关
|
||||
* @link 参考:https://cn.vitejs.dev/guide/env-and-mode.html
|
||||
* @returns 返回 `VITE_xxx` 环境变量和模式信息
|
||||
*/
|
||||
export function loadEnv(): ViteEnv {
|
||||
const env = process.env.NODE_ENV;
|
||||
const ret: any = {};
|
||||
const envList = [`.env.${env}.local`, `.env.${env}`, '.env.local', '.env', ,];
|
||||
const envList = [`.env.${env}.local`, `.env.${env}`, '.env.local', '.env'];
|
||||
envList.forEach((e) => {
|
||||
dotenv.config({ path: e });
|
||||
});
|
||||
for (const envName of Object.keys(process.env)) {
|
||||
console.log(envName);
|
||||
let realName = (process.env as any)[envName].replace(/\\n/g, '\n');
|
||||
realName = realName === 'true' ? true : realName === 'false' ? false : realName;
|
||||
if (envName === 'VITE_PORT') realName = Number(realName);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// 页面添加水印效果
|
||||
const setWatermark = (str: any) => {
|
||||
const setWatermark = (str: string) => {
|
||||
const id = '1.23452384164.123412416';
|
||||
if (document.getElementById(id) !== null) document.body.removeChild(document.getElementById(id) as any);
|
||||
const can = document.createElement('canvas');
|
||||
|
|
@ -26,10 +26,14 @@ const setWatermark = (str: any) => {
|
|||
return id;
|
||||
};
|
||||
|
||||
// 定义导出方法集合
|
||||
/**
|
||||
* 页面添加水印效果
|
||||
* @method set 设置水印
|
||||
* @method del 删除水印
|
||||
*/
|
||||
const watermark = {
|
||||
// 设置水印
|
||||
set: (str: any) => {
|
||||
set: (str: string) => {
|
||||
let id = setWatermark(str);
|
||||
if (document.getElementById(id) === null) id = setWatermark(str);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
// sky 天气
|
||||
/**
|
||||
* sky 天气
|
||||
* @returns 返回模拟数据
|
||||
*/
|
||||
export const skyList = [
|
||||
{
|
||||
v1: '时间',
|
||||
|
|
@ -24,7 +27,10 @@ export const skyList = [
|
|||
},
|
||||
];
|
||||
|
||||
// 当前设置状态
|
||||
/**
|
||||
* 当前设置状态
|
||||
* @returns 返回模拟数据
|
||||
*/
|
||||
export const dBtnList = [
|
||||
{
|
||||
v2: '阳光玫瑰种植',
|
||||
|
|
@ -33,7 +39,10 @@ export const dBtnList = [
|
|||
},
|
||||
];
|
||||
|
||||
// 当前设备监测
|
||||
/**
|
||||
* 当前设备监测
|
||||
* @returns 返回模拟数据
|
||||
*/
|
||||
export const chartData4List = [
|
||||
{
|
||||
label: '温度',
|
||||
|
|
@ -49,7 +58,10 @@ export const chartData4List = [
|
|||
},
|
||||
];
|
||||
|
||||
// 3DEarth 地图周围按钮组
|
||||
/**
|
||||
* 3DEarth 地图周围按钮组
|
||||
* @returns 返回模拟数据
|
||||
*/
|
||||
export const earth3DBtnList = [
|
||||
{
|
||||
topLevelClass: 'fixed-top',
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
<script lang="ts">
|
||||
import { reactive, toRefs, onBeforeMount, onUnmounted } from 'vue';
|
||||
import { formatDate } from '/@/utils/formatTime.ts';
|
||||
import { formatDate } from '/@/utils/formatTime';
|
||||
export default {
|
||||
name: 'chartHead',
|
||||
setup() {
|
||||
|
|
|
|||
|
|
@ -203,11 +203,11 @@
|
|||
|
||||
<script lang="ts">
|
||||
import { toRefs, reactive, computed, onMounted, getCurrentInstance } from 'vue';
|
||||
import { useStore } from '/@/store/index.ts';
|
||||
import { useStore } from '/@/store/index';
|
||||
import ChartHead from '/@/views/chart/head.vue';
|
||||
import * as echarts from 'echarts';
|
||||
import 'echarts-wordcloud';
|
||||
import { skyList, dBtnList, chartData4List, earth3DBtnList } from '/@/views/chart/chart.ts';
|
||||
import { skyList, dBtnList, chartData4List, earth3DBtnList } from '/@/views/chart/chart';
|
||||
export default {
|
||||
name: 'chartIndex',
|
||||
components: { ChartHead },
|
||||
|
|
|
|||
|
|
@ -20,13 +20,13 @@
|
|||
|
||||
<script lang="ts">
|
||||
import { useRouter } from 'vue-router';
|
||||
import { clearSession } from '/@/utils/storage.ts';
|
||||
import { Session } from '/@/utils/storage';
|
||||
export default {
|
||||
name: '401',
|
||||
setup() {
|
||||
const router = useRouter();
|
||||
const onSetAuth = () => {
|
||||
clearSession();
|
||||
Session.clear();
|
||||
router.push('/login');
|
||||
};
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@
|
|||
import { toRefs, reactive, computed, onMounted } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
import 'echarts/extension/bmap/bmap';
|
||||
import { useStore } from '/@/store/index.ts';
|
||||
import { echartsMapList, echartsMapData } from './mock.ts';
|
||||
import { useStore } from '/@/store/index';
|
||||
import { echartsMapList, echartsMapData } from './mock';
|
||||
export default {
|
||||
name: 'funEchartsMap',
|
||||
setup() {
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@
|
|||
<script lang="ts">
|
||||
import { toRefs, reactive, computed, onMounted, getCurrentInstance } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
import { useStore } from '/@/store/index.ts';
|
||||
import { echartsTreeList } from './mock.ts';
|
||||
import { useStore } from '/@/store/index';
|
||||
import { echartsTreeList } from './mock';
|
||||
export default {
|
||||
name: 'funEchartsTree',
|
||||
setup() {
|
||||
|
|
|
|||
|
|
@ -4,11 +4,13 @@
|
|||
<el-col :sm="6" class="mb15">
|
||||
<div class="home-card-item home-card-first">
|
||||
<div class="flex-margin flex">
|
||||
<img src="https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1813762643,1914315241&fm=26&gp=0.jpg" />
|
||||
<img :src="getUserInfos.photo" />
|
||||
<div class="home-card-first-right ml15">
|
||||
<div class="flex-margin">
|
||||
<div class="home-card-first-right-title">{{ currentTime }},admin!</div>
|
||||
<div class="home-card-first-right-msg mt5">超级管理</div>
|
||||
<div class="home-card-first-right-title">
|
||||
{{ currentTime }},{{ getUserInfos.userName === '' ? 'test' : getUserInfos.userName }}!
|
||||
</div>
|
||||
<div class="home-card-first-right-msg mt5">{{ getUserInfos.userName === 'admin' ? '超级管理' : '普通用户' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -97,12 +99,14 @@
|
|||
import { toRefs, reactive, onMounted, nextTick, computed, getCurrentInstance } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
import { CountUp } from 'countup.js';
|
||||
import { formatAxis } from '/@/utils/formatTime.ts';
|
||||
import { topCardItemList, environmentList, activitiesList } from './mock.ts';
|
||||
import { formatAxis } from '/@/utils/formatTime';
|
||||
import { useStore } from '/@/store/index';
|
||||
import { topCardItemList, environmentList, activitiesList } from './mock';
|
||||
export default {
|
||||
name: 'home',
|
||||
setup() {
|
||||
const { proxy } = getCurrentInstance() as any;
|
||||
const store = useStore();
|
||||
const state = reactive({
|
||||
topCardItemList,
|
||||
environmentList,
|
||||
|
|
@ -127,6 +131,10 @@ export default {
|
|||
],
|
||||
},
|
||||
});
|
||||
// 获取用户信息 vuex
|
||||
const getUserInfos = computed(() => {
|
||||
return store.state.userInfos.userInfos;
|
||||
});
|
||||
// 当前时间提示语
|
||||
const currentTime = computed(() => {
|
||||
return formatAxis(new Date());
|
||||
|
|
@ -247,6 +255,7 @@ export default {
|
|||
initHomeOvertime();
|
||||
});
|
||||
return {
|
||||
getUserInfos,
|
||||
currentTime,
|
||||
...toRefs(state),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
// 最顶部 card
|
||||
/**
|
||||
* 最顶部 card
|
||||
* @returns 返回模拟数据
|
||||
*/
|
||||
export const topCardItemList = [
|
||||
{
|
||||
title: '今日访问人数',
|
||||
|
|
@ -29,7 +32,10 @@ export const topCardItemList = [
|
|||
},
|
||||
];
|
||||
|
||||
// 环境监测
|
||||
/**
|
||||
* 环境监测
|
||||
* @returns 返回模拟数据
|
||||
*/
|
||||
export const environmentList = [
|
||||
{
|
||||
icon: 'iconfont icon-yangan',
|
||||
|
|
@ -57,7 +63,10 @@ export const environmentList = [
|
|||
},
|
||||
];
|
||||
|
||||
// 动态信息
|
||||
/**
|
||||
* 动态信息
|
||||
* @returns 返回模拟数据
|
||||
*/
|
||||
export const activitiesList = [
|
||||
{
|
||||
time1: '今天',
|
||||
|
|
|
|||
|
|
@ -205,7 +205,7 @@ import LimitsFrontEndPage from '/@/views/limits/frontEnd/page/index.vue';
|
|||
import Auth from '/@/components/auth/auth.vue';
|
||||
import Auths from '/@/components/auth/auths.vue';
|
||||
import AuthAll from '/@/components/auth/authAll.vue';
|
||||
import { auth, auths, authAll } from '/@/utils/authFunction.ts';
|
||||
import { auth, auths, authAll } from '/@/utils/authFunction';
|
||||
export default {
|
||||
name: 'limitsFrontEndBtn',
|
||||
components: { LimitsFrontEndPage, Auth, Auths, AuthAll },
|
||||
|
|
|
|||
|
|
@ -24,9 +24,9 @@
|
|||
|
||||
<script lang="ts">
|
||||
import { toRefs, reactive, computed, onMounted } from 'vue';
|
||||
import { useStore } from '/@/store/index.ts';
|
||||
import { resetRoute, setAddRoute, setFilterMenu, setCacheTagsViewRoutes } from '/@/router/index.ts';
|
||||
import { setSession } from '/@/utils/storage.ts';
|
||||
import { useStore } from '/@/store/index';
|
||||
import { resetRoute, setAddRoute, setFilterMenuAndCacheTagsViewRoutes } from '/@/router/index';
|
||||
import { Session } from '/@/utils/storage';
|
||||
export default {
|
||||
name: 'limitsFrontEndPage',
|
||||
setup() {
|
||||
|
|
@ -47,25 +47,20 @@ export default {
|
|||
const initUserAuth = () => {
|
||||
state.userAuth = store.state.userInfos.userInfos.authPageList[0];
|
||||
};
|
||||
// 重新执行添加动态路由、过滤权限菜单、缓存等方法
|
||||
const initAllFun = () => {
|
||||
setAddRoute();
|
||||
setFilterMenu();
|
||||
setCacheTagsViewRoutes();
|
||||
};
|
||||
// 用户权限改变时
|
||||
const onRadioChange = () => {
|
||||
const onRadioChange = async () => {
|
||||
resetRoute();
|
||||
let defaultAuthPageList: Array<string> = [];
|
||||
let defaultAuthBtnList: Array<string> = [];
|
||||
// admin 页面权限标识,对应路由 meta.auth
|
||||
// admin 页面权限标识,对应路由 meta.auth,用于控制路由的显示/隐藏
|
||||
let adminAuthPageList: Array<string> = ['admin'];
|
||||
// admin 按钮权限标识
|
||||
let adminAuthBtnList: Array<string> = ['btn.add', 'btn.del', 'btn.edit', 'btn.link'];
|
||||
// test 页面权限标识,对应路由 meta.auth
|
||||
// test 页面权限标识,对应路由 meta.auth,用于控制路由的显示/隐藏
|
||||
let testAuthPageList: Array<string> = ['test'];
|
||||
// test 按钮权限标识
|
||||
let testAuthBtnList: Array<string> = ['btn.add', 'btn.link'];
|
||||
// 不同用户模拟不同的用户权限
|
||||
if (state.userAuth === 'admin') {
|
||||
defaultAuthPageList = adminAuthPageList;
|
||||
defaultAuthBtnList = adminAuthBtnList;
|
||||
|
|
@ -83,9 +78,10 @@ export default {
|
|||
authPageList: defaultAuthPageList,
|
||||
authBtnList: defaultAuthBtnList,
|
||||
};
|
||||
setSession('userInfo', userInfos);
|
||||
Session.set('userInfo', userInfos);
|
||||
store.dispatch('userInfos/setUserInfos', userInfos); // 请注意执行顺序(存储用户信息vuex)
|
||||
initAllFun(); // 请注意执行顺序
|
||||
await setAddRoute();
|
||||
setFilterMenuAndCacheTagsViewRoutes();
|
||||
};
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
|
|
|
|||
|
|
@ -55,10 +55,11 @@ import { toRefs, reactive, defineComponent, computed, getCurrentInstance } from
|
|||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { initAllFun, initBackEndControlRoutesFun } from '/@/router/index.ts';
|
||||
import { useStore } from '/@/store/index.ts';
|
||||
import { setSession } from '/@/utils/storage.ts';
|
||||
import { formatAxis } from '/@/utils/formatTime.ts';
|
||||
import { initFrontEndControlRoutes } from '/@/router/frontEnd';
|
||||
import { initBackEndControlRoutes } from '/@/router/backEnd';
|
||||
import { useStore } from '/@/store/index';
|
||||
import { Session } from '/@/utils/storage';
|
||||
import { formatAxis } from '/@/utils/formatTime';
|
||||
export default defineComponent({
|
||||
name: 'login',
|
||||
setup() {
|
||||
|
|
@ -86,14 +87,15 @@ export default defineComponent({
|
|||
state.loading.signIn = true;
|
||||
let defaultAuthPageList: Array<string> = [];
|
||||
let defaultAuthBtnList: Array<string> = [];
|
||||
// admin 页面权限标识,对应路由 meta.auth
|
||||
// admin 页面权限标识,对应路由 meta.auth,用于控制路由的显示/隐藏
|
||||
let adminAuthPageList: Array<string> = ['admin'];
|
||||
// admin 按钮权限标识
|
||||
let adminAuthBtnList: Array<string> = ['btn.add', 'btn.del', 'btn.edit', 'btn.link'];
|
||||
// test 页面权限标识,对应路由 meta.auth
|
||||
// test 页面权限标识,对应路由 meta.auth,用于控制路由的显示/隐藏
|
||||
let testAuthPageList: Array<string> = ['test'];
|
||||
// test 按钮权限标识
|
||||
let testAuthBtnList: Array<string> = ['btn.add', 'btn.link'];
|
||||
// 不同用户模拟不同的用户权限
|
||||
if (state.ruleForm.userName === 'admin') {
|
||||
defaultAuthPageList = adminAuthPageList;
|
||||
defaultAuthBtnList = adminAuthBtnList;
|
||||
|
|
@ -113,20 +115,20 @@ export default defineComponent({
|
|||
authBtnList: defaultAuthBtnList,
|
||||
};
|
||||
// 存储 token 到浏览器缓存
|
||||
setSession('token', Math.random().toString(36).substr(0));
|
||||
Session.set('token', Math.random().toString(36).substr(0));
|
||||
// 存储用户信息到浏览器缓存
|
||||
setSession('userInfo', userInfos);
|
||||
Session.set('userInfo', userInfos);
|
||||
// 1、请注意执行顺序(存储用户信息到vuex)
|
||||
store.dispatch('userInfos/setUserInfos', userInfos);
|
||||
if (!store.state.themeConfig.themeConfig.isRequestRoutes) {
|
||||
// 前端控制路由,2、请注意执行顺序
|
||||
await initAllFun();
|
||||
await initFrontEndControlRoutes();
|
||||
signInSuccess();
|
||||
} else {
|
||||
// 模拟后端控制路由,isRequestRoutes 为 true,则开启后端控制路由
|
||||
// 添加完动态路由,再进行 router 跳转,否则可能报错 No match found for location with path "/"
|
||||
await initBackEndControlRoutesFun();
|
||||
// 执行完 initBackEndControlRoutesFun,再执行 signInSuccess
|
||||
await initBackEndControlRoutes();
|
||||
// 执行完 initBackEndControlRoutes,再执行 signInSuccess
|
||||
signInSuccess();
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
import { toRefs, reactive, computed } from 'vue';
|
||||
import Account from '/@/views/login/component/account.vue';
|
||||
import Mobile from '/@/views/login/component/mobile.vue';
|
||||
import { useStore } from '/@/store/index.ts';
|
||||
import { useStore } from '/@/store/index';
|
||||
export default {
|
||||
name: 'login',
|
||||
components: { Account, Mobile },
|
||||
|
|
@ -89,7 +89,7 @@ export default {
|
|||
left: 50%;
|
||||
transform: translate(-50%, -50%) translate3d(0, 0, 0);
|
||||
background-color: rgba(255, 255, 255, 0.99);
|
||||
box-shadow: 0 2px 12px 0 var(--color-primary-light-5);
|
||||
border: 5px solid var(--color-primary-light-8);
|
||||
border-radius: 4px;
|
||||
transition: height 0.2s linear;
|
||||
height: 480px;
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
<script lang="ts">
|
||||
import { toRefs, reactive, onMounted } from 'vue';
|
||||
import initIconfont from '/@/utils/getStyleSheets.ts';
|
||||
import initIconfont from '/@/utils/getStyleSheets';
|
||||
export default {
|
||||
name: 'pagesAwesome',
|
||||
setup() {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
<script lang="ts">
|
||||
import { toRefs, reactive, onMounted } from 'vue';
|
||||
import initIconfont from '/@/utils/getStyleSheets.ts';
|
||||
import initIconfont from '/@/utils/getStyleSheets';
|
||||
export default {
|
||||
name: 'pagesElement',
|
||||
setup() {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
<script lang="ts">
|
||||
import { toRefs, reactive, computed } from 'vue';
|
||||
import { useStore } from '/@/store/index.ts';
|
||||
import { useStore } from '/@/store/index';
|
||||
export default {
|
||||
name: 'pagesFilteringDetails',
|
||||
setup() {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
<script lang="ts">
|
||||
import { toRefs, reactive, computed } from 'vue';
|
||||
import { useStore } from '/@/store/index.ts';
|
||||
import { useStore } from '/@/store/index';
|
||||
export default {
|
||||
name: 'pagesFilteringDetails1',
|
||||
setup() {
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@
|
|||
<script lang="ts">
|
||||
import { ref, toRefs, reactive, onMounted, nextTick } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { filtering, filterList } from './mock.ts';
|
||||
import { filtering, filterList } from './mock';
|
||||
export default {
|
||||
name: 'pagesFiltering',
|
||||
setup() {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
<script lang="ts">
|
||||
import { toRefs, reactive, onMounted } from 'vue';
|
||||
import initIconfont from '/@/utils/getStyleSheets.ts';
|
||||
import initIconfont from '/@/utils/getStyleSheets';
|
||||
export default {
|
||||
name: 'pagesIocnfont',
|
||||
setup() {
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@
|
|||
<script lang="ts">
|
||||
import { toRefs, reactive } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { filterList } from './mock.ts';
|
||||
import { filterList } from './mock';
|
||||
export default {
|
||||
name: 'pagesListAdapt',
|
||||
setup() {
|
||||
|
|
|
|||
|
|
@ -180,8 +180,8 @@
|
|||
|
||||
<script lang="ts">
|
||||
import { toRefs, reactive, computed } from 'vue';
|
||||
import { formatAxis } from '/@/utils/formatTime.ts';
|
||||
import { newsInfoList, recommendList } from './mock.ts';
|
||||
import { formatAxis } from '/@/utils/formatTime';
|
||||
import { newsInfoList, recommendList } from './mock';
|
||||
export default {
|
||||
name: 'personal',
|
||||
setup() {
|
||||
|
|
|
|||
|
|
@ -1,60 +1,66 @@
|
|||
// 消息通知
|
||||
/**
|
||||
* 消息通知
|
||||
* @returns 返回模拟数据
|
||||
*/
|
||||
export const newsInfoList: Array<object> = [
|
||||
{
|
||||
title: '[发布] 2021年02月28日发布基于 vue3.x + vite v1.0.0 版本',
|
||||
date: '02/28',
|
||||
link: 'https://gitee.com/lyt-top/vue-next-admin'
|
||||
link: 'https://gitee.com/lyt-top/vue-next-admin',
|
||||
},
|
||||
{
|
||||
title: '[发布] 2021年04月15日发布 vue2.x + webpack 重构版本',
|
||||
date: '04/15',
|
||||
link: 'https://gitee.com/lyt-top/vue-next-admin/tree/vue-prev-admin/'
|
||||
link: 'https://gitee.com/lyt-top/vue-next-admin/tree/vue-prev-admin/',
|
||||
},
|
||||
{
|
||||
title: '[重构] 2021年04月10日 重构 vue2.x + webpack v1.0.0 版本',
|
||||
date: '04/10',
|
||||
link: 'https://gitee.com/lyt-top/vue-next-admin/tree/vue-prev-admin/'
|
||||
link: 'https://gitee.com/lyt-top/vue-next-admin/tree/vue-prev-admin/',
|
||||
},
|
||||
{
|
||||
title: '[预览] 2020年12月08日,基于 vue3.x 版本后台模板的预览',
|
||||
date: '12/08',
|
||||
link: 'http://lyt-top.gitee.io/vue-next-admin-preview/#/login'
|
||||
link: 'http://lyt-top.gitee.io/vue-next-admin-preview/#/login',
|
||||
},
|
||||
{
|
||||
title: '[预览] 2020年11月15日,基于 vue2.x 版本后台模板的预览',
|
||||
date: '11/15',
|
||||
link: 'https://lyt-top.gitee.io/vue-prev-admin-preview/#/login'
|
||||
}
|
||||
link: 'https://lyt-top.gitee.io/vue-prev-admin-preview/#/login',
|
||||
},
|
||||
];
|
||||
|
||||
// 营销推荐
|
||||
/**
|
||||
* 营销推荐
|
||||
* @returns 返回模拟数据
|
||||
*/
|
||||
export const recommendList: Array<object> = [
|
||||
{
|
||||
title: '优惠券',
|
||||
msg: '现金券、折扣券、营销必备',
|
||||
icon: 'el-icon-food',
|
||||
bg: '#48D18D',
|
||||
iconColor: '#64d89d'
|
||||
iconColor: '#64d89d',
|
||||
},
|
||||
{
|
||||
title: '多人拼团',
|
||||
msg: '社交电商、开辟流量',
|
||||
icon: 'el-icon-shopping-bag-1',
|
||||
bg: '#F95959',
|
||||
iconColor: '#F86C6B'
|
||||
iconColor: '#F86C6B',
|
||||
},
|
||||
{
|
||||
title: '分销中心',
|
||||
msg: '轻松招募分销员,成功推广奖励',
|
||||
icon: 'el-icon-school',
|
||||
bg: '#8595F4',
|
||||
iconColor: '#92A1F4'
|
||||
iconColor: '#92A1F4',
|
||||
},
|
||||
{
|
||||
title: '秒杀',
|
||||
msg: '超低价抢购引导更多销量',
|
||||
icon: 'el-icon-alarm-clock',
|
||||
bg: '#FEBB50',
|
||||
iconColor: '#FDC566'
|
||||
}
|
||||
iconColor: '#FDC566',
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -98,14 +98,14 @@
|
|||
|
||||
<script lang="ts">
|
||||
import { reactive, toRefs } from 'vue';
|
||||
// import { setBackEndControlRefreshRoutes } from "/@/router/index.ts";
|
||||
// import { setBackEndControlRefreshRoutes } from "/@/router/backEnd";
|
||||
export default {
|
||||
name: 'systemAddMenu',
|
||||
setup() {
|
||||
const state = reactive({
|
||||
isShowDialog: false,
|
||||
/**
|
||||
* 参数请参考 `/src/router/index.ts` 中的 `dynamicRoutes` 路由菜单格式(请注意参数类型!)
|
||||
* 参数请参考 `/src/router/route.ts` 中的 `dynamicRoutes` 路由菜单格式(请注意参数类型!)
|
||||
* 受到 `element plus` 类型 `string/number/object` 影响,不可使用 `:value="true"`
|
||||
* 的写法,所以传值到后台时,需要转换成布尔值,否则页面可能出现玄学。
|
||||
* 路由权限标识为数组格式,基本都需要自行转换类型
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@
|
|||
<script lang="ts">
|
||||
import { reactive, toRefs } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
// import { setBackEndControlRefreshRoutes } from "/@/router/index.ts";
|
||||
// import { setBackEndControlRefreshRoutes } from "/@/router/backEnd";
|
||||
export default {
|
||||
name: 'systemEditMenu',
|
||||
setup() {
|
||||
|
|
@ -107,7 +107,7 @@ export default {
|
|||
const state = reactive({
|
||||
isShowDialog: false,
|
||||
/**
|
||||
* 参数请参考 `/src/router/index.ts` 中的 `dynamicRoutes` 路由菜单格式(请注意参数类型!)
|
||||
* 参数请参考 `/src/router/route.ts` 中的 `dynamicRoutes` 路由菜单格式(请注意参数类型!)
|
||||
* 受到 `element plus` 类型 `string/number/object` 影响,不可使用 `:value="true"`
|
||||
* 的写法,所以传值到后台时,需要转换成布尔值,否则页面可能出现玄学。
|
||||
* 路由权限标识为数组格式,基本都需要自行转换类型
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@
|
|||
<script lang="ts">
|
||||
import { ref, toRefs, reactive, computed } from 'vue';
|
||||
import { ElMessageBox } from 'element-plus';
|
||||
import { useStore } from '/@/store/index.ts';
|
||||
import { useStore } from '/@/store/index';
|
||||
import AddMenu from '/@/views/system/menu/component/addMenu.vue';
|
||||
import EditMenu from '/@/views/system/menu/component/editMenu.vue';
|
||||
export default {
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ import {
|
|||
verifyPostalCode,
|
||||
verifyUrl,
|
||||
verifyCarNum,
|
||||
} from '/@/utils/toolsValidate.ts';
|
||||
} from '/@/utils/toolsValidate';
|
||||
export default {
|
||||
name: 'tools',
|
||||
setup() {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import vue from '@vitejs/plugin-vue';
|
||||
import { resolve } from 'path';
|
||||
import type { UserConfig } from 'vite';
|
||||
import { loadEnv } from './src/utils/viteBuild.ts';
|
||||
import { loadEnv } from './src/utils/viteBuild';
|
||||
|
||||
const pathResolve = (dir: string): any => {
|
||||
return resolve(__dirname, '.', dir);
|
||||
|
|
|
|||
Loading…
Reference in New Issue