import moment from 'moment'; import { exportDocx } from '@/utils/doc'; import dataAnalysisApi from '@/api/dataAnalysisApi'; import { FactorDatas } from '@/model/FactorDatas'; import factorDataParser from '@/utils/chart/factor-data-parser'; import chartToImg from '@/utils/chart/chart-to-img'; const groupBy = (array, func) => { const groups = {}; array.forEach((item) => { const key = func(item); if (!groups[key]) { groups[key] = []; } groups[key].push(item); }); return Object.keys(groups).map((key) => ({ key, values: groups[key] })); }; const templateParam = () => { return { // 走航任务情况 cityName: '上海市', districtName: '长宁区', createTime: '2024年9月9日', missionTime: '2024年9月6日', missionDate: '9月6日', startTime: '13:00', endTime: '17:00', missionPeriod: '下午', region: '仙霞站', radius: '2公里', // 走航当日天气状况 pollutionDegree: '优', aqi: 46, mainFactor: '无', factorAvgDes: 'PM2.5(46μg/m3)、PM10(66μg/m3)、O3-8H(138μg/m3)、SO2(15μg/m3)、NO2(41μg/m3)、CO(0.7mg/m3)', weather: '多云,18-28℃,东南风2级', // 走航路线图 roadMapUrl: '', // 走航监测因子情况 focusFactor: 'PM2.5、PM10、VOCs、O3', mainFactorStatus: '走航期间,PM2.5、PM10等监测因子浓度均值高于长宁空气质量背景,', // mainFactorStatus:'走航期间,PM2.5、PM10等监测因子浓度均值均处于优,与长宁空气质量背景基本一致,', factorDetailList: [ { factor: 'PM2.5', avgValue: 22, minValue: 19, maxValue: 25 } ], clueByAreaList: [ { _index: 1, _area: '某某区域周边', clueByFactorList: [ { factor: 'PM₂.₅', clues: [ { _factorNames: 'PM2.5', _time: '10:22:28 - 10:22:34', _riskRegion: '长宁区清溪路可乐东路', _exceptionType: '快速上升', _chart: '', _conclusion: '在10:22:28至10:22:34之间,出现快速上升,VOC最低值为135.95μg/m³,最高值为135.95μg/m³,均值为135.95μg/m³,发现3个风险源,包含2个加油站,1个汽修。', _scenes: '1.上海依德汽车维修有限公司,汽修企业,位于上海市长宁区北虹路1079号,距仙霞站1887米。\r\n……' } ] } ] } ] }; }; function genMission(param, mission) { param.cityName = mission.cityName; param.districtName = mission.districtName; param.createTime = moment().format('YYYY-MM-DD'); param.missionTime = moment(mission.startTime).format('YYYY年MM月DD日'); param.missionDate = moment(mission.startTime).format('MM月DD日'); param.startTime = moment(mission.startTime).format('HH:mm'); param.endTime = moment(mission.endTime).format('HH:mm'); // 根据startTime计算所处时段 const hour = moment(mission.startTime).hour(); if (hour >= 0 && hour < 6) { param.missionPeriod = '凌晨'; } else if (hour >= 6 && hour < 9) { param.missionPeriod = '早上'; } else if (hour >= 9 && hour < 12) { param.missionPeriod = '上午'; } else if (hour >= 12 && hour < 14) { param.missionPeriod = '中午'; } else if (hour >= 14 && hour < 18) { param.missionPeriod = '下午'; } else if (hour >= 18 && hour < 22) { param.missionPeriod = '晚上'; } else { param.missionPeriod = '深夜'; } param.region = mission.region; param.radius = mission.radius ? `${mission.radius}公里` : ''; // 走航当日天气状况 // param.pollutionDegree = mission.pollutionDegree; // param.aqi = mission.aqi; // param.mainFactor = mission.mainFactor; // param.factorAvgDes = mission.factorAvgDes; // param.weather = mission.weather; } function genMissionSummary(param, mission) { return dataAnalysisApi .fetchOneMissionSummary(mission.missionCode) .then((res) => { param.focusRegion = res.data.focusRegion.join('、'); }); } function genRoadMap(param, mission) {} function genFactorDetail(param, mission, focusFactor) { return dataAnalysisApi .fetchOneMissionDetail(mission.missionCode) .then((res) => { param.focusFactor = focusFactor.join('、'); param.mainFactorStatus = '走航期间,PM2.5、PM10等监测因子浓度均值高于长宁空气质量背景,'; param.factorDetailList = res.data.dataStatistics .filter((item) => { return focusFactor.includes(item.factor); }) .forEach((item) => { item.avgValue = item.avgValue.toFixed(2); item.minValue = item.minValue.toFixed(2); item.maxValue = item.maxValue.toFixed(2); }); }); } function genClueByRiskArea(param, mission) { return dataAnalysisApi .fetchOneClueByRiskArea(mission.missionCode) .then((res) => { const clues = res.data.flatMap((item) => item.clueByFactorList.flatMap((cbf) => cbf.clues) ); param.clueByAreaList = groupBy( clues, (clue) => clue.pollutedArea.address ).map((item) => { const { key: area, values: clues } = item; return { _area: area, clues: clues.map((clue) => { return { _factorNames: Object.keys(clue.pollutedData.statisticMap) .map((e) => e) .join('、'), _time: moment(clue.pollutedData.startTime).format('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') : '无' }; }) }; }); }); } function generateChartImg(pollutedData) { const exceptionIndexArr = []; pollutedData.dataVoList.forEach((e) => { const i = pollutedData.historyDataList.findIndex((v) => v.time == e.time); exceptionIndexArr.push([i - 1 < 0 ? 0 : i - 1, i]); }); const factorDatas = new FactorDatas(); const images = []; 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 + '' } ]); _chartOptions.forEach((o) => { images.push({ url: chartToImg.generateEchartsImage(o, exceptionIndexArr, 20) }); }); } }); return images; } async function genTemplateParams(mission, focusFactor) { const param = templateParam(); await genMission(param, mission); await genMissionSummary(param, mission); await genRoadMap(param, mission); await genFactorDetail(param, mission, focusFactor); await genClueByRiskArea(param, mission); Object.keys(param).forEach((key) => { if (typeof param[key] === 'string') { param[key] = param[key]?.trim() || ''; } }); console.log('genTemplateParams', param); return param; } function downloadReport(mission, focusFactor = ['PM25', 'PM10']) { return genTemplateParams(mission, focusFactor).then((param) => { exportDocx('/underway_mission_report.docx', param, `走航任务报告.docx`, { horizontalHeight: 250, verticalWidth: 568, scale: 2 }); }); } export { downloadReport };