|
|
- import _ from 'lodash'
- import { getuuid, isEqual, isValueEmpty } from '@/utils/index.js'
- import { isShowOtherByCheckboxTree } from '@/utils/formPackageCommon.js'
- export default {
- inject: ['getZdxgjl', 'updateZdxgjl'],
- watch: {
- formData: {
- immediate: true,
- deep: true, // 深度监听,以便检测嵌套对象变化
- handler(v) {
- if (v) {
- this.handleFormField(true)
- }
- }
- },
- fieldItemLabel: {
- immediate: true,
- deep: true, // 深度监听,以便检测嵌套对象变化
- handler(v) {
- if (v) {
- console.log(v, 'fieldItemLabel')
- }
- }
- },
- formConfig: {
- immediate: true,
- deep: true, // 深度监听,以便检测嵌套对象变化
- handler(v) {
- this.handleFormField()
- }
- }
- },
- data() {
- return {
- uuid: getuuid(),
- oldFormFields: {},
- clickableKey: ''
- }
- },
- mounted() {
- this.handleFormField()
- },
- unmounted() {
- this.formFields = {} //清空当前填写的数据
- },
-
- methods: {
- onSelectChange(key, val, type) {
- // 获取对应的配制
- const currentConfig = this.allFieldsConfig[key]
- if (currentConfig?.selectTo) {
- this.formFields[currentConfig?.selectTo] = val
- }
- this.onValueChangeCompareTo(key, val)
- this.formFields[key] = val
- this.$emit('select', { key, value: val, type, ...this.formFields })
- // 清除该表单项的错误状态
- if (this.errors[key]) {
- this.$set(this.errors, key, false)
- }
- },
-
- //试剂/仪器等弹窗提交
- onRegentSubmit(data, inputValue, key, item) {
- this.updateFormData(key, inputValue)
- this.$emit('onRegentSubmit', {
- selectInfo: data,
- inputValue,
- key,
- config: item
- })
- },
- getRegentItem(item, fieldCode = 'type') {
- const type = item[fieldCode]
- const fillType =
- fieldCode === 'type' ? item.fillType : item.subFillType || item.fillType
- return {
- label: '',
- type,
- fillType,
- parentLabel: item.label,
- filledCodes: item.filledCodes,
- qxbdType: item.qxbdType,
- checkType: item.checkType,
- regentFillType: item.regentFillType
- }
- },
-
- handleClickButton(key) {
- this.$emit('clickButton', key)
- },
- getFillType(type) {
- const typeObj = {
- actFill: 'orange-border', //实际填写的边框颜色
- green: 'green-border',
- preFill: 'blue-border' //预填写的边框颜色
- }
- return typeObj[type] || ''
- },
- onInputNumberChange(key, val) {
- this.formFields[key] = val
- // 清除该表单项的错误状态
- if (this.errors[key]) {
- this.$set(this.errors, key, false)
- }
- },
- //批量更新表单数据
- batchUpdateFormData(data) {
- const cloneFormFields = JSON.parse(JSON.stringify(this.formFields))
- Object.keys(data).forEach((key) => {
- this.oldFormFields[key] = cloneFormFields[key]
- this.formFields[key] = data[key]
- // 清除该表单项的错误状态
- if (this.errors[key]) {
- this.$set(this.errors, key, false)
- }
- })
- },
- //更新表单数据
- updateFormData(key, value, data) {
- const { isUpdateRecord, signData } = data || {}
- // 深拷贝当前表单数据,避免直接修改原数据
- const cloneFormFields = JSON.parse(JSON.stringify(this.formFields))
-
- this.oldFormFields[key] = cloneFormFields[key]
- this.formFields[key] = value
- // 清除该表单项的错误状态
- if (this.errors[key]) {
- this.$set(this.errors, key, false)
- }
-
- if (isUpdateRecord) {
- setTimeout(() => {
- this.$refs[key][0].handleUpdateRecord(signData, {
- oldValue: this.oldFormFields[key],
- inputValue: value
- })
- }, 10)
- }
- },
-
- handleClickable(sItem, key) {
- if (this.templateFillType !== 'actFill') {
- return
- }
- this.clickableKey = key
- this.$emit('clickable', sItem)
- },
- //根据span判断一行显示几列
- getSpanClass(sItem) {
- const spanArr = ['full-row', '', 'three-row']
- if (sItem.span) {
- return spanArr[sItem.span - 1]
- }
- return ''
- },
- //获取其他下拉框的配制
- getOtherItem(sItem) {
- return {
- label: sItem.otherLabel
- ? this.$t(sItem.otherLabel)
- : this.$t('template.common.other'),
- fillType: sItem.fillType,
- maxlength: sItem.otherMaxlength || 50,
- parentLabel: sItem.label,
- options: sItem.otherOptions || []
- }
- },
- getRadioOtherItem(sItem) {
- return {
- // label: sItem.otherLabel ? this.$t(sItem.otherLabel) : this.$t("template.common.other"),
- fillType: sItem.fillType,
- maxlength: sItem.otherMaxlength || 50,
- parentLabel: sItem.label
- }
- },
- getClickableItem(sItem) {
- return {
- label: '',
- type: 'clickable',
- fillType: sItem.subFillType || sItem.fillType,
- parentLabel: sItem.label
- }
- },
- getSubItem(sItem) {
- const config = {
- label: '',
- options: sItem.subOptions || [],
- fillType: sItem.subFillType || sItem.fillType,
- parentLabel: sItem.label
- }
- if (sItem.subDisabled) {
- config.disabled = sItem.subDisabled
- }
- return config
- },
- //获取第三个的配制
- getThirdItem(sItem) {
- const config = {
- label: '',
- options: sItem.thirdOptions || [],
- fillType: sItem.thirdFillType,
- parentLabel: sItem.label,
- maxlength: sItem.thirdMaxlength || 50
- }
- if (sItem.thirdDisabled) {
- config.disabled = sItem.thirdDisabled
- }
- return config
- },
- // 根据formConfig回填form表单数据
- handleFormField(update = false) {
- const result = {}
- let config = {}
- const { formConfig, formData, formFields } = this
- // 遍历配制
- formConfig.forEach((item) => {
- if (item.config) {
- // 合并配制项
- config = { ...config, ...item.config }
-
- // 处理每个配制项
- Object.keys(item.config).forEach((key) => {
- const currentConfig = item.config[key]
- let value = formData[key]
-
- // 如果formFields中已经有值,保持原值(用户输入或之前设置的值)
- if (
- formFields[key] !== null &&
- formFields[key] !== undefined &&
- formFields[key] !== ''
- // typeof formFields[key] !== 'object'
- ) {
- // 保留原值,不使用formData中的值
- result[key] = formFields[key]
- } else {
- // 使用formData中的值
- result[key] = value
- }
-
- // 处理特殊字段 - "其他"字段
- if (currentConfig.otherCode) {
- const { otherCode, type } = currentConfig
- //如果是更新的话,优先使用formFields中的值
- if (update) {
- result[otherCode] =
- formFields[otherCode] || formData[otherCode] || ''
- } else {
- result[otherCode] =
- formData[otherCode] || formFields[otherCode] || ''
- }
- config[otherCode] = {
- label: 'template.common.other',
- parentType: type,
- parentKey: key,
- type: 'input',
- fillType: currentConfig.fillType
- }
- }
- if (currentConfig.thirdOtherCode) {
- const { thirdOtherCode, type } = currentConfig
- //如果是更新的话,优先使用formFields中的值
- if (update) {
- result[thirdOtherCode] =
- formFields[thirdOtherCode] || formData[thirdOtherCode] || ''
- } else {
- result[thirdOtherCode] =
- formData[thirdOtherCode] || formFields[thirdOtherCode] || ''
- }
- config[thirdOtherCode] = {
- label: 'template.common.other',
- parentType: type,
- parentKey: key,
- type: 'input',
- fillType: currentConfig.fillType
- }
- }
- if (currentConfig.subKey) {
- const { subKey } = currentConfig
- if (update) {
- result[subKey] = formFields[subKey] || formData[subKey] || ''
- } else {
- result[subKey] = formData[subKey] || formFields[subKey] || ''
- }
- config[subKey] = {
- label: currentConfig.label,
- subKey,
- type: currentConfig.subType,
- fillType: currentConfig.subFillType || currentConfig.fillType,
- selectTo: currentConfig.selectTo
- }
- }
- if (currentConfig.thirdKey) {
- const { thirdKey } = currentConfig
- if (update) {
- result[thirdKey] =
- formFields[thirdKey] || formData[thirdKey] || ''
- } else {
- result[thirdKey] =
- formFields[thirdKey] || formData[thirdKey] || ''
- }
- config[thirdKey] = {
- label: currentConfig.label,
- thirdKey,
- type: currentConfig.thirdType,
- fillType: currentConfig.thirdFillType,
- selectTo: currentConfig.selectTo
- }
- }
- if (currentConfig.fourthKey) {
- const { fourthKey } = currentConfig
- if (update) {
- result[fourthKey] =
- formFields[fourthKey] || formData[fourthKey] || ''
- } else {
- result[fourthKey] =
- formFields[fourthKey] || formData[fourthKey] || ''
- }
- config[fourthKey] = {
- label: currentConfig.label,
- fourthKey,
- type: currentConfig.fourthType,
- fillType: currentConfig.fourthFillType,
- selectTo: currentConfig.selectTo
- }
- }
-
- // 检查compareTo字段
- if (
- currentConfig.compareTo &&
- formData[currentConfig.compareTo] &&
- result[key]
- ) {
- const compareToValue = formData[currentConfig.compareTo]
- const currentValue = result[key]
- this.compareFieldsIsEqual(currentValue, compareToValue, key)
- }
- // 检查compareTo字段
- if (
- currentConfig.subCompareTo &&
- formData[currentConfig.subCompareTo] &&
- result[currentConfig.subKey]
- ) {
- const compareToValue = formData[currentConfig.subCompareTo]
- const currentValue = result[currentConfig.subKey]
- this.compareFieldsIsEqual(
- currentValue,
- compareToValue,
- currentConfig.subKey
- )
- }
- if (
- currentConfig.otherCodeCompareTo &&
- formData[currentConfig.otherCodeCompareTo] &&
- result[currentConfig.otherCode]
- ) {
- const compareToValue = formData[currentConfig.otherCodeCompareTo]
- const currentValue = result[currentConfig.otherCode]
- this.compareFieldsIsEqual(
- currentValue,
- compareToValue,
- currentConfig.otherCode
- )
- }
- })
-
- // 处理可能存在的直接otherCode字段
- if (item.config?.otherCode) {
- config[item.config?.otherCode] = item.config?.otherCode
- }
- if (item.config?.thirdOtherCode) {
- config[item.config?.thirdOtherCode] = item.config?.thirdOtherCode
- }
- }
- })
- // 处理selectInfo_开头的字段,步骤表单需要保留selectInfo_开头的字段
- const selectInfoKeys = Object.keys(formData).filter((key) =>
- key.startsWith('selectInfo_')
- )
- selectInfoKeys.forEach((key) => {
- result[key] = formData[key]
- })
- // 更新表单字段
- this.formFields = { ...result }
- this.allFieldsConfig = config
- },
- //比较值是否相等
- compareFieldsIsEqual(currentValue, compareToValue, key) {
- if (!currentValue || !compareToValue) return
- // 如果当前值与compareTo字段的值不相等,则设置橙色背景
- if (isEqual(currentValue, compareToValue)) {
- // 如果相等,移除橙色背景(如果之前设置了的话)
- this.$set(this.orangeBgFields, key, false)
- } else {
- this.$set(this.orangeBgFields, key, true)
- }
- },
- //判断是否禁用
- getDisabled() {
- const { item } = this
- const { fillType } = item
- if (item.hasOwnProperty('disabled')) {
- return item.disabled
- } else {
- if (fillType === 'actFill') {
- //当模板状态是实际填写时,只有当fillType是actFill时才能填写
- return this.templateFillType !== 'actFill'
- } else if (fillType === 'preFill') {
- //当模板状态是预填写时,只有当fillType是preFill才能填写
- return this.templateFillType !== 'preFill'
- } else {
- return true
- }
- }
- },
- // 表单数据校验
- validateFormData() {
- const { formFields, allFieldsConfig } = this
- const errors = []
- // 清空之前的错误状态
- this.errors = {}
- for (const key in allFieldsConfig) {
- const o = allFieldsConfig[key]
- if (o.otherCode) {
- //
- if (o.type === 'select') {
- const isSelectedOther = this.isShowOther(formFields[key], o)
- if (!isSelectedOther) {
- //如果其他选项没有被选择,清空其他字段
- formFields[o.otherCode] = ''
- }
- } else if (o.subType === 'select') {
- const isSelectedOther = this.isShowOther(formFields[o.subKey], o)
- if (!isSelectedOther) {
- //如果其他选项没有被选择,清空其他字段
- formFields[o.otherCode] = ''
- }
- } else if (o.type === 'radioAndOther') {
- const isSelectedOther = this.isShowOtherByRadioAndOther(
- formFields[key],
- o
- )
- if (!isSelectedOther) {
- //如果其他选项没有被选择,清空其他字段
- formFields[o.otherCode] = ''
- }
- }
- }
- if (o.type === 'attachment' && o.fillType === this.templateFillType) {
- const attValue = formFields[key]
- if (!attValue || attValue == '[]') {
- errors.push({
- field: key,
- label: o.label,
- error: '请上传附件'
- })
- this.$set(this.errors, key, true)
- }
- } else if (o.type === 'fqyq' && o.fillType === this.templateFillType) {
- const fqyqValue = formFields[key] || {}
- const { mainRadio, subRadio, inputValue } = fqyqValue
- if (!mainRadio) {
- errors.push({
- field: key,
- label: o.label,
- error: '请选择是否在规定时间完成'
- })
- this.$set(this.errors, key, true)
- } else {
- if (mainRadio === '是') {
- if (!subRadio) {
- errors.push({
- field: key,
- label: o.label,
- error: '请选择是否在规定时间完成'
- })
- this.$set(this.errors, key, true)
- } else if (!inputValue) {
- errors.push({
- field: key,
- label: o.label,
- error: '请输入信息'
- })
- this.$set(this.errors, key, true)
- }
- }
- }
-
- continue
- } else if (
- o.type === 'checkboxTree' &&
- o.fillType === this.templateFillType
- ) {
- const checkboxTreeValue = formFields[key] || {}
- const { checkedValues = [], otherValues = {} } = checkboxTreeValue
- const { options = [] } = o
- //需要校验第一层是否有选中项
- const parentOptions = options.map((item) => item.label)
- const isChecked = checkedValues.some((option) => {
- return option.checked === true
- })
- //获取所有选中的选项
- const allCheckedOptions = checkedValues
- .filter((item) => item.checked)
- .map((item) => item.label)
- //再筛选出需要显示其他输入框的选项
- const otherOptions = allCheckedOptions.filter((label) =>
- isShowOtherByCheckboxTree(label)
- )
- const isHasOtherInfo = otherOptions.every((item) => otherValues[item])
- console.log(isChecked, isHasOtherInfo, 'isChecked')
- if (!isChecked || !isHasOtherInfo) {
- errors.push({
- field: key,
- label: o.label,
- error: '请选择方法学验证'
- })
- this.$set(this.errors, key, true)
- }
- continue
- } else if (
- o.type === 'radioAndOther' &&
- o.fillType === this.templateFillType
- ) {
- const radioValue = formFields[key] || {}
- const { otherCode } = o
- const otherValue = formFields[otherCode] || ''
- const isShow = this.isShowOtherByRadioAndOther(radioValue, o)
- if (isShow && !otherValue) {
- errors.push({
- field: key,
- label: o.label,
- error: '请输入信息'
- })
- this.$set(this.errors, key, true)
- }
- // if (!radioValue) {
- // errors.push({
- // field: key,
- // label: o.label,
- // error: "请选择方法学验证"
- // });
- // this.$set(this.errors, key, true);
- // }
- continue
- }
- if (isValueEmpty(formFields[key])) {
- // 其他字段需要判断是否显示再校验
- if (
- o.label === 'template.common.other' &&
- !this.isShowOther(formFields[o.parentKey])
- ) {
- continue
- }
-
- //span的字段不校验
- if (o.type === 'span' || o.type === 'text' || o.type === 'button') {
- continue
- }
- if (o.fillType === this.templateFillType && !o.disabled) {
- let prefix = ''
- if (
- o.type === 'input' ||
- o.type === 'inputNumber' ||
- o.type === 'textarea'
- ) {
- prefix = '填写'
- } else {
- prefix = '选择'
- }
-
- const errorItem = {
- field: key,
- label: o.label,
- error: `请${prefix}${o.label}`
- }
-
- errors.push(errorItem)
- this.$set(this.errors, key, true)
- }
- }
- }
- console.log(errors, 'errors')
- return {
- valid: errors.length === 0,
- errors: errors
- }
- },
- getFormData() {
- // 同时执行数据校验和子组件校验
- const validateResult = this.validateFormData()
- const subComponentValidateResult = this.validateSubComponents()
- // const subComponentValidateResult = {valid: true, error: ''};
-
- return new Promise((resolve, reject) => {
- if (validateResult.valid && subComponentValidateResult.valid) {
- resolve(this.formFields)
- } else if (!validateResult.valid) {
- // this.$message.error("表单内容未填完,请填写后再提交");
- reject(validateResult.errors[0].error)
- } else {
- reject(subComponentValidateResult.error)
- }
- })
- },
- // 子组件校验钩子方法,子组件可以重写此方法来添加额外的校验逻辑
- validateSubComponents() {
- return {
- valid: true,
- error: ''
- }
- },
- //直接获取表单数据,不做校验
- getFilledFormData() {
- return this.formFields
- },
- getFormDataByKey(key) {
- return this.formFields[key]
- },
- onBlur(key, val) {
- // compareTo 功能:当fillType==="actFill"时,判断当前值是否与compareTo字段的值一样,如果不一样则将当前input框的背景色标记成橙色
- this.onValueChangeCompareTo(key, val)
- if (this.errors[key]) {
- this.$set(this.errors, key, false)
- }
- this.$emit('blur', { key, value: val, ...this.formFields })
- },
- onValueChangeCompareTo(key, val, compKey) {
- // compareTo 功能:当fillType==="actFill"时,判断当前值是否与compareTo字段的值一样,如果不一样则将当前input框的背景色标记成橙色
- const currentFieldConfig = this.allFieldsConfig[key]
- if (currentFieldConfig && currentFieldConfig.fillType === 'actFill') {
- if (currentFieldConfig.compareTo || compKey) {
- const compareToKey = compKey || currentFieldConfig.compareTo
- const compareToValue = this.formFields[compareToKey]
- this.compareFieldsIsEqual(val, compareToValue, key)
- }
- if (
- currentFieldConfig.otherCodeCompareTo &&
- this.formFields[currentFieldConfig.otherCodeCompareTo] &&
- this.formFields[currentFieldConfig.otherCode]
- ) {
- const compareToValue =
- this.formFields[currentFieldConfig.otherCodeCompareTo]
- const currentValue = this.formFields[currentFieldConfig.otherCode]
- this.compareFieldsIsEqual(
- currentValue,
- compareToValue,
- currentFieldConfig.otherCode
- )
- }
- if (
- currentFieldConfig.subCompareTo &&
- this.formFields[currentFieldConfig.subCompareTo] &&
- this.formFields[currentFieldConfig.subKey]
- ) {
- const compareToValue =
- this.formFields[currentFieldConfig.subCompareTo]
- const currentValue = this.formFields[currentFieldConfig.subKey]
- this.compareFieldsIsEqual(
- currentValue,
- compareToValue,
- currentFieldConfig.subKey
- )
- }
- }
- },
- onAttachmentChange(key, val) {
- this.formFields[key] = val
- // 清除该表单项的错误状态
- if (this.errors[key]) {
- this.$set(this.errors, key, false)
- }
-
- // 如果是checkboxList类型,需要处理otherValues
- if (val && typeof val === 'object' && val.otherValues) {
- // 将otherValues中的每个值也保存到formFields中
- Object.keys(val.otherValues).forEach((otherCode) => {
- this.formFields[otherCode] = val.otherValues[otherCode]
- })
- }
- },
- //复制
- onCopy(config, key) {
- const { formFields } = this
- if (config.copyFrom) {
- formFields[key] = formFields[config.copyFrom]
- this.onBlur(key, formFields[key])
- }
- },
- resetRecord(key) {
- this.formFields = { ...this.formFields, ...this.oldFormFields }
- this.oldFormFields = {}
- }
- }
- }
|