阿里云OSS、用户认证与就诊人

news2025/1/23 22:28:28

oss 模块搭建与实现

这里采用的方式是通过后端传 oss,可以对比下 谷粒商城里面的,从后端拿上传凭证,然后前端直传的方式

<dependency>
    <groupId>joda-time</groupId>
    <artifactId>joda-time</artifactId>
</dependency>

<!-- 阿里云oss依赖 -->
<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
</dependency>

配置文件

server.port=8207

spring.application.name=service-oss

spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8

spring.cloud.nacos.discovery.server-addr=localhost:8848

aliyun.oss.endpoint=oss-cn-hangzhou.aliyuncs.com
aliyun.oss.accessKeyId=LTAI5tCvwJjdKorLjaS9ynds
aliyun.oss.secret=xxxx
aliyun.oss.bucket=xxxx

配置常量读取

@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;
    }
}

Service 核心实现

@Service
public class FileServiceImpl implements FileService {
    //获取上传文件
    @Override
    public String upload(MultipartFile file) {
        // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
        String endpoint = ConstantOssPropertiesUtils.EDNPOINT;
        // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
        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();
            //为防止文件名重复造成文件覆盖,生成随机值,添加到文件中
            String uuid = UUID.randomUUID().toString().replaceAll("-","");
            filename = uuid + filename;
            //按照当前日期创建文件夹,上传到当前文件夹里面  /2021/02/01/01.jpg
            String timeUrl = new DateTime().toString("yyyy/MM/dd");
            filename = timeUrl + "/" + filename;

            // 调用方法,实现上传  参数2为上传文件(路径+)名称
            ossClient.putObject(bucketName, filename, inputStream);
            // 关闭OSSClient。
            ossClient.shutdown();
            // 返回上传后文件路径
            // 例:https://yygh-atguigu-li.oss-cn-beijing.aliyuncs.com/qq.jpg
            String url = "https://" + bucketName + "." + endpoint + "/" + filename;
            return url;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
}

controller

@RestController
@RequestMapping("/api/oss/file")
public class FileApiController {

    @Autowired
    private FileService fileService;

    //上传文件到阿里云
    @PostMapping("fileUpload")
    public Result fileUpload(MultipartFile file){  //通过MultipartFile可以得到上传文件
        //获取上传文件
        String url = fileService.upload(file);  //上传后得到路径
        return Result.ok(url);
    }
}

用户认证功能实现

用户登录成功后都要进行身份认证,认证通过后才可以预约挂号

认证过程:用户填写信息(姓名、证件类型、证件号码和证件照片)==> 平台审批

用户认证设计接口:

1、提交认证

2、上传证件图片

3、获取提交认证信息

后端实现

service

@Override
    public void userAuth(Long userId, UserAuthVo userAuthVo) {
        //1.根据用户id查询用户信息
        UserInfo userInfo = baseMapper.selectById(userId);
        //2.设置认证信息
        //认证人姓名
        userInfo.setName(userAuthVo.getName());
        //其他认证信息
        userInfo.setCertificatesType(userAuthVo.getCertificatesType());
        userInfo.setCertificatesNo(userAuthVo.getCertificatesNo());
        userInfo.setCertificatesUrl(userAuthVo.getCertificatesUrl());
        userInfo.setAuthStatus(AuthStatusEnum.AUTH_RUN.getStatus());
        //3.进行信息更新
        baseMapper.updateById(userInfo);
    }

用户信息解析

public class AuthContextHolder {
    //获取当前用户id
    public static Long getUserId(HttpServletRequest request) {
        //从header中获取token
        String token = request.getHeader("token");
        //从token中获取userid
        Long userId = JwtHelper.getUserId(token);
        return userId;
    }

    //获取当前用户名称
    public static String getUserName(HttpServletRequest request) {
        //从header中获取token
        String token = request.getHeader("token");
        //从token中获取userid
        String userName = JwtHelper.getUserName(token);
        return userName;
    }
}

接口实现

@ApiOperation("用户认证接口")
    @PostMapping("auth/userAuth")
    public Result userAuth(@RequestBody UserAuthVo userAuthVo, HttpServletRequest request) {
        // 传递 用户id 和 认证数据vo对象
        userInfoService.userAuth(AuthContextHolder.getUserId(request), userAuthVo);


        return Result.ok();
    }

