尚医通-day14【创建订单】(内附源码)

宁睿  金牌会员 | 2023-6-19 21:37:46 | 来自手机 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 965|帖子 965|积分 2905

页面预览

订单详情



订单列表


第01章-创建订单

生成订单分析

  • 生成订单方法参数:就诊人id与 排班id
  • 生成订单需要获取就诊人信息(微服务远程调用service-user)
  • 获取排班信息与规则信息(微服务远程调用service-hosp)
  • 下单后,通过接口去医院预约下单(httpclient远程调用医院端的接口)
  • 下单成功更新排班信息并发送短信(向mq发送信息)
1、创建订单微服务

1.1、创建数据库

资料:资料>订单微服务>guigu_syt_order.sql
1.2、创建service-order微服务

在service模块下创建service-order模块

1.3、添加依赖

在service-order中添加依赖:
  1. <dependencies>
  2.    
  3.     <dependency>
  4.         <groupId>com.atguigu</groupId>
  5.         <artifactId>model</artifactId>
  6.         <version>1.0</version>
  7.     </dependency>
  8.    
  9.     <dependency>
  10.         <groupId>com.atguigu</groupId>
  11.         <artifactId>service-util</artifactId>
  12.         <version>1.0</version>
  13.     </dependency>
  14.    
  15.     <dependency>
  16.         <groupId>com.atguigu</groupId>
  17.         <artifactId>spring-security</artifactId>
  18.         <version>1.0</version>
  19.     </dependency>
  20.    
  21.     <dependency>
  22.         <groupId>mysql</groupId>
  23.         <artifactId>mysql-connector-java</artifactId>
  24.     </dependency>
  25.    
  26.    
  27.     <dependency>
  28.         <groupId>joda-time</groupId>
  29.         <artifactId>joda-time</artifactId>
  30.     </dependency>
  31.    
  32.     <dependency>
  33.         <groupId>org.springframework.boot</groupId>
  34.         <artifactId>spring-boot-starter-test</artifactId>
  35.         <scope>test</scope>
  36.     </dependency>
  37. </dependencies>
复制代码
1.4、使用代码生成器

找到service-util模块中的代码生成器,修改moduleName为order,并执行,然后删除entity包,相关类中引入model模块中的类
1.5、创建配置文件

在server-order模块中resources目录下创建文件
application.yml:
  1. spring:
  2.   application:
  3.     name: service-order
  4.   profiles:
  5.     active: dev,redis
复制代码
application-dev.yml:
  1. mybatis-plus:
  2.   configuration:
  3.     log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  4.   mapper-locations: classpath:com/atguigu/syt/order/mapper/xml/*.xml
  5. server:
  6.   port: 8205
  7. spring:
  8.   cloud:
  9.     nacos:
  10.       discovery:
  11.         server-addr: 127.0.0.1:8848
  12.   datasource:
  13.     driver-class-name: com.mysql.cj.jdbc.Driver
  14.     password: 123456
  15.     url: jdbc:mysql://localhost:3306/guigu_syt_order?characterEncoding=utf-8&serverTimezone=GMT%2B8&useSSL=false
  16.     username: root
  17.   jackson:
  18.     date-format: yyyy-MM-dd HH:mm:ss
  19.     time-zone: GMT+8
  20. logging:
  21.   level:
  22.     root: info
  23.   file:
  24.     path: order
  25. feign:
  26.   client:
  27.     config:
  28.       default:
  29.         connect-timeout: 2000 #连接建立的超时时长,单位是ms,默认1s
  30.         read-timeout: 2000 #处理请求的超时时间,单位是ms,默认为1s
  31.   sentinel:
  32.     enabled: true #开启Feign对Sentinel的支持
复制代码
1.6、配置网关

在server-gateway中配置网关路由
  1.         - id: service-order
  2.           predicates: Path=/*/order/**
  3.           uri: lb://service-order
复制代码
1.7、创建启动类
  1. package com.atguigu.syt.order;
  2. @SpringBootApplication
  3. @ComponentScan(basePackages = {"com.atguigu"})
  4. @EnableFeignClients("com.atguigu.syt")
  5. public class ServiceOrderApplication {
  6.     public static void main(String[] args) {
  7.         SpringApplication.run(ServiceOrderApplication.class, args);
  8.     }
  9. }
复制代码
2、获取就诊人接口

2.1、Controller

在service-user模块创建controller.inner包,创建InnerPatientController类
  1. package com.atguigu.syt.user.controller.inner;
  2. @Api(tags = "就诊人接口-供其他微服务远程调用")
  3. @RestController
  4. @RequestMapping("/inner/user/patient")
  5. public class InnerPatientController {
  6.     @Resource
  7.     private PatientService patientService;
  8.     @ApiOperation("获取就诊人")
  9.     @ApiImplicitParam(name = "id",value = "就诊人id", required = true)
  10.     @GetMapping("/get/{id}")
  11.     public Patient getPatient(@PathVariable("id") Long id) {
  12.         return patientService.getById(id);
  13.     }
  14. }
复制代码
2.2、创建service-user-client模块

在service-client下创建service-user-client
在service-client中添加依赖
  1. <dependency>
  2.     <groupId>com.atguigu</groupId>
  3.     <artifactId>model</artifactId>
  4.     <version>1.0</version>
  5. </dependency>
复制代码
2.3、创建Feign接口

在service-user-client中创建接口
  1. package com.atguigu.syt.user.client;
  2. @FeignClient(
  3.         value = "service-user",
  4.         contextId = "patientFeignClient",
  5.         fallback = PatientDegradeFeignClient.class)
  6. public interface PatientFeignClient {
  7.     /**
  8.      * 获取就诊人
  9.      * @param id
  10.      * @return
  11.      */
  12.     @GetMapping("/inner/user/patient/get/{id}")
  13.     Patient getPatient(@PathVariable Long id);
  14. }
