xyc
5 天以前 9e82f0464bb28474f1d9fe6aeb25365d2d66c802
traffic-audit-web/src/views/ExplainReview.vue
@@ -12,37 +12,47 @@
          <el-menu-item index="/report">报表生成</el-menu-item>
          <el-menu-item index="/rules">规则管理</el-menu-item>
          <el-menu-item index="/users">用户管理</el-menu-item>
        </el-menu>
</el-menu>
      </el-aside>
      <el-main>
        <h3>企业解释</h3>
        <el-form :inline="true">
        <el-form :inline="true" @submit.native.prevent>
          <el-form-item label="报表类型">
            <el-select v-model="reportType" style="width:190px" @change="onTypeChange">
              <el-option label="货运(H203-2)" value="H2032"></el-option>
              <el-option label="公路旅客(H203-1)" value="H2031"></el-option>
              <el-option label="城市公交(CITY_BUS)" value="CITY_BUS"></el-option>
              <el-option label="巡游出租(CITY_TAXI)" value="CITY_TAXI"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="报表期">
            <el-date-picker v-model="period" type="month" placeholder="全部" value-format="yyyy-MM" clearable style="width:140px" @change="loadData"></el-date-picker>
          </el-form-item>
          <el-form-item label="企业名称">
            <el-input v-model="keyword" placeholder="输入企业名称关键字" clearable style="width:220px" @keyup.enter.native="loadData"></el-input>
          <el-form-item :label="keywordLabel">
            <el-input v-model="keyword" :placeholder="keywordPlaceholder" clearable style="width:220px" @keyup.enter.native="loadData"></el-input>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="loadData">查询</el-button>
          </el-form-item>
          <el-form-item label="仅显示已填写">
            <el-switch v-model="hasExplanation" @change="onFilterChange"></el-switch>
          </el-form-item>
          <el-form-item>
            <span style="color:#909399;font-size:12px">共 {{ total }} 条解释</span>
            <span style="color:#909399;font-size:12px">共 {{ total }} 条记录<template v-if="hasExplanation">(已填写解释)</template></span>
          </el-form-item>
        </el-form>
        <div class="table-area">
        <el-table :data="records" border v-loading="loading" size="small" style="width:100%" height="100%">
          <el-table-column prop="reportPeriod" label="报表期" width="100"></el-table-column>
          <el-table-column prop="regionCode" label="所属地区" width="100"></el-table-column>
          <el-table-column prop="enterpriseCode" label="企业代码" min-width="140" show-overflow-tooltip></el-table-column>
          <el-table-column prop="enterpriseName" label="企业名称" min-width="200" show-overflow-tooltip></el-table-column>
          <el-table-column prop="vehicleTotal" label="车辆数" width="90"></el-table-column>
          <el-table-column prop="tonsTotal" label="吨位" width="100"></el-table-column>
          <el-table-column prop="freightTotal" label="货运量" width="110"></el-table-column>
          <el-table-column prop="turnoverTotal" label="周转量" width="120"></el-table-column>
          <el-table-column prop="avgDistance" label="平均运距" width="100"></el-table-column>
          <el-table-column prop="verifyExplanation" label="企业解释" min-width="280" show-overflow-tooltip></el-table-column>
          <el-table-column label="操作" width="100" fixed="right">
        <el-table :data="records" border v-loading="loading" size="mini" :row-style="{ height: '32px' }" style="width:100%" height="100%">
          <el-table-column v-for="col in columns" :key="col.prop" v-bind="col">
            <template slot-scope="scope">
              <template v-if="col.prop === 'verifyExplanation'">
                <span v-if="scope.row.verifyExplanation" class="expl-text">{{ scope.row.verifyExplanation }}</span>
                <el-tag v-else size="mini" type="warning" effect="plain">未填写</el-tag>
              </template>
              <span v-else>{{ scope.row[col.prop] }}</span>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="110" fixed="right">
            <template slot-scope="scope">
              <el-button size="mini" type="primary" @click="analyze(scope.row)">AI 分析</el-button>
            </template>
