From f4b965dbad0b4f5693b6271232ef4120ba39ddae Mon Sep 17 00:00:00 2001
From: Riku <risaku@163.com>
Date: 星期三, 01 一月 2025 20:42:12 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/hc-satellite-dataimport-1227_2' into master-temp

---
 src/views/satellitetelemetry/component/SatelliteImport.vue |  225 ++++++++++++++++++++++
 src/api/gridApi.js                                         |   70 ++++++
 src/components.d.ts                                        |    1 
 src/views/HomePage.vue                                     |   20 ++
 src/views/satellitetelemetry/component/AODImport.vue       |  227 ++++++++++++++++++++++
 5 files changed, 542 insertions(+), 1 deletions(-)

diff --git a/src/api/gridApi.js b/src/api/gridApi.js
index 4cf424c..8ced630 100644
--- a/src/api/gridApi.js
+++ b/src/api/gridApi.js
@@ -1,5 +1,6 @@
 import { $http } from './index';
 
+import { Base64 } from 'js-base64';
 /**
  * 鍗槦閬ユ祴缃戞牸鐩稿叧鎺ュ彛API
  */
@@ -47,6 +48,23 @@
       .then((res) => res.data);
   },
 
+  /**
+   * 鑾峰彇缃戞牸缁勪笅鐨勯仴娴媋od
+   * @param {*} groupId
+   * @param {*} dataTime
+   * @returns
+   */
+  fetchGridAod(groupId, dataTime) {
+    return $http
+      .get(`air/satellite/grid/aod`, {
+        params: {
+          groupId,
+          dataTime
+        }
+      })
+      .then((res) => res.data);
+  },
+
   fetchGridDataDetail(dataId, groupId, cellId) {
     return $http
       .get(`air/satellite/grid/data/detail`, {
@@ -57,5 +75,55 @@
         }
       })
       .then((res) => res.data);
+  },
+  downloadTemplate() {
+    return $http
+      .get(`air/satellite/import/grid/data/download/template`, {
+        responseType: 'blob'
+      })
+      .then((res) => {
+        const name = Base64.decode(res.headers.get('fileName'));
+        const blob = new Blob([res.data], {
+          type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
+        });
+        const url = window.URL.createObjectURL(blob);
+        const link = document.createElement('a');
+        link.href = url;
+        link.download = name;
+        document.body.appendChild(link);
+        link.click();
+        document.body.removeChild(link);
+        window.URL.revokeObjectURL(url);
+      });
+  },
+  importData(dataForm) {
+    return $http
+      .post(`air/satellite/import/grid/data`, dataForm)
+      .then((res) => res.data);
+  },
+  downloadAODTemplate() {
+    return $http
+      .get(`air/satellite/import/grid/aod/download/template`, {
+        responseType: 'blob'
+      })
+      .then((res) => {
+        const name = Base64.decode(res.headers.get('fileName'));
+        const blob = new Blob([res.data], {
+          type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
+        });
+        const url = window.URL.createObjectURL(blob);
+        const link = document.createElement('a');
+        link.href = url;
+        link.download = name;
+        document.body.appendChild(link);
+        link.click();
+        document.body.removeChild(link);
+        window.URL.revokeObjectURL(url);
+      });
+  },
+  importAOD(dataForm) {
+    return $http
+      .post(`air/satellite/import/grid/aod`, dataForm)
+      .then((res) => res.data);
   }
-};
+};
\ No newline at end of file
diff --git a/src/components.d.ts b/src/components.d.ts
index cdfa990..f0ccb89 100644
--- a/src/components.d.ts
+++ b/src/components.d.ts
@@ -40,6 +40,7 @@
     ElTable: typeof import('element-plus/es')['ElTable']
     ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
     ElText: typeof import('element-plus/es')['ElText']
+    ElUpload: typeof import('element-plus/es')['ElUpload']
     FactorCheckbox: typeof import('./components/monitor/FactorCheckbox.vue')['default']
     FactorLegend: typeof import('./components/monitor/FactorLegend.vue')['default']
     FactorRadio: typeof import('./components/monitor/FactorRadio.vue')['default']
diff --git a/src/views/HomePage.vue b/src/views/HomePage.vue
index 49b914b..99df365 100644
--- a/src/views/HomePage.vue
+++ b/src/views/HomePage.vue
@@ -10,14 +10,23 @@
       <!-- <MapLocation></MapLocation> -->
       <SceneSearch></SceneSearch>
       <MapScene></MapScene>