复制代码
降级:
  1. package com.atguigu.syt.user.client.impl;
  2. @Component
  3. public class PatientDegradeFeignClient implements PatientFeignClient {
  4.     @Override
  5.     public Patient getPatient(Long id) {
  6.         return null;
  7.     }
  8. }
复制代码
3、获取排班信息接口

3.1、Controller

在service-hosp模块创建controller.inner包,创建InnerScheduleController类
  1. package com.atguigu.syt.hosp.controller.inner;
  2. @Api(tags = "医院接口-供其他微服务远程调用")
  3. @RestController
  4. @RequestMapping("/inner/hosp/hospital")
  5. public class InnerScheduleController {
  6.     @Resource
  7.     private ScheduleService scheduleService;
  8.     @ApiOperation("根据排班id获取预约下单数据")
  9.     @ApiImplicitParam(name = "scheduleId",value = "排班id", required = true)
  10.     @GetMapping("/getScheduleOrderVo/{scheduleId}")
  11.     public ScheduleOrderVo getScheduleOrderVo(@PathVariable String scheduleId) {
  12.         return scheduleService.getScheduleOrderVo(scheduleId);
  13.     }
  14. }
复制代码
3.2、Service

接口:ServiceScheduleService
  1. /**
  2. * 获取排班相关数据
  3. * @param scheduleId
  4. * @return
  5. */
  6. ScheduleOrderVo getScheduleOrderVo(String scheduleId);
复制代码
实现:ScheduleServiceImpl
  1. @Override
  2. public ScheduleOrderVo getScheduleOrderVo(String scheduleId) {
  3.     Schedule schedule = this.getDetailById(scheduleId);
  4.     String hosname = (String)schedule.getParam().get("hosname");
  5.     String depname = (String)schedule.getParam().get("depname");
  6.     ScheduleOrderVo scheduleOrderVo = new ScheduleOrderVo();
  7.     scheduleOrderVo.setHoscode(schedule.getHoscode()); //医院编号
  8.     scheduleOrderVo.setHosname(hosname); //医院名称
  9.     scheduleOrderVo.setDepcode(schedule.getDepcode()); //科室编号
  10.     scheduleOrderVo.setDepname(depname); //科室名称
  11.     scheduleOrderVo.setHosScheduleId(schedule.getHosScheduleId()); //医院端的排班主键
  12.     scheduleOrderVo.setAvailableNumber(schedule.getAvailableNumber()); //剩余预约数
  13.     scheduleOrderVo.setTitle(hosname + depname + "挂号费");
  14.     scheduleOrderVo.setReserveDate(schedule.getWorkDate()); //安排日期
  15.     scheduleOrderVo.setReserveTime(schedule.getWorkTime()); //安排时间(0:上午 1:下午)
  16.     scheduleOrderVo.setAmount(schedule.getAmount());//挂号费用
  17.     //获取预约规则相关数据
  18.     Hospital hospital = hospitalRepository.findByHoscode(schedule.getHoscode());
  19.     BookingRule bookingRule = hospital.getBookingRule();
  20.     String quitTime = bookingRule.getQuitTime();//退号时间
  21.     //退号实际时间(如:就诊前一天为-1,当天为0)
  22.     DateTime quitDay = new DateTime(schedule.getWorkDate()).plusDays(bookingRule.getQuitDay());//退号日期
  23.     DateTime quitDateTime = this.getDateTime(quitDay, quitTime);//可退号的具体的日期和时间
  24.     scheduleOrderVo.setQuitTime(quitDateTime.toDate());
  25.     return scheduleOrderVo;
  26. }
