业务需求:
用户多部门多职位,但有一个主单位,主单位必须,但职位不必须,每个单位下包含不同职位,同一用户在同一单位下只能拥有一个同一职位
左侧机构结构是树形菜单,对应机构表,使用el-casecader级联选择器(带radio单选框形式的) ,右侧职位结构是普通列表,使用el-select 选择器,根据左侧选择的项动态显示右边展示的内容,并验证是否与已选择项冲突。
主职项使用el-radio单选按钮,与上下行唯一冲突,默认进入页面就有第一行内容并且主职选中。因为用户至少有一个部门,这里为了直接设置了第一项不可删除且为必选,是否主职自己设定,但设定为主职的项也不可删除,除非取消主职设定,主职务所在单位即为主单位,主单位必需,主职务不必需。
可使用增加按钮添加新的机构和职位行...
表单绑定验证rule::rules="dataRule"
<el-form :model="dataForm"
:rules="dataRule"
@keyup.enter.native="dataFormSubmitHandle()"
label-width="120px"
ref="dataForm"
:inline="true"
size="mini">
table部分代码:
<el-col :span="22">
<!--机构职位-->
<div style="height:30px;margin:0px 0px 10px 30px;width:800px;">
<span style="disply:block;float:left;font-weight:bold;color:#5CACEE;">职位</span>
<el-button @click="addJob()" style="float:right;" type="primary" size="mini" :disabled="info">新增</el-button>
</div>
</el-col>
<el-table :data="dataForm.deptJobList"
border
height="280px"
v-loading="slaveJobListLoading">
<el-table-column header-align="center" align="center" min-width="80" label="机构">
<template slot-scope="scope">
<el-form-item :prop="'deptJobList[' + scope.$index + '].deptId'"
label-width="0px"
:inline-message="true">
<el-cascader
:key="caseCaderKey"
:options="depts"
:disabled="info"
@change="deptChange(scope.row.deptId,scope.$index)"
v-model="scope.row.deptId"
:props="{ checkStrictly: true, value: 'id', label: 'name',emitPath:false }"
clearable>
</el-cascader>
</el-form-item>
</template>
</el-table-column>
<el-table-column header-align="center" align="center" min-width="40" label="职位">
<template slot-scope="scope">
<el-form-item :prop="'deptJobList[' + scope.$index + '].jobCode'"
label-width="0px"
:inline-message="true">
<el-select placeholder="职位"
clearable
:disabled="info"
v-model="scope.row.jobCode"
ref="selectCode{{scope.$index}}"
@change="jobChange(scope.row,scope.row.jobCode,scope.row.deptId,scope.$index)">
<el-option v-for="(item) in dataForm.deptJobList[scope.$index].jobs"
:key="item.jobCode"
:label="item.jobName"
:value="item.jobCode">
</el-option>
</el-select>
</el-form-item>
</template>
</el-table-column>
<el-table-column header-align="center" align="center" min-width="15" label="主职">
<!-- <template slot-scope="scope">
<el-form-item prop="isMain">
{{ scope.$index===0?'是':'否' }}
</el-form-item>
</template> -->
<template slot-scope="scope">
<el-form-item prop="isMain">
<el-radio-group v-model="scope.row.isMain" @change="isMaster(scope.$index)" :disabled="info">
<el-radio :label="isMainFlag">是</el-radio>
</el-radio-group>
</el-form-item>
</template>
</el-table-column>
<el-table-column header-align="center" align="center" min-width="35" label="排序">
<template slot-scope="scope">
<el-form-item prop="sort">
<!-- <el-input placeholder="排序" v-model="dataForm.deptJobList[scope.$index].sort"></el-input> -->
<el-input-number
:min="0"
:disabled="info"
v-model="dataForm.deptJobList[scope.$index].sort"
controls-position="right"
placeholder="请输入排序"
@change="toInteger(scope.$index)"
/>
</el-form-item>
</template>
</el-table-column>
<el-table-column header-align="center" align="center" min-width="20" label="操作">
<template slot-scope="scope">
<el-form-item>
<el-button @click="delJob(scope.row,scope.$index)" type="danger" size="small" :disabled="(scope.$index===0)?true:false || info">删除</el-button>
</el-form-item>
</template>
</el-table-column>
</el-table>
大多数情况下,dataRule会使用计算属性的方式来动态验证:
computed: {
dataRule () {
var validatePassword = (rule, value, callback) => {
if (value && !this.dataForm.id && !/\S/.test(value)) {
return callback(new Error(this.$t('validate.required')))
}
this.$refs.dataForm.validateField("comfirmPassword")
callback()
}
var validateComfirmPassword = (rule, value, callback) => {
if (value && !this.dataForm.id && !/\S/.test(value)) {
return callback(new Error(this.$t('validate.required')))
}
if ((!this.dataForm.id && this.dataForm.password !== value) || (this.dataForm.id && !this.resetPassword && this.dataForm.password !== value)) {
return callback(new Error(this.$t('user.validate.comfirmPassword')))
}
callback()
}
var validateJob = (rule, value, callback) => {
let index = rule.field.split('[')[1].split(']')[0]
let deptId = this.dataForm.deptJobList[index].deptId
let jobCode = this.dataForm.deptJobList[index].jobCode
var flag = 0
this.dataForm.deptJobList.forEach((item) => {
if (item.deptId === deptId && item.jobCode === jobCode) {
flag++
if(flag == 2){
return callback(new Error('用户在同部门下不可拥有重复职务!'))
}
}
})
callback()
}
var valdateChar = (rule,value,callback) =>{
const pattern = /[`~!@#$^&*()=|{}':;',\\\[\]\.<>\/?~!@#¥……&*()——|{}【】';:""'。,、?\s]/g
var newValue = value.replace(pattern,"")
if(value !== newValue){
return callback(new Error("不可使用_和%之外的其他特殊字符"))
}
callback()
}
return {
username: [
{
required: true,
message: this.$t('validate.required'),
trigger: 'blur'
},
{
validator: valdateChar, trigger: 'blur'
}
],
password: [{ validator: validatePassword, trigger: 'blur' }],
comfirmPassword: [
{ validator: validateComfirmPassword, trigger: 'blur' }
],
realName: [
{
required: true,
message: this.$t('validate.required'),
trigger: 'blur'
},
{
validator: valdateChar, trigger: 'blur'
}
],
type: [
{
required: true,
message: this.$t('validate.required'),
trigger: 'blur'
},
{
required: true,
message: this.$t('validate.required'),
trigger: 'change'
}
],
'deptJobList[0].deptId': [
{
required: true,
message: "至少拥有一个所在机构",
trigger: 'blur'
},
{
required: true,
message: "至少拥有一个所在机构",
trigger: 'change'
}
],
'deptJobList[0].jobCode': [
{ validator: validateJob, trigger: 'change' }
],
jobCode : [
{ validator: validateJob, trigger: 'change' }
],
}
}
},
增加动态添加验证的方法:
addDeptJobDataRule (index) {
this.dataRule['deptJobList[' + index + '].deptId'] = [
{ required: true, message: '机构不能为空值,可去除该行', trigger: 'blur' }
]
this.dataRule['deptJobList[' + index + '].jobCode'] = this.dataRule.jobCode
},
添加table行时也需要调用增加验证的方法:
addJob () {
const obj = {
deptId: '',
deptName: '',
deptCode: '',
jobCode: '',
jobName: '',
isMain: false,
sort: '',
jobs: []
}
this.dataForm.deptJobList.push(obj)
this.addDeptJobDataRule(this.dataForm.deptJobList.length - 1)
},
回显时也要根据回显的行数动态增加:
getInfo () {
this.$axios.get(`/sys/user/${this.dataForm.id}`).then((res) => {
this.dataForm = {
...this.dataForm,
...res,
roleIdList: []
}
// 角色配置, 区分是否为默认角色
// this.dataForm.roleIdList = [...res.roleIdList]
// this.roleIdListDefault = [...res.roleIdList]
this.resetPassword = true
this.dataForm.password = '**********'
this.dataForm.comfirmPassword = '**********'
const list = this.dataForm.deptJobList
if(list != null || list.length >0){
for(let i=0;i<list.length;i++){
let deptId = list[i].deptId
const jobList = []
this.jobs.forEach((item, index) => {
if (item.deptId === deptId) {
jobList.push(item)
}
})
this.dataForm.deptJobList[i].jobs = [...jobList]
this.addDeptJobDataRule(i)
}
for(let i=0;i<list.length;i++){
let isMain = list[i].isMain
if(isMain == true){
this.mainIndex = i
}
}
}
})
},