| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352 |
- <template>
- <div>
- <!-- 在线填报弹窗(单记录类型,编辑模式) -->
- <survey-form-dialog
- :visible.sync="surveyFormDialogVisible"
- :survey-data="{ ...(currentTemplateRow || {}), ...surveyDetailData }"
- :form-fields="formFields"
- :is-view-mode="isViewMode"
- :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: {},
- })
- "
- />
- <!-- 固定表填报弹窗(编辑模式) -->
- <fixed-table-dialog
- :visible.sync="fixedTableDialogVisible"
- :survey-data="{ ...(currentTemplateRow || {}), fixedHeaders }"
- :table-items="tableItems"
- :audit-periods="auditPeriods"
- :is-view-mode="isViewMode"
- :request-type="2"
- :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"
- :request-type="2"
- :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"
- @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"
- align="center"
- >
- <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.isUpload === 1 || scope.row.isUpload === '1'"
- style="color: #67c23a"
- >
- 已上传
- </span>
- <span v-else class="text-danger">未上传</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'">
- <el-button
- v-if="scope.row.isUpload === 1 || scope.row.isUpload === '1'"
- type="text"
- size="small"
- @click="handleFileView(scope.row)"
- >
- 查看
- </el-button>
- <el-button
- v-if="scope.row.isUpload === 1 || scope.row.isUpload === '1'"
- type="text"
- size="small"
- @click="$emit('handleFileDownload', scope.row)"
- >
- 下载
- </el-button>
- <el-button
- v-if="
- scope.row.auditedStatus !== '1' &&
- (currentNode === 'clcs' || currentNode === 'tjcl')
- "
- 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
- type="text"
- size="small"
- @click="handleTemplateDownload(scope.row)"
- >
- 模版下载
- </el-button>
- <el-button
- v-if="
- scope.row.auditedStatus !== '1' &&
- (currentNode === 'clcs' || currentNode === 'tjcl')
- "
- 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"
- :audited-unit-id="auditedUnitId"
- :upload-id="(currentTemplateRow && currentTemplateRow.uploadId) || ''"
- :survey-template-id="getSurveyTemplateId(currentTemplateRow)"
- :catalog-id="(currentTemplateRow && currentTemplateRow.catalogId) || ''"
- />
- <!-- 动态表弹窗(查看模式) -->
- <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 {
- 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'
- 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: '',
- },
- taskId: {
- type: [String, Number],
- default: '',
- },
- },
- data() {
- return {
- pendingUploadRow: null,
- dataUploadAccept: '.xls,.xlsx',
- // 模板查看相关
- currentTemplateRow: null,
- singleDialogVisible: false,
- fixedDialogVisible: false,
- dynamicDialogVisible: false,
- // 在线填报(编辑)相关
- surveyFormDialogVisible: false,
- fixedTableDialogVisible: false,
- dynamicTableDialogVisible: false,
- formFields: [],
- surveyDetailData: {},
- tableItems: [],
- auditPeriods: [],
- dynamicTableData: [],
- dynamicDialogKey: 0,
- fixedHeaders: null,
- }
- },
- computed: {},
- mounted() {
- // 直接使用this.currentNode访问props值,无需在data中重复定义
- },
- 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') {
- // 只要有 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') {
- await this.initFixedTableData()
- } else if (t === '3') {
- this.resetDynamicDialogState()
- await this.initDynamicTableData()
- }
- },
- // 预览:与 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 保持一致
- handleViewTemplate(row) {
- this.currentTemplateRow = row || null
- const t = String(
- (row && (row.templateType || row.templatetype)) || ''
- ).trim()
- if (t === '1') {
- this.singleDialogVisible = true
- } else if (t === '2') {
- this.fixedDialogVisible = true
- } else if (t === '3') {
- this.dynamicDialogVisible = true
- } 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
- // 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 uploadPresetTemplate(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)
- try {
- // 显示加载提示
- const 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
- }
- // if (row.materialId) {
- // params.materialId = row.materialId
- // }
- // 如果接口需要其他参数,可以继续添加
- // 调用下载接口
- const response = await downloadPresetTemplate(params)
- // 关闭加载提示
- loading.close()
- // 处理响应数据
- // response 可能是 { data, headers } 格式,也可能是直接的 Blob
- let blob = response.data || response
- let fileName = ''
- const headers = response.headers || {}
- // 尝试从响应头中获取文件名
- if (headers['content-disposition']) {
- const contentDisposition = headers['content-disposition']
- const fileNameMatch = contentDisposition.match(
- /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/
- )
- if (fileNameMatch && fileNameMatch[1]) {
- fileName = decodeURIComponent(
- fileNameMatch[1].replace(/['"]/g, '')
- )
- }
- }
- // 如果响应头中没有文件名,使用默认文件名
- if (!fileName) {
- const defaultName = row.informationName || row.name || '模板文件'
- fileName = `${defaultName}_模板.xlsx`
- }
- // 确保文件名有扩展名
- if (!/\.[a-zA-Z0-9]+$/.test(fileName)) {
- fileName += '.xlsx'
- }
- // 创建 Blob URL 并触发下载
- const url = window.URL.createObjectURL(new Blob([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)
- // 释放 URL 对象
- window.URL.revokeObjectURL(url)
- this.$message.success('模板下载成功')
- } catch (error) {
- console.error('模板下载失败:', error)
- 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,
- 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) {
- 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),
- type: 2,
- })
- 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>
- <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>
|