前端初始化
@@ -0,0 +1,540 @@
|
||||
<template>
|
||||
<div id="app">
|
||||
<i @click="closeLoading" class="custom-close el-icon-close" v-if="$store.state.isLoading"></i>
|
||||
<router-view/>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {loading} from "./utils/request";
|
||||
|
||||
export default {
|
||||
name: "ReportManager",
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
methods: {
|
||||
getQueryVariable(r, variable) {
|
||||
if (r) {
|
||||
var query = r.split('?');
|
||||
if (query && query.length == 2) {
|
||||
var vars = query[1].split("&");
|
||||
for (var i = 0; i < vars.length; i++) {
|
||||
var pair = vars[i].split("=");
|
||||
if (pair[0] == variable) {
|
||||
return pair[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
closeLoading() {
|
||||
loading.close();
|
||||
this.$store.commit('saveIsLoading', false);
|
||||
},
|
||||
},
|
||||
created() {
|
||||
let _that = this
|
||||
// var path = window.location.search
|
||||
// var ticket = this.getQueryVariable(path, 'ticket')
|
||||
// var loginType = this.getQueryVariable(path, 'loginType')
|
||||
// if (loginType == 1) {
|
||||
// window.open('http://10.12.1.78:9090/cas/login?service=http://192.168.144.22:9966/home', '_self');
|
||||
// } else {
|
||||
// // if (ticket) {
|
||||
// // var params = {
|
||||
// // service: 'http://localhost:8080/home',
|
||||
// // ticket: ticket
|
||||
// // }
|
||||
// // this.$api.login.loginByTicket(params).then(res => {
|
||||
// // if (res.respCode !== '0') {
|
||||
// // // this.verifyCode();
|
||||
// // return this.$message.error(res.data.message);
|
||||
// // }
|
||||
// // this.$message.success('登录成功');
|
||||
// // _that.$store.commit('saveUserInfo', res.data);
|
||||
// // _that.$router.push('/home');
|
||||
// // }).catch(_ => {
|
||||
// // // this.verifyCode();
|
||||
// // this.$router.push('/');
|
||||
// // })
|
||||
// //
|
||||
// // } else {
|
||||
// // this.$router.push('/');
|
||||
// // }
|
||||
// }
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
text-decoration: none;
|
||||
list-style: none;
|
||||
box-sizing: border-box;
|
||||
outline: none;
|
||||
font-style: normal;
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
}
|
||||
|
||||
html, body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
#app {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
min-width: 1200px;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
/* =============================================== 多选select =============================================== */
|
||||
.el-select {
|
||||
.el-select__tags-text {
|
||||
max-width: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.el-select-dropdown {
|
||||
z-index: 7777 !important;
|
||||
}
|
||||
|
||||
.el-cascader__tags .el-tag {
|
||||
max-width: 40px !important;
|
||||
}
|
||||
|
||||
.el-cascader .el-input .el-input__inner {
|
||||
height: 24px !important;
|
||||
}
|
||||
|
||||
|
||||
/* =============================================== 页面加载 =============================================== */
|
||||
.el-loading-mask.is-fullscreen {
|
||||
z-index: 8888 !important;
|
||||
}
|
||||
|
||||
.custom-close {
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
top: 20px;
|
||||
z-index: 9999;
|
||||
font-size: 30px;
|
||||
color: #6c6c6c;
|
||||
}
|
||||
|
||||
/* =============================================== 页面最小高度 =============================================== */
|
||||
.content-height {
|
||||
min-height: calc(100vh - 60px - 20px);
|
||||
box-shadow: 0 6px 11px 0 rgba(163, 163, 163, 0.2);
|
||||
border-radius: 6px;
|
||||
background: #FFFFFF;
|
||||
}
|
||||
|
||||
/* =============================================== el-button =============================================== */
|
||||
.el-button.del-btn {
|
||||
color: #ED5C57 !important;
|
||||
}
|
||||
|
||||
.el-button.el-button--primary:hover, .el-button.el-button--primary:focus {
|
||||
border-color: #1890FF !important;
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
.el-button.el-button--primary:hover,
|
||||
.el-button.el-button--primary:focus {
|
||||
border-color: #1890FF !important;
|
||||
background-color: #1890FF !important;
|
||||
color: #FFFFFF !important;
|
||||
}
|
||||
|
||||
.el-button.el-button--primary:active {
|
||||
color: #1890FF !important;
|
||||
}
|
||||
|
||||
.el-button--text {
|
||||
color: #1890FF !important;
|
||||
border: 0 !important;
|
||||
}
|
||||
|
||||
.el-button--text:hover, .el-button--text:focus {
|
||||
border: 0 transparent !important;
|
||||
}
|
||||
|
||||
.el-button--primary.is-plain,
|
||||
.el-button--primary.is-plain:hover,
|
||||
.el-button--primary.is-plain:focus {
|
||||
background-color: transparent !important;
|
||||
color: #1890FF !important;
|
||||
border-color: #1890FF !important;
|
||||
}
|
||||
|
||||
/* =============================================== input内容颜色 =============================================== */
|
||||
.el-input__inner,
|
||||
.el-textarea__inner {
|
||||
font-weight: 400;
|
||||
color: #434343;
|
||||
}
|
||||
|
||||
/* =============================================== 虚拟滚动条 =============================================== */
|
||||
.el-scrollbar {
|
||||
.el-scrollbar__wrap {
|
||||
overflow-x: hidden;
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* =============================================== vxetable header高度 =============================================== */
|
||||
.vxe-header--row {
|
||||
th.vxe-header--column {
|
||||
height: 40px !important;
|
||||
}
|
||||
|
||||
th.vxe-header--column.col--checkbox {
|
||||
padding: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* =============================================== vxetable滚动条 =============================================== */
|
||||
/*滚动条整体部分*/
|
||||
.vxe-table ::-webkit-scrollbar {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
/*滚动条的轨道*/
|
||||
.vxe-table ::-webkit-scrollbar-track {
|
||||
background-color: #EAEAEA;
|
||||
}
|
||||
|
||||
/*滚动条里面的小方块,能向上向下移动*/
|
||||
.vxe-table ::-webkit-scrollbar-thumb {
|
||||
background-color: #D8D8D8;
|
||||
border-radius: 5px;
|
||||
border: 1px solid #D8D8D8;
|
||||
box-shadow: inset 0 0 6px rgba(0, 0, 0, .1);
|
||||
}
|
||||
|
||||
.vxe-table ::-webkit-scrollbar-thumb:hover {
|
||||
background-color: #D8D8D8;
|
||||
}
|
||||
|
||||
.vxe-table ::-webkit-scrollbar-thumb:active {
|
||||
background-color: #D8D8D8;
|
||||
}
|
||||
|
||||
/*边角,即两个滚动条的交汇处*/
|
||||
.vxe-table ::-webkit-scrollbar-corner {
|
||||
background-color: #EAEAEA;
|
||||
}
|
||||
|
||||
/* =============================================== 分页基本样式 =============================================== */
|
||||
.el-pagination {
|
||||
text-align: right;
|
||||
|
||||
.el-pagination__total,
|
||||
.el-pagination__sizes {
|
||||
float: left;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
.el-input--mini .el-input__inner {
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 0 !important;
|
||||
text-align: center;
|
||||
background-color: #FAFAFA !important;
|
||||
color: #606266 !important;
|
||||
}
|
||||
|
||||
.el-pager {
|
||||
margin: 0 5px;
|
||||
|
||||
.number {
|
||||
background-color: #FAFAFA !important;
|
||||
margin: 0 5px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.number.active {
|
||||
background-color: rgba(64, 158, 255, 0.1) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* =============================================== 弹窗 =============================================== */
|
||||
.el-dialog {
|
||||
position: absolute !important;
|
||||
top: 50% !important;
|
||||
left: 50% !important;
|
||||
transform: translate(-50%, -50%) !important;
|
||||
margin: 0 !important;
|
||||
min-width: 600px !important;
|
||||
border-radius: 6px !important;
|
||||
|
||||
.el-dialog__header {
|
||||
height: 52px;
|
||||
line-height: 52px;
|
||||
padding-bottom: 0;
|
||||
margin: 0 18px 0 22px;
|
||||
border-bottom: 1px solid #EBEEF5;
|
||||
font-weight: 600;
|
||||
color: #262626;
|
||||
|
||||
.el-dialog__headerbtn {
|
||||
margin: 16px 24px 0 0;
|
||||
|
||||
.el-dialog__close {
|
||||
font-size: 24px;
|
||||
color: #6C6C6C;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-dialog__body {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* =============================================== search-tag =============================================== */
|
||||
.search-tag {
|
||||
box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0) !important;
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.25) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.test {
|
||||
width: auto!important;
|
||||
padding: 0px !important;
|
||||
}
|
||||
.ql-snow .ql-tooltip[data-mode='link']::before {
|
||||
content: '请输入链接地址:';
|
||||
}
|
||||
|
||||
.ql-snow .ql-tooltip.ql-editing a.ql-action::after {
|
||||
border-right: 0px;
|
||||
content: '保存';
|
||||
padding-right: 0px;
|
||||
}
|
||||
|
||||
.ql-snow .ql-tooltip[data-mode='video']::before {
|
||||
content: '请输入视频地址:';
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-size {
|
||||
width: 70px!important;
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value='14px']::before,
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value='14px']::before {
|
||||
content: '14px';
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value='16px']::before,
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value='16px']::before {
|
||||
content: '16px';
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value='18px']::before,
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value='18px']::before {
|
||||
content: '18px';
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value='20px']::before,
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value='20px']::before {
|
||||
content: '20px';
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value='32px']::before,
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value='32px']::before {
|
||||
content: '32px';
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-header .ql-picker-label::before,
|
||||
.ql-snow .ql-picker.ql-header .ql-picker-item::before {
|
||||
content: '文本';
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value='1']::before,
|
||||
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value='1']::before {
|
||||
content: '标题1';
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value='2']::before,
|
||||
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value='2']::before {
|
||||
content: '标题2';
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value='3']::before,
|
||||
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value='3']::before {
|
||||
content: '标题3';
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value='4']::before,
|
||||
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value='4']::before {
|
||||
content: '标题4';
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value='5']::before,
|
||||
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value='5']::before {
|
||||
content: '标题5';
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value='6']::before,
|
||||
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value='6']::before {
|
||||
content: '标题6';
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item::before {
|
||||
content: '标准字体';
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value='serif']::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value='serif']::before {
|
||||
content: '衬线字体';
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value='monospace']::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value='monospace']::before {
|
||||
content: '等宽字体';
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-lineheight .ql-picker-label::before {
|
||||
content: '行高';
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='initial']::before {
|
||||
content: '默认';
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='1']::before {
|
||||
content: '1';
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='1.5']::before {
|
||||
content: '1.5';
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='1.75']::before {
|
||||
content: '1.75';
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='2']::before {
|
||||
content: '2';
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='3']::before {
|
||||
content: '3';
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='4']::before {
|
||||
content: '4';
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='5']::before {
|
||||
content: '5';
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-lineheight {
|
||||
width: 70px;
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=SimSun]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=SimSun]::before {
|
||||
content: "宋体";
|
||||
font-family: "SimSun";
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=SimHei]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=SimHei]::before {
|
||||
content: "黑体";
|
||||
font-family: "SimHei";
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Microsoft-YaHei]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Microsoft-YaHei]::before {
|
||||
content: "微软雅黑";
|
||||
font-family: "Microsoft YaHei";
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=KaiTi]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=KaiTi]::before {
|
||||
content: "楷体";
|
||||
font-family: "KaiTi";
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=FangSong]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=FangSong]::before {
|
||||
content: "仿宋";
|
||||
font-family: "FangSong";
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Arial]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Arial]::before {
|
||||
content: "Arial";
|
||||
font-family: "Arial";
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Times-New-Roman]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Times-New-Roman]::before {
|
||||
content: "Times New Roman";
|
||||
font-family: "Times New Roman";
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=sans-serif]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=sans-serif]::before {
|
||||
content: "sans-serif";
|
||||
font-family: "sans-serif";
|
||||
}
|
||||
|
||||
.ql-font-SimSun {
|
||||
font-family: "SimSun";
|
||||
}
|
||||
|
||||
.ql-font-SimHei {
|
||||
font-family: "SimHei";
|
||||
}
|
||||
|
||||
.ql-font-Microsoft-YaHei {
|
||||
font-family: "Microsoft YaHei";
|
||||
}
|
||||
|
||||
.ql-font-KaiTi {
|
||||
font-family: "KaiTi";
|
||||
}
|
||||
|
||||
.ql-font-FangSong {
|
||||
font-family: "FangSong";
|
||||
}
|
||||
|
||||
.ql-font-Arial {
|
||||
font-family: "Arial";
|
||||
}
|
||||
|
||||
.ql-font-Times-New-Roman {
|
||||
font-family: "Times New Roman";
|
||||
}
|
||||
|
||||
.ql-font-sans-serif {
|
||||
font-family: "sans-serif";
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,35 @@
|
||||
import Vue from "vue";
|
||||
|
||||
/**
|
||||
* 多层级的对象合并
|
||||
* @param target 目标对象(需要合并到的对象)
|
||||
* @param source 资源(拥有的对象)
|
||||
* @returns {target} 合并后的对象
|
||||
*/
|
||||
function assignObj(target, source) {
|
||||
if (typeof (target) !== 'object' || typeof (source) !== 'object') {
|
||||
return source;
|
||||
}
|
||||
for (let key in source) {
|
||||
target[key] = assignObj(target[key], source[key]);
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取API
|
||||
* @type {{install(): *|{}}} Vue.use默认执行的方法
|
||||
*/
|
||||
export default {
|
||||
install() {
|
||||
Vue.prototype.$api = {}
|
||||
const requireComponents = require.context('./modules', true, /\.js/)
|
||||
requireComponents.keys().forEach(file => {
|
||||
const mod = requireComponents(file);
|
||||
let fileName = file.replace(/\.\/|\.js/g, '');
|
||||
fileName = fileName.split('/').map(item => item.replace(/\./g, '_')).reverse().reduce((p, c) => ({[c]: p}), mod.default);
|
||||
Vue.prototype.$api = assignObj(Vue.prototype.$api, fileName)
|
||||
})
|
||||
return Vue.prototype.$api
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,31 @@
|
||||
import {instance as request} from "@/utils/request";
|
||||
|
||||
|
||||
|
||||
export default {
|
||||
// 获取查询项
|
||||
queryGetQuery(data) {
|
||||
return request({
|
||||
url: `/api/query/getQuery`,
|
||||
method: 'GET',
|
||||
params: data
|
||||
})
|
||||
},
|
||||
// 获取品牌
|
||||
queryGetBrand(data) {
|
||||
return request({
|
||||
url: `/api/query/getBrand`,
|
||||
method: 'GET',
|
||||
params: data
|
||||
})
|
||||
},
|
||||
// 获取车型
|
||||
marketSegmentsVehicleSeries(data) {
|
||||
return request({
|
||||
url: `/api/marketSegmentsCompete/vehicleSeries`,
|
||||
method: 'POST',
|
||||
params: data
|
||||
})
|
||||
},
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import {instance as request} from "@/utils/request";
|
||||
// 细分市场竞争格局
|
||||
export default {
|
||||
// 车型对比
|
||||
chooseStyle(data) {
|
||||
return request({
|
||||
url: `/api/chooseStyle`,
|
||||
method: 'GET',
|
||||
params: data,
|
||||
});
|
||||
},
|
||||
//配置查询
|
||||
configQuery(data) {
|
||||
return request({
|
||||
url: `/api/configQuery`,
|
||||
method: 'GET',
|
||||
params: data,
|
||||
});
|
||||
},
|
||||
//基础信息配置查询
|
||||
configGradientTable(data) {
|
||||
return request({
|
||||
url: `/api/gradientContrast`,
|
||||
method: 'GET',
|
||||
params: data,
|
||||
});
|
||||
},
|
||||
// 添加车型
|
||||
chooseStyleAdd(data) {
|
||||
return request({
|
||||
url: `/api/chooseStyle/add`,
|
||||
method: 'GET',
|
||||
params: data,
|
||||
});
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import {instance as request} from "@/utils/request";
|
||||
// 细分市场竞争格局
|
||||
export default {
|
||||
// 车型对比
|
||||
chooseStyle(data) {
|
||||
return request({
|
||||
url: `/api/chooseStyle`,
|
||||
method: 'GET',
|
||||
params: data,
|
||||
});
|
||||
},
|
||||
//配置查询
|
||||
configQuery(data) {
|
||||
return request({
|
||||
url: `/api/configQuery`,
|
||||
method: 'GET',
|
||||
params: data,
|
||||
});
|
||||
},
|
||||
//基础信息配置查询
|
||||
configBaseQuery(data) {
|
||||
return request({
|
||||
url: `/api/configQuery/carBaseInfo`,
|
||||
method: 'GET',
|
||||
params: data,
|
||||
});
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import {instance as request} from "@/utils/request";
|
||||
|
||||
export default {
|
||||
// 获取查询项
|
||||
queryTableData(data) {
|
||||
return request({
|
||||
url: '/api/eatpContrast',
|
||||
method: 'GET',
|
||||
params: data
|
||||
})
|
||||
},
|
||||
queryOtherData(data) {
|
||||
return request({
|
||||
url: '/api/eatpContrast/page',
|
||||
method: 'GET',
|
||||
params: data
|
||||
})
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import {instance as request} from "@/utils/request";
|
||||
|
||||
export default {
|
||||
// 登录
|
||||
login(data) {
|
||||
return request({
|
||||
url: `/api/login`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
},
|
||||
// 长按ticket登录
|
||||
// loginByTicket(data) {
|
||||
// return request({
|
||||
// url: `/api/cas/validateLogin?service=`+data.service+'&ticket='+data.ticket,
|
||||
// method: 'get'
|
||||
// })
|
||||
// },
|
||||
pageLog(data) {
|
||||
return request({
|
||||
url: `/api/log/log/save?accessPage=`+data,
|
||||
method: 'get'
|
||||
})
|
||||
},
|
||||
// 获取验证码
|
||||
verifyCode(data) {
|
||||
return request({
|
||||
url: `/api/verifyCode`,
|
||||
method: 'get',
|
||||
params: data,
|
||||
responseType: 'arraybuffer'
|
||||
})
|
||||
},
|
||||
// 退出登录
|
||||
logout(data) {
|
||||
return request({
|
||||
url: `/api/logout`,
|
||||
method: 'get',
|
||||
param: data,
|
||||
})
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
import {instance as request} from "@/utils/request";
|
||||
|
||||
export default {
|
||||
|
||||
// 删除
|
||||
delSysRole(data){
|
||||
return request({
|
||||
url: `/api/sys/role/${data.id}`,
|
||||
method: 'DELETE',
|
||||
})
|
||||
},
|
||||
|
||||
// 修改
|
||||
putSysRole(data){
|
||||
return request({
|
||||
url: `/api/sys/role`,
|
||||
method: 'PUT',
|
||||
data
|
||||
})
|
||||
},
|
||||
// 配置角色菜单
|
||||
sysRoleSaveRoleMenu(data){
|
||||
return request({
|
||||
url: `/api/sys/role/saveRoleMenu`,
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
|
||||
// 配置角色首页
|
||||
sysRoleSaveRoleHome(data){
|
||||
return request({
|
||||
url: `/api/sys/role/saveRoleHome`,
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
// 获取角色首页
|
||||
sysRoleGetRoleHome(data){
|
||||
return request({
|
||||
url: `/api/sys/role/getRoleHome`,
|
||||
method: 'GET',
|
||||
params: data
|
||||
})
|
||||
},
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
import {instance as request} from "@/utils/request";
|
||||
|
||||
export default {
|
||||
// 查询菜单
|
||||
sysMenuFindAllMenus(data) {
|
||||
return request({
|
||||
url: `/api/sys/menu/findAllMenus`,
|
||||
method: 'GET',
|
||||
params: data
|
||||
})
|
||||
},
|
||||
// 新增
|
||||
postSysMenu(data) {
|
||||
return request({
|
||||
url: `/api/sys/menu`,
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
},
|
||||
// 删除
|
||||
sysMenuDeleteId(data) {
|
||||
return request({
|
||||
url: `/api/sys/menu/${data.ids}`,
|
||||
method: 'DELETE',
|
||||
})
|
||||
},
|
||||
// 修改
|
||||
putSysMenu(data) {
|
||||
return request({
|
||||
url: `/api/sys/menu`,
|
||||
method: 'PUT',
|
||||
data
|
||||
})
|
||||
},
|
||||
// 角色对应的菜单
|
||||
getSysMenu(data) {
|
||||
return request({
|
||||
url: `/api/sys/menu`,
|
||||
method: 'GET',
|
||||
params: data
|
||||
})
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import {instance as request} from "@/utils/request";
|
||||
// 细分市场竞争格局
|
||||
export default {
|
||||
// 车型对比
|
||||
modelContrastVehicleContrast(data) {
|
||||
return request({
|
||||
url: `/api/modelContrast/vehicleContrast`,
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
},
|
||||
// 获取款型下拉框
|
||||
modelContrastGetKxmcList(data) {
|
||||
return request({
|
||||
url: `/api/modelContrast/getKxmcList`,
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
},
|
||||
// 一个对比组款型对比
|
||||
modelContrastKxContrast(data) {
|
||||
return request({
|
||||
url: `/api/modelContrast/kxContrast`,
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
},
|
||||
|
||||
// 一个对比组的款型对比Execel导出
|
||||
modelContrastKxExcel(data) {
|
||||
return request({
|
||||
url: `/api/modelContrast/kxExcel`,
|
||||
method: 'POST',
|
||||
data,
|
||||
responseType: 'blob'
|
||||
})
|
||||
},
|
||||
// 车型对比Execel导出
|
||||
modelContrastVehicleExcel(data) {
|
||||
return request({
|
||||
url: `/api/modelContrast/vehicleExcel`,
|
||||
method: 'POST',
|
||||
data,
|
||||
responseType: 'blob'
|
||||
})
|
||||
},
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import {instance as request} from "@/utils/request";
|
||||
// 车型竞争格局
|
||||
export default {
|
||||
// Excel导出
|
||||
vehicleModelCompeteDownload(data) {
|
||||
return request({
|
||||
url: `/api/vehicleModelCompete/download`,
|
||||
method: 'GET',
|
||||
params: data,
|
||||
responseType: 'blob'
|
||||
})
|
||||
},
|
||||
// 主销TP
|
||||
vehicleModelCompeteKingpinTP(data) {
|
||||
return request({
|
||||
url: `/api/vehicleModelCompete/kingpinTP`,
|
||||
method: 'POST',
|
||||
params: data
|
||||
})
|
||||
},
|
||||
// 时间段加权TP
|
||||
vehicleModelCompeteWeightedTP(data) {
|
||||
return request({
|
||||
url: `/api/vehicleModelCompete/weightedTP`,
|
||||
method: 'POST',
|
||||
params: data
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
import {instance as request} from "@/utils/request";
|
||||
// 分价格段市占率
|
||||
export default {
|
||||
// 宽表基础数据
|
||||
baseDataList(data) {
|
||||
return request({
|
||||
url: `/api/baseData/list`,
|
||||
method: 'GET',
|
||||
params: data
|
||||
})
|
||||
},
|
||||
// Excel导出
|
||||
baseDataDownload(data) {
|
||||
return request({
|
||||
url: `/api/baseData/download`,
|
||||
method: 'GET',
|
||||
params: data,
|
||||
responseType: 'blob'
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import {instance as request} from "@/utils/request";
|
||||
// 分价格段市占率
|
||||
export default {
|
||||
// 车型趋势Execel导出
|
||||
vehicleTrendVehicleTrendExcel(data) {
|
||||
return request({
|
||||
url: `/api/vehicleTrend/vehicleTrendExcel`,
|
||||
method: 'POST',
|
||||
data,
|
||||
responseType: 'blob'
|
||||
})
|
||||
},
|
||||
// 车型趋势
|
||||
vehicleTrendVehicleTrendMap(data) {
|
||||
return request({
|
||||
url: `/api/vehicleTrend/vehicleTrendMap`,
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import {instance as request} from "@/utils/request";
|
||||
// 细分市场竞争格局
|
||||
export default {
|
||||
// 整体加权TP
|
||||
marketSegmentsCompeteOverallWeightedTP(data) {
|
||||
return request({
|
||||
url: `/api/marketSegmentsCompete/overallWeightedTP`,
|
||||
method: 'POST',
|
||||
params: data
|
||||
})
|
||||
},
|
||||
// 主销TP
|
||||
marketSegmentsCompeteKingpinTP(data) {
|
||||
return request({
|
||||
url: `/api/marketSegmentsCompete/kingpinTP`,
|
||||
method: 'POST',
|
||||
params: data
|
||||
})
|
||||
},
|
||||
// Excel导出
|
||||
marketSegmentsCompeteDownload(data) {
|
||||
return request({
|
||||
url: `/api/marketSegmentsCompete/download`,
|
||||
method: 'GET',
|
||||
params: data,
|
||||
responseType: 'blob'
|
||||
})
|
||||
},
|
||||
// downloadPPT
|
||||
pptDownload(data) {
|
||||
return request({
|
||||
url: `/api/pptDownload/download`,
|
||||
method: 'POST',
|
||||
data,
|
||||
responseType: 'blob'
|
||||
})
|
||||
},
|
||||
// downloadPPT
|
||||
pptDownloads(data) {
|
||||
return request({
|
||||
url: `/api/pptDownload/downloads`,
|
||||
method: 'POST',
|
||||
data,
|
||||
responseType: 'blob'
|
||||
})
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
import {instance as request} from "@/utils/request";
|
||||
// 分价格段市占率
|
||||
export default {
|
||||
// 计算分价格段占比-国别大类
|
||||
priceGetCltPriceStatistic(data) {
|
||||
return request({
|
||||
url: `/api/price/getCltPriceStatistic`,
|
||||
method: 'GET',
|
||||
params: data
|
||||
})
|
||||
},
|
||||
// 计算分价格段占比-细分大类
|
||||
priceGetSltPriceStatistic(data) {
|
||||
return request({
|
||||
url: `/api/price/getSltPriceStatistic`,
|
||||
method: 'GET',
|
||||
params: data
|
||||
})
|
||||
},
|
||||
// 计算分价格段占比-细分大类-图
|
||||
getSltPriceStatisticChart(data) {
|
||||
return request({
|
||||
url: `/api/price/getSltPriceStatisticChart`,
|
||||
method: 'GET',
|
||||
params: data
|
||||
})
|
||||
},
|
||||
// 计算分价格段占比-细分大类-表
|
||||
getSltPriceStatisticTable(data) {
|
||||
return request({
|
||||
url: `/api/price/getSltPriceStatisticTable`,
|
||||
method: 'GET',
|
||||
params: data
|
||||
})
|
||||
},
|
||||
// 计算分价格段占比-整体
|
||||
priceGetToalPriceStatistic(data) {
|
||||
return request({
|
||||
url: `/api/price/getToalPriceStatistic`,
|
||||
method: 'GET',
|
||||
params: data
|
||||
})
|
||||
},
|
||||
|
||||
// priceType: tp msrp showType: 'MIX' type: 0 1 2 unit: 1元 2 万元
|
||||
// excel导出
|
||||
priceDownload(data) {
|
||||
return request({
|
||||
url: `/api/price/download/${data.type}`,
|
||||
method: 'GET',
|
||||
params: data,
|
||||
responseType: 'blob'
|
||||
})
|
||||
},
|
||||
// ppt导出 isUseGb
|
||||
pricePpt(data) {
|
||||
return request({
|
||||
url: `/api/price/ppt`,
|
||||
method: 'GET',
|
||||
params: data,
|
||||
responseType: 'blob'
|
||||
})
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import {instance as request} from "@/utils/request";
|
||||
// 分价格段市占率
|
||||
export default {
|
||||
// 整体趋势Execel导出
|
||||
wholeTrendWholeTrendExcel(data) {
|
||||
return request({
|
||||
url: `/api/wholeTrend/wholeTrendExcel`,
|
||||
method: 'POST',
|
||||
data,
|
||||
responseType: 'blob'
|
||||
})
|
||||
},
|
||||
// 整体趋势
|
||||
wholeTrendWholeTrendMap(data) {
|
||||
return request({
|
||||
url: `/api/wholeTrend/wholeTrendMap`,
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
import {instance as request} from "@/utils/request";
|
||||
export function reportUploadPicFile(data){
|
||||
return request({
|
||||
url: `/api/report/uploadPicFile`,
|
||||
method: 'POST',
|
||||
data,
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
}
|
||||
})
|
||||
}
|
||||
export default {
|
||||
// 日志列表
|
||||
reportLogList(data){
|
||||
return request({
|
||||
url: `/api/reportLog/list`,
|
||||
method: 'GET',
|
||||
params: data
|
||||
})
|
||||
},
|
||||
// 标签管理
|
||||
labelAdd(data){
|
||||
return request({
|
||||
url: `/api/label/add`,
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
},
|
||||
// 标签列表
|
||||
labelList(data){
|
||||
return request({
|
||||
url: `/api/label/list`,
|
||||
method: 'GET',
|
||||
params: data
|
||||
})
|
||||
},
|
||||
// 标签删除|单个
|
||||
labelDeleteId(data){
|
||||
return request({
|
||||
url: `/api/label/delete/${data.id}`,
|
||||
method: 'POST',
|
||||
})
|
||||
},
|
||||
|
||||
// 新增或编辑报告
|
||||
reportAdd(data){
|
||||
return request({
|
||||
url: `/api/report/add`,
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
},
|
||||
// 详情||上传文件
|
||||
reportUploadFile(data){
|
||||
return request({
|
||||
url: `/api/report/uploadFile`,
|
||||
method: 'POST',
|
||||
data,
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
}
|
||||
})
|
||||
},
|
||||
// 获取报告预览
|
||||
reportGetReportHtmlId(data){
|
||||
return request({
|
||||
url: `/api/report/getReportHtml/${data.id}`,
|
||||
method: 'GET',
|
||||
})
|
||||
},
|
||||
|
||||
// 删除报告
|
||||
reportDelete(data){
|
||||
return request({
|
||||
url: `/api/report/delete`,
|
||||
method: 'POST',
|
||||
params: data,
|
||||
})
|
||||
},
|
||||
// 报告列表
|
||||
reportList(data){
|
||||
return request({
|
||||
url: `/api/report/list`,
|
||||
method: 'POST',
|
||||
data,
|
||||
})
|
||||
},
|
||||
// 获取报告日期列表
|
||||
reportDateList(data){
|
||||
return request({
|
||||
url: `/api/report/reportDateList`,
|
||||
method: 'GET',
|
||||
params: data,
|
||||
})
|
||||
},
|
||||
// 标签批量保存
|
||||
labelSave(data){
|
||||
return request({
|
||||
url: `/api/label/save`,
|
||||
method: 'POST',
|
||||
data,
|
||||
})
|
||||
},
|
||||
// 下载文件
|
||||
reportDownload(data){
|
||||
return request({
|
||||
url: `/api/report/download`,
|
||||
method: 'GET',
|
||||
params: data,
|
||||
responseType: 'blob'
|
||||
})
|
||||
},
|
||||
// 上传图片
|
||||
reportUploadPicFile(data){
|
||||
return request({
|
||||
url: `/api/report/uploadPicFile`,
|
||||
method: 'POST',
|
||||
data,
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
}
|
||||
})
|
||||
},
|
||||
// 标签顺序
|
||||
labelMove(data){
|
||||
return request({
|
||||
url: `/api/label/move`,
|
||||
method: 'POST',
|
||||
params: data,
|
||||
})
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
import {instance as request} from "@/utils/request";
|
||||
|
||||
export default {
|
||||
// 列表
|
||||
getSysRole(data){
|
||||
return request({
|
||||
url: `/api/sys/role`,
|
||||
method: 'GET',
|
||||
params: data
|
||||
})
|
||||
},
|
||||
// 删除
|
||||
delSysRole(data){
|
||||
return request({
|
||||
url: `/api/sys/role/${data.id}`,
|
||||
method: 'DELETE',
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
// 新增
|
||||
postSysRole(data){
|
||||
return request({
|
||||
url: `/api/sys/role`,
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
},
|
||||
// 修改
|
||||
putSysRole(data){
|
||||
return request({
|
||||
url: `/api/sys/role`,
|
||||
method: 'PUT',
|
||||
data
|
||||
})
|
||||
},
|
||||
// 配置角色菜单
|
||||
sysRoleSaveRoleMenu(data){
|
||||
return request({
|
||||
url: `/api/sys/role/saveRoleMenu`,
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
|
||||
// 配置角色首页
|
||||
sysRoleSaveRoleHome(data){
|
||||
return request({
|
||||
url: `/api/sys/role/saveRoleHome`,
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
// 获取角色首页
|
||||
sysRoleGetRoleHome(data){
|
||||
return request({
|
||||
url: `/api/sys/role/getRoleHome`,
|
||||
method: 'GET',
|
||||
params: data
|
||||
})
|
||||
},
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import {instance as request} from "@/utils/request";
|
||||
|
||||
export default {
|
||||
// 新增|编辑
|
||||
sysUserAddUser(data){
|
||||
return request({
|
||||
url: `/api/sys/user/addUser`,
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
},
|
||||
// 用户启用或禁用
|
||||
sysUserIsUse(data){
|
||||
return request({
|
||||
url: `/api/sys/user/isUse/${data.USID}/${data.type}`,
|
||||
method: 'POST',
|
||||
})
|
||||
},
|
||||
// 获取所有用户
|
||||
sysUserList(data){
|
||||
return request({
|
||||
url: `/api/sys/user/list`,
|
||||
method: 'GET',
|
||||
params: data
|
||||
})
|
||||
},
|
||||
// 获取所有用户
|
||||
sysUserAllList(){
|
||||
return request({
|
||||
url: `/api/sys/user/allList`,
|
||||
method: 'GET',
|
||||
})
|
||||
},
|
||||
// 删除用户
|
||||
sysUserDelete(data){
|
||||
return request({
|
||||
url: `/api/sys/user/delete`,
|
||||
method: 'POST',
|
||||
params: data
|
||||
})
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/* ElementUI */
|
||||
$--color-primary: #1890FF;
|
||||
$--button-primary-border-color: #1890FF;
|
||||
$--button-mini-font-size: 14px;
|
||||
$--button-mini-padding-vertical: 4px;
|
||||
$--button-mini-padding-horizontal: 26px;
|
||||
$--input-mini-height: 24px;
|
||||
$--checkbox-checked-font-color: #1890FF;
|
||||
$--checkbox-checked-icon-color: #1890FF;
|
||||
$--checkbox-checked-background-color: #FFFFFF;
|
||||
$--checkbox-font-weight: 400;
|
||||
$--pagination-button-width: 30px;
|
||||
$--pagination-button-height: 30px;
|
||||
$--menu-item-font-size: 16px;
|
||||
$--menu-item-font-color: #606266;
|
||||
$--select-input-focus-border-color: #1890FF;
|
||||
$--dialog-title-font-size: 16px;
|
||||
$--dialog-padding-primary: 0;
|
||||
|
||||
/* VXE-Table */
|
||||
$vxe-table-border-color: #EBEEF5;
|
||||
$vxe-table-header-font-weight: 500;
|
||||
$vxe-table-header-background-color: #F2F6FC;
|
||||
$vxe-table-header-font-color: #262626;
|
||||
$vxe-table-row-striped-background-color: #FAFAFA;
|
||||
|
||||
/* ElementUI 主题必需 */
|
||||
$--font-path: '~element-ui/lib/theme-chalk/fonts';
|
||||
@import "../../../node_modules/element-ui/packages/theme-chalk/src/index";
|
||||
|
||||
/* VXE-Table 主题必需*/
|
||||
@import '../../../node_modules/vxe-table/styles/index.scss';
|
||||
@@ -0,0 +1,11 @@
|
||||
u {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
em {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
s, strike, del {
|
||||
text-decoration: line-through
|
||||
}
|
||||
|
After Width: | Height: | Size: 5.7 KiB |
|
After Width: | Height: | Size: 222 KiB |
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 291 KiB |
|
After Width: | Height: | Size: 442 B |
|
After Width: | Height: | Size: 192 KiB |
|
After Width: | Height: | Size: 410 B |
|
After Width: | Height: | Size: 656 B |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 565 B |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 738 B |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 922 B |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 637 B |
|
After Width: | Height: | Size: 973 B |
|
After Width: | Height: | Size: 347 B |
|
After Width: | Height: | Size: 452 B |
|
After Width: | Height: | Size: 631 B |
|
After Width: | Height: | Size: 665 B |
|
After Width: | Height: | Size: 656 B |
|
After Width: | Height: | Size: 573 B |
|
After Width: | Height: | Size: 234 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 431 B |
|
After Width: | Height: | Size: 6.7 KiB |
@@ -0,0 +1,340 @@
|
||||
<template>
|
||||
<el-scrollbar class="demo-content">
|
||||
<el-divider>表格</el-divider>
|
||||
<vxe-table class="tree-data" :data="treeData" :empty-render="{name: 'NotData'}" align="center" border height="800px" row-id="id"
|
||||
:tree-config="{transform: true, rowField: 'id', parentField: 'parentId', expandAll: false }">
|
||||
<vxe-column show-overflow show-header-overflow field="date" title="时间" align="left" width="200" tree-node>
|
||||
<template #header>
|
||||
<div class="first-col">
|
||||
<div class="first-col-top">名称</div>
|
||||
<div class="first-col-bottom">类型</div>
|
||||
</div>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<template v-for="item in tableHeader">
|
||||
<vxe-column show-overflow show-header-overflow :field="item.field" :title="item.title"></vxe-column>
|
||||
</template>
|
||||
</vxe-table>
|
||||
|
||||
<el-divider>修改echarts横坐标顺序</el-divider>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<v-chart style="height: 300px;" :options="option1" autoresize theme="dark"></v-chart>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<div class="sort-data">
|
||||
<vuedraggable v-model="sortData">
|
||||
<transition-group>
|
||||
<template v-for="item in sortData">
|
||||
<el-button type="primary" :key="item.id">{{item.name}}</el-button>
|
||||
</template>
|
||||
</transition-group>
|
||||
</vuedraggable>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-divider>周选择器</el-divider>
|
||||
|
||||
<el-date-picker v-model="week" type="week" format="yyyy 第 WW 周" placeholder="选择周" :picker-options="{firstDayOfWeek: 1}"
|
||||
@change="handleWeekChange"/>
|
||||
{{ startDate }}~{{ endDate }} | {{ year_week }}
|
||||
|
||||
<el-divider>自定义ElementUI主题样式</el-divider>
|
||||
<el-button type="primary" size="mini">按钮</el-button>
|
||||
<el-button type="primary" size="small">按钮</el-button>
|
||||
<el-button type="primary" size="medium">按钮</el-button>
|
||||
<el-button type="primary" size="default">按钮</el-button>
|
||||
|
||||
<!--<el-divider>全局指令(获取当前标签的DOM)</el-divider>-->
|
||||
<!--<div v-dom>获取当前标签的DOM</div>-->
|
||||
|
||||
<el-divider>全局过滤器(格式化时间)</el-divider>
|
||||
<div>{{ new Date() | formatDate }}</div>
|
||||
|
||||
<el-divider>全局调用Api(使用请求拦截器)</el-divider>
|
||||
<el-button @click="exFun">Request</el-button>
|
||||
|
||||
<el-divider>vue-echarts</el-divider>
|
||||
<el-button style="margin-bottom: 10px;" @click="changeOption">修改</el-button>
|
||||
<v-chart style="height: 300px;" :options="option" autoresize theme="dark"></v-chart>
|
||||
|
||||
<el-divider>el-scrollbar</el-divider>
|
||||
<p>{{ max }} {{ value }}</p>
|
||||
<el-scrollbar ref="scrollbar" style="height: 200px;border: 1px solid #333;">
|
||||
<p v-for="item in 20" :key="item"
|
||||
style="text-align: center;background: #99a9bf;margin: 10px;line-height: 30px;">{{ item }}</p>
|
||||
</el-scrollbar>
|
||||
<el-slider v-model="value" :max="max" :format-tooltip="formatTooltip"></el-slider>
|
||||
|
||||
<el-divider>VXETable(表格与分页)</el-divider>
|
||||
<vxe-table :empty-render="{name: 'NotData'}" border show-overflow highlight-hover-row ref="xTable" height="200"
|
||||
:sort-config="{trigger: 'cell'}">
|
||||
<vxe-column show-overflow type="seq" width="100"></vxe-column>
|
||||
<vxe-column show-overflow field="name" title="Name" sortable></vxe-column>
|
||||
<vxe-column show-overflow field="sex" title="Sex"></vxe-column>
|
||||
<vxe-column show-overflow field="age" title="Age"></vxe-column>
|
||||
<vxe-column show-overflow field="address" title="Address" show-overflow></vxe-column>
|
||||
</vxe-table>
|
||||
<vxe-pager align="left" :current-page.sync="q.page" :page-size.sync="q.size" :total="q.total"></vxe-pager>
|
||||
|
||||
<el-divider>vuex-persistedstate</el-divider>
|
||||
<el-button @click="saveUserInfo">vuex-persistedstate: {{ $store.state.userInfo }}</el-button>
|
||||
|
||||
<el-divider>uuid</el-divider>
|
||||
<p>uuid: {{ uuid }}</p>
|
||||
|
||||
</el-scrollbar>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {v4 as uuidv4} from "uuid";
|
||||
import vuedraggable from 'vuedraggable'
|
||||
|
||||
export default {
|
||||
name: "Demo",
|
||||
components: {
|
||||
vuedraggable
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
option1: {
|
||||
xAxis: {
|
||||
type: "category",
|
||||
data: [],
|
||||
},
|
||||
yAxis: {
|
||||
type: "value",
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: [],
|
||||
type: "scatter",
|
||||
symbolSize: function (data) {
|
||||
return data[1] / 2.5;
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
sortData: [
|
||||
{id: uuidv4(), name: 'Mon', value: 150},
|
||||
{id: uuidv4(), name: 'Tue', value: 230},
|
||||
{id: uuidv4(), name: 'Wed', value: 224},
|
||||
{id: uuidv4(), name: 'Thu', value: 218},
|
||||
{id: uuidv4(), name: 'Fri', value: 135},
|
||||
{id: uuidv4(), name: 'Sat', value: 147},
|
||||
{id: uuidv4(), name: 'Sun', value: 260},
|
||||
],
|
||||
week: "",
|
||||
year_week: "",
|
||||
startDate: "",
|
||||
endDate: "",
|
||||
option: {
|
||||
xAxis: {
|
||||
type: "category",
|
||||
data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
|
||||
},
|
||||
yAxis: {
|
||||
type: "value",
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: [150, 230, 224, 218, 135, 147, 260],
|
||||
type: "line",
|
||||
},
|
||||
],
|
||||
},
|
||||
max: 0,
|
||||
value: 0,
|
||||
q: {
|
||||
page: 1,
|
||||
size: 20,
|
||||
total: 200,
|
||||
},
|
||||
uuid: uuidv4(),
|
||||
tableHeader: [
|
||||
{ field: 'a', title: '2020-01'},
|
||||
{ field: 'b', title: '2020-02'},
|
||||
{ field: 'c', title: '2020-03'},
|
||||
{ field: 'd', title: '2020-04'},
|
||||
],
|
||||
treeData: [
|
||||
{ id: 10000, parentId: null, a: 'Test1', b: '1111', c: '222', d: '3333' },
|
||||
{ id: 10001, parentId: 10000, a: 'Test1', b: '1111', c: '222', d: '3333' },
|
||||
{ id: 10002, parentId: 10000, a: 'Test1', b: '1111', c: '222', d: '3333' },
|
||||
{ id: 10003, parentId: 10000, a: 'Test1', b: '1111', c: '222', d: '3333' },
|
||||
{ id: 20000, parentId: null, a: 'Test2', b: '1111', c: '222', d: '3333' },
|
||||
{ id: 20001, parentId: 20000, a: 'Test2', b: '1111', c: '222', d: '3333' },
|
||||
{ id: 20002, parentId: 20000, a: 'Test2', b: '1111', c: '222', d: '3333' },
|
||||
{ id: 20003, parentId: 20000, a: 'Test2', b: '1111', c: '222', d: '3333' },
|
||||
{ id: 20004, parentId: 20000, a: 'Test2', b: '1111', c: '222', d: '3333' },
|
||||
{ id: 30000, parentId: null, a: 'Test3', b: '1111', c: '222', d: '3333' },
|
||||
{ id: 30001, parentId: 30000, a: 'Test3', b: '1111', c: '222', d: '3333' },
|
||||
{ id: 40000, parentId: null, a: 'Test4', b: '1111', c: '222', d: '3333' },
|
||||
],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
handleTree(arr){
|
||||
let cloneData = JSON.parse(JSON.stringify(arr)) // 对源数据深度克隆
|
||||
return cloneData.filter((father) => {
|
||||
let branchArr = cloneData.filter(child => father.id == child.parentId); //返回每一项的子级数组
|
||||
father.children = branchArr.length > 0 ? branchArr : null; //如果存在子级,则给父级添加一个children属性,并赋值
|
||||
return father.parentId == -1; //返回第一层
|
||||
})
|
||||
},
|
||||
|
||||
handleWeekChange(val) {
|
||||
let date = `${new Date(val).getFullYear()}-${new Date(val).getMonth() + 1}-${new Date(val).getDate()}`;
|
||||
|
||||
let firstTime = new Date(date).getTime() - 24 * 60 * 60 * 1000;
|
||||
this.startDate = `${new Date(firstTime).getFullYear()}-${new Date(firstTime).getMonth() + 1}-${new Date(firstTime).getDate()}`;
|
||||
|
||||
let lastTime = new Date(date).getTime() + 5 * 24 * 60 * 60 * 1000;
|
||||
this.endDate = `${new Date(lastTime).getFullYear()}-${new Date(lastTime).getMonth() + 1}-${new Date(lastTime).getDate()}`;
|
||||
|
||||
let year = require("moment")(val).utcOffset("+08:00").format("yyyy");
|
||||
let week = require("moment")(val).utcOffset("+08:00").format("WW");
|
||||
this.year_week = `${year} 第 ${week} 周`;
|
||||
},
|
||||
// Api
|
||||
exFun() {
|
||||
console.log(require("moment"));
|
||||
this.$api.ex
|
||||
.exFun()
|
||||
.then((res) => {
|
||||
console.log(res);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
},
|
||||
|
||||
// vue-echarts
|
||||
changeOption() {
|
||||
this.option.series[0].type = "bar";
|
||||
},
|
||||
|
||||
// el-scrollbar
|
||||
scrollChange() {
|
||||
this.max =
|
||||
this.$refs.scrollbar.wrap.scrollHeight -
|
||||
this.$refs.scrollbar.wrap.clientHeight;
|
||||
this.$refs.scrollbar.wrap.onscroll = (e) => {
|
||||
this.value = e.target.scrollTop;
|
||||
};
|
||||
},
|
||||
formatTooltip(value) {
|
||||
this.$refs.scrollbar.wrap.scrollTop = value;
|
||||
},
|
||||
|
||||
// VXETable
|
||||
getTableData() {
|
||||
this.$nextTick(() => {
|
||||
const $table = this.$refs.xTable;
|
||||
const list = [];
|
||||
for (let index = 0; index < 50; index++) {
|
||||
list.push({
|
||||
name: `名称${index}`,
|
||||
sex: "0",
|
||||
num: 123,
|
||||
age: 18,
|
||||
num2: 234,
|
||||
rate: 3,
|
||||
address: "shenzhen",
|
||||
});
|
||||
}
|
||||
$table.loadData(list);
|
||||
});
|
||||
},
|
||||
|
||||
// vuex-persistedstate
|
||||
saveUserInfo() {
|
||||
// this.$store.commit("saveUserInfo", {name: "Lee"});
|
||||
},
|
||||
},
|
||||
created() {
|
||||
console.log("created");
|
||||
},
|
||||
mounted() {
|
||||
this.scrollChange();
|
||||
this.getTableData();
|
||||
console.log("mounted");
|
||||
},
|
||||
updated(){
|
||||
// 修改统计顺序
|
||||
this.option1.xAxis.data = this.sortData.map(item => item.name);
|
||||
this.option1.series[0].data = this.sortData.map(item => [item.name, item.value]);
|
||||
},
|
||||
// 进入组件执行 仅在keep-alive时起作用
|
||||
activated() {
|
||||
this.$refs.scrollbar.wrap.scrollTop = this.value;
|
||||
console.log("activated");
|
||||
},
|
||||
// 离开组件执行 仅在keep-alive时起作用
|
||||
deactivated() {
|
||||
console.log("deactivated");
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.demo-content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 20px;
|
||||
background-color: #FAFAFA;
|
||||
.sort-data{
|
||||
padding: 5px 10px;
|
||||
background-color: #333333;
|
||||
>div>span{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
.el-button{
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
.tree-data{
|
||||
::v-deep .vxe-header--column.col--ellipsis > .vxe-cell:first-child{
|
||||
padding: 0;
|
||||
.first-col {
|
||||
position: relative;
|
||||
height: 40px;
|
||||
width: 200px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
&:before{
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: -2px;
|
||||
top: 20px;
|
||||
width: 204px;
|
||||
height: 1px;
|
||||
transform: rotate(11deg);
|
||||
background-color: #e8eaec;
|
||||
}
|
||||
.first-col-top {
|
||||
flex: 1;
|
||||
text-align: left;
|
||||
padding: 10px 0 0 10px;
|
||||
}
|
||||
.first-col-bottom{
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
padding: 0 10px 10px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
::v-deep .vxe-table--body .vxe-body--row>td:first-child{
|
||||
background-color: #F2F6FC;
|
||||
|
||||
}
|
||||
::v-deep .vxe-table--body tbody> tr:nth-child(2n) td{
|
||||
background-color: #FAFAFA;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,308 @@
|
||||
<template>
|
||||
<div></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from 'echarts/lib/echarts'
|
||||
import debounce from 'lodash/debounce'
|
||||
import {addListener, removeListener} from 'resize-detector'
|
||||
|
||||
// enumerating ECharts events for now
|
||||
const EVENTS = [
|
||||
'legendselectchanged',
|
||||
'legendselected',
|
||||
'legendunselected',
|
||||
'legendscroll',
|
||||
'datazoom',
|
||||
'datarangeselected',
|
||||
'timelinechanged',
|
||||
'timelineplaychanged',
|
||||
'restore',
|
||||
'dataviewchanged',
|
||||
'magictypechanged',
|
||||
'geoselectchanged',
|
||||
'geoselected',
|
||||
'geounselected',
|
||||
'pieselectchanged',
|
||||
'pieselected',
|
||||
'pieunselected',
|
||||
'mapselectchanged',
|
||||
'mapselected',
|
||||
'mapunselected',
|
||||
'axisareaselected',
|
||||
'focusnodeadjacency',
|
||||
'unfocusnodeadjacency',
|
||||
'brush',
|
||||
'brushselected',
|
||||
'rendered',
|
||||
'finished',
|
||||
'click',
|
||||
'dblclick',
|
||||
'mouseover',
|
||||
'mouseout',
|
||||
'mousemove',
|
||||
'mousedown',
|
||||
'mouseup',
|
||||
'globalout',
|
||||
'contextmenu'
|
||||
]
|
||||
|
||||
const ZR_EVENTS = [
|
||||
'click',
|
||||
'mousedown',
|
||||
'mouseup',
|
||||
'mousewheel',
|
||||
'dblclick',
|
||||
'contextmenu'
|
||||
]
|
||||
|
||||
const INIT_TRIGGERS = ['theme', 'initOptions', 'autoresize']
|
||||
const REWATCH_TRIGGERS = ['manualUpdate', 'watchShallow']
|
||||
|
||||
export default {
|
||||
props: {
|
||||
options: Object,
|
||||
theme: [String, Object],
|
||||
initOptions: Object,
|
||||
group: String,
|
||||
autoresize: Boolean,
|
||||
watchShallow: Boolean,
|
||||
manualUpdate: Boolean
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
lastArea: 0
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
group(group) {
|
||||
this.chart.group = group
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
// provide an explicit merge option method
|
||||
mergeOptions(options, notMerge, lazyUpdate) {
|
||||
if (this.manualUpdate) {
|
||||
this.manualOptions = options
|
||||
}
|
||||
|
||||
if (!this.chart) {
|
||||
this.init(options)
|
||||
} else {
|
||||
this.delegateMethod('setOption', options, notMerge, lazyUpdate)
|
||||
}
|
||||
},
|
||||
// just delegates ECharts methods to Vue component
|
||||
// use explicit params to reduce transpiled size for now
|
||||
appendData(params) {
|
||||
this.delegateMethod('appendData', params)
|
||||
},
|
||||
resize(options) {
|
||||
this.delegateMethod('resize', options)
|
||||
},
|
||||
dispatchAction(payload) {
|
||||
this.delegateMethod('dispatchAction', payload)
|
||||
},
|
||||
convertToPixel(finder, value) {
|
||||
return this.delegateMethod('convertToPixel', finder, value)
|
||||
},
|
||||
convertFromPixel(finder, value) {
|
||||
return this.delegateMethod('convertFromPixel', finder, value)
|
||||
},
|
||||
containPixel(finder, value) {
|
||||
return this.delegateMethod('containPixel', finder, value)
|
||||
},
|
||||
showLoading(type, options) {
|
||||
this.delegateMethod('showLoading', type, options)
|
||||
},
|
||||
hideLoading() {
|
||||
this.delegateMethod('hideLoading')
|
||||
},
|
||||
getDataURL(options) {
|
||||
return this.delegateMethod('getDataURL', options)
|
||||
},
|
||||
getConnectedDataURL(options) {
|
||||
return this.delegateMethod('getConnectedDataURL', options)
|
||||
},
|
||||
clear() {
|
||||
this.delegateMethod('clear')
|
||||
},
|
||||
dispose() {
|
||||
this.delegateMethod('dispose')
|
||||
},
|
||||
delegateMethod(name, ...args) {
|
||||
if (!this.chart) {
|
||||
this.init()
|
||||
}
|
||||
return this.chart[name](...args)
|
||||
},
|
||||
delegateGet(methodName) {
|
||||
if (!this.chart) {
|
||||
this.init()
|
||||
}
|
||||
return this.chart[methodName]()
|
||||
},
|
||||
getArea() {
|
||||
return this.$el.offsetWidth * this.$el.offsetHeight
|
||||
},
|
||||
init(options) {
|
||||
if (this.chart) {
|
||||
return
|
||||
}
|
||||
|
||||
let chart = echarts.init(this.$el, this.theme, this.initOptions)
|
||||
|
||||
if (this.group) {
|
||||
chart.group = this.group
|
||||
}
|
||||
|
||||
chart.setOption(options || this.manualOptions || this.options || {}, true)
|
||||
|
||||
// expose ECharts events as custom events
|
||||
EVENTS.forEach(event => {
|
||||
chart.on(event, params => {
|
||||
this.$emit(event, params)
|
||||
})
|
||||
})
|
||||
|
||||
ZR_EVENTS.forEach(event => {
|
||||
chart.getZr().on(event, params => {
|
||||
this.$emit(`zr:${event}`, params)
|
||||
})
|
||||
})
|
||||
|
||||
if (this.autoresize) {
|
||||
this.lastArea = this.getArea()
|
||||
this.__resizeHandler = debounce(() => {
|
||||
if (this.lastArea === 0) {
|
||||
// emulate initial render for initially hidden charts
|
||||
this.mergeOptions({}, true)
|
||||
this.resize()
|
||||
this.mergeOptions(this.options || this.manualOptions || {}, true)
|
||||
} else {
|
||||
this.resize()
|
||||
}
|
||||
this.lastArea = this.getArea()
|
||||
}, 100, {leading: true})
|
||||
addListener(this.$el, this.__resizeHandler)
|
||||
}
|
||||
|
||||
Object.defineProperties(this, {
|
||||
// Only recalculated when accessed from JavaScript.
|
||||
// Won't update DOM on value change because getters
|
||||
// don't depend on reactive values
|
||||
width: {
|
||||
configurable: true,
|
||||
get: () => {
|
||||
return this.delegateGet('getWidth')
|
||||
}
|
||||
},
|
||||
height: {
|
||||
configurable: true,
|
||||
get: () => {
|
||||
return this.delegateGet('getHeight')
|
||||
}
|
||||
},
|
||||
isDisposed: {
|
||||
configurable: true,
|
||||
get: () => {
|
||||
return !!this.delegateGet('isDisposed')
|
||||
}
|
||||
},
|
||||
computedOptions: {
|
||||
configurable: true,
|
||||
get: () => {
|
||||
return this.delegateGet('getOption')
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
this.chart = chart
|
||||
},
|
||||
initOptionsWatcher() {
|
||||
if (this.__unwatchOptions) {
|
||||
this.__unwatchOptions()
|
||||
this.__unwatchOptions = null
|
||||
}
|
||||
|
||||
if (!this.manualUpdate) {
|
||||
this.__unwatchOptions = this.$watch('options', (val, oldVal) => {
|
||||
if (!this.chart && val) {
|
||||
this.init()
|
||||
} else {
|
||||
// mutating `options` will lead to merging
|
||||
// replacing it with new reference will lead to not merging
|
||||
// eg.
|
||||
// `this.options = Object.assign({}, this.options, { ... })`
|
||||
// will trigger `this.chart.setOption(val, true)
|
||||
// `this.options.title.text = 'Trends'`
|
||||
// will trigger `this.chart.setOption(val, false)`
|
||||
this.chart.setOption(val, val !== oldVal)
|
||||
}
|
||||
}, {deep: !this.watchShallow})
|
||||
}
|
||||
},
|
||||
destroy() {
|
||||
if (this.autoresize) {
|
||||
removeListener(this.$el, this.__resizeHandler)
|
||||
}
|
||||
this.dispose()
|
||||
this.chart = null
|
||||
},
|
||||
refresh() {
|
||||
if (this.chart) {
|
||||
this.destroy()
|
||||
this.init()
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.initOptionsWatcher()
|
||||
|
||||
INIT_TRIGGERS.forEach(prop => {
|
||||
this.$watch(prop, () => {
|
||||
this.refresh()
|
||||
}, {deep: true})
|
||||
})
|
||||
|
||||
REWATCH_TRIGGERS.forEach(prop => {
|
||||
this.$watch(prop, () => {
|
||||
this.initOptionsWatcher()
|
||||
this.refresh()
|
||||
})
|
||||
})
|
||||
},
|
||||
mounted() {
|
||||
// auto init if `options` is already provided
|
||||
if (this.options) {
|
||||
this.init()
|
||||
}
|
||||
},
|
||||
activated() {
|
||||
if (this.autoresize) {
|
||||
this.chart && this.chart.resize()
|
||||
}
|
||||
},
|
||||
destroyed() {
|
||||
if (this.chart) {
|
||||
this.destroy()
|
||||
}
|
||||
},
|
||||
connect(group) {
|
||||
if (typeof group !== 'string') {
|
||||
group = group.map(chart => chart.chart)
|
||||
}
|
||||
echarts.connect(group)
|
||||
},
|
||||
disconnect(group) {
|
||||
echarts.disConnect(group)
|
||||
},
|
||||
registerMap(mapName, geoJSON, specialAreas) {
|
||||
echarts.registerMap(mapName, geoJSON, specialAreas)
|
||||
},
|
||||
registerTheme(name, theme) {
|
||||
echarts.registerTheme(name, theme)
|
||||
},
|
||||
graphic: echarts.graphic
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,222 @@
|
||||
<template>
|
||||
<div class="header">
|
||||
<div class="logo">
|
||||
<img src="@/assets/imgs/logo.jpg" alt="">
|
||||
</div>
|
||||
<div class="breadcrumb">
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item :to="{ path: '/report/list', query: {showId: $route.query.id } }"><img
|
||||
src="@/assets/imgs/icon-home.png" alt=""><span>首页</span></el-breadcrumb-item>
|
||||
<el-breadcrumb-item v-if="this.$route.path == '/system/urlIndex'">{{this.$store.state.menuName}}</el-breadcrumb-item>
|
||||
<el-breadcrumb-item v-else-if="this.$route.path == '/system/401Page'">{{this.$store.state.menuName}}</el-breadcrumb-item>
|
||||
<template v-else v-for="item in $route.meta.crumb">
|
||||
<el-breadcrumb-item>{{ item }}</el-breadcrumb-item>
|
||||
</template>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
|
||||
<div style="display: flex;margin-left: auto">
|
||||
<div class="setsys-menu" @click="goSystemPage" v-if="isSystemManager">
|
||||
<img src="../assets/imgs/icon-setting.png" alt="" width="14" height="14">
|
||||
<span>系统设置</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
||||
<el-popover v-model="popoverValue" trigger="click" transition="">
|
||||
<div class="user-operate">
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-button type="text" @click="logout">退出系统</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="user" slot="reference">
|
||||
<img src="@/assets/imgs/avatar.png" alt="">
|
||||
<span>你好,{{$store.state.userInfo.usname}}</span>
|
||||
<i v-if="!popoverValue" class="el-icon-arrow-down"></i>
|
||||
<i v-else class="el-icon-arrow-up"></i>
|
||||
</div>
|
||||
</el-popover>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapGetters} from 'vuex';
|
||||
import {BASE_URL} from "../utils/http";
|
||||
|
||||
export default {
|
||||
name: "Header",
|
||||
data() {
|
||||
return {
|
||||
popoverValue: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
menuData: 'menuData',
|
||||
}),
|
||||
isSystemManager() {
|
||||
return this.menuData.some(menu => menu.id === 'AVL9YSB7ZF');
|
||||
},
|
||||
isSystemManagerBelong() {
|
||||
return this.menuData.some(menu => menu.id === 'AVL9YSB7ZF' && menu.belong == 1);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
// 退出系统
|
||||
logout() {
|
||||
this.$confirm('确定退出系统?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.$api.login.logout().then(_ => {
|
||||
this.$message.success('退出成功');
|
||||
this.$store.commit('saveUserInfo', null);
|
||||
|
||||
// var sevice = "http://"+window.location.host+"/";
|
||||
// var serviceUrl = encodeURIComponent(sevice);
|
||||
//正式
|
||||
// window.open("https://caddmuat.changan.com.cn/cas/logout?service=http://10.64.23.30:7766/home", '_self');
|
||||
//测试
|
||||
// window.open(BASE_URL.BASE_CHANGAN + "/logout?service=" + BASE_URL.BASE_LOCAL + "/login?loginType=1", '_self');
|
||||
this.$router.push('/login');
|
||||
})
|
||||
})
|
||||
},
|
||||
goSystemPage() {
|
||||
if(this.isSystemManagerBelong){
|
||||
if (this.$route.path === '/system/menu') return;
|
||||
this.$store.commit('savePathUrl', '/system/menu');
|
||||
this.$router.push({path: '/system/menu', query: {id: 'AVL9YSB7ZF'}});
|
||||
}else{
|
||||
if(this.$route.path == '/system/401Page'){
|
||||
|
||||
}else{
|
||||
this.$router.replace({name: '401Page', query: {id: 'AVL9YSB7ZF'}});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
background: rgb(4, 71, 155);
|
||||
|
||||
.logo {
|
||||
width: 200px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
width: auto !important;
|
||||
height: 40px !important;
|
||||
// width: 172px;
|
||||
// height: 26px;
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.breadcrumb {
|
||||
padding-left: 30px;
|
||||
height: 100%;
|
||||
|
||||
::v-deep .el-breadcrumb {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
|
||||
.el-breadcrumb__item {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
|
||||
.el-breadcrumb__inner {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
margin-right: 3px;
|
||||
margin-top: -2px;
|
||||
}
|
||||
|
||||
span {
|
||||
color: #FFFFFF;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.el-breadcrumb__separator {
|
||||
margin: 0 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.setsys-menu {
|
||||
margin-right: 10px;
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
/*position: absolute;*/
|
||||
/*right: 225px;*/
|
||||
cursor: pointer;
|
||||
|
||||
span {
|
||||
color: #FFFFFF;
|
||||
margin-left: 5px;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.user {
|
||||
/*position: absolute;*/
|
||||
/*top: 0;*/
|
||||
/*right: 0;*/
|
||||
/*bottom: 0;*/
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 16px;
|
||||
color: #FFFFFF;
|
||||
margin-right: 19px;
|
||||
}
|
||||
|
||||
i {
|
||||
margin-right: 17px;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.user-operate {
|
||||
::v-deep .el-button {
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,194 @@
|
||||
<template>
|
||||
<div class="menu-submenu" :class="{'submenu-active': $route.path.indexOf(path) !== -1}">
|
||||
<!-- 遍历菜单数据 -->
|
||||
<MenuItem :key="item.id" v-for="(item, index) in menuData" :menuItemData="item">
|
||||
<!-- 没有children的子菜单 -->
|
||||
<template v-if="!item.children">
|
||||
<div class="menu-content" :class="{'active': item.href.indexOf($route.path) !== -1 || (item.href==$store.state.pathUrl)}">
|
||||
<div class="menu-data" @click="handleRouter(item)"
|
||||
:style="{'padding-left': item.level >= 2 ? '30px' : '10px'}">
|
||||
<div class="menu-data-flex">
|
||||
<img class="menu-icon" v-if="item.icon" :src="item.icon" alt="">
|
||||
<span> <i class="icon-level2" v-if="item.level===3"></i> {{ item.label }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<!-- 有children的子菜单 -->
|
||||
<template v-else>
|
||||
<div class="menu-content"
|
||||
:class="{'active': item.href.indexOf($route.path) !== -1 || (item.href==$store.state.pathUrl), 'is-collage': !item.isCollage}"
|
||||
@click="collageMenu(item)">
|
||||
<div class="menu-data"
|
||||
:class="item.level === 1 ? 'bor-b' : ''"
|
||||
:style="{'padding-left': item.level >= 2 ? '30px' : '10px'}">
|
||||
<div class="menu-data-flex">
|
||||
<img class="menu-icon" v-if="item.icon" :src="item.icon" alt="">
|
||||
<span>{{ item.label }}</span>
|
||||
</div>
|
||||
<template v-if="item.level === 1">
|
||||
<i v-if="!item.isCollage" class="el-icon-arrow-right" style="margin-right: 12px;"></i>
|
||||
<i v-else class="el-icon-arrow-down" style="margin-right: 12px;"></i>
|
||||
</template>
|
||||
<template v-else>
|
||||
<i v-if="!item.isCollage" class="el-icon-plus" style="margin-right: 12px;"></i>
|
||||
<i v-else class="el-icon-minus" style="margin-right: 12px;"></i>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 递归操作 -->
|
||||
<Menu :menuData="item.children" :path="item.href"></Menu>
|
||||
</template>
|
||||
</MenuItem>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {createLogger} from 'vuex';
|
||||
import MenuItem from "./MenuItem";
|
||||
import login from '../api/modules/login'
|
||||
import store from '../store'
|
||||
export default {
|
||||
name: "Menu",
|
||||
props: ["menuData", "path"],
|
||||
components: {
|
||||
MenuItem
|
||||
},
|
||||
methods: {
|
||||
handleRouter(item) {
|
||||
if(item.belong == 0){
|
||||
this.$store.commit('saveMenuName', item.label);
|
||||
if(this.$route.path == '/system/401Page'){
|
||||
|
||||
}else{
|
||||
this.$router.push({name: '401Page', query: this.$route.query});
|
||||
}
|
||||
}else{
|
||||
this.$store.commit('savePathUrl', item.href);
|
||||
if (item.isUrl && Number(item.isUrl || 0)) {
|
||||
var param = this.$route.query
|
||||
// delete(this.$route.query.itemHref)
|
||||
|
||||
// param.itemHref = item.href
|
||||
if(this.$route.path == '/system/urlIndex'){
|
||||
this.$store.commit('saveMenuName', item.label);
|
||||
login.pageLog(this.$store.state.menuName).then(res => {
|
||||
}).catch(_ => {
|
||||
})
|
||||
}else{
|
||||
this.$store.commit('saveMenuName', item.label);
|
||||
this.$router.push({name: 'urlIndex', query: param});
|
||||
}
|
||||
} else {
|
||||
if (this.$route.path === item.href) return;
|
||||
// delete(this.$route.query.itemHref)
|
||||
this.$router.push({path: item.href, query: this.$route.query});
|
||||
}
|
||||
}
|
||||
},
|
||||
collageMenu(item) {
|
||||
item.isCollage = !item.isCollage;
|
||||
console.log(item.isCollage);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.menu-submenu {
|
||||
background-color: #f3f6fd;
|
||||
|
||||
&.submenu-active {
|
||||
// background-color: #f3f6fd;
|
||||
|
||||
}
|
||||
|
||||
.menu-content {
|
||||
overflow: hidden;
|
||||
height: 48px;
|
||||
|
||||
&.active {
|
||||
.menu-data {
|
||||
position: relative;
|
||||
// background-color: rgba(216, 230, 246, 1);
|
||||
background-color: #c7d0dd;
|
||||
// border-radius: 100px 0 0 100px;
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 4px;
|
||||
background-color: #168fe3;
|
||||
}
|
||||
|
||||
span {
|
||||
// color: rgba(24, 144, 255, 1);
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.is-collage + .menu-submenu {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.menu-data {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
/*justify-content: space-between;*/
|
||||
align-items: center;
|
||||
padding-left: 21px;
|
||||
// margin-top: 6px;
|
||||
height: 100%;
|
||||
// background-color: #EDEDED;
|
||||
|
||||
.menu-data-flex {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.menu-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-right: 5px;
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
color: #262626;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
/*white-space: nowrap;*/
|
||||
}
|
||||
}
|
||||
|
||||
.menu-submenu {
|
||||
.menu-data {
|
||||
span {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.icon-level2 {
|
||||
display: inline-block;
|
||||
width: 3px;
|
||||
height: 3px;
|
||||
background-color: #333;
|
||||
// background-color: rgba(183, 191, 195, 1);
|
||||
border-radius: 50%;
|
||||
margin-right: 3px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.bor-b {
|
||||
border-top: 1px solid #e3e8f3;
|
||||
border-bottom: 1px solid #e3e8f3;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,18 @@
|
||||
<template>
|
||||
<div class="menu-item" :class="{'active': (menuItemData.href.indexOf($route.path) !== -1) || (menuItemData.href == $store.state.pathUrl)}"><slot/></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "MenuItem",
|
||||
props: ['menuItemData']
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.menu-item{
|
||||
&.active{
|
||||
// background: #F8F8FA;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,256 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
title="品牌->车型->款型"
|
||||
style=";font-family: auto"
|
||||
class="my-dialog"
|
||||
:visible.sync="dialogVisible">
|
||||
<div class="AZClass">
|
||||
<div class="word-list" ref="letterList">
|
||||
<div class="letterClass" :class="{hoverClass: clicked == item}"
|
||||
v-for="item in wordList"
|
||||
:key="item"
|
||||
@click="goIndex(item)">
|
||||
{{ item }}
|
||||
</div>
|
||||
</div>
|
||||
<el-cascader-panel style="height:638px" :props="{multiple:false}" ref="groupRef" :options="options"
|
||||
@change="selectFun">
|
||||
<template slot-scope="{ node, data }" :class="{hoverClass: data.level != 3}">
|
||||
<div v-if="data.level != 3">
|
||||
<span v-if="wordList.indexOf(data.label) != -1">{{ data.label }}</span>
|
||||
<span v-else>{{ data.label }}</span>
|
||||
</div>
|
||||
<div v-else style="display: inline-flex;width: 100%;padding-bottom: 5px">
|
||||
<span style="display: inline-block;width: 66%;white-space: break-spaces;line-height: 17px">{{data.data.kxmc}}</span>
|
||||
<span style="display: inline-block;width: 17%;line-height: 17px;position: absolute;left: 66%">{{data.data.msrpw ? (data.data.msrpw + '万') : '-'}}</span>
|
||||
<span style="display: inline-block;width: 17%;line-height: 17px;position: absolute;left: 83%">{{data.data.mix && data.data.mix!='-' ? data.data.mix : '0.00%'}}</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-cascader-panel>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
clicked: '',
|
||||
options: [],
|
||||
wordList: [
|
||||
'A',
|
||||
'B',
|
||||
'C',
|
||||
'D',
|
||||
'E',
|
||||
'F',
|
||||
'G',
|
||||
'H',
|
||||
'I',
|
||||
'J',
|
||||
'K',
|
||||
'L',
|
||||
'M',
|
||||
'N',
|
||||
'O',
|
||||
'P',
|
||||
'Q',
|
||||
'R',
|
||||
'S',
|
||||
'T',
|
||||
'U',
|
||||
'V',
|
||||
'W',
|
||||
'X',
|
||||
'Y',
|
||||
'Z'
|
||||
],
|
||||
dialogVisible: false
|
||||
}
|
||||
},
|
||||
props: ['callback'],
|
||||
mounted() {
|
||||
this.getList()
|
||||
this.clicked = ''
|
||||
},
|
||||
methods: {
|
||||
changeOpen() {
|
||||
this.dialogVisible = !this.dialogVisible
|
||||
},
|
||||
selectFun(item) {
|
||||
if (this.callback && item.length == 3) {
|
||||
this.callback(item)
|
||||
this.dialogVisible = false
|
||||
}
|
||||
},
|
||||
getList() {
|
||||
this.options = []
|
||||
this.$api.config.gradient.chooseStyleAdd().then(res => {
|
||||
this.options = this.formatDataFirst(res.data)
|
||||
// Object.keys(res.data).forEach(key => {
|
||||
// // tag
|
||||
// let d = {
|
||||
// value:key,
|
||||
// label:key
|
||||
// }
|
||||
// this.options.push(d)
|
||||
// // info
|
||||
// let info = res.data[key]
|
||||
// Object.keys(info).forEach(newkey => {
|
||||
// debugger
|
||||
// let ib = {
|
||||
// value:newkey,
|
||||
// label:newkey,
|
||||
// children:info[newkey]
|
||||
// }
|
||||
// this.options.push(ib)
|
||||
// })
|
||||
|
||||
// });
|
||||
//
|
||||
})
|
||||
},
|
||||
formatDataFirst(data) {
|
||||
let list = []
|
||||
Object.keys(data).forEach(key => {
|
||||
// tag
|
||||
let d = {
|
||||
level: 1,
|
||||
value: key,
|
||||
label: key
|
||||
}
|
||||
list.push(d)
|
||||
// info
|
||||
let info = data[key]
|
||||
Object.keys(info).forEach(newkey => {
|
||||
let ib = {
|
||||
level: 1,
|
||||
value: newkey,
|
||||
label: newkey,
|
||||
children: []
|
||||
}
|
||||
ib.children = this.formatData(info[newkey])
|
||||
list.push(ib)
|
||||
})
|
||||
|
||||
});
|
||||
return list
|
||||
},
|
||||
formatData(data) {
|
||||
let list = []
|
||||
Object.keys(data).forEach(key => {
|
||||
let id = data[key]
|
||||
let d = {
|
||||
level: 2,
|
||||
value: key,
|
||||
label: key,
|
||||
children: []
|
||||
}
|
||||
id.forEach(newdata => {
|
||||
let ib = {
|
||||
level: 3,
|
||||
value: newdata,
|
||||
label: newdata['kxmc'] + (newdata['msrpw'] ? (" " + newdata['msrpw']) : '') + " " + newdata['mix'],
|
||||
data: newdata
|
||||
}
|
||||
d.children.push(ib)
|
||||
})
|
||||
// debugger
|
||||
list.push(d)
|
||||
})
|
||||
|
||||
return list
|
||||
},
|
||||
goIndex(params) {
|
||||
const groupRef = this.$refs.groupRef.$children[0].$children[0].$refs.resize
|
||||
const titleRef = this.$refs.groupRef.$children[0].$children[0].$refs.resize.childNodes
|
||||
this.clicked = params
|
||||
titleRef.forEach((item) => {
|
||||
if (item.innerText === params) {
|
||||
// debugger
|
||||
groupRef.parentElement.scrollTo({
|
||||
top: item.offsetTop,
|
||||
behavior: 'smooth' // 平滑移动
|
||||
})
|
||||
}
|
||||
})
|
||||
// groupRef.scrollTop = offsetTop
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.AZClass {
|
||||
// background: #fff;
|
||||
display: flex;
|
||||
// position: absolute;
|
||||
// top: 0;
|
||||
// left: 0;
|
||||
// z-index: 999;
|
||||
}
|
||||
|
||||
.word-list {
|
||||
color: #fff;
|
||||
background-color: #1f69c3;
|
||||
font-size: 14px;
|
||||
line-height: 18px;
|
||||
padding: 6px;
|
||||
text-align: center;
|
||||
width: 30px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.letterClass {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.letterClass:hover {
|
||||
font-size: 16px;
|
||||
font-weight: bolder;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.hoverClass {
|
||||
font-size: 16px;
|
||||
font-weight: bolder;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.el-scrollbar ::v-deep .el-scrollbar__wrap {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.my-dialog {
|
||||
height: 1000px
|
||||
}
|
||||
|
||||
.el-dialog__title {
|
||||
font-family: auto;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style>
|
||||
.AZClass .el-cascader-menu .el-cascader-menu__wrap {
|
||||
height: 630px !important;
|
||||
}
|
||||
|
||||
.my-dialog .el-dialog {
|
||||
width: 930px;
|
||||
}
|
||||
|
||||
.my-dialog .el-cascader-menu {
|
||||
width: 240px;
|
||||
}
|
||||
|
||||
.my-dialog .el-cascader-menu:last-child {
|
||||
width: 420px;
|
||||
}
|
||||
|
||||
.my-dialog .el-cascader-menu:nth-child(3) .el-cascader-node {
|
||||
height: auto;
|
||||
line-height: 17px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,17 @@
|
||||
import Vue from "vue";
|
||||
|
||||
/**
|
||||
* 获取API
|
||||
* @type {{install(): *|{}}} Vue.use默认执行的方法
|
||||
*/
|
||||
export default {
|
||||
install() {
|
||||
const requireComponents = require.context('./modules', false, /\.js/);
|
||||
requireComponents.keys().forEach(file => {
|
||||
const directives = requireComponents(file).default;
|
||||
for (const directive in directives) {
|
||||
Vue.directive(directive, directives[directive]);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,11 @@
|
||||
import Vue from "vue";
|
||||
|
||||
export default {
|
||||
tableMinHeight: {
|
||||
// 指令的定义
|
||||
inserted(el, binding, vnode) {
|
||||
let dom = el.getElementsByClassName('vxe-table--body-wrapper body--wrapper').item(0);
|
||||
dom.style.setProperty('min-height', binding.value, 'important')
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import Vue from "vue";
|
||||
|
||||
/**
|
||||
* 获取API
|
||||
* @type {{install(): *|{}}} Vue.use默认执行的方法
|
||||
*/
|
||||
export default {
|
||||
install() {
|
||||
const requireComponents = require.context('./modules', false, /\.js/);
|
||||
requireComponents.keys().forEach(file => {
|
||||
const filters = requireComponents(file).default;
|
||||
for (const filter in filters) {
|
||||
Vue.filter(filter, filters[filter]);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
export default {
|
||||
formatDate: function (value) {
|
||||
let date = new Date(value);
|
||||
let y = date.getFullYear();
|
||||
let m = date.getMonth() + 1;
|
||||
let d = date.getDate();
|
||||
return `${y}/${m}/${d}`;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
import Vue from 'vue'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
import store from './store'
|
||||
|
||||
import config from "@/utils/config";
|
||||
// VXETable
|
||||
import 'xe-utils'
|
||||
import VXETable from 'vxe-table'
|
||||
import 'vxe-table/lib/style.css'
|
||||
// ElementUI
|
||||
import ElementUI from 'element-ui';
|
||||
import './assets/css/element-variables.scss'
|
||||
// ECharts
|
||||
import 'echarts'
|
||||
import ECharts from './components/ECharts';
|
||||
// Api
|
||||
import Api from './api'
|
||||
|
||||
// 自定义指令
|
||||
import Directive from './directives'
|
||||
// 自定义过滤器
|
||||
import Filter from './filters'
|
||||
// 加密函数
|
||||
import JSEncrypt from '../src/assets/js/jsencrypt.min.js';
|
||||
|
||||
VXETable.setup({
|
||||
table: {
|
||||
resizable: true,
|
||||
}
|
||||
})
|
||||
|
||||
Vue.use(VXETable);
|
||||
// 富文本引用
|
||||
import VueQuillEditor from 'vue-quill-editor'
|
||||
// require styles 引入样式
|
||||
import 'quill/dist/quill.core.css'
|
||||
import 'quill/dist/quill.snow.css'
|
||||
import 'quill/dist/quill.bubble.css'
|
||||
Vue.use(VueQuillEditor)
|
||||
Vue.use(ElementUI, {size: 'mini', zIndex: 3000});
|
||||
Vue.component('v-chart', ECharts);
|
||||
Vue.use(Api);
|
||||
Vue.use(Directive);
|
||||
Vue.use(Filter);
|
||||
Vue.prototype.$JSEncrypt = (data) => {
|
||||
if(data === ''){
|
||||
return '';
|
||||
}
|
||||
let encryptor = new JSEncrypt();
|
||||
encryptor.setPublicKey(config.PUBLIC_KEY);
|
||||
return encryptor.encrypt(data) || '';
|
||||
}
|
||||
|
||||
VXETable.renderer.add('NotData', {
|
||||
// 空内容模板
|
||||
renderEmpty (h, renderOpts) {
|
||||
return [
|
||||
<span>
|
||||
<img width="100" src={require('./assets/imgs/icon-nodata.png')}/>
|
||||
<p style="margin-top: 10px;">暂无数据</p>
|
||||
</span>
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
new Vue({
|
||||
router,
|
||||
store,
|
||||
render: h => h(App)
|
||||
}).$mount('#app')
|
||||
@@ -0,0 +1,81 @@
|
||||
import Vue from 'vue'
|
||||
import VueRouter from 'vue-router'
|
||||
import store from '../store'
|
||||
import login from '../api/modules/login'
|
||||
import {BASE_URL} from "../utils/http"
|
||||
|
||||
Vue.use(VueRouter)
|
||||
|
||||
let routes = [];
|
||||
|
||||
const requireComponents = require.context('./modules', false, /\.js/);
|
||||
requireComponents.keys().forEach(file => routes = [...routes, ...requireComponents(file).default]);
|
||||
|
||||
const router = new VueRouter({
|
||||
mode: 'history',
|
||||
base: process.env.BASE_URL,
|
||||
routes,
|
||||
scrollBehavior(to, from, position) {
|
||||
return position;
|
||||
},
|
||||
})
|
||||
|
||||
// 路由守卫
|
||||
router.beforeEach((to, from, next) => {
|
||||
/**
|
||||
* 仅报告价格板块
|
||||
* 报告板块 http://10.10.1.184:8080/#/report/list?id=XBFBR7UADZ
|
||||
* 价格板块 http://10.10.1.184:8080/#/overall/opricetrend?id=SBME88VTUD
|
||||
*/
|
||||
// store.commit('saveUserInfo', {});
|
||||
// store.commit('saveMenuData', menuTree);
|
||||
// var url = BASE_URL.BASE_LOCAL + '/login?loginType=1'
|
||||
|
||||
// var loginUrl = BASE_URL.BASE_CHANGAN + "/login?service=" + url;
|
||||
// var logoutUrl = BASE_URL.BASE_CHANGAN + "/logout?service=" + url
|
||||
if (to.meta.crumb) {
|
||||
var jumpStr = to.meta.crumb.join('/')
|
||||
if(jumpStr){
|
||||
if (jumpStr == 'urlIndex' && to.path != '/system/401Page') {
|
||||
login.pageLog(store.state.menuName).then(res => {
|
||||
}).catch(_ => {
|
||||
})
|
||||
}else{
|
||||
login.pageLog(jumpStr).then(res => {
|
||||
}).catch(_ => {
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
// debugger
|
||||
// if (to.query.loginType) {
|
||||
// if (to.query.loginType == 1 && to.query.ticket) {
|
||||
// var params = {
|
||||
// service: url,
|
||||
// ticket: to.query.ticket
|
||||
// }
|
||||
// login.loginByTicket(params).then(res => {
|
||||
// if (res.respCode !== '0') {
|
||||
// // this.verifyCode();
|
||||
// // return this.$message.error(res.data.message);
|
||||
// }
|
||||
// // this.$message.success('登录成功');
|
||||
// store.commit('saveUserInfo', res.data);
|
||||
// next('/home');
|
||||
// }).catch(_ => {
|
||||
// window.open(logoutUrl, '_self');
|
||||
// })
|
||||
// } else {
|
||||
// window.open(loginUrl, '_self');
|
||||
// }
|
||||
// } else if (to.path.toLowerCase() !== '/login') {
|
||||
// if (!store.state.userInfo) {
|
||||
// window.open(logoutUrl, '_self');
|
||||
// }
|
||||
// next();
|
||||
// } else {
|
||||
next();
|
||||
// }
|
||||
})
|
||||
|
||||
export default router
|
||||
@@ -0,0 +1,53 @@
|
||||
const routes = [
|
||||
{
|
||||
path: '/system',
|
||||
name: '',
|
||||
component: () => import('../../views/Layout.vue'),
|
||||
children: [
|
||||
{
|
||||
path: 'urlIndex',
|
||||
name: 'urlIndex',
|
||||
component: () => import('../../views/System/urlIndex.vue'),
|
||||
meta: {
|
||||
crumb: ['urlIndex'],
|
||||
}
|
||||
}]},
|
||||
{
|
||||
path: '/',
|
||||
redirect: {
|
||||
name: 'Login'
|
||||
// path: '/report/list?id=XBFBR7UADZ'
|
||||
}
|
||||
},
|
||||
// 登录
|
||||
{
|
||||
path: '/login',
|
||||
name: 'Login',
|
||||
component: () => import('../../views/Login.vue')
|
||||
},
|
||||
// // 注册
|
||||
// {
|
||||
// path: '/register',
|
||||
// name: 'Register',
|
||||
// component: () => import('../../views/Register.vue')
|
||||
// },
|
||||
// 首页
|
||||
// {
|
||||
// path: '/home',
|
||||
// name: 'Home',
|
||||
// component: () => import('../../views/Home.vue')
|
||||
// },
|
||||
{
|
||||
path: '/layout',
|
||||
name: 'LayoutBox',
|
||||
component: () => import('../../views/Layout.vue')
|
||||
},
|
||||
// // Demo
|
||||
// {
|
||||
// path: '/demo',
|
||||
// name: 'Demo',
|
||||
// component: () => import('../../components/Demo.vue')
|
||||
// },
|
||||
];
|
||||
|
||||
export default routes;
|
||||
@@ -0,0 +1,39 @@
|
||||
const routes = [
|
||||
// 报告管理
|
||||
{
|
||||
path: '/report',
|
||||
name: 'Layout',
|
||||
component: () => import('../../views/Layout.vue'),
|
||||
children: [
|
||||
// 报告列表
|
||||
{
|
||||
path: 'list',
|
||||
name: 'ReportList',
|
||||
component: () => import('../../views/Report/ReportList.vue'),
|
||||
meta: {
|
||||
crumb: ['报告列表'],
|
||||
}
|
||||
},
|
||||
// 报告详情
|
||||
{
|
||||
path: 'detail',
|
||||
name: 'ReportDetail',
|
||||
component: () => import('../../views/Report/ReportDetail.vue'),
|
||||
meta: {
|
||||
crumb: ['报告详情'],
|
||||
}
|
||||
},
|
||||
// 报告管理
|
||||
{
|
||||
path: '/report/manager',
|
||||
name: 'ReportManager',
|
||||
component: () => import('../../views/Report/ReportManager.vue'),
|
||||
meta: {
|
||||
crumb: ['报告管理'],
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
];
|
||||
|
||||
export default routes;
|
||||
@@ -0,0 +1,65 @@
|
||||
const routes = [
|
||||
// 系统管理
|
||||
{
|
||||
path: '/system',
|
||||
name: '',
|
||||
component: () => import('../../views/Layout.vue'),
|
||||
children: [
|
||||
// 菜单管理
|
||||
{
|
||||
path: 'menu',
|
||||
name: 'MenuManager',
|
||||
component: () => import('../../views/System/MenuManager.vue'),
|
||||
meta: {
|
||||
crumb: ['菜单管理'],
|
||||
}
|
||||
},
|
||||
// 用户管理
|
||||
{
|
||||
path: 'user',
|
||||
name: 'User',
|
||||
component: () => import('../../views/System/User.vue'),
|
||||
meta: {
|
||||
crumb: ['用户管理'],
|
||||
}
|
||||
},
|
||||
// 角色管理
|
||||
{
|
||||
path: 'role',
|
||||
name: 'Role',
|
||||
component: () => import('../../views/System/Role.vue'),
|
||||
meta: {
|
||||
crumb: ['角色管理'],
|
||||
}
|
||||
},
|
||||
// // 角色管理
|
||||
// {
|
||||
// path: 'mail',
|
||||
// name: 'Mail',
|
||||
// component: () => import('../../views/System/mail.vue'),
|
||||
// meta: {
|
||||
// crumb: ['邮件管理'],
|
||||
// }
|
||||
// },
|
||||
// // 角色管理
|
||||
// {
|
||||
// path: 'notification',
|
||||
// name: 'Notification',
|
||||
// component: () => import('../../views/System/notification.vue'),
|
||||
// meta: {
|
||||
// crumb: ['通知管理'],
|
||||
// }
|
||||
// },
|
||||
{
|
||||
path: '401Page',
|
||||
name: '401Page',
|
||||
component: () => import('../../views/System/401Page.vue'),
|
||||
meta: {
|
||||
crumb: ['暂无权限'],
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
];
|
||||
|
||||
export default routes;
|
||||
@@ -0,0 +1,43 @@
|
||||
import Vue from 'vue'
|
||||
import Vuex from 'vuex'
|
||||
import createPersistedState from 'vuex-persistedstate'
|
||||
|
||||
Vue.use(Vuex)
|
||||
|
||||
export default new Vuex.Store({
|
||||
state: {
|
||||
userInfo: null,
|
||||
isLoading: false,
|
||||
rememberData: null,
|
||||
menuData: [],
|
||||
pathUrl: '',
|
||||
menuName: '',
|
||||
},
|
||||
getters: {
|
||||
menuData: (state) => state.menuData,
|
||||
menuName: (state) => state.menuName,
|
||||
},
|
||||
mutations: {
|
||||
saveUserInfo(state, data) {
|
||||
state.userInfo = data;
|
||||
},
|
||||
saveIsLoading(state, data){
|
||||
state.isLoading = data;
|
||||
},
|
||||
saveRememberData(state, data){
|
||||
state.rememberData = data;
|
||||
},
|
||||
saveMenuData(state, data){
|
||||
state.menuData = data;
|
||||
},
|
||||
savePathUrl(state, data){
|
||||
state.pathUrl = data;
|
||||
},
|
||||
saveMenuName(state, data){
|
||||
state.menuName = data;
|
||||
},
|
||||
},
|
||||
actions: {},
|
||||
modules: {},
|
||||
plugins: [createPersistedState()]
|
||||
})
|
||||
@@ -0,0 +1,3 @@
|
||||
export default {
|
||||
PUBLIC_KEY: `MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDKwvimHNGEiyV5L73llAeTv8O/3c9KLZLjNDpzNVOvzowk1MJySdSh6BiZPFXGLJ49Rrp/0U1L68ZCvC2Zv07YYTrr7Bd8o8lKB9HlUqcJo/seIHrLCLl2ePuLn+NYtIM4xxbbvAOdy5Ep/QbK4aWz8G7vsx8pctijLksYKNBQyQIDAQAB`,
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import {fileType} from "./fileType";
|
||||
|
||||
export const downloadFile = (res) => {
|
||||
let file_name = decodeURI(res.headers["content-disposition"]).split('=').pop();
|
||||
let file_type = file_name.split('.').pop();
|
||||
let blobData = new Blob([res.data], {type: fileType[file_type]});
|
||||
let downloadUrl = window.URL.createObjectURL(blobData);
|
||||
let anchor = document.createElement("a");
|
||||
anchor.href = downloadUrl;
|
||||
anchor.download = file_name;
|
||||
anchor.click();
|
||||
window.URL.revokeObjectURL(blobData);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
export const fileType = {
|
||||
pdf: 'application/pdf',
|
||||
xls: 'application/vnd.ms-excel',
|
||||
xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
doc: 'application/msword',
|
||||
docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
ppt: 'application/vnd.ms-powerpoint',
|
||||
pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
||||
png: 'image/png',
|
||||
jpg: 'image/jpeg',
|
||||
rar: 'application/x-rar',
|
||||
zip: 'application/zip',
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
export const BASE_URL = {
|
||||
// LOGIN_URL : "http://192.168.144.29:9090/cas/login?service=http://192.168.144.22:9966/login?loginType=1",
|
||||
// LOGOUT_URL : "http://192.168.144.29:9090/cas/logout?service=http://192.168.144.22:9966/login?loginType=1",
|
||||
|
||||
//内部测试
|
||||
// BASE_CHANGAN:'http://192.168.144.29:9090/cas',
|
||||
BASE_LOCAL:'http://127.0.0.1:8080',
|
||||
BASE_LOCAL_IMG:'http://127.0.0.1:8080',
|
||||
|
||||
// //企业测试
|
||||
// BASE_CHANGAN:'https://caddmuat.changan.com.cn/cas',
|
||||
// BASE_LOCAL:'https://caddmuat.changan.com.cn/mi',
|
||||
// BASE_LOCAL_IMG:'https://caddmuat.changan.com.cn',
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import Quill from "quill";
|
||||
|
||||
let Parchment = Quill.import("parchment");
|
||||
|
||||
class lineHeightAttributor extends Parchment.Attributor.Style {
|
||||
}
|
||||
|
||||
const lineHeightStyle = new lineHeightAttributor("lineHeight", "line-height", {
|
||||
scope: Parchment.Scope.INLINE,
|
||||
whitelist: ["initial", "1", "1.5", "1.75", "2", "3", "4"]
|
||||
});
|
||||
|
||||
export {lineHeightStyle};
|
||||
@@ -0,0 +1,128 @@
|
||||
[
|
||||
{
|
||||
"id": "37SSNVGSP9",
|
||||
"parentId": "AVL9YSB7ZF",
|
||||
"label": "菜单管理",
|
||||
"href": "/system/menu",
|
||||
"icon": "/api/home/pic//20211208163844522.png"
|
||||
},
|
||||
{
|
||||
"id": "6F46UACEMG",
|
||||
"parentId": "SBME88VTUD",
|
||||
"label": "整体市场价格分析",
|
||||
"href": "overall",
|
||||
"icon": "/api/home/pic//20211209090648732.png"
|
||||
},
|
||||
{
|
||||
"id": "KF8L94BZC4",
|
||||
"parentId": "8SJZZFCZJS",
|
||||
"label": "车型量价查询",
|
||||
"href": "/models/modelsquery",
|
||||
"icon": ""
|
||||
},
|
||||
{
|
||||
"id": "PNK5Z3REGN",
|
||||
"parentId": "6F46UACEMG",
|
||||
"label": "价格趋势",
|
||||
"href": "/overall/opricetrend",
|
||||
"icon": ""
|
||||
},
|
||||
{
|
||||
"id": "UZHN9Z835U",
|
||||
"parentId": "XBFBR7UADZ",
|
||||
"label": "报告列表",
|
||||
"href": "/report/list",
|
||||
"icon": "/api/home/pic//20211209090610575.png"
|
||||
},
|
||||
{
|
||||
"id": "XBFBR7UADZ",
|
||||
"parentId": "6f6fafb4a7",
|
||||
"label": "报告板块",
|
||||
"href": "/report/list",
|
||||
"icon": "/api/home/pic//20211116142717856.png"
|
||||
},
|
||||
{
|
||||
"id": "8SJZZFCZJS",
|
||||
"parentId": "SBME88VTUD",
|
||||
"label": "车型市场价格分析",
|
||||
"href": "models",
|
||||
"icon": "/api/home/pic//20211209090657836.png"
|
||||
},
|
||||
{
|
||||
"id": "A5DMDVJFHF",
|
||||
"parentId": "AVL9YSB7ZF",
|
||||
"label": "角色管理",
|
||||
"href": "/system/role",
|
||||
"icon": "/api/home/pic//20211117143545387.png"
|
||||
},
|
||||
{
|
||||
"id": "ASPYP4MLJZ",
|
||||
"parentId": "XBFBR7UADZ",
|
||||
"label": "报告管理",
|
||||
"href": "/report/manager",
|
||||
"icon": "/api/home/pic//20211209090620133.png"
|
||||
},
|
||||
{
|
||||
"id": "AVL9YSB7ZF",
|
||||
"parentId": "6f6fafb4a7",
|
||||
"label": "系统管理",
|
||||
"href": "/system/menu",
|
||||
"icon": "/api/home/pic//20211117143522174.png"
|
||||
},
|
||||
{
|
||||
"id": "JM54MJCN3X",
|
||||
"parentId": "6F46UACEMG",
|
||||
"label": "分价格段市占率",
|
||||
"href": "/overall/occupancy",
|
||||
"icon": ""
|
||||
},
|
||||
{
|
||||
"id": "KTBEN9KFFW",
|
||||
"parentId": "8SJZZFCZJS",
|
||||
"label": "价格趋势",
|
||||
"href": "/models/mpricetrend",
|
||||
"icon": ""
|
||||
},
|
||||
{
|
||||
"id": "5AFTKUQ2Q5",
|
||||
"parentId": "8SJZZFCZJS",
|
||||
"label": "车型对比分析",
|
||||
"href": "/models/contrast",
|
||||
"icon": ""
|
||||
},
|
||||
{
|
||||
"id": "CC5ZS54PPK",
|
||||
"parentId": "AVL9YSB7ZF",
|
||||
"label": "用户管理",
|
||||
"href": "/system/user",
|
||||
"icon": "/api/home/pic//20211116145901232.png"
|
||||
},
|
||||
{
|
||||
"id": "KFP3AXHFP9",
|
||||
"parentId": "6F46UACEMG",
|
||||
"label": "细分市场竞争格局",
|
||||
"href": "/overall/marketpattern",
|
||||
"icon": ""
|
||||
},
|
||||
{
|
||||
"id": "SBME88VTUD",
|
||||
"parentId": "6f6fafb4a7",
|
||||
"label": "价格板块",
|
||||
"href": "/overall/opricetrend",
|
||||
"icon": "/api/home/pic//20211116153747821.png"
|
||||
},
|
||||
{
|
||||
"id": "2EDDH5GWZJ",
|
||||
"parentId": "8SJZZFCZJS",
|
||||
"label": "车型竞争格局",
|
||||
"href": "/models/modelspattern",
|
||||
"icon": ""
|
||||
},
|
||||
{
|
||||
"id": "6f6fafb4a7",
|
||||
"parentId": "0",
|
||||
"label": "顶级菜单",
|
||||
"href": null,
|
||||
"icon": null
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,104 @@
|
||||
import axios from 'axios';
|
||||
import {Message, Loading} from 'element-ui';
|
||||
import store from '../store';
|
||||
import router from "../router";
|
||||
import {BASE_URL} from "../utils/http";
|
||||
|
||||
// 记录请求个数、加载
|
||||
let count = 0, loading = null;
|
||||
|
||||
// axios实例化
|
||||
const instance = axios.create({
|
||||
baseURL: '/library',
|
||||
// timeout: 60000,
|
||||
headers: {
|
||||
'Cache-Control': 'no-cache',
|
||||
'Pragma': 'no-cache'
|
||||
}
|
||||
});
|
||||
// 添加请求拦截器
|
||||
instance.interceptors.request.use(function (config) {
|
||||
// 在发送请求之前做些什么
|
||||
loading = Loading.service(null);
|
||||
count++;
|
||||
store.commit('saveIsLoading', true);
|
||||
return config;
|
||||
}, function (error) {
|
||||
// 对请求错误做些什么
|
||||
count--;
|
||||
if (count < 1) {
|
||||
loading.close();
|
||||
store.commit('saveIsLoading', false);
|
||||
}
|
||||
Message.error(error);
|
||||
return Promise.reject(error);
|
||||
});
|
||||
|
||||
// 添加响应拦截器
|
||||
instance.interceptors.response.use(function (response) {
|
||||
// 对响应数据做点什么
|
||||
count--;
|
||||
if (count < 1) {
|
||||
loading.close();
|
||||
store.commit('saveIsLoading', false);
|
||||
}
|
||||
|
||||
// 登录超时
|
||||
if (response.data.respCode === '401') {
|
||||
store.commit('saveUserInfo', null);
|
||||
router.push('/login');
|
||||
Message.error('登录超时过期');
|
||||
// var url = 'http://192.168.144.22:9966/login?loginType=1'
|
||||
// // var url = 'http://10.64.23.30:7766/home'
|
||||
//
|
||||
// return window.open('http://192.168.144.29:9090/cas/login?service='+url, '_self');
|
||||
// return window.open('https://caddmuat.changan.com.cn/cas/login?service='+url, '_self');
|
||||
// window.open(BASE_URL.BASE_CHANGAN + "/logout?service=" + BASE_URL.BASE_LOCAL + "/login?loginType=1", '_self');
|
||||
}
|
||||
|
||||
// 请求成功
|
||||
if (response.status === 200) {
|
||||
if (response.data.respCode === "0") {
|
||||
return response.data;
|
||||
} else if (response.data.respCode === "-1") {
|
||||
Message.error(response.data.message);
|
||||
return Promise.reject(response);
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
} else { // 请求失败
|
||||
Message.error(response.data.message);
|
||||
return Promise.reject(response);
|
||||
}
|
||||
|
||||
}, function (error) {
|
||||
// 对响应错误做点什么
|
||||
count--;
|
||||
if (count < 1) {
|
||||
loading.close();
|
||||
store.commit('saveIsLoading', false);
|
||||
}
|
||||
|
||||
// 登录过期
|
||||
if (error.response.status === 401) {
|
||||
store.commit('saveUserInfo', null);
|
||||
router.push('/login');
|
||||
Message.error('登录超时过期');
|
||||
// window.open(BASE_URL.BASE_CHANGAN + "/logout?service=" + BASE_URL.BASE_LOCAL + "/login?loginType=1", '_self');
|
||||
// var url = 'http://192.168.144.22:9966/login?loginType=1'
|
||||
// // var url = 'http://10.64.23.30:7766/home'
|
||||
//
|
||||
// return window.open('http://192.168.144.29:9090/cas/login?service='+url, '_self');
|
||||
// // return window.open('https://caddmuat.changan.com.cn/cas/login?service='+url, '_self');
|
||||
}
|
||||
|
||||
// 判断超时
|
||||
if (error.code === "ECONNABORTED" && error.message.indexOf('timeout') !== -1 && !error.config._retry) {
|
||||
Message.error(error.message);
|
||||
} else {
|
||||
Message.error(error.message);
|
||||
}
|
||||
return Promise.reject(error);
|
||||
});
|
||||
|
||||
export {instance, loading};
|
||||
@@ -0,0 +1,173 @@
|
||||
<template>
|
||||
<el-container>
|
||||
<el-header>
|
||||
<Header></Header>
|
||||
|
||||
</el-header>
|
||||
<el-container class="main-content">
|
||||
<el-aside width="200px">
|
||||
<el-scrollbar class="menu">
|
||||
<Menu :menuData="menuData"></Menu>
|
||||
</el-scrollbar>
|
||||
</el-aside>
|
||||
<el-main>
|
||||
<el-scrollbar class="main main1">
|
||||
<router-view/>
|
||||
</el-scrollbar>
|
||||
</el-main>
|
||||
</el-container>
|
||||
</el-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Header from '@/components/Header';
|
||||
import Menu from '@/components/Menu';
|
||||
|
||||
export default {
|
||||
name: "Layout",
|
||||
components: {
|
||||
Header,
|
||||
Menu
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
menuData: []
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'$route.path': {
|
||||
handler(val) {
|
||||
this.getMenu();
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleTree(arr, parentId) {
|
||||
let cloneData = JSON.parse(JSON.stringify(arr)); // 对源数据深度克隆
|
||||
return cloneData.filter((father) => {
|
||||
let branchArr = cloneData.filter(child => father.id === child.parentId); //返回每一项的子级数组
|
||||
father.children = branchArr.length > 0 ? branchArr : null; //如果存在子级,则给父级添加一个children属性,并赋值
|
||||
return father.parentId === parentId; //返回第一层
|
||||
})
|
||||
},
|
||||
addLevel(data, level) {
|
||||
data.forEach(item => {
|
||||
item.level = level;
|
||||
if (item.children) {
|
||||
this.addLevel(item.children, level + 1);
|
||||
}
|
||||
});
|
||||
return data;
|
||||
},
|
||||
getMenu() {
|
||||
if (!this.$route.query.id) {
|
||||
return this.$router.push({path: '/report/list', query:{"id": "AEHJB8YNJ3"}});
|
||||
}
|
||||
let data = JSON.parse(JSON.stringify(this.$store.state.menuData));
|
||||
let menu = data.filter(item => item.parentId === this.$route.query.id);
|
||||
let menuData = [];
|
||||
let menuFun = (menu) => {
|
||||
menuData = [...menuData, ...menu];
|
||||
let parentIds = menu.map(item => item.id);
|
||||
if (parentIds.length) {
|
||||
menuFun(data.filter(item => parentIds.find(el => el === item.parentId)))
|
||||
}
|
||||
};
|
||||
menuFun(menu);
|
||||
let treeData = this.handleTree(menuData, this.$route.query.id);
|
||||
this.menuData = this.addLevel(treeData, 1);
|
||||
},
|
||||
getSysMenu() {
|
||||
this.$api.role.sysRoleGetRoleHome({roleId: this.$store.state.userInfo.roleIdList[0]}).then(({data}) => {
|
||||
if (data === null) {
|
||||
data = []
|
||||
}
|
||||
data = data.sort((a, b) => a.sort - b.sort);
|
||||
let menu = data;//.filter(item => item.belong);
|
||||
let menuData = [];
|
||||
let menuFun = (menu) => {
|
||||
menuData = [...menuData, ...menu]
|
||||
let parentIds = menu.map(item => item.parentId);
|
||||
if (parentIds.length) {
|
||||
menuFun(data.filter(item => parentIds.find(el => el === item.id)))
|
||||
}
|
||||
}
|
||||
menuFun(menu);
|
||||
|
||||
let treeData = menuData.map(item => ({
|
||||
id: item.id,
|
||||
parentId: item.parentId,
|
||||
label: item.name,
|
||||
href: item.href,
|
||||
icon: item.iconHref,
|
||||
isCollage: true,
|
||||
belong: item.belong,
|
||||
isUrl: item.isUrl
|
||||
}));
|
||||
// 去重
|
||||
let obj = {};
|
||||
treeData.forEach(item => {
|
||||
obj[item.id] = item;
|
||||
})
|
||||
|
||||
this.$store.commit('saveMenuData', Object.values(obj));
|
||||
|
||||
this.getMenu();
|
||||
});
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 判定菜单是否存在,存在则不加载
|
||||
let menuData = this.$store.state.menuData;
|
||||
if (menuData.length == 0) {
|
||||
this.getSysMenu();
|
||||
} else {
|
||||
this.getMenu();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.el-header {
|
||||
background: url("../assets/imgs/bg-header.png") no-repeat center center;
|
||||
background-size: cover;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
height: calc(100vh - 60px);
|
||||
|
||||
.el-aside {
|
||||
background-color: #FFFFFF;
|
||||
|
||||
.menu {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.el-main {
|
||||
background-color: #F8F8FA;
|
||||
padding: 0;
|
||||
|
||||
::v-deep .main.el-scrollbar {
|
||||
height: 100%;
|
||||
|
||||
.el-scrollbar__view {
|
||||
padding: 10px 8px;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .main1.el-scrollbar {
|
||||
height: 100%;
|
||||
|
||||
.el-scrollbar__view {
|
||||
height: 100% !important;
|
||||
padding: 10px 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,171 @@
|
||||
<template>
|
||||
<div class="login">
|
||||
<div class="login-main">
|
||||
<div class="login-box">
|
||||
<el-form :model="form" label-position="top" label-width="80px">
|
||||
<el-form-item>
|
||||
<h1>长安汽车-科技长安,智慧伙伴</h1>
|
||||
</el-form-item>
|
||||
<el-form-item label="用户名:">
|
||||
<el-input v-model="form.username" prefix-icon="el-icon-user" size="small"
|
||||
placeholder="请输入用户名"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="密码:">
|
||||
<el-input v-model="form.password" prefix-icon="el-icon-edit" type="password" size="small"
|
||||
placeholder="请输入密码"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="验证码:">
|
||||
<el-input v-model="form.verifyCode" prefix-icon="el-icon-edit-outline" size="small"
|
||||
placeholder="请输入验证码">
|
||||
<div slot="append" style="width: 100px;height: 30px;">
|
||||
<el-image style="width: 100%; height: 100%" @click="verifyCode" :src="verifyImg"
|
||||
fit="fill"></el-image>
|
||||
</div>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-checkbox v-model="isChecked">记住密码</el-checkbox>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" size="small" style="width: 100%;" @click="login">登录</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {Base64} from "js-base64";
|
||||
|
||||
export default {
|
||||
name: "Login",
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
username: '',
|
||||
password: '',
|
||||
verifyCode: '',
|
||||
},
|
||||
verifyImg: '',
|
||||
isChecked: false,
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.init();
|
||||
},
|
||||
methods: {
|
||||
getQueryVariable(r, variable) {
|
||||
if (r) {
|
||||
var query = r.split('?');
|
||||
if (query && query.length == 2) {
|
||||
var vars = query[1].split("&");
|
||||
for (var i = 0; i < vars.length; i++) {
|
||||
var pair = vars[i].split("=");
|
||||
if (pair[0] == variable) {
|
||||
return pair[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
init() {
|
||||
this.isChecked = !!this.$store.state.rememberData;
|
||||
if (this.isChecked) {
|
||||
this.form.username = this.$store.state.rememberData.username;
|
||||
this.form.password = this.$store.state.rememberData.password;
|
||||
}
|
||||
this.verifyCode();
|
||||
},
|
||||
// 登录
|
||||
login() {
|
||||
if (!this.form.username) {
|
||||
return this.$message.warning('请输入用户名')
|
||||
}
|
||||
if (!this.form.password) {
|
||||
return this.$message.warning('请输入密码')
|
||||
}
|
||||
if (!this.form.verifyCode) {
|
||||
return this.$message.warning('请输入验证码')
|
||||
}
|
||||
if (this.form.verifyCode.length !== 4) {
|
||||
return this.$message.warning('请检查验证码')
|
||||
}
|
||||
this.$store.commit('saveRememberData', this.isChecked ? {
|
||||
username: this.form.username,
|
||||
password: this.form.password
|
||||
} : null);
|
||||
let data = JSON.parse(JSON.stringify(this.form));
|
||||
data.username = this.$JSEncrypt(data.username);
|
||||
data.password = this.$JSEncrypt(data.password);
|
||||
let jsonData = JSON.stringify(data);
|
||||
this.$api.login.login(Base64.encode(jsonData)).then(res => {
|
||||
if (res.respCode !== '0') {
|
||||
this.verifyCode();
|
||||
return this.$message.error(res.data.message);
|
||||
}
|
||||
this.$message.success('登录成功');
|
||||
this.$store.commit('saveUserInfo', res.data);
|
||||
this.$router.push({path: '/report/list', query:{"id": "AEHJB8YNJ3"}});
|
||||
|
||||
}).catch(_ => {
|
||||
this.verifyCode();
|
||||
})
|
||||
},
|
||||
// 获取验证码
|
||||
verifyCode() {
|
||||
this.$api.login.verifyCode({})
|
||||
.then(res => {
|
||||
this.verifyImg = `data: image/jpeg;base64,${btoa(new Uint8Array(res.data).reduce((data, byte) => data + String.fromCharCode(byte), ''))}`
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.login {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #1fc8db;
|
||||
background-image: linear-gradient(45deg, #9fb8ad 0%, #1fc8db 51%, #2cb5e8 75%);
|
||||
position: relative;
|
||||
|
||||
.login-main {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
|
||||
.login-box {
|
||||
background-color: #fff;
|
||||
width: 400px;
|
||||
min-height: 200px;
|
||||
margin-top: 20px;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 0 20px 0 rgb(0 0 0 / .2);
|
||||
padding: 30px 20px;
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
color: #2b2b2b;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
::v-deep .el-form-item {
|
||||
margin-bottom: 10px;
|
||||
|
||||
.el-form-item__label {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.el-input-group__append {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,15 @@
|
||||
<template>
|
||||
<div>
|
||||
注册
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "Register"
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,154 @@
|
||||
<template>
|
||||
<div class="content-height report-detail">
|
||||
<div class="title">
|
||||
<el-tooltip :content="row.name" placement="top-start">
|
||||
<span>{{ row.name || '-' }}</span>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div class="desc">
|
||||
<el-row>
|
||||
<el-col :span="24" class="desc-item">
|
||||
<label>关键词</label>
|
||||
<div>{{ row.keyContent || '-' }}</div>
|
||||
</el-col>
|
||||
<el-col :span="24" class="desc-item">
|
||||
<label>内容摘要</label>
|
||||
<p>{{ row.mainContent || '-' }}</p>
|
||||
</el-col>
|
||||
<el-col :span="24" class="desc-item">
|
||||
<label>所属部门</label>
|
||||
<div>{{ row.department || '-' }}</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="report-download">
|
||||
<span>报告详情</span>
|
||||
<el-button type="primary" @click="downloadRow(row)">报告下载</el-button>
|
||||
</div>
|
||||
<div class="preview-content" v-html="content"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {downloadFile} from "../../utils/downloadFile";
|
||||
|
||||
export default {
|
||||
name: "ReportDetail",
|
||||
data(){
|
||||
return {
|
||||
content: '',
|
||||
row: {},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 预览
|
||||
previewRow() {
|
||||
if(!this.$route.query.row){
|
||||
this.$router.push({path: '/report/list', query: {id: this.$route.query.id}});
|
||||
return
|
||||
}
|
||||
this.row = JSON.parse(this.$route.query.row);
|
||||
this.$api.report.reportGetReportHtmlId({id: this.row.id}).then(({data}) => {
|
||||
this.content = data.content;
|
||||
})
|
||||
},
|
||||
// 下载
|
||||
downloadRow(row){
|
||||
// this.$confirm('此操作将下载所选数据文件, 是否继续?', '提示', {
|
||||
// confirmButtonText: '确定',
|
||||
// cancelButtonText: '取消',
|
||||
// type: 'warning'
|
||||
// }).then(() => {
|
||||
this.$api.report.reportDownload({fileId: row.fileId}).then(res => {
|
||||
downloadFile(res);
|
||||
})
|
||||
// })
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.previewRow();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.report-detail {
|
||||
.title {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
border-bottom: 1px solid #EBEEF5;
|
||||
height: 42px;
|
||||
line-height: 42px;
|
||||
margin: 0 18px 0 22px;
|
||||
text-align: center;
|
||||
|
||||
span {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #262626;
|
||||
}
|
||||
}
|
||||
.desc{
|
||||
padding: 11px 26px 6px 48px;
|
||||
|
||||
.desc-item{
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 12px;
|
||||
label{
|
||||
display: inline-block;
|
||||
height: 19px;
|
||||
line-height: 19px;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: #595959;
|
||||
width: 64px;
|
||||
border-right: 1px solid #BFBFBF;
|
||||
margin-right: 9px;
|
||||
}
|
||||
div,p{
|
||||
flex: 1;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: #434343;
|
||||
}
|
||||
p{
|
||||
line-height: 20px;
|
||||
text-align: justify;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.report-download {
|
||||
height: 40px;
|
||||
background: #F2F6FC;
|
||||
border: 1px solid #EBEEF5;
|
||||
margin: 0 14px 0 13px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 7px 0 9px;
|
||||
|
||||
span {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #262626;
|
||||
}
|
||||
}
|
||||
|
||||
.preview-content {
|
||||
margin: 0 14px 0 13px;
|
||||
padding-bottom: 11px;
|
||||
|
||||
img {
|
||||
max-width: 100% !important;
|
||||
}
|
||||
table{
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,552 @@
|
||||
<template>
|
||||
<div class="content-height report-list">
|
||||
<div class="title">
|
||||
<span>报告列表</span>
|
||||
</div>
|
||||
<div class="tag-search">
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<div class="tag-item">
|
||||
<label class="tag-title">报告年份</label>
|
||||
<el-select v-model="q.year" multiple collapse-tags placeholder="请选择报告年份">
|
||||
<template v-for="item in yearList">
|
||||
<el-option :label="item" :value="item" :key="item"></el-option>
|
||||
</template>
|
||||
</el-select>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<div class="tag-item">
|
||||
<el-tooltip :content="tagData[1].name" placement="top">
|
||||
<label class="tag-title">{{ tagData[1].name }}</label>
|
||||
</el-tooltip>
|
||||
<div class="tag-show" :class="{'active': tagData[1].tagShow}">
|
||||
<el-checkbox :indeterminate="tagData[1].isIndeterminate" v-model="tagData[1].checkAll"
|
||||
@change="(val) => handleCheckAllChange(val, 1)">全部
|
||||
</el-checkbox>
|
||||
<el-checkbox-group v-model="q.labelOneId"
|
||||
@change="(val) => handleCheckedTagsChange(val, 1)">
|
||||
<template v-for="item in tagData[1].tags">
|
||||
<el-checkbox :label="item.id" :key="item.id">{{ item.name }}</el-checkbox>
|
||||
</template>
|
||||
</el-checkbox-group>
|
||||
<i @click="switchTagShow(1)"
|
||||
:class="{'el-icon-arrow-down': !tagData[1].tagShow, 'el-icon-arrow-up': tagData[1].tagShow}"></i>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<div class="tag-item">
|
||||
<el-tooltip :content="tagData[2].name" placement="top">
|
||||
<label class="tag-title">{{ tagData[2].name }}</label>
|
||||
</el-tooltip>
|
||||
<div class="tag-show" :class="{'active': tagData[2].tagShow}">
|
||||
<el-checkbox :indeterminate="tagData[2].isIndeterminate" v-model="tagData[2].checkAll"
|
||||
@change="(val) => handleCheckAllChange(val, 2)">全部
|
||||
</el-checkbox>
|
||||
<el-checkbox-group v-model="q.labelTwoId"
|
||||
@change="(val) => handleCheckedTagsChange(val, 2)">
|
||||
<template v-for="item in tagData[2].tags">
|
||||
<el-checkbox :label="item.id" :key="item.id">{{ item.name }}</el-checkbox>
|
||||
</template>
|
||||
</el-checkbox-group>
|
||||
<i @click="switchTagShow(2)"
|
||||
:class="{'el-icon-arrow-down': !tagData[2].tagShow, 'el-icon-arrow-up': tagData[2].tagShow}"></i>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<div class="tag-item">
|
||||
<el-tooltip :content="tagData[3].name" placement="top">
|
||||
<label class="tag-title">{{ tagData[3].name }}</label>
|
||||
</el-tooltip>
|
||||
<div class="tag-show" :class="{'active': tagData[3].tagShow}">
|
||||
<el-checkbox :indeterminate="tagData[3].isIndeterminate" v-model="tagData[3].checkAll"
|
||||
@change="(val) => handleCheckAllChange(val, 3)">全部
|
||||
</el-checkbox>
|
||||
<el-checkbox-group v-model="q.labelThreeId"
|
||||
@change="(val) => handleCheckedTagsChange(val, 3)">
|
||||
<template v-for="item in tagData[3].tags">
|
||||
<el-checkbox :label="item.id" :key="item.id">{{ item.name }}</el-checkbox>
|
||||
</template>
|
||||
</el-checkbox-group>
|
||||
<i @click="switchTagShow(3)"
|
||||
:class="{'el-icon-arrow-down': !tagData[3].tagShow, 'el-icon-arrow-up': tagData[3].tagShow}"></i>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<div class="tag-item">
|
||||
<label class="tag-title">搜索:</label>
|
||||
<el-input v-model="q.keyContent" placeholder="请输入搜索内容"></el-input>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="12" align="right" class="tag-btns">
|
||||
<el-button type="primary" @click="search">查询</el-button>
|
||||
<el-button type="default" @click="reset">重置</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="table">
|
||||
<vxe-table :data="tableData" :empty-render="{name: 'NotData'}" align="center" border stripe v-table-min-height="'calc(100vh - 420px)'">
|
||||
<vxe-column show-overflow show-header-overflow type="seq" title="序号" width="77">
|
||||
<template #default="{ row, rowIndex }">
|
||||
{{ rowIndex + (q.pageNo - 1) * q.pageSize + 1 }}
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column show-header-overflow field="name" title="报告名称">
|
||||
<template #default="{ row, rowIndex }">
|
||||
<div class="row-info">
|
||||
<img v-if="row.fileType === '3'" class="icon-file-type" src="@/assets/imgs/icon-pdf.png" alt="">
|
||||
<img v-if="row.fileType === '4'" class="icon-file-type" src="@/assets/imgs/icon-doc.png" alt="">
|
||||
<img v-if="row.fileType === '1'" class="icon-file-type" src="@/assets/imgs/icon-ppt.png" alt="">
|
||||
<img v-if="row.fileType === '2'" class="icon-file-type" src="@/assets/imgs/icon-excel.png" alt="">
|
||||
|
||||
<div class="row-text">
|
||||
<label class="row-title" @click="goReportDetail(row)">
|
||||
<el-tooltip :content="row.name" placement="top-start">
|
||||
<span>{{row.name}}</span>
|
||||
</el-tooltip>
|
||||
</label>
|
||||
<div class="tag-info">
|
||||
<span class="icon-tag-item"><img src="@/assets/imgs/icon-time.png"
|
||||
alt=""><span>{{row.year}}</span></span>
|
||||
<span class="icon-tag-item"><img src="@/assets/imgs/icon-tag01.png"
|
||||
alt=""><span>{{row.labelOneName}}</span></span>
|
||||
<span class="icon-tag-item"><img src="@/assets/imgs/icon-tag02.png"
|
||||
alt=""><span>{{row.labelTwoName}}</span></span>
|
||||
<span class="icon-tag-item"><img src="@/assets/imgs/icon-tag03.png"
|
||||
alt=""><span>{{row.labelThreeName}}</span></span>
|
||||
<!--<span class="icon-tag-item"><span>{{(row.fileSize / 1024 / 1024).toFixed(2) }}MB</span></span>-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column show-overflow show-header-overflow title="操作" width="200" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button type="text" @click="previewRow(row)">预览</el-button>
|
||||
<el-button type="text" @click="downloadRow(row)">下载</el-button>
|
||||
</template>
|
||||
</vxe-column>
|
||||
</vxe-table>
|
||||
<el-pagination
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
:current-page="q.pageNo"
|
||||
:page-sizes="[5, 10, 20]"
|
||||
:page-size="q.pageSize"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total"/>
|
||||
</div>
|
||||
|
||||
<!--预览-->
|
||||
<el-dialog title="预览" :visible.sync="dialogPreview" width="1000px" :close-on-click-modal="false"
|
||||
:close-on-press-escape="false" :fullscreen="fullscreen">
|
||||
<div slot="title" class="dialog-title">
|
||||
<span>预览</span>
|
||||
<img v-if="!fullscreen" class="full-screen" src="@/assets/imgs/icon-full.png" alt="" @click="fullscreen = !fullscreen">
|
||||
<img v-else class="full-screen" src="@/assets/imgs/icon-small.png" alt="" @click="fullscreen = !fullscreen">
|
||||
</div>
|
||||
<div class="preview-dialog-body" :class="{'active': fullscreen}">
|
||||
<!-- <img v-if="!fullscreen" class="full-screen" src="@/assets/imgs/icon-full.png" alt="" @click="fullscreen = !fullscreen">
|
||||
<img v-else class="full-screen" src="@/assets/imgs/icon-small.png" alt="" @click="fullscreen = !fullscreen"> -->
|
||||
<el-scrollbar>
|
||||
<div class="preview-content" v-html="content"></div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {downloadFile} from "../../utils/downloadFile";
|
||||
|
||||
export default {
|
||||
name: "ReportList",
|
||||
data() {
|
||||
return {
|
||||
fullscreen: false,
|
||||
q: {
|
||||
keyContent: '',
|
||||
year: [],
|
||||
labelOneId: [],
|
||||
labelTwoId: [],
|
||||
labelThreeId: [],
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
total: 0,
|
||||
tableData: [],
|
||||
yearList: [],
|
||||
tagData: {
|
||||
1: {
|
||||
name: '',
|
||||
tagShow: false,
|
||||
tags: [],
|
||||
isIndeterminate: true,
|
||||
checkAll: false,
|
||||
},
|
||||
2: {
|
||||
name: '',
|
||||
tagShow: false,
|
||||
tags: [],
|
||||
isIndeterminate: true,
|
||||
checkAll: false,
|
||||
},
|
||||
3: {
|
||||
name: '',
|
||||
tagShow: false,
|
||||
tags: [],
|
||||
isIndeterminate: true,
|
||||
checkAll: false,
|
||||
},
|
||||
},
|
||||
dialogPreview: false, // 预览
|
||||
content: '',
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
this.labelList();
|
||||
this.reportDateList();
|
||||
this.reportList();
|
||||
},
|
||||
// 标签列表
|
||||
labelList() {
|
||||
this.$api.report.labelList().then(({data}) => {
|
||||
this.tagData[1].name = data.labelOne.name;
|
||||
this.tagData[2].name = data.labelTwo.name;
|
||||
this.tagData[3].name = data.labelThree.name;
|
||||
this.tagData[1].tags = data.labelOne.childList;
|
||||
this.tagData[2].tags = data.labelTwo.childList;
|
||||
this.tagData[3].tags = data.labelThree.childList;
|
||||
})
|
||||
},
|
||||
search(){
|
||||
this.q.pageNo = 1;
|
||||
this.reportList();
|
||||
},
|
||||
// 列表
|
||||
reportList() {
|
||||
this.$api.report.reportList(this.q).then(({data}) => {
|
||||
this.tableData = data.records;
|
||||
this.total = data.total;
|
||||
this.q.pageNo = data.current;
|
||||
this.q.pageSize = data.size;
|
||||
if(!data.records.length && this.q.pageNo !== 1){
|
||||
this.q.pageNo = 1;
|
||||
this.reportList();
|
||||
}
|
||||
})
|
||||
},
|
||||
// 监听全选按钮
|
||||
handleCheckAllChange(val, type) {
|
||||
switch (type) {
|
||||
case 1:
|
||||
this.q.labelOneId = val ? this.tagData[type].tags.map(item => item.id) : [];
|
||||
break;
|
||||
case 2:
|
||||
this.q.labelTwoId = val ? this.tagData[type].tags.map(item => item.id) : [];
|
||||
break;
|
||||
case 3:
|
||||
this.q.labelThreeId = val ? this.tagData[type].tags.map(item => item.id) : [];
|
||||
break;
|
||||
}
|
||||
this.tagData[type].isIndeterminate = !val;
|
||||
},
|
||||
// 监听group checkbox
|
||||
handleCheckedTagsChange(val, type) {
|
||||
this.tagData[type].checkAll = (val.length === this.tagData[type].tags.length);
|
||||
this.tagData[type].isIndeterminate = val.length < this.tagData[type].tags.length;
|
||||
},
|
||||
// 切换展开隐藏
|
||||
switchTagShow(type) {
|
||||
this.tagData[type].tagShow = !this.tagData[type].tagShow;
|
||||
},
|
||||
// 日期列表
|
||||
reportDateList() {
|
||||
this.$api.report.reportDateList().then(({data}) => {
|
||||
this.yearList = data.list;
|
||||
})
|
||||
},
|
||||
// 单页数据量
|
||||
handleSizeChange(val) {
|
||||
this.q.pageSize = val;
|
||||
this.q.pageNo = 1;
|
||||
this.reportList();
|
||||
},
|
||||
// 第几页
|
||||
handleCurrentChange(val) {
|
||||
this.q.pageNo = val;
|
||||
this.reportList();
|
||||
},
|
||||
// 预览
|
||||
previewRow(row) {
|
||||
this.fullscreen = false;
|
||||
this.$api.report.reportGetReportHtmlId({id: row.id}).then(({data}) => {
|
||||
this.content = data.content;
|
||||
this.dialogPreview = true;
|
||||
})
|
||||
},
|
||||
// 重置
|
||||
reset() {
|
||||
this.q = {
|
||||
keyContent: '',
|
||||
year: [],
|
||||
labelOneId: [],
|
||||
labelTwoId: [],
|
||||
labelThreeId: [],
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
};
|
||||
this.total = 0;
|
||||
this.tableData = [];
|
||||
this.tagData[1].checkAll = false;
|
||||
this.tagData[1].isIndeterminate = true;
|
||||
this.tagData[2].checkAll = false;
|
||||
this.tagData[2].isIndeterminate = true;
|
||||
this.tagData[3].checkAll = false;
|
||||
this.tagData[3].isIndeterminate = true;
|
||||
this.reportList();
|
||||
},
|
||||
// 下载
|
||||
downloadRow(row) {
|
||||
// this.$confirm('此操作将下载所选数据文件, 是否继续?', '提示', {
|
||||
// confirmButtonText: '确定',
|
||||
// cancelButtonText: '取消',
|
||||
// type: 'warning'
|
||||
// }).then(() => {
|
||||
this.$api.report.reportDownload({fileId: row.fileId}).then(res => {
|
||||
downloadFile(res);
|
||||
})
|
||||
// })
|
||||
},
|
||||
// 跳转到详情
|
||||
goReportDetail(row) {
|
||||
this.$router.push({path: '/report/detail', query: {id: this.$route.query.id, row: JSON.stringify(row)}});
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.init();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.report-list {
|
||||
.title {
|
||||
border-bottom: 1px solid #EBEEF5;
|
||||
height: 42px;
|
||||
line-height: 42px;
|
||||
margin: 0 18px 0 22px;
|
||||
|
||||
span {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #262626;
|
||||
}
|
||||
}
|
||||
|
||||
.tag-search {
|
||||
padding-top: 9px;
|
||||
|
||||
::v-deep .el-date-picker,
|
||||
::v-deep .el-input {
|
||||
width: 240px;
|
||||
}
|
||||
|
||||
.tag-item {
|
||||
margin-bottom: 15px;
|
||||
display: flex;
|
||||
|
||||
.year {
|
||||
::v-deep .el-input__inner {
|
||||
padding: 0 15px !important;
|
||||
}
|
||||
}
|
||||
|
||||
label.tag-title {
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
color: #646464;
|
||||
display: inline-block;
|
||||
width: 112px;
|
||||
height: 19px;
|
||||
line-height: 19px;
|
||||
padding-left: 48px;
|
||||
border-right: 1px solid #BFBFBF;
|
||||
margin-right: 10px;
|
||||
margin-top: 2.5px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.tag-show {
|
||||
flex: 1;
|
||||
margin-right: 28px;
|
||||
height: 19px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
&.active {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
::v-deep .check-active{
|
||||
.el-checkbox__label{
|
||||
color: #434343;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .el-checkbox {
|
||||
margin-right: 15px;
|
||||
color: #434343;
|
||||
}
|
||||
|
||||
::v-deep .el-checkbox__label {
|
||||
min-width: 80px;
|
||||
}
|
||||
|
||||
::v-deep .el-checkbox-group {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.el-icon-arrow-down,
|
||||
.el-icon-arrow-up {
|
||||
color: #C0C4CC;
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tag-btns {
|
||||
padding-right: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.table {
|
||||
margin: 0 14px 0 13px;
|
||||
|
||||
.row-info {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
|
||||
.icon-file-type {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
margin-right: 21px;
|
||||
}
|
||||
|
||||
.row-text {
|
||||
width: calc(100% - 48px - 21px);
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
text-align: left;
|
||||
|
||||
.row-title {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #262626;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: #1890FF;
|
||||
}
|
||||
}
|
||||
|
||||
.tag-info {
|
||||
.icon-tag-item {
|
||||
margin-left: 12px;
|
||||
|
||||
img {
|
||||
width: 12px;
|
||||
margin-right: 5px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
span {
|
||||
display: inline-block;
|
||||
min-width: 80px;
|
||||
font-size: 12px;
|
||||
color: #8C8C8C;
|
||||
font-weight: 500;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .el-pagination {
|
||||
margin-top: 13px;
|
||||
padding-left: 20px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.dialog-title{
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
.full-screen{
|
||||
cursor: pointer;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
vertical-align: middle;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.preview-dialog-body {
|
||||
padding: 9px 25px 17px 22px;
|
||||
height: 60vh;
|
||||
position: relative;
|
||||
&.active{
|
||||
height: calc(100vh - 52px);
|
||||
}
|
||||
.full-screen{
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
right: 35px;
|
||||
top: 10px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
//&:hover{
|
||||
// color: #199BFF;
|
||||
//}
|
||||
}
|
||||
|
||||
::v-deep .el-scrollbar {
|
||||
height: 100%;
|
||||
.el-scrollbar__wrap{
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.el-scrollbar__view {
|
||||
padding: 0 !important;
|
||||
|
||||
.preview-content{
|
||||
img {
|
||||
max-width: 100% !important;
|
||||
}
|
||||
table{
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,18 @@
|
||||
<template>
|
||||
<div style="font-size: 14px">
|
||||
您没有当前页面的权限,请向管理员申请
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Page401',
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
methods: {}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
@@ -0,0 +1,475 @@
|
||||
<template>
|
||||
<div class="content-height system-menu-manager">
|
||||
<div class="title">
|
||||
<span>菜单管理</span>
|
||||
</div>
|
||||
<div class="search">
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<div class="operate-box">
|
||||
<el-button @click="addMenu(null, 0)">新增菜单</el-button>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="table">
|
||||
<vxe-table :data="tableData" :empty-render="{name: 'NotData'}" align="left" border
|
||||
:tree-config="{transform: true, rowField: 'id', parentField: 'parentId', expandAll: true }"
|
||||
v-table-min-height="'calc(100vh - 320px + 44px + 42px)'">
|
||||
<vxe-column show-overflow show-header-overflow type="seq" title="序号" width="77"></vxe-column>
|
||||
<vxe-column show-overflow show-header-overflow title="名称" width="300" align="center" tree-node>
|
||||
<template #default="{ row, level }">
|
||||
<div class="menu-image">
|
||||
<el-image v-if="level === 0 || level === 2" :src="row.iconHref"></el-image>
|
||||
<span>{{row.name}}</span>
|
||||
</div>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column show-overflow show-header-overflow field="href" title="路径" align="center"></vxe-column>
|
||||
<vxe-column show-overflow show-header-overflow field="sort" title="排序" width="60"
|
||||
align="center"></vxe-column>
|
||||
<vxe-column show-overflow show-header-overflow field="remarks" title="描述" align="center"></vxe-column>
|
||||
<vxe-column show-overflow show-header-overflow title="操作" width="200" fixed="right" align="center">
|
||||
<template #default="{ row, level }">
|
||||
<el-button type="text" @click="addMenu(row, level)">添加子菜单</el-button>
|
||||
<el-button type="text" @click="modifyRow(row, level)">编辑</el-button>
|
||||
<el-button type="text" class="del-btn" @click="deleteRow(row)">删除</el-button>
|
||||
</template>
|
||||
</vxe-column>
|
||||
</vxe-table>
|
||||
</div>
|
||||
<!-- 新增/编辑/查看 菜单 -->
|
||||
<el-dialog :title="dialogTitle + '菜单'" :visible.sync="dialogMenu" width="750px" :close-on-click-modal="false"
|
||||
:close-on-press-escape="false" modal-append-to-body append-to-body>
|
||||
<div class="menu-form">
|
||||
<el-form :model="form" label-width="186px" :disabled="mode === 'view'">
|
||||
<el-form-item label="菜单名称:" required>
|
||||
<el-input v-model="form.name" maxlength="20" placeholder="请输入菜单名称" show-word-limit></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="菜单路径:">
|
||||
|
||||
<el-input v-model="form.href" placeholder="请输入菜单路径" show-word-limit></el-input>
|
||||
|
||||
<!--<el-select v-model="form.href" filterable placeholder="请选择菜单路径">-->
|
||||
<!--<el-option label="-" value=""></el-option>-->
|
||||
<!--<template v-for="item in pathList">-->
|
||||
<!--<el-option :label="item" :value="item" :key="item"></el-option>-->
|
||||
<!--</template>-->
|
||||
<!--</el-select>-->
|
||||
</el-form-item>
|
||||
<el-form-item label="菜单图标:" class="icon-menu-item" v-if="level === 0 || level === 2">
|
||||
<el-upload action="#" :http-request="(params)=>uploadFile(params)"
|
||||
:show-file-list="false" :before-upload="beforeUploadFile">
|
||||
<span class="icon-menu-text">
|
||||
<img v-if="form.icon" :src="form.iconHref" alt="" class="icon-menu">
|
||||
<i v-else class="el-icon-plus"></i>
|
||||
</span>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<el-form-item label="菜单排序:" required>
|
||||
<el-input-number v-model="form.sort" controls-position="right" :min="1" :step="1"
|
||||
step-strictly></el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item label="菜单描述:">
|
||||
<el-input v-model="form.remarks" maxlength="500" type="textarea" placeholder="请填写"
|
||||
show-word-limit></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="跳转网页:" class="jumpClass">
|
||||
<el-checkbox v-model="form.isUrl" true-label="1" false-label="0"></el-checkbox>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="done">
|
||||
<el-button v-if="mode !== 'view'" type="primary" @click="postOrPutSysMenu">确定</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {fileType} from "@/utils/fileType";
|
||||
|
||||
export default {
|
||||
name: "MenuManager",
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
name: '', // 名称
|
||||
href: '', // 路径
|
||||
icon: '', // 图标
|
||||
iconHref: '', // 图标路径
|
||||
sort: '', // 排序
|
||||
remarks: '', // 描述
|
||||
id: '',
|
||||
parentId: '',
|
||||
isUrl: 0,
|
||||
},
|
||||
tableData: [],
|
||||
dialogMenu: false,
|
||||
mode: '',
|
||||
pathList: [],
|
||||
level: 0,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
this.sysMenuFindAllMenus();
|
||||
this.getRouterPath();
|
||||
},
|
||||
// 菜单
|
||||
sysMenuFindAllMenus() {
|
||||
this.$api.menu.sysMenuFindAllMenus().then(({data}) => {
|
||||
this.tableData = data.filter(item => item.id !== '6f6fafb4a7').sort((a, b) => {
|
||||
return a.sort - b.sort;
|
||||
});
|
||||
})
|
||||
},
|
||||
// 新增弹窗
|
||||
addMenu(row, level) {
|
||||
this.mode = 'add';
|
||||
this.level = level + 1;
|
||||
this.form = {
|
||||
name: '', // 名称
|
||||
href: '', // 路径
|
||||
icon: '', // 图标
|
||||
iconHref: '', // 图标路径
|
||||
sort: '', // 排序
|
||||
remarks: '', // 描述
|
||||
id: '',
|
||||
parentId: '',
|
||||
isUrl: 0,
|
||||
};
|
||||
this.form.parentId = row ? row.id : '6f6fafb4a7';
|
||||
this.dialogMenu = true;
|
||||
},
|
||||
// 新增 修改
|
||||
postOrPutSysMenu() {
|
||||
if (!this.form.name) {
|
||||
return this.$message.warning('请输入菜单名称');
|
||||
}
|
||||
if (this.level === 0 || this.level === 2) {
|
||||
// if (!this.form.icon) {
|
||||
// return this.$message.warning('请上传菜单图标');
|
||||
// }
|
||||
}
|
||||
if (this.mode === 'add') {
|
||||
this.$api.menu.postSysMenu(this.form).then(_ => {
|
||||
this.$message.success('操作成功');
|
||||
this.dialogMenu = false;
|
||||
this.sysMenuFindAllMenus();
|
||||
})
|
||||
}
|
||||
if (this.mode === 'modify') {
|
||||
this.$api.menu.putSysMenu(this.form).then(_ => {
|
||||
this.$message.success('操作成功');
|
||||
this.dialogMenu = false;
|
||||
this.sysMenuFindAllMenus();
|
||||
})
|
||||
}
|
||||
},
|
||||
// 图标上传
|
||||
uploadFile(params) {
|
||||
let fd = new FormData();
|
||||
fd.append('file', params.file);
|
||||
this.$api.report.reportUploadPicFile(fd).then(({data}) => {
|
||||
this.form.icon = data.key;
|
||||
this.form.iconHref = data.value;
|
||||
})
|
||||
},
|
||||
beforeUploadFile(file) {
|
||||
const isType = (file.type === fileType.png || file.type === fileType.jpg);
|
||||
const isSize = file.size / 1024 / 1024 < 2;
|
||||
if (!isType) {
|
||||
this.$message.error('仅能上传 png|jpg 格式文件');
|
||||
}
|
||||
if (!isSize) {
|
||||
this.$message.error('您最大可上传2M文件');
|
||||
}
|
||||
return isType && isSize;
|
||||
},
|
||||
// 删除
|
||||
deleteRow(row) {
|
||||
this.$confirm('此操作将删除所选数据, 是否继续?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.$api.menu.sysMenuDeleteId({ids: row.id}).then(_ => {
|
||||
this.$message.success('操作成功');
|
||||
this.sysMenuFindAllMenus();
|
||||
})
|
||||
})
|
||||
},
|
||||
// 编辑
|
||||
modifyRow(row, level) {
|
||||
this.level = level;
|
||||
this.mode = 'modify';
|
||||
this.form = JSON.parse(JSON.stringify(row));
|
||||
this.dialogMenu = true;
|
||||
},
|
||||
// 获取存在路径
|
||||
getRouterPath() {
|
||||
let pathList = [];
|
||||
let pathFun = (data, url) => {
|
||||
data.forEach(item => {
|
||||
if (item.children) {
|
||||
pathFun(item.children, item.path);
|
||||
} else {
|
||||
pathList.push(`${url ? (url + '/') : ''}${item.path}`);
|
||||
}
|
||||
})
|
||||
}
|
||||
pathFun(this.$router.options.routes);
|
||||
this.pathList = pathList;
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
dialogTitle() {
|
||||
switch (this.mode) {
|
||||
case 'add':
|
||||
return '新增';
|
||||
case 'modify':
|
||||
return '编辑';
|
||||
case 'view':
|
||||
return '查看';
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.init();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.jumpClass .el-checkbox {
|
||||
line-height: 36px;
|
||||
}
|
||||
|
||||
.system-menu-manager {
|
||||
.title {
|
||||
border-bottom: 1px solid #EBEEF5;
|
||||
height: 42px;
|
||||
line-height: 42px;
|
||||
margin: 0 18px 0 22px;
|
||||
|
||||
span {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #262626;
|
||||
}
|
||||
}
|
||||
|
||||
.search {
|
||||
.search-box-left {
|
||||
padding-top: 20px;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
|
||||
label {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: #595959;
|
||||
margin-right: 5px;
|
||||
padding-left: 22px;
|
||||
}
|
||||
|
||||
.year {
|
||||
::v-deep .el-input__inner {
|
||||
padding: 0 15px !important;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .el-input {
|
||||
width: 167px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1366px) {
|
||||
::v-deep .el-input {
|
||||
width: 135px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .el-button {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
|
||||
.search-box-right {
|
||||
padding-top: 20px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
padding-right: 14px;
|
||||
}
|
||||
|
||||
.operate-box {
|
||||
padding-left: 13px;
|
||||
padding-bottom: 11px;
|
||||
padding-top: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
.table {
|
||||
margin: 0 14px 0 13px;
|
||||
padding-bottom: 10px;
|
||||
|
||||
// ::v-deep .el-icon-circle-plus,
|
||||
// ::v-deep .el-icon-remove{
|
||||
// font-size: 18px;
|
||||
// margin-top: -4px;
|
||||
// margin-left: -1.5px;
|
||||
// }
|
||||
|
||||
|
||||
.menu-image {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
|
||||
::v-deep .el-image {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
margin: 0 5px;
|
||||
|
||||
.el-image__error {
|
||||
font-size: 12px;
|
||||
line-height: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .el-pagination {
|
||||
margin-top: 13px;
|
||||
padding-left: 20px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.menu-form {
|
||||
padding-top: 26px;
|
||||
|
||||
::v-deep .el-form {
|
||||
padding-right: 79px;
|
||||
|
||||
.icon-menu-item .el-form-item__content > div:first-child {
|
||||
display: flex !important;
|
||||
}
|
||||
|
||||
.el-form-item {
|
||||
margin-bottom: 10px;
|
||||
|
||||
.el-form-item__label {
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #262626;
|
||||
}
|
||||
|
||||
.el-input__inner {
|
||||
min-height: 36px;
|
||||
}
|
||||
|
||||
.el-input__inner,
|
||||
.el-textarea__inner {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: #434343;
|
||||
}
|
||||
|
||||
.el-select {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.el-date-editor {
|
||||
width: 100%;
|
||||
|
||||
.el-input__inner {
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
.el-input__suffix {
|
||||
font-size: 16px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.icon-auth {
|
||||
.el-icon-arrow-up {
|
||||
margin-top: 2px;
|
||||
transform: rotateZ(0) !important;
|
||||
}
|
||||
|
||||
.el-icon-arrow-up:before {
|
||||
content: '';
|
||||
background: url("../../assets/imgs/icon-user.png") no-repeat center center;
|
||||
display: inline-block;
|
||||
width: 12px;
|
||||
height: 14px;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.el-input-number {
|
||||
width: 100%;
|
||||
|
||||
input {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.el-input-number__decrease,
|
||||
.el-input-number__increase {
|
||||
height: 18px;
|
||||
line-height: 18px;
|
||||
font-size: 14px;
|
||||
width: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.icon-menu-text {
|
||||
display: flex;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
overflow: hidden;
|
||||
border: 1px dashed #8C8C8C;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #8C8C8C;
|
||||
font-size: 18px;
|
||||
|
||||
.icon-menu {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.el-button {
|
||||
width: 80px;
|
||||
height: 36px;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.done {
|
||||
text-align: center;
|
||||
padding: 40px 0;
|
||||
|
||||
::v-deep .el-button {
|
||||
width: 80px;
|
||||
height: 36px;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,459 @@
|
||||
<template>
|
||||
<div class="content-height system-role">
|
||||
<div class="title">
|
||||
<span>角色管理</span>
|
||||
</div>
|
||||
<div class="search">
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<div class="operate-box">
|
||||
<el-button @click="addRole">新增角色</el-button>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="table">
|
||||
<vxe-table :data="tableData" :empty-render="{name: 'NotData'}" align="center" border stripe
|
||||
v-table-min-height="'calc(100vh - 320px + 44px + 42px)'">
|
||||
<vxe-column show-overflow show-header-overflow type="seq" title="序号" width="77"></vxe-column>
|
||||
<vxe-column show-overflow show-header-overflow field="rname" title="名称"></vxe-column>
|
||||
<vxe-column show-overflow show-header-overflow field="rdesc" title="描述"></vxe-column>
|
||||
<vxe-column show-overflow show-header-overflow title="操作" width="250" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button type="text" @click="modifyRow(row)">编辑</el-button>
|
||||
<el-button type="text" @click="openPermission(row, 2)">角色权限</el-button>
|
||||
<el-button type="text" @click="openPermission(row, 1)">首页权限</el-button>
|
||||
<el-button type="text" class="del-btn" @click="delSysRole(row)">删除</el-button>
|
||||
</template>
|
||||
</vxe-column>
|
||||
</vxe-table>
|
||||
</div>
|
||||
<!-- 新增/编辑 角色 -->
|
||||
<el-dialog :title="dialogTitle + '角色'" :visible.sync="dialogRole" width="750px" :close-on-click-modal="false"
|
||||
:close-on-press-escape="false" modal-append-to-body append-to-body>
|
||||
<div class="role-form">
|
||||
<el-form :model="form" label-width="186px" :disabled="mode === 'view'">
|
||||
<el-form-item label="角色名称:" required>
|
||||
<el-input v-model="form.rname" maxlength="10" placeholder="请输入角色名称" show-word-limit></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="角色描述:">
|
||||
<el-input v-model="form.rdesc" maxlength="500" type="textarea" placeholder="请输入角色描述" show-word-limit></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="done">
|
||||
<el-button v-if="mode !== 'view'" type="primary" @click="postOrPutSysRole">确定</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<!-- 角色权限 -->
|
||||
<el-dialog :title="isHomePage === 2 ? '角色权限' : '首页权限'" :visible.sync="dialogPermission" width="750px" :close-on-click-modal="false"
|
||||
:close-on-press-escape="false" modal-append-to-body append-to-body>
|
||||
<div class="permission-form">
|
||||
<vxe-table ref="rolePermission" :data="treeData" :empty-render="{name: 'NotData'}" align="left" border height="300px" row-id="id"
|
||||
:tree-config="{transform: true, rowField: 'id', parentField: 'parentId', expandAll: true }"
|
||||
:checkbox-config="checkboxConfig" :key="tableKey">
|
||||
<vxe-column show-overflow type="checkbox" width="77" align="center"></vxe-column>
|
||||
<vxe-column show-overflow show-header-overflow type="seq" title="序号" width="77"></vxe-column>
|
||||
<vxe-column show-overflow show-header-overflow title="名称" tree-node>
|
||||
<template #default="{ row, level }">
|
||||
<div class="menu-image">
|
||||
<el-image v-if="level === 0 || level === 1" :src="row.iconHref"></el-image>
|
||||
<span>{{ row.name }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</vxe-column>
|
||||
</vxe-table>
|
||||
<div class="done">
|
||||
<template v-if="isHomePage === 1">
|
||||
<el-button type="primary" @click="sysRoleSaveRoleHome">确定</el-button>
|
||||
<el-button @click="getSysHome(roleId)">重置</el-button>
|
||||
</template>
|
||||
<template v-if="isHomePage === 2">
|
||||
<el-button type="primary" @click="sysRoleSaveRoleMenu">确定</el-button>
|
||||
<el-button @click="getSysMenu(roleId)">重置</el-button>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {v4 as uuidv4} from 'uuid';
|
||||
export default {
|
||||
name: "Role",
|
||||
data() {
|
||||
return {
|
||||
tableData: [], // 角色列表
|
||||
dialogRole: false,
|
||||
mode: '',
|
||||
form: {
|
||||
rname: '',
|
||||
rdesc: '',
|
||||
rid: ''
|
||||
},
|
||||
dialogPermission: false,
|
||||
treeData: [],
|
||||
checkboxConfig: {
|
||||
checkRowKeys: []
|
||||
},
|
||||
roleId: '',
|
||||
tableKey: uuidv4(),
|
||||
isHomePage: null, // 配置首页 1首页 2权限
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
this.getSysRole();
|
||||
this.sysMenuFindAllMenus();
|
||||
},
|
||||
/* =============================================== 角色列表 =============================================== */
|
||||
// 角色列表
|
||||
getSysRole() {
|
||||
this.$api.role.getSysRole().then(({data}) => {
|
||||
this.tableData = data;
|
||||
})
|
||||
},
|
||||
// 删除角色
|
||||
delSysRole(row) {
|
||||
this.$confirm('此操作将删除所选角色, 是否继续?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.$api.role.delSysRole({id: row.rid}).then(({data}) => {
|
||||
this.$message.success('操作成功');
|
||||
this.getSysRole();
|
||||
})
|
||||
})
|
||||
},
|
||||
/* =============================================== 角色弹窗 =============================================== */
|
||||
// 新增角色
|
||||
addRole() {
|
||||
this.mode = 'add';
|
||||
this.form = {
|
||||
rname: '',
|
||||
rdesc: '',
|
||||
rid: ''
|
||||
}
|
||||
this.dialogRole = true;
|
||||
},
|
||||
// 编辑角色
|
||||
modifyRow(row) {
|
||||
this.mode = 'modify';
|
||||
this.form = {
|
||||
rname: row.rname,
|
||||
rdesc: row.rdesc,
|
||||
rid: row.rid
|
||||
}
|
||||
this.dialogRole = true;
|
||||
},
|
||||
// 新增 修改
|
||||
postOrPutSysRole() {
|
||||
if (!this.form.rname) {
|
||||
return this.$message.warning('请输入角色名称');
|
||||
}
|
||||
if (this.mode === 'add') {
|
||||
this.$api.role.postSysRole(this.form).then(_ => {
|
||||
this.$message.success('操作成功');
|
||||
this.dialogRole = false;
|
||||
this.getSysRole();
|
||||
})
|
||||
}
|
||||
if (this.mode === 'modify') {
|
||||
this.$api.role.putSysRole(this.form).then(_ => {
|
||||
this.$message.success('操作成功');
|
||||
this.dialogRole = false;
|
||||
this.getSysRole();
|
||||
})
|
||||
}
|
||||
},
|
||||
/* =============================================== 角色权限 =============================================== */
|
||||
// 获取菜单
|
||||
openPermission(row, type) {
|
||||
this.roleId = row.rid;
|
||||
this.isHomePage = type;
|
||||
if(type === 2){
|
||||
this.$api.menu.getSysMenu({roleId: row.rid}).then(({data}) => {
|
||||
this.checkboxConfig.checkRowKeys = data.filter(item => item.belong === 1).map(item => item.id);
|
||||
this.tableKey = uuidv4();
|
||||
this.dialogPermission = true;
|
||||
})
|
||||
}else if(type === 1) {
|
||||
this.$api.role.sysRoleGetRoleHome({roleId: row.rid}).then(({data}) => {
|
||||
if(data === null){
|
||||
data = []
|
||||
}
|
||||
this.checkboxConfig.checkRowKeys = data.filter(item => item.belong === 1).map(item => item.id);
|
||||
this.tableKey = uuidv4();
|
||||
this.dialogPermission = true;
|
||||
})
|
||||
}
|
||||
},
|
||||
// 获取权限
|
||||
getSysMenu(roleId){
|
||||
this.$api.menu.getSysMenu({roleId}).then(({data}) => {
|
||||
this.checkboxConfig.checkRowKeys = data.filter(item => item.belong === 1).map(item => item.id);
|
||||
this.tableKey = uuidv4();
|
||||
})
|
||||
},
|
||||
// 获取首页
|
||||
getSysHome(roleId){
|
||||
this.$api.role.sysRoleGetRoleHome({roleId}).then(({data}) => {
|
||||
if(data === null){
|
||||
data = []
|
||||
}
|
||||
this.checkboxConfig.checkRowKeys = data.filter(item => item.belong === 1).map(item => item.id);
|
||||
this.tableKey = uuidv4();
|
||||
})
|
||||
},
|
||||
// 添加权限
|
||||
sysRoleSaveRoleMenu() {
|
||||
let ids = this.$refs.rolePermission.getCheckboxRecords().map(item => item.id);
|
||||
let params = {
|
||||
rid: this.roleId,
|
||||
menusstr: ids
|
||||
}
|
||||
this.$api.role.sysRoleSaveRoleMenu(params).then(_ => {
|
||||
this.$message.success('操作成功');
|
||||
this.dialogPermission = false;
|
||||
})
|
||||
},
|
||||
// 首页配置
|
||||
sysRoleSaveRoleHome(){
|
||||
let ids = this.$refs.rolePermission.getCheckboxRecords().map(item => item.id);
|
||||
let params = {
|
||||
rid: this.roleId,
|
||||
menusstr: ids
|
||||
}
|
||||
this.$api.role.sysRoleSaveRoleHome(params).then(_ => {
|
||||
this.$message.success('操作成功');
|
||||
this.dialogPermission = false;
|
||||
})
|
||||
},
|
||||
|
||||
// 菜单
|
||||
sysMenuFindAllMenus() {
|
||||
this.$api.menu.sysMenuFindAllMenus().then(({data}) => {
|
||||
this.treeData = data.filter(item => item.id !== '6f6fafb4a7').sort((a, b) => {
|
||||
return a.sort - b.sort;
|
||||
});
|
||||
})
|
||||
},
|
||||
|
||||
},
|
||||
computed: {
|
||||
dialogTitle() {
|
||||
switch (this.mode) {
|
||||
case 'add':
|
||||
return '新增';
|
||||
case 'modify':
|
||||
return '编辑';
|
||||
case 'view':
|
||||
return '查看';
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.init();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.system-role {
|
||||
.title {
|
||||
border-bottom: 1px solid #EBEEF5;
|
||||
height: 42px;
|
||||
line-height: 42px;
|
||||
margin: 0 18px 0 22px;
|
||||
|
||||
span {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #262626;
|
||||
}
|
||||
}
|
||||
|
||||
.search {
|
||||
.search-box-left {
|
||||
padding-top: 20px;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
|
||||
label {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: #595959;
|
||||
margin-right: 5px;
|
||||
padding-left: 22px;
|
||||
}
|
||||
|
||||
.year {
|
||||
::v-deep .el-input__inner {
|
||||
padding: 0 15px !important;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .el-input {
|
||||
width: 167px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1366px) {
|
||||
::v-deep .el-input {
|
||||
width: 135px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .el-button {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
|
||||
.search-box-right {
|
||||
padding-top: 20px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
padding-right: 14px;
|
||||
}
|
||||
|
||||
.operate-box {
|
||||
padding-left: 13px;
|
||||
padding-bottom: 11px;
|
||||
padding-top: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
.table {
|
||||
margin: 0 14px 0 13px;
|
||||
padding-bottom: 10px;
|
||||
|
||||
::v-deep .el-pagination {
|
||||
margin-top: 13px;
|
||||
padding-left: 20px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.role-form {
|
||||
padding-top: 26px;
|
||||
|
||||
::v-deep .el-form {
|
||||
padding-right: 79px;
|
||||
|
||||
.el-form-item {
|
||||
margin-bottom: 10px;
|
||||
|
||||
.el-form-item__label {
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #262626;
|
||||
}
|
||||
|
||||
.el-input__inner {
|
||||
min-height: 36px;
|
||||
}
|
||||
|
||||
.el-input__inner,
|
||||
.el-textarea__inner {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: #434343;
|
||||
}
|
||||
|
||||
.el-select {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.el-date-editor {
|
||||
width: 100%;
|
||||
|
||||
.el-input__inner {
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
.el-input__suffix {
|
||||
font-size: 16px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.icon-auth {
|
||||
.el-icon-arrow-up {
|
||||
margin-top: 2px;
|
||||
transform: rotateZ(0) !important;
|
||||
}
|
||||
|
||||
.el-icon-arrow-up:before {
|
||||
content: '';
|
||||
background: url("../../assets/imgs/icon-user.png") no-repeat center center;
|
||||
display: inline-block;
|
||||
width: 12px;
|
||||
height: 14px;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.el-button {
|
||||
width: 80px;
|
||||
height: 36px;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.done {
|
||||
text-align: center;
|
||||
padding: 40px 0;
|
||||
|
||||
::v-deep .el-button {
|
||||
width: 80px;
|
||||
height: 36px;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.permission-form {
|
||||
padding: 26px 33px 0 33px;
|
||||
|
||||
.menu-image {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
|
||||
::v-deep .el-image {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
margin: 0 5px;
|
||||
|
||||
.el-image__error {
|
||||
font-size: 12px;
|
||||
line-height: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.done {
|
||||
text-align: center;
|
||||
padding: 40px 0;
|
||||
|
||||
::v-deep .el-button {
|
||||
width: 80px;
|
||||
height: 36px;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,525 @@
|
||||
<template>
|
||||
<div class="content-height system-user">
|
||||
<div class="title">
|
||||
<span>用户管理</span>
|
||||
</div>
|
||||
<div class="search">
|
||||
<el-row>
|
||||
<el-col :span="20">
|
||||
<div class="search-box-left">
|
||||
<label>用户名:</label>
|
||||
<el-input v-model="q.account" placeholder="请输入用户名"></el-input>
|
||||
<label>角色名:</label>
|
||||
<el-select v-model="q.roleName" class="icon-auth" placeholder="请选择角色名">
|
||||
<el-option label="全部" value=""></el-option>
|
||||
<template v-for="item in roleList">
|
||||
<el-option :label="item.rname" :value="item.rname" :key="item.rid"></el-option>
|
||||
</template>
|
||||
</el-select>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="4" align="right">
|
||||
<div class="search-box-right">
|
||||
<el-button type="primary" @click="search">查询</el-button>
|
||||
<el-button @click="reset">重置</el-button>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<div class="operate-box">
|
||||
<el-button @click="add">新增用户</el-button>
|
||||
<el-button @click="getSelectUser">批量删除</el-button>
|
||||
<el-button @click="downloadTemp">模板下载</el-button>
|
||||
<el-upload
|
||||
class="upload-demo"
|
||||
action="/library/api/sys/user/import"
|
||||
:show-file-list="false"
|
||||
:on-success="uploadPDFSuccess"
|
||||
style="display: inline-block;margin-right: 10px;margin-left: 10px;">
|
||||
<el-button @click="newAddFunc">批量导入</el-button>
|
||||
</el-upload>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="table">
|
||||
<vxe-table ref="userTable" :data="tableData" :empty-render="{name: 'NotData'}" align="center" border stripe
|
||||
v-table-min-height="'calc(100vh - 320px)'">
|
||||
<vxe-column show-overflow type="checkbox" width="77"></vxe-column>
|
||||
<vxe-column show-overflow show-header-overflow type="seq" title="序号" width="77">
|
||||
<template #default="{ row, rowIndex }">
|
||||
{{ rowIndex + (q.pageNo - 1) * q.pageSize + 1 }}
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column show-overflow show-header-overflow field="ACCOUNT" title="用户名"></vxe-column>
|
||||
<vxe-column show-overflow show-header-overflow field="CELLPHONE_NUMBER" title="手机号"></vxe-column>
|
||||
<vxe-column show-overflow show-header-overflow field="CREATEDATE" title="创建时间"></vxe-column>
|
||||
<vxe-column show-overflow show-header-overflow field="DEPARTMENT" title="部门"></vxe-column>
|
||||
<vxe-column show-overflow show-header-overflow field="EMAIL" title="邮箱"></vxe-column>
|
||||
<vxe-column show-overflow show-header-overflow field="ROLENAME" title="角色"></vxe-column>
|
||||
<vxe-column show-overflow show-header-overflow field="USNAME" title="姓名"></vxe-column>
|
||||
<vxe-column show-overflow show-header-overflow title="启用/禁用" width="100" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-switch v-model="row.ISUSE" active-value="1" inactive-value="0"
|
||||
@change="(val) => sysUserIsUse(val, row)"></el-switch>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column show-overflow show-header-overflow title="操作" width="200" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button type="text" @click="openRowData('view', row)">查看</el-button>
|
||||
<el-button type="text" @click="openRowData('modify', row)">编辑</el-button>
|
||||
<el-button type="text" class="del-btn" @click="deleteRow(row)">删除</el-button>
|
||||
</template>
|
||||
</vxe-column>
|
||||
</vxe-table>
|
||||
<el-pagination
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
:current-page="q.pageNo"
|
||||
:page-sizes="[5, 10, 20]"
|
||||
:page-size="q.pageSize"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total"/>
|
||||
</div>
|
||||
<!-- 新增/编辑/查看 用户 -->
|
||||
<el-dialog :title="dialogTitle + '用户'" :visible.sync="dialogUser" width="750px" :close-on-click-modal="false"
|
||||
:close-on-press-escape="false" modal-append-to-body append-to-body>
|
||||
<div class="user-form">
|
||||
<el-form :model="form" label-width="186px" :disabled="mode === 'view'">
|
||||
<el-form-item label="用户名:" required>
|
||||
<el-input v-model="form.account" maxlength="20" show-word-limit placeholder="请输入用户名"></el-input>
|
||||
</el-form-item>
|
||||
<!--<el-form-item label="密码:" :required="mode === 'add'" v-if="mode !== 'view'">-->
|
||||
<!--<el-input v-model="form.password" maxlength="20" type="password" placeholder="请输入密码"></el-input>-->
|
||||
<!--</el-form-item>-->
|
||||
<!--<el-form-item label="确认密码:" :required="mode === 'add'" v-if="mode !== 'view'">-->
|
||||
<!--<el-input v-model="repassword" maxlength="20" type="password" placeholder="请确认密码"></el-input>-->
|
||||
<!--</el-form-item>-->
|
||||
<el-form-item label="手机号:">
|
||||
<el-input v-model="form.cellPhoneNumber" placeholder="请输入手机号"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="部门:">
|
||||
<el-input v-model="form.department" maxlength="50" show-word-limit placeholder="请输入部门"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="邮箱:">
|
||||
<el-input v-model="form.email" placeholder="请输入邮箱"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="角色:" required>
|
||||
<el-select v-model="form.roleIdList[0]" class="icon-auth" placeholder="请选择角色">
|
||||
<template v-for="item in roleList">
|
||||
<el-option :label="item.rname" :value="item.rid" :key="item.rid"></el-option>
|
||||
</template>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="姓名:" required>
|
||||
<el-input v-model="form.usname" maxlength="20" show-word-limit placeholder="请输入姓名"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="done">
|
||||
<el-button v-if="mode !== 'view'" type="primary" @click="sysUserAddUser">确定</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {Base64} from "js-base64";
|
||||
|
||||
export default {
|
||||
name: "User",
|
||||
data() {
|
||||
return {
|
||||
q: {
|
||||
account: '', // 用户名
|
||||
roleName: '', // 角色名称
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
total: 0,
|
||||
tableData: [],
|
||||
mode: '',
|
||||
dialogUser: false,
|
||||
form: {
|
||||
account: '', // 用户名
|
||||
cellPhoneNumber: '', // 手机号
|
||||
department: '', // 部门
|
||||
email: '', // 邮箱
|
||||
password: '', // 密码
|
||||
usid: '',
|
||||
usname: '', // 姓名
|
||||
roleIdList: [''], // 角色
|
||||
},
|
||||
repassword: '',
|
||||
roleList: [],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
search(){
|
||||
this.q.pageNo = 1;
|
||||
this.sysUserList();
|
||||
},
|
||||
// 获取所有用户
|
||||
sysUserList() {
|
||||
this.$api.user.sysUserList(this.q).then(({data}) => {
|
||||
this.tableData = data.records;
|
||||
this.total = data.total;
|
||||
this.q.pageNo = data.current;
|
||||
this.q.pageSize = data.size;
|
||||
if(!data.records.length && this.q.pageNo !== 1){
|
||||
this.q.pageNo = 1;
|
||||
this.sysUserList();
|
||||
}
|
||||
})
|
||||
},
|
||||
// 重置
|
||||
reset() {
|
||||
this.q = {
|
||||
account: '', // 用户名
|
||||
roleName: '', // 角色名称
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
};
|
||||
this.total = 0;
|
||||
this.tableData = [];
|
||||
this.sysUserList();
|
||||
},
|
||||
// 单页数据量
|
||||
handleSizeChange(val) {
|
||||
this.q.pageSize = val;
|
||||
this.q.pageNo = 1;
|
||||
this.sysUserList();
|
||||
},
|
||||
// 第几页
|
||||
handleCurrentChange(val) {
|
||||
this.q.pageNo = val;
|
||||
this.sysUserList();
|
||||
},
|
||||
// 新增
|
||||
add() {
|
||||
this.mode = 'add';
|
||||
this.form = {
|
||||
account: '', // 用户名
|
||||
cellPhoneNumber: '', // 手机号
|
||||
department: '', // 部门
|
||||
email: '', // 邮箱
|
||||
password: '', // 密码
|
||||
usid: '',
|
||||
usname: '', // 姓名
|
||||
roleIdList: [''], // 角色
|
||||
};
|
||||
this.repassword = '';
|
||||
this.dialogUser = true;
|
||||
},
|
||||
// 启用/禁用
|
||||
sysUserIsUse(val, row) {
|
||||
this.$confirm(val === '0' ? '此操作将禁用所选用户, 是否继续?' : '此操作将启用所选用户, 是否继续?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.$api.user.sysUserIsUse({USID: row.USID, type: val}).then(_ => {
|
||||
this.$message.success('操作成功');
|
||||
this.sysUserList();
|
||||
})
|
||||
}).catch(() => {
|
||||
row.ISUSE = val === '1' ? '0' : '1';
|
||||
});
|
||||
},
|
||||
// 删除
|
||||
deleteRow(row) {
|
||||
this.deleteUser(row.USID);
|
||||
},
|
||||
// 验证
|
||||
checkUserForm() {
|
||||
if (this.mode === 'add') {
|
||||
if (!this.form.account || !(/^[a-zA-Z0-9]*$/.test(this.form.account))) {
|
||||
return this.$message.warning('用户名只能为纯数字、纯字母或字母数字组合') && false;
|
||||
}
|
||||
// // 密码
|
||||
// if (!(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{8,}$/.test(this.form.password))) {
|
||||
// return this.$message.warning('密码至少8个字符,至少1个大写字母,1个小写字母,1个数字') && false;
|
||||
// }
|
||||
// if (this.repassword !== this.form.password) {
|
||||
// return this.$message.warning('请检查密码') && false;
|
||||
// }
|
||||
}
|
||||
if(this.mode === 'modify'){
|
||||
// if (this.form.password || this.repassword) {
|
||||
// // 密码
|
||||
// if (!(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{8,}$/.test(this.form.password))) {
|
||||
// return this.$message.warning('密码至少8个字符,至少1个大写字母,1个小写字母,1个数字') && false;
|
||||
// }
|
||||
// if (this.repassword !== this.form.password) {
|
||||
// return this.$message.warning('请检查密码') && false;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
if (this.form.cellPhoneNumber && !(/^1[3|4|5|7|8|9][0-9]{9}$/.test(this.form.cellPhoneNumber))) {
|
||||
return this.$message.warning('请检查手机号') && false;
|
||||
}
|
||||
if (this.form.email && !(/^[\w-.]+@[a-z\d-]+(\.[a-z\d-]+)*\.[a-z\d]{2,6}$/i.test(this.form.email))) {
|
||||
return this.$message.warning('请检查邮箱') && false;
|
||||
}
|
||||
if (!this.form.roleIdList[0]) {
|
||||
return this.$message.warning('请选择角色') && false;
|
||||
}
|
||||
if (!this.form.usname) {
|
||||
return this.$message.warning('请输入姓名') && false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
// 新增用户
|
||||
sysUserAddUser() {
|
||||
if (!this.checkUserForm()) return;
|
||||
let data = JSON.parse(JSON.stringify(this.form));
|
||||
data.account = this.$JSEncrypt(data.account);
|
||||
data.password = this.$JSEncrypt(data.password);
|
||||
let jsonData = JSON.stringify(data);
|
||||
this.$api.user.sysUserAddUser(Base64.encodeURI(jsonData)).then(_ => {
|
||||
this.$message.success('操作成功');
|
||||
this.dialogUser = false;
|
||||
this.reset();
|
||||
})
|
||||
},
|
||||
// 编辑查看用户
|
||||
openRowData(mode, row) {
|
||||
this.mode = mode;
|
||||
this.form = {
|
||||
account: row.ACCOUNT, // 用户名
|
||||
cellPhoneNumber: row.CELLPHONE_NUMBER, // 手机号
|
||||
department: row.DEPARTMENT, // 部门
|
||||
email: row.EMAIL, // 邮箱
|
||||
password: '', // 密码
|
||||
usid: row.USID, // 用户ID
|
||||
usname: row.USNAME, // 姓名
|
||||
roleIdList: [row.ROLEID], // 角色
|
||||
}
|
||||
this.repassword = '';
|
||||
this.dialogUser = true;
|
||||
},
|
||||
newAddFunc(){
|
||||
|
||||
},
|
||||
uploadPDFSuccess(response, file, fileList) {
|
||||
if (response.ok) {
|
||||
this.$message.success('导入成功');
|
||||
this.reset()
|
||||
} else {
|
||||
this.$message.error(response.message);
|
||||
}
|
||||
},
|
||||
downloadTemp(){
|
||||
window.open('/library/api/sys/user/template')
|
||||
},
|
||||
// 多选用户
|
||||
getSelectUser() {
|
||||
let users = this.$refs.userTable.getCheckboxRecords();
|
||||
if (!users.length) {
|
||||
return this.$message.warning('请选择数据后在进行操作');
|
||||
}
|
||||
let ids = users.map(item => item.USID).join(',');
|
||||
this.deleteUser(ids);
|
||||
},
|
||||
// 删除用户
|
||||
deleteUser(ids) {
|
||||
this.$confirm('此操作将删除所选用户, 是否继续?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.$api.user.sysUserDelete({ids}).then(_ => {
|
||||
this.$message.success('操作成功');
|
||||
this.sysUserList();
|
||||
})
|
||||
})
|
||||
},
|
||||
// 角色列表
|
||||
getSysRole() {
|
||||
this.$api.role.getSysRole().then(({data}) => {
|
||||
this.roleList = data;
|
||||
})
|
||||
},
|
||||
|
||||
},
|
||||
computed: {
|
||||
dialogTitle() {
|
||||
switch (this.mode) {
|
||||
case 'add':
|
||||
return '新增';
|
||||
case 'modify':
|
||||
return '编辑';
|
||||
case 'view':
|
||||
return '查看';
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.sysUserList();
|
||||
this.getSysRole();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.system-user {
|
||||
.title {
|
||||
border-bottom: 1px solid #EBEEF5;
|
||||
height: 42px;
|
||||
line-height: 42px;
|
||||
margin: 0 18px 0 22px;
|
||||
|
||||
span {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #262626;
|
||||
}
|
||||
}
|
||||
|
||||
.search {
|
||||
.search-box-left {
|
||||
padding-top: 20px;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
|
||||
label {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: #595959;
|
||||
margin-right: 5px;
|
||||
padding-left: 22px;
|
||||
}
|
||||
|
||||
.year {
|
||||
::v-deep .el-input__inner {
|
||||
padding: 0 15px !important;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .el-input {
|
||||
width: 167px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1366px) {
|
||||
::v-deep .el-input {
|
||||
width: 135px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .el-button {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
|
||||
.search-box-right {
|
||||
padding-top: 20px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
padding-right: 14px;
|
||||
}
|
||||
|
||||
.operate-box {
|
||||
padding-left: 13px;
|
||||
padding-bottom: 11px;
|
||||
padding-top: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
.table {
|
||||
margin: 0 14px 0 13px;
|
||||
|
||||
::v-deep .el-pagination {
|
||||
margin-top: 13px;
|
||||
padding-left: 20px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.user-form {
|
||||
padding-top: 26px;
|
||||
|
||||
::v-deep .el-form {
|
||||
padding-right: 79px;
|
||||
|
||||
.el-form-item {
|
||||
margin-bottom: 10px;
|
||||
|
||||
.el-form-item__label {
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #262626;
|
||||
}
|
||||
|
||||
.el-input__inner {
|
||||
min-height: 36px;
|
||||
}
|
||||
|
||||
.el-input__inner,
|
||||
.el-textarea__inner {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: #434343;
|
||||
}
|
||||
|
||||
.el-select {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.el-date-editor {
|
||||
width: 100%;
|
||||
|
||||
.el-input__inner {
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
.el-input__suffix {
|
||||
font-size: 16px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.icon-auth {
|
||||
.el-icon-arrow-up {
|
||||
margin-top: 2px;
|
||||
transform: rotateZ(0) !important;
|
||||
}
|
||||
|
||||
.el-icon-arrow-up:before {
|
||||
content: '';
|
||||
background: url("../../assets/imgs/icon-user.png") no-repeat center center;
|
||||
display: inline-block;
|
||||
width: 12px;
|
||||
height: 14px;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.el-button {
|
||||
width: 80px;
|
||||
height: 36px;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.done {
|
||||
text-align: center;
|
||||
padding: 40px 0;
|
||||
|
||||
::v-deep .el-button {
|
||||
width: 80px;
|
||||
height: 36px;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,266 @@
|
||||
<template>
|
||||
<div class="content-height system-menu-manager">
|
||||
<iframe :src="this.$store.state.pathUrl" id="mobsf" frameborder="0" style="width: 100%"></iframe>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: "MenuManager",
|
||||
data() {
|
||||
return {
|
||||
url: ''
|
||||
}
|
||||
},
|
||||
methods: {},
|
||||
computed: {},
|
||||
created() {
|
||||
this.url = this.$store.state.pathUrl
|
||||
},
|
||||
mounted() {
|
||||
/**
|
||||
* iframe-宽高自适应显示
|
||||
*/
|
||||
function changeMobsfIframe() {
|
||||
const mobsf = document.getElementById('mobsf');
|
||||
const deviceWidth = document.body.clientWidth;
|
||||
const deviceHeight = document.body.clientHeight;
|
||||
mobsf.style.width = '100%'; //数字是页面布局宽度差值
|
||||
mobsf.style.height = (Number(deviceHeight) - 86) + 'px'; //数字是页面布局高度差
|
||||
}
|
||||
|
||||
changeMobsfIframe()
|
||||
|
||||
window.onresize = function () {
|
||||
changeMobsfIframe()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.jumpClass .el-checkbox {
|
||||
line-height: 36px;
|
||||
}
|
||||
|
||||
.system-menu-manager {
|
||||
.title {
|
||||
border-bottom: 1px solid #EBEEF5;
|
||||
height: 42px;
|
||||
line-height: 42px;
|
||||
margin: 0 18px 0 22px;
|
||||
|
||||
span {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #262626;
|
||||
}
|
||||
}
|
||||
|
||||
.search {
|
||||
.search-box-left {
|
||||
padding-top: 20px;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
|
||||
label {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: #595959;
|
||||
margin-right: 5px;
|
||||
padding-left: 22px;
|
||||
}
|
||||
|
||||
.year {
|
||||
::v-deep .el-input__inner {
|
||||
padding: 0 15px !important;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .el-input {
|
||||
width: 167px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1366px) {
|
||||
::v-deep .el-input {
|
||||
width: 135px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .el-button {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
|
||||
.search-box-right {
|
||||
padding-top: 20px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
padding-right: 14px;
|
||||
}
|
||||
|
||||
.operate-box {
|
||||
padding-left: 13px;
|
||||
padding-bottom: 11px;
|
||||
padding-top: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
.table {
|
||||
margin: 0 14px 0 13px;
|
||||
padding-bottom: 10px;
|
||||
|
||||
.menu-image {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
|
||||
::v-deep .el-image {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
margin: 0 5px;
|
||||
|
||||
.el-image__error {
|
||||
font-size: 12px;
|
||||
line-height: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .el-pagination {
|
||||
margin-top: 13px;
|
||||
padding-left: 20px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.menu-form {
|
||||
padding-top: 26px;
|
||||
|
||||
::v-deep .el-form {
|
||||
padding-right: 79px;
|
||||
|
||||
.icon-menu-item .el-form-item__content > div:first-child {
|
||||
display: flex !important;
|
||||
}
|
||||
|
||||
.el-form-item {
|
||||
margin-bottom: 10px;
|
||||
|
||||
.el-form-item__label {
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #262626;
|
||||
}
|
||||
|
||||
.el-input__inner {
|
||||
min-height: 36px;
|
||||
}
|
||||
|
||||
.el-input__inner,
|
||||
.el-textarea__inner {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: #434343;
|
||||
}
|
||||
|
||||
.el-select {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.el-date-editor {
|
||||
width: 100%;
|
||||
|
||||
.el-input__inner {
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
.el-input__suffix {
|
||||
font-size: 16px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.icon-auth {
|
||||
.el-icon-arrow-up {
|
||||
margin-top: 2px;
|
||||
transform: rotateZ(0) !important;
|
||||
}
|
||||
|
||||
.el-icon-arrow-up:before {
|
||||
content: '';
|
||||
background: url("../../assets/imgs/icon-user.png") no-repeat center center;
|
||||
display: inline-block;
|
||||
width: 12px;
|
||||
height: 14px;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.el-input-number {
|
||||
width: 100%;
|
||||
|
||||
input {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.el-input-number__decrease,
|
||||
.el-input-number__increase {
|
||||
height: 18px;
|
||||
line-height: 18px;
|
||||
font-size: 14px;
|
||||
width: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.icon-menu-text {
|
||||
display: flex;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
overflow: hidden;
|
||||
border: 1px dashed #8C8C8C;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #8C8C8C;
|
||||
font-size: 18px;
|
||||
|
||||
.icon-menu {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.el-button {
|
||||
width: 80px;
|
||||
height: 36px;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.done {
|
||||
text-align: center;
|
||||
padding: 40px 0;
|
||||
|
||||
::v-deep .el-button {
|
||||
width: 80px;
|
||||
height: 36px;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||