+      <el-button @click="satelliteImportVisible = !satelliteImportVisible" type="primary" class="el-button-custom satellite-right-top p-events-auto">鐩戞祴鏁版嵁瀵煎叆</el-button>
+      <el-button @click="aodImportVisible = !aodImportVisible" type="primary" class="el-button-custom aod-right-top p-events-auto">AOD鏁版嵁瀵煎叆</el-button>
     </el-row>
     <!-- <CoreMenu></CoreMenu> -->
     <router-view></router-view>
   </div>
+  <SatelliteImport v-model="satelliteImportVisible"></SatelliteImport>
+  <AODImport v-model="aodImportVisible"></AODImport>
 </template>
 
 <script setup>
 // import SatelliteTelemetry from '@/views/satellitetelemetry/SatelliteTelemetry.vue';
+import { ref } from 'vue';
+import SatelliteImport from './satellitetelemetry/component/SatelliteImport.vue';
+import AODImport from './satellitetelemetry/component/AODImport.vue';
+const satelliteImportVisible = ref(false)
+const aodImportVisible = ref(false)
 </script>
 
 <style scoped>
@@ -37,8 +46,19 @@
 .dropdown-wrap {
   /* background-color: aliceblue; */
   position: absolute;
+  width: 99.5vw;
   top: 10px;
   left: 2px;
   gap: 4px;
 }
+.satellite-right-top {
+  width: 120px;
+  position: absolute;
+  right: 0px;
+}
+
+.aod-right-top {
+  position: absolute;
+  right: 124px;
+}
 </style>
