尚医通-阿里云OSS、用户认证与就诊人

嚴華  论坛元老 | 2024-7-30 17:10:35 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 1849|帖子 1849|积分 5547

oss 模块搭建与实现

这里采用的方式是通过后端传 oss,可以对比下 谷粒商城里面的,从后端拿上传凭证,然后前端直传的方式
  1. <dependency>
  2.     <groupId>joda-time</groupId>
  3.     <artifactId>joda-time</artifactId>
  4. </dependency>
  5. <!-- 阿里云oss依赖 -->
  6. <dependency>
  7.     <groupId>com.aliyun.oss</groupId>
  8.     <artifactId>aliyun-sdk-oss</artifactId>
  9. </dependency>
复制代码
配置文件
  1. server.port=8207
  2. spring.application.name=service-oss
  3. spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
  4. spring.jackson.time-zone=GMT+8
  5. spring.cloud.nacos.discovery.server-addr=localhost:8848
  6. aliyun.oss.endpoint=oss-cn-hangzhou.aliyuncs.com
  7. aliyun.oss.accessKeyId=LTAI5tCvwJjdKorLjaS9ynds
  8. aliyun.oss.secret=xxxx
  9. aliyun.oss.bucket=xxxx
复制代码
配置常量读取
  1. @Component
  2. public class ConstantOssPropertiesUtils implements InitializingBean {
  3.     @Value("${aliyun.oss.endpoint}")
  4.     private String endpoint;
  5.     @Value("${aliyun.oss.accessKeyId}")
  6.     private String accessKeyId;
  7.     @Value("${aliyun.oss.secret}")
  8.     private String secret;
  9.     @Value("${aliyun.oss.bucket}")
  10.     private String bucket;
  11.     public static String EDNPOINT;
  12.     public static String ACCESS_KEY_ID;
  13.     public static String SECRECT;
  14.     public static String BUCKET;
  15.     @Override
  16.     public void afterPropertiesSet() throws Exception {
  17.         EDNPOINT = endpoint;
  18.         ACCESS_KEY_ID = accessKeyId;
  19.         SECRECT = secret;
  20.         BUCKET = bucket;
  21.     }
  22. }
复制代码
Service 核心实现
  1. @Service
  2. public class FileServiceImpl implements FileService {
  3.     //获取上传文件
  4.     @Override
  5.     public String upload(MultipartFile file) {
  6.         // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
  7.         String endpoint = ConstantOssPropertiesUtils.EDNPOINT;
  8.         // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
  9.         String accessKeyId = ConstantOssPropertiesUtils.ACCESS_KEY_ID;
  10.         String accessKeySecret = ConstantOssPropertiesUtils.SECRECT;
  11.         String bucketName = ConstantOssPropertiesUtils.BUCKET;
  12.         try {
  13.             // 创建OSSClient实例。
  14.             OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
  15.             // 获取文件流
  16.             InputStream inputStream = file.getInputStream();
  17.             String filename = file.getOriginalFilename();
  18.             //为防止文件名重复造成文件覆盖,生成随机值,添加到文件中
  19.             String uuid = UUID.randomUUID().toString().replaceAll("-","");
  20.             filename = uuid + filename;
  21.             //按照当前日期创建文件夹,上传到当前文件夹里面  /2021/02/01/01.jpg
  22.             String timeUrl = new DateTime().toString("yyyy/MM/dd");
  23.             filename = timeUrl + "/" + filename;
  24.             // 调用方法,实现上传  参数2为上传文件(路径+)名称
  25.             ossClient.putObject(bucketName, filename, inputStream);
  26.             // 关闭OSSClient。
  27.             ossClient.shutdown();
  28.             // 返回上传后文件路径
  29.             // 例:https://yygh-atguigu-li.oss-cn-beijing.aliyuncs.com/qq.jpg
  30.             String url = "https://" + bucketName + "." + endpoint + "/" + filename;
  31.             return url;
  32.         } catch (IOException e) {
  33.             e.printStackTrace();
  34.             return null;
  35.         }
  36.     }
  37. }