复制代码
3.3、创建service-hosp-client模块

在service-client下创建service-hosp-client
3.4、创建Feign接口

在service-hosp-client中创建接口
  1. package com.atguigu.syt.hosp.client;
  2. @FeignClient(
  3.     value = "service-hosp",
  4.     contextId = "scheduleFeignClient",
  5.     fallback = ScheduleDegradeFeignClient.class
  6. )
  7. public interface ScheduleFeignClient {
  8.     /**
  9.      * 根据排班id获取预约下单数据
  10.      * @param scheduleId
  11.      * @return
  12.      */
  13.     @GetMapping("/inner/hosp/hospital/getScheduleOrderVo/{scheduleId}")
  14.     ScheduleOrderVo getScheduleOrderVo(@PathVariable("scheduleId") String scheduleId);
  15. }
复制代码
降级:
  1. package com.atguigu.syt.hosp.client.impl;
  2. @Component
  3. public class ScheduleDegradeFeignClient implements ScheduleFeignClient {
  4.     @Override
  5.     public ScheduleOrderVo getScheduleOrderVo(String scheduleId) {
  6.         return null;
  7.     }
  8. }
复制代码
4、生成订单

4.1、service中引入依赖
  1. <dependency>
  2.     <groupId>com.atguigu</groupId>
  3.     <artifactId>service-user-client</artifactId>
  4.     <version>1.0</version>
  5. </dependency>
  6. <dependency>
  7.     <groupId>com.atguigu</groupId>
  8.     <artifactId>service-hosp-client</artifactId>
  9.     <version>1.0</version>
  10. </dependency>
复制代码
4.2、Controller

在service-order中创建controller.front包,创建FrontOrderInfoController类,定义创建订单接口
  1. package com.atguigu.syt.order.controller.front;
  2. @Api(tags = "订单接口")
  3. @RestController
  4. @RequestMapping("/front/order/orderInfo")
  5. public class FrontOrderInfoController {
  6.     @Resource
  7.     private OrderInfoService orderInfoService;
  8.     @Resource
  9.     private AuthContextHolder authContextHolder;
  10.     @ApiOperation("创建订单")
  11.     @ApiImplicitParams({
  12.             @ApiImplicitParam(name = "scheduleId",value = "排班id", required = true),
  13.             @ApiImplicitParam(name = "patientId",value = "就诊人id", required = true)})
  14.     @PostMapping("/auth/submitOrder/{scheduleId}/{patientId}")
  15.     public Result<Long> submitOrder(@PathVariable String scheduleId, @PathVariable Long patientId, HttpServletRequest request, HttpServletResponse response) {
  16.         authContextHolder.checkAuth(request, response);
  17.         Long orderId = orderInfoService.submitOrder(scheduleId, patientId);
  18.         return Result.ok(orderId);
  19.     }
  20. }
复制代码
4.3、Service

接口:OrderInfoService
  1. /**
  2.      * 根据排班id和就诊人id创建订单
  3.      * @param scheduleId
  4.      * @param patientId
  5.      * @return 新订单id
  6.      */
  7. Long submitOrder(String scheduleId, Long patientId);
