【华夏OA项目实战】3-18 实现验证用户名和电话的RESTful接口

本课程开发软件与项目初始代码可以通过云盘下载,答疑服务可以关注视频片头的二维码获取。
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.daoUserMapper.java接口中,声明DAO方法。

public interface UserMapper {
    ……
    public boolean checkUsernameConflict(Map param);
    public boolean checkTelConflict(Map param);
}

2. 编写Dubbo层

com.example.hxoa.cloud.dubboUserApi.java接口中,声明抽象方法。

public interface UserApi {
    ……
    public R checkUsernameConflict(Map param);
    public R checkTelConflict(Map param);
}

com.example.hxoa.cloud.oms.apiUserApiHandler.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.dubboUserApi.java接口中,声明抽象方法。

public interface UserApi {
    ……
    public R checkUsernameConflict(Map param);
    public R checkTelConflict(Map param);
}

2. 编写业务层

com.example.hxoa.cloud.mis.serviceUserService.java接口中,声明抽象方法。

public interface UserService {
    ……
    public Map checkUsernameConflict(Map param);
    public Map checkTelConflict(Map param);
}

com.example.hxoa.cloud.mis.service.implUserServiceImpl.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.controllerUserController.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: '请选择用户状态'}
        ]
    }

});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值