| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991 |
- <template>
- <el-dialog
- title="调查表填报"
- :visible.sync="dialogVisible"
- width="800px"
- :close-on-click-modal="false"
- :show-close="true"
- append-to-body
- :modal="false"
- @close="handleClose"
- >
- <el-form ref="surveyForm" :model="form" :rules="rules" label-width="120px">
- <el-row :gutter="20">
- <!-- 动态生成表单字段 -->
- <el-col
- v-for="(field, index) in effectiveFormFields"
- :key="`${field.prop || field.id || 'field'}-${index}`"
- :span="field.colSpan || 12"
- >
- <el-form-item :label="field.label" :prop="field.prop">
- <!-- 文本输入框 -->
- <el-input
- v-if="field.type === 'input' || !field.type"
- v-model="form[field.prop]"
- :placeholder="field.placeholder || `请输入${field.label}`"
- :disabled="field.disabled || isViewMode"
- :maxlength="field.formatLength || field.totalLength"
- />
- <!-- 数字输入框 -->
- <el-input-number
- v-else-if="field.type === 'number'"
- v-model="form[field.prop]"
- :placeholder="field.placeholder || `请输入${field.label}`"
- :disabled="field.disabled || isViewMode"
- :min="field.min"
- :max="field.max"
- :precision="field.precision"
- style="width: 100%"
- />
- <!-- 下拉选择框(字典类型) -->
- <el-select
- v-else-if="
- field.type === 'select' && (field.dictCode || field.dictType)
- "
- v-model="form[field.prop]"
- :placeholder="field.placeholder || `请选择${field.label}`"
- :disabled="field.disabled || isViewMode"
- style="width: 100%"
- :clearable="field.clearable !== false"
- :multiple="field.multiple"
- >
- <el-option
- v-for="item in getDictOptions(field.dictCode || field.dictType)"
- :key="item.key || item.value"
- :label="item.name || item.label"
- :value="item.key || item.value"
- />
- </el-select>
- <!-- 下拉选择框(自定义选项) -->
- <el-select
- v-else-if="field.type === 'select' && field.options"
- v-model="form[field.prop]"
- :placeholder="field.placeholder || `请选择${field.label}`"
- :disabled="field.disabled || isViewMode"
- style="width: 100%"
- :clearable="field.clearable !== false"
- :multiple="field.multiple"
- >
- <el-option
- v-for="item in field.options"
- :key="item.value || item.key"
- :label="item.label || item.name"
- :value="item.value || item.key"
- />
- </el-select>
- <!-- 日期选择器 -->
- <el-date-picker
- v-else-if="field.type === 'date'"
- v-model="form[field.prop]"
- type="date"
- :placeholder="field.placeholder || `请选择${field.label}`"
- :disabled="field.disabled || isViewMode"
- style="width: 100%"
- :format="field.format || 'yyyy-MM-dd'"
- :value-format="field.valueFormat || 'yyyy-MM-dd'"
- />
- <!-- 日期时间选择器 -->
- <el-date-picker
- v-else-if="field.type === 'datetime'"
- v-model="form[field.prop]"
- type="datetime"
- :placeholder="field.placeholder || `请选择${field.label}`"
- :disabled="field.disabled || isViewMode"
- style="width: 100%"
- :format="field.format || 'yyyy-MM-dd HH:mm:ss'"
- :value-format="field.valueFormat || 'yyyy-MM-dd HH:mm:ss'"
- />
- <!-- 年份选择器 -->
- <el-date-picker
- v-else-if="field.type === 'year'"
- v-model="form[field.prop]"
- type="year"
- :placeholder="field.placeholder || `请选择${field.label}`"
- :disabled="field.disabled || isViewMode"
- style="width: 100%"
- :format="field.format || 'yyyy'"
- :value-format="field.valueFormat || 'yyyy'"
- />
- <!-- 文本域 -->
- <el-input
- v-else-if="field.type === 'textarea'"
- v-model="form[field.prop]"
- type="textarea"
- :rows="field.rows || 3"
- :placeholder="field.placeholder || `请输入${field.label}`"
- :disabled="field.disabled || isViewMode"
- />
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <div slot="footer" class="dialog-footer">
- <el-button type="primary" @click="handleSave">保存</el-button>
- <el-button @click="handleCancel">取消</el-button>
- </div>
- </el-dialog>
- </template>
- <script>
- import { Message } from 'element-ui'
- import { dictMixin } from '@/mixins/useDict'
- import { saveSingleRecordSurvey } from '@/api/audit/survey'
- import { getListBySurveyTemplateIdAndVersion } from '@/api/costSurveyTemplateHeaders'
- export default {
- name: 'SurveyFormDialog',
- mixins: [dictMixin],
- props: {
- visible: {
- type: Boolean,
- default: false,
- },
- surveyData: {
- type: Object,
- default: () => ({}),
- },
- // 表单字段配置
- // 格式: [
- // {
- // prop: 'institutionName', // 字段属性名
- // label: '机构名称', // 字段标签
- // type: 'input', // 字段类型: input, select, date, number, textarea等
- // colSpan: 12, // 列宽,默认12(占一半)
- // dictType: 'institutionNature', // 字典类型(如果type为select且使用字典)
- // options: [], // 自定义选项(如果type为select且不使用字典)
- // placeholder: '请输入机构名称',
- // rules: [], // 验证规则
- // defaultValue: '', // 默认值
- // disabled: false, // 是否禁用
- // clearable: true, // 是否可清空
- // multiple: false, // 是否多选
- // }
- // ]
- formFields: {
- type: Array,
- default: () => [],
- },
- // 是否查看模式
- isViewMode: {
- type: Boolean,
- default: false,
- },
- // 被监审单位ID
- auditedUnitId: {
- type: String,
- default: '',
- },
- // 上传记录ID
- uploadId: {
- type: String,
- default: '',
- },
- // 成本调查表模板ID
- surveyTemplateId: {
- type: String,
- default: '',
- },
- // 目录ID
- catalogId: {
- type: String,
- default: '',
- },
- // 任务ID
- taskId: {
- type: [String, Number],
- default: '',
- },
- // 统一控制接口 type(1=成本调查表,2=报送资料)
- requestType: {
- type: [String, Number],
- default: 1,
- },
- },
- data() {
- return {
- dialogVisible: false,
- form: {},
- rules: {},
- dictData: {}, // 初始化字典数据对象
- internalFormFields: [],
- }
- },
- computed: {
- // 计算需要获取的字典类型
- dictTypes() {
- const types = new Set()
- this.effectiveFormFields.forEach((field) => {
- const dictKey = field.dictCode || field.dictType
- if (field.type === 'select' && dictKey) {
- types.add(dictKey)
- }
- })
- return Array.from(types)
- },
- effectiveFormFields() {
- const pickVisible = (arr) =>
- (arr || []).filter(
- (f) =>
- f &&
- (f.showVisible === undefined || String(f.showVisible) !== '0')
- )
- if (this.internalFormFields && this.internalFormFields.length > 0) {
- return pickVisible(this.internalFormFields)
- }
- if (Array.isArray(this.formFields) && this.formFields.length > 0) {
- return pickVisible(this.formFields)
- }
- return pickVisible(this.getDefaultFormFields())
- },
- },
- watch: {
- visible: {
- async handler(newVal) {
- this.dialogVisible = newVal
- if (newVal) {
- // 弹窗打开时,强制重新获取字段配置并初始化表单
- // 先清空旧数据,确保重新加载
- this.internalFormFields = []
- this.form = {}
- this.rules = {}
- // 等待字段配置加载完成
- await this.ensureTemplateFields()
- // 确保 DOM 更新后再初始化表单
- await this.$nextTick()
- this.initForm()
- } else {
- // 关闭弹窗时,清理表单数据但保留字段配置(可选)
- // this.internalFormFields = []
- this.form = {}
- this.rules = {}
- if (this.$refs.surveyForm) {
- this.$refs.surveyForm.clearValidate()
- }
- }
- },
- immediate: true,
- },
- dialogVisible(newVal) {
- if (!newVal) {
- this.$emit('update:visible', false)
- }
- },
- formFields: {
- handler(newVal) {
- if (Array.isArray(newVal) && newVal.length > 0) {
- this.internalFormFields = []
- }
- // 字段配置变化时重新初始化
- if (this.dialogVisible) {
- this.initForm()
- }
- },
- deep: true,
- },
- surveyData: {
- async handler() {
- await this.ensureTemplateFields()
- // 详情数据变化时重新初始化表单(用于回显数据)
- if (this.dialogVisible) {
- this.initForm()
- }
- },
- deep: true,
- },
- surveyTemplateId: {
- async handler() {
- await this.ensureTemplateFields()
- if (this.dialogVisible) {
- this.initForm()
- }
- },
- },
- },
- async created() {
- await this.ensureTemplateFields()
- // 初始化字典数据
- this.initDictData()
- },
- methods: {
- async ensureTemplateFields() {
- const hasExternalFields =
- Array.isArray(this.formFields) && this.formFields.length > 0
- const templateId =
- this.surveyTemplateId ||
- this.surveyData.surveyTemplateId ||
- this.surveyData.surveyId ||
- ''
- if (!templateId) {
- return
- }
- // 只有在没有外部字段配置时才获取内部字段
- if (!hasExternalFields) {
- try {
- const params = {
- surveyTemplateId: templateId,
- type: this.requestType,
- }
- 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') {
- // 对象格式:从 fixedFields 和 fixedFieldids 解析
- const { fixedFields, fixedFieldids } = res.value
- if (fixedFields && fixedFieldids) {
- const labels = String(fixedFields)
- .split(',')
- .map((item) => item.trim())
- .filter(Boolean)
- const ids = String(fixedFieldids)
- .split(',')
- .map((item) => item.trim())
- .filter(Boolean)
- mapped = labels.map((label, index) => ({
- prop: ids[index] || `field_${index}`,
- label,
- type: 'input',
- colSpan: 12,
- placeholder: `请输入${label}`,
- required: false,
- }))
- }
- }
- // 使用 Vue.set 确保响应式更新
- if (mapped.length > 0) {
- this.$set(this, 'internalFormFields', mapped)
- }
- }
- } catch (error) {
- console.error('获取调查表字段失败:', error)
- }
- }
- },
- 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 explicitFieldType =
- (getVal(['fieldType', 'field_type'], '') || '') + ''
- const ftLower = explicitFieldType.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 (ftLower === 'boolean' || columnTypeLower.includes('boolean')) {
- type = 'select'
- // 若后端未提供字典,提供是否选项
- if (!options || options.length === 0) {
- options = [
- { label: '是', value: 'true' },
- { label: '否', value: 'false' },
- ]
- }
- } 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 (ftLower === 'integer' || columnTypeLower.includes('int')) {
- type = 'number'
- } else if (
- ftLower === 'double' ||
- columnTypeLower.includes('decimal') ||
- columnTypeLower.includes('float') ||
- columnTypeLower.includes('double')
- ) {
- type = 'number'
- } else if (dictCode || options.length > 0) {
- type = 'select'
- } 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
- )
- let precision = toNumber(
- getVal(
- ['fieldTypeNointLen', 'field_typenointlen', 'precision'],
- undefined
- )
- )
- // 根据字段类型修正精度:integer=0,double=指定小数位
- if (type === 'number') {
- if (ftLower === 'integer') precision = 0
- if (ftLower === 'double' && precision === undefined)
- precision = decimalLength !== undefined ? decimalLength : 2
- }
- 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,
- showVisible: getVal(['showVisible', 'show_visible'], '1'),
- 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) => {
- 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) => {
- 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) => {
- if (value === undefined || value === null || value === '') {
- callback()
- return
- }
- callback()
- },
- trigger: 'change',
- })
- }
- }
- if (type === 'year' || isAuditPeriod) {
- rules.push({
- validator: (_, value, callback) => {
- 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
- },
- // 初始化字典数据
- initDictData() {
- if (this.dictTypes.length > 0) {
- // 初始化字典数据对象
- this.dictTypes.forEach((type) => {
- if (!this.dictData[type]) {
- this.$set(this.dictData, type, [])
- }
- })
- // 调用父级 mixin 的方法获取字典数据
- if (this.dictTypes.length > 0) {
- this.getDictType()
- }
- }
- },
- // 获取字典选项
- getDictOptions(dictType) {
- if (!dictType || !this.dictData || !this.dictData[dictType]) {
- return []
- }
- return this.dictData[dictType] || []
- },
- initForm() {
- const fields = this.effectiveFormFields
- if (!fields || fields.length === 0) {
- return
- }
- const form = {}
- const rules = {}
- fields.forEach((field) => {
- if (!field || !field.prop) {
- return
- }
- // 初始化表单值
- if (
- this.surveyData &&
- this.surveyData[field.prop] !== undefined &&
- this.surveyData[field.prop] !== null &&
- this.surveyData[field.prop] !== ''
- ) {
- form[field.prop] = this.surveyData[field.prop]
- } else if (field.defaultValue !== undefined) {
- form[field.prop] = field.defaultValue
- } else {
- form[field.prop] = field.multiple ? [] : ''
- }
- // 初始化验证规则 - 这是关键!必须正确设置 rules
- // 优先使用字段配置中的 rules(从 mapApiFieldToFormField 返回的完整规则)
- if (
- field.rules &&
- Array.isArray(field.rules) &&
- field.rules.length > 0
- ) {
- // 使用完整的规则数组
- rules[field.prop] = [...field.rules]
- } else if (field.required) {
- // 如果字段是必填的但没有 rules,添加必填验证
- const message =
- field.type === 'select'
- ? `请选择${field.label}`
- : field.type === 'date' ||
- field.type === 'datetime' ||
- field.type === 'year'
- ? `请选择${field.label}`
- : `请输入${field.label}`
- rules[field.prop] = [
- {
- required: true,
- message: message,
- trigger:
- field.type === 'select' ||
- field.type === 'date' ||
- field.type === 'datetime' ||
- field.type === 'year'
- ? 'change'
- : 'blur',
- },
- ]
- }
- })
- // 使用 Vue.set 确保响应式更新
- this.$set(this, 'form', form)
- this.$set(this, 'rules', rules)
- // 初始化字典数据
- this.initDictData()
- // 确保表单组件能识别新的规则
- this.$nextTick(() => {
- if (this.$refs.surveyForm) {
- this.$refs.surveyForm.clearValidate()
- }
- })
- },
- // 获取默认表单字段配置(兼容旧版本)
- getDefaultFormFields() {
- return [
- // {
- // prop: 'institutionName',
- // label: '机构名称',
- // type: 'input',
- // colSpan: 12,
- // defaultValue: '幼儿园基本情况',
- // required: true,
- // },
- // {
- // prop: 'institutionNature',
- // label: '机构性质',
- // type: 'select',
- // colSpan: 12,
- // dictType: 'institutionNature', // 字典类型
- // defaultValue: '公办',
- // required: true,
- // },
- // {
- // prop: 'institutionLevel',
- // label: '机构评定等级',
- // type: 'select',
- // colSpan: 12,
- // dictType: 'institutionLevel', // 字典类型
- // defaultValue: '省一级',
- // required: true,
- // },
- // {
- // prop: 'educationMode',
- // label: '机构办学方式',
- // type: 'select',
- // colSpan: 12,
- // dictType: 'educationMode', // 字典类型
- // defaultValue: '全日制',
- // required: true,
- // },
- // {
- // prop: 'institutionAddress',
- // label: '机构地址',
- // type: 'input',
- // colSpan: 12,
- // required: true,
- // },
- // {
- // prop: 'formFiller',
- // label: '机构填表人',
- // type: 'input',
- // colSpan: 12,
- // required: true,
- // },
- // {
- // prop: 'financialManager',
- // label: '机构财务负责人',
- // type: 'input',
- // colSpan: 12,
- // required: true,
- // },
- // {
- // prop: 'contactPhone',
- // label: '机构联系电话',
- // type: 'input',
- // colSpan: 12,
- // required: true,
- // rules: [
- // {
- // required: true,
- // message: '请输入机构联系电话',
- // trigger: 'blur',
- // },
- // {
- // pattern: /^1[3-9]\d{9}$/,
- // message: '请输入正确的手机号码',
- // trigger: 'blur',
- // },
- // ],
- // },
- // {
- // prop: 'formFillDate',
- // label: '机构填表日期',
- // type: 'date',
- // colSpan: 12,
- // required: true,
- // },
- ]
- },
- handleClose() {
- this.dialogVisible = false
- this.$emit('update:visible', false)
- },
- handleCancel() {
- this.handleClose()
- },
- async handleSave() {
- this.$refs.surveyForm.validate(async (valid) => {
- if (valid) {
- try {
- // 判断是否有数据(编辑模式):如果有 uploadId,说明是编辑已有数据
- const hasData = !!(
- this.uploadId ||
- this.surveyData.uploadId ||
- this.surveyData.id
- )
- // 将表单数据转换为接口需要的格式
- const saveData = this.effectiveFormFields.map((field) => {
- const dataItem = {
- auditedUnitId:
- this.auditedUnitId || this.surveyData.auditedUnitId || '',
- surveyTemplateId:
- this.surveyTemplateId ||
- this.surveyData.surveyTemplateId ||
- '',
- catalogId: this.catalogId || this.surveyData.catalogId || '',
- taskId: this.taskId || this.surveyData.taskId || '',
- rowid: field.prop, // 字段ID(对应 fixedFieldids)
- rkey: field.label, // 字段名称(对应 fixedFields,即 label)
- rvalue: this.form[field.prop] || '', // 字段值(表单输入的值)
- type: this.requestType,
- }
- // 如果有数据(编辑模式),添加 uploadId 字段
- if (hasData) {
- dataItem.uploadId =
- this.uploadId ||
- this.surveyData.uploadId ||
- this.surveyData.id ||
- ''
- }
- return dataItem
- })
- console.log('保存表单数据:', saveData)
- // 调用保存接口
- const res = await saveSingleRecordSurvey(saveData)
- if (res && res.code === 200) {
- Message.success('保存成功')
- // 触发保存事件,将数据传递给父组件
- this.$emit('save', { ...this.form })
- // 触发刷新事件,通知父组件刷新列表
- this.$emit('refresh')
- this.handleClose()
- } else {
- Message.error(res.message || '保存失败')
- }
- } catch (err) {
- console.error('保存失败', err)
- // Message.error(err.message || '保存失败')
- }
- } else {
- Message.error('请完善表单信息')
- return false
- }
- })
- },
- },
- }
- </script>
- <style scoped lang="scss">
- .dialog-footer {
- text-align: center;
- .el-button {
- margin: 0 10px;
- }
- }
- ::v-deep .el-dialog__header {
- padding: 20px 20px 10px;
- .el-dialog__title {
- font-size: 18px;
- font-weight: 600;
- color: #303133;
- }
- }
- ::v-deep .el-form-item {
- margin-bottom: 20px;
- .el-form-item__label {
- // color: #409eff;
- font-weight: 500;
- }
- }
- </style>
|