newOaWorkflowForm.vue 8.6 KB
<template>
  <div class="new-oa-workflow-form">
    <el-card class="form-card">
      <el-form ref="form" :model="formData" label-width="120px" label-position="right" class="text-left">
        <div v-for="(item, index) in components" :key="index">
          <!-- 标题 -->
          <el-divider v-if="item.type == 'text'" content-position="left">
            <span class="form-title">{{ item.text }}</span>
          </el-divider>

          <!-- 文本框 -->
          <el-form-item v-if="item.type == 'textfield'" :label="item.label" :prop="item.key"
            :rules="getValidationRules(item)">
            <el-input v-model="item.value" :placeholder="item.description" clearable>
            </el-input>
          </el-form-item>

          <!-- 数字框 -->
          <el-form-item v-if="item.type == 'number'" :label="item.label" :prop="item.key"
            :rules="getValidationRules(item)">
            <el-input-number v-model="item.value" :placeholder="item.description" :min="0" style="width: 100%">
            </el-input-number>
          </el-form-item>

          <!-- 文本域 -->
          <el-form-item v-if="item.type == 'textarea'" :label="item.label" :prop="item.key"
            :rules="getValidationRules(item)">
            <el-input v-model="item.value" type="textarea" :rows="4" :placeholder="item.description">
            </el-input>
          </el-form-item>

          <!-- 日期选择 -->
          <el-form-item v-if="item.type == 'textdate'" :label="item.label" :prop="item.key"
            :rules="getValidationRules(item)">
            <el-date-picker v-model="item.value" type="date" :placeholder="item.description" format="yyyy-MM-dd"
              value-format="yyyy-MM-dd" style="width: 100%">
            </el-date-picker>
          </el-form-item>

          <!-- 时间选择 -->
          <el-form-item v-if="item.type == 'textdatetime'" :label="item.label" :prop="item.key"
            :rules="getValidationRules(item)">
            <el-time-picker v-model="item.value" :placeholder="item.description" format="HH:mm"
              value-format="HH:mm" style="width: 100%">
            </el-time-picker>
          </el-form-item>

          <!-- 单选框 -->
          <el-form-item v-if="item.type == 'radio'" :label="item.label" :prop="item.key"
            :rules="getValidationRules(item)">
            <el-radio-group v-model="item.value">
              <el-radio v-for="(option, optionIndex) in item.values" :key="optionIndex" :label="option.value">
                {{ option.label }}
              </el-radio>
            </el-radio-group>
          </el-form-item>

          <!-- 下拉选择 -->
          <el-form-item v-if="item.type == 'select'" :label="item.label" :prop="item.key"
            :rules="getValidationRules(item)">
            <el-select v-model="item.value" :placeholder="item.description" style="width: 100%" clearable>
              <el-option v-for="(option, optionIndex) in item.values" :key="optionIndex" :label="option.label"
                :value="option.value">
              </el-option>
            </el-select>
          </el-form-item>

          <!-- 复选框 -->
          <el-form-item v-if="item.type == 'checkbox'" :label="item.label" :prop="item.key"
            :rules="getValidationRules(item)">
            <el-checkbox-group v-model="item.value">
              <el-checkbox v-for="(option, optionIndex) in item.values" :key="optionIndex" :label="option.value">
                {{ option.label }}
              </el-checkbox>
            </el-checkbox-group>
          </el-form-item>

          <!-- 文件上传 -->
          <el-form-item v-if="item.type == 'button' && item.action == 'submit'" :label="$t('common.file')">
            <div class="upload-section">
              <upload-file ref="uploadFile" @notify="handleFileUpload" />
            </div>
          </el-form-item>

          <!-- 提交按钮 -->
          <el-form-item v-if="item.type == 'button' && item.action == 'submit'" class="text-right">
            <el-button type="primary" @click="_doSubmit" :loading="submitLoading">
              <i class="el-icon-check"></i>
              {{ item.label }}
            </el-button>
          </el-form-item>

          <!-- 重置按钮 -->
          <el-form-item v-if="item.type == 'button' && item.action == 'reset'"  class="text-right">
            <el-button @click="_doReset">
              <i class="el-icon-refresh"></i>
              {{ item.label }}
            </el-button>
          </el-form-item>
        </div>

      </el-form>
    </el-card>
  </div>
