<template>
|
<el-col>
|
<el-row justify="end" class="fixed-div">
|
<!-- 按钮组 -->
|
<div class="btn-group">
|
<el-button v-if="this.activeStep.id > 0" @click="beforeStep"
|
>上一步</el-button
|
>
|
<el-button
|
v-if="this.activeStep.id == 0"
|
@click="genDialog = true"
|
type="primary"
|
>产品生成配置</el-button
|
>
|
<el-button
|
v-if="this.activeStep.id == 1"
|
@click="gooderDialog = true"
|
type="primary"
|
>产品优化配置</el-button
|
>
|
<!-- <el-button type="primary" @click="chartDialog = true"
|
>图表展示</el-button
|
> -->
|
<el-button
|
v-if="this.activeStep.id == 2"
|
type="primary"
|
@click="previewProduct"
|
>生成</el-button
|
>
|
</div>
|
</el-row>
|
</el-col>
|
<!-- 步骤 -->
|
<el-steps
|
:active="activeStep.id"
|
finish-status="success"
|
style=""
|
align-center
|
>
|
<el-step v-for="(s, i) in steps" :key="s.id" :title="s.name" />
|
</el-steps>
|
<div class="center-div">
|
<span class="title-input"> {{ title }} </span><br />
|
</div>
|
<div class="center-div">
|
<div
|
v-show="this.activeStep.id != 0"
|
class="main"
|
v-loading="searchLoading"
|
>
|
<span class="second-title"> {{ `一、监管概况` }} </span>
|
<CompProdGenMonitorInfoDescription
|
id="descriptionComp"
|
class="product-item-margin"
|
:table-data="tableData"
|
:location="formSearch._locations"
|
ref="prodGenDescriptionRef"
|
@generated-description="onGeneratedDescription"
|
>
|
</CompProdGenMonitorInfoDescription>
|
<template v-if="showChart">
|
<span class="second-title"> {{ `二、统计透视` }} </span>
|
<div class="charts product-item-margin">
|
<div class="chart-item" v-for="chart in charts" :key="chart.id">
|
<div class="chart" ref="myChart" :id="chart.id"></div>
|
<!-- <el-button
|
type="danger"
|
@click="charts = charts.filter((item) => item.id != chart.id)"
|
>删除</el-button
|
> -->
|
</div>
|
</div>
|
</template>
|
<span class="second-title"> {{ `三、详细清单` }} </span>
|
<DynamicTable
|
ref="dynamicTableRef"
|
v-loading="loading"
|
:table-header="tableConfig"
|
@search="onSearch"
|
:pagination="false"
|
></DynamicTable>
|
</div>
|
<el-empty
|
v-show="this.activeStep.id == 0"
|
style="font-size: large"
|
description="未配置产品"
|
/>
|
</div>
|
|
<el-dialog title="产品生成配置" v-model="genDialog">
|
<ComSelectMonitorTaskProdStage
|
:table-header="tableConfig"
|
@next="selectProdStageOver"
|
>
|
</ComSelectMonitorTaskProdStage>
|
</el-dialog>
|
<el-dialog title="产品优化" v-model="gooderDialog" destroy-on-close>
|
<CompGooderProdStage
|
:table-header="tableConfig"
|
@selected-gooder="onselectedGooder"
|
>
|
</CompGooderProdStage>
|
</el-dialog>
|
<el-dialog title="图表展示" v-model="chartDialog" destroy-on-close>
|
<CompShowEChart
|
@painted-chart="onPaintedChart"
|
:table-data="tableData"
|
:table-header="tableConfig"
|
ref="chartRef"
|
>
|
</CompShowEChart>
|
</el-dialog>
|
</template>
|
<script>
|
import sceneApi from '@/api/fysp/sceneApi';
|
import taskApi from '@/api/fysp/taskApi.js';
|
import DynamicTable from './components/DynamicTable.vue';
|
import { load } from '@amap/amap-jsapi-loader';
|
import ComSelectMonitorTaskProdStage from './components/ComSelectMonitorTaskProdStage.vue';
|
import CompProdGenMonitorInfoDescription from './components/CompProdGenMonitorInfoDescription.vue';
|
import CompShowEChart from './components/CompShowEChart.vue';
|
import htmlTransfer from './js/htmlTransfer';
|
import dayjs from 'dayjs';
|
import CompGooderProdStage from './components/CompGooderProdStage,.vue';
|
import genChart from './js/genChart';
|
export default {
|
components: {
|
DynamicTable,
|
ComSelectMonitorTaskProdStage,
|
CompProdGenMonitorInfoDescription,
|
CompShowEChart,
|
CompGooderProdStage
|
},
|
computed: {
|
title() {
|
return (
|
(this.formSearch._locations.tName ||
|
this.formSearch._locations.dName ||
|
this.formSearch._locations.cName ||
|
this.formSearch._locations.pName ||
|
'') + '监管清单'
|
);
|
}
|
},
|
watch: {
|
oneValue: {
|
handler(nv, ov) {
|
console.log('master', nv);
|
},
|
immediate: true,
|
deep: true
|
}
|
},
|
data() {
|
return {
|
gooderDialog: false,
|
activeStep: {
|
id: 0,
|
name: '产品配置生成'
|
},
|
steps: [
|
{
|
id: 0,
|
name: '产品配置生成'
|
},
|
{
|
id: 1,
|
name: '产品配置优化'
|
},
|
{
|
id: 2,
|
name: '生成'
|
}
|
],
|
mainVisible: false,
|
showChart: false,
|
chartDialog: false,
|
genDialog: false,
|
oneValue: {
|
_locations: {},
|
_scenetype: []
|
},
|
charts: [],
|
chart: {},
|
loading: false,
|
tableConfig: [],
|
tableData: [],
|
formSearch: {
|
topTask: '',
|
_locations: {},
|
searchText: '',
|
_scenetype: {},
|
online: {},
|
topTasks: []
|
},
|
topTasks: []
|
};
|
},
|
mounted() {
|
this.getOptions();
|
this.genHeaders();
|
},
|
methods: {
|
genWord() {
|
let imgUrls = this.charts.map((item) => {
|
return htmlTransfer.chartToImageUrl(
|
this.$echarts.getInstanceByDom(document.getElementById(item.id))
|
);
|
});
|
const data = {
|
title: this.title,
|
description: this.description,
|
tableData: this.tableData,
|
imgUrls: imgUrls
|
};
|
const imgSize = {
|
imgUrl: [200, 200]
|
};
|
htmlTransfer.ExportBriefDataDocx(
|
'.\\test.docx', // 模板路径
|
data, // 数据
|
this.title, // 文件名
|
imgSize
|
);
|
},
|
previewProduct() {
|
this.genWord();
|
},
|
onGeneratedDescription(description) {
|
this.description = description;
|
},
|
onPaintedChart(chartOption) {
|
this.showChart = true;
|
let id = `chart${this.charts.length}`;
|
this.charts.push({
|
id: id,
|
option: chartOption
|
});
|
console.log('chartOption', chartOption);
|
setTimeout(() => {
|
const dom = document.getElementById(id);
|
|
const myChart = this.$echarts.init(dom); // 初始化echarts实例
|
this.chart = myChart;
|
myChart.setOption(chartOption);
|
this.chartDialog = false;
|
}, 100);
|
},
|
// 第一阶段确定之后的回调
|
selectProdStageOver(result) {
|
this.genDialog = false;
|
this.nextStep();
|
if (result != null) {
|
this.formSearch._locations = result._locations;
|
this.formSearch.topTasks = result.topTasks;
|
|
this.$refs.dynamicTableRef.onSearch();
|
}
|
console.log('第一阶段返回值', result);
|
},
|
onTopTaskChange(value) {
|
this.$refs.dynamicTableRef.onSearch();
|
},
|
//获取查询条件
|
getOptions() {
|
taskApi.getTopTask().then((res) => {
|
const list = res.map((r) => {
|
return {
|
value: r.tguid,
|
label: r.name,
|
data: r
|
};
|
});
|
this.topTasks = list;
|
this.formSearch.topTask = list[0];
|
// this.$refs.dynamicTableRef.onSearch();
|
});
|
},
|
addSceneRegion(obj) {
|
obj.scene._region =
|
obj.scene.provincename +
|
obj.scene.cityname +
|
obj.scene.districtname +
|
obj.scene.townname +
|
obj.scene.location;
|
},
|
standardSupervisedNum(obj) {
|
obj.extension1 = obj.extension1 ? obj.extension1 : 0;
|
},
|
addSupervisedTime(monitorObj) {
|
console.log('monitorObj', monitorObj);
|
if (!('_subTasks' in monitorObj) || monitorObj._subTasks.length == 0) {
|
monitorObj._executionstarttime = '/';
|
return;
|
}
|
monitorObj._executionstarttime = monitorObj._subTasks
|
.map((item) => dayjs(item.executionstarttime).format('YYYY-MM-DD'))
|
.join(',');
|
},
|
|
onSearch(page, func) {
|
this.loading = true;
|
// 获取当前监管任务下所有子任务
|
const getAllNeedSubTaskPromises = this.formSearch.topTasks.map((item) => {
|
return taskApi.getByTopTaskAndDate({ topTaskId: item.tguid });
|
});
|
|
const subTaskPromises = this.formSearch.topTasks.map((item) => {
|
return taskApi.fetchMonitorObjectVersion(item.tguid);
|
});
|
Promise.all(getAllNeedSubTaskPromises)
|
.then((results) => {
|
// 将二维数组展平成一维数组
|
const subTasks = results.reduce((acc, val) => acc.concat(val), []);
|
console.log('subTasks', subTasks);
|
|
return Promise.all(subTasks);
|
})
|
.then((allSubTasks) => {
|
// 使用 Promise.all 等待所有的子任务请求完成
|
Promise.all(subTaskPromises)
|
.then((results) => {
|
console.log('results', results);
|
// 将二维数组展平成一维数组
|
const flatResults = results.reduce(
|
(acc, val) => acc.concat(val),
|
[]
|
);
|
// 再次使用 Promise.all 处理一维数组中的每个元素
|
return Promise.all(flatResults);
|
})
|
.then((moniterRes) => {
|
// 保存日任务列表
|
taskApi.getTopTaskWithDayTask().then((allTopAndDay) => {
|
let topWithDyTask = allTopAndDay.filter((item) => {
|
return (
|
this.formSearch.topTasks
|
.map((top) => top.tguid)
|
.indexOf(item.tguid) != -1
|
);
|
});
|
|
const subTasks = [];
|
for (const r of moniterRes) {
|
// 赋值总任务 _topTask.daytaskList 为日任务列表
|
r._topTask = topWithDyTask.filter(
|
(item) => item.tguid == r.tid
|
)[0];
|
r._topTask.daytaskList.forEach((dayTask) => {
|
let dayTaskId = dayTask.tguid;
|
let topTaskId = dayTask.tsguid;
|
let sceneId = r.sguid;
|
let subTasks = this.selectSubTaskBySceneIdAndTaskId(
|
allSubTasks,
|
sceneId,
|
topTaskId,
|
dayTaskId
|
);
|
if (subTasks) {
|
r._subTasks = subTasks;
|
}
|
});
|
// 生成场景区域列
|
this.addSceneRegion(r);
|
// 标准化已监管次数
|
this.standardSupervisedNum(r);
|
// 生成监管时间列
|
this.addSupervisedTime(r);
|
// r._topTask = this.formSearch.topTask.data;
|
subTasks.push(r);
|
}
|
this.tableData = subTasks;
|
this.genSomeCharts();
|
func({
|
data: subTasks
|
});
|
this.loading = false;
|
});
|
})
|
.catch((error) => {
|
this.loading = false;
|
console.error('Error fetching subtasks:', error);
|
});
|
});
|
},
|
genSomeCharts() {
|
console.log("this.ta", this.tableData);
|
// 添加图表
|
this.charts = [];
|
this.showChart = true;
|
// 生成区域中的下一级的图表
|
const l = this.formSearch._locations;
|
console.log(this.tableData);
|
|
let positionProp = '';
|
if (l.pName != null) {
|
positionProp = 'cityname';
|
if (l.cName != null) {
|
positionProp = 'districtname';
|
if (l.dName != null) {
|
positionProp = 'townname';
|
if (l.tName != null) {
|
positionProp = 'townname';
|
}
|
}
|
}
|
}
|
positionProp = 'scene.' + positionProp;
|
[
|
genChart.getChartByDataAndProp(this.tableData, 'sceneType', '类型', 'bar'),
|
genChart.getPieChartByDataAndProp(
|
this.tableData,
|
positionProp,
|
'所属区域'
|
)
|
].forEach((item) => {
|
let id = `chart${this.charts.length}`;
|
this.charts.push({
|
id: id,
|
option: item
|
});
|
setTimeout(() => {
|
this.paintChart(id, item);
|
}, 100);
|
});
|
},
|
paintChart(id, chartOption) {
|
const dom = document.getElementById(id);
|
var startX, startY, chartWidth, chartHeight;
|
const myChart = this.$echarts.init(dom); // 初始化echarts实例
|
// 开始拖拽
|
myChart.getZr().on('mousedown', function (event) {
|
if (event.target) {
|
startX = event.offsetX;
|
startY = event.offsetY;
|
chartWidth = myChart.getWidth();
|
chartHeight = myChart.getHeight();
|
}
|
});
|
|
// 拖动调整宽度
|
myChart.getZr().on('mouseup', function (event) {
|
if (startX != null || startY != null) {
|
var deltaX = event.offsetX - startX;
|
var deltaY = event.offsetY - startY;
|
myChart.resize({
|
width: chartWidth + deltaX,
|
height: chartHeight + deltaY
|
});
|
}
|
startX = null;
|
startY = null;
|
});
|
|
this.chart = myChart;
|
myChart.setOption(chartOption);
|
this.chartDialog = false;
|
},
|
selectSubTaskBySceneIdAndTaskId(subTasks, sceneId, topTaskId, dayTaskId) {
|
return subTasks.filter(
|
(item) =>
|
item.scenseid == sceneId &&
|
item.tguid == topTaskId &&
|
item.tsguid == dayTaskId
|
);
|
},
|
beforeStep() {
|
let currId = this.activeStep.id;
|
this.activeStep = this.steps.filter((item) => item.id == currId - 1)[0];
|
},
|
nextStep() {
|
let currId = this.activeStep.id;
|
this.activeStep = this.steps.filter(
|
(item) => item.id == (currId + 1) % this.steps.length
|
)[0];
|
},
|
onselectedGooder(result) {
|
let copy = this.tableConfig.map((item) => item);
|
result.forEach((item) => {
|
copy = copy.filter(
|
(copyItem) => !(copyItem.id == item.id1 || copyItem.id == item.id2)
|
);
|
copy.push(item);
|
this.tableData.forEach(
|
(tableItem) =>
|
(tableItem[item.prop] = `${tableItem[item.prop1]},${
|
tableItem[item.prop2]
|
}`)
|
);
|
copy.sort((a, b) => a.id - b.id);
|
});
|
this.tableConfig = copy;
|
this.gooderDialog = false;
|
this.nextStep();
|
},
|
genHeaders() {
|
this.tableConfig = [
|
{
|
id: 1,
|
label: '场景名称',
|
prop: 'scene.name',
|
width: '80'
|
},
|
{
|
id: 2,
|
label: '场景所属区域',
|
prop: 'scene._region',
|
width: '80'
|
},
|
{
|
id: 3,
|
label: '场景类型',
|
prop: 'scene.type',
|
width: '20'
|
},
|
{
|
id: 4,
|
label: '计划次数',
|
prop: 'monitornum',
|
width: '20'
|
},
|
{
|
id: 5,
|
label: '实际已监管次数',
|
prop: 'extension1',
|
width: '20'
|
},
|
{
|
id: 6,
|
label: '实际执行日期',
|
prop: '_executionstarttime',
|
width: '20'
|
}
|
];
|
}
|
}
|
};
|
</script>
|
<style scoped>
|
.options {
|
display: flex;
|
padding: 5px;
|
}
|
.title-input {
|
margin-top: -20px;
|
border-radius: 6px;
|
color: #000;
|
width: 80%;
|
font-size: 1.5rem;
|
line-height: 5rem;
|
text-align: center;
|
border: none;
|
}
|
.center-div {
|
display: flex;
|
justify-content: center;
|
}
|
.btn-group {
|
/* background-color: rgb(32, 127, 211); */
|
white-space: nowrap;
|
}
|
.chart {
|
margin-top: 5px;
|
margin-bottom: 2px;
|
width: 100%;
|
height: 500px;
|
}
|
/* 固定定位的 div */
|
.fixed-div {
|
position: fixed;
|
top: 7%;
|
right: 20px; /* 距离右侧 20px */
|
width: 'auto'; /* div 的宽度 */
|
background-color: #f2f2f200; /* 背景颜色 */
|
padding: 5px;
|
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.11); /* 阴影效果 */
|
z-index: 1000; /* 确保 div 在页面其他内容之上 */
|
}
|
.charts {
|
display: flex;
|
flex-wrap: wrap;
|
}
|
.chart-item {
|
text-align: center;
|
width: 30%;
|
}
|
.product-item-margin {
|
margin-bottom: 5px;
|
}
|
.second-title {
|
color: var(--el-text-color-primary);
|
font-size: 16px;
|
font-weight: bold;
|
margin-bottom: 16px;
|
}
|
.main {
|
/* text-align: center; */
|
width: 95%;
|
}
|
</style>
|