From f37845dd0a787dd42bf6c72e923433f30fcd8cc3 Mon Sep 17 00:00:00 2001
From: guonan <guonan201020@163.com>
Date: 星期四, 03 七月 2025 15:40:09 +0800
Subject: [PATCH] 实时模拟

---
 src/views/left/CitySim.vue |  382 ++++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 323 insertions(+), 59 deletions(-)

diff --git a/src/views/left/CitySim.vue b/src/views/left/CitySim.vue
index e40b495..f74e646 100644
--- a/src/views/left/CitySim.vue
+++ b/src/views/left/CitySim.vue
@@ -10,18 +10,28 @@
     <div class="left-top" v-if="simStore.selectTab == '閲嶇偣鍖哄煙浠跨湡'">
       閲嶇偣鍖哄煙浠跨湡锛�10m绮惧害锛�
     </div>
-    <div class="forms">
-      <el-form :model="forms" label-width="auto" style="max-width: 600px">
+    <div class="left-top" v-if="simStore.selectTab == '閲嶇偣娌熶豢鐪�'">
+      鍘嗗彶妯℃嫙
+    </div>
+
+    <div class="forms" :class="{ 'no-background': !showBackground }">
+      <el-form
+        :rules="rules"
+        :model="forms"
+        label-width="auto"
+        style="max-width: 600px"
+      >
         <el-form-item label="鏂规鍚嶇О:">
           <el-input
             v-model="forms.name"
             style="max-width: 600px"
-            placeholder="Please input"
+            placeholder="璇疯緭鍏ユ柟妗堝悕绉�"
           >
           </el-input>
         </el-form-item>
         <el-form-item label="涓婁紶鍙傛暟">
           <el-upload
+            :on-remove="handleRemove"
             v-model:file-list="forms.fileList"
             class="upload-demo"
             :auto-upload="false"
@@ -39,8 +49,9 @@
         <el-form-item label="闆ㄥ己鍗曚綅" v-if="forms.fileList.length !== 0">
           <el-select
             v-model="forms.intensityUnit"
-            placeholder="Select"
+            placeholder="璇烽�夋嫨闆ㄥ己鍗曚綅"
             style="max-width: 600px"
+            :disabled="!!forms.intensityUnit"
           >
             <el-option
               v-for="item in intensityOptions"
@@ -57,7 +68,7 @@
           <el-select
             @change="changeGeom"
             v-model="forms.geom"
-            placeholder="Select"
+            placeholder="璇烽�夋嫨妯℃嫙鍖哄煙"
             style="max-width: 600px"
           >
             <el-option
@@ -75,7 +86,7 @@
           <el-select
             @change="changeGeom"
             v-model="forms.geom"
-            placeholder="Select"
+            placeholder="璇烽�夋嫨妯℃嫙鍖哄煙"
             style="max-width: 600px"
           >
             <el-option
@@ -91,7 +102,7 @@
           <el-input
             v-model="forms.rainfall"
             style="max-width: 600px"
-            placeholder="Please input"
+            placeholder="璇疯緭鍏ラ檷闆ㄩ噺"
           >
             <template #append>mm</template>
           </el-input>
@@ -101,7 +112,7 @@
             v-if="forms.fileList.length !== 0"
             v-model="forms.hours"
             type="datetime"
-            placeholder="Select date and time"
+            placeholder="璇烽�夋嫨寮�濮嬫椂闂�"
           />
           <el-date-picker
             v-if="forms.fileList.length == 0"
@@ -120,7 +131,7 @@
             disabled
             v-model="forms.duration"
             style="max-width: 600px"
-            placeholder="Please input"
+            placeholder="璇疯緭鍏ラ檷闆ㄦ椂闀�"
           >
             <template #append>h</template>
           </el-input>
@@ -130,7 +141,7 @@
           <el-input
             v-model="forms.intensity"
             style="max-width: 600px"
-            placeholder="Please input"
+            placeholder="璇疯緭鍏ラ檷闆ㄥ己搴�"
           >
             <template #append>mm/h</template>
           </el-input>
@@ -140,7 +151,7 @@
       </el-form>
       <div style="display: flex; justify-content: flex-end">
         <el-button type="primary" @click="addSimCheme">淇濆瓨鏂规</el-button>
-        <el-button type="success" @click="startPlay">寮�濮嬫ā鎷�</el-button>
+        <el-button type="success" @click="startPlay">淇濆瓨骞跺紑濮嬫ā鎷�</el-button>
       </div>
     </div>
   </div>