复制代码
controller
  1. @RestController
  2. @RequestMapping("/api/oss/file")
  3. public class FileApiController {
  4.     @Autowired
  5.     private FileService fileService;
  6.     //上传文件到阿里云
  7.     @PostMapping("fileUpload")
  8.     public Result fileUpload(MultipartFile file){  //通过MultipartFile可以得到上传文件
  9.         //获取上传文件
  10.         String url = fileService.upload(file);  //上传后得到路径
  11.         return Result.ok(url);
  12.     }
  13. }
复制代码
用户认证功能实现

用户登录乐成后都要举行身份认证,认证通过后才可以预约挂号
认证过程:用户填写信息(姓名、证件类型、证件号码和证件照片)==> 平台审批
用户认证计划接口:
1、提交认证
2、上传证件图片
3、获取提交认证信息
后端实现

service
  1. @Override
  2.     public void userAuth(Long userId, UserAuthVo userAuthVo) {
  3.         //1.根据用户id查询用户信息
  4.         UserInfo userInfo = baseMapper.selectById(userId);
  5.         //2.设置认证信息
  6.         //认证人姓名
  7.         userInfo.setName(userAuthVo.getName());
  8.         //其他认证信息
  9.         userInfo.setCertificatesType(userAuthVo.getCertificatesType());
  10.         userInfo.setCertificatesNo(userAuthVo.getCertificatesNo());
  11.         userInfo.setCertificatesUrl(userAuthVo.getCertificatesUrl());
  12.         userInfo.setAuthStatus(AuthStatusEnum.AUTH_RUN.getStatus());
  13.         //3.进行信息更新
  14.         baseMapper.updateById(userInfo);
  15.     }
复制代码
用户信息剖析
  1. public class AuthContextHolder {
  2.     //获取当前用户id
  3.     public static Long getUserId(HttpServletRequest request) {
  4.         //从header中获取token
  5.         String token = request.getHeader("token");
  6.         //从token中获取userid
  7.         Long userId = JwtHelper.getUserId(token);
  8.         return userId;
  9.     }
  10.     //获取当前用户名称
  11.     public static String getUserName(HttpServletRequest request) {
  12.         //从header中获取token
  13.         String token = request.getHeader("token");
  14.         //从token中获取userid
  15.         String userName = JwtHelper.getUserName(token);
  16.         return userName;
  17.     }
  18. }
复制代码
接口实现
  1. @ApiOperation("用户认证接口")
  2.     @PostMapping("auth/userAuth")
  3.     public Result userAuth(@RequestBody UserAuthVo userAuthVo, HttpServletRequest request) {
  4.         // 传递 用户id 和 认证数据vo对象
  5.         userInfoService.userAuth(AuthContextHolder.getUserId(request), userAuthVo);
  6.         return Result.ok();
  7.     }
  8.     @ApiOperation("获取用户id信息接口")
  9.     @GetMapping("auth/getUserInfo")
  10.     public Result getUserInfo(HttpServletRequest request) {
  11.         Long userId = AuthContextHolder.getUserId(request);
  12.         UserInfo userInfo = userInfoService.getById(userId);
  13.         return Result.ok(userInfo);
  14.     }
复制代码
前端实现

  1. //用户认证接口
  2. saveUserAuth(userAuth) {
  3.     return request({
  4.         url: `${api_name}/auth/userAuth`,
  5.         method: 'post',
  6.         data: userAuth
  7.     })
  8. },
  9. //根据userid获取用户信息
  10. getUserInfo() {
  11.     return request({
  12.         url: `${api_name}/auth/getUserInfo`,
  13.         method: `get`
  14.     })
  15. },