    @ApiOperation("获取用户id信息接口")
    @GetMapping("auth/getUserInfo")
    public Result getUserInfo(HttpServletRequest request) {
        Long userId = AuthContextHolder.getUserId(request);

        UserInfo userInfo = userInfoService.getById(userId);

        return Result.ok(userInfo);
    }

前端实现

//用户认证接口
saveUserAuth(userAuth) {
    return request({
        url: `${api_name}/auth/userAuth`,
        method: 'post',
        data: userAuth
    })
},
//根据userid获取用户信息
getUserInfo() {
    return request({
        url: `${api_name}/auth/getUserInfo`,
        method: `get`
    })
},
<template>
  <!-- header -->
  <div class="nav-container page-component">
    <!--左侧导航 #start -->
    <div class="nav left-nav">
      <div class="nav-item selected">
        <span
          class="v-link selected dark"
          οnclick="javascript:window.location='/user'"
          >实名认证
        </span>
      </div>
      <div class="nav-item">
        <span
          class="v-link selected dark"
          οnclick="javascript:window.location='/order'"
        >
          挂号订单
        </span>
      </div>
      <div class="nav-item">
        <span
          class="v-link clickable dark"
          οnclick="javascript:window.location='/patient'"
        >
          就诊人管理
        </span>
      </div>
      <div class="nav-item">
        <span class="v-link clickable dark"> 修改账号信息 </span>
      </div>
      <div class="nav-item">
        <span class="v-link clickable dark"> 意见反馈 </span>
      </div>
    </div>
    <!-- 左侧导航 #end -->
    <!-- 右侧内容 #start -->
    <div class="page-container">
      <div>
        <div class="title">实名认证</div>
        <div class="status-bar">
          <div class="status-wrapper">
            <span class="iconfont"></span>{{ userInfo.param.authStatusString }}
          </div>
        </div>
        <div class="tips">
          <span class="iconfont"></span>
          完成实名认证后才能添加就诊人,正常进行挂号,为了不影响后续步骤,建议提前实名认证。
        </div>
        <div class="form-wrapper" v-if="userInfo.authStatus == 0">
          <div>
            <el-form
              :model="userAuah"
              label-width="110px"
              label-position="left"
            >
              <el-form-item prop="name" label="姓名:" class="form-normal">
                <div class="name-input">
                  <el-input
                    v-model="userAuah.name"
                    placeholder="请输入联系人姓名全称"
                    class="input v-input"
                  />
                </div>
              </el-form-item>
              <el-form-item prop="certificatesType" label="证件类型:">
                <el-select
                  v-model="userAuah.certificatesType"
                  placeholder="请选择证件类型"
                  class="v-select patient-select"
                >
                  <el-option
                    v-for="item in certificatesTypeList"
                    :key="item.value"
                    :label="item.name"
                    :value="item.name"
                  >
                  </el-option>
                </el-select>
              </el-form-item>
              <el-form-item prop="certificatesNo" label="证件号码:">
                <el-input
                  v-model="userAuah.certificatesNo"
                  placeholder="请输入联系人证件号码"
                  class="input v-input"
                />
              </el-form-item>
              <el-form-item prop="name" label="上传证件:">
                <div class="upload-wrapper">
                  <div class="avatar-uploader">
                    <el-upload
                      class="avatar-uploader"
                      :action="fileUrl"
                      :show-file-list="false"
                      :on-success="onUploadSuccess"
                    >
                      <div class="upload-inner-wrapper">
                        <img
                          v-if="userAuah.certificatesUrl"
                          :src="userAuah.certificatesUrl"
                          class="avatar"
                        />
                        <i v-else class="el-icon-plus avatar-uploader-icon"></i>
                        <div v-if="!userAuah.certificatesUrl" class="text">
                          上传证件合照
                        </div>
                      </div>
                    </el-upload>
                  </div>
                  <img
                    src="//img.114yygh.com/static/web/auth_example.png"
                    class="example"
                  />
                </div>
              </el-form-item>
            </el-form>
            <div class="bottom-wrapper">
              <div class="button-wrapper">
                <div class="v-button" @click="saveUserAuah()">
                  {{ submitBnt }}
                </div>
              </div>
            </div>
          </div>
        </div>
        <div class="context-container" v-if="userInfo.authStatus != 0">
          <div>
            <el-form
              :model="formData"
              label-width="110px"
              label-position="right"
            >
              <el-form-item prop="name" label="姓名:" class="form-normal">
                <div class="name-input">
                  {{ userInfo.name }}
                </div>
              </el-form-item>
              <el-form-item prop="name" label="证件类型:">
                {{ userInfo.certificatesType }}
              </el-form-item>
              <el-form-item prop="name" label="证件号码:">
                {{ userInfo.certificatesNo }}
              </el-form-item>
            </el-form>
          </div>
        </div>
      </div>
    </div>
    <!-- 右侧内容 #end -->
    <!-- 登录弹出框 -->
  </div>
  <!-- footer -->
</template>

<script>
import "~/assets/css/hospital_personal.css";
import "~/assets/css/hospital.css";
import "~/assets/css/personal.css";

import dictApi from "@/api/dict";
import userInfoApi from "@/api/userInfo";

const defaultForm = {
  name: "",
  certificatesType: "",
  certificatesNo: "",
  certificatesUrl: "",
};
export default {
  data() {
    return {
      userAuah: defaultForm,
      certificatesTypeList: [],
      fileUrl: "http://localhost:81/api/oss/file/fileUpload",
      userInfo: {
        param: {},
      },
      submitBnt: "提交",
    };
  },
  created() {
    this.init();
  },
  methods: {
    init() {
      this.getUserInfo();
      this.getDict();
    },
    getUserInfo() {
      userInfoApi.getUserInfo().then((response) => {
        this.userInfo = response.data;
      });
    },
    saveUserAuah() {
      if (this.submitBnt == "正在提交...") {
        this.$message.info("重复提交");
        return;
      }
      this.submitBnt = "正在提交...";
      userInfoApi
        .saveUserAuth(this.userAuah)
        .then((response) => {
          this.$message.success("提交成功");
          window.location.reload();
        })
        .catch((e) => {
          this.submitBnt = "提交";
        });
    },
    getDict() {
      dictApi.findByDictCode("CertificatesType").then((response) => {
        this.certificatesTypeList = response.data;
      });
    },
    onUploadSuccess(response, file) {
      if (response.code !== 200) {
        this.$message.error("上传失败");
        return;
      }
      // 填充上传文件列表
      this.userAuah.certificatesUrl = file.response.data;
    },
  },
};
</script>
<style>
.header-wrapper .title {
  font-size: 16px;
  margin-top: 0;
}
.content-wrapper {
  margin-left: 0;
}
.patient-card .el-card__header .detail {
  font-size: 14px;
}
.page-container .title {
  letter-spacing: 1px;
  font-weight: 700;
  color: #333;
  font-size: 16px;
  margin-top: 0;
  margin-bottom: 20px;
}
.page-container .tips {
  width: 100%;
  padding-left: 0;
}
.page-container .form-wrapper {
  padding-left: 92px;
  width: 580px;
}
.form-normal {
  height: 40px;
}
.bottom-wrapper {
  width: 100%;
  padding: 0;
  margin-top: 0;
}
</style>

上传文件报错

image-20221125144039120

oss模块添加配置

spring.servlet.multipart.max-file-size=500MB
spring.servlet.multipart.max-request-size=500MB

image-20221125144155639

预约挂号页面调整

预约挂号前验证 是否实名认证

// 预约
    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;
    },

