尚医通-day14【创建订单】(内附源码)
页面预览
订单详情
订单列表
第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中添加依赖:
<dependencies>
<!--实体-->
<dependency>
<groupId>com.atguigu</groupId>
<artifactId>model</artifactId>
<version>1.0</version>
</dependency>
<!--服务通用配置-->
<dependency>
<groupId>com.atguigu</groupId>
<artifactId>service-util</artifactId>
<version>1.0</version>
</dependency>
<!--自定义安全模块-->
<dependency>
<groupId>com.atguigu</groupId>
<artifactId>spring-security</artifactId>
<version>1.0</version>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--时间日期工具-->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
<!-- 单元测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
1.4、使用代码生成器
找到service-util模块中的代码生成器,修改moduleName为order
,并执行,然后删除entity包,相关类中引入model模块中的类
1.5、创建配置文件
在server-order模块中resources目录下创建文件
application.yml
:
spring:
application:
name: service-order
profiles:
active: dev,redis
application-dev.yml
:
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mapper-locations: classpath:com/atguigu/syt/order/mapper/xml/*.xml
server:
port: 8205
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
password: 123456
url: jdbc:mysql://localhost:3306/guigu_syt_order?characterEncoding=utf-8&serverTimezone=GMT%2B8&useSSL=false
username: root
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
logging:
level:
root: info
file:
path: order
feign:
client:
config:
default:
connect-timeout: 2000 #连接建立的超时时长,单位是ms,默认1s
read-timeout: 2000 #处理请求的超时时间,单位是ms,默认为1s
sentinel:
enabled: true #开启Feign对Sentinel的支持
1.6、配置网关
在server-gateway中配置网关路由
- id: service-order
predicates: Path=/*/order/**
uri: lb://service-order
1.7、创建启动类
package com.atguigu.syt.order;
@SpringBootApplication
@ComponentScan(basePackages = {"com.atguigu"})
@EnableFeignClients("com.atguigu.syt")
public class ServiceOrderApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceOrderApplication.class, args);
}
}
2、获取就诊人接口
2.1、Controller
在service-user模块创建controller.inner包,创建InnerPatientController类
package com.atguigu.syt.user.controller.inner;
@Api(tags = "就诊人接口-供其他微服务远程调用")
@RestController
@RequestMapping("/inner/user/patient")
public class InnerPatientController {
@Resource
private PatientService patientService;
@ApiOperation("获取就诊人")
@ApiImplicitParam(name = "id",value = "就诊人id", required = true)
@GetMapping("/get/{id}")
public Patient getPatient(@PathVariable("id") Long id) {
return patientService.getById(id);
}
}
2.2、创建service-user-client模块
在service-client下创建service-user-client
在service-client
中添加依赖
<dependency>
<groupId>com.atguigu</groupId>
<artifactId>model</artifactId>
<version>1.0</version>
</dependency>
2.3、创建Feign接口
在service-user-client中创建接口
package com.atguigu.syt.user.client;
@FeignClient(
value = "service-user",
contextId = "patientFeignClient",
fallback = PatientDegradeFeignClient.class)
public interface PatientFeignClient {
/**
* 获取就诊人
* @param id
* @return
*/
@GetMapping("/inner/user/patient/get/{id}")
Patient getPatient(@PathVariable Long id);
}
降级:
package com.atguigu.syt.user.client.impl;
@Component
public class PatientDegradeFeignClient implements PatientFeignClient {
@Override
public Patient getPatient(Long id) {
return null;
}
}
3、获取排班信息接口
3.1、Controller
在service-hosp模块创建controller.inner包,创建InnerScheduleController类
package com.atguigu.syt.hosp.controller.inner;
@Api(tags = "医院接口-供其他微服务远程调用")
@RestController
@RequestMapping("/inner/hosp/hospital")
public class InnerScheduleController {
@Resource
private ScheduleService scheduleService;
@ApiOperation("根据排班id获取预约下单数据")
@ApiImplicitParam(name = "scheduleId",value = "排班id", required = true)
@GetMapping("/getScheduleOrderVo/{scheduleId}")
public ScheduleOrderVo getScheduleOrderVo(@PathVariable String scheduleId) {
return scheduleService.getScheduleOrderVo(scheduleId);
}
}
3.2、Service
接口:ServiceScheduleService
/**
* 获取排班相关数据
* @param scheduleId
* @return
*/
ScheduleOrderVo getScheduleOrderVo(String scheduleId);
实现:ScheduleServiceImpl
@Override
public ScheduleOrderVo getScheduleOrderVo(String scheduleId) {
Schedule schedule = this.getDetailById(scheduleId);
String hosname = (String)schedule.getParam().get("hosname");
String depname = (String)schedule.getParam().get("depname");
ScheduleOrderVo scheduleOrderVo = new ScheduleOrderVo();
scheduleOrderVo.setHoscode(schedule.getHoscode()); //医院编号
scheduleOrderVo.setHosname(hosname); //医院名称
scheduleOrderVo.setDepcode(schedule.getDepcode()); //科室编号
scheduleOrderVo.setDepname(depname); //科室名称
scheduleOrderVo.setHosScheduleId(schedule.getHosScheduleId()); //医院端的排班主键
scheduleOrderVo.setAvailableNumber(schedule.getAvailableNumber()); //剩余预约数
scheduleOrderVo.setTitle(hosname + depname + "挂号费");
scheduleOrderVo.setReserveDate(schedule.getWorkDate()); //安排日期
scheduleOrderVo.setReserveTime(schedule.getWorkTime()); //安排时间(0:上午 1:下午)
scheduleOrderVo.setAmount(schedule.getAmount());//挂号费用
//获取预约规则相关数据
Hospital hospital = hospitalRepository.findByHoscode(schedule.getHoscode());
BookingRule bookingRule = hospital.getBookingRule();
String quitTime = bookingRule.getQuitTime();//退号时间
//退号实际时间(如:就诊前一天为-1,当天为0)
DateTime quitDay = new DateTime(schedule.getWorkDate()).plusDays(bookingRule.getQuitDay());//退号日期
DateTime quitDateTime = this.getDateTime(quitDay, quitTime);//可退号的具体的日期和时间
scheduleOrderVo.setQuitTime(quitDateTime.toDate());
return scheduleOrderVo;
}
3.3、创建service-hosp-client模块
在service-client下创建service-hosp-client
3.4、创建Feign接口
在service-hosp-client中创建接口
package com.atguigu.syt.hosp.client;
@FeignClient(
value = "service-hosp",
contextId = "scheduleFeignClient",
fallback = ScheduleDegradeFeignClient.class
)
public interface ScheduleFeignClient {
/**
* 根据排班id获取预约下单数据
* @param scheduleId
* @return
*/
@GetMapping("/inner/hosp/hospital/getScheduleOrderVo/{scheduleId}")
ScheduleOrderVo getScheduleOrderVo(@PathVariable("scheduleId") String scheduleId);
}
降级:
package com.atguigu.syt.hosp.client.impl;
@Component
public class ScheduleDegradeFeignClient implements ScheduleFeignClient {
@Override
public ScheduleOrderVo getScheduleOrderVo(String scheduleId) {
return null;
}
}
4、生成订单
4.1、service中引入依赖
<dependency>
<groupId>com.atguigu</groupId>
<artifactId>service-user-client</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.atguigu</groupId>
<artifactId>service-hosp-client</artifactId>
<version>1.0</version>
</dependency>
4.2、Controller
在service-order中创建controller.front包,创建FrontOrderInfoController类,定义创建订单接口
package com.atguigu.syt.order.controller.front;
@Api(tags = "订单接口")
@RestController
@RequestMapping("/front/order/orderInfo")
public class FrontOrderInfoController {
@Resource
private OrderInfoService orderInfoService;
@Resource
private AuthContextHolder authContextHolder;
@ApiOperation("创建订单")
@ApiImplicitParams({
@ApiImplicitParam(name = "scheduleId",value = "排班id", required = true),
@ApiImplicitParam(name = "patientId",value = "就诊人id", required = true)})
@PostMapping("/auth/submitOrder/{scheduleId}/{patientId}")
public Result<Long> submitOrder(@PathVariable String scheduleId, @PathVariable Long patientId, HttpServletRequest request, HttpServletResponse response) {
authContextHolder.checkAuth(request, response);
Long orderId = orderInfoService.submitOrder(scheduleId, patientId);
return Result.ok(orderId);
}
}
4.3、Service
接口:OrderInfoService
/**
* 根据排班id和就诊人id创建订单
* @param scheduleId
* @param patientId
* @return 新订单id
*/
Long submitOrder(String scheduleId, Long patientId);
实现:OrderInfoServiceImpl
@Resource
private PatientFeignClient patientFeignClient;
@Resource
private ScheduleFeignClient scheduleFeignClient;
@Override
public Long submitOrder(String scheduleId, Long patientId) {
//就诊人数据:远程获取就诊人数据(openfeign)
Patient patient = patientFeignClient.getPatient(patientId);
if(patient == null) {
throw new GuiguException(ResultCodeEnum.PARAM_ERROR);
}
//获取医院排班相关数据
ScheduleOrderVo scheduleOrderVo = scheduleFeignClient.getScheduleOrderVo(scheduleId);
if(scheduleOrderVo == null) {
throw new GuiguException(ResultCodeEnum.PARAM_ERROR);
}
//SignInfoVo signInfoVo = hospitalFeignClient.getSignInfoVo(scheduleOrderVo.getHoscode());
SignInfoVo signInfoVo = new SignInfoVo();
signInfoVo.setSignKey("8af52af00baf6aec434109fc17164aae");
signInfoVo.setApiUrl("http://localhost:9998");
if(signInfoVo == null) {
throw new GuiguException(ResultCodeEnum.PARAM_ERROR);
}
if(scheduleOrderVo.getAvailableNumber() <= 0) {
throw new GuiguException(ResultCodeEnum.NUMBER_NO);
}
//创建订单对象
OrderInfo orderInfo = new OrderInfo();
//基本信息
String outTradeNo = UUID.randomUUID().toString().replace("-", "");
orderInfo.setOutTradeNo(outTradeNo); //订单号
orderInfo.setOrderStatus(OrderStatusEnum.UNPAID.getStatus());//未支付
//就诊人数据
orderInfo.setPatientId(patientId);
orderInfo.setPatientPhone(patient.getPhone());
orderInfo.setPatientName(patient.getName());
orderInfo.setUserId(patient.getUserId());
//医院排班相关数据
orderInfo.setScheduleId(scheduleId);
BeanUtils.copyProperties(scheduleOrderVo, orderInfo);//拷贝相关属性
//step4:调用医院端接口获取相关数据
Map<String, Object> paramsMap = new HashMap<>();
paramsMap.put("hoscode", scheduleOrderVo.getHoscode());
paramsMap.put("depcode", scheduleOrderVo.getDepcode());
paramsMap.put("hosScheduleId", scheduleOrderVo.getHosScheduleId());
paramsMap.put(
"reserveDate",
new DateTime(scheduleOrderVo.getReserveDate()).toString("yyyy-MM-dd")
);
paramsMap.put("reserveTime", scheduleOrderVo.getReserveTime());
paramsMap.put("amount", scheduleOrderVo.getAmount());
paramsMap.put("name", patient.getName());
paramsMap.put("certificatesType", patient.getCertificatesType());
paramsMap.put("certificatesNo", patient.getCertificatesNo());
paramsMap.put("sex", patient.getSex());
paramsMap.put("birthdate", patient.getBirthdate());
paramsMap.put("phone", patient.getPhone());
paramsMap.put("isMarry", patient.getIsMarry());
paramsMap.put("timestamp", HttpRequestHelper.getTimestamp());
paramsMap.put("sign", HttpRequestHelper.getSign(paramsMap, signInfoVo.getSignKey()));//标准签名
JSONObject jsonResult = HttpRequestHelper.sendRequest(
paramsMap, signInfoVo.getApiUrl() + "/order/submitOrder"
);
log.info("结果:" + jsonResult.toJSONString());
if(jsonResult.getInteger("code") != 200){//失败
log.error("预约失败,"
+ "code:" + jsonResult.getInteger("code")
+ ",message:" + jsonResult.getString("message")
);
throw new GuiguException(ResultCodeEnum.FAIL.getCode(), jsonResult.getString("message"));
}
JSONObject data = jsonResult.getJSONObject("data");
String hosOrderId = data.getString("hosOrderId");
Integer number = data.getInteger("number");
String fetchTime = data.getString("fetchTime");
String fetchAddress = data.getString("fetchAddress");
orderInfo.setHosOrderId(hosOrderId);
orderInfo.setNumber(number);
orderInfo.setFetchTime(fetchTime);
orderInfo.setFetchAddress(fetchAddress);
baseMapper.insert(orderInfo);
//使用这两个数据更新平台端的最新的排班数量
Integer reservedNumber = data.getInteger("reservedNumber");
Integer availableNumber = data.getInteger("availableNumber");
//目的1:更新mongodb数据库中的排班数量
//TODO 中间件:MQ 异步解耦
//目的2:给就诊人发短信 TODO:MQ
return orderInfo.getId(); //返回订单id
}
5、前端整合
5.1、api
创建api/orderInfo.js
import request from '@/utils/request'
export default {
//生成订单
submitOrder(scheduleId, patientId) {
return request({
url: `/front/order/orderInfo/auth/submitOrder/${scheduleId}/${patientId}`,
method: 'post'
})
}
}
5.2、组件
在booking.vue组件中完善下单方法
<div class="v-button" @click="submitOrder()">{{orderText}}</div>
定义data
orderBtnDisabled: false, //防止重复提交
orderText: '确认挂号'
引入api
import orderInfoApi from '~/api/orderInfo'
完善方法
//确认挂号
submitOrder() {
if (this.orderBtnDisabled) return
this.orderBtnDisabled = true
this.orderText = '预约挂号中...'
orderInfoApi
.submitOrder(this.scheduleId, this.patient.id)
.then((response) => {
window.location.href = '/order/show?orderId=' + response.data
})
},
第02章-订单详情(作业)
1、后端接口
1.1、Controller
在FrontOrderInfoController中添加方法
@ApiOperation("根据订单id查询订单详情")
@ApiImplicitParam(name = "orderId",value = "订单id", required = true)
@GetMapping("/auth/getOrder/{orderId}")
public Result<OrderInfo> getOrder(@PathVariable Long orderId, HttpServletRequest request, HttpServletResponse response) {
authContextHolder.checkAuth(request, response);
OrderInfo orderInfo = orderInfoService.getOrderInfo(orderId);
return Result.ok(orderInfo);
}
1.2、Service
接口:OrderInfoService
/**
* 根据订单id获取订单详情
* @param orderId
* @return
*/
OrderInfo getOrderInfo(Long orderId);
实现:OrderInfoServiceImpl
@Override
public OrderInfo getOrderInfo(Long orderId) {
OrderInfo orderInfo = baseMapper.selectById(orderId);
return this.packOrderInfo(orderInfo);
}
辅助方法
/**
* 封装订单数据
* @param orderInfo
* @return
*/
private OrderInfo packOrderInfo(OrderInfo orderInfo) {
orderInfo.getParam().put(
"orderStatusString",
OrderStatusEnum.getStatusNameByStatus(orderInfo.getOrderStatus())
);
return orderInfo;
}
3、前端整合
3.1、api
在orderInfo.js添加方法
//订单详情
getOrder(orderId) {
return request({
url: `/front/order/orderInfo/auth/getOrder/${orderId}`,
method: `get`
})
},
2、页面渲染
资料:资料>订单微服务>order
pages/order/show.vue组件
第03章-订单列表(作业)
1、后端接口
1.1、Controller
在FrontOrderInfoController中添加方法
@ApiOperation("订单列表")
@GetMapping("/auth/list")
public Result<List<OrderInfo>> list(HttpServletRequest request, HttpServletResponse response) {
Long userId = authContextHolder.checkAuth(request, response);
List<OrderInfo> orderInfolist = orderInfoService.selectList(userId);
return Result.ok(orderInfolist);
}
1.2、Service
接口:OrderInfoService
/**
* 获取当前用户订单列表
* @param userId
* @return
*/
List<OrderInfo> selectList(Long userId);
实现:OrderInfoServiceImpl
@Override
public List<OrderInfo> selectList(Long userId) {
LambdaQueryWrapper<OrderInfo> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(OrderInfo::getUserId, userId);
List<OrderInfo> orderInfoList = baseMapper.selectList(queryWrapper);
orderInfoList.stream().forEach(this::packOrderInfo);
return orderInfoList;
}
2、前端整合
2.1、api
在orderInfo.js添加方法
//订单列表
getList() {
return request({
url: `/front/order/orderInfo/auth/list`,
method: `get`
})
},
2.2、页面渲
资料:资料>订单微服务>order
pages/order/index.vue组件
源码:https://gitee.com/dengyaojava/guigu-syt-parent
尚医通-day14【创建订单】(内附源码)的更多相关文章
- 基于电商直播SDK快速实现一个淘宝直播APP【内附源码】
现在各大互联网APP都标配电商直播带货了,没有直播带货开发经验都感觉自己跟不上技术的进步.今天快速基于Java实现一个安卓端电商直播APP,深入理解整个电商直播开发流程.我们最终实现效果如下: 按照惯 ...
- 从零实现在线云相亲APP|程序员脱单神器(内附源码Demo)
实时音视频通话涉及到的技术栈.人力成本.硬件成本非常大,一般个人开发者基本无法独立完成一个功能健全并且稳定的实时音视频应用.本文介绍一天之内,无任何实时音视频低层技术的android开发者完成实时相亲 ...
- 干货:Java多线程详解(内附源码)
线程是程序执行的最小单元,多线程是指程序同一时间可以有多个执行单元运行(这个与你的CPU核心有关). 在java中开启一个新线程非常简单,创建一个Thread对象,然后调用它的start方法,一个 ...
- 如何0代码实现多人音视频通话?【内附源码/Demo】
3月15日新增"1860+1194",全国进入了抗疫关键时期.响应政策多地采取了社会面清零策略. 3月14日零点,深圳按下了暂停键. 应疫情防控要求,深圳全市暂停生产经营活动,严格 ...
- jquery省市区三级联动(数据来源国家统计局官网)内附源码下载
很久很久没有写博了. 今天更新了项目的省市区三级联动数据,更新后最新的海南三沙都有,分享给所有需要的小伙伴们... JQUERY + JSON,无数据库,纯JS代码,无加密,无压缩,可直接使用在任何项 ...
- Liferay 7:Liferay DXP全套教程内附源码
分享是美德 都是英文教程,有不明白的问题可以随时咨询我. http://www.javasavvy.com/liferay-7-hooks-tutorials/
- java小项目之:抽奖系统!java初学者必备(内附源码)
[Java]Java摇奖源码,Java抽奖源码,Java随机抽奖源码 任务描述 本次任务要求为某商场开发一套幸运抽奖系统,客户必须首先注册成为该商场会员,会员登录成功后,就可以参加抽奖活动了.注册 用 ...
- Matlab.NET混合编程技巧之——直接调用Matlab内置函数(附源码)
原文:[原创]Matlab.NET混合编程技巧之--直接调用Matlab内置函数(附源码) 在我的上一篇文章[原创]Matlab.NET混编技巧之——找出Matlab内置函数中,已经大概的介绍了mat ...
- SpringCloud-服务注册与实现-Eureka创建服务提供者(附源码下载)
场景 SpringCloud-服务注册与实现-Eureka创建服务注册中心(附源码下载): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/deta ...
- Django集成Markdown编辑器【附源码】
专注内容写作的你一定不要错过markdown 简单介绍 markdown是一种标记语言,通过简单的标记语法可以使普通的文本内容具有一定的格式,使用非常简单,学习成本极低 目前各大Blog平台都已支持m ...
随机推荐
- GitLab 安装部署使用
GitLab介绍 GitLab:是一个基于Git实现的在线代码仓库托管软件,你可以用gitlab自己搭建一个类似于Github一样的系统,一般用于在企业.学校等内部网络搭建git私服. 功能:Gitl ...
- 人工智能 deepface 换脸技术 学习
介绍 Deepface是一个轻量级的python人脸识别和人脸属性分析(年龄.性别.情感和种族)框架.它是一种混合人脸识别框架缠绕状态的最先进的模型:VGG-Face,Google FaceNet,O ...
- day93:flask:Cookie&Session&请求钩子&捕获错误&上下文&Flask-Script
目录 1.HTTP的会话控制 2.Cookie 3.Session 4.请求钩子 5.捕获错误 6.上下文:context 7.Flask-Script 1.HTTP的会话控制 1.什么是会话控制? ...
- DG:三种模式切换
应用归档日志方式进行数据同步 SQL> alter system set log_archive_dest_2='SERVICE=standby arch noaffirm valid_for= ...
- C#版本LINQ增强开源库
LINQ对应的中文名称是:语言集成查询,是对一系列直接将查询功能集成到C#语言技术的统称,我们最常用的场景是,用于数据库的查询功能. 在.Net中,本身对Objects也支持LINQ的扩展,但是对于一 ...
- 版本依赖控制工具Maven
Maven 简介 依赖管理工具 如果说A工程里面用到了B工程的类.接口.配置文件等这样的资源,那么就说A依赖B 构建管理工具 构建:使用原材料生产产品的过程 安装:把一个Maven工程经过打包操作生产 ...
- 【Ubuntu】 Perf工具的使用
一.perf工具的安装 sudo apt-get install linux-tools-common sudo apt-get install linux-tools-"$(uname - ...
- Simulation-计算统计-随机数生成
library('ggplot2') library('dplyr') Lecture 6 Methods for generating random numbers Goal: Use U(0, 1 ...
- GPT护理机器人 - 让护士的工作变简单
引子 书接上文<GPT接入企微应用 - 让工作快乐起来>,我把GPT接入了企微应用,不少同事都开始尝试起来了.有的浅尝辄止,有的刨根问底,五花八门,无所不有.这里摘抄几份: "帮 ...
- selenium IDE插件的配置使用
开头 Selenium提供了一个可以自动录制脚本的插件 叫selenium IDE 让我们一起看看如何安装使用 安装 因为google扩展商城大多数人用不了,所以我们选用的是edag来下载seleni ...