Переглянути джерело

fix: 成本调查报送资料表头居中,监审意见流程到哪一步显示哪一步,任务制定签章按钮移除,任务制定工作环节预置流转操作显示默认通过、归档

shiyanyu 1 місяць тому
батько
коміт
51719a7248

+ 10 - 0
src/api/costSurveyTemplateHeaders.js

@@ -39,3 +39,13 @@ export function delBatchSaveOrUpdate(id) {
     },
   })
 }
+
+export function getListBySurveyFdTemplateIdAndVersion(params) {
+  return request({
+    url:
+      url +
+      '/costSurveyTemplateHeaders/v1/getlistBySurveyFdTemplateIdAndVersion',
+    method: 'get',
+    params,
+  })
+}

+ 1 - 1
src/components/task/components/costSurvey.vue

@@ -13,7 +13,7 @@
         prop="name"
         label="成本调查表"
         min-width="200"
-        align="left"
+        align="center"
         header-align="center"
         show-overflow-tooltip
       />

+ 1 - 0
src/components/task/components/submitData.vue

@@ -23,6 +23,7 @@
           prop="informationName"
           label="报送资料"
           min-width="200"
+          align="center"
         />
 
         <el-table-column label="资料类型" width="200" align="center">

+ 6 - 1
src/components/task/taskInfo.vue

@@ -334,6 +334,7 @@
                 prop="informationName"
                 label="报送资料"
                 min-width="280"
+                align="center"
               >
                 <template slot-scope="scope">
                   <div
@@ -508,7 +509,11 @@
                 width="60"
                 align="center"
               ></el-table-column>
-              <el-table-column label="成本调查表" min-width="220">
+              <el-table-column
+                label="成本调查表"
+                min-width="220"
+                align="center"
+              >
                 <template slot-scope="scope">
                   <span>{{ scope.row.name }}</span>
                 </template>

+ 17 - 17
src/views/EntDeclaration/auditTaskManagement/components/CostSurveyTab.vue

@@ -77,7 +77,7 @@
           {{ scope.$index + 1 }}
         </template>
       </el-table-column>
-      <el-table-column label="成本调查表" min-width="220">
+      <el-table-column label="成本调查表" min-width="220" align="center">
         <template slot-scope="scope">
           <span
             :style="{
@@ -143,22 +143,22 @@
       </el-table-column>
       <el-table-column label="初审结果" width="100" align="center">
         <template slot-scope="scope">
-            <span
-              :class="{
-                'result-pending':
-                  !scope.row.auditedStatus || scope.row.auditedStatus === '0',
-                'result-pass': scope.row.auditedStatus === '1',
-                'result-fail': scope.row.auditedStatus === '2',
-              }"
-            >
-              {{
-                !scope.row.auditedStatus || scope.row.auditedStatus === '0'
-                  ? '未审核'
-                  : scope.row.auditedStatus === '1'
-                    ? '通过'
-                    : '不通过'
-              }}
-            </span>
+          <span
+            :class="{
+              'result-pending':
+                !scope.row.auditedStatus || scope.row.auditedStatus === '0',
+              'result-pass': scope.row.auditedStatus === '1',
+              'result-fail': scope.row.auditedStatus === '2',
+            }"
+          >
+            {{
+              !scope.row.auditedStatus || scope.row.auditedStatus === '0'
+                ? '未审核'
+                : scope.row.auditedStatus === '1'
+                ? '通过'
+                : '不通过'
+            }}
+          </span>
         </template>
       </el-table-column>
       <!-- 操作列(根据“表格类型”显示不同按钮) -->

+ 743 - 1
src/views/EntDeclaration/auditTaskManagement/components/DataRequirementsTab.vue

@@ -1,5 +1,92 @@
 <template>
   <div>
