尚医通-订单业务

尚医通-订单业务

该模块需要企业用户开通商家付款码,并设置相关证书位置

位置:

service模块\service_order子模块\api包\OrderApiController.java

订单表结构:

下单参数:就诊人id与排班id

1、下单我们要获取就诊人信息

2、获取排班下单信息与规则信息

3、获取医院签名信息,然后通过接口去医院预约下单

4、下单成功更新排班信息与发送短信

01 生成挂号订单

前端请求:
1
@PostMapping("auth/submitOrder/{scheduleId}/{patientId}")
后端处理:
1
2
3
4
5
public Result savaOrders(@PathVariable String scheduleId,
@PathVariable Long patientId) {
Long orderId = orderService.saveOrder(scheduleId,patientId);
return Result.ok(orderId);
}

saveOrder方法具体实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
public Long saveOrder(String scheduleId, Long patientId) {
//获取就诊人信息
Patient patient = patientFeignClient.getPatientOrder(patientId);

//获取排班相关信息
ScheduleOrderVo scheduleOrderVo = hospitalFeignClient.getScheduleOrderVo(scheduleId);

//判断当前时间是否还可以预约
if(new DateTime(scheduleOrderVo.getStartTime()).isAfterNow()
|| new DateTime(scheduleOrderVo.getEndTime()).isBeforeNow()) {
throw new YyghException(ResultCodeEnum.TIME_NO);
}

//获取签名信息
SignInfoVo signInfoVo = hospitalFeignClient.getSignInfoVo(scheduleOrderVo.getHoscode());

//添加到订单表
OrderInfo orderInfo = new OrderInfo();
//scheduleOrderVo 数据复制到 orderInfo
BeanUtils.copyProperties(scheduleOrderVo,orderInfo);
//向orderInfo设置其他数据
String outTradeNo = System.currentTimeMillis() + ""+ new Random().nextInt(100);
orderInfo.setOutTradeNo(outTradeNo);
orderInfo.setScheduleId(scheduleId);
orderInfo.setUserId(patient.getUserId());
orderInfo.setPatientId(patientId);
orderInfo.setPatientName(patient.getName());
orderInfo.setPatientPhone(patient.getPhone());
orderInfo.setOrderStatus(OrderStatusEnum.UNPAID.getStatus());
baseMapper.insert(orderInfo);

//调用医院接口,实现预约挂号操作
//设置调用医院接口需要参数,参数放到map集合
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("hoscode",orderInfo.getHoscode());
paramMap.put("depcode",orderInfo.getDepcode());
paramMap.put("hosScheduleId",orderInfo.getScheduleId());
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());

String sign = HttpRequestHelper.getSign(paramMap, signInfoVo.getSignKey());
paramMap.put("sign", sign);

//请求医院系统接口
JSONObject result = HttpRequestHelper.sendRequest(paramMap, signInfoVo.getApiUrl() + "/order/submitOrder");

if(result.getInteger("code")==200) {
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");
//发送mq消息,号源更新和短信通知
//发送mq信息更新号源
OrderMqVo orderMqVo = new OrderMqVo();
orderMqVo.setScheduleId(scheduleId);
orderMqVo.setReservedNumber(reservedNumber);
orderMqVo.setAvailableNumber(availableNumber);
//短信提示
MsmVo msmVo = new MsmVo();
msmVo.setPhone(orderInfo.getPatientPhone());
String reserveDate = new DateTime(orderInfo.getReserveDate()).toString("yyyy-MM-dd") + (orderInfo.getReserveTime()==0 ? "上午" : "下午");
Map<String,Object> param = new HashMap<String,Object>(){{
put("title", orderInfo.getHosname()+"|"+orderInfo.getDepname()+"|"+orderInfo.getTitle());
put("amount", orderInfo.getAmount());
put("reserveDate", reserveDate);
put("name", orderInfo.getPatientName());
put("quitTime", new DateTime(orderInfo.getQuitTime()).toString("yyyy-MM-dd HH:mm"));
}};
msmVo.setParam(param);
orderMqVo.setMsmVo(msmVo);

rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_ORDER, MqConst.ROUTING_ORDER, orderMqVo);
} else {
throw new YyghException(result.getString("message"), ResultCodeEnum.FAIL.getCode());
}
return orderInfo.getId();
}

