页面预览
就诊人管理
就诊人列表

添加就诊人



查看就诊人

管理员系统用户管理
前面我们完成了用户登录、用户认证与就诊人管理,现在我们需要把这些信息在我们的平台管理系统中进行统一管理
用户列表
用户详情

第01章-token刷新
简单的设置redis和cookie的过期时间,会导致用户在操作的过程中掉线,为了解决这个问题,我们可以使用token续期的方案,具体的做法是生成一个刷新token。
1、存储token
设置token与refreshToken,都包含用户信息(userId、name、headimgurl),可以一样可以不一样,refreshToken比token时间更长,如token30分钟,refreshToken60分钟
在ApiWxController的callback方法的return "redirect:"前面,将之前的生成token和存储token的相关代码封装到saveToken方法中。
将如下代码进行封装:

封装成如下代码:- @Resource
- private AuthContextHolder authContextHolder;
复制代码- UserVo userVo = new UserVo();
- userVo.setName(name);
- userVo.setUserId(userInfo.getId());
- userVo.setHeadimgurl(userInfo.getHeadImgUrl());
- authContextHolder.saveToken(userVo, response);
- return "redirect:" + constantProperties.getSytBaseUrl();
复制代码 service-util中引入依赖- <dependency>
- <groupId>com.atguigu</groupId>
- <artifactId>model</artifactId>
- <version>1.0</version>
- </dependency>
复制代码 在AuthContextHolder中添加如下方法:- /**
- * 将token和refreshToken保存在redis和cookie中的通用方法
- * @param userVo
- * @param response
- */
- public void saveToken(UserVo userVo, HttpServletResponse response) {
- int redisMaxTime = 30;
- //生成token/refreshToken
- String token = getToken();
- String refreshToken = getToken();
- //将生成token/refreshToken存入redis:token做键,userVo做值
- redisTemplate.opsForValue()//30分钟
- .set("user:token:" + token, userVo, redisMaxTime, TimeUnit.MINUTES);
- redisTemplate.opsForValue()//60分钟
- .set("user:refreshToken:" + refreshToken, userVo, redisMaxTime * 2, TimeUnit.MINUTES);
- //将token、refreshToken和name存入cookie
- int cookieMaxTime = 60 * 30;//30分钟
- CookieUtils.setCookie(response, "token", token, cookieMaxTime);
- CookieUtils.setCookie(response, "refreshToken", refreshToken, cookieMaxTime * 2);
- CookieUtils.setCookie(response, "name", URLEncoder.encode(userVo.getName()), cookieMaxTime * 2);
- CookieUtils.setCookie(response, "headimgurl", URLEncoder.encode(userVo.getHeadimgurl()), cookieMaxTime * 2);
- }
复制代码- private String getToken(){
- return UUID.randomUUID().toString().replaceAll("-", "");
- }
复制代码 3、续期token
修改checkAuth方法,当token不存在时,续期token- /**
- * 检查授权状态并续期
- * @param request
- * @return
- */
- public Long checkAuth(HttpServletRequest request, HttpServletResponse response){
- //从http请求头中获取token
- String token = request.getHeader("token");
- if(StringUtils.isEmpty(token)) {
- //throw new GuiguException(ResultCodeEnum.LOGIN_AUTH);
- return refreshToken(request, response);//刷新token
- }
- Object userVoObj = redisTemplate.opsForValue().get("user:token:" + token);
- if(userVoObj == null){
- //throw new GuiguException(ResultCodeEnum.LOGIN_AUTH);
- return refreshToken(request, response);//刷新token
- }
- UserVo userVo = (UserVo)userVoObj;
- return userVo.getUserId();
- }
复制代码- /**
- * 刷新token
- * @param request
- * @param response
- * @return
- */
- public Long refreshToken(HttpServletRequest request, HttpServletResponse response) {
- //从cookie中获取刷新token
- String refreshToken = CookieUtils.getCookie(request, "refreshToken");
- //从redis中根据刷新token获取用户信息
- Object userVoObj = redisTemplate.opsForValue().get("user:refreshToken:" + refreshToken);
- if(userVoObj == null) {
- //LOGIN_AURH(214, "登录过期"),
- throw new GuiguException(ResultCodeEnum.LOGIN_TIMEOUT);//登录过期
- }
- UserVo userVo = (UserVo) userVoObj;
- saveToken(userVo, response);
- return userVo.getUserId();
- }
复制代码 4、修改checkAuth方法的调用
FrontUserInfoController和FrontFileController中的方法,添加response参数
5、cookie跨域
跨域ajax访问时,session_id不会被存储,cookie不会被传递到后端,因此需要解决cookie跨域存储的问题
解决方案:
(1)网关配置文件CorsConfig中添加如下设置:- config.setAllowCredentials(true); //避免跨域访问时session_id每次不一致
复制代码 (2)前端axios初始化文件request.js添加如下设置:- withCredentials: true //避免跨域访问时session_id每次不一致
复制代码 6、前端request.js拦截处理
如果接口返回214状态(登录超时),说明用户超时未操作,直接退出。- // http response 拦截器
- service.interceptors.response.use(
- response => {
- //如果响应码是214,则需要登录超时
- if (response.data.code === 214) {
- // to re-login
- MessageBox.confirm('登录超时, 请重新登录', '确认退出', {
- confirmButtonText: '重新登录',
- cancelButtonText: '回到首页',
- type: 'warning'
- }).then(() => {
- window.location.href = process.env.BASE_API + '/front/user/wx/login'
- }).catch(()=>{
- window.location.href = '/'
- })
-
- }else if (response.data.code !== 200) {
- Message({
- message: response.data.message,
- type: 'error',
- duration: 5 * 1000
- })
- return Promise.reject(response.data)
- } else {
- return response.data
- }
- },
- error => {
- return Promise.reject(error.response)
- })
复制代码 7、myheader.vue
myheader.vue中showInfo方法的修改,保证token过期后,用户名信息依然显示- showInfo() {
- let refreshToken = cookie.get('refreshToken')
- if (refreshToken) {
- this.name = cookie.get('name')
- this.headimgurl = cookie.get('headimgurl')
- }
- },
复制代码 myheader.vue中退出登录方法的修改,需要清空refreshToken- cookie.set('name', '', {domain: 'localhost'})
- cookie.set('token', '', {domain: 'localhost'})
- cookie.set('refreshToken', '', {domain: 'localhost'}) //清空refreshToken
- cookie.set('headimgurl', '', {domain: 'localhost'})
复制代码 补充:由于我们解决了cookie的ajax传递跨域问题,因此之前通过header传输的token其实可以不必要了,我们可以直接在后端从cookie中获取token的值,如下:- String token = request.getHeader("token");
- //以上可以替换为如下:
- String token = CookieUtils.getCookie(request, "token");
复制代码 第02章-就诊人管理
1、后端接口
1.1、添加就诊人
FrontPatientController:- package com.atguigu.syt.user.controller.front;
- @Api(tags = "就诊人管理")
- @RestController
- @RequestMapping("/front/user/patient")
- public class FrontPatientController {
- @Resource
- private PatientService patientService;
- @Resource
- private AuthContextHolder authContextHolder;
- @ApiOperation("添加就诊人")
- @ApiImplicitParam(name = "patient",value = "就诊人对象", required = true)
- @PostMapping("/auth/save")
- public Result savePatient(@RequestBody Patient patient, HttpServletRequest request, HttpServletResponse response) {
- Long userId = authContextHolder.checkAuth(request, response);
- patient.setUserId(userId);
- patientService.save(patient);
- return Result.ok().message("保存成功");
- }
- }
复制代码 1.2、修改
FrontPatientController:- @ApiOperation("修改就诊人")
- @ApiImplicitParam(name = "patient",value = "就诊人对象", required = true)
- @PutMapping("/auth/update")
- public Result updatePatient(@RequestBody Patient patient, HttpServletRequest request, HttpServletResponse response) {
- authContextHolder.checkAuth(request, response);
- patientService.updateById(patient);
- return Result.ok().message("修改成功");
- }
复制代码 1.3、根据id获取就诊人
FrontPatientController:- @ApiOperation("根据id获取就诊人信息")
- @ApiImplicitParam(name = "id",value = "就诊人id", required = true)
- @GetMapping("/auth/get/{id}")
- public Result<Patient> getPatient(@PathVariable Long id, HttpServletRequest request, HttpServletResponse response) {
- Long userId = authContextHolder.checkAuth(request, response);
- //加上userId参数,只可以获取自己名下的就诊人信息
- Patient patient = patientService.getPatientById(id, userId);
- return Result.ok(patient);
- }
复制代码 接口:PatientService- /**
- * 根据id获取本人名下的就诊人信息
- * @param id
- * @param userId
- * @return
- */
- Patient getPatientById(Long id, Long userId);
复制代码 实现:PatientServiceImpl- @Override
- public Patient getPatientById(Long id, Long userId) {
- LambdaQueryWrapper<Patient> queryWrapper = new LambdaQueryWrapper<>();
- queryWrapper.eq(Patient::getUserId, userId).eq(Patient::getId, id);
- Patient patient = baseMapper.selectOne(queryWrapper);
- //封装数据
- return this.packPatient(patient);
- }
复制代码 辅助方法- @Resource
- private DictFeignClient dictFeignClient;
- @Resource
- private RegionFeignClient regionFeignClient;
复制代码- /**
- * 封装Patient对象里面其他参数
- * @param patient
- * @return
- */
- private Patient packPatient(Patient patient) {
- String certificatesTypeString = dictFeignClient.getName(DictTypeEnum.CERTIFICATES_TYPE.getDictTypeId(),patient.getCertificatesType());
- String contactsCertificatesTypeString = dictFeignClient.getName(
- DictTypeEnum.CERTIFICATES_TYPE.getDictTypeId(),patient.getContactsCertificatesType());
- String provinceString = regionFeignClient.getName(patient.getProvinceCode());
- String cityString = regionFeignClient.getName(patient.getCityCode());
- String districtString = regionFeignClient.getName(patient.getDistrictCode());
- patient.getParam().put("certificatesTypeString", certificatesTypeString);
- patient.getParam().put("contactsCertificatesTypeString", contactsCertificatesTypeString);
- patient.getParam().put("provinceString", provinceString);
- patient.getParam().put("cityString", cityString);
- patient.getParam().put("districtString", districtString);
- patient.getParam().put("fullAddress",
- provinceString + cityString + districtString + patient.getAddress());
- return patient;
- }
复制代码 1.4、获取就诊人列表
FrontPatientController- @ApiOperation("获取就诊人列表")
- @GetMapping("/auth/findAll")
- public Result<List<Patient>> findAll(HttpServletRequest request, HttpServletResponse response) {
- Long userId = authContextHolder.checkAuth(request, response);
- List<Patient> list = patientService.findByUserId(userId);
- return Result.ok(list);
- }
复制代码 接口:PatientService- /**
- * 根据userId获取就诊人列表
- * @param userId
- * @return
- */
- List<Patient> findByUserId(Long userId);
复制代码 实现:PatientServiceImpl- @Override
- public List<Patient> findByUserId(Long userId) {
- LambdaQueryWrapper<Patient> queryWrapper = new LambdaQueryWrapper<>();
- queryWrapper.eq(Patient::getUserId, userId);
- List<Patient> patientList = baseMapper.selectList(queryWrapper);
- patientList.forEach(patient -> {
- patient.getParam().put("expenseMethod", patient.getIsInsure()==0?"自费":"医保");
- });
- return patientList;
- }
复制代码 1.5、删除就诊人
FrontPatientController:- @ApiOperation("删除就诊人")
- @DeleteMapping("/auth/remove/{id}")
- public Result removePatient(@PathVariable Long id, HttpServletRequest request, HttpServletResponse response) {
- Long userId = authContextHolder.checkAuth(request, response);
- //加上userId参数,只可以删除自己名下的就诊人信息
- patientService.removeById(id, userId);
- return Result.ok();
- }
复制代码 接口:PatientService- /**
- * 根据id删除自己名下的就诊人信息
- * @param id
- * @param userId
- */
- void removeById(Long id, Long userId);
复制代码 实现:PatientServiceImpl- @Override
- public void removeById(Long id, Long userId) {
- LambdaQueryWrapper<Patient> queryWrapper = new LambdaQueryWrapper<>();
- queryWrapper.eq(Patient::getUserId, userId).eq(Patient::getId, id);
- baseMapper.delete(queryWrapper);
- }
复制代码 2、前端整合
2.1、api
创建api/patient.js- import request from '~/utils/request'
- export default {
- save(patient) {
- return request({
- url: `/front/user/patient/auth/save`,
- method: 'post',
- data: patient
- })
- },
- updateById(patient) {
- return request({
- url: `/front/user/patient/auth/update`,
- method: 'put',
- data: patient
- })
- },
- getById(id) {
- return request({
- url: `/front/user/patient/auth/get/${id}`,
- method: 'get'
- })
- },
- findList() {
- return request({
- url: `/front/user/patient/auth/findAll`,
- method: `get`
- })
- },
- removeById(id) {
- return request({
- url: `/front/user/patient/auth/remove/${id}`,
- method: 'delete'
- })
- }
- }
复制代码 2.2、页面渲染
资料:资料>就诊人管理>
就诊人列表:pages/patient/index.vue
就诊人添加与修改 :pages/patient/add.vue
就诊人详情与删除:pages/patient/show.vue
第03章-管理系统用户管理(作业)
1、后端接口
1.1、用户列表
AdminUserInfoController:- package com.atguigu.syt.user.controller.admin;
- @Api(tags = "用户管理接口")
- @RestController
- @RequestMapping("/admin/user/userInfo")
- public class AdminUserInfoController {
- @Resource
- private UserInfoService userInfoService;
- @ApiOperation("分页条件查询")
- @ApiImplicitParams({
- @ApiImplicitParam(name = "page",value = "页码",required = true),
- @ApiImplicitParam(name = "limit",value = "每页记录数",required = true),
- @ApiImplicitParam(name = "userInfoQueryVo",value = "查询对象",required = false)
- })
- @GetMapping("/{page}/{limit}")
- public Result<IPage<UserInfo>> list(
- @PathVariable Long page,
- @PathVariable Long limit,
- UserInfoQueryVo userInfoQueryVo
- ) {
- Page<UserInfo> pageParam = new Page<>(page,limit);
- IPage<UserInfo> pageModel = userInfoService.selectPage(pageParam, userInfoQueryVo);
- return Result.ok(pageModel);
- }
- }
复制代码 Service接口:UserInfoService- /**
- * 查询用户分页列表
- * @param pageParam
- * @param userInfoQueryVo
- * @return
- */
- IPage<UserInfo> selectPage(Page<UserInfo> pageParam, UserInfoQueryVo userInfoQueryVo);
复制代码 Service实现:UserInfoServiceImpl- @Override
- public IPage<UserInfo> selectPage(Page<UserInfo> pageParam, UserInfoQueryVo userInfoQueryVo) {
- //UserInfoQueryVo获取条件值
- String keyword = userInfoQueryVo.getKeyword(); //用户名称
- String createTimeBegin = userInfoQueryVo.getCreateTimeBegin(); //开始时间
- String createTimeEnd = userInfoQueryVo.getCreateTimeEnd(); //结束时间
- //对条件值进行非空判断
- LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
- wrapper.and(!StringUtils.isEmpty(keyword),
- i -> i.like(UserInfo::getName, keyword).or().like(UserInfo::getPhone, keyword))
- .ge(!StringUtils.isEmpty(createTimeBegin), UserInfo::getCreateTime, createTimeBegin)
- .le(!StringUtils.isEmpty(createTimeEnd), UserInfo::getCreateTime, createTimeEnd);
- //调用mapper的方法
- IPage<UserInfo> pages = baseMapper.selectPage(pageParam, wrapper);
- //编号变成对应值封装
- pages.getRecords().forEach(this::packUserInfoForList);
- return pages;
- }
复制代码 辅助方法:- /**
- * 封装用户状态、认证状态、证件类型信息
- * @param userInfo
- * @return
- */
- private UserInfo packUserInfoForList(UserInfo userInfo) {
- //判断用户是否已经提交实名认证
- if(userInfo.getAuthStatus().intValue() != AuthStatusEnum.NO_AUTH.getStatus().intValue()){
- String certificatesTypeString = dictFeignClient.getName(
- DictTypeEnum.CERTIFICATES_TYPE.getDictTypeId(),
- userInfo.getCertificatesType()
- );
- userInfo.getParam().put("certificatesTypeString", certificatesTypeString);
- }
-
- userInfo.getParam().put("authStatusString", AuthStatusEnum.getStatusNameByStatus(userInfo.getAuthStatus()));
- userInfo.getParam().put("statusString", UserStatusEnum.getStatusNameByStatus(userInfo.getStatus()));
- return userInfo;
- }
复制代码 1.2、锁定和解锁
Controller:在AdminUserInfoController中添加方法- @ApiOperation("锁定和解锁")
- @ApiImplicitParams({
- @ApiImplicitParam(name = "userId",value = "用户id",required = true),
- @ApiImplicitParam(name = "status",value = "用户状态",required = true)
- })
- @PutMapping("lock/{userId}/{status}")
- public Result lock(
- @PathVariable("userId") Long userId,
- @PathVariable("status") Integer status){
- boolean result = userInfoService.lock(userId, status);
- if(result){
- return Result.ok().message("设置成功");
- }else{
- return Result.ok().message("设置失败");
- }
- }
复制代码 Service接口:UserInfoService- /**
- * 锁定和解锁用户
- * @param userId
- * @param status
- * @return
- */
- boolean lock(Long userId, Integer status);
复制代码 Service实现:UserInfoServiceImpl- @Override
- public boolean lock(Long userId, Integer status) {
- if(status == 0 || status == 1){
- UserInfo userInfo = new UserInfo();
- userInfo.setId(userId);
- userInfo.setStatus(status);
- return this.updateById(userInfo);
- }
- return false;
- }
复制代码 1.3、用户详情
Controller:在AdminUserInfoController中添加方法- @ApiOperation("用户详情")
- @ApiImplicitParam(name = "userId",value = "用户id",required = true)
- @GetMapping("show/{userId}")
- public Result<Map<String, Object>> show(@PathVariable Long userId) {
- return Result.ok(userInfoService.show(userId));
- }
复制代码 Service接口:UserInfoService- /**
- * 根据用户id获取用户详情
- * @param userId
- * @return
- */
- Map<String, Object> show(Long userId);
复制代码 Service实现:UserInfoServiceImpl- @Resource
- private PatientService patientService;
复制代码- @Override
- public Map<String, Object> show(Long userId) {
- Map<String,Object> map = new HashMap<>();
- //根据userid查询用户信息
- UserInfo userInfo = this.packUserInfo(baseMapper.selectById(userId));
- map.put("userInfo",userInfo);
- //根据userid查询就诊人信息
- List<Patient> patientList = patientService.findByUserId(userId);
- map.put("patientList",patientList);
- return map;
- }
复制代码 1.4、用户认证审批
Controller:在AdminUserInfoController中添加方法- @ApiOperation("认证审批")
- @ApiImplicitParams({
- @ApiImplicitParam(name = "userId",value = "用户id",required = true),
- @ApiImplicitParam(name = "authStatus",value = "用户认证审批状态",required = true)
- })
- @PutMapping("approval/{userId}/{authStatus}")
- public Result approval(@PathVariable Long userId, @PathVariable Integer authStatus) {
- boolean result = userInfoService.approval(userId,authStatus);
- if(result){
- return Result.ok().message("审批成功");
- }else{
- return Result.ok().message("审批失败");
- }
- }
复制代码 Service接口:UserInfoService- /**
- * 审核用户
- * @param userId
- * @param authStatus
- * @return
- */
- boolean approval(Long userId, Integer authStatus);
复制代码 Service实现:UserInfoServiceImpl- /**
- * 认证审批 2通过 -1不通过
- * @param userId
- * @param authStatus
- * @return
- */
- @Override
- public boolean approval(Long userId, Integer authStatus) {
- if(authStatus == AuthStatusEnum.AUTH_SUCCESS.getStatus()
- || authStatus == AuthStatusEnum.AUTH_FAIL.getStatus()){
- UserInfo userInfo = new UserInfo();
- userInfo.setId(userId);
- userInfo.setAuthStatus(authStatus);
- return this.updateById(userInfo);
- }
- return false;
- }
复制代码 2、前端整合
2.1、页面
在后台管理系统前端项目中添加如下页面,资料:资料>用户管理
用户列表:src/views/syt/userInfo/list.vue
用户详情,详情页面展示用户信息、用户就诊人信息:src/views/syt/userInfo/show.vue
2.2、路由
静态路由:- {
- path: '/userInfo',
- component: Layout,
- redirect: '/userInfo/list',
- name: 'userInfo',
- meta: { title: '用户管理', icon: 'user' },
- alwaysShow: true,
- children: [
- {
- path: 'list',
- name: 'userInfoList',
- component: () => import('@/views/syt/userInfo/list'),
- meta: { title: '用户列表', icon: 'el-icon-s-unfold' }
- },
- {
- path: 'show/:id',
- name: 'userInfoShow',
- component: () => import('@/views/syt/userInfo/show'),
- meta: { title: '查看用户' },
- hidden: true
- }
- ]
- },
复制代码 动态路由:
用户管理:

用户列表:

查看用户:

2.3、api
创建src/api/syt/userInfo.js- import request from '@/utils/request'
- const apiName = '/admin/user/userInfo'
- export default {
- //用户列表
- getPageList(page, limit, searchObj) {
- return request({
- url: `${apiName}/${page}/${limit}`,
- method: 'get',
- params: searchObj
- })
- },
- //锁定与解锁
- lock(id, status) {
- return request({
- url: `${apiName}/lock/${id}/${status}`,
- method: 'put'
- })
- },
- //用户详情
- show(id) {
- return request({
- url: `${apiName}/show/${id}`,
- method: 'get'
- })
- },
- //认证审批
- approval(id, authStatus) {
- return request({
- url: `${apiName}/approval/${id}/${authStatus}`,
- method: 'put'
- })
- }
- }
复制代码 源码:https://gitee.com/dengyaojava/guigu-syt-parent
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |