中间数据产品
1. 新增报告生成提示;
2. 新增报告文件下载;
3. 修复报告页面展示时,相同名称的列数据无法正确展示的问题;
已修改5个文件
已添加1个文件
156 ■■■■ 文件已修改
src/api/fysp/dataproductApi.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components.d.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/bg-task/FYBgTaskCard.vue 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/bg-task/FYBgTaskDialog.vue 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/stores/bgtaskStore.js 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/fysp/data-product/components/BaseDataProduct.vue 73 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/fysp/dataproductApi.js
@@ -18,7 +18,7 @@
        }
        // æ–‡æ¡£å·²å­˜åœ¨ï¼Œè¿”回文件数据流
        else {
          return res.data
          return res
          // const name = Base64.decode(res.headers.get('filename'));
          // const url = window.URL.createObjectURL(res.data);
          // const link = document.createElement('a');
src/components.d.ts
@@ -57,6 +57,7 @@
    ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
    ElRow: typeof import('element-plus/es')['ElRow']
    ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
    ElSegmented: typeof import('element-plus/es')['ElSegmented']
    ElSelect: typeof import('element-plus/es')['ElSelect']
    ElSpace: typeof import('element-plus/es')['ElSpace']
    ElStep: typeof import('element-plus/es')['ElStep']
src/components/bg-task/FYBgTaskCard.vue
@@ -4,7 +4,9 @@
      <el-row justify="space-between">
        <div>
          <div><el-text tag="b" size="large">后台任务</el-text></div>
          <el-text size="small" type="info">显示当前正在进行的后台耗时任务状态</el-text>
          <el-text size="small" type="info"
            >显示当前正在进行的后台耗时任务状态</el-text
          >
        </div>
        <el-button
          icon="Refresh"
@@ -46,11 +48,13 @@
import { useFetchData } from '@/composables/fetchData';
import bgtaskApi from '@/api/fysp/bgtaskApi';
import { enumBgTask, BG_TASK_TYPE, BG_TASK_STATUS } from '@/enum/bgTask';
import { useBgtaskStore } from '@/stores/bgtaskStore';
export default {
  setup() {
    const { loading, fetchData } = useFetchData();
    return { loading, fetchData };
    const { registerOnFetchTask } = useBgtaskStore();
    return { loading, fetchData, registerOnFetchTask };
  },
  props: {
    modelValue: Number
@@ -80,14 +84,18 @@
    addTask() {},
    newTestTask() {
      this.fetchData((page, pageSize) => {
        return bgtaskApi.newTestTask(`Test-Task-${++this.taskIndex}`).then((res) => {
        return bgtaskApi
          .newTestTask(`Test-Task-${++this.taskIndex}`)
          .then((res) => {
          this.taskList.push(res.data);
        });
      });
    },
    startNewTestTask() {
      this.fetchData((page, pageSize) => {
        return bgtaskApi.startNewTestTask(`Test-Task-${++this.taskIndex}`).then((res) => {
        return bgtaskApi
          .startNewTestTask(`Test-Task-${++this.taskIndex}`)
          .then((res) => {
          this.taskList.push(res.data);
        });
      });
@@ -153,6 +161,7 @@
  },
  mounted() {
    this.fetchTask();
    this.registerOnFetchTask(this.fetchTask);
    // setInterval(() => {
    //   this.fetchTask();
    // }, 10000);
src/components/bg-task/FYBgTaskDialog.vue
@@ -1,9 +1,16 @@
<template>
  <el-popover placement="bottom" :width="600" trigger="click">
  <el-popover
    placement="bottom"
    :width="600"
    trigger="click"
    v-model:visible="bgtaskStore.dialogShow"
  >
    <template #reference>
      <el-badge :value="runningNum" :hidden="runningNum == 0" class="m-r-16">
        <el-button circle>
          <el-icon v-if="runningNum > 0" color="red" class="is-loading"><Clock /></el-icon>
          <el-icon v-if="runningNum > 0" color="red" class="is-loading"
            ><Clock
          /></el-icon>
          <el-icon v-else><Clock /></el-icon>
        </el-button>
      </el-badge>
@@ -12,13 +19,13 @@
    <FYBgTaskCard v-model="runningNum"></FYBgTaskCard>
  </el-popover>
</template>
<script>
export default {
  data() {
    return {
      runningNum: 0
    };
  }
};
<script setup>
import { ref } from 'vue';
import { useBgtaskStore } from '@/stores/bgtaskStore';
const bgtaskStore = useBgtaskStore();
const runningNum = ref(0);
</script>
<style scoped></style>
src/stores/bgtaskStore.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,36 @@
import { defineStore } from 'pinia';
import { ref } from 'vue';
export const useBgtaskStore = defineStore('bgtask', () => {
  // å¼¹å‡ºæ¡†æ˜¾ç¤º
  const dialogShow = ref(false);
  const events = [];
  function toggleShow(show) {
    if (typeof show === 'boolean') {
      dialogShow.value = show;
    } else {
      dialogShow.value = !dialogShow.value;
    }
  }
  function registerOnFetchTask(func) {
    events.push(func);
  }
  function fetchTask() {
    events.forEach((e) => {
      if (typeof e === 'function') {
        e();
      }
    });
  }
  return {
    dialogShow,
    toggleShow,
    registerOnFetchTask,
    fetchTask
  };
});
src/views/fysp/data-product/components/BaseDataProduct.vue
@@ -23,11 +23,11 @@
    </template>
    <template #buttons>
      <CompReportDownloadDialog
        name="问题与整改汇总分析与动态跟踪清单"
        :name="fileName"
        :locations="formSearch.locations"
        :scenetype="formSearch.scenetype"
        :time="formSearch.time"
        @submit="handleSearch"
        @submit="(e) => handleSearch(e, true)"
      ></CompReportDownloadDialog>
    </template>
  </FYSearchBar>
@@ -57,27 +57,27 @@
      <el-table-column
        v-for="(item, index) in activeExcelData.head"
        :key="index"
        :prop="item.name"
        :prop="item.prop"
        :label="item.name"
      >
        <template v-if="item.children" #default="{ row }">
          <span v-html="row[item.name]"></span>
          <span v-html="row[item.prop]"></span>
          <el-table-column
            v-for="(item1, index1) in item.children"
            :key="index1"
            :prop="item1.name"
            :prop="item1.prop"
            :label="item1.name"
          >
            <template v-if="item1.children" #default="scope1">
              <span v-html="scope1.row[item1.name]"></span>
              <span v-html="scope1.row[item1.prop]"></span>
              <el-table-column
                v-for="(item2, index2) in item1.children"
                :key="index2"
                :prop="item2.name"
                :prop="item2.prop"
                :label="item2.name"
              >
                <template v-if="item2.children" #default="scope2">
                  <span v-html="scope2.row[item2.name]"></span>
                  <span v-html="scope2.row[item2.prop]"></span>
                </template>
              </el-table-column>
            </template>
@@ -102,12 +102,16 @@
//引入相关样式
import '@vue-office/excel/lib/index.css';
import { ref, onMounted } from 'vue';
import { ref, onMounted, computed } from 'vue';
import dayjs from 'dayjs';
import * as XLSX from 'xlsx';
import * as ExcelJS from 'exceljs';
import dataproductApi from '@/api/fysp/dataproductApi';
import CompReportDownloadDialog from './CompReportDownloadDialog.vue';
import { Base64 } from 'js-base64';
import { useBgtaskStore } from '@/stores/bgtaskStore';
const bgtaskStore = useBgtaskStore();
const emit = defineEmits(['search']);
@@ -125,6 +129,19 @@
  headNum: {
    type: Number,
    default: 1
  }
});
const fileName = computed(() => {
  switch (props.productType) {
    case 1:
      return '问题与整改汇总分析与动态跟踪清单';
    case 2:
      return '规范性评估与分析清单';
    case 3:
      return '问题与整改分布分析清单';
    default:
      return '报告清单';
  }
});
@@ -158,7 +175,7 @@
  getTable(activeSheet.value);
}
function handleSearch(forceUpdate) {
function handleSearch(forceUpdate, isDownload) {
  const locations = formSearch.value.locations;
  const time = formSearch.value.time;
  const scenetype = formSearch.value.scenetype;
@@ -178,13 +195,29 @@
  dataproductApi
    .downloadProduct(area, props.productType, forceUpdate ? forceUpdate : false)
    .then(async (res) => {
      // const data = new Uint8Array(res);
      res.arrayBuffer().then((data) => {
      if (res == false) {
        alert('报告生成中,可在后台任务查看生成进度');
        bgtaskStore.dialogShow = true;
        bgtaskStore.fetchTask();
      } else {
        if (isDownload) {
          const name = Base64.decode(res.headers.get('filename'));
          const url = window.URL.createObjectURL(res.data);
          const link = document.createElement('a');
          link.href = url;
          link.setAttribute('download', name);
          document.body.appendChild(link);
          link.click();
          document.body.removeChild(link);
          window.URL.revokeObjectURL(url);
        } else {
          res.data.arrayBuffer().then((data) => {
        workbook = XLSX.read(data, { type: 'array' });
        sheetNames.value = workbook.SheetNames;
        activeSheet.value = sheetNames.value[0];
        getTable(activeSheet.value);
      });
        }
      // const workbook = new ExcelJS.Workbook();
      // await workbook.xlsx.load(res);
@@ -202,6 +235,7 @@
      // })
      // excel.value = new ArrayBuffer(res)
      }
    })
    .finally(() => (loading.value = false));
}
@@ -229,7 +263,7 @@
    // console.log(tableData);
    const t = strToTableObj(tableData);
    console.log(t);
    // console.log(t);
    // console.log(head);
    // console.log(data);
    excelDatas.value.set(sheetName, t);
@@ -296,14 +330,17 @@
    const row = rows[i];
    if (lastHead.length == 0) {
      row.forEach((r, y) => {
        lastHead.push({ name: r });
        dataKeys.push(r);
        const prop = r == '' ? r : `id-${r}-${y}`;
        lastHead.push({ name: r, prop });
        dataKeys.push(prop);
      });
    } else {
      const newHead = [];
      row.forEach((r, y) => {
        const prop = `id-${r}-${y}`;
        if (dataKeys[y] == '') {
          dataKeys[y] = r;
          // lastHead[y] = { name: r, prop };
          dataKeys[y] = prop;
        }
        const last = lastHead[y];
@@ -311,7 +348,7 @@
          console.log(last);
        }
        if (last.name == '') {
          newHead.push({ name: r });
          newHead.push({ name: r, prop });
          offset++;
        } else if (r != '') {
          newHead.push({
@@ -320,7 +357,7 @@
          });
          offset = 1;
        } else {
          newHead.push({ name: '' });
          newHead.push({ name: '', prop });
          let _index = newHead.length - 1 - offset;
          _index = _index >= 0 ? _index : 0;
          newHead[_index].children.push(last);