+    <!-- 在线填报弹窗(单记录类型,编辑模式) -->
+    <survey-form-dialog
+      :visible.sync="surveyFormDialogVisible"
+      :survey-data="{ ...(currentTemplateRow || {}), ...surveyDetailData }"
+      :form-fields="formFields"
+      :is-view-mode="isViewMode"
+      :audited-unit-id="auditedUnitId"
+      :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: {},
+        })
+      "
+    />
+
+    <!-- 固定表填报弹窗(编辑模式) -->
+    <fixed-table-dialog
+      :visible.sync="fixedTableDialogVisible"
+      :survey-data="{ ...(currentTemplateRow || {}), fixedHeaders }"
+      :table-items="tableItems"
+      :audit-periods="auditPeriods"
+      :is-view-mode="isViewMode"
+      :audited-unit-id="auditedUnitId"
+      :upload-id="
+        (currentTemplateRow &&
+          (currentTemplateRow.uploadId || currentTemplateRow.id)) ||
+        ''
+      "
+      :survey-template-id="getSurveyTemplateId(currentTemplateRow)"
+      :catalog-id="(currentTemplateRow && currentTemplateRow.catalogId) || ''"
+      @save="
+        $emit('handle-fixed-table-save', {
+          row: currentTemplateRow,
+          tableData: $event,
+        })
+      "
+      @refresh="
+        $emit('handle-fixed-table-save', {
+          row: currentTemplateRow,
+          tableData: {},
+        })
+      "
+    />
+
+    <!-- 动态表填报弹窗(编辑模式) -->
+    <dynamic-table-dialog
+      :key="dynamicDialogKey"
+      :visible.sync="dynamicTableDialogVisible"
+      :survey-data="currentTemplateRow || {}"
+      :table-data="dynamicTableData"
+      :table-items="tableItems"
+      :is-view-mode="isViewMode"
+      :audited-unit-id="auditedUnitId"
+      :upload-id="
+        (currentTemplateRow &&
+          (currentTemplateRow.uploadId || currentTemplateRow.id)) ||
+        ''
+      "
+      :survey-template-id="getSurveyTemplateId(currentTemplateRow)"
+      :catalog-id="(currentTemplateRow && currentTemplateRow.catalogId) || ''"
+      @save="
+        $emit('handle-dynamic-table-save', {
+          row: currentTemplateRow,
+          tableData: $event,
+        })
+      "
+      @refresh="
+        $emit('handle-dynamic-table-save', {
+          row: currentTemplateRow,
+          tableData: {},
+        })
+      "
+    />
+
     <el-button
       type="primary"
       :disabled="isViewMode"
@@ -22,7 +109,12 @@
           </span>
         </template>
       </el-table-column>
-      <el-table-column prop="informationName" label="报送资料" min-width="280">
+      <el-table-column
+        prop="informationName"
+        label="报送资料"
+        min-width="280"
+        align="center"
+      >
         <template slot-scope="scope">
           <div v-if="scope.row.isCategoryHeader" class="category-header-cell">
             {{ scope.row.categoryName }}
@@ -156,6 +248,14 @@
                 查看
               </el-button>
               <el-button
+                v-if="scope.row.formatRequired === '3'"
+                type="text"
+                size="small"
+                @click="handleOnlineSubmission(scope.row)"
+              >
+                在线填报
+              </el-button>
+              <el-button
                 type="text"
                 size="small"
                 @click="handleTemplateDownload(scope.row)"
@@ -225,6 +325,14 @@
     downloadPresetTemplate,
     uploadPresetTemplate,
   } from '@/api/auditTaskProcessing'
+  import {
+    getSingleRecordSurveyList,
+    getSurveyDetail,
+    getDynamicTableData,
+    downloadTemplate,
+    importData,
+  } from '@/api/audit/survey'
+  import { getListBySurveyFdTemplateIdAndVersion } 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'
@@ -270,6 +378,17 @@
         singleDialogVisible: false,
         fixedDialogVisible: false,
         dynamicDialogVisible: false,
+        // 在线填报(编辑)相关
+        surveyFormDialogVisible: false,
+        fixedTableDialogVisible: false,
+        dynamicTableDialogVisible: false,
+        formFields: [],
+        surveyDetailData: {},
+        tableItems: [],
+        auditPeriods: [],
+        dynamicTableData: [],
+        dynamicDialogKey: 0,
+        fixedHeaders: null,
       }
     },
     computed: {},
