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