Riku
2025-07-13 2e2fe3dcf3f68ad8d18b07eefd8b862cabf44f42
1. 新增联合执法清单界面
已修改3个文件
已添加1个文件
388 ■■■■■ 文件已修改
src/components.d.ts 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/constants/menu.js 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.js 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/fysp/data-product/ProdLawEnforceList.vue 362 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components.d.ts
@@ -13,19 +13,15 @@
    CompGenericWrapper: typeof import('./components/CompGenericWrapper.vue')['default']
    CompQuickSet: typeof import('./components/search-option/CompQuickSet.vue')['default']
    Content: typeof import('./components/core/Content.vue')['default']
    ElAffix: typeof import('element-plus/es')['ElAffix']
    ElAside: typeof import('element-plus/es')['ElAside']
    ElAvatar: typeof import('element-plus/es')['ElAvatar']
    ElBadge: typeof import('element-plus/es')['ElBadge']
    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']
    ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
    ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
    ElCol: typeof import('element-plus/es')['ElCol']
    ElCollapse: typeof import('element-plus/es')['ElCollapse']
    ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
@@ -37,9 +33,6 @@
    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']
@@ -49,17 +42,13 @@
    ElImageViewer: typeof import('element-plus/es')['ElImageViewer']
    ElInput: typeof import('element-plus/es')['ElInput']
    ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
    ElLink: typeof import('element-plus/es')['ElLink']
    ElMain: typeof import('element-plus/es')['ElMain']
    ElMenu: typeof import('element-plus/es')['ElMenu']
    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']
@@ -78,7 +67,6 @@
    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/constants/menu.js
@@ -87,7 +87,13 @@
        path: '/fysp/data-product/dailyreport',
        icon: 'Document',
        name: '日报管理'
      }
      },
      {
        path: '/fysp/data-product/lawenforcelist',
        icon: 'Document',
        name: '联合执法清单'
      },
    ]
  },
  {
src/router/index.js
@@ -41,6 +41,12 @@
    path: '/fysp/data-product/scenereport',
    component: () => import('@/views/fysp/data-product/ProdSceneReport.vue')
  },
  {
    //场景报告
    name: 'lawenforcelist',
    path: '/fysp/data-product/lawenforcelist',
    component: () => import('@/views/fysp/data-product/ProdLawEnforceList.vue')
  },
  // {
  //   //场景报告-工地
  //   name: 'construction',
src/views/fysp/data-product/ProdLawEnforceList.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,362 @@
<template>
  <FYTable
    @search="onSearch"
    :pagination="false"
    ref="tableRef"
    @cell-click="cellClick"
    :cell-class-name="cellClassName"
    @table-paste="handlePaste"
    @sort-change="handleSortChange"
  >
    <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="month"
        v-model:value="formSearch.time"
      ></FYOptionTime>
    </template>
    <template #options-expand>
      <el-form :inline="true">
        <CompQuickSet @quick-set="setOptions"></CompQuickSet>
      </el-form>
      <el-descriptions v-if="this.tableData.length > 0" title="" :column="1" direction="vertical" border>
        <el-descriptions-item label="联合执法清单">
          {{ listSummary }}
        </el-descriptions-item>
      </el-descriptions>
    </template>
    <template #table-column="{ size }">
      <el-table-column fixed="left" label="序号" width="80">
        <template #default="{ row }">
          {{ row.index + 1 }}
        </template>
      </el-table-column>
      <el-table-column
        prop="sceneName"
        :show-overflow-tooltip="true"
        label="名称"
        width="300"
      >
      </el-table-column>
      <!-- <el-table-column
          prop="subTaskTime"
          label="巡查日期"
          width="110"
          sortable="custom"
          :formatter="timeFormat"
        /> -->
      <!-- <el-table-column
        prop="evaluation.resultscorebef"
        label="得分"
        width="90"
        sortable="custom"
      /> -->
      <!-- <el-table-column
          prop="evaluation.resultscorebef"
          label="环信码"
          width="100"
        >
          <template #default="{ row }">
            <span :style="`color: ${toCode(row).color};`">{{
              toCode(row).name
            }}</span>
          </template>
        </el-table-column> -->
      <el-table-column prop="dname" label="区县" width="90" />
      <el-table-column
        prop="tname"
        label="街道"
        width="110"
        :filters="townFilters"
        :filter-method="filterHandler"
      />
      <el-table-column prop="evaluation.scenseaddress" label="地址" />
      <!-- <el-table-column prop="biArea" label="集中区" width="110" />
        <el-table-column prop="biManagementCompany" label="物业" min-width="110"/> -->
      <!-- <el-table-column fixed="right" align="right" label="操作" width="160">
          <template #default="{ row }">
            <el-button type="primary" size="small" @click="editRow(row)"
              >查看</el-button
            >
          </template>
        </el-table-column> -->
    </template>
  </FYTable>
