This commit is contained in:
chengdandan 2022-12-14 16:20:12 +08:00
commit 9bf5f04624
69 changed files with 16609 additions and 0 deletions

3
.browserslistrc Normal file
View File

@ -0,0 +1,3 @@
> 1%
last 2 versions
not ie <= 8

6
.prettierrc Normal file
View File

@ -0,0 +1,6 @@
{
"tabWidth": 4,
"singleQuote": true,
"trailingComma": "none",
"printWidth": 140
}

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 hxhpg
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

13
README.md Normal file
View File

@ -0,0 +1,13 @@
# vue-secondMenu-test
Vue + ElementUI 后台管理系统实现顶部一级菜单栏,左侧二级菜单栏
项目实现了登录功能,一二级菜单联动选择展示不同的主体内容部分,封装了 axios 请求库,还简单配置了管理员和普通用户的权限区分。
## 运行项目
npm install
npm run dev

5
babel.config.js Normal file
View File

@ -0,0 +1,5 @@
module.exports = {
presets: [
'@vue/app'
]
}

12141
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

35
package.json Normal file
View File

@ -0,0 +1,35 @@
{
"name": "data-audit-hxh",
"version": "2.0.0",
"private": true,
"scripts": {
"dev": "vue-cli-service serve --open",
"build": "vue-cli-service build"
},
"dependencies": {
"axios": "^0.18.1",
"babel-polyfill": "^6.26.0",
"echarts": "^4.9.0",
"element-ui": "^2.13.2",
"js-cookie": "^3.0.1",
"mavon-editor": "^2.6.17",
"mqtt": "^4.3.7",
"node-sass": "^5.0.0",
"sass-loader": "^10.1.0",
"view-design": "^4.3.2",
"vue": "^2.6.10",
"vue-cropperjs": "^3.0.0",
"vue-i18n": "^8.10.0",
"vue-quill-editor": "^3.0.6",
"vue-router": "^3.0.3",
"vue-schart": "^2.0.0",
"vuedraggable": "^2.17.0",
"vuex": "3.6.2"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^3.9.0",
"@vue/cli-service": "^3.9.0",
"vue-resource": "^1.5.1",
"vue-template-compiler": "^2.6.12"
}
}

5
postcss.config.js Normal file
View File

@ -0,0 +1,5 @@
module.exports = {
plugins: {
autoprefixer: {}
}
}

17
public/index.html Normal file
View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
<link rel="stylesheet" href="//at.alicdn.com/t/font_830376_qzecyukz0s.css">
<title>后台管理系统</title>
</head>
<body>
<noscript>
<strong>We're sorry but vms doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

22
src/App.vue Normal file
View File

@ -0,0 +1,22 @@
<template>
<div id="app" :class="style ? 'theme1' : ''">
<router-view></router-view>
</div>
</template>
<script>
import bus from '@/utils/bus';
export default {
data(){
return{
style: false
}
},
created(){
bus.$on('global_theme', (msg) => { // global_theme
this.style = msg;
});
}
}
</script>

9
src/api/login.js Normal file
View File

@ -0,0 +1,9 @@
import request from '@/utils/request.js';
export function loginApi(data) { // 登录接口
return request({
url: '/hxh/api-test/login',
method: 'post',
data: data
});
}

9
src/api/test.js Normal file
View File

@ -0,0 +1,9 @@
import request from '@/utils/request.js';
export function testApi(data) { // 测试接口
return request({
url: '/hxh/api-test/testApi',
method: 'post',
data: data
});
}

164
src/assets/css/main.css Normal file
View File

@ -0,0 +1,164 @@
* {
margin: 0;
padding: 0;
}
html,
body,
#app {
width: 100%;
height: 100%;
background: #f0f0f0;
}
body {
font-family: 'PingFang SC', "Helvetica Neue", Helvetica, "microsoft yahei", arial, STHeiTi, sans-serif;
}
a {
text-decoration: none;
}
.header{
background-color: white;
}
.login-wrap{
background: #324157;
}
.plugins-tips{
background: #eef1f6;
padding: 20px 10px;
margin-bottom: 20px;
}
.plugins-tips a{
color: #20a0ff;
}
.el-upload--text em {
color: #20a0ff;
}
.pure-button{
background: #20a0ff;
}
.tags-li.active {
border: 1px solid #409EFF;
background-color: #409EFF;
}
.message-title{
color: #20a0ff;
}
.collapse-btn:hover{
background: none;
}
/* 错误页面总体样式 */
.error-page{
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
width: 100%;
height: 100%;
background: #f3f3f3;
box-sizing: border-box;
}
.error-code{
line-height: 1;
font-size: 250px;
font-weight: bolder;
color: #f02d2d;
}
.error-code span{
color: #00a854;
}
.error-desc{
font-size: 30px;
color: #777;
}
.error-handle{
margin-top: 30px;
padding-bottom: 200px;
}
.error-btn{
margin-left: 100px;
}
/* 页面主体部分 */
.content-box {
position: absolute;
left: 250px; /* 控制左侧二级菜单栏的宽度 */
right: 0;
top: 70px;
bottom: 0;
padding: 10px 20px;
-webkit-transition: left .3s ease-in-out;
transition: left .3s ease-in-out;
background: #f0f0f0;
}
.content {
width: auto;
height: 100%;
padding: 10px;
overflow-y: scroll;
box-sizing: border-box;
}
.content-collapse {
left: 65px;
}
.container {
padding: 20px; /* 控制主体部分与主体边框的距离 */
background: #fff;
border: 1px solid #ddd;
border-radius: 5px;
}
.crumbs {
margin: 10px 0;
}
.el-table th {
background-color: #f5f7fa !important;
}
.pagination {
margin: 20px 0;
text-align: right;
}
.el-button+.el-tooltip {
margin-left: 10px;
}
.el-table tr:hover {
background: #f6faff;
}
.mgb20 {
margin-bottom: 20px;
}
.move-enter-active,
.move-leave-active {
transition: opacity .5s;
}
.move-enter,
.move-leave {
opacity: 0;
}
/* 表格栏样式 */
.table-container {
margin-top: 20px;
}
/* 分页栏样式 */
.pagination-area {
width: 100%;
text-align: right;
margin: 20px 0 10px 0;
}
/* 测试主体页面的 div 样式 */
.test-div{
margin: 15px;
}

51
src/assets/css/theme.scss Normal file
View File

@ -0,0 +1,51 @@
.theme1{
/* 将自己想要换肤后变化的样式写入该处,根据自己的需要进行修改和添加 */
.sidebar-el-menu:not(.el-menu--collapse) {
background: #012d4b !important;
}
.sidebar > ul {
background: #012d4b !important;
}
/* 左侧菜单栏样式 */
.el-menu-item{
color: white !important; /* 默认 black */
background: #012d4b !important;
}
.el-menu-item, .el-submenu__title {
background: #012d4b !important;
}
/* 页面顶部的样式 */
.header {
/* background-image:url("../../assets/img/main-bg1-top.jpg");
background-repeat:no-repeat;
background-size:100% 200%; */
background-color: #001d30 !important;
color: white !important;
}
.el-dropdown-link {
color: white !important;
}
/* --------------- 水平一级菜单栏的样式--------------------- */
.el-menu--horizontal > .el-menu-item.is-active {
border-bottom: 2px solid #7FFFD4 !important; /* 默认 blue */
color: #7FFFD4 !important; /* 默认 blue */
}
.el-menu--horizontal > .el-menu-item {
background: transparent !important;
color: white !important; /* 默认 black */
}
.el-menu--horizontal > .el-menu-item:hover {
background: transparent !important;
color: white !important;
}
/* 消息按钮颜色样式 */
.el-icon-bell{
color: white;
}
.el-icon-caret-bottom{
color: white;
}
}

BIN
src/assets/img/img.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
src/assets/img/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

View File

@ -0,0 +1,47 @@
<template>
<section class="main">
<div class="crumbs">
<el-breadcrumb separator="/">
<el-breadcrumb-item>{{ $t('i18n.breadcrumb') }}</el-breadcrumb-item>
</el-breadcrumb>
</div>
<div class="container">
<span>{{ $t('i18n.tips') }}</span>
<el-button type="primary" @click="$i18n.locale = $i18n.locale === 'zh' ? 'en' : 'zh'">{{ $t('i18n.btn') }}</el-button>
<div class="list">
<h2>{{ $t('i18n.title1') }}</h2>
<p>{{ $t('i18n.p1') }}</p>
<p>{{ $t('i18n.p2') }}</p>
<p>{{ $t('i18n.p3') }}</p>
</div>
<h2>{{ $t('i18n.title2') }}</h2>
<div>
<i18n path="i18n.info" tag="p">
<a place="action" href="https://element.eleme.cn/2.0/#/zh-CN/component/i18n">{{ $t('i18n.value') }}</a>
</i18n>
</div>
</div>
</section>
</template>
<script>
export default {
data() {
return {
}
}
}
</script>
<style scoped>
.list {
padding: 30px 0;
}
.list p {
margin-bottom: 20px;
}
a {
color: #409eff;
}
</style>

View File

@ -0,0 +1,101 @@
<template>
<div :class="{'hidden':hidden}" class="pagination-container">
<el-pagination
:background="background"
:current-page.sync="currentPage"
:page-size.sync="pageSize"
:layout="layout"
:page-sizes="pageSizes"
:total="total"
v-bind="$attrs"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
></el-pagination>
</div>
</template>
<script>
import { scrollTo } from '@/utils/scroll-to';
export default {
name: 'Pagination',
props: {
total: {
required: true,
type: Number
},
page: {
type: Number,
default: 1
},
limit: {
type: Number,
default: 20
},
pageSizes: {
type: Array,
default() {
return [10, 20, 30, 50, 100]
}
},
layout: {
type: String,
default: 'total, sizes, prev, pager, next, jumper'
},
background: {
type: Boolean,
default: true
},
autoScroll: {
type: Boolean,
default: true
},
hidden: {
type: Boolean,
default: false
}
},
computed: {
currentPage: {
get() {
return this.page;
},
set(val) {
this.$emit('update:page', val);
}
},
pageSize: {
get() {
return this.limit;
},
set(val) {
this.$emit('update:limit', val);
}
}
},
methods: {
handleSizeChange(val) {
this.$emit('pagination', { page: this.currentPage, limit: val });
if (this.autoScroll) {
scrollTo(0, 800);
}
},
handleCurrentChange(val) {
this.$emit('pagination', { page: val, limit: this.pageSize });
if (this.autoScroll) {
scrollTo(0, 800);
}
}
}
}
</script>
<style scoped>
.pagination-container {
background: #fff;
padding: 10px 0 0 16px;
}
.pagination-container.hidden {
display: none;
}
</style>

View File

@ -0,0 +1,169 @@
<template>
<div class="wrapper">
<!-- 页面头部部分 -->
<div class="header">
<div class="logo">后台管理系统</div>
<!-- 水平一级菜单 -->
<div style="float:left;">
<!-- <el-menu
mode="horizontal"
text-color="#000000"
active-text-color="#3989fa"
:default-active="toIndex"
@select="handleSelect">
<el-menu-item v-for="(item, index) in itemList" :index="item.path" :key="index">
<span slot="title">{{ item.title }}</span>
</el-menu-item>
</el-menu> -->
</div>
<div class="header-right">
<div class="header-user-con">
<!-- 切换主题 -->
<div @click="handleChangeStyle()">
<el-tooltip content="切换主题" placement="bottom">
<i :class="globalTheme ? 'el-icon-moon' : 'el-icon-sunny'"></i>
</el-tooltip>
</div>
<!-- 用户头像 -->
<div class="user-avator">
<img src="@/assets/img/img.jpg"/>
</div>
<!-- 用户名下拉菜单 -->
<el-dropdown class="user-name" trigger="click" @command="handleCommand">
<span class="el-dropdown-link"> {{ username }} <i class="el-icon-caret-bottom"></i></span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item disabled>修改密码</el-dropdown-item>
<el-dropdown-item command="loginout">退出登录</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
</div>
<!-- 页面左侧二级菜单栏和主体内容区域部分 -->
<el-main>
<router-view></router-view>
</el-main>
</div>
</template>
<script>
import bus from "@/utils/bus";
export default {
data(){
return{
itemList: [ //
// { path: '/Home', title: '' },
{ path: '/test1', title: '一级菜单1' },
{ path: '/test2', title: '一级菜单2' },
{ path: '/test3', title: '一级菜单3' },
{ path: '/permission', title: '管理员权限' },
// { path: '/i18n', title: '' }
],
globalTheme: false,
}
},
computed: {
username(){
return localStorage.getItem('ms_username') || '';
},
toIndex(){ //
return '/' + this.$route.path.split('/')[1];
},
},
created() {
this.globalTheme = JSON.parse(localStorage.getItem('global_theme'));
bus.$emit('global_theme', this.globalTheme); // globalTheme
},
methods: {
handleSelect(path){ //
this.$router.push({
path: path
});
},
handleCommand(command){ //
if(command == 'loginout'){
localStorage.removeItem('ms_username');
this.$router.push({
path: '/Login'
});
}
},
handleChangeStyle(){ //
this.globalTheme = !this.globalTheme;
localStorage.setItem('global_theme', this.globalTheme); // globalTheme
bus.$emit('global_theme', this.globalTheme); // globalTheme
}
}
}
</script>
<style scoped>
.wrapper {
width: 100%;
height: 100%;
background: #f0f0f0;
}
.header {
position: relative;
box-sizing: border-box;
width: 100%;
height: 70px;
font-size: 22px;
}
.header .logo {
float: left;
margin-left: 60px;
margin-top: 17.5px;
height: 29px;
width: 160px;
vertical-align: middle;
}
/* --------------- 用户头像区域的样式 ---------------- */
.header-right {
float: right;
padding-right: 50px;
}
.header-user-con {
display: flex;
align-items: center;
justify-content: center;
height: 70px;
}
.user-avator {
margin-left: 20px;
}
.user-avator img {
display: block;
width: 40px;
height: 40px;
border-radius: 50%;
}
.user-name {
margin-left: 10px;
}
.el-dropdown-link {
cursor: pointer;
}
.el-dropdown-menu__item {
text-align: center;
}
/* --------------- 水平一级菜单栏的样式--------------------- */
.el-menu.el-menu--horizontal {
border-bottom: none !important;
float: left;
margin-left: 50px;
background: transparent;
}
.el-menu--horizontal > .el-menu-item.is-active {
/* border-bottom: 2px solid #3989fa;
color: #3989fa; */
font-weight: bold;
}
.el-menu--horizontal > .el-menu-item {
font-size: 16px;
margin: 0 15px;
}
</style>

