src/views/satellitetelemetry/component/SatelliteImport.vue
@@ -1,47 +1,123 @@
<template>
  <CardDialog title="监测数据导入" :model-value="modelValue" :width="420" @changed="handleChange">
  <el-button
    type="primary"
    class="el-button-custom p-events-auto satellite-right-top"
    @click="modelValue = !modelValue"
  >
    监测数据导入
  </el-button>
  <CardDialog
    title="监测数据导入"
    v-model="modelValue"
    :width="420"
    @changed="handleChange"
    destroy-on-close
    :before-close="init"
  >
    <div class="download">
      <el-button @click="downloadTemplate" type="primary" class="el-button-custom" size="small"
        v-loading="downloadLoading">下载模板</el-button>
      <el-button
        @click="downloadTemplate"
        type="primary"
        class="el-button-custom"
        size="small"
        :loading="downloadLoading"
        >下载模板</el-button
      >
    </div>
    <el-form :model="formObj" :rules="rules" ref="formRef" label-position="right" label-width="60px">
    <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
          :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-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
            v-loading="tipTextLoading"
            v-if="!formObj.file || (formObj.file && formObj.file.length == 0)"
          >
            <el-text class="mx-1" type="danger" v-if="hasGridData == true"
              >当日遥测数据已存在,请勾选
              <el-checkbox
                v-model="formObj.update"
                label="同意"
                size="small"
                :disabled="hasGridData == undefined || hasGridData == false"
              />后进行数据更新覆盖</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">
        <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>
            <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
            @click="onSubmit"
            type="primary"
            class="el-button-custom import-button"
            size="small"
            :disabled="!formObj.file || formObj.file.length == 0"
            :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-text class="mx-1" type="danger" truncated>{{
          errorTipMsg
        }}</el-text>
        <el-text class="mx-1" type="success" truncated>{{
          successTipMsg
        }}</el-text>
      </el-form-item>
    </el-form>
  </CardDialog>
@@ -54,7 +130,7 @@
const gridGroupRef = ref(null);
const uploadRef = ref(null);
// 是否有数据布尔类型 默认为空
// 是否有数据布尔类型 默认为空
const hasGridData = ref(null);
const location = ref({});
const gridGroup = ref({});
@@ -62,19 +138,30 @@
const loading = ref(false);
// 下载模板时展示在下载按钮上的加载
const downloadLoading = ref(false);
// 提示当日网格组是否有数据的loading
const tipTextLoading = ref(false);
// 在导入按钮下方(界面的下面)错误和正确信息
const errorTipMsg = ref('');
const successTipMsg = ref('');
const rules = {
  dateTime: [{ required: true, message: '时间不能为空', trigger: 'blur' }],
  dateTime: [{ required: true, message: '时间不能为空', trigger: 'blur' }]
};
const props = defineProps({
  modelValue: Boolean
});
const modelValue = ref(false);
const init = (done) => {
  loading.value = false
  downloadLoading.value = false
  tipTextLoading.value = false
  hasGridData.value = undefined
  formObj.value.dateTime = undefined
  resetApiTipMsg()
  done()
}
const resetApiTipMsg = () => {
  successTipMsg.value = ''
  errorTipMsg.value = ''
  successTipMsg.value = '';
  errorTipMsg.value = '';
};
const emit = defineEmits(['update:modelValue']);
@@ -84,23 +171,42 @@
};
const downloadTemplate = () => {
  downloadLoading.value = true
  gridApi.downloadTemplate().then(res => {
    downloadLoading.value = false
  }).catch(e => {
    downloadLoading.value = false
  });
  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;
    }
  })
  tipTextLoading.value = true;
  gridApi
    .fetchGridData(
      gridGroup.value.id,
      dayjs(formObj.value.dateTime).format('YYYY-MM-DD HH:mm:ss')
    )
    .then((res) => {
      // 延迟100ms结束loading状态
      setTimeout(() => {
        tipTextLoading.value = false;
      }, 100);
      if (res.data && res.data.length > 0) {
        hasGridData.value = true;
      } else {
        formObj.value.update = false;
        hasGridData.value = false;
      }
    })
    .catch((e) => {
      // 延迟100ms结束loading状态
      setTimeout(() => {
        tipTextLoading.value = false;
      }, 100);
    });
};
const handleImportClick = () => {
  loading.value = true;
@@ -112,7 +218,9 @@
  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' });
    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);
@@ -124,53 +232,60 @@
    gridApi
      .importData(formData)
      .then((res) => {
        resetApiTipMsg()
        resetApiTipMsg();
        loading.value = false;
        if (res && res.success == true) {
          // 导入成功,1.导入或者覆盖成功,是否为空状态改变了,重新检查
          checkEmpty()
          successTipMsg.value = res.data.result
          checkEmpty();
          // 根据当前操作是插入还是更新展示成功消息
          if (isUpdate) {
            successTipMsg.value = '覆盖成功';
          }else {
            successTipMsg.value = '导入成功';
          }
        } else {
          errorTipMsg.value = res.message
          errorTipMsg.value = res.message;
        }
      }).catch(e => {
        loading.value = false;
        errorTipMsg.value = e
      })
  }
      .catch((e) => {
        loading.value = false;
        errorTipMsg.value = e;
      });
  };
};
// 当选择文件后: 1. 重置提示信息,防止误导 2.对文件类型的检查
const handleUploadChange = (file, files) => {
  resetApiTipMsg()
  resetApiTipMsg();
  const fileType = file.raw.type;
  // 检查文件类型是否为 'xlsx'
  if (fileType !== 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') {
  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 file = files[0];
  uploadRef.value.clearFiles();
  uploadRef.value.handleStart(file);
};
const { formObj, formRef, edit, onSubmit, onCancel } = useFormConfirm({
  submit: {
    do: handleImportClick
  },
  cancel: {
    do: () => {
    }
    do: () => {}
  }
});
watch(location, (nv, ov) => {
  if (nv != ov) {
    resetApiTipMsg()
    resetApiTipMsg();
    const area = {
      provinceCode: nv.pCode,
      provinceName: nv.pName,
@@ -185,17 +300,30 @@
  }
});
// 当网格组和时间都不为空 并且 有一个条件改变后重新检查是否有网格数据
watch(gridGroup, (nv) => {
  if (nv && Object.keys(nv).length === 0 && formObj.value.dateTime && Object.keys(formObj.value.dateTime).length === 0) {
    checkEmpty()
  }
}, { deep: true });
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 });
watch(
  formObj,
  (nv) => {
    if (nv.dateTime && gridGroup.value) {
      checkEmpty();
    }
  },
  { deep: true }
);
</script>
<style scoped>
.download {
@@ -222,4 +350,19 @@
::v-deep .el-select {
  width: 200px !important;
}
::v-deep .el-checkbox.el-checkbox--small .el-checkbox__label {
  font-size: 15px !important;
}
::v-deep .el-upload-list__item-file-name {
  color: white;
  overflow: visible;
}
.satellite-right-top {
  width: 120px;
  position: absolute;
  right: 0px;
}
</style>