02 根据订单id查询订单详情

前端请求:
1
@GetMapping("auth/getOrders/{orderId}")
后端处理:
1
2
3
4
public Result getOrders(@PathVariable String orderId) {
OrderInfo orderInfo = orderService.getOrder(orderId);
return Result.ok(orderInfo);
}

getOrder方法具体实现

1
2
3
4
public OrderInfo getOrder(String orderId) {
OrderInfo orderInfo = baseMapper.selectById(orderId);
return this.packOrderInfo(orderInfo);
}

03 订单列表(条件查询带分页)

前端请求:
1
@GetMapping("auth/{page}/{limit}")
后端处理:
1
2
3
4
5
6
7
8
9
10
public Result list(@PathVariable Long page,
@PathVariable Long limit,
OrderQueryVo orderQueryVo, HttpServletRequest request) {
//设置当前用户id
orderQueryVo.setUserId(AuthContextHolder.getUserId(request));
Page<OrderInfo> pageParam = new Page<>(page,limit);
IPage<OrderInfo> pageModel =
orderService.selectPage(pageParam,orderQueryVo);
return Result.ok(pageModel);
}

selectPage方法具体实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public IPage<OrderInfo> selectPage(Page<OrderInfo> pageParam, OrderQueryVo orderQueryVo) {
//orderQueryVo获取条件值
String name = orderQueryVo.getKeyword(); //医院名称
Long patientId = orderQueryVo.getPatientId(); //就诊人名称
String orderStatus = orderQueryVo.getOrderStatus(); //订单状态
String reserveDate = orderQueryVo.getReserveDate();//安排时间
String createTimeBegin = orderQueryVo.getCreateTimeBegin();
String createTimeEnd = orderQueryVo.getCreateTimeEnd();

//对条件值进行非空判断
QueryWrapper<OrderInfo> wrapper = new QueryWrapper<>();
if(!StringUtils.isEmpty(name)) {
wrapper.like("hosname",name);
}
if(!StringUtils.isEmpty(patientId)) {
wrapper.eq("patient_id",patientId);
}
if(!StringUtils.isEmpty(orderStatus)) {
wrapper.eq("order_status",orderStatus);
}
if(!StringUtils.isEmpty(reserveDate)) {
wrapper.ge("reserve_date",reserveDate);
}
if(!StringUtils.isEmpty(createTimeBegin)) {
wrapper.ge("create_time",createTimeBegin);
}
if(!StringUtils.isEmpty(createTimeEnd)) {
wrapper.le("create_time",createTimeEnd);
}
//调用mapper的方法
IPage<OrderInfo> pages = baseMapper.selectPage(pageParam, wrapper);
//编号变成对应值封装
pages.getRecords().stream().forEach(item -> {
this.packOrderInfo(item);
});
return pages;
}

04 获取订单状态

前端请求:
1
@GetMapping("auth/getStatusList")
后端处理:
1
2
3
public Result getStatusList() {
return Result.ok(OrderStatusEnum.getStatusList());
}

05 取消预约

前端请求:
1
@GetMapping("auth/cancelOrder/{orderId}")
后端处理:
1
2
3
4
public Result cancelOrder(@PathVariable Long orderId) {
Boolean isOrder = orderService.cancelOrder(orderId);
return Result.ok(isOrder);
}