diff --git a/src/views/satellitetelemetry/component/AODImport.vue b/src/views/satellitetelemetry/component/AODImport.vue
new file mode 100644
index 0000000..34167b4
--- /dev/null
+++ b/src/views/satellitetelemetry/component/AODImport.vue
@@ -0,0 +1,227 @@
+<template>
+  <CardDialog title="AOD鏁版嵁瀵煎叆" :model-value="modelValue" :width="420" @changed="handleChange">
+    <div class="download">
+      <el-button @click="downloadTemplate" type="primary" class="el-button-custom" size="small"
+        v-loading="downloadLoading">涓嬭浇妯℃澘</el-button>
+    </div>
+    <el-form :model="formObj" :rules="rules" ref="formRef" label-position="right" label-width="60px">
+      <el-form-item label="鍖哄煙">
+        <OptionLocation2 :level="3" :initValue="true" :checkStrictly="false" :allOption="true" v-model="location"
+          width="200">
+        </OptionLocation2>
+      </el-form-item>
+      <OptionGridGroup ref="gridGroupRef" v-model="gridGroup"></OptionGridGroup>
+      <el-form-item label="鏃堕棿" prop="dateTime">
+        <el-date-picker v-model="formObj.dateTime" type="date" placeholder="閫夋嫨鏃堕棿" size="small" :clearable="false" />
+      </el-form-item>
+      <el-form-item label="">
+        <el-row>
+          <el-col>
+            <label><el-checkbox v-model="formObj.update" label="" size="small"
+                :disabled="hasGridAod == undefined || hasGridAod == false" />鍚屾剰</label>
+          </el-col>
+          <el-col>
+            <el-text class="mx-1" type="danger" v-if="hasGridAod == true">褰撴棩AOD鏁版嵁宸插瓨鍦紝璇峰嬀閫夊悓鎰忓悗杩涜鏁版嵁鏇存柊瑕嗙洊</el-text>
+            <el-text class="mx-1" type="success" v-else-if="hasGridAod == false">褰撴棩AOD鏃犳暟鎹紝鍙柊澧炲鍏�</el-text>
+          </el-col>
+        </el-row>
+      </el-form-item>
+      <el-form-item>
+        <el-upload v-model:file-list="formObj.file" accept=".xlsx" :limit="1" :auto-upload="false" ref="uploadRef"
+          :on-exceed="handleUploadExceed" :on-change="handleUploadChange">
+          <template #trigger>
+            <el-button :disabled="formObj.update == undefined || (hasGridAod == true && formObj.update == false)"
+              type="primary" class="el-button-custom select-file-button" size="small" accept=".xlsx">閫夋嫨鏂囦欢</el-button>
+          </template>
+          <el-button @click="onSubmit" type="primary" class="el-button-custom import-button" size="small"
+            :disabled="!formObj.file || formObj.file.length == 0" v-loading="loading">
+            瀵煎叆
+          </el-button>
+        </el-upload>
+      </el-form-item>
+      <el-form-item>
+        <el-text class="mx-1" type="danger">{{ errorTipMsg }}</el-text>
+        <el-text class="mx-1" type="success">{{ successTipMsg }}</el-text>
+      </el-form-item>
+    </el-form>
+  </CardDialog>
+</template>
+<script setup>
+import { ref, watch, defineProps, defineEmits } from 'vue';
+import gridApi from '@/api/gridApi';
+import { dayjs, ElMessage } from 'element-plus';
+import { useFormConfirm } from '@/composables/formConfirm';
+
+const gridGroupRef = ref(null);
+const uploadRef = ref(null);
+// 鏄惁鏈夋暟鎹竷灏旂被鍨� 榛樿涓虹┖ 
+const hasGridAod = ref(null);
+const location = ref({});
+const gridGroup = ref({});
+// 瀵煎叆鏃跺睍绀哄湪瀵煎叆鎸夐挳涓婄殑鍔犺浇
+const loading = ref(false);
+// 涓嬭浇妯℃澘鏃跺睍绀哄湪涓嬭浇鎸夐挳涓婄殑鍔犺浇
+const downloadLoading = ref(false);
+// 鍦ㄥ鍏ユ寜閽笅鏂癸紙鐣岄潰鐨勪笅闈級閿欒鍜屾纭俊鎭�
+const errorTipMsg = ref('');
+const successTipMsg = ref('');
+const rules = {
+  dateTime: [{ required: true, message: '鏃堕棿涓嶈兘涓虹┖', trigger: 'blur' }]
+};
+
+const props = defineProps({
+  modelValue: Boolean
+});
+
+const emit = defineEmits(['update:modelValue']);
+
+const handleChange = (value) => {
+  emit('update:modelValue', value);
+};
+
+const downloadTemplate = () => {
+  downloadLoading.value = true
+  gridApi.downloadAODTemplate().then(res => {
+    downloadLoading.value = false
+  }).catch(e => {
+    downloadLoading.value = false
+  });
+};
+
+// 閫氳繃缃戞牸缁勫拰鏃堕棿 鏌ヨ 鍦ㄨ繖涓や釜鍙傛暟鏉′欢涓嬫槸鍚︽湁缃戞牸鏁版嵁锛屽苟鎻愮ず鍦ㄧ晫闈腑鏈夋垨鑰呮病鏈�
+const checkEmpty = () => {
+  gridApi.fetchGridAod(gridGroup.value.id, dayjs(formObj.value.dateTime).format('YYYY-MM-DD HH:mm:ss')).then(res => {
+    if (res.data && res.data.length > 0) {
+      hasGridAod.value = true;
+    } else {
+      formObj.value.update = false
+      hasGridAod.value = false;
+    }
+  })
+};
+const handleImportClick = () => {
+  loading.value = true;
+  const isUpdate = formObj.value.update ? formObj.value.update : false;
+
+  const formData = new FormData();
+  // 鏂囦欢杞崲涓轰簩杩涘埗
+  const reader = new FileReader();
+  reader.readAsArrayBuffer(formObj.value.file[0].raw);
+  reader.onload = async (theFile) => {
+    const binary = new Blob([theFile.target.result], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
+    formData.append('excel', binary);
+    formData.append('groupId', gridGroup.value.id);
+    formData.append(
+      'dateTime',
+      dayjs(formObj.value.dateTime).format('YYYY-MM-DD HH:mm:ss')
+    );
+    formData.append('update', isUpdate);
+    gridApi
+      .importAOD(formData)
+      .then((res) => {
+        resetApiTipMsg()
+        loading.value = false;
+        if (res && res.success == true) {
+          // 瀵煎叆鎴愬姛锛�1.瀵煎叆鎴栬�呰鐩栨垚鍔燂紝鏄惁涓虹┖鐘舵�佹敼鍙樹簡锛岄噸鏂版鏌�
+          checkEmpty()
+          successTipMsg.value = res.data.result
+        } else {
+          errorTipMsg.value = res.message
+        }
+      }).catch(e => {
+        loading.value = false;
+        errorTipMsg.value = e
+      })
+  }
+};
+const resetApiTipMsg = () => {
+  successTipMsg.value = ''
+  errorTipMsg.value = ''
+};
+// 褰撻�夋嫨鏂囦欢鍚庯細 1. 閲嶇疆鎻愮ず淇℃伅锛岄槻姝㈣瀵� 2.瀵规枃浠剁被鍨嬬殑妫�鏌�
+const handleUploadChange = (file, files) => {
+  resetApiTipMsg()
+  const fileType = file.raw.type;
+  // 妫�鏌ユ枃浠剁被鍨嬫槸鍚︿负 'xlsx'
+  if (fileType !== 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') {
+    ElMessage({
+      message: '鏂囦欢绫诲瀷閿欒锛岃閲嶆柊涓婁紶xlsx绫诲瀷鏂囦欢',
+      type: 'error'
+    })
+    files.splice(0, 1); // 闃绘涓婁紶
+  }
+};
+// 鏂伴�夋嫨鏂囦欢鏇挎崲鏃ф枃浠�
+const handleUploadExceed = (files) => {
+  const file = files[0]
+  uploadRef.value.clearFiles()
+  uploadRef.value.handleStart(file)
+};
+const { formObj, formRef, edit, onSubmit, onCancel } = useFormConfirm({
+  submit: {
+    do: handleImportClick
+  },
+  cancel: {
+    do: () => {
+
+    }
+  }
+});
+
+
+
+watch(location, (nv, ov) => {
+  if (nv != ov) {
+    resetApiTipMsg()
+    const area = {
+      provinceCode: nv.pCode,
+      provinceName: nv.pName,
+      cityCode: nv.cCode,
+      cityName: nv.cName,
+      districtCode: nv.dCode,
+      districtName: nv.dName,
+      townCode: nv.tCode,
+      townName: nv.tName
+    };
+    gridGroupRef.value.fetchGridGroup(area);
+  }
+});
+
+watch(gridGroup, (nv) => {
+  if (nv && Object.keys(nv).length === 0 && formObj.value.dateTime && Object.keys(formObj.value.dateTime).length === 0) {
+    checkEmpty()
+  }
+}, { deep: true });
+
+watch(formObj.value, (nv) => {
+  if (nv.dateTime && gridGroup.value) {
+    checkEmpty()
+  }
+}, { deep: true });
+</script>
+<style scoped>
+.download {
+  display: flex;
+  justify-content: flex-end;
+}
+
+.click_to_show-btn {
+  z-index: 1000;
+}
+
+.select-file-button {
+  /* margin-left: 5px; */
+}
+
+.import-button {
+  margin-left: 20px;
+}
+
+::v-deep .el-date-editor {
+  width: 200px !important;
+}
+
+::v-deep .el-select {
+  width: 200px !important;
+}
+</style>
\ No newline at end of file
diff --git a/src/views/satellitetelemetry/component/SatelliteImport.vue b/src/views/satellitetelemetry/component/SatelliteImport.vue
new file mode 100644
index 0000000..eb962bd
--- /dev/null
+++ b/src/views/satellitetelemetry/component/SatelliteImport.vue
@@ -0,0 +1,225 @@
+<template>
+  <CardDialog title="鐩戞祴鏁版嵁瀵煎叆" :model-value="modelValue" :width="420" @changed="handleChange">
+    <div class="download">
+      <el-button @click="downloadTemplate" type="primary" class="el-button-custom" size="small"
+        v-loading="downloadLoading">涓嬭浇妯℃澘</el-button>
+    </div>
+    <el-form :model="formObj" :rules="rules" ref="formRef" label-position="right" label-width="60px">
+      <el-form-item label="鍖哄煙">
+        <OptionLocation2 :level="3" :initValue="true" :checkStrictly="false" :allOption="true" v-model="location"
+          width="200">
+        </OptionLocation2>
+      </el-form-item>
+      <OptionGridGroup ref="gridGroupRef" v-model="gridGroup"></OptionGridGroup>
+      <el-form-item label="鏃堕棿" prop="dateTime">
+        <el-date-picker v-model="formObj.dateTime" type="date" placeholder="閫夋嫨鏃堕棿" size="small" :clearable="false"/>
+      </el-form-item>
+      <el-form-item label="">
+        <el-row>
+          <el-col>
+            <label><el-checkbox v-model="formObj.update" label="" size="small"
+                :disabled="hasGridData == undefined || hasGridData == false" />鍚屾剰</label>
+          </el-col>
+          <el-col>
+            <el-text class="mx-1" type="danger" v-if="hasGridData == true">褰撴棩閬ユ祴鏁版嵁宸插瓨鍦紝璇峰嬀閫夊悓鎰忓悗杩涜鏁版嵁鏇存柊瑕嗙洊</el-text>
+            <el-text class="mx-1" type="success" v-else-if="hasGridData == false">褰撴棩閬ユ祴鏃犳暟鎹紝鍙柊澧炲鍏�</el-text>
+          </el-col>
+        </el-row>
+      </el-form-item>
+      <el-form-item>
+        <el-upload v-model:file-list="formObj.file" accept=".xlsx" :limit="1" :auto-upload="false" ref="uploadRef"
+          :on-exceed="handleUploadExceed" :on-change="handleUploadChange">
+          <template #trigger>
+            <el-button :disabled="formObj.update == undefined || (hasGridData == true && formObj.update == false)"
+              type="primary" class="el-button-custom select-file-button" size="small" accept=".xlsx">閫夋嫨鏂囦欢</el-button>
+          </template>
+          <el-button @click="onSubmit" type="primary" class="el-button-custom import-button" size="small" :disabled="!formObj.file || formObj.file.length == 0"
+            v-loading="loading">
+            瀵煎叆
+          </el-button>
+        </el-upload>
+      </el-form-item>
+      <el-form-item>
+        <el-text class="mx-1" type="danger">{{ errorTipMsg }}</el-text>
+        <el-text class="mx-1" type="success">{{ successTipMsg }}</el-text>
+      </el-form-item>
+    </el-form>
+  </CardDialog>
+</template>
+<script setup>
+import { ref, watch, defineProps, defineEmits } from 'vue';
+import gridApi from '@/api/gridApi';
+import { dayjs, ElMessage } from 'element-plus';
+import { useFormConfirm } from '@/composables/formConfirm';
+
+const gridGroupRef = ref(null);
+const uploadRef = ref(null);
+// 鏄惁鏈夋暟鎹竷灏旂被鍨� 榛樿涓虹┖ 
+const hasGridData = ref(null);
+const location = ref({});
+const gridGroup = ref({});
+// 瀵煎叆鏃跺睍绀哄湪瀵煎叆鎸夐挳涓婄殑鍔犺浇
+const loading = ref(false);
+// 涓嬭浇妯℃澘鏃跺睍绀哄湪涓嬭浇鎸夐挳涓婄殑鍔犺浇
+const downloadLoading = ref(false);
+// 鍦ㄥ鍏ユ寜閽笅鏂癸紙鐣岄潰鐨勪笅闈級閿欒鍜屾纭俊鎭�
+const errorTipMsg = ref('');
+const successTipMsg = ref('');
+const rules = {
+  dateTime: [{ required: true, message: '鏃堕棿涓嶈兘涓虹┖', trigger: 'blur' }],
+};
+const props = defineProps({
+  modelValue: Boolean
+});
+
+const resetApiTipMsg = () => {
+  successTipMsg.value = ''
+  errorTipMsg.value = ''
+};
+
+const emit = defineEmits(['update:modelValue']);
+
+const handleChange = (value) => {
+  emit('update:modelValue', value);
+};
+
+const downloadTemplate = () => {
+  downloadLoading.value = true
+  gridApi.downloadTemplate().then(res => {
+    downloadLoading.value = false
+  }).catch(e => {
+    downloadLoading.value = false
+  });
+};
+// 閫氳繃缃戞牸缁勫拰鏃堕棿 鏌ヨ 鍦ㄨ繖涓や釜鍙傛暟鏉′欢涓嬫槸鍚︽湁缃戞牸鏁版嵁锛屽苟鎻愮ず鍦ㄧ晫闈腑鏈夋垨鑰呮病鏈�
+const checkEmpty = () => {
+  gridApi.fetchGridData(gridGroup.value.id, dayjs(formObj.value.dateTime).format('YYYY-MM-DD HH:mm:ss')).then(res => {
+    if (res.data && res.data.length > 0) {
+      hasGridData.value = true;
+    } else {
+      formObj.value.update = false
+      hasGridData.value = false;
+    }
+  })
+};
+const handleImportClick = () => {
+  loading.value = true;
+  const isUpdate = formObj.value.update ? formObj.value.update : false;
+  const type = 0;
+
+  const formData = new FormData();
+  // 鏂囦欢杞崲涓轰簩杩涘埗
+  const reader = new FileReader();
+  reader.readAsArrayBuffer(formObj.value.file[0].raw);
+  reader.onload = async (theFile) => {
+    const binary = new Blob([theFile.target.result], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
+    formData.append('excel', binary);
+    formData.append('groupId', gridGroup.value.id);
+    formData.append('type', type);
+    formData.append(
+      'dateTime',
+      dayjs(formObj.value.dateTime).format('YYYY-MM-DD HH:mm:ss')
+    );
+    formData.append('update', isUpdate);
+    gridApi
+      .importData(formData)
+      .then((res) => {
+        resetApiTipMsg()
+        loading.value = false;
+        if (res && res.success == true) {
+          // 瀵煎叆鎴愬姛锛�1.瀵煎叆鎴栬�呰鐩栨垚鍔燂紝鏄惁涓虹┖鐘舵�佹敼鍙樹簡锛岄噸鏂版鏌�
+          checkEmpty()
+          successTipMsg.value = res.data.result
+        } else {
+          errorTipMsg.value = res.message
+        }
+      }).catch(e => {
+        loading.value = false;
+        errorTipMsg.value = e
+      })
+  }
+};
+// 褰撻�夋嫨鏂囦欢鍚庯細 1. 閲嶇疆鎻愮ず淇℃伅锛岄槻姝㈣瀵� 2.瀵规枃浠剁被鍨嬬殑妫�鏌�
+const handleUploadChange = (file, files) => {
+  resetApiTipMsg()
+  const fileType = file.raw.type;
+  // 妫�鏌ユ枃浠剁被鍨嬫槸鍚︿负 'xlsx'
+  if (fileType !== 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') {
+    ElMessage({
+      message: '鏂囦欢绫诲瀷閿欒锛岃閲嶆柊涓婁紶xlsx绫诲瀷鏂囦欢',
+      type: 'error'
+    })
+    files.splice(0, 1); // 闃绘涓婁紶
+  }
+};
+// 鏂伴�夋嫨鏂囦欢鏇挎崲鏃ф枃浠�
+const handleUploadExceed = (files) => {
+  const file = files[0]
+  uploadRef.value.clearFiles()
+  uploadRef.value.handleStart(file)
+};
+const { formObj, formRef, edit, onSubmit, onCancel } = useFormConfirm({
+  submit: {
+    do: handleImportClick
+  },
+  cancel: {
+    do: () => {
+
+    }
+  }
+});
+watch(location, (nv, ov) => {
+  if (nv != ov) {
+    resetApiTipMsg()
+    const area = {
+      provinceCode: nv.pCode,
+      provinceName: nv.pName,
+      cityCode: nv.cCode,
+      cityName: nv.cName,
+      districtCode: nv.dCode,
+      districtName: nv.dName,
+      townCode: nv.tCode,
+      townName: nv.tName
+    };
+    gridGroupRef.value.fetchGridGroup(area);
+  }
+});
+// 褰撶綉鏍肩粍鍜屾椂闂撮兘涓嶄负绌� 骞朵笖 鏈変竴涓潯浠舵敼鍙樺悗閲嶆柊妫�鏌ユ槸鍚︽湁缃戞牸鏁版嵁
+watch(gridGroup, (nv) => {
+  if (nv && Object.keys(nv).length === 0 && formObj.value.dateTime && Object.keys(formObj.value.dateTime).length === 0) {
+    checkEmpty()
+  }
+}, { deep: true });
+
+watch(formObj, (nv) => {
+  if (nv.dateTime && gridGroup.value) {
+    checkEmpty()
+  }
+}, { deep: true });
+</script>
+<style scoped>
+.download {
+  display: flex;
+  justify-content: flex-end;
+}
+
+.select-file-button {
+  /* margin-left: 5px; */
+}
+
+.import-button {
+  margin-left: 20px;
+}
+
+.click_to_show-btn {
+  z-index: 1000;
+}
+
+::v-deep .el-date-editor {
+  width: 200px !important;
+}
+
+::v-deep .el-select {
+  width: 200px !important;
+}
+</style>

--
Gitblit v1.9.3