Commit 0381940e authored by 赵啸非's avatar 赵啸非

Merge remote-tracking branch 'origin/master'

parents 9ef093fb 5bff9990
......@@ -22,6 +22,7 @@
"element-ui": "^2.15.10",
"file-saver": "^2.0.2",
"hammerjs": "^2.0.8",
"html2canvas": "^1.4.1",
"moment": "^2.29.4",
"npm": "^6.13.7",
"secure-ls": "^1.2.6",
......
......@@ -44,7 +44,7 @@ export default {
let obj = {
deviceInfo: {
enabled: 1,
productId: 3,
productId: 10,
productName: "样表系统",
siteCode: "511500000000-0001",
siteId: 1,
......@@ -64,12 +64,13 @@ export default {
},
serviceInfo: {
homeUrl: "http://192.168.0.24:8080/#/",
serverUrl: "http://112.19.80.237:11078/",
serverUrl: "http://192.168.0.98:11078/",
},
devicenum: "18-93-7F-C0-AD-B5",
// devicenum: "B8-13-32-86-9F-04",
};
local.setLocal("devicenum", obj.devicenum);
local.setLocal("deviceInfo", obj.deviceInfo);
this.SET_deviceCode(obj.devicenum);
this.WebSocketMq(obj);
}
......@@ -113,9 +114,10 @@ export default {
getInfo() {
let routeQuery = this.urlGet();
if (JSON.stringify(routeQuery) !== "{}") {
let { devicenum } = routeQuery;
let { devicenum, deviceInfo } = routeQuery;
this.devicenum = devicenum;
local.setLocal("devicenum", devicenum);
local.setLocal("deviceInfo", deviceInfo);
this.SET_deviceCode(devicenum);
}
},
......@@ -144,7 +146,7 @@ export default {
if (this.linkDom) {
this.linkDom.remove();
}
if (data[0].cssFilePath) {
if (data.length && data[0].cssFilePath) {
let link = document.createElement("link");
this.linkDom = link;
link.rel = "stylesheet";
......
......@@ -137,3 +137,39 @@ export const getDeviceList = (data) => {
},
});
};
//热力图背景图上传
export function screenSave(params = {}) {
let deviceInfo = {};
try {
let { productId, productName } = local.getLocal("deviceInfo");
deviceInfo = { productId, productName };
} catch (error) {}
let javaBase = local.getLocal("serverUrl");
params["deviceNum"] = local.getLocal("devicenum");
return request({
url: `${javaBase}basics_api/zwfw/page/bury/screen/save`,
method: "post",
data: {
...deviceInfo,
...params,
},
});
}
//java数据埋点
export function burySave(params = {}) {
let deviceInfo = {};
try {
let { productId, productName } = local.getLocal("deviceInfo");
deviceInfo = { productId, productName };
} catch (error) {}
let javaBase = local.getLocal("serverUrl");
params["deviceNum"] = local.getLocal("devicenum");
return request({
url: `${javaBase}basics_api/zwfw/page/bury/save`,
method: "post",
data: {
...deviceInfo,
...params,
},
});
}
<template>
<div class="enabled" v-show="!enabled">
<div class="enabled_box">
<img class="enabled_img" src="../assets/img/tingyong.png" />
<img class="enabled_img" src="@/assets/img/no_network@2x.png" />
<span class="text">设备已停用,请联系管理员~</span>
</div>
</div>
</template>
......@@ -22,7 +23,7 @@ export default {
.enabled {
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.2);
background-color: rgba(0, 0, 0, 0.7);
position: fixed;
top: 0px;
left: 0px;
......@@ -33,11 +34,17 @@ export default {
.enabled_box {
width: 400px;
height: 400px;
background-color: #fff;
border-radius: 4px;
color: #333;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: #fff;
font-size: 24px;
.enabled_img {
width: 100%;
height: 100%;
margin-bottom: 20px;
}
}
}
......
......@@ -7,7 +7,17 @@
<div></div>
</slot>
<div class="right-box flex aic">
<div class="back-one flex aic jcc pointer" @click="handleBack">
<div
class="back-one flex aic jcc pointer"
@click="handleBack"
v-onEvent="{
eventName: '点击',
eventCode: 'Click',
businessCode: 'back',
businessName: '返回',
routers: $route,
}"
>
<span class="back-text">返回</span>
</div>
<slot name="right"><div></div></slot>
......@@ -37,6 +47,7 @@ export default {
.header {
width: 100%;
height: 100px;
flex-shrink: 0;
// padding: 0px 40px;
margin-bottom: 10px;
// background: var(--main-theme-color);
......
......@@ -23,6 +23,13 @@
v-for="v in matterInfo.matterDatumList"
:key="v.id"
@click="handleCheck(v)"
v-onEvent="{
eventName: '点击',
eventCode: 'Click',
businessCode: 'check_materials',
businessName: '查看表单',
routers: $route,
}"
>
<div class="pic-box">
<div class="pic-img-box">
......@@ -43,7 +50,7 @@
></div>
</div>
<!-- <el-empty class="empty" :image-size="200" v-else></el-empty> -->
<YEmpty v-else width="400"></YEmpty>
<YEmpty v-else width="200" text="暂无数据"></YEmpty>
</el-drawer>
</div>
</template>
......
<template>
<div class="network_error" v-show="isShowError">
<div class="network_error_box">
<img class="network_error_img" src="../assets/img/网络出错@3x.png" />
<img class="network_error_img" src="@/assets/img/no_network@2x.png" />
<span>哎呀,网络出错了~</span>
</div>
</div>
</template>
......@@ -22,7 +23,7 @@ export default {
.network_error {
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.2);
background-color: rgba(0, 0, 0, 0.7);
position: fixed;
top: 0px;
left: 0px;
......@@ -33,11 +34,16 @@ export default {
.network_error_box {
width: 400px;
height: 400px;
background-color: #fff;
border-radius: 4px;
color: #333;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: #fff;
font-size: 24px;
.network_error_img {
width: 100%;
height: 100%;
}
}
}
......
......@@ -5,6 +5,13 @@
:value="value"
@keyup.native.enter="handleSearch"
@input="changeInput"
v-onEvent="{
eventName: '输入',
eventCode: 'Put',
businessCode: 'search',
businessName: '搜索',
routers: $route,
}"
>
<i
v-show="value"
......@@ -13,7 +20,17 @@
@click="handleClose"
></i>
</el-input>
<el-button class="search-btn" @click="handleSearch">
<el-button
class="search-btn"
v-onEvent="{
eventName: '点击',
eventCode: 'Click',
businessCode: 'search',
businessName: '搜索',
routers: $route,
}"
@click="handleSearch"
>
<span class="flex aic jcc">
<img class="mr10" src="../assets/img/sousuo.png" /> 搜索
</span>
......@@ -101,4 +118,4 @@ export default {
border-color: var(--main-theme-color);
}
}
</style>
\ No newline at end of file
</style>
<template>
<div class="empty">
<div :style="{ width: width.includes('px') ? width : width + 'px' }">
<div
class="content"
:style="{ width: width.includes('px') ? width : width + 'px' }"
>
<img v-if="img" :src="img" />
<span v-if="text">{{ text }}</span>
<span v-if="text">
{{ text }}
</span>
</div>
</div>
</template>
......@@ -16,7 +21,7 @@ export default {
},
img: {
type: String,
default: require("../assets/img/暂无信息/暂无列表@3x.png"),
default: require("@/assets/img/no_data@2x.png"),
},
text: {
type: String,
......@@ -35,5 +40,11 @@ export default {
width: 100%;
height: 100%;
}
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
}
</style>
......@@ -31,6 +31,9 @@ Vue.use(scroll);
import format from "vue-text-format";
Vue.use(format);
// 引入数据埋点
import vueStatistics from "@/utils/vue-statistics";
Vue.use(vueStatistics, { router });
// 中央事件
Vue.prototype.$bus = new Vue();
......
......@@ -36,6 +36,13 @@
v-model="search"
placeholder="输入事项表单关键词或排队编号查询"
@keyup.native.enter="handleSearch"
v-onEvent="{
eventName: '输入',
eventCode: 'Put',
businessCode: 'home_search',
businessName: '首页搜索',
routers: $route,
}"
>
<i
v-show="search"
......@@ -44,7 +51,17 @@
@click="handleClose"
></i>
</el-input>
<el-button class="search-btn" @click="handleSearch">
<el-button
class="search-btn"
v-onEvent="{
eventName: '点击',
eventCode: 'Click',
businessCode: 'home_search',
businessName: '首页搜索',
routers: $route,
}"
@click="handleSearch"
>
<span class="flex aic jcc">
<img class="mr10" src="../../assets/img/sousuo.png" /> 搜索
</span>
......@@ -55,7 +72,16 @@
<img src="../../assets/img/icon_hot.png" />
<span>热门词汇:</span>
</div>
<div @click="handleClick($event)">
<div
@click="handleClick($event)"
v-onEvent="{
eventName: '点击',
eventCode: 'Click',
businessCode: 'hot_words',
businessName: '热门词汇',
routers: $route,
}"
>
<vue-seamless-scroll
:data="homeInfo.hotWords"
:class-option="optionLeft"
......@@ -104,7 +130,18 @@
<img v-if="i < 3" :src="checkTopImg(i)" />
<span v-else>{{ i + 1 }}.</span>
</div>
<p class="flex1" v-ellipsis @click="checkMaterial(v)">
<p
class="flex1"
v-ellipsis
v-onEvent="{
eventName: '点击',
eventCode: 'Click',
businessCode: 'hot_materials',
businessName: '热门表单',
routers: $route,
}"
@click="checkMaterial(v)"
>
{{ v.materialName ? v.materialName : v.materiaFullName }}
</p>
</div>
......@@ -114,7 +151,16 @@
</div>
<div class="right flex flexc aic jcb">
<div class="right-top flex aic jcb">
<router-link to="/matterList">
<router-link
to="/matterList"
v-onEvent="{
eventName: '点击',
eventCode: 'Click',
businessCode: 'speed_check',
businessName: '快速查看',
routers: $route,
}"
>
<div class="fill-btn flex aic jcc pointer main-ksck-img">
<span class="fill-btn-text1"></span>
<span class="fill-btn-text2"></span>
......@@ -145,7 +191,18 @@
<img v-if="i < 3" :src="checkTopImg(i)" />
<span v-else>{{ i + 1 }}.</span>
</div>
<p class="flex1" v-ellipsis @click="checkMatter(v)">
<p
class="flex1"
v-ellipsis
v-onEvent="{
eventName: '点击',
eventCode: 'Click',
businessCode: 'hot_matter',
businessName: '热门事项',
routers: $route,
}"
@click="checkMatter(v)"
>
{{ v.matterName ? v.matterName : v.matterFullName }}
</p>
</div>
......@@ -187,7 +244,7 @@
<script>
// import { getHomeInfo } from "@/api";
import MateralsList from "@/components/MateralsList.vue";
import { mapState } from "vuex";
import { mapState, mapMutations } from "vuex";
export default {
components: {
MateralsList,
......@@ -237,6 +294,7 @@ export default {
},
},
methods: {
...mapMutations(["SET_operTime"]),
// 获取首页数据展示
// async getHomeInfo() {
// let res = await getHomeInfo({});
......@@ -285,11 +343,14 @@ export default {
},
// 查看材料列表
checkMatter(row) {
let time = this.$moment().format("YYYY-MM-DD HH:mm:ss");
this.SET_operTime(time);
this.matterInfo = row;
this.visible = true;
},
// 查看材料
checkMaterial(row) {
this.SET_operTime("");
this.$router.push({
path: "/showmaterials",
query: {
......
......@@ -26,6 +26,13 @@
v-for="matter in matterList"
:key="matter.id"
@click="handleCheck(matter)"
v-onEvent="{
eventName: '点击',
eventCode: 'Click',
businessCode: 'check_matter',
businessName: '查看事项',
routers: $route,
}"
>
<div v-if="matter.isRecommend" class="hot-icon flex jcc aic">
<i class="iconfont icon-hot"></i>
......@@ -74,7 +81,7 @@
:key="'list' + item"
></div>
</div>
<YEmpty v-else width="400"></YEmpty>
<YEmpty v-else width="200" text="暂无数据"></YEmpty>
<!-- 分页 -->
<div class="tac">
<el-pagination
......@@ -106,6 +113,7 @@ import SearchBox from "@/components/SearchBox.vue";
import MateralsList from "@/components/MateralsList.vue";
import YEmpty from "@/components/YEmpty.vue";
import { getSampleformMatterList, getMatterForFlownum } from "@/api";
import { mapMutations } from "vuex";
export default {
components: {
Header,
......@@ -142,6 +150,7 @@ export default {
},
},
methods: {
...mapMutations(["SET_operTime"]),
// 区分搜索
async typeSearch() {
let reg = /^[\u4e00-\u9fa5]+$/;
......@@ -188,6 +197,8 @@ export default {
},
// 查看
handleCheck(row) {
let time = this.$moment().format("YYYY-MM-DD HH:mm:ss");
this.SET_operTime(time);
this.matterInfo = row;
this.visible = true;
},
......@@ -326,4 +337,4 @@ export default {
font-size: 28px;
}
}
</style>
\ No newline at end of file
</style>
......@@ -32,6 +32,13 @@
v-for="v in matterList"
:key="v.id"
@click="handleCheck(v)"
v-onEvent="{
eventName: '点击',
eventCode: 'Click',
businessCode: 'check_matter',
businessName: '查看事项',
routers: $route,
}"
>
<div v-if="v.isRecommend" class="hot-icon flex jcc aic">
<i class="iconfont icon-hot"></i>
......@@ -49,7 +56,7 @@
</div>
</div>
<!-- <el-empty class="empty" :image-size="200" v-else></el-empty> -->
<YEmpty v-else width="400"></YEmpty>
<YEmpty v-else width="200" text="暂无数据"></YEmpty>
<!-- 分页 -->
<div class="tac">
<el-pagination
......@@ -83,6 +90,7 @@ import SearchBox from "@/components/SearchBox.vue";
import MateralsList from "../../components/MateralsList.vue";
import YEmpty from "@/components/YEmpty.vue";
import { getDeviceMatterList } from "@/api";
import { mapMutations } from "vuex";
export default {
components: {
Header,
......@@ -117,6 +125,7 @@ export default {
},
},
methods: {
...mapMutations(["SET_operTime"]),
// 获取事项列表
async getDeviceMatterList() {
let res = await getDeviceMatterList({
......@@ -147,6 +156,8 @@ export default {
this.getDeviceMatterList();
},
handleCheck(row) {
let time = this.$moment().format("YYYY-MM-DD HH:mm:ss");
this.SET_operTime(time);
this.matterInfo = row;
this.visible = true;
},
......
......@@ -7,6 +7,13 @@
slot="right"
class="back-home flex aic jcc ml20"
@click="handleBackHome"
v-onEvent="{
eventName: '点击',
eventCode: 'Click',
businessCode: 'back_homepage',
businessName: '返回首页',
routers: $route,
}"
>
<i class="iconfont icon-home mr10"></i>
<span>首页</span>
......@@ -41,10 +48,30 @@
</div>
<!-- 放大,缩小 -->
<div class="control-box">
<div class="control-btn" @click="handleEnlargement">
<div
class="control-btn"
v-onEvent="{
eventName: '点击',
eventCode: 'Click',
businessCode: 'expansion',
businessName: '放大表单',
routers: $route,
}"
@click="handleEnlargement"
>
<i class="el-icon-zoom-in"></i>
</div>
<div class="control-btn" @click="handleShrink">
<div
class="control-btn"
v-onEvent="{
eventName: '点击',
eventCode: 'Click',
businessCode: 'shrink',
businessName: '缩小表单',
routers: $route,
}"
@click="handleShrink"
>
<i class="el-icon-zoom-out"></i>
</div>
</div>
......@@ -52,7 +79,17 @@
<div class="sidebar-box" :class="{ show: !showSidebar }">
<!-- 侧边内容 -->
<div class="sidebar-main">
<div class="title flex jcc aic" @click="showSidebar = false">
<div
class="title flex jcc aic"
v-onEvent="{
eventName: '点击',
eventCode: 'Click',
businessCode: 'hidden_sidebar',
businessName: '隐藏边栏',
routers: $route,
}"
@click="showSidebar = false"
>
<span class="mr30"> 样表展示 </span>
<span class="icon2">
<i class="el-icon-d-arrow-left"></i>
......@@ -75,6 +112,13 @@
v-for="(v, i) in materailsList"
:key="v.id"
@click="changeIndex(v, i)"
v-onEvent="{
eventName: '点击',
eventCode: 'Click',
businessCode: 'change_materials',
businessName: '切换表单',
routers: $route,
}"
>
{{ v.materialName ? v.materialName : v.materiaFullName }}
<div class="line"></div>
......@@ -87,6 +131,13 @@
class="sidebar-btn flex jcc aic"
v-show="!showSidebar"
@click="showSidebar = true"
v-onEvent="{
eventName: '点击',
eventCode: 'Click',
businessCode: 'show_sidebar',
businessName: '显示边栏',
routers: $route,
}"
>
<div class="sidebar-btn-text flex flexc aic">
<span class="sidebar-btn-title"> 样表展示 </span>
......@@ -107,6 +158,7 @@
import Header from "@/components/Header.vue";
import { getMaterialsList, checkMaterials } from "@/api";
import local from "@/utils/local";
import { mapGetters } from "vuex";
// import Hammer from "hammerjs";
export default {
components: {
......@@ -126,6 +178,9 @@ export default {
width: 800,
};
},
computed: {
...mapGetters(["operTime"]),
},
created() {
this.getMaterialsList();
// this.materailsList=this.matterInfo.matterDatumList;
......@@ -202,6 +257,7 @@ export default {
matterFullName,
materialName,
materialFullName,
operTime: this.operTime ? this.operTime : null,
});
},
// 切换材料
......@@ -432,4 +488,4 @@ export default {
}
}
}
</style>
\ No newline at end of file
</style>
......@@ -7,6 +7,13 @@
v-for="(v, i) in deptList"
:key="v.deptCode"
@click="changeDept(v.deptCode, i)"
v-onEvent="{
eventName: '点击',
eventCode: 'Click',
businessCode: 'change_dept',
businessName: '切换部门',
routers: $route,
}"
>
<div class="dept-name">
{{ v.deptAbb ? v.deptAbb : v.name }}
......
......@@ -9,14 +9,13 @@ VueRouter.prototype.push = function (location) {
Vue.use(VueRouter);
const routes = [
{
path: "/",
redirect: "/home",
},
// 首页
{
path: "/home",
path: "/",
component: () => import("@/pages/home/Home.vue"),
meta: {
name: "首页",
},
},
// 快速查看
......@@ -27,6 +26,9 @@ const routes = [
{
path: "",
component: () => import("@/pages/showpage/MatterList.vue"),
meta: {
name: "快速查看",
},
},
],
},
......@@ -38,6 +40,9 @@ const routes = [
{
path: "",
component: () => import("@/pages/searchpage/SearchPage.vue"),
meta: {
name: "快速搜索",
},
},
],
},
......@@ -49,6 +54,9 @@ const routes = [
{
path: "",
component: () => import("@/pages/showpage/MatterIfy.vue"),
meta: {
name: "事项分类",
},
},
],
},
......@@ -60,6 +68,9 @@ const routes = [
{
path: "",
component: () => import("@/pages/showpage/ShowMaterials.vue"),
meta: {
name: "材料展示",
},
},
],
},
......
......@@ -14,6 +14,7 @@ export default new Vuex.Store({
deviceCode: "", // 设备编码
times: 300, // 倒计时时间
defaultTimes: 300, // 倒计时时间
operTime: "", // 样表打开时间
},
getters: {
deviceCode(state) {
......@@ -25,8 +26,14 @@ export default new Vuex.Store({
defaultTimes(state) {
return state.defaultTimes;
},
operTime(state) {
return state.operTime;
},
},
mutations: {
SET_operTime(state, operTime) {
state.operTime = operTime;
},
SET_devicenum(state, devicenum) {
state.devicenum = devicenum;
},
......
import html2canvas from "html2canvas";
import { burySave, screenSave } from "@/api";
let routerArr = []; //每次流程路径
let lastRouterArr = []; //上一次流程路径
let putStartTime = null;
export default {
install(Vue, options) {
const { router } = options;
// 监听路由数据
router.beforeEach((to, from, next) => {
document.title = to.meta.name || "";
next();
// 统计路由次数
const { path, meta } = to;
if (path == "/" || path == "/home") {
lastRouterArr = routerArr;
routerArr = [];
} else {
lastRouterArr = [];
}
// 保存每次流程
routerArr.push({
//页面路由信息
sourceCode: from.path || "/", //开始页面编码(路由)
sourceName: from.meta.name || "首页", //开始页面名称
targetCode: path, //目标页面编码(路由)
targetName: meta.name, //目标页面名称
});
// 后台桑基图请求数据
try {
let { productId } = JSON.parse(localStorage.getItem("deviceInfo"));
if (!productId) return; //未获取设备信息取消
burySave({
// "deviceNum":"",
// "productId": "",//产品id
// "productName": "",//产品名称
pageCode: path, //页面编码(页面路由)
pageName: meta.name, //页面名称
// "sceneDepth": 1,//场景维度
depthValue: lastRouterArr.length > 0 ? lastRouterArr.length : "", //本次访问深度 每次回到首页为每次流程
depthArr: lastRouterArr.length > 0 ? lastRouterArr : [],
// "eventInfo": {//页面事件信息
// "businessCode": '',//业务场景编码
// "businessName": '',//业务场景名称
// // "eventCode": "u9xo59",//事件编码
// // "eventName": "ku7l71",//事件名称
// // "takeTime": 12345,//事件耗时(单位毫秒)
// "coordinate": `${event.pageX},${event.pageY}`//事件坐标(x,y)
// },
routeInfo: {
//页面路由信息
sourceCode: from.path || "/", //开始页面编码(路由)
sourceName: from.meta.name || "首页", //开始页面名称
targetCode: path, //目标页面编码(路由)
targetName: meta.name, //目标页面名称
},
});
} catch (error) {}
});
// 封装事件埋点
Vue.directive("onEvent", {
bind: (el, bindings) => {
const { businessCode, businessName, eventCode, eventName, routers } =
bindings.value;
if (eventCode == "Click") {
el.addEventListener("click", (event) => {
const { meta, path } = routers;
try {
burySave({
// "deviceNum":"",//设备编码
// "productId": "",//产品id
// "productName": "",//产品名称
pageCode: path, //页面编码(页面路由)
pageName: meta.name, //页面名称
// "sceneDepth": 1,//场景维度
// "depthValue": 1,//本次访问深度
eventInfo: {
//页面事件信息
businessCode: businessCode, //业务场景编码
businessName: businessName, //业务场景名称
eventCode: eventCode, //事件编码
eventName: eventName, //事件名称
takeTime: 1000, //事件耗时(单位毫秒)
coordinate: `${event.pageX},${event.pageY}`, //事件坐标(x,y)生成热力图
},
// "routeInfo": {//页面路由信息
// "sourceCode": "6mq7ry",//开始页面编码(路由)
// "sourceName": "fxb3mk",//开始页面名称
// "targetCode": "fzrr3u",//目标页面编码(路由)
// "targetName": "fzrr3u"//目标页面名称
// }
});
} catch (error) {}
});
}
if (eventCode == "Put") {
let input = el.querySelector("input");
input.addEventListener("blur", (event) => {
let endPutTime = new Date();
const { meta, path } = routers;
try {
burySave({
// "deviceNum":"",//设备编码
// "productId": "",//产品id
// "productName": "",//产品名称
pageCode: path, //页面编码(页面路由)
pageName: meta.name, //页面名称
// "sceneDepth": 1,//场景维度
// "depthValue": 1,//本次访问深度
eventInfo: {
//页面事件信息
businessCode: businessCode, //业务场景编码
businessName: businessName, //业务场景名称
eventCode: eventCode, //事件编码
eventName: eventName, //事件名称
takeTime: endPutTime - putStartTime, //事件耗时(单位毫秒)
},
// "routeInfo": {//页面路由信息
// "sourceCode": "6mq7ry",//开始页面编码(路由)
// "sourceName": "fxb3mk",//开始页面名称
// "targetCode": "fzrr3u",//目标页面编码(路由)
// "targetName": "fzrr3u"//目标页面名称
// }
});
} catch (error) {}
});
input.addEventListener("focus", (event) => {
putStartTime = new Date();
console.log(event, putStartTime, "@@@@@");
});
}
},
});
// 封装函数
Vue.prototype.$onEvent = function (obj) {
const {
businessCode,
businessName,
eventCode,
eventName,
routers,
takeTime,
} = obj;
const { meta, path } = routers;
try {
burySave({
// "deviceNum":"",//设备编码
// "productId": "",//产品id
// "productName": "",//产品名称
pageCode: path, //页面编码(页面路由)
pageName: meta.name, //页面名称
// "sceneDepth": 1,//场景维度
// "depthValue": 1,//本次访问深度
eventInfo: {
//页面事件信息
businessCode: businessCode, //业务场景编码
businessName: businessName, //业务场景名称
eventCode: eventCode, //事件编码
eventName: eventName, //事件名称
takeTime: takeTime || 1000, //事件耗时(单位毫秒)
// "coordinate": ``//事件坐标(x,y)生成热力图
},
// "routeInfo": {//页面路由信息
// "sourceCode": "6mq7ry",//开始页面编码(路由)
// "sourceName": "fxb3mk",//开始页面名称
// "targetCode": "fzrr3u",//目标页面编码(路由)
// "targetName": "fzrr3u"//目标页面名称
// }
});
} catch (error) {}
};
// 热力图背景图生成
const rightDom = document.createElement("div");
rightDom.style.width = "200px";
rightDom.style.height = "100px";
rightDom.style.zIndex = 999;
rightDom.style.position = "fixed";
rightDom.style.top = 0;
rightDom.style.right = "50%";
rightDom.style.marginRight = "-100px";
document.body.appendChild(rightDom);
rightDom.addEventListener("dblclick", function () {
const { meta, fullPath } = router.app.$route;
html2canvas(document.body, {
backgroundColor: null,
allowTaint: false,
useCORS: true,
shadow: false,
}).then((canvas) => {
try {
screenSave({
// "deviceNum":"",//设备编码
// "productId": "",//产品id
// "productName": "",//产品名称
pageCode: fullPath, //页面编码(页面路由)
pageName: meta.name, //页面名称
screenUrl: canvas.toDataURL("image/png"),
});
} catch (error) {}
});
});
},
};
......@@ -2148,6 +2148,11 @@ balanced-match@^1.0.0:
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
base64-arraybuffer@^1.0.2:
version "1.0.2"
resolved "https://registry.npmmirror.com/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz#1c37589a7c4b0746e34bd1feb951da2df01c1bdc"
integrity sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==
base64-js@^1.3.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
......@@ -3037,6 +3042,13 @@ css-declaration-sorter@^6.3.0:
resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz#be5e1d71b7a992433fb1c542c7a1b835e45682ec"
integrity sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w==
css-line-break@^2.1.0:
version "2.1.0"
resolved "https://registry.npmmirror.com/css-line-break/-/css-line-break-2.1.0.tgz#bfef660dfa6f5397ea54116bb3cb4873edbc4fa0"
integrity sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==
dependencies:
utrie "^1.0.2"
css-loader@^3.5.3:
version "3.6.0"
resolved "https://registry.npmmirror.com/css-loader/-/css-loader-3.6.0.tgz#2e4b2c7e6e2d27f8c8f28f61bffcd2e6c91ef645"
......@@ -4800,6 +4812,14 @@ html-webpack-plugin@^5.1.0:
pretty-error "^4.0.0"
tapable "^2.0.0"
html2canvas@^1.4.1:
version "1.4.1"
resolved "https://registry.npmmirror.com/html2canvas/-/html2canvas-1.4.1.tgz#7cef1888311b5011d507794a066041b14669a543"
integrity sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==
dependencies:
css-line-break "^2.1.0"
text-segmentation "^1.0.3"
htmlparser2@^3.8.3:
version "3.10.1"
resolved "https://registry.npmmirror.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f"
......@@ -9104,6 +9124,13 @@ terser@^5.10.0, terser@^5.14.1:
commander "^2.20.0"
source-map-support "~0.5.20"
text-segmentation@^1.0.3:
version "1.0.3"
resolved "https://registry.npmmirror.com/text-segmentation/-/text-segmentation-1.0.3.tgz#52a388159efffe746b24a63ba311b6ac9f2d7943"
integrity sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==
dependencies:
utrie "^1.0.2"
text-table@^0.2.0, text-table@~0.2.0:
version "0.2.0"
resolved "https://registry.npmmirror.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
......@@ -9504,6 +9531,13 @@ utils-merge@1.0.1:
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==
utrie@^1.0.2:
version "1.0.2"
resolved "https://registry.npmmirror.com/utrie/-/utrie-1.0.2.tgz#d42fe44de9bc0119c25de7f564a6ed1b2c87a645"
integrity sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==
dependencies:
base64-arraybuffer "^1.0.2"
uuid@^3.3.2, uuid@^3.3.3:
version "3.4.0"
resolved "https://registry.npmmirror.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
......
#门户
VUE_APP_API_portal_URL=http://192.168.0.98:11072
# 系统名称
VUE_APP_sysName = '数字化样表系统'
......@@ -17,6 +17,7 @@
"beautifier": "^0.1.7",
"clipboard": "^2.0.4",
"core-js": "^3.8.3",
"crypto-js": "^4.1.1",
"css-loader": "^3.5.3",
"element-china-area-data": "^5.0.2",
"element-ui": "^2.15.10",
......
......@@ -5,7 +5,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>样表管理系统</title>
<title></title>
</head>
<body>
<noscript>
......
......@@ -63,3 +63,12 @@ export const saveDeviceEnable = (data) => {
data,
});
};
// 删除设备
export const delDevice = (params) => {
return request({
url: `/sampleform/device/delete`,
method: "get",
params,
});
};
......@@ -30,12 +30,25 @@
.bgg {
background-color: #1bbc9b;
}
.bgw{
background-color: #fff;
}
/* 版心 */
.container {
width: 1200px;
}
.container_width {
width: 1880px;
}
.container_height {
height: 820px;
}
.w-full{
width:100%;
}
.h-full{
height:100%
}
/* 弹性布局 */
.flex {
display: flex;
......@@ -129,7 +142,9 @@
.ml25 {
margin-left: 25px;
}
.mr5 {
margin-right: 5px;
}
.mr10 {
margin-right: 10px;
}
......@@ -304,22 +319,6 @@
text-align: right;
}
/* title */
.color_title {
margin-left: 15px;
position: relative;
margin-bottom: 15px;
}
.color_title::before {
content: "";
width: 4px;
height: 20px;
position: absolute;
top: 0px;
left: -16px;
background-color: #1890ff;
}
/**
element-ui
*/
......@@ -351,9 +350,12 @@
.gutter {
width: 6px !important;
}
.auto-scroll{
overflow-y: auto;
}
::-webkit-scrollbar {
width: 6px;
height: 6px;
overflow-y: auto;
}
......@@ -364,7 +366,7 @@
::-webkit-scrollbar-track {
border-radius: 6px;
background: rgba(0, 0, 0, 0);
background: rbga(0, 0, 0, 0);
}
.autoWidth {
......@@ -387,29 +389,47 @@
.el-tooltip__popper {
max-width: 20%;
}
.el-drawer__header{
.el-drawer__header {
margin-bottom: 20px !important;
}
.el-drawer__body{
border-top:1px solid #ececec;
.el-drawer__body {
border-top: 1px solid #ececec;
}
.el-button--primary{
.el-button--primary {
background: linear-gradient(90deg, #5ab6ff, #2e9aff) !important;
border: none !important;
border-color: transparent !important;
}
.el-dialog__header{
.el-dialog__title{
color: #1890FF !important;
.el-dialog__header {
.el-dialog__title {
color: #1890ff !important;
font-size: 18px;
font-weight: bold;
}
.el-dialog__close{
.el-dialog__close {
color: #188fff !important;
font-size: 26px;
font-weight: bold;
}
}
.el-pagination__jump{
.el-pagination__jump {
margin-left: 0px !important;
}
\ No newline at end of file
}
.el-tabs__nav-scroll {
padding-left: 15px;
.tab-label {
font-weight: bold;
color: rgba(0, 0, 0, 0.65);
}
.is-active {
.tab-label {
color:#2681e8
}
}
}
.el-tabs__header{
margin: 0px !important;
}
// .el-tabs__content {
// padding: 0px 15px 15px 15px;
// }
<template>
<div class="tab-header">
<i v-if="icon" :class="['mr5', 'primary', icon]"></i>
<span class="label">{{ label }}</span>
</div>
</template>
<script>
export default {
props: {
icon: {
type: String,
default: "",
},
label: {
type: String,
default: "",
},
},
};
</script>
<style lang="less" scoped>
.tab-header {
display: flex;
align-items: center;
width: 100%;
height: 40px;
padding: 0px 15px;
font-size: 14px;
position: relative;
cursor: default;
&::after {
content: "";
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 2px;
background-color: #e4e7ed;
z-index: 1;
}
.label {
font-weight: bold;
color: rgba(0, 0, 0, 0.65);
}
}
</style>
\ No newline at end of file
<template>
<div class="device">
<el-card shadow="never">
<div slot="header">
<span>样表设备</span>
</div>
<div class="device bgw flex flexc">
<TabHeader icon="el-icon-notebook-2" label="数字样表设备"></TabHeader>
<div class="flex1 pd15 auto-scroll">
<TableHeader>
<div slot="left">
<!-- <el-button size="small" type="primary" @click="handleAdd"
......@@ -141,7 +139,7 @@
</el-table-column>
<el-table-column align="center" prop="deviceRemark" label="备注">
</el-table-column>
<el-table-column align="center" label="操作" width="160">
<el-table-column align="center" label="操作" width="200">
<template slot-scope="scope">
<div class="flex jca">
<span
......@@ -162,9 +160,9 @@
<span class="primary pointer" @click="handleEdit(scope.row)"
>编辑</span
>
<!-- <span class="delete pointer" @click="handleDel(scope.row.id)"
<span class="delete pointer" @click="handleDel(scope.row.id)"
>删除</span
> -->
>
</div>
</template>
</el-table-column>
......@@ -177,7 +175,8 @@
@currentChange="changePagination"
@sizeChange="changeSize"
></Pagination>
</el-card>
</div>
<!-- 新增设备 -->
<AddDevice
:dict="dict"
......@@ -196,10 +195,12 @@ import TableHeader from "@/components/TableHeader.vue";
import Pagination from "@/components/Pagination.vue";
import AddMatter from "./modal/AddMatter.vue";
import AddDevice from "./modal/AddDevice.vue";
import TabHeader from "@/components/TabHeader.vue";
import {
getDeviceList,
saveDeviceEnable,
saveDeviceActive,
delDevice,
} from "@/api/device";
import local from "@/utils/local";
export default {
......@@ -208,6 +209,7 @@ export default {
AddDevice,
AddMatter,
Pagination,
TabHeader,
},
data() {
return {
......@@ -326,7 +328,12 @@ export default {
type: "warning",
})
.then(async () => {
console.log(id);
let res = await delDevice({ id });
let { code, msg } = res.data;
if (code == 1) {
this.$message.success(msg);
this.getDeviceList();
}
})
.catch(() => {
console.log("取消成功!");
......@@ -359,11 +366,7 @@ export default {
<style lang="less" scoped>
.device {
width: 100%;
min-height: 100%;
display: flex;
:deep(.el-card) {
height: auto;
}
height: 100%;
.select {
width: 220px !important;
}
......
......@@ -159,10 +159,10 @@
</el-row>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button size="small" @click="handleReset">重 置</el-button>
<el-button size="small" type="primary" @click="handleOk"
>确 定</el-button
>
<el-button size="small" @click="handleReset">重 置</el-button>
</span>
</el-dialog>
</div>
......
......@@ -4,6 +4,8 @@
<script>
import local from "@/utils/local";
import { mapMutations } from "vuex";
import { calcMenu } from "@/router";
// import { getSiteTree } from "@/services/businessMatter";
export default {
data() {
......@@ -15,55 +17,17 @@ export default {
this.getInfo();
},
methods: {
// 扁平化树形结构
// extractTree(arrs, childs, attrArr) {
// let attrList = [];
// if (!Array.isArray(arrs) && !arrs.length) return [];
// if (typeof childs !== "string") return [];
// if (
// !Array.isArray(attrArr) ||
// (Array.isArray(attrArr) && !attrArr.length)
// ) {
// attrList = Object.keys(arrs[0]);
// attrList.splice(attrList.indexOf(childs), 1);
// attrList.splice(attrList.indexOf("isLeaf"), 1);
// } else {
// attrList = attrArr;
// }
// let list = [];
// const getObj = (arr) => {
// arr.forEach(function (row) {
// let obj = {};
// attrList.forEach((item) => {
// obj[item] = row[item];
// });
// list.push(obj);
// if (row[childs]) {
// getObj(row[childs]);
// }
// });
// return list;
// };
// return getObj(arrs);
// },
...mapMutations(["SET_sysName", "SET_sysLogo", "SET_token", "SET_path"]),
// 获取token和站点信息
async getInfo() {
let token = this.$route.query.token;
let siteid = this.$route.query.siteid;
let { token, siteid, sysName, sysLogo, path } = this.$route.query;
if (token) {
local.setLocal("sampleToken", token);
// let res = await getSiteTree({});
// let { siteTree } = res.data.data;
// let siteList = this.extractTree(siteTree, "children").filter(
// (v) => v.type === "site"
// );
// let arr = siteList.filter((v) => v.id == siteid);
// let siteInfo = {
// siteName: arr[0].label,
// siteid: arr[0].id,
// };
// local.setLocal("siteInfo", siteInfo);
local.setLocal("sampleSiteId", siteid);
this.SET_token(token);
this.SET_sysName(sysName);
this.SET_sysLogo(sysLogo);
this.SET_path(path);
calcMenu();
this.$router.push("/basicsset");
} else {
this.$message.warning("跳转失败,请重新登录");
......
......@@ -21,8 +21,23 @@
>
</el-breadcrumb>
</div> -->
<div class="out-box flex1">
<router-view></router-view>
<div class="main flex1 flex flexc">
<!-- <el-tabs :value="activeKey" @tab-click="changeRouter">
<el-tab-pane v-for="v in subMenus" :key="v.path" :name="v.path">
<template slot="label">
<i v-if="v.meta.icon" :class="['mr5', 'primary', v.meta.icon]"></i>
<span class="tab-label">{{ v.meta.title }}</span>
</template>
</el-tab-pane>
</el-tabs> -->
<div class="out-box flex1">
<keep-alive>
<!-- 需要缓存的视图组件 -->
<router-view v-if="$route.meta.keepAlive"> </router-view>
</keep-alive>
<!-- 不需要缓存的视图组件 -->
<router-view v-if="!$route.meta.keepAlive"> </router-view>
</div>
</div>
</div>
</template>
......@@ -30,28 +45,38 @@
<script>
import Header from "./components/Header.vue";
import { getdeptList } from "@/api/department";
import { mapMutations } from "vuex";
import { mapMutations, mapState } from "vuex";
import local from "@/utils/local";
import { findBottomSubarrays } from "@/utils";
export default {
components: {
Header,
},
data() {
return {
systemName: process.env.VUE_APP_sysName,
portalUrl: process.env.VUE_APP_API_portal_URL,
breads: [],
subMenus: [],
};
},
created() {
this.calcBreads();
// this.getSubMenus();
document.title = this.sysName ? this.sysName : this.systemName; // 设置项目标题
// this.calcBreads();
this.getdeptList();
},
watch: {
"$route.path"() {
this.calcBreads();
// watch: {
// "$route.path"() {
// this.calcBreads();
// },
// },
computed: {
...mapState(["sysName"]),
activeKey() {
return this.$route.path;
},
},
computed: {},
methods: {
...mapMutations(["SET_deptList"]),
// 计算面包屑
......@@ -67,6 +92,18 @@ export default {
this.breads = [...temp, ...r];
},
// 获取当前顶层路由下的所有子路由
getSubMenus() {
let path = this.$route?.meta.activeMenu
? this.$route.meta.activeMenu
: this.$route.path;
let options = this.$router.options.routes[0].children;
let curRouters = options.filter((v) => v.path == path);
this.subMenus = findBottomSubarrays(curRouters).filter(
(v) => !v.meta.hidden
);
},
// 获取部门列表
async getdeptList() {
let res = await getdeptList({
......@@ -81,6 +118,10 @@ export default {
this.SET_deptList(data.data);
}
},
changeRouter(e) {
this.$router.push(e.name);
},
},
};
</script>
......@@ -88,18 +129,24 @@ export default {
<style lang="less" scoped>
.layouts {
width: 100%;
min-width: 1620px;
// min-width: 1620px;
height: 100%;
padding-bottom: 10px;
padding-bottom: 15px;
// .crumbs {
// margin: 10px 0px;
// width: 98%;
// }
.out-box {
.main {
width: 98%;
margin-top: 10px;
margin-top: 15px;
// padding-bottom: 15px;
border-radius: 4px;
background-color: #fff;
overflow-y: auto;
// background-color: #fff;
}
.out-box {
// padding: 15px;
overflow-y: auto;
}
}
......
......@@ -2,13 +2,14 @@
<div class="header flex aic jcb">
<div class="left flex aic">
<img
class="pointer mr10"
width="32"
src="../../../assets/img/logo.png"
class="pointer mr10 logo"
:src="sysLogo ? api + sysLogo : require('@/assets/img/logo.png')"
alt="LOGO"
@click="handleGoHome"
/>
<h1 class="title pointer" @click="handleGoHome">样表管理系统</h1>
<h1 class="title pointer" @click="handleGoHome">
{{ sysName ? sysName : systemName }}
</h1>
<HeaderSite class="mr50 ml20"></HeaderSite>
<!-- 导航 -->
<el-menu
......@@ -17,16 +18,43 @@
router
text-color="rgba(254, 254, 254, 0.65)"
>
<el-menu-item v-for="v in meuns" :key="v.path" :index="v.path">
<template v-for="v in menus">
<!-- 有子路由 -->
<el-submenu
v-if="!v.hideChildrenInMenu && v.children && v.children.length"
:key="'a' + v.path"
:index="v.path"
>
<template slot="title">
<i v-if="v.meta && v.meta.icon" :class="v.meta.icon"></i>
{{ v.meta.title }}
</template>
<el-menu-item
v-for="item in v.children"
:key="item.path"
:index="item.path"
>
<i v-if="item.meta && item.meta.icon" :class="item.meta.icon"></i>
{{ item.meta && item.meta.title }}
</el-menu-item>
</el-submenu>
<!-- 单个路由 -->
<el-menu-item v-else :key="v.path" :index="v.path">
<i v-if="v.meta && v.meta.icon" :class="v.meta.icon"></i>
{{ v.meta.title }}
</el-menu-item>
</template>
<!-- <el-menu-item v-for="v in menus" :key="v.path" :index="v.path">
<i :class="v.meta.icon"></i>
{{ v.meta.title }}
</el-menu-item>
</el-menu-item> -->
</el-menu>
</div>
<!-- 返回门户 -->
<div class="back-btn">
<el-tooltip effect="dark" content="返回门户" placement="bottom">
<a class="pointer" :href="portal">
<a class="pointer" :href="portal + (path ? path : '')">
<i class="el-icon-s-home"></i> 返回门户
</a>
</el-tooltip>
......@@ -36,13 +64,16 @@
<script>
import HeaderSite from "./HeaderSite.vue";
import { mapState } from "vuex";
export default {
components: {
HeaderSite,
},
data() {
return {
portal: process.env.VUE_APP_API_portal_URL + "/#/home/siteArrange",
systemName: process.env.VUE_APP_sysName,
api: process.env.VUE_APP_API_IMG_URL,
portal: process.env.VUE_APP_API_portal_URL + "/#",
};
},
computed: {
......@@ -54,9 +85,7 @@ export default {
}
return path;
},
meuns() {
return this.$store.state.menus;
},
...mapState(["menus", "sysName", "sysLogo", "path"]),
},
created() {},
methods: {
......@@ -75,8 +104,17 @@ export default {
// background-color: #2681e8;
background: linear-gradient(90deg, #1845c6 0%, #2999ff 100%);
color: #fff;
flex-shrink: 0;
.logo {
height: 32px;
object-fit: contain;
}
.left {
height: 100%;
}
.title {
font-size: 20px;
max-width: 200px;
font-size: 18px;
}
.back-btn {
a {
......@@ -86,31 +124,66 @@ export default {
}
}
/deep/.el-menu {
height: 64px !important;
border: none !important;
background-color: transparent;
}
/deep/.el-menu-item {
height: 100% !important;
border: none !important;
display: flex;
align-items: center;
background-color: transparent;
i {
color: rgba(254, 254, 254, 0.65);
}
.el-menu-item {
height: 100% !important;
border: none !important;
display: flex;
align-items: center;
color: rgba(254, 254, 254, 0.65);
&:hover {
// background-color: transparent !important;
color: #fff !important;
background-color: #1890ff !important;
// border-bottom: 2px solid #fff !important;
}
}
}
/deep/.el-submenu {
height: 100% !important;
.el-submenu__title {
height: 100% !important;
display: flex;
align-items: center;
color: rgba(254, 254, 254, 0.65) !important;
border: none !important;
&:hover {
// background-color: transparent !important;
color: #fff !important;
background-color: #1890ff !important;
// border-bottom: 2px solid #fff !important;
}
}
}
.el-menu--horizontal .el-menu .el-menu-item {
color: #909399;
&:hover {
// background-color: transparent !important;
background-color: #1890ff !important;
color: #fff !important;
// border-bottom: 2px solid #fff !important;
i {
color: #1890ff;
}
color: #1890ff;
}
}
.el-menu--horizontal .el-menu .el-menu-item.is-active {
color: #1890ff !important;
}
/deep/.is-active {
border: none !important;
// border-bottom: 2px solid #fff !important;
color: #fff !important;
// background-color: transparent !important;
background-color: #1890ff !important;
.el-submenu__title {
border: none !important;
color: #fff !important;
// background-color: transparent !important;
background-color: #1890ff !important;
}
}
</style>
\ No newline at end of file
<template>
<el-popover placement="bottom-start" trigger="manual" v-model="visible">
<a slot="reference" class="ant-dropdown-link" @click="visible = true">
{{ siteName }} <i class="el-icon-arrow-down"></i>
</a>
<div class="content" style="min-width: 50vw; min-height: 200px">
<div class="flex_row flex_align_c primary-color name">
<i class="el-icon-location" style="margin-right: 10px"></i>
<span style="">{{ siteName }}</span>
</div>
<div class="site-list">
<span
v-for="(item, index) in sitelist"
:key="index"
:class="{ 'primary-color': item.id == checkid }"
@click="setSite(item)"
>{{ item.label }}</span
>
</div>
<div class="check-site">
<span>您的选择是:</span>
<span
v-for="(item, index) in checkarr"
:key="index"
@click="updataSite(item)"
>{{ index > 0 ? ">" : "" }}{{ item.label }}</span
>
</div>
<div class="site-btn">
<el-button
type="primary"
size="small"
style="margin-right: 10px"
@click="onSucessSite"
:disabled="isSite"
>确定</el-button
>
<el-button size="small" @click="visible = false">取消</el-button>
</div>
</div>
</el-popover>
<!-- <div :trigger="['click']" class="trigger" @click="ontrigger">
<slot>
<a class="ant-dropdown-link" @click="(e) => e.preventDefault()">
{{ siteName }} <i class="el-icon-arrow-down"></i>
</a>
</slot>
<div slot="overlay" class="select-site" v-if="show">
<div class="flex_row flex_align_c primary-color name">
<i class="el-icon-location"></i>
<span style="">{{ siteName }}</span>
</div>
<div class="site-list">
<span
v-for="(item, index) in sitelist"
:key="index"
:class="{ 'primary-color': item.id == checkid }"
@click="setSite(item)"
>{{ item.label }}</span
>
</div>
<div class="check-site">
<span>您的选择是:</span>
<span
v-for="(item, index) in checkarr"
:key="index"
@click="updataSite(item)"
>{{ index > 0 ? ">" : "" }}{{ item.label }}</span
>
</div>
<div class="site-btn">
<el-button
type="primary"
size="small"
style="margin-right: 10px"
@click="onSucessSite"
:disabled="isSite"
>确定</el-button
>
<el-button size="small" @click="show = false">取消</el-button>
</div>
</div>
</div> -->
</template>
<script>
import { getSiteTree } from "@/api/siteInfo";
import local from "@/utils/local";
// import Cookie from "js-cookie";
export default {
data() {
return {
sitelist: [],
visible: false,
offsetLeft: 0,
checkarr: [], //选中站点
checkid: undefined, //最终选中站点
siteName: "请选择站点",
isSite: true,
};
},
computed: {},
created() {
this.getwaitedListdata();
},
mounted() {},
methods: {
// 确认站点
onSucessSite() {
if (this.checkarr.length == 0) return;
let obj = this.checkarr[this.checkarr.length - 1];
this.clickSite(obj);
},
// 选中
setSite(obj) {
this.checkid = undefined;
// 为子节点不添加数据
let data = this.checkarr[this.checkarr.length - 1];
if (data && (data.isLeaf || data.children.length == 0)) {
// 如果为子节点更新最后一个数据
this.checkid = obj.id;
this.checkarr[this.checkarr.length - 1] = obj;
} else {
this.checkarr.push(obj);
if (obj.children && obj.children.length > 0) {
this.sitelist = obj.children;
}
}
if (obj && obj.type == "site") {
this.isSite = false;
} else {
this.isSite = true;
}
},
// 更新选中
updataSite(row) {
const { id } = row;
this.checkid = undefined;
let index = this.checkarr.findIndex((v) => v.id == id);
this.checkarr.length = index + 1;
this.sitelist = row.children;
if (row && row.type == "site") {
this.isSite = false;
} else {
this.isSite = true;
}
// this.getwaitedListdata(id);
},
getwaitedListdata() {
getSiteTree()
.then((res) => {
const { code, data } = res.data;
if (code == 1) {
const { siteTree } = data;
this.sitelist = siteTree;
let arr = [];
const treeFn = function (e) {
e.forEach((element) => {
arr.push(element);
if (element.children && element.children.length > 0) {
treeFn(element.children);
}
});
};
const siteid = local.getLocal("sampleSiteId");
treeFn(siteTree);
const siteObj = arr.find((v) => v.id == siteid);
this.siteName = siteObj ? siteObj.label : "请选择站点";
}
})
.catch((err) => {
console.log(err);
});
},
clickSite(obj) {
// Cookie.set("siteid", obj.id);
// let siteInfo = {
// siteName: obj.label,
// siteid: obj.id,
// };
local.setLocal("sampleSiteId", obj.id);
this.show = false;
if (location.href.search(/token/gi) >= 0) {
setTimeout(() => {
location.reload();
});
} else {
location.reload();
}
},
// ontrigger(e) {
// if (e.target && e.target.nodeName == "A") {
// this.show = !this.show;
// }
// },
},
};
</script>
<style lang="less" scoped>
.ant-dropdown-link {
padding: 0 20px;
font-size: 16px;
min-width: 200px;
display: inline-block;
}
.content {
display: flex;
flex-direction: column;
justify-content: space-around;
.name {
font-size: 20px;
color: #1890ff;
}
.site-list {
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
display: flex;
flex-wrap: wrap;
span {
line-height: 1.5;
padding: 10px 20px;
cursor: pointer;
&:hover {
color: #1890ff;
}
}
}
.check-site,
.site-btn {
padding: 0 20px;
}
.check-site {
cursor: pointer;
}
}
.trigger {
display: inline-block;
position: relative;
}
.ant-dropdown-link {
padding: 0 20px;
font-size: 16px;
display: inline-block;
color: #fff;
cursor: pointer;
}
.select-site {
position: fixed;
left: 300px !important;
top: 65px;
background: #fff;
border-radius: 6px;
padding: 10px;
min-width: 60%;
max-width: 80%;
z-index: 9;
color: rgba(0, 0, 0, 0.8);
font-size: 14px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
.name {
font-size: 20px;
}
.site-list {
// padding: 10px 0;
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
overflow: hidden;
span {
float: left;
line-height: 1.5;
padding: 10px 20px;
cursor: pointer;
&:hover {
color: #1890ff;
}
}
}
.check-site,
.site-btn {
padding: 0 20px;
}
}
</style>
......@@ -3,7 +3,10 @@
<a slot="reference" class="ant-dropdown-link" @click="visible = true">
{{ siteName }} <i class="el-icon-arrow-down"></i>
</a>
<div class="content" style="min-width: 50vw; min-height: 200px">
<div
class="content"
style="min-width: 60vw; max-width: 80vw; min-height: 200px"
>
<div class="flex_row flex_align_c primary-color name">
<i class="el-icon-location" style="margin-right: 10px"></i>
<span style="">{{ siteName }}</span>
......@@ -27,15 +30,15 @@
>
</div>
<div class="site-btn">
<el-button size="small" @click="visible = false">取消</el-button>
<el-button
type="primary"
size="small"
style="margin-right: 10px"
@click="onSucessSite"
:disabled="isSite"
>确定</el-button
>
<el-button size="small" @click="visible = false">取消</el-button>
</div>
</div>
</el-popover>
......@@ -115,16 +118,22 @@ export default {
this.checkid = undefined;
// 为子节点不添加数据
let data = this.checkarr[this.checkarr.length - 1];
if (data && (data.isLeaf || data.children.length == 0)) {
// 如果为子节点更新最后一个数据
this.checkid = obj.id;
this.checkarr[this.checkarr.length - 1] = obj;
// 如果选中数据有子集更新站点列表
if (obj.children && obj.children.length > 0) {
this.sitelist = obj.children;
}
} else {
this.checkarr.push(obj);
if (obj.children && obj.children.length > 0) {
this.sitelist = obj.children;
}
}
if (obj && obj.type == "site") {
this.isSite = false;
} else {
......@@ -136,8 +145,13 @@ export default {
const { id } = row;
this.checkid = undefined;
let index = this.checkarr.findIndex((v) => v.id == id);
this.checkarr.length = index + 1;
this.sitelist = row.children;
if (index > -1) {
this.checkarr.splice(index + 1, this.checkarr.length - (index + 1));
}
if (row.children && row.children.length > 0) {
this.sitelist = row.children;
}
if (row && row.type == "site") {
this.isSite = false;
......@@ -147,30 +161,27 @@ export default {
// this.getwaitedListdata(id);
},
getwaitedListdata() {
getSiteTree()
.then((res) => {
const { code, data } = res.data;
if (code == 1) {
const { siteTree } = data;
this.sitelist = siteTree;
let arr = [];
const treeFn = function (e) {
e.forEach((element) => {
arr.push(element);
if (element.children && element.children.length > 0) {
treeFn(element.children);
}
});
};
const siteid = local.getLocal("sampleSiteId");
treeFn(siteTree);
const siteObj = arr.find((v) => v.id == siteid);
this.siteName = siteObj ? siteObj.label : "请选择站点";
}
})
.catch((err) => {
console.log(err);
});
getSiteTree().then((res) => {
const { code, data } = res.data;
if (code == 1) {
const { siteTree } = data;
this.sitelist = siteTree;
let arr = [];
const treeFn = function (e) {
e.forEach((element) => {
arr.push(element);
if (element.children && element.children.length > 0) {
treeFn(element.children);
}
});
};
const siteid = local.getLocal("sampleSiteId");
treeFn(siteTree);
const siteObj = arr.find((v) => v.id == siteid);
this.siteName = siteObj ? siteObj.label : "请选择站点";
}
});
},
clickSite(obj) {
// Cookie.set("siteid", obj.id);
......
......@@ -38,6 +38,7 @@
import { login } from "@/api/login";
import local from "@/utils/local";
import { calcMenu } from "@/router";
import { mapMutations } from "vuex";
export default {
name: "login",
data() {
......@@ -53,6 +54,7 @@ export default {
},
created() {},
methods: {
...mapMutations(["SET_token"]),
async login() {
let res = await login(this.form);
let { data, code } = res.data;
......@@ -62,8 +64,8 @@ export default {
let siteIds = data.user.siteIds;
let siteid = siteIds.split(",")[0];
if (token) {
local.setLocal("sampleToken", token);
local.setLocal("sampleSiteId", siteid);
this.SET_token(token);
// 渲染菜单
calcMenu();
this.$router.push("/basicsset");
......
<template>
<div class="basics-set">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>样表基础设置</span>
</div>
<div class="basics-set bgw flex flexc">
<TabHeader icon="el-icon-notebook-2" label="样表基础设置"></TabHeader>
<div class="pd15 flex1 auto-scroll">
<div class="header">
<span class="mr15 title">热门搜索词汇</span>
<span class="tips"
......@@ -62,15 +60,18 @@
>
</el-button>
</div>
</el-card>
</div>
</div>
</template>
<script>
import { getBaseSetInfo, saveBaseSet } from "@/api/baseSet";
import local from "@/utils/local";
import TabHeader from "@/components/TabHeader.vue";
export default {
components: {
TabHeader,
},
data() {
return {
siteId: local.getLocal("sampleSiteId")
......@@ -172,18 +173,13 @@ export default {
<style lang="less" scoped>
.basics-set {
width: 100%;
min-height: 100%;
display: flex;
height: 100%;
.title {
font-size: 15px;
color: #000;
}
}
:deep(.el-card) {
height: auto;
}
.header {
.tips {
font-size: 14px;
......
<template>
<div class="library-manage">
<el-card class="box-card" shadow="never">
<div slot="header" class="clearfix">
<span>公共库管理</span>
</div>
<div class="library-manage bgw flex flexc">
<TabHeader icon="el-icon-notebook-2" label="公共库管理"></TabHeader>
<div class="pd15 flex1 auto-scroll">
<TableHeader>
<div slot="left">
<!-- <el-button size="small" type="primary" @click="handleAddMaterials"
......@@ -113,7 +111,8 @@
@currentChange="changePagination"
@sizeChange="changeSize"
></Pagination>
</el-card>
</div>
<!-- 添加材料 -->
<!-- <AddMaterals
ref="AddMaterals"
......@@ -132,6 +131,7 @@
import TableHeader from "@/components/TableHeader.vue";
import PreviewMaterals from "./modal/PreviewMaterals.vue";
import Pagination from "@/components/Pagination.vue";
import TabHeader from "@/components/TabHeader.vue";
import { getPubdatumList, delPubdatum } from "@/api/libray";
import { mapGetters } from "vuex";
export default {
......@@ -139,6 +139,7 @@ export default {
TableHeader,
PreviewMaterals,
Pagination,
TabHeader,
},
data() {
return {
......@@ -264,12 +265,8 @@ export default {
<style lang="less" scoped>
.library-manage {
display: flex;
width: 100%;
min-height: 100%;
:deep(.el-card) {
height: auto;
}
height: 100%;
.short {
overflow: hidden;
text-overflow: ellipsis;
......
<template>
<div class="materias-manage flex">
<div class="left">
<el-card class="box-card" shadow="never">
<div slot="header">
<span>事项列表</span>
</div>
<div class="materias-manage flex jcb">
<div class="left h-full bgw flex flexc">
<TabHeader icon="el-icon-notebook-2" label="事项列表"></TabHeader>
<div class="pd15 flex1 auto-scroll">
<TableHeader>
<div slot="left">
<el-button size="small" type="primary" @click="setCurrent">{{
......@@ -15,16 +13,17 @@
<el-select
v-model="departmentLeft"
size="small"
style="width: 120px"
placeholder="选择部门"
class="autoWidth"
filterable
>
<template slot="prefix">
<!-- <template slot="prefix">
{{
(deptList.find((v) => v.deptNumber === departmentLeft) || {})
.name
}}
</template>
</template> -->
<el-option
v-for="item in deptList"
:key="item.deptNumber"
......@@ -108,13 +107,11 @@
@currentChange="leftChangePagination"
@sizeChange="leftChangeSize"
></Pagination>
</el-card>
</div>
</div>
<div class="right">
<el-card class="box-card" shadow="never">
<div slot="header">
<span>材料列表 </span>
</div>
<div class="right h-full bgw flex flexc">
<TabHeader icon="el-icon-notebook-2" label="材料列表"></TabHeader>
<div class="pd15 flex1 auto-scroll">
<!-- 内容 -->
<TableHeader>
<div slot="left">
......@@ -138,16 +135,16 @@
<el-select
v-model="departmentRight"
size="small"
style="width: 120px"
placeholder="选择部门"
class="autoWidth"
filterable
>
<template slot="prefix">
<!-- <template slot="prefix">
{{
(deptList.find((v) => v.deptNumber === departmentRight) || {})
.name
}}
</template>
</template> -->
<el-option
v-for="item in deptList"
:key="item.deptNumber"
......@@ -264,39 +261,39 @@
@currentChange="rightChangePagination"
@sizeChange="rightChangeSize"
></Pagination>
</el-card>
</div>
<!-- 新增材料 -->
<AddMaterials
ref="AddMaterials"
:addMaterialsVisible.sync="addMaterialsVisible"
:title="title"
@addSuccess="addSuccess"
></AddMaterials>
<!-- 预览材料 -->
<PreviewMaterials
:drawer.sync="drawer"
:materialsInfo="materialsInfo"
></PreviewMaterials>
</div>
<!-- 新增材料 -->
<AddMaterials
ref="AddMaterials"
:addMaterialsVisible.sync="addMaterialsVisible"
:title="title"
@addSuccess="addSuccess"
></AddMaterials>
<!-- 预览材料 -->
<PreviewMaterials
:drawer.sync="drawer"
:materialsInfo="materialsInfo"
></PreviewMaterials>
<!-- 公共库 -->
<CommonLib
ref="CommonLib"
:matterId="activeDep.id"
@ok="addSuccess"
:libVisible.sync="libVisible"
></CommonLib>
<!-- 新增文件夹 -->
<AddFolders
ref="AddFolders"
:addFolderVisible.sync="addFolderVisible"
></AddFolders>
<!-- 文件夹 -->
<FolderList
ref="FolderList"
@addSuccess="materialsToFolderOk"
:folderListVisible.sync="folderListVisible"
></FolderList>
<!-- 公共库 -->
<CommonLib
ref="CommonLib"
:matterId="activeDep.id"
@ok="addSuccess"
:libVisible.sync="libVisible"
></CommonLib>
<!-- 新增文件夹 -->
<AddFolders
ref="AddFolders"
:addFolderVisible.sync="addFolderVisible"
></AddFolders>
<!-- 文件夹 -->
<FolderList
ref="FolderList"
@addSuccess="materialsToFolderOk"
:folderListVisible.sync="folderListVisible"
></FolderList>
</div>
</div>
</template>
......@@ -308,6 +305,7 @@ import CommonLib from "./modal/CommonLib.vue";
import Pagination from "@/components/Pagination.vue";
import AddFolders from "./modal/AddFolders.vue";
import FolderList from "./modal/FolderList.vue";
import TabHeader from "@/components/TabHeader.vue";
import { getWriteMatterList } from "@/api/matter";
import {
getMaterialsList,
......@@ -325,6 +323,7 @@ export default {
Pagination,
AddFolders,
FolderList,
TabHeader,
},
data() {
return {
......@@ -580,7 +579,7 @@ export default {
<style lang="less" scoped>
.materias-manage {
width: 100%;
min-height: 100%;
height: 100%;
.short {
overflow: hidden;
text-overflow: ellipsis;
......@@ -601,11 +600,11 @@ export default {
}
.left {
width: 40%;
height: auto;
width: 39%;
border-radius: 4px;
}
.right {
width: 60%;
height: auto;
width: 59%;
border-radius: 4px;
}
</style>
\ No newline at end of file
......@@ -61,7 +61,9 @@
:on-remove="handleRemoveSamplePath"
:file-list="samplePathFileList"
:on-success="OnsuccessSamplePath"
:headers="headers"
:headers="{
Authorization: token,
}"
>
<!-- accept="application/vnd.openxmlformats-officedocument.wordprocessingml.document" -->
<el-button size="small" type="primary">上传文件</el-button>
......@@ -86,6 +88,7 @@
<script>
import local from "@/utils/local";
import { saveMaterials } from "@/api/materials";
import { mapGetters } from "vuex";
export default {
props: {
title: {
......@@ -140,14 +143,10 @@ export default {
// { required: true, message: "请上传模板", trigger: "change" },
// ],
},
headers: {
Authorization: local.getLocal("sampleToken")
? local.getLocal("sampleToken")
: "",
},
};
},
computed: {
...mapGetters(["token"]),
Visible: {
get() {
return this.addMaterialsVisible;
......
<template>
<div class="matter-manage flex">
<div class="matter-manage flex jcb">
<!-- 左 -->
<div class="left">
<el-card class="box-card" shadow="never">
<div slot="header">
<span>样表系统事项列表</span>
</div>
<div class="left h-full bgw flex flexc">
<TabHeader icon="el-icon-notebook-2" label="样表系统事项列表"></TabHeader>
<div class="pd15 flex1 auto-scroll">
<TableHeader>
<div slot="left">
<el-button size="small" type="primary" @click="handleAddMatter"
......@@ -19,16 +17,16 @@
<el-select
v-model="departmentLeft"
size="small"
style="width: 120px"
placeholder="选择部门"
class="autoWidth"
filterable
>
<template slot="prefix">
<!-- <template slot="prefix">
{{
(deptList.find((v) => v.deptNumber === departmentLeft) || {})
.name
}}
</template>
</template> -->
<el-option
v-for="item in deptList"
:key="item.deptNumber"
......@@ -147,14 +145,20 @@
@currentChange="leftChangePagination"
@sizeChange="leftChangeSize"
></Pagination>
</el-card>
</div>
<!-- 新增事项 -->
<AddMatter
ref="AddMatter"
:addMatterVisible.sync="addMatterVisible"
:departmentList="deptList"
:title="title"
@addMatter="getWriteMatterList"
></AddMatter>
</div>
<!-- -->
<div class="right">
<el-card class="box-card" shadow="never">
<div slot="header">
<span>站点事项列表 </span>
</div>
<div class="right h-full bgw flex flexc">
<TabHeader icon="el-icon-notebook-2" label="站点事项列表"></TabHeader>
<div class="pd15 flex1 auto-scroll">
<!-- 内容 -->
<TableHeader>
<div slot="left">
......@@ -166,16 +170,16 @@
<el-select
v-model="departmentRight"
size="small"
style="width: 120px"
placeholder="选择部门"
class="autoWidth"
filterable
>
<template slot="prefix">
<!-- <template slot="prefix">
{{
(deptList.find((v) => v.deptNumber === departmentRight) || {})
.name
}}
</template>
</template> -->
<el-option
v-for="item in deptList"
:key="item.deptNumber"
......@@ -240,6 +244,14 @@
label="事项名称"
>
</el-table-column>
<el-table-column width="100" align="center" label="事项来源">
<template slot-scope="scope">
<el-tag size="small" type="success" v-if="scope.row.source == 0"
>一体化添加</el-tag
>
<el-tag size="small" v-else>自建事项</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="160">
<template slot-scope="scope">
<span class="primary pointer" @click="handleJoin(scope.row.id)"
......@@ -256,16 +268,8 @@
@currentChange="rightChangePagination"
@sizeChange="rightChangeSize"
></Pagination>
</el-card>
</div>
</div>
<!-- 新增事项 -->
<AddMatter
ref="AddMatter"
:addMatterVisible.sync="addMatterVisible"
:departmentList="deptList"
:title="title"
@addMatter="getWriteMatterList"
></AddMatter>
</div>
</template>
......@@ -273,6 +277,7 @@
import TableHeader from "@/components/TableHeader.vue";
import AddMatter from "./modal/AddMatter.vue";
import Pagination from "@/components/Pagination.vue";
import TabHeader from "@/components/TabHeader.vue";
import { mapGetters } from "vuex";
import {
// getMatterList,
......@@ -288,6 +293,7 @@ export default {
TableHeader,
AddMatter,
Pagination,
TabHeader,
},
data() {
return {
......@@ -510,8 +516,7 @@ export default {
<style lang="less" scoped>
.matter-manage {
width: 100%;
min-height: 100%;
display: flex;
height: 100%;
.short {
overflow: hidden;
text-overflow: ellipsis;
......@@ -528,11 +533,11 @@ export default {
// height: 550px;
// }
.left {
width: 50%;
height: auto;
width: 49%;
border-radius: 4px;
}
.right {
width: 50%;
height: auto;
width: 49%;
border-radius: 4px;
}
</style>
<template>
<div class="skin-set">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>皮肤管理</span>
</div>
<div class="skin-set bgw flex flexc">
<TabHeader icon="el-icon-notebook-2" label="皮肤管理"></TabHeader>
<div class="pd15 flex1 auto-scroll">
<!-- 皮肤列表 -->
<div class="skin-box">
<div class="skin-category">
......@@ -32,28 +30,29 @@
</div>
</div>
</div>
<!-- 图片预览 -->
<el-image-viewer
v-if="previewImg"
:on-close="
() => {
(previewImg = false), (previewUrl = '');
}
"
:url-list="previewUrl"
/>
</el-card>
</div>
<!-- 图片预览 -->
<el-image-viewer
v-if="previewImg"
:on-close="
() => {
(previewImg = false), (previewUrl = '');
}
"
:url-list="previewUrl"
/>
</div>
</template>
<script>
import local from "@/utils/local";
import ElImageViewer from "element-ui/packages/image/src/image-viewer";
import TabHeader from "@/components/TabHeader.vue";
import { getSkinList, useSkin } from "@/api/skin";
export default {
components: {
ElImageViewer,
TabHeader,
},
data() {
return {
......@@ -140,13 +139,10 @@ export default {
<style lang="less" scoped>
.skin-set {
display: flex;
width: 100%;
min-height: 100%;
}
:deep(.el-card) {
height: auto;
height: 100%;
}
.skin-category {
margin-bottom: 30px;
}
......
<template>
<div class="system flex flexc">
<div class="system bgw flex flexc">
<el-tabs :value="activeKey" @tab-click="changeRouter">
<el-tab-pane label="系统参数" name="/system/parameter"></el-tab-pane>
<el-tab-pane label="任务信息" name="/system/task"></el-tab-pane>
<el-tab-pane label="操作日志" name="/system/systemlogs"></el-tab-pane>
<el-tab-pane v-for="v in subMenus" :key="v.path" :name="v.path">
<template slot="label">
<i v-if="v.meta.icon" :class="['mr5', 'primary', v.meta.icon]"></i>
<span class="tab-label">{{ v.meta.title }}</span>
</template>
</el-tab-pane>
</el-tabs>
<div class="system-out-box flex1">
<router-view></router-view>
......@@ -12,16 +15,36 @@
</template>
<script>
import { findBottomSubarrays } from "@/utils";
export default {
data() {
return {
subMenus: [],
};
},
computed: {
activeKey() {
return this.$route.path;
},
},
created() {
this.getSubMenus();
},
methods: {
changeRouter(e) {
this.$router.push(e.name);
},
// 获取当前顶层路由下的所有子路由
getSubMenus() {
let path = this.$route?.meta.activeMenu
? this.$route.meta.activeMenu
: this.$route.path;
let options = this.$router.options.routes[0].children;
let curRouters = options.filter((v) => v.path == path);
this.subMenus = findBottomSubarrays(curRouters).filter(
(v) => !v.meta.hidden
);
},
},
};
</script>
......@@ -34,11 +57,8 @@ export default {
width: 100%;
height: 100%;
.system-out-box {
padding: 0px 15px 15px 15px;
padding: 15px;
overflow-y: auto;
}
/deep/.ant-tabs-nav-container {
border-bottom: 1px solid #f0f0f0 !important;
}
}
</style>
\ No newline at end of file
......@@ -15,7 +15,7 @@
v-model="searchVal"
style="width: 200px"
class="ml10 mr10"
placeholder="请输入参数名称搜索"
placeholder="请输入任务名称搜索"
@keyup.native.enter="handleSearch"
></el-input>
<el-button size="small" type="primary" @click="handleSearch"
......
import Vue from "vue";
import Vuex from "vuex";
import createPersistedState from "vuex-persistedstate";
import SecureLS from "secure-ls";
var ls = new SecureLS({ isCompression: false });
// import SecureLS from "secure-ls";
// var ls = new SecureLS({ isCompression: false });
import { SessionCrypto } from "@/utils";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
menus: [], // 菜单
token: "",
siteId: "", // 站点id
deptList: [], // 部门列表
sysName: "", // 系统名称
sysLogo: "", // 系统logo
path: "", // 门户跳转过来的路由
},
getters: {
SET_path(state, path) {
state.path = path;
},
token(state) {
return state.token;
},
siteId(state) {
return state.siteId;
},
deptList(state) {
return state.deptList;
},
path(state) {
return state.path;
},
},
mutations: {
SET_MENUS(state, menus) {
......@@ -29,6 +43,15 @@ export default new Vuex.Store({
SET_deptList(state, deptList) {
state.deptList = deptList;
},
SET_sysName(state, sysName) {
state.sysName = sysName;
},
SET_sysLogo(state, sysLogo) {
state.sysLogo = sysLogo;
},
SET_token(state, token) {
state.token = token;
},
},
actions: {},
modules: {},
......@@ -38,11 +61,11 @@ export default new Vuex.Store({
// storage: window.sessionStorage,
// }),
createPersistedState({
key: "info",
key: "sample",
storage: {
getItem: (key) => ls.get(key),
setItem: (key, value) => ls.set(key, value),
removeItem: (key) => ls.remove(key),
getItem: (key) => SessionCrypto.getItem(key),
setItem: (key, value) => SessionCrypto.setItem(key, value),
removeItem: (key) => SessionCrypto.remove(key),
},
}),
],
......
import CryptoJS from "crypto-js";
// 递归获取底层子数组
export function findBottomSubarrays(arr) {
let bottomSubarrays = [];
function recursiveSearch(subArr) {
for (let item of subArr) {
if (item.children && item.children.length) {
recursiveSearch(item.children);
} else {
bottomSubarrays.push(...subArr);
break;
}
}
}
recursiveSearch(arr);
return bottomSubarrays;
}
// 加密数据
export let encrypt = (str, keyStr, ivStr) => {
keyStr = keyStr ? keyStr : "0000000671595991";
ivStr = ivStr ? ivStr : "tdrdadq59tbss5n7";
//密钥16位
let key = CryptoJS.enc.Utf8.parse(keyStr);
//加密向量16位
let iv = CryptoJS.enc.Utf8.parse(ivStr);
let encrypted = CryptoJS.AES.encrypt(str, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
});
return encrypted.toString();
};
// 解密
export const decrypt = (word, keyStr, ivStr) => {
keyStr = keyStr ? keyStr : "0000000671595991";
ivStr = ivStr ? ivStr : "tdrdadq59tbss5n7";
let key = CryptoJS.enc.Utf8.parse(keyStr);
let iv = CryptoJS.enc.Utf8.parse(ivStr);
let decrypt = CryptoJS.AES.decrypt(word, key, {
iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
});
return decrypt.toString(CryptoJS.enc.Utf8);
};
/**
* 加密存储临时数据并解析对象
*/
const aseKey = "**_FXxx_1234_KEY";
const KEY = "KEY_EXTRA";
export class SessionCrypto {
// 加密
static setItem(key = KEY, value = "") {
if (typeof key === "string") {
const stringify = JSON.stringify(value);
const encrypt = CryptoJS.AES.encrypt(
stringify,
CryptoJS.enc.Utf8.parse(aseKey),
{
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7,
}
).toString();
window.sessionStorage.setItem(key, encrypt);
return encrypt;
}
}
// 解密
static getItem(key = KEY) {
const ssStr = window.sessionStorage.getItem(key) || "";
try {
if (ssStr) {
const decrypt = CryptoJS.AES.decrypt(
ssStr,
CryptoJS.enc.Utf8.parse(aseKey),
{
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7,
}
).toString(CryptoJS.enc.Utf8);
const parseStr = JSON.parse(decrypt);
return parseStr;
}
return "";
} catch (e) {
return "";
}
}
// 删除
static remove(key) {
window.sessionStorage.removeItem(key);
}
}
......@@ -3,7 +3,8 @@
*/
import axios from "axios";
import { Message } from "element-ui";
import local from "@/utils/local";
// import local from "@/utils/local";
import store from "@/store";
// import router from "@/router"
// 请求超时时间
// axios.defaults.timeout = 10 * 1000;
......@@ -13,7 +14,7 @@ axios.defaults.baseURL = process.env.VUE_APP_API_BASE_URL;
// 请求拦截
axios.interceptors.request.use(
(config) => {
let token = local.getLocal("sampleToken");
let token = store.getters.token;
if (token) {
config.headers.Authorization = token;
config.headers.Authtoken = token;
......@@ -40,6 +41,7 @@ axios.interceptors.response.use(
message: msg,
});
setTimeout(() => {
store.commit("SET_token", "");
location.href = process.env.VUE_APP_API_portal_URL;
}, 2000);
}
......
......@@ -3014,6 +3014,11 @@ crypto-js@^3.1.6:
resolved "https://registry.npmmirror.com/crypto-js/-/crypto-js-3.3.0.tgz#846dd1cce2f68aacfa156c8578f926a609b7976b"
integrity sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q==
crypto-js@^4.1.1:
version "4.1.1"
resolved "https://registry.npmmirror.com/crypto-js/-/crypto-js-4.1.1.tgz#9e485bcf03521041bd85844786b83fb7619736cf"
integrity sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==
crypto-random-string@^1.0.0:
version "1.0.0"
resolved "https://registry.npmmirror.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment