尚医通概览
尚医通概览
项目介绍
医院预约挂号项目,包含三个系统:
- 预约挂号系统前台
- 预约挂号系统管理员后台
- 外部医院管理后台(已经开发好)
如图所示:
项目功能
预约挂号系统前台
- 登录
- 首页信息展示
- 预约挂号
- 支付订单
预约挂号系统管理员后台
- 数据字典
- easy Excel 导入导出
- 医院管理
- 用户管理
- 订单(预约)管理
- 统计管理
医院接口模拟平台
相当于医院自己维护的系统,通过签名校验的方式调研我们提供的接口来管理医院数据。
技术栈
前端
- Vue
- vue-admin-template管理员模板
- ueQriously二维码生成库
- babel
- webpack
- nuxt服务端渲染
- element ui
后端
微服务:
- Spring Cloud Alibaba框架
- Nacos注册中心
- Spring Cloud Feign远程调用
- Spring Cloud Gateway微服务网关
- Maven子父多模块
- Docker(部署项目、安装服务)
数据存储:
- MongoDB:负责存医院基本信息(性更高)
- mySQL:存储用户、订单、预约等关系信息
中间件:
- Redis:缓存、存储验证码
- RabbitMQ:应用解耦、消息通知
- Nginx:部署项目
工具库:
- easy excel:读写Excel文件
- Json Web Token:生成jwt token
- Joda Time:日期时间操作
架构中并没搭建集群,都是用的单机版
项目学习
本项目重点知识
- 微服务的思想、划分以及实现方式,以及相关技术的用法:
- 注册中心
- 客户端调用
- 微服务网关
- 熟悉一个完整的业务流程(信息发布=>信息展示=>购买=>下单支付=>统计管理)
- 登录认证机制,包括手机号登录、微信扫码登绿、OAuth、JWT等知识
- 如何运用合适的数据库来解决问题?比如MySQL存储关系型数据、Redis用于缓存、MongoDB存储一些非关系型的数据(提高访问速度)、RāobitMQ来实现异步通知和应用解耦。
- 调用第三方API来解决实际问题,比如微信接口、OSS、SMS
- 学习项目的目录结构及编码规范,比如通用返回对象、全局异常处理器、ContextHolder等
项目启动流程
启动nacos
startup.cmd -m standalone
启动docker上的rabbit,redis,MongoDB
启动后端
spring一键启动启动yygh_sit,用户前台
选第二个dev nuxt启动yygh_admin,管理员后台
选第一个start
端口分析:
- 80是服务网关
- 8160是用户api接口服务
- 8201是医院api接口服务
- 8202是数据字典服务
- 8204是短信 api接口服务
- 8205是文件api接口服务
- 8206是订单api接口服务
- 8207是定时任务服务
- 8208是统计api接口服务
- 9998是接口模拟系统
测试前台vue_site可以只启动:80,8160,8201,8202,8204
管理后台vue_admin可以直接运行
后端微服务学习:
本项目的服务划分如下:
- common项目公共代码
- model项目数据模型层(只提供接口,便于公用)
- service具体的业务逻辑(微服务)
- service client服务调用客户端(只提供接口,便于公用)
- service_.gateway(微服务网关)负责统一校验/拦截、跨域、请求转发
- 公共服务:数据字典管理,导入导出(公共用的枚举值)
- 医院服务:管理医院,医院信息、排版信息、医院设置信息的增删改查
- 短信服务(SMS):负责发送短信验证码
- 用户服务:管理用户、就诊人、用户登泉
- 订单服务:支付订单,订单(预约)管理
- 存储服务:上传文件(上传用户的图片)
- 统计服务:分析下单情况
- 定时任务服务:每天8点就医提醒
数据库设置:
yygh_cnm
dict:组织架构表,数据字典的数据yygh_hosp
hospital_set,医院列表yygh_manage
hospital_set,医院设置表
order_info,订单表
schedule,医生排班表yygh_order
order_info,订单表
payment_info,支付信息表
refund_info,退款信息表yygh_user
patient,就诊人表
user_info.用户表
user_login_record,用户登录记录表
首先搭建父工程模块yygh-parent,该模块不需要编写代码只需要一个POM文件即可。它的作用就是一个规范,将要使用的依赖引入并指定版本号,在后续的子模块中只需要引入依赖不需要指定版本号
1 |
|
整体结构
common模块:
将会重复使用的模块抽离出来形成一个单独模块,其他模块在使用的时候直接在POM中加入依赖即可
common目录结构:
common:公共模块父节点
common-util:工具类模块,所有模块都可以依赖于它
rabbit-util:rabbitmq业务封装
service-util:service服务的工具包,包含service服务的公共配置类,所有service模块依赖于它
common_util子模块:
设置项目编码中的统一规范
- GlobalExceptionHandler:默认全局异常
- YyghException:自定义全局异常
- JwtHelper:设置JWT的登录验证
- Result:自定义返回类型
- ResultCodeEnum:返回状态码,例如200成功201失败
- AuthContextHolder:获取当前用户信息
rabbit-util子模块:
进行rabbitmq的业务封装
- MQConfig:mq的配置文件,例如设置消息转换器,将消息队列中的数据转换成指定类型
- MqConst:设置消息的状态码
- RabbitService:消息的发送
service-util子模块:
service服务的工具包
- RedisConfig:Redis配置文件
- Swagger2Config:Swagger配置文件
- HttpRequestHelper:自定义service请求
- HttpUtil:自定义Http请求
- MD5:设置MD5加密
hospital-manage模块:
医院接口模拟端(已开发,直接使用)
hospital-manage目录结构:
application.yml:
1 |
|
设置项目环境为dev
相应的就会执行application-dev.yml中的配置
model模块:
根据数据库中的表创建对应的实体类
目录结构:
在实体类中添加注解
1 |
|
在字段上添加注解
1 |
|
对于使用EasyExcel要进行导入导出的数据添加注解
1 |
|
Service模块:
api接口服务父节点
目录结构:
service:api接口服务父节点
- service-hosp:医院api接口服务
- service-cmn:数据字典服务
- service-user:用户api接口服务
- service-order:订单api接口服务
- service-oss:文件api接口服务
- service-sms:短信 api接口服务
- service-task:定时任务服务
- service-statistics:统计api接口服务
service-cmn子模块:
公共api接口服务
目录结构:
关于Service模块大致都是这么一个结构
首先在mapper包中创建为当前模块使用的mapper接口继承Basemapper,使用mybatisplus包中封装好的增删改查方法如果需要写其他的sql语句再在该接口中增加抽象方法
1 |
|
在service包中编写业务接口并创建抽象方法、
1 |
|
在impl中实现该接口并在实现的抽象方法中编写具体的业务逻辑,添加@service注解交给spring管理
1 |
|
在controller包中注入sevice接口,调用service中的各种方法处理请求
1 |
|
@Autowired为什么注入接口就可以使用其实现类?
@Autowired默认按byType(自动装配)注入:寻找实现了interface的Bean(在实现类上添加注解@Service后就相当于在xml中编写了配置),这个注解适用于只有一个Bean实现了接口的情况。
能不能直接注入接口的实现类?
开发中往往会对实现类做增强,如事务,日志等,实现增强的AOP技术是通过动态代理实现的,而spring默认是JDK动态代理,对实现类对象做增强得到的增强类与实现类是兄弟关系,所以不能用实现类接收增强类对象,只能用接口接收。如果将对象注入给实现类而非接口的话,在代理时就会报错。
可以用Cglib代理强制实现,cglib代理类和实现类之间是父子关系,自然可以用父类(实现类)去接收子类对象(代理类对象即增强类对象)。
在config包中创建配置类:对当前模块进行配置,例如设置数据库的查询分页
1 |
|
listener为EasyExcel的导入导出配置类
service-hosp子模块:
医院api接口服务
目录结构:
在mapper包中除了原来的mapper接口还有xml包用于对应mapper接口
当Basemapper中方法不能满足需求时在xml中编写自己的sql语句
1 |
|
repository包和mapper包类似,创建接口继承 Mongodb调用对数据库的增删改查方法,根据业务需求增加抽象方法
HospitalReceiver:对rabbit消息队列进行设置
controller包:
将经常使用的控制类放到api包下,处理经常发出的请求
service-msm子模块:
短信 api接口服务
目录结构:
service-order子模块:
订单api接口服务
目录结构:
service-oss子模块:
文件api接口服务
目录结构:
service-statistics子模块:
统计api接口服务
目录结构:
service-task子模块:
定时任务服务
目录结构:
service-user子模块:
用户api接口服务
目录结构:
service-client模块:
feign服务调用父节点
目录结构:
service-cmn-client:公共api接口
service-hosp-client:医院api接口
service-order-client:订单api接口
service-user-client:用户api接口
Feign是声明式Web Service客户端,它让微服务之间的调用变得更简单,类似controller调用service。SpringCloud集成了Ribbon和Eureka,可以使用Feigin提供负载均衡的http客户端
只需要创建一个接口,然后添加注解即可使用Feign
1 |
|
当声明FeignClient后其他微服务就可以直接注入使用该模块,使得微服务之间的调用更方便了
1 |
|
server-gateway模块:
服务网关过滤请求设置访问路由