</template>

<script>
import UploadFile from '@/components/upload/uploadFile'
import { queryOaWorkflowForm, saveOaWorkflowFormData } from '@/api/oa/newOaWorkflowApi'

export default {
  name: 'NewOaWorkflowForm',
  components: { UploadFile },

  data() {
    return {
      formJson: {},
      components: [],
      formData: {},
      fileName: '',
      realFileName: '',
      callBackListener: 'newOaWorkflowForm',
      callBackFunction: 'fileName',
      submitLoading: false,
      showUploadComponent: false
    }
  },

  mounted() {
  },

  methods: {
    open(params) {
      this.flowId = params.flowId
      this.listOaWorkflowForm()
    },

    async listOaWorkflowForm() {
      try {
        const res = await queryOaWorkflowForm({
          page: 1,
          row: 1,
          flowId: this.flowId
        })
        console.log(res)
        this.formJson = JSON.parse(res.data[0].formJson)
        this.initForm()
      } catch (error) {
        console.error('获取表单配置失败:', error)
        this.$message.error('获取表单配置失败')
      }
    },

    initForm() {
      this.components = this.formJson.components
      this.formData = {}

      this.components.forEach(item => {
        if (item.type !== 'button' && item.type !== 'text') {
          // 初始化表单数据
          if (item.type === 'checkbox') {
            this.formData[item.key] = []
          } else if (item.type === 'radio' || item.type === 'select') {
            this.formData[item.key] = item.values && item.values.length > 0 ? item.values[0].value : ''
          } else {
            this.formData[item.key] = ''
          }
        }
      })
    },

    getValidationRules(item) {
      const rules = []
      if (item.validate && item.validate.required) {
        rules.push({
          required: true,
          message: `${item.label}不能为空`,
          trigger: 'blur'
        })
      }
      return rules
    },

    async _doSubmit() {
      try {
        // 表单验证
        await this.$refs.form.validate()

        this.submitLoading = true

        const _data = {
          fileName: this.fileName,
          realFileName: this.realFileName,
          flowId: this.flowId,
          ...this.formData
        }

        const res = await saveOaWorkflowFormData(_data)
        if (res.code === 0) {
          this.$message.success(this.$t('common.submitSuccess'))
          this.resetForm()
          this.$emit('switch-tab', 'newOaWorkflowPool')
        } else {
          this.$message.error(res.msg || this.$t('common.submitFailed'))
        }
      } catch (error) {
        if (error.message) {
          // 表单验证错误
          return
        }
        console.error('提交表单失败:', error)
        this.$message.error(this.$t('common.submitFailed'))
      } finally {
        this.submitLoading = false
      }
    },

    _doReset() {
      let _that = this;
      _that.components.forEach(item => {
        item.value = "";
        if (item.type == 'textdate' || item.type == 'textdatetime') {
          item.value = "请选择";
        }

        if (item.type == "radio" || item.type == "select") {
          item.valueIndex = 0;
        }
      });
      this.$forceUpdate();
    },

    _doUploadFile() {
      this.showUploadComponent = true
      this.$nextTick(() => {
        this.$refs.uploadFile.open()
      })
    },

    resetForm() {
      this.$refs.form.resetFields()
      if (this.$refs.uploadFile) {
        this.$refs.uploadFile.clear()
      }
      this.fileName = ''
      this.realFileName = ''
      this.formJson = {}
      this.components = []
      this.formData = {}
      this.showUploadComponent = false
    },

    handleFileUpload(fileInfo) {
      this.fileName = fileInfo.fileName
      this.realFileName = fileInfo.realFileName
    }
  }
}
</script>

<style lang="scss" scoped>
.new-oa-workflow-form {
  .form-card {
    .form-title {
      font-size: 16px;
      font-weight: 600;
      color: #303133;
    }

    .upload-section {
      .file-info {
        margin-bottom: 10px;
      }
    }

    .el-form-item {
      margin-bottom: 22px;
    }

    .el-divider {
      margin: 24px 0;
    }
  }
}
</style>