鞍山做网站的公司,制作企业网站得多长时间,网站模板的好处,平面设计接单能赚多少钱一.登录
1.1 生成验证码 基本思路 后端生成一个表达式,74?11 74?转成图片,传到前端进行展示 将结果11存入redis 前端代码实现: 请求后端地址:http://localhost/dev-api/captchaImage,通过反向代理解决前后端跨域问题,将请求路径变为:http://localhost:8080/captchaImag…一.登录
1.1 生成验证码 基本思路 后端生成一个表达式,74?11 74?转成图片,传到前端进行展示 将结果11存入redis 前端代码实现: 请求后端地址:http://localhost/dev-api/captchaImage,通过反向代理解决前后端跨域问题,将请求路径变为:http://localhost:8080/captchaImage 后端代码实现: /*** 生成验证码*/
GetMapping(/captchaImage)
public AjaxResult getCode(HttpServletResponse response) throws IOException
{AjaxResult ajax AjaxResult.success();boolean captchaEnabled configService.selectCaptchaEnabled();ajax.put(captchaEnabled, captchaEnabled);if (!captchaEnabled){return ajax;}// 保存验证码信息String uuid IdUtils.simpleUUID();String verifyKey CacheConstants.CAPTCHA_CODE_KEY uuid;String capStr null, code null;BufferedImage image null;// 生成验证码String captchaType RuoYiConfig.getCaptchaType();if (math.equals(captchaType)){String capText captchaProducerMath.createText();capStr capText.substring(0, capText.lastIndexOf());code capText.substring(capText.lastIndexOf() 1);image captchaProducerMath.createImage(capStr);}else if (char.equals(captchaType)){capStr code captchaProducer.createText();image captchaProducer.createImage(capStr);}redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);// 转换流信息写出FastByteArrayOutputStream os new FastByteArrayOutputStream();try{ImageIO.write(image, jpg, os);}catch (IOException e){return AjaxResult.error(e.getMessage());}ajax.put(uuid, uuid);ajax.put(img, Base64.encode(os.toByteArray()));return ajax;
}1.2 登录 后端 1.校验验证码2.校验用户名和密码3.生成ToKen /*** 登录方法* * param loginBody 登录信息* return 结果*/
PostMapping(/login)
public AjaxResult login(RequestBody LoginBody loginBody)
{AjaxResult ajax AjaxResult.success();// 生成令牌String token loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),loginBody.getUuid());ajax.put(Constants.TOKEN, token);return ajax;
}使用异步任务管理器,结合线程池,实现了异步的操作日志记录,和业务逻辑实现异步解耦合.
1.3 获取用户信息
/*** 获取用户信息* * return 用户信息*/
GetMapping(getInfo)
public AjaxResult getInfo()
{SysUser user SecurityUtils.getLoginUser().getUser();// 角色集合SetString roles permissionService.getRolePermission(user); // 超级管理员// 权限集合SetString permissions permissionService.getMenuPermission(user); // *:*:*AjaxResult ajax AjaxResult.success();ajax.put(user, user);ajax.put(roles, roles);ajax.put(permissions, permissions);return ajax;
}获取当前用户的角色和权限信息,存储到Vuex中
1.4 获取路由信息 根据当前用户的权限信息获取动态路由,最终完成动态菜单的展示 /*** 获取路由信息* * return 路由信息*/
GetMapping(getRouters)
public AjaxResult getRouters()
{Long userId SecurityUtils.getUserId();ListSysMenu menus menuService.selectMenuTreeByUserId(userId);return AjaxResult.success(menuService.buildMenus(menus));
}二.首页加载 当用户登录成功以后我们可以根据路由看出,默认跳转到路由/viees/index.vue页面 三.用户管理
3.1 查询 流程:加载vue页面 - 请求后台数据 获取用户信息后端 /*** 获取用户列表*/
PreAuthorize(ss.hasPermi(system:user:list))
GetMapping(/list)
public TableDataInfo list(SysUser user)
{startPage(); // 做分页ListSysUser list userService.selectUserList(user); // 查询数据return getDataTable(list); // 返回结果
}获取树状图后端 /*** 获取部门树列表*/
PreAuthorize(ss.hasPermi(system:user:list))
GetMapping(/deptTree)
public AjaxResult deptTree(SysDept dept)
{return success(deptService.selectDeptTreeList(dept));
}3.2 添加用户
前端
/** 新增按钮操作 */
handleAdd() {this.reset();// 清空表单getUser().then(response {this.postOptions response.posts;// 岗位this.roleOptions response.roles;// 角色this.open true;this.title 添加用户;this.form.password this.initPassword;});
},/** 提交按钮 */submitForm: function() {this.$refs[form].validate(valid {if (valid) {if (this.form.userId ! undefined) {updateUser(this.form).then(response {this.$modal.msgSuccess(修改成功);this.open false;this.getList();});} else {addUser(this.form).then(response {this.$modal.msgSuccess(新增成功);this.open false;this.getList();});}}});},后端
/*** 根据用户编号获取详细信息*/
PreAuthorize(ss.hasPermi(system:user:query))
GetMapping(value { /, /{userId} })
public AjaxResult getInfo(PathVariable(value userId, required false) Long userId)
{userService.checkUserDataScope(userId);AjaxResult ajax AjaxResult.success();ListSysRole roles roleService.selectRoleAll();ajax.put(roles, SysUser.isAdmin(userId) ? roles : roles.stream().filter(r - !r.isAdmin()).collect(Collectors.toList()));ajax.put(posts, postService.selectPostAll());if (StringUtils.isNotNull(userId)){SysUser sysUser userService.selectUserById(userId);ajax.put(AjaxResult.DATA_TAG, sysUser);ajax.put(postIds, postService.selectPostListByUserId(userId));ajax.put(roleIds, sysUser.getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList()));}return ajax;
}/*** 新增用户*/
PreAuthorize(ss.hasPermi(system:user:add))
Log(title 用户管理, businessType BusinessType.INSERT)
PostMapping
public AjaxResult add(Validated RequestBody SysUser user)
{if (!userService.checkUserNameUnique(user)){return error(新增用户 user.getUserName() 失败登录账号已存在);}else if (StringUtils.isNotEmpty(user.getPhonenumber()) !userService.checkPhoneUnique(user)){return error(新增用户 user.getUserName() 失败手机号码已存在);}else if (StringUtils.isNotEmpty(user.getEmail()) !userService.checkEmailUnique(user)){return error(新增用户 user.getUserName() 失败邮箱账号已存在);}user.setCreateBy(getUsername());user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));return toAjax(userService.insertUser(user));
}修改和删除查看源码步骤相同,这里省略 四.异步任务管理器 这里选取一段代码作示例:com.ruoyi.framework.web.service.SysLoginService AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message(user.password.not.match)));通过异步任务管理器记录登录日志
AsyncManager.me():获取一个AsyncManager对象执行execute方法,传入的是一个Task对象,实现了Runnable接口表示是一个任务,由线程Thread去执行
/*** 记录登录信息* * param username 用户名* param status 状态* param message 消息* param args 列表* return 任务task*/
public static TimerTask recordLogininfor(final String username, final String status, final String message,final Object... args)
{final UserAgent userAgent UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader(User-Agent));final String ip IpUtils.getIpAddr();return new TimerTask(){Overridepublic void run(){String address AddressUtils.getRealAddressByIP(ip);StringBuilder s new StringBuilder();s.append(LogUtils.getBlock(ip));s.append(address);s.append(LogUtils.getBlock(username));s.append(LogUtils.getBlock(status));s.append(LogUtils.getBlock(message));// 打印信息到日志sys_user_logger.info(s.toString(), args);// 获取客户端操作系统String os userAgent.getOperatingSystem().getName();// 获取客户端浏览器String browser userAgent.getBrowser().getName();// 封装对象SysLogininfor logininfor new SysLogininfor();logininfor.setUserName(username);logininfor.setIpaddr(ip);logininfor.setLoginLocation(address);logininfor.setBrowser(browser);logininfor.setOs(os);logininfor.setMsg(message);// 日志状态if (StringUtils.equalsAny(status, Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER)){logininfor.setStatus(Constants.SUCCESS);}else if (Constants.LOGIN_FAIL.equals(status)){logininfor.setStatus(Constants.FAIL);}// 插入数据SpringUtils.getBean(ISysLogininforService.class).insertLogininfor(logininfor);}};
}封装了登录用户的信息,执行添加操作,这里不会执行,而是将任务交给线程对象来执行 异步任务管理器,内部定义了一个线程池,然后根据业务创建添加日志的任务,交给线程池来处理,这样做到日志和业务的抽象,解耦合,日志全部统一处理. 五.代码自动生成
5.1 创建数据表
use ry_vue;
create table test_user
(id int primary key auto_increment,name varchar(11),password varchar(11)
);5.2 系统工具–代码生成 5.2.1 导入数据表 5.2.2 编辑数据表 5.2.3 点击生成代码 5.2.4 解压压缩包 5.2.5 导入代码,重启项目
后端 前端 数据库