riku
2025-10-21 dca26bac2c05fcfc9c7ed477b32a7fab1295a688
src/views/historymode/component/MissionReport.vue
@@ -14,14 +14,19 @@
        ></OptionLocation2>
      </el-form-item>
      <OptionTime v-model="formObj.timeArray"></OptionTime>
      <el-form-item label="移除其他区县" prop="removeOtherDistrict">
      <el-form-item label="区县筛选" prop="removeOtherDistrict">
        <el-checkbox v-model="formObj.removeOtherDistrict"
          >移除其他区县</el-checkbox
        >
      </el-form-item>
      <el-form-item label="移除未污染源" prop="removeNoPollutedSource">
      <el-form-item label="污染源筛选" prop="removeNoPollutedSource">
        <el-checkbox v-model="formObj.removeNoPollutedSource"
          >移除未发现污染源的线索</el-checkbox
        >
      </el-form-item>
      <el-form-item label="隐患区域" prop="showPollutedArea">
        <el-checkbox v-model="formObj.showPollutedArea"
          >将典型隐患区域表格作为附件展示</el-checkbox
        >
      </el-form-item>
      <el-form-item>
@@ -83,6 +88,7 @@
import { Legend } from '@/model/Legend';
import { getHexColor, getColorBetweenTwoColors } from '@/utils/color';
import { getGridDataDetailFactorValue } from '@/model/GridDataDetail';
import { factorName } from '@/constant/factor-name';
// 借用卫星遥测模块中的100米网格
const props = defineProps({
@@ -145,16 +151,19 @@
      mainFactor: '',
      _abnormalFactors: '',
      sceneCount: 0,
      _kilometres: '1000'
      _kilometres: '1000',
      _keyScene: '1个国控点(静安监测站)和2个市控点(和田中学、市北高新)',
      exceptionCount: 0,
      _focusScene: ''
    }
  ],
  missionDetailList: [
    {
      _index: 1,
      missionCode: '',
      _startTime: '2025年07月29日',
      _time: '09:00至14:30',
      _kilometres: '1000',
      _keyScene: '1个国控点(静安监测站)和2个市控点(和田中学、市北高新)',
      _dataStatistics: [
        {
          factor: 'PM10',
@@ -235,7 +244,9 @@
};
const handleGenerateImg = () => {
  generateClueByRiskArea(params.value).then(() => {});
  generateClueByRiskArea(params.value).then(() => {
    generateDocx();
  });
};
function generateMissionSummary(param) {
@@ -244,6 +255,10 @@
      new Date(res.data.startTime),
      new Date(res.data.endTime)
    );
    templateParam.subTitle =
      templateParam.sryTime.indexOf('季度') !== -1
        ? templateParam.sryTime.replace(/(.*)/, '')
        : templateParam.sryTime;
    templateParam.sryArea = res.data.area.districtName;
    templateParam.sryCount = res.data.count;
    templateParam.sryKm = Math.round(res.data.kilometres / 1000);
@@ -269,9 +284,9 @@
  return dataAnalysisApi.fetchMissionList(param).then((res) => {
    templateParam.missionInfoList = res.data.map((item) => {
      item._time = formatDateTimeRange(item.startTime, item.endTime);
      item._airQulity = `AQI:${item.aqi}(${item.pollutionDegree})`;
      item._airQulity = `${item.aqi}(${item.pollutionDegree})`;
      item._abnormalFactors = item.abnormalFactors
        .map((factor) => factor)
        .map((factor) => factorName[factor])
        .join('、');
      item._kilometres = Math.round(item.kilometres / 1000);
@@ -306,7 +321,7 @@
      item._startTime = t[0];
      item._time = t[1];
      item._kilometres = Math.round(item.kilometres / 1000);
      item._airQulity = `AQI:${item.aqi}(${item.pollutionDegree})`;
      item._airQulity = `${item.aqi}(${item.pollutionDegree})`;
      const factorNames = radioOptions(TYPE0).map((e) => e.name);
      item._dataStatistics = item.dataStatistics.filter((e) => {
@@ -315,9 +330,9 @@
      radioOptions(TYPE0).forEach((f) => {
        const _factor = item.dataStatistics.find((e) => e.factor == f.name);
        item[`avgValue_${f.name}`] = _factor?.avgValue ?? '-';
        item[`maxValue_${f.name}`] = _factor?.maxValue ?? '-';
        item[`minValue_${f.name}`] = _factor?.minValue ?? '-';
        item[`avgValue_${f.name}`] = _factor?.avgValue.toFixed(0) ?? '-';
        item[`maxValue_${f.name}`] = _factor?.maxValue.toFixed(0) ?? '-';
        item[`minValue_${f.name}`] = _factor?.minValue.toFixed(0) ?? '-';
      });
      return item;
@@ -334,46 +349,84 @@
    removeNoPollutedSource: param.removeNoPollutedSource
  };
  return dataAnalysisApi.fetchClueByRiskArea(_param).then((res) => {
    templateParam.clueByAreaList = res.data.map((item, index) => {
      return {
        _index: index + 1,
        // _area: `${item.sceneInfo.type}${item.sceneInfo.name}周边`,
        _area: `${item.address}`,
        clueByFactorList: item.clueByFactorList.map((cbf) => {
          return {
            factor: cbf.factor,
            clues: cbf.clues.map((clue) => {
    templateParam.showPollutedArea = formObj.value.showPollutedArea;
    templateParam.clueByAreaList = res.data
      .groupBy((e) => e.township)
      .map((item, index) => {
        const { key: township, values: clues } = item;
        return {
          _index: index + 1,
          // _area: `${item.sceneInfo.type}${item.sceneInfo.name}周边`,
          _area: `${township}`,
          clueByFactorList: clues
            .groupBy((e) => e.factorTag)
            .map((item2, index2) => {
              const { key: factorTag, values: clues2 } = item2;
              const factorNames = [...new Set(clues2.flatMap((e) => e.factors))]
                .map((e) => factorName[e])
                .join('、');
              return {
                _factorNames: Object.keys(clue.pollutedData.statisticMap)
                  .map((e) => e)
                  .join('、'),
                _time:
                  moment(clue.pollutedData.startTime).format(
                    'YYYY-MM-DD HH:mm:ss'
                  ) +
                  ' - ' +
                  moment(clue.pollutedData.endTime).format('HH:mm:ss'),
                _riskRegion: clue.pollutedArea.address
                  ? clue.pollutedArea.address
                  : '',
                _exceptionType: clue.pollutedData.exception,
                _images: generateChartImg(clue.pollutedData),
                _conclusion: clue.pollutedSource.conclusion,
                _scenes:
                  clue.pollutedSource.sceneList.length > 0
                    ? clue.pollutedSource.sceneList
                        .map(
                          (s, index) =>
                            `${index + 1}. ${s.name},${s.type},位于${s.location},距${s.closestStation.name}${parseInt(s.length)}米;`
                        )
                        .join('\n')
                    : '无'
                index: index2 + 1,
                factor: factorNames,
                clues: clues2.map((item3, index3) => {
                  const clue = item3.clue;
                  let _riskRegion = '';
                  if (
                    clue.pollutedArea.address.indexOf(
                      clue.pollutedArea.streetNumber
                    ) == -1
                  ) {
                    _riskRegion +=
                      (clue.pollutedArea.address ?? '') +
                      '(' +
                      (clue.pollutedArea.street ?? '') +
                      (clue.pollutedArea.streetNumber ?? '') +
                      (clue.pollutedArea.direction ?? '') +
                      ')';
                  } else {
                    _riskRegion = clue.pollutedArea.address;
                  }
                  return {
                    index: index3 + 1 + '',
                    showPollutedArea: formObj.value.showPollutedArea,
                    _title:
                      (clue.pollutedArea.street ?? '') +
                      (clue.pollutedArea.streetNumber ?? '') +
                      (clue.pollutedArea.direction ?? ''),
                    _factorNames: Object.keys(clue.pollutedData.statisticMap)
                      .map((e) => factorName[e])
                      .join('、'),
                    _time:
                      moment(clue.pollutedData.startTime).format(
                        'YYYY-MM-DD HH:mm:ss'
                      ) +
                      ' - ' +
                      moment(clue.pollutedData.endTime).format('HH:mm:ss'),
                    _riskRegion: _riskRegion,
                    _exceptionType: clue.pollutedData.exception,
                    _images: generateChartImg(clue.pollutedData),
                    _conclusion: clue.pollutedSource.conclusion,
                    _hasScene: clue.pollutedSource.sceneList.length > 0,
                    // _scenes:
                    //   clue.pollutedSource.sceneList.length > 0
                    //     ? clue.pollutedSource.sceneList
                    //         .map(
                    //           (s, index) =>
                    //             `${index + 1}. ${s.name},${s.type},位于${s.location},距${s.closestStation.name}${parseInt(s.length)}米;`
                    //         )
                    //         .join('\r\n')
                    //     : '无',
                    _scenes: clue.pollutedSource.sceneList.map((s, index) => {
                      return {
                        des: `${index + 1}. ${s.name},${s.type},位于${s.location},距${s.closestStation.name}${parseInt(s.length)}米;`
                      };
                    })
                  };
                })
              };
            })
          };
        })
      };
    });
        };
      });
  });
}
@@ -389,13 +442,17 @@
  factorDatas.setData(pollutedData.historyDataList, 0, () => {
    for (const key in pollutedData.statisticMap) {
      const value = pollutedData.statisticMap[key];
      const _chartOptions = factorDataParser.parseData(factorDatas, [
        {
          label: value.factorName,
          name: value.factorName,
          value: value.factorId + ''
        }
      ]);
      const _chartOptions = factorDataParser.parseData(
        factorDatas,
        [
          {
            label: value.factorName,
            name: value.factorName,
            value: value.factorId + ''
          }
        ],
        false
      );
      _chartOptions.forEach((o) => {
        images.push({
          url: chartToImg.generateEchartsImage(o, exceptionIndexArr, 20)
@@ -431,7 +488,37 @@
        _missionDes: `${item.missionList.map((m) => m.missionCode).join('、')}共${item.missionList.length}次`
      };
      const _highRiskGridList = [];
      item.highRiskGridList.forEach((g, i) => {
      Object.keys(item.highRiskGridMap).forEach((key, i) => {
        const g = item.highRiskGridMap[key][0];
        const infoDes = item.highRiskGridMap[key].map((e) => {
          return {
            factorValue: e.factorValue,
            // 四至范围,顺序为最小经度,最大经度,最小纬度,最大纬度
            _boundsDes: `经度${e.bounds[0]}至${e.bounds[1]},纬度${e.bounds[2]}至${e.bounds[3]}`,
            // 涉及街镇
            town: e.town,
            _scenesDes:
              e.highRiskScenes.length > 0
                ? `涉及的污染场景包括${e.highRiskScenes.map((s) => s.name).join('、')}`
                : '网格内可能存在隐藏风险源'
          };
        });
        const infoDes2 = item.highRiskGridMap2[key].map((e) => {
          return {
            factorValue: e.factorValue,
            // 四至范围,顺序为最小经度,最大经度,最小纬度,最大纬度
            _boundsDes: `经度${e.bounds[0]}至${e.bounds[1]},纬度${e.bounds[2]}至${e.bounds[3]}`,
            // 涉及街镇
            town: e.town,
            _scenesDes:
              e.highRiskScenes.length > 0
                ? `涉及的污染场景包括${e.highRiskScenes.map((s) => s.name).join('、')}`
                : '网格内可能存在隐藏风险源'
          };
        });
        // })
        // item.highRiskGridList.forEach((g, i) => {
        // const g = item.highRiskGridList[0];
        // const i = 0;
        const p = generateGridFusionImg(g.factorType, item.gridFusionList).then(
@@ -439,20 +526,13 @@
            const { url1, url2 } = url;
            _highRiskGridList.push({
              index: i + 1,
              factor: g.factorType,
              factor: factorName[g.factorType],
              // 标准色网格图
              gridImgUrl1: url1,
              // 对比色网格图
              gridImgUrl2: url2,
              factorValue: g.factorValue,
              // 四至范围,顺序为最小经度,最大经度,最小纬度,最大纬度
              _boundsDes: `经度${g.bounds[0]}至${g.bounds[1]},纬度${g.bounds[2]}至${g.bounds[3]}`,
              // 涉及街镇
              town: g.town,
              _scenesDes:
                g.highRiskScenes.length > 0
                  ? `涉及的污染场景包括${g.highRiskScenes.map((s) => s.name).join('、')}`
                  : '网格内可能存在隐藏风险源'
              infoDes: infoDes,
              infoDes2: infoDes2
            });
          }
        );
@@ -633,19 +713,28 @@
  // 不是季度第一天则返回具体日期范围
  if (!quarter) {
    return `${startYear}年${startMonth + 1}月${startDate}日-${endYear}年${endMonth + 1}月${endDate}日`;
    // return `${startYear}年${startMonth + 1}月${startDate}日-${endYear}年${endMonth + 1}月${endDate}日`;
    return startYear == endYear
      ? `${startYear}年${startMonth + 1}月-${endMonth + 1}月`
      : `${startYear}年${startMonth + 1}月-${endYear}年${endMonth + 1}月`;
  }
  // 验证是否为对应季度最后一个月
  const expectedEndMonth = quarter * 3 - 1; // Q1:2(3月), Q2:5(6月), Q3:8(9月), Q4:11(12月)
  if (endMonth !== expectedEndMonth) {
    return `${startYear}年${startMonth + 1}月${startDate}日-${endYear}年${endMonth + 1}月${endDate}日`;
    // return `${startYear}年${startMonth + 1}月${startDate}日-${endYear}年${endMonth + 1}月${endDate}日`;
    return startYear == endYear
      ? `${startYear}年${startMonth + 1}月-${endMonth + 1}月`
      : `${startYear}年${startMonth + 1}月-${endYear}年${endMonth + 1}月`;
  }
  // 验证是否为季度最后一天
  const lastDayOfEndMonth = new Date(endYear, endMonth + 1, 0).getDate();
  if (endDate !== lastDayOfEndMonth) {
    return `${startYear}年${startMonth + 1}月${startDate}日-${endYear}年${endMonth + 1}月${endDate}日`;
    // return `${startYear}年${startMonth + 1}月${startDate}日-${endYear}年${endMonth + 1}月${endDate}日`;
    return startYear == endYear
      ? `${startYear}年${startMonth + 1}月-${endMonth + 1}月`
      : `${startYear}年${startMonth + 1}月-${endYear}年${endMonth + 1}月`;
  }
  const quarterNames = ['', '第一季度', '第二季度', '第三季度', '第四季度'];