@@ -153,7 +164,8 @@
 import { ElMessage, ElMessageBox } from "element-plus";
 import { initeWaterPrimitiveView } from "@/utils/water";
 import { SimAPIStore } from "@/store/simAPI";
-import { getRegionData } from "@/api/trApi";
+import { getRegionData, getSimStart, getSimDataById } from "@/api/trApi";
+
 import { storeToRefs } from "pinia";
 import dayjs from "dayjs";
 import { EventBus } from "@/eventBus"; // 寮曞叆浜嬩欢鎬荤嚎
@@ -163,9 +175,18 @@
 
 const options = reactive([]);
 
+// 鍘嗗彶妯℃嫙閫変腑鍖哄煙
+const props = defineProps({
+  selectedArea: {
+    type: Object,
+    required: true,
+  },
+});
+
 const intensityOptions = ref([
   { value: "mm/h", label: "mm/h" },
   { value: "mm/5min", label: "mm/5min" },
+  { value: "mm/min", label: "mm/min" },
 ]);
 
 // 瀹氫箟涓�涓柟娉曪紝鐢ㄤ簬鏍规嵁 type 鑾峰彇鍖哄煙鏁版嵁
@@ -187,6 +208,8 @@
   fetchRegionData(1);
 });
 
+const showBackground = ref(true); // 榛樿鏄剧ず鑳屾櫙鍥�
+
 // 鐩戝惉 selectTab 鐨勫彉鍖�
 watch(selectTab, (newVal) => {
   let type;
@@ -197,10 +220,21 @@
     case "閲嶇偣鍖哄煙浠跨湡":
       type = 2;
       break;
+    case "閲嶇偣娌熶豢鐪�":
+      type = 3;
+      break;
     default:
       type = 1; // 榛樿鍊�
   }
+  // 鏍规嵁 type 璁剧疆鏄惁鏄剧ず鑳屾櫙鍥撅紙鍥犱负鍘嗗彶妯℃嫙涓〃鍗曞甫浜嗚儗鏅浘锛�
+  if (type == 3) {
+    showBackground.value = false;
+  } else {
+    showBackground.value = true;
+  }
   fetchRegionData(type);
+  // Tab鍒囨崲鐨勬椂鍊欐竻绌鸿〃鍗�
+  resetForm();
 });
 
 // 娉ㄥ叆鐖剁粍浠舵彁渚涚殑鏂规硶
