深海科学与工程研究所安全巡检系统
祖安之光
2025-10-15 6390fa18f5c2df1158a0d664786797b0e8b2fbf9
src/views/components/formDialog.vue
@@ -16,7 +16,7 @@
          size="default"
          ref="formRef"
          :rules="state.formRules"
          label-width="150px"
          label-width="160px"
      >
        <template v-for="(item, index) in config.formItems" :key="index">
        <el-divider v-if="item.type === 'divider'" content-position="left">{{item.content}}</el-divider>
@@ -201,13 +201,11 @@
  title: '',
  formData: {},
  formRules: {},
  // 文件上传相关
  uploadUrl: props.uploadConfig.uploadUrl,
  header: {
    Authorization: getToken()
  },
  fileLists: {}, // 存储各上传字段的文件列表
  // 数据列表
  fileLists: {},
  companyList: [],
  deptList: [],
  userList: [],
@@ -215,34 +213,29 @@
  dialogImageUrl: ''
})
// 初始化表单数据
const initFormData = () => {
  const formData = {}
  state.fileLists = {}
  // 初始化普通表单项
  props.config.formItems?.forEach(item => {
    // 对于多选选择框,默认值为空数组
    if (item.type === 'select' && item.multiple) {
      formData[item.prop] = Array.isArray(item.defaultValue) ? item.defaultValue : []
    } else {
      formData[item.prop] = item.defaultValue !== undefined ? item.defaultValue : null
    }
    // 初始化文件上传字段的文件列表
    if (item.type === 'upload') {
      state.fileLists[item.prop] = []
    }
  })
  // 初始化表单规则
  const formRules = {}
  props.config.formItems?.forEach(item => {
    if (item.rules) {
      formRules[item.prop] = item.rules
    }
    // 为文件上传字段添加自定义验证规则
    if (item.type === 'upload' && item.required) {
      formRules[item.prop] = formRules[item.prop] || []
      formRules[item.prop].push({
@@ -258,7 +251,6 @@
      })
    }
    // 为多选选择框添加自定义验证规则
    if (item.type === 'select' && item.multiple && item.required) {
      formRules[item.prop] = formRules[item.prop] || []
      formRules[item.prop].push({
@@ -278,16 +270,13 @@
  state.formRules = formRules
}
// 获取选项数据
const getOptions = (options) => {
  if (!options) return []
  // 如果是函数,执行函数获取选项
  if (typeof options === 'function') {
    return options()
  }
  // 如果是数组,直接返回
  if (Array.isArray(options)) {
    return options
  }
@@ -298,17 +287,14 @@
const getCascaderOptions = (item) => {
  if (!item.options) return []
  // 如果是函数,执行函数获取选项
  if (typeof item.options === 'function') {
    return item.options()
  }
  // 如果是数组,直接返回
  if (Array.isArray(item.options)) {
    return item.options
  }
  // 如果是响应式引用
  if (item.options && typeof item.options === 'object' && 'value' in item.options) {
    return item.options.value
  }
@@ -316,7 +302,6 @@
  return []
}
// 文件上传前的校验
const beforeUpload = (rawFile, item) => {
  const maxSize = item.maxSize || 5
  if (rawFile.size / 1024 / 1024 > maxSize) {
@@ -326,12 +311,10 @@
  return true
}
// 文件上传成功处理
const handleUploadSuccess = (res, uploadFile, prop) => {
  if (res.code === 200) {
    ElMessage.success('上传成功')
  } else {
    // 上传失败,移除文件
    state.fileLists[prop] = state.fileLists[prop].filter(file => file.uid !== uploadFile.uid)
    ElMessage.warning(res.message || '文件上传失败')
  }
@@ -340,7 +323,6 @@
  }).join(',')
}
// 文件移除处理
const handleRemove = async (file, uploadFiles, prop) => {
  try {
    if(file.uid){
@@ -363,12 +345,10 @@
  state.dialogVisible = true
}
// 超出文件数量限制提示
const showTip = () => {
  ElMessage.warning('超出文件上传数量')
}
// 处理事件
const handleEvent = async (eventName, value) => {
  try {
    if (eventName === 'getUserListByRole' && props.dataLoader.getUserListByRole) {
@@ -390,12 +370,11 @@
  }
}
// 打开对话框
const openDialog = async (type, initialData) => {
  state.title = type === 'add' ? '新增' : type === 'edit' ? '编辑' : type === 'rectify' ? '整改' : '查看'
  // 初始化表单数据
  initFormData()
  // 加载初始数据
  try {
    if (props.dataLoader.loadInitialData) {
      const initialData = await props.dataLoader.loadInitialData(id)
@@ -405,11 +384,10 @@
    console.error('无初始数据:', error)
  }
  // 如果有初始数据,填充表单
  if (initialData) {
    Object.keys(state.formData).forEach(key => {
      if (key in initialData) {
        // 对于多选字段,确保值是数组
        const item = props.config.formItems.find(i => i.prop === key)
        if (item && item.type === 'select' && item.multiple) {
          state.formData[key] = Array.isArray(initialData[key]) ? initialData[key] : (initialData[key] ? [initialData[key]] : [])
@@ -419,7 +397,7 @@
      }
    })
    state.formData.id = initialData.id || null
    // 初始化文件上传字段的文件列表
    props.config.formItems?.forEach(item => {
      if (item.type === 'upload' && initialData[item.prop]) {
        state.fileLists[item.prop] = [{
@@ -448,10 +426,9 @@
  try {
    const valid = await formRef.value.validate()
    if (valid) {
      // 准备提交数据
      const submitData = { ...state.formData }
      // 对于多选字段,如果是空数组则转为null(根据后端需求)
      props.config.formItems?.forEach(item => {
        if (item.type === 'select' && item.multiple &&
            Array.isArray(submitData[item.prop]) &&
@@ -460,7 +437,6 @@
        }
      })
      // 触发提交事件
      emit('submit', submitData, state.title)
    }
  } catch (error) {
@@ -469,20 +445,20 @@
  }
}
// 关闭对话框
const closeDialog = () => {
  formRef.value.clearValidate()
  formRef.value.resetFields()
  dialogVisible.value = false
}
// 暴露方法给父组件
defineExpose({
  openDialog,
  closeDialog
})
// 初始化
initFormData()
</script>
@@ -499,7 +475,7 @@
  margin-top: 7px;
}
// 多选选择框样式调整
:deep(.el-select__tags) {
  white-space: nowrap;
  overflow: hidden;