فهرست منبع

Merge remote-tracking branch 'origin/master'

zzw 1 ماه پیش
والد
کامیت
a022c1dfcd

+ 760 - 30
src/views/costAudit/auditInfo/auditManage/costSurvey.vue

@@ -1,51 +1,781 @@
 <template>
 <template>
   <div>
   <div>
-    <!-- 成本调查表内容 -->
-    <el-table border :data="surveyData.list" style="width: 100%">
+    <!-- 调查表填报弹窗(单记录类型,只读) -->
+    <survey-form-dialog
+      :visible.sync="surveyFormDialogVisible"
+      :survey-data="{ ...currentSurveyRow, ...surveyDetailData }"
+      :form-fields="formFields"
+      :is-view-mode="true"
+      :audited-unit-id="auditedUnitId"
+      :upload-id="
+        currentSurveyRow && currentSurveyRow.id ? currentSurveyRow.id : uploadId
+      "
+      :survey-template-id="
+        currentSurveyRow && currentSurveyRow.surveyTemplateId
+          ? currentSurveyRow.surveyTemplateId
+          : surveyTemplateId
+      "
+      :catalog-id="catalogId"
+      @save="noop"
+      @refresh="noop"
+    />
+
+    <!-- 固定表填报弹窗(只读) -->
+    <fixed-table-dialog
+      :visible.sync="fixedTableDialogVisible"
+      :survey-data="{ ...currentSurveyRow, fixedHeaders }"
+      :table-items="tableItems"
+      :audit-periods="auditPeriods"
+      :is-view-mode="true"
+      :audited-unit-id="auditedUnitId"
+      :upload-id="
+        currentSurveyRow && currentSurveyRow.id ? currentSurveyRow.id : uploadId
+      "
+      :survey-template-id="
+        currentSurveyRow && currentSurveyRow.surveyTemplateId
+          ? currentSurveyRow.surveyTemplateId
+          : surveyTemplateId
+      "
+      :catalog-id="catalogId"
+      @save="noop"
+      @refresh="noop"
+    />
+
+    <!-- 动态表填报弹窗(只读) -->
+    <dynamic-table-dialog
+      :key="dynamicDialogKey"
+      :visible.sync="dynamicTableDialogVisible"
+      :survey-data="currentSurveyRow"
+      :table-data="dynamicTableData"
+      :table-items="tableItems"
+      :is-view-mode="true"
+      :audited-unit-id="auditedUnitId"
+      :upload-id="
+        currentSurveyRow && (currentSurveyRow.uploadId || currentSurveyRow.id)
+          ? currentSurveyRow.uploadId || currentSurveyRow.id
+          : uploadId
+      "
+      :catalog-id="catalogId"
+      :survey-template-id="
+        currentSurveyRow && currentSurveyRow.surveyTemplateId
+          ? currentSurveyRow.surveyTemplateId
+          : surveyTemplateId
+      "
+      @save="noop"
+      @refresh="noop"
+    />
+
+    <el-table
+      style="width: 100%; margin-top: 20px"
+      :data="paginatedData"
+      border
+      size="medium"
+    >
+      <!-- 序号列 -->
+      <el-table-column prop="index" label="序号" width="60" align="center">
+        <template slot-scope="scope">{{ scope.$index + 1 }}</template>
+      </el-table-column>
+
+      <!-- 成本调查表名称(点击查看) -->
+      <el-table-column label="成本调查表" min-width="220">
+        <template slot-scope="scope">
+          <span
+            :style="{
+              color: scope.row.isDisabled ? '#909399' : '#409EFF',
+              cursor: scope.row.isDisabled ? 'default' : 'pointer',
+            }"
+            @click="!scope.row.isDisabled && handleOnlineFillClick(scope.row)"
+          >
+            {{ scope.row.name }}
+          </span>
+        </template>
+      </el-table-column>
+
+      <!-- 资料类型 -->
       <el-table-column
       <el-table-column
-        prop="index"
-        label="序号"
-        width="80"
+        prop="dataType"
+        label="资料类型"
+        width="120"
         align="center"
         align="center"
