SpringBoot整合CRM客户管理系统(一)

1. 主要技术

SpringBoot+Mybatis+spring+mysql+layui

2. 目前的项目图

 

 

 3. 目前的实现功能

(1)登录功能

登录的逻辑主要是下判断是否存在该用户,如果存在该用户就比较密码是否正确,如果正确登录成功。

主要是三层:

controller:接受请求、返回结果

  • 接受前端的参数

  • 调用service层的登录方法

  • 返回给前端

  •   @PostMapping("login")
        @ResponseBody
        public ResultInfo userLogin(String userName,String userPwd){
            ResultInfo resultInfo=new ResultInfo();
            UserModel userModel=userService.userLogin(userName,userPwd);
            resultInfo.setResult(userModel);
            return resultInfo;
        }

service层:业务逻辑层(非空判断、条件判断)

  • 判空操作

  • 调用dao层通过用户名查询对象

  •   @Resource
        private UserMapper userMapper;
    
        /***
         * login成功后返回一个userModel
         * 1.检查用户、密码是否为空
         * 2.通过用户名查询user
         * 3.检查密码是否正确
         * 4.生成一个usermodel返回给controller
         * @param userName
         * @param userPwd
         * @return
         */
        @Override
        public UserModel userLogin(String userName,String userPwd){
            checkLoginParams(userName,userPwd);
            User user=userMapper.queryByUserByName(userName);
            AssertUtil.isTrue(user==null,"用户姓名不存在");
            checkUserPwd(userPwd,user.getUserPassword());
            return buildUserInfo(user);
        }
    
        private UserModel buildUserInfo(User user) {
            UserModel userModel=new UserModel();
            userModel.setUserIdStr(UserIDBase64.encoderUserID(user.getId()));
            userModel.setUserName(user.getUserName());
            userModel.setTrueName(user.getTrueName());
            return  userModel;
        }
    
        private void checkUserPwd(String userPwd, String userPassword) {
            userPwd= Md5Util.encode(userPwd);
            AssertUtil.isTrue(!userPwd.equals(userPassword),"用户密码不正确");
        }
    
        /***
         * 检查用户名、密码是否为空
         * @param userName
         * @param userPwd
         */
        private void checkLoginParams(String userName, String userPwd) {
            AssertUtil.isTrue(StringUtils.isBlank(userName),"用户姓名不能为空");
            AssertUtil.isTrue(StringUtils.isBlank(userPwd),"用户密码不能为空");
        }

其中AssertUtil为工具类:

public class AssertUtil {


    public  static void isTrue(Boolean flag,String msg){
        if(flag){
            throw  new ParamsException(msg);
        }
    }

}

dao层:与数据层相关

(2)修改密码

思路:

controller层:

接受前端传到的三个参数(旧密码、新密码、确认的新密码)

利用request获取到cookie中的主键ID

调用service层的修改密码方法

返回给前端参数

@ResponseBody
@PostMapping("updatePassword")
public ResultInfo updatePassword(HttpServletRequest request,String oldPassword, String newPassword, String repeatPassword){
    ResultInfo resultInfo=new ResultInfo();
    System.out.println(oldPassword);
    try{
        Integer userId= LoginUserUtil.releaseUserIdFromCookie(request);
        userService.updatePassword(userId,oldPassword,newPassword,repeatPassword);

    }catch (ParamsException p){
        resultInfo.setCode(p.getCode());
        resultInfo.setMsg(p.getMsg());
        p.printStackTrace();
    }catch (Exception e){
        resultInfo.setCode(500);
        resultInfo.setMsg("登录失败");
        e.printStackTrace();
    }
    return resultInfo;
}
@RequestMapping("toPasswordPage")
public  String toPasswordPage(){
    return "user/password";
}

service层:

接受controller的四个参数

通过id查询用户user

参数校验:

user是否为空

旧密码是否为空,旧密码是否错误

新密码是否为空,新密码是否与旧密码相同

确认新密码是否为空,确认信密码是否与新密码相同

对新密码进行加密

调用dao层进行密码更新

执行更新判断受影响行数,判断是否更新成功

@Override
@Transactional(propagation = Propagation.REQUIRED)
public void updatePassword(Integer userId,String oldPwd,String newPwd,String repeatPwd ){
    User user=userMapper.selectByPrimaryKey(userId);
    AssertUtil.isTrue(user==null,"待更新记录不存在");
    System.out.println(oldPwd);
    checkPasswordParams(user,oldPwd,newPwd,repeatPwd);
    user.setUserPassword(Md5Util.encode(newPwd));
    userMapper.updateByPrimaryKeySelective(user);
    AssertUtil.isTrue(userMapper.updateByPrimaryKeySelective(user)<1,"修改密码失败");

}

private void checkPasswordParams(User user,String oldPwd, String newPwd, String repeatPwd) {
    AssertUtil.isTrue(StringUtils.isBlank(oldPwd),"旧密码不能为空");
    AssertUtil.isTrue(user.getUserPassword().equals(Md5Util.encode(oldPwd)),"原始密码不正确");
    AssertUtil.isTrue(StringUtils.isBlank(newPwd),"新密码不能为空");
    AssertUtil.isTrue(newPwd.equals(oldPwd),"新密码不能与旧密码相同");
    AssertUtil.isTrue(StringUtils.isBlank(repeatPwd),"确认新密码不能为空");
    AssertUtil.isTrue(!repeatPwd.equals(newPwd),"确认新密码与新密码不一致");
}

dao层:

数据库的update操作

(3)记住我、退出功能

记住我和退出主要都是通过cookies进行实现,主要在前端js就可以实现

