init: 初始化 hgmj 后台管理项目

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-10-08 17:48:09 +08:00
co-authored by Claude Opus 4.7
commit 397398b746
645 changed files with 179153 additions and 0 deletions
+319
View File
@@ -0,0 +1,319 @@
<template>
<el-main>
<div class="main">
<div class="route-tags">
<div class="btn-hover out-box color-11">
<div class="popup">导航标签:</div>
</div>
<div
class="btn-hover out-box"
:class="['color-' + (i + 1), { active: i === index }]"
v-for="(item, i) in tags"
:key="i"
@click="cutRouter(i, item.router)"
>
<div class="popup">
{{ item.routerName }}
<i class="el-icon-close" @click.stop="remove(i)"></i>
</div>
</div>
<!--假加载条美化效果-->
<div class="outside-bar">
<div class="inside-bar" :class="loading ? 'loading' : ''"></div>
</div>
</div>
<keep-alive>
<router-view
v-if="$route.meta.keepAlive"
style="min-height: 100%"
></router-view>
</keep-alive>
<router-view
v-if="!$route.meta.keepAlive"
style="min-height: 100%"
></router-view>
</div>
</el-main>
</template>
<script>
import { setTimeout } from "timers";
export default {
data() {
return {
index: 0,
loading: false
};
},
computed: {
tags() {
return this.$store.state.routerTags;
},
routerIndex() {
return this.$store.state.routerIndex;
}
},
methods: {
// 切换tags路由
cutRouter(i, router) {
this.loading = true;
setTimeout(() => {
this.loading = false;
}, 500);
this.index = i;
if (!router) {
return;
}
this.$store.dispatch("setRouterActive", router);
this.$router.push({
path: router
});
},
// 删除tsgs 路由
remove(i) {
this.$store.dispatch("removeRouterTag", i);
let routerTag = this.$store.state.routerTags;
this.cutRouter(routerTag.length, routerTag[routerTag.length - 1].router);
}
},
watch: {
routerIndex(i) {
i--;
this.cutRouter(i, "");
}
}
};
</script>
<style lang="scss">
.el-main {
height: 100%;
overflow: hidden !important;
padding: 0 !important;
position: relative;
.main {
width: 100%;
height: 100%;
background: white;
overflow-y: auto !important;
padding: 60px 20px 20px 20px !important;
position: relative;
}
.route-tags {
width: calc(100% - 40px);
height: 40px;
background: white;
margin-bottom: 15px;
display: inline-block;
box-shadow: 0px 15px 10px -10px rgba(0, 0, 0, 0.1);
border-radius: 0 0 5px 5px;
position: fixed;
top: 80px;
left: 270px;
z-index: 888;
.outside-bar {
width: 100%;
height: 3px;
position: absolute;
bottom: 0;
overflow: hidden;
}
.inside-bar {
width: 0%;
height: 100%;
background-image: linear-gradient(
to right,
#fc6076,
#ff9a44,
#ef9d43,
#e75516,
#667eea,
#764ba2,
#6b8dd6,
#8e37d7,
#25aae1,
#40e495,
#30dd8a,
#2bb673
);
}
.loading {
animation: bar 0.5s;
}
@keyframes bar {
from {
width: 0;
}
to {
width: 100%;
}
}
.out-box {
width: auto;
float: left;
font-size: 12px;
position: relative;
color: #fff;
cursor: pointer;
height: 25px;
text-align: center;
border: none;
background-size: 300% 100%;
margin-right: 15px;
margin-top: 7px;
border-radius: 3px;
line-height: 27px;
-o-transition: all 0.4s ease-in-out;
-webkit-transition: all 0.4s ease-in-out;
transition: all 0.4s ease-in-out;
&:hover {
cursor: pointer;
background-position: 100% 0;
-o-transition: all 0.4s ease-in-out;
-webkit-transition: all 0.4s ease-in-out;
transition: all 0.4s ease-in-out;
}
&:before {
content: "";
width: 6px;
height: 6px;
background: transparent;
position: absolute;
border-radius: 100%;
left: 3px;
top: 10px;
}
}
.active {
&:before {
background: white !important;
}
}
.popup {
width: 100%;
height: 100%;
padding: 0 15px;
background: rgba(0, 0, 0, 0.3);
border-radius: 3px;
}
.el-icon-close {
position: absolute;
right: 0;
color: white;
&:hover {
color: red;
}
}
.color-1 {
background-image: linear-gradient(
to right,
#25aae1,
#40e495,
#30dd8a,
#2bb673
);
box-shadow: 0 4px 15px 0 rgba(49, 196, 190, 0.75);
}
.color-2 {
background-image: linear-gradient(
to right,
#f5ce62,
#e43603,
#fa7199,
#e85a19
);
box-shadow: 0 4px 15px 0 rgba(229, 66, 10, 0.75);
}
.color-3 {
background-image: linear-gradient(
to right,
#667eea,
#764ba2,
#6b8dd6,
#8e37d7
);
box-shadow: 0 4px 15px 0 rgba(116, 79, 168, 0.75);
}
.color-4 {
background-image: linear-gradient(
to right,
#fc6076,
#ff9a44,
#ef9d43,
#e75516
);
box-shadow: 0 4px 15px 0 rgba(252, 104, 110, 0.75);
}
.color-5 {
background-image: linear-gradient(
to right,
#0ba360,
#3cba92,
#30dd8a,
#2bb673
);
box-shadow: 0 4px 15px 0 rgba(23, 168, 108, 0.75);
}
.color-6 {
background-image: linear-gradient(
to right,
#009245,
#fcee21,
#00a8c5,
#d9e021
);
box-shadow: 0 4px 15px 0 rgba(83, 176, 57, 0.75);
}
.color-7 {
background-image: linear-gradient(
to right,
#6253e1,
#852d91,
#a3a1ff,
#f24645
);
box-shadow: 0 4px 15px 0 rgba(126, 52, 161, 0.75);
}
.color-8 {
background-image: linear-gradient(
to right,
#29323c,
#485563,
#2b5876,
#4e4376
);
box-shadow: 0 4px 15px 0 rgba(45, 54, 65, 0.75);
}
.color-9 {
background-image: linear-gradient(
to right,
#25aae1,
#4481eb,
#04befe,
#3f86ed
);
box-shadow: 0 4px 15px 0 rgba(65, 132, 234, 0.75);
}
.color-10 {
background-image: linear-gradient(
to right,
#ed6ea0,
#ec8c69,
#f7186a,
#fbb03b
);
box-shadow: 0 4px 15px 0 rgba(236, 116, 149, 0.75);
}
.color-11 {
background-image: linear-gradient(
to right,
#eb3941,
#f15e64,
#e14e53,
#e2373f
);
box-shadow: 0 5px 15px rgba(242, 97, 103, 0.4);
}
}
}
</style>
+188
View File
@@ -0,0 +1,188 @@
<template>
<el-header>
<div class="logo-text">
<img :src="logoImg" class="logoImg" />
<span>91短剧后台管理系统</span>
</div>
<div class="header-btn">
<el-select
v-model="selectedLine"
@change="lineChange"
size="mini"
placeholder="请选择线路"
>
<el-option
v-for="(item, index) in $imgUrls"
:key="index"
:label="item.desc || `线路${index + 1}`"
:value="index"
>
</el-option>
</el-select>
<el-button
v-show="isShow"
class="beilv"
id="beilv"
style="width:30px"
type="text"
@click="getValue()"
>{{ expansionFactor }}</el-button
>
<span class="exit" @click="logout">退出</span>
<span>
您好!
<i class="user-name">{{ userInfo ? userInfo.admin.name : "未知" }}</i
>,欢迎登录
</span>
</div>
</el-header>
</template>
<script>
// import API from '@/api'
import { mapActions, mapGetters } from "vuex";
import local from "@/utils/localStroage.js";
export default {
name: "dg-header",
data() {
return {
isShow: true,
userName: "",
logoImg: require("../../../assets/images/icon.png"),
selectedLine: 0,
};
},
computed: {
...mapGetters(["expansionFactor"]),
userInfo: () => {
return local.get("userInfo");
},
},
created() {
// window.console.log(this.$store.state.beilv);
// 从localStroage读取用户登录信息,存在则自动填充密码
let _index = localStorage.getItem("overallSituationLine");
if (_index) {
this.selectedLine = Number(_index);
}
},
methods: {
...mapActions(["setBeilv"]),
lineChange(v) {
this.$setOverallSituationLine(v);
},
getValue() {
this.$prompt("请输倍率", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
inputPattern: /^\d+(\.\d+)?$/,
inputErrorMessage: "请输入倍率不为负的数字",
})
.then(({ value }) => {
this.setBeilv(value);
this.isShow = false;
this.$message({
type: "success",
message: "你的输入的倍率是: " + value,
});
})
.catch(() => {
this.$message({
type: "info",
message: "取消输入",
});
});
},
// 点击退出
logout() {
this.$confirm("您确定要退出当前账户?", "退出提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
this.exit();
})
.catch(() => {});
},
// 登出
exit() {
local.remove("userInfo");
local.remove("role");
// this.$store.dispatch("refreshRouter");
this.$store.dispatch("removeAllTag");
this.$router.push({
path: "/login",
});
// let params = {
// name: this.userInfo.name
// }
// API.logout(params).then(res => {
// if (res.code === 200) {
// local.remove('userInfo')
// this.$router.push({
// name: 'login'
// })
// } else {
// this.$message.error('登出失败')
// }
// })
},
},
};
</script>
<style lang="scss">
.el-header {
// background: url("../../../assets/images/header-bg.png");
text-align: center;
width: 100%;
height: 80px !important;
line-height: 80px;
display: flex;
background-color: #161823;
.logo-text {
font-size: 22px;
color: #fff;
flex: 1;
text-align: left;
display: inline;
.logoImg {
width: 60px;
height: 60px;
vertical-align: middle;
}
span {
vertical-align: middle;
margin-left: 15px;
}
}
.header-btn {
flex: 1;
text-align: right;
font-size: 14px;
color: #fff;
.beilv {
position: fixed;
top: 23px;
left: 371px;
position: fixed;
}
input {
border: none;
outline: none;
}
}
.user-name {
color: white;
}
.exit {
margin: 0 20px;
cursor: pointer;
&:hover {
color: white;
}
}
}</style
>''
+120
View File
@@ -0,0 +1,120 @@
<template>
<el-aside width="250px">
<el-menu
:default-active="activeRouter"
router
class="el-menu-vertical-demo"
background-color="#161823"
:unique-opened="true"
text-color="#A7A8AC"
active-text-color="#FFF"
>
<siderbar-item
v-for="(item, i) in menuList"
:key="i"
:item="item"
></siderbar-item>
</el-menu>
</el-aside>
</template>
<script>
import siderbarItem from './siderbarItem'
export default {
data() {
return {
activeRouter: this.$route.path,
menu: []
}
},
components: {
siderbarItem
},
computed: {
// 实时计算当前选中路由名称
stateRouter() {
return this.$store.state.activeRouter
},
// 实时获取菜单
menuList() {
return this.$store.state.routerList
},
},
watch: {
stateRouter(router) {
this.activeRouter = router
}
}
}
</script>
<style lang="scss">
.el-aside {
// color: #333;
// background: url("../../../assets/images/timg.jpeg");
// padding-bottom: 20px;
.el-menu {
border-right: none;
min-height: 100%;
}
&::-webkit-scrollbar {
/*滚动条整体样式*/
width: 6px; /*高宽分别对应横竖滚动条的尺寸*/
}
&::-webkit-scrollbar-thumb {
width: 4px;
border-radius: 10px;
// background-color: #721729;
}
&::-webkit-scrollbar-track {
background-color: #161823;
}
.el-menu-item {
// background: transparent !important;
font-size: 13px;
&:hover {
background: #fff !important;
color: #000 !important;
i {
color: #000 !important;
}
}
}
.el-submenu {
font-size: 13px;
}
.el-menu-item-group__title {
display: none;
}
.el-submenu__title {
&:hover {
background: #fff !important;
color: #000 !important;
i {
color: #000 !important;
}
}
}
.el-icon-arrow-down {
color: white;
}
.el-menu-vertical-demo {
background: rgba(0, 0, 0, 0.5) !important;
}
.is-active {
color: #000 !important;
background-color: #fff !important;
}
.is-active i {
color: #000 !important;
}
.el-submenu__title i {
color: white !important;
}
.icon {
margin-top: -3px;
}
}
</style>
+64
View File
@@ -0,0 +1,64 @@
<template>
<div>
<el-menu-item
:index="item.path"
@click="addRouterTag(item.path,item.title)"
v-if="item.level === 0 || !item.icon"
>
<i :class="item.icon + ' icon'" style="color:white"></i>
<span slot="title">{{item.title}}</span>
</el-menu-item>
<el-submenu :index="item.path" v-else>
<template slot="title">
<i :class="item.icon + ' icon'" style="color:white"></i>
<span>{{item.title}}</span>
</template>
<el-menu-item-group>
<siderbar-item v-for="(items,i) in visibleChildren" :key="i" :item="items"></siderbar-item>
</el-menu-item-group>
</el-submenu>
</div>
</template>
<script>
export default {
name: "siderbarItem",
props: ["item"],
computed: {
visibleChildren() {
const children = this.item.children || [];
return children.filter((c) => !(c.meta && c.meta.hideInMenu));
},
},
mounted() {
// 初始化路由tags显示
this.addRouterTag(this.$route.path, this.$route.meta.title);
},
methods: {
// 提交当前选中路由名称和路径到vuex
addRouterTag(router, routerName) {
if (router === "/welcome") {
return;
}
this.$store.dispatch("setRouterActive", router);
let routers = this.$store.state.routerTags;
let flag = true;
let index;
if (routers.length === 0) {
this.$store.dispatch("setRouterTag", { router, routerName });
return;
}
routers.forEach((item, i) => {
if (item.router === router) {
flag = false;
index = i;
}
});
if (flag) {
this.$store.dispatch("setRouterTag", { router, routerName });
} else {
this.$store.dispatch("setRouterIndex", index + 1);
}
}
}
};
</script>
+45
View File
@@ -0,0 +1,45 @@
<template>
<el-container class="main" direction="vertical">
<!--头部-->
<dg-header></dg-header>
<el-container class="content" style="height: calc(100% - 80px)">
<!--导航-->
<dg-nav></dg-nav>
<!--中间展示区域-->
<dg-content></dg-content>
</el-container>
</el-container>
</template>
<script>
import DgHeader from './components/header'
import DgNav from './components/nav'
import DgContent from './components/content'
export default {
components: {
DgHeader,
DgNav,
DgContent
}
}
</script>
<style lang="scss">
.main {
width: 100%;
height: 100%;
overflow: hidden;
&::-webkit-scrollbar {
/*滚动条整体样式*/
width: 8px; /*高宽分别对应横竖滚动条的尺寸*/
}
&::-webkit-scrollbar-thumb {
border-radius: 10px;
background-color: #ccc;
}
&::-webkit-scrollbar-track {
background-color: rgba(0, 0, 0, 0);
}
}
</style>