<template>
|
<!-- 主内容 -->
|
<div class="m-task container">
|
<!--头部信息-->
|
<div class="h-top col-md-12">
|
<div class="options">
|
<!-- <input type="date" class="c-time c-check" /> -->
|
<!-- 时间 -->
|
<el-form-item label="时间" :prop="prop" style="margin-left: 10px">
|
<el-date-picker
|
v-model="formSearch.time"
|
type="date"
|
placeholder="选择时间"
|
start-placeholder="选择开始时间"
|
end-placeholder="选择结束时间"
|
style="width: 180px"
|
/>
|
</el-form-item>
|
<el-form-item label="区域" :prop="prop" style="margin-left: 10px">
|
<el-select
|
placeholder="Select"
|
v-model="formSearch.districtCode"
|
class="c-area c-check"
|
style="width: 100px"
|
>
|
<el-option label="金山区" value="310116"></el-option>
|
<el-option label="静安区" value="310106"></el-option>
|
<el-option label="徐汇区" value="310104"></el-option>
|
<el-option label="长宁区" value="310105"></el-option>
|
</el-select>
|
</el-form-item>
|
|
<el-button
|
style="margin-left: 10px"
|
class="check-msg"
|
@click="search"
|
type="primary"
|
>查询</el-button
|
>
|
<el-button type="primary" class="" @click="exportToExcel()">
|
生成报告
|
</el-button>
|
</div>
|
<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
|
name="desc"
|
class="desc-textarea"
|
rows="5"
|
value=""
|
cols=""
|
disabled
|
></span>
|
<div class="report-table row">
|
<table id="table_subtask" class="" border="1"></table>
|
</div>
|
</div>
|
|
<div class="dark-screen">
|
<i class="fa fa-spinner fa-spin fa-3x" style="color: white"></i>
|
</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';
|
export default {
|
name: 'DailyReport',
|
computed: {
|
reportName() {
|
var city = '';
|
switch (this.formSearch.districtCode) {
|
case '310116':
|
city = '金山区';
|
break;
|
case '310106':
|
city = '静安区';
|
break;
|
case '310104':
|
city = '徐汇区';
|
break;
|
case '310105':
|
city = '长宁区';
|
break;
|
}
|
|
let title = `${city}扬尘污染辅助监管工作日报`;
|
return title;
|
}
|
},
|
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: []
|
},
|
formSearch: {
|
time: [],
|
districtCode: '310116'
|
}
|
};
|
},
|
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`
|
);
|
},
|
downloadFile() {
|
// 文件标题
|
let title = this.reportName;
|
// 表头描述
|
let desc = document.querySelector('.desc-textarea').textContent;
|
// 时间
|
let time = document
|
.querySelector('.desc-textarea')
|
.textContent.split(',')[0];
|
|
// 获取数据
|
let thData = Array.from(document.getElementsByTagName('th')).map(
|
(th) => th.innerText
|
);
|
let tdData = Array.from(document.getElementsByTagName('td')).map(
|
(td) => td.innerText
|
);
|
let totalList = [];
|
let subList = [];
|
let index = 2;
|
|
let inputStatus = true;
|
for (let j = 0; j < thData.length; j++) {
|
subList.push(thData[j]);
|
}
|
totalList.push(subList);
|
subList = [];
|
|
for (let i = 0; i < tdData.length; i++) {
|
if (tdData[i] !== String(index)) {
|
if (tdData[i] !== '') {
|
subList.push(tdData[i]);
|
} else {
|
if (inputStatus) {
|
let inputList = document.querySelectorAll(`.input-${subList[0]}`);
|
for (let j = 0; j < inputList.length; j++) {
|
subList.push(inputList[j].value);
|
}
|
inputStatus = false;
|
} else {
|
inputStatus = true;
|
}
|
}
|
} else {
|
totalList.push(subList);
|
subList = [String(index)];
|
index += 1;
|
}
|
}
|
totalList.push(subList);
|
|
// index: 0 head
|
// other: data
|
// title
|
|
let fileData = {
|
title: title,
|
time: time,
|
desc: desc,
|
data: totalList
|
};
|
|
// if (fileData.title && fileData.time && fileData.desc && fileData.data.length) {
|
// fetch("http://47.100.191.150:9002/dustmonitor/report", {
|
// method: "POST",
|
// headers: {
|
// "Content-Type": "application/json"
|
// },
|
// body: JSON.stringify(fileData)
|
// })
|
// .then(response => response.json())
|
// .then(res => {
|
// if (res.status === 200) {
|
// let name = res.name.split("./")[1];
|
// setTimeout(() => {
|
// let a = document.createElement("a");
|
// a.href = appConfig.downloadUrl + name;
|
// a.download = name; // 设置下载文件名
|
// document.body.appendChild(a);
|
// a.click();
|
// document.body.removeChild(a);
|
// }, 1000);
|
// }
|
// })
|
// .catch(error => console.error("Error:", error));
|
// }
|
},
|
search() {
|
let sTime = dayjs(this.formSearch.time).hour(0).minute(0).second(0);
|
let eTime = dayjs(this.formSearch.time).hour(23).minute(59).second(59);
|
eTime = eTime.toISOString();
|
sTime = sTime.toISOString();
|
|
let config = {
|
startTime: sTime,
|
endTime: eTime,
|
districtCode: this.formSearch.districtCode
|
};
|
analysisApi.checkProblem(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; //总计整改数量
|
|
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]);
|
});
|
|
let countStr = '';
|
for (const key in countMap) {
|
const e = countMap[key];
|
if (countStr != '') {
|
countStr += '、';
|
}
|
countStr += `${key}${e}个`;
|
}
|
|
var descMsg = `共巡查${res.tableContent.length}个扬尘场景(${countStr}),共发现问题${proCount}项,督促整改了${changeCount}项;前期余留问题均已销项。`;
|
console.log('descMsg', descMsg);
|
|
// 获取所有类名为 'desc-textarea' 的元素
|
const textareas = document.querySelectorAll('.desc-textarea');
|
|
// 遍历这些元素并设置其 HTML 内容
|
textareas.forEach(function (textarea) {
|
textarea.innerHTML = descMsg;
|
});
|
// $('.desc-textarea').html('');
|
// $('.desc-textarea').html(descMsg);
|
});
|
}
|
}
|
};
|
</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>
|