当前位置:网站首页>Day117.尚医通:生成挂号订单模块
Day117.尚医通:生成挂号订单模块
2022-08-02 22:44:00 【焰火青年·】
目录
一、搭建生成挂号订单模块
1. 需求分析
(1) 点击“确认挂号” 按钮,生成挂号订单,存入订单表
(2) 调用医院系统进行挂号确认,挂号成功需要更新订单表
(3) 挂号成功,更新号源信息,通知就诊人挂号成功 (异步MQ)
接口分析:
(1) 根据排班id查询相关信息
(2) 根据就诊人id查询就诊人的相关信息
2. 确认库表
设计表:故意添加冗余字段,保证读的效率,牺牲写的效率
3. 搭建订单模块 service_orders
<dependencies>
<dependency>
<groupId>com.atguigu</groupId>
<artifactId>service_cmn_client</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
application.properties
# 服务端口
server.port=8206
# 服务名
spring.application.name=service-orders
# 环境设置:dev、test、prod
spring.profiles.active=dev
# mysql数据库连接
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/yygh_order?characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=*******
#返回json的全局时间格式
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
#mybatis日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
# mongodb
spring.data.mongodb.uri=mongodb://192.168.86.86:27017/test
# nacos服务地址
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
#rabbitmq地址
#spring.rabbitmq.host=192.168.44.165
#spring.rabbitmq.port=5672
#spring.rabbitmq.username=guest
#spring.rabbitmq.password=guest
gateway 添加路由
#设置路由id
spring.cloud.gateway.routes[6].id=service-orders
#设置路由的uri
spring.cloud.gateway.routes[6].uri=lb://service-orders
#设置路由断言,代理servicerId为auth-service的/auth/路径
spring.cloud.gateway.routes[6].predicates= Path=/*/order/**
启动类
@SpringBootApplication
@ComponentScan(basePackages = {"com.atguigu"})
@EnableDiscoveryClient
@EnableFeignClients(basePackages = {"com.atguigu"})
@MapperScan("com.atguigu.yygh.order.mapper")
public class ServiceOrderApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceOrderApplication.class, args);
}
}
二、生成挂号订单接口 (就诊人调用封装)
1. 分析接口
*参数:scheduleId、patientId
*返回值:orderId
2. controller
@ApiOperation(value = "创建订单")
@PostMapping("auth/submitOrder/{scheduleId}/{patientId}")
public R submitOrder(@PathVariable String scheduleId,
@PathVariable Long patientId) {
Long orderId = orderService.saveOrder(scheduleId, patientId);
return R.ok().data("orderId",orderId);
}
3. service
//创建订单
@Override
public Long saveOrder(String scheduleId, Long patientId) {
//1.根据patientId 跨模块查询就诊人信息
//2.跨模块查询医院排班信息(医院、科室、排班、预约规则) scheduleId
//3.整合数据,创建订单,插入数据库
//4.调用医院系统进行挂号确认
//5.TODO 发送MQ消息通知就诊人,更新号源
return null;
}
4. 在user模块实现查询就诊人信息 (远程调用)
(1). 分析接口
*参数:patientId
*返回值:patient
(2). PatientApiController
@ApiOperation(value = "获取就诊人(远程调用)")
@GetMapping("inner/get/{id}")
public Patient getPatientOrder(
@PathVariable("id") Long id) {
//模块间调用,不需要翻译字段
Patient patient = patientService.getById(id);
return patient;
}
(3). 创建user模块远程调用接口
搭建service_user_client模块
@FeignClient(value = "service-user")
@Repository
public interface PatientFeignClient {
//获取就诊人,注意@PathVariable("id")不能省略,路径必须完整
@GetMapping("/api/user/patient/inner/get/{id}")
Patient getPatientOrder(@PathVariable("id") Long id);
}
5. 生成挂号订单接口 (远程调用获取排班信息、规则信息)
(1). 分析接口:
*参数:scheduleId
*返回值:ScheduleOrderVo
(2). HospitalApiController
@ApiOperation(value = "根据排班id获取预约下单数据")
@GetMapping("inner/getScheduleOrderVo/{scheduleId}")
public ScheduleOrderVo getScheduleOrderVo(
@PathVariable("scheduleId") String scheduleId) {
ScheduleOrderVo scheduleOrderVo = scheduleService.getScheduleOrderVo(scheduleId);
return scheduleOrderVo;
}
(3). service
//根据排班id获取预约下单数据
@Override
public ScheduleOrderVo getScheduleOrderVo(String scheduleId) {
//1.根据排班id获取排班信息
Schedule schedule = scheduleRepository.findById(scheduleId).get();
if(schedule==null){
throw new YyghException(20001,"排班信息有误");
}
//2.根据hoscode查询医院信息
String hoscode = schedule.getHoscode();
Hospital hospital = hospitalService.getHospital(hoscode);
if(hospital==null){
throw new YyghException(20001,"医院信息有误");
}
//3.从医院信息中取出预约规则
BookingRule bookingRule = hospital.getBookingRule();
//4.封装基础数据
ScheduleOrderVo scheduleOrderVo = new ScheduleOrderVo();
scheduleOrderVo.setHoscode(hospital.getHoscode());
scheduleOrderVo.setHosname(hospital.getHosname());
scheduleOrderVo.setDepcode(schedule.getDepcode());
scheduleOrderVo.setDepname(departmentService.getDepartment(schedule.getHoscode(), schedule.getDepcode()).getDepname());
scheduleOrderVo.setHosScheduleId(schedule.getHosScheduleId());
scheduleOrderVo.setAvailableNumber(schedule.getAvailableNumber());
scheduleOrderVo.setTitle(schedule.getTitle());
scheduleOrderVo.setReserveDate(schedule.getWorkDate());
scheduleOrderVo.setReserveTime(schedule.getWorkTime());
scheduleOrderVo.setAmount(schedule.getAmount());
//5.封装根据预约规则推算的时间信息
//5.1推算可以退号的截止日期+时间
//退号截止天数(如:就诊前一天为-1,当天为0)
DateTime quitDate = new DateTime(schedule.getWorkDate())
.plusDays(bookingRule.getQuitDay()); //plusDays 负数,往回推算
//日期+时间拼装
DateTime quitDateTime = this.getDateTime(quitDate.toDate(), bookingRule.getQuitTime());
scheduleOrderVo.setQuitTime(quitDateTime.toDate());
//预约开始时间
DateTime startTime = this.getDateTime(new Date(), bookingRule.getReleaseTime());
scheduleOrderVo.setStartTime(startTime.toDate());
//预约截止时间
DateTime endTime = this.getDateTime(
new DateTime().plusDays(bookingRule.getCycle()).toDate(),
bookingRule.getStopTime());
scheduleOrderVo.setEndTime(endTime.toDate());
//当天停止挂号时间
DateTime stopTime = this.getDateTime(new Date(), bookingRule.getStopTime());
scheduleOrderVo.setStartTime(startTime.toDate());
return scheduleOrderVo;
}
(4). 创建远程调用接口
搭建service_hosp_client
@FeignClient(value = "service-hosp")
@Repository
public interface HospitalFeignClient {
//根据排班id获取预约下单数据
@GetMapping("/api/hosp/hospital/inner/getScheduleOrderVo/{scheduleId}")
ScheduleOrderVo getScheduleOrderVo(@PathVariable("scheduleId") String scheduleId);
}
三、生成挂号订单接口 (远程调用\获取排班信息\创建订单)
1. 准备工作
(1). 确认启动类注解 @EnableFeignClients
(2). 引入相关模块依赖
<dependencies>
<!-- 日期工具类依赖 -->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
<dependency>
<groupId>com.atguigu</groupId>
<artifactId>service_cmn_client</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.atguigu</groupId>
<artifactId>service_hosp_client</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.atguigu</groupId>
<artifactId>service_user_client</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
(3). 封装工具类
(4). 省略签名校验,注释掉医院平台放校验代码
如果是Mysql5.5,添加自动填充
2. service
@Service
public class OrderServiceImpl
extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderService {
@Autowired
private PatientFeignClient patientFeignClient;
@Autowired
private HospitalFeignClient hospitalFeignClient;
//创建订单
@Override
public Long saveOrder(String scheduleId, Long patientId) {
//1.根据patientId 跨模块查询就诊人信息
Patient patient = patientFeignClient.getPatientOrder(patientId);
if(patient==null){
throw new YyghException(20001,"获取就诊人信息有误");
}
//2.跨模块查询医院排班信息(医院、科室、排班、预约规则) scheduleId
ScheduleOrderVo scheduleOrderVo = hospitalFeignClient.getScheduleOrderVo(scheduleId);
if(scheduleOrderVo==null){
throw new YyghException(20001,"获取排班相关信息有误");
}
//2.1 创建订单前,时间合法性校验 (大于开始时间 小于结束时间)
if(new DateTime(scheduleOrderVo.getStartTime()).isAfterNow() ||
new DateTime(scheduleOrderVo.getEndTime()).isBeforeNow()){
throw new YyghException(20001,"未到挂号时间");
}
//2.2 确认是否有号源
if(scheduleOrderVo.getAvailableNumber()<=0){
throw new YyghException(20001,"号源已挂满");
}
//3.整合数据,创建订单,插入数据库
OrderInfo orderInfo = new OrderInfo();
BeanUtils.copyProperties(scheduleOrderVo, orderInfo);
String outTradeNo = System.currentTimeMillis() + ""+ new Random().nextInt(100);
orderInfo.setOutTradeNo(outTradeNo);
orderInfo.setUserId(patient.getUserId());
orderInfo.setPatientId(patientId);
orderInfo.setPatientName(patient.getName());
orderInfo.setPatientPhone(patient.getPhone());
orderInfo.setOrderStatus(OrderStatusEnum.UNPAID.getStatus());
this.save(orderInfo);
//4.调用医院系统进行挂号确认 (参考API接口文档)
//4.1封装调用医院接口参数
Map<String,Object> paramMap = new HashMap<>();
paramMap.put("hoscode",orderInfo.getHoscode());
paramMap.put("depcode",orderInfo.getDepcode());
paramMap.put("hosScheduleId",orderInfo.getHosScheduleId());
paramMap.put("reserveDate",new DateTime(orderInfo.getReserveDate()).toString("yyyy-MM-dd"));
paramMap.put("reserveTime", orderInfo.getReserveTime());
paramMap.put("amount",orderInfo.getAmount());
paramMap.put("name", patient.getName());
paramMap.put("certificatesType",patient.getCertificatesType());
paramMap.put("certificatesNo", patient.getCertificatesNo());
paramMap.put("sex",patient.getSex());
paramMap.put("birthdate", patient.getBirthdate());
paramMap.put("phone",patient.getPhone());
paramMap.put("isMarry", patient.getIsMarry());
paramMap.put("provinceCode",patient.getProvinceCode());
paramMap.put("cityCode", patient.getCityCode());
paramMap.put("districtCode",patient.getDistrictCode());
paramMap.put("address",patient.getAddress());
//联系人
paramMap.put("contactsName",patient.getContactsName());
paramMap.put("contactsCertificatesType", patient.getContactsCertificatesType());
paramMap.put("contactsCertificatesNo",patient.getContactsCertificatesNo());
paramMap.put("contactsPhone",patient.getContactsPhone());
paramMap.put("timestamp", HttpRequestHelper.getTimestamp());
//MD5加密签名校验,省略
paramMap.put("sign", "");
//4.2通过工具发送请求,获取响应
JSONObject result = HttpRequestHelper.sendRequest(
paramMap, "http://localhost:9998/order/submitOrder");
//4.3判断挂号确认是否成功
if(result.getInteger("code") == 200){ //ResultCodeEnum.SUCCESS 200
//4.4取出返回结果,更新订单信息
JSONObject jsonObject = result.getJSONObject("data");
//预约记录唯一标识(医院预约记录主键)
String hosRecordId = jsonObject.getString("hosRecordId");
//预约序号
Integer number = jsonObject.getInteger("number");;
//取号时间
String fetchTime = jsonObject.getString("fetchTime");;
//取号地址
String fetchAddress = jsonObject.getString("fetchAddress");;
//更新订单
orderInfo.setHosRecordId(hosRecordId);
orderInfo.setNumber(number);
orderInfo.setFetchTime(fetchTime);
orderInfo.setFetchAddress(fetchAddress);
baseMapper.updateById(orderInfo);
//排班可预约数
Integer reservedNumber = jsonObject.getInteger("reservedNumber");
//排班剩余预约数
Integer availableNumber = jsonObject.getInteger("availableNumber");
//5.TODO 发送MQ消息通知就诊人,更新号源
}else {
throw new YyghException(20001,"确认挂号失败");
}
return orderInfo.getId();
}
}
四、前端实现,测试
1. 确认入口
2. 创建 api/orderinfo.js
import request from '@/utils/request'
const api_name = `/api/order/orderInfo`
export default {
submitOrder(scheduleId, patientId) {
return request({
url: `${api_name}/auth/submitOrder/${scheduleId}/${patientId}`,
method: 'post'
})
}
}
3. 实现JS方法
booking.vue
import orderinfoApi from '@/api/orderinfo'
...
//确认挂号
submitOrder() {
//校验就诊人id
if (this.patient.id == null) {
this.$message.error('请选择就诊人')
return
}
// 防止重复提交
if (this.submitBnt == '正在提交...') {
this.$message.error('重复提交')
return
}
this.submitBnt = '正在提交...'
orderinfoApi.submitOrder(this.scheduleId, this.patient.id)
.then(response => {
let orderId = response.data.orderId
window.location.href = '/order/show?orderId=' + orderId
}).catch(e => {
this.submitBnt = '确认挂号'
})
},
4. 测试
503 访问不到服务 Nacos 配置错误,服务名错误
边栏推荐
猜你喜欢
Jmeter二次开发实现rsa加密
R语言自学 1 - 向量
学习基因富集工具DAVID(3)
程序员的七夕浪漫时刻
The latest real software test interview questions are shared. Are you afraid that you will not be able to enter the big factory after collecting them?
最新真实软件测试面试题分享,收藏了还怕进入不了大厂?
Test | ali internship 90 days in life: from the perspective of interns, talk about personal growth
redis的学习笔记
Swift中的类型相关内容
CAS:474922-22-0,DSPE-PEG-MAL,磷脂-聚乙二醇-马来酰亚胺科研试剂供应
随机推荐
聚乙二醇衍生物4-Arm PEG-DSPE,四臂-聚乙二醇-磷脂
# DWD层及DIM层构建## ,220801 ,
数字化转型巨浪拍岸,成长型企业如何“渡河”?
工业元宇宙的价值和发展
买母婴产品先来京东“券民空间站”抢券!大牌好物低至5折
TCP三次握手与四次挥手
创建型模式 - 简单工厂模式StaticFactoryMethod
airflow db init 报错
【斯坦福计网CS144项目】Lab5: NetworkInterface
总数据量超万亿行,玉溪卷烟厂通过正确选择时序数据库轻松应对
思源笔记 本地存储无使用第三方同步盘,突然打不开文件。
「X」to「Earn」:赛道现状与破局思路
浅读一下dotenv的主干逻辑的源码
IDO代币预售合约系统开发技术详细
CodeTON Round 2 A - D
Web APIs BOM- 操作浏览器-Window对象
threejs dynamically adjust the camera position so that the camera can see the object exactly
软件测试到底自学还是报班?
Auto.js脚本程序打包
ssm整合(三)Controller 和 视图层编写