<template>
  <div>
    <!-- 在线填报弹窗（单记录类型，可编辑/只读由 isViewMode/viewModeForDialog 控制） -->
    <survey-form-dialog
      :visible.sync="surveyFormDialogVisible"
      :survey-data="{ ...(currentTemplateRow || {}), ...surveyDetailData }"
      :form-fields="formFields"
      :is-view-mode="viewModeForDialog"
      :audited-unit-id="auditedUnitId"
      :request-type="2"
      :upload-id="
        (currentTemplateRow &&
          (currentTemplateRow.uploadId || currentTemplateRow.id)) ||
        ''
      "
      :survey-template-id="getSurveyTemplateId(currentTemplateRow)"
      :catalog-id="(currentTemplateRow && currentTemplateRow.catalogId) || ''"
      @save="
        $emit('handle-survey-form-save', {
          row: currentTemplateRow,
          formData: $event,
        })
      "
      @refresh="
        $emit('handle-survey-form-save', {
          row: currentTemplateRow,
          formData: {},
        })
      "
    />

    <!-- 固定表填报弹窗（可编辑/只读由 isViewMode/viewModeForDialog 控制） -->
    <fixed-table-dialog
      :visible.sync="fixedTableDialogVisible"
      :survey-data="{ ...currentSurveyRow, fixedHeaders }"
      :fixed-fields="fixedFields || ''"
      :fixed-fieldids="fixedFieldids || ''"
      :columns-meta="columnsMeta"
      :table-items="tableItems"
      :audit-periods="auditPeriods"
      :project-audit-periods="auditPeriod"
      :project-audit-period="auditPeriod"
      :project-id="projectId"
      :is-view-mode="viewModeForDialog"
      :request-type="2"
      :audited-unit-id="auditedUnitId"
      :upload-id="
        currentSurveyRow && currentSurveyRow.id ? currentSurveyRow.id : uploadId
      "
      :survey-template-id="
        currentSurveyRow && currentSurveyRow.surveyTemplateId
          ? currentSurveyRow.surveyTemplateId
          : surveyTemplateId
      "
      :catalog-id="catalogId"
      :task-id="taskId"
      :cross-table-info="crossTableInfo"
      @save="handleFixedTableSave"
      @refresh="handleRefresh"
    />

    <!-- 动态表填报弹窗（可编辑/只读由 isViewMode/viewModeForDialog 控制） -->
    <dynamic-table-dialog
      :key="dynamicDialogKey"
      :visible.sync="dynamicTableDialogVisible"
      :survey-data="currentSurveyRow"
      :table-data="dynamicTableData"
      :table-items="tableItems"
      :is-view-mode="viewModeForDialog"
      :request-type="2"
      :audited-unit-id="auditedUnitId"
      :upload-id="
        currentSurveyRow && (currentSurveyRow.uploadId || currentSurveyRow.id)
          ? currentSurveyRow.uploadId || currentSurveyRow.id
          : uploadId
      "
      :catalog-id="catalogId"
      :survey-template-id="
        getSurveyTemplateId(currentSurveyRow) || surveyTemplateId
      "
      @save="handleDynamicTableSave"
      @refresh="handleRefresh"
    />

    <el-button
      type="primary"
      :disabled="isViewMode"
      @click="$emit('handleAddMaterial')"
    >
      补充材料
    </el-button>
    <el-table
      style="margin-top: 20px"
      border
      :data="dataRequirements"
      size="mini"
      :show-header="true"
      :row-class-name="getRowClassName"
    >
      <el-table-column prop="seq" label="序号" width="80" align="center">
        <template slot-scope="scope">
          <span v-if="!scope.row.isCategoryHeader">
            {{ scope.row.seq || scope.row.index }}
          </span>
        </template>
      </el-table-column>
      <el-table-column
        prop="informationName"
        label="报送资料"
        min-width="280"
        header-align="center"
        align="left"
      >
        <template slot-scope="scope">
          <div v-if="scope.row.isCategoryHeader" class="category-header-cell">
            {{ scope.row.categoryName }}
          </div>
          <span v-else>{{ scope.row.informationName || '-' }}</span>
        </template>
      </el-table-column>
      <el-table-column
        prop="formatRequired"
        label="资料类型"
        width="130"
        align="center"
      >
        <template slot-scope="scope">
          <span v-if="!scope.row.isCategoryHeader">
            <span
              v-if="
                scope.row.formatRequired !== null &&
                scope.row.formatRequired !== undefined
              "
            >
              {{
                getDictName('formatAsk', String(scope.row.formatRequired)) ||
                scope.row.formatRequired
              }}
            </span>
            <span v-else>-</span>
          </span>
        </template>
      </el-table-column>
      <el-table-column
        prop="isRequired"
        label="是否必填"
        width="110"
        align="center"
      >
        <template slot-scope="scope">
          <span v-if="!scope.row.isCategoryHeader">
            {{ scope.row.isRequired === '1' ? '是' : '否' }}
          </span>
        </template>
      </el-table-column>
      <el-table-column
        prop="isUpload"
        label="是否上传"
        width="110"
        align="center"
      >
        <template slot-scope="scope">
          <span v-if="!scope.row.isCategoryHeader">
            <span v-if="scope.row.informationName == '动态表'">
              <span
                v-if="uploadStatusMap[scope.row.id] === '已上传'"
                style="color: #67c23a"
              >
                {{ uploadStatusMap[scope.row.id] || '-' }}
              </span>
              <span
                v-else-if="uploadStatusMap[scope.row.id] === '未上传'"
                class="text-danger"
              >
                {{ uploadStatusMap[scope.row.id] }}
              </span>
              <span v-else>-</span>
            </span>
            <span v-else>
              <span
                v-if="scope.row.isUpload === 1 || scope.row.isUpload === '1'"
                style="color: #67c23a"
              >
                已上传
              </span>
              <span v-else class="text-danger">未上传</span>
            </span>
          </span>
        </template>
      </el-table-column>
      <el-table-column
        prop="isRequired"
        label="审核状态"
        width="110"
        align="center"
      >
        <template slot-scope="scope">
          <span v-if="!scope.row.isCategoryHeader">
            <span
              v-if="
                scope.row.auditedStatus !== null &&
                scope.row.auditedStatus !== undefined
              "
            >
              {{
                getDictName('clshzt', String(scope.row.auditedStatus)) ||
                scope.row.auditedStatus
              }}
            </span>
            <span v-else>-</span>
          </span>
        </template>
      </el-table-column>
      <el-table-column prop="operation" label="操作" width="220" align="center">
        <template slot-scope="scope">
          <template v-if="!scope.row.isCategoryHeader">
            <template v-if="String(scope.row.formatRequired) !== '3'">
              <!-- 固定表：也支持在线填报（templateType=2） -->
              <template v-if="String(scope.row.templateType) === '2'">
                <el-button
                  v-if="scope.row.isUpload === 1 || scope.row.isUpload === '1'"
                  type="text"
                  size="small"
                  @click="handleViewTemplate(scope.row)"
                >
                  查看
                </el-button>
                <el-button
                  type="text"
                  size="small"
                  :disabled="isViewMode"
                  @click="handleOnlineSubmission(scope.row)"
                >
                  在线填报
                </el-button>
              </template>

              <el-button
                v-if="
                  (scope.row.isUpload === 1 || scope.row.isUpload === '1') &&
                  String(scope.row.templateType) !== '2'
                "
                type="text"
                size="small"
                @click="handleFileView(scope.row)"
              >
                查看
              </el-button>
              <el-button
                v-if="
                  (scope.row.isUpload === 1 || scope.row.isUpload === '1') &&
                  String(scope.row.templateType) !== '2'
                "
                type="text"
                size="small"
                @click="$emit('handleFileDownload', scope.row)"
              >
                下载
              </el-button>
              <el-button
                v-if="
                  scope.row.auditedStatus !== '1' &&
                  (currentNode === 'clcs' || currentNode === 'tjcl') &&
                  String(scope.row.templateType) !== '2'
                "
                type="text"
                size="small"
                :disabled="isViewMode"
                @click="
                  $emit(
                    'handleFileUpload',
                    scope.row,
                    getUploadAccept(scope.row)
                  )
                "
              >
                上传
              </el-button>
            </template>
            <template v-else>
              <!-- v-if="scope.row.isUpload === 1 || scope.row.isUpload === '1'" -->
              <el-button
                v-if="scope.row.isUpload === 1 || scope.row.isUpload === '1'"
                type="text"
                size="small"
                @click="handleViewTemplate(scope.row)"
              >
                查看
              </el-button>
              <el-button
                v-if="scope.row.formatRequired === '3'"
                type="text"
                size="small"
                @click="handleOnlineSubmission(scope.row)"
              >
                在线填报
              </el-button>
              <el-button
                v-if="
                  scope.row.formatRequired === '3' &&
                  scope.row.templateType !== '1'
                "
                type="text"
                size="small"
                @click="handleTemplateDownload(scope.row)"
              >
                模版下载
              </el-button>
              <el-button
                v-if="
                  scope.row.auditedStatus !== '1' &&
                  (currentNode === 'clcs' || currentNode === 'tjcl') &&
                  scope.row.formatRequired === '3' &&
                  scope.row.templateType !== '1' &&
                  scope.row.informationName !== '动态表' &&
                  scope.row.templateType !== '3'
                "
                type="text"
                size="small"
                :disabled="isViewMode"
                @click="triggerDataUpload(scope.row)"
              >
                数据上传
              </el-button>
            </template>
          </template>
        </template>
      </el-table-column>
    </el-table>
    <input
      ref="dataUploadInput"
      type="file"
      :accept="dataUploadAccept"
      style="display: none"
      @change="handleDataFileChange"
    />

    <!-- 单记录弹窗（查看模式） -->
    <survey-form-dialog
      :visible.sync="singleDialogVisible"
      :survey-data="{}"
      :is-view-mode="true"
      :request-type="2"
      :audited-unit-id="auditedUnitId"
      :upload-id="(currentTemplateRow && currentTemplateRow.uploadId) || ''"
      :survey-template-id="getSurveyTemplateId(currentTemplateRow)"
      :catalog-id="(currentTemplateRow && currentTemplateRow.catalogId) || ''"
    />

    <!-- 固定表弹窗（查看模式） -->
    <fixed-table-dialog
      :visible.sync="fixedDialogVisible"
      :is-view-mode="true"
      :request-type="2"
      :project-id="projectId"
      :audited-unit-id="auditedUnitId"
      :audit-periods="auditPeriods"
      :project-audit-periods="auditPeriod"
      :project-audit-period="auditPeriod"
      :upload-id="(currentTemplateRow && currentTemplateRow.uploadId) || ''"
      :survey-template-id="getSurveyTemplateId(currentTemplateRow)"
      :catalog-id="(currentTemplateRow && currentTemplateRow.catalogId) || ''"
      :cross-table-info="crossTableInfo"
    />

    <!-- 动态表弹窗（查看模式） -->
    <dynamic-table-dialog
      :visible.sync="dynamicDialogVisible"
      :is-view-mode="true"
      :request-type="2"
      :audited-unit-id="auditedUnitId"
      :upload-id="(currentTemplateRow && currentTemplateRow.uploadId) || ''"
      :survey-template-id="getSurveyTemplateId(currentTemplateRow)"
      :catalog-id="(currentTemplateRow && currentTemplateRow.catalogId) || ''"
    />
  </div>
