<template>
|
<!-- 主内容 -->
|
<FYSearchBar ref="searchRef" @search="search" :loading="loading">
|
<template #options>
|
<!-- 区县 -->
|
<FYOptionLocation
|
:allOption="false"
|
:level="3"
|
:checkStrictly="false"
|
v-model:value="formSearch.locations"
|
style="width: 300px"
|
></FYOptionLocation>
|
<!-- 场景类型 -->
|
<!-- <FYOptionScene
|
:allOption="true"
|
:type="2"
|
v-model:value="formSearch.scenetype"
|
></FYOptionScene> -->
|
<!-- 时间 -->
|
<FYOptionTime
|
:initValue="false"
|
type="datetimerange"
|
v-model:value="formSearch.timeArray"
|
style="width: 250px"
|
></FYOptionTime>
|
</template>
|
<template #buttons>
|
<el-button
|
icon="Download"
|
type="primary"
|
class=""
|
:loading="docLoading"
|
:disabled="!docParam"
|
@click="genWord()"
|
>
|
生成报告
|
</el-button>
|
<el-button
|
icon="Download"
|
type="success"
|
class=""
|
:disabled="!docParam"
|
@click="exportToExcel()"
|
>
|
下载表格
|
</el-button>
|
</template>
|
</FYSearchBar>
|
|
<div class="m-task container">
|
<!--头部信息-->
|
<div class="h-top col-md-12">
|
<div class="m-top">
|
<span class="title-input"> {{ reportName }} </span>
|
<!-- <input
|
type="text"
|
class="title-input"
|
value="秋冬污染季期间徐汇区扬尘污染辅助监管工作日报"
|
/> -->
|
</div>
|
</div>
|
|
<div class="m-msg col-md-12">
|
<span>{{ descMsg }}</span>
|
<div class="report-table row">
|
<table id="table_subtask" class="" border="1"></table>
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<script>
|
import taskApi from '@/api/fysp/taskApi';
|
import dayjs from 'dayjs';
|
import * as XLSX from 'xlsx';
|
import FileSaver from 'file-saver';
|
import analysisApi from '@/api/fysp/analysisApi.js';
|
import { exportDocx } from '@/utils/doc';
|
|
export default {
|
name: 'DailyReport',
|
computed: {
|
reportName() {
|
return `${this.formSearch.locations.dName}扬尘污染辅助监管工作日报`;
|
}
|
},
|
data() {
|
return {
|
CompTable: {
|
title: [],
|
content: [],
|
tableStyleClass: 'comp-table',
|
rowStyleClss: 'oddrowcolor',
|
|
init: function (title, content) {
|
this.title = title;
|
this.content = content;
|
},
|
|
/**
|
* 展示表格
|
* @param {*} elementId table的id
|
*/
|
show: function (elementId) {
|
const table = document.getElementById(elementId);
|
if (table) {
|
table.innerHTML = '';
|
table.classList.add(this.tableStyleClass);
|
this.createHead(elementId);
|
this.createContents(elementId);
|
}
|
},
|
|
/**
|
* 生成表头
|
* @param {*} elementId
|
*/
|
createHead: function (elementId) {
|
const element = document.getElementById(elementId);
|
if (element) {
|
const row = document.createElement('tr');
|
for (let index = 0; index < this.title.length; index++) {
|
const th = document.createElement('th');
|
th.setAttribute('align', 'center');
|
th.textContent =
|
this.title[index] === undefined ? '' : this.title[index];
|
row.appendChild(th);
|
}
|
element.appendChild(row);
|
}
|
},
|
|
/**
|
* 生成表内容
|
* @param {*} elementId
|
*/
|
createContents: function (elementId) {
|
const element = document.getElementById(elementId);
|
if (element) {
|
for (let index = 0; index < this.content.length; index++) {
|
if (index % 2 === 0) {
|
this.rowStyleClss = 'evenrowcolor';
|
} else {
|
this.rowStyleClss = 'oddrowcolor';
|
}
|
const rowArray = this.content[index];
|
this.createRow(rowArray, elementId);
|
}
|
}
|
},
|
|
/**
|
* 生成一行(包括合并单元格)
|
* @param {*} rowArray
|
*/
|
createRow: function (rowArray, elementId) {
|
const maxRows = this.getMaxRow(rowArray);
|
const leftArray = [];
|
|
const tr = document.createElement('tr');
|
for (let i = 0; i < rowArray.length; i++) {
|
let cell = rowArray[i];
|
if (Array.isArray(cell)) {
|
const rowspan = maxRows / cell.length;
|
const td = document.createElement('td');
|
td.setAttribute('rowspan', rowspan);
|
td.classList.add(this.rowStyleClss);
|
td.textContent = cell[0] === undefined ? '' : cell[0];
|
tr.appendChild(td);
|
leftArray.push(cell.slice(1)); // Save the rest of the cell contents
|
} else {
|
const td = document.createElement('td');
|
td.setAttribute('rowspan', maxRows);
|
td.classList.add(this.rowStyleClss);
|
td.textContent = cell === undefined ? '' : cell;
|
tr.appendChild(td);
|
}
|
}
|
document.getElementById(elementId).appendChild(tr);
|
|
for (let i = 1; i < maxRows; i++) {
|
const tr = document.createElement('tr');
|
leftArray.forEach((cell, y) => {
|
if (i < cell.length) {
|
const td = document.createElement('td');
|
td.setAttribute('rowspan', maxRows / (cell.length - i));
|
td.classList.add(this.rowStyleClss);
|
td.textContent = cell[i] === undefined ? '' : cell[i];
|
tr.appendChild(td);
|
}
|
});
|
document.getElementById(elementId).appendChild(tr);
|
}
|
},
|
|
/**
|
* 获取这一行中需要合并的行数
|
* @param {*} rowArray
|
*/
|
getMaxRow: function (rowArray) {
|
let maxRows = 1;
|
rowArray.forEach((element) => {
|
if (Array.isArray(element) && element.length > maxRows) {
|
maxRows = element.length;
|
}
|
});
|
return maxRows;
|
}
|
},
|
|
canClickDay: [],
|
excelConfig: {
|
title: '',
|
data: [],
|
fields: []
|
},
|
table: {
|
headers: [],
|
data: []
|
},
|
loading: false,
|
formSearch: {
|
locations: {},
|
scenetype: {},
|
time: [],
|
timeArray: [new Date(), new Date()],
|
districtCode: '310116'
|
},
|
descMsg: '',
|
// 导出报告参数
|
docParam: undefined,
|
docLoading: false
|
};
|
},
|
watch: {
|
formSearch: {
|
handler(nV, oV) {
|
// this.getCanClickDay();
|
},
|
deep: true
|
// immediate: true
|
}
|
},
|
mounted() {
|
this.formSearch.time = new Date();
|
},
|
methods: {
|
disabledDate(time) {
|
this.getCanClickDay();
|
let disabled =
|
this.canClickDay.filter((item) => {
|
let date = dayjs(time);
|
let itemDay = new Date(item);
|
console.log(
|
'curr preview time canClickDay',
|
itemDay.getFullYear(),
|
itemDay.getMonth(),
|
itemDay.getDate()
|
);
|
console.log(
|
'curr preview time date',
|
date.year(),
|
date.month(),
|
date.date()
|
);
|
return (
|
date.year() == itemDay.getFullYear() &&
|
date.month() == itemDay.getMonth() &&
|
date.date() == itemDay.getDate()
|
);
|
}).length == 0;
|
return !disabled;
|
},
|
getSelectedCityname() {
|
let city = '';
|
|
switch (this.formSearch.districtCode) {
|
case '310116':
|
city = '金山区';
|
break;
|
case '310106':
|
city = '静安区';
|
break;
|
case '310104':
|
city = '徐汇区';
|
break;
|
case '310105':
|
city = '长宁区';
|
break;
|
}
|
return city;
|
},
|
getCanClickDay() {
|
taskApi.getTopTask().then((res) => {
|
this.canClickDay = [];
|
let city = this.getSelectedCityname();
|
res
|
.filter((r) => {
|
return (
|
r.districtname == city &&
|
dayjs(this.formSearch.time).year() == dayjs(r.starttime).year() &&
|
dayjs(this.formSearch.time).month() == dayjs(r.starttime).month()
|
);
|
})
|
.map((topTask) => {
|
taskApi.fetchDayTasks(topTask.tguid).then((res) => {
|
res.forEach((r) => {
|
let formSearchDate = dayjs(this.formSearch.time);
|
let date = new Date();
|
dayjs(date)
|
.year(formSearchDate.year())
|
.month(formSearchDate.month())
|
.date(Number(r.date.slice(8, 10)));
|
this.canClickDay.push(date);
|
});
|
console.log('this.canClickDay', this.canClickDay);
|
});
|
});
|
});
|
},
|
exportToExcel() {
|
// 创建工作簿
|
const wb = XLSX.utils.book_new();
|
|
var wsData = [];
|
for (let index = 0; index < this.table.data.length; index++) {
|
const dataItem = this.table.data[index];
|
var row = {};
|
wsData.push(row);
|
for (let index = 0; index < dataItem.length; index++) {
|
row[this.table.headers[index]] = dataItem[index];
|
}
|
}
|
console.log('data', wsData);
|
|
// 创建工作表
|
const ws = XLSX.utils.json_to_sheet(wsData);
|
|
// 将工作表添加到工作簿
|
XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');
|
|
// 生成Excel文件
|
const wbout = XLSX.write(wb, { bookType: 'xlsx', type: 'binary' });
|
|
// 字符串转ArrayBuffer
|
function s2ab(s) {
|
const buf = new ArrayBuffer(s.length);
|
const view = new Uint8Array(buf);
|
for (let i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xff;
|
return buf;
|
}
|
|
// 保存文件
|
FileSaver.saveAs(
|
new Blob([s2ab(wbout)], { type: 'application/octet-stream' }),
|
`${this.reportName}.xlsx`
|
);
|
},
|
search() {
|
let sTime = dayjs(this.formSearch.timeArray[0])
|
.hour(0)
|
.minute(0)
|
.second(0)
|
.millisecond(0);
|
let eTime = dayjs(this.formSearch.timeArray[1])
|
.hour(23)
|
.minute(59)
|
.second(59)
|
.millisecond(0);
|
// eTime = eTime.toISOString();
|
// sTime = sTime.toISOString();
|
|
let config = {
|
startTime: sTime.toDate(),
|
endTime: eTime.toDate(),
|
districtCode: this.formSearch.locations.dCode
|
};
|
this.loading = true;
|
analysisApi
|
.dailyreport(config)
|
.then((res) => {
|
this.table.headers = res.tableTitle[0];
|
this.table.data = res.tableContent;
|
|
this.CompTable.init(res.tableTitle[0], res.tableContent);
|
this.CompTable.show('table_subtask');
|
|
const countMap = new Map(); //各场景数量
|
let proCount = 0; //总计问题数量
|
let changeCount = 0; //总计整改数量
|
const tableRows = [];
|
|
res.tableContent.forEach((cList) => {
|
const sceneType = cList[2];
|
if (!(sceneType in countMap)) {
|
countMap[sceneType] = 0;
|
}
|
countMap[sceneType] += 1;
|
proCount += Number(cList[10]);
|
changeCount += Number(cList[13]);
|
|
tableRows.push({
|
sIndex: cList[0],
|
sType: sceneType,
|
sName: cList[3],
|
sLocation: cList[4],
|
sProblemList: cList[8].split('\n'),
|
time: cList[6],
|
sTown: cList[5],
|
sChangeList: cList[11].split('\n')
|
});
|
});
|
|
let countStr = '';
|
for (const key in countMap) {
|
const e = countMap[key];
|
if (countStr != '') {
|
countStr += '、';
|
}
|
countStr += `${key}${e}个`;
|
}
|
this.descMsg = `共巡查${res.tableContent.length}个扬尘场景(${countStr}),共发现问题${proCount}项,督促整改了${changeCount}项。`;
|
|
this.docParam = {
|
month: sTime.month() + 1,
|
day: sTime.date(),
|
index: 1,
|
hasMoreDays: !sTime.isSame(eTime, 'day'),
|
endMonth: eTime.month() + 1,
|
endDay: eTime.date(),
|
totalScene: res.tableContent.length,
|
sceneNumTxt: countStr,
|
proNum: proCount,
|
changeNum: changeCount,
|
unChangeNum: proCount - changeCount,
|
table1: tableRows
|
};
|
})
|
.finally(() => (this.loading = false));
|
},
|
// 生成word报告
|
genWord() {
|
if (this.docParam) {
|
const param = this.docParam;
|
exportDocx(
|
'/秋冬季空气质量攻坚工作提示模板.docx',
|
param,
|
`秋冬季空气质量攻坚工作提示(${param.month}月${param.day}日).docx`
|
);
|
}
|
}
|
}
|
};
|
</script>
|
<style>
|
.options {
|
display: flex;
|
}
|
.c-time {
|
width: 12rem;
|
height: 3rem;
|
border-radius: 3px;
|
|
font-size: 1rem;
|
}
|
.download-div {
|
}
|
.download-btn {
|
background-color: #5599cc;
|
width: 10rem;
|
height: 2.6rem;
|
color: #ffffff;
|
border-radius: 3px;
|
margin-right: 2rem;
|
}
|
.h-top .m-top {
|
/* width: 100%; */
|
padding-right: 8rem;
|
/* padding: 0 7% 0 0%; */
|
/* min-height: 8rem; */
|
display: flex;
|
flex-direction: column;
|
justify-content: space-between;
|
align-items: center;
|
}
|
.title-input {
|
margin-top: -20px;
|
border-radius: 6px;
|
color: #000;
|
width: 80%;
|
font-size: 1.5rem;
|
line-height: 5rem;
|
text-align: center;
|
border: none;
|
}
|
.report-desc {
|
width: 80%;
|
margin-top: 5rem;
|
}
|
.desc-textarea {
|
width: 100%;
|
text-indent: 6rem;
|
font-size: 1rem;
|
margin-left: 5px;
|
}
|
.report-table {
|
width: 100%;
|
margin-top: 2rem;
|
table-layout: fixed;
|
}
|
.r-table {
|
width: 100%;
|
font-size: 2rem;
|
}
|
.r-table tr {
|
height: auto;
|
}
|
.r-table th {
|
height: 100%;
|
text-align: center;
|
}
|
.r-table td {
|
border-width: 1px;
|
min-width: 6rem;
|
}
|
.render-html {
|
cursor: pointer;
|
}
|
.h-top .m-top .task-div {
|
width: 100%;
|
display: flex;
|
justify-content: flex-end;
|
height: 2.6rem;
|
margin-bottom: 1rem;
|
}
|
|
/******************************表格样式*******************************/
|
table.comp-table {
|
font-family: verdana, arial, sans-serif;
|
font-size: 11px;
|
color: #333333;
|
border-width: 1px;
|
border-color: #666666;
|
border-collapse: collapse;
|
margin: 4px;
|
width: 87vw;
|
}
|
table.comp-table th {
|
border-width: 1px;
|
padding: 8px;
|
border-style: solid;
|
border-color: #666666;
|
background-color: #dedede;
|
text-align: center; /** 设置水平方向居中 */
|
vertical-align: middle; /** 设置垂直方向居中 */
|
}
|
table.comp-table td {
|
border-width: 1px;
|
padding: 8px;
|
border-style: solid;
|
border-color: #666666;
|
/* background-color: #ffffff; */
|
}
|
.oddrowcolor {
|
background-color: #d9f2f5;
|
}
|
.evenrowcolor {
|
background-color: #eff6f8;
|
}
|
/**********************************************************************/
|
</style>
|