Commit ebcb3902 authored by YIyiyi's avatar YIyiyi

perf: 整体优化业务数据分析

parent a5f2dd07
# 开发环境配置 # 开发环境配置
NODE_ENV = development NODE_ENV = development
# VUE_APP_API_BASE_URL=http://112.19.80.237:11078
# VUE_APP_API_BASE_URL=http://8.136.255.30:11078 # VUE_APP_API_BASE_URL=http://8.136.255.30:11078
VUE_APP_API_BASE_URL=http://192.168.0.98:11078 VUE_APP_API_BASE_URL=http://192.168.0.98:11078
#图片显示拼接 #图片显示拼接
# VUE_APP_API_IMG_URL=http://112.19.80.237:11078/
# VUE_APP_API_IMG_URL=http://8.136.255.30:11078/ # VUE_APP_API_IMG_URL=http://8.136.255.30:11078/
VUE_APP_API_IMG_URL=http://192.168.0.98:11078/ VUE_APP_API_IMG_URL=http://192.168.0.98:11078/
#余林 #余林
# VUE_APP_API_PHP_URL=http://112.19.80.237:8090
# VUE_APP_API_PHP_URL=http://8.136.255.30:8090 # VUE_APP_API_PHP_URL=http://8.136.255.30:8090
VUE_APP_API_PHP_URL=http://192.168.0.98:8090 VUE_APP_API_PHP_URL=http://192.168.0.98:8090
#宜宾 #宜宾
......
...@@ -65,3 +65,8 @@ export function pageLlist(params) { ...@@ -65,3 +65,8 @@ export function pageLlist(params) {
export function userSiteBus(params) { export function userSiteBus(params) {
return http.get(`${BASEURL}/inter/statistic/busIdForName`, params); return http.get(`${BASEURL}/inter/statistic/busIdForName`, params);
} }
// 获取排号业务列表
export function businessPtree(params) {
return http.get(`${BASEURL}/admin/business/businessPtree`, params);
}
...@@ -79,3 +79,19 @@ export class SessionCrypto { ...@@ -79,3 +79,19 @@ export class SessionCrypto {
window.sessionStorage.removeItem(key); window.sessionStorage.removeItem(key);
} }
} }
// 扁平化树形结构(有子数组返回子数组否则返回本身)
export function filterarrays(arr, field = "children") {
let data = [];
function recursiveSearch(subArr) {
for (let item of subArr) {
if (item[field] && item[field].length) {
recursiveSearch(item[field]);
} else {
data.push(item);
}
}
}
recursiveSearch(arr);
return data;
}
<template> <template>
<div> <div>
<div :id="id" :style="{height: this.height+'px', width: this.width+'px'}"></div> <div
</div> :id="id"
:style="{ height: this.height + 'px', width: this.width + 'px' }"
></div>
</div>
</template> </template>
<script> <script>
import * as echarts from 'echarts' import * as echarts from "echarts";
let myChart= null
export default { export default {
props: { props: {
id: { id: {
type: String type: String,
}, },
height: { height: {
type: String | Number type: String | Number,
}, },
width:{ width: {
type: String | Number, type: String | Number,
},
datas: Object
}, },
data() { datas: Object,
return { },
} data() {
return {
myChart: null,
};
},
watch: {
datas: function (obj) {
let arr = [];
if (obj) {
obj.dataList.map((item) => {
let obj = {
name: "",
type: "line",
emphasis: {
focus: "series",
},
data: [],
};
if (item) {
obj.name = item.name;
obj.data = item.data;
arr.push(obj);
}
});
this.lineInit(obj.title, obj.legend, obj.xData, arr, obj);
}
},
},
methods: {
autoResize() {
this.myChart && this.myChart.resize();
},
lineInit(title, legend, xData, data, datas) {
if (!this.myChart) {
this.myChart = echarts.init(document.getElementById(this.id));
}
let option = {
title: {
text: title,
textStyle: {
fontSize: "14",
},
},
tooltip: {
trigger: "axis",
},
legend: {
data: legend,
},
dataZoom: {
type: "inside",
startValue: datas.startValue ? datas.startValue : 0,
endValue: datas.endValue ? datas.endValue : 16,
},
grid: {
left: "3%",
right: "4%",
bottom: "3%",
containLabel: true,
},
xAxis: [
{
type: "category",
boundaryGap: false,
data: xData,
},
],
yAxis: [
{
type: "value",
},
],
series: data,
};
this.myChart.setOption(option);
// 让图表跟随屏幕自动的去适应
window.addEventListener("resize", this.autoResize);
}, },
watch:{ },
datas: function(obj){ beforeDestroy() {
let arr= [] window.removeEventListener("resize", this.autoResize);
if(obj){ },
obj.dataList.map((item)=>{ };
let obj= {
name: '',
type: 'line',
emphasis: {
focus: 'series'
},
data: []
}
if(item){
obj.name= item.name
obj.data= item.data
arr.push(obj)
}
})
this.lineInit(obj.title, obj.legend, obj.xData, arr)
}
}
},
methods: {
lineInit(title, legend, xData, data) {
myChart = echarts.init(document.getElementById(this.id))
let option = {
title: {
text: title,
textStyle: {
fontSize: '14'
}
},
tooltip: {
trigger: 'axis'
},
legend: {
data: legend
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: [
{
type: 'category',
boundaryGap: false,
data: xData
}
],
yAxis: [
{
type: 'value'
}
],
series: data
}
myChart.setOption(option)
// 让图表跟随屏幕自动的去适应
window.addEventListener('resize', function () {
myChart.resize()
})
}
}
}
</script> </script>
<style lang="less" scoped> <style lang="less" scoped></style>
</style>
\ No newline at end of file
<template> <template>
<div> <div class="analysiscontent">
<a-card :bordered="false" class="mb_15"> <a-card :bordered="false" class="mb_15">
<template slot="title"> <template slot="title">
<div class="head"> <div class="head">
<div class="head_title">分析结果</div> <div class="head_title">分析结果</div>
</div> </div>
</template> </template>
<a-row type="flex" align="middle" v-if="formState"> <a-row type="flex" align="middle" v-if="formState">
<a-col :span="4"> <a-col :span="4">
<div class="f_40 f_center">{{ formState.name }}</div> <div class="f_40 f_center">{{ formState.name }}</div>
<div class="f_center">业务名称</div> <div class="f_center">业务名称</div>
</a-col> </a-col>
<a-col :span="10"> <a-col :span="10">
<a-form layout="horizontal" :model="formState" :label-col="{span: 4}" :wrapper-col="{span: 20}"> <a-form
<a-form-item label="流水号:">{{ formState.flownum?formState.flownum:'--' }}</a-form-item> layout="horizontal"
<a-form-item label="关联排号:">{{ formState.device_name?formState.device_name:'--' }}</a-form-item> :model="formState"
<a-form-item label="受理区域:"> :label-col="{ span: 4 }"
<a-tag v-for="(item, index) in formState.region" :key="index">{{ item }}</a-tag> :wrapper-col="{ span: 20 }"
<span v-if="formState.region.length<1">--</span> >
</a-form-item> <a-form-item label="流水号:">{{
<a-form-item label="是否延时:">{{ formState.isweek_work ? '是' : '否' }}</a-form-item> formState.flownum ? formState.flownum : "--"
<a-form-item label="优先叫号:">{{ formState.first ? '是' : '否' }}</a-form-item> }}</a-form-item>
</a-form> <a-form-item label="关联排号:">{{
</a-col> formState.device_name ? formState.device_name : "--"
<a-col :span="10"> }}</a-form-item>
<a-form layout="horizontal" :model="formState" :label-col="{span: 4}" :wrapper-col="{span: 20}"> <a-form-item label="受理区域:">
<a-form-item label="业务级别:">{{ formState.level ? '二级业务' : '一级业务' }}</a-form-item> <template v-if="formState.region && formState.region.length">
<a-form-item label="父级业务:">{{ formState.parent_name?formState.parent_name:'--' }}</a-form-item> <a-tag v-for="(item, index) in formState.region" :key="index">{{
<a-form-item label="关联事项:"> item
<a-tag v-for="(item, index) in formState.matter" :key="index">{{ item.matterName }}</a-tag> }}</a-tag>
<span v-if="formState.matter.length<1">--</span> </template>
</a-form-item> <span v-else>--</span>
<a-form-item label="是否预约:">{{ formState.canorder ? '允许' : '不允许'}}</a-form-item> </a-form-item>
<a-form-item label="验证方式:">{{testWay.length>0?testWay.join(','):'--'}}</a-form-item> <a-form-item label="是否延时:">{{
</a-form> formState.isweek_work ? "是" : "否"
</a-col> }}</a-form-item>
</a-row> <a-form-item label="优先叫号:">{{
</a-card> formState.first ? "是" : "否"
<a-card :bordered="false" class="mb_15"> }}</a-form-item>
<template slot="title"> </a-form>
<div class="head"> </a-col>
<div class="head_title">使用趋势</div> <a-col :span="10">
</div> <a-form
</template> layout="horizontal"
<template #extra> :model="formState"
<a-select :label-col="{ span: 4 }"
ref="select" :wrapper-col="{ span: 20 }"
v-model:value="useNumber" >
:options="options" <a-form-item label="业务级别:">{{
style="width: 120px" formState.level ? "二级业务" : "一级业务"
@change="handleChange" }}</a-form-item>
> <a-form-item label="父级业务:">{{
</a-select> formState.parent_name ? formState.parent_name : "--"
</template> }}</a-form-item>
<LineChart <a-form-item label="关联事项:">
:id="`one_line`" <template v-if="formState.matter && formState.matter.length">
:datas="lineData" <a-tag v-for="(item, index) in formState.matter" :key="index">{{
:height="200" item.matterName
:width="1700" }}</a-tag>
/> </template>
</a-card> <span v-else>--</span>
</div> </a-form-item>
<a-form-item label="是否预约:">{{
formState.canorder ? "允许" : "不允许"
}}</a-form-item>
<a-form-item label="验证方式:">{{
testWay.length > 0 ? testWay.join(",") : "--"
}}</a-form-item>
</a-form>
</a-col>
</a-row>
</a-card>
<a-card :bordered="false" class="mb_15">
<template slot="title">
<div class="head">
<div class="head_title">使用趋势</div>
</div>
</template>
<template #extra>
<a-select
ref="select"
v-model="selected"
:options="options"
style="width: 120px"
@change="handleChange"
>
</a-select>
</template>
<LineChart :id="`one_line`" :datas="lineData" :height="200" />
</a-card>
</div>
</template> </template>
<script > <script>
import axios from 'axios' // import axios from "axios";
import LineChart from "../Component/line/index.vue"; import LineChart from "../Component/line/index.vue";
import {getBusInfoById} from '@/api/dataActuary.js' import { getBusInfoById } from "@/api/dataActuary.js";
export default { export default {
components:{ components: {
LineChart LineChart,
}, },
props:{ props: {},
data() {
return {
options: [
{
value: "1",
label: "近7日",
},
{
value: "2",
label: "近30日",
},
{
value: "3",
label: "近3个月",
},
{
value: "4",
label: "本年度",
},
],
siteid: localStorage.getItem("siteId"),
selected: "1",
lineData: {},
useNumber: "0",
checkId: "",
formState: {},
testWay: [],
};
},
mounted() {
// this.getAnalysisData();
},
}, watch: {
data(){ "$route.query": {
return{ handler() {
options:[ this.getAnalysisData();
{ },
value: '0', deep: true,
label: '今天', immediate: true,
}, },
{ },
value: '1',
label: '近7日', methods: {
}, async getAnalysisData() {
{ let res = await getBusInfoById({
value: '2', busid: this.$route.query.id,
label: '近30日', siteid: this.siteid,
}, selected: this.selected,
{ });
value: '3', if (res.code == 1) {
label: '近3个月', this.testWay = [
}, {
{ key: res.data.phone,
value: '4', label: "手机号",
label: '本年度', },
}, {
], key: res.data.idcardtake,
lineData: {}, label: "身份证",
useNumber: '0', },
checkId: '', {
formState: {}, key: res.data.face,
testWay:[] label: "人脸",
} },
}, ]
mounted(){ .filter((v) => v.key)
// this.getAnalysisData() .map((v) => {
}, if (v.key) {
watch:{ return v.label;
'$route.query': { }
immediate: true, });
handler(newVal, oldVal){ this.formState = res.data;
this.checkId= newVal.id console.log(res.data);
this.getAnalysisData() this.$nextTick(() => {
} this.lineData = {
} title: "",
}, legend: ["排队次数", "预约次数"],
methods: { xData:
async getAnalysisData(selected) { res.data.qh_list.length > 0
let pramse = (selected || selected===0 ||selected==='0')?{busid: this.checkId, siteid: localStorage.getItem('siteId'),selected:selected }:{busid: this.checkId, siteid: localStorage.getItem('siteId') } ? res.data.qh_list.map((item) => item.datetime)
const res = await getBusInfoById(pramse) : res.data.wy_list.map((item) => item.datetime),
if(res.code == 1){ dataList: [
if (res.data.phone) this.testWay.push('手机号') {
if (res.data.idcardtake) this.testWay.push('身份证') name: "排队次数",
if (res.data.face) this.testWay.push('人脸') data: res.data.qh_list.map((item) => item.nums),
this.formState= res.data },
this.lineData= { {
title: '', name: "预约次数",
legend: ['排队次数','预约次数'], data: res.data.wy_list.map((item) => item.nums),
xData: res.data.qh_list.length > 0 ? res.data.qh_list.map(item=>item.datetime) : res.data.wy_list.map(item=>item.datetime), },
dataList: [ ],
{name: '排队次数', data: res.data.qh_list.map(item=>item.nums)}, };
{name: '预约次数', data: res.data.wy_list.map(item=>item.nums)}, });
] }
}
} // let pramse =
}, // selected || selected === 0 || selected === "0"
handleChange(e){ // ? {
this.getAnalysisData(e) // busid: this.checkId,
} // siteid: localStorage.getItem("siteId"),
}, // selected: selected,
} // }
// : { busid: this.checkId, siteid: localStorage.getItem("siteId") };
// const res = await getBusInfoById(pramse);
// if (res.code == 1) {
// if (res.data.phone) this.testWay.push("手机号");
// if (res.data.idcardtake) this.testWay.push("身份证");
// if (res.data.face) this.testWay.push("人脸");
// this.formState = res.data;
// this.lineData = {
// title: "",
// legend: ["排队次数", "预约次数"],
// xData:
// res.data.qh_list.length > 0
// ? res.data.qh_list.map((item) => item.datetime)
// : res.data.wy_list.map((item) => item.datetime),
// dataList: [
// {
// name: "排队次数",
// data: res.data.qh_list.map((item) => item.nums),
// },
// {
// name: "预约次数",
// data: res.data.wy_list.map((item) => item.nums),
// },
// ],
// };
// }
},
handleChange() {
this.getAnalysisData();
},
},
};
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
/deep/ .ant-form-item{ .analysiscontent {
margin-bottom: 0 width: 100%;
}
/deep/ .ant-form-item {
margin-bottom: 0;
} }
.head{ .head {
display: flex; display: flex;
justify-content: flex-start; justify-content: flex-start;
align-items: center; align-items: center;
.head_title{ .head_title {
font-weight: 700; font-weight: 700;
font-style: normal; font-style: normal;
font-size: 1.125rem; font-size: 1.125rem;
color: #0595FD; color: #0595fd;
margin-right: 1.25rem; margin-right: 1.25rem;
} }
.head_desc{ .head_desc {
font-weight: 400; font-weight: 400;
font-style: normal; font-style: normal;
font-size: 14px; font-size: 14px;
color: #888888; color: #888888;
} }
} }
.mb_15{ .mb_15 {
margin-bottom: .9375rem; margin-bottom: 0.9375rem;
} }
.f_40{ .f_40 {
font-size: 2rem; font-size: 2rem;
} }
.f_center{ .f_center {
text-align: center; text-align: center;
} }
</style> </style>
\ No newline at end of file
...@@ -151,11 +151,7 @@ ...@@ -151,11 +151,7 @@
<span slot="index" slot-scope="text, record, index"> <span slot="index" slot-scope="text, record, index">
{{ index + 1 }} {{ index + 1 }}
</span> </span>
<span <span slot="nums" slot-scope="text" style="display: flex">
slot="nums"
slot-scope="text, record, index"
style="display: flex"
>
<a-progress <a-progress
:percent="text" :percent="text"
:showInfo="false" :showInfo="false"
...@@ -198,11 +194,7 @@ ...@@ -198,11 +194,7 @@
<span slot="index" slot-scope="text, record, index"> <span slot="index" slot-scope="text, record, index">
{{ index + 1 }} {{ index + 1 }}
</span> </span>
<span <span slot="nums" slot-scope="text" style="display: flex">
slot="nums"
slot-scope="text, record, index"
style="display: flex"
>
<a-progress <a-progress
:percent="text" :percent="text"
:showInfo="false" :showInfo="false"
...@@ -247,11 +239,7 @@ ...@@ -247,11 +239,7 @@
<span slot="index" slot-scope="text, record, index"> <span slot="index" slot-scope="text, record, index">
{{ index + 1 }} {{ index + 1 }}
</span> </span>
<span <span slot="nums" slot-scope="text" style="display: flex">
slot="nums"
slot-scope="text, record, index"
style="display: flex"
>
<a-progress <a-progress
:percent="text" :percent="text"
:showInfo="false" :showInfo="false"
...@@ -294,11 +282,7 @@ ...@@ -294,11 +282,7 @@
<span slot="index" slot-scope="text, record, index"> <span slot="index" slot-scope="text, record, index">
{{ index + 1 }} {{ index + 1 }}
</span> </span>
<span <span slot="nums" slot-scope="text" style="display: flex">
slot="nums"
slot-scope="text, record, index"
style="display: flex"
>
<a-progress <a-progress
:percent="text" :percent="text"
:showInfo="false" :showInfo="false"
...@@ -315,7 +299,7 @@ ...@@ -315,7 +299,7 @@
</div> </div>
</template> </template>
<script > <script>
import Pie from "../Component/emptyPie/index.vue"; import Pie from "../Component/emptyPie/index.vue";
import axios from "axios"; import axios from "axios";
import { import {
...@@ -761,4 +745,4 @@ export default { ...@@ -761,4 +745,4 @@ export default {
.mb_15 { .mb_15 {
margin-bottom: 0.9375rem; margin-bottom: 0.9375rem;
} }
</style> </style>
\ No newline at end of file
...@@ -7,7 +7,35 @@ ...@@ -7,7 +7,35 @@
</div> </div>
<div class="searchBox"> <div class="searchBox">
<a-space> <a-space>
<a-auto-complete <a-select
style="width: 35.625rem"
allowClear
showSearch
v-model="business"
optionFilterProp="label"
placeholder="请输入业务名称搜索"
>
<a-select-option
v-for="v in businessList"
:key="v.id"
:value="String(v.id)"
:label="v.name + '--' + v.flownum"
>
{{ `${v.name}--${v.flownum}` }}
</a-select-option>
</a-select>
<a-button type="primary" class="addclass" @click="startAnalysis"
>开始分析</a-button
>
<a-button
type="primary"
class="addclass"
v-if="btnShow"
@click="backBase"
>返回</a-button
>
<!-- <a-auto-complete
v-model="businessName" v-model="businessName"
:data-source="dataSource" :data-source="dataSource"
optionLabelProp="value" optionLabelProp="value"
...@@ -25,7 +53,7 @@ ...@@ -25,7 +53,7 @@
> >
<a-button type="primary" class="addclass" v-else @click="backBase" <a-button type="primary" class="addclass" v-else @click="backBase"
>返回</a-button >返回</a-button
> > -->
</a-space> </a-space>
</div> </div>
</div> </div>
...@@ -37,9 +65,10 @@ ...@@ -37,9 +65,10 @@
</template> </template>
<script> <script>
import _ from "lodash"; import _ from "lodash";
import axios from "axios"; // import axios from "axios";
import Breadcrumb from "./breadcrumb/index.vue"; import Breadcrumb from "./breadcrumb/index.vue";
import { userSiteBus } from "@/api/dataActuary"; import { userSiteBus, businessPtree } from "@/api/dataActuary";
import { filterarrays } from "@/utils";
export default { export default {
components: { components: {
Breadcrumb, Breadcrumb,
...@@ -47,39 +76,50 @@ export default { ...@@ -47,39 +76,50 @@ export default {
data() { data() {
return { return {
// 搜索框 // 搜索框
businessName: "", // businessName: "",
business: undefined,
businessList: [],
dataSource: [], dataSource: [],
sourceList: [], sourceList: [],
// dataList: [], // dataList: [],
btnShow: false,
}; };
}, },
mounted() { mounted() {
// this.getList() // this.getList()
}, },
created() {}, created() {
computed: {}, this.businessPtree();
},
computed: {
btnShow() {
return this.$route.path == "/home/dataActuary/business/analysiscontent";
},
},
methods: { methods: {
// 获取排号业务列表
async businessPtree() {
let res = await businessPtree({
page: 1,
size: -1,
});
if (res.code == 1) {
this.businessList = filterarrays(res.data.data, "children");
this.business = this.$route.query.id;
}
},
startAnalysis() { startAnalysis() {
if (!this.businessName) { if (!this.business) {
this.$message.error("请输入业务名称搜索"); this.$message.warning("请先选择业务");
} else { } else {
let item = this.sourceList.filter((i) => { this.$router.push({
return i.name == this.businessName; path: "analysiscontent",
})[0]; query: { id: this.business },
if (item) { });
this.$router.push({
path: "analysiscontent",
query: { id: item.id },
});
this.btnShow = true;
}
} }
}, },
backBase() { backBase() {
this.$router.push({ path: "basecontent" }); this.$router.push({ path: "basecontent" });
this.btnShow = false; this.business = undefined;
this.businessName = "";
}, },
// async getList(){ // async getList(){
// await axios.get('http://192.168.0.98:8090/inter/statistic/busList',{params: {siteid: 1}}).then((res)=>{ // await axios.get('http://192.168.0.98:8090/inter/statistic/busList',{params: {siteid: 1}}).then((res)=>{
...@@ -90,29 +130,33 @@ export default { ...@@ -90,29 +130,33 @@ export default {
// } // }
// }) // })
// }, // },
onSearch: _.debounce(function (val) { // onSearch: _.debounce(function (val) {
this.dataSource = []; // this.dataSource = [];
userSiteBus({ // userSiteBus({
siteid: localStorage.getItem("siteId"), // siteid: localStorage.getItem("siteId"),
bus_name: val, // bus_name: val,
}).then((res) => { // page: 1,
if (res.code == 1) { // size: -1,
this.sourceList = res.data; // }).then((res) => {
res.data.forEach((r) => { // if (res.code == 1) {
this.dataSource.push(r.name); // this.sourceList = res.data;
}); // console.log(res.data);
} // res.data.forEach((r) => {
}); // this.dataSource.push(r.name);
}, 0), // });
onSelect(val) { // }
this.businessName = val; // });
}, // }, 0),
// onSelect(val) {
// this.businessName = val;
// },
}, },
}; };
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
@headerH: 4.5rem; @headerH: 4.5rem;
.Container { .Container {
width: 100%;
height: 100% !important; height: 100% !important;
// background: #fac; // background: #fac;
background: #f5f5f5; background: #f5f5f5;
......
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