riku
2024-10-24 fab51ed95159ffb71d58030a0d9f303c36733add
Merge remote-tracking branch 'supervisionVue/hc-dataAnalysis-1023'
已修改1个文件
已添加1个文件
614 ■■■■■ 文件已修改
src/api/fysp/analysisApi.js 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/fysp/data-product/ProdDailyReport.vue 607 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/fysp/analysisApi.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,7 @@
import { $fysp } from '../index';
export default {
    checkProblem(data) {
        return $fysp.post(`search/dailyreport`, data).then((res) => res.data);
    },
}
src/views/fysp/data-product/ProdDailyReport.vue
@@ -1,9 +1,614 @@
<template>
  <div>DailyReport</div>
  <!-- ä¸»å†…容 -->
  <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>