表格动态表单验证-开发预演

<template>
  <div>
    <os-dialog
      class="common-dialog"
      width="1200px"
      title="中考类型设置"
      :visible.sync="showsDialog"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      @opened="onDialogOpened"
      @closed="onDialogClosed"
    >
      <el-form
        ref="form"
        label-width="130px"
        :model="formData"
        :rules="rules"
        v-loading="dialogLoading"
        @submit.native.prevent
      >
        <el-form-item label="测评类别:">
          <div class="flex">
            <el-form-item prop="year">
              <el-select
                v-model="formData.year"
                placeholder="请选择学年"
                @change="getExamTypeData"
              >
                <el-option
                  v-for="item in formData.yearList"
                  :key="item"
                  :label="item"
                  :value="item"
                >
                </el-option>
              </el-select>
            </el-form-item>
            <el-form-item prop="province">
              <el-select
                v-model="formData.province"
                placeholder="请选择省份"
                @change="getProvince"
              >
                <el-option
                  v-for="item in examTypeData"
                  :key="item.provinceCode"
                  :label="item.province"
                  :value="item.provinceCode"
                >
                </el-option>
              </el-select>
            </el-form-item>
          </div>
        </el-form-item>
        <el-form-item label="项目分值:">
          <div class="score-sun">
            总分<el-input
              :disabled="true"
              class="score-input"
              v-model="formData.score"
              maxlength="20"
              placeholder="总分"
            >
            </el-input>
          </div>
          <el-table
            :data="formData.scoreList"
            ref="tableDataRef"
            style="width: 100%"
            class="score-table"
          >
            <el-table-column
              align="center"
              label="类型"
              width="110"
              prop="name"
            >
            </el-table-column>
            <el-table-column
              align="center"
              label="计分项目数"
              prop="itemNum"
              width="200"
            >
              <template slot-scope="scope">
                <el-form-item
                  :prop="'scoreList.' + scope.$index + '.itemNum'"
                  :rules="[
                    {
                      required: true,
                      message: '请输入计分项目数',
                      trigger: 'blur',
                    },
                  ]"
                >
                  <el-input-number
                    :min="1"
                    label="描述文字"
                    :max="
                      scope.row.manList.length > scope.row.womanList.length
                        ? scope.row.womanList.length
                        : scope.row.manList.length
                    "
                    v-model="scope.row.itemNum"
                    @input="onExchange(scope.$index, scope.row, 'erroritemNum')"
                  ></el-input-number>
                </el-form-item>
              </template>
            </el-table-column>

            <el-table-column align="center" label="类型总分" width="120">
              <template slot-scope="scope">
                <el-form-item
                  :prop="'scoreList.' + scope.$index + '.score'"
                  :rules="[
                    {
                      required: true,
                      message: '请输入类型总分',
                      trigger: 'blur',
                    },
                  ]"
                >
                  <el-input
                    size="medium"
                    placeholder="类型总分"
                    v-model="scope.row.score"
                    @input="onExchange(scope.$index, scope.row, 'errorscore')"
                  >
                  </el-input>
                </el-form-item>
              </template>
            </el-table-column>
            <el-table-column
              align="center"
              label="男生项目"
              prop="errormanList"
            >
              <template slot-scope="scope">
                <el-form-item
                  :prop="'scoreList.' + scope.$index + '.manList'"
                  :rules="[
                    {
                      required: true,
                      message: '至少选择一项男生项目',
                      trigger: 'blur',
                    },
                  ]"
                >
                  <el-select
                    multiple
                    collapse-tags
                    size="medium"
                    v-model="scope.row.manList"
                    placeholder="请选择男生项目"
                    @input="onExchange(scope.$index, scope.row, 'errormanList')"
                  >
                    <el-option
                      v-for="item in menList"
                      :label="item.name"
                      :value="item.id"
                      :key="item.id"
                    >
                    </el-option>
                  </el-select>
                </el-form-item>
              </template>
            </el-table-column>
            <el-table-column align="center" label="女生项目" prop="womanList">
              <template slot-scope="scope">
                <el-form-item
                  :prop="'scoreList.' + scope.$index + '.womanList'"
                  :rules="[
                    {
                      required: true,
                      message: '至少选择一项女生项目',
                      trigger: 'blur',
                    },
                  ]"
                >
                  <el-select
                    multiple
                    collapse-tags
                    size="medium"
                    v-model="scope.row.womanList"
                    placeholder="请选择"
                    @input="
                      onExchange(scope.$index, scope.row, 'errorwomanList')
                    "
                  >
                    <el-option
                      v-for="item in womenList"
                      :label="item.name"
                      :value="item.id"
                      :key="item.id"
                    >
                    </el-option>
                  </el-select>
                </el-form-item>
              </template>
            </el-table-column>
          </el-table>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="common-dialog-footer">
          <os-button size="small" @click="showsDialog = false">取 消</os-button>
          <os-button size="small" type="primary" @click="handleSave"
            >保 存</os-button
          >
        </div>
      </template>
    </os-dialog>
  </div>
</template>
<script>
class Form {
  constructor() {
    this.score = 0
    this.scoreList = []
    this.yearList = [] // 动态年份数据
    this.provinceCode = ''
  }
}
import apis from '@/apis/apiList.js'
import showMessage from 'lib/helper/showMessage'

