Merge branch 'master' of https://github.com/zouzhibin/vue-admin-perfect into vue-i18n
Conflicts: src/layout/Header/components/globalComSize.vue src/router/modules/charts.ts src/router/modules/error.ts src/router/modules/other.ts src/router/modules/table.ts
This commit is contained in:
commit
c0f5728373
|
|
@ -2,9 +2,9 @@
|
||||||
<html lang="en" class="dark">
|
<html lang="en" class="dark">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
<link rel="icon" href="/favicon.ico">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Vite + Vue + TS</title>
|
<title>Vue admin perfect</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
<link rel="icon" href="/favicon.ico">
|
||||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
<el-breadcrumb class="app-breadcrumb" separator="/">
|
<el-breadcrumb class="app-breadcrumb" separator="/">
|
||||||
<transition-group name="breadcrumb" mode="out-in">
|
<transition-group name="breadcrumb" mode="out-in">
|
||||||
<el-breadcrumb-item v-for="(item, index) in levelList" :key="item.path">
|
<el-breadcrumb-item v-for="(item, index) in matched" :key="item.name">
|
||||||
<span v-if="item.redirect === 'noRedirect' || index == levelList.length - 1" class="no-redirect">{{ item.meta.title }}</span>
|
<span v-if="item.redirect === 'noRedirect' || index == matched.length - 1" class="no-redirect">{{ item.meta.title }}</span>
|
||||||
<a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
|
<a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
|
||||||
</el-breadcrumb-item>
|
</el-breadcrumb-item>
|
||||||
</transition-group>
|
</transition-group>
|
||||||
|
|
@ -11,45 +11,20 @@
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import pathToRegexp from 'path-to-regexp'
|
import pathToRegexp from 'path-to-regexp'
|
||||||
import { onMounted, ref, watch } from 'vue'
|
import { onMounted, ref, watch,computed } from 'vue'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute ,useRouter} from 'vue-router'
|
||||||
|
|
||||||
const levelList = ref([])
|
const levelList = ref([])
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
// 获取面包屑
|
const handleLink = (item)=>{
|
||||||
const getBreadcrumb = () => {
|
router.push({
|
||||||
let matched = route.matched.filter((item) => item.meta && item.meta.title)
|
path:item.path
|
||||||
const first = matched[0]
|
|
||||||
levelList.value = matched.filter(
|
|
||||||
(item) => item.meta && item.meta.title && item.meta.breadcrumb !== false,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleLink = ()=>{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
getBreadcrumb()
|
|
||||||
watch(route, () => {
|
|
||||||
if (route.path.startsWith('/redirect/')) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
getBreadcrumb()
|
|
||||||
})
|
})
|
||||||
})
|
}
|
||||||
|
|
||||||
|
const matched = computed(() => route.matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false));
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.app-breadcrumb.el-breadcrumb {
|
|
||||||
margin-left: 10px;
|
|
||||||
display: inline-block;
|
|
||||||
font-size: 14px;
|
|
||||||
margin-bottom: 4px;
|
|
||||||
.no-redirect {
|
|
||||||
color:#303133;
|
|
||||||
cursor: text;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
||||||
|
|
@ -11,11 +11,11 @@
|
||||||
<el-form-item label="姓名">
|
<el-form-item label="姓名">
|
||||||
<el-input v-model="ruleForm.name" disabled></el-input>
|
<el-input v-model="ruleForm.name" disabled></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="手机号码">
|
<el-form-item label="旧的密码" prop="password">
|
||||||
<el-input v-model="ruleForm.mobile" disabled></el-input>
|
<el-input v-model="ruleForm.password" type="password"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="修改密码" prop="password">
|
<el-form-item label="新的密码" prop="configPassword">
|
||||||
<el-input v-model="ruleForm.password"></el-input>
|
<el-input v-model="ruleForm.configPassword" type="password"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
|
|
@ -29,9 +29,10 @@
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, defineExpose, reactive } from 'vue'
|
import { ref, defineExpose, reactive } from 'vue'
|
||||||
import { ElMessageBox } from 'element-plus'
|
|
||||||
import type { ElForm } from 'element-plus'
|
import type { ElForm } from 'element-plus'
|
||||||
const dialogVisible = ref(false)
|
const dialogVisible = ref(false)
|
||||||
|
import {useUserStore} from "@/store/modules/user"
|
||||||
|
const UserStore = useUserStore()
|
||||||
const show = () => {
|
const show = () => {
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true
|
||||||
}
|
}
|
||||||
|
|
@ -43,15 +44,15 @@
|
||||||
const formSize = ref('')
|
const formSize = ref('')
|
||||||
const ruleFormRef = ref<FormInstance>()
|
const ruleFormRef = ref<FormInstance>()
|
||||||
const ruleForm = reactive({
|
const ruleForm = reactive({
|
||||||
name: '',
|
name: UserStore.userInfo.username,
|
||||||
mobile: '',
|
password: UserStore.userInfo.password,
|
||||||
password: '',
|
configPassword: '',
|
||||||
})
|
})
|
||||||
const rules = reactive({
|
const rules = reactive({
|
||||||
password: [
|
configPassword: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: '请输入密码',
|
message: '请输入新的密码',
|
||||||
trigger: 'blur',
|
trigger: 'blur',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,9 @@ const setAssemblySize = (item: string) => {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.transverseMenu .size-icon {
|
.transverseMenu {
|
||||||
color: white;
|
.size-icon {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,10 @@
|
||||||
<div
|
<div
|
||||||
class="m-layout-header"
|
class="m-layout-header"
|
||||||
:class="[
|
:class="[
|
||||||
SettingStore.themeConfig.fixedHeader&&'zb-fixed-header',
|
SettingStore.themeConfig.fixedHeader?'zb-fixed-header':'zb-no-fixed-header',
|
||||||
isCollapse?'fixed-header-collapse':'fixed-header-no-collapse'
|
mode === 'horizontal'?'':isCollapse?'fixed-header-collapse':'fixed-header-no-collapse'
|
||||||
]"
|
]"
|
||||||
|
|
||||||
>
|
>
|
||||||
<!-- :style="{ left: `${mode === 'horizontal' ? 0 : isCollapse ? '60' : '210'}px` }"-->
|
|
||||||
<div
|
<div
|
||||||
class="header"
|
class="header"
|
||||||
:class="{
|
:class="{
|
||||||
|
|
@ -16,7 +14,7 @@
|
||||||
>
|
>
|
||||||
<u-menu v-if="mode === 'horizontal'" />
|
<u-menu v-if="mode === 'horizontal'" />
|
||||||
<div class="left" v-if="mode === 'vertical'">
|
<div class="left" v-if="mode === 'vertical'">
|
||||||
<div>
|
<div class="hamburger-container">
|
||||||
<el-icon class="icon" v-if="isCollapse" @click="handleCollapse"><expand /></el-icon>
|
<el-icon class="icon" v-if="isCollapse" @click="handleCollapse"><expand /></el-icon>
|
||||||
<el-icon class="icon" v-else @click="handleCollapse"><fold /></el-icon>
|
<el-icon class="icon" v-else @click="handleCollapse"><fold /></el-icon>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -46,8 +44,10 @@
|
||||||
</span>
|
</span>
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<el-dropdown-menu>
|
<el-dropdown-menu>
|
||||||
<el-dropdown-item :command="1">退出登录</el-dropdown-item>
|
<el-dropdown-item :command="2" >
|
||||||
<el-dropdown-item :command="2">修改密码</el-dropdown-item>
|
<el-icon><Edit /></el-icon>修改密码</el-dropdown-item>
|
||||||
|
<el-dropdown-item :command="1" divided>
|
||||||
|
<el-icon><SwitchButton /></el-icon>退出登录</el-dropdown-item>
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
</template>
|
</template>
|
||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
|
|
@ -101,10 +101,14 @@
|
||||||
})
|
})
|
||||||
.then(async () => {
|
.then(async () => {
|
||||||
try {
|
try {
|
||||||
await UserStore.logout()
|
|
||||||
router.push({ path: '/login' })
|
router.push({ path: '/login' })
|
||||||
|
await UserStore.logout()
|
||||||
PermissionStore.clearRoutes()
|
PermissionStore.clearRoutes()
|
||||||
TagsViewStore.clearVisitedView()
|
TagsViewStore.clearVisitedView()
|
||||||
|
ElMessage({
|
||||||
|
type: "success",
|
||||||
|
message: "退出登录成功!"
|
||||||
|
});
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
})
|
})
|
||||||
.catch(() => {})
|
.catch(() => {})
|
||||||
|
|
@ -142,12 +146,13 @@
|
||||||
border-bottom: 1px solid #eee;
|
border-bottom: 1px solid #eee;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0 10px;
|
padding: 0 10px 0 0;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
.left {
|
.left {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
.right {
|
.right {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -163,7 +168,18 @@
|
||||||
right: 0;
|
right: 0;
|
||||||
z-index: 9;
|
z-index: 9;
|
||||||
}
|
}
|
||||||
|
.zb-no-fixed-header{
|
||||||
|
width: 100%!important;;
|
||||||
|
}
|
||||||
|
.hamburger-container{
|
||||||
|
padding: 0px 15px;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
&:hover {
|
||||||
|
background: rgba(0, 0, 0, .025)
|
||||||
|
}
|
||||||
|
}
|
||||||
.m-layout-header {
|
.m-layout-header {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background: white;
|
background: white;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
<el-menu
|
<el-menu
|
||||||
:default-active="activeMenu"
|
:default-active="activeMenu"
|
||||||
background-color="#304156"
|
background-color="#304156"
|
||||||
text-color="#fff"
|
text-color="#bfcbd9"
|
||||||
:mode="mode"
|
:mode="mode"
|
||||||
:unique-opened="SettingStore.themeConfig.uniqueOpened"
|
:unique-opened="SettingStore.themeConfig.uniqueOpened"
|
||||||
:collapse-transition="false"
|
:collapse-transition="false"
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import {usePermissionStore} from "@/store/modules/permission"
|
import {usePermissionStore} from "@/store/modules/permission"
|
||||||
import {useSettingStore} from "@/store/modules/setting"
|
import {useSettingStore} from "@/store/modules/setting"
|
||||||
import { ref, computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
|
|
||||||
// 在setup中获取store
|
// 在setup中获取store
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
@ -33,8 +33,6 @@
|
||||||
// 获取路由
|
// 获取路由
|
||||||
const permission_routes = computed(() => PermissionStore.permission_routes)
|
const permission_routes = computed(() => PermissionStore.permission_routes)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const activeMenu = computed(() => {
|
const activeMenu = computed(() => {
|
||||||
const { meta, path } = route
|
const { meta, path } = route
|
||||||
// if set path, the sidebar will highlight the path you set
|
// if set path, the sidebar will highlight the path you set
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
import UMenu from './components/Menu.vue'
|
import UMenu from './components/Menu.vue'
|
||||||
import logo from './components/Logo.vue'
|
import logo from './components/Logo.vue'
|
||||||
import {useSettingStore} from "@/store/modules/setting"
|
import {useSettingStore} from "@/store/modules/setting"
|
||||||
import { ref, computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
|
|
||||||
const SettingStore = useSettingStore()
|
const SettingStore = useSettingStore()
|
||||||
// 是否折叠
|
// 是否折叠
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ import Layout from "@/layout/index.vue";
|
||||||
const chartsRouter = {
|
const chartsRouter = {
|
||||||
path: '/charts',
|
path: '/charts',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
redirect: 'noRedirect',
|
redirect: '/charts/migration',
|
||||||
name: 'visualizationChart',
|
name: 'Charts',
|
||||||
meta: {
|
meta: {
|
||||||
title: '可视化图表',
|
title: '可视化图表',
|
||||||
icon: 'trend-charts',
|
icon: 'trend-charts',
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import Layout from "@/layout/index.vue";
|
||||||
const chartsRouter = {
|
const chartsRouter = {
|
||||||
path: '/chat',
|
path: '/chat',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
redirect: 'noRedirect',
|
redirect: '/charts/index',
|
||||||
name: 'chat',
|
name: 'chat',
|
||||||
meta: {
|
meta: {
|
||||||
title: '聊天框',
|
title: '聊天框',
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import Layout from '@/layout/index.vue'
|
||||||
const clipboardTable = {
|
const clipboardTable = {
|
||||||
path: '/clipboard',
|
path: '/clipboard',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
redirect: 'noRedirect',
|
redirect: '/clipboard/index',
|
||||||
name: 'clipboard',
|
name: 'clipboard',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'clipboard',
|
title: 'clipboard',
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,8 @@ import Layout from "@/layout/index.vue";
|
||||||
const errorRouter = {
|
const errorRouter = {
|
||||||
path: '/error',
|
path: '/error',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
redirect: 'noRedirect',
|
redirect: '/error/404',
|
||||||
name: 'errorPages',
|
name: 'error',
|
||||||
meta: {
|
meta: {
|
||||||
title: '错误页面',
|
title: '错误页面',
|
||||||
icon: 'School'
|
icon: 'School'
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import Layout from "@/layout/index.vue";
|
||||||
const excelRouter = {
|
const excelRouter = {
|
||||||
path: '/excel',
|
path: '/excel',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
redirect: 'noRedirect',
|
redirect: '/excel/export-excel',
|
||||||
name: 'excel',
|
name: 'excel',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'Excel',
|
title: 'Excel',
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import Layout from "@/layout/index.vue";
|
||||||
const formRouter = {
|
const formRouter = {
|
||||||
path: '/form',
|
path: '/form',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
redirect: 'noRedirect',
|
redirect: '/form/validateForm',
|
||||||
name: 'form',
|
name: 'form',
|
||||||
alwaysShow:true,
|
alwaysShow:true,
|
||||||
meta: {
|
meta: {
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import Layout from "@/layout/index.vue";
|
||||||
const nestedRouter = {
|
const nestedRouter = {
|
||||||
path: '/nested',
|
path: '/nested',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
redirect: 'noRedirect',
|
redirect: '/form/menu1',
|
||||||
name: 'nested',
|
name: 'nested',
|
||||||
meta: {
|
meta: {
|
||||||
title: '路由嵌套',
|
title: '路由嵌套',
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ import Layout from '@/layout/index.vue'
|
||||||
const othersRouter = {
|
const othersRouter = {
|
||||||
path: '/other',
|
path: '/other',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
redirect: 'noRedirect',
|
redirect: '/other/editor',
|
||||||
name: 'expansionComponents',
|
name: 'other',
|
||||||
meta: {
|
meta: {
|
||||||
title: '扩展组件',
|
title: '扩展组件',
|
||||||
icon: 'management'
|
icon: 'management'
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import Layout from '@/layout/index.vue'
|
||||||
const systemRouter = {
|
const systemRouter = {
|
||||||
path: '/system',
|
path: '/system',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
redirect: 'noRedirect',
|
redirect: '/system/page',
|
||||||
name: 'system',
|
name: 'system',
|
||||||
meta: {
|
meta: {
|
||||||
title: '系统管理',
|
title: '系统管理',
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@ import Layout from "@/layout/index.vue";
|
||||||
const tableRouter = {
|
const tableRouter = {
|
||||||
path: '/table',
|
path: '/table',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
redirect: 'noRedirect',
|
redirect: '/table/comprehensive',
|
||||||
name: 'Table',
|
name: 'table',
|
||||||
meta: {
|
meta: {
|
||||||
title: '超级表格',
|
title: '超级表格',
|
||||||
icon: 'School'
|
icon: 'School'
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,14 @@ html.dark {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.zb-pro-table .header{
|
||||||
|
background: none!important;
|
||||||
|
border: var(--zb-border-light);
|
||||||
|
}
|
||||||
|
.zb-pro-table .footer{
|
||||||
|
background: none!important;
|
||||||
|
border: var(--zb-border-light);
|
||||||
|
}
|
||||||
// m-layout-header
|
// m-layout-header
|
||||||
.m-layout-header{
|
.m-layout-header{
|
||||||
color: var(--el-text-color-primary) !important;
|
color: var(--el-text-color-primary) !important;
|
||||||
|
|
@ -143,5 +150,9 @@ html.dark {
|
||||||
color: white!important;
|
color: white!important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.el-table__header th {
|
||||||
|
font-weight: bold;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
.el-table__header th {
|
||||||
|
font-weight: bold;
|
||||||
|
color: #252525;
|
||||||
|
background: #fafafa;
|
||||||
|
}
|
||||||
|
|
@ -2,5 +2,6 @@
|
||||||
@import './sidebar.scss';
|
@import './sidebar.scss';
|
||||||
@import './transition.scss';
|
@import './transition.scss';
|
||||||
@import "./common.scss";
|
@import "./common.scss";
|
||||||
|
@import "./element.scss";
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,19 @@
|
||||||
// position: absolute;
|
// position: absolute;
|
||||||
// z-index: -1;
|
// z-index: -1;
|
||||||
//}
|
//}
|
||||||
|
.breadcrumb-enter-active,
|
||||||
|
.breadcrumb-leave-active {
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
.breadcrumb-enter-from,
|
||||||
|
.breadcrumb-leave-active {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(10px);
|
||||||
|
}
|
||||||
|
.breadcrumb-leave-active {
|
||||||
|
position: absolute;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.fade-transform-leave-active,
|
.fade-transform-leave-active,
|
||||||
|
|
|
||||||
|
|
@ -479,3 +479,16 @@ export function getLightColor(color: string, level: number) {
|
||||||
for (let i = 0; i < 3; i++) rgb[i] = Math.floor((255 - rgb[i]) * level + rgb[i]);
|
for (let i = 0; i < 3; i++) rgb[i] = Math.floor((255 - rgb[i]) * level + rgb[i]);
|
||||||
return rgbToHex(rgb[0], rgb[1], rgb[2]);
|
return rgbToHex(rgb[0], rgb[1], rgb[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getTimeState() {
|
||||||
|
// 获取当前时间
|
||||||
|
let timeNow = new Date();
|
||||||
|
// 获取当前小时
|
||||||
|
let hours = timeNow.getHours();
|
||||||
|
// 判断当前时间段
|
||||||
|
if (hours >= 6 && hours <= 10) return `早上好 ⛅`;
|
||||||
|
if (hours >= 10 && hours <= 14) return `中午好 🌞`;
|
||||||
|
if (hours >= 14 && hours <= 18) return `下午好 🌞`;
|
||||||
|
if (hours >= 18 && hours <= 24) return `晚上好 🌛`;
|
||||||
|
if (hours >= 0 && hours <= 6) return `凌晨好 🌛`;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<u-container-layout>
|
<u-container-layout>
|
||||||
<div style="margin-bottom: 15px; display: flex; align-items: center">
|
<div class="header">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="input"
|
v-model="input"
|
||||||
placeholder="请输入文件名"
|
placeholder="请输入文件名"
|
||||||
|
|
@ -22,11 +22,13 @@
|
||||||
<el-icon style="margin-right: 10px"><document-remove /></el-icon>导出 Excel
|
<el-icon style="margin-right: 10px"><document-remove /></el-icon>导出 Excel
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
<el-table :data="list" style="width: 100%" border>
|
<div class="footer">
|
||||||
<template v-for="(item, index) in column" :key="index">
|
<el-table :data="list" border class="table">
|
||||||
<el-table-column :prop="item.name" :label="item.label" :width="item.width" />
|
<template v-for="(item, index) in column" :key="index">
|
||||||
</template>
|
<el-table-column :prop="item.name" :label="item.label" :width="item.width" />
|
||||||
</el-table>
|
</template>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
</u-container-layout>
|
</u-container-layout>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -100,4 +102,22 @@
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style></style>
|
<style lang="scss" scoped>
|
||||||
|
.header{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.footer{
|
||||||
|
flex: 1;
|
||||||
|
position: relative;
|
||||||
|
.table{
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<u-container-layout>
|
<u-container-layout>
|
||||||
<div style="margin-bottom: 15px; display: flex; align-items: center">
|
<div class=".header">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="input"
|
v-model="input"
|
||||||
placeholder="请输入文件名"
|
placeholder="请输入文件名"
|
||||||
|
|
@ -10,11 +10,13 @@
|
||||||
<el-icon style="margin-right: 10px"><document-remove /></el-icon>导出样式 Excel
|
<el-icon style="margin-right: 10px"><document-remove /></el-icon>导出样式 Excel
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
<el-table :data="list" style="width: 100%" border>
|
<div class="footer">
|
||||||
<template v-for="(item, index) in column" :key="index">
|
<el-table :data="list" class="table" border>
|
||||||
<el-table-column :prop="item.name" :label="item.label" :width="item.width" />
|
<template v-for="(item, index) in column" :key="index">
|
||||||
</template>
|
<el-table-column :prop="item.name" :label="item.label" :width="item.width" />
|
||||||
</el-table>
|
</template>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
</u-container-layout>
|
</u-container-layout>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -88,4 +90,22 @@
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style></style>
|
<style lang="scss" scoped>
|
||||||
|
.header{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.footer{
|
||||||
|
flex: 1;
|
||||||
|
position: relative;
|
||||||
|
.table{
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -63,9 +63,12 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, reactive } from 'vue'
|
import { ref, reactive } from 'vue'
|
||||||
import type { FormInstance } from 'element-plus'
|
import type { FormInstance } from 'element-plus'
|
||||||
|
import { ElNotification } from "element-plus";
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import {useUserStore} from "@/store/modules/user"
|
import {useUserStore} from "@/store/modules/user"
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
|
import {getTimeState} from '@/utils/index'
|
||||||
|
|
||||||
const ruleFormRef = ref<FormInstance>()
|
const ruleFormRef = ref<FormInstance>()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const UserStore = useUserStore()
|
const UserStore = useUserStore()
|
||||||
|
|
@ -108,14 +111,18 @@
|
||||||
const submitForm = (formEl: FormInstance | undefined) => {
|
const submitForm = (formEl: FormInstance | undefined) => {
|
||||||
if (!formEl) return
|
if (!formEl) return
|
||||||
formEl.validate(async (valid) => {
|
formEl.validate(async (valid) => {
|
||||||
console.log('valid==', valid)
|
|
||||||
if (valid) {
|
if (valid) {
|
||||||
// 登录
|
// 登录
|
||||||
await UserStore.login( ruleForm)
|
await UserStore.login( ruleForm)
|
||||||
ElMessage.success('登录成功')
|
|
||||||
router.push({
|
router.push({
|
||||||
path: '/',
|
path: '/',
|
||||||
})
|
})
|
||||||
|
ElNotification({
|
||||||
|
title: getTimeState(),
|
||||||
|
message: "欢迎登录 Vue Admin Perfect",
|
||||||
|
type: "success",
|
||||||
|
duration: 3000
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
console.log('error submit!')
|
console.log('error submit!')
|
||||||
return false
|
return false
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<u-container-layout style="min-height: 300px">
|
<u-container-layout style="min-height: 300px">
|
||||||
<el-button @contextmenu.prevent="rightClick">右键菜单</el-button>
|
<el-button @contextmenu.prevent="rightClick" style="width: 200px">右键菜单</el-button>
|
||||||
<u-right-click-menu :left="clientX" :top="clientY" @ok="operatingRightAction" :data="data" />
|
<u-right-click-menu :left="clientX" :top="clientY" @ok="operatingRightAction" :data="data" />
|
||||||
</u-container-layout>
|
</u-container-layout>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import URightClickMenu from '@/components/u-rightClickMenu/index.vue'
|
import URightClickMenu from '@/components/u-rightClickMenu/index.vue'
|
||||||
|
|
||||||
const clientX = ref(0)
|
const clientX = ref(0)
|
||||||
const clientY = ref(0)
|
const clientY = ref(0)
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue