src/views/fysp/evaluation/components/CompDataResultEdit.vue
@@ -4,61 +4,251 @@
      ref="upload"
      class="upload-file"
      :limit="1"
      accept=".xls,.xlsx"
      :on-change="handleChange"
      :on-exceed="handleExceed"
      :auto-upload="false"
    >
      <template #trigger>
        <el-button type="primary">上传监测数据统计结果</el-button>
        <el-button type="primary" :loading="tableLoading">导入文件</el-button>
      </template>
      <template #tip>
        <div>
          <el-text type="danger">{{ tips }}</el-text>
        </div>
      </template>
    </el-upload>
    <el-text>{{ loadTxt }}</el-text>
    <div v-if="tableLoading">
      <el-icon class="is-loading"><Loading /></el-icon>
      <el-text>{{ loadTxt }}</el-text>
    </div>
  </el-row>
  <el-table
    ref="tableRef"
    :data="data"
    v-loading="loading"
    v-loading="tableLoading"
    table-layout="fixed"
    :stripe="true"
    row-key="id"
    :expand-row-keys="expandRowKeys"
    :row-class-name="tableRowClassName"
    size="small"
    height="60vh"
    border
  >
    <!-- <el-table-column type="expand">
      <template #default="{ row }">
        {{ row.drSceneName }}
      </template>
    </el-table-column> -->
    <el-table-column
      v-if="isUploadNewFile"
      prop="isFound"
      label="合规"
      width="30"
    >
      <template #default="{ row }">
        <el-icon class="is-loading" v-if="row.loading">
          <Loading color="#409eff" />
        </el-icon>
        <el-icon v-else>
          <Check v-if="row.isFound" />
          <Close v-else />
        </el-icon>
      </template>
    </el-table-column>
    <el-table-column
      :show-overflow-tooltip="true"
      prop="drSceneName"
      label="名称"
      width="300"
    />
    <el-table-column prop="drDeviceCode" label="设备号" width="130" />
    <el-table-column prop="drTime" label="时间" width="100">
    >
      <template #default="{ row }">
        <span>{{ $fm.formatYMD(row.drTime) }}</span>
        <el-input
          v-if="isUploadNewFile && !row.isFound"
          size="small"
          v-model="row.drSceneName"
          @change="(e) => handleSceneNameChange(e, row)"
        />
        <span v-else>{{ row.drSceneName }}</span>
      </template>
    </el-table-column>
    <el-table-column prop="drExceedTimes" label="超标次数" />
    <el-table-column prop="drAvg" label="平均值" />
    <el-table-column prop="drMax" label="最大值" />
    <el-table-column prop="drMin" label="最小值" />
    <el-table-column prop="drOverAvgPer" label="超区均值百分比" />
    <el-table-column prop="drDataNum" label="数据量" />
    <el-table-column prop="drEffectiveRate" label="有效率" />
    <el-table-column prop="drDeviceCode" label="设备号" width="130">
      <template #default="{ row }">
        <el-input
          v-if="isUploadNewFile && !row.isFound"
          size="small"
          v-model="row.drDeviceCode"
        />
        <span v-else>{{ row.drDeviceCode }}</span>
      </template>
    </el-table-column>
    <el-table-column prop="drTime" label="时间" width="100">
      <template #default="{ row }">
        <span>{{ $fm.formatYM(row.drTime) }}</span>
      </template>
    </el-table-column>
    <el-table-column prop="drExceedTimes" label="超标次数">
      <template #default="{ row }">
        <el-input
          v-if="isUploadNewFile && !row.isFound"
          size="small"
          v-model="row.drExceedTimes"
        />
        <span v-else>{{ row.drExceedTimes }}</span>
      </template>
    </el-table-column>
    <el-table-column prop="drAvg" label="平均值">
      <template #default="{ row }">
        <el-input
          v-if="isUploadNewFile && !row.isFound"
          size="small"
          v-model="row.drAvg"
        />
        <span v-else>{{ row.drAvg }}</span>
      </template>
    </el-table-column>
    <el-table-column prop="drMax" label="最大值">
      <template #default="{ row }">
        <el-input
          v-if="isUploadNewFile && !row.isFound"
          size="small"
          v-model="row.drMax"
        />
        <span v-else>{{ row.drMax }}</span>
      </template>
    </el-table-column>
    <el-table-column prop="drMin" label="最小值">
      <template #default="{ row }">
        <el-input
          v-if="isUploadNewFile && !row.isFound"
          size="small"
          v-model="row.drMin"
        />
        <span v-else>{{ row.drMin }}</span>
      </template>
    </el-table-column>
    <el-table-column prop="drOverAvgPer" label="超区均值百分比">
      <template #default="{ row }">
        <el-input
          v-if="isUploadNewFile && !row.isFound"
          size="small"
          v-model="row.drOverAvgPer"
        />
        <span v-else>{{ row.drOverAvgPer }}</span>
      </template>
    </el-table-column>
    <el-table-column prop="drDataNum" label="数据量">
      <template #default="{ row }">
        <el-input
          v-if="isUploadNewFile && !row.isFound"
          size="small"
          v-model="row.drDataNum"
        />
        <span v-else>{{ row.drDataNum }}</span>
      </template>
    </el-table-column>
    <el-table-column prop="drEffectiveRate" label="有效率">
      <template #default="{ row }">
        <el-input
          v-if="isUploadNewFile && !row.isFound"
          size="small"
          v-model="row.drEffectiveRate"
          placeholder="场景名称"
        />
        <span v-else>{{ row.drEffectiveRate }}</span>
      </template>
    </el-table-column>
    <el-table-column v-if="isUploadNewFile" type="expand">
      <template #default="{ row }">
        <div class="p-v-4">
          <div v-if="!row.isFound" class="p-h-16">
            <div v-if="row.notSure">
              <el-text type="warning" size="small"
                >未找到该场景,但找到了有相似名称的场景,请确定是哪个场景</el-text
              >
              <div class="m-t-8">
                <el-button
                  v-for="(v, i) in row.sourceScene"
                  :key="v.guid"
                  type="primary"
                  text
                  bg
                  size="small"
                  @click="handleRadioChange(v, row)"
                >
                  {{ v.name }}
                </el-button>
                <!-- <el-radio-group v-model="row.radioValue">
                <el-radio
                  v-for="(v, i) in row.sourceScene"
                  :key="v.guid"
                  :value="i"
                  size="small"
                  border
                  @change="handleRadioChange(v, row)"
                  >{{ v.name }}</el-radio
                >
              </el-radio-group> -->
              </div>
            </div>
            <div v-else>
              <el-text type="danger" size="small"
                >未找到该场景,也没有任何相似名称的场景,请修改场景名称或去除该场景</el-text
              >
            </div>
          </div>
          <div v-else class="p-h-16">
            <el-text type="success" size="small"> 已正确匹配到该场景 </el-text>
          </div>
        </div>
      </template>
    </el-table-column>
  </el-table>
  <el-button
    type="primary"
    :loading="uploadLoading"
    icon="upload"
    @click="uploadFile"
    >上传统计结果</el-button
  >
</template>
<script setup>
import { ref, watch, onMounted } from 'vue';
import { ref, reactive, watch, onMounted, getCurrentInstance } from 'vue';
import { genFileId } from 'element-plus';
import monitordataApi from '@/api/fysp/monitordataApi';
import sceneApi from '@/api/fysp/sceneApi';
import * as XLSX from 'xlsx';
const cns = getCurrentInstance();
const $fm = cns.appContext.config.globalProperties.$fm;
const props = defineProps({
  areaInfo: { type: Object }
});
let workbook;
const isUploadNewFile = ref(false);
const data = ref([]);
const expandRowKeys = ref([]);
const upload = ref();
const tableLoading = ref(false);
const loadTxt = ref('');
const tips = ref('');
const uploadLoading = ref(false);
const tableRowClassName = ({ row, rowIndex }) => {
  if (row.loading) {
    return 'loading-row';
  } else if (row.isFound == undefined) {
    return '';
  } else {
    return row.isFound
      ? 'success-row'
      : row.notSure
        ? 'warning-row'
        : 'danger-row';
  }
};
// 获取历史统计结果
function fetchDustDataResult() {
@@ -75,18 +265,101 @@
}
function handleChange(uploadFile, uploadFiles) {
  expandRowKeys.value = [];
  tableLoading.value = true;
  loadTxt.value = '文件解析中...';
  // console.log(uploadFile, uploadFiles);
  const fileReader = new FileReader();
  fileReader.onload = (file) => {
    const data = file.target.result;
    workbook = XLSX.read(data, { type: 'array' });
    const fileData = file.target.result;
    workbook = XLSX.read(fileData, { type: 'array' });
    console.log(workbook.SheetNames);
    if (workbook.SheetNames.length == 0) {
      tips.value = 'excel文件错误,没有sheet表单';
      return;
    }
    const worksheet = workbook.Sheets[workbook.SheetNames[0]];
    const tableData = XLSX.utils.sheet_to_json(worksheet);
    data.value = tableData.map((v, i) => {
      return reactive({
        id: i,
        drSceneName: v['名称'],
        drDeviceCode: v['设备号'],
        drTime: $fm.formatDateFromExcel(v['时间'], '-'),
        drExceedTimes: v['超标次数'],
        drAvg: v['平均值'],
        drMax: v['最大值'],
        drMin: v['最小值'],
        drOverAvgPer: v['超区均值百分比'],
        drDataNum: v['数据量'],
        drEffectiveRate: v['有效率']
      });
    });
    // console.log(tableData);
    setTimeout(() => {
      tableLoading.value = false;
      isUploadNewFile.value = true;
      data.value.forEach((d) => {
        searchScene(d);
      });
    }, 1000);
  };
  fileReader.readAsArrayBuffer(uploadFile.raw);
}
// 查询从文件上传的每个场景是否能在系统中找到对应的场景信息
function searchScene(d) {
  d.loading = true;
  if (!d.drSceneName) {
    d.isFound = false;
    d.loading = false;
    return Promise;
  } else {
    sceneApi
      .findScene({ name: d.drSceneName })
      .then((res) => {
        setTimeout(() => {
          if (res.length > 0) {
            const findRes = res.find((v) => v.name == d.drSceneName);
            if (findRes) {
              d.drSceneId = res[0].guid;
              d.isFound = true;
            } else {
              d.isFound = false;
              d.notSure = true;
              expandRowKeys.value.push(d.id);
            }
            d.sourceScene = res;
          } else {
            d.isFound = false;
            expandRowKeys.value.push(d.id);
          }
          d.loading = false;
        }, 1000);
      })
      .finally(() => {
        setTimeout(() => {
          d.loading = false;
        }, 1000);
      });
  }
}
function handleSceneNameChange(newName, row) {
  searchScene(row);
}
function handleRadioChange(value, row) {
  const scene = value;
  row.drSceneId = scene.guid;
  row.drSceneName = scene.name;
  searchScene(row);
}
// 上传统计结果文档
function uploadFile() {}
function uploadFile() {
  monitordataApi.uploadDustDataResult(data.value).then((res) => {});
}
onMounted(() => {
  fetchDustDataResult();
@@ -102,4 +375,42 @@
:deep(.el-text) {
  align-self: auto;
}
:deep(.el-table__expanded-cell) {
  padding: 0;
  /* background-color: var(--el-bg-color-page); */
}
/* :deep(.el-table__body tr>td.hover-cell) {
  background-color: red !important;
} */
/* .el-table--enable-row-hover
  .el-table__body
  tr:hover
  > td
  :deep(.el-table__cell) {
  background-color: red !important;
} */
</style>
<style>
.el-table .warning-row {
  --el-table-tr-bg-color: var(--el-color-warning-light-5);
}
.el-table .success-row {
  --el-table-tr-bg-color: var(--el-color-success-light-7);
}
.el-table .danger-row {
  --el-table-tr-bg-color: var(--el-color-danger-light-5);
}
.el-table .loading-row {
  color: var(--el-text-color-disabled);
  /* --el-table-tr-bg-color: var(--el-text-color-placeholder); */
  --el-table-tr-bg-color: var(--el-bg-color);
}
/* .el-table__body tr>td.hover-cell {
  background-color: red !important;
} */
/* .el-table--enable-row-hover .el-table__body tr:hover>td.el-table__cell {
  background-color: unset;
} */
</style>