复制代码
实现:OrderInfoServiceImpl
  1. @Resource
  2. private PatientFeignClient patientFeignClient;
  3. @Resource
  4. private ScheduleFeignClient scheduleFeignClient;
  5. @Override
  6. public Long submitOrder(String scheduleId, Long patientId) {
  7.     //就诊人数据:远程获取就诊人数据(openfeign)
  8.     Patient patient = patientFeignClient.getPatient(patientId);
  9.     if(patient == null) {
  10.         throw new GuiguException(ResultCodeEnum.PARAM_ERROR);
  11.     }
  12.     //获取医院排班相关数据
  13.     ScheduleOrderVo scheduleOrderVo = scheduleFeignClient.getScheduleOrderVo(scheduleId);
  14.     if(scheduleOrderVo == null) {
  15.         throw new GuiguException(ResultCodeEnum.PARAM_ERROR);
  16.     }
  17.     //SignInfoVo signInfoVo = hospitalFeignClient.getSignInfoVo(scheduleOrderVo.getHoscode());
  18.     SignInfoVo signInfoVo = new SignInfoVo();
  19.     signInfoVo.setSignKey("8af52af00baf6aec434109fc17164aae");
  20.     signInfoVo.setApiUrl("http://localhost:9998");
  21.     if(signInfoVo == null) {
  22.         throw new GuiguException(ResultCodeEnum.PARAM_ERROR);
  23.     }
  24.     if(scheduleOrderVo.getAvailableNumber() <= 0) {
  25.         throw new GuiguException(ResultCodeEnum.NUMBER_NO);
  26.     }
  27.     //创建订单对象
  28.     OrderInfo orderInfo = new OrderInfo();
  29.     //基本信息
  30.     String outTradeNo = UUID.randomUUID().toString().replace("-", "");
  31.     orderInfo.setOutTradeNo(outTradeNo); //订单号
  32.     orderInfo.setOrderStatus(OrderStatusEnum.UNPAID.getStatus());//未支付
  33.     //就诊人数据
  34.     orderInfo.setPatientId(patientId);
  35.     orderInfo.setPatientPhone(patient.getPhone());
  36.     orderInfo.setPatientName(patient.getName());
  37.     orderInfo.setUserId(patient.getUserId());
  38.     //医院排班相关数据
  39.     orderInfo.setScheduleId(scheduleId);
  40.     BeanUtils.copyProperties(scheduleOrderVo, orderInfo);//拷贝相关属性
  41.     //step4:调用医院端接口获取相关数据
  42.     Map<String, Object> paramsMap = new HashMap<>();
  43.     paramsMap.put("hoscode", scheduleOrderVo.getHoscode());
  44.     paramsMap.put("depcode", scheduleOrderVo.getDepcode());
  45.     paramsMap.put("hosScheduleId", scheduleOrderVo.getHosScheduleId());
  46.     paramsMap.put(
  47.         "reserveDate",
  48.         new DateTime(scheduleOrderVo.getReserveDate()).toString("yyyy-MM-dd")
  49.     );
  50.     paramsMap.put("reserveTime", scheduleOrderVo.getReserveTime());
  51.     paramsMap.put("amount", scheduleOrderVo.getAmount());
  52.     paramsMap.put("name", patient.getName());
  53.     paramsMap.put("certificatesType", patient.getCertificatesType());
  54.     paramsMap.put("certificatesNo", patient.getCertificatesNo());
  55.     paramsMap.put("sex", patient.getSex());
  56.     paramsMap.put("birthdate", patient.getBirthdate());
  57.     paramsMap.put("phone", patient.getPhone());
  58.     paramsMap.put("isMarry", patient.getIsMarry());
  59.     paramsMap.put("timestamp", HttpRequestHelper.getTimestamp());
  60.     paramsMap.put("sign", HttpRequestHelper.getSign(paramsMap, signInfoVo.getSignKey()));//标准签名
  61.     JSONObject jsonResult = HttpRequestHelper.sendRequest(
  62.         paramsMap, signInfoVo.getApiUrl() + "/order/submitOrder"
  63.     );
  64.     log.info("结果:" + jsonResult.toJSONString());
  65.     if(jsonResult.getInteger("code") != 200){//失败
  66.         log.error("预约失败,"
  67.                   + "code:" + jsonResult.getInteger("code")
  68.                   + ",message:" + jsonResult.getString("message")
  69.                  );
  70.         throw new GuiguException(ResultCodeEnum.FAIL.getCode(), jsonResult.getString("message"));
  71.     }
  72.     JSONObject data = jsonResult.getJSONObject("data");
  73.     String hosOrderId = data.getString("hosOrderId");
  74.     Integer number = data.getInteger("number");
  75.     String fetchTime = data.getString("fetchTime");
  76.     String fetchAddress = data.getString("fetchAddress");
  77.     orderInfo.setHosOrderId(hosOrderId);
  78.     orderInfo.setNumber(number);
  79.     orderInfo.setFetchTime(fetchTime);
  80.     orderInfo.setFetchAddress(fetchAddress);
  81.     baseMapper.insert(orderInfo);
  82.     //使用这两个数据更新平台端的最新的排班数量
  83.     Integer reservedNumber = data.getInteger("reservedNumber");
  84.     Integer availableNumber = data.getInteger("availableNumber");
  85.     //目的1:更新mongodb数据库中的排班数量
  86.     //TODO 中间件:MQ 异步解耦
  87.     //目的2:给就诊人发短信 TODO:MQ
  88.     return orderInfo.getId(); //返回订单id
  89. }