cancelOrder方法具体实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
public Boolean cancelOrder(Long orderId) {
//获取订单信息
OrderInfo orderInfo = baseMapper.selectById(orderId);
//判断是否取消
DateTime quitTime = new DateTime(orderInfo.getQuitTime());
if(quitTime.isBeforeNow()) {
throw new YyghException(ResultCodeEnum.CANCEL_ORDER_NO);
}
//调用医院接口实现预约取消
SignInfoVo signInfoVo = hospitalFeignClient.getSignInfoVo(orderInfo.getHoscode());
if(null == signInfoVo) {
throw new YyghException(ResultCodeEnum.PARAM_ERROR);
}
Map<String, Object> reqMap = new HashMap<>();
reqMap.put("hoscode",orderInfo.getHoscode());
reqMap.put("hosRecordId",orderInfo.getHosRecordId());
reqMap.put("timestamp", HttpRequestHelper.getTimestamp());
String sign = HttpRequestHelper.getSign(reqMap, signInfoVo.getSignKey());
reqMap.put("sign", sign);

JSONObject result = HttpRequestHelper.sendRequest(reqMap,
signInfoVo.getApiUrl()+"/order/updateCancelStatus");
//根据医院接口返回数据
if(result.getInteger("code")!=200) {
throw new YyghException(result.getString("message"), ResultCodeEnum.FAIL.getCode());
} else {
//判断当前订单是否可以取消
if(orderInfo.getOrderStatus().intValue() == OrderStatusEnum.PAID.getStatus().intValue()) {
Boolean isRefund = weixinService.refund(orderId);
if(!isRefund) {
throw new YyghException(ResultCodeEnum.CANCEL_ORDER_FAIL);
}
//更新订单状态
orderInfo.setOrderStatus(OrderStatusEnum.CANCLE.getStatus());
baseMapper.updateById(orderInfo);

//发送mq更新预约数量
OrderMqVo orderMqVo = new OrderMqVo();
orderMqVo.setScheduleId(orderInfo.getScheduleId());
//短信提示
MsmVo msmVo = new MsmVo();
msmVo.setPhone(orderInfo.getPatientPhone());
String reserveDate = new DateTime(orderInfo.getReserveDate()).toString("yyyy-MM-dd") + (orderInfo.getReserveTime()==0 ? "上午": "下午");
Map<String,Object> param = new HashMap<String,Object>(){{
put("title", orderInfo.getHosname()+"|"+orderInfo.getDepname()+"|"+orderInfo.getTitle());
put("reserveDate", reserveDate);
put("name", orderInfo.getPatientName());
}};
msmVo.setParam(param);
orderMqVo.setMsmVo(msmVo);
rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_ORDER, MqConst.ROUTING_ORDER, orderMqVo);
}
}
return true;
}

07 获取订单统计数据

前端请求:
1
@PostMapping("inner/getCountMap")
后端处理:
1
2
3
public Map<String, Object> getCountMap(@RequestBody OrderCountQueryVo orderCountQueryVo) {
return orderService.getCountMap(orderCountQueryVo);
}

getCountMap方法具体实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public Map<String, Object> getCountMap(OrderCountQueryVo orderCountQueryVo) {
//调用mapper方法得到数据
List<OrderCountVo> orderCountVoList = baseMapper.selectOrderCount(orderCountQueryVo);

//获取x需要数据 ,日期数据 list集合
List<String> dateList = orderCountVoList.stream().map(OrderCountVo::getReserveDate).collect(Collectors.toList());

//获取y需要数据,具体数量 list集合
List<Integer> countList =orderCountVoList.stream().map(OrderCountVo::getCount).collect(Collectors.toList());

Map<String,Object> map = new HashMap<>();
map.put("dateList",dateList);
map.put("countList",countList);
return map;
}

微信处理

service模块\service_order子模块\api包\WeixinController.java

01 生成微信支付二维码

前端请求:
1
@GetMapping("createNative/{orderId}")
后端处理:
1
2
3
4
public Result createNative(@PathVariable Long orderId) {
Map map = weixinService.createNative(orderId);
return Result.ok(map);
}