@@ -278,6 +397,47 @@
     },
 
     methods: {
+      // 在线填报入口:与 CostSurveyTab 一致
+      async handleOnlineSubmission(row) {
+        if (!row) return
+        this.currentTemplateRow = row
+        this.surveyDetailData = {}
+
+        const t = String(row.templateType || row.templatetype || '').trim()
+        // 1=单记录,2=固定表,3=动态表
+        if (t === '1') {
+          if ((row.uploadId || row.id) && this.auditedUnitId) {
+            try {
+              const params = {
+                uploadId: row.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 && typeof res.value === 'object') {
+                  Object.assign(detailData, res.value)
+                }
+                this.surveyDetailData = detailData
+              }
+            } catch (err) {
+              console.error('获取单记录详情失败', err)
+            }
+          }
+          await this.initFormFields()
+        } else if (t === '2') {
+          await this.initFixedTableData()
+        } else if (t === '3') {
+          this.resetDynamicDialogState()
+          await this.initDynamicTableData()
+        }
+      },
       // 预览:与 UploadComponent.vue 的 handlePreview 一致
       handleFileView(row) {
         console.log(row, '这一行数据')
@@ -571,6 +731,588 @@
           this.$message.error(error.message || '模板下载失败,请稍后重试')
         }
       },
+      // 以下为在线填报所需方法,与 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,
+          }
+          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
+              ),
+            }
+            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
+              ),
+            }
+            const res = await getSingleRecordSurveyList(params)
+            if (res && res.code === 200 && res.value) {
+              const { itemlist } = res.value
+              if (itemlist && 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) {
+            console.error('获取固定表配置失败', err)
+            this.tableItems = this.getMockTableItems()
+          }
+        } else if (
+          this.currentTemplateRow &&
+          this.currentTemplateRow.tableItems
+        ) {
+          this.tableItems = this.currentTemplateRow.tableItems
+        } else {
+          this.tableItems = this.getMockTableItems()
+        }
+
+        // 监审期间
+        const currentYear = new Date().getFullYear()
+        this.auditPeriods = [
+          String(currentYear - 2),
+          String(currentYear - 1),
+          String(currentYear),
+        ]
+
+        try {
+          const headerRes = await getListBySurveyFdTemplateIdAndVersion({
+            surveyTemplateId: this.getSurveyTemplateId(this.currentTemplateRow),
+          })
+          if (headerRes && headerRes.code === 200) {
+            this.fixedHeaders = headerRes.value || null
+          } else {
+            this.fixedHeaders = null
+          }
+        } catch (e) {
+          this.fixedHeaders = null
+        }
+
+        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>

+ 13 - 13
src/views/costAudit/auditInfo/auditManage/auditOpinion.vue

@@ -56,7 +56,7 @@
     </div>
 
     <!-- 被审核单位反馈意见 -->
-    <div class="opinion-section">
+    <div v-if="isConclusionEditable" class="opinion-section">
       <div class="opinion-header">
         <h3>监审单位反馈意见:</h3>
       </div>
@@ -88,7 +88,7 @@
     </div>
 
     <!-- 成本审核结论意见 -->
-    <div class="opinion-section">
+    <div v-if="isConclusionEditable" class="opinion-section">
       <div class="opinion-header">
         <h3>成本审核结论意见</h3>
         <el-button
@@ -111,9 +111,9 @@
             :disabled="!isConclusionEditable"
           ></el-input>
         </el-form-item>
-        <el-form-item label="整改要求及时间:">
+        <el-form-item label="其他需要说明的事项:">
           <el-input
-            v-model="conclusionOpinionForm.rectificationRequirements"
+            v-model="conclusionOpinionForm.otherExplanations"
             type="textarea"
             :rows="3"
             :disabled="!isConclusionEditable"
@@ -171,7 +171,7 @@
         conclusionOpinionForm: {
           id: '',
           conclusionOpinion: '',
-          rectificationRequirements: '',
+          otherExplanations: '',
           remark: '',
         },
       }