View File

@ -0,0 +1,30 @@
export const messages = {
'zh': {
i18n: {
breadcrumb: '国际化产品',
tips: '通过切换语言按钮,来改变当前内容的语言。',
btn: '切换英文',
title1: '常用用法',
p1: '要是你把你的秘密告诉了风,那就别怪风把它带给树。',
p2: '没有什么比信念更能支撑我们度过艰难的时光了。',
p3: '只要能把自己的事做好,并让自己快乐,你就领先于大多数人了。',
title2: '组件插值',
info: 'Element组件需要国际化请参考 {action}。',
value: '文档'
}
},
'en': {
i18n: {
breadcrumb: 'International Products',
tips: 'Click on the button to change the current language. ',
btn: 'Switch Chinese',
title1: 'Common usage',
p1: "If you reveal your secrets to the wind you should not blame the wind for revealing them to the trees.",
p2: "Nothing can help us endure dark times better than our faith. ",
p3: "If you can do what you do best and be happy, you're further along in life than most people.",
title2: 'Component interpolation',
info: 'The default language of Element is Chinese. If you wish to use another language, please refer to the {action}.',
value: 'documentation'
}
}
}

View File

@ -0,0 +1,79 @@
<template>
<div id="LineECharts" :style="{ width: 'auto', height: '400px' }"></div>
</template>
<script>
export default {
name: 'LineECharts', // 线
data(){
return {
}
},
methods: {
drawLine(){
//
// let nowTime = new Date().toLocaleDateString().split('/').join('-');
// domecharts
let myChartOne = this.$echarts.init(document.getElementById('LineECharts'));
//
myChartOne.setOption({
title: {
text: '折线图堆叠'
},
tooltip: {
trigger: 'axis'
},
legend: {
data: ['邮件营销', '视频广告', '搜索引擎']
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
toolbox: {
feature: {
saveAsImage: {}
}
},
xAxis: {
type: 'category',
boundaryGap: false,
data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
},
yAxis: {
type: 'value'
},
series: [
{
name: '邮件营销',
type: 'line',
stack: '总量',
data: [120, 132, 101, 134, 90, 230, 210]
},
{
name: '视频广告',
type: 'line',
stack: '总量',
data: [356, 332, 301, 254, 290, 430, 510]
},
{
name: '搜索引擎',
type: 'line',
stack: '总量',
data: [820, 932, 901, 934, 1290, 1330, 1320]
}
]
});
window.onresize = () => { //
myChartOne.resize();
};
}
},
mounted() {
this.drawLine();
}
}
</script>

View File

@ -0,0 +1,49 @@
<template>
<div class="navMenu">
<label v-for="navMenu in navMenus">
<!--只有一级菜单-->
<el-menu-item v-if="!navMenu.children"
:index="navMenu.url"
:route="navMenu.url"
>
<!--图标-->
<i :class="navMenu.icon"></i>
<!--标题-->
<span slot="title">{{navMenu.title}}</span>
</el-menu-item>
<!--有多级菜单-->
<el-submenu v-if="navMenu.children"
:key="navMenu.url"
:index="navMenu.url"
>
<template slot="title">
<i :class="navMenu.icon"></i>
<span> {{navMenu.title}}</span>
</template>
<!--递归组件把遍历的值传回子组件完成递归调用-->
<nav-menu :navMenus="navMenu.children"></nav-menu>
</el-submenu>
</label>
</div>
</template>
<script>
export default {
name: 'NavMenu', //使
props: ['navMenus'], //
data() {
return {}
},
methods: {
handleSelect(key,keyPath){
console.log('1212')
console.log(key,keyPath)
}
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,96 @@
<template>
<div class="navMenu">
<el-menu
router
:default-active="$route.path"
class="el-menu-vertical-demo"
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b">
<label v-for="navMenu in navMenus">
<!--只有一级菜单-->
<el-menu-item v-if="!navMenu.children"
:index="navMenu.path"
:route="navMenu.path"
>
<!--图标-->
<i :class="navMenu.icon"></i>
<!--标题-->
<span slot="title">{{navMenu.title}}</span>
</el-menu-item>
<!--有多级菜单-->
<el-submenu v-if="navMenu.children"
:key="navMenu.path"
:index="navMenu.path"
>
<template slot="title">
<i :class="navMenu.icon"></i>
<span> {{navMenu.title}}</span>
</template>
<!--递归组件把遍历的值传回子组件完成递归调用-->
<nav-menu :navMenus="navMenu.children"></nav-menu>
</el-submenu>
</label>
</el-menu>
</div>
</template>
<script>
export default {
name: 'NavMenu', //使
props: ['navMenus'], //
data() {
return {}
},
computed: {
toIndex(){ //
return this.$route.path.split('/')[2];
}
},
methods: {
handleSelect(key,keyPath){
console.log('1212')
console.log(key,keyPath)
}
}
}
</script>
<style lang="scss" scoped>
/* 左侧菜单栏定位和位置大小设定 */
.sidebar {
display: block;
position: absolute;
left: 0;
top: 70px;
bottom: 0;
overflow-y: scroll;
}
.sidebar::-webkit-scrollbar {
width: 0;
}
.sidebar-el-menu {
width: 250px;
}
.sidebar > ul {
height: 100%;
}
/* 左侧二级菜单项的样式 */
.el-menu-item{
font-size: 14px !important;
padding-left: 35px !important;
}
/* 左侧二级菜单选中时的样式 */
.el-menu-item.is-active {
color: white !important;
background: #3989fa !important;
}
.el-menu-item, .el-submenu__title {
height: 50px !important;
line-height: 50px !important;
}
</style>

69
src/main.js Normal file
View File

@ -0,0 +1,69 @@
import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import ViewUI from 'view-design';
import 'view-design/dist/styles/iview.css';
import axios from 'axios';
import App from './App.vue';
import store from './store';
import router from './router/index.js';
import echarts from 'echarts';
import VueI18n from 'vue-i18n';
import { messages } from './components/common/i18n.js';
import { formatSeconds } from './utils/tools.js';
import 'babel-polyfill';
import './assets/css/main.css';
import './assets/css/theme.scss';
Vue.use(ElementUI);
Vue.use(ViewUI);
Vue.use(VueI18n);
const i18n = new VueI18n({
locale: 'zh',
messages
});
Vue.prototype.$axios = axios;
Vue.prototype.$echarts = echarts;
Vue.prototype.$formatSeconds = formatSeconds; // 全局使用该工具函数
Array.prototype.pushNoRepeat = function(){ // 往数组里添加不重复数据
for(var i=0; i<arguments.length; i++){
var ele = arguments[i];
if(this.indexOf(ele) == -1){
this.push(ele);
}
}
}
Vue.config.productionTip = false;
// 使用钩子函数对路由进行权限跳转
router.beforeEach((to, from, next) => {
document.title = `${to.meta.title} | 后台管理系统`;
const role = localStorage.getItem('ms_username');
if (!role && to.path !== '/Login') {
next('/Login');
} else if (to.meta.permission) { // 如果是管理员权限则可进入,这里只是简单的模拟管理员权限而已
role === 'admin' ? next() : next('/403');
} else {
// 简单的判断IE10及以下该组件不兼容
if (navigator.userAgent.indexOf('MSIE') > -1) {
Vue.prototype.$alert('vue-quill-editor组件不兼容IE10及以下浏览器请使用更高版本的浏览器查看', '浏览器不兼容通知', {
confirmButtonText: '确定'
});
} else {
next();
}
}
});
new Vue({
el: '#app',
router,
store,
i18n,
render: h => h(App)
});

33
src/page/403.vue Normal file
View File

@ -0,0 +1,33 @@
<template>
<div class="error-page">
<div class="error-code">4<span>0</span>3</div>
<div class="error-desc">啊哦~ 你没有权限访问该页面哦</div>
<div class="error-handle">
<router-link to="/">
<el-button type="primary" size="large">返回首页</el-button>
</router-link>
<el-button class="error-btn" type="primary" size="large" @click="goBack()">返回上一页</el-button>
</div>
</div>
</template>
<script>
export default {
data(){
return{
}
},
methods: {
goBack(){
this.$router.go(-1);
}
}
}
</script>
<style scoped>
.error-code{
color: #f02d2d;
}
</style>

33
src/page/404.vue Normal file
View File

@ -0,0 +1,33 @@
<template>
<div class="error-page">
<div class="error-code">4<span>0</span>4</div>
<div class="error-desc">啊哦~ 你所访问的页面不存在</div>
<div class="error-handle">
<router-link to="/">
<el-button type="primary" size="large">返回首页</el-button>
</router-link>
<el-button class="error-btn" type="primary" size="large" @click="goBack()">返回上一页</el-button>
</div>
</div>
</template>
<script>
export default {
data(){
return{
}
},
methods: {
goBack(){
this.$router.go(-1);
}
}
}
</script>
<style scoped>
.error-code{
color: #2d8cf0;
}
</style>

488
src/page/Home.vue Normal file
View File

@ -0,0 +1,488 @@
<template>
<div>
<el-card>
<div slot="header">
<Icon type="md-aperture" size="30" color="#2e71ea"/><span class="clearfix">今日头条</span>
<Dropdown style="margin-left:50px;">
<a href="javascript:void(0)">
<span>切换媒体</span><Icon size="20" type="ios-arrow-down" />
</a>
<DropdownMenu slot="list">
<DropdownItem>今日头条</DropdownItem>
<DropdownItem>广点通</DropdownItem>
<DropdownItem>快手</DropdownItem>
</DropdownMenu>
</Dropdown>
<Form ref="searchForm" :model="searchForm" inline class="search-form">
<FormItem prop="date">
<span>日期</span>
<el-select v-model="searchForm.date" filterable placeholder="请选择日期">
<el-option v-for="(item, index) in dateSelectList" :key="index" :value="item">{{ item }}</el-option>
</el-select>
</FormItem>
</Form>
<el-button class="programmaticBatchBtn">
<img src="@/assets/img/mg-icon-intelligence.gif"/>程序化批量
</el-button>
<el-button type="primary" icon="el-icon-plus" style="float:right;" size="small">新建广告计划</el-button>
</div>
<el-row :gutter="35" style="margin:0 auto; margin-bottom:20px;">
<el-col :span="6">
<el-card shadow="never" style="border-top: 4px solid rgb(58, 160, 255);">
<div class="colorCardsBody">
<span>投放中计划<i class="el-icon-d-arrow-right"></i></span>
<p>0</p>
</div>
</el-card>
</el-col>
<el-col :span="6">
<el-card shadow="never" style="border-top: 4px solid red;">
<div class="colorCardsBody">
<span>审核不通过计划<i class="el-icon-d-arrow-right"></i></span>
<p>0</p>
</div>
</el-card>
</el-col>
<el-col :span="6">
<el-card shadow="never" style="border-top: 4px solid rgb(250, 211, 55);">
<div class="colorCardsBody">
<span>预算不足计划<i class="el-icon-d-arrow-right"></i></span>
<p>0</p>
</div>
</el-card>
</el-col>
<el-col :span="6">
<el-card shadow="never" style="border-top: 4px solid rgb(78, 203, 115);">
<div class="colorCardsBody">
<span>托管中计划<i class="el-icon-d-arrow-right"></i></span>
<p>0</p>
</div>
</el-card>
</el-col>
</el-row>
<el-row :gutter="35" style="margin:0 auto; margin-bottom:20px;">
<el-col :span="24">
<div style="padding:28px 40px 0 40px;" class="dataOverview">
<div class="overview-list-item">
<p class="overview-list-text">总消耗</p>
<p class="overview-list-count">28871.28</p>
<p :class="setColor(-57.52)">-57.52%</p>
</div>
<div class="overview-list-item">
<p class="overview-list-text">激活数</p>
<p class="overview-list-count">194</p>
<p :class="setColor(-71.00)">-71.00%</p>
</div>
<div class="overview-list-item">
<p class="overview-list-text">激活成本</p>
<p class="overview-list-count">148.82</p>
<p :class="setColor(46.49)">46.49%</p>
</div>
<div class="overview-list-item">
<p class="overview-list-text">注册数</p>
<p class="overview-list-count">147</p>
<p :class="setColor(-75.34)">-75.34%</p>
</div>
<div class="overview-list-item">
<p class="overview-list-text">注册成本</p>
<p class="overview-list-count">196.4</p>
<p :class="setColor(72.22)">72.22%</p>
</div>
<div class="overview-list-item">
<p class="overview-list-text">付费数</p>
<p class="overview-list-count">23</p>
<p :class="setColor(-55.77)">-55.77%</p>
</div>
<div class="overview-list-item">
<p class="overview-list-text">付费成本</p>
<p class="overview-list-count">1255.27</p>
<p :class="setColor(-3.96)">-3.96%</p>
</div>
</div>
</el-col>
</el-row>
</el-card>
<el-card style="margin-top:30px;">
<div slot="header">
<span class="clearfix">效果总览</span>
<Form ref="searchForm" :model="searchForm" inline class="search-form-2">
<el-row :gutter="50">
<el-col :span="6">
<FormItem prop="mediaAccount">
<span>媒体账号</span>
<el-select v-model="searchForm.mediaAccount" filterable placeholder="请选择媒体账号">
<el-option value="全部媒体账号">全部媒体账号</el-option>
<el-option v-for="(item, index) in mediaAccountList" :key="index" :value="item">{{ item }}</el-option>
</el-select>
</FormItem>
</el-col>
<el-col :span="6">
<FormItem prop="application">
<span>应用</span>
<el-select v-model="searchForm.application" filterable placeholder="请选择应用">
<el-option v-for="(item, index) in applicationList" :key="index" :value="item">{{ item }}</el-option>
</el-select>
</FormItem>
</el-col>
<el-col :span="6">
<FormItem FormItem prop="mediaType">
<span>媒体</span>
<el-select v-model="searchForm.mediaType" filterable placeholder="请选择媒体">
<el-option v-for="(item, index) in mediaTypeList" :key="index" :value="item">{{ item }}</el-option>
</el-select>
</FormItem>
</el-col>
<el-col :span="6">
<FormItem prop="date2">
<span>日期</span>
<el-select v-model="searchForm.date2" filterable placeholder="请选择日期">
<el-option v-for="(item, index) in dateSelectList" :key="index" :value="item">{{ item }}</el-option>
</el-select>
</FormItem>
</el-col>
</el-row>
</Form>
</div>
<div>
<LineECharts></LineECharts>
</div>
</el-card>
<el-row :gutter="20">
<el-col :span="12">
<el-card style="margin-top:30px;">
<div slot="header">
<span class="clearfix">TOP广告</span>
<Form ref="searchFormTop" :model="searchFormTop" inline class="search-form-2">
<el-row :gutter="10">
<el-col :span="8">
<FormItem prop="applicationTop">
<el-select v-model="searchFormTop.applicationTop" filterable placeholder="请选择应用">
<el-option value="全部应用">全部应用</el-option>
<el-option v-for="(item, index) in applicationList" :key="index" :value="item">{{ item }}</el-option>
</el-select>
</FormItem>
</el-col>
<el-col :span="8">
<FormItem prop="mediaTypeTop">
<el-select v-model="searchFormTop.mediaTypeTop" filterable placeholder="请选择媒体">
<el-option v-for="(item, index) in mediaTypeList" :key="index" :value="item">{{ item }}</el-option>
</el-select>
</FormItem>
</el-col>
<el-col :span="8">
<FormItem prop="dateTop">
<el-select v-model="searchFormTop.dateTop" filterable placeholder="请选择日期">
<el-option v-for="(item, index) in dateSelectList" :key="index" :value="item">{{ item }}</el-option>
</el-select>
</FormItem>
</el-col>
</el-row>
</Form>
</div>
<div>
<el-table :data="tableDataTopAd" border>
<el-table-column type="index" label="序号" width="50" align="center"></el-table-column>
<el-table-column
v-for="(item, index) in columnTopAd" :key="index"
:prop="item.prop" :label="item.label"
align="center" :width="item.width ? item.width : ''"
:show-overflow-tooltip="item.prop == 'remark' ? true : false">
<template slot-scope="scope">
<span v-if="item.isSlot">
<span v-if="item.prop == 'planName'">
<el-tag type="success">{{ scope.row[item.prop] }}</el-tag>
</span>
</span>
<span v-else>{{ scope.row[item.prop] }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center">
<template slot-scope="scope">
<el-button type="text" size="small" @click="handleUpdate(scope.row, 1)"> 编辑 1 </el-button>
<el-button type="text" size="small" @click="handleDelete(scope.row, 1)"> 删除 1 </el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页组件 -->
<Pagination
:total="totalOne"
:page.sync="pageIndexOne"
:limit.sync="pageSizeOne"
@pagination="getTableDataOne"
></Pagination>
<div slot="footer" style="float:right; margin:10px 10px;">
<el-button type="text" size="20">查看详情<i class="el-icon-d-arrow-right"></i></el-button>
</div>
</div>
</el-card>
</el-col>
<el-col :span="12">
<el-card style="margin-top:30px;">
<div slot="header">
<span class="clearfix">TOP创意</span>
<Form ref="searchFormTop" :model="searchFormTop" inline class="search-form-2">
<el-row :gutter="10">
<el-col :span="8">
<FormItem prop="applicationTop2">
<el-select v-model="searchFormTop.applicationTop2" filterable placeholder="请选择应用">
<el-option value="全部应用">全部应用</el-option>
<el-option v-for="(item, index) in applicationList" :key="index" :value="item">{{ item }}</el-option>
</el-select>
</FormItem>
</el-col>
<el-col :span="8">
<FormItem prop="mediaTypeTop2">
<el-select v-model="searchFormTop.mediaTypeTop2" filterable placeholder="请选择媒体">
<el-option v-for="(item, index) in mediaTypeList" :key="index" :value="item">{{ item }}</el-option>
</el-select>
</FormItem>
</el-col>
<el-col :span="8">
<FormItem prop="dateTop2">
<el-select v-model="searchFormTop.dateTop2" filterable placeholder="请选择日期">
<el-option v-for="(item, index) in dateSelectList" :key="index" :value="item">{{ item }}</el-option>
</el-select>
</FormItem>
</el-col>
</el-row>
</Form>
</div>
<div>
<el-table :data="tableDataTopIdea" border>
<el-table-column type="index" label="序号" width="50" align="center"></el-table-column>
<el-table-column
v-for="(item, index) in columnTopIdea" :key="index"
:prop="item.prop" :label="item.label"
align="center" :width="item.width ? item.width : ''"
:show-overflow-tooltip="item.prop == 'remark' ? true : false">
<template slot-scope="scope">
<span v-if="item.isSlot">
<span v-if="item.prop == 'planName'">
<el-tag type="success">{{ scope.row[item.prop] }}</el-tag>
</span>
</span>
<span v-else>{{ scope.row[item.prop] }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center">
<template slot-scope="scope">
<el-button type="text" size="small" @click="handleUpdate(scope.row, 2)"> 编辑 2 </el-button>
<el-button type="text" size="small" @click="handleDelete(scope.row, 2)"> 删除 2 </el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页组件 -->
<Pagination
:total="totalTwo"
:page.sync="pageIndexTwo"
:limit.sync="pageSizeTwo"
@pagination="getTableDataTwo"
></Pagination>
<div class="blankContent"></div>
</div>
</el-card>
</el-col>
</el-row>
</div>
</template>
<script>
import Pagination from '@/components/common/Pagination';
import LineECharts from '@/components/home/LineECharts';
export default {
name: 'Home', //
data(){
return{
name: localStorage.getItem('ms_username'),
dateSelectList: ['今天','昨天','过去7天','过去30天','本周','上周','本月','上月'], //
mediaAccountList: ['媒体账号1','媒体账号2','媒体账号3','媒体账号4'], //
applicationList: ['应用1','应用2','应用3','应用4','应用5'], //
mediaTypeList: ['今日头条','广点通','快手'], //
searchForm:{ //
date: "",
date2: "",
mediaAccount: "",
application: "",
mediaType: ""
},
searchFormTop:{ // TOP广TOP
applicationTop: "", // TOP广
mediaTypeTop: "",
dateTop: "",
applicationTop2: "", // TOP
mediaTypeTop2: "",
dateTop2: "",
},
columnTopAd: [ // TOP广
{ label: '计划名称', prop: 'planName', isSlot: true},
{ label: '消耗', prop: 'expend'},
{ label: '消耗变化率', prop: 'expendRate'},
{ label: '转化数', prop: 'TransformNumber'},
{ label: '转化率', prop: 'TransformRate'},
],
tableDataTopAd: [], // TOP广
columnTopIdea: [ // TOP
],
tableDataTopIdea: [], // TOP
totalOne: 0, // TOP广
pageIndexOne: 1,
pageSizeOne: 20,
totalTwo: 0, // TOP
pageIndexTwo: 1,
pageSizeTwo: 20,
}
},
components: {
Pagination,
LineECharts
},
created() {
},
methods: {
setColor(dataVal){
if(dataVal > 0){
return 'overview-list-trend-up';
}else{
return 'overview-list-trend-down';
}
},
getTableDataOne(){
console.log('TOP广告的分页触发');
},
getTableDataTwo(){
console.log('TOP创意的分页触发');
},
handleUpdate(row, type){
if(type == 1){ // TOP广
}else{ // TOP
}
},
handleDelete(row, type){
if(type == 1){ // TOP广
}else{ // TOP
}
}
}
}
</script>
<style scoped>
.el-row {
margin-bottom: 20px;
}
/* 卡片标题字体的样式 */
.clearfix{
padding-left: 5px;
font-size: 22px;
font-weight: bold;
}
/* 四个彩色卡片的相关样式 */
.colorCardsBody{
padding: 18px 40px;
}
.colorCardsBody span{
font-size: 16px;
color: #515a6e;
}
.colorCardsBody p{
font-family: Roboto-Medium !important;
padding-top: 15px;
font-size: 18px;
font-weight: 800;
}
/* 数据总览区域的整体样式设置 */
.dataOverview{
padding: 0 30px;
display: flex;
justify-content: space-between;
align-items: center;
}
/* 数据总览里的每一条信息项 */
.overview-list-item {
padding: 0 25px;
border-left: 1px solid rgba(220,222,226,.5);
flex: 1;
}
.overview-list-item:first-child {
border: none;
}
/* 数据总览里每条信息项的文本部分 */
.overview-list-text {
color: #515a6e;
font-size: 14px;
margin-bottom: 24px;
}
.overview-list-count {
color: #17233d;
font-weight: 700;
margin-bottom: 16px;
font-size: 16px;
}
.overview-list-trend-up {
font-size: 14px;
color: blue;
}
.overview-list-trend-down {
font-size: 14px;
color: red;
}
.programmaticBatchBtn{ /* 程序化批量的按钮样式 */
float: right;
padding: 4px 11px 3px 11px;
margin-left: 20px;
margin-right: 50px;
font-size: 14px;
color: rgb(255, 255, 255);
background-color: rgb(0, 182, 151);
}
.programmaticBatchBtn img{ /* 程序化批量按钮上的动图标 */
width: 24px;
display: inline-block;
vertical-align: middle; /* 让该图标在 Y 轴上居中 */
}
.search-form{ /* 日期筛选控件的样式 */
display: inline;
margin-left: 20px;
margin-right: 8px;
float: right;
}
.search-form span,.search-form-2 span{ /* 筛选控件的前面字体样式 */
margin-right: 10px;
font-weight: bold;
}
.search-form-2{ /* “效果总览” 卡片里的筛选控件定位设置 */
margin-top:30px;
margin-bottom: -40px;
margin-left: 30px;
}
.blankContent{ /* TOP 创意卡片底部空白部分,为了和 TOP 广告底部对齐 */
width: auto;
height: 40px;
}
</style>

107
src/page/Login.vue Normal file
View File

@ -0,0 +1,107 @@
<template>
<div class="login-wrap">
<div class="ms-login">
<div class="ms-title">欢迎登录</div>
<el-form :model="param" :rules="rules" ref="login" label-width="0px" class="ms-content">
<el-form-item prop="username">
<el-input v-model="param.username" placeholder="输入账号">
<el-button slot="prepend" icon="el-icon-user"></el-button>
</el-input>
</el-form-item>
<el-form-item prop="password" style="margin-top: 25px">
<el-input type="password" placeholder="登录密码" v-model="param.password" @keyup.enter.native="submitForm()">
<el-button slot="prepend" icon="el-icon-lock"></el-button>
</el-input>
</el-form-item>
<div class="login-btn">
<el-button type="primary" @click="submitForm()">登录</el-button>
<span>账号密码随便填写 admin 是管理员其他为普通用户</span>
</div>
</el-form>
</div>
</div>
</template>
<script>
import { loginApi } from '@/api/login';
export default {
name: 'Login', //
data(){
return{
param: {
username: 'admin',
password: '123456'
},
rules: {
username: [{ required: true, message: '账号不能为空', trigger: 'blur' }],
password: [{ required: true, message: '密码不能为空', trigger: 'blur' }]
}
}
},
created() {
this.getType();
},
methods: {
getType() {
let datas = {
telephone: '13088888888',
typeCode: 2
};
loginApi(datas).then((res) => {
console.log('c', res);
});
},
submitForm() {
this.$refs.login.validate((valid) => {
if (valid) {
this.$message.success('登录成功');
localStorage.setItem('ms_username', this.param.username);
this.$router.push('/');
} else {
this.$message.error('请输入账号和密码');
console.log('error submit!!');
return false;
}
});
}
}
}
</script>
<style scoped>
.login-wrap {
position: absolute;
width: 100%;
height: 100%;
background: url('../assets/img/newlogin-bg.jpg');
}
.ms-title {
width: 100%;
text-align: center;
font-size: 22px;
margin: 25px 0px 15px;
}
.ms-login {
position: relative;
width: 450px;
height: 335px;
max-width: 90%;
margin: 275px auto;
border-radius: 5px;
background: white;
overflow: hidden;
}
.ms-content {
padding: 30px 30px;
}
.login-btn {
margin-top: 10%;
}
.login-btn button {
width: 100%;
height: 36px;
text-align: center;
margin-bottom: 10px;
}
</style>

41
src/page/Permission.vue Normal file
View File

@ -0,0 +1,41 @@
<template>
<div>
<div class="crumbs">
<el-breadcrumb separator="/">
<el-breadcrumb-item><i class="el-icon-warning"></i> 权限测试</el-breadcrumb-item>
</el-breadcrumb>
</div>
<div class="container">
<h1>管理员权限页面</h1>
<p>只有用 admin 账号登录的才拥有管理员权限才能进到这个页面其他账号想进来都会跳到403页面重新用管理员账号登录才有权限</p>
<p>想尝试一下<router-link to="/Login" class="logout">退出登录</router-link>便</p>
</div>
</div>
</template>
<script>
export default {
data(){
return{
}
}
}
</script>
<style scoped>
h1{
text-align: center;
margin: 30px 0;
}
p{
line-height: 30px;
margin-bottom: 10px;
text-indent: 2em;
}
.logout{
color: #409EFF;
}
</style>

95
src/page/test1/index.vue Normal file
View File

@ -0,0 +1,95 @@
<template>
<div>
<!-- 一级菜单下面所拥有的二级菜单 -->
<el-aside>
<SideMenu :navMenus="leftMenus"></SideMenu>
<!-- <el-aside>
<el-menu
router
:default-active="$route.path"
class="el-menu-vertical-demo"
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b">
<home-left :navMenus="leftMenus"/>
</el-menu>
</el-aside> -->
</el-aside>
<!-- 以及二级菜单所对应的页面 -->
<el-main>
<router-view></router-view>
</el-main>
</div>
</template>
<script>
import SideMenu from '@/components/sidemenu/SideMenu';
export default {
components: {
SideMenu
},
data(){
return{
itemList: [
{ path: 'test1-1', title: '二级菜单1-1' ,
children:[{path: 'test6-6', title: '二级菜单6-6' ,}]
},
{ path: 'test1-2', title: '二级菜单1-2' },
{ path: 'test1-3', title: '二级菜单1-3' },
{ path: 'test1-4', title: '二级菜单1-4' },
{ path: 'test1-5', title: '二级菜单1-5' }
],
leftMenus: [
{
title : '分析',
path: 'index',
icon : 'el-icon-user-solid',
},
{
title : '控制中心',
path: 'ControlCenter',
icon : 'el-icon-s-goods',
children : [
{
title : '通用',
path: 'test1-2',
icon : 'el-icon-s-goods',
children : [
{
title : '关于本机',
path: 'AboutMachine',
icon : 'bars',
},
{
title : '网络',
path: 'network',
icon : 'tool',
},
{
title : 'VPN',
path: 'VPN',
icon : 'tool',
},
{
title : '自定义操作',
path: 'CustomOperations',
icon : 'tool',
},
{
title : '健康检测',
path: 'HealthCheck',
icon : 'tool',
}
]
},
]
},
],
}
}
}
</script>

113
src/page/test1/test1-1.vue Normal file
View File

@ -0,0 +1,113 @@
<template>
<div class="content-box">
<div class="container">
<p>主题页面 1 - 1</p>
<div class="table-container">
<el-table ref="Table1"
:data="list"
style="width: 100%;"
@selection-change="handleSelectionChange"
border>
<el-table-column type="selection" align="center"></el-table-column>
<el-table-column type="index" label="序号" align="center" width="50"></el-table-column>
<el-table-column label="姓名" align="center">
<template slot-scope="scope">{{scope.row.userName}}</template>
</el-table-column>
<el-table-column label="性别" align="center">
<template slot-scope="scope">{{scope.row.sex}}</template>
</el-table-column>
<el-table-column label="年龄" align="center">
<template slot-scope="scope">{{scope.row.age}}</template>
</el-table-column>
<el-table-column label="民族" align="center">
<template slot-scope="scope">{{scope.row.nation}}</template>
</el-table-column>
<el-table-column label="学历" align="center">
<template slot-scope="scope">{{scope.row.education}}</template>
</el-table-column>
<el-table-column label="操作" width="120" align="center" fixed="right">
<template slot-scope="scope">
<el-button type="text"
@click="handleUpdate(scope.$index, scope.row)">编辑</el-button>
<el-button type="text"
@click="handleDelete(scope.$index, scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="pagination-area">
<el-pagination
background
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
layout="total, sizes, prev, pager, next, jumper"
:current-page.sync="listQuery.pageNum"
:page-size="listQuery.pageSize"
:page-sizes="[10,20,50]"
:total="total">
</el-pagination>
</div>
</div>
</div>
</template>
<script>
import { testApi } from '@/api/test';
const defaultListQuery = {
pageNum: 1,
pageSize: 10,
keyword: ""
};
export default {
data(){
return{
listQuery: Object.assign({}, defaultListQuery),
list: [],
total: 0,
listLoading: true,
selectedList: [],
}
},
created() {
this.getList();
},
methods:{
// handleResetSearch() { //
// this.listQuery = Object.assign({}, defaultListQuery); //
// this.getList(); //
// },
// handleSearchList() { //
// this.listQuery.pageNum = 1;
// this.getList();
// },
handleSizeChange(val) { //
this.listQuery.pageNum = 1;
this.listQuery.pageSize = val;
this.getList();
},
handleCurrentChange(val) { //
this.listQuery.pageNum = val;
this.getList();
},
getList() { //
this.listLoading = true;
testApi(this.listQuery).then(res => {
this.listLoading = false;
this.list = res.data.list;
this.total = res.data.total;
}).catch(err => {
this.listLoading = false;
});
},
handleSelectionChange(val){ //
this.selectedList = val;
},
}
}
</script>

View File

@ -0,0 +1,28 @@
<template>
<div class="content-box">
<div class="container">
<p>主体页面 1 - 2 </p>
<div class="test-div">
<i class="el-icon-edit"></i>
<i class="el-icon-share"></i>
<i class="el-icon-delete"></i>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return{
}
}
}
</script>
<style>
.test-div i{
font-size: 25px;
}
</style>

View File

@ -0,0 +1,24 @@
<template>
<div class="content-box">
<div class="container">
<p>主体页面 1 - 3 </p>
<div class="test-div">
<el-radio-group v-model="radio">
<el-radio :label="1">选项一</el-radio>
<el-radio :label="2">选项二</el-radio>
<el-radio :label="3">选项三</el-radio>
</el-radio-group>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return{
radio: 1
}
}
}
</script>

View File

@ -0,0 +1,21 @@
<template>
<div class="content-box">
<div class="container">
<p>主体页面 1 - 4 </p>
<div class="test-div">
<span>自定义初始值 {{ value }}</span>
<el-slider v-model="value" style="width:50%;"></el-slider>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return{
value: 25
}
}
}
</script>

