• Day117.尚医通:生成挂号订单模块


    目录

    一、搭建生成挂号订单模块

    二、生成挂号订单接口 (就诊人调用封装)

    4. 在user模块实现查询就诊人信息 (远程调用)

    5. 生成挂号订单接口 (远程调用获取排班信息、规则信息)

    三、生成挂号订单接口 (远程调用\获取排班信息\创建订单)

    四、前端实现,测试

    五、集成RabbitMQ 消息中间件

    1、通过Docker 安装

    2、封装rabbit和短信发送

    3、短信模块改造

    4、封装更新排班方法

    5、完善下单接口:短信提示、更新号源


    一、搭建生成挂号订单模块

    1. 需求分析

    (1) 点击“确认挂号” 按钮,生成挂号订单,存入订单表

    (2) 调用医院系统进行挂号确认,挂号成功需要更新订单表

    (3) 挂号成功,更新号源信息,通知就诊人挂号成功 (异步MQ)

    接口分析:

    (1) 根据排班id查询相关信息

    (2) 根据就诊人id查询就诊人的相关信息

    2. 确认库表

    设计表:故意添加冗余字段,保证读的效率,牺牲写的效率

    3. 搭建订单模块 service_orders

    1. <dependencies>
    2. <dependency>
    3. <groupId>com.atguigugroupId>
    4. <artifactId>service_cmn_clientartifactId>
    5. <version>0.0.1-SNAPSHOTversion>
    6. dependency>
    7. dependencies>

    application.properties

    1. # 服务端口
    2. server.port=8206
    3. # 服务名
    4. spring.application.name=service-orders
    5. # 环境设置:dev、test、prod
    6. spring.profiles.active=dev
    7. # mysql数据库连接
    8. spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    9. spring.datasource.url=jdbc:mysql://localhost:3306/yygh_order?characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
    10. spring.datasource.username=root
    11. spring.datasource.password=*******
    12. #返回json的全局时间格式
    13. spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
    14. spring.jackson.time-zone=GMT+8
    15. #mybatis日志
    16. mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
    17. # mongodb
    18. spring.data.mongodb.uri=mongodb://192.168.86.86:27017/test
    19. # nacos服务地址
    20. spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
    21. #rabbitmq地址
    22. #spring.rabbitmq.host=192.168.44.165
    23. #spring.rabbitmq.port=5672
    24. #spring.rabbitmq.username=guest
    25. #spring.rabbitmq.password=guest

    gateway 添加路由

    1. #设置路由id
    2. spring.cloud.gateway.routes[6].id=service-orders
    3. #设置路由的uri
    4. spring.cloud.gateway.routes[6].uri=lb://service-orders
    5. #设置路由断言,代理servicerId为auth-service的/auth/路径
    6. spring.cloud.gateway.routes[6].predicates= Path=/*/order/**

    启动类

    1. @SpringBootApplication
    2. @ComponentScan(basePackages = {"com.atguigu"})
    3. @EnableDiscoveryClient
    4. @EnableFeignClients(basePackages = {"com.atguigu"})
    5. @MapperScan("com.atguigu.yygh.order.mapper")
    6. public class ServiceOrderApplication {
    7. public static void main(String[] args) {
    8. SpringApplication.run(ServiceOrderApplication.class, args);
    9. }
    10. }

    二、生成挂号订单接口 (就诊人调用封装)

    1. 分析接口

    *参数:scheduleId、patientId

    *返回值:orderId

    2. controller 

    1. @ApiOperation(value = "创建订单")
    2. @PostMapping("auth/submitOrder/{scheduleId}/{patientId}")
    3. public R submitOrder(@PathVariable String scheduleId,
    4. @PathVariable Long patientId) {
    5. Long orderId = orderService.saveOrder(scheduleId, patientId);
    6. return R.ok().data("orderId",orderId);
    7. }

    3. service 

    1. //创建订单
    2. @Override
    3. public Long saveOrder(String scheduleId, Long patientId) {
    4. //1.根据patientId 跨模块查询就诊人信息
    5. //2.跨模块查询医院排班信息(医院、科室、排班、预约规则) scheduleId
    6. //3.整合数据,创建订单,插入数据库
    7. //4.调用医院系统进行挂号确认
    8. //5.TODO 发送MQ消息通知就诊人,更新号源
    9. return null;
    10. }

    4. 在user模块实现查询就诊人信息 (远程调用)

    (1). 分析接口

    *参数:patientId

    *返回值:patient

    (2). PatientApiController

    1. @ApiOperation(value = "获取就诊人(远程调用)")
    2. @GetMapping("inner/get/{id}")
    3. public Patient getPatientOrder(
    4. @PathVariable("id") Long id) {
    5. //模块间调用,不需要翻译字段
    6. Patient patient = patientService.getById(id);
    7. return patient;
    8. }

    (3). 创建user模块远程调用接口

    搭建service_user_client模块

    1. @FeignClient(value = "service-user")
    2. @Repository
    3. public interface PatientFeignClient {
    4. //获取就诊人,注意@PathVariable("id")不能省略,路径必须完整
    5. @GetMapping("/api/user/patient/inner/get/{id}")
    6. Patient getPatientOrder(@PathVariable("id") Long id);
    7. }

    5. 生成挂号订单接口 (远程调用获取排班信息、规则信息)

    (1). 分析接口:

    *参数:scheduleId

    *返回值:ScheduleOrderVo

    (2). HospitalApiController

    1. @ApiOperation(value = "根据排班id获取预约下单数据")
    2. @GetMapping("inner/getScheduleOrderVo/{scheduleId}")
    3. public ScheduleOrderVo getScheduleOrderVo(
    4. @PathVariable("scheduleId") String scheduleId) {
    5. ScheduleOrderVo scheduleOrderVo = scheduleService.getScheduleOrderVo(scheduleId);
    6. return scheduleOrderVo;
    7. }

    (3). service

    1. //根据排班id获取预约下单数据
    2. @Override
    3. public ScheduleOrderVo getScheduleOrderVo(String scheduleId) {
    4. //1.根据排班id获取排班信息
    5. Schedule schedule = scheduleRepository.findById(scheduleId).get();
    6. if(schedule==null){
    7. throw new YyghException(20001,"排班信息有误");
    8. }
    9. //2.根据hoscode查询医院信息
    10. String hoscode = schedule.getHoscode();
    11. Hospital hospital = hospitalService.getHospital(hoscode);
    12. if(hospital==null){
    13. throw new YyghException(20001,"医院信息有误");
    14. }
    15. //3.从医院信息中取出预约规则
    16. BookingRule bookingRule = hospital.getBookingRule();
    17. //4.封装基础数据
    18. ScheduleOrderVo scheduleOrderVo = new ScheduleOrderVo();
    19. scheduleOrderVo.setHoscode(hospital.getHoscode());
    20. scheduleOrderVo.setHosname(hospital.getHosname());
    21. scheduleOrderVo.setDepcode(schedule.getDepcode());
    22. scheduleOrderVo.setDepname(departmentService.getDepartment(schedule.getHoscode(), schedule.getDepcode()).getDepname());
    23. scheduleOrderVo.setHosScheduleId(schedule.getHosScheduleId());
    24. scheduleOrderVo.setAvailableNumber(schedule.getAvailableNumber());
    25. scheduleOrderVo.setTitle(schedule.getTitle());
    26. scheduleOrderVo.setReserveDate(schedule.getWorkDate());
    27. scheduleOrderVo.setReserveTime(schedule.getWorkTime());
    28. scheduleOrderVo.setAmount(schedule.getAmount());
    29. //5.封装根据预约规则推算的时间信息
    30. //5.1推算可以退号的截止日期+时间
    31. //退号截止天数(如:就诊前一天为-1,当天为0)
    32. DateTime quitDate = new DateTime(schedule.getWorkDate())
    33. .plusDays(bookingRule.getQuitDay()); //plusDays 负数,往回推算
    34. //日期+时间拼装
    35. DateTime quitDateTime = this.getDateTime(quitDate.toDate(), bookingRule.getQuitTime());
    36. scheduleOrderVo.setQuitTime(quitDateTime.toDate());
    37. //预约开始时间
    38. DateTime startTime = this.getDateTime(new Date(), bookingRule.getReleaseTime());
    39. scheduleOrderVo.setStartTime(startTime.toDate());
    40. //预约截止时间
    41. DateTime endTime = this.getDateTime(
    42. new DateTime().plusDays(bookingRule.getCycle()).toDate(),
    43. bookingRule.getStopTime());
    44. scheduleOrderVo.setEndTime(endTime.toDate());
    45. //当天停止挂号时间
    46. DateTime stopTime = this.getDateTime(new Date(), bookingRule.getStopTime());
    47. scheduleOrderVo.setStartTime(startTime.toDate());
    48. return scheduleOrderVo;
    49. }

    (4). 创建远程调用接口

    搭建service_hosp_client

    1. @FeignClient(value = "service-hosp")
    2. @Repository
    3. public interface HospitalFeignClient {
    4. //根据排班id获取预约下单数据
    5. @GetMapping("/api/hosp/hospital/inner/getScheduleOrderVo/{scheduleId}")
    6. ScheduleOrderVo getScheduleOrderVo(@PathVariable("scheduleId") String scheduleId);
    7. }

    三、生成挂号订单接口 (远程调用\获取排班信息\创建订单)

    1. 准备工作

    (1). 确认启动类注解 @EnableFeignClients

    (2). 引入相关模块依赖

    1. <dependencies>
    2. <dependency>
    3. <groupId>joda-timegroupId>
    4. <artifactId>joda-timeartifactId>
    5. dependency>
    6. <dependency>
    7. <groupId>com.atguigugroupId>
    8. <artifactId>service_cmn_clientartifactId>
    9. <version>0.0.1-SNAPSHOTversion>
    10. dependency>
    11. <dependency>
    12. <groupId>com.atguigugroupId>
    13. <artifactId>service_hosp_clientartifactId>
    14. <version>0.0.1-SNAPSHOTversion>
    15. dependency>
    16. <dependency>
    17. <groupId>com.atguigugroupId>
    18. <artifactId>service_user_clientartifactId>
    19. <version>0.0.1-SNAPSHOTversion>
    20. dependency>
    21. dependencies>

    (3). 封装工具类

    (4). 省略签名校验,注释掉医院平台放校验代码

    如果是Mysql5.5,添加自动填充 

    2. service

    1. @Service
    2. public class OrderServiceImpl
    3. extends ServiceImpl implements OrderService {
    4. @Autowired
    5. private PatientFeignClient patientFeignClient;
    6. @Autowired
    7. private HospitalFeignClient hospitalFeignClient;
    8. //创建订单
    9. @Override
    10. public Long saveOrder(String scheduleId, Long patientId) {
    11. //1.根据patientId 跨模块查询就诊人信息
    12. Patient patient = patientFeignClient.getPatientOrder(patientId);
    13. if(patient==null){
    14. throw new YyghException(20001,"获取就诊人信息有误");
    15. }
    16. //2.跨模块查询医院排班信息(医院、科室、排班、预约规则) scheduleId
    17. ScheduleOrderVo scheduleOrderVo = hospitalFeignClient.getScheduleOrderVo(scheduleId);
    18. if(scheduleOrderVo==null){
    19. throw new YyghException(20001,"获取排班相关信息有误");
    20. }
    21. //2.1 创建订单前,时间合法性校验 (大于开始时间 小于结束时间)
    22. if(new DateTime(scheduleOrderVo.getStartTime()).isAfterNow() ||
    23. new DateTime(scheduleOrderVo.getEndTime()).isBeforeNow()){
    24. throw new YyghException(20001,"未到挂号时间");
    25. }
    26. //2.2 确认是否有号源
    27. if(scheduleOrderVo.getAvailableNumber()<=0){
    28. throw new YyghException(20001,"号源已挂满");
    29. }
    30. //3.整合数据,创建订单,插入数据库
    31. OrderInfo orderInfo = new OrderInfo();
    32. BeanUtils.copyProperties(scheduleOrderVo, orderInfo);
    33. String outTradeNo = System.currentTimeMillis() + ""+ new Random().nextInt(100);
    34. orderInfo.setOutTradeNo(outTradeNo);
    35. orderInfo.setUserId(patient.getUserId());
    36. orderInfo.setPatientId(patientId);
    37. orderInfo.setPatientName(patient.getName());
    38. orderInfo.setPatientPhone(patient.getPhone());
    39. orderInfo.setOrderStatus(OrderStatusEnum.UNPAID.getStatus());
    40. this.save(orderInfo);
    41. //4.调用医院系统进行挂号确认 (参考API接口文档)
    42. //4.1封装调用医院接口参数
    43. Map paramMap = new HashMap<>();
    44. paramMap.put("hoscode",orderInfo.getHoscode());
    45. paramMap.put("depcode",orderInfo.getDepcode());
    46. paramMap.put("hosScheduleId",orderInfo.getHosScheduleId());
    47. paramMap.put("reserveDate",new DateTime(orderInfo.getReserveDate()).toString("yyyy-MM-dd"));
    48. paramMap.put("reserveTime", orderInfo.getReserveTime());
    49. paramMap.put("amount",orderInfo.getAmount());
    50. paramMap.put("name", patient.getName());
    51. paramMap.put("certificatesType",patient.getCertificatesType());
    52. paramMap.put("certificatesNo", patient.getCertificatesNo());
    53. paramMap.put("sex",patient.getSex());
    54. paramMap.put("birthdate", patient.getBirthdate());
    55. paramMap.put("phone",patient.getPhone());
    56. paramMap.put("isMarry", patient.getIsMarry());
    57. paramMap.put("provinceCode",patient.getProvinceCode());
    58. paramMap.put("cityCode", patient.getCityCode());
    59. paramMap.put("districtCode",patient.getDistrictCode());
    60. paramMap.put("address",patient.getAddress());
    61. //联系人
    62. paramMap.put("contactsName",patient.getContactsName());
    63. paramMap.put("contactsCertificatesType", patient.getContactsCertificatesType());
    64. paramMap.put("contactsCertificatesNo",patient.getContactsCertificatesNo());
    65. paramMap.put("contactsPhone",patient.getContactsPhone());
    66. paramMap.put("timestamp", HttpRequestHelper.getTimestamp());
    67. //MD5加密签名校验,省略
    68. paramMap.put("sign", "");
    69. //4.2通过工具发送请求,获取响应
    70. JSONObject result = HttpRequestHelper.sendRequest(
    71. paramMap, "http://localhost:9998/order/submitOrder");
    72. //4.3判断挂号确认是否成功
    73. if(result.getInteger("code") == 200){ //ResultCodeEnum.SUCCESS 200
    74. //4.4取出返回结果,更新订单信息
    75. JSONObject jsonObject = result.getJSONObject("data");
    76. //预约记录唯一标识(医院预约记录主键)
    77. String hosRecordId = jsonObject.getString("hosRecordId");
    78. //预约序号
    79. Integer number = jsonObject.getInteger("number");;
    80. //取号时间
    81. String fetchTime = jsonObject.getString("fetchTime");;
    82. //取号地址
    83. String fetchAddress = jsonObject.getString("fetchAddress");;
    84. //更新订单
    85. orderInfo.setHosRecordId(hosRecordId);
    86. orderInfo.setNumber(number);
    87. orderInfo.setFetchTime(fetchTime);
    88. orderInfo.setFetchAddress(fetchAddress);
    89. baseMapper.updateById(orderInfo);
    90. //排班可预约数
    91. Integer reservedNumber = jsonObject.getInteger("reservedNumber");
    92. //排班剩余预约数
    93. Integer availableNumber = jsonObject.getInteger("availableNumber");
    94. //5.TODO 发送MQ消息通知就诊人,更新号源
    95. }else {
    96. throw new YyghException(20001,"确认挂号失败");
    97. }
    98. return orderInfo.getId();
    99. }
    100. }

    四、前端实现,测试

    1. 确认入口

    2. 创建 api/orderinfo.js

    1. import request from '@/utils/request'
    2. const api_name = `/api/order/orderInfo`
    3. export default {
    4. submitOrder(scheduleId, patientId) {
    5. return request({
    6. url: `${api_name}/auth/submitOrder/${scheduleId}/${patientId}`,
    7. method: 'post'
    8. })
    9. }
    10. }

    3. 实现JS方法

    booking.vue

    1. import orderinfoApi from '@/api/orderinfo'
    2. ...
    3. //确认挂号
    4. submitOrder() {
    5. //校验就诊人id
    6. if (this.patient.id == null) {
    7. this.$message.error('请选择就诊人')
    8. return
    9. }
    10. // 防止重复提交
    11. if (this.submitBnt == '正在提交...') {
    12. this.$message.error('重复提交')
    13. return
    14. }
    15. this.submitBnt = '正在提交...'
    16. orderinfoApi.submitOrder(this.scheduleId, this.patient.id)
    17. .then(response => {
    18. let orderId = response.data.orderId
    19. window.location.href = '/order/show?orderId=' + orderId
    20. }).catch(e => {
    21. this.submitBnt = '确认挂号'
    22. })
    23. },

    4. 测试 

     

    503 访问不到服务 Nacos 配置错误,服务名错误

    五、集成RabbitMQ 消息中间件

    削峰填谷:异步处理、流量消峰

    1、通过Docker 安装

    #拉取镜像
    docker pull rabbitmq:management

    #创建容器启动
    docker run -d --restart=always -p 5672:5672 -p 15672:15672 --name rabbitmq rabbitmq:management

    访问:http://192.168.86.86:15672/

    默认用户名密码:guest

    2、封装rabbit和短信发送

    在common搭建rabbit_util模块,引入依赖

    1. <dependencies>
    2. <dependency>
    3. <groupId>org.springframework.bootgroupId>
    4. <artifactId>spring-boot-starter-actuatorartifactId>
    5. dependency>
    6. <dependency>
    7. <groupId>org.springframework.cloudgroupId>
    8. <artifactId>spring-cloud-starter-bus-amqpartifactId>
    9. dependency>
    10. <dependency>
    11. <groupId>com.alibabagroupId>
    12. <artifactId>fastjsonartifactId>
    13. dependency>
    14. dependencies>

    添加service方法 

    1. @Service
    2. public class RabbitService {
    3. @Autowired
    4. private RabbitTemplate rabbitTemplate;
    5. /**
    6. * 发送消息
    7. * @param exchange 交换机
    8. * @param routingKey 路由键
    9. * @param message 消息
    10. */
    11. public boolean sendMessage(String exchange, String routingKey, Object message) {
    12. rabbitTemplate.convertAndSend(exchange, routingKey, message);
    13. return true;
    14. }
    15. }

    配置mq消息转换器  默认是字符串转换器

    1. @Configuration
    2. public class MQConfig {
    3. @Bean
    4. public MessageConverter messageConverter(){
    5. return new Jackson2JsonMessageConverter();
    6. }
    7. }

    添加常量类

    1. public class MqConst {
    2. /**
    3. * 预约下单
    4. */
    5. public static final String EXCHANGE_DIRECT_ORDER = "exchange.direct.order";
    6. public static final String ROUTING_ORDER = "order";
    7. //队列
    8. public static final String QUEUE_ORDER = "queue.order";
    9. /**
    10. * 短信
    11. */
    12. public static final String EXCHANGE_DIRECT_MSM = "exchange.direct.msm";
    13. public static final String ROUTING_MSM_ITEM = "msm.item";
    14. //队列
    15. public static final String QUEUE_MSM_ITEM = "queue.msm.item";
    16. }

    3、短信模块改造

    1. service_msm引入依赖

    1. <dependency>
    2. <groupId>com.atguigugroupId>
    3. <artifactId>rabbit_utilartifactId>
    4. <version>0.0.1-SNAPSHOTversion>
    5. dependency>

    2. 添加mq配置信息

    1. #rabbitmq地址
    2. spring.rabbitmq.host=192.168.86.86
    3. spring.rabbitmq.port=5672
    4. spring.rabbitmq.username=guest
    5. spring.rabbitmq.password=guest

    3. 确认实体 

    4. service 新增短信发送方法

    阿里云短信服务 营销签名、模板申请不下来,用发送验证码模拟

    1. //发送挂号成功短信
    2. boolean send(MsmVo msmVo);
    3. //发送挂号成功短信
    4. @Override
    5. public boolean send(MsmVo msmVo) {
    6. String phone = msmVo.getPhone();
    7. String templateCode = msmVo.getTemplateCode();
    8. Map param = msmVo.getParam();
    9. //模拟发送
    10. String code = RandomUtil.getFourBitRandom();
    11. Map paramMap = new HashMap<>();
    12. paramMap.put("code",code);
    13. boolean isSend = this.send(phone, paramMap);
    14. return isSend;
    15. }

    5. 创建rabbit监听器

    receiver.SmsReceiver

    1. @Component
    2. public class SmsReceiver {
    3. @Autowired
    4. private MsmService msmService;
    5. //指定队列、交换机、路由key
    6. @RabbitListener(bindings = @QueueBinding(
    7. value = @Queue(value = MqConst.QUEUE_MSM_ITEM, durable = "true"),
    8. exchange = @Exchange(value = MqConst.EXCHANGE_DIRECT_MSM),
    9. key = {MqConst.ROUTING_MSM_ITEM}
    10. ))
    11. public void send(MsmVo msmVo, Message message, Channel channel) {
    12. msmService.send(msmVo);
    13. }
    14. }

    4、封装更新排班方法

    1. hosp 引入依赖

    1. <dependency>
    2. <groupId>com.atguigugroupId>
    3. <artifactId>rabbit_utilartifactId>
    4. <version>0.0.1-SNAPSHOTversion>
    5. dependency>

    2. 添加rabbit配置

    1. #rabbitmq地址
    2. spring.rabbitmq.host=192.168.86.86
    3. spring.rabbitmq.port=5672
    4. spring.rabbitmq.username=guest
    5. spring.rabbitmq.password=guest
    6. #redis
    7. spring.redis.host=192.168.86.86
    8. spring.redis.port=6379
    9. spring.redis.database= 0
    10. spring.redis.timeout=1800000

    启动,radis报错

    rabbit 触发了redis自动配置类,所以还需添加redis相关配置 (或启动类进行排除)

    3. 确认实体

    4. 实现服务接口

    ScheduleService 新增方法

    1. //修改排班
    2. void update(Schedule schedule);
    3. //根据医院编码、医院排班id获取排班信息
    4. Schedule getScheduleByIds(String hoscode, String scheduleId);
    5. //修改排班
    6. @Override
    7. public void update(Schedule schedule) {
    8. scheduleRepository.save(schedule);
    9. }
    10. //根据医院编码、医院排班id获取排班信息
    11. @Override
    12. public Schedule getScheduleByIds(String hoscode, String scheduleId) {
    13. Schedule schedule = scheduleRepository.getByHoscodeAndHosScheduleId(hoscode, scheduleId);
    14. return schedule;
    15. }

    5. 创建监听器

    receiver.HospitalReceiver

    1. @Component
    2. public class HospitalReceiver {
    3. @Autowired
    4. private ScheduleService scheduleService;
    5. @Autowired
    6. private RabbitService rabbitService;
    7. @RabbitListener(bindings = @QueueBinding(
    8. value = @Queue(value = MqConst.QUEUE_ORDER, durable = "true"),
    9. exchange = @Exchange(value = MqConst.EXCHANGE_DIRECT_ORDER),
    10. key = {MqConst.ROUTING_ORDER}
    11. ))
    12. public void receiver(OrderMqVo orderMqVo, Message message, Channel channel) throws IOException {
    13. //1.取出参数
    14. String hoscode = orderMqVo.getHoscode();
    15. String hosScheduleId = orderMqVo.getScheduleId();
    16. Integer reservedNumber = orderMqVo.getReservedNumber();
    17. Integer availableNumber = orderMqVo.getAvailableNumber();
    18. MsmVo msmVo = orderMqVo.getMsmVo();
    19. //2.根据参数查询排班信息
    20. Schedule schedule = scheduleService.getScheduleByIds(hoscode, hosScheduleId);
    21. //3.更新排班信息
    22. schedule.setReservedNumber(reservedNumber);
    23. schedule.setAvailableNumber(availableNumber);
    24. schedule.setUpdateTime(new Date()); //MongoDB不会自动更新时间
    25. scheduleService.update(schedule);
    26. //4.发送短信相关MQ消息
    27. if(msmVo!=null){
    28. rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_MSM, MqConst.ROUTING_MSM_ITEM, msmVo);
    29. }
    30. }
    31. }

    5、完善下单接口:短信提示、更新号源

    1. orders 模块引入依赖

    1. <dependency>
    2. <groupId>com.atguigugroupId>
    3. <artifactId>rabbit_utilartifactId>
    4. <version>0.0.1-SNAPSHOTversion>
    5. dependency>

    2. orders 模块引入配置

    1. #rabbitmq地址
    2. spring.rabbitmq.host=192.168.86.86
    3. spring.rabbitmq.port=5672
    4. spring.rabbitmq.username=guest
    5. spring.rabbitmq.password=guest
    6. #redis
    7. spring.redis.host=192.168.86.86
    8. spring.redis.port=6379
    9. spring.redis.database= 0
    10. spring.redis.timeout=1800000

    3. 补全接口

    发送MQ消息通知就诊人,更新号源信息

    1. //创建订单
    2. @Override
    3. public Long saveOrder(String scheduleId, Long patientId) {
    4. //1.根据patientId 跨模块查询就诊人信息
    5. Patient patient = patientFeignClient.getPatientOrder(patientId);
    6. if(patient==null){
    7. throw new YyghException(20001,"获取就诊人信息有误");
    8. }
    9. //2.跨模块查询医院排班信息(医院、科室、排班、预约规则) scheduleId
    10. ScheduleOrderVo scheduleOrderVo = hospitalFeignClient.getScheduleOrderVo(scheduleId);
    11. if(scheduleOrderVo==null){
    12. throw new YyghException(20001,"获取排班相关信息有误");
    13. }
    14. //2.1 创建订单前,时间合法性校验 (大于开始时间 小于结束时间)
    15. if(new DateTime(scheduleOrderVo.getStartTime()).isAfterNow() ||
    16. new DateTime(scheduleOrderVo.getEndTime()).isBeforeNow()){
    17. throw new YyghException(20001,"未到挂号时间");
    18. }
    19. //2.2 确认是否有号源
    20. if(scheduleOrderVo.getAvailableNumber()<=0){
    21. throw new YyghException(20001,"号源已挂满");
    22. }
    23. //3.整合数据,创建订单,插入数据库
    24. OrderInfo orderInfo = new OrderInfo();
    25. BeanUtils.copyProperties(scheduleOrderVo, orderInfo);
    26. String outTradeNo = System.currentTimeMillis() + ""+ new Random().nextInt(100);
    27. orderInfo.setOutTradeNo(outTradeNo);
    28. orderInfo.setUserId(patient.getUserId());
    29. orderInfo.setPatientId(patientId);
    30. orderInfo.setPatientName(patient.getName());
    31. orderInfo.setPatientPhone(patient.getPhone());
    32. orderInfo.setOrderStatus(OrderStatusEnum.UNPAID.getStatus());
    33. this.save(orderInfo);
    34. //4.调用医院系统进行挂号确认 (参考API接口文档)
    35. //4.1封装调用医院接口参数
    36. Map paramMap = new HashMap<>();
    37. paramMap.put("hoscode",orderInfo.getHoscode());
    38. paramMap.put("depcode",orderInfo.getDepcode());
    39. paramMap.put("hosScheduleId",orderInfo.getHosScheduleId());
    40. paramMap.put("reserveDate",new DateTime(orderInfo.getReserveDate()).toString("yyyy-MM-dd"));
    41. paramMap.put("reserveTime", orderInfo.getReserveTime());
    42. paramMap.put("amount",orderInfo.getAmount());
    43. paramMap.put("name", patient.getName());
    44. paramMap.put("certificatesType",patient.getCertificatesType());
    45. paramMap.put("certificatesNo", patient.getCertificatesNo());
    46. paramMap.put("sex",patient.getSex());
    47. paramMap.put("birthdate", patient.getBirthdate());
    48. paramMap.put("phone",patient.getPhone());
    49. paramMap.put("isMarry", patient.getIsMarry());
    50. paramMap.put("provinceCode",patient.getProvinceCode());
    51. paramMap.put("cityCode", patient.getCityCode());
    52. paramMap.put("districtCode",patient.getDistrictCode());
    53. paramMap.put("address",patient.getAddress());
    54. //联系人
    55. paramMap.put("contactsName",patient.getContactsName());
    56. paramMap.put("contactsCertificatesType", patient.getContactsCertificatesType());
    57. paramMap.put("contactsCertificatesNo",patient.getContactsCertificatesNo());
    58. paramMap.put("contactsPhone",patient.getContactsPhone());
    59. paramMap.put("timestamp", HttpRequestHelper.getTimestamp());
    60. //MD5加密签名校验,省略
    61. paramMap.put("sign", "");
    62. //4.2通过工具发送请求,获取响应
    63. JSONObject result = HttpRequestHelper.sendRequest(
    64. paramMap, "http://localhost:9998/order/submitOrder");
    65. //4.3判断挂号确认是否成功
    66. if(result.getInteger("code") == 200){ //ResultCodeEnum.SUCCESS 200
    67. //4.4取出返回结果,更新订单信息
    68. JSONObject jsonObject = result.getJSONObject("data");
    69. //预约记录唯一标识(医院预约记录主键)
    70. String hosRecordId = jsonObject.getString("hosRecordId");
    71. //预约序号
    72. Integer number = jsonObject.getInteger("number");;
    73. //取号时间
    74. String fetchTime = jsonObject.getString("fetchTime");;
    75. //取号地址
    76. String fetchAddress = jsonObject.getString("fetchAddress");;
    77. //更新订单
    78. orderInfo.setHosRecordId(hosRecordId);
    79. orderInfo.setNumber(number);
    80. orderInfo.setFetchTime(fetchTime);
    81. orderInfo.setFetchAddress(fetchAddress);
    82. baseMapper.updateById(orderInfo);
    83. //排班可预约数
    84. Integer reservedNumber = jsonObject.getInteger("reservedNumber");
    85. //排班剩余预约数
    86. Integer availableNumber = jsonObject.getInteger("availableNumber");
    87. //5.TODO 发送MQ消息通知就诊人,更新号源
    88. //发送mq信息更新号源和短信通知
    89. OrderMqVo orderMqVo = new OrderMqVo();
    90. orderMqVo.setHoscode(orderInfo.getHoscode());
    91. orderMqVo.setScheduleId(orderInfo.getHosScheduleId());
    92. orderMqVo.setReservedNumber(reservedNumber);
    93. orderMqVo.setAvailableNumber(availableNumber);
    94. //短信提示
    95. MsmVo msmVo = new MsmVo();
    96. msmVo.setPhone(orderInfo.getPatientPhone());
    97. String reserveDate =
    98. new DateTime(orderInfo.getReserveDate()).toString("yyyy-MM-dd")
    99. + (orderInfo.getReserveTime()==0 ? "上午": "下午");
    100. Map param = new HashMap(){{
    101. put("title", orderInfo.getHosname()+"|"+orderInfo.getDepname()+"|"+orderInfo.getTitle());
    102. put("amount", orderInfo.getAmount());
    103. put("reserveDate", reserveDate);
    104. put("name", orderInfo.getPatientName());
    105. put("quitTime", new DateTime(orderInfo.getQuitTime()).toString("yyyy-MM-dd HH:mm"));
    106. }};
    107. msmVo.setParam(param);
    108. orderMqVo.setMsmVo(msmVo);
    109. //发送消息到队列,更新号源,发送短信
    110. rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_ORDER, MqConst.ROUTING_ORDER, orderMqVo);
    111. }else {
    112. throw new YyghException(20001,"确认挂号失败");
    113. }
    114. return orderInfo.getId();
    115. }

    4. 重新提交订单测试,收到短信

  • 相关阅读:
    基于Python_Django的社会实践活动管理系统设计与实现
    Shell脚本:Linux Shell脚本学习指南(第一部分Shell基础)二
    多线程---操作系统
    总结1062
    【JavaEE】_ajax构造HTTP请求
    FFmpeg安卓平台编译
    STC不同系列单片机的软串口位时间函数差异
    同态加密:以CKKS为例的Bootstrapping操作介绍(不定期更新)
    自然语言推断-PyTorch
    第十三届蓝桥杯模拟赛第三期
  • 原文地址:https://blog.csdn.net/a111042555/article/details/126122274