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

添加就诊人

查看就诊人

![image-20230225060710

管理员系统用户管理

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

用户列表用户详情

第01章-token刷新

简单的设置redis和cookie的过期时间,会导致用户在操作的过程中掉线,为了解决这个问题,我们可以使用token续期的方案,具体的做法是生成一个刷新token。

1、存储token

设置token与refreshToken,都包含用户信息(userId、name、headimgurl),可以一样可以不一样,refreshToken比token时间更长,如token30分钟,refreshToken60分钟

ApiWxController的callback方法的return "redirect:"前面,将之前的生成token和存储token的相关代码封装到saveToken方法中。

将如下代码进行封装:

封装成如下代码:

@Resourceprivate 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中引入依赖

    com.atguigu    model    1.0

在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-loginMessageBox.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'}) //清空refreshTokencookie.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 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

@Overridepublic Patient getPatientById(Long id, Long userId) {    LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper();    queryWrapper.eq(Patient::getUserId, userId).eq(Patient::getId, id);    Patient patient = baseMapper.selectOne(queryWrapper);    //封装数据    return this.packPatient(patient);}

辅助方法

@Resourceprivate DictFeignClient dictFeignClient;@Resourceprivate 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> findAll(HttpServletRequest request, HttpServletResponse response) {    Long userId = authContextHolder.checkAuth(request, response);    List list = patientService.findByUserId(userId);    return Result.ok(list);}

接口:PatientService

/**     * 根据userId获取就诊人列表     * @param userId     * @return     */List findByUserId(Long userId);

实现:PatientServiceImpl

@Overridepublic List findByUserId(Long userId) {    LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper();    queryWrapper.eq(Patient::getUserId, userId);    List 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

@Overridepublic void removeById(Long id, Long userId) {    LambdaQueryWrapper 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> list(            @PathVariable Long page,            @PathVariable Long limit,            UserInfoQueryVo userInfoQueryVo    ) {        Page pageParam = new Page(page,limit);        IPage pageModel = userInfoService.selectPage(pageParam, userInfoQueryVo);        return Result.ok(pageModel);    }}

Service接口:UserInfoService

/**     * 查询用户分页列表     * @param pageParam     * @param userInfoQueryVo     * @return     */IPage selectPage(Page pageParam, UserInfoQueryVo userInfoQueryVo);

Service实现:UserInfoServiceImpl

@Overridepublic IPage selectPage(Page pageParam, UserInfoQueryVo userInfoQueryVo) {    //UserInfoQueryVo获取条件值    String keyword = userInfoQueryVo.getKeyword(); //用户名称    String createTimeBegin = userInfoQueryVo.getCreateTimeBegin(); //开始时间    String createTimeEnd = userInfoQueryVo.getCreateTimeEnd(); //结束时间    //对条件值进行非空判断    LambdaQueryWrapper 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 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

@Overridepublic 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> show(@PathVariable Long userId) {    return Result.ok(userInfoService.show(userId));}

Service接口:UserInfoService

/**     * 根据用户id获取用户详情     * @param userId     * @return     */Map show(Long userId);

Service实现:UserInfoServiceImpl

@Resourceprivate PatientService patientService;
@Overridepublic Map show(Long userId) {    Map map = new HashMap();    //根据userid查询用户信息    UserInfo userInfo = this.packUserInfo(baseMapper.selectById(userId));    map.put("userInfo",userInfo);    //根据userid查询就诊人信息    List 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     */@Overridepublic 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

本文来自博客园,作者:自律即自由-,转载请注明原文链接:https://www.cnblogs.com/deyo/p/17487118.html