// 如果点击记住我 设置cookie 过期时间7天
if($("input[type='checkbox']").is(':checked')){
    // 写入cookie 7天
    $.cookie("userId",result.userIdStr, { expires: 7 });
    $.cookie("userName",result.userName, { expires: 7 });
    $.cookie("trueName",result.trueName, { expires: 7 });
}
$(".login-out").click(function () {
    layer.confirm('是否登出当前用户?', {icon: 3, title:'提示'}, function(index){
        $.removeCookie("userId",{path:"/"})
        $.removeCookie("userName",{path:"/"})
        $.removeCookie("trueName",{path:"/"})
        window.parent.location.href = ctx + "/index";
        layer.close(index);
    });

(4)拦截器

当用户未登录的时候不能直接访问到主页面main

 拦截器:

/**
 * 非法访问拦截
 */
public class NoLoginInterceptor extends HandlerInterceptorAdapter {

    @Resource
    private UserServiceImpl userService;
    /**
     * 判断用户是否是登录状态
     *  获取Cookie对象,解析用户ID的值
     *      如果用户ID不为空,且在数据库中存在对应的用户记录,表示请求合法
     *      否则,请求不合法,进行拦截,重定向到登录页面
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                             Object handler) throws Exception {

        // 获取Cookie中的用户ID
        Integer userId = LoginUserUtil.releaseUserIdFromCookie(request);
        // 判断用户ID是否不为空,且数据库中存在对应的用户记录
        if (null == userId || null == userService.selectByPrimaryKey(userId)) {
            // 抛出未登录异常
            throw new UnLoginException();
        }
        return true;
    }
}

配置拦截器:

@Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {

    @Bean
    public NoLoginInterceptor noLoginInterceptor() {
        return new NoLoginInterceptor();
    }

    /**
     * 添加拦截器
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 需要一个实现HandlerInterceptor接口的拦截器实例,这里使用的是 NoLoginInterceptor
        registry.addInterceptor(noLoginInterceptor())
                // 用于设置拦截器的过滤路径规则
                .addPathPatterns("/**")
                // 用于设置不需要拦截的过滤规则
                .excludePathPatterns("/index","/user/login","/css/**","/images/**","/js/**","/lib/**");
    }
}

4. 异常 

(1)参数异常

/**
 * 自定义参数异常
 */
public class ParamsException extends RuntimeException {
    private Integer code=300;
    private String msg="参数异常!";


    public ParamsException() {
        super("参数异常!");
    }

    public ParamsException(String msg) {
        super(msg);
        this.msg = msg;
    }

    public ParamsException(Integer code) {
        super("参数异常!");
        this.code = code;
    }

    public ParamsException(Integer code, String msg) {
        super(msg);
        this.code = code;
        this.msg = msg;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}

(2)全局异常处理

/*
    全局异常处理
    @ResponseBody响应内容为json数据,反之则是响应内容为页面
 */
@Component
public class GlobalExceptionResolver implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler, Exception e) {
        ModelAndView mv = new ModelAndView();

        //默认返回
        mv.setViewName("error");
        mv.addObject("code",500);
        mv.addObject("msg","系统出现异常,请稍后重试");

        //如果用户未登录,抛出未登录异常,则无需进行后续判断
        if(e instanceof UnLoginException){
            mv.setViewName("un_login");
            mv.addObject("msg","用户未登录!");
            mv.addObject("ctx",httpServletRequest.getContextPath());
            return mv;
        }
        //判断是否符合请求格式
        if (handler instanceof HandlerMethod){
            HandlerMethod hm = (HandlerMethod) handler;
            ResponseBody responseBody = hm.getMethod().getDeclaredAnnotation(ResponseBody.class);
            if(responseBody == null){
                //如果为视图
                //判断是否为参数异常
                if(e instanceof ParamsException){
                    ParamsException PE = (ParamsException) e;
                    mv.addObject("msg",PE.getMsg());
                    mv.addObject("code",PE.getCode());
                }
                //是否为认证异常
                else  if(e instanceof AuthException){
                    AuthException ae = (AuthException) e;
                    mv.addObject("msg",ae.getMsg());
                    mv.addObject("code",ae.getCode());
                }
                return mv;
            } else{
                //如果为json格式
                ResultInfo resultInfo = new ResultInfo();

                //默认数据
                resultInfo.setCode(500);
                resultInfo.setMsg("系统出现错误,稍后重试");

                //参数错误
                if(e instanceof ParamsException){
                    ParamsException PE = (ParamsException) e;
                    resultInfo.setCode(PE.getCode());
                    resultInfo.setMsg(PE.getMsg());
                }
                //如果是认证错误
                else  if(e instanceof AuthException){
                    AuthException ae = (AuthException) e;
                    resultInfo.setCode(ae.getCode());
                    resultInfo.setMsg(ae.getMsg());
                }
                //返回json格式的错误信息
                httpServletResponse.setContentType("application/json;charset=utf-8");
                httpServletResponse.setCharacterEncoding("utf-8");
                //使用流操作返回
                PrintWriter pw = null;
                try {
                    pw=httpServletResponse.getWriter();
                    pw.write(JSON.toJSONString(resultInfo));
                    pw.flush();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }finally {
                    if(null != pw){
                        pw.close();
                    }
                }
                return null;
            }

        } else {
            //返回默认数据
            return mv;
        }


    }
}

(3)未登录异常

public class UnLoginException extends RuntimeException {
    private Integer code=300;
    private String msg="用户未登录!";


    public UnLoginException() {
        super("用户未登录!");
    }

    public UnLoginException(String msg) {
        super(msg);
        this.msg = msg;
    }

    public UnLoginException(Integer code) {
        super("用户未登录!");
        this.code = code;
    }

    public UnLoginException(Integer code, String msg) {
        super(msg);
        this.code = code;
        this.msg = msg;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值