就诊人管理

预约下单需要选择就诊人,因此我们要实现就诊人管理,前端就诊人管理其实就是要实现一个完整的增删改查

user 远程调用 cmn 模块,查看数据字典

这个功能需要提一下的这块的处理,对于数据的封装,所有的基础资料只存了 code, 剩余的信息远程调用 cmn 模块获取,重点注意下这里的

//根据登录用户id获取就诊列表
    @Override
    public List<Patient> findAllUserId(Long userId) {
        //据登录用户id查询所有就诊人信息列表
        QueryWrapper<Patient> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId);
        List<Patient> patientList = baseMapper.selectList(wrapper);
        //通过远程调用得到部分编码对应的具体内容,查询数据字典表中的内容  例如 编号2000对应的是身份证方式
        patientList.stream().forEach(item -> {
            this.packPatient(item);  //将param中的一些属性封装进patient中
        });
        return patientList;
    }

//将param中的一些属性封装进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;
    }

其他代码可自行参考资料中的代码

做完之后的效果

image-20221127190249380 image-20221127190304821

用户管理

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

除去增删查改还有 锁定,认证审批接口,也比较常规,简单看下效果,代码就不看了

image-20221127194441036

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/40271.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数字化管理门店| 甜品店管理系统

对不少女生来说&#xff0c;甜品店绝对算是经常去的地方&#xff0c;尤其出新品的时候&#xff0c;就如奶茶店一样在排队&#xff0c;在武汉一家足球场的旁边&#xff0c;有一家“甜如箭丘”品牌门店&#xff0c;整体环境装修的非常附有文艺感&#xff0c;明亮的店堂&#xff0…