View File

@ -0,0 +1,24 @@
<template>
<div class="content-box">
<div class="container">
<p>主体页面 1 - 5 </p>
<div class="test-div">
<el-tag effect="dark">标签一</el-tag>
<el-tag type="success">标签二</el-tag>
<el-tag type="info">标签三</el-tag>
<el-tag type="warning" effect="dark">标签四</el-tag>
<el-tag type="danger" effect="dark">标签五</el-tag>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return{
}
}
}
</script>

113
src/page/test1/test6-6.vue Normal file
View File

@ -0,0 +1,113 @@
<template>
<div class="content-box">
<div class="container">
<p>主题页面 1 - 1</p>
<div class="table-container">
<el-table ref="Table1"
:data="list"
style="width: 100%;"
@selection-change="handleSelectionChange"
border>
<el-table-column type="selection" align="center"></el-table-column>
<el-table-column type="index" label="序号" align="center" width="50"></el-table-column>
<el-table-column label="姓名1111111" align="center">
<template slot-scope="scope">{{scope.row.userName}}</template>
</el-table-column>
<el-table-column label="性别" align="center">
<template slot-scope="scope">{{scope.row.sex}}</template>
</el-table-column>
<el-table-column label="年龄" align="center">
<template slot-scope="scope">{{scope.row.age}}</template>
</el-table-column>
<el-table-column label="民族" align="center">
<template slot-scope="scope">{{scope.row.nation}}</template>
</el-table-column>
<el-table-column label="学历" align="center">
<template slot-scope="scope">{{scope.row.education}}</template>
</el-table-column>
<el-table-column label="操作" width="120" align="center" fixed="right">
<template slot-scope="scope">
<el-button type="text"
@click="handleUpdate(scope.$index, scope.row)">编辑</el-button>
<el-button type="text"
@click="handleDelete(scope.$index, scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="pagination-area">
<el-pagination
background
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
layout="total, sizes, prev, pager, next, jumper"
:current-page.sync="listQuery.pageNum"
:page-size="listQuery.pageSize"
:page-sizes="[10,20,50]"
:total="total">
</el-pagination>
</div>
</div>
</div>
</template>
<script>
import { testApi } from '@/api/test';
const defaultListQuery = {
pageNum: 1,
pageSize: 10,
keyword: ""
};
export default {
data(){
return{
listQuery: Object.assign({}, defaultListQuery),
list: [],
total: 0,
listLoading: true,
selectedList: [],
}
},
created() {
this.getList();
},
methods:{
// handleResetSearch() { //
// this.listQuery = Object.assign({}, defaultListQuery); //
// this.getList(); //
// },
// handleSearchList() { //
// this.listQuery.pageNum = 1;
// this.getList();
// },
handleSizeChange(val) { //
this.listQuery.pageNum = 1;
this.listQuery.pageSize = val;
this.getList();
},
handleCurrentChange(val) { //
this.listQuery.pageNum = val;
this.getList();
},
getList() { //
this.listLoading = true;
testApi(this.listQuery).then(res => {
this.listLoading = false;
this.list = res.data.list;
this.total = res.data.total;
}).catch(err => {
this.listLoading = false;
});
},
handleSelectionChange(val){ //
this.selectedList = val;
},
}
}
</script>

