admin-webpc/src/views/home.vue

467 lines
12 KiB
Vue
Raw Normal View History

2025-02-03 23:58:33 +08:00
<template>
<div class="common-layout">
<el-container>
<el-aside
:width="isCollapse ? '63px' : '200px'"
style="background: #1d3043"
>
<div
class="collapse white"
:style="{
fontSize: isCollapse ? '35px' : '20px',
background: '#18222c',
}"
>
{{ isCollapse ? "管" : "管理系统" }}
</div>
<div class="flex-a p5">
<div class="person_img2" style="display: flex; align-items: center">
<el-avatar
:style="{
width: isCollapse ? '40px' : '80px',
height: isCollapse ? '40px' : '80px',
}"
src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png"
/>
</div>
<div class="f14 white" v-if="!isCollapse">
<div>管理员</div>
</div>
</div>
<el-menu
:default-active="state.activePath"
class="el-menu-vertical-demo"
:collapse="isCollapse"
router
background-color="#1d3043"
active-color="red"
active-text-color="#ffd04b"
>
<div v-for="item in state.menuList" :key="item.id">
<el-menu-item
:index="'/' + item.browserUrl"
v-if="item.children.length == 0"
>
<el-icon><Link /></el-icon>
<template #title>{{ item.name }} </template>
</el-menu-item>
<el-sub-menu v-else>
<template #title>
<el-icon><Link /></el-icon>
<span class="ml15">{{ item.name }}</span>
</template>
<div v-for="item2 in item.children" :key="item2.id">
<el-menu-item-group>
<el-menu-item :index="'/' + item2.browserUrl">
<el-icon><Link /></el-icon>{{ item2.name }}</el-menu-item
>
</el-menu-item-group>
</div>
</el-sub-menu>
</div>
</el-menu>
</el-aside>
<el-container
:style="{
height: '100vh',
}"
>
<el-header
:style="{
height: '50px',
background: '#1d3043',
}"
class="flex-s white"
>
<div class="flex">
<el-radio-group v-model="isCollapse">
<el-radio-button :value="false" v-if="isCollapse"
><el-icon :size="25"><Fold /></el-icon
></el-radio-button>
<el-radio-button :value="true" v-if="!isCollapse"
><el-icon :size="25"><Fold /></el-icon
></el-radio-button>
</el-radio-group>
<div @click="reload" class="flex mlr10">
<el-icon :size="20"><RefreshRight /></el-icon>
</div>
<div @click="toggleFullScreen" class="flex ml20">
<el-icon :size="19" class=""><FullScreen /></el-icon>
</div>
</div>
<div class="flex">
<div class="header_info">
2025-02-04 00:13:16 +08:00
<!-- <div class="flex" @click="state.userVisible = true">
2025-02-03 23:58:33 +08:00
<el-icon size="20"><EditPen /></el-icon>
2025-02-04 00:13:16 +08:00
</div> -->
2025-02-03 23:58:33 +08:00
<div class="flex ml20" @click="loginOut">
<el-icon size="20"><SwitchButton /></el-icon>退
</div>
</div>
</div>
</el-header>
<el-main class="p5">
<el-tabs
@tab-click="tabClick"
@tab-remove="tabRemove"
v-model="state.activeTab"
type="border-card"
>
<el-tab-pane
v-for="item in state.tabsItem"
:label="item.title"
:name="item.name"
:ref="item.ref"
:closable="item.closable"
>
<keepAlive>
<component
v-if="isRouterAlive"
:is="dom[state.tabsItem.content]"
:key="state.activeTab"
/>
</keepAlive>
</el-tab-pane>
</el-tabs>
</el-main>
<!-- <el-footer
:style="{
height: '30px',
lineHeight: '30px',
}"
><div>
<strong>
Copyright © 2016-2020
<a href="javascript:;">管理系统</a>
</strong>
. All rights reserved.
</div></el-footer
> -->
</el-container>
</el-container>
<el-dialog
title="修改密码"
v-model="state.userVisible"
@close="userDialog"
width="25%"
>
<el-form
label-width="100px"
ref="userRef"
:model="alterUserInfo"
size="mini"
:rules="rules"
>
<div>
<el-form-item
style="width: 89%"
prop="currentPassword"
label="旧密码"
>
<el-input
show-password
v-model="alterUserInfo.currentPassword"
></el-input>
</el-form-item>
<el-form-item style="width: 89%" prop="password" label="新密码">
<el-input show-password v-model="alterUserInfo.password"></el-input>
</el-form-item>
<el-form-item
style="width: 89%"
prop="confirmPassword"
label="再次确定"
>
<el-input
show-password
v-model="alterUserInfo.confirmPassword"
></el-input>
</el-form-item>
</div>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="state.userVisible = false">取消</el-button>
<el-button type="primary" @click="alterPassword(userRef)">
保存
</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script lang="ts" setup>
import {
ref,
watch,
shallowRef,
onMounted,
reactive,
nextTick,
getCurrentInstance,
} from "vue";
import { useRouter } from "vue-router";
import type { FormInstance, FormRules } from "element-plus";
import index from "./index.vue";
import about from "./about.vue";
2025-02-04 00:13:16 +08:00
import order from "./order.vue";
2025-02-03 23:58:33 +08:00
const { appContext } = getCurrentInstance();
const dom = shallowRef({
2025-02-04 00:13:16 +08:00
order,
2025-02-03 23:58:33 +08:00
about,
index,
});
const proxy = appContext.config.globalProperties;
const router = useRouter();
const state = reactive({
userVisible: false,
activePath: "/index",
activeTab: "index",
tabsItem: [
{
title: "租户管理",
name: "index",
// 导入的组件
content: "index",
ref: "tabs",
closable: false,
query: "",
path: "/index",
},
],
menuList: [
{
action: "index",
appIcon: null,
browserUrl: "index",
children: [],
icon: "fa fa-link",
name: "租户管理",
},
{
action: "about",
appIcon: null,
browserUrl: "about",
children: [],
icon: "fa fa-link",
2025-02-04 00:13:16 +08:00
name: "产品",
2025-02-03 23:58:33 +08:00
},
{
2025-02-04 00:13:16 +08:00
action: "order",
2025-02-03 23:58:33 +08:00
appIcon: null,
2025-02-04 00:13:16 +08:00
browserUrl: "order",
2025-02-03 23:58:33 +08:00
children: [],
icon: "fa fa-link",
2025-02-04 00:13:16 +08:00
name: "订单管理",
2025-02-03 23:58:33 +08:00
},
] as any,
});
const validatePass = (rule: any, value: any, callback: any) => {
console.log(value);
if (value.length < 6) {
callback(new Error("密码长度不能小于6位"));
} else {
callback();
}
};
const alterUserInfo = reactive({
currentPassword: "",
password: "",
confirmPassword: "",
});
const userRef = ref<FormInstance>();
const rules = {
currentPassword: [
{ required: true, message: "请输入密码", trigger: "blur" },
{ validator: validatePass, trigger: "blur" },
],
password: [
{ required: true, message: "请输入密码", trigger: "blur" },
{ validator: validatePass, trigger: "blur" },
],
confirmPassword: [
{ required: true, message: "请确认密码", trigger: "blur" },
{
validator: (rule: any, value: any, callback: any) => {
if (value !== alterUserInfo.password) {
callback(new Error("两次输入的密码不一致"));
} else {
callback();
}
},
trigger: "blur",
},
],
};
const isRouterAlive = ref(true);
// 在组件挂载时获取用户信息
let isCollapse = ref<Boolean>(false);
onMounted(async () => {
console.log(8888);
});
// 刷新
const reload = () => {
// router.go(0);
isRouterAlive.value = false;
nextTick(() => {
isRouterAlive.value = true;
});
};
// 退出登录
const loginOut = () => {
router.push("/login");
};
// 关闭dialog
const userDialog = () => {
for (let i in alterUserInfo) {
alterUserInfo[i] = "";
}
};
//修改密码
const alterPassword = (formEl: FormInstance | undefined) => {
if (!formEl) return;
formEl.validate(async (valid: any, fields: any) => {
if (valid) {
state.userVisible = false;
router.push("/login");
} else {
return proxy.$messageE("请完善信息");
}
});
};
// 全屏
const isFullScreen = ref(false);
function toggleFullScreen() {
if (!document.fullscreenElement && !isFullScreen.value) {
// 进入全屏
document.documentElement.requestFullscreen().then(() => {
isFullScreen.value = true;
});
} else {
// 退出全屏
if (document.exitFullscreen) {
document.exitFullscreen().then(() => {
isFullScreen.value = false;
});
}
}
}
// 监听全屏状态变化
document.addEventListener("fullscreenchange", () => {
isFullScreen.value = !!document.fullscreenElement;
});
// 点击tab
const tabClick = (tab: any) => {
let val = state.tabsItem.filter((item) => tab.props.label == item.title);
router.push(val[0].path);
state.activePath = val[0].path;
};
// 关闭tab
const tabRemove = (tab: any) => {
state.tabsItem.forEach((val: any, index: Number) => {
if (val.name === tab) {
state.tabsItem.splice(index, 1);
if (tab === state.activeTab) {
router.push(state.tabsItem[index - 1].path);
state.activePath = state.tabsItem[index - 1].path;
state.activeTab = state.tabsItem[index - 1].name;
}
}
});
};
// 监听当前路由
watch(
() => router.currentRoute.value,
(val: any) => {
console.log(8888, val);
state.activePath = val.path;
state.tabsItem.title = val.meta.name;
state.tabsItem.name = val.meta.comp;
state.tabsItem.closable = true;
state.tabsItem.ref = "tabs";
state.tabsItem.content = val.meta.comp;
state.tabsItem.query = val.query.id;
state.tabsItem.path = val.path;
console.log(56696, state.tabsItem);
let result = state.tabsItem.some((item) => item.title == val.meta.name);
console.log(result);
state.activeTab = val.meta.comp;
if (!result) {
state.tabsItem.push({
title: val.meta.name,
name: val.meta.comp,
// 导入的组件
content: val.meta.comp,
ref: "tabs",
closable: true,
query: "",
path: "/" + val.meta.comp,
});
} else {
return;
}
},
{ immediate: true }
);
</script>
<style>
.header_info {
display: flex;
justify-content: right;
align-items: center;
width: auto;
}
.collapse {
text-align: center;
cursor: pointer;
align-items: center;
width: 100%;
height: 50px;
line-height: 50px;
}
.person_img2 img {
margin: 0 auto;
border-radius: 50%;
/* background: #ffffff; */
}
.el-tab-pane {
max-height: calc(100vh - 150px);
overflow-y: hidden;
}
.el-radio-button__inner {
background: #1d3043;
color: white;
border-color: #1d3043;
}
.el-radio-button__original-radio:checked + .el-radio-button__inner {
background: #1d3043;
border-color: #1d3043;
}
.el-radio-button:first-child .el-radio-button__inner {
border-left: #1d3043;
}
.el-menu {
border-right: none;
}
.el-menu-item-group__title {
padding: 0 !important;
}
.el-menu-item {
color: white;
}
.el-main {
padding: 0;
}
</style>