From f5052fa7d4e73c0df5a02a6ad8987f35df42b8f8 Mon Sep 17 00:00:00 2001 From: riku <risaku@163.com> Date: 星期四, 07 十一月 2024 17:23:50 +0800 Subject: [PATCH] 1. 完成场景报告模块 2. 日报管理模块添加时间范围选择以及word报告生成 --- src/views/fysp/data-product/ProdDailyReport.vue | 564 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 563 insertions(+), 1 deletions(-) diff --git a/src/views/fysp/data-product/ProdDailyReport.vue b/src/views/fysp/data-product/ProdDailyReport.vue index 78b8c00..510d10a 100644 --- a/src/views/fysp/data-product/ProdDailyReport.vue +++ b/src/views/fysp/data-product/ProdDailyReport.vue @@ -1,9 +1,571 @@ <template> - <div>DailyReport</div> + <!-- 涓诲唴瀹� --> + <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="绉嬪啲姹℃煋瀛f湡闂村緪姹囧尯鎵皹姹℃煋杈呭姪鐩戠宸ヤ綔鏃ユ姤" + /> --> + </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鐨刬d + */ + 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}椤癸紝鐫d績鏁存敼浜�${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( + '/绉嬪啲瀛g┖姘旇川閲忔敾鍧氬伐浣滄彁绀烘ā鏉�.docx', + param, + `绉嬪啲瀛g┖姘旇川閲忔敾鍧氬伐浣滄彁绀猴紙${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> -- Gitblit v1.9.3