mirror of
https://github.com/cool-team-official/cool-admin-vue.git
synced 2025-12-12 05:32:48 +00:00
调整目录结构,添加主题
This commit is contained in:
parent
7670b07db6
commit
5df168bf69
@ -9,9 +9,10 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^0.21.1",
|
"axios": "^0.21.1",
|
||||||
"cl-admin": "^1.3.0",
|
"cl-admin": "^1.3.1",
|
||||||
"cl-admin-crud": "^1.4.0",
|
"cl-admin-crud": "^1.4.0",
|
||||||
"cl-admin-export": "^1.0.5",
|
"cl-admin-export": "^1.0.5",
|
||||||
|
"cl-admin-theme": "^0.0.2",
|
||||||
"clipboard": "^2.0.7",
|
"clipboard": "^2.0.7",
|
||||||
"codemirror": "^5.59.4",
|
"codemirror": "^5.59.4",
|
||||||
"core-js": "^3.6.5",
|
"core-js": "^3.6.5",
|
||||||
|
|||||||
13161
public/theme/black.css
Normal file
13161
public/theme/black.css
Normal file
File diff suppressed because it is too large
Load Diff
13215
public/theme/blue.css
Normal file
13215
public/theme/blue.css
Normal file
File diff suppressed because it is too large
Load Diff
BIN
public/theme/fonts/element-icons.ttf
Normal file
BIN
public/theme/fonts/element-icons.ttf
Normal file
Binary file not shown.
BIN
public/theme/fonts/element-icons.woff
Normal file
BIN
public/theme/fonts/element-icons.woff
Normal file
Binary file not shown.
13215
public/theme/green.css
Normal file
13215
public/theme/green.css
Normal file
File diff suppressed because it is too large
Load Diff
13154
public/theme/purple.css
Normal file
13154
public/theme/purple.css
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,5 @@
|
|||||||
$color-main: var(--color-main, #2f3447);
|
|
||||||
$color-danger: #f56c6c;
|
|
||||||
$color-primary: #4165d7;
|
$color-primary: #4165d7;
|
||||||
$color-success: #67c23a;
|
$color-success: #67c23a;
|
||||||
|
$color-danger: #f56c6c;
|
||||||
$color-info: #909399;
|
$color-info: #909399;
|
||||||
$color-warning: #e6a23c;
|
$color-warning: #e6a23c;
|
||||||
|
|||||||
@ -31,17 +31,17 @@ export const iconfontUrl = ``;
|
|||||||
|
|
||||||
// 程序配置参数
|
// 程序配置参数
|
||||||
export const app = {
|
export const app = {
|
||||||
name: "cool-admin",
|
name: "COOL-ADMIN",
|
||||||
|
|
||||||
conf: {
|
conf: {
|
||||||
// 是否显示一级菜单栏
|
showAMenu: false, // 是否显示一级菜单栏
|
||||||
showAMenu: false,
|
showRouteNav: true, // 是否显示路由导航栏
|
||||||
// 是否显示路由导航栏
|
showProcess: true, // 是否显示页面进程栏
|
||||||
showRouteNav: true,
|
customMenu: false // 自定义菜单
|
||||||
// 是否显示页面进程栏
|
},
|
||||||
showProcess: true,
|
|
||||||
// 自定义菜单
|
theme: {
|
||||||
customMenu: false
|
url: "" // 主题样式地址
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import Crud from "cl-admin-crud";
|
import Crud from "cl-admin-crud";
|
||||||
import Export from "cl-admin-export";
|
import Export from "cl-admin-export";
|
||||||
|
import Theme from "cl-admin-theme";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
modules: [
|
modules: [
|
||||||
@ -36,6 +37,9 @@ export default {
|
|||||||
"copy",
|
"copy",
|
||||||
"distpicker",
|
"distpicker",
|
||||||
"demo",
|
"demo",
|
||||||
"theme"
|
{
|
||||||
|
name: "theme",
|
||||||
|
value: Theme
|
||||||
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,11 +1,14 @@
|
|||||||
import { iconfontUrl } from "@/config/env";
|
import { iconfontUrl, app } from "@/config/env";
|
||||||
|
import { createLink } from "../utils";
|
||||||
|
|
||||||
|
if (app.theme) {
|
||||||
|
if (app.theme.url) {
|
||||||
|
createLink(app.theme.url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (iconfontUrl) {
|
if (iconfontUrl) {
|
||||||
const link = document.createElement("link");
|
createLink(iconfontUrl);
|
||||||
link.type = "text/css";
|
|
||||||
link.rel = "stylesheet";
|
|
||||||
link.href = iconfontUrl;
|
|
||||||
document.getElementsByTagName("head")[0].appendChild(link);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const requireAll = requireContext => requireContext.keys().map(requireContext);
|
const requireAll = requireContext => requireContext.keys().map(requireContext);
|
||||||
|
|||||||
@ -348,14 +348,12 @@ export default {
|
|||||||
|
|
||||||
div {
|
div {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: $color-main;
|
|
||||||
flex: 1;
|
flex: 1;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
i {
|
i {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
color: $color-main;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,6 +31,7 @@
|
|||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
margin: 0 15px 0 5px;
|
margin: 0 15px 0 5px;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
top: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
span {
|
span {
|
||||||
|
|||||||
@ -1,6 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="app-topbar-menu">
|
<div class="cl-menu-topbar">
|
||||||
<el-menu :default-active="index" mode="horizontal" @select="onSelect">
|
<el-menu
|
||||||
|
:default-active="index"
|
||||||
|
mode="horizontal"
|
||||||
|
background-color="transparent"
|
||||||
|
@select="onSelect"
|
||||||
|
>
|
||||||
<el-menu-item v-for="(item, index) in menuGroup" :index="`${index}`" :key="index">
|
<el-menu-item v-for="(item, index) in menuGroup" :index="`${index}`" :key="index">
|
||||||
<icon-svg v-if="item.icon" :name="item.icon"></icon-svg>
|
<icon-svg v-if="item.icon" :name="item.icon"></icon-svg>
|
||||||
<span>{{ item.name }}</span>
|
<span>{{ item.name }}</span>
|
||||||
@ -49,7 +54,7 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.app-topbar-menu {
|
.cl-menu-topbar {
|
||||||
/deep/.el-menu {
|
/deep/.el-menu {
|
||||||
height: 50px;
|
height: 50px;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
@ -72,6 +77,7 @@ export default {
|
|||||||
|
|
||||||
&.is-active {
|
&.is-active {
|
||||||
background: rgba(255, 255, 255, 0.13);
|
background: rgba(255, 255, 255, 0.13);
|
||||||
|
color: $color-primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
/deep/.icon-svg {
|
/deep/.icon-svg {
|
||||||
|
|||||||
@ -213,7 +213,7 @@ export default {
|
|||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background-color: $color-main;
|
background-color: $color-primary;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,7 +226,7 @@ export default {
|
|||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
span {
|
span {
|
||||||
color: $color-main;
|
color: $color-primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
i {
|
i {
|
||||||
@ -235,7 +235,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
&:before {
|
&:before {
|
||||||
background-color: $color-main;
|
background-color: $color-primary;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -118,8 +118,8 @@ export default {
|
|||||||
|
|
||||||
.el-button {
|
.el-button {
|
||||||
margin-left: 15px;
|
margin-left: 15px;
|
||||||
background-color: $color-main;
|
background-color: $color-primary;
|
||||||
border-color: $color-main;
|
border-color: $color-primary;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
padding: 0 30px;
|
padding: 0 30px;
|
||||||
letter-spacing: 1px;
|
letter-spacing: 1px;
|
||||||
@ -132,7 +132,6 @@ export default {
|
|||||||
margin-top: 40px;
|
margin-top: 40px;
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: $color-main;
|
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
transition: all 0.5s;
|
transition: all 0.5s;
|
||||||
-webkit-transition: all 0.5s;
|
-webkit-transition: all 0.5s;
|
||||||
@ -140,10 +139,6 @@ export default {
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
margin: 0 15px;
|
margin: 0 15px;
|
||||||
padding-bottom: 2px;
|
padding-bottom: 2px;
|
||||||
|
|
||||||
&::after {
|
|
||||||
border-color: $color-main;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -122,7 +122,7 @@ export default {
|
|||||||
height: 100vh;
|
height: 100vh;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
position: relative;
|
position: relative;
|
||||||
background-color: $color-main;
|
background-color: $color-primary;
|
||||||
|
|
||||||
.box {
|
.box {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@ -47,13 +47,17 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
|
// 设置浏览器信息
|
||||||
SET_BROWSER(state) {
|
SET_BROWSER(state) {
|
||||||
state.browser = getBrowser();
|
state.browser = getBrowser();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 收起左侧菜单
|
||||||
COLLAPSE_MENU(state, val = false) {
|
COLLAPSE_MENU(state, val = false) {
|
||||||
state.collapse = val;
|
state.collapse = val;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 更新应用配置
|
||||||
UPDATE_CONF(state, val) {
|
UPDATE_CONF(state, val) {
|
||||||
deepMerge(state.conf, val);
|
deepMerge(state.conf, val);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,3 +29,17 @@ export function firstMenu(list) {
|
|||||||
|
|
||||||
return path || "/404";
|
return path || "/404";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function createLink(url, id) {
|
||||||
|
const link = document.createElement("link");
|
||||||
|
link.href = url;
|
||||||
|
link.type = "text/css";
|
||||||
|
link.rel = "stylesheet";
|
||||||
|
if (id) {
|
||||||
|
link.id = id;
|
||||||
|
}
|
||||||
|
document
|
||||||
|
.getElementsByTagName("head")
|
||||||
|
.item(0)
|
||||||
|
.appendChild(link);
|
||||||
|
}
|
||||||
|
|||||||
@ -516,7 +516,6 @@ export default {
|
|||||||
left: 0;
|
left: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
color: $color-main;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
|
|||||||
@ -732,7 +732,7 @@ export default {
|
|||||||
|
|
||||||
&.is-active {
|
&.is-active {
|
||||||
background-color: #eee;
|
background-color: #eee;
|
||||||
border-color: $color-main;
|
border-color: $color-primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
|
|||||||
@ -241,7 +241,7 @@ export default {
|
|||||||
|
|
||||||
.content {
|
.content {
|
||||||
border-top-right-radius: 0;
|
border-top-right-radius: 0;
|
||||||
background-color: $color-main;
|
background-color: $color-primary;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -158,7 +158,7 @@ export default {
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
|
||||||
span {
|
span {
|
||||||
background-color: $color-main;
|
background-color: $color-primary;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
padding: 2px 5px;
|
padding: 2px 5px;
|
||||||
@ -183,8 +183,6 @@ export default {
|
|||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: $color-main;
|
|
||||||
|
|
||||||
&:after {
|
&:after {
|
||||||
content: "";
|
content: "";
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -192,7 +190,7 @@ export default {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: -2px;
|
bottom: -2px;
|
||||||
left: 0;
|
left: 0;
|
||||||
background-color: $color-main;
|
background-color: $color-primary;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +0,0 @@
|
|||||||
import Theme from "./theme";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
Theme
|
|
||||||
};
|
|
||||||
@ -1,158 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="cl-theme">
|
|
||||||
<li @click="open">
|
|
||||||
<icon-svg :size="18" name="icon-theme"></icon-svg>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<el-drawer title="系统设置" :visible.sync="drawer.visible" size="300px">
|
|
||||||
<div class="cl-theme__color is-card">
|
|
||||||
<p>主题色</p>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li
|
|
||||||
v-for="(color, name) in thems"
|
|
||||||
:key="name"
|
|
||||||
:style="{
|
|
||||||
backgroundColor: color
|
|
||||||
}"
|
|
||||||
@click="changeColor(name, color)"
|
|
||||||
></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="cl-theme__switch is-card">
|
|
||||||
<p>内容区域</p>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<span>显示一级菜单栏</span>
|
|
||||||
<el-switch size="mini" v-model="form.showAMenu"></el-switch>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span>显示路由导航栏</span>
|
|
||||||
<el-switch size="mini" v-model="form.showRouteNav"></el-switch>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span>显示页面进程栏</span>
|
|
||||||
<el-switch size="mini" v-model="form.showProcess"></el-switch>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</el-drawer>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "cl-theme",
|
|
||||||
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
drawer: {
|
|
||||||
visible: false
|
|
||||||
},
|
|
||||||
form: {
|
|
||||||
showAMenu: false,
|
|
||||||
showRouteNav: true,
|
|
||||||
showProcess: true
|
|
||||||
},
|
|
||||||
thems: {
|
|
||||||
blue: "#4165d7",
|
|
||||||
black: "#2f3447",
|
|
||||||
green: "#51C21A",
|
|
||||||
purple: "#d0378d"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
watch: {
|
|
||||||
form: {
|
|
||||||
deep: true,
|
|
||||||
handler(val) {
|
|
||||||
this.$store.commit("UPDATE_CONF", val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
open() {
|
|
||||||
this.drawer.visible = true;
|
|
||||||
},
|
|
||||||
|
|
||||||
changeColor(name, color) {
|
|
||||||
this.$message.success("切换主题中");
|
|
||||||
|
|
||||||
const theme = document.getElementById("theme-style");
|
|
||||||
const link = theme || document.createElement("link");
|
|
||||||
|
|
||||||
link.href = `http://192.168.199.148:5000/${name}.css`;
|
|
||||||
|
|
||||||
if (!theme) {
|
|
||||||
link.type = "text/css";
|
|
||||||
link.rel = "stylesheet";
|
|
||||||
link.id = "theme-style";
|
|
||||||
|
|
||||||
document
|
|
||||||
.getElementsByTagName("head")
|
|
||||||
.item(0)
|
|
||||||
.appendChild(link);
|
|
||||||
}
|
|
||||||
|
|
||||||
// document.getElementsByTagName("body")[0].style.setProperty("--color-main", color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.cl-theme {
|
|
||||||
.is-card {
|
|
||||||
padding: 20px 0;
|
|
||||||
margin: 0 20px 20px 20px;
|
|
||||||
border-bottom: 1px solid #f7f7f7;
|
|
||||||
|
|
||||||
& > p {
|
|
||||||
font-size: 15px;
|
|
||||||
font-weight: bold;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__switch {
|
|
||||||
ul {
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
li {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
height: 40px;
|
|
||||||
list-style: none;
|
|
||||||
|
|
||||||
span {
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__color {
|
|
||||||
ul {
|
|
||||||
display: flex;
|
|
||||||
margin-top: 20px;
|
|
||||||
|
|
||||||
li {
|
|
||||||
list-style: none;
|
|
||||||
height: 20px;
|
|
||||||
width: 20px;
|
|
||||||
border-radius: 3px;
|
|
||||||
margin-right: 10px;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
opacity: 0.7;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
import components from "./components";
|
|
||||||
|
|
||||||
export default { components };
|
|
||||||
@ -544,7 +544,7 @@ export default {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
border-color: #409eff;
|
border-color: $color-primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cl-upload__cover {
|
.cl-upload__cover {
|
||||||
@ -565,6 +565,8 @@ export default {
|
|||||||
|
|
||||||
&--picture-card {
|
&--picture-card {
|
||||||
/deep/.el-upload {
|
/deep/.el-upload {
|
||||||
|
background-color: #fff;
|
||||||
|
|
||||||
.cl-upload__icon {
|
.cl-upload__icon {
|
||||||
position: relative;
|
position: relative;
|
||||||
top: 4px;
|
top: 4px;
|
||||||
|
|||||||
@ -1,11 +0,0 @@
|
|||||||
Promise.prototype.done = function(cb) {
|
|
||||||
let P = this.constructor;
|
|
||||||
|
|
||||||
return this.then(
|
|
||||||
value => P.resolve(cb()).then(() => value),
|
|
||||||
reason =>
|
|
||||||
P.resolve(cb()).then(() => {
|
|
||||||
throw reason;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
import { BaseService, Service, Permission } from "./service";
|
|
||||||
import { SET_SERVICE, SET_ROUTER, SET_MODULE } from "./set";
|
|
||||||
import "./common";
|
|
||||||
|
|
||||||
async function bootstrap(options = {}) {
|
|
||||||
const { modules } = options;
|
|
||||||
|
|
||||||
SET_ROUTER();
|
|
||||||
SET_SERVICE();
|
|
||||||
SET_MODULE({ events: modules });
|
|
||||||
}
|
|
||||||
export { Service, Permission, BaseService, bootstrap };
|
|
||||||
@ -1,118 +0,0 @@
|
|||||||
import request from "@/service/request";
|
|
||||||
import { baseUrl } from "@/config/env";
|
|
||||||
|
|
||||||
export default class BaseService {
|
|
||||||
constructor() {
|
|
||||||
const crud = {
|
|
||||||
page: "page",
|
|
||||||
list: "list",
|
|
||||||
info: "info",
|
|
||||||
add: "add",
|
|
||||||
delete: "delete",
|
|
||||||
update: "update"
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!this.permission) {
|
|
||||||
this.permission = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i in crud) {
|
|
||||||
if (this.namespace) {
|
|
||||||
this.permission[i] = this.namespace.replace(/\//g, ":") + ":" + crud[i];
|
|
||||||
} else {
|
|
||||||
this.permission[i] = crud[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
request(options = {}) {
|
|
||||||
if (!options.params) {
|
|
||||||
options.params = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
let path = "";
|
|
||||||
|
|
||||||
if (process.env.NODE_ENV == "development") {
|
|
||||||
path = this.proxy || baseUrl;
|
|
||||||
} else {
|
|
||||||
if (this.proxy) {
|
|
||||||
path = this.url;
|
|
||||||
} else {
|
|
||||||
path = baseUrl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.namespace) {
|
|
||||||
path += "/" + this.namespace;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.url.indexOf("http") !== 0) {
|
|
||||||
if (options.url[0] === "@") {
|
|
||||||
options.url = options.url.replace("@", "");
|
|
||||||
} else {
|
|
||||||
options.url = path + options.url;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return request(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
list(params) {
|
|
||||||
return this.request({
|
|
||||||
url: "/list",
|
|
||||||
method: "POST",
|
|
||||||
data: {
|
|
||||||
...params
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
page(params) {
|
|
||||||
return this.request({
|
|
||||||
url: "/page",
|
|
||||||
method: "POST",
|
|
||||||
data: {
|
|
||||||
...params
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
info(params) {
|
|
||||||
return this.request({
|
|
||||||
url: "/info",
|
|
||||||
params: {
|
|
||||||
...params
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
update(params) {
|
|
||||||
return this.request({
|
|
||||||
url: "/update",
|
|
||||||
method: "POST",
|
|
||||||
data: {
|
|
||||||
...params
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
delete(params) {
|
|
||||||
return this.request({
|
|
||||||
url: "/delete",
|
|
||||||
method: "POST",
|
|
||||||
data: {
|
|
||||||
...params
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
add(params) {
|
|
||||||
return this.request({
|
|
||||||
url: "/add",
|
|
||||||
method: "POST",
|
|
||||||
data: {
|
|
||||||
...params
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,38 +0,0 @@
|
|||||||
import { isObject } from "../utils";
|
|
||||||
|
|
||||||
export function Permission(value) {
|
|
||||||
return function (target, key, descriptor) {
|
|
||||||
if (!target.permission) {
|
|
||||||
target.permission = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
target.permission[key] = (
|
|
||||||
(target.namespace ? target.namespace + "/" : "") + value
|
|
||||||
).replace(/\//g, ":");
|
|
||||||
}, 0);
|
|
||||||
|
|
||||||
return descriptor;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Service(value) {
|
|
||||||
return function (target) {
|
|
||||||
// 命名
|
|
||||||
if (typeof value == "string") {
|
|
||||||
target.prototype.namespace = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 复杂项
|
|
||||||
if (isObject(value)) {
|
|
||||||
let { proxy, namespace, url } = value;
|
|
||||||
|
|
||||||
target.prototype.namespace = namespace;
|
|
||||||
|
|
||||||
if (proxy) {
|
|
||||||
target.prototype.proxy = proxy;
|
|
||||||
target.prototype.url = url || process.env.PROXY_LIST[proxy].target;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
import BaseService from "./base";
|
|
||||||
import { Service, Permission } from "./desorator";
|
|
||||||
|
|
||||||
export { BaseService, Service, Permission };
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
import SET_SERVICE from "./service";
|
|
||||||
import SET_ROUTER from "./router";
|
|
||||||
import SET_MODULE from "./module";
|
|
||||||
|
|
||||||
export { SET_SERVICE, SET_ROUTER, SET_MODULE };
|
|
||||||
@ -1,157 +0,0 @@
|
|||||||
import Vue from "vue";
|
|
||||||
import cool from "@/cool";
|
|
||||||
import store from "@/store";
|
|
||||||
import router from "@/router";
|
|
||||||
import { deepMerge, isFunction, isObject, isString } from "../utils";
|
|
||||||
|
|
||||||
// 模块列表
|
|
||||||
let modules = [];
|
|
||||||
|
|
||||||
export default function () {
|
|
||||||
const files = require.context("@/cool/modules", true, /index.js$/);
|
|
||||||
|
|
||||||
// 本地模块
|
|
||||||
const local = files
|
|
||||||
.keys()
|
|
||||||
.map(e => {
|
|
||||||
let [, name, , error] = e.split("/");
|
|
||||||
|
|
||||||
if (!error) {
|
|
||||||
return {
|
|
||||||
name,
|
|
||||||
value: files(e).default
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.filter(Boolean);
|
|
||||||
|
|
||||||
// 安装模块
|
|
||||||
function install(mod) {
|
|
||||||
const { store: _store, components, service, directives, filters, pages, views, name } = mod;
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 注册vuex模块
|
|
||||||
if (_store) {
|
|
||||||
for (let i in _store) {
|
|
||||||
store.registerModule(`${name}-${i}`, _store[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 注册组件
|
|
||||||
if (components) {
|
|
||||||
for (let i in components) {
|
|
||||||
Vue.component(components[i].name, components[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 注册请求服务
|
|
||||||
if (service) {
|
|
||||||
deepMerge(store.$service, service);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 注册指令
|
|
||||||
if (directives) {
|
|
||||||
for (let i in directives) {
|
|
||||||
Vue.directive(i, directives[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 注册过滤器
|
|
||||||
if (filters) {
|
|
||||||
for (let i in filters) {
|
|
||||||
Vue.filter(i, filters[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 注册页面
|
|
||||||
if (pages) {
|
|
||||||
pages.forEach(e => {
|
|
||||||
router.addRoute(e);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 注册视图
|
|
||||||
if (views) {
|
|
||||||
views.forEach(e => {
|
|
||||||
if (!e.meta) {
|
|
||||||
e.meta = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.path) {
|
|
||||||
router.$plugin.addViews([e], {
|
|
||||||
ignore404: true
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
console.error(`[${name}-views]:path in null`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error(`模块 ${name} 异常`, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 解析模块
|
|
||||||
cool.modules.map(e => {
|
|
||||||
if (!e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mod = null;
|
|
||||||
|
|
||||||
// Parse
|
|
||||||
if (isString(e)) {
|
|
||||||
mod = {
|
|
||||||
name: e
|
|
||||||
};
|
|
||||||
} else if (isObject(e)) {
|
|
||||||
mod = e;
|
|
||||||
} else if (isArray(e)) {
|
|
||||||
mod = {
|
|
||||||
name: e[0],
|
|
||||||
value: e[1],
|
|
||||||
options: e[2]
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
console.error(e, "格式错误");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set
|
|
||||||
if (mod.value) {
|
|
||||||
if (isFunction(mod.value.install)) {
|
|
||||||
mod.value = mod.value.install(Vue, mod.options);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const item = local.find(m => m.name === mod.name);
|
|
||||||
|
|
||||||
if (item) {
|
|
||||||
mod.value = item.value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mod.value) {
|
|
||||||
console.error(mod.name, "不是一个有效的模块");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 是否开启
|
|
||||||
if (mod.options && mod.options.enable === false) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mod) {
|
|
||||||
mod = {
|
|
||||||
name: mod.name,
|
|
||||||
options: mod.options,
|
|
||||||
...mod.value
|
|
||||||
};
|
|
||||||
|
|
||||||
modules.push(mod);
|
|
||||||
install(mod);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 缓存模块
|
|
||||||
store.commit("SET_MODULE", modules);
|
|
||||||
}
|
|
||||||
@ -1,113 +0,0 @@
|
|||||||
import VueRouter from "vue-router";
|
|
||||||
import { Message } from "element-ui";
|
|
||||||
import store from "@/store";
|
|
||||||
import router, { ignore } from "@/router";
|
|
||||||
import storage from "../utils/storage";
|
|
||||||
|
|
||||||
// Remove Navigating to current location (XXX) is not allowed
|
|
||||||
const routerPush = VueRouter.prototype.push;
|
|
||||||
VueRouter.prototype.push = function push(location) {
|
|
||||||
return routerPush.call(this, location).catch(error => error);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function () {
|
|
||||||
router.$plugin = {
|
|
||||||
addViews: (list, options) => {
|
|
||||||
if (!options) {
|
|
||||||
options = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse route config
|
|
||||||
list.map(e => {
|
|
||||||
if (!e.component) {
|
|
||||||
let url = e.viewPath;
|
|
||||||
|
|
||||||
if (url) {
|
|
||||||
if (
|
|
||||||
/^(http[s]?:\/\/)([0-9a-z.]+)(:[0-9]+)?([/0-9a-z.]+)?(\?[0-9a-z&=]+)?(#[0-9-a-z]+)?/i.test(
|
|
||||||
url
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
e.meta.iframeUrl = url;
|
|
||||||
e.component = () =>
|
|
||||||
import(`@/cool/modules/base/pages/iframe/index.vue`);
|
|
||||||
} else {
|
|
||||||
e.component = () => import(`@/${url}`);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
e.redirect = "/404";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Batch add route
|
|
||||||
list.forEach(e => {
|
|
||||||
router.addRoute("index", e);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add 404 rule
|
|
||||||
if (!options.ignore404) {
|
|
||||||
router.addRoute({
|
|
||||||
path: "*",
|
|
||||||
redirect: "/404"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
to: url => {
|
|
||||||
if (router.path != url) {
|
|
||||||
router.push(url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
router.beforeEach((to, from, next) => {
|
|
||||||
const { token, browser } = store.getters;
|
|
||||||
|
|
||||||
if (token) {
|
|
||||||
if (to.path.indexOf("/login") === 0) {
|
|
||||||
// 登录成功且 token 未过期,回到首页
|
|
||||||
if (!storage.isExpired("token")) {
|
|
||||||
return next("/");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 添加路由进程
|
|
||||||
store.commit("ADD_PROCESS", {
|
|
||||||
label: (to.meta && to.meta.label) || to.name,
|
|
||||||
value: to.fullPath
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!ignore.token.some(e => to.path.indexOf(e) === 0)) {
|
|
||||||
return next("/login");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// H5 下关闭左侧菜单
|
|
||||||
if (browser.isMobile) {
|
|
||||||
store.commit("COLLAPSE_MENU", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
|
|
||||||
let lock = false;
|
|
||||||
|
|
||||||
router.onError(err => {
|
|
||||||
if (!lock) {
|
|
||||||
lock = true;
|
|
||||||
|
|
||||||
if (err.code == "MODULE_NOT_FOUND") {
|
|
||||||
console.error(err.message.replace("Cannot find module ", ""), "路由组件不存在");
|
|
||||||
|
|
||||||
Message.error(`路由组件路径错误`);
|
|
||||||
} else {
|
|
||||||
console.error(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
lock = false;
|
|
||||||
}, 0);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@ -1,53 +0,0 @@
|
|||||||
import Vue from "vue";
|
|
||||||
import path from "path";
|
|
||||||
import store from "@/store";
|
|
||||||
|
|
||||||
export default function() {
|
|
||||||
const files = require.context("@/service/", true, /\.js$/);
|
|
||||||
const ignore = ["./request.js"];
|
|
||||||
|
|
||||||
let modules = {};
|
|
||||||
|
|
||||||
files
|
|
||||||
.keys()
|
|
||||||
.filter(e => !ignore.includes(e))
|
|
||||||
.map(e => {
|
|
||||||
if (e.includes("--ignore")) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
let list = e.substr(2).split("/");
|
|
||||||
let parents = list.slice(0, list.length - 1);
|
|
||||||
let name = path.basename(e, ".js");
|
|
||||||
|
|
||||||
let curr = modules;
|
|
||||||
let prev = null;
|
|
||||||
let key = null;
|
|
||||||
|
|
||||||
parents.forEach(k => {
|
|
||||||
if (!curr[k]) {
|
|
||||||
curr[k] = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
prev = curr;
|
|
||||||
curr = curr[k];
|
|
||||||
key = k;
|
|
||||||
});
|
|
||||||
|
|
||||||
let ep = files(e);
|
|
||||||
|
|
||||||
if (ep.default) {
|
|
||||||
let service = new ep.default();
|
|
||||||
|
|
||||||
if (name == "index") {
|
|
||||||
prev[key] = service;
|
|
||||||
} else {
|
|
||||||
curr[name] = service;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.error(`Service must export default [${e}]`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Vue.prototype.$service = store.$service = modules;
|
|
||||||
}
|
|
||||||
@ -1,266 +0,0 @@
|
|||||||
import { routerMode } from "@/config/env";
|
|
||||||
import storage from "./storage";
|
|
||||||
|
|
||||||
export function getUrlParam(name) {
|
|
||||||
let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
|
|
||||||
let r = window.location.search.substr(1).match(reg);
|
|
||||||
if (r != null) return decodeURIComponent(r[2]);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isPc() {
|
|
||||||
const userAgentInfo = navigator.userAgent;
|
|
||||||
const Agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
|
|
||||||
let flag = true;
|
|
||||||
for (let v = 0; v < Agents.length; v++) {
|
|
||||||
if (userAgentInfo.indexOf(Agents[v]) > 0) {
|
|
||||||
flag = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return flag;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const isIOS = !!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
|
|
||||||
|
|
||||||
export function getBrowser() {
|
|
||||||
let ua = navigator.userAgent.toLowerCase();
|
|
||||||
let btypeInfo = (ua.match(/firefox|chrome|safari|opera/g) || "other")[0];
|
|
||||||
if ((ua.match(/msie|trident/g) || [])[0]) {
|
|
||||||
btypeInfo = "msie";
|
|
||||||
}
|
|
||||||
let pc = "";
|
|
||||||
let prefix = "";
|
|
||||||
let plat = "";
|
|
||||||
|
|
||||||
let isTocuh =
|
|
||||||
"ontouchstart" in window || ua.indexOf("touch") !== -1 || ua.indexOf("mobile") !== -1;
|
|
||||||
if (isTocuh) {
|
|
||||||
if (ua.indexOf("ipad") !== -1) {
|
|
||||||
pc = "pad";
|
|
||||||
} else if (ua.indexOf("mobile") !== -1) {
|
|
||||||
pc = "mobile";
|
|
||||||
} else if (ua.indexOf("android") !== -1) {
|
|
||||||
pc = "androidPad";
|
|
||||||
} else {
|
|
||||||
pc = "pc";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pc = "pc";
|
|
||||||
}
|
|
||||||
switch (btypeInfo) {
|
|
||||||
case "chrome":
|
|
||||||
case "safari":
|
|
||||||
case "mobile":
|
|
||||||
prefix = "webkit";
|
|
||||||
break;
|
|
||||||
case "msie":
|
|
||||||
prefix = "ms";
|
|
||||||
break;
|
|
||||||
case "firefox":
|
|
||||||
prefix = "Moz";
|
|
||||||
break;
|
|
||||||
case "opera":
|
|
||||||
prefix = "O";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
prefix = "webkit";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
plat = ua.indexOf("android") > 0 ? "android" : navigator.platform.toLowerCase();
|
|
||||||
return {
|
|
||||||
version: (ua.match(/[\s\S]+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [])[1],
|
|
||||||
plat: plat,
|
|
||||||
type: btypeInfo,
|
|
||||||
pc: pc,
|
|
||||||
prefix: prefix,
|
|
||||||
isMobile: pc == "pc" ? false : true
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function href(path, newWindow) {
|
|
||||||
let { search, origin, pathname } = window.location;
|
|
||||||
|
|
||||||
if (pathname == path) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
let url = "";
|
|
||||||
|
|
||||||
if (routerMode == "history") {
|
|
||||||
url = origin + path;
|
|
||||||
} else {
|
|
||||||
url = origin + search + "#" + path;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newWindow) {
|
|
||||||
window.open(url);
|
|
||||||
} else {
|
|
||||||
window.location.href = url;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function orderBy(list, key) {
|
|
||||||
return list.sort((a, b) => a[key] - b[key]);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function deepTree(list) {
|
|
||||||
let newList = [];
|
|
||||||
let map = {};
|
|
||||||
|
|
||||||
list.forEach(e => (map[e.id] = e));
|
|
||||||
|
|
||||||
list.forEach(e => {
|
|
||||||
let parent = map[e.parentId];
|
|
||||||
|
|
||||||
if (parent) {
|
|
||||||
(parent.children || (parent.children = [])).push(e);
|
|
||||||
} else {
|
|
||||||
newList.push(e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const fn = list => {
|
|
||||||
list.map(e => {
|
|
||||||
if (e.children instanceof Array) {
|
|
||||||
e.children = orderBy(e.children, "orderNum");
|
|
||||||
|
|
||||||
fn(e.children);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
fn(newList);
|
|
||||||
|
|
||||||
return orderBy(newList, "orderNum");
|
|
||||||
}
|
|
||||||
|
|
||||||
export function revDeepTree(list = []) {
|
|
||||||
let d = [];
|
|
||||||
let id = 0;
|
|
||||||
|
|
||||||
const deep = (list, parentId) => {
|
|
||||||
list.forEach(e => {
|
|
||||||
if (!e.id) {
|
|
||||||
e.id = id++;
|
|
||||||
}
|
|
||||||
|
|
||||||
e.parentId = parentId;
|
|
||||||
|
|
||||||
d.push(e);
|
|
||||||
|
|
||||||
if (e.children && isArray(e.children)) {
|
|
||||||
deep(e.children, e.id);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
deep(list || [], null);
|
|
||||||
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function debounce(fn, delay) {
|
|
||||||
let timer = null;
|
|
||||||
|
|
||||||
return function() {
|
|
||||||
let args = arguments;
|
|
||||||
let context = this;
|
|
||||||
|
|
||||||
if (timer) {
|
|
||||||
clearTimeout(timer);
|
|
||||||
|
|
||||||
timer = setTimeout(function() {
|
|
||||||
fn.apply(context, args);
|
|
||||||
}, delay);
|
|
||||||
} else {
|
|
||||||
timer = setTimeout(function() {
|
|
||||||
fn.apply(context, args);
|
|
||||||
}, delay);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isArray(value) {
|
|
||||||
if (typeof Array.isArray === "function") {
|
|
||||||
return Array.isArray(value);
|
|
||||||
} else {
|
|
||||||
return Object.prototype.toString.call(value) === "[object Array]";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isObject(value) {
|
|
||||||
return Object.prototype.toString.call(value) === "[object Object]";
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isNumber(value) {
|
|
||||||
return !isNaN(Number(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isFunction(value) {
|
|
||||||
return typeof value == "function";
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isString(value) {
|
|
||||||
return typeof value == "string";
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isEmpty(value) {
|
|
||||||
if (isArray(value)) {
|
|
||||||
return value.length === 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isObject(value)) {
|
|
||||||
return Object.keys(value).length === 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value === "" || value === undefined || value === null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function last(data) {
|
|
||||||
if (isArray(data) || isString(data)) {
|
|
||||||
return data[data.length - 1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function cloneDeep(obj) {
|
|
||||||
let d = isArray(obj) ? obj : {};
|
|
||||||
|
|
||||||
if (isObject(obj)) {
|
|
||||||
for (let key in obj) {
|
|
||||||
if (obj.hasOwnProperty && obj.hasOwnProperty(key)) {
|
|
||||||
if (obj[key] && typeof obj[key] === "object") {
|
|
||||||
d[key] = cloneDeep(obj[key]);
|
|
||||||
} else {
|
|
||||||
d[key] = obj[key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function clone(obj) {
|
|
||||||
return Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj));
|
|
||||||
}
|
|
||||||
|
|
||||||
export function deepMerge(a, b) {
|
|
||||||
let k;
|
|
||||||
for (k in b) {
|
|
||||||
a[k] =
|
|
||||||
a[k] && a[k].toString() === "[object Object]" ? deepMerge(a[k], b[k]) : (a[k] = b[k]);
|
|
||||||
}
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function contains(parent, node) {
|
|
||||||
if (document.documentElement.contains) {
|
|
||||||
return parent !== node && parent.contains(node);
|
|
||||||
} else {
|
|
||||||
while (node && (node = node.parentNode)) if (node === parent) return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export { storage };
|
|
||||||
@ -1,81 +0,0 @@
|
|||||||
import store from "store";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
// 后缀标识
|
|
||||||
suffix: "_deadtime",
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取
|
|
||||||
* @param {string} key 关键字
|
|
||||||
*/
|
|
||||||
get(key) {
|
|
||||||
return store.get(key);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取全部
|
|
||||||
*/
|
|
||||||
info() {
|
|
||||||
let d = {};
|
|
||||||
|
|
||||||
store.each(function(value, key) {
|
|
||||||
d[key] = value;
|
|
||||||
});
|
|
||||||
|
|
||||||
return d;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置
|
|
||||||
* @param {string} key 关键字
|
|
||||||
* @param {*} value 值
|
|
||||||
* @param {number} expires 过期时间
|
|
||||||
*/
|
|
||||||
set(key, value, expires) {
|
|
||||||
store.set(key, value);
|
|
||||||
|
|
||||||
if (expires) {
|
|
||||||
store.set(`${key}${this.suffix}`, Date.parse(new Date()) + expires * 1000);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否过期
|
|
||||||
* @param {string} key 关键字
|
|
||||||
*/
|
|
||||||
isExpired(key) {
|
|
||||||
return (this.getExpiration(key) || 0) - Date.parse(new Date()) <= 2000;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取到期时间
|
|
||||||
* @param {string} key 关键字
|
|
||||||
*/
|
|
||||||
getExpiration(key) {
|
|
||||||
return this.get(key + this.suffix);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 移除
|
|
||||||
* @param {string} key 关键字
|
|
||||||
*/
|
|
||||||
remove(key) {
|
|
||||||
store.remove(key);
|
|
||||||
this.removeExpiration(key);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 移除到期时间
|
|
||||||
* @param {string} key 关键字
|
|
||||||
*/
|
|
||||||
removeExpiration(key) {
|
|
||||||
store.remove(key + this.suffix);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 清理
|
|
||||||
*/
|
|
||||||
clearAll() {
|
|
||||||
store.clearAll();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@ -75,7 +75,6 @@ export default {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
&__left {
|
&__left {
|
||||||
background-color: $color-main;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 255px;
|
width: 255px;
|
||||||
|
|||||||
@ -1,14 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="app-slider">
|
<div class="app-slider">
|
||||||
<div class="app-slider__logo">
|
<div class="app-slider__logo" @click="toHome">
|
||||||
<a href="https://cool-admin.com/">
|
<img src="@/assets/icon/logo/silder-simple.png" />
|
||||||
<img
|
<span v-if="!menuCollapse || browser.isMobile">{{ appInfo.name }}</span>
|
||||||
class="c"
|
|
||||||
src="@/assets/icon/logo/silder.png"
|
|
||||||
v-if="!menuCollapse || browser.isMobile"
|
|
||||||
/>
|
|
||||||
<img class="z" src="@/assets/icon/logo/silder-simple.png" v-else />
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="app-slider__menu">
|
<div class="app-slider__menu">
|
||||||
@ -22,7 +16,13 @@ import { mapGetters } from "vuex";
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(["menuCollapse", "browser"])
|
...mapGetters(["menuCollapse", "browser", "appInfo"])
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
toHome() {
|
||||||
|
location.href = "https://cool-js.com/";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
@ -31,23 +31,28 @@ export default {
|
|||||||
.app-slider {
|
.app-slider {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
|
||||||
background-color: $color-main;
|
background-color: #2f3447;
|
||||||
|
|
||||||
&__logo {
|
&__logo {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
height: 80px;
|
height: 80px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
.c {
|
img {
|
||||||
height: 30px;
|
|
||||||
width: 193px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.z {
|
|
||||||
height: 30px;
|
height: 30px;
|
||||||
width: 30px;
|
width: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #fff;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 26px;
|
||||||
|
margin-left: 10px;
|
||||||
|
font-family: inherit;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__menu {
|
&__menu {
|
||||||
|
|||||||
@ -24,7 +24,7 @@
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
<!-- 主题 -->
|
<!-- 主题 -->
|
||||||
<li>
|
<li v-if="modules.theme">
|
||||||
<cl-theme />
|
<cl-theme />
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@ -95,6 +95,7 @@ export default {
|
|||||||
height: 40px;
|
height: 40px;
|
||||||
width: 40px;
|
width: 40px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
margin-right: 10px;
|
||||||
|
|
||||||
.icon-svg {
|
.icon-svg {
|
||||||
height: 22px;
|
height: 22px;
|
||||||
|
|||||||
@ -84,7 +84,6 @@ export default {
|
|||||||
height: 50px;
|
height: 50px;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: $color-main;
|
|
||||||
padding: 0 20px;
|
padding: 0 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -252,7 +252,6 @@ export default {
|
|||||||
height: 50px;
|
height: 50px;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: $color-main;
|
|
||||||
padding: 0 20px;
|
padding: 0 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -108,7 +108,6 @@ export default {
|
|||||||
height: 50px;
|
height: 50px;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: $color-main;
|
|
||||||
padding: 0 20px;
|
padding: 0 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,7 +132,7 @@ export default {
|
|||||||
color: #d8d8d8;
|
color: #d8d8d8;
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
color: $color-main;
|
color: #000;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:not(.active):hover {
|
&:not(.active):hover {
|
||||||
@ -185,7 +184,7 @@ export default {
|
|||||||
&:nth-last-child(n + 3) {
|
&:nth-last-child(n + 3) {
|
||||||
span {
|
span {
|
||||||
&:first-child {
|
&:first-child {
|
||||||
background-color: $color-main;
|
background-color: #000;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -134,7 +134,7 @@ export default {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
color: $color-main;
|
color: #000;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -151,7 +151,7 @@ export default {
|
|||||||
height: 8px;
|
height: 8px;
|
||||||
width: 8px;
|
width: 8px;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
background-color: $color-main;
|
background-color: #000;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: -15px;
|
left: -15px;
|
||||||
top: 4px;
|
top: 4px;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user