30
src/page/test2/index.vue Normal file
View File

@ -0,0 +1,30 @@
<template>
<div>
<el-aside>
<SideMenu :itemList='itemList'></SideMenu>
</el-aside>
<el-main>
<router-view></router-view>
</el-main>
</div>
</template>
<script>
import SideMenu from '@/components/sidemenu/SideMenu';
export default {
components: {
SideMenu
},
data(){
return{
itemList: [
{ path: 'test2-1', title: '二级菜单2-1' },
{ path: 'test2-2', title: '二级菜单2-2' },
{ path: 'test2-3', title: '二级菜单2-3' }
]
}
},
}
</script>

View File

@ -0,0 +1,32 @@
<template>
<div class="content-box">
<div class="container">
<p>主体页面 2 - 1 </p>
<div class="test-div">
<el-steps :active="active" finish-status="success" style="width:50%;">
<el-step title="步骤 1"></el-step>
<el-step title="步骤 2"></el-step>
<el-step title="步骤 3"></el-step>
</el-steps>
<el-button @click="next()" type="primary">下一步</el-button>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return{
active: 0
}
},
methods: {
next() {
if (this.active++ > 2) {
this.active = 0;
}
}
}
}
</script>

102
src/page/test2/test2-2.vue Normal file
View File

@ -0,0 +1,102 @@
<template>
<div class="content-box">
<div class="container">
<p>主体页面 2 - 2 </p>
<div class="table-container">
<el-table ref="Table2"
:data="list"
style="width: 100%;"
show-overflow-tooltip="true"
@selection-change="handleSelectionChange"
border>
<el-table-column type="selection" align="center"></el-table-column>
<el-table-column type="index" label="序号" align="center" width="50"></el-table-column>
<el-table-column label="人员ID" align="center">
<template slot-scope="scope">{{scope.row.PersonID}}</template>
</el-table-column>
<el-table-column label="人员姓名" align="center">
<template slot-scope="scope">{{scope.row.FullName}}</template>
</el-table-column>
<el-table-column label="学历" align="center">
<template slot-scope="scope">{{scope.row.Degree}}</template>
</el-table-column>
<el-table-column label="毕业院校" align="center">
<template slot-scope="scope">{{scope.row.University}}</template>
</el-table-column>
<el-table-column label="专业" align="center">
<template slot-scope="scope">{{scope.row.Major}}</template>
</el-table-column>
<el-table-column label="入校时间" align="center">
<template slot-scope="scope">{{scope.row.AdmissionTime}}</template>
</el-table-column>
<el-table-column label="毕业时间" align="center">
<template slot-scope="scope">{{scope.row.GraduationTime}}</template>
</el-table-column>
<el-table-column label="截止日期" align="center">
<template slot-scope="scope">{{scope.row.EndDate}}</template>
</el-table-column>
<el-table-column label="操作" width="120" align="center" fixed="right">
<template slot-scope="scope">
<el-button type="text"
@click="handleUpdate(scope.$index, scope.row)">编辑</el-button>
<el-button type="text"
@click="handleDelete(scope.$index, scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
<!-- 分页组件 -->
<Pagination
:total="total"
:page.sync="listQuery.pageNum"
:limit.sync="listQuery.pageSize"
@pagination="getList"
></Pagination>
</div>
</div>
</template>
<script>
import Pagination from '@/components/common/Pagination';
import { testApi } from '@/api/test';
const defaultListQuery = {
pageNum: 1,
pageSize: 10,
keyword: ""
};
export default {
data(){
return{
listQuery: Object.assign({}, defaultListQuery),
list: [],
total: 0,
listLoading: true,
selectedList: [],
}
},
components: {
Pagination
},
created() {
this.getList();
},
methods:{
getList() { //
this.listLoading = true;
testApi(this.listQuery).then(res => {
this.listLoading = false;
this.list = res.data.list;
this.total = res.data.total;
});
},
handleSelectionChange(val){ //
this.selectedList = val;
},
}
}
</script>