</template>
<script>
/**
 * è”合执法清单
 */
import dayjs from 'dayjs';
import evaluateApi from '@/api/fysp/evaluateApi';
import { envCreditCode } from '@/constants/index';
import { useTablePaste } from '@/composables/tablePaste';
import { useCloned } from '@vueuse/core';
import { useMessageBoxTip } from '@/composables/messageBox';
export default {
  setup() {
    const {
      cellClick,
      cellClassName,
      handlePaste,
      setTableData,
      addRefreshEvent,
      tableData
    } = useTablePaste({
      score1: 8,
      score2: 9
    });
    return {
      cellClick,
      cellClassName,
      handlePaste,
      setTableData,
      addRefreshEvent,
      tableData
    };
  },
  data() {
    return {
      formSearch: {
        locations: {},
        scenetype: {},
        time: dayjs().add(-1, 'M').date(1).toDate()
      },
      townFilters: [],
      // åŽŸå§‹æ•°æ®ï¼Œç”¨äºŽæŽ’åºå–æ¶ˆåŽ
      orginData: [],
      evaluationRule: undefined,
      evaluationSubRule: undefined,
      //监测数据规则名称
      ruleName: {
        score1: {
          id: undefined,
          name: '监测数据出现单日及以上有效超标'
        },
        score2: {
          id: undefined,
          name: '监测数据月均值超区域月均值20%以上或数据明显异常'
        }
      },
      updateLoading: false
    };
  },
  computed: {
    area() {
      const { locations, scenetype, time } = this.formSearch;
      return {
        provincecode: locations.pCode,
        provincename: locations.pName,
        citycode: locations.cCode,
        cityname: locations.cName,
        districtcode: locations.dCode,
        districtname: locations.dName,
        starttime: dayjs(time).format('YYYY-MM-DD HH:mm:ss'),
        scensetypeid: scenetype.value
      };
    },
    listSummary() {
      if (this.tableData.length > 0) {
        const { locations, scenetype, time } = this.formSearch;
        return `根据${locations.dName}${dayjs(time).format(
          'YYYYå¹´MM月'
        )}的现场整改情况以及自动评分结果,并结合历史巡查记录,得出以下综合得分最差的10å®¶${
          scenetype.label
        }作为联合执法备选清单。`;
      } else {
        return ``;
      }
    }
  },
  methods: {
    // _getParam() {
    //   const { locations, scenetype, time } = this.formSearch;
    //   return {
    //     provincecode: locations.pCode,
    //     provincename: locations.pName,
    //     citycode: locations.cCode,
    //     cityname: locations.cName,
    //     districtcode: locations.dCode,
    //     districtname: locations.dName,
    //     starttime: dayjs(time).format('YYYY-MM-DD HH:mm:ss'),
    //     scensetypeid: scenetype.value
    //   };
    // },
    editRow(row) {
      this.$router.push(`evalutationEdit/${row.subTaskId}`);
    },
    setOptions(param) {
      this.formSearch.locations = param.locations;
      this.formSearch.scenetype = param.scenetype;
      this.formSearch.sourceType = param.sourceType;
      this.$refs.tableRef.onSearch();
    },
    onSearch(page, func) {
      this.$refs.tableRef.clearSort();
      this.fetchEvaluationRule(this.area).then(() => {
        evaluateApi.fetchAutoEvaluation(this.area).then((res) => {
          if (res.data) {
            this.tableData = res.data
              .filter((d) => {
                return d.evaluation != null;
              })
              .slice(0, 10);
            this.tableData.sort((a, b) => {
              const s1 = a.evaluation
                ? parseInt(a.evaluation.resultscorebef)
                : 0;
              const s2 = b.evaluation
                ? parseInt(b.evaluation.resultscorebef)
                : 0;
              return s1 - s2;
            });
            this.orginData = useCloned(this.tableData).cloned;
            this.getFilters(res.data);
            if (typeof func === 'function') {
              func({ data: this.tableData });
            }
          } else {
            this.tableData = [];
            this.orginData = [];
            if (typeof func === 'function') {
              func({ data: this.tableData });
            }
          }
        });
      });
    },
    fetchEvaluationRule() {
      const param = {
        // è‡ªåŠ¨è¯„ä¼°ç±»åž‹
        taskTypeId: 99,
        ...this.area
      };
      // èŽ·å–è¯„ä¼°æ€»è§„åˆ™
      return evaluateApi.fetchEvaluationRule(param).then((res) => {
        if (res.data.length > 0) {
          this.evaluationRule = res.data[0];
          // èŽ·å–å…·ä½“å­è§„åˆ™
          return evaluateApi
            .getSubRules(this.evaluationRule.guid)
            .then((res) => {
              this.evaluationSubRule = res.data;
              // æŸ¥æ‰¾å¯å¯¼å…¥å¾—分的规则id
              for (const key in this.ruleName) {
                const value = this.ruleName[key];
                const subrule = this.evaluationSubRule.find((v) => {
                  return v.itemname == value.name;
                });
                if (subrule) {
                  value.id = subrule.guid;
                }
              }
            });
        }
      });
    },
    getFilters(data) {
      const townList = [];
      data.forEach((e) => {
        if (townList.indexOf(e.tname) == -1) {
          townList.push(e.tname);
        }
      });
      this.townFilters = townList.map((v) => {
        return { text: v, value: v };
      });
    },
    toCode(row, column) {
      if (row.evaluation) {
        return envCreditCode(row.evaluation.resultscorebef);
      } else {
        return '';
      }
    },
    timeFormat(row, column) {
      const time = row.subTaskTime;
      if (time) {
        return dayjs(time).format('MM-DD');
      } else {
        return '';
      }
    },
    filterHandler(value, row, column) {
      const property = column['property'];
      return row[property] === value;
    },
    sortScore(a, b) {
      const s1 = a.evaluation ? parseInt(a.evaluation.resultscorebef) : 0;
      const s2 = b.evaluation ? parseInt(b.evaluation.resultscorebef) : 0;
      return s1 - s2;
    },
    handleSortChange({ column, prop, order }) {
      console.log(column, prop, order);
      if (order == null) {
        this.orginData.forEach((e, i) => {
          this.tableData[i] = e;
        });
      } else if (prop == 'evaluation.resultscorebef') {
        this.tableData.sort((a, b) => {
          const s1 = a.evaluation ? parseInt(a.evaluation.resultscorebef) : 0;
          const s2 = b.evaluation ? parseInt(b.evaluation.resultscorebef) : 0;
          if (order == 'ascending') {
            return s1 - s2;
          } else if (order == 'descending') {
            return s2 - s1;
          }
        });
      } else if (prop == 'sceneIndex') {
        this.tableData.sort((a, b) => {
          if (order == 'ascending') {
            if (a.sceneIndex === b.sceneIndex) {
              return a.subTaskTime > b.subTaskTime ? 1 : -1;
            } else {
              return a.sceneIndex - b.sceneIndex;
            }
          } else if (order == 'descending') {
            if (a.sceneIndex === b.sceneIndex) {
              return b.subTaskTime > a.subTaskTime ? 1 : -1;
            } else {
              return b.sceneIndex - a.sceneIndex;
            }
          }
        });
      } else if (prop == 'subTaskTime') {
        this.tableData.sort((a, b) => {
          if (order == 'ascending') {
            return a[prop] > b[prop] ? 1 : -1;
            // return dayjs(a).isAfter(dayjs(b)) ? 1 : -1;
          } else if (order == 'descending') {
            return b[prop] > a[prop] ? 1 : -1;
            // return dayjs(b).isAfter(dayjs(a)) ? 1 : -1;
          }
        });
      }
    }
  },
  mounted() {
    this.addRefreshEvent(this.$refs.tableRef.doLayout);
  }
};
</script>
<style scoped></style>