Преглед изворни кода

年度预测数据、季度预测数据、月度预测数据修改

littleblue55 пре 1 месец
родитељ
комит
c3a047a5c4

+ 467 - 159
src/views/dashboard/sandianpredict.vue

@@ -1,84 +1,133 @@
 <template>
+  <!-- littlegreen - 月度预测数据 - 补充form-label-->
   <div :class="className" :style="{ height: height, width: width }">
     <div class="select-container">
-      <el-select v-model="selectedEnterprise" @change="updateChart">
-        <el-option v-for="item in uniqueEnterprises" :key="item.enterpriseName" :value="item.enterpriseName">
-          {{ item.enterpriseName }}
-        </el-option>
-      </el-select>
-      <el-select v-model="selectedDataKey" @change="updateChart">
-        <el-option v-for="key in dataKeys" :key="key" :value="key" :label="keyToChinese[key]">
-          {{ keyToChinese[key] }}
-        </el-option>
-      </el-select>
-      <el-select v-model="selectedYear" @change="updateChart">
-        <el-option v-for="year in availableYears" :key="year" :value="year">
-          {{ year }}
-        </el-option>
-      </el-select>
-      <el-select v-model="selectedModel" @change="updateChart">
-        <el-option v-for="model in availableModels" :key="model" :value="model">
-          {{ model }}
-        </el-option>
-      </el-select>
-    <div style="display: inline; padding-left: 10px;">采用的预测模型:{{ selectedModel }}</div>
+      <el-form
+        style="
+          display: grid;
+          grid-template-columns: 1fr 1fr 1fr;
+          align-items: center;
+          grid-gap: 20px;
+        "
+        label-width="120px"
+      >
+        <el-form-item label="企业" style="margin-bottom: 0">
+          <el-select v-model="selectedEnterprise" style="width: 100%">
+            <el-option
+              v-for="item in uniqueEnterprises"
+              :key="item.enterpriseName"
+              :value="item.enterpriseName"
+            >
+              {{ item.enterpriseName }}
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="评估指标" style="margin-bottom: 0">
+          <el-select v-model="selectedDataKey" style="width: 100%">
+            <el-option
+              v-for="key in dataKeys"
+              :key="key"
+              :value="key"
+              :label="keyToChinese[key]"
+            >
+              {{ keyToChinese[key] }}
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="年度" style="margin-bottom: 0">
+          <el-select v-model="selectedYear" style="width: 100%">
+            <el-option v-for="year in availableYears" :key="year" :value="year">
+              {{ year }}
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="报警阈值" style="margin-bottom: 0">
+          <el-input
+            v-model="errorVal"
+            placeholder="报警阈值"
+            clearable
+            style="width: 100%"
+          />
+        </el-form-item>
+        <el-form-item label="预测模型" style="margin-bottom: 0">
+          <el-select v-model="selectedModel" style="width: 100%">
+            <el-option
+              v-for="model in availableModels"
+              :key="model"
+              :value="model"
+            >
+              {{ model }}
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="采用预测模型" style="margin-bottom: 0">
+          <div style="display: inline; padding-left: 10px">
+            {{ selectedModel }}
+          </div>
+        </el-form-item>
+        <el-form-item  style="margin-bottom: 0">
+          <el-button type="primary" icon="el-icon-search" @click="updateChart" size="mini"
+            >搜索</el-button
+          >
+        </el-form-item>
+      </el-form>
     </div>
     <div ref="chart" :style="{ height: height, width: width }"></div>
   </div>
 </template>
 
 <script>
-import * as echarts from 'echarts'
+import * as echarts from "echarts";
 import { listPredict } from "@/api/predict/predict";
 import { listBase_data_month } from "@/api/base_data_month/base_data_month";