</template>

<script>
  import { uploadPresetTemplate } from '@/api/auditTaskProcessing'
  import {
    getSingleRecordSurveyList,
    getSurveyDetail,
    getDynamicTableData,
    downloadTemplate,
    importData,
    getCrossTableData,
  } from '@/api/audit/survey'
  import { getListBySurveyTemplateIdAndVersion } from '@/api/costSurveyTemplateHeaders'
  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'
  export default {
    name: 'DataRequirementsTab',
    components: {
      SurveyFormDialog,
      FixedTableDialog,
      DynamicTableDialog,
    },
    props: {
      dataRequirements: {
        type: Array,
        default: () => [],
      },
      isViewMode: {
        type: Boolean,
        default: false,
      },
      dictData: {
        type: Object,
        default: () => ({}),
      },
      currentNode: {
        type: String,
        default: '',
      },
      auditedUnitId: {
        type: [String, Number],
        default: '',
      },
      // 任务ID（用于上传等场景）
      taskId: {
        type: [String, Number],
        default: '',
      },
      // 监审期间（与 CostSurveyTab 对齐，便于统一传递给子组件）
      auditPeriod: {
        type: [String, Array],
        default: null,
      },
      // 以下三个用于与 CostSurveyTab 一致的透传参数
      uploadId: {
        type: [String, Number],
        default: '',
      },
      surveyTemplateId: {
        type: [String, Number],
        default: '',
      },
      catalogId: {
        type: [String, Number],
        default: '',
      },
      // 立项信息ID（用于 FixedTableDialog 优先用接口 auditPeriod 渲染年份）
      projectId: {
        type: [String, Number],
        default: '',
      },
    },
    data() {
      return {
        pendingUploadRow: null,
        dataUploadAccept: '.xls,.xlsx',
        // 模板查看相关
        currentTemplateRow: null,
        currentSurveyRow: null,
        singleDialogVisible: false,
        fixedDialogVisible: false,
        dynamicDialogVisible: false,
        // 在线填报/查看共用弹窗的只读控制
        viewModeForDialog: false,
        // 在线填报（编辑）相关
        surveyFormDialogVisible: false,
        fixedTableDialogVisible: false,
        dynamicTableDialogVisible: false,
        formFields: [],
        surveyDetailData: {},
        tableItems: [],
        auditPeriods: [],
        dynamicTableData: [],
        dynamicDialogKey: 0,
        fixedDialogKey: 0,
        fixedHeaders: null,
        // 与 CostSurveyTab 对齐的固定表头派生字段
        fixedFields: '',
        fixedFieldids: '',
        columnsMeta: [],
        uploadStatusMap: {},
        // 跨表引用数据（与 CostSurveyTab 对齐：按年份分组）
        crossTableInfo: {
          isCrossTable: false,
          crossTableName: '',
          data: {},
          years: [],
          getValue: () => undefined,
        },
      }
    },
    // ...
    watch: {
      auditPeriod: {
        immediate: true,
        deep: true,
        handler(val) {
          if (!val) return
          if (Array.isArray(val)) {
            this.auditPeriods = val.map((p) => String(p))
          } else {
            const str = String(val).trim()
            if (!str) return
            if (str.includes(',')) {
              this.auditPeriods = str
                .split(',')
                .map((s) => s.trim())
                .filter(Boolean)
            } else 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 = []
                if (!isNaN(start) && !isNaN(end) && end >= start) {
                  for (let y = start; y <= end; y++) years.push(String(y))
                }
                this.auditPeriods = years
              }
            } else {
              this.auditPeriods = [str]
            }
          }
        },
      },
      // 监听dataRequirements变化，预加载所有动态表上传状态
      dataRequirements: {
        immediate: true,
        deep: true,
        handler(newVal, oldVal) {
          if (newVal && newVal.length > 0) {
            this.preloadAllDynamicTableStatus()
          }
        },
      },
    },
    methods: {
      // 异步获取上传状态并直接更新row属性
      async fetchUploadStatus(row) {
        try {
          const uploadId = row.uploadId || row.id || ''
          const auditedUnitId = this.auditedUnitId || row.auditedUnitId || ''
          const catalogId = row.catalogId || ''
          const surveyTemplateId = this.getSurveyTemplateId(row)

          const params = {
            uploadId,
            auditedUnitId,
            catalogId,
            surveyTemplateId,
            type: 2,
          }

          const res = await getDynamicTableData(params)

          // 直接更新row的uploadStatus属性
          if (res && res.code === 200) {
            const records = res.value?.records || res.value || []
            this.$set(
              this.uploadStatusMap,
              uploadId,
              records.length > 0 ? '已上传' : '未上传'
            )
          } else {
            this.uploadStatusMap[uploadId] = ''
          }

          // 触发表格更新
          this.$nextTick(() => {
            this.$forceUpdate()
          })
        } catch (error) {
          console.error('获取上传状态失败:', error)
          // 错误情况下更新为未上传状态
          row.uploadStatus = '未上传'
          // 确保表格更新
          this.$nextTick(() => {
            this.$forceUpdate()
          })
        }
      },
      // 预加载所有动态表上传状态
      async preloadAllDynamicTableStatus() {
        if (!this.dataRequirements || this.dataRequirements.length === 0) return

        const dynamicTableRows = this.dataRequirements.filter(
          (row) => !row.isCategoryHeader && row.informationName === '动态表'
        )

        // 并行请求所有动态表的上传状态，不设置初始加载状态
        const promises = dynamicTableRows.map((row) => {
          return this.fetchUploadStatus(row)
        })

        try {
          await Promise.all(promises)
        } catch (error) {
          console.error('预加载上传状态失败:', error)
        } finally {
          // 确保表格更新
          this.$nextTick(() => {
            this.$forceUpdate()
          })
        }
      },
      // 加载跨表引用数据（固定表/动态表使用，type=2=报送资料）
      async loadCrossTableInfo(row) {
        const surveyTemplateId = this.getSurveyTemplateId(row)
        const taskId = (row && (row.taskId || row.taskID)) || this.taskId || ''

        if (!surveyTemplateId || !taskId) {
          this.crossTableInfo = {
            isCrossTable: false,
            crossTableName: '',
            data: {},
            years: [],
            getValue: () => undefined,
          }
          return true
        }

        try {
          const res = await getCrossTableData({
            taskId,
            surveyTemplateId,
            type: 2,
          })

          const wrapper = res || {}
          const wrappedValue = wrapper.value || wrapper.data || wrapper
          const code =
            wrapper.code !== undefined && wrapper.code !== null
              ? wrapper.code
              : wrappedValue && wrappedValue.code

          if (!(code === 0 || code === 200)) {
            this.crossTableInfo = {
              isCrossTable: false,
              crossTableName: '',
              data: {},
              years: [],
              getValue: () => undefined,
            }
            return true
          }

          const d = wrappedValue || {}
          const dataByYearRaw = d && d.data
          const isEmptyArray =
            Array.isArray(dataByYearRaw) && dataByYearRaw.length === 0
          const dataByYear =
            !dataByYearRaw || Array.isArray(dataByYearRaw) ? {} : dataByYearRaw
          const years = Object.keys(dataByYear)
            .map((y) => String(y))
            .filter(Boolean)
            .sort()

          // 若标记为跨表但未返回任何跨表数据：提示 + 阻止打开弹窗
          if (d && d.isCrossTable && (isEmptyArray || years.length === 0)) {
            this.$message &&
              this.$message.warning &&
              this.$message.warning(
                `跨表引用数据为空，请先完善【${
                  d.crossTableName || '跨表'
                }】后再试`
              )

            this.crossTableInfo = {
              isCrossTable: !!d.isCrossTable,
              crossTableName: d.crossTableName || '',
              data: {},
              years: [],
              getValue: () => undefined,
            }
            return false
          }

          this.crossTableInfo = {
            isCrossTable: !!d.isCrossTable,
            crossTableName: d.crossTableName || '',
            data: dataByYear,
            years,
            getValue: (year, key) => {
              const y = year === undefined || year === null ? '' : String(year)
              const k = key === undefined || key === null ? '' : String(key)
              if (!y || !k) return undefined
              return dataByYear && dataByYear[y] ? dataByYear[y][k] : undefined
            },
          }

          return true
        } catch (e) {
          console.error('获取跨表引用数据失败:', e)
          this.crossTableInfo = {
            isCrossTable: false,
            crossTableName: '',
            data: {},
            years: [],
            getValue: () => undefined,
          }
          return true
        }
      },
      // 在线填报入口：与 CostSurveyTab 一致
      async handleOnlineSubmission(row) {
        if (!row) return
        this.currentTemplateRow = row
        this.currentSurveyRow = row
        this.surveyDetailData = {}
        // 在线填报时使用页面传入的 isViewMode，不强制只读
        this.viewModeForDialog = false

        const t = String(row.templateType || row.templatetype || '').trim()
        // 1=单记录，2=固定表，3=动态表
        if (t === '1') {
          // 只要有 uploadId/id 就尝试回显数据
          if (row.uploadId || row.id) {
            try {
              const params = {
                uploadId: row.uploadId || row.id,
                auditedUnitId: this.auditedUnitId,
                type: 2,
              }
              const res = await getSurveyDetail(params)
              if (res && res.code === 200 && res.value) {
                console.log(res, 'getUploadData')
                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 && typeof res.value === 'object') {
                  Object.assign(detailData, res.value)
                }
                this.surveyDetailData = detailData
              }
            } catch (err) {
              console.error('获取单记录详情失败', err)
            }
          }
          await this.initFormFields()
        } else if (t === '2') {
          const ok = await this.loadCrossTableInfo(row)
          if (!ok) return
          await this.initFixedTableData()
        } else if (t === '3') {
          this.resetDynamicDialogState()
          await this.initDynamicTableData()
        }
      },
      // 处理固定表保存（与 CostSurveyTab 对齐）
      handleFixedTableSave(tableData) {
        this.$emit('handle-fixed-table-save', {
          row: this.currentSurveyRow || this.currentTemplateRow,
          tableData,
        })
      },
      // 处理刷新（与 CostSurveyTab 对齐）
      handleRefresh() {
        this.$emit('handle-survey-form-save', {
          row: this.currentSurveyRow || this.currentTemplateRow,
          formData: {},
        })
      },
      // 处理动态表保存（与 CostSurveyTab 对齐）
      handleDynamicTableSave(tableData) {
        this.$emit('handle-dynamic-table-save', {
          row: this.currentSurveyRow || this.currentTemplateRow,
          tableData,
        })
        this.handleRefresh()
      },
      // 预览：与 UploadComponent.vue 的 handlePreview 一致
      handleFileView(row) {
        console.log(row, '这一行数据')
        try {
          const filePath =
            row?.filePath ||
            row?.filepath ||
            row?.fileUrl ||
            row?.url ||
            row?.path ||
            ''
          if (!filePath) {
            this.$message &&
              this.$message.warning &&
              this.$message.warning('未找到可预览的文件路径')
            return
          }
          const encodedUrl = encodeURIComponent(
            Base64.encode((window.context && window.context.form) + filePath)
          )
          window.open(`${host}:8012/onlinePreview?url=${encodedUrl}`)
          // 兼容保留：通知父组件
          this.$emit('handleFileView', row)
        } catch (e) {
          console.error('文件预览失败: ', e)
          this.$message &&
            this.$message.error &&
            this.$message.error('文件预览失败')
        }
      },
      // 模版查看：与 submitData.vue 的 handleViewTemplate 保持一致
      async handleViewTemplate(row) {
        this.currentTemplateRow = row || null
        this.currentSurveyRow = row || null
        const t = String(
          (row && (row.templateType || row.templatetype)) || ''
        ).trim()
        // 点击“查看”时，复用在线填报的弹窗和数据加载逻辑，但强制只读
        this.viewModeForDialog = true
        if (t === '1' || t === '2' || t === '3') {
          if (!row) return
          this.currentTemplateRow = row
          this.surveyDetailData = {}
          // 在线填报时使用页面传入的 isViewMode，不强制只读
          this.viewModeForDialog = true

          const t = String(row.templateType || row.templatetype || '').trim()
          // 1=单记录，2=固定表，3=动态表
          if (t === '1') {
            // 只要有 uploadId/id 就尝试回显数据
            if (row.uploadId || row.id) {
              try {
                const params = {
                  uploadId: row.uploadId || row.id,
                  auditedUnitId: this.auditedUnitId,
                  type: 2,
                }
                const res = await getSurveyDetail(params)
                if (res && res.code === 200 && res.value) {
                  console.log(res, 'getUploadData')
                  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 && typeof res.value === 'object') {
                    Object.assign(detailData, res.value)
                  }
                  this.surveyDetailData = detailData
                }
              } catch (err) {
                console.error('获取单记录详情失败', err)
              }
            }
            await this.initFormFields()
          } else if (t === '2') {
            const ok = await this.loadCrossTableInfo(row)
            if (!ok) return
            await this.initFixedTableData()
          } else if (t === '3') {
            this.resetDynamicDialogState()
            await this.initDynamicTableData()
          }
        } else {
          this.$message &&
            this.$message.warning &&
            this.$message.warning('未知的模板类型，无法打开预置模板')
        }
      },
      // 根据资料类型返回上传accept白名单
      getUploadAccept(row) {
        const fmt = row && row.formatRequired
        const fmtStr = fmt != null ? String(fmt).toLowerCase() : ''
        if (
          fmtStr === '1' ||
          fmtStr.includes('doc') ||
          fmtStr.includes('word') ||
          fmtStr.includes('pdf') ||
          fmtStr.includes('文档')
        ) {
          return '.pdf,.doc,.docx'
        }
        if (
          fmtStr === '2' ||
          fmtStr.includes('excel') ||
          fmtStr.includes('xls') ||
          fmtStr.includes('xlsx') ||
          fmtStr.includes('表格')
        ) {
          return '.xls,.xlsx'
        }
        return '.pdf,.doc,.docx,.xls,.xlsx'
      },
      getDataUploadAccept(row) {
        const fmt = row && row.formatRequired
        const fmtStr = fmt != null ? String(fmt).toLowerCase() : ''
        if (
          fmtStr === '3' ||
          fmtStr.includes('模版') ||
          fmtStr.includes('模板')
        ) {
          return '.xls,.xlsx'
        }
        return '.xls,.xlsx'
      },
      getRowClassName(data) {
        if (data.row.isCategoryHeader) {
          return 'category-header-row'
        }
        return ''
      },
      getDictName(dictType, dictKey) {
        const list = (this.dictData && this.dictData[dictType]) || []
        if (!Array.isArray(list) || dictKey === undefined || dictKey === null) {
          return ''
        }
        const item = list.find(
          (it) =>
            String(it.key) === String(dictKey) ||
            String(it.value) === String(dictKey)
        )
        return item ? item.name : ''
      },
      getSurveyTemplateId(row) {
        return (
          row?.surveyTemplateId ||
          row?.templateId ||
          row?.surveyTemplateID ||
          row?.templateID ||
          ''
        )
      },
      getMaterialId(row) {
        return row?.materialId || row?.id || row?.materialID || ''
      },
      resetDataUploadState() {
        const input = this.$refs.dataUploadInput
        if (input) {
          input.value = ''
        }
        this.pendingUploadRow = null
      },
      triggerDataUpload(row) {
        console.log(row)
        if (!row || this.isViewMode) {
          return
        }
        const surveyTemplateId = this.getSurveyTemplateId(row)
        if (!surveyTemplateId) {
          this.$message.warning('缺少模板信息，无法上传数据')
          return
        }
        this.pendingUploadRow = row
        this.dataUploadAccept = this.getDataUploadAccept(row)
        this.$nextTick(() => {
          const input = this.$refs.dataUploadInput
          if (input) {
            input.value = ''
            input.click()
          }
        })
      },
      async handleDataFileChange(event) {
        const files = event?.target?.files
        if (!this.pendingUploadRow || !files || !files.length) {
          this.resetDataUploadState()
          return
        }
        const file = files[0]
        if (!file) {
          this.$message.warning('请选择需要上传的文件')
          this.resetDataUploadState()
          return
        }

        const surveyTemplateId = this.getSurveyTemplateId(this.pendingUploadRow)
        const materialId = this.getMaterialId(this.pendingUploadRow)
        if (!surveyTemplateId) {
          this.$message.warning('缺少模板信息，无法上传数据')
          this.resetDataUploadState()
          return
        }
        if (!materialId) {
          this.$message.warning('缺少资料标识，无法上传数据')
          this.resetDataUploadState()
          return
        }

        const formData = new FormData()
        formData.append('file', file)
        formData.append('surveyTemplateId', surveyTemplateId)
        formData.append('materialId', materialId)
        // const auditedUnitId =this.pendingUploadRow.auditedUnitId
        const taskId = this.pendingUploadRow.taskId || this.taskId
        // formData.append('auditedUnitId', auditedUnitId)
        formData.append('taskId', taskId)
        formData.append('type', '2')

        const loading = this.$loading({
          lock: true,
          text: '数据上传中...',
          spinner: 'el-icon-loading',
          background: 'rgba(0, 0, 0, 0.7)',
        })

        try {
          const response = await importData(formData)
          loading.close()

          const success =
            response &&
            (response.code === 200 ||
              response.success === true ||
              response.status === 200)

          if (success) {
            this.$message.success('数据上传成功')
            this.$emit('data-upload-success', {
              row: this.pendingUploadRow,
              response,
            })
          } else {
            const message =
              response?.message ||
              response?.msg ||
              response?.data?.message ||
              '数据上传失败，请稍后重试'
            this.$message.error(message)
          }
        } catch (error) {
          loading.close()
          console.error('数据上传失败:', error)
          // this.$message.error(error.message || '数据上传失败，请稍后重试')
        } finally {
          this.resetDataUploadState()
        }
      },
      // 处理模板下载
      async handleTemplateDownload(row) {
        console.log(row)
        let loading
        try {
          // 显示加载提示
          loading = this.$loading({
            lock: true,
            text: '模板下载中...',
            spinner: 'el-icon-loading',
            background: 'rgba(0, 0, 0, 0.7)',
          })

          // 构建请求参数
          const params = { type: 2 }
          const surveyTemplateId = this.getSurveyTemplateId(row)
          if (surveyTemplateId) {
            params.surveyTemplateId = surveyTemplateId
          }
          // 追加 taskId（来自行或页面 props）
          const taskId = row && (row.taskId || row.taskID)
          if (taskId || this.taskId) {
            params.taskId = taskId || this.taskId
          }

          const response = await downloadTemplate(params)

          // 下载接口可能返回两类数据：
          // 1) 正常：Blob（xlsx）
          // 2) 异常：JSON（{code:500,state:false,message:'...'}），但由于 responseType=blob，前端拿到的可能仍是 Blob
          const getJsonFromBlobIfPossible = async (blob) => {
            if (!(blob instanceof Blob)) return null
            try {
              const text = await blob.text()
              if (!text) return null
              return JSON.parse(text)
            } catch (e) {
              return null
            }
          }

          let maybeJson = null
          if (
            response &&
            response.data &&
            typeof response.data === 'object' &&
            !(response.data instanceof Blob)
          ) {
            maybeJson = response.data
          } else if (
            response &&
            typeof response === 'object' &&
            !(response instanceof Blob) &&
            !(response.data instanceof Blob)
          ) {
            maybeJson = response
          } else if (response && response.data instanceof Blob) {
            maybeJson = await getJsonFromBlobIfPossible(response.data)
          } else if (response instanceof Blob) {
            maybeJson = await getJsonFromBlobIfPossible(response)
          }

          console.log('下载模板接口返回数据：', maybeJson)

          if (
            maybeJson &&
            (maybeJson.state === false ||
              (maybeJson.code !== undefined &&
                maybeJson.code !== null &&
                ![0, 200].includes(Number(maybeJson.code))))
          ) {
            const msg =
              maybeJson.message ||
              maybeJson.msg ||
              '导出失败：该表存在跨表引用且部分年份数据缺失，请先完善后再下载'
            this.$message && this.$message.warning && this.$message.warning(msg)
            return
          }

          // 处理响应数据
          // response 可能是 { data, headers } 格式，也可能是直接的 Blob
          const blobData = (response && response.data) || response
          const blob =
            blobData instanceof Blob ? blobData : new Blob([blobData])

          // 文件名：优先从响应头获取
          let fileName = ''
          const headers = (response && response.headers) || {}
          const contentDisposition =
            headers['content-disposition'] || headers['Content-Disposition']
          if (contentDisposition) {
            const fileNameMatch = contentDisposition.match(
              /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/
            )
            if (fileNameMatch && fileNameMatch[1]) {
              try {
                fileName = decodeURIComponent(
                  fileNameMatch[1].replace(/['"]/g, '')
                )
              } catch (e) {
                fileName = fileNameMatch[1].replace(/['"]/g, '')
              }
            }
          }

          if (!fileName) {
            const defaultName = row?.informationName || row?.name || '模板文件'
            fileName = `${defaultName}_模板.xlsx`
          }
          if (!/\.[a-zA-Z0-9]+$/.test(fileName)) {
            fileName += '.xlsx'
          }

          const url = window.URL.createObjectURL(blob)
          const link = document.createElement('a')
          link.style.display = 'none'
          link.href = url
          link.download = fileName
          document.body.appendChild(link)
          link.click()
          document.body.removeChild(link)
          window.URL.revokeObjectURL(url)

          this.$message &&
            this.$message.success &&
            this.$message.success('开始下载文件')
        } catch (error) {
          // 兼容：axios 抛错时，错误信息可能在 error.response.data（同样可能是 Blob）
          try {
            const errRes = error && error.response
            const errData = errRes && errRes.data
            let errJson = null
            if (
              errData &&
              typeof errData === 'object' &&
              !(errData instanceof Blob)
            ) {
              errJson = errData
            } else if (errData instanceof Blob) {
              try {
                const text = await errData.text()
                errJson = text ? JSON.parse(text) : null
              } catch (_) {
                errJson = null
              }
            }
            if (errJson && (errJson.message || errJson.msg)) {
              this.$message &&
                this.$message.warning &&
                this.$message.warning(errJson.message || errJson.msg)
              return
            }
          } catch (_) {
            // ignore
          }

          console.error('模板下载失败:', error)
          this.$message &&
            this.$message.error &&
            this.$message.error(error.message || '模板下载失败，请稍后重试')
        } finally {
          if (loading && loading.close) loading.close()
        }
      },
      // 以下为在线填报所需方法，与 CostSurveyTab 对齐
      async initDynamicTableData() {
        try {
          const uploadId =
            (this.currentTemplateRow &&
              (this.currentTemplateRow.uploadId ||
                this.currentTemplateRow.id)) ||
            ''
          const auditedUnitId =
            this.auditedUnitId ||
            (this.currentTemplateRow &&
              this.currentTemplateRow.auditedUnitId) ||
            ''
          const catalogId =
            (this.currentTemplateRow && this.currentTemplateRow.catalogId) || ''
          const surveyTemplateId = this.getSurveyTemplateId(
            this.currentTemplateRow
          )

          const params = {
            uploadId,
            auditedUnitId,
            catalogId,
            surveyTemplateId,
            type: 2,
          }
          const res = await getDynamicTableData(params)
          if (res && res.code === 200) {
            const records = res.value?.records || res.value || []
            this.dynamicTableData = Array.isArray(records) ? records : []
          } else {
            this.dynamicTableData =
              this.currentTemplateRow?.dynamicTableData || []
          }

          if (
            this.currentTemplateRow &&
            this.currentTemplateRow.tableItems &&
            this.currentTemplateRow.tableItems.length > 0
          ) {
            this.tableItems = this.currentTemplateRow.tableItems
          } else {
            this.tableItems = this.getMockTableItems()
          }
          this.dynamicTableDialogVisible = true
        } catch (error) {
          console.error('获取动态表数据失败', error)
          this.dynamicTableData =
            this.currentTemplateRow?.dynamicTableData || []
          this.tableItems =
            this.currentTemplateRow?.tableItems || this.getMockTableItems()
          this.dynamicTableDialogVisible = true
        }
      },
      async initFormFields() {
        if (
          this.currentTemplateRow &&
          this.getSurveyTemplateId(this.currentTemplateRow)
        ) {
          try {
            const params = {
              surveyTemplateId: this.getSurveyTemplateId(
                this.currentTemplateRow
              ),
              type: 2,
            }
            const res = await getListBySurveyFdTemplateIdAndVersion(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: false,
                    clearable: true,
                    multiple: false,
                    required: false,
                  }))
                }
              }
              this.formFields =
                mapped.length > 0 ? mapped : this.getMockFormFields()
            } else {
              this.formFields = this.getMockFormFields()
            }
            this.surveyFormDialogVisible = true
          } catch (err) {
            console.error('获取单记录表单字段配置失败', err)
            this.formFields = this.getMockFormFields()
            this.surveyFormDialogVisible = true
          }
        } else {
          this.formFields = this.getMockFormFields()
          this.surveyFormDialogVisible = true
        }
      },
      async initFixedTableData() {
        if (
          this.currentTemplateRow &&
          this.getSurveyTemplateId(this.currentTemplateRow)
        ) {
          try {
            const params = {
              surveyTemplateId: this.getSurveyTemplateId(
                this.currentTemplateRow
              ),
              type: 2,
            }
            const res = await getSingleRecordSurveyList(params)
            if (res && res.code === 200 && res.value) {
              // 将接口返回的数据转换为固定表配置格式
              // 固定表使用 itemlist，不使用 fixedFields 和 fixedFieldids
              const { itemlist } = res.value
              console.log('itemlist', itemlist)
              // 如果有 itemlist，使用 itemlist 作为表格项配置
              if (itemlist && Array.isArray(itemlist) && itemlist.length > 0) {
                this.tableItems = itemlist.map((item, index) => ({
                  id: item.id || item.itemId || '',
                  rowid: item.rowid || item.id || item.itemId || '', // rowid 用于父子关系
                  seq: item.序号, // 序号就是序号
                  itemName: item.项目 || '', // 项目就是项目
                  unit: item.unit || '', // 单位是 unit
                  isCategory: item.isCategory || false,
                  categorySeq: item.categorySeq || '',
                  categoryId: item.categoryId || '',
                  parentid:
                    item.parentid !== undefined
                      ? item.parentid
                      : item.parentId !== undefined
                      ? item.parentId
                      : '-1', // 父项ID，默认为 '-1'（父项）
                  validateRules: item.validateRules || {},
                  linkageRules: item.linkageRules || {},
                  children: item.children || [],
                  ...item, // 保留其他字段
                }))
                // 若该接口同时提供 fixedFields/fixedFieldids，则同步到弹窗表头
                if (res.value.fixedFields && res.value.fixedFieldids) {
                  this.fixedFields = res.value.fixedFields
                  console.log(this.fixedFields, 'biaogeshuju')
                  this.fixedFieldids = res.value.fixedFieldids
                }
              } else {
                // 如果没有 itemlist，使用假数据
                this.tableItems = this.getMockTableItems()
              }
            } else {
              this.tableItems = this.getMockTableItems()
            }
          } catch (err) {
            console.error('获取固定表配置失败', err)
            this.tableItems = this.getMockTableItems()
          }
        } else if (
          this.currentTemplateRow &&
          this.currentTemplateRow.tableItems
        ) {
          this.tableItems = this.currentTemplateRow.tableItems
        } else {
          this.tableItems = this.getMockTableItems()
        }

        // 监审期间：优先使用 props.auditPeriod，其次使用行上的 auditPeriod，否则默认最近三年
        if (this.auditPeriod) {
          if (Array.isArray(this.auditPeriod)) {
            this.auditPeriods = this.auditPeriod.map((p) => String(p))
          } else {
            this.auditPeriods = this.parseAuditPeriod(this.auditPeriod)
          }
        } else if (
          this.currentTemplateRow &&
          this.currentTemplateRow.auditPeriod
        ) {
          this.auditPeriods = this.parseAuditPeriod(
            this.currentTemplateRow.auditPeriod
          )
        } else {
          const currentYear = new Date().getFullYear()
          this.auditPeriods = [
            String(currentYear - 2),
            String(currentYear - 1),
            String(currentYear),
          ]
        }

        try {
          const headerRes = await getListBySurveyTemplateIdAndVersion({
            surveyTemplateId: this.getSurveyTemplateId(this.currentTemplateRow),
            type: 2,
          })
          if (headerRes && headerRes.code === 200) {
            const hdrVal = headerRes.value
            // 统一规范：columnsMeta + fixedFields + fixedFieldids
            let columnsMeta = []
            let fixedFieldsStr = this.fixedFields || ''
            let fixedFieldidsStr = this.fixedFieldids || ''

            if (Array.isArray(hdrVal)) {
              columnsMeta = hdrVal
            } else if (hdrVal && typeof hdrVal === 'object') {
              const {
                fixedFields,
                fixedFieldids,
                columnsMeta: metas,
                headers,
                items,
              } = hdrVal
              fixedFieldsStr = fixedFieldsStr || fixedFields || ''
              fixedFieldidsStr = fixedFieldidsStr || fixedFieldids || ''
              columnsMeta = Array.isArray(metas)
                ? metas
                : Array.isArray(headers)
                ? headers
                : Array.isArray(items)
                ? items
                : []
            }

            // 如未提供 fixedFields/fixedFieldids，则从 columnsMeta 推导
            if (
              (!fixedFieldsStr || !fixedFieldidsStr) &&
              Array.isArray(columnsMeta) &&
              columnsMeta.length
            ) {
              const labels = columnsMeta
                .map((m) => (m && (m.label || m.fieldName || m.name)) || '')
                .map((s) => String(s || '').trim())
                .filter(Boolean)
              const ids = columnsMeta
                .map(
                  (m) =>
                    (m && (m.fieldId || m.fieldName || m.prop || m.code)) || ''
                )
                .map((s) => String(s || '').trim())
                .filter(Boolean)
              if (labels.length) fixedFieldsStr = labels.join(',')
              if (ids.length) fixedFieldidsStr = ids.join(',')
            }

            // 回写到实例；优先保留服务端原始 fixedHeaders，以与成本调查表保持一致
            this.columnsMeta = columnsMeta
            this.fixedFields = fixedFieldsStr
            this.fixedFieldids = fixedFieldidsStr
            if (hdrVal) {
              this.fixedHeaders = hdrVal
            } else if (
              (Array.isArray(this.columnsMeta) && this.columnsMeta.length) ||
              (this.fixedFields && this.fixedFields.length) ||
              (this.fixedFieldids && this.fixedFieldids.length)
            ) {
              this.fixedHeaders = {
                fixedFields: this.fixedFields,
                fixedFieldids: this.fixedFieldids,
                columnsMeta: this.columnsMeta,
              }
            } else {
              this.fixedHeaders = null
            }
          } else {
            this.fixedHeaders = null
            this.fixedFields = ''
            this.fixedFieldids = ''
            this.columnsMeta = []
          }
        } catch (e) {
          this.fixedHeaders = null
          this.fixedFields = ''
          this.fixedFieldids = ''
          this.columnsMeta = []
        }

        this.fixedDialogKey++
        this.fixedTableDialogVisible = true
      },
      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) => {
              if (value === undefined || value === null || value === '')
                return callback()
              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) => {
              if (value === undefined || value === null || value === '')
                return callback()
              if (Number.isNaN(Number(value)))
                return callback(new Error(`${label}必须为数字`))
              const pure = String(value).replace('-', '')
              if (numberTotal && pure.replace('.', '').length > numberTotal)
                return callback(
                  new Error(`${label}总位数不能超过${numberTotal}`)
                )
              if (decimalLength !== undefined && decimalLength !== null) {
                const decimals = pure.split('.')[1] || ''
                if (decimals.length > decimalLength)
                  return callback(
                    new Error(`${label}小数位不能超过${decimalLength}位`)
                  )
              }
              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) => {
              if (value === undefined || value === null || value === '')
                return callback()
              const pattern = /^\d{4}$/
              if (!pattern.test(String(value)))
                callback(new Error(`${label}必须是四位年份`))
              else callback()
            },
            trigger: 'change',
          })
        }
        return rules
      },
      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,
        }
      },
      getMockFormFields() {
        // return [
        //   {
        //     prop: 'institutionName',
        //     label: '机构名称',
        //     type: 'input',
        //     colSpan: 12,
        //     defaultValue: '幼儿园基本情况',
        //     placeholder: '请输入机构名称',
        //     required: true,
        //   },
        //   {
        //     prop: 'institutionNature',
        //     label: '机构性质',
        //     type: 'select',
        //     colSpan: 12,
        //     dictType: 'institutionNature',
        //     defaultValue: '公办',
        //     placeholder: '请选择机构性质',
        //     required: true,
        //     clearable: true,
        //   },
        //   {
        //     prop: 'institutionLevel',
        //     label: '机构评定等级',
        //     type: 'select',
        //     colSpan: 12,
        //     dictType: 'institutionLevel',
        //     defaultValue: '省一级',
        //     placeholder: '请选择机构评定等级',
        //     required: true,
        //     clearable: true,
        //   },
        //   {
        //     prop: 'educationMode',
        //     label: '机构办学方式',
        //     type: 'select',
        //     colSpan: 12,
        //     dictType: 'educationMode',
        //     defaultValue: '全日制',
        //     placeholder: '请选择机构办学方式',
        //     required: true,
        //     clearable: true,
        //   },
        //   {
        //     prop: 'institutionAddress',
        //     label: '机构地址',
        //     type: 'input',
        //     colSpan: 12,
        //     placeholder: '请输入机构地址',
        //     required: true,
        //   },
        //   {
        //     prop: 'formFiller',
        //     label: '机构填表人',
        //     type: 'input',
        //     colSpan: 12,
        //     placeholder: '请输入机构填表人',
        //     required: true,
        //   },
        //   {
        //     prop: 'financialManager',
        //     label: '机构财务负责人',
        //     type: 'input',
        //     colSpan: 12,
        //     placeholder: '请输入机构财务负责人',
        //     required: true,
        //   },
        //   {
        //     prop: 'contactPhone',
        //     label: '机构联系电话',
        //     type: 'input',
        //     colSpan: 12,
        //     placeholder: '请输入机构联系电话',
        //     required: true,
        //     rules: [
        //       {
        //         required: true,
        //         message: '请输入机构联系电话',
        //         trigger: 'blur',
        //       },
        //       {
        //         pattern: /^1[3-9]\d{9}$/,
        //         message: '请输入正确的手机号码',
        //         trigger: 'blur',
        //       },
        //     ],
        //   },
        // ]
      },
      getMockTableItems() {
        // return [
        //   {
        //     id: '1',
        //     itemName: '班级数',
        //     unit: '个',
        //     isCategory: false,
        //     seq: 1,
        //     validateRules: { required: true, type: 'number', min: 0 },
        //   },
        //   {
        //     id: '2',
        //     itemName: '幼儿学生人数',
        //     unit: '人',
        //     isCategory: false,
        //     seq: 2,
        //     validateRules: { required: true, type: 'number', min: 0 },
        //   },
        // ]
      },
      resetDynamicDialogState() {
        this.dynamicTableDialogVisible = false
        this.dynamicTableData = []
        this.tableItems = []
        this.dynamicDialogKey = Date.now()
      },
    },
  }
</script>

<style scoped>
  .text-danger {
    color: #d9001b;
  }

  /* 类别头行样式 */
  .category-header-row {
    background-color: #f5f7fa !important;
  }
  .category-header-row td {
    background-color: #f5f7fa !important;
    padding: 12px 16px !important;
  }
  .category-header-cell {
    font-weight: 700;
    color: #303133;
    padding-left: 16px;
  }
</style>
