riku
2025-08-01 5efcf83a4a67bf5cefbee480c58a697553f9f8de
新增问题复发清清单界面
已修改7个文件
已添加1个文件
231 ■■■■■ 文件已修改
src/api/fysp/dataproductApi.js 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/index.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components.d.ts 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/search-option/FYOptionTime.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/table/FYTable.vue 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/constants/menu.js 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.js 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/fysp/data-product/base-data-product/PordProblemRecurrence.vue 156 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/fysp/dataproductApi.js
@@ -18,7 +18,7 @@
        }
        // æ–‡æ¡£å·²å­˜åœ¨ï¼Œè¿”回文件数据流
        else {
          return res
          return res;
          // const name = Base64.decode(res.headers.get('filename'));
          // const url = window.URL.createObjectURL(res.data);
          // const link = document.createElement('a');
@@ -30,5 +30,23 @@
          // window.URL.revokeObjectURL(url);
        }
      });
  },
  /**
   * èŽ·å–é—®é¢˜æ•´æ”¹æ¸…å•
   */
  fetchProbChangeList(option) {
    return $fysp.post(`dataProduct/problemChange?`, option).then((res) => {
      return res.data;
    });
  },
  /**
   * èŽ·å–é—®é¢˜å¤å‘æ¸…å•
   */
  fetchProbRecurrence(option) {
    return $fysp.post(`dataProduct/problemRecurrence?`, option).then((res) => {
      return res.data;
    });
  }
};
src/api/index.js
@@ -1,7 +1,7 @@
import axios from 'axios';
import { ElMessage } from 'element-plus';
const debug = false;
const debug = true;
// let ip1 = 'http://47.100.191.150:9005/';
// let ip1_file = 'http://47.100.191.150:9005/';
src/components.d.ts
@@ -20,6 +20,7 @@
    ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb']
    ElBreadcrumbItem: typeof import('element-plus/es')['ElBreadcrumbItem']
    ElButton: typeof import('element-plus/es')['ElButton']
    ElButtonGroup: typeof import('element-plus/es')['ElButtonGroup']
    ElCalendar: typeof import('element-plus/es')['ElCalendar']
    ElCard: typeof import('element-plus/es')['ElCard']
    ElCascader: typeof import('element-plus/es')['ElCascader']
@@ -36,6 +37,9 @@
    ElDialog: typeof import('element-plus/es')['ElDialog']
    ElDivider: typeof import('element-plus/es')['ElDivider']
    ElDrawer: typeof import('element-plus/es')['ElDrawer']
    ElDropdown: typeof import('element-plus/es')['ElDropdown']
    ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
    ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu']
    ElEmpty: typeof import('element-plus/es')['ElEmpty']
    ElForm: typeof import('element-plus/es')['ElForm']
    ElFormItem: typeof import('element-plus/es')['ElFormItem']
@@ -51,8 +55,11 @@
    ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
    ElMenuItemGroup: typeof import('element-plus/es')['ElMenuItemGroup']
    ElOption: typeof import('element-plus/es')['ElOption']
    ElPageHeader: typeof import('element-plus/es')['ElPageHeader']
    ElPagination: typeof import('element-plus/es')['ElPagination']
    ElPopconfirm: typeof import('element-plus/es')['ElPopconfirm']
    ElPopover: typeof import('element-plus/es')['ElPopover']
    ElRadio: typeof import('element-plus/es')['ElRadio']
    ElRadioButton: typeof import('element-plus/es')['ElRadioButton']
    ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
    ElRow: typeof import('element-plus/es')['ElRow']
@@ -71,6 +78,7 @@
    ElTag: typeof import('element-plus/es')['ElTag']
    ElText: typeof import('element-plus/es')['ElText']
    ElTooltip: typeof import('element-plus/es')['ElTooltip']
    ElTransfer: typeof import('element-plus/es')['ElTransfer']
    ElTree: typeof import('element-plus/es')['ElTree']
    ElUpload: typeof import('element-plus/es')['ElUpload']
    Footer: typeof import('./components/core/Footer.vue')['default']