@@ -239,6 +273,9 @@
 
 const addSimCheme = async () => {
   try {
+    if (selectTab.value == "閲嶇偣娌熶豢鐪�") {
+      forms.geom = props.selectedArea;
+    }
     await simStore.addSimCheme(forms);
     resetForm(); // 鍙湁鍦ㄤ繚瀛樻垚鍔熷悗鎵嶉噸缃〃鍗�
     EventBus.emit("close-selectArea");
@@ -293,7 +330,6 @@
 // 瑙f瀽Excel鏂囦欢
 const parseExcel = (data) => {
   const workbook = XLSX.read(data, { type: "array" });
-  console.log(workbook, "wokr");
   const firstSheetName = workbook.SheetNames[0];
   const worksheet = workbook.Sheets[firstSheetName];
   const jsonData = XLSX.utils.sheet_to_json(worksheet, {
@@ -302,14 +338,6 @@
   });
 
   processData(jsonData);
-};
-
-const transformKeys = (data) => {
-  return data.map((item) => ({
-    time: item["鏃堕棿"], // "鏃堕棿" 鈫� "time"
-    intensity: parseFloat(item["灏忔椂闆ㄥ己mm/h"]), // 杞负娴偣鏁�
-    total: parseFloat(item["绱闆ㄩ噺"]), // 杞负娴偣鏁�
-  }));
 };
 
 /**
@@ -344,62 +372,249 @@
   if (!header) return "";
 
   // 鐩存帴鍖归厤 "mm/h"銆�"m/s" 绛夊父瑙佸崟浣�
-  const unitRegex = /(mm\/h|m\/s|mm|鈩億%|hPa|km\/h)/; // 鏍规嵁闇�瑕佹墿灞�
+  const unitRegex = /(mm\/h|mm\/1min|mm\/5min|mm\/15min)/; // 鏍规嵁闇�瑕佹墿灞�
   const match = header.match(unitRegex);
   return match ? match[0] : "";
 };
 
-// 澶勭悊鏁版嵁
+const transformKeys = (data) => {
+  return data.map((item) => ({
+    time: item["鏃堕棿"], // "鏃堕棿" 鈫� "time"
+    intensity: parseFloat(item["灏忔椂闆ㄥ己"]), // 杞负娴偣鏁�
+    total: parseFloat(item["绱闆ㄩ噺"]), // 杞负娴偣鏁�
+  }));
+};
+
+// 鍙厤缃殑瀛楁鍚嶅尮閰嶈鍒�
+const COLUMN_MATCH_RULES = {
+  time: ["鏃堕棿", "time", "datetime", "date"],
+  intensity: [
+    "闆ㄥ己",
+    "灏忔椂闆ㄥ己",
+    "rain_intensity",
+    "rain_rate",
+    "hour_rain",
+    "闄嶉洦寮哄害",
+  ],
+  totalRainfall: [
+    "绱闆ㄩ噺",
+    "鎬婚洦閲�",
+    "total_rain",
+    "cumulative_rainfall",
+    "闄嶉洦鎬婚噺",
+  ],
+};
+
+/**
+ * 鑷姩鍖归厤瀛楁鍚�
+ * @param {Object} headers - 琛ㄥご瀵硅薄锛堢涓�琛岋級
+ * @returns {{time: string, intensity: string, totalRainfall: string}}
+ */
+function matchColumns(headers) {
+  const matched = {
+    time: null,
+    intensity: null,
+    totalRainfall: null,
+  };
+
+  for (const header of Object.keys(headers)) {
+    const cleanHeader = header.trim();
+
+    if (
+      !matched.time &&
+      COLUMN_MATCH_RULES.time.some((k) => cleanHeader.includes(k))
+    ) {
+      matched.time = header;
+    }
+
+    if (
+      !matched.intensity &&
+      COLUMN_MATCH_RULES.intensity.some((k) => cleanHeader.includes(k))
+    ) {
+      matched.intensity = header;
+    }
+
+    if (
+      !matched.totalRainfall &&
+      COLUMN_MATCH_RULES.totalRainfall.some((k) => cleanHeader.includes(k))
+    ) {
+      matched.totalRainfall = header;
+    }
+  }
+
+  return matched;
+}
+
+/**
+ * 鏁版嵁澶勭悊涓诲嚱鏁�
+ * @param {Array} data - 瑙f瀽鍚庣殑鍘熷鏁版嵁鏁扮粍锛屾瘡涓厓绱犳槸涓�涓璞�
+ */
 const processData = (data) => {
-  // 1. 妫�鏌ユ暟鎹槸鍚︿负绌�
+  // 妫�鏌ユ槸鍚︿负绌烘暟鎹�
   if (data.length === 0) {
     ElMessage.warning("鏂囦欢鍐呭涓虹┖锛�");
     return;
   }
 
-  // 2. 鑾峰彇琛ㄥご锛堢涓�鍒楁槸鏃堕棿鍒楋級
-  const tableColumns = Object.keys(data[0]);
-  const timeColumn = tableColumns[0]; // 鍋囪绗竴鍒楁槸鏃堕棿
+  // 鍖归厤鍒楀悕锛堜緥濡傗�滄椂闂粹�濄�佲�滃皬鏃堕洦寮衡�濓級
+  const columns = matchColumns(data[0]);
 
-  // 3. 鏍¢獙鏃堕棿鍒楁槸鍚︽寜鍗囧簭鎺掑垪
-  if (!isTimeColumnSorted(data, timeColumn)) {
-    ElMessage.error("鏃堕棿鍒楀繀椤绘寜鍗囧簭鎺掑垪锛�");
+  // 鏍¢獙蹇呰瀛楁鏄惁瀛樺湪
+  if (!columns.time) {
+    ElMessage.error(
+      "鏈壘鍒版湁鏁堢殑鏃堕棿鍒楋紝璇锋鏌ュ垪鍚嶆槸鍚︿负鈥滄椂闂粹�濇垨鍏朵粬鏀寔鐨勬牸寮�"
+    );
     forms.fileList = [];
-    return; // 缁堟澶勭悊
+    return;
   }
 
-  const intensityColumn = tableColumns[1]; // 闆ㄥ己鍒楋紙濡� "灏忔椂闆ㄥ己(mm/h)"锛�
-  console.log(intensityColumn, "intensityColumnintensityColumnintensityColumn");
-  // 3. 鎻愬彇绗簩鍒楃殑鍗曚綅锛堝 "(mm/h)" 鈫� "mm/h"锛�
-  const intensityUnit = extractUnitFromHeader(intensityColumn);
-  console.log(
-    intensityUnit,
-    "intensityUnitintensityUnitintensityUnitintensityUnit"
+  if (!columns.intensity) {
+    ElMessage.error(
+      "鏈壘鍒版湁鏁堢殑闆ㄥ己鍒楋紝璇锋鏌ュ垪鍚嶆槸鍚︿负鈥滃皬鏃堕洦寮衡�濇垨鍏朵粬鏀寔鐨勬牸寮�"
+    );
+    forms.fileList = [];
+    return;
+  }
+
+  // 鏍¢獙鏃堕棿鍒楁槸鍚﹀崌搴忔帓鍒�
+  if (!isTimeColumnSorted(data, columns.time)) {
+    ElMessage.error("鏃堕棿鍒楀繀椤绘寜鍗囧簭鎺掑垪锛�");
+    forms.fileList = [];
+    return;
+  }
+
+  // 鎻愬彇鍗曚綅锛堝 mm/h锛夛紝鑻ユ病鏈夊垯璁句负绌哄瓧绗︿覆
+  forms.intensityUnit = extractUnitFromHeader(columns.intensity) || "";
+
+  // 灏嗗師濮嬫暟鎹浆鎹负缁熶竴缁撴瀯鐨勫璞℃暟缁�
+  const rawRainFallList = data.map((row) => ({
+    time: row[columns.time],
+    intensity: parseFloat(row[columns.intensity]),
+    total: columns.totalRainfall
+      ? parseFloat(row[columns.totalRainfall])
+      : undefined,
+  }));
+
+  // 鏇存柊 forms.rainFallList锛屽彲鐢ㄤ簬鍥捐〃鏄剧ず绛夌敤閫�
+  forms.rainFallList = rawRainFallList;
+
+
+  // 鍒ゆ柇鏄惁涓烘暣灏忔椂鏁版嵁锛堝嵆鐩搁偦鏃堕棿闂撮殧鏄惁涓烘暣灏忔椂锛�
+  const isHourlyData = checkIfHourlyData(rawRainFallList);
+
+  let hourlyRainfallList = [];
+
+  if (!isHourlyData) {
+    // 濡傛灉涓嶆槸鏁村皬鏃舵暟鎹紝鎸夊皬鏃惰繘琛岃仛鍚堝鐞�
+    hourlyRainfallList = aggregateToHourlyRainfall(rawRainFallList);
+    console.log(hourlyRainfallList, "淇鍚庣殑灏忔椂闆ㄥ己");
+  } else {
+    // 濡傛灉鏄暣灏忔椂鏁版嵁锛岀洿鎺ヤ娇鐢ㄥ師濮嬮洦寮哄��
+    hourlyRainfallList = rawRainFallList.map((item) => ({
+      time: item.time,
+      intensity: item.intensity,
+    }));
+  }
+
+  // 璁$畻璧峰鏃堕棿鍜岀粨鏉熸椂闂达紙姣鏁帮級
+  const firstTime = parseDateTime(hourlyRainfallList[0]?.time);
+  const lastTime = parseDateTime(
+    hourlyRainfallList[hourlyRainfallList.length - 1]?.time
   );
-  forms.intensityUnit = intensityUnit; // 瀛樺偍鍗曚綅锛堝彲閫夛級
 
-  // 4. 濡傛灉鏍¢獙閫氳繃锛岀户缁鐞嗘暟鎹�
-  forms.rainFallList = transformKeys(data);
-  console.log(forms.rainFallList, "data");
+  // 璁$畻鎸佺画鏃堕棿锛堝崟浣嶏細灏忔椂锛�
+  const durationSeconds = Math.floor((lastTime - firstTime) / 1000);
+  forms.duration = (durationSeconds / 3600).toFixed(2); // 鍗曚綅锛氬皬鏃�
 
-  // 5. 璁$畻闄嶉洦鏃堕暱銆佹渶澶ч洦寮恒�佺疮璁¢洦閲忥紙鍘熼�昏緫锛�
-  const firstTime = parseDateTime(data[0][timeColumn]);
-  const lastTime = parseDateTime(data[data.length - 1][timeColumn]);
-  const timeDuration = Math.floor((lastTime - firstTime) / 1000);
-  forms.duration = (timeDuration / 3600).toFixed(2);
-
-  const maxValue = Math.max(
-    ...data.map((row) => {
-      const value = parseFloat(row[tableColumns[1]]);
-      return isNaN(value) ? -Infinity : value;
-    })
+  // 鎵惧嚭鏈�澶у皬鏃堕洦寮�
+  const maxIntensity = Math.max(
+    ...hourlyRainfallList.map((item) => item.intensity).filter((v) => !isNaN(v))
   ).toFixed(2);
-  forms.intensity = maxValue;
+  forms.intensity = maxIntensity;
 
-  const lastValue = data[data.length - 1][tableColumns[2]];
-  forms.rainfall = lastValue;
+  // 鑻ユ湁鎬婚檷闆ㄩ噺鍒楋紝鍙栧嚭鏈�鍚庝竴涓�间綔涓烘�婚檷闆ㄩ噺
+  if (columns.totalRainfall) {
+    const lastTotal = parseFloat(data[data.length - 1][columns.totalRainfall]);
+    forms.rainfall = isNaN(lastTotal) ? 0 : lastTotal.toFixed(2);
+  } else {
+    forms.rainfall = 0;
+  }
 };
 
+/**
+ * 妫�鏌ユ暟鎹槸鍚︿负鏁村皬鏃惰褰�
+ * @param {Array} rainList - 鍘熷闄嶉洦鏁版嵁鍒楄〃锛屾瘡涓厓绱犲寘鍚� time 鍜� intensity
+ * @returns {boolean} - 鏄惁涓烘暣灏忔椂鏁版嵁
+ */
+function checkIfHourlyData(rainList) {
+  if (rainList.length < 2) return true; // 鍙湁涓�涓偣锛岄粯璁よ涓烘暣灏忔椂鏁版嵁
+
+  for (let i = 1; i < rainList.length; i++) {
+    // 瑙f瀽涓や釜鐩搁偦鏃堕棿鐐�
+    const time1 = parseDateTime(rainList[i - 1].time);
+    const time2 = parseDateTime(rainList[i].time);
+
+    // 璁$畻鏃堕棿宸紙鍒嗛挓锛�
+    const diffMinutes = Math.abs(time2 - time1) / (1000 * 60);
+
+    // 濡傛灉鏃堕棿宸笉鏄暣灏忔椂锛堜笉鑳借60鏁撮櫎锛夛紝鍒欎笉鏄暣灏忔椂鏁版嵁
+    if (diffMinutes % 60 !== 0) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+/**
+ * 灏嗕换鎰忔椂闂寸矑搴︾殑闆ㄥ己鏁版嵁锛屾寜灏忔椂鑱氬悎涓衡�滃皬鏃堕洦寮衡��
+ * @param {Array} rainList - 鍘熷鏁版嵁鍒楄〃锛屾瘡涓厓绱犲寘鍚� time 鍜� intensity
+ * @returns {Array} - 鎸夊皬鏃跺垎缁勭殑鑱氬悎缁撴灉
+ */
+function aggregateToHourlyRainfall(rainList) {
+  const grouped = {}; // 鐢ㄤ簬涓存椂瀛樺偍姣忎釜灏忔椂鐨勬暟鎹�
+
+  for (const item of rainList) {
+    // 瑙f瀽鏃堕棿瀛楃涓蹭负鏃堕棿鎴�
+    const timestamp = parseDateTime(item.time);
+
+    // 濡傛灉瑙f瀽澶辫触锛岃烦杩囧綋鍓嶉」
+    if (isNaN(timestamp)) {
+      console.warn("鏃犳晥鐨勬椂闂存牸寮忥紝宸茶烦杩�", item.time);
+      continue;
+    }
+
+    // 灏嗘椂闂存埑杞负 Date 瀵硅薄浠ヤ究鎿嶄綔鏃ユ湡
+    const dt = new Date(timestamp);
+
+    // 鏋勯�犲勾鏈堟棩+灏忔椂閿紙濡傦細"2024-08-25 14"锛�
+    const year = String(dt.getFullYear()).padStart(4, "0");
+    const month = String(dt.getMonth() + 1).padStart(2, "0"); // 娉ㄦ剰鏈堜唤浠�0寮�濮�
+    const date = String(dt.getDate()).padStart(2, "0");
+    const hour = String(dt.getHours()).padStart(2, "0");
+
+    const hourKey = `${year}-${month}-${date} ${hour}`;
+
+    // 鍒濆鍖栬灏忔椂鐨勮仛鍚堝璞�
+    if (!grouped[hourKey]) {
+      grouped[hourKey] = {
+        time: `${hourKey}:00:00`, // 鏍囧噯鍖栦负鏁寸偣鏃堕棿
+        intensity: 0,
+      };
+    }
+
+    // 绱姞璇ュ皬鏃跺唴鎵�鏈夐洦寮哄��
+    grouped[hourKey].intensity += item.intensity;
+  }
+
+  // 灏嗚仛鍚堢粨鏋滆浆涓烘暟缁勫苟淇濈暀涓や綅灏忔暟
+  const result = Object.values(grouped).map((item) => ({
+    time: item.time,
+    intensity: Number(item.intensity.toFixed(2)),
+  }));
+
+  return result;
+}
 /**
  * 瑙f瀽鏃ユ湡鏃堕棿瀛楃涓叉垨Excel鏁板瓧鏃ユ湡锛岃繑鍥炴椂闂存埑锛堟绉掓暟锛�
  * @param {string|number} dateString - 鏃ユ湡瀛楃涓叉垨Excel鏁板瓧鏃ユ湡
@@ -455,6 +670,16 @@
   ElMessage.warning("姣忔鍙兘涓婁紶涓�涓枃浠�");
 };
 
+const handleRemove = () => {
+  forms.rainfall = null;
+  forms.duration = null;
+  forms.intensity = null;
+  forms.fileList = [];
+  forms.rainFallList = [];
+  forms.hours = null;
+  forms.intensityUnit = "";
+};
+
 const beforeUpload = (file) => {
   const isExcel = file.name.endsWith(".xlsx") || file.name.endsWith(".xls");
   const isCSV = file.name.endsWith(".csv");
@@ -466,9 +691,39 @@
 };
 
 // 寮�濮嬫ā鎷�
-function startPlay() {
-  initeWaterPrimitiveView();
-  startSimulate();
+async function startPlay() {
+  try {
+    // 淇濆瓨鏂规
+    if (selectTab.value == "閲嶇偣娌熶豢鐪�") {
+      forms.geom = props.selectedArea;
+    }
+    const res = await simStore.addSimCheme(forms);
+    const schemeId = res.data?.data?.id;
+
+    if (!schemeId) {
+      ElMessage.error("鏂规淇濆瓨澶辫触锛屾湭鑾峰彇鍒版湁鏁� ID");
+      return;
+    }
+
+    // 璋冪敤姹傝В鍣�
+    const simStartRes = await getSimStart(schemeId);
+
+    // 鍏抽棴閫夋嫨鍖哄煙绐楀彛銆佸垵濮嬪寲瑙嗗浘骞跺紑濮嬫ā鎷�
+    EventBus.emit("close-selectArea");
+    simStore.shouldPoll = true;
+
+    // 鏆傛椂涓嶅湪姝ゅ寮�濮嬫ā鎷燂紝妯℃嫙閮藉湪鏂规鍒楄〃涓繘琛屾ā鎷�
+    // initeWaterPrimitiveView();
+    // startSimulate();
+
+    ElMessage.warning({
+      message: "璇疯繑鍥炴柟妗堝垪琛ㄧ瓑寰呮ā鎷熺粨鏋滐紒",
+      duration: 10000, // 鎻愮ず妗嗘樉绀烘椂闀匡紝鍗曚綅涓烘绉掞紝榛樿鏄�3000姣
+    });
+  } catch (error) {
+    console.error("鍚姩妯℃嫙杩囩▼涓彂鐢熼敊璇細", error);
+    // ElMessage.error("鍚姩妯℃嫙澶辫触锛岃绋嶅悗鍐嶈瘯");
+  }
 }
 </script>
 
@@ -480,6 +735,12 @@
   height: 100%;
   padding: 10px 10px 0px 0px;
   box-sizing: border-box;
+  transition: background 0.3s ease; // 鍙�夎繃娓℃晥鏋�
+}
+
+.forms.no-background {
+  margin-top: 0px;
+  background-image: none;
 }
 /deep/ .el-input-group__append,
 .el-input-group__prepend {
@@ -489,4 +750,7 @@
 /deep/ .el-form-item__label {
   color: #61f7d4 !important;
 }
+/deep/ .el-upload-list__item-file-name {
+  white-space: normal;
+}
 </style>

--
Gitblit v1.9.3