第7章 网络优化与正则化

系列文章目录 第1章 绪论 第2章 机器学习概述 第3章 线性模型 第4章 前馈神经网络 第5章 卷积神经网络 第6章 循环神经网络 第7章 网络优化与正则化 第8章 注意力机制与外部记忆 第9章 无监督学习 第10章 模型独立的学习方式 第11章 概率图模型 第12章 深度信念网络 第13章 深…

[Flask]Pycharm+Flask零基础项目搭建入门

Flask在Python web开发中虽然热度低于Django但是也存在不小的市场空间&#xff0c;能作为一个主流web开发框架之一也不是浪得虚名&#xff0c;还是有不少干货在里面的&#xff0c;Flask也具备了不少的自身优势&#xff0c;在后面的认识中我们再逐步深入了解 今天我们就来带大家…

池式结构:对象池(Object Pool)

本文是对 http://gameprogrammingpatterns.com/object-pool.html 的原创翻译。部分地方使用意译&#xff0c;不准确的地方请各位指证。 一、对象池的意义 通过重新使用固定的池式结构中的对象&#xff0c;来代替单独分配和释放对象&#xff0c;可以提高程序的性能和内存使用。…

裸 VSCode 必备插件

VSCode 轻量、开源&#xff0c;新鲜下载的 VSCode 可谓是身无长物、一穷二白&#xff0c;连个项目管理的功能都没有。 身轻如燕的 VSCode 对于后端开发说可能有点幼稚&#xff0c;但对于前端来说刚刚好&#xff0c;毕竟不需要搞什么 Docker、数据库等等&#xff0c;装俩 VSCod…

02 本机搭建kubernetes学习环境kubemini

文章目录1. 什么是容器编排&#xff1f;2. 什么是 Kubernetes&#xff1f;2.1 Kubernetes 到底能够为我们做什么呢&#xff1f;3. 什么是 minikube4. 如何搭建 minikube 环境4.1 minikube 安装4.2 kubectl 安装5. 验证实验节点5.1 kubectl 使用5.2 在kubernetes 运行第一个应用…

第148篇 笔记-DeFi

定义&#xff1a;去中心化金融(Decentralized finance)&#xff0c;简称“DeFi”&#xff0c;是指基于区块链的无许可和透明金融服务生态系统。 DeFi是区块链、智能合约和预言机带来的最重大进步之一。DeFi一开始是在去中心化基础设施上重新创建通用金融工具的运动&#xff0c…

循环玩具游戏

一 问题描述 有个名为 Looploop 的玩具&#xff0c;这个玩具有 N 个元素&#xff0c;以循环方式排列。有一个箭头指向其中一个元素&#xff0c;还有两个预设参数 k1 和 k 2。 上图显示了一个由 6 个元素组成的循环。假设预设参数 k13&#xff0c;k2 4&#xff0c;对这个玩具做…