src/components/search-option/FYOptionTime.vue
@@ -19,6 +19,7 @@
const MONTH = 'month';
const DATE = 'date';
const RANGE = 'datetimerange';
const RANGE2 = 'daterange';
export default {
  props: {
src/components/table/FYTable.vue
@@ -40,6 +40,7 @@
    :cell-class-name="cellClassName"
    @paste="handlePaste"
    @sort-change="handleSortChange"
    :show-overflow-tooltip="true"
    border
  >
    <slot name="table-column" :size="fontSize"></slot>
@@ -219,7 +220,7 @@
  mounted() {
    this.tableHeight = this.calcTableHeight();
    this.onSearch();
  }
  },
};
</script>
src/constants/menu.js
@@ -47,20 +47,25 @@
    icon: 'DataAnalysis',
    name: '基础数据产品',
    children: [
      // {
      //   path: '/fysp/data-product/base/ProdScenseInfo',
      //   icon: 'Document',
      //   name: '场景清单',
      // },
      // {
      //   path: '/fysp/data-product/base/ProdMonitorTaskInfo',
      //   icon: 'Document',
      //   name: '监管清单',
      // },
      // {
      //   path: '/fysp/data-product/base/ProdTreatmentDeviceInfo',
      //   icon: 'Document',
      //   name: '防治设备清单',
      // },
      {
        path: '/fysp/data-product/ProdScenseInfo',
        path: '/fysp/data-product/base/PordProblemRecurrence',
        icon: 'Document',
        name: '场景清单',
      },
      {
        path: '/fysp/data-product/ProdMonitorTaskInfo',
        icon: 'Document',
        name: '监管清单',
      },
      {
        path: '/fysp/data-product/ProdTreatmentDeviceInfo',
        icon: 'Document',
        name: '防治设备清单',
        name: '问题复发清单',
      },
    ]
  },
