本课程开发软件与项目初始代码可以通过云盘下载,答疑服务可以关注视频片头的二维码获取。
https://www.123912.com/s/A75eVv-27mod,提取码:yton
教学视频
目前我们已经能在用户模块VUE页面中显示弹窗界面,我们在弹窗中输入新用户信息的时候,需要验证该用户名是否被占用。除了用户名之外,电话号码也需要验证是否被占用。这节课我们把验证用户名和电话占用的代码实现,结合前端页面的验证来测试一下。
视频中有代码讲解,大家认真观看视频,不要快进。有些操作只在视频中演示,只对着手册操作并不能完成案例,切记!
一、编写hxoa-oms
子系统
1. 编写持久层
在UserMapper.xml
文件中,声明SQL语句,验证用户名以及电话。为了能保证IS NOT NULL
表达式执行,子查询SQL语句必须最多只能返回一条记录,所以在子查询中添加了LIMIT 1
子句。
<select id="checkUsernameConflict" parameterType="Map" resultType="boolean">
SELECT (
(
SELECT id
FROM tb_user
WHERE username = #{username}
<if test="id!= null">
AND id != #{id}
</if>
LIMIT 1
) IS NOT NULL
) AS consequence
</select>
<select id="checkTelConflict" parameterType="Map" resultType="boolean">
SELECT (
(
SELECT id
FROM tb_user
WHERE tel = #{tel}
<if test="id!= null">
AND id != #{id}
</if>
LIMIT 1
) IS NOT NULL
) AS consequence
</select>
在com.example.hxoa.cloud.oms.db.dao
包UserMapper.java
接口中,声明DAO方法。
public interface UserMapper {
……
public boolean checkUsernameConflict(Map param);
public boolean checkTelConflict(Map param);
}
2. 编写Dubbo层
在com.example.hxoa.cloud.dubbo
包UserApi.java
接口中,声明抽象方法。
public interface UserApi {
……
public R checkUsernameConflict(Map param);
public R checkTelConflict(Map param);
}
在com.example.hxoa.cloud.oms.api
包UserApiHandler.java
类中,实现抽象方法。
@DubboService
@Slf4j
public class UserApiHandler implements UserApi {
……
@Override
@SentinelResource("UserApiHandler.checkUsernameConflict")
public R checkUsernameConflict(Map param) {
boolean bool = userMapper.checkUsernameConflict(param);
return R.ok().setAttributeAll(new HashMap() {{
put("status", "SUCCESS");
put("isConflict", bool);
}});
}
@Override
@SentinelResource("UserApiHandler.checkTelConflict")
public R checkTelConflict(Map param) {
boolean bool = userMapper.checkTelConflict(param);
return R.ok().setAttributeAll(new HashMap() {{
put("status", "SUCCESS");
put("isConflict", bool);
}});
}
}
二、编写hxos-mis
子系统
1. 编写Dubbo层
在com.example.hxoa.cloud.dubbo
包UserApi.java
接口中,声明抽象方法。
public interface UserApi {
……
public R checkUsernameConflict(Map param);
public R checkTelConflict(Map param);
}
2. 编写业务层
在com.example.hxoa.cloud.mis.service
包UserService.java
接口中,声明抽象方法。
public interface UserService {
……
public Map checkUsernameConflict(Map param);
public Map checkTelConflict(Map param);
}
在com.example.hxoa.cloud.mis.service.impl
包UserServiceImpl.java
类中,实现抽象方法。
@Service
public class UserServiceImpl implements UserService {
……
@Override
public Map checkUsernameConflict(Map param) {
R r = userApi.checkUsernameConflict(param);
Map result = r.getAttributeAll();
return result;
}
@Override
public Map checkTelConflict(Map param) {
R r = userApi.checkTelConflict(param);
Map result = r.getAttributeAll();
return result;
}
}
3. 编写Web层
在com.example.hxoa.cloud.mis.controller.form
包中,创建CheckUsernameConflictForm.java
类。
@Data
public class CheckUsernameConflictForm {
@Min(value = 1, message = "id必须大于0")
private Long id;
@NotBlank(message = "用户名不能为空")
@Pattern(regexp = "^[a-zA-Z0-9]{5,50}$", message = "用户名格式不正确")
private String username;
}
在com.example.hxoa.cloud.mis.controller.form
包中,创建CheckTelConflictForm.java
类。
@Data
public class CheckTelConflictForm {
@Min(value = 1, message = "id必须大于0")
private Long id;
@NotBlank(message = "手机号码不能为空")
@Pattern(regexp = "^1[34578]\\d{9}$", message = "手机号码格式不正确")
private String tel;
}
在com.example.hxoa.cloud.mis.controller
包UserController.java
类中,声明Web方法。
@RestController
@RequestMapping("/user")
public class UserController {
……
@PostMapping("/check-username-conflict")
@SaCheckLogin
@SentinelResource("UserController.checkUsernameConflict")
public R checkUsernameConflict(@RequestBody @Valid CheckUsernameConflictForm form) {
Map param = BeanUtil.beanToMap(form);
Map result = userService.checkUsernameConflict(param);
return R.ok().setAttributeAll(result);
}
@PostMapping("/check-tel-conflict")
@SaCheckLogin
@SentinelResource("UserController.checkTelConflict")
public R checkTelConflict(@RequestBody @Valid CheckTelConflictForm form) {
Map param = BeanUtil.beanToMap(form);
Map result = userService.checkTelConflict(param);
return R.ok().setAttributeAll(result);
}
}
三、了解前端验证代码
在user.vue
页面中,响应对象里面定义了弹窗面板中表单控件的验证规则。验证用户名和电话的时候会发起Ajax请求,检验用户名和电话号码是否被占用。
const dialog = reactive({
visible: false,
formData: {
id: null,
username: null,
password: null,
confirmPassword: null,
name: null,
gender: null,
tel: null,
email: null,
roleId: [],
deptId: null,
jobId: null,
status: "正常"
},
rule: {
username: [
{required: true, message: "请输入用户名"},
{min: 5, max: 50, message: "长度在5到50个字符之间", trigger: "blur"},
{pattern: "^[a-zA-Z0-9]{5,50}$", message: "用户名格式错误", trigger: "blur"},
{
validator: (rule, value, callback) => {
const data = {
id: dialog.formData.id,
username: value
}
proxy.$http("/mis/user/check-username-conflict", "POST", data, true, resp => {
let result = resp.result;
if (result.status == "SUCCESS") {
if (result.isConflict === false) {
callback();
}
else {
callback(new Error("用户名已存在"));
}
}
})
},
trigger: "blur"
}
],
name: [
{required: true, message: "请输入姓名"},
{min: 2, max: 20, message: "长度在2到20个字符之间", trigger: "blur"},
{pattern: "^[\u4e00-\u9fa5]{2,20}$", message: "用户名格式错误", trigger: "blur"}
],
gender: [
{required: true, message: '请选择性别'}
],
password: [
{required: true, message: "请输入密码"},
{min: 6, max: 20, message: "长度在6到20个字符之间", trigger: "blur"},
],
confirmPassword: [
{required: true, message: "请重复输入密码"},
{min: 6, max: 20, message: "长度在6到20个字符之间", trigger: "blur"},
{
validator: (rule, value, callback) => {
if (value !== dialog.formData.password) {
callback(new Error('两次输入密码不一致'));
}
else {
callback();
}
}, trigger: "blur"
}
],
tel: [
{required: true, message: "请输入手机号码"},
{pattern: "^1[34578]\\d{9}$", message: "手机号码格式错误", trigger: "blur"},
{
validator: (rule, value, callback) => {
const data = {
id: dialog.formData.id,
tel: value
}
proxy.$http("/mis/user/check-tel-conflict", "POST", data, true, resp => {
let result = resp.result;
if (result.status == "SUCCESS") {
if (result.isConflict === false) {
callback();
}
else {
callback(new Error('手机号码已存在'));
}
}
})
},
trigger: "blur"
}
],
email: [
{required: true, message: "请输入电子邮箱"},
{
pattern: "^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})$",
message: "电子邮箱格式错误",
trigger: "blur"
}
],
roleId: [
{required: true, message: '请选择关联角色'}
],
deptId: [
{required: true, message: '请选择所属部门'}
],
jobId: [
{required: true, message: '请选择担任职务'}
],
status: [
{required: true, message: '请选择用户状态'}
]
}
});