| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781 |
- <template>
- <div>
- <!-- 调查表填报弹窗(单记录类型,只读) -->
- <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
- prop="dataType"
- label="资料类型"
- width="120"
- align="center"
- />
- <!-- 表格类型 -->
- <el-table-column
- prop="tableType"
- label="表格类型"
- width="120"
- align="center"
- />
- <!-- 是否必填 -->
- <el-table-column
- prop="isRequired"
- label="是否必填"
- width="100"
- align="center"
- >
- <template slot-scope="scope">
- <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>
- </template>
- </el-table-column>
- </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>
- </template>
- <script>
- 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>
|