【谷粒商城 - k8s、devOps专栏】

一、K8s快速入门 其他项目的K8S笔记&#xff1a;https://blog.csdn.net/hancoder/category_11140481.html 1&#xff09;简介 kubernetes简称k8s。是用于自动部署&#xff0c;扩展和管理容器化应用程序的开源系统。 部署方式的进化&#xff1a; [外链图片转存失败,源站可能…

STM32系列(HAL库) ——定时器编码器/正交解码模式

STM32定时器的正交解码模式多用于检测电机的编码器脉冲数做闭环控制&#xff0c;如PID。本文简单介绍一下定时器在Cubemx如何配置以及程序引用到的API函数。 一、前期准备 1、硬件&#xff1a; STM32C8T6最小系统板USB-TTL串口模块ST-Link下载器 2、软件&#xff1a; keil5…

Linux

1.入门概述 我们为什么要学习Linux linux诞生了这么多年&#xff0c;以前还喊着如何能取代windows系统&#xff0c;现在这个口号已经小多了&#xff0c;任何事物发展都有其局限性都有其天花板。就如同在国内再搞一个社交软件取代腾讯一样&#xff0c;想想而已基本不可能&#x…

斐波那契散列和hashMap实践

斐波那契散列和hashMap实践 适合的场景&#xff1a;抽奖(游戏、轮盘、活动促销等等) 如果有不对的地方&#xff0c;欢迎指正&#xff01; HashMap实现数据散列&#xff1a; 配置项目&#xff0c;引入pom.xml: <dependency><groupId>com.alibaba</groupId&g…

排序算法-冒泡排序

基本思路 遍历给定的数组&#xff0c;从左往右&#xff0c;两两比较&#xff0c;小的放在左边&#xff0c;大的放在右边&#xff0c;遍历完成&#xff0c;数组有序。 先来看一个冒泡排序的过程&#xff1a; 给定数组&#xff1a;[5,3,2,1,4] 排序结果&#xff1a;[1,2,3,4,5…

Sha1,Sha256 哈希(摘要)处理

具体参考&#xff1a;Sha1,Sha256哈希&#xff08;摘要&#xff09;在线处理工具

显示今天的年、月、日日期、时间的数据处理timetuple()

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 显示今天的年、月、日 日期、时间的数据处理 timetuple() [太阳]选择题 对下面描述错误的选项为&#xff1f; import datetime dtdatetime.date.today() print("【显示】dt",dt) p…

Redis最全详解(三)——SpringBoot整合2种方式

SpringBoot整合Redis 常用 api 介绍 有两个 redis 模板&#xff1a;RedisTemplate 和 StringRedisTemplate。我们不使用 RedisTemplate&#xff0c;RedisTemplate 提供给我们操作对象&#xff0c;操作对象的时候&#xff0c;我们通常是以 json 格式存储&#xff0c;但在存储的…

[附源码]java毕业设计作业自动评阅系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【window下配置Maxim SDK环境】

【window下配置Maxim SDK环境】1. 前言2. Maxim SDK下载3. Maxim SDK安装3.1 安装详解3.2 安装完成4. 测试环境4.1 新建Hello word demo4.2 编译调试下载4.2.1 clean4.2.2 build4.2.3 Openocd5. 实验效果6.小结1. 前言 MAX78000FTHR为快速开发平台&#xff0c;帮助工程师利用M…

第149篇 笔记-web3

定义&#xff1a;Web3是基于去中心化原则的互联网新革命。Web3将当今丰富的交互式数字体验与为用户提供所有权和加密保证的基础设施相结合。 最近在传统技术部门和区块链生态系统的行业领导者中&#xff0c;Web3已成为主流意识&#xff0c;其对互联网的过去和未来有着广泛的影…

蜂鸟E203学习笔记(三)——流水线结构

握手和反压 首先介绍握手协议 valid-ready握手协议 valid先发起请求 ready先发出请求 同时发出请求 仔细观察上述3幅时序图&#xff0c;我们了解valid-ready握手机制需要注意三件事&#xff1a; valid与ready不可过度依赖&#xff0c;比如valid不可以等待ready到达再拉高&…