View File

@ -0,0 +1,39 @@
<template>
<div class="content-box">
<div class="container">
<p>主体页面 2 - 3 </p>
<div class="test-div" style="width:400px;">
<el-carousel height="150px" class="customize-carousel">
<el-carousel-item v-for="item in 4" :key="item">
<h3>{{ item }}</h3>
</el-carousel-item>
</el-carousel>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return{
}
},
}
</script>
<style lang="scss">
.customize-carousel .el-carousel__item h3 {
color: #475669;
font-size: 16px;
line-height: 150px;
margin: 0 50%;
}
.customize-carousel .el-carousel__item:nth-child(2n) {
background-color: #99a9bf;
}
.customize-carousel .el-carousel__item:nth-child(2n+1) {
background-color: #d3dce6;
}
</style>

29
src/page/test3/index.vue Normal file
View File

@ -0,0 +1,29 @@
<template>
<div>
<el-aside>
<SideMenu :itemList="itemList"></SideMenu>
</el-aside>
<el-main>
<router-view></router-view>
</el-main>
</div>
</template>
<script>
import SideMenu from '@/components/sidemenu/SideMenu';
export default {
components: {
SideMenu
},
data(){
return {
itemList: [
{ path: 'test3-1', title: '二级菜单3-1' },
{ path: 'test3-2', title: '二级菜单3-2' }
]
}
}
}
</script>

View File

@ -0,0 +1,78 @@
<template>
<div class="content-box" >
<div class="container">
<p>主体页面 3 - 1 </p>
<div class="test-div">
<el-tree
:data="treeData"
show-checkbox
node-key="id"
:props="defaultProps">
</el-tree>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return{
treeData: [
{
id: 1,
label: '一级 1',
children: [
{
id: 4,
label: '二级 1-1',
children: [
{
id: 9,
label: '三级 1-1-1'
},
{
id: 10,
label: '三级 1-1-2'
}
]
}
]
},
{
id: 2,
label: '一级 2',
children: [
{
id: 5,
label: '二级 2-1'
},
{
id: 6,
label: '二级 2-2'
}
]
},
{
id: 3,
label: '一级 3',
children: [
{
id: 7,
label: '二级 3-1'
},
{
id: 8,
label: '二级 3-2'
}
]
}
],
defaultProps: {
children: 'children',
label: 'label'
}
}
}
}
</script>

View File

@ -0,0 +1,42 @@
<template>
<div class="content-box">
<div class="container">
<p>主题页面 3 - 2</p>
<div class="test-div">
<el-alert
title="成功提示的文案"
type="success"
:closable="false"
center
show-icon>
</el-alert>
<el-alert
title="消息提示的文案"
type="info"
show-icon>
</el-alert>
<el-alert
title="警告提示的文案"
type="warning"
close-text="好的">
</el-alert>
<el-alert
title="错误提示的文案"
type="error"
description="文字说明文字说明文字说明文字说明文字说明文字说明"
show-icon>
</el-alert>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return{
}
}
}
</script>

180
src/router/index.js Normal file
View File

@ -0,0 +1,180 @@
import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter);
const originalPush = VueRouter.prototype.push;
VueRouter.prototype.push = function push(location) {
return originalPush.call(this, location).catch(err => err);
}
export default new VueRouter({
routes: [
{
path: '/', // 程序启动默认路由
component: () => import('@/components/common/Whole.vue'),
meta: { title: '整体页面布局' },
redirect: '/test1', // 重定向到首页
children: [
// {
// path: '/Home',
// component: () => import('@/page/Home.vue'),
// meta: { title: '首页' }
// },
{
path: '/test1',
component: () => import('@/page/test1/index.vue'),
meta: { title: '一级菜单1' },
redirect: '/test1/test1-1', // 该配置是若点击选择一级菜单时,默认选中并跳转到该一级菜单下的第一个二级菜单
children:[
{
path: 'test1-1',
component: () => import('@/page/test1/test1-1.vue'),
meta: { title: '二级菜单1-1' },
},
{
path: 'test1-2',
component: () => import('@/page/test1/test1-2.vue'),
meta: { title: '二级菜单1-2' },
},
{
path: 'test1-3',
component: () => import('@/page/test1/test1-3.vue'),
meta: { title: '二级菜单1-3' },
},
{
path: 'test1-4',
component: () => import('@/page/test1/test1-4.vue'),
meta: { title: '二级菜单1-4' },
},
{
path: 'test1-5',
component: () => import('@/page/test1/test1-5.vue'),
meta: { title: '二级菜单1-5' },
},
{
path: 'index',
meta: { title: '分析' },
component: () => import ('@/views/index.vue')
},
{
path: 'AboutMachine',
name: 'AboutMachine',
meta: {
title: '关于本机'
},
component: () =>
import ('@/views/general/AboutMachine.vue'),
}, {
path: 'network',
name: 'network',
meta: {
title: '网络'
},
component: () =>
import ('@/views/general/network.vue'),
}, {
path: 'VPN',
name: 'VPN',
meta: {
title: 'VPN'
},
component: () =>
import ('@/views/general/VPN.vue'),
}, {
path: 'CustomOperations',
name: 'CustomOperations',
meta: {
title: '自定义操作'
},
component: () =>
import ('@/views/general/CustomOperations.vue'),
}, {
path: 'HealthCheck',
name: 'HealthCheck',
meta: {
title: '健康检测'
},
component: () =>
import ('@/views/general/HealthCheck.vue'),
}
]
},
{
path: '/test2',
component: () => import('@/page/test2/index.vue'),
meta: { title: '一级菜单2' },
redirect: '/test2/test2-1', // 该配置是若点击选择父目录时,默认选中该父目录下的子路径页面
children:[
{
path: 'test2-1',
component: () => import('@/page/test2/test2-1.vue'),
meta: { title: '二级菜单2-1' },
},
{
path: 'test2-2',
component: () => import('@/page/test2/test2-2.vue'),
meta: { title: '二级菜单2-2' },
},
{
path: 'test2-3',
component: () => import('@/page/test2/test2-3.vue'),
meta: { title: '二级菜单2-3' },
},
]
},
{
path: '/test3',
component: () => import('@/page/test3/index.vue'),
meta: { title: '一级菜单3' },
redirect: '/test3/test3-1',
children:[
{
path: 'test3-1',
component: () => import('@/page/test3/test3-1.vue'),
meta: { title: '二级菜单3-1' }
},
{
path: 'test3-2',
component: () => import('@/page/test3/test3-2.vue'),
meta: { title: '二级菜单3-2' }
},
]
},
{
path: '/i18n', // 国际化组件
component: () => import('@/components/common/I18n.vue'),
meta: { title: '国际化' }
},
{
path: '/permission', // 权限页面
component: () => import('@/page/Permission.vue'),
meta: {
title: '权限测试',
permission: true
}
},
{
path: '/404',
component: () => import('@/page/404.vue'),
meta: { title: '404' }
},
{
path: '/403',
component: () => import('@/page/403.vue'),
meta: { title: '403' }
},
]
},
{
path: '/Login', // 登录页面
component: () => import('@/page/Login.vue'),
meta: { title: '登录' }
},
{
path: '*',
redirect: '/404'
}
]
});

19
src/store/index.js Normal file
View File

@ -0,0 +1,19 @@
import Vue from 'vue';
import Vuex from 'vuex';
import Cookies from 'js-cookie';
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
authToken: Cookies.get('authToken') || ''
},
mutations: {
},
actions: {
}
});
export default store;

3
src/utils/bus.js Normal file
View File

@ -0,0 +1,3 @@
import Vue from 'vue'
const bus = new Vue() // 使用 Event Bus
export default bus

34
src/utils/request.js Normal file
View File

@ -0,0 +1,34 @@
import axios from 'axios';
import store from '@/store/index.js';
import { Message } from 'element-ui';
// 创建 axios 实例
const service = axios.create({
baseURL: 'https://api.example.com',
// withCredentials: true,
timeout: 60000
});
// 请求拦截器
service.interceptors.request.use(config => {
config.headers['authToken'] = store.state.authToken;
config.headers['ms_username'] = localStorage.getItem('ms_username');
return config;
}, error => {
console.log('request error',error);
return Promise.reject(error);
});
// 响应拦截器
service.interceptors.response.use(response => {
return response;
}, error => {
console.log('response error', error);
Message({
message: error.message,
type: 'error'
});
return Promise.reject(error);
});
export default service;

58
src/utils/scroll-to.js Normal file
View File

@ -0,0 +1,58 @@
Math.easeInOutQuad = function(t, b, c, d) {
t /= d / 2
if (t < 1) {
return c / 2 * t * t + b
}
t--
return -c / 2 * (t * (t - 2) - 1) + b
}
// requestAnimationFrame for Smart Animating http://goo.gl/sx5sts
var requestAnimFrame = (function() {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60) }
})()
/**
* Because it's so fucking difficult to detect the scrolling element, just move them all
* @param {number} amount
*/
function move(amount) {
document.documentElement.scrollTop = amount
document.body.parentNode.scrollTop = amount
document.body.scrollTop = amount
}
function position() {
return document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop
}
/**
* @param {number} to
* @param {number} duration
* @param {Function} callback
*/
export function scrollTo(to, duration, callback) {
const start = position()
const change = to - start
const increment = 20
let currentTime = 0
duration = (typeof (duration) === 'undefined') ? 500 : duration
var animateScroll = function() {
// increment the time
currentTime += increment
// find the value with the quadratic in-out easing function
var val = Math.easeInOutQuad(currentTime, start, change, duration)
// move the document.body
move(val)
// do the animation unless its over
if (currentTime < duration) {
requestAnimFrame(animateScroll)
} else {
if (callback && typeof (callback) === 'function') {
// the animation is done so lets callback
callback()
}
}
}
animateScroll()
}

324
src/utils/tools.js Normal file
View File