-        header-align="center"
-      ></el-table-column>
-      <el-table-column
-        prop="name"
-        label="成本调查表"
-        min-width="200"
-        align="left"
-        header-align="center"
-        show-overflow-tooltip
-      ></el-table-column>
+      />
+
+      <!-- 表格类型 -->
       <el-table-column
       <el-table-column
-        prop="type"
-        label="资料类型"
+        prop="tableType"
+        label="表格类型"
         width="120"
         width="120"
         align="center"
         align="center"
-        header-align="center"
-      ></el-table-column>
+      />
+
+      <!-- 是否必填 -->
       <el-table-column
       <el-table-column
-        prop="required"
+        prop="isRequired"
         label="是否必填"
         label="是否必填"
         width="100"
         width="100"
         align="center"
         align="center"
-        header-align="center"
-      ></el-table-column>
-      <el-table-column
-        label="操作"
-        width="120"
-        align="center"
-        header-align="center"
       >
       >
         <template slot-scope="scope">
         <template slot-scope="scope">
-          <el-button type="text" @click="handleViewTemplate(scope.row)">
-            查看模板
+          <span>
+            {{
+              scope.row.isRequired === '是' ||
+              scope.row.isRequired === '1' ||
+              scope.row.isRequired === 1
+                ? '是'
+                : '否'
+            }}
+          </span>
+        </template>
+      </el-table-column>
+
+      <!-- 是否上传(只读显示) -->
+      <el-table-column label="是否上传" width="100" align="center">
+        <template slot-scope="scope">
+          <span
+            :style="{
+              color: scope.row.isUploaded === true ? '#67c23a' : '#f56c6c',
+            }"
+          >
+            {{ scope.row.isUploaded === true ? '已上传' : '未上传' }}
+          </span>
+        </template>
+      </el-table-column>
+
+      <!-- 操作列(只保留查看) -->
+      <el-table-column label="操作" width="160" align="center">
+        <template slot-scope="scope">
+          <el-button
+            type="text"
+            size="small"
+            @click="handleOnlineFillClick(scope.row)"
+          >
+            查看
           </el-button>
           </el-button>
         </template>
         </template>
       </el-table-column>
       </el-table-column>
     </el-table>
     </el-table>
+
+    <el-pagination
+      background
+      layout="total, sizes, prev, pager, next"
+      :current-page="pagination.currentPage"
+      :page-sizes="[10, 20, 30, 50]"
+      :page-size="pagination.pageSize"
+      :total="pagination.total"
+      style="margin-top: 20px; text-align: right"
+      @current-change="handlePageChange"
+      @size-change="handleSizeChange"
+    />
   </div>
   </div>
 </template>
 </template>
+
 <script>
 <script>
