Commit d0eb3bec authored by 廖旭伟's avatar 廖旭伟

Merge remote-tracking branch 'origin/master'

parents 0a00901d e3a722de
......@@ -25,6 +25,7 @@
"china-division": "^2.5.0",
"clipboard": "^2.0.6",
"core-js": "^3.6.5",
"crypto-js": "^4.1.1",
"date-fns": "^2.14.0",
"echarts": "^5.2.2",
"element-china-area-data": "^5.0.2",
......
......@@ -31,16 +31,17 @@
border-bottom: 1px solid rgb(224, 224, 224) !important;
}
.ant-tabs-tab{
.ant-tabs-tab {
font-weight: bold;
color: rgba(0, 0, 0, 0.65);
i{
color:#1890ff
i {
color: #1890ff;
}
}
.ant-spin-nested-loading,.ant-spin-container{
width:100%;
height:100%;
.ant-spin-nested-loading,
.ant-spin-container {
width: 100%;
height: 100%;
}
/* 溢出表格滚动条 */
/* 表格 */
......@@ -56,10 +57,9 @@
tr:only-child > th:last-child {
border-right-color: #f0f0f0 !important;
}
}
.ant-table-placeholder{
width:calc(100% - 6px)
.ant-table-placeholder {
width: calc(100% - 6px);
}
.ant-table-header {
background: #fff;
......@@ -119,3 +119,10 @@
// justify-content:space-between;
// margin-bottom: 20px;
// }
// 统一设置表格为空时的展示
.ant-table-tbody {
td:empty::after {
content: "--";
}
}
......@@ -2,8 +2,9 @@ import Vue from "vue";
import Vuex from "vuex";
import modules from "./modules";
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/util";
Vue.use(Vuex);
const store = new Vuex.Store({
modules,
......@@ -15,9 +16,9 @@ const store = new Vuex.Store({
createPersistedState({
key: "info",
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 enquireJs from "enquire.js";
import CryptoJS from "crypto-js";
export function isDef(v) {
return v !== undefined && v !== null;
}
......@@ -62,3 +62,52 @@ export const extractTree = (arrs, childs, attrArr) => {
};
return getObj(arrs);
};
/**
* 加密存储临时数据并解析对象
*/
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);
}
}
......@@ -3676,6 +3676,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@^2.0.0:
version "2.0.0"
resolved "https://registry.npm.taobao.org/crypto-random-string/download/crypto-random-string-2.0.0.tgz?cache=0&sync_timestamp=1583560482221&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcrypto-random-string%2Fdownload%2Fcrypto-random-string-2.0.0.tgz"
......
......@@ -777,3 +777,10 @@ img {
// }
// }
// }
// 统一设置表格为空时的展示
.ant-table-tbody {
td:empty::after {
content: "--";
}
}
\ No newline at end of file
......@@ -2,9 +2,10 @@ import Vue from "vue";
import Vuex from "vuex";
import modules from "./modules";
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 VuexReset from "@ianwalter/vuex-reset";
import { SessionCrypto } from "@/utils";
// import persistedState from 'vuex-persistedstate'
Vue.use(Vuex);
const store = new Vuex.Store({
......@@ -16,9 +17,9 @@ const store = new Vuex.Store({
createPersistedState({
key: "info",
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),
},
}),
],
......
......@@ -16,3 +16,66 @@ export let encrypt = (str, keyStr, ivStr) => {
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);
}
}
......@@ -80,13 +80,20 @@ export default {
this.queryform.dateTimeStart = this.time ? this.time[0] : null;
this.queryform.dateTimeStart = this.time ? this.time[1] : null;
getWayAccessAnalyse(this.queryform).then((res) => {
let data = res.data.data.map((item, i) =>
item.code != "/sceneSignIn"
? {
name: item.name,
}
: ""
);
let newobj = {};
let data = res.data.data.reduce((preVal, curVal) => {
newobj[curVal.name]
? ""
: (newobj[curVal.name] = preVal.push(curVal));
return preVal;
}, []);
// let data = res.data.data.map((item, i) =>
// item.code != "/sceneSignIn"
// ? {
// name: item.name,
// }
// : ""
// );
let links = res.data.links.map((item) => ({
source: item.sourceName,
target: item.targetName,
......@@ -96,7 +103,7 @@ export default {
},
}));
data = data.filter((v) => v);
links = links.filter((v) => v.target != "首页");
links = links.filter((v) => v.target != "首页" && v.target != v.source);
this.init(data, links);
});
},
......
......@@ -217,12 +217,14 @@ export default {
display: flex;
.img-dv {
width: 60%;
flex: 1;
margin: 100px;
height: 600px;
position: relative;
img {
width: 100%;
height: 100%;
}
#queuing {
......@@ -236,7 +238,7 @@ export default {
}
.list-dv {
width: 40%;
width: 55%;
min-height: 100%;
border-left: solid 1px #efefef;
box-sizing: border-box;
......
<template>
<!-- 使用习惯分析 -->
<div class="page">
<a-form-model :model="queryform" :label-col="labelCol" :wrapper-col="wrapperCol" layout="inline">
<a-form-model
:model="queryform"
:label-col="labelCol"
:wrapper-col="wrapperCol"
layout="inline"
>
<a-form-model-item>
<a-select v-model="queryform.productId" style="width: 200px" placeholder="选择产品">
<a-select-option :value="item.id" v-for="(item,index) in product" :key="index">
{{item.title}}
<a-select
v-model="queryform.productId"
style="width: 200px"
placeholder="选择产品"
>
<a-select-option
:value="item.id"
v-for="(item, index) in product"
:key="index"
>
{{ item.title }}
</a-select-option>
</a-select>
</a-form-model-item>
<a-form-model-item>
<a-range-picker valueFormat="yyyy-MM-DD" v-model="time" style="width: 300px" :allowClear="false"/>
<a-range-picker
valueFormat="yyyy-MM-DD"
v-model="time"
style="width: 300px"
:allowClear="false"
/>
</a-form-model-item>
<a-form-model-item>
<a-button type="primary" class="addclass" @click="getData">
......@@ -27,187 +45,225 @@
</template>
<script>
import * as echarts from 'echarts'
import moment from 'moment';
import {getUsageCensus} from '@/api/dataActuary.js'
import product from "../mixins/product"
export default {
mixins:[product],
import * as echarts from "echarts";
import moment from "moment";
import { getUsageCensus } from "@/api/dataActuary.js";
import product from "../mixins/product";
export default {
mixins: [product],
data() {
return {
queryform: {
productId: 1,
dateTimeStart: moment().format('yyyy-MM-DD'),
dateTimeEnd: moment().format('yyyy-MM-DD'),
pageCode: '/'
},
time: [moment().format('yyyy-MM-DD'), moment().format('yyyy-MM-DD')],
product: [{
title: '排队机',
id: 1
}],
dateTimeStart: moment().format("yyyy-MM-DD"),
dateTimeEnd: moment().format("yyyy-MM-DD"),
pageCode: "/",
},
time: [moment().format("yyyy-MM-DD"), moment().format("yyyy-MM-DD")],
product: [
{
title: "排队机",
id: 1,
},
],
labelCol: {
span: 1
span: 1,
},
wrapperCol: {
span: 14
span: 14,
},
}
};
},
mounted() {
this.getData()
this.getData();
},
methods: {
getData() {
this.queryform.dateTimeStart = this.time ? this.time[0] : null
this.queryform.dateTimeEnd = this.time ? this.time[1] : null
getUsageCensus(this.queryform).then(res=>{
let data = res.data.map(({businessName,propValue})=>({name:businessName,value:propValue * 100}))
this.initType(data)
})
},
initWay(){
let chartDom = document.getElementById('way')
this.queryform.dateTimeStart = this.time ? this.time[0] : null;
this.queryform.dateTimeEnd = this.time ? this.time[1] : null;
this.queryform.productId == 1
? (this.queryform.businessCodeList = ["iDCardSignIn"])
: "";
console.log(this.queryform);
getUsageCensus(this.queryform).then((res) => {
let data = res.data.map(({ businessName, propValue }) => ({
name: businessName,
value: propValue * 100,
}));
this.initType(data);
});
},
initWay() {
let chartDom = document.getElementById("way");
let myChart = echarts.init(chartDom);
myChart.setOption({
title: {
text: '取号方式分析',
left: 'center'
text: "取号方式分析",
left: "center",
},
tooltip: {
trigger: 'item',
trigger: "item",
},
legend: {
bottom: 0,
left: 'center',
left: "center",
itemWidth: 10,
itemHeight: 10
itemHeight: 10,
},
color: ['#6395F9', '#64DAAB', '#647798', '#F6C02D', '#7567FA', '#75CBED'],
series: [{
name: 'Access From',
type: 'pie',
radius: '65%',
color: [
"#6395F9",
"#64DAAB",
"#647798",
"#F6C02D",
"#7567FA",
"#75CBED",
],
series: [
{
name: "Access From",
type: "pie",
radius: "65%",
label: {
normal: {
formatter: '{d}%' //自定义显示格式(b:name, c:value, d:百分比)
}
formatter: "{d}%", //自定义显示格式(b:name, c:value, d:百分比)
},
},
labelLine: {
normal: {
length: 1
}
length: 1,
},
},
data: [{
data: [
{
value: 1048,
name: 'Search Engine'
name: "Search Engine",
},
{
value: 735,
name: 'Direct'
name: "Direct",
},
{
value: 580,
name: 'Email'
name: "Email",
},
{
value: 484,
name: 'Union Ads'
name: "Union Ads",
},
{
value: 300,
name: 'Video Ads'
}
name: "Video Ads",
},
],
}]
})
},
],
});
},
initType(data) {
console.log(data)
let chartDom = document.getElementById('type')
console.log(data);
let chartDom = document.getElementById("type");
let myChart = echarts.init(chartDom);
myChart.setOption({
title: {
text: this.queryform.productId==1?'取号类型分析':'功能使用分布',
left: 'center'
text: this.queryform.productId == 1 ? "取号类型分析" : "功能使用分布",
left: "center",
},
tooltip: {
trigger: 'item',
trigger: "item",
},
legend: {
bottom: 0,
left: 'center',
left: "center",
itemWidth: 10,
itemHeight: 10
itemHeight: 10,
},
color: ['#6395F9', '#64DAAB', '#647798', '#F6C02D', '#7567FA', '#75CBED'],
series: [{
type: 'pie',
radius: '65%',
color: [
"#6395F9",
"#64DAAB",
"#647798",
"#F6C02D",
"#7567FA",
"#75CBED",
],
series: [
{
type: "pie",
radius: "65%",
label: {
normal: {
formatter: '{d}%' //自定义显示格式(b:name, c:value, d:百分比)
}
formatter: "{d}%", //自定义显示格式(b:name, c:value, d:百分比)
},
},
labelLine: {
normal: {
length: 1
}
length: 1,
},
},
data: data,
},
data: data
}]
})
],
});
},
initCanal() {
let chartDom = document.getElementById('canal')
let chartDom = document.getElementById("canal");
let myChart = echarts.init(chartDom);
myChart.setOption({
title: {
text: '取号渠道分析',
left: 'center'
text: "取号渠道分析",
left: "center",
},
tooltip: {
trigger: 'item',
trigger: "item",
},
legend: {
bottom: 0,
left: 'center',
left: "center",
itemWidth: 10,
itemHeight: 10
itemHeight: 10,
},
color: ['#6395F9', '#64DAAB', '#647798', '#F6C02D', '#7567FA', '#75CBED'],
series: [{
name: 'Access From',
type: 'pie',
radius: '65%',
color: [
"#6395F9",
"#64DAAB",
"#647798",
"#F6C02D",
"#7567FA",
"#75CBED",
],
series: [
{
name: "Access From",
type: "pie",
radius: "65%",
label: {
normal: {
formatter: '{d}%' //自定义显示格式(b:name, c:value, d:百分比)
}
formatter: "{d}%", //自定义显示格式(b:name, c:value, d:百分比)
},
},
labelLine: {
normal: {
length: 1
}
length: 1,
},
data: [{
},
data: [
{
value: 1048,
name: '终端取号'
name: "终端取号",
},
{
value: 735,
name: '在线取号'
}
]
}]
})
}
}
};
name: "在线取号",
},
],
},
],
});
},
},
};
</script>
<style lang="less" scoped>
.page {
.page {
height: calc(100% - 50px);
display: flex;
flex-direction: column;
......@@ -222,10 +278,12 @@
justify-content: center;
padding: 50px 0;
#canal,#type,#way {
#canal,
#type,
#way {
width: 30%;
height: 100%;
}
}
}
}
</style>
......@@ -361,6 +361,7 @@ export default {
this.$emit("update", { total, time: this.searchForm.time });
}
this.loading = false;
this.$forceUpdate();
},
// 翻页
......
......@@ -354,6 +354,7 @@ export default {
this.$emit("update", { total, time: this.searchForm.time });
}
this.loading = false;
this.$forceUpdate();
},
// 翻页
......
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