复制代码
  1. <template>
  2.   <!-- header -->
  3.   <div class="nav-container page-component">
  4.     <!--左侧导航 #start -->
  5.     <div class="nav left-nav">
  6.       <div class="nav-item selected">
  7.         <span
  8.           class="v-link selected dark"
  9.           οnclick="javascript:window.location='/user'"
  10.           >实名认证
  11.         </span>
  12.       </div>
  13.       <div class="nav-item">
  14.         <span
  15.           class="v-link selected dark"
  16.           οnclick="javascript:window.location='/order'"
  17.         >
  18.           挂号订单
  19.         </span>
  20.       </div>
  21.       <div class="nav-item">
  22.         <span
  23.           class="v-link clickable dark"
  24.           οnclick="javascript:window.location='/patient'"
  25.         >
  26.           就诊人管理
  27.         </span>
  28.       </div>
  29.       <div class="nav-item">
  30.         <span class="v-link clickable dark"> 修改账号信息 </span>
  31.       </div>
  32.       <div class="nav-item">
  33.         <span class="v-link clickable dark"> 意见反馈 </span>
  34.       </div>
  35.     </div>
  36.     <!-- 左侧导航 #end -->
  37.     <!-- 右侧内容 #start -->
  38.     <div class="page-container">
  39.       <div>
  40.         <div class="title">实名认证</div>
  41.         <div class="status-bar">
  42.           <div class="status-wrapper">
  43.             <span class="iconfont"></span>{{ userInfo.param.authStatusString }}
  44.           </div>
  45.         </div>
  46.         <div class="tips">
  47.           <span class="iconfont"></span>
  48.           完成实名认证后才能添加就诊人,正常进行挂号,为了不影响后续步骤,建议提前实名认证。
  49.         </div>
  50.         <div class="form-wrapper" v-if="userInfo.authStatus == 0">
  51.           <div>
  52.             <el-form
  53.               :model="userAuah"
  54.               label-width="110px"
  55.               label-position="left"
  56.             >
  57.               <el-form-item prop="name" label="姓名:" class="form-normal">
  58.                 <div class="name-input">
  59.                   <el-input
  60.                     v-model="userAuah.name"
  61.                     placeholder="请输入联系人姓名全称"
  62.                     class="input v-input"
  63.                   />
  64.                 </div>
  65.               </el-form-item>
  66.               <el-form-item prop="certificatesType" label="证件类型:">
  67.                 <el-select
  68.                   v-model="userAuah.certificatesType"
  69.                   placeholder="请选择证件类型"
  70.                   class="v-select patient-select"
  71.                 >
  72.                   <el-option
  73.                     v-for="item in certificatesTypeList"
  74.                     :key="item.value"
  75.                     :label="item.name"
  76.                     :value="item.name"
  77.                   >
  78.                   </el-option>
  79.                 </el-select>
  80.               </el-form-item>
  81.               <el-form-item prop="certificatesNo" label="证件号码:">
  82.                 <el-input
  83.                   v-model="userAuah.certificatesNo"
  84.                   placeholder="请输入联系人证件号码"
  85.                   class="input v-input"
  86.                 />
  87.               </el-form-item>
  88.               <el-form-item prop="name" label="上传证件:">
  89.                 <div class="upload-wrapper">
  90.                   <div class="avatar-uploader">
  91.                     <el-upload
  92.                       class="avatar-uploader"
  93.                       :action="fileUrl"
  94.                       :show-file-list="false"
  95.                       :on-success="onUploadSuccess"
  96.                     >
  97.                       <div class="upload-inner-wrapper">
  98.                         <img
  99.                           v-if="userAuah.certificatesUrl"
  100.                           :src="userAuah.certificatesUrl"
  101.                           class="avatar"
  102.                         />
  103.                         <i v-else class="el-icon-plus avatar-uploader-icon"></i>
  104.                         <div v-if="!userAuah.certificatesUrl" class="text">
  105.                           上传证件合照
  106.                         </div>
  107.                       </div>
  108.                     </el-upload>
  109.                   </div>
  110.                   <img
  111.                     src="//img.114yygh.com/static/web/auth_example.png"
  112.                     class="example"
  113.                   />
  114.                 </div>
  115.               </el-form-item>
  116.             </el-form>
  117.             <div class="bottom-wrapper">
  118.               <div class="button-wrapper">
  119.                 <div class="v-button" @click="saveUserAuah()">
  120.                   {{ submitBnt }}
  121.                 </div>
  122.               </div>
  123.             </div>
  124.           </div>
  125.         </div>
  126.         <div class="context-container" v-if="userInfo.authStatus != 0">
  127.           <div>
  128.             <el-form
  129.               :model="formData"
  130.               label-width="110px"
  131.               label-position="right"
  132.             >
  133.               <el-form-item prop="name" label="姓名:" class="form-normal">
  134.                 <div class="name-input">
  135.                   {{ userInfo.name }}
  136.                 </div>
  137.               </el-form-item>
  138.               <el-form-item prop="name" label="证件类型:">
  139.                 {{ userInfo.certificatesType }}
  140.               </el-form-item>
  141.               <el-form-item prop="name" label="证件号码:">
  142.                 {{ userInfo.certificatesNo }}
  143.               </el-form-item>
  144.             </el-form>
  145.           </div>
  146.         </div>
  147.       </div>
  148.     </div>
  149.     <!-- 右侧内容 #end -->
  150.     <!-- 登录弹出框 -->
  151.   </div>
  152.   <!-- footer -->
  153. </template>
  154. <script>
  155. import "~/assets/css/hospital_personal.css";
  156. import "~/assets/css/hospital.css";
  157. import "~/assets/css/personal.css";
  158. import dictApi from "@/api/dict";
  159. import userInfoApi from "@/api/userInfo";
  160. const defaultForm = {
  161.   name: "",
  162.   certificatesType: "",
  163.   certificatesNo: "",
  164.   certificatesUrl: "",
  165. };
  166. export default {
  167.   data() {
  168.     return {
  169.       userAuah: defaultForm,
  170.       certificatesTypeList: [],
  171.       fileUrl: "http://localhost:81/api/oss/file/fileUpload",
  172.       userInfo: {
  173.         param: {},
  174.       },
  175.       submitBnt: "提交",
  176.     };
  177.   },
  178.   created() {
  179.     this.init();
  180.   },
  181.   methods: {
  182.     init() {
  183.       this.getUserInfo();
  184.       this.getDict();
  185.     },
  186.     getUserInfo() {
  187.       userInfoApi.getUserInfo().then((response) => {
  188.         this.userInfo = response.data;
  189.       });
  190.     },
  191.     saveUserAuah() {
  192.       if (this.submitBnt == "正在提交...") {
  193.         this.$message.info("重复提交");
  194.         return;
  195.       }
  196.       this.submitBnt = "正在提交...";
  197.       userInfoApi
  198.         .saveUserAuth(this.userAuah)
  199.         .then((response) => {
  200.           this.$message.success("提交成功");
  201.           window.location.reload();
  202.         })
  203.         .catch((e) => {
  204.           this.submitBnt = "提交";
  205.         });
  206.     },
  207.     getDict() {
  208.       dictApi.findByDictCode("CertificatesType").then((response) => {
  209.         this.certificatesTypeList = response.data;
  210.       });
  211.     },
  212.     onUploadSuccess(response, file) {
  213.       if (response.code !== 200) {
  214.         this.$message.error("上传失败");
  215.         return;
  216.       }
  217.       // 填充上传文件列表
  218.       this.userAuah.certificatesUrl = file.response.data;
  219.     },
  220.   },
  221. };
  222. </script>
  223. <style>
  224. .header-wrapper .title {
  225.   font-size: 16px;
  226.   margin-top: 0;
  227. }
  228. .content-wrapper {
  229.   margin-left: 0;
  230. }
  231. .patient-card .el-card__header .detail {
  232.   font-size: 14px;
  233. }
  234. .page-container .title {
  235.   letter-spacing: 1px;
  236.   font-weight: 700;
  237.   color: #333;
  238.   font-size: 16px;
  239.   margin-top: 0;
  240.   margin-bottom: 20px;
  241. }
  242. .page-container .tips {
  243.   width: 100%;
  244.   padding-left: 0;
  245. }
  246. .page-container .form-wrapper {
  247.   padding-left: 92px;
  248.   width: 580px;
  249. }
  250. .form-normal {
  251.   height: 40px;
  252. }
  253. .bottom-wrapper {
  254.   width: 100%;
  255.   padding: 0;
  256.   margin-top: 0;
  257. }
  258. </style>
