'admin-21.06.19:修复诸多问题,具体查看CHANGELOG.md文件1.04更新日志'

This commit is contained in:
lyt-Top 2021-06-19 17:49:42 +08:00
parent 1ade90a114
commit 9a43e1d6c7
94 changed files with 1734 additions and 1344 deletions

View File

@ -57,5 +57,6 @@ module.exports = {
'no-unused-vars': 'error',
'no-v-model-argument': 'off',
'no-case-declarations': 'off',
'no-console': 'error',
},
};

View File

@ -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

View File

@ -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": [

7
shim.d.ts vendored
View File

@ -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;
}

View File

@ -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;
});
}
);

View File

@ -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',

View File

@ -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',

View File

@ -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: {

View File

@ -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: {

View File

@ -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: {

View File

@ -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: {

View File

@ -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';
// 定义语言国际化内容
/**

View File

@ -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',

View File

@ -71,6 +71,7 @@ export default {
dropdown3: '404',
dropdown4: '401',
dropdown5: '退出登录',
dropdown6: '代码仓库',
searchPlaceholder: '菜单搜索:支持中文、路由路径',
newTitle: '通知',
newBtn: '全部已读',

View File

@ -71,6 +71,7 @@ export default {
dropdown3: '404',
dropdown4: '401',
dropdown5: '登出',
dropdown6: '程式碼倉庫',
searchPlaceholder: '選單蒐索:支援中文、路由路徑',
newTitle: '通知',
newBtn: '全部已讀',

View File

@ -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 },

View File

@ -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() {

View File

@ -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 },

View File

@ -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 },

View File

@ -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,
});
}

View File

@ -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 = () => {

View File

@ -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() {

View File

@ -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 },

View File

@ -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 },

View File

@ -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 },

View File

@ -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 },

View File

@ -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() {

View File

@ -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 },

View File

@ -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() {

View File

@ -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(() => {

View File

@ -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();
}

View File

@ -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 },

View File

@ -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 });

View File

@ -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 },

View File

@ -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 },

View File

@ -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() {

View File

@ -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';

98
src/router/backEnd.ts Normal file
View File

@ -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;
}
}

24
src/router/frontEnd.ts Normal file
View File

@ -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();
}

File diff suppressed because it is too large Load Diff

869
src/router/route.ts Normal file
View File

@ -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: '没有权限',
},
},
];

View File

@ -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() {

View File

@ -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

View File

@ -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'));
}
},
},

View File

@ -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;
}
}
}

View File

@ -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) {

View File

@ -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;
});
});

View File

@ -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);
}

View File

@ -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;

View File

@ -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);

21
src/utils/deepClone.ts Normal file
View File

@ -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;
}

View File

@ -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);

View File

@ -1,20 +1,17 @@
/*
* (Y) 1-4
* (m)(d)(H)(M)(S) 1-2
* (W) 1-3
* (q为阿拉伯数字Q为中文数字)14
*
* 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
* 2460 * 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 2460 * 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 '早上好';

View File

@ -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: () => {

View File

@ -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);

View File

@ -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(() => {});

View File

@ -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();
},

View File

@ -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) {

View File

@ -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颜色值' });

View File

@ -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 (

View File

@ -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);

View File

@ -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);
},

View File

@ -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',

View File

@ -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() {

View File

@ -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 },

View File

@ -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 {

View File

@ -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() {

View File

@ -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() {

View File

@ -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),
};

View File

@ -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: '今天',

View File

@ -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 },

View File

@ -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(() => {

View File

@ -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();
}
};

View File

@ -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;

View File

@ -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() {

View File

@ -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() {

View File

@ -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() {

View File

@ -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() {

View File

@ -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() {

View File

@ -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() {

View File

@ -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() {

View File

@ -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() {

View File

@ -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',
},
];

View File

@ -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"`
* 的写法所以传值到后台时需要转换成布尔值否则页面可能出现玄学
* 路由权限标识为数组格式基本都需要自行转换类型

View File

@ -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"`
* 的写法所以传值到后台时需要转换成布尔值否则页面可能出现玄学
* 路由权限标识为数组格式基本都需要自行转换类型

View File

@ -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 {

View File

@ -195,7 +195,7 @@ import {
verifyPostalCode,
verifyUrl,
verifyCarNum,
} from '/@/utils/toolsValidate.ts';
} from '/@/utils/toolsValidate';
export default {
name: 'tools',
setup() {

View File

@ -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);