@@ -224,13 +224,13 @@
             // 回显结论意见数据(如果接口返回了结论意见)
             if (
               data.conclusionOpinion !== undefined ||
-              data.rectificationRequirements !== undefined ||
+              data.otherExplanations !== undefined ||
               data.remark !== undefined
             ) {
               this.conclusionOpinionForm = {
                 id: data.conclusionId || data.id || '',
                 conclusionOpinion: data.conclusionOpinion || '',
-                rectificationRequirements: data.rectificationRequirements || '',
+                otherExplanations: data.otherExplanations || '',
                 remark: data.remark || '',
               }
             }
@@ -307,8 +307,9 @@
               if (res.value && res.value.id) {
                 this.preliminaryOpinionForm.id = res.value.id
               }
-              // 通知父组件刷新列表
-              this.$emit('refresh')
+              // 通知父组件刷新列表并关闭弹窗,要求分页回到第一页
+              this.$emit('refresh', { resetToFirst: true })
+              this.$emit('close')
             } else {
               this.$message({ type: 'error', message: res.message })
             }
@@ -337,8 +338,7 @@
             this.preliminaryOpinionForm.preliminaryOpinion || '',
           // 成本审核结论意见数据
           conclusionOpinion: this.conclusionOpinionForm.conclusionOpinion || '',
-          rectificationRequirements:
-            this.conclusionOpinionForm.rectificationRequirements || '',
+          otherExplanations: this.conclusionOpinionForm.otherExplanations || '',
           remark: this.conclusionOpinionForm.remark || '',
           // 监审单位反馈意见数据
           feedbackOpinion: this.feedbackForm.feedbackOpinion || '',
@@ -369,8 +369,8 @@
               if (res.value && res.value.conclusionId) {
                 this.conclusionOpinionForm.id = res.value.conclusionId
               }
-              // 通知父组件刷新列表并关闭弹窗
-              this.$emit('refresh')
+              // 通知父组件刷新列表并关闭弹窗,要求分页回到第一页
+              this.$emit('refresh', { resetToFirst: true })
               this.$emit('close')
             } else {
               this.$message({ type: 'error', message: res.message })

+ 1 - 1
src/views/costAudit/auditInfo/auditManage/costSurvey.vue

@@ -77,7 +77,7 @@
       </el-table-column>
 
       <!-- 成本调查表名称(点击查看) -->
-      <el-table-column label="成本调查表" min-width="220">
+      <el-table-column label="成本调查表" min-width="220" align="center">
         <template slot-scope="scope">
           <span
             :style="{

+ 4 - 4
src/views/costAudit/auditInfo/auditManage/details.vue

@@ -428,10 +428,10 @@
         this.$emit('update:visible', false)
         this.$emit('close')
       },