复制代码
上传文件报错

oss模块添加配置
  1. spring.servlet.multipart.max-file-size=500MB
  2. spring.servlet.multipart.max-request-size=500MB
复制代码

预约挂号页面调解

预约挂号前验证 是否实名认证
  1. // 预约
  2.     schedule(depcode) {
  3.       // 登录判断
  4.       let token = cookie.get("token");
  5.       if (!token) {
  6.         loginEvent.$emit("loginDialogEvent");
  7.         return;
  8.       } //判断认证
  9.       userInfoApi.getUserInfo().then((response) => {
  10.         let authStatus = response.data.authStatus; // 状态为2认证通过
  11.         if (!authStatus || authStatus != 2) {
  12.           window.location.href = "/user";
  13.           return;
  14.         }
  15.       });
  16.       window.location.href =
  17.         "/hospital/schedule?hoscode=" +
  18.         this.hospital.hoscode +
  19.         "&depcode=" +
  20.         depcode;
  21.     },
复制代码
就诊人管理

预约下单必要选择就诊人,因此我们要实现就诊人管理,前端就诊人管理其实就是要实现一个完整的增删改查
user 长途调用 cmn 模块,检察数据字典
这个功能必要提一下的这块的处理惩罚,对于数据的封装,所有的基础资料只存了 code, 剩余的信息长途调用 cmn 模块获取,重点注意下这里的
  1. //根据登录用户id获取就诊列表
  2.     @Override
  3.     public List<Patient> findAllUserId(Long userId) {
  4.         //据登录用户id查询所有就诊人信息列表
  5.         QueryWrapper<Patient> wrapper = new QueryWrapper<>();
  6.         wrapper.eq("user_id", userId);
  7.         List<Patient> patientList = baseMapper.selectList(wrapper);
  8.         //通过远程调用得到部分编码对应的具体内容,查询数据字典表中的内容  例如 编号2000对应的是身份证方式
  9.         patientList.stream().forEach(item -> {
  10.             this.packPatient(item);  //将param中的一些属性封装进patient中
  11.         });
  12.         return patientList;
  13.     }
  14. //将param中的一些属性封装进patient中
  15.     private Patient packPatient(Patient patient) {
  16.         //根据证件类型,获取证件类型名称
  17.         String certificatesTypeString = dictFeignClient.getName
  18.                 (DictEnum.CERTIFICATES_TYPE.getDictCode(), patient.getCertificatesType());
  19.         //联系人证件类型
  20.         String contactsCertificatesTypeString = dictFeignClient.getName
  21.                 (DictEnum.CERTIFICATES_TYPE.getDictCode(), patient.getContactsCertificatesType());
  22.         //省
  23.         String provinceString = dictFeignClient.getName(patient.getProvinceCode());
  24.         //市
  25.         String cityString = dictFeignClient.getName(patient.getCityCode());
  26.         //区
  27.         String districtString = dictFeignClient.getName(patient.getDistrictCode());
  28.         patient.getParam().put("certificatesTypeString", certificatesTypeString);
  29.         patient.getParam().put("contactsCertificatesTypeString", contactsCertificatesTypeString);
  30.         patient.getParam().put("provinceString", provinceString);
  31.         patient.getParam().put("cityString", cityString);
  32.         patient.getParam().put("districtString", districtString);
  33.         patient.getParam().put("fullAddress", provinceString + cityString + districtString + patient.getAddress());
  34.         return patient;
  35.     }
复制代码
其他代码可自行参考资料中的代码
做完之后的结果
用户管理

前面我们做了用户登录、用户认证与就诊人,如今我们必要把这些信息在我们的平台管理体系做一个统一管理
撤消增删查改还有 锁定,认证审批接口,也比力常规,简朴看下结果,代码就不看了


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

嚴華

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表