@ -0,0 +1,324 @@
export const forEach = (arr, fn) => {
if (!arr.length || !fn) return
let i = -1
let len = arr.length
while (++i < len) {
let item = arr[i]
fn(item, i, arr)
}
}
/**
* @param {Array} arr1
* @param {Array} arr2
* @description 得到两个数组的交集, 两个数组的元素为数值或字符串
*/
export const getIntersection = (arr1, arr2) => {
let len = Math.min(arr1.length, arr2.length)
let i = -1
let res = []
while (++i < len) {
const item = arr2[i]
if (arr1.indexOf(item) > -1) res.push(item)
}
return res
}
/**
* @param {Array} arr1
* @param {Array} arr2
* @description 得到两个数组的并集, 两个数组的元素为数值或字符串
*/
export const getUnion = (arr1, arr2) => {
return Array.from(new Set([...arr1, ...arr2]))
}
/**
* @param {Array} target 目标数组
* @param {Array} arr 需要查询的数组
* @description 判断要查询的数组是否至少有一个元素包含在目标数组中
*/
export const hasOneOf = (targetarr, arr) => {
return targetarr.some(_ => arr.indexOf(_) > -1)
}
/**
* @param {String|Number} value 要验证的字符串或数值
* @param {*} validList 用来验证的列表
*/
export function oneOf (value, validList) {
for (let i = 0; i < validList.length; i++) {
if (value === validList[i]) {
return true
}
}
return false
}
/**
* @param {Number} timeStamp 判断时间戳格式是否是毫秒
* @returns {Boolean}
*/
const isMillisecond = timeStamp => {
const timeStr = String(timeStamp)
return timeStr.length > 10
}
/**
* @param {Number} timeStamp 传入的时间戳
* @param {Number} currentTime 当前时间时间戳
* @returns {Boolean} 传入的时间戳是否早于当前时间戳
*/
const isEarly = (timeStamp, currentTime) => {
return timeStamp < currentTime
}
/**
* @param {Number} num 数值
* @returns {String} 处理后的字符串
* @description 如果传入的数值小于10即位数只有1位则在前面补充0
*/
const getHandledValue = num => {
return num < 10 ? '0' + num : num
}
/**
* @param {Number} timeStamp 传入的时间戳
* @param {Number} startType 要返回的时间字符串的格式类型传入'year'则返回年开头的完整时间
*/
const getDate = (timeStamp, startType) => {
const d = new Date(timeStamp * 1000)
const year = d.getFullYear()
const month = getHandledValue(d.getMonth() + 1)
const date = getHandledValue(d.getDate())
const hours = getHandledValue(d.getHours())
const minutes = getHandledValue(d.getMinutes())
const second = getHandledValue(d.getSeconds())
let resStr = ''
if (startType === 'year') resStr = year + '-' + month + '-' + date + ' ' + hours + ':' + minutes + ':' + second
else resStr = month + '-' + date + ' ' + hours + ':' + minutes
return resStr
}
/**
* @param {String|Number} timeStamp 时间戳
* @returns {String} 相对时间字符串
*/
export const getRelativeTime = timeStamp => {
// 判断当前传入的时间戳是秒格式还是毫秒
const IS_MILLISECOND = isMillisecond(timeStamp)
// 如果是毫秒格式则转为秒格式
if (IS_MILLISECOND) Math.floor(timeStamp /= 1000)
// 传入的时间戳可以是数值或字符串类型,这里统一转为数值类型
timeStamp = Number(timeStamp)
// 获取当前时间时间戳
const currentTime = Math.floor(Date.parse(new Date()) / 1000)
// 判断传入时间戳是否早于当前时间戳
const IS_EARLY = isEarly(timeStamp, currentTime)
// 获取两个时间戳差值
let diff = currentTime - timeStamp
// 如果IS_EARLY为false则差值取反
if (!IS_EARLY) diff = -diff
let resStr = ''
const dirStr = IS_EARLY ? '前' : '后'
// 少于等于59秒
if (diff <= 59) resStr = diff + '秒' + dirStr
// 多于59秒少于等于59分钟59秒
else if (diff > 59 && diff <= 3599) resStr = Math.floor(diff / 60) + '分钟' + dirStr
// 多于59分钟59秒少于等于23小时59分钟59秒
else if (diff > 3599 && diff <= 86399) resStr = Math.floor(diff / 3600) + '小时' + dirStr
// 多于23小时59分钟59秒少于等于29天59分钟59秒
else if (diff > 86399 && diff <= 2623859) resStr = Math.floor(diff / 86400) + '天' + dirStr
// 多于29天59分钟59秒少于364天23小时59分钟59秒且传入的时间戳早于当前
else if (diff > 2623859 && diff <= 31567859 && IS_EARLY) resStr = getDate(timeStamp)
else resStr = getDate(timeStamp, 'year')
return resStr
}
/**
* @returns {String} 当前浏览器名称
*/
export const getExplorer = () => {
const ua = window.navigator.userAgent
const isExplorer = (exp) => {
return ua.indexOf(exp) > -1
}
if (isExplorer('MSIE')) return 'IE'
else if (isExplorer('Firefox')) return 'Firefox'
else if (isExplorer('Chrome')) return 'Chrome'
else if (isExplorer('Opera')) return 'Opera'
else if (isExplorer('Safari')) return 'Safari'
}
/**
* @description 绑定事件 on(element, event, handler)
*/
export const on = (function () {
if (document.addEventListener) {
return function (element, event, handler) {
if (element && event && handler) {
element.addEventListener(event, handler, false)
}
}
} else {
return function (element, event, handler) {
if (element && event && handler) {
element.attachEvent('on' + event, handler)
}
}
}
})()
/**
* @description 解绑事件 off(element, event, handler)
*/
export const off = (function () {
if (document.removeEventListener) {
return function (element, event, handler) {
if (element && event) {
element.removeEventListener(event, handler, false)
}
}
} else {
return function (element, event, handler) {
if (element && event) {
element.detachEvent('on' + event, handler)
}
}
}
})()
/**
* 判断一个对象是否存在key如果传入第二个参数key则是判断这个obj对象是否存在key这个属性
* 如果没有传入key这个参数则判断obj对象是否有键值对
*/
export const hasKey = (obj, key) => {
if (key) return key in obj
else {
let keysArr = Object.keys(obj)
return keysArr.length
}
}
/**
* @param {*} obj1 对象
* @param {*} obj2 对象
* @description 判断两个对象是否相等这两个对象的值只能是数字或字符串
*/
export const objEqual = (obj1, obj2) => {
const keysArr1 = Object.keys(obj1)
const keysArr2 = Object.keys(obj2)
if (keysArr1.length !== keysArr2.length) return false
else if (keysArr1.length === 0 && keysArr2.length === 0) return true
/* eslint-disable-next-line */
else return !keysArr1.some(key => obj1[key] != obj2[key])
}
/**
* @param {*} date1 开始日期
* @param {*} date2 结束日期
* @description 计算两个日期相差天数
*/
export const getDaysBetween = (date1, date2) => {
var startDate = Date.parse(date1)
var endDate = Date.parse(date2)
var days = (endDate - startDate) / (1 * 24 * 60 * 60 * 1000)
return days
}
/**
* @param {*} date1 日期1
* @param {*} date2 日期2
* @description 判断日期是否同一周内
*/
export const isSameWeek = (date1, date2) => {
var oneDayTime = 1000 * 60 * 60 * 24
var oldCount = parseInt(date1.getTime() / oneDayTime)
var nowOther = parseInt(date2.getTime() / oneDayTime)
return parseInt((oldCount + 4) / 7) === parseInt((nowOther + 4) / 7)
}
// 秒数(ss) 转 d天h小时m分钟s秒 的时间格式表示
export function formatSeconds(value) {
var secondTime = parseInt(value) // 秒
var minuteTime = 0 // 分
var hourTime = 0 // 小时
var dayTime = 0 // 天
var result = ''
if (value < 60) {
result = secondTime + ' 秒 '
} else {
if (secondTime >= 60) { // 如果秒数大于60将秒数转换成整数
// 获取分钟除以60取整数得到整数分钟
minuteTime = parseInt(secondTime / 60)
// 获取秒数,秒数取佘,得到整数秒数
secondTime = parseInt(secondTime % 60)
// 如果分钟大于60将分钟转换成小时
if (minuteTime >= 60) {
// 获取小时获取分钟除以60得到整数小时
hourTime = parseInt(minuteTime / 60)
// 获取小时后取佘的分获取分钟除以60取佘的分
minuteTime = parseInt(minuteTime % 60)
if (hourTime >= 24) {
// 获取天数, 获取小时除以24得到整数天
dayTime = parseInt(hourTime / 24)
// 获取小时后取余小时获取分钟除以24取余的分
hourTime = parseInt(hourTime % 24)
}
}
}
if (secondTime > 0) {
// secondTime = parseInt(secondTime) >= 10 ? secondTime : '0' + secondTime // 用于个位数时前面补0
result = '' + secondTime + ' 秒 '
}
if (minuteTime > 0) {
// minuteTime = parseInt(minuteTime) >= 10 ? minuteTime : '0' + minuteTime // 用于个位数时前面补0
result = '' + minuteTime + ' 分钟 ' + result
}
if (hourTime > 0) {
result = '' + parseInt(hourTime) + ' 小时 ' + result
}
if (dayTime > 0) {
result = '' + parseInt(dayTime) + ' 天 ' + result
}
}
return result
}
// 秒数(ss)转 hh:mm:ss 时间格式
export function secToTime(data) {
var time = Number(data)
var h = Math.floor(time / 3600)
var m = Math.floor((time % 3600) / 60)
var s = parseInt(time % 3600) % 60
var hh = h < 10 ? "0" + h : h
var mm = m < 10 ? "0" + m : m
var ss = s < 10 ? "0" + s : s
return hh + ":" + mm + ":" + ss
}
// hh:mm:ss 时间格式转秒数(ss)
export function timeToSec(time) {
if (time !== null) {
var s = ""
var hour = time.split(":")[0]
var min = time.split(":")[1]
var sec = time.split(":")[2]
s = Number(hour * 3600) + Number(min * 60) + Number(sec)
return s
}
}
// 获取 URL 上的参数
export function getUrlParams(name) {
if (name == null || name === 'undefined') {
return null
}
var searchStr = decodeURI(window.location.href).replace('?', '&')
var infoIndex = searchStr.indexOf(name + '=')
if (infoIndex === -1) { return null }
var searchInfo = searchStr.substring(infoIndex + name.length + 1)
var tagIndex = searchInfo.indexOf('&')
if (tagIndex !== -1) { searchInfo = searchInfo.substring(0, tagIndex) }
return searchInfo
}

28
src/views/IPSetting.vue Normal file
View File

@ -0,0 +1,28 @@
<template>
<div class="content-box">
<div class="container">
<p>主体页面 1 - 2 </p>
<div class="test-div">
<i class="el-icon-edit"></i>
<i class="el-icon-share"></i>
<i class="el-icon-delete"></i>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return{
}
}
}
</script>
<style>
.test-div i{
font-size: 25px;
}
</style>

View File

@ -0,0 +1,28 @@
<template>
<div class="content-box">
<div class="container">
<p>主体页面 1 - 2 </p>
<div class="test-div">
<i class="el-icon-edit"></i>
<i class="el-icon-share"></i>
<i class="el-icon-delete"></i>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return{
}
}
}
</script>
<style>
.test-div i{
font-size: 25px;
}
</style>

View File

@ -0,0 +1,28 @@
<template>
<div class="content-box">
<div class="container">
<p>主体页面 1 - 2 </p>
<div class="test-div">
<i class="el-icon-edit"></i>
<i class="el-icon-share"></i>
<i class="el-icon-delete"></i>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return{
}
}
}
</script>
<style>
.test-div i{
font-size: 25px;
}
</style>

View File

@ -0,0 +1,28 @@
<template>
<div class="content-box">
<div class="container">
<p>主体页面 1 - 2 </p>
<div class="test-div">
<i class="el-icon-edit"></i>
<i class="el-icon-share"></i>
<i class="el-icon-delete"></i>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return{
}
}
}
</script>
<style>
.test-div i{
font-size: 25px;
}
</style>

View File

@ -0,0 +1,28 @@
<template>
<div class="content-box">
<div class="container">
<p>主体页面 1 - 2 </p>
<div class="test-div">
<i class="el-icon-edit"></i>
<i class="el-icon-share"></i>
<i class="el-icon-delete"></i>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return{
}
}
}
</script>
<style>
.test-div i{
font-size: 25px;
}
</style>

View File

@ -0,0 +1,28 @@
<template>
<div class="content-box">
<div class="container">
<p>主体页面 1 - 2 </p>
<div class="test-div">
<i class="el-icon-edit"></i>
<i class="el-icon-share"></i>
<i class="el-icon-delete"></i>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return{
}
}
}
</script>
<style>
.test-div i{
font-size: 25px;
}
</style>

View File

@ -0,0 +1,28 @@
<template>
<div class="content-box">
<div class="container">
<p>主体页面 1 - 2 </p>
<div class="test-div">
<i class="el-icon-edit"></i>
<i class="el-icon-share"></i>
<i class="el-icon-delete"></i>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return{
}
}
}
</script>
<style>
.test-div i{
font-size: 25px;
}
</style>

View File

@ -0,0 +1,28 @@
<template>
<div class="content-box">
<div class="container">
<p>主体页面 1 - 2 </p>
<div class="test-div">
<i class="el-icon-edit"></i>
<i class="el-icon-share"></i>
<i class="el-icon-delete"></i>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return{
}
}
}
</script>
<style>
.test-div i{
font-size: 25px;
}
</style>

View File

@ -0,0 +1,28 @@
<template>
<div class="content-box">
<div class="container">
<p>关于本机 </p>
<div class="test-div">
<i class="el-icon-edit"></i>
<i class="el-icon-share"></i>
<i class="el-icon-delete"></i>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return{
}
}
}
</script>
<style>
.test-div i{
font-size: 25px;
}
</style>

View File

@ -0,0 +1,28 @@
<template>
<div class="content-box">
<div class="container">
<p>自定义操作</p>
<div class="test-div">
<i class="el-icon-edit"></i>
<i class="el-icon-share"></i>
<i class="el-icon-delete"></i>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return{
}
}
}
</script>
<style>
.test-div i{
font-size: 25px;
}
</style>

View File

@ -0,0 +1,28 @@
<template>
<div class="content-box">
<div class="container">
<p>健康检测 </p>
<div class="test-div">
<i class="el-icon-edit"></i>
<i class="el-icon-share"></i>
<i class="el-icon-delete"></i>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return{
}
}
}
</script>
<style>
.test-div i{
font-size: 25px;
}
</style>

28
src/views/general/VPN.vue Normal file
View File

@ -0,0 +1,28 @@
<template>
<div class="content-box">
<div class="container">
<p>VPN </p>
<div class="test-div">
<i class="el-icon-edit"></i>
<i class="el-icon-share"></i>
<i class="el-icon-delete"></i>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return{
}
}
}
</script>
<style>
.test-div i{
font-size: 25px;
}
</style>

View File

@ -0,0 +1,28 @@
<template>
<div class="content-box">
<div class="container">
<p>网络 </p>
<div class="test-div">
<i class="el-icon-edit"></i>
<i class="el-icon-share"></i>
<i class="el-icon-delete"></i>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return{
}
}
}
</script>
<style>
.test-div i{
font-size: 25px;
}
</style>