-  export default {}
+  import SurveyFormDialog from '@/views/EntDeclaration/auditTaskManagement/components/SurveyFormDialog.vue'
+  import FixedTableDialog from '@/views/EntDeclaration/auditTaskManagement/components/FixedTableDialog.vue'
+  import DynamicTableDialog from '@/views/EntDeclaration/auditTaskManagement/components/DynamicTableDialog.vue'
+  import {
+    getSingleRecordSurveyList,
+    getSurveyDetail,
+    getDynamicTableData,
+  } from '@/api/audit/survey'
+  import { getListBySurveyTemplateIdAndVersion } from '@/api/costSurveyTemplateHeaders'
+
+  export default {
+    name: 'CostSurveyViewOnly',
+    components: { SurveyFormDialog, FixedTableDialog, DynamicTableDialog },
+    props: {
+      paginatedData: { type: Array, default: () => [] },
+      pagination: {
+        type: Object,
+        default: () => ({ currentPage: 1, pageSize: 10, total: 0 }),
+      },
+      auditedUnitId: { type: String, default: '' },
+      uploadId: { type: String, default: '' },
+      surveyTemplateId: { type: String, default: '' },
+      catalogId: { type: String, default: '' },
+    },
+    data() {
+      return {
+        surveyFormDialogVisible: false,
+        fixedTableDialogVisible: false,
+        dynamicTableDialogVisible: false,
+        currentSurveyRow: null,
+        formFields: [],
+        surveyDetailData: {},
+        tableItems: [],
+        auditPeriods: [],
+        dynamicTableData: [],
+        dynamicDialogKey: 0,
+        dynamicTableLoading: false,
+        fixedHeaders: null,
+      }
+    },
+    methods: {
+      // 查看(只读)
+      async handleOnlineFillClick(row) {
+        this.currentSurveyRow = row
+        this.surveyDetailData = {}
+        if (row.tableType === '单记录') {
+          if (row.id && this.auditedUnitId) {
+            try {
+              const params = {
+                uploadId: row.id,
+                auditedUnitId: this.auditedUnitId,
+              }
+              const res = await getSurveyDetail(params)
+              if (res && res.code === 200 && res.value) {
+                const detailData = {}
+                if (Array.isArray(res.value)) {
+                  res.value.forEach((item) => {
+                    if (item.rowid && item.rvalue !== undefined)
+                      detailData[item.rowid] = item.rvalue
+                  })
+                } else if (res.value) {
+                  Object.assign(detailData, res.value)
+                }
+                this.surveyDetailData = detailData
+              }
+            } catch (err) {}
+          }
+          await this.initFormFields()
+        } else if (row.tableType === '固定表') {
+          await this.initFixedTableData()
+        } else if (row.tableType === '动态表') {
+          this.resetDynamicDialogState()
+          await this.initDynamicTableData()
+        }
+      },
+      handlePageChange(page) {
+        this.$emit('handle-page-change', page)
+      },
+      handleSizeChange(size) {
+        this.$emit('handle-size-change', size)
+      },
+      async initDynamicTableData() {
+        try {
+          this.dynamicTableLoading = true
+          const uploadId =
+            (this.currentSurveyRow &&
+              (this.currentSurveyRow.uploadId || this.currentSurveyRow.id)) ||
+            this.uploadId ||
+            ''
+          const auditedUnitId =
+            this.auditedUnitId ||
+            (this.currentSurveyRow && this.currentSurveyRow.auditedUnitId) ||
+            ''
+          const catalogId =
+            (this.currentSurveyRow && this.currentSurveyRow.catalogId) ||
+            this.catalogId ||
+            ''
+          const surveyTemplateId =
+            (this.currentSurveyRow && this.currentSurveyRow.surveyTemplateId) ||
+            this.surveyTemplateId ||
+            ''
+          const params = {
+            uploadId,
+            auditedUnitId,
+            catalogId,
+            surveyTemplateId,
+          }
+          const res = await getDynamicTableData(params)
+          if (res && res.code === 200) {
+            const records =
+              (res.value && (res.value.records || res.value)) || []
+            this.dynamicTableData = Array.isArray(records) ? records : []
+          } else {
+            this.dynamicTableData =
+              (this.currentSurveyRow &&
+                this.currentSurveyRow.dynamicTableData) ||
+              []
+          }
+          if (
+            this.currentSurveyRow &&
+            this.currentSurveyRow.tableItems &&
+            this.currentSurveyRow.tableItems.length > 0
+          ) {
+            this.tableItems = this.currentSurveyRow.tableItems
+          } else {
+            this.tableItems = this.getMockTableItems()
+          }
+          this.dynamicTableDialogVisible = true
+        } catch (error) {
+          this.dynamicTableData =
+            (this.currentSurveyRow && this.currentSurveyRow.dynamicTableData) ||
+            []
+          this.tableItems =
+            (this.currentSurveyRow && this.currentSurveyRow.tableItems) ||
+            this.getMockTableItems()
+          this.dynamicTableDialogVisible = true
+        } finally {
+          this.dynamicTableLoading = false
+        }
+      },
+      async initFormFields() {
+        if (
+          this.currentSurveyRow &&
+          this.currentSurveyRow.tableType === '单记录' &&
+          this.currentSurveyRow.surveyTemplateId
+        ) {
+          try {
+            const params = {
+              surveyTemplateId: this.currentSurveyRow.surveyTemplateId,
+            }
+            const res = await getListBySurveyTemplateIdAndVersion(params)
+            if (res && res.code === 200) {
+              let mapped = []
+              if (Array.isArray(res.value)) {
+                mapped = res.value
+                  .map((item, index) =>
+                    this.mapApiFieldToFormField(item, index)
+                  )
+                  .filter(Boolean)
+              } else if (res.value && typeof res.value === 'object') {
+                const { fixedFields, fixedFieldids } = res.value
+                if (fixedFields && fixedFieldids) {
+                  const labels = fixedFields.split(',').map((i) => i.trim())
+                  const ids = fixedFieldids.split(',').map((i) => i.trim())
+                  mapped = labels.map((label, index) => ({
+                    prop: ids[index] || `field_${index}`,
+                    label,
+                    type: 'input',
+                    colSpan: 12,
+                    placeholder: `请输入${label}`,
+                    rules: [],
+                    defaultValue: '',
+                    disabled: true,
+                    clearable: true,
+                    multiple: false,
+                    required: false,
+                  }))
+                }
+              }
+              this.formFields =
+                mapped.length > 0 ? mapped : this.getMockFormFields()
+            } else {
+              this.formFields = this.getMockFormFields()
+            }
+            this.surveyFormDialogVisible = true
+          } catch (err) {
+            this.formFields = this.getMockFormFields()
+            this.surveyFormDialogVisible = true
+          }
+        } else if (this.currentSurveyRow && this.currentSurveyRow.formFields) {
+          this.formFields = this.currentSurveyRow.formFields
+          this.surveyFormDialogVisible = true
+        } else {
+          this.formFields = this.getMockFormFields()
+          this.surveyFormDialogVisible = true
+        }
+      },
+      mapApiFieldToFormField(item, index = 0) {
+        if (!item) return null
+        const getVal = (keys, fallback) => {
+          for (const key of keys) {
+            if (
+              key &&
+              item[key] !== undefined &&
+              item[key] !== null &&
+              item[key] !== ''
+            ) {
+              return item[key]
+            }
+          }
+          return fallback
+        }
+        const toBool = (value) => {
+          if (value === undefined || value === null) return false
+          if (typeof value === 'boolean') return value
+          if (typeof value === 'number') return value === 1
+          const str = String(value).trim().toLowerCase()
+          return ['1', 'true', 'y', 'yes', '是'].includes(str)
+        }
+        const toNumber = (value) => {
+          if (value === undefined || value === null || value === '')
+            return undefined
+          const num = Number(value)
+          return Number.isNaN(num) ? undefined : num
+        }
+        const prop =
+          getVal(
+            [
+              'fieldName',
+              'field_name',
+              'columnName',
+              'column_name',
+              'fieldCode',
+            ],
+            undefined
+          ) || `field_${index}`
+        const label =
+          getVal(
+            [
+              'columnComment',
+              'column_comment',
+              'fieldCname',
+              'field_cname',
+              'fieldLabel',
+              'field_label',
+            ],
+            prop
+          ) || prop
+        const columnType =
+          (getVal(
+            ['columnType', 'column_type', 'fieldType', 'field_type'],
+            ''
+          ) || '') + ''
+        const columnTypeLower = columnType.toLowerCase()
+        const totalLength = toNumber(
+          getVal(
+            ['fieldTypeLen', 'field_typelen', 'length', 'fieldLength'],
+            undefined
+          )
+        )
+        const decimalLength = toNumber(
+          getVal(
+            ['fieldTypeNointLen', 'field_typenointlen', 'scale'],
+            undefined
+          )
+        )
+        const isAuditPeriod = toBool(
+          getVal(['isAuditPeriod', 'is_audit_period'], false)
+        )
+        const dictCode =
+          getVal(
+            [
+              'dictCode',
+              'dict_code',
+              'dictId',
+              'dictid',
+              'dictType',
+              'dict_type',
+            ],
+            ''
+          ) || ''
+        const optionsRaw = getVal(['options'], [])
+        let options = []
+        if (Array.isArray(optionsRaw)) options = optionsRaw
+        else if (typeof optionsRaw === 'string' && optionsRaw.trim() !== '') {
+          options = optionsRaw
+            .split(',')
+            .map((value) => ({ label: value.trim(), value: value.trim() }))
+        }
+        let type = getVal(['componentType', 'type'], '')
+        if (!type) {
+          if (dictCode || options.length > 0) type = 'select'
+          else if (
+            columnTypeLower.includes('datetime') ||
+            columnTypeLower.includes('timestamp') ||
+            columnTypeLower.includes('date time')
+          )
+            type = 'datetime'
+          else if (columnTypeLower.includes('date')) type = 'date'
+          else if (columnTypeLower.includes('year')) type = 'year'
+          else if (
+            columnTypeLower.includes('int') ||
+            columnTypeLower.includes('number') ||
+            columnTypeLower.includes('decimal') ||
+            columnTypeLower.includes('float') ||
+            columnTypeLower.includes('double')
+          )
+            type = 'number'
+          else type = 'input'
+        }
+        const required = toBool(
+          getVal(['isRequired', 'is_required', 'required'], false)
+        )
+        const multiple = toBool(
+          getVal(['isMultiple', 'is_multiple', 'multiple'], false)
+        )
+        const colSpan =
+          toNumber(
+            getVal(['colSpan', 'colspan', 'columnSpan', 'column_span'], 12)
+          ) || 12
+        const placeholder =
+          getVal(
+            ['placeholder', 'columnComment', 'column_comment'],
+            undefined
+          ) || (type === 'select' ? `请选择${label}` : `请输入${label}`)
+        const defaultValue = getVal(
+          ['defaultValue', 'default_value', 'defaultVal', 'default_val'],
+          undefined
+        )
+        const precision = toNumber(
+          getVal(
+            ['fieldTypeNointLen', 'field_typenointlen', 'precision'],
+            undefined
+          )
+        )
+        const min = toNumber(getVal(['min'], undefined))
+        const max = toNumber(getVal(['max'], undefined))
+        const format = getVal(['format'], undefined)
+        const valueFormat =
+          getVal(['valueFormat', 'value_format'], undefined) ||
+          (type === 'datetime'
+            ? 'yyyy-MM-dd HH:mm:ss'
+            : type === 'date'
+            ? 'yyyy-MM-dd'
+            : type === 'year'
+            ? 'yyyy'
+            : undefined)
+        const formatLength = this.extractLengthFromFormat(format)
+        const rules = this.buildFieldRules({
+          type,
+          label,
+          required,
+          totalLength,
+          decimalLength,
+          formatLength,
+          format,
+          isAuditPeriod,
+        })
+        return {
+          prop,
+          label,
+          type,
+          colSpan,
+          placeholder,
+          dictCode,
+          dictType: dictCode,
+          options,
+          required,
+          defaultValue,
+          multiple,
+          precision,
+          min,
+          max,
+          format,
+          valueFormat,
+          totalLength,
+          decimalLength,
+          formatLength,
+          rules,
+        }
+      },
+      extractLengthFromFormat(format) {
+        if (!format) return undefined
+        const str = String(format).trim()
+        if (!str) return undefined
+        const match = str.match(/\d+/)
+        if (match && match[0]) {
+          const len = Number(match[0])
+          return Number.isNaN(len) ? undefined : len
+        }
+        return undefined
+      },
+      buildFieldRules(meta) {
+        const {
+          type,
+          label,
+          required,
+          totalLength,
+          decimalLength,
+          formatLength,
+          format,
+          isAuditPeriod,
+        } = meta || {}
+        const rules = []
+        const trigger = type === 'select' ? 'change' : 'blur'
+        if (required) {
+          rules.push({
+            required: true,
+            message: `${type === 'select' ? '请选择' : '请输入'}${label}`,
+            trigger,
+          })
+        }
+        const inputMaxLength = formatLength || totalLength
+        if (type === 'input' && inputMaxLength) {
+          rules.push({
+            validator: (_, _value, callback) => {
+              const value = _value
+              if (value === undefined || value === null || value === '') {
+                callback()
+                return
+              }
+              const str = String(value)
+              if (str.length > inputMaxLength) {
+                callback(
+                  new Error(`${label}长度不能超过${inputMaxLength}个字符`)
+                )
+              } else {
+                callback()
+              }
+            },
+            trigger: 'blur',
+          })
+        }
+        const numberTotal = totalLength || formatLength
+        if (type === 'number') {
+          rules.push({
+            validator: (_, _value, callback) => {
+              const value = _value
+              if (value === undefined || value === null || value === '') {
+                callback()
+                return
+              }
+              if (Number.isNaN(Number(value))) {
+                callback(new Error(`${label}必须为数字`))
+                return
+              }
+              const pure = String(value).replace('-', '')
+              if (numberTotal && pure.replace('.', '').length > numberTotal) {
+                callback(new Error(`${label}总位数不能超过${numberTotal}`))
+                return
+              }
+              if (decimalLength !== undefined && decimalLength !== null) {
+                const decimals = pure.split('.')[1] || ''
+                if (decimals.length > decimalLength) {
+                  callback(
+                    new Error(`${label}小数位不能超过${decimalLength}位`)
+                  )
+                  return
+                }
+              }
+              callback()
+            },
+            trigger: 'blur',
+          })
+        }
+        if (type === 'datetime' || type === 'date') {
+          if (format) {
+            rules.push({
+              validator: (_, _value, callback) => {
+                callback()
+              },
+              trigger: 'change',
+            })
+          }
+        }
+        if (type === 'year' || isAuditPeriod) {
+          rules.push({
+            validator: (_, _value, callback) => {
+              const value = _value
+              if (value === undefined || value === null || value === '') {
+                callback()
+                return
+              }
+              const pattern = /^\d{4}$/
+              if (!pattern.test(String(value))) {
+                callback(new Error(`${label}必须是四位年份`))
+              } else {
+                callback()
+              }
+            },
+            trigger: 'change',
+          })
+        }
+        return rules
+      },
+      getMockTableItems() {
+        return []
+      },
+      // 解析监审期间字符串(如 "2022,2023,2024" 或 "2022-2024")
+      parseAuditPeriod(periodStr) {
+        if (!periodStr) return []
+        const str = String(periodStr)
+        if (str.includes(',')) {
+          return str.split(',').map((p) => String(p).trim())
+        }
+        if (str.includes('-')) {
+          const parts = str.split('-')
+          if (parts.length === 2) {
+            const start = parseInt(parts[0].trim())
+            const end = parseInt(parts[1].trim())
+            const years = []
+            for (let y = start; y <= end; y++) years.push(String(y))
+            return years
+          }
+        }
+        return [String(str)]
+      },
+      // 初始化固定表数据(只读)
+      async initFixedTableData() {
+        // 仅当当前行为固定表且包含模板ID时调用
+        if (
+          this.currentSurveyRow &&
+          this.currentSurveyRow.tableType === '固定表' &&
+          this.currentSurveyRow.surveyTemplateId
+        ) {
+          try {
+            // 1) 获取固定表项配置(itemlist)
+            const params = {
+              surveyTemplateId: this.currentSurveyRow.surveyTemplateId,
+            }
+            const res = await getSingleRecordSurveyList(params)
+            if (res && res.code === 200 && res.value) {
+              const { itemlist } = res.value || {}
+              if (Array.isArray(itemlist) && itemlist.length > 0) {
+                this.tableItems = itemlist.map((item) => ({
+                  id: item.id || item.itemId || '',
+                  rowid: item.rowid || item.id || item.itemId || '',
+                  seq: item.序号,
+                  itemName: item.项目 || '',
+                  unit: item.unit || '',
+                  isCategory: item.isCategory || false,
+                  categorySeq: item.categorySeq || '',
+                  categoryId: item.categoryId || '',
+                  parentid:
+                    item.parentid !== undefined
+                      ? item.parentid
+                      : item.parentId !== undefined
+                      ? item.parentId
+                      : '-1',
+                  validateRules: item.validateRules || {},
+                  linkageRules: item.linkageRules || {},
+                  children: item.children || [],
+                  ...item,
+                }))
+              } else {
+                this.tableItems = this.getMockTableItems()
+              }
+            } else {
+              this.tableItems = this.getMockTableItems()
+            }
+          } catch (err) {
+            this.tableItems = this.getMockTableItems()
+          }
+
+          // 2) 初始化监审期间:优先当前行,其次默认最近3年
+          if (this.currentSurveyRow && this.currentSurveyRow.auditPeriod) {
+            this.auditPeriods = this.parseAuditPeriod(
+              this.currentSurveyRow.auditPeriod
+            )
+          } else {
+            const currentYear = new Date().getFullYear()
+            this.auditPeriods = [
+              String(currentYear - 2),
+              String(currentYear - 1),
+              String(currentYear),
+            ]
+          }
+
+          // 3) 额外拉取表头/规则信息,并透传给弹窗
+          try {
+            const headerRes = await getListBySurveyTemplateIdAndVersion({
+              surveyTemplateId: this.currentSurveyRow.surveyTemplateId,
+            })
+            if (headerRes && headerRes.code === 200) {
+              this.fixedHeaders = headerRes.value || null
+            } else {
+              this.fixedHeaders = null
+            }
+          } catch (e) {
+            this.fixedHeaders = null
+          }
+
+          // 4) 打开固定表弹窗
+          this.fixedTableDialogVisible = true
+          return
+        }
+        // 兜底:没有条件则使用当前行自带配置或空
+        this.tableItems =
+          (this.currentSurveyRow && this.currentSurveyRow.tableItems) ||
+          this.getMockTableItems()
+        this.fixedHeaders = null
+        this.fixedTableDialogVisible = true
+      },
+      resetDynamicDialogState() {
+        this.dynamicDialogKey += 1
+      },
+      noop() {},
+    },
+  }
 </script>
 </script>

