From 32eedf2857255cf29985ffc0cc73e75eccda39bf Mon Sep 17 00:00:00 2001
From: Riku <risaku@163.com>
Date: 星期六, 20 九月 2025 22:18:15 +0800
Subject: [PATCH] 2025.9.20 完成现场巡查基础数据产品和月度巡查简报的中间数据产品

---
 src/views/fysp/data-product/middle-data-product/ProdProblemCountSummary.vue |  166 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 161 insertions(+), 5 deletions(-)

diff --git a/src/views/fysp/data-product/middle-data-product/ProdProblemCountSummary.vue b/src/views/fysp/data-product/middle-data-product/ProdProblemCountSummary.vue
index fe5212f..83aac7e 100644
--- a/src/views/fysp/data-product/middle-data-product/ProdProblemCountSummary.vue
+++ b/src/views/fysp/data-product/middle-data-product/ProdProblemCountSummary.vue
@@ -1,33 +1,189 @@
 <template>
   <BaseProdProcess
     v-model:active="active"
+    @onStep1="onStep1"
     @onStep2="onStep2"
     @onStep3="onStep3"
     :loading="loading"
   >
-    <template #step1>
-      <ProdQueryOptCompare @submit="onStep1"></ProdQueryOptCompare>
+    <template #step1="{ onSearch }">
+      <ProdQueryOptCompare :loading="loading" @submit="onSearch"></ProdQueryOptCompare>
+    </template>
+    <template #step2="{ contentHeight }">
+      <el-scrollbar :height="contentHeight">
+        <el-table
+          id="prod-problem-count-table"
+          :data="tableData"
+          v-loading="loading"
+          table-layout="fixed"
+          :show-overflow-tooltip="true"
+          size="small"
+          border
+        >
+          <el-table-column fixed="left" type="index" label="缂栧彿" width="50">
+          </el-table-column>
+          <el-table-column
+            fixed="left"
+            prop="districtName"
+            label="鍖哄幙"
+            width="110"
+          >
+          </el-table-column>
+          <el-table-column prop="townName" label="琛楅晣" width="110" />
+          <el-table-column
+            prop="sceneCount"
+            label="鏈湡鍦烘櫙鏁�"
+            min-width="70"
+          />
+          <el-table-column
+            prop="lastSceneCount"
+            label="涓婃湡鍦烘櫙鏁�"
+            min-width="70"
+          />
+          <el-table-column
+            prop="problemCount"
+            label="鏈湡闂鏁�"
+            min-width="70"
+          />
+          <el-table-column
+            prop="lastProblemCount"
+            label="涓婃湡闂鏁�"
+            min-width="70"
+          />
+          <el-table-column
+            prop="ratio"
+            label="鏈湡闂鏁板潎鍊�"
+            min-width="70"
+            :formatter="ratioFormat"
+          />
+          <el-table-column
+            prop="lastRatio"
+            label="涓婃湡闂鏁板潎鍊�"
+            min-width="70"
+            :formatter="ratioFormat"
+          />
+        </el-table>
+        <el-row justify="center">
+          <div
+            ref="chartRef"
+            style="height: 400px; width: 100%; max-width: 800px"
+          ></div>
+        </el-row>
+      </el-scrollbar>
     </template>
   </BaseProdProcess>
 </template>
 <script setup>
-import { ref } from 'vue';
+import { computed, ref } from 'vue';
+import * as echarts from 'echarts';
+import dayjs from 'dayjs';
 import BaseProdProcess from '@/views/fysp/data-product/components/BaseProdProcess.vue';
 import dataprodmiddleApi from '@/api/fysp/dataprodmiddleApi.js';
 import { conversionFromTable } from '@/utils/excel';
 import { useProdStepChange } from '@/views/fysp/data-product/prod-step-change.js';
+import { barChartOption, downloadChartImage } from '@/utils/echart-util.js';
 import ProdQueryOptCompare from '@/views/fysp/data-product/components/ProdQueryOptCompare.vue';
 
 const { active, changeActive } = useProdStepChange();
 const loading = ref(false);