export default {
  name: 'one-type-set',
  props: {
    examPlanId: {
      type: String,
      default: '',
    },
  },

  data() {
    return {
      examTypeData: [], // 下拉数据
      showsDialog: false, // 是否显示弹窗
      dialogLoading: false, // 弹框Loading
      formData: new Form(), // 表单数据
      typeList: [],
      menList: [], // 男项目列表
      womenList: [], // 女项目列表
      isEdit: false,
      // 表单校验规则
      rules: {
        year: [{ required: true, message: '请选择学年', trigger: 'blur' }],
        province: [{ required: true, message: '请选择省份', trigger: 'blur' }],
      },
    }
  },

  created() {},

  methods: {
    /**
     * @function 打开弹窗
     */
    open(isEdit) {
      this.showsDialog = true
      this.isEdit = isEdit
    },

    /**
     * @function 数据列表改变操作
     * @param {string} index 下标
     * @param {string} row 列数据
     * @param {string} name 编辑时的类型
     */
    onExchange(index, row, name) {
      let moment = this.formData.scoreList[index] // 此处的tableData为自己的table表格绑定的data数组
      this.$set(this.formData.scoreList, index, moment) // 此处是将修改的那一行的数据重新赋值给table表格对应的那一行,触发热更新
      this.formData.scoreList[index].itemNum = 1 // 项目变更后项目数初始化为 1
      // 如果总分变更则重新计算总分
      if (name === 'errorscore') {
        this.totalScore()
        if (row.score === '') {
          row.errorscore = '请输入项目总分'
        }
      }
      if (name === 'erroritemNum' && row.itemNum === '') {
        row.erroritemNum = '请输入计分项目数'
      }
      if (name === 'errormanList' && row.manList === '') {
        row.errormanList = '至少选择一项男生项目'
      }
      if (name === 'errorwomanList' && row.womanList === []) {
        row.errorwomanList = '至少选择一项女生项目'
      }
    },

    // 计算总分
    totalScore() {
      this.formData.score = 0
      this.formData.scoreList.map((r) => {
        this.formData.score += Number(r.score || 0)
      })
    },

    /**
     * @function 弹窗打开回调
     */
    onDialogOpened() {
      let year =
        new Date().getMonth() + 1 >= 7
          ? new Date().getFullYear() + 1
          : new Date().getFullYear()
      for (let i = year; i >= 2022; i--) {
        this.formData.yearList.push(i)
      }
      this.getIndicatorList('1')
      this.getIndicatorList('2')
      if (this.isEdit) {
        this.getSettingData()
      }
    },

    /**
     * @function 中考类型设置回显
     */
    getSettingData() {
      this.$http
        .get(apis._apis_mid_exam_plan_findMidTermExamPlanEcho, {
          params: { examPlanId: this.examPlanId },
        })
        .then((res) => {
          if (res.data.code !== 200) return
          const data = res.data.data
          this.formData = { ...data }
          ;(this.formData.province = data.provinceCode),
            this.getExamTypeData(data.year)
          this.totalScore()
        })
    },

    // 获取指标
    getIndicatorList(gender) {
      this.$http
        .get(apis._apis_common_operationIndicatorList, {
          params: { ignore: true, gender },
        })
        .then((res) => {
          if (res.data.code !== 200) return
          if (gender === '1') {
            this.menList = res.data.data || {}
          } else {
            this.womenList = res.data.data || {}
          }
        })
    },

    /**
     * @function 关闭弹窗回调
     */
    onDialogClosed() {
      this.formData = new Form()
      this.$refs.form.resetFields()
    },

    /**
     * 获取中考类别下拉
     * @param {*} year 年份
     */
    getExamTypeData(year) {
      this.$http
        .get(apis._apis_common_getMidExamType, {
          params: { year },
        })
        .then((res) => {
          if (res.data.code !== 200) {
            return
          }
          this.examTypeData = res.data.data || {}
        })
    },

    /**
     * @function 切换时构造列表数据
     * @param {*} val 列表数据
     */
    getProvince(val) {
      this.formData.province = val
      this.formData.scoreList = []
      this.formData.provinceCode = val
      this.examTypeData.map((res) => {
        if (res.provinceCode === val) {
          res.categoryList.map((r) => {
            this.formData.scoreList.push({
              ...r,
              itemNum: '',
              womanList: res.categoryList.womanList || [],
              manList: res.categoryList.manList || [],
            })
          })
        }
      })
      this.totalScore()
    },

    /**
     * @function 点击保存
     */
    handleSave() {
      if (this.success) {
        showMessage('修改成功')
        return
      }
      this.$refs.form.validate((valid) => {
        if (!valid) return
        const url = this.isEdit
          ? apis._apis_mid_exam_plan_midTermExamTypeSet
          : apis._apis_mid_exam_plan_midTermExamTypeSet
        const params = {
          ...this.formData,
          examPlanId: this.examPlanId,
          score: this.formData.score,
        }
        this.$http.post(url, params).then((res) => {
          if (res.data.code === 200) {
            showMessage(this.isEdit ? '修改成功' : '添加成功')
            this.showsDialog = false
            this.$emit('close')
          }
        })
      })
    },

    /**
     * @function 关闭弹窗
     */
    close() {
      this.formData = new Form()
      this.showsDialog = false
    },
  },
}
</script>
<style lang="scss" scoped>
.full-width {
  width: 100% !important;
}
.score-sun {
  display: flex;
  justify-content: flex-end;
}
.score-input {
  width: 200px;
  margin-left: 10px;
}
.score-table {
  margin-top: 20px;
  /deep/ {
    .el-table__header-wrapper {
      .el-table__cell {
        padding: 0px;
      }
    }
    .el-table .el-table__cell {
      padding: 6px 0;
    }
    .el-form-item {
      margin-bottom: 22px !important;
    }
  }
}
.flex {
  display: flex;
  align-items: center;
  height: 40px;
  /deep/ {
    .el-switch {
      margin-right: 16px;
    }
    .is-required {
      margin-right: 10px;
    }
  }
}
</style>
posted @   会飞的小白  阅读(12)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示