-require('echarts/theme/macarons')
-import resize from './mixins/resize'
+require("echarts/theme/macarons");
+import resize from "./mixins/resize";
 
 export default {
   mixins: [resize],
   props: {
     className: {
       type: String,
-      default: 'chart'
+      default: "chart",
     },
     width: {
       type: String,
-      default: '100%'
+      default: "100%",
     },
     height: {
       type: String,
-      default: '400px'
-    }
+      default: "400px",
+    },
   },
   data() {
     return {
+      errorVal: null,
       chart: null,
       chartData: [],
       base_data_monthData: [],
-      selectedDataKey: 'totalIndustrialValuePredict',// 默认第一个
+      selectedDataKey: "totalIndustrialValuePredict", // 默认第一个
 
       dataKeys: [
-        'totalIndustrialValuePredict',
+        "totalIndustrialValuePredict",
         // 'taxableIncomePredict',
         // 'paidTaxPredict',
         // 'energyConsumePredict',
-         'powerConsumePredict'
+        "powerConsumePredict",
       ],
       keyToChinese: {
-        'totalIndustrialValuePredict': '工业总产值预测',
+        totalIndustrialValuePredict: "工业总产值预测",
         // 'taxableIncomePredict': '应税收入预测',
         // 'paidTaxPredict': '实缴税金预测',
         // 'energyConsumePredict': '能源消费量预测'
-         'powerConsumePredict': '电力消费预测'
-        
+        powerConsumePredict: "电力消费预测",
       },
 
       keyToChineseTruth: {
-        'totalIndustrialValuePredict': '工业总产值实际数据',
-        'taxableIncomePredict': '应税收入实际数据',
-        'paidTaxPredict': '实缴税金实际数据',
-        'energyConsumePredict': '能源消费量实际数据',
-        'powerConsumePredict': '电力消费预测'
+        totalIndustrialValuePredict: "工业总产值实际数据",
+        taxableIncomePredict: "应税收入实际数据",
+        paidTaxPredict: "实缴税金实际数据",
+        energyConsumePredict: "能源消费量实际数据",
+        powerConsumePredict: "电力消费实际数据",
       },
       selectedYear: null,
       selectedEnterprise: null,
@@ -103,17 +152,17 @@ export default {
         energyConsume: null,
         year: this.selectedYear,
         month: null,
-        model: null
+        model: null,
       },
       availableYears: [],
       uniqueEnterprises: [],
-      availableModels: []
-    }
+      availableModels: [],
+    };
   },
   mounted() {
     this.$nextTick(() => {
       this.fetchData();
-    })
+    });
   },
   beforeDestroy() {
     if (this.chart) {
@@ -122,157 +171,416 @@ export default {
   },
   methods: {
     fetchData() {
-      listPredict(this.queryParams).then(response => {
-        this.chartData = response.rows;
-        console.log(this.chartData)
-        this.availableYears = [...new Set(this.chartData.map(item => item.year))];
-        this.selectedYear = this.availableYears[0] || null;
-        this.uniqueEnterprises = [...new Set(this.chartData.map(item => ({enterpriseName: item.enterpriseName})))];
-        this.uniqueEnterprises = Array.from(new Set(this.chartData.map(item => item.enterpriseName))).map(name => ({enterpriseName: name}));
-        this.selectedEnterprise = this.uniqueEnterprises.length > 0 ? this.uniqueEnterprises[0].enterpriseName : null;
-        this.availableModels = [...new Set(this.chartData.map(item => item.model))];
-        this.selectedModel = this.availableModels[0] || null;
+      listPredict(this.queryParams)
+        .then((response) => {
+          this.chartData = response.rows;
+          // console.log(this.chartData);
+          this.availableYears = [
+            ...new Set(this.chartData.map((item) => item.year)),
+          ];
+          this.selectedYear = this.availableYears[0] || null;
+          this.uniqueEnterprises = [
+            ...new Set(
+              this.chartData.map((item) => ({
+                enterpriseName: item.enterpriseName,
+              }))
+            ),
+          ];
+          this.uniqueEnterprises = Array.from(
+            new Set(this.chartData.map((item) => item.enterpriseName))
+          ).map((name) => ({ enterpriseName: name }));
+          this.selectedEnterprise =
+            this.uniqueEnterprises.length > 0
+              ? this.uniqueEnterprises[0].enterpriseName
+              : null;
+          this.availableModels = [
+            ...new Set(this.chartData.map((item) => item.model)),
+          ];
+          this.selectedModel = this.availableModels[0] || null;
 
-        // 获取实际数据
-        listBase_data_month(this.queryParams).then(response => {
-          this.base_data_monthData = response.rows;
-          console.log('vvv' + this.base_data_monthData.length) // 10
-          this.initChart();
+          // 获取实际数据
+          listBase_data_month(this.queryParams).then((response) => {
+            this.base_data_monthData = response.rows;
+            // console.log("vvv" + this.base_data_monthData.length); // 10
+            this.initChart();
+          });
+        })
+        .catch((error) => {
+          console.error("Error fetching data:", error);
         });
-      }).catch(error => {
-        console.error('Error fetching data:', error);
-      });
     },
     initChart() {
       if (this.chart) {
         this.chart.dispose();
       }
-      this.chart = echarts.init(this.$refs.chart, 'macarons');
+      this.chart = echarts.init(this.$refs.chart, "macarons");
       this.updateChart();
     },
+    // littlegreen 检验是否正确填写预警值
+    checkErrorVal(number) {
+      let val = parseFloat(number);
+      let flag;
+      if (!number) {
+        return (flag = 0);
+      }
+      if (isNaN(val)) {
+        this.$message({
+          message: "请输入有效的数字。",
+          type: "error",
+        });
+        return (flag = 2);
+      }
+      return (flag = 1);
+    },
     updateChart() {
+      const that = this;
+      let flag = that.checkErrorVal(that.errorVal);
+      if (flag == 2) {
+        return;
+      }
       if (!this.chart) {
         return;
       }
-
-      let filteredData = this.chartData.filter(item =>
-        item.year === this.selectedYear &&
-        item.enterpriseName === this.selectedEnterprise &&
-        item.model === this.selectedModel
+      let filteredData = this.chartData.filter(
+        (item) =>
+          item.year === this.selectedYear &&
+          item.enterpriseName === this.selectedEnterprise &&
+          item.model === this.selectedModel
       );
+      // console.log(filteredData,"filteredData")
       //const xValues = filteredData.map(item => item.month + '月');
-      const xValues = ['1月', '2月', '3月', '4月', '5月', '6月','7月', '8月', '9月', '10月', '11月', '12月',];
+      const xValues = [
+        "1月",
+        "2月",
+        "3月",
+        "4月",
+        "5月",
+        "6月",
+        "7月",
+        "8月",
+        "9月",
+        "10月",
+        "11月",
+        "12月",
+      ];
       let yValues;
-
       // 根据选择的不同预测数据 key 获取对应的值
       switch (this.selectedDataKey) {
-        case 'totalIndustrialValuePredict':
-          yValues = filteredData.map(item => [item.totalIndustrialValuePredict, item.month]);
+        case "totalIndustrialValuePredict":
+          yValues = filteredData.map((item) => [
+            item.totalIndustrialValuePredict,
+            item.month,
+          ]);
+          break;
+        case "taxableIncomePredict":
+          yValues = filteredData.map((item) => [
+            item.taxableIncomePredict,
+            item.month,
+          ]);
+          break;
+        case "paidTaxPredict":
+          yValues = filteredData.map((item) => [
+            item.paidTaxPredict,
+            item.month,
+          ]);
           break;
-        case 'taxableIncomePredict':
-          yValues = filteredData.map(item => [item.taxableIncomePredict, item.month]);
+        case "energyConsumePredict":
+          yValues = filteredData.map((item) => [
+            item.energyConsumePredict,
+            item.month,
+          ]);
           break;
-        case 'paidTaxPredict':
-          yValues = filteredData.map(item => [item.paidTaxPredict, item.month]);
+        case "powerConsumePredict":
+          yValues = filteredData.map((item) => [
+            item.powerConsumePredict,
+            item.month,
+          ]);
           break;
-        case 'energyConsumePredict':
-          yValues = filteredData.map(item => [item.energyConsumePredict, item.month]);
+        case "fundingConsumePredict":
+          yValues = filteredData.map((item) => [
+            item.fundingConsumePredict,
+            item.month,
+          ]);
           break;
-        case 'powerConsumePredict':
-            yValues = filteredData.map(item => [item.powerConsumePredict, item.month]);
-            break;
-        case 'fundingConsumePredict':
-            yValues = filteredData.map(item => [item.fundingConsumePredict, item.month]);
-            break;
       }
-
-     // 处理实际数据
-      const base_data_monthFiltered = this.base_data_monthData.filter(item =>
-        item.year === this.selectedYear &&
-        item.enterpriseName === this.selectedEnterprise
+      // console.log(yValues, "yValues"); // 预测数据
+      // // 处理实际数据
+      // console.log(this.base_data_monthData, "初始过往数据");
+      // console.log(filteredData, "过滤好的预测数据");
+      const base_data_monthFiltered = this.base_data_monthData.filter(
+        (item) =>
+          item.year === this.selectedYear &&
+          item.enterpriseName === this.selectedEnterprise
+      );
+      // console.log(base_data_monthFiltered, "base_data_monthFiltered"); //往期数据
+      const base_data_monthXValues = base_data_monthFiltered.map(
+        (item) => item.month + "月"
       );
-      const base_data_monthXValues = base_data_monthFiltered.map(item => item.month + '月');
       let base_data_monthYValues;
 
       switch (this.selectedDataKey) {
-        case 'totalIndustrialValuePredict':
-          base_data_monthYValues = base_data_monthFiltered.map(item => [item.totalIndustrialValue, item.month]);
+        case "totalIndustrialValuePredict":
+          base_data_monthYValues = base_data_monthFiltered.map((item) => [
+            item.totalIndustrialValue,
+            item.month,
+          ]);
           break;
-        case 'taxableIncomePredict':
-          base_data_monthYValues = base_data_monthFiltered.map(item => [item.taxableIncome, item.month]);
+        case "taxableIncomePredict":
+          base_data_monthYValues = base_data_monthFiltered.map((item) => [
+            item.taxableIncome,
+            item.month,
+          ]);
           break;
-        case 'paidTaxPredict':
-          base_data_monthYValues = base_data_monthFiltered.map(item => [item.paidTax, item.month]);
+        case "paidTaxPredict":
+          base_data_monthYValues = base_data_monthFiltered.map((item) => [
+            item.paidTax,
+            item.month,
+          ]);
           break;
-        case 'powerConsumePredict':
-          base_data_monthYValues = base_data_monthFiltered.map(item => [item.powerConsume, item.month]);
+        case "powerConsumePredict":
+          base_data_monthYValues = base_data_monthFiltered.map((item) => [
+            item.powerConsume,
+            item.month,
+          ]);
           break;
-        case 'energyConsumePredict':
-          base_data_monthYValues = base_data_monthFiltered.map(item => [item.energyConsume, item.month]);
+        case "energyConsumePredict":
+          base_data_monthYValues = base_data_monthFiltered.map((item) => [
+            item.energyConsume,
+            item.month,
+          ]);
           break;
       }
-
-      this.chart.setOption({
-        tooltip: {
-          trigger: 'axis',
-          axisPointer: {
-            type: 'shadow'
-          }
-        },
-        legend: {
-          data: [
-            this.selectedEnterprise + ' ' + this.selectedYear + '年' + this.keyToChinese[this.selectedDataKey],
-            this.selectedEnterprise + ' ' + this.selectedYear + '年' + this.keyToChineseTruth[this.selectedDataKey],
-          ]
-        },
-        grid: {
-          left: '3%',
-          right: '4%',
-          bottom: '3%',
-          containLabel: true
-        },
-        xAxis: {
-          type: 'category',
-          data: xValues,
-          axisLabel: {
-            fontSize: 12
+      // littlegreen - 获取预警的markArae
+      function getErrorArray(flag, yValues, monthYValues, xValues) {
+        if (flag == 0) {
+          return [];
+        }
+        const errorArray = [];
+        yValues.forEach((yValue) => {
+          const yVal = yValue[0];
+          const month = yValue[1];
+          // 在 base_data_monthYValues 中找到相应的月
+          const baseData = monthYValues.find((base) => base[1] === month);
+          if (baseData) {
+            const baseVal = baseData[0];
+            // 计算差值
+            const difference = Math.abs(baseVal - yVal);
+            // 如果差值大于10,添加该月到新数组
+            if (difference > that.errorVal) {
+              // 10-90 80分成xValues.length份
+              errorArray.push([
+                {
+                  x:
+                    10 +
+                    (80 / xValues.length) * xValues.indexOf(month + "月") +
+                    "%",
+                },
+                {
+                  x:
+                    10 +
+                    (80 / xValues.length) *
+                      (xValues.indexOf(month + "月") + 1) +
+                    "%",
+                },
+              ]);
+            }
           }
-        },
-        yAxis: {
-          type: 'value'
-        },
-        series: [
-           {
-             name: this.selectedEnterprise + ' ' + this.selectedYear + '年' + this.keyToChinese[this.selectedDataKey],
-             type: 'line',
-             data: yValues.map((value) => [xValues[Number(value[1]) - 1], value[0]]),// 根据多少月去获取对应的数据
-             color: '#4CAF50'
-           },
-          {
-            name: this.selectedEnterprise + ' ' + this.selectedYear + '年' + this.keyToChineseTruth[this.selectedDataKey],
-          // + this.keyToChinese[this.selectedDataKey],
-            type: 'line',
-            // data: base_data_monthYValues.map((value, index) => [base_data_monthXValues[index], value]),
-            data: base_data_monthYValues.map((value) => [xValues[value[1] - 1], value[0]]),
-            color: '#FF5722'
-          }
-        ]
-      });
-    }
-  }
-  ,
-  watch: {
-    selectedDataKey() {
-      this.updateChart();
-    },
-    selectedYear() {
-      this.updateChart();
+        });
+        return errorArray;
+      }
+
+      this.chart.setOption(
+        {
+          legend: {
+            data: [
+              this.selectedEnterprise +
+                " " +
+                this.selectedYear +
+                "年" +
+                this.keyToChineseTruth[this.selectedDataKey],
+              this.selectedEnterprise +
+                " " +
+                this.selectedYear +
+                "年" +
+                this.keyToChinese[this.selectedDataKey],
+            ],
+          },
+          tooltip: {
+            trigger: "axis",
+          },
+          toolbox: {
+            show: false,
+            feature: {
+              saveAsImage: {},
+            },
+          },
+          xAxis: {
+            type: "category",
+            data: xValues,
+          },
+          yAxis: {
+            type: "value",
+          },
+          series: [
+            {
+              name:
+                this.selectedEnterprise +
+                " " +
+                this.selectedYear +
+                "年" +
+                this.keyToChineseTruth[this.selectedDataKey],
+              // + this.keyToChinese[this.selectedDataKey],
+              type: "line",
+              smooth: true,
+              data: base_data_monthYValues.map((value) => [
+                xValues[value[1] - 1],
+                value[0],
+              ]),
+              color: "#4CAF50",
+              markArea: {
+                itemStyle: {
+                  color: "rgba(255, 173, 177, 0.4)",
+                },
+                data: getErrorArray(
+                  flag,
+                  yValues,
+                  base_data_monthYValues,
+                  xValues
+                ),
+              },
+            },
+            {
+              name:
+                this.selectedEnterprise +
+                " " +
+                this.selectedYear +
+                "年" +
+                this.keyToChinese[this.selectedDataKey],
+              type: "line",
+              smooth: true,
+              color: "#FF5722",
+              data: yValues.map((value) => [
+                xValues[Number(value[1]) - 1],
+                value[0],
+              ]),
+            },
+          ],
+        }
+        //   {
+        //   tooltip: {
+        //     trigger: "axis",
+        //     axisPointer: {
+        //       type: "shadow",
+        //     },
+        //   },
+        //   legend: {
+        //     data: [
+        //       this.selectedEnterprise +
+        //         " " +
+        //         this.selectedYear +
+        //         "年" +
+        //         this.keyToChinese[this.selectedDataKey],
+        //       this.selectedEnterprise +
+        //         " " +
+        //         this.selectedYear +
+        //         "年" +
+        //         this.keyToChineseTruth[this.selectedDataKey],
+        //     ],
+        //   },
+        //   grid: {
+        //     left: "3%",
+        //     right: "4%",
+        //     bottom: "3%",
+        //     containLabel: true,
+        //   },
+        //   xAxis: {
+        //     type: "category",
+        //     data: xValues,
+        //     boundaryGap: true,
+        //     axisLabel: {
+        //       fontSize: 12,
+        //     },
+        //   },
+        //   yAxis: {
+        //     type: "value",
+        //   },
+        //   series: [
+        //     {
+        //       name:
+        //         this.selectedEnterprise +
+        //         " " +
+        //         this.selectedYear +
+        //         "年" +
+        //         this.keyToChinese[this.selectedDataKey],
+        //       type: "line",
+        //       data: yValues.map((value) => [
+        //         xValues[Number(value[1]) - 1],
+        //         value[0],
+        //       ]), // 根据多少月去获取对应的数据
+        //       // color: "#4CAF50",
+        //       itemStyle: {
+        //         normal: {
+        //           color: function (params) {
+        //             const value = params.data[1];
+        //             if (flag == 1) {
+        //               if (value >= that.errorVal)
+        //                 //预警值有值
+        //                 return "blue";
+        //             }
+        //             return "#4CAF50";
+        //           },
+        //         },
+        //       },
+        //     },
+        //     {
+        //       name:
+        //         this.selectedEnterprise +
+        //         " " +
+        //         this.selectedYear +
+        //         "年" +
+        //         this.keyToChineseTruth[this.selectedDataKey],
+        //       // + this.keyToChinese[this.selectedDataKey],
+        //       type: "line",
+        //       // data: base_data_monthYValues.map((value, index) => [base_data_monthXValues[index], value]),
+        //       data: base_data_monthYValues.map((value) => [
+        //         xValues[value[1] - 1],
+        //         value[0],
+        //       ]),
+        //       color: "#FF5722",
+        //       markArea: {
+        //         itemStyle: {
+        //           color: "rgba(255, 173, 177, 0.4)",
+        //         },
+        //         data: [
+        //           [
+        //             {
+        //               name: "Morning Peak",
+        //               x: "10%",
+        //             },
+        //             {
+        //               x: 10 + (80 / 12) * 5 + "%",
+        //             },
+        //           ],
+        //         ],
+        //       },
+        //     },
+        //   ],
+        // }
+      );
     },
-    selectedEnterprise() {
-      this.updateChart();
-    }
-  }
-}
+  },
+  watch: {
+    // selectedDataKey() {
+    //   this.updateChart();
+    // },
+    // selectedYear() {
+    //   this.updateChart();
+    // },
+    // selectedEnterprise() {
+    //   this.updateChart();
+    // },
+  },
+};
 </script>
 
 <style scoped>

+ 431 - 230
src/views/dashboard/sandianpredictseason.vue

@@ -1,300 +1,501 @@
 <template>
-    <div :class="className" :style="{ height: height, width: width }">
-      <div class="select-container">
-        <el-select v-model="selectedEnterprise" @change="updateChart">
-          <el-option v-for="item in uniqueEnterprises" :key="item.enterpriseName" :value="item.enterpriseName">
-            {{ item.enterpriseName }}
-          </el-option>
-        </el-select>
-        <el-select v-model="selectedDataKey" @change="updateChart">
-          <el-option v-for="key in dataKeys" :key="key" :value="key" :label="keyToChinese[key]">
-            {{ keyToChinese[key] }}
-          </el-option>
-        </el-select>
-        <el-select v-model="selectedYear" @change="updateChart">
-          <el-option v-for="year in availableYears" :key="year" :value="year">
-            {{ year }}
-          </el-option>
-        </el-select>
-        <el-select v-model="selectedModel" @change="updateChart">
-          <el-option v-for="model in availableModels" :key="model" :value="model">
-            {{ model }}
-          </el-option>
-        </el-select>
-      <div style="display: inline; padding-left: 10px;">采用的预测模型:{{ selectedModel }}</div>
-      </div>
-      <div ref="chart" :style="{ height: height, width: width }"></div>
+  <!-- littlegreen - 季度预测数据 - 补充form-label-->
+  <div :class="className" :style="{ height: height, width: width }">
+    <div class="select-container">
+      <el-form
+        style="
+          display: grid;
+          grid-template-columns: 1fr 1fr 1fr;
+          align-items: center;
+          grid-gap: 20px;
+        "
+        label-width="120px"
+      >
+        <el-form-item label="企业" style="margin-bottom: 0">
+          <el-select style="width: 100%" v-model="selectedEnterprise">
+            <el-option
+              v-for="item in uniqueEnterprises"
+              :key="item.enterpriseName"
+              :value="item.enterpriseName"
+            >
+              {{ item.enterpriseName }}
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="评估指标" style="margin-bottom: 0">
+          <el-select style="width: 100%" v-model="selectedDataKey">
+            <el-option
+              v-for="key in dataKeys"
+              :key="key"
+              :value="key"
+              :label="keyToChinese[key]"
+            >
+              {{ keyToChinese[key] }}
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="年度" style="margin-bottom: 0">
+          <el-select style="width: 100%" v-model="selectedYear">
+            <el-option v-for="year in availableYears" :key="year" :value="year">
+              {{ year }}
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="报警阈值" style="margin-bottom: 0">
+          <el-input
+            v-model="errorVal"
+            placeholder="报警阈值"
+            clearable
+            style="width: 100%"
+          />
+        </el-form-item>
+        <el-form-item label="预测模型" style="margin-bottom: 0">
+          <el-select style="width: 100%" v-model="selectedModel">
+            <el-option
+              v-for="model in availableModels"
+              :key="model"
+              :value="model"
+            >
+              {{ model }}
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="采用预测模型:" style="margin-bottom: 0">
+          <div style="display: inline; padding-left: 10px">
+            {{ selectedModel }}
+          </div>
+        </el-form-item>
+        <el-form-item  style="margin-bottom: 0">
+          <el-button type="primary" icon="el-icon-search" @click="updateChart" size="mini"
+            >搜索</el-button
+          >
+        </el-form-item>
+      </el-form>
     </div>
-  </template>
+    <div ref="chart" :style="{ height: height, width: width }"></div>
+  </div>
+</template>
 
-  <script>
-  import * as echarts from 'echarts'
-  import { listPredict } from "@/api/predict_season/predict_season";
-  import { listBase_data_season } from "@/api/base_data_season/base_data_season";
-  require('echarts/theme/macarons')
-  import resize from './mixins/resize'
+<script>
+import * as echarts from "echarts";
+import { listPredict } from "@/api/predict_season/predict_season";
+import { listBase_data_season } from "@/api/base_data_season/base_data_season";
+require("echarts/theme/macarons");
+import resize from "./mixins/resize";
 
-  export default {
-    mixins: [resize],
-    props: {
-      className: {
-        type: String,
-        default: 'chart'
-      },
-      width: {
-        type: String,
-        default: '100%'
-      },
-      height: {
-        type: String,
-        default: '400px'
-      }
+export default {
+  mixins: [resize],
+  props: {
+    className: {
+      type: String,
+      default: "chart",
     },
-    data() {
-      return {
-        chart: null,
-        chartData: [],
-        base_data_seasonData: [],
-        selectedDataKey: 'taxableIncomePredict',// 默认第一个
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "400px",
+    },
+  },
+  data() {
+    return {
+      errorVal: null,
+      chart: null,
+      chartData: [],
+      base_data_seasonData: [],
+      selectedDataKey: "taxableIncomePredict", // 默认第一个
 
-        dataKeys: [
+      dataKeys: [
         //   'totalIndustrialValuePredict',
-          'taxableIncomePredict',
-          'paidTaxPredict',
+        "taxableIncomePredict",
+        "paidTaxPredict",
         //   'energyConsumePredict',
-        ],
-        keyToChinese: {
+      ],
+      keyToChinese: {
         //   'totalIndustrialValuePredict': '工业总产值预测',
-          'taxableIncomePredict': '应税收入预测',
-          'paidTaxPredict': '实缴税金预测',
+        taxableIncomePredict: "应税收入预测",
+        paidTaxPredict: "实缴税金预测",
         //   'energyConsumePredict': '能源消费量预测'
-        },
+      },
 
-        keyToChineseTruth: {
-          'totalIndustrialValuePredict': '工业总产值实际数据',
-          'taxableIncomePredict': '应税收入实际数据',
-          'paidTaxPredict': '实缴税金实际数据',
-          'energyConsumePredict': '能源消费量实际数据'
-        },
-        selectedYear: null,
-        selectedEnterprise: null,
-        selectedModel: null,
-        queryParams: {
-          pageNum: 1,
-          pageSize: 2000000,
-          enterpriseName: this.selectedEnterprise,
-          location: null,
-          code: null,
-          mainBusiness: null,
-          landArea: null,
-          totalIndustrialValue: null,
-          gdp: null,
-          taxableIncome: null,
-          paidTax: null,
-          mainBusinessIncome: null,
-          employeeNumber: null,
-          profit: null,
-          ownerEquity: null,
-          funding: null,
-          energyConsume: null,
-          year: this.selectedYear,
-          month: null,
-          model: null
-        },
-        availableYears: [],
-        uniqueEnterprises: [],
-        availableModels: []
+      keyToChineseTruth: {
+        totalIndustrialValuePredict: "工业总产值实际数据",
+        taxableIncomePredict: "应税收入实际数据",
+        paidTaxPredict: "实缴税金实际数据",
+        energyConsumePredict: "能源消费量实际数据",
+      },
+      selectedYear: null,
+      selectedEnterprise: null,
+      selectedModel: null,
+      queryParams: {
+        pageNum: 1,
+        pageSize: 2000000,
+        enterpriseName: this.selectedEnterprise,
+        location: null,
+        code: null,
+        mainBusiness: null,
+        landArea: null,
+        totalIndustrialValue: null,
+        gdp: null,
+        taxableIncome: null,
+        paidTax: null,
+        mainBusinessIncome: null,
+        employeeNumber: null,
+        profit: null,
+        ownerEquity: null,
+        funding: null,
+        energyConsume: null,
+        year: this.selectedYear,
+        month: null,
+        model: null,
+      },
+      availableYears: [],
+      uniqueEnterprises: [],
+      availableModels: [],
+    };
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.fetchData();
+    });
+  },
+  beforeDestroy() {
+    if (this.chart) {
+      this.chart.dispose();
+    }
+  },
+  methods: {
+    // littlegreen 检验是否正确填写预警值
+    checkErrorVal(number) {
+      let val = parseFloat(number);
+      let flag;
+      if (!number) {
+        return (flag = 0);
       }
-    },
-    mounted() {
-      this.$nextTick(() => {
-        this.fetchData();
-      })
-    },
-    beforeDestroy() {
-      if (this.chart) {
-        this.chart.dispose();
+      if (isNaN(val)) {
+        this.$message({
+          message: "请输入有效的数字。",
+          type: "error",
+        });
+        return (flag = 2);
       }
+      return (flag = 1);
     },
-    methods: {
-      fetchData() {
-        listPredict(this.queryParams).then(response => {
+    fetchData() {
+      listPredict(this.queryParams)
+        .then((response) => {
           this.chartData = response.rows;
           //console.log(this.chartData)
-          this.availableYears = [...new Set(this.chartData.map(item => item.year))];
+          this.availableYears = [
+            ...new Set(this.chartData.map((item) => item.year)),
+          ];
           this.selectedYear = this.availableYears[0] || null;
-          this.uniqueEnterprises = [...new Set(this.chartData.map(item => ({enterpriseName: item.enterpriseName})))];
-          this.uniqueEnterprises = Array.from(new Set(this.chartData.map(item => item.enterpriseName))).map(name => ({enterpriseName: name}));
-          this.selectedEnterprise = this.uniqueEnterprises.length > 0 ? this.uniqueEnterprises[0].enterpriseName : null;
-          this.availableModels = [...new Set(this.chartData.map(item => item.model))];
+          this.uniqueEnterprises = [
+            ...new Set(
+              this.chartData.map((item) => ({
+                enterpriseName: item.enterpriseName,
+              }))
+            ),
+          ];
+          this.uniqueEnterprises = Array.from(
+            new Set(this.chartData.map((item) => item.enterpriseName))
+          ).map((name) => ({ enterpriseName: name }));
+          this.selectedEnterprise =
+            this.uniqueEnterprises.length > 0
+              ? this.uniqueEnterprises[0].enterpriseName
+              : null;
+          this.availableModels = [
+            ...new Set(this.chartData.map((item) => item.model)),
+          ];
           this.selectedModel = this.availableModels[0] || null;
 
           // 获取实际数据
-          listBase_data_season(this.queryParams).then(response => {
+          listBase_data_season(this.queryParams).then((response) => {
             this.base_data_seasonData = response.rows;
-            console.log('vvv' + this.base_data_seasonData.length) 
+            console.log("vvv" + this.base_data_seasonData.length);
             this.initChart();
           });
-        }).catch(error => {
-          console.error('Error fetching data:', error);
+        })
+        .catch((error) => {
+          console.error("Error fetching data:", error);
         });
-      },
-      initChart() {
-        if (this.chart) {
-          this.chart.dispose();
-        }
-        this.chart = echarts.init(this.$refs.chart, 'macarons');
-        this.updateChart();
-      },
-      updateChart() {
-        if (!this.chart) {
-          return;
-        }
+    },
+    initChart() {
+      if (this.chart) {
+        this.chart.dispose();
+      }
+      this.chart = echarts.init(this.$refs.chart, "macarons");
+      this.updateChart();
+    },
+    updateChart() {
+      const that = this;
+      let flag = that.checkErrorVal(that.errorVal);
+      if (flag == 2) {
+        return;
+      }
+      if (!this.chart) {
+        return;
+      }
 
-        let filteredData = this.chartData.filter(item =>
-        item.year === this.selectedYear &&
-        item.enterpriseName === this.selectedEnterprise &&
-        item.model === this.selectedModel
+      let filteredData = this.chartData.filter(
+        (item) =>
+          item.year === this.selectedYear &&
+          item.enterpriseName === this.selectedEnterprise &&
+          item.model === this.selectedModel
       );
       //const xValues = filteredData.map(item => item.month + '月');
-      const xValues = ['1季度', '2季度', '3季度', '4季度'];
+      const xValues = ["1季度", "2季度", "3季度", "4季度"];
       let yValues;
 
       // 根据选择的不同预测数据 key 获取对应的预测值
       switch (this.selectedDataKey) {
-        case 'totalIndustrialValuePredict':
-          yValues = filteredData.map(item => [item.totalIndustrialValuePredict, item.season]);
+        case "totalIndustrialValuePredict":
+          yValues = filteredData.map((item) => [
+            item.totalIndustrialValuePredict,
+            item.season,
+          ]);
+          break;
+        case "taxableIncomePredict":
+          yValues = filteredData.map((item) => [
+            item.taxableIncomePredict,
+            item.month,
+          ]);
           break;
-        case 'taxableIncomePredict':
-          yValues = filteredData.map(item => [item.taxableIncomePredict, item.month]);
+        case "paidTaxPredict":
+          yValues = filteredData.map((item) => [
+            item.paidTaxPredict,
+            item.month,
+          ]);
           break;
-        case 'paidTaxPredict':
-          yValues = filteredData.map(item => [item.paidTaxPredict, item.month]);
+        case "energyConsumePredict":
+          yValues = filteredData.map((item) => [
+            item.energyConsumePredict,
+            item.season,
+          ]);
           break;
-        case 'energyConsumePredict':
-          yValues = filteredData.map(item => [item.energyConsumePredict, item.season]);
+        case "powerConsumePredict":
+          yValues = filteredData.map((item) => [
+            item.powerConsumePredict,
+            item.season,
+          ]);
+          break;
+        case "fundingConsumePredict":
+          yValues = filteredData.map((item) => [
+            item.fundingConsumePredict,
+            item.season,
+          ]);
           break;
-        case 'powerConsumePredict':
-            yValues = filteredData.map(item => [item.powerConsumePredict, item.season]);
-            break;
-        case 'fundingConsumePredict':
-            yValues = filteredData.map(item => [item.fundingConsumePredict, item.season]);
-            break;
       }
 
       // console.log('jjj', yValues);
 
-     // 处理实际数据
-      const base_data_seasonFiltered = this.base_data_seasonData.filter(item =>
-        item.year === this.selectedYear &&
-        item.enterpriseName === this.selectedEnterprise
+      // 处理实际数据
+      const base_data_seasonFiltered = this.base_data_seasonData.filter(
+        (item) =>
+          item.year === this.selectedYear &&
+          item.enterpriseName === this.selectedEnterprise
       );
       // const base_data_seasonXValues = base_data_monthFiltered.map(item => item.month + '月');
       let base_data_seasonYValues;
 
       switch (this.selectedDataKey) {
-        case 'totalIndustrialValuePredict':
-          base_data_seasonYValues = base_data_seasonFiltered.map(item => [item.totalIndustrialValue, item.month]);
+        case "totalIndustrialValuePredict":
+          base_data_seasonYValues = base_data_seasonFiltered.map((item) => [
+            item.totalIndustrialValue,
+            item.month,
+          ]);
           break;
-        case 'taxableIncomePredict':
-          base_data_seasonYValues = base_data_seasonFiltered.map(item => [item.taxableIncome, item.season]);
+        case "taxableIncomePredict":
+          base_data_seasonYValues = base_data_seasonFiltered.map((item) => [
+            item.taxableIncome,
+            item.season,
+          ]);
           break;
-        case 'paidTaxPredict':
-          base_data_seasonYValues = base_data_seasonFiltered.map(item => [item.paidTax, item.season]);
+        case "paidTaxPredict":
+          base_data_seasonYValues = base_data_seasonFiltered.map((item) => [
+            item.paidTax,
+            item.season,
+          ]);
           break;
-        case 'powerConsumePredict':
-          base_data_seasonYValues = base_data_seasonFiltered.map(item => [item.powerConsume, item.month]);
+        case "powerConsumePredict":
+          base_data_seasonYValues = base_data_seasonFiltered.map((item) => [
+            item.powerConsume,
+            item.month,
+          ]);
           break;
-        case 'energyConsumePredict':
-          base_data_seasonYValues = base_data_seasonFiltered.map(item => [item.energyConsume, item.month]);
+        case "energyConsumePredict":
+          base_data_seasonYValues = base_data_seasonFiltered.map((item) => [
+            item.energyConsume,
+            item.month,
+          ]);
           break;
       }
+      // littlegreen - 获取预警的markArae
+      function getErrorArray(flag, yValues, monthYValues, xValues) {
+        if (flag == 0) {
+          return [];
+        }
+        const errorArray = [];
+        yValues.forEach((yValue) => {
+          const yVal = yValue[0];
+          const month = yValue[1];
+          console.log(yVal,month)
+          // 在 base_data_monthYValues 中找到相应的月
+          const baseData = monthYValues.find((base) => base[1] === month);
+          if (baseData) {
+            const baseVal = baseData[0];
+            // 计算差值
+            const difference = Math.abs(baseVal - yVal);
+            // 如果差值大于10,添加该月到新数组
+            if (difference > that.errorVal) {
+              // 10-90 80分成xValues.length份
+              errorArray.push([
+                {
+                  x:
+                    10 +
+                    (80 / xValues.length) * xValues.indexOf(month + "季度") +
+                    "%",
+                },
+                {
+                  x:
+                    10 +
+                    (80 / xValues.length) *
+                      (xValues.indexOf(month + "季度") + 1) +
+                    "%",
+                },
+              ]);
+            }
+          }
+        });
+        return errorArray;
+      }
 
+      // console.log(yValues, base_data_seasonYValues, xValues);
+      // yValues = [[3000, "2"],[5009, "3"]];
+      // base_data_seasonYValues = [
+      //   [1882, "1"],
+      //   [3263, "2"],
+      //   [4900, "3"]
+      // ];
       this.chart.setOption({
         tooltip: {
-          trigger: 'axis',
-          axisPointer: {
-            type: 'shadow'
-          }
+          trigger: "axis",
+          // axisPointer: {
+          //   type: "shadow",
+          // },
         },
         legend: {
           data: [
-            this.selectedEnterprise + ' ' + this.selectedYear + '年' + this.keyToChinese[this.selectedDataKey],
-            this.selectedEnterprise + ' ' + this.selectedYear + '年' + this.keyToChineseTruth[this.selectedDataKey],
-          ]
-        },
-        grid: {
-          left: '3%',
-          right: '4%',
-          bottom: '3%',
-          containLabel: true
+            this.selectedEnterprise +
+              " " +
+              this.selectedYear +
+              "年" +
+              this.keyToChinese[this.selectedDataKey],
+            this.selectedEnterprise +
+              " " +
+              this.selectedYear +
+              "年" +
+              this.keyToChineseTruth[this.selectedDataKey],
+          ],
         },
+        // grid: {
+        //   left: "3%",
+        //   right: "4%",
+        //   bottom: "3%",
+        //   containLabel: true,
+        // },
         xAxis: {
-          type: 'category',
+          type: "category",
           data: xValues,
           axisLabel: {
-            fontSize: 12
-          }
+            fontSize: 12,
+          },
         },
         yAxis: {
-          type: 'value'
+          type: "value",
         },
         series: [
-           {
-             name: this.selectedEnterprise + ' ' + this.selectedYear + '年' + this.keyToChinese[this.selectedDataKey],
-             type: 'line',
-             data: yValues.map((value) => [xValues[value[1] - 1], value[0]]),// 根据多少季度去获取对应的数据
-             color: '#4CAF50'
-           },
           {
-            name: this.selectedEnterprise + ' ' + this.selectedYear + '年' + this.keyToChineseTruth[this.selectedDataKey],
-            type: 'line',
-            data: base_data_seasonYValues.map((value) => [xValues[value[1] - 1], value[0]]),
-            color: '#FF5722'
-          }
-        ]
+            name:
+              this.selectedEnterprise +
+              " " +
+              this.selectedYear +
+              "年" +
+              this.keyToChinese[this.selectedDataKey],
+            type: "line",
+            data: yValues.map((value) => [value[1] + "季度", value[0]]), // 根据多少季度去获取对应的数据
+            color: "#4CAF50",
+          },
+          {
+            name:
+              this.selectedEnterprise +
+              " " +
+              this.selectedYear +
+              "年" +
+              this.keyToChineseTruth[this.selectedDataKey],
+            type: "line",
+            data: base_data_seasonYValues.map((value) => [
+              value[1] + "季度",
+              value[0],
+            ]),
+            color: "#FF5722",
+            markArea: {
+              itemStyle: {
+                color: "rgba(255, 173, 177, 0.4)",
+              },
+              data: getErrorArray(
+                flag,
+                yValues,
+                base_data_seasonYValues,
+                xValues
+              ),
+            },
+          },
+        ],
       });
-    }
-    }
-    ,
-    watch: {
-      selectedDataKey() {
-        this.updateChart();
-      },
-      selectedYear() {
-        this.updateChart();
-      },
-      selectedEnterprise() {
-        this.updateChart();
-      }
-    }
-  }
-  </script>
+    },
+  },
+  watch: {
+    // littlegreen - 注释掉更新
+    // selectedDataKey() {
+    //   this.updateChart();
+    // },
+    // selectedYear() {
+    //   this.updateChart();
+    // },
+    // selectedEnterprise() {
+    //   this.updateChart();
+    // },
+  },
+};
+</script>
 
-  <style scoped>
-  .select-container {
-    margin: 10px 5px;
-    font-size: 16px;
-  }
+<style scoped>
+.select-container {
+  margin: 10px 5px;
+  font-size: 16px;
+}
 
-  .select-container select {
-    padding: 10px 20px;
-    margin-right: 10px;
-    border: 1px solid #121315;
-    border-radius: 4px;
-    background-color: white;
-    color: #121315;
-    font-size: 16px;
-    cursor: pointer;
-    outline: none;
-  }
+.select-container select {
+  padding: 10px 20px;
+  margin-right: 10px;
+  border: 1px solid #121315;
+  border-radius: 4px;
+  background-color: white;
+  color: #121315;
+  font-size: 16px;
+  cursor: pointer;
+  outline: none;
+}
 
-  .select-container select:hover {
-    border-color: #1a7cc8;
-  }
+.select-container select:hover {
+  border-color: #1a7cc8;
+}
 
-  .select-container select:focus {
-    border-color: #121315;
-    box-shadow: 0 0 0 2px rgba(64, 159, 255, 0.2);
-  }
-  </style>
+.select-container select:focus {
+  border-color: #121315;
+  box-shadow: 0 0 0 2px rgba(64, 159, 255, 0.2);
+}
+</style>

+ 465 - 252
src/views/dashboard/sandianpredictyear.vue

@@ -1,308 +1,521 @@
 <template>
-    <div :class="className" :style="{ height: height, width: width }">
-      <div class="select-container">
-        <el-select v-model="selectedEnterprise" @change="updateChart">
-          <el-option v-for="item in uniqueEnterprises" :key="item.enterpriseName" :value="item.enterpriseName">
-            {{ item.enterpriseName }}
-          </el-option>
-        </el-select>
-        <el-select v-model="selectedDataKey" @change="updateChart">
-          <el-option v-for="key in dataKeys" :key="key" :value="key" :label="keyToChinese[key]">
-            {{ keyToChinese[key] }}
-          </el-option>
-        </el-select>
-        <el-select v-model="selectedYear" @change="updateChart">
-          <el-option v-for="year in availableYears" :key="year" :value="year">
-            {{ year }}
-          </el-option>
-        </el-select>
-        <el-select v-model="selectedModel" @change="updateChart">
-          <el-option v-for="model in availableModels" :key="model" :value="model">
-            {{ model }}
-          </el-option>
-        </el-select>
-      <div style="display: inline; padding-left: 10px;">采用的预测模型:{{ selectedModel }}</div>
-      </div>
-      <div ref="chart" :style="{ height: height, width: width }"></div>
+  <!-- 年度预测数据 - littlegreen - 补充form-label -->
+  <div :class="className" :style="{ height: height, width: width }">
+    <div class="select-container">
+      <el-form
+        style="
+          display: grid;
+          grid-template-columns: 1fr 1fr 1fr;
+          align-items: center;
+          grid-gap: 20px;
+        "
+        label-width="120px"
+      >
+        <el-form-item label="企业" style="margin-bottom: 0">
+          <el-select v-model="selectedEnterprise" style="width: 100%">
+            <el-option
+              v-for="item in uniqueEnterprises"
+              :key="item.enterpriseName"
+              :value="item.enterpriseName"
+            >
+              {{ item.enterpriseName }}
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="评估指标" style="margin-bottom: 0">
+          <el-select v-model="selectedDataKey" style="width: 100%">
+            <el-option
+              v-for="key in dataKeys"
+              :key="key"
+              :value="key"
+              :label="keyToChinese[key]"
+            >
+              {{ keyToChinese[key] }}
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="年度" style="margin-bottom: 0">
+          <el-select v-model="selectedYear" style="width: 100%">
+            <el-option v-for="year in availableYears" :key="year" :value="year">
+              {{ year }}
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="预测模型" style="margin-bottom: 0">
+          <el-select v-model="selectedModel" style="width: 100%">
+            <el-option
+              v-for="model in availableModels"
+              :key="model"
+              :value="model"
+            >
+              {{ model }}
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="报警阈值" style="margin-bottom: 0">
+          <el-input
+            v-model="errorVal"
+            placeholder="报警阈值"
+            clearable
+            style="width: 100%"
+          />
+        </el-form-item>
+        <el-form-item label="采用预测模型:" style="margin-bottom: 0">
+          <div style="display: inline; padding-left: 10px">
+            {{ selectedModel }}
+          </div>
+        </el-form-item>
+        <el-form-item  style="margin-bottom: 0">
+          <el-button type="primary" icon="el-icon-search" @click="updateChart" size="mini"
+            >搜索</el-button>
+        </el-form-item>
+      </el-form>
     </div>
-  </template>
-  
-  <script>
-  import * as echarts from 'echarts'
-  import { listPredict } from "@/api/predict_year/predict_year";
-  import { listBase_data_year } from "@/api/base_data_year/base_data_year";
-  require('echarts/theme/macarons')
-  import resize from './mixins/resize'
-  
-  export default {
-    mixins: [resize],
-    props: {
-      className: {
-        type: String,
-        default: 'chart'
-      },
-      width: {
-        type: String,
-        default: '100%'
-      },
-      height: {
-        type: String,
-        default: '400px'
-      }
+    <div ref="chart" :style="{ height: height, width: width }"></div>
+  </div>
+</template>
+
+<script>
+import * as echarts from "echarts";
+import { listPredict } from "@/api/predict_year/predict_year";
+import { listBase_data_year } from "@/api/base_data_year/base_data_year";
+require("echarts/theme/macarons");
+import resize from "./mixins/resize";
+import basicInfoFormVue from '../tool/gen/basicInfoForm.vue';
+
+export default {
+  mixins: [resize],
+  props: {
+    className: {
+      type: String,
+      default: "chart",
     },
-    data() {
-      return {
-        chart: null,
-        chartData: [],
-        base_data_yearData: [],
-        selectedDataKey: 'energyConsumePredict',// 默认第一个
-  
-        dataKeys: [
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "400px",
+    },
+  },
+  data() {
+    return {
+      errorVal: null,
+      chart: null,
+      chartData: [],
+      base_data_yearData: [],
+      selectedDataKey: "energyConsumePredict", // 默认第一个
+
+      dataKeys: [
         //   'totalIndustrialValuePredict',
         //   'taxableIncomePredict',
         //   'paidTaxPredict',
-          'energyConsumePredict',
+        "energyConsumePredict",
         // 'powerConsumePredict',
-          'fundingConsumePredict'
-        ],
-        keyToChinese: {
+        "fundingConsumePredict",
+      ],
+      keyToChinese: {
         //   'totalIndustrialValuePredict': '工业总产值预测',
         //   'taxableIncomePredict': '应税收入预测',
         //   'paidTaxPredict': '实缴税金预测',
-          'energyConsumePredict': '能源消费量预测',
-          //'powerConsumePredict': '电力消费量预测',
-          'fundingConsumePredict': '研发经费预测'
-        },
-  
-        keyToChineseTruth: {
-          'totalIndustrialValuePredict': '工业总产值实际数据',
-          'taxableIncomePredict': '应税收入实际数据',
-          'paidTaxPredict': '实缴税金实际数据',
-          'energyConsumePredict': '能源消费量实际数据',
-          'powerConsumePredict': '电力消费量实际数据',
-          'fundingConsumePredict': '研发经费实际数据'
-        },
-        selectedYear: null,
-        selectedEnterprise: null,
-        selectedModel: null,
-        queryParams: {
-          pageNum: 1,
-          pageSize: 2000000,
-          enterpriseName: this.selectedEnterprise,
-          location: null,
-          code: null,
-          mainBusiness: null,
-          landArea: null,
-          totalIndustrialValue: null,
-          gdp: null,
-          taxableIncome: null,
-          paidTax: null,
-          mainBusinessIncome: null,
-          employeeNumber: null,
-          profit: null,
-          ownerEquity: null,
-          funding: null,
-          energyConsume: null,
-          year: this.selectedYear,
-          month: null,
-          model: null
-        },
-        availableYears: [],
-        uniqueEnterprises: [],
-        availableModels: []
-      }
-    },
-    mounted() {
-      this.$nextTick(() => {
-        this.fetchData();
-      })
-    },
-    beforeDestroy() {
-      if (this.chart) {
-        this.chart.dispose();
-      }
-    },
-    methods: {
-      fetchData() {
-        listPredict(this.queryParams).then(response => {
+        energyConsumePredict: "能源消费量预测",
+        //'powerConsumePredict': '电力消费量预测',
+        fundingConsumePredict: "研发经费预测",
+      },
+
+      keyToChineseTruth: {
+        totalIndustrialValuePredict: "工业总产值实际数据",
+        taxableIncomePredict: "应税收入实际数据",
+        paidTaxPredict: "实缴税金实际数据",
+        energyConsumePredict: "能源消费量实际数据",
+        powerConsumePredict: "电力消费量实际数据",
+        fundingConsumePredict: "研发经费实际数据",
+      },
+      selectedYear: null,
+      selectedEnterprise: null,
+      selectedModel: null,
+      queryParams: {
+        pageNum: 1,
+        pageSize: 2000000,
+        enterpriseName: this.selectedEnterprise,
+        location: null,
+        code: null,
+        mainBusiness: null,
+        landArea: null,
+        totalIndustrialValue: null,
+        gdp: null,
+        taxableIncome: null,
+        paidTax: null,
+        mainBusinessIncome: null,
+        employeeNumber: null,
+        profit: null,
+        ownerEquity: null,
+        funding: null,
+        energyConsume: null,
+        year: this.selectedYear,
+        month: null,
+        model: null,
+      },
+      availableYears: [],
+      uniqueEnterprises: [],
+      availableModels: [],
+    };
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.fetchData();
+    });
+  },
+  beforeDestroy() {
+    if (this.chart) {
+      this.chart.dispose();
+    }
+  },
+  methods: {
+    fetchData() {
+      listPredict(this.queryParams)
+        .then((response) => {
           this.chartData = response.rows;
-          console.log(this.chartData)
-          this.availableYears = [...new Set(this.chartData.map(item => item.year))];
+          // console.log(this.chartData);
+          this.availableYears = [
+            ...new Set(this.chartData.map((item) => item.year)),
+          ];
           this.selectedYear = this.availableYears[0] || null;
-          this.uniqueEnterprises = [...new Set(this.chartData.map(item => ({enterpriseName: item.enterpriseName})))];
-          this.uniqueEnterprises = Array.from(new Set(this.chartData.map(item => item.enterpriseName))).map(name => ({enterpriseName: name}));
-          this.selectedEnterprise = this.uniqueEnterprises.length > 0 ? this.uniqueEnterprises[0].enterpriseName : null;
-          this.availableModels = [...new Set(this.chartData.map(item => item.model))];
+          this.uniqueEnterprises = [
+            ...new Set(
+              this.chartData.map((item) => ({
+                enterpriseName: item.enterpriseName,
+              }))
+            ),
+          ];
+          this.uniqueEnterprises = Array.from(
+            new Set(this.chartData.map((item) => item.enterpriseName))
+          ).map((name) => ({ enterpriseName: name }));
+          this.selectedEnterprise =
+            this.uniqueEnterprises.length > 0
+              ? this.uniqueEnterprises[0].enterpriseName
+              : null;
+          this.availableModels = [
+            ...new Set(this.chartData.map((item) => item.model)),
+          ];
           this.selectedModel = this.availableModels[0] || null;
-  
+
           // 获取实际数据
-          listBase_data_year(this.queryParams).then(response => {
+          listBase_data_year(this.queryParams).then((response) => {
             this.base_data_yearData = response.rows;
             this.initChart();
           });
-        }).catch(error => {
-          console.error('Error fetching data:', error);
+        })
+        .catch((error) => {
+          console.error("Error fetching data:", error);
         });
-      },
-      initChart() {
-        if (this.chart) {
-          this.chart.dispose();
-        }
-        this.chart = echarts.init(this.$refs.chart, 'macarons');
-        this.updateChart();
-      },
-      updateChart() {
-        if (!this.chart) {
-          return;
-        }
-  
-        let filteredData = this.chartData.filter(item =>
-        item.year === this.selectedYear &&
-        item.enterpriseName === this.selectedEnterprise &&
-        item.model === this.selectedModel
+    },
+    initChart() {
+      if (this.chart) {
+        this.chart.dispose();
+      }
+      this.chart = echarts.init(this.$refs.chart, "macarons");
+      this.updateChart();
+    },
+    // littlegreen 检验是否正确填写预警值
+    checkErrorVal(number) {
+      let val = parseFloat(number);
+      let flag;
+      if (!number) {
+        return (flag = 0);
+      }
+      if (isNaN(val)) {
+        this.$message({
+          message: "请输入有效的数字。",
+          type: "error",
+        });
+        return (flag = 2);
+      }
+      return (flag = 1);
+    },
+    updateChart() {
+      // littlegreen - 如果预警值不为空,判断是否为数字,不是数字就return
+      const that = this;
+      let flag = this.checkErrorVal(this.errorVal);
+      if (flag == 2) {
+        return;
+      }
+      if (!this.chart) {
+        return;
+      }
+      let filteredData = this.chartData.filter(
+        (item) =>
+          item.year === this.selectedYear &&
+          item.enterpriseName === this.selectedEnterprise &&
+          item.model === this.selectedModel
       );
-      const xValues = filteredData.map(item => item.year + '年');
+      const xValues = filteredData.map((item) => item.year + "年");
       let yValues;
 
       // 根据选择的不同预测数据 key 获取对应的值
       switch (this.selectedDataKey) {
-        case 'totalIndustrialValuePredict':
-          yValues = filteredData.map(item => [item.totalIndustrialValuePredict, item.year]);
+        case "totalIndustrialValuePredict":
+          yValues = filteredData.map((item) => [
+            item.totalIndustrialValuePredict,
+            item.year,
+          ]);
+          break;
+        case "taxableIncomePredict":
+          yValues = filteredData.map((item) => [
+            item.taxableIncomePredict,
+            item.year,
+          ]);
           break;
-        case 'taxableIncomePredict':
-          yValues = filteredData.map(item => [item.taxableIncomePredict, item.year]);
+        case "paidTaxPredict":
+          yValues = filteredData.map((item) => [
+            item.paidTaxPredict,
+            item.year,
+          ]);
           break;
-        case 'paidTaxPredict':
-          yValues = filteredData.map(item => [item.paidTaxPredict, item.year]);
+        case "energyConsumePredict":
+          yValues = filteredData.map((item) => [
+            item.energyConsumePredict,
+            item.year,
+          ]);
           break;
-        case 'energyConsumePredict':
-          yValues = filteredData.map(item => [item.energyConsumePredict, item.year]);
+        case "powerConsumePredict":
+          yValues = filteredData.map((item) => [
+            item.powerConsumePredict,
+            item.year,
+          ]);
+          break;
+        case "fundingConsumePredict":
+          yValues = filteredData.map((item) => [
+            item.fundingConsumePredict,
+            item.year,
+          ]);
           break;
-        case 'powerConsumePredict':
-            yValues = filteredData.map(item => [item.powerConsumePredict, item.year]);
-            break;
-        case 'fundingConsumePredict':
-            yValues = filteredData.map(item => [item.fundingConsumePredict, item.year]);
-            break;
       }
 
-     // 处理实际数据
-      const base_data_yearFiltered = this.base_data_yearData.filter(item =>
-        item.year === this.selectedYear &&
-        item.enterpriseName === this.selectedEnterprise
+      // 处理实际数据
+      const base_data_yearFiltered = this.base_data_yearData.filter(
+        (item) =>
+          item.year === this.selectedYear &&
+          item.enterpriseName === this.selectedEnterprise
+      );
+      const base_data_yearXValues = base_data_yearFiltered.map(
+        (item) => item.year + "年"
       );
-      const base_data_yearXValues = base_data_yearFiltered.map(item => item.year + '年');
       let base_data_yearYValues;
 
       switch (this.selectedDataKey) {
-        case 'totalIndustrialValuePredict':
-          base_data_yearYValues = base_data_yearFiltered.map(item => [item.totalIndustrialValue, item.year]);
+        case "totalIndustrialValuePredict":
+          base_data_yearYValues = base_data_yearFiltered.map((item) => [
+            item.totalIndustrialValue,
+            item.year,
+          ]);
           break;
-        case 'taxableIncomePredict':
-          base_data_yearYValues = base_data_yearFiltered.map(item => [item.taxableIncome, item.year]);
+        case "taxableIncomePredict":
+          base_data_yearYValues = base_data_yearFiltered.map((item) => [
+            item.taxableIncome,
+            item.year,
+          ]);
           break;
-        case 'paidTaxPredict':
-          base_data_yearYValues = base_data_yearFiltered.map(item => [item.paidTax, item.year]);
+        case "paidTaxPredict":
+          base_data_yearYValues = base_data_yearFiltered.map((item) => [
+            item.paidTax,
+            item.year,
+          ]);
           break;
-        case 'powerConsumePredict':
-          base_data_yearYValues = base_data_yearFiltered.map(item => [item.powerConsume, item.year]);
+        case "powerConsumePredict":
+          base_data_yearYValues = base_data_yearFiltered.map((item) => [
+            item.powerConsume,
+            item.year,
+          ]);
           break;
-        case 'energyConsumePredict':
-          base_data_yearYValues = base_data_yearFiltered.map(item => [item.energyConsume, item.year]);
+        case "energyConsumePredict":
+          base_data_yearYValues = base_data_yearFiltered.map((item) => [
+            item.energyConsume,
+            item.year,
+          ]);
           break;
-        case 'fundingConsumePredict':
-          base_data_yearYValues = base_data_yearFiltered.map(item => [item.funding, item.year]);
+        case "fundingConsumePredict":
+          base_data_yearYValues = base_data_yearFiltered.map((item) => [
+            item.funding,
+            item.year,
+          ]);
           break;
       }
 
-      console.log('lll', base_data_yearYValues);
-
+      // littlegreen - 获取预警的markArae
+      function getErrorArray(flag, yValues, monthYValues, xValues) {
+        if (flag == 0) {
+          return [];
+        }
+        const errorArray = [];
+        yValues.forEach((yValue) => {
+          const yVal = yValue[0];
+          const month = yValue[1];
+          // 在 base_data_monthYValues 中找到相应的月
+          const baseData = monthYValues.find((base) => base[1] === month);
+          if (baseData) {
+            const baseVal = baseData[0];
+            // 计算差值
+            const difference = Math.abs(baseVal - yVal);
+            // 如果差值大于10,添加该月到新数组
+            if (difference > that.errorVal) {
+              errorArray.push([
+                {
+                  x: 10 + (80 / (xValues.length)) * (xValues.indexOf(month+"年")) + "%",
+                },
+                {
+                  x: 10 + (80 / (xValues.length)) * (xValues.indexOf(month+"年") + 1) + "%",
+                },
+              ]);
+            }
+          }
+        });
+        return errorArray;
+      }
       this.chart.setOption({
         tooltip: {
-          trigger: 'axis',
-          axisPointer: {
-            type: 'shadow'
-          }
+          trigger: "axis",
+          // axisPointer: {
+          //   type: "shadow",
+          // },
         },
         legend: {
           data: [
-            this.selectedEnterprise + ' ' + this.selectedYear + '年' + this.keyToChinese[this.selectedDataKey],
-            this.selectedEnterprise + ' ' + this.selectedYear + '年' + this.keyToChineseTruth[this.selectedDataKey],
-          ]
-        },
-        grid: {
-          left: '3%',
-          right: '4%',
-          bottom: '3%',
-          containLabel: true
+            this.selectedEnterprise +
+              " " +
+              this.selectedYear +
+              "年" +
+              this.keyToChinese[this.selectedDataKey],
+            this.selectedEnterprise +
+              " " +
+              this.selectedYear +
+              "年" +
+              this.keyToChineseTruth[this.selectedDataKey],
+          ],
         },
+        // grid: {
+        //   left: "3%",
+        //   right: "4%",
+        //   bottom: "3%",
+        //   containLabel: true,
+        // },
         xAxis: {
-          type: 'category',
+          type: "category",
           data: xValues,
           axisLabel: {
-            fontSize: 12
-          }
+            fontSize: 12,
+          },
         },
         yAxis: {
-          type: 'value'
+          type: "value",
         },
         series: [
-           {
-             name: this.selectedEnterprise + ' ' + this.selectedYear + '年' + this.keyToChinese[this.selectedDataKey],
-             type: 'line',
-             data: yValues.map((value) => [xValues[0], value[0]]),// 根据多少年去获取对应的数据
-             color: '#4CAF50'
-           },
           {
-            name: this.selectedEnterprise + ' ' + this.selectedYear + '年' + this.keyToChineseTruth[this.selectedDataKey],
-            type: 'line',
-            data: base_data_yearYValues.map((value) => [xValues[0], value[0]]),
-            color: '#FF5722'
-          }
-        ]
+            name:
+              this.selectedEnterprise +
+              " " +
+              this.selectedYear +
+              "年" +
+              this.keyToChinese[this.selectedDataKey],
+            type: "line",
+            data: yValues.map((value) => [
+              value[1]+"年",
+              value[0]
+              ]), // 根据多少年去获取对应的数据
+            color: "#4CAF50",
+            // itemStyle: {
+            //   // color: "rgba(245,0,0,0.6)",
+            //   normal: {
+            //     color: function (params) {
+            //       const value = params.data[1];
+            //       if (flag == 1) {
+            //         if (value >= that.errorVal)
+            //           //预警值有值
+            //           return "blue";
+            //       }
+            //       return "#4CAF50";
+            //     },
+            //   },
+            // },
+          },
+          {
+            name:
+              this.selectedEnterprise +
+              " " +
+              this.selectedYear +
+              "年" +
+              this.keyToChineseTruth[this.selectedDataKey],
+            type: "line",
+            data: base_data_yearYValues.map((value) => [
+              value[1]+"年",
+              value[0]
+            ]),
+            color: "#FF5722",
+            markArea: {
+              itemStyle: {
+                color: "rgba(255, 173, 177, 0.4)",
+              },
+              data: getErrorArray(flag, yValues, base_data_yearYValues, xValues),
+            },
+            // itemStyle: {
+            //   // color: "rgba(245,0,0,0.6)",
+            //   normal: {
+            //     color: function (params) {
+            //       const value = params.data[1];
+            //       if (flag == 1) {
+            //         if (value >= that.errorVal)
+            //           //预警值有值
+            //           return "blue";
+            //       }
+            //       return "#FF5722";
+            //     },
+            //   },
+            // }
+          },
+        ],
       });
-    }
-    }
-    ,
-    watch: {
-      selectedDataKey() {
-        this.updateChart();
-      },
-      selectedYear() {
-        this.updateChart();
-      },
-      selectedEnterprise() {
-        this.updateChart();
-      }
-    }
-  }
-  </script>
-  
-  <style scoped>
-  .select-container {
-    margin: 10px 5px;
-    font-size: 16px;
-  }
-  
-  .select-container select {
-    padding: 10px 20px;
-    margin-right: 10px;
-    border: 1px solid #121315;
-    border-radius: 4px;
-    background-color: white;
-    color: #121315;
-    font-size: 16px;
-    cursor: pointer;
-    outline: none;
-  }
-  
-  .select-container select:hover {
-    border-color: #1a7cc8;
-  }
-  
-  .select-container select:focus {
-    border-color: #121315;
-    box-shadow: 0 0 0 2px rgba(64, 159, 255, 0.2);
-  }
-  </style>
-  
+    },
+  },
+  watch: {
+    // littlegreen - 不用实时更新
+    // selectedDataKey() {
+    //   this.updateChart();
+    // },
+    // selectedYear() {
+    //   this.updateChart();
+    // },
+    // selectedEnterprise() {
+    //   this.updateChart();
+    // },
+  },
+};
+</script>
+
+<style scoped>
+.select-container {
+  margin: 10px 5px;
+  font-size: 16px;
+}
+
+.select-container select {
+  padding: 10px 20px;
+  margin-right: 10px;
+  border: 1px solid #121315;
+  border-radius: 4px;
+  background-color: white;
+  color: #121315;
+  font-size: 16px;
+  cursor: pointer;
+  outline: none;
+}
+
+.select-container select:hover {
+  border-color: #1a7cc8;
+}
+
+.select-container select:focus {
+  border-color: #121315;
+  box-shadow: 0 0 0 2px rgba(64, 159, 255, 0.2);
+}
+</style>