一、整合oss
1、注册开通阿里云oss
进入oss控制台传送门
点击创建对应的bucketl
进入我们创建的bucket列表
2、获取我们必须的参数
- 地域节点Endpoint
- AccessKey ID与AccessKey Secret
3、进入JavaSDK学习使用上传文件
(1)引入依赖
JAVA8依赖
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.10.2</version>
</dependency>
JAVA9及其以上的依赖
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
<!-- no more than 2.3.3-->
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.3</version>
</dependency>
(3)文件上传(流式文件上传)
我们选择流式文件上传
// yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
String endpoint = "yourEndpoint";
// 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
String accessKeyId = "yourAccessKeyId";
String accessKeySecret = "yourAccessKeySecret";
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
// 填写本地文件的完整路径。如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件流。
InputStream inputStream = new FileInputStream("D:\\localpath\\examplefile.txt");
// 依次填写Bucket名称(例如examplebucket)和Object完整路径(例如exampledir/exampleobject.txt)。Object完整路径中不能包含Bucket名称。
ossClient.putObject("examplebucket", "exampledir/exampleobject.txt", inputStream);
// 关闭OSSClient。
ossClient.shutdown();
4、项目整合OSS
(1)创建OSS模块,用来专门完成文件上传服务
(2)创建controller
@RestController
@RequestMapping("/api/oss/file")
public class FileApiController {
@Autowired
private FileService fileService;
@ApiOperation("/")
@PostMapping("/fileUpload")
public Result fileUpload(@RequestPart MultipartFile file) {
String imagesUrl = fileService.upload(file);
return Result.ok(imagesUrl);
}
}
(3)service层
需要注意的我们为了访问我们上传的文件名字存在重复,解决方案为,获取当前上传的文件的名字,我们使用UUID生产一个字符串与我们文件名字拼接在一起,形成一个新的文件名字,此外我们又进一步操作,获取当天的时间日期数据,按照年月日创建我们的文件夹存放我们的上传文件,进一步减少重复。
获取时间日期格式使用的是时间日期工具类,之后返回我们的文件保存路劲url。
@Service
public class FileServiceImpl implements FileService {
@Override
public String upload(MultipartFile file) {
// 1、判断文件是否为空,以及文件类型检验,检验通过进行数据的存储
// 2、文件效验通过,进行文件上传操作
// 获取常量值
String endpoint = ConstantOssPropertiesUtils.EDNPOINT;
String accessKeyId = ConstantOssPropertiesUtils.ACCESS_KEY_ID;
String accessKeySecret = ConstantOssPropertiesUtils.SECRECT;
String bucket = ConstantOssPropertiesUtils.BUCKET;
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
// 创建文件输出流
InputStream inputStream = null;
try {
// 获取文件流
inputStream = file.getInputStream();
String filename = file.getOriginalFilename();
// 给文件名字添加一个随机的UUID防止名字一样
filename = UUID.randomUUID().toString() + filename;
// 设置保存文件在oss的路径
// 按照当前日期设置文件的保存路径,进一步防止文件名字一样
String timeUrl = new DateTime().toString("yyyy/MM/dd");
String savePath = timeUrl + "/" + filename;
// 上传
ossClient.putObject(bucket, savePath, inputStream);
// 拼接文件的访问url地址
String url = "https://" + bucket + "." + endpoint + "/" + savePath;
//返回
return url;
} catch (IOException e) {
e.printStackTrace();
return null;
} finally {
// 关闭OSSClient。
ossClient.shutdown();
try {
// 关闭文件输出流
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
}
(4)将我们必要的参数保存在配置文件中读取
(5)创建工具类,读取配置文件内容
@Component
public class ConstantOssPropertiesUtils implements InitializingBean {
@Value("${aliyun.oss.endpoint}")
private String endpoint;
@Value("${aliyun.oss.accessKeyId}")
private String accessKeyId;
@Value("${aliyun.oss.secret}")
private String secret;
@Value("${aliyun.oss.bucket}")
private String bucket;
public static String EDNPOINT;
public static String ACCESS_KEY_ID;
public static String SECRECT;
public static String BUCKET;
@Override
public void afterPropertiesSet() throws Exception {
EDNPOINT = endpoint;
ACCESS_KEY_ID = accessKeyId;
SECRECT = secret;
BUCKET = bucket;
}
}
二、用户认证
1、分析
用户登录成功后都要进行身份认证,认证通过后才可以预约挂号 认证过程:用户填写信息(姓名、证件类型、证件号码和证件照片)==> 平台审批
用户认证设计接口:
1、提交认证 2、上传证件图片 3、获取提交认证信息
其实就是对我们登录之后信息的完善,使用微信,手机号登录其实我们都只保存了用户手机号,昵称等等,关于身份证,其他信息我们都没有保存,所以我们后续的认证就是一个update操作,根据我们提供的vo参数进行更新,我们从我们token中获取当前正在登录(发起请求的用户)的id,更具id’,获取先关的信息,更新操作。
2、userinfo表设计
3、数据传递的VO类
@Data
@ApiModel(description="会员认证对象")
public class UserAuthVo {
@ApiModelProperty(value = "用户姓名")
@TableField("name")
private String name;
@ApiModelProperty(value = "证件类型")
@TableField("certificates_type")
private String certificatesType;
@ApiModelProperty(value = "证件编号")
@TableField("certificates_no")
private String certificatesNo;
@ApiModelProperty(value = "证件路径")
@TableField("certificates_url")
private String certificatesUrl;
}
4、contoller层
接受我们传递过来的Vo实体类,调用service完成信息的更新,完成认证
@ApiOperation(value = "根据token进行用户认证")
@PostMapping("auth/userAuth")
public Result userAuth(@RequestBody UserAuthVo userAuthVo, HttpServletRequest request) {
userInfoService.userAuth(userAuthVo, AuthContextHolder.getUserId(request));
return Result.ok();
}
5、service层
@Override
public void userAuth(UserAuthVo userAuthVo, Long userId) {
// 更具Id获取到用户信息
UserInfo userInfo = baseMapper.selectById(userId);
// 对用户信息进行添加操作
// 认证人姓名
userInfo.setName(userAuthVo.getName());
// 其他认证信息
userInfo.setCertificatesType(userAuthVo.getCertificatesType());
userInfo.setCertificatesNo(userAuthVo.getCertificatesNo());
userInfo.setCertificatesUrl(userAuthVo.getCertificatesUrl());
// 设置用户的状态 认证状态(0:未认证 1:认证中 2:认证成功 -1:认证失败)
userInfo.setAuthStatus(AuthStatusEnum.AUTH_RUN.getStatus());
baseMapper.updateById(userInfo);
}
三、救诊人CRUD
1、分析
每个用户都可以添加几个就诊人,比如说,儿子可以添加爸爸,妈妈的就诊信息,挂号时,可以选择给谁挂号,就这些操作,增删改查就诊人
2、就诊人实体类分析
3、获取就诊人
横简单,但是有一个注意点,就是我们需要对参数完成包装,因为之前我们做的,需要对我们证件类型,位置信息,通过查询字典获取对应的实际值,保存到参数中,用户获取信息,凸显出有一个额外map属性的重要性
3.1、获取就诊人列表
(1)controller
@ApiOperation(value = "获取就诊人列表")
@GetMapping("/auth/findAll")
public Result findAll(HttpServletRequest request) {
Long userId = AuthContextHolder.getUserId(request);
List<Patient> patientList = patientService.findAllByUserId(userId);
return Result.ok(patientList);
}
(2)service
@Override
public List<Patient> findAllByUserId(Long userId) {
QueryWrapper<Patient> wrapper = new QueryWrapper();
wrapper.eq("user_id", userId);
List<Patient> patientList = baseMapper.selectList(wrapper);
patientList.stream().forEach(item -> {
this.setParam(item);
});
return patientList;
}
(3)包装参数的方法
private Patient setParam(Patient patient) {
//根据证件类型编码,获取证件类型具体指
Result certificatesType = dictFeignClient.getName(DictEnum.CERTIFICATES_TYPE.getDictCode(), patient.getCertificatesType());//联系人证件
//联系人证件类型(练习人证件可有可无)
if (StringUtils.isEmpty(patient.getContactsCertificatesType())) {
patient.getParam().put("contactsCertificatesTypeString", "");
} else {
Result contactsCertificatesType = dictFeignClient.getName(DictEnum.CERTIFICATES_TYPE.getDictCode(), patient.getContactsCertificatesType());
patient.getParam().put("contactsCertificatesTypeString", contactsCertificatesType.getData());
}
//省
Result province = dictFeignClient.getName(patient.getProvinceCode());
//市
Result city = dictFeignClient.getName(patient.getCityCode());
//区
Result district = dictFeignClient.getName(patient.getDistrictCode());
// 参数封装
patient.getParam().put("certificatesTypeString", certificatesType.getData());
patient.getParam().put("provinceString", province.getData());
patient.getParam().put("cityString", city.getData());
patient.getParam().put("districtString", district.getData());
patient.getParam().put("fullAddress", (String) province.getData() + (String) city.getData() + (String) district.getData() + patient.getAddress());
return patient;
}
3.2、更具就诊人Id获取对应的信息
@ApiOperation(value = "获取就诊人信息")
@GetMapping("/auth/get/{id}")
public Result getPatient(@PathVariable Long id) {
Patient patient = patientService.getPatientById(id);
return Result.ok(patient);
}
@Override
public Patient getPatientById(Long id) {
Patient patient = baseMapper.selectById(id);
this.setParam(patient);
return patient;
}
4、删改增(mp一步完成)
@ApiOperation(value = "添加用户")
@PostMapping("/auth/save")
public Result savePatient(@RequestBody Patient patient, HttpServletRequest request) {
Long userId = AuthContextHolder.getUserId(request);
patient.setUserId(userId);
patientService.save(patient);
return Result.ok();
}
@ApiOperation(value = "删除用户的的救诊人")
@DeleteMapping("/auth/remove/{id}")
public Result deletePatient(@PathVariable Long id) {
patientService.removeById(id);
return Result.ok();
}
@ApiOperation(value = "更改救诊人信息")
@PutMapping("/auth/update")
public Result update(@RequestBody Patient patient) {
patientService.updateById(patient);
return Result.ok();
}
四、平台统一管理用户,效验认证
1、分析
我们平台对我们当前用户进行一个统一的认证和管理
- 显示出所有的用户列表
- 查看该用户的详情信息
- 锁定与解锁该用户
- 获取所有没有认证通过的列表
- 认证用户是否通过
2、操作(简单不在详细赘述)
(1)controller
@Api(tags = "后台用户统一管理")
@RestController
@RequestMapping("/admin/user")
public class UserController {
@Autowired
private UserInfoService userInfoService;
/**
* get 请求无法接受请求的请求体,只能接受请求参数,不用使用@RequestBod,接受不到请求体
* 使用get请求的自动封装对象
*
* @param pageNum
* @param pageSize
* @param userInfoQueryVo
* @return
*/
@ApiOperation("获取用户类表")
@GetMapping("/{pageNum}/{pageSize}")
public Result list(
@PathVariable("pageNum") Long pageNum,
@PathVariable("pageSize") Long pageSize, UserInfoQueryVo userInfoQueryVo) {
Page<UserInfo> page = new Page<>(pageNum, pageSize);
Page<UserInfo> userInfoPage = null;
if (userInfoQueryVo == null) {
userInfoPage = userInfoService.getPages(page);
} else {
userInfoPage = userInfoService.getPages(page, userInfoQueryVo);
}
return Result.ok(userInfoPage);
}
@ApiOperation(value = "锁定状态的修改")
@PutMapping("/lock/{userId}/{status}")
public Result lock(
@PathVariable("userId") Long userId,
@PathVariable("status") Integer status) {
userInfoService.lock(userId, status);
return Result.ok();
}
@ApiOperation(value = "获取用户详情信息")
@GetMapping("/show/{userId}")
public Result show(@PathVariable Long userId) {
Map<String, Object> map = userInfoService.show(userId);
return Result.ok(map);
}
@ApiOperation(value = "认证审批")
@PutMapping("approval/{userId}/{authStatus}")
public Result approval(@PathVariable Long userId, @PathVariable Integer authStatus) {
userInfoService.approval(userId, authStatus);
return Result.ok();
}
}
(4)service
@Override
public UserInfo getUserInfoByOpenId(String openId) {
return baseMapper.selectOne(new QueryWrapper<UserInfo>().eq("openid", openId));
}
@Override
public void userAuth(UserAuthVo userAuthVo, Long userId) {
// 更具Id获取到用户信息
UserInfo userInfo = baseMapper.selectById(userId);
// 对用户信息进行添加操作
// 认证人姓名
userInfo.setName(userAuthVo.getName());
// 其他认证信息
userInfo.setCertificatesType(userAuthVo.getCertificatesType());
userInfo.setCertificatesNo(userAuthVo.getCertificatesNo());
userInfo.setCertificatesUrl(userAuthVo.getCertificatesUrl());
// 设置用户的状态 认证状态(0:未认证 1:认证中 2:认证成功 -1:认证失败)
userInfo.setAuthStatus(AuthStatusEnum.AUTH_RUN.getStatus());
baseMapper.updateById(userInfo);
}
@Override
public Page<UserInfo> getPages(Page<UserInfo> page, UserInfoQueryVo userInfoQueryVo) {
//UserInfoQueryVo获取条件值
String name = userInfoQueryVo.getKeyword(); //用户名称
Integer status = userInfoQueryVo.getStatus();//用户状态
Integer authStatus = userInfoQueryVo.getAuthStatus(); //认证状态
String createTimeBegin = userInfoQueryVo.getCreateTimeBegin(); //开始时间
String createTimeEnd = userInfoQueryVo.getCreateTimeEnd(); //结束时间
//对条件值进行非空判断,封装查询条件
QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
if (!StringUtils.isEmpty(name)) {
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);
}
// 获取分页数据
Page<UserInfo> userInfoPage = baseMapper.selectPage(page, wrapper);
// 包装一些参数
userInfoPage.getRecords().stream().forEach(item -> {
this.packageUserInfo(item);
});
return userInfoPage;
}
@Override
public void lock(Long userId, Integer status) {
// 对修改状态进行限制,因为我们状态只有0和1两种状态
if (status.intValue() == 0 || status.intValue() == 1) {
UserInfo userInfo = new UserInfo();
userInfo.setId(userId);
userInfo.setStatus(status);
baseMapper.updateById(userInfo);
}
}
@Override
public Map<String, Object> show(Long userId) {
HashMap<String, Object> map = new HashMap<>();
UserInfo userInfo = baseMapper.selectById(userId);
map.put("userInfo", userInfo);
// 获取用户下的所有的就诊人信息
List<Patient> patients = patientService.findAllByUserId(userId);
map.put("patientList", patients);
return map;
}
@Override
public Page<UserInfo> getPages(Page<UserInfo> page) {
Page<UserInfo> userInfoPage = baseMapper.selectPage(page, null);
// 包装一些参数
userInfoPage.getRecords().stream().forEach(item -> {
this.packageUserInfo(item);
});
return userInfoPage;
}
private void packageUserInfo(UserInfo userInfo) {
// 调用枚举类的静态方法获取当前用户认证状态
userInfo.getParam().put("authStatusString", AuthStatusEnum.getStatusNameByStatus(userInfo.getAuthStatus()));
userInfo.getParam().put("statusString", userInfo.getStatus() == 0 ? "锁定" : "正常");
}
@Override
public void approval(Long userId, Integer authStatus) {
if (authStatus.intValue() == 2 || authStatus.intValue() == -1) {
UserInfo userInfo = baseMapper.selectById(userId);
userInfo.setAuthStatus(authStatus);
baseMapper.updateById(userInfo);
}
}