+ 103 - 3
src/views/costAudit/auditInfo/auditManage/details.vue

@@ -34,9 +34,14 @@
         </el-tab-pane>
         </el-tab-pane>
         <el-tab-pane label="成本调查表" name="costSurvey">
         <el-tab-pane label="成本调查表" name="costSurvey">
           <cost-survey
           <cost-survey
-            :id="id"
-            :current-node="currentNode"
-            :current-status="currentStatus"
+            :paginated-data="costSurveyPaginated"
+            :pagination="costSurveyPagination"
+            :audited-unit-id="auditedUnitId"
+            :upload-id="''"
+            :survey-template-id="''"
+            :catalog-id="catalogId"
+            @handle-page-change="handleCostSurveyPageChange"
+            @handle-size-change="handleCostSurveySizeChange"
           />
           />
         </el-tab-pane>
         </el-tab-pane>
         <el-tab-pane
         <el-tab-pane
@@ -204,6 +209,7 @@
     doProcessBtn,
     doProcessBtn,
   } from '@/api/dataPreliminaryReview'
   } from '@/api/dataPreliminaryReview'
   import { getTaskRequirementList } from '@/api/auditTaskProcessing'
   import { getTaskRequirementList } from '@/api/auditTaskProcessing'
+  import { getSurveyList } from '@/api/audit/survey'
   export default {
   export default {
     name: 'Details',
     name: 'Details',
     components: {
     components: {
@@ -236,6 +242,11 @@
         type: String,
         type: String,
         default: '',
         default: '',
       },
       },
+      // 任务信息(从props传入,替代路由query)
+      taskInfo: {
+        type: Object,
+        default: () => ({}),
+      },
     },
     },
     data() {
     data() {
       return {
       return {
@@ -243,6 +254,10 @@
         activeTab: 'submitData', // 默认选中报送资料标签页
         activeTab: 'submitData', // 默认选中报送资料标签页
         // 报送资料数据(从接口获取后下发给子组件)
         // 报送资料数据(从接口获取后下发给子组件)
         submitMaterials: [],
         submitMaterials: [],
+        // 成本调查表数据
+        costSurveyAll: [],
+        costSurveyPaginated: [],
+        costSurveyPagination: { currentPage: 1, pageSize: 10, total: 0 },
         // 弹窗显示状态
         // 弹窗显示状态
         showSupplementDialog: false,
         showSupplementDialog: false,
         showAbortDialog: false,
         showAbortDialog: false,
@@ -400,6 +415,11 @@
         if (tab && tab.name === 'submitData' && this.id) {
         if (tab && tab.name === 'submitData' && this.id) {
           this.loadSubmitMaterials()
           this.loadSubmitMaterials()
         }
         }
+        if (tab && tab.name === 'costSurvey' && this.id) {
+          // 加载成本调查表列表
+          console.log(122)
+          this.loadCostSurveyList()
+        }
       },
       },
       async loadSubmitMaterials() {
       async loadSubmitMaterials() {
         try {
         try {
@@ -410,6 +430,86 @@
           this.submitMaterials = []
           this.submitMaterials = []
         }
         }
       },
       },
+      // 加载“成本调查表”列表:使用 getSurveyList 接口(从父组件传入的 catalogId/auditedUnitId)
+      async loadCostSurveyList() {
+        console.log(this.taskInfo, '这行数据')
+        try {
+          const params = {
+            catalogId: this.taskInfo.catalogId,
+            pageNum: this.costSurveyPagination.currentPage,
+            pageSize: this.costSurveyPagination.pageSize,
+          }
+
+          console.log('[CostSurvey] call getSurveyList with:', params)
+          const resp = await getSurveyList(params)
+          // 兼容不同返回结构
+          const raw =
+            (resp &&
+              ((resp.value && (resp.value.records || resp.value)) ||
+                resp.data ||
+                resp)) ||
+            []
+          const list = Array.isArray(raw)
+            ? raw
+            : Array.isArray(raw.records)
+            ? raw.records
+            : []
+          const rows = list.map((it) => {
+            const t = String(it.templateType || it.templatetype || '')
+            const tableType =
+              t === '1'
+                ? '单记录'
+                : t === '2'
+                ? '固定表'
+                : t === '3'
+                ? '动态表'
+                : ''
+            return {
+              id: it.uploadId || it.id || '',
+              name: it.surveyTemplateName,
+              dataType: it.dataType || '预置模板',
+              tableType,
+              isRequired: String(it.isRequired) === '1' ? '是' : '否',
+              isUploaded: String(it.isUpload) === '1' || it.isUpload === true,
+              uploadId: it.uploadId || it.id || '',
+              surveyTemplateId: it.templateId || it.surveyTemplateId || '',
+              catalogId: it.catalogId || this.catalogId || '',
+              auditedUnitId: it.auditedUnitId || this.auditedUnitId || '',
+              tableItems: it.tableItems || [],
+              dynamicTableData: it.dynamicTableData || [],
+            }
+          })
+          console.log(
+            '[CostSurvey] mapped rows from getSurveyList:',
+            rows.length,
+            rows
+          )
+          this.costSurveyAll = rows
+          this.costSurveyPagination.total = rows.length
+          this.costSurveyPagination.currentPage = 1
+          this.paginateCostSurvey()
+        } catch (e) {
+          console.error('[CostSurvey] loadCostSurveyList error:', e)
+          this.costSurveyAll = []
+          this.costSurveyPagination = { currentPage: 1, pageSize: 10, total: 0 }
+          this.costSurveyPaginated = []
+        }
+      },
+      paginateCostSurvey() {
+        const { currentPage, pageSize } = this.costSurveyPagination
+        const start = (currentPage - 1) * pageSize
+        const end = start + pageSize
+        this.costSurveyPaginated = this.costSurveyAll.slice(start, end)
+      },
+      handleCostSurveyPageChange(page) {
+        this.costSurveyPagination.currentPage = page
+        this.paginateCostSurvey()
+      },
+      handleCostSurveySizeChange(size) {
+        this.costSurveyPagination.pageSize = size
+        this.costSurveyPagination.currentPage = 1
+        this.paginateCostSurvey()
+      },
       // 处理审核操作按钮点击
       // 处理审核操作按钮点击
       handleAuditPass(item) {
       handleAuditPass(item) {
         this.additionalParams = {
         this.additionalParams = {

+ 2 - 0
src/views/costAudit/auditInfo/auditManage/index.vue

@@ -176,6 +176,7 @@
       :visible.sync="detailsVisible"
       :visible.sync="detailsVisible"
       :current-node="selectedProject && selectedProject.currentNode"
       :current-node="selectedProject && selectedProject.currentNode"
       :current-status="selectedProject && selectedProject.status"
       :current-status="selectedProject && selectedProject.status"
+      :task-info="selectedProject"
       @close="handleDetailsClose"
       @close="handleDetailsClose"
       @refresh="handleRefresh"
       @refresh="handleRefresh"
     />
     />
@@ -304,6 +305,7 @@
                       projectId: child.projectId,
                       projectId: child.projectId,
                       auditedUnitId: child.auditedUnitId,
                       auditedUnitId: child.auditedUnitId,
                       taskId: child.id,
                       taskId: child.id,
+                      catalogId: child.catalogId,
                     }))
                     }))
                   : [],
                   : [],
               }
               }