@@ -64,22 +74,87 @@
import AppHeader from '@/components/AppHeader.vue'
import api from '@/api'
import AiChatDialog from '@/components/AiChatDialog'
const COLS = {
  H2032: [
    { prop: 'reportPeriod', label: '报表期', width: 100 },
    { prop: 'regionCode', label: '所属地区', width: 100 },
    { prop: 'enterpriseCode', label: '企业代码', minWidth: 140, showOverflowTooltip: true },
    { prop: 'enterpriseName', label: '企业名称', minWidth: 200, showOverflowTooltip: true },
    { prop: 'vehicleTotal', label: '车辆数', width: 90 },
    { prop: 'tonsTotal', label: '吨位', width: 100 },
    { prop: 'freightTotal', label: '货运量(吨)', width: 110 },
    { prop: 'turnoverTotal', label: '周转量(吨公里)', width: 130 },
    { prop: 'avgDistance', label: '平均运距(公里)', width: 120 },
    { prop: 'verifyExplanation', label: '企业解释', minWidth: 260, showOverflowTooltip: true }
  ],
  H2031: [
    { prop: 'reportPeriod', label: '报表期', width: 100 },
    { prop: 'regionCode', label: '所属地区', width: 100 },
    { prop: 'enterpriseCode', label: '企业代码', minWidth: 140, showOverflowTooltip: true },
    { prop: 'enterpriseName', label: '企业名称', minWidth: 200, showOverflowTooltip: true },
    { prop: 'vehicleTotal', label: '车辆数', width: 90 },
    { prop: 'seatTotal', label: '载客位数', width: 100 },
    { prop: 'passengerTotal', label: '客运量(万人)', width: 110 },
    { prop: 'turnoverTotal', label: '周转量(万人公里)', width: 130 },
    { prop: 'avgDistance', label: '平均运距(公里)', width: 120 },
    { prop: 'verifyExplanation', label: '企业解释', minWidth: 260, showOverflowTooltip: true }
  ],
  CITY_BUS: [
    { prop: 'reportPeriod', label: '报表期', width: 100 },
    { prop: 'regionCode', label: '所属地区', width: 100 },
    { prop: 'city', label: '市州', width: 100 },
    { prop: 'enterpriseName', label: '企业名称', minWidth: 220, showOverflowTooltip: true },
    { prop: 'opVehicles', label: '运营车数', width: 90 },
    { prop: 'passengerVolume', label: '客运量(万人次)', width: 120 },
    { prop: 'turnover', label: '周转量(万人公里)', width: 130 },
    { prop: 'avgDistance', label: '平均运距(公里)', width: 120 },
    { prop: 'verifyExplanation', label: '企业解释', minWidth: 260, showOverflowTooltip: true }
  ],
  CITY_TAXI: [
    { prop: 'reportPeriod', label: '报表期', width: 100 },
    { prop: 'regionCode', label: '所属地区', width: 100 },
    { prop: 'city', label: '市州', width: 110 },
    { prop: 'tripTotal', label: '载客车次总数', width: 110 },
    { prop: 'passengerVolume', label: '客运量(万人次)', width: 120 },
    { prop: 'turnover', label: '周转量(万人公里)', width: 130 },
    { prop: 'opVehicles', label: '运营车辆数', width: 100 },
    { prop: 'avgDistance', label: '平均运距(公里)', width: 120 },
    { prop: 'verifyExplanation', label: '企业解释', minWidth: 260, showOverflowTooltip: true }
  ]
}
const TABLE_NAME = {
  H2032: 'h2032_enterprise_monthly',
  H2031: 'h2031_enterprise_monthly',
  CITY_BUS: 'city_bus_monthly',
  CITY_TAXI: 'city_taxi_monthly'
}
export default {
  components: { AppHeader },
  name: 'ExplainReview',
  components: { AppHeader, AiChatDialog },
  components: { AiChatDialog },
  data() {
    return {
      period: '', keyword: '', page: 1, size: 20, total: 0, records: [], loading: false,
      reportType: 'H2032',
      period: '', keyword: '', hasExplanation: false, page: 1, size: 20, total: 0, records: [], loading: false,
      chatVisible: false, chatContext: {}
    }
  },
  computed: {
    columns() { return COLS[this.reportType] || COLS.H2032 },
    keywordLabel() { return this.reportType === 'CITY_TAXI' ? '市州名称' : '企业名称' },
    keywordPlaceholder() { return this.reportType === 'CITY_TAXI' ? '输入市州名称关键字' : '输入企业名称关键字' }
  },
  methods: {
    onTypeChange() { this.page = 1; this.loadData() },
    onFilterChange() { this.page = 1; this.loadData() },
    loadData() {
      this.loading = true
      api.get('/explain/list', {
        params: {
          reportType: this.reportType,
          period: this.period || undefined,
          keyword: this.keyword || undefined,
          hasExplanation: this.hasExplanation || undefined,
          page: this.page,
          size: this.size
        }
@@ -103,16 +178,26 @@
      this.chatContext = {
        reportId: row.id,
        reportPeriod: row.reportPeriod || this.period,
        enterpriseName: row.enterpriseName || '',
        verifyExplanation: explanation
        enterpriseName: row.enterpriseName || row.city || '',
        verifyExplanation: explanation,
        reportType: this.reportType,
        tableName: TABLE_NAME[this.reportType] || ''
      }
      this.chatVisible = true
    }
  },
  mounted() {
    const q = this.$route.query
    if (q.reportType && COLS[q.reportType]) this.reportType = q.reportType
    if (q.period) this.period = q.period
    if (q.keyword) this.keyword = q.keyword
    this.loadData()
  }
}
</script>
<style scoped>
</style>
.el-header { background: #409EFF; color: white; line-height: 60px; font-size: 18px; }
.el-table td { padding: 3px 0; }
.el-table th { padding: 4px 0; }
.expl-text { display: inline-block; max-height: 62px; overflow-y: auto; white-space: pre-wrap; word-break: break-all; line-height: 1.4; }
</style>