复制代码
第02章-订单详情(作业)

1、后端接口

1.1、Controller

在FrontOrderInfoController中添加方法
  1. import request from '@/utils/request'
  2. export default {
  3.   //生成订单
  4.   submitOrder(scheduleId, patientId) {
  5.     return request({
  6.       url: `/front/order/orderInfo/auth/submitOrder/${scheduleId}/${patientId}`,
  7.       method: 'post'
  8.     })
  9.   }
  10. }
复制代码
1.2、Service

接口:OrderInfoService
  1. {{orderText}}
复制代码
实现:OrderInfoServiceImpl
  1. orderBtnDisabled: false, //防止重复提交
  2. orderText: '确认挂号'
复制代码
辅助方法
  1. import orderInfoApi from '~/api/orderInfo'
复制代码
3、前端整合

3.1、api

在orderInfo.js添加方法
  1. //确认挂号
  2. submitOrder() {
  3.     if (this.orderBtnDisabled) return
  4.     this.orderBtnDisabled = true
  5.     this.orderText = '预约挂号中...'
  6.     orderInfoApi
  7.         .submitOrder(this.scheduleId, this.patient.id)
  8.         .then((response) => {
  9.         window.location.href = '/order/show?orderId=' + response.data
  10.     })
  11. },
复制代码
2、页面渲染

资料:资料>订单微服务>order
pages/order/show.vue组件
第03章-订单列表(作业)

1、后端接口

1.1、Controller

在FrontOrderInfoController中添加方法
  1. @ApiOperation("根据订单id查询订单详情")
  2. @ApiImplicitParam(name = "orderId",value = "订单id", required = true)
  3. @GetMapping("/auth/getOrder/{orderId}")
  4. public Result<OrderInfo> getOrder(@PathVariable Long orderId, HttpServletRequest request, HttpServletResponse response) {
  5.     authContextHolder.checkAuth(request, response);
  6.     OrderInfo orderInfo = orderInfoService.getOrderInfo(orderId);
  7.     return Result.ok(orderInfo);
  8. }
复制代码
1.2、Service

接口:OrderInfoService
  1. /**
  2.      * 根据订单id获取订单详情
  3.      * @param orderId
  4.      * @return
  5.      */
  6. OrderInfo getOrderInfo(Long orderId);
复制代码
实现:OrderInfoServiceImpl
  1. @Override
  2. public OrderInfo getOrderInfo(Long orderId) {
  3.     OrderInfo orderInfo = baseMapper.selectById(orderId);
  4.     return this.packOrderInfo(orderInfo);
  5. }
复制代码
2、前端整合

2.1、api

在orderInfo.js添加方法
  1. /**
  2.      * 封装订单数据
  3.      * @param orderInfo
  4.      * @return
  5.      */
  6. private OrderInfo packOrderInfo(OrderInfo orderInfo) {
  7.     orderInfo.getParam().put(
  8.         "orderStatusString",
  9.         OrderStatusEnum.getStatusNameByStatus(orderInfo.getOrderStatus())
  10.     );
  11.     return orderInfo;
  12. }
复制代码
2.2、页面渲

资料:资料>订单微服务>order
pages/order/index.vue组件
源码:https://gitee.com/dengyaojava/guigu-syt-parent

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

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

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

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

本版积分规则

宁睿

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表