+const tableData1 = ref([]);
+const tableData2 = ref([]);
+const chartRef = ref(null);
+let chart;
+
+const tableData = computed(() => {
+  return tableData1.value.map((item) => {
+    const last = tableData2.value.find(
+      (item2) => item2.townCode === item.townCode
+    );
+    item.ratio = Math.round(item.ratio * 10) / 10 || 0;
+    return {
+      ...item,
+      lastSceneCount: last?.sceneCount || 0,
+      lastProblemCount: last?.problemCount || 0,
+      lastRatio: Math.round(item.ratio * 10) / 10 || 0
+    };
+  });
+});
 
 function onStep1(opts) {
-  console.log('onStep1', opts);
+  loading.value = true;
+  const p1 = dataprodmiddleApi.fetchProblemCountByArea(opts[0]).then((res) => {
+    if (res.success) {
+      tableData1.value = res.data;
+    }
+  });
+  const p2 = dataprodmiddleApi.fetchProblemCountByArea(opts[1]).then((res) => {
+    if (res.success) {
+      tableData2.value = res.data;
+    }
+  });
+  Promise.all([p1, p2])
+    .then(() => {
+      changeActive();
+      setTimeout(() => {
+        genChart(opts[0], opts[1]);
+      }, 500);
+    })
+    .finally(() => {
+      loading.value = false;
+    });
 }
 
 function onStep2() {
   changeActive();
 }
 
-function onStep3(val) {}
+function onStep3(val) {
+  if (val.downloadType == '1') {
+    loading.value = true;
+    conversionFromTable('prod-problem-count-table', '鎵皹姹℃煋闂鏁板潎鍊煎姣�');
+    downloadChartImage(chart, '鎵皹姹℃煋闂鏁板潎鍊煎姣�');
+    loading.value = false;
+  }
+}
+
+function genChart(opt1, opt2) {
+  if (chart == undefined) {
+    chart = echarts.init(chartRef.value);
+  }
+  const year = dayjs(opt1.startTime).year();
+  const month1 = dayjs(opt1.startTime).month() + 1;
+  const month2 = dayjs(opt2.startTime).month() + 1;
+  const time = `${year}骞�${month1}鏈堛��${month2}鏈坄;
+  const option = barChartOption();
+  option.title.text = `${time}鍚勮閬擄紙闀囷級${opt1.sceneTypeName}鎵皹姹℃煋闂鏁板潎鍊煎姣擿;
+
+  option.xAxis.name = '琛楅亾锛堥晣锛�';
+  option.xAxis.data = tableData.value.map((item) => item.townName);
+  option.yAxis.name = '闂鏁板潎鍊�';
+
+  option.series = [
+    {
+      name: `${month1}鏈坄,
+      type: 'bar', // 鍥捐〃绫诲瀷鏀逛负鏌辩姸鍥�
+      data: tableData1.value.map((item) => item.ratio),
+      label: {
+        show: true,
+        position: 'top', // 鏍囩鏄剧ず鍦ㄦ煴瀛愰《閮�
+        formatter: '{c}' // 鏍囩鏍煎紡锛氭暟閲�
+      }
+    },
+    {
+      name: `${month2}鏈坄,
+      type: 'bar', // 鍥捐〃绫诲瀷鏀逛负鏌辩姸鍥�
+      data: tableData1.value.map((item) => item.ratio),
+      label: {
+        show: true,
+        position: 'top', // 鏍囩鏄剧ず鍦ㄦ煴瀛愰《閮�
+        formatter: '{c}' // 鏍囩鏍煎紡锛氭暟閲�
+      }
+    }
+  ];
+  chart.setOption(option);
+}
+
+function ratioFormat(row, column, cellValue, index) {
+  return Math.round(cellValue * 10) / 10;
+}
 </script>

--
Gitblit v1.9.3