前端
<el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="120px">
<el-row>
<el-col :span="12">
<el-form-item label="姓名/名称" prop="userName">
<el-input v-model="form.userName" placeholder="请输入姓名/名称"/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="手机号码" prop="mobile">
<el-input v-model="form.mobile" placeholder="请输入手机号码"/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="邮箱" prop="email">
<el-input v-model="form.email" placeholder="请输入邮箱"/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="性别" prop="gender">
<el-radio v-model="form.gender"
:label="dict.value"
v-for="dict in dict.type.gender"
:key="dict.value">{{ dict.label }}
</el-radio>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-row>
<el-col :span="12">
<el-form-item label="密码" prop="password">
<el-input v-model="form.password" placeholder="请输入密码" type="password" maxlength="20"
show-password/>
<password-strength v-model="form.password" style="padding-top: 10px;"></password-strength>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="确认密码" prop="confirmPassword">
<el-input v-model="form.confirmPassword" placeholder="请输入确认密码" type="password" maxlength="20"
show-password/>
</el-form-item>
</el-col>
</el-row>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="所属地域" prop="areaCode">
<treeselect v-model="form.areaCode" :options="tzSysTreeDictOptions"
:normalizer="normalizer" placeholder="请所属地域"/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="领域" prop="domain">
<el-select v-model="form.domain" placeholder="请选择领域" style="width:100%">
<el-option
v-for="dict in dict.type.tzLyUserDomain"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="证件类型" prop="idType">
<el-select v-model="form.idType" placeholder="请选择证件类型" style="width:100%">
<el-option
v-for="dict in dict.type.certType"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="证件号码" prop="idCard">
<el-input v-model="form.idCard" placeholder="请输入证件号码" style="width:100%"/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="民族" prop="ethnicity">
<el-select v-model="form.ethnicity" placeholder="请选择民族" style="width:100%">
<el-option
v-for="dict in dict.type.ethnicity"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="政治面貌" prop="politicalStatus">
<el-select v-model="form.politicalStatus" placeholder="请选择政治面貌" style="width:100%">
<el-option
v-for="dict in dict.type.politicalStatus"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="职业" prop="occupation">
<el-select v-model="form.occupation" placeholder="请选择职业" style="width:100%">
<el-option
v-for="dict in dict.type.trade"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="工作单位(公司)" prop="unit">
<el-input v-model="form.unit" placeholder="请输入工作单位(公司)"/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="职务" prop="job">
<el-input v-model="form.job" placeholder="请输入职务"/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="个人介绍" prop="introduction">
<el-input v-model="form.introduction" placeholder="请输入个人介绍"/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</el-dialog>
// 表单校验
rules: {
userName: [
{ required: true, message: '姓名/名称不能为空', trigger: 'blur' }
],
mobile: [
{ required: true, trigger: 'blur', validator: this.validatePhoneNumber }
],
password: [
{ trigger: 'blur', validator: this.validatePassword }
],
confirmPassword: [
{ trigger: 'blur', validator: this.validateConfirmPassword }
],
email: [
{ required: true, message: '邮箱不能为空', trigger: 'blur' },
{
pattern: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,
message: '请输入正确的邮箱地址',
trigger: ['blur', 'change']
}
],
areaCode: [
{ required: true, message: '所属地域不能为空', trigger: 'blur' }
],
domain: [
{ required: true, message: '领域不能为空', trigger: 'blur' }
],
idType: [
{ required: true, message: '证件类型不能为空', trigger: 'blur' }
],
idCard: [
{ required: true, validator: this.validateChineseIDCard, trigger: 'blur' }
]
},
//校验确认密码
validateConfirmPassword(rule, value, callback) {
if (!this.isInsert) {
callback()
}
if (value !== this.form.password) {
callback(new Error('密码和确认密码不一致'))
} else {
callback()
}
},
//校验身份证号码
validateChineseIDCard(rule, value, callback) {
if (this.form.idType!=='1'){
callback()
}
const reg = /(^\d{15}$)|(^\d{17}(\d|X|x)$)/
if (!value) {
callback(new Error('身份证号码不能为空'))
} else if (!reg.test(value)) {
callback(new Error('身份证号码格式不正确'))
} else {
callback()
}
},
//校验密码
validatePassword(rule, value, callback) {
if (!this.isInsert) {
callback()
}
// 密码必须包含数字、小写字母、大写字母和特殊字符中的至少三种
const reg = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[\W_]).{6,20}$/
if (!value) {
callback(new Error('密码长度要在 6 到 20 个字符'))
} else if (value.length < 6 || value.length > 20) {
callback(new Error('密码长度要在 6 到 20 个字符'))
} else if (!reg.test(value)) {
callback(new Error('密码必须包含数字、小写字母、大写字母和特殊字符中的至少三种'))
} else {
callback()
}
},
//校验手机号码
validatePhoneNumber(rule, value, callback) {
const reg = /^1[3-9]\d{9}$/
if (!value) {
callback(new Error('手机号不能为空'))
} else if (!reg.test(value)) {
callback(new Error('手机号格式不正确'))
} else {
callback()
}
},
后端
枚举
package com.huida.common.valid;
import javax.validation.groups.Default;
public interface ValidParameterTzLyUser extends Default {
interface User {
}
interface Group {
}
}
实体
/**
* 密码
* 不传递密码给前端,但是后端数据库查出来使用,允许前端传密码过来
*/
@Size(min = 1, max = 30, message = "密码长度不能超过30个字符",
groups = {ValidParameterTzLyUser.User.class, ValidParameterTzLyUser.Group.class})
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private String password;
/**
* 统一社会信用代码,企业账号要校验统一社会信用代码
*/
@Size(min = 1, max = 32, message = "统一社会信用代码不能为空,统一社会信用代码长度不大于32",
groups = {ValidParameterTzLyUser.User.class, ValidParameterTzLyUser.Group.class})
private String shxydm;
/**
* springboot自带参数校验
*/
private static final javax.validation.Validator VALIDATOR = Validation.buildDefaultValidatorFactory().getValidator();
public static void validate(TzLyUser tzLyUser) {
//校验参数
Set<ConstraintViolation<TzLyUser>> validate = null;
if (TzLyConstants.IDENTITY_REGISTER_USERS.equals(tzLyUser.getIdentity())) {
validate = VALIDATOR.validate(tzLyUser, ValidParameterTzLyUser.User.class);
} else if (TzLyConstants.IDENTITY_AUTH_GROUP.equals(tzLyUser.getIdentity())) {
validate = VALIDATOR.validate(tzLyUser, ValidParameterTzLyUser.Group.class);
}
if (ObjectUtils.isNotEmpty(validate)) {
StringBuilder sb =new StringBuilder();
for (ConstraintViolation<TzLyUser> violation : validate) {
sb.append(violation.getMessage());
sb.append("\n");
System.out.println(violation.getMessage());
System.out.println(violation);
}
throw new TipUserException(sb.toString());
}
if (!PhoneUtil.isMobile(tzLyUser.getMobile())) {
throw new TipUserException("手机号码格式不正确");
}
if (!tzLyUserService.checkMobileUnique(tzLyUser)) {
throw new TipUserException("注册失败,手机号码已存在");
}
String msg = PasswdUtils.verifyPassLevel(tzLyUser.getPassword());
if (StringUtils.isNotBlank(msg)) {
throw new TipUserException(msg);
}
}