940
src/views/index.vue Normal file
View File

@ -0,0 +1,940 @@
<template>
<div class="content-box">
<div class="container">
<div style="width:80%;height:800px">
<img :src='imgUrl' width="100%" height="100%"/>
</div>
</div>
</div>
</template>
<script>
import mqtt from "mqtt"; // mqtt
import axios from 'axios'
export default {
data() {
return {
hideBoxShow:true, //
closeStatus: null,
modelOthers: false,
componentShow: "",
isShowBtn: true, //
isShowBtn1: false, //
inputVal: "",
dateTime: this.$moment(new Date()).format("LL"),
nowTime: "",
weekday: this.$moment().format("dddd"),
ins: 0,
imgUrl:'',
btnPic: [
// require("@/assets/images/homeActive.png"),
// require("@/assets/images/battery.png"),
// require("@/assets/images/stock.png"),
// require("@/assets/images/productionInformation.png"),
// require("@/assets/images/equipment.png"),
// require("@/assets/images/operationMG.png"),
],
statusInfo: [
{
count: 15,
name: "穿梭车在线数量",
// icon: require("../assets/images/.png"),
color: "#01A8FC",
},
{
count: 26,
name: "任务数量",
// icon: require("../assets/images/.png"),
color: "#FDA401",
},
],
messageInfo: [],
orderList: [],
enterList: [],
stockInfo: [],
perCent: 0,
perCent1: 0,
perCent2: 0,
facToal: "",
wbContent:'',
wxContent:'',
inContent:'',
outContent:'',
containerDetails:"",
locdesc:'',
weatherItem:{},
loadingShow1:true,
carInfo:[], //
carName:'',
palletizerInfo:[], //
palletizerName:'',
destackerInfo:[], //
destackerName:'',
hoistInfo:[], //
hoistName:'',
battaryStationInfo:[],//
battaryStationName:"",
conveyorInfo:[], //
conveyorName:"",
};
},
mounted() {
setInterval(() => {
this.nowTime = this.$moment(new Date()).format("LTS");
}, 1000);
this.getMessage();
//
getfacMaintainRecord({ type: 0 }).then((res) => {
console.log("消息提醒",res.data)
// this.messageInfo = this.messageInfo.concat(JSON.parse(res.data.split('#')[0]));
this.messageInfo = res.data;
// this.messageInfo.push(JSON.parse(res.data.split('#')[0]))
//
});
// getfacKeepRecord({ type: 0 }).then((res) => {
// this.messageInfo = this.messageInfo.concat(res.data);
// console.log(this.messageInfo, ",,qweqw");
// // this.messageInfo.push(res.data[1])
// });
// this.getDataByMqtt()
this.getstatus();
this.getInhouse();
this.getOuthouse();
this.handleWather();
this.getDeviceStatusData()
},
created() {
this.testMqtt()
},
methods: {
//
async squareList() {
let arrList = await getInventoryStatus({ type: 3 });
getInventoryMessage({ type: 0 }).then((res) => {
//
var arr = res.data;
console.log(arr, ",arr,,,");
console.log(arrList, ",,,arrList");
arr.forEach((item, index) => {
let obj = {
cId: index + 526,
parentName: "货箱",
name: `货箱${1 + index}`,
pos: [2971.08, 383.81, -3099.09],
size: [1, 1, 1],
rotate: [0, 0, 0],
wirePos: [item.LIE, item.LAYER, item.LINE],
affiliation: [],
type: "货箱",
visible: true,
passenger: [],
taskCode: -1,
PLTNUM: "",
VPLTNUM: "",
LOCNUM: item.LOCNUM,
LOCDESC: item.LOCDESC,
LOCSTORESTATUS: item.LOCSTORESTATUS,
ITEMCMBNUM: item.ITEMCMBNUM,
};
arrList.data.forEach((items) => {
if (item.LOCNUM == items.CURRLOC) {
obj.PLTNUM = items.PLTNUM;
obj.VPLTNUM = items.VPLTNUM;
obj.cId = items.PLTNUM
}else if(item.LOCNUM == items.DLOC){
obj.PLTNUM = items.PLTNUM;
obj.VPLTNUM = items.VPLTNUM;
obj.cId = items.PLTNUM
}
});
var tarpos = this.wireSYs(item);
obj.pos = tarpos;
item.LAYER==1?obj.pos[1] = 50.9:obj.pos[1] = 364.81;
if(item.ITEMCMBNUM == '6000'){
obj.parentName = '双箱_Empty'
}else{
obj.parentName = '双箱_Full'
}
if (item.LOCSTORESTATUS != "Free") {
modelResource.push(obj);
this.realObj.forEach((items) => {
if (obj.parentName === items.parentName) {
this.createNode(obj, this.modelarray);
this.models[obj.cId].s3([
1.3299999999999992, 2.6210000000000004, 1.33,
]);
this.models[obj.cId].cParentName = '货箱';
// this.models[obj.cId].setImage('box');
// this.models[317].setImage('box')
}
});
}
});
});
},
// mqtt
testMqtt() {
this.getDataByMqtt()
//
// for (let key in this.carId) {
// this.getDataByMqtt(
// // "ws:ht.mqtt.umayle.com:2022/mqtt",
// "ws:220.163.114.157:8083/mqtt",
// "Car" + key,
// this.carId[key]
// );
// }
// //
// for (let i = 0; i < this.convoyorCIdGroup.length; i++) {
// this.getDataByMqtt(
// "ws:220.163.114.157:8083/mqtt",
// "InConvoyor" + this.convoyorCIdGroup[i],
// this.convoyorCIdGroup[i]
// );
// }
// //
// for (let i = 0; i < this.outConvoyorCIdGroup.length; i++) {
// this.getDataByMqtt(
// "ws:220.163.114.157:8083/mqtt",
// "OUTConvoyor" + this.outConvoyorCIdGroup[i],
// this.outConvoyorCIdGroup[i]
// );
// }
// for (let key in this.BattaryArr) {
// this.getDataByMqtt(
// "ws:220.163.114.157:8083/mqtt",
// "Battary_Sation" + key,
// this.BattaryArr[key]
// );
// }
// // elvArr
// for (let key in this.elvArr) {
// this.getDataByMqtt(
// "ws:220.163.114.157:8083/mqtt",
// "ELV" + key,
// this.elvArr[key]
// );
// }
// //
// for (let key in this.stampArr) {
// this.getDataByMqtt(
// "ws:220.163.114.157:8083/mqtt",
// "INCMD" + key,
// this.stampArr[key]
// );
// }
},
//
loadingShow(data){
this.loadingShow1 = data
},
// mqtt
getDataByMqtt(url, topic, cIdNum) {
const clientId = "test_id_" + String(new Date().getTime()); //
const host = 'ws://172.16.1.168:10087/'; // urlws://broker.emqx.io:8083/mqtt
const options = {
//
// IP
// host: host,
// port: port,
// host:"172.16.1.168:10086",
keepalive: 60, // 60s0
username: 'admin', //
password: '123456', //
clientId: clientId, // ID
protocolId: "MQTT",
protocolVersion: 4,
clean: true, // false线QoS12
reconnectPeriod: 2000, // 1000
connectTimeout: 30 * 1000, // CONNACK
will: {
// Broker
topic: "videoTest", //
payload: "[MQTT-TEST] 遗嘱消息:连接异常断开!", //
qos: 1, // QoS(Quality of Service)QoS0QoS11QoS21
retain: false, //
},
};
if (this.mqttClient == undefined) {
this.mqttClient = mqtt.connect(host, options); //
// const client = mqtt.connect(host, options); //
// const client = mqtt.connect(host) //
//
console.log("this.mqttClient",this.mqttClient)
this.mqttClient.on("error", (err) => {
console.log("[MQTT-TEST] 连接错误:",err);
this.mqttClient.end();
});
//
this.mqttClient.on("reconnect", (reconnect) => {
console.log("[MQTT-TEST] 重连中……",reconnect);
});
//
this.mqttClient.on("connect", (connect) => {
console.log("[MQTT-TEST] 已连接的客户端ID: ",connect);
//
this.mqttClient.subscribe('img', { qos: 1 });
});
//
this.mqttClient.on("message", (topic, message, packet) => {
console.log("[MQTT-TEST] 已连接的客户端ID: ",message);
console.log(
`[MQTT-TEST] 从主题 "${topic}" 收到的内容: ${message.toString()}`,
new Date(),
new Date().getMilliseconds()
);
//
// let dataReceived = JSON.parse(message.toString());
// console.log("[MQTT-TEST] ID: ",dataReceived);
try{
const utf8decoder = new TextDecoder()
const u8arr = new Uint8Array(message)
const temp = utf8decoder.decode(u8arr) //
const msg = JSON.parse(temp) //JSON
console.log("msg",msg) //msgJSON
this.imgUrl='data:image/png;base64,' + msg.pic;
console.log("imageUrl",imageUrl)
}catch{
let imageType = 'arraybuffer';
const blob = new Blob([message], { type: imageType })
const imageUrl = (window.URL || window.webkitURL).createObjectURL(blob)
console.log("imageUrl",imageUrl)
}
let that = this;
var cId;
if (topic.indexOf("Car") != -1) {
cId = this.carId[topic.replace("Car", "")];
} else if (topic.indexOf("InConvoyor") != -1) {
cId = topic.replace("InConvoyor", "");
} else if (topic.indexOf("Battary_Sation") != -1) {
cId = this.BattaryArr[topic.replace("Battary_Sation", "")];
} else if (topic.indexOf("ELV") != "-1") {
cId = this.elvArr[topic.replace("ELV", "")][0];
this.models[cId].topic = topic;
} else if (topic.indexOf("INCMD") != -1) {
cId = this.stampArr[topic.replace("INCMD", "")][0];
console.log(cId, "topiccid");
this.models[cId].topic = topic;
} else if (topic.indexOf("OUTConvoyor") != -1) {
cId = topic.replace("OUTConvoyor", "");
}
// var convoyorData = that.convoyorCIdGroup[i];
// if (that.models[cId] != undefined) {
// try {
// that.models[cId].receiveData(dataReceived, topic);
// } catch (err) {
// console.error(err);
// }
// }
});
}
},
//
getDeviceStatusData(){
//
getDeviceStatus().then((res) => {
console.log("res1111",res.data)
// this.enterList = res.data;
// console.log(res, "123123");
this.statusInfo[1].count = res.data.MessionNum
});
//穿
getDeviceDetails({deviceNum:'Num'}).then((res) => {
console.log("res1111",res.data)
// this.enterList = res.data;
// console.log(res, "123123");
this.statusInfo[0].count = res.data.CarOnlineNum
});
},
handleSearch(){
this.modelOthers = true;
      this.$refs.htModels.finbBox(this.inputVal);
      console.log(this.$refs.htModels,'asdasdasd');
this.inputVal = ''
    },
handleRow(val){
this.modelOthers = true;
      this.$refs.htModels.finbBox(val);
    },
//
handleWather(){
axios({url:'https://restapi.amap.com/v3/weather/weatherInfo?key=bc2b906032fdd8a63cbd0790d656b1d7&city=620100',methods:''}).then(res=>{
this.weatherItem = res.data.lives[0]
console.log(this.weatherItem,'asdsads');
})
},
getmessageInfoData(val){
console.log("val",val)
if(val==true){
getfacMaintainRecord({ type: 0 }).then((res) => {
console.log("消息提醒",res.data)
this.messageInfo = res.data;
});
}
},
Onweather(name){
// switch (name) {
// case "":
// return require('../assets/weather/Cloudy .png');
// case "":
// return require('../assets/weather/Cloudy .png')
// case "":
// return require('../assets/weather/rainstorm.png')
// case "":
// return require('../assets/weather/hail.png')
// case "":
// return require('../assets/weather/gale.png')
// case "":
// return require('../assets/weather/bigsnow.png')
// case "":
// return require('../assets/weather/bigrain.png')
// case "":
// return require('../assets/weather/thunder.png')
// case "":
// return require('../assets/weather/shower.png')
// case "":
// return require('../assets/weather/sand.png')
// case "":
// return require('../assets/weather/sun.png')
// case "":
// return require('../assets/weather/smog.png')
// case "":
// return require('../assets/weather/snow.png')
// case "":
// return require('../assets/weather/rain.png')
// case "":
// return require('../assets/weather/rainlitter.png')
// case "":
// return require('../assets/weather/night.png')
// case "":
// return require('../assets/weather/rainsnow.png')
// case "":
// return require('../assets/weather/moon.png')
// case "":
// return require('../assets/weather/mieddlesnow.png')
// case "":
// return require('../assets/weather/middlerain.png')
// }
},
//
getInhouse() {
getInwarehouse({ type: 0 }).then((res) => {
this.enterList = res.data;
console.log(res, "123123");
});
},
//
getOuthouse() {
getOutwarehouse({ type: 0 }).then((res) => {
console.log(res.data);
this.orderList = res.data;
});
},
//
getMessage() {
getInventoryMessage({ type: 1 }).then((res) => {
const arr = [];
arr.push(
res.data.MoveOut,
res.data.MoveIn,
res.data.load,
res.data.free
);
this.menusInit(arr);
});
},
//
getstatus() {
getInventoryStatus({ type: 2 }).then((res) => {
console.log(JSON.parse(res.data.split("#")[0]), ",,,qwe123");
var obj = JSON.parse(res.data.split("#")[0]);
var obj2 = JSON.parse(res.data.split("#")[2]);
var arr = [];
Object.keys(obj).forEach((item) => {
Object.keys(obj2).forEach((items) => {
if (item == items) {
arr.push({
name: obj[item].substring(0, 2),
type: obj[item].substring(2, obj[item].length - 2),
smoke: "烟丝",
perCent: obj2[item],
});
}
});
});
this.perCent = arr[0].perCent;
this.perCent1 = arr[1].perCent;
this.perCent2 = arr[2].perCent;
this.stockInfo = arr;
});
},
//
utcToLocal(date) {
const fmt = "YYYY-MM-DD hh:mm:ss";
return this.$moment(date).format(fmt);
},
/**
*
* 设备弹窗
*/
getEquipmentInfo(data) {
if (data.cType == "货箱") {
// PLTNUM
// VPLTNUM
this.locdesc = data.LOCDESC
getCountBox({ type: 3 ,PLTNUM:data.PLTNUM}).then((res) => {
console.log(res.data,'箱子')
this.containerDetails = res.data
this.componentShow = "container";
this.modelOthers = true;
});
} else if (data.cType == "码垛机") {
let deviceNum = ''
if (data.cId == 144) {
deviceNum = 'INCMD4'
}else{
deviceNum = 'INCMD3'
}
getDeviceDetails(
{
deviceNum: deviceNum
}).then((res)=>{
this.palletizerName = deviceNum
this.palletizerInfo = res.data
this.componentShow = "palletizer";
this.modelOthers = true;
})
}
// else if (data.cType == "") {
// this.componentShow = "packingStation";
// this.modelOthers = true;
// }
else if (data.cType == "拆垛机") {
let deviceNum = ''
console.log(data,'拆垛机');
if (data.cId == 142) {
deviceNum = 'INCMD6'
}else if(data.cId == 146){
deviceNum = 'INCMD5'
}else if (data.cId == 149) {
deviceNum = 'INCMD2'
}else if (data.cId == 151) {
deviceNum = 'INCMD1'
}
getDeviceDetails(
{
deviceNum: deviceNum
}).then((res)=>{
this.destackerInfo = res.data
this.destackerName = deviceNum
this.componentShow = "destacker";
this.modelOthers = true;
})
} else if (data.cType == "往复式输送升降机") {
let deviceNum = ''
if (data.cId == 320) {
deviceNum = 'ELV1'
}else if(data.cId == 319){
deviceNum = 'ELV2'
}else if (data.cId == 318) {
deviceNum = 'ELV3'
}else if (data.cId == 317) {
deviceNum = 'ELV4'
}else if(data.cId == 313){
deviceNum = 'ELV5'
}else if(data.cId == 321){
deviceNum = 'ELV6'
}
getDeviceDetails(
{
deviceNum: deviceNum
}).then((res)=>{
this.hoistInfo = res.data
this.hoistName = deviceNum
this.componentShow = "hoist";
this.modelOthers = true;
})
} else if (data.cType == "智能双向穿梭车") {
getDeviceDetails(
{
deviceNum:'Car'+ data.cName.slice(11)
}).then((res)=>{
this.carName = 'Car' + data.cName.slice(11)
this.componentShow = "suttleCar";
this.modelOthers = true;
this.carInfo = res.data
})
} else if (data.cType == "快换电池装置") {
let deviceNum = ''
if (data.cId == 476) {
deviceNum = 'Battary_Sation2'
}else if(data.cId == 361){
deviceNum = 'Battary_Sation1'
}
getDeviceDetails(
{
deviceNum: deviceNum
}).then((res)=>{
this.componentShow = "battery";
this.modelOthers = true;
this.battaryStationInfo = res.data
this.battaryStationName = deviceNum
})
}else if (data.cType == "链式输送机") {
let deviceNum = ''
if (data.cId.toString().substring(0,2) == "51") {
deviceNum = 'InConvoyor' + data.cId
}else if (data.cId.toString().substring(0,2) == "53") {
deviceNum = 'OUTConvoyor' + data.cId
}
getDeviceDetails(
{
deviceNum: deviceNum
}).then((res)=>{
this.modelOthers = true;
this.componentShow = "conveyor";
this.conveyorInfo = res.data
this.conveyorName = deviceNum
})
}
},
/**
* 详情弹窗
*/
informationInfo(data,item) {
if (data == "出库工单") {
this.componentShow = "wireFeeder";
this.modelOthers = true;
this.outContent = this.orderList
}else if (data == "入库工单") {
this.componentShow = "inFeeder";
this.modelOthers = true;
this.inContent = this.enterList
}else if (data == "库存消息") {
this.componentShow = "lnventory";
this.modelOthers = true;
// this.inContent = this.enterList
} else if (data == "各品牌库存情况") {
this.componentShow = "lnventoryLeft";
this.modelOthers = true;
// this.inContent = this.enterList
} else if (data == "消息提醒") {
this.componentShow = "maintenanceRemindTable";
this.modelOthers = true;
// this.inContent = this.enterList
} else if (data == "维保提醒") {
if(item.keepName){
this.componentShow = "maintenance";
this.modelOthers = true;
this.wbContent=item
}else{
this.componentShow = "maintenanceRemind";
this.modelOthers = true;
this.wxContent=item
}
// getfacManage({ type: 3,facCode: item.facCode
// ,id: item.id
// ,mark:1}).then((res) => {
// console.log("res.data",res.data)
// });
}
},
getCloseStatus(status) {
this.hideBoxShow = true
this.closeStatus = status;
// if (status == 1) {
// this.btnPic[0] = require("@/assets/images/homeActive.png");
// this.btnPic[1] = require("@/assets/images/battery.png");
// }
// if (status == 2) {
// this.btnPic[0] = require("@/assets/images/homeActive.png");
// this.btnPic[2] = require("@/assets/images/equipment.png");
// }
// if (status == 3) {
// this.btnPic[0] = require("@/assets/images/homeActive.png");
// this.btnPic[1] = require("@/assets/images/productionInformation.png");
// }
// if (status == 4) {
// this.btnPic[0] = require("@/assets/images/homeActive.png");
// this.btnPic[3] = require("@/assets/images/operationMG.png");
// }
},
handleActive(item, e) {
this.hideBoxShow = false
this.ins = item;
this.btnPic = [
// require("@/assets/images/home.png"),
// require("@/assets/images/battery.png"),
// require("@/assets/images/stock.png"),
// require("@/assets/images/productionInformation.png"),
// require("@/assets/images/equipment.png"),
// require("@/assets/images/operationMG.png"),
];
if (item == 0) {
// this.btnPic[item] = require("@/assets/images/homeActive.png");
}
// else if (item == 1) {
// this.componentShow = "batteryManagement";
// this.modelOthers = true;
// this.btnPic[item] = require("@/assets/images/batteryActive.png");
// }
else if (item == 2) {
this.componentShow = "deviceManagement";
this.modelOthers = true;
// this.btnPic[item] = require("@/assets/images/equipmentActive.png");
} else if (item == 1) {
this.componentShow = "productionInformation";
this.modelOthers = true;
// this.btnPic[
// item
// ] = require("@/assets/images/productionInformationActive.png");
} else if (item == 3) {
this.componentShow = "operationMaintenance";
this.modelOthers = true;
// this.btnPic[item] = require("@/assets/images/operationMGActive.png");
}
// else if (item == 2) {
// this.btnPic[item] = require("@/assets/images/stockActive.png");
// }
// else if (item == 3) {
// this.componentShow = "deviceManagement";
// this.modelOthers = true;
// this.btnPic[item] = require("@/assets/images/equipmentActive.png");
// } else if (item == 4) {
// this.componentShow = "productionInformation";
// this.modelOthers = true;
// this.btnPic[
// item
// ] = require("@/assets/images/productionInformationActive.png");
// } else if (item == 5) {
// this.componentShow = "operationMaintenance";
// this.modelOthers = true;
// this.btnPic[item] = require("@/assets/images/operationMGActive.png");
// }
this.$forceUpdate();
},
//
menusInit(arr) {
let domechart = document.getElementById("menusBar");
let myCharts = echarts.init(domechart);
var datapictorialBar = arr;
var pictorialBarColor = [" #155b5b", " #16485a ", "#41362d"];
//
var maxList = Math.max.apply(null, arr) + 10;
console.log(maxList, datapictorialBar, ",,,maxList");
let option = {
grid: {
top: 18,
bottom: 18,
left: 15,
right: 20,
},
xAxis: {
show: false,
},
yAxis: [
{
show: true,
type: "category",
data: ["入库中", "出库中","实箱","空箱", ],
axisLine: {
show: false,
},
axisTick: {
show: false,
},
axisLabel: {
color: "#ffffff",
fontSize: 14,
inside: true,
padding: [-45, 0, 0, -10],
align: "left",
},
},
{
show: true,
type: "category",
axisLine: {
show: false,
},
axisTick: {
show: false,
},
},
],
series: [
{
name: "销量",
type: "bar",
barWidth: 20, //
barGap: 36,
data: [maxList, maxList, maxList, maxList],
itemStyle: {
normal: {
//
color: "rgba(0, 153, 145, 0)",
borderColor: "#cca272",
borderWidth: 1,
borderType: "solid",
},
},
},
{
//
type: "pictorialBar",
colorBy: "data",
label: {
//
show: true, //
position: "right", //
offset: [-30, -18],
fontSize: 18,
fontWeight: "bold",
color: "#155b5b",
},
itemStyle: {
normal: {
color: function (params) {
// colorList
var colorList = [
["#1afbd3", "#155b5b"],
["#19a1cc", "#16485a"],
["#19a1cc", "#16485a"],
["#ec8d41", "#41362d"],
];
var colorItem = colorList[params.dataIndex];
return new echarts.graphic.LinearGradient(
1,
0,
0,
0,
[
{
offset: 0,
color: colorItem[0],
},
{
offset: 1,
color: colorItem[1],
},
],
false
);
},
},
},
symbolRepeat: "fixed",
symbolMargin: 1,
symbol: "roundRect",
symbolClip: true,
symbolSize: [8, 18],
symbolPosition: "start",
symbolOffset: [1, 0],
// symbolBoundingData: this.total,
data: datapictorialBar,
width: 13,
z: 0,
zlevel: 3,
},
],
};
myCharts.setOption(option);
},
//
isShowBtnMore() {
this.isShowBtn = false;
window.setTimeout((e) => {
this.isShowBtn1 = true;
}, 1100);
},
isShowBtnMore1() {
this.isShowBtn1 = false;
this.isShowBtn = true;
},
//
hideBox(){
this.$refs.htModels.handleFirstBox();
}
},
components: {
// echars,
// echarts1,
// echarts2,
// HomeLeft
// home,
// equipmentManage,
// batteryManagement, //
// productionInformation, //
// deviceManagement, //
// operationMaintenance, //
// container, //
// palletizer, //
// packingStation, //
// destacker, //
// hoist, //
// suttleCar, // 穿
// battery, //
// wireFeeder, //
// inFeeder,//
// lnventory,
// equipmentInspection, //
// maintenance, //
// maintenanceRemind,
// lnventoryLeft,
// maintenanceRemindTable,
// conveyor,//
},
};
</script>
<style>
.el-header, .el-footer {
background-color: #B3C0D1;
color: #333;
text-align: center;
line-height: 60px;
}
.el-aside {
background-color: #D3DCE6;
color: #333;
text-align: center;
line-height: 200px;
}
.el-main {
background-color: #E9EEF3;
color: #333;
text-align: center;
line-height: 160px;
}
body > .el-container {
margin-bottom: 40px;
}
.el-container:nth-child(5) .el-aside,
.el-container:nth-child(6) .el-aside {
line-height: 260px;
}
.el-container:nth-child(7) .el-aside {
line-height: 320px;
}
</style>