-      // 处理审核意见保存成功后的刷新
-      handleAuditOpinionRefresh() {
-        // 触发父组件刷新列表
-        this.$emit('refresh')
+      // 处理审核意见保存成功后的刷新(透传payload)
+      handleAuditOpinionRefresh(payload) {
+        // 触发父组件刷新列表,透传重置页码标记
+        this.$emit('refresh', payload)
       },
       open() {
         // 打开弹窗方法,供父组件通过ref调用

+ 5 - 3
src/views/costAudit/auditInfo/auditManage/index.vue

@@ -388,9 +388,11 @@
         // 可以在这里添加刷新列表的逻辑
       },
 
-      // 刷新表格数据
-      handleRefresh() {
-        // 刷新列表数据
+      // 刷新表格数据(可选重置到第一页)
+      handleRefresh(payload) {
+        if (payload && payload.resetToFirst) {
+          this.currentPage = 1
+        }
         this.loadAuditProjectList()
       },
 

+ 1 - 0
src/views/costAudit/auditInfo/auditManage/submitData.vue

@@ -23,6 +23,7 @@
           prop="informationName"
           label="报送资料"
           min-width="200"
+          align="center"
         />
 
         <el-table-column label="资料类型" width="200" align="center">

+ 2 - 2
src/views/costAudit/projectInfo/auditTaskManage/taskCustomizedRelease/auditNoticeTab.vue

@@ -101,14 +101,14 @@
             >
               修改
             </el-button>
-            <el-button
+            <!-- <el-button
               v-if="!isView"
               type="text"
               size="mini"
               @click="handleSignDocument(scope.row)"
             >
               签章
-            </el-button>
+            </el-button> -->
             <el-button
               v-if="!isView"
               type="text"

+ 57 - 11
src/views/costAudit/projectInfo/auditTaskManage/taskCustomizedRelease/workflowTab.vue

@@ -457,22 +457,41 @@
         this.dialogs.setStepDialogVisible = true
         if (this.workflowData.list.length > 0) {
           this.workflowData.stepList = this.workflowData.list
-          this.workflowData.stepList = this.workflowData.list.map((item) => ({
-            ...item,
-            userId: item.userId ? item.userId.split(',') : [],
-            status: item.status ? item.status.split(',') : [],
-          }))
+          this.workflowData.stepList = this.workflowData.list.map((item) => {
+            const mapped = {
+              ...item,
+              userId: item.userId ? item.userId.split(',') : [],
+              status: item.status ? item.status.split(',') : [],
+            }
+            // 默认预置流转操作:归档环节默认“归档”,其他默认“通过”
+            if (!mapped.status || mapped.status.length === 0) {
+              const defaultKey = this.isArchiveNode(mapped)
+                ? this.getProcessStatusKeyByName('归档')
+                : this.getProcessStatusKeyByName('通过')
+              mapped.status = defaultKey ? [defaultKey] : []
+            }
+            return mapped
+          })
         } else {
           getCostProjectNodeTmpletePageList({
             pageNum: this.workflowData.pagination.currentPage,
             pageSize: this.workflowData.pagination.pageSize,
             processId: '1',
           }).then((res) => {
-            this.workflowData.stepList = res.value.records.map((item) => ({
-              ...item,
-              userId: item.userId ? item.userId.split(',') : [],
-              status: item.status ? item.status.split(',') : [],
-            }))
+            this.workflowData.stepList = res.value.records.map((item) => {
+              const mapped = {
+                ...item,
+                userId: item.userId ? item.userId.split(',') : [],
+                status: item.status ? item.status.split(',') : [],
+              }
+              if (!mapped.status || mapped.status.length === 0) {
+                const defaultKey = this.isArchiveNode(mapped)
+                  ? this.getProcessStatusKeyByName('归档')
+                  : this.getProcessStatusKeyByName('通过')
+                mapped.status = defaultKey ? [defaultKey] : []
+              }
+              return mapped
+            })
             this.workflowData.pagination.total = res.value.total
           })
         }
@@ -480,10 +499,18 @@
       // 设置流程环节
       handleSetStep(row) {
         this.getUser()
+        const statusArr = row.status ? row.status.split(',') : []
+        let finalStatus = statusArr
+        if (!finalStatus || finalStatus.length === 0) {
+          const defaultKey = this.isArchiveNode(row)
+            ? this.getProcessStatusKeyByName('归档')
+            : this.getProcessStatusKeyByName('通过')
+          finalStatus = defaultKey ? [defaultKey] : []
+        }
         this.formData.currentStep = {
           ...row,
           userId: row.userId ? row.userId.split(',') : [],
-          status: row.status ? row.status.split(',') : [],
+          status: finalStatus,
         }
         this.dialogs.stepDialogVisible = true
         this.loading.save = false
@@ -611,6 +638,25 @@
             this.loading.save = false
           })
       },
+      // 判断是否归档环节
+      isArchiveNode(row) {
+        const key = (row && row.processNodeKey) || ''
+        const val = (row && row.processNodeValue) || ''
+        const keyLower = String(key).toLowerCase()
+        return (
+          String(val).includes('归档') ||
+          keyLower === 'gd' ||
+          keyLower === 'guidang' ||
+          keyLower.includes('archive')
+        )
+      },
+      // 根据字典名称获取预置流转操作key
+      getProcessStatusKeyByName(name) {
+        const list = (this.dictData && this.dictData['processStatus']) || []
+        if (!Array.isArray(list)) return ''
+        const item = list.find((it) => it.name === name)
+        return item ? item.key : ''
+      },
     },
   }
 </script>