src/router/index.js
@@ -170,21 +170,27 @@
  {
    // åŸºç¡€äº§å“-场景清单
    name: 'ProdScenseInfo',
    path: '/fysp/data-product/ProdScenseInfo',
    path: '/fysp/data-product/base/ProdScenseInfo',
    component: () => import('@/views/fysp/data-product/base-data-product/ProdScenseInfo.vue')
  },
  {
    // åŸºç¡€äº§å“-监管清单
    name: 'ProdMonitorTaskInfo',
    path: '/fysp/data-product/ProdMonitorTaskInfo',
    path: '/fysp/data-product/base/ProdMonitorTaskInfo',
    component: () => import('@/views/fysp/data-product/base-data-product/ProdMonitorTaskInfo.vue')
  },
  {
    // åŸºç¡€äº§å“-防治设备清单
    name: 'ProdTreatmentDeviceInfo',
    path: '/fysp/data-product/ProdTreatmentDeviceInfo',
    path: '/fysp/data-product/base/ProdTreatmentDeviceInfo',
    component: () => import('@/views/fysp/data-product/base-data-product/ProdTreatmentDeviceInfo.vue')
  },
  {
    // åŸºç¡€äº§å“-问题复发清单
    name: 'PordProblemRecurrence',
    path: '/fysp/data-product/base/PordProblemRecurrence',
    component: () => import('@/views/fysp/data-product/base-data-product/PordProblemRecurrence.vue')
  },
  /**********************************飞羽环境***********************************************/
  {
src/views/fysp/data-product/base-data-product/PordProblemRecurrence.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,156 @@
<template>
  <FYTable
    @search="onSearch"
    :data="showData"
    :pagination="false"
    ref="tableRef"
  >
    <template #options>
      <!-- åŒºåŽ¿ -->
      <FYOptionLocation
        :allOption="false"
        :level="3"
        :checkStrictly="false"
        v-model:value="formSearch.locations"
      ></FYOptionLocation>
      <!-- åœºæ™¯ç±»åž‹ -->
      <FYOptionScene
        :allOption="false"
        :type="2"
        v-model:value="formSearch.scenetype"
      ></FYOptionScene>
      <!-- æ—¶é—´ -->
      <FYOptionTime
        :initValue="false"
        type="daterange"
        v-model:value="formSearch.timeArr"
        style="width: 300px"
      ></FYOptionTime>
    </template>
    <template #options-expand>
      <el-radio-group v-model="radio">
        <el-radio :value="1">按问题名称统计</el-radio>
        <el-radio :value="2">按问题类型统计</el-radio>
      </el-radio-group>
    </template>
    <template #buttons> </template>
    <template #table-column="{ size }">
      <!-- <el-table-column fixed="left" label="序号" width="53">
        <template #default="{ row }">
          {{ row.index + 1 }}
        </template>
      </el-table-column> -->
      <el-table-column fixed="left" label="唯一编号" width="90" prop="index">
      </el-table-column>
      <el-table-column
        prop="sceneName"
        :show-overflow-tooltip="true"
        label="名称"
      >
      </el-table-column>
      <el-table-column prop="sceneType" label="类型" width="60" />
      <!-- <el-table-column prop="provinceName" label="省份" width="90">
      </el-table-column>
      <el-table-column prop="cityName" label="城市" width="90">
      </el-table-column> -->
      <el-table-column prop="districtName" label="区县" width="90">
      </el-table-column>
      <el-table-column prop="townName" label="街镇" width="110">
      </el-table-column>
      <el-table-column prop="problemType" label="问题类型" width="110">
      </el-table-column>
      <el-table-column
        v-if="radio == 1"
        prop="problemName"
        label="问题名称"
        width="200"
      >
      </el-table-column>
      <el-table-column prop="proNum" label="问题数" width="70">
      </el-table-column>
      <el-table-column prop="changeNum" label="整改数" width="70">
      </el-table-column>
    </template>
  </FYTable>
</template>
<script setup>
import { ref, computed } from 'vue';
import dayjs from 'dayjs';
import dataproductApi from '@/api/fysp/dataproductApi.js';
const radio = ref(1);
const tableRef = ref(null);
const tableData = ref([]);
const formSearch = ref({
  locations: {},
  scenetype: {},
  timeArr: [dayjs().add(-1, 'M').date(1).toDate(), dayjs().toDate()]
});
const option = computed(() => {
  const { locations, scenetype, timeArr } = formSearch.value;
  return {
    provinceCode: locations.pCode,
    cityCode: locations.cCode,
    districtCode: locations.dCode,
    townCode: locations.tCode,
    startTime: dayjs(timeArr[0]).format('YYYY-MM-DD HH:mm:ss'),
    endTime: dayjs(timeArr[1])
      .hour(23)
      .minute(59)
      .second(59)
      .format('YYYY-MM-DD HH:mm:ss'),
    sceneTypeId: scenetype.value
  };
});
const showData = computed(() => {
  let res = [];
  switch (radio.value) {
    case 1:
      res = tableData.value;
      break;
    case 2:
      tableData.value.forEach((tb) => {
        const r = res.find((v) => {
          return v.sceneName == tb.sceneName && v.problemType == tb.problemType;
        });
        if (r == undefined) {
          res.push({ ...tb });
        } else {
          r.proNum += tb.proNum;
          r.changeNum += tb.changeNum;
        }
      });
      break;
    default:
      res = tableData.value;
      break;
  }
  if (tableRef.value) {
    tableRef.value.doLayout();
  }
  return res;
});
function onSearch(page, callback) {
  fetchProbRecurrence().finally(() => callback());
}
function fetchProbRecurrence() {
  return dataproductApi.fetchProbRecurrence(option.value).then((res) => {
    tableData.value = res.data;
  });
}
// function handleChange(value) {
//   switch (value) {
//     case 1:
//       break;
//     case 2:
//       break;
//     default:
//       break;
//   }
// }
</script>