0
src/views/interface.vue Normal file
View File

28
src/views/logs.vue Normal file
View File

@ -0,0 +1,28 @@
<template>
<div class="content-box">
<div class="container">
<p>主体页面 1 - 2 </p>
<div class="test-div">
<i class="el-icon-edit"></i>
<i class="el-icon-share"></i>
<i class="el-icon-delete"></i>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return{
}
}
}
</script>
<style>
.test-div i{
font-size: 25px;
}
</style>

28
src/views/myId.vue Normal file
View File

@ -0,0 +1,28 @@
<template>
<div class="content-box">
<div class="container">
<p>主体页面 1 - 2 </p>
<div class="test-div">
<i class="el-icon-edit"></i>
<i class="el-icon-share"></i>
<i class="el-icon-delete"></i>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return{
}
}
}
</script>
<style>
.test-div i{
font-size: 25px;
}
</style>

18
vue.config.js Normal file
View File

@ -0,0 +1,18 @@
module.exports = {
assetsDir: 'static',
productionSourceMap: false,
configureWebpack: {
devtool: 'source-map'
}
// devServer: {
// proxy: {
// '/api':{
// target:'http://jsonplaceholder.typicode.com',
// changeOrigin:true,
// pathRewrite:{
// '/api': ''
// }
// }
// }
// }
}