<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>
|
<CompProdGenScenseDescription
|
id="descriptionComp"
|
class="product-item-margin"
|
:table-data="tableData"
|
:location="formSearch._locations"
|
ref="prodGenDescriptionRef"
|
@generated-description="onGeneratedDescription"
|
>
|
</CompProdGenScenseDescription>
|
<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
|
class="product-item-margin"
|
ref="dynamicTableRef"
|
: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">
|
<CompSelectProdStage
|
:table-header="tableConfig"
|
@next="selectProdStageOver"
|
>
|
</CompSelectProdStage>
|
</el-dialog>
|
<el-dialog title="产品预览" v-model="previewDialog" destroy-on-close>
|
<CompSelectProdStage @next="selectProdStageOver"> </CompSelectProdStage>
|
</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 DynamicTable from './components/DynamicTable.vue';
|
import CompSelectProdStage from './components/CompSelectProdStage.vue';
|
import sceneApi from '@/api/fysp/sceneApi';
|
import taskApi from '@/api/fysp/taskApi.js';
|
import CompProdGenScenseDescription from './components/CompProdGenScenseDescription.vue';
|
import htmlTransfer from './js/htmlTransfer';
|
import CompShowEChart from './components/CompShowEChart.vue';
|
import html2canvas from 'html2canvas';
|
import CompGooderProdStage from './components/CompGooderProdStage,.vue';
|
import dayjs from 'dayjs';
|
import genChart from './js/genChart';
|
export default {
|
computed: {
|
title() {
|
return (
|
(this.formSearch._locations.tName ||
|
this.formSearch._locations.dName ||
|
this.formSearch._locations.cName ||
|
this.formSearch._locations.pName ||
|
'') + '地区场景清单'
|
);
|
}
|
},
|
components: {
|
DynamicTable,
|
CompSelectProdStage,
|
CompProdGenScenseDescription,
|
CompShowEChart,
|
CompGooderProdStage
|
},
|
data() {
|
return {
|
activeStep: {
|
id: 0,
|
name: '产品配置生成'
|
},
|
steps: [
|
{
|
id: 0,
|
name: '产品配置生成'
|
},
|
{
|
id: 1,
|
name: '产品配置优化'
|
},
|
{
|
id: 2,
|
name: '生成'
|
}
|
],
|
gooderDialog: false,
|
searchLoading: false,
|
description: '',
|
showChart: false,
|
chart: {},
|
charts: [],
|
chartDialog: false,
|
genDialog: false,
|
tableConfig: [],
|
tableData: [],
|
formSearch: {
|
_locations: {},
|
searchText: '',
|
_scenetypes: [],
|
_scenetype: {},
|
online: {}
|
}
|
};
|
},
|
mounted() {
|
this.genHeaders();
|
},
|
methods: {
|
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();
|
},
|
captureScreenshot() {
|
const element = document.getElementById('descriptionComp');
|
|
return html2canvas(element).then((canvas) =>
|
canvas.toDataURL('image/png')
|
);
|
},
|
onGeneratedDescription(description) {
|
this.description = description;
|
},
|
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;
|
},
|
onPaintedChart(chartOption) {
|
this.showChart = true;
|
let id = `chart${this.charts.length}`;
|
this.charts.push({
|
id: id,
|
option: chartOption
|
});
|
console.log('chartOption', chartOption);
|
|
setTimeout(() => {
|
this.paintChart(id, chartOption);
|
}, 100);
|
},
|
genWord() {
|
let imgUrls = this.charts.map((item) => {
|
return htmlTransfer.chartToImageUrl(
|
this.$echarts.getInstanceByDom(document.getElementById(item.id))
|
);
|
});
|
|
this.captureScreenshot().then((item) => {
|
const month = dayjs(new Date()).month() + 1;
|
const day = dayjs(new Date()).date();
|
const data = {
|
title: this.title,
|
month: month,
|
day: day,
|
sceneTypeImg: imgUrls[0],
|
positionImg: imgUrls[1],
|
description: this.description,
|
tableData: this.tableData,
|
imgUrls: imgUrls
|
};
|
const imgSize = {
|
imgUrl: [300, 350]
|
};
|
htmlTransfer.ExportBriefDataDocx(
|
'.\\test.docx', // 模板路径
|
data, // 数据
|
this.title, // 文件名
|
imgSize
|
);
|
});
|
},
|
previewProduct() {
|
this.genWord();
|
},
|
// 第一阶段确定之后的回调
|
selectProdStageOver(result) {
|
this.genDialog = false;
|
this.nextStep();
|
if (result != null) {
|
this.formSearch._locations = result._locations;
|
this.formSearch._scenetypes = result._scenetype;
|
|
this.$refs.dynamicTableRef.onSearch();
|
}
|
},
|
genSomeCharts() {
|
// 添加图表
|
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';
|
}
|
}
|
}
|
}
|
[
|
genChart.getChartByDataAndProp(this.tableData, 'type', '类型', '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);
|
});
|
},
|
getList(page) {
|
let promises = [];
|
if (this.formSearch._scenetypes == undefined) {
|
let obj = {};
|
this.fillPosition(obj);
|
promises.push(
|
// sceneApi.searchScene(obj, page.currentPage, page.pageSize)
|
sceneApi.searchScene(obj, 1, 9999)
|
);
|
this.addOnlineProp();
|
this.addExistTopTask();
|
return promises;
|
} else {
|
for (
|
let index = 0;
|
index < this.formSearch._scenetypes.length;
|
index++
|
) {
|
const item = this.formSearch._scenetypes[index];
|
let obj = {
|
// online: true
|
};
|
this.fillPosition(obj);
|
obj.scensetypeid = item.value;
|
if (obj.scensetypeid == '0') obj.scensetypeid = null;
|
promises.push(sceneApi.searchScene(obj, 1, 9999));
|
}
|
this.addOnlineProp();
|
this.addExistTopTask();
|
return promises;
|
}
|
},
|
onSearch(page, func) {
|
this.searchLoading = true;
|
return Promise.all(this.getList(page)).then((results) => {
|
this.tableData = [];
|
|
results.forEach((res) => {
|
if (res.success) {
|
res.data.forEach((item) => {
|
this.tableData.push(item);
|
});
|
}
|
});
|
this.addOnlineProp();
|
this.addExistTopTask();
|
this.genSomeCharts();
|
this.searchLoading = false;
|
func({
|
data: this.tableData
|
});
|
});
|
},
|
fillPosition(area) {
|
const f = this.formSearch;
|
// 行政区划
|
area.provincecode = f._locations.pCode;
|
area.citycode = f._locations.cCode;
|
area.districtcode = f._locations.dCode;
|
area.towncode = f._locations.tCode;
|
},
|
getArea(area) {
|
const f = this.formSearch;
|
// 场景类型
|
area.scensetypeid = f._scenetype.value;
|
if (area.scensetypeid == '0') area.scensetypeid = null;
|
// 上下线状态
|
area.online = f.online.value;
|
// 查询关键字(场景名称)
|
area.sceneName = f.searchText;
|
},
|
addOnlineProp() {
|
this.tableData.forEach(
|
(item) => (item._isOnline = item.extension1 == 1 ? '是' : '否')
|
);
|
},
|
addExistTopTask() {
|
taskApi.getTopTask().then((res) => {
|
const topTaskId = res[0].tguid;
|
taskApi.fetchMonitorObjectVersion(topTaskId).then((subTaskRes) => {
|
let alreadyExistTopTask = subTaskRes.map((item) => item.sguid);
|
this.noExistTopTaskNum = 0;
|
this.existTopTaskNum = 0;
|
this.tableData.forEach((e) => {
|
if (alreadyExistTopTask.indexOf(e.guid) == -1) {
|
e._isExistInTopTask = '不在监管计划内';
|
} else {
|
e._isExistInTopTask = '在监管计划内';
|
}
|
});
|
});
|
});
|
},
|
genHeaders() {
|
this.tableConfig = [
|
{
|
id: 1,
|
label: '编号',
|
prop: 'index',
|
width: '80',
|
disabled: true
|
},
|
{
|
id: 2,
|
label: '名称',
|
prop: 'name',
|
width: '400',
|
disabled: true
|
},
|
{
|
id: 3,
|
label: '类型',
|
prop: 'type',
|
width: '130',
|
sortable: true,
|
disabled: true
|
},
|
{
|
id: 4,
|
label: '省',
|
prop: 'provincename',
|
width: '90',
|
disabled: true
|
},
|
{
|
id: 5,
|
label: '市',
|
prop: 'cityname',
|
width: '90',
|
disabled: true
|
},
|
{
|
id: 6,
|
label: '区县',
|
prop: 'districtname',
|
width: '90',
|
disabled: true
|
},
|
{
|
id: 7,
|
label: '街道',
|
prop: 'townname',
|
width: '110',
|
disabled: true
|
},
|
{
|
id: 8,
|
label: '地址',
|
prop: 'location',
|
width: '400',
|
disabled: true
|
},
|
{
|
id: 9,
|
label: '经度',
|
prop: 'longitude',
|
width: '110',
|
merge: 10,
|
title: '经纬度',
|
disabled: true
|
},
|
{
|
id: 10,
|
label: '纬度',
|
prop: 'latitude',
|
width: '110',
|
merge: 9,
|
disabled: true
|
},
|
{
|
id: 11,
|
label: '联系人',
|
prop: 'contacts',
|
width: '110',
|
disabled: true
|
},
|
{
|
id: 12,
|
label: '联系电话',
|
prop: 'contactst',
|
width: '110',
|
disabled: true
|
},
|
{
|
id: 13,
|
label: '备注',
|
prop: 'remark',
|
width: '110'
|
},
|
{
|
id: 14,
|
label: '运营中',
|
prop: '_isOnline',
|
width: '110',
|
sortable: true,
|
disabled: true
|
},
|
{
|
id: 15,
|
label: '是否存在于总任务中',
|
prop: '_isExistInTopTask',
|
width: '110',
|
sortable: true,
|
disabled: true
|
}
|
];
|
}
|
}
|
};
|
</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;
|
}
|
.fixed-div-steps {
|
position: fixed;
|
top: 7%;
|
width: 100%; /* div 的宽度 */
|
background-color: #f2f2f200; /* 背景颜色 */
|
padding: 5px;
|
z-index: 1000; /* 确保 div 在页面其他内容之上 */
|
}
|
/* 固定定位的 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>
|