createNative方法具体实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
public Map createNative(Long orderId) {
try {
//从redis获取数据
Map payMap = (Map)redisTemplate.opsForValue().get(orderId.toString());
if(payMap != null) {
return payMap;
}
//1 根据orderId获取订单信息
OrderInfo order = orderService.getById(orderId);
//2 向支付记录表添加信息
paymentService.savePaymentInfo(order, PaymentTypeEnum.WEIXIN.getStatus());
//3设置参数,
//把参数转换xml格式,使用商户key进行加密
Map paramMap = new HashMap();
paramMap.put("appid", ConstantPropertiesUtils.APPID);
paramMap.put("mch_id", ConstantPropertiesUtils.PARTNER);
paramMap.put("nonce_str", WXPayUtil.generateNonceStr());
String body = order.getReserveDate() + "就诊"+ order.getDepname();
paramMap.put("body", body);
paramMap.put("out_trade_no", order.getOutTradeNo());
paramMap.put("total_fee", "1"); //为了测试,统一写成这个值
paramMap.put("spbill_create_ip", "127.0.0.1");
paramMap.put("notify_url", "http://guli.shop/api/order/weixinPay/weixinNotify");
paramMap.put("trade_type", "NATIVE");
//4 调用微信生成二维码接口,httpclient调用
HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder");
//设置map参数
client.setXmlParam(WXPayUtil.generateSignedXml(paramMap,ConstantPropertiesUtils.PARTNERKEY));
client.setHttps(true);
client.post();
//5 返回相关数据
String xml = client.getContent();
//转换map集合
Map<String, String> resultMap = WXPayUtil.xmlToMap(xml);
System.out.println("resultMap:"+resultMap);
//6 封装返回结果集
Map map = new HashMap<>();
map.put("orderId", orderId);
map.put("totalFee", order.getAmount());
map.put("resultCode", resultMap.get("result_code"));
map.put("codeUrl", resultMap.get("code_url")); //二维码地址

if(resultMap.get("result_code") != null) {
redisTemplate.opsForValue().set(orderId.toString(),map,120, TimeUnit.MINUTES);
}
return map;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}

02 查询支付状态

前端请求:
1
@GetMapping("queryPayStatus/{orderId}")
后端处理:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public Result queryPayStatus(@PathVariable Long orderId) {
//调用微信接口实现支付状态查询
Map<String,String> resultMap = weixinService.queryPayStatus(orderId);
//判断
if(resultMap == null) {
return Result.fail().message("支付出错");
}
if("SUCCESS".equals(resultMap.get("trade_state"))) { //支付成功
//更新订单状态
String out_trade_no = resultMap.get("out_trade_no");//订单编码
paymentService.paySuccess(out_trade_no,resultMap);
return Result.ok().message("支付成功");
}
return Result.ok().message("支付中");
}

queryPayStatus方法具体实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public Map<String, String> queryPayStatus(Long orderId) {
try {
//1 根据orderId获取订单信息
OrderInfo orderInfo = orderService.getById(orderId);

//2 封装提交参数
Map paramMap = new HashMap();
paramMap.put("appid", ConstantPropertiesUtils.APPID);
paramMap.put("mch_id", ConstantPropertiesUtils.PARTNER);
paramMap.put("out_trade_no", orderInfo.getOutTradeNo());
paramMap.put("nonce_str", WXPayUtil.generateNonceStr());

//3 设置请求内容
HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/orderquery");
client.setXmlParam(WXPayUtil.generateSignedXml(paramMap,ConstantPropertiesUtils.PARTNERKEY));
client.setHttps(true);
client.post();

//4 得到微信接口返回数据
String xml = client.getContent();
Map<String, String> resultMap = WXPayUtil.xmlToMap(xml);
System.out.println("支付状态resultMap:"+resultMap);
//5 把接口数据返回
return resultMap;
}catch(Exception e) {
return null;
}
}

尚医通-订单业务
https://yztldxdz.top/2022/10/22/尚医通-订单业务/
发布于
2022年10月22日
许可协议