wangjuncheng
2025-04-15 cb95acc00b13c9a644e08b281d1dc6f71232cd46
Merge branch 'master' of http://103.135.160.14:9034/r/NslWeb

# Conflicts:
# src/views/left/CitySim.vue
已修改3个文件
457 ■■■■ 文件已修改
package-lock.json 179 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/left/CitySim.vue 274 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package-lock.json
@@ -15,12 +15,14 @@
        "element-plus": "^2.9.5",
        "less": "^4.2.2",
        "less-loader": "^12.2.0",
        "papaparse": "^5.5.2",
        "pinia": "^3.0.2",
        "sdp": "^3.2.0",
        "vue": "^3.2.13",
        "vue-router": "^4.0.3",
        "vue-seamless-scroll": "^1.1.23",
        "vuex": "^4.0.0"
        "vuex": "^4.0.0",
        "xlsx": "^0.18.5"
      },
      "devDependencies": {
        "@vue/cli-plugin-babel": "~5.0.0",
@@ -3035,6 +3037,15 @@
        "node": ">= 10.0.0"
      }
    },
    "node_modules/adler-32": {
      "version": "1.3.1",
      "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz",
      "integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==",
      "license": "Apache-2.0",
      "engines": {
        "node": ">=0.8"
      }
    },
    "node_modules/ajv": {
      "version": "6.12.6",
      "resolved": "https://registry.npmmirror.com/ajv/-/ajv-6.12.6.tgz",
@@ -3695,6 +3706,19 @@
        "node": ">=4"
      }
    },
    "node_modules/cfb": {
      "version": "1.2.2",
      "resolved": "https://registry.npmjs.org/cfb/-/cfb-1.2.2.tgz",
      "integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==",
      "license": "Apache-2.0",
      "dependencies": {
        "adler-32": "~1.3.0",
        "crc-32": "~1.2.0"
      },
      "engines": {
        "node": ">=0.8"
      }
    },
    "node_modules/chalk": {
      "version": "3.0.0",
      "resolved": "https://registry.npmmirror.com/chalk/-/chalk-3.0.0.tgz",
@@ -3872,6 +3896,15 @@
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/codepage": {
      "version": "1.15.0",
      "resolved": "https://registry.npmjs.org/codepage/-/codepage-1.15.0.tgz",
      "integrity": "sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==",
      "license": "Apache-2.0",
      "engines": {
        "node": ">=0.8"
      }
    },
    "node_modules/color-convert": {
@@ -4146,6 +4179,18 @@
      },
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/crc-32": {
      "version": "1.2.2",
      "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz",
      "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==",
      "license": "Apache-2.0",
      "bin": {
        "crc32": "bin/crc32.njs"
      },
      "engines": {
        "node": ">=0.8"
      }
    },
    "node_modules/cross-spawn": {
@@ -5465,6 +5510,15 @@
      "dev": true,
      "engines": {
        "node": ">= 0.6"
      }
    },
    "node_modules/frac": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/frac/-/frac-1.1.2.tgz",
      "integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==",
      "license": "Apache-2.0",
      "engines": {
        "node": ">=0.8"
      }
    },
    "node_modules/fraction.js": {
@@ -7591,6 +7645,12 @@
        "node": ">=6"
      }
    },
    "node_modules/papaparse": {
      "version": "5.5.2",
      "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.5.2.tgz",
      "integrity": "sha512-PZXg8UuAc4PcVwLosEEDYjPyfWnTEhOrUfdv+3Bx+NuAb+5NhDmXzg5fHWmdCh1mP5p7JAZfFr3IMQfcntNAdA==",
      "license": "MIT"
    },
    "node_modules/param-case": {
      "version": "3.0.4",
      "resolved": "https://registry.npmmirror.com/param-case/-/param-case-3.0.4.tgz",
@@ -9436,6 +9496,18 @@
        "node": ">=0.10.0"
      }
    },
    "node_modules/ssf": {
      "version": "0.11.2",
      "resolved": "https://registry.npmjs.org/ssf/-/ssf-0.11.2.tgz",
      "integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==",
      "license": "Apache-2.0",
      "dependencies": {
        "frac": "~1.1.2"
      },
      "engines": {
        "node": ">=0.8"
      }
    },
    "node_modules/ssri": {
      "version": "8.0.1",
      "resolved": "https://registry.npmmirror.com/ssri/-/ssri-8.0.1.tgz",
@@ -10663,6 +10735,24 @@
      "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==",
      "dev": true
    },
    "node_modules/wmf": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/wmf/-/wmf-1.0.2.tgz",
      "integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==",
      "license": "Apache-2.0",
      "engines": {
        "node": ">=0.8"
      }
    },
    "node_modules/word": {
      "version": "0.3.0",
      "resolved": "https://registry.npmjs.org/word/-/word-0.3.0.tgz",
      "integrity": "sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==",
      "license": "Apache-2.0",
      "engines": {
        "node": ">=0.8"
      }
    },
    "node_modules/wrap-ansi": {
      "version": "7.0.0",
      "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
@@ -10705,6 +10795,27 @@
        "utf-8-validate": {
          "optional": true
        }
      }
    },
    "node_modules/xlsx": {
      "version": "0.18.5",
      "resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.18.5.tgz",
      "integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==",
      "license": "Apache-2.0",
      "dependencies": {
        "adler-32": "~1.3.0",
        "cfb": "~1.2.1",
        "codepage": "~1.15.0",
        "crc-32": "~1.2.1",
        "ssf": "~0.11.2",
        "wmf": "~1.0.1",
        "word": "~0.3.0"
      },
      "bin": {
        "xlsx": "bin/xlsx.njs"
      },
      "engines": {
        "node": ">=0.8"
      }
    },
    "node_modules/y18n": {
@@ -13032,6 +13143,11 @@
      "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==",
      "dev": true
    },
    "adler-32": {
      "version": "1.3.1",
      "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz",
      "integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A=="
    },
    "ajv": {
      "version": "6.12.6",
      "resolved": "https://registry.npmmirror.com/ajv/-/ajv-6.12.6.tgz",
@@ -13489,6 +13605,15 @@
      "integrity": "sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==",
      "dev": true
    },
    "cfb": {
      "version": "1.2.2",
      "resolved": "https://registry.npmjs.org/cfb/-/cfb-1.2.2.tgz",
      "integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==",
      "requires": {
        "adler-32": "~1.3.0",
        "crc-32": "~1.2.0"
      }
    },
    "chalk": {
      "version": "3.0.0",
      "resolved": "https://registry.npmmirror.com/chalk/-/chalk-3.0.0.tgz",
@@ -13620,6 +13745,11 @@
        "kind-of": "^6.0.2",
        "shallow-clone": "^3.0.0"
      }
    },
    "codepage": {
      "version": "1.15.0",
      "resolved": "https://registry.npmjs.org/codepage/-/codepage-1.15.0.tgz",
      "integrity": "sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA=="
    },
    "color-convert": {
      "version": "2.0.1",
@@ -13835,6 +13965,11 @@
        "path-type": "^4.0.0",
        "yaml": "^1.10.0"
      }
    },
    "crc-32": {
      "version": "1.2.2",
      "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz",
      "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ=="
    },
    "cross-spawn": {
      "version": "6.0.6",
@@ -14807,6 +14942,11 @@
      "resolved": "https://registry.npmmirror.com/forwarded/-/forwarded-0.2.0.tgz",
      "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
      "dev": true
    },
    "frac": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/frac/-/frac-1.1.2.tgz",
      "integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA=="
    },
    "fraction.js": {
      "version": "4.3.7",
@@ -16350,6 +16490,11 @@
      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
      "dev": true
    },
    "papaparse": {
      "version": "5.5.2",
      "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.5.2.tgz",
      "integrity": "sha512-PZXg8UuAc4PcVwLosEEDYjPyfWnTEhOrUfdv+3Bx+NuAb+5NhDmXzg5fHWmdCh1mP5p7JAZfFr3IMQfcntNAdA=="
    },
    "param-case": {
      "version": "3.0.4",
      "resolved": "https://registry.npmmirror.com/param-case/-/param-case-3.0.4.tgz",
@@ -17692,6 +17837,14 @@
      "resolved": "https://registry.npmmirror.com/speakingurl/-/speakingurl-14.0.1.tgz",
      "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ=="
    },
    "ssf": {
      "version": "0.11.2",
      "resolved": "https://registry.npmjs.org/ssf/-/ssf-0.11.2.tgz",
      "integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==",
      "requires": {
        "frac": "~1.1.2"
      }
    },
    "ssri": {
      "version": "8.0.1",
      "resolved": "https://registry.npmmirror.com/ssri/-/ssri-8.0.1.tgz",
@@ -18581,6 +18734,16 @@
      "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==",
      "dev": true
    },
    "wmf": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/wmf/-/wmf-1.0.2.tgz",
      "integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw=="
    },
    "word": {
      "version": "0.3.0",
      "resolved": "https://registry.npmjs.org/word/-/word-0.3.0.tgz",
      "integrity": "sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA=="
    },
    "wrap-ansi": {
      "version": "7.0.0",
      "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
@@ -18605,6 +18768,20 @@
      "dev": true,
      "requires": {}
    },
    "xlsx": {
      "version": "0.18.5",
      "resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.18.5.tgz",
      "integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==",
      "requires": {
        "adler-32": "~1.3.0",
        "cfb": "~1.2.1",
        "codepage": "~1.15.0",
        "crc-32": "~1.2.1",
        "ssf": "~0.11.2",
        "wmf": "~1.0.1",
        "word": "~0.3.0"
      }
    },
    "y18n": {
      "version": "5.0.8",
      "resolved": "https://registry.npmmirror.com/y18n/-/y18n-5.0.8.tgz",
package.json
@@ -14,12 +14,14 @@
    "element-plus": "^2.9.5",
    "less": "^4.2.2",
    "less-loader": "^12.2.0",
    "papaparse": "^5.5.2",
    "pinia": "^3.0.2",
    "sdp": "^3.2.0",
    "vue": "^3.2.13",
    "vue-router": "^4.0.3",
    "vue-seamless-scroll": "^1.1.23",
    "vuex": "^4.0.0"
    "vuex": "^4.0.0",
    "xlsx": "^0.18.5"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "~5.0.0",
src/views/left/CitySim.vue
@@ -12,12 +12,10 @@
          <el-upload
            v-model:file-list="forms.fileList"
            class="upload-demo"
            action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
            multiple
            :on-preview="handlePreview"
            :on-remove="handleRemove"
            :before-remove="beforeRemove"
            :limit="3"
            :auto-upload="false"
            :multiple="false"
            :on-change="handleFileChange"
            :limit="1"
            :on-exceed="handleExceed"
            :before-upload="beforeUpload"
            accept=".xlsx,.xls,.csv"
@@ -40,6 +38,8 @@
            />
          </el-select>
        </el-form-item>
        
        <el-form-item label="重点区域" v-if="disForm == '重点区域仿真'">
          <el-select
@@ -65,6 +65,7 @@
            <template #append>mm</template>
          </el-input>
        </el-form-item>
        <el-form-item label="降雨时长:">
          <el-input
            v-model="forms.duration"
@@ -72,8 +73,9 @@
            placeholder="Please input"
          >
            <template #append>h</template>
          </el-input></el-form-item
        >
          </el-input>
        </el-form-item>
        <el-form-item label="降雨强度:">
          <el-input
            v-model="forms.intensity"
@@ -83,14 +85,13 @@
            <template #append>mm/h</template>
          </el-input>
        </el-form-item>
        <el-form-item label="仿真参数:"> </el-form-item>
      </el-form>
      <div style="display: flex; justify-content: flex-end">
        <el-button type="primary" @click="openSaveDialog">保存方案</el-button>
        <el-button type="success" @click="startPlay">开始模拟</el-button>
      </div>
    </div>
    <!-- 保存方案对话框 -->
    <el-dialog
      v-model="saveDialogVisible"
@@ -101,12 +102,16 @@
    >
      <div class="dialog-content">
        <p><strong>模拟类型:</strong>{{ dialogTitle }}</p>
        <p v-if="disForm === '行政区划仿真'"><strong>行政区域:</strong>{{ forms.eare }}</p>
        <p v-if="disForm === '重点区域仿真'"><strong>重点区域:</strong>{{ forms.eares }}</p>
          <p v-if="disForm === '行政区划仿真'">
            <strong>行政区域:</strong>{{ forms.eare }}
          </p>
          <p v-if="disForm === '重点区域仿真'">
            <strong>重点区域:</strong>{{ forms.eares }}
          </p>
        <p><strong>降雨量:</strong>{{ forms.rainfall }} mm</p>
        <p><strong>降雨时长:</strong>{{ forms.duration }} h</p>
        <p><strong>降雨强度:</strong>{{ forms.intensity }} mm/h</p>
        <!-- <p><strong>上传文件:</strong>{{ uploadedFilesText }}</p> -->
          <p><strong>上传文件:</strong>{{ uploadedFilesText }}</p>
      </div>
      <template #footer>
        <span class="dialog-footer">
@@ -116,30 +121,29 @@
      </template>
    </el-dialog>
  </div>
  </div>
</template>
<script setup>
import { reactive, ref, computed ,watch} from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { reactive, ref, watch, inject, computed } from "vue";
import * as XLSX from "xlsx";
import Papa from "papaparse";
import { ElMessage } from "element-plus";
// 定义 Props
const props = defineProps({
  clickValue: String,
});
// 数据绑定
const disForm = ref(""); // 当前显示的表单类型
// 注入父组件提供的方法
const { startSimulate, endSimulate } = inject("simulateActions");
const saveDialogVisible = ref(false); // 控制保存方案对话框的显示状态
// 表单数据
const forms = reactive({
  eare: "北京市", // 行政区域
  eares: "孙胡沟", // 重点区域
  rainfall: "50", // 降雨量
  duration: "5", // 降雨时长
  intensity: "70", // 降雨强度
  fileList: [], // 上传的文件列表
  eare: "北京市",
  eares: "孙胡沟",
  rainfall: "",
  duration: "",
  intensity: "",
  fileList: [],
});
// 行政区域选项
// 城市和重点区域选项
const cityOptions = [
  { value: "北京市", label: "北京市" },
  { value: "东城区", label: "东城区" },
@@ -159,8 +163,6 @@
  { value: "密云区", label: "密云区" },
  { value: "延庆区", label: "延庆区" },
];
// 重点区域选项
const earesOptions = [
  { value: "孙胡沟", label: "孙胡沟" },
  { value: "鱼水洞后沟", label: "鱼水洞后沟" },
@@ -176,17 +178,8 @@
// 计算属性:获取上传文件的名称列表
const uploadedFilesText = computed(() => {
  return forms.fileList.map(file => file.name).join(", ") || "无";
  return forms.fileList.map((file) => file.name).join(", ") || "无";
});
// 监听 Props 变化,更新当前表单类型
watch(
  () => props.clickValue,
  (newValue) => {
    disForm.value = newValue || "行政区划仿真";
  },
  { immediate: true, deep: true }
);
// 打开保存方案对话框
const openSaveDialog = () => {
@@ -210,7 +203,7 @@
// 确认保存
const confirmSave = () => {
  console.log('保存方案成功', {
  console.log("保存方案成功", {
    模拟类型: dialogTitle.value,
    行政区域: disForm.value === "行政区划仿真" ? forms.eare : null,
    重点区域: disForm.value === "重点区域仿真" ? forms.eares : null,
@@ -219,63 +212,156 @@
    降雨强度: `${forms.intensity} mm/h`,
    上传文件: forms.fileList.map(file => file.name),
  });
  ElMessage.success('方案已保存');
  ElMessage.success("方案已保存");
  saveDialogVisible.value = false;
  resetForm();
};
// 重置表单
const resetForm = () => {
  forms.eare = "北京市";
  forms.eares = "孙胡沟";
  forms.rainfall = "";
  forms.duration = "";
  forms.intensity = "";
  forms.fileList = [];
};
// 文件变化时触发解析
const handleFileChange = (file) => {
  const reader = new FileReader();
  reader.onload = (e) => {
    const data = e.target.result;
    if (file.name.endsWith(".csv")) {
      parseCSV(data);
    } else {
      parseExcel(data);
    }
  };
  reader.readAsArrayBuffer(file.raw);
};
// 解析CSV文件
const parseCSV = (data) => {
  Papa.parse(new TextDecoder("utf-8").decode(data), {
    complete: (results) => {
      if (results.data.length > 0) {
        processData(results.data);
      }
    },
    header: true,
    skipEmptyLines: true,
  });
};
// 解析Excel文件
const parseExcel = (data) => {
  const workbook = XLSX.read(data, { type: "array" });
  const firstSheetName = workbook.SheetNames[0];
  const worksheet = workbook.Sheets[firstSheetName];
  const jsonData = XLSX.utils.sheet_to_json(worksheet);
  processData(jsonData);
};
// 处理数据
const processData = (data) => {
  if (data.length === 0) return;
  const tableColumns = Object.keys(data[0]);
  // 第一列:时间
  const firstTime = parseDateTime(data[0][tableColumns[0]]);
  const lastTime = parseDateTime(data[data.length - 1][tableColumns[0]]);
  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;
    })
  ).toFixed(2);
  forms.intensity = maxValue; // 更新降雨强度
  // 第三列:累计降雨量
  const lastValue = data[data.length - 1][tableColumns[2]];
  forms.rainfall = lastValue; // 更新降雨量
};
// 解析日期时间
const parseDateTime = (dateString) => {
  if (typeof dateString === "number") {
    const parsedDate = XLSX.SSF.parse_date_code(dateString);
    if (parsedDate) {
      return new Date(
        parsedDate.y,
        parsedDate.m - 1,
        parsedDate.d,
        parsedDate.H || 0,
        parsedDate.M || 0,
        parsedDate.S || 0
      ).getTime();
    }
  }
  const parsedDate = new Date(dateString);
  if (!isNaN(parsedDate.getTime())) {
    return parsedDate.getTime();
  }
  const parts = dateString.split(/[/\s:]/);
  if (parts.length >= 6) {
    const year = parseInt(parts[0], 10);
    const month = parseInt(parts[1], 10) - 1;
    const day = parseInt(parts[2], 10);
    const hour = parseInt(parts[3], 10) || 0;
    const minute = parseInt(parts[4], 10) || 0;
    const second = parseInt(parts[5], 10) || 0;
    const date = new Date(year, month, day, hour, minute, second);
    if (!isNaN(date.getTime())) {
      return date.getTime();
    }
  }
  console.warn(`无法解析日期: ${dateString}`);
  return NaN;
};
const handleExceed = () => {
  ElMessage.warning("每次只能上传一个文件");
};
const beforeUpload = (file) => {
  const isExcel = file.name.endsWith(".xlsx") || file.name.endsWith(".xls");
  const isCSV = file.name.endsWith(".csv");
  if (!isExcel && !isCSV) {
    ElMessage.error("只能上传Excel或CSV文件");
    return false;
  }
  return true;
};
const disForm = ref("");
// 定义 Props
const props = defineProps({
  clickValue: String,
});
// 监听 Props 变化
watch(
  () => props.clickValue,
  (newValue) => {
    disForm.value = newValue || "行政区划仿真";
  },
  { immediate: true, deep: true }
);
// 开始模拟
function startPlay() {
  console.log("开始模拟按钮被点击");
}
// 文件上传相关方法
function handleRemove(file, uploadFiles) {
  console.log(file, uploadFiles);
}
function handlePreview(uploadFile) {
  console.log(uploadFile);
}
function handleExceed(files, uploadFiles) {
  ElMessage.warning(
    `The limit is 3, you selected ${files.length} files this time, add up to ${
      files.length + uploadFiles.length
    } totally`
  );
}
const beforeUpload = (file) => {
  const allowedTypes = [
    "application/vnd.ms-excel",
    "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
    "text/csv",
    "application/csv",
    "text/x-csv",
    "application/x-csv",
    "text/comma-separated-values",
    "text/x-comma-separated-values",
  ];
  const isAllowed = allowedTypes.includes(file.type);
  const extension = file.name.split(".").pop().toLowerCase();
  const isExtensionValid = ["xls", "xlsx", "csv"].includes(extension);
  if (!isAllowed || !isExtensionValid) {
    ElMessage.error("只能上传 Excel (.xls, .xlsx) 或 CSV 文件");
    return false; // 阻止上传
  }
  return true; // 允许上传
};
function beforeRemove(uploadFile, uploadFiles) {
  return ElMessageBox.confirm(
    `Cancel the transfer of ${uploadFile.name} ?`
  ).then(
    () => true,
    () => false
  );
  startSimulate();
}
</script>