一、 阿里云oss
用户认证需要上传证件图片、首页轮播也需要上传图片,因此我们要做文件服务,阿里云oss是一个很好的分布式文件服务系统,所以我们只需要集成阿里云oss即可
1、开通“对象存储OSS”服务
(1)申请阿里云账号
(2)实名认证
(3)开通“对象存储OSS”服务
(4)进入管理控制台
1.1创建Bucket
1.2上传默认头像
1.3获取用户acesskeys
2、使用SDK文档
3、文件服务实现
3.1搭建service-oss模块
3.1.1 搭建service-oss模块
3.1.2 修改配置
1、修改pom.xml,引入阿里云oss依赖
| <dependencies>
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
</dependency>
_<!-- 日期工具栏依赖 --><br /> _<**dependency**><br /> <**groupId**>joda-time</**groupId**><br /> <**artifactId**>joda-time</**artifactId**><br /> </**dependency**><br /></**dependencies**> |
| —- |
2、添加配置文件application.properties
# 服务端口server.port=8205# 服务名spring.application.name=service-oss #返回json的全局时间格式spring.jackson.date-format=yyyy-MM-dd HH:mm:ssspring.jackson.time-zone=GMT+8 # nacos服务地址spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848 aliyun.oss.endpoint=oss-cn-beijing.aliyuncs.comaliyun.oss.accessKeyId=LTAI4G4SV6WtST7UYH776b64aliyun.oss.secret=X9KHNYgztNr9MI5Zp8JffQPZO4uJo5aliyun.oss.bucket=yygh-atguigu |
---|
3.1.3 启动类
//取消数据源自动配置@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)@EnableDiscoveryClient @ComponentScan(basePackages = {“com.atguigu”})public class ServiceOssApplication { public static void main(String[] args) { SpringApplication.run(ServiceOssApplication.class, args); } } |
---|
3.1.4配置网关
#设置路由idspring.cloud.gateway.routes[5].id=service-oss#设置路由的urispring.cloud.gateway.routes[5].uri=lb://service-oss#设置路由断言,代理servicerId为auth-service的/auth/路径spring.cloud.gateway.routes[5].predicates= Path=//oss/* |
---|
3.2 测试SDK
3.3封装service接口
public interface FileService { _//上传文件到阿里云oss _String upload(MultipartFile file); } |
---|
2、创建com.atguigu.yygh.oss.utils.ConstantOssPropertiesUtils配置类
| @Componentpublic class ConstantOssPropertiesUtils implements InitializingBean {
@Value(**"${aliyun.oss.endpoint}"**)<br /> **private **String **endpoint**;
@Value(**"${aliyun.oss.accessKeyId}"**)<br /> **private **String **accessKeyId**;
@Value(**"${aliyun.oss.secret}"**)<br /> **private **String **secret**;
@Value(**"${aliyun.oss.bucket}"**)<br /> **private **String **bucket**;
**public static **String _EDNPOINT_;<br /> **public static **String _ACCESS_KEY_ID_;<br /> **public static **String _SECRECT_;<br /> **public static **String _BUCKET_;
@Override<br /> **public void **afterPropertiesSet() **throws **Exception {<br /> _EDNPOINT_=**endpoint**;<br /> _ACCESS_KEY_ID_=**accessKeyId**;<br /> _SECRECT_=**secret**;<br /> _BUCKET_=**bucket**;<br /> }<br />} |
| —- |
3、创建接口类实现类
@Servicepublic class FileServiceImpl implements FileService { @Override public String upload(MultipartFile file) { // Endpoint以杭州为例,其它Region请按实际情况填写。 _String endpoint = ConstantOssPropertiesUtils._EDNPOINT; String accessKeyId = ConstantOssPropertiesUtils.ACCESS_KEY_ID; String accessKeySecret = ConstantOssPropertiesUtils.SECRECT; String bucketName = ConstantOssPropertiesUtils.BUCKET; try { // 创建OSSClient实例。 _OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); // 上传文件流。 InputStream inputStream = file.getInputStream(); String fileName = file.getOriginalFilename(); //生成随机唯一值,使用uuid,添加到文件名称里面 String uuid = UUID._randomUUID().toString().replaceAll(“-“,“”); fileName = uuid+fileName; //按照当前日期,创建文件夹,上传到创建文件夹里面 // 2021/02/02/01.jpg _String timeUrl = new DateTime().toString(“yyyy/MM/dd”); fileName = timeUrl+“/“+fileName; //调用方法实现上传 ossClient.putObject(bucketName, fileName, inputStream); // 关闭OSSClient。 ossClient.shutdown(); //上传之后文件路径 // [_https://yygh-atguigu.oss-cn-beijing.aliyuncs.com/01.jpg](https://yygh-atguigu.oss-cn-beijing.aliyuncs.com/01.jpg)__ String url = “https://“+bucketName+“.”+endpoint+“/“+fileName; //返回 _return url; } catch (IOException e) { e.printStackTrace(); return null; } } } |
---|
3.4封装controller接口
@RestController @RequestMapping(“/api/oss/file”)public class FileApiController { @Autowired private FileService fileService; //上传文件到阿里云oss @PostMapping(“fileUpload”) public Result fileUpload(MultipartFile file) { //获取上传文件 _String url = fileService.upload(file); return Result._ok(url); } } |
---|
2 用户认证
3 需求分析
用户登录成功后都要进行身份认证,认证通过后才可以预约挂号
认证过程:用户填写信息(姓名、证件类型、证件号码和证件照片)==> 平台审批
用户认证设计接口:
//用户认证void userAuth(Long userId, UserAuthVo userAuthVo); |
---|
2、在UserInfoServiceImpl类添加实现
//用户认证@Overridepublic void userAuth(Long userId, UserAuthVo userAuthVo) { //根据用户id查询用户信息 _UserInfo userInfo = baseMapper.selectById(userId); //设置认证信息 //认证人姓名 userInfo.setName(userAuthVo.getName()); //其他认证信息 userInfo.setCertificatesType(userAuthVo.getCertificatesType()); userInfo.setCertificatesNo(userAuthVo.getCertificatesNo()); userInfo.setCertificatesUrl(userAuthVo.getCertificatesUrl()); userInfo.setAuthStatus(AuthStatusEnum.**_AUTH_RUN.getStatus()); //进行信息更新 baseMapper**.updateById(userInfo); } |
---|
2.2 获取当前用户工具类
在common-util模块添加工具类
//获取当前用户信息工具类public class AuthContextHolder { //获取当前用户id public static Long getUserId(HttpServletRequest request) { //从header获取token _String token = request.getHeader(“token”); //jwt从token获取userid Long userId = JwtHelper._getUserId(token); return userId; } //获取当前用户名称 public static String getUserName(HttpServletRequest request) { //从header获取token _String token = request.getHeader(“token”); //jwt从token获取userid String userName = JwtHelper._getUserName(token); return userName; } } |
---|
2.3 添加controller方法
在UserInfoApiController类添加方法
//用户认证接口@PostMapping(“auth/userAuth”)public Result userAuth(@RequestBody UserAuthVo userAuthVo, HttpServletRequest request) { //传递两个参数,第一个参数用户id,第二个参数认证数据vo对象 userInfoService.userAuth(AuthContextHolder.getUserId(request),userAuthVo); return Result.ok(); } //获取用户id信息接口@GetMapping(“auth/getUserInfo”)public Result getUserInfo(HttpServletRequest request) { Long userId = AuthContextHolder.getUserId(request); UserInfo userInfo = userInfoService.getById(userId); return Result.ok(userInfo); } |
---|
3、前端
3.1封装api请求
在/api/userInfo.js添加方法
getUserInfo() {return request({ url: `${api_name}/auth/getUserInfo`, method: get })}, saveUserAuah(userAuah) { return request({ url: `${api_name}/auth/userAuah`, method: ‘post’, data: userAuah }) } |
---|
3.2 页面展示
创建/pages/user/index.vue组件
4、预约挂号页面调整
如果要预约挂号,我们必须要认证通过后才可以,所以我们在预约挂号前要做认证判断,如果没有认证通过,则跳转到认证页面
修改/pages/hospital/_hoscode.vue组件
import userInfoApi from ‘@/api/userInfo’ schedule(depcode) { // 登录判断 let token = cookie.get(‘token’) if (!token) { loginEvent.$emit(‘loginDialogEvent’) return } //判断认证 userInfoApi.getUserInfo().then(response => { let authStatus = response.data.authStatus // 状态为2认证通过 if (!authStatus || authStatus != 2) { window.location.href = ‘/user’ return } }) window.location.href = ‘/hospital/schedule?hoscode=’ + this.hospital.hoscode + “&depcode=”+ depcode }, |
---|
三、就诊人管理
5 需求分析
预约下单需要选择就诊人,因此我们要实现就诊人管理,前端就诊人管理其实就是要实现一个完整的增删改查
6 api接口
2.1 引入依赖
<dependencies> <dependency> <groupId>com.atguigu</groupId> <artifactId>service_cmn_client</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies> |
---|
2.2 添加Mapper
添加com.atguigu.yygh.user.mapper.PatientMapper
public interface PatientMapper extends BaseMapper } |
---|
2.3 添加service接口及实现类
1、添加com.atguigu.yygh.user.service.PatientService 接口
public interface PatientService extends IService //获取就诊人列表 _List _Patient getPatientId(Long id); } |
---|
2、添加com.atguigu.yygh.user.service.impl.PatientServiceImpl接口实现
@Servicepublic class PatientServiceImpl extends ServiceImpl @Autowired private DictFeignClient dictFeignClient; //获取就诊人列表 @Override public List //根据userid查询所有就诊人信息列表 _QueryWrapper wrapper.eq(“user_id”,userId); List patientList.stream().forEach(item -> { //其他参数封装 this.packPatient(item); }); return patientList; } @Override public Patient getPatientId(Long id) { return this.packPatient(baseMapper.selectById(id)); } //Patient对象里面其他参数封装 private Patient packPatient(Patient patient) { //根据证件类型编码,获取证件类型具体指 String certificatesTypeString = dictFeignClient.getName(DictEnum.**_CERTIFICATES_TYPE.getDictCode(), patient.getCertificatesType());_//联系人证件 //联系人证件类型 _String contactsCertificatesTypeString = dictFeignClient.getName(DictEnum.CERTIFICATES_TYPE.getDictCode(),patient.getContactsCertificatesType()); _//省 _String provinceString = dictFeignClient.getName(patient.getProvinceCode()); _//市 _String cityString = dictFeignClient.getName(patient.getCityCode()); _//区 _String districtString = dictFeignClient.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; } } |
---|
2.4 添加controller
添加com.atguigu.yygh.user.api.PatientApiController
//就诊人管理接口@RestController @RequestMapping(“/api/user/patient”)public class PatientApiController { @Autowired private PatientService patientService; //获取就诊人列表 @GetMapping(“auth/findAll”) public Result findAll(HttpServletRequest request) { //获取当前登录用户id _Long userId = AuthContextHolder._getUserId(request); List return Result.ok(list); } //添加就诊人 @PostMapping(“auth/save”) public Result savePatient(@RequestBody Patient patient,HttpServletRequest request) { //获取当前登录用户id _Long userId = AuthContextHolder._getUserId(request); patient.setUserId(userId); patientService.save(patient); return Result.ok(); } //根据id获取就诊人信息 @GetMapping(“auth/get/{id}”) public Result getPatient(@PathVariable Long id) { Patient patient = patientService.getPatientId(id); return Result.ok(patient); } //修改就诊人 @PostMapping(“auth/update”) public Result updatePatient(@RequestBody Patient patient) { patientService.updateById(patient); return Result.ok(); } //删除就诊人 @DeleteMapping(“auth/remove/{id}”) public Result removePatient(@PathVariable Long id) { patientService.removeById(id); return Result.ok(); } } |
---|
7 前端
3.1 封装api请求
创建/api/patient.js文件
import request from ‘@/utils/request’ const api_name = /api/user/patient export default { //就诊人列表 findList() { return request({ url: ${api_name}/auth/findAll ,method: get }) }, //根据id查询就诊人信息 getById(id) { return request({ url: ${api_name}/auth/get/${id} ,method: ‘get’ }) }, //添加就诊人信息 save(patient) { return request({ url: ${api_name}/auth/save ,method: ‘post’, data: patient }) }, //修改就诊人信息 updateById(patient) { return request({ url: ${api_name}/auth/update ,method: ‘post’, data: patient }) }, //删除就诊人信息 removeById(id) { return request({ url: ${api_name}/auth/remove/${id} ,method: ‘delete’ }) } } |
---|
3.2 列表
添加/pages/patient/index.vue组件
3.3 添加与修改
添加/pages/patient/add.vue组件
3.4 详情与删除
添加/pages/patient/show.vue组件
四、平台用户管理
前面我们做了用户登录、用户认证与就诊人,现在我们需要把这些信息在我们的平台管理系统做一个统一管理
操作模块:service-user
8 用户列表
8.1 api接口
8.1.1 添加service接口与实现
1、在UserInfoService类添加接口
_//用户列表(条件查询带分页)_IPage |
---|
2、在UserInfoServiceImpl类添加实现
| //用户列表(条件查询带分页)
@Override
public IPage
//UserInfoQueryVo获取条件值
_String name = userInfoQueryVo.getKeyword(); //用户名称
Integer status = userInfoQueryVo.getStatus();//用户状态
Integer authStatus = userInfoQueryVo.getAuthStatus(); //认证状态
String createTimeBegin = userInfoQueryVo.getCreateTimeBegin(); //开始时间
String createTimeEnd = userInfoQueryVo.getCreateTimeEnd(); //结束时间
//对条件值进行非空判断
QueryWrapper
if(!StringUtils._isEmpty
wrapper.like(“name”,name);
}
if(!StringUtils.isEmpty(status)) {
wrapper.eq(“status”,status);
}
if(!StringUtils.isEmpty(authStatus)) {
wrapper.eq(“auth_status”,authStatus);
}
if(!StringUtils.isEmpty(createTimeBegin)) {
wrapper.ge(“create_time”,createTimeBegin);
}
if(!StringUtils.isEmpty(createTimeEnd)) {
wrapper.le(“create_time”,createTimeEnd);
}
//调用mapper的方法
_IPage
_pages.getRecords().stream().forEach(item -> {
this.packageUserInfo(item);
});
return pages;
}
_//编号变成对应值封装<br /> _**private **UserInfo packageUserInfo(UserInfo userInfo) {<br /> _//处理认证状态编码<br /> _userInfo.getParam().put(**"authStatusString"**,AuthStatusEnum._getStatusNameByStatus_(userInfo.getAuthStatus()));<br /> _//处理用户状态 0 1<br /> _String statusString = userInfo.getStatus().intValue()==0 ?**"锁定" **: **"正常"**;<br /> userInfo.getParam().put(**"statusString"**,statusString);<br /> **return **userInfo;<br /> } |
| —- |
8.1.2 添加controller方法
添加com.atguigu.yygh.user.controller.UserController类
| @RestController
@RequestMapping(“/admin/user”)public class UserController {
@Autowired<br /> **private **UserInfoService **userInfoService**;
_//用户列表(条件查询带分页)<br /> _@GetMapping(**"{page}/{limit}"**)<br /> **public **Result list(@PathVariable Long page,<br /> @PathVariable Long limit,<br /> UserInfoQueryVo userInfoQueryVo) {<br /> Page<UserInfo> pageParam = **new **Page<>(page,limit);<br /> IPage<UserInfo> pageModel =<br /> **userInfoService**.selectPage(pageParam,userInfoQueryVo);<br /> **return **Result._ok_(pageModel);<br /> }<br />} |
| —- |
8.2 前端
1.2.1 添加路由
在 src/router/index.js 文件添加路由
{ path: ‘/user’, component: Layout, redirect: ‘/user/userInfo/list’, name: ‘userInfo’, meta: { title: ‘用户管理’, icon: ‘table’ }, alwaysShow: true, children: [ { path: ‘userInfo/list’, name: ‘用户列表’, component: () =>import(‘@/views/user/userInfo/list’), meta: { title: ‘用户列表’, icon: ‘table’ } } ] }, |
---|
1.2.2封装api请求
创建/api/user/userInfo.js
import request from ‘@/utils/request’ const api_name = ‘/admin/user’ export default { getPageList(page, limit, searchObj) { return request({ url: `${api_name}/${page}/${limit}`, method: ‘get’, params: searchObj }) } } |
---|
1.2.3 添加组件
创建/views/user/userInfo/list.vue组件
type=”datetime” placeholder=”选择开始时间” value-format=”yyyy-MM-dd HH:mm:ss” default-time=”00:00:00” /> 至 type=”datetime” placeholder=”选择截止时间” value-format=”yyyy-MM-dd HH:mm:ss” default-time=”00:00:00” /> :data=”list” stripe style=”width: 100%”> width=”70” align=”center”> {{ (page - 1) * limit + scope.$index + 1 }} :total=”total” :page-size=”limit” :page-sizes=”[5, 10, 20, 30, 40, 50, 100]” style=”padding: 30px 0; text-align: center;” layout=”sizes, prev, pager, next, jumper, ->, total, slot” @current-change=”fetchData” @size-change=”changeSize” /> |
---|
9 锁定
2.1 api接口
2.1.1添加service接口与实现
1、在UserInfoService类添加接口
/* 用户锁定 * @param __userId* @param __status 0:锁定 1:正常 */void lock(Long userId, Integer status); |
---|
2、在UserInfoServiceImpl类添加实现
@Overridepublic void lock(Long userId, Integer status) { if(status.intValue() == 0 || status.intValue() == 1) { UserInfo userInfo = this.getById(userId); userInfo.setStatus(status); this.updateById(userInfo); } } |
---|
2.1.2添加controller方法
在UserController类添加方法
@ApiOperation(value = “锁定”)@GetMapping(“lock/{userId}/{status}”)public Result lock( @PathVariable(“userId”) Long userId, @PathVariable(“status”) Integer status){ userInfoService.lock(userId, status); return Result.ok(); } |
---|
2.2前端
2.2.1 封装api请求
在/api/user/userInfo.js文件添加方法
lock(id, status) { return request({ url: ${api_name}/lock/${id}/${status} ,method: ‘get’ }) } |
---|
2.2.2 添加组件
修改/views/user/userInfo/list.vue组件
添加方法
// 锁定 lock(id, status) { this.$confirm(‘确定该操作吗?’, ‘提示’, { confirmButtonText: ‘确定’, cancelButtonText: ‘取消’, type: ‘warning’ }).then(() => { // promise // 点击确定,远程调用ajax return userInfoApi.lock(id, status) }).then((response) => { this.fetchData(this.page) if (response.code) { this.$message({ type: ‘success’, message: ‘操作成功!’ }) } }) } |
---|
10 详情
3.1 api接口
3.1.1添加service接口与实现
1、在UserInfoService类添加接口
/* 详情 * @param __userId* @return_*/_Map |
---|
2、在UserInfoServiceImpl类添加实现
@Autowiredprivate PatientService patientService; |
---|
//用户详情@Overridepublic Map Map //根据userid查询用户信息 _UserInfo userInfo = this.packageUserInfo(baseMapper.selectById(userId)); map.put(“userInfo”,userInfo); //根据userid查询就诊人信息 _List map.put(“patientList”,patientList); return map; } |
3.1.2添加controller方法
在UserController类添加方法
//用户详情@GetMapping(“show/{userId}”)public Result show(@PathVariable Long userId) { Map return Result.ok(map); } |
---|
3.2前端
3.2.1 添加路由
{ path: ‘/user’, component: Layout, redirect: ‘/user/userInfo/list’, name: ‘userInfo’, meta: { title: ‘用户管理’, icon: ‘table’ }, alwaysShow: true, children: [ { path: ‘userInfo/list’, name: ‘用户列表’, component: () =>import(‘@/views/user/userInfo/list’), meta: { title: ‘用户列表’, icon: ‘table’ } }, { path: ‘userInfo/show/:id’, name: ‘用户查看’, component: () =>import(‘@/views/user/userInfo/show’), meta: { title: ‘用户查看’ }, hidden: true } ] }, |
---|
3.2.2封装api请求
在/api/user/userInfo.js文件添加方法
//用户详情 show(id) { return request({ url: ${api_name}/show/${id} ,method: ‘get’ }) } |
---|
3.2.3 修改列表组件
3.2.4 添加组件
添加/views/user/userInfo/show.vue组件
用户信息
认证信息
就诊人信息:data=”patientList” stripe style=”width: 100%”> width=”70” align=”center”> {{ scope.$index + 1 }} {{ scope.row.sex == 1 ? ‘男’ : ‘女’ }} {{ scope.row.isMarry == 1 ? ‘时’ : ‘否’ }} |
||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
11 用户认证列表
api接口与用户列表一致,只是默认加了一个认证状态搜索条件:authStatus
4.1 添加路由
{ path: ‘userInfo/authList’, name: ‘认证审批列表’, component: () =>import(‘@/views/user/userInfo/authList’), meta: { title: ‘认证审批列表’, icon: ‘table’ } } |
---|
4.2 添加组件
添加/views/user/userInfo/authList.vue组件
type=”datetime” placeholder=”选择开始时间” value-format=”yyyy-MM-dd HH:mm:ss” default-time=”00:00:00” /> 至 type=”datetime” placeholder=”选择截止时间” value-format=”yyyy-MM-dd HH:mm:ss” default-time=”00:00:00” /> :data=”list” stripe style=”width: 100%”> width=”70” align=”center”> {{ (page - 1) * limit + scope.$index + 1 }} :total=”total” :page-size=”limit” :page-sizes=”[5, 10, 20, 30, 40, 50, 100]” style=”padding: 30px 0; text-align: center;” layout=”sizes, prev, pager, next, jumper, ->, total, slot” @current-change=”fetchData” @size-change=”changeSize” /> |
---|
12 用户认证审批
5.1 api接口
5.1.1添加service接口与实现
1、在UserInfoService类添加接口
/* 认证审批 * @param __userId* @param __authStatus 2:通过 -1:不通过 */void approval(Long userId, Integer authStatus); |
---|
2、在UserInfoServiceImpl类添加实现
//认证审批 2通过 -1不通过@Overridepublic void approval(Long userId, Integer authStatus) { if(authStatus.intValue()==2 || authStatus.intValue()==-1) { UserInfo userInfo = baseMapper.selectById(userId); userInfo.setAuthStatus(authStatus); baseMapper.updateById(userInfo); } } |
---|
5.1.2添加controller方法
在UserController类添加方法
//认证审批@GetMapping(“approval/{userId}/{authStatus}”)public Result approval(@PathVariable Long userId,@PathVariable Integer authStatus) { userInfoService.approval(userId,authStatus); return Result.ok(); } |
---|
5.2 前端
5.2.1 封装api请求
在/api/userInfo.js文件添加方法
//认证审批 approval(id, authStatus) { return request({ url: ${api_name}/approval/${id}/${authStatus} ,method: ‘get’ }) } |
---|
5.2.2 添加组件
修改/views/user/userInfo/authList.vue组件
添加方法
// 审批 approval(id, authStatus) { // debugger this.$confirm(‘确定该操作吗?’, ‘提示’, { confirmButtonText: ‘确定’, cancelButtonText: ‘取消’, type: ‘warning’ }).then(() => { // promise // 点击确定,远程调用ajax return userInfoApi.approval(id, authStatus) }).then((response) => { this.fetchData(this.page) if (response.code) { this.$message({ type: ‘success’, message: ‘操作成功!’ }) } }) } |
---|