尚医通 (二十二)预约下单
目录
- 一、预约下单功能(一)
- 1、需求
- 2、搭建订单模块
- 3、封装Feign调用获取就诊人接口
- 4、封装Feign调用获取排班下单信息接口
- 二、预约下单功能(二)
- 1、实现生成订单接口
- 三、预约下单功能(三)
- 四、预约下单功能(四)
- 1、生成订单后处理逻辑-封装短信接口
- 2、生成订单后处理逻辑-更新排班数量
- 3、生成订单后处理逻辑-完善订单接口
- 五、订单列表功能
- 1、订单列表接口
- 2、订单列表前端
- 六、订单详情功能
一、预约下单功能(一)
1、需求
(1)订单表结构
(2)生成订单分析
生成订单需要的参数:就诊人id与 排班id
第一、生成订单需要获取就诊人信息
第二、获取排班下单信息与规则信息
第三、下单后,然后通过接口去医院预约下单
第四、下单成功更新排班信息与发送短信
2、搭建订单模块
(1)搭建service_order模块
(2)引入依赖
<dependencies><dependency><groupId>com.donglin</groupId><artifactId>service_cmn_client</artifactId><version>0.0.1-SNAPSHOT</version></dependency>
</dependencies>
(3)添加配置文件
# 服务端口
server.port=8207
# 服务名
spring.application.name=service-orders
# 环境设置:dev、test、prod
spring.profiles.active=dev# mysql数据库连接
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://192.168.121.140:3306/yygh_order?characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456#返回json的全局时间格式
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8spring.data.mongodb.uri=mongodb://192.168.121.140: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=guestspring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.database= 0
spring.redis.timeout=1800000spring.redis.lettuce.pool.max-active=20
spring.redis.lettuce.pool.max-wait=-1
#最大阻塞等待时间(负数表示没限制)
spring.redis.lettuce.pool.max-idle=5
spring.redis.lettuce.pool.min-idle=0
(4)创建启动类
@SpringBootApplication
@MapperScan("com.donglin.yygh.order.mapper")
@ComponentScan(basePackages = {"com.donglin"})
@EnableDiscoveryClient
@EnableFeignClients(basePackages = {"com.donglin"})
public class ServiceOrderApplication {public static void main(String[] args) {SpringApplication.run(ServiceOrderApplication.class, args);}
}
(5)配置网关
properties
#设置路由id
spring.cloud.gateway.routes[7].id=service-orders
#设置路由的uri
spring.cloud.gateway.routes[7].uri=lb://service-orders
#设置路由断言,代理servicerId为auth-service的/auth/路径
spring.cloud.gateway.routes[7].predicates= Path=/*/order/**
yml
- id: service-ordersuri: lb://service-orderspredicates:- Path=/*/order/** # 路径匹配
(6)创建订单的Mapper、Service和Controller
//创建mapper
public interface OrderInfoMapper extends BaseMapper<OrderInfo> {}//创建service
public interface OrderInfoService extends IService<OrderInfo> {//保存订单Long submitOrder(String scheduleId, Long patientId);
}//创建service实现类
@Service
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService {@Overridepublic Long submitOrder(String scheduleId, Long patientId) {return null;}
}@Api(tags = "订单接口")
@RestController
@RequestMapping("/api/order/orderInfo")
public class OrderInfoController {@Autowiredprivate OrderInfoService orderInfoService;@ApiOperation(value = "创建订单")@PostMapping("/{scheduleId}/{patientId}")public R submitOrder(@ApiParam(name = "scheduleId", value = "排班id", required = true)@PathVariable String scheduleId,@ApiParam(name = "patientId", value = "就诊人id", required = true)@PathVariable Long patientId) {Long orderId = orderInfoService.submitOrder(scheduleId, patientId);return R.ok().data("orderId",orderId);}}
3、封装Feign调用获取就诊人接口
(1)在PatientController类添加方法
操作模块service_user
@ApiOperation(value = "获取就诊人")@GetMapping("{id}")public Patient getPatientOrder(@ApiParam(name = "id", value = "就诊人id", required = true)@PathVariable("id") Long id) {return patientService.getById(id);}
(2)搭建service_user_client模块
(3)添加Feign接口类
@FeignClient(value = "service-user")
@Repository
public interface PatientFeignClient {//获取就诊人@GetMapping("/user/userinfo/patient/{id}")public Patient getPatientOrder(@PathVariable("id") Long id);
}
4、封装Feign调用获取排班下单信息接口
(1)在ScheduleService添加接口和实现
操作模块service_hosp
//根据排班id获取预约下单数据实现@Overridepublic ScheduleOrderVo getScheduleOrderVo(String scheduleId) {ScheduleOrderVo scheduleOrderVo = new ScheduleOrderVo();//排班信息Schedule schedule = scheduleRepository.findById(scheduleId).get();if(null == schedule) {throw new YyghException();}//获取预约规则信息Hospital hospital = hospitalService.getByHoscode(schedule.getHoscode());if(null == hospital) {throw new YyghException();}BookingRule bookingRule = hospital.getBookingRule();if(null == bookingRule) {throw new YyghException();}scheduleOrderVo.setHoscode(schedule.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());//退号截止天数(如:就诊前一天为-1,当天为0)int quitDay = bookingRule.getQuitDay();DateTime quitTime = this.getDateTime(new DateTime(schedule.getWorkDate()).plusDays(quitDay).toDate(), bookingRule.getQuitTime());scheduleOrderVo.setQuitTime(quitTime.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(schedule.getWorkDate(), bookingRule.getStopTime());scheduleOrderVo.setStopTime(stopTime.toDate());return scheduleOrderVo;}
(3)搭建service_hosp_client
(4)添加Feign接口类
注意调用的时候两方都加上@PathVariable,以免之后报错
@FeignClient(value = "service-hosp")
@Repository
public interface HospitalFeignClient {@GetMapping("/user/hosp/schedule/{scheduleId}")public ScheduleOrderVo getScheduleOrderVo(@PathVariable("scheduleId") String scheduleId);
}
二、预约下单功能(二)
1、实现生成订单接口
(1)service_order引入依赖
<dependencies><dependency><groupId>com.donglin</groupId><artifactId>service_cmn_client</artifactId><version>0.0.1-SNAPSHOT</version></dependency><dependency><groupId>com.donglin</groupId><artifactId>service_hosp_client</artifactId><version>0.0.1-SNAPSHOT</version></dependency><dependency><groupId>com.donglin</groupId><artifactId>service_user_client</artifactId><version>0.0.1-SNAPSHOT</version></dependency>
</dependencies>
(2)封装工具类
(3)实现生成订单
@Service
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService {@Autowiredprivate HospitalFeignClient hospitalFeignClient;@Autowiredprivate PatientFeignClient patientFeignClient;@Autowiredprivate RabbitService rabbitService;//生成订单@Overridepublic Long submitOrder(String scheduleId, Long patientId) {//1 根据scheduleId获取排班数据ScheduleOrderVo scheduleOrderVo = hospitalFeignClient.getScheduleOrderVo(scheduleId);//2 根据patientId获取就诊人信息Patient patient = patientFeignClient.getPatientOrder(patientId);//3 平台里面 ==> 调用医院订单确认接口,// 3.1 如果医院返回失败,挂号失败//使用map集合封装需要传过医院数据Map<String, Object> paramMap = new HashMap<>();paramMap.put("hoscode",scheduleOrderVo.getHoscode());paramMap.put("depcode",scheduleOrderVo.getDepcode());paramMap.put("hosScheduleId",scheduleOrderVo.getHosScheduleId());paramMap.put("reserveDate",new DateTime(scheduleOrderVo.getReserveDate()).toString("yyyy-MM-dd"));paramMap.put("reserveTime", scheduleOrderVo.getReserveTime());paramMap.put("amount",scheduleOrderVo.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", "");//使用httpclient发送请求,请求医院接口JSONObject result =HttpRequestHelper.sendRequest(paramMap, "http://localhost:9998/order/submitOrder");//根据医院接口返回状态码判断 200 成功if(result.getInteger("code") == 200) { //挂号成功// 3.2 如果返回成功,得到返回其他数据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");;//4 如果医院接口返回成功,添加上面三部分数据到数据库OrderInfo orderInfo = new OrderInfo();//设置添加数据--排班数据BeanUtils.copyProperties(scheduleOrderVo, orderInfo);//设置添加数据--就诊人数据//订单号String outTradeNo = System.currentTimeMillis() + ""+ new Random().nextInt(100);orderInfo.setOutTradeNo(outTradeNo);orderInfo.setScheduleId(scheduleOrderVo.getHosScheduleId());orderInfo.setUserId(patient.getUserId());orderInfo.setPatientId(patientId);orderInfo.setPatientName(patient.getName());orderInfo.setPatientPhone(patient.getPhone());orderInfo.setOrderStatus(OrderStatusEnum.UNPAID.getStatus());//设置添加数据--医院接口返回数据orderInfo.setHosRecordId(hosRecordId);orderInfo.setNumber(number);orderInfo.setFetchTime(fetchTime);orderInfo.setFetchAddress(fetchAddress);//调用方法添加baseMapper.insert(orderInfo);//TODO 5 根据医院返回数据,更新排班数量//排班可预约数Integer reservedNumber = jsonObject.getInteger("reservedNumber");//排班剩余预约数Integer availableNumber = jsonObject.getInteger("availableNumber");//TODO 6 给就诊人发送短信//7.返回订单的idreturn orderInfo.getId();} else {throw new YyghException(20001, "号源已满");}}}
三、预约下单功能(三)
1、生成订单前端整合
(1)封装api方法
创建api/order.js
import request from '@/utils/request'const api_name = `/api/order/orderInfo`export default {submitOrder(scheduleId, patientId) {return request({url: `${api_name}/${scheduleId}/${patientId}`,method: 'post'})}
}
(2)在booking.vue组件完善下单方法
import orderInfoApi from '@/api/order'submitOrder() {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.orderIdwindow.location.href = '/order/show?orderId=' + orderId}).catch(e => {this.submitBnt = '确认挂号'})
},
2、生成订单后处理逻辑-更新订单信息
预约成功后我们要 更新订单信息,更新预约数 和 短信提醒预约成功,为了提高下单的并发性,这部分逻辑我们就交给mq为我们完成,预约成功发送消息即可
(1)修改OrderServiceImpl方法
//生成预约挂号订单
@Override
public Long submitOrder(String scheduleId, Long patientId) {...............//TODO 5 根据医院返回数据,更新排班数量//排班可预约数Integer reservedNumber = jsonObject.getInteger("reservedNumber");//排班剩余预约数Integer availableNumber = jsonObject.getInteger("availableNumber");//发送mq信息更新号源和短信通知OrderMqVo orderMqVo = new OrderMqVo();orderMqVo.setScheduleId(scheduleId);orderMqVo.setReservedNumber(reservedNumber);orderMqVo.setAvailableNumber(availableNumber);//TODO 6 给就诊人发送短信//短信提示SmsVo msmVo = new SmsVo();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.setSmsVo(msmVo);rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_ORDER, MqConst.ROUTING_ORDER, orderMqVo);//返回订单号return orderInfo.getId();
3、生成订单后处理逻辑-rabbit-util模块封装
(1)rabbitMQ简介
以商品订单场景为例,
如果商品服务和订单服务是两个不同的微服务,在下单的过程中订单服务需要调用商品服务进行扣库存操作。按照传统的方式,下单过程要等到调用完毕之后才能返回下单成功,如果网络产生波动等原因使得商品服务扣库存延迟或者失败,会带来较差的用户体验,如果在高并发的场景下,这样的处理显然是不合适的,那怎么进行优化呢?这就需要消息队列登场了。
消息队列提供一个异步通信机制,消息的发送者不必一直等待到消息被成功处理才返回,而是立即返回。消息中间件负责处理网络通信,如果网络连接不可用,消息被暂存于队列当中,当网络畅通的时候在将消息转发给相应的应用程序或者服务,当然前提是这些服务订阅了该队列。如果在商品服务和订单服务之间使用消息中间件,既可以提高并发量,又降低服务之间的耦合度。
RabbitMQ就是这样一款消息队列。RabbitMQ是一个开源的消息代理的队列服务器,用来通过普通协议在完全不同的应用之间共享数据。
典型应用场景:
异步处理。把消息放入消息中间件中,等到需要的时候再去处理。
流量削峰。例如秒杀活动,在短时间内访问量急剧增加,使用消息队列,当消息队列满了就拒绝响应,跳转到错误页面,这样就可以使得系统不会因为超负载而崩溃
(2)安装rabbitMQ
#拉取镜像
docker pull rabbitmq:3.8-management#创建容器启动
docker run -d --restart=always -p 5672:5672 -p 15672:15672 --name rabbitmq rabbitmq:3.8-management
(3)服务rabbitMQ后台
管理后台:http://IP:15672
(4)在common搭建rabbit_util模块
(4)在rabbit_util引入依赖
<dependencies><!--rabbitmq消息队列--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bus-amqp</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId></dependency>
</dependencies>
(5)添加service方法
@Component
public class RabbitService {@Autowiredprivate RabbitTemplate rabbitTemplate;//rabbirmq: String.getBytes()//{// key:value1,// }public boolean sendMessage(String exchange,String routingkey,Object message){rabbitTemplate.convertAndSend(exchange,routingkey,message);return true;}
}
(6)配置mq消息转换器
@SpringBootConfiguration
public class RabbitConfig {//作用:就是将发送到RabbitMQ中的pojo对象自动就行转换为json格式存储// 从rabbitmq中消费消息时,自动把json格式的字符串转换为pojo对象@Beanpublic MessageConverter getMessageConverter(){return new Jackson2JsonMessageConverter();}
}
说明:默认是字符串转换器
(7)添加常量类
public class MqConst {/*** 预约下单*/public static final String EXCHANGE_DIRECT_ORDER = "exchange.direct.order";public static final String ROUTING_ORDER = "order";//队列public static final String QUEUE_ORDER = "queue.order";/*** 短信*/public static final String EXCHANGE_DIRECT_SMS = "exchange.direct.msm";public static final String ROUTING_SMS_ITEM = "msm.item";//队列public static final String QUEUE_MSM_SMS = "queue.msm.item";
}
四、预约下单功能(四)
1、生成订单后处理逻辑-封装短信接口
操作service_sms模块
(1)service_sms引入依赖
<dependency><groupId>com.donglin</groupId><artifactId>rabbit_util</artifactId><version>0.0.1-SNAPSHOT</version>
</dependency>
(2)service_sms添加配置
#rabbitmq地址
spring.rabbitmq.host=192.168.121.140
spring.rabbitmq.port=5672
spring.rabbitmq.virtual-host=/
spring.rabbitmq.username=admin
spring.rabbitmq.password=admin
(3)在model模块封装短信实体
@Data
@ApiModel(description = "短信实体")
public class SmsVo {@ApiModelProperty(value = "phone")private String phone;@ApiModelProperty(value = "短信模板code")private String templateCode;@ApiModelProperty(value = "短信模板参数")private Map<String,Object> param;
}
(4)service_sms封装service接口和实现
//发送短信接口boolean sendMessage(SmsVo smsVo);//发送短信实现@Overridepublic boolean sendMessage(SmsVo smsVo) {if (!StringUtils.isEmpty(smsVo.getPhone())) {//给就诊人短信提醒System.out.println("给就诊人短信提醒");//仅为了测试return this.sendCode(smsVo.getPhone());}return false;}
(5)封装mq监听器
@Component
public class SmsListener {@Autowiredprivate SmsService smsService;@RabbitListener(bindings = {@QueueBinding(value = @Queue(name = MqConst.QUEUE_MSM_SMS),exchange = @Exchange(name = MqConst.EXCHANGE_DIRECT_SMS),key = MqConst.ROUTING_SMS_ITEM)})public void consume(SmsVo msmVo, Message message, Channel channel){smsService.sendMessage(msmVo);}
}
2、生成订单后处理逻辑-更新排班数量
操作模块:service_hosp
(1)service_hosp引入依赖
<!--rabbitmq消息队列-->
<dependency><groupId>com.donglin</groupId><artifactId>rabbit_util</artifactId><version>0.0.1-SNAPSHOT</version>
</dependency>
(2)添加配置
rabbitmq地址
spring.rabbitmq.host=192.168.121.140
spring.rabbitmq.port=5672
spring.rabbitmq.virtual-host=/
spring.rabbitmq.username=admin
spring.rabbitmq.password=admin
(3)在model模块封装更新排班实体
@Data
@ApiModel(description = "OrderMqVo")
public class OrderMqVo {@ApiModelProperty(value = "可预约数")private Integer reservedNumber;@ApiModelProperty(value = "剩余预约数")private Integer availableNumber;@ApiModelProperty(value = "排班id")private String scheduleId;@ApiModelProperty(value = "短信实体")private SmsVo smsVo;}
(4)封装更新排班方法
操作ScheduleService
boolean updateAvailableNumber(String scheduleId, Integer availableNumber);@Overridepublic boolean updateAvailableNumber(String scheduleId, Integer availableNumber) {Schedule schedule = scheduleRepository.findById(scheduleId).get();schedule.setAvailableNumber(availableNumber);schedule.setUpdateTime(new Date());scheduleRepository.save(schedule);return true;}
(5)封装mq监听器
@Component
public class OrderMqListener {@Autowiredprivate ScheduleService scheduleService;@Autowiredprivate RabbitService rabbitService;@RabbitListener(bindings = {@QueueBinding(value =@Queue(name = MqConst.QUEUE_ORDER,durable = "true"),//创建队列exchange = @Exchange(name = MqConst.EXCHANGE_DIRECT_ORDER), //创建交换机key=MqConst.ROUTING_ORDER)})public void consume(OrderMqVo orderMqVo, Message message, Channel channel){String scheduleId = orderMqVo.getScheduleId();Integer availableNumber = orderMqVo.getAvailableNumber();boolean flag= scheduleService.updateAvailableNumber(scheduleId,availableNumber);SmsVo msmVo = orderMqVo.getSmsVo();if(flag && msmVo != null){rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_SMS,MqConst.ROUTING_SMS_ITEM,msmVo);}}
}
3、生成订单后处理逻辑-完善订单接口
操作service_order
(1)引入依赖
<dependency><groupId>com.donglin</groupId><artifactId>rabbit_util</artifactId><version>0.0.1-SNAPSHOT</version>
</dependency>
(2)添加配置
#rabbitmq地址
spring.rabbitmq.host=192.168.121.140
spring.rabbitmq.port=5672
spring.rabbitmq.virtual-host=/
spring.rabbitmq.username=admin
spring.rabbitmq.password=admin
(3)修改OrderServiceImpl类下单方法
@Autowired
private RabbitService rabbitService;//生成预约挂号订单
@Override
public Long submitOrder(String scheduleId, Long patientId) {.....................................//TODO 5 根据医院返回数据,更新排班数量//排班可预约数Integer reservedNumber = jsonObject.getInteger("reservedNumber");//排班剩余预约数Integer availableNumber = jsonObject.getInteger("availableNumber");//TODO 6 给就诊人发送短信//发送mq信息更新号源和短信通知OrderMqVo orderMqVo = new OrderMqVo();orderMqVo.setScheduleId(scheduleId);orderMqVo.setReservedNumber(reservedNumber);orderMqVo.setAvailableNumber(availableNumber);//短信提示SmsVo smsVo = new SmsVo();smsVo.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"));}};smsVo.setParam(param);orderMqVo.setSmsVo(smsVo);rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_ORDER, MqConst.ROUTING_ORDER, orderMqVo);//7 返回订单号return orderInfo.getId();} else { //挂号失败throw new YyghException(20001, "挂号失败");}
五、订单列表功能
1、订单列表接口
(1)创建service接口和实现
OrderInfoService接口和实现类
/*** 分页列表*/Page<OrderInfo> getOrderInfoPage(Integer pageNum, Integer pageSize, OrderQueryVo orderQueryVo);//实现列表//(条件查询带分页)@Overridepublic Page<OrderInfo> getOrderInfoPage(Integer pageNum, Integer pageSize, OrderQueryVo orderQueryVo) {Page page=new Page(pageNum,pageSize);QueryWrapper<OrderInfo> queryWrapper=new QueryWrapper<OrderInfo>();Long userId = orderQueryVo.getUserId(); //用户idString outTradeNo = orderQueryVo.getOutTradeNo();//订单号String keyword = orderQueryVo.getKeyword();//医院名称Long patientId = orderQueryVo.getPatientId(); //就诊人idString orderStatus = orderQueryVo.getOrderStatus();//订单状态String reserveDate = orderQueryVo.getReserveDate(); //预约日期String createTimeBegin = orderQueryVo.getCreateTimeBegin();//下订单时间String createTimeEnd = orderQueryVo.getCreateTimeEnd();//下订单时间if(!StringUtils.isEmpty(userId)){queryWrapper.eq("user_id", userId);}if(!StringUtils.isEmpty(outTradeNo)){queryWrapper.eq("out_trade_no", outTradeNo);}if(!StringUtils.isEmpty(keyword)){queryWrapper.like("hosname", keyword);}if(!StringUtils.isEmpty(patientId)){queryWrapper.eq("patient_id", patientId);}if(!StringUtils.isEmpty(orderStatus)){queryWrapper.eq("order_status", orderStatus);}if(!StringUtils.isEmpty(reserveDate)){queryWrapper.ge("reserve_date", reserveDate);}if(!StringUtils.isEmpty(createTimeBegin)){queryWrapper.ge("create_time", createTimeBegin);}if(!StringUtils.isEmpty(createTimeEnd)){queryWrapper.le("create_time", createTimeEnd);}Page<OrderInfo> page1 = baseMapper.selectPage(page, queryWrapper);page1.getRecords().parallelStream().forEach(item->{this.packageOrderInfo(item);});return page1;}private void packageOrderInfo(OrderInfo item) {item.getParam().put("orderStatusString",OrderStatusEnum.getStatusNameByStatus(item.getOrderStatus()));}
(2)创建controller
在OrderInfoController类添加方法
@GetMapping("/list")public R getOrderList(){List<Map<String, Object>> statusList = OrderStatusEnum.getStatusList();return R.ok().data("list",statusList);}@GetMapping("/{pageNum}/{pageSize}")public R getOrderInfoPage(@PathVariable Integer pageNum,@PathVariable Integer pageSize,OrderQueryVo orderQueryVo,@RequestHeader String token){Long userId = JwtHelper.getUserId(token);orderQueryVo.setUserId(userId);Page<OrderInfo> page= orderInfoService.getOrderInfoPage(pageNum,pageSize,orderQueryVo);return R.ok().data("page",page);}
2、订单列表前端
(1)封装api请求
在api/order.js定义方法
//订单列表getPageList(pageNum, pageSize, searchObj) {return request({url: `${api_name}/${pageNum}/${pageSize}`,method: `get`,params: searchObj})
},
//订单状态getStatusList() {return request({url: `${api_name}/list`,method: 'get'})},
(2)页面显示
创建/pages/order/index.vue组件
<template><!-- header --><div class="nav-container page-component"><!--左侧导航 #start --><div class="nav left-nav"><div class="nav-item "><span class="v-link clickable dark" onclick="javascript:window.location='/user'">实名认证 </span></div><div class="nav-item selected"><span class="v-link selected dark" onclick="javascript:window.location='/order'"> 挂号订单 </span></div><div class="nav-item "><span class="v-link clickable dark" onclick="javascript:window.location='/patient'"> 就诊人管理 </span></div><div class="nav-item "><span class="v-link clickable dark"> 修改账号信息 </span></div><div class="nav-item "><span class="v-link clickable dark"> 意见反馈 </span></div></div><!-- 左侧导航 #end --><!-- 右侧内容 #start --><div class="page-container"><div class="personal-order"><div class="title"> 挂号订单</div><el-form :inline="true"><el-form-item label="就诊人:"><el-select v-model="searchObj.patientId" placeholder="请选择就诊人" class="v-select patient-select"><el-optionv-for="item in patientList":key="item.id":label="item.name + '【' + item.certificatesNo + '】'":value="item.id"></el-option></el-select></el-form-item><el-form-item label="订单状态:" style="margin-left: 80px"><el-select v-model="searchObj.orderStatus" placeholder="全部" class="v-select patient-select" style="width: 200px;"><el-optionv-for="item in statusList":key="item.status":label="item.comment":value="item.status"></el-option></el-select></el-form-item><el-form-item><el-button type="text" class="search-button v-link highlight clickable selected" @click="fetchData()">查询</el-button></el-form-item></el-form><div class="table-wrapper table"><el-table:data="list"stripestyle="width: 100%"><el-table-columnlabel="就诊时间"width="120"><template slot-scope="scope">{{ scope.row.reserveDate }} {{ scope.row.reserveTime === 0 ? '上午' : '下午' }}</template></el-table-column><el-table-columnprop="hosname"label="医院"width="100"></el-table-column><el-table-columnprop="depname"label="科室"></el-table-column><el-table-columnprop="title"label="医生"></el-table-column><el-table-columnprop="amount"label="医事服务费"></el-table-column><el-table-columnprop="patientName"label="就诊人"></el-table-column><el-table-columnprop="param.orderStatusString"label="订单状态"></el-table-column><el-table-column label="操作"><template slot-scope="scope"><el-button type="text" class="v-link highlight clickable selected" @click="show(scope.row.id)">详情</el-button></template></el-table-column></el-table></div><!-- 分页 --><el-paginationclass="pagination"layout="prev, pager, next":current-page="page":total="total":page-size="limit"@current-change="fetchData"></el-pagination></div></div><!-- 右侧内容 #end --></div><!-- footer --></template><script>import '~/assets/css/hospital_personal.css'import '~/assets/css/hospital.css'import orderInfoApi from '@/api/order'import patientApi from '@/api/patient'export default {data() {return {list: [], // banner列表total: 0, // 数据库中的总记录数page: 1, // 默认页码limit: 10, // 每页记录数searchObj: {}, // 查询表单对象patientList: [],statusList: []}},created() {this.orderId = this.$route.query.orderIdthis.fetchData()this.findPatientList()this.getStatusList()},methods: {fetchData(page = 1) {this.page = pageorderInfoApi.getPageList(this.page, this.limit, this.searchObj).then(response => {console.log(response.data);this.list = response.data.page.recordsthis.total = response.data.page.total})},findPatientList() {patientApi.findList().then(response => {this.patientList = response.data.listconsole.log(this.patientList);})},getStatusList() {orderInfoApi.getStatusList().then(response => {this.statusList = response.data.listconsole.log(this.statusList);})},changeSize(size) {console.log(size)this.limit = sizethis.fetchData(1)},show(id) {window.location.href = '/order/show?orderId=' + id}}}</script>
六、订单详情功能
1、订单详情接口
(1)OrderInfoService添加方法
/*** 获取订单详情*/OrderInfo detail(Long orderId);//实现方法@Overridepublic OrderInfo detail(Long orderId) {OrderInfo orderInfo = baseMapper.selectById(orderId);this.packageOrderInfo(orderInfo);return orderInfo;}
(2)OrderApiCont添加方法
在OrderInfoController类添加方法
//根据订单id查询订单详情@GetMapping("/{orderId}")public R detail(@PathVariable Long orderId){OrderInfo orderInfo = orderInfoService.detail(orderId);return R.ok().data("orderInfo",orderInfo);}
2、订单详情前端
(1)封装api方法
在order.js添加方法定义
//订单详情
getOrders(orderId) {return request({url: `${api_name}/${orderId}`,method: `get`})
},
(2)添加页面
创建/pages/order/show.vue组件
<template><!-- header --><div class="nav-container page-component"><!--左侧导航 #start --><div class="nav left-nav"><div class="nav-item "><span class="v-link clickable dark" onclick="javascript:window.location='/user'">实名认证 </span></div><div class="nav-item selected"><span class="v-link selected dark" onclick="javascript:window.location='/order'"> 挂号订单 </span></div><div class="nav-item "><span class="v-link clickable dark" onclick="javascript:window.location='/patient'"> 就诊人管理 </span></div><div class="nav-item "><span class="v-link clickable dark"> 修改账号信息 </span></div><div class="nav-item "><span class="v-link clickable dark"> 意见反馈 </span></div></div><!-- 左侧导航 #end --><!-- 右侧内容 #start --><div class="page-container"><div class="order-detail"><div class="title"> 挂号详情</div><div class="status-bar"><div class="left-wrapper"><div class="status-wrapper BOOKING_SUCCESS"><span class="iconfont"></span> {{ orderInfo.param.orderStatusString }}</div></div><div class="right-wrapper"><img src="//img.114yygh.com/static/web/code_order_detail.png" class="code-img"><div class="content-wrapper"><div> 微信<span class="iconfont"></span>关注“北京114预约挂号”</div><div class="watch-wrapper"> 快速挂号,轻松就医</div></div></div></div><div class="info-wrapper"><div class="title-wrapper"><div class="block"></div><div>挂号信息</div></div><div class="info-form"><el-form ref="form" :model="form"><el-form-item label="就诊人信息:"><div class="content"><span>{{ orderInfo.patientName }}</span></div></el-form-item><el-form-item label="就诊日期:"><div class="content"><span>{{ orderInfo.reserveDate }} {{ orderInfo.reserveTime == 0 ? '上午' : '下午' }}</span></div></el-form-item><el-form-item label="就诊医院:"><div class="content"><span>{{ orderInfo.hosname }} </span></div></el-form-item><el-form-item label="就诊科室:"><div class="content"><span>{{ orderInfo.depname }} </span></div></el-form-item><el-form-item label="医生职称:"><div class="content"><span>{{ orderInfo.title }} </span></div></el-form-item><el-form-item label="医事服务费:"><div class="content"><div class="fee">{{ orderInfo.amount }}元</div></div></el-form-item><el-form-item label="挂号单号:"><div class="content"><span>{{ orderInfo.outTradeNo }} </span></div></el-form-item><el-form-item label="挂号时间:"><div class="content"><span>{{ orderInfo.createTime }}</span></div></el-form-item></el-form></div></div><div class="rule-wrapper mt40"><div class="rule-title"> 注意事项</div><div>1、请确认就诊人信息是否准确,若填写错误将无法取号就诊,损失由本人承担;<br><span style="color:red">2、【取号】就诊当天需在{{ orderInfo.fetchTime }}在医院取号,未取号视为爽约,该号不退不换;</span><br>3、【退号】在{{ orderInfo.quitTime }}前可在线退号 ,逾期将不可办理退号退费;<br>4、北京114预约挂号支持自费患者使用身份证预约,同时支持北京市医保患者使用北京社保卡在平台预约挂号。请于就诊当日,携带预约挂号所使用的有效身份证件到院取号;<br>5、请注意北京市医保患者在住院期间不能使用社保卡在门诊取号。</div></div><div class="bottom-wrapper mt60" v-if="orderInfo.orderStatus == 0 || orderInfo.orderStatus == 1"><div class="button-wrapper"><div class="v-button white" @click="cancelOrder()">取消预约</div></div><div class="button-wrapper ml20" v-if="orderInfo.orderStatus == 0"><div class="v-button" @click="pay()">支付</div></div></div></div></div><!-- 右侧内容 #end --><!-- 微信支付弹出框 --><el-dialog :visible.sync="dialogPayVisible" style="text-align: left" :append-to-body="true" width="500px" @close="closeDialog"><div class="container"><div class="operate-view" style="height: 350px;"><div class="wrapper wechat"><div><img src="data:images/weixin.jpg" alt=""><div style="text-align: center;line-height: 25px;margin-bottom: 40px;">请使用微信扫一扫<br/>扫描二维码支付</div></div></div></div></div></el-dialog></div><!-- footer --></template><script>import '~/assets/css/hospital_personal.css'import '~/assets/css/hospital.css'import orderInfoApi from '@/api/order'export default {data() {return {orderId: null,orderInfo: {param: {}},dialogPayVisible: false,payObj: {},timer: null // 定时器名称}},created() {this.orderId = this.$route.query.orderIdthis.init()},methods: {init() {orderInfoApi.getOrders(this.orderId).then(response => {console.log(response.data);this.orderInfo = response.data.orderInfo})}}}</script><style>.info-wrapper {padding-left: 0;padding-top: 0;}.content-wrapper {color: #333;font-size: 14px;padding-bottom: 0;}.bottom-wrapper {width: 100%;}.button-wrapper {margin: 0;}.el-form-item {margin-bottom: 5px;}.bottom-wrapper .button-wrapper {margin-top: 0;}</style>
尚医通 (二十二)预约下单相关推荐
- 尚医通 (三十五) --------- 预约下单
目录 一.预约下单前端 1. 封装 api 请求 2. 页面修改 二.后端逻辑 1. 需求分析 2. 搭建 service-order 模块 3. 添加订单基础类 4. 封装 Feign 调用获取就诊 ...
- 尚医通 (三十六) --------- 微信支付
目录 一.微信支付介绍 二.微信支付开发 1. api 接口 2. 前端 3. 处理支付结果 三.取消预约 1. 需求描述 2. 开发微信退款接口 3. 前端 一.微信支付介绍 A.微信扫码支付申请 ...
- 尚医通项目150-170:预约挂号、微信支付功能
前台用户系统 预约挂号 1.接口分析 (1)根据预约周期,展示可预约日期数据,按分页展示 (2)选择日期展示当天可预约列表(该接口后台已经实现过) 2.页面展示分析 (1)分页展示可预约日期,根据有号 ...
- 尚医通 (十八)微信登录
目录 一.生成微信登录二维码 1.准备工作 2.后端开发service_user 3.前端显示登录二维码 4.二维码出现不了进行调试 二.开发微信扫描回调 1.准备工作 2.后台开发 3.前台开发 三 ...
- 尚医通 (十九)用户认证
目录 一.对象存储OSS 1.开通"对象存储OSS"服务 2.创建Bucket 3.上传默认头像 4.创建RAM用户 5.使用SDK 二.后端集成OSS 1.新建云存储微服务 2. ...
- 尚医通(十五)医院排班管理
目录 一.医院排班管理需求 1.页面效果 2.接口分析 二.科室列表(接口) 1.添加service接口和实现 2.添加DepartmentController方法 三.科室列表(前端) 1.添加隐藏 ...
- 尚医通【预约挂号系统】总结
这里写目录标题 1.项目介绍 2.技术点 3.业务流程 4.项目架构 5.项目源码(包含sql) 6.启动步骤 7.项目模块说明 8.项目功能总结 9.效果图 后台管理端 前端展示端 数据库 1.项目 ...
- 尚医通_第1章-项目简介
尚医通_第1章-项目简介 文章目录 尚医通_第1章-项目简介 二.业务流程 三.系统架构 一.功能简介 尚医通即为网上预约挂号系统,网上预约挂号是近年来开展的一项便民就医服务,旨在缓解看病难.挂号难的 ...
- 尚医通 (一)项目介绍
目录 一.功能简介 二.技术点 三.业务流程 四.系统架构 一.功能简介 尚医通即为网上预约挂号系统,网上预约挂号是近年来开展的一项便民就医服务,旨在缓解看病难.挂号难的就医难题,许多患者为看一次病要 ...
- 尚医通 (一) --------- 项目介绍
目录 一.简介 二.将会学到 三.业务流程 四.服务架构 一.简介 尚医通即为网上预约挂号系统,网上预约挂号是近年来开展的一项便民就医服务,旨在缓解看病难.挂号难的就医难题,许多患者为看一次病要跑很多 ...
最新文章
- JQuery笔记(一)
- 每日一皮:资深程序员调试代码的样子...
- 荣耀10 Turbo版将上线发布,游戏玩家欢呼的手游利器
- OpenKruise 2021 规划曝光:More than workloads
- Tomcat Instance in Eclipse and in local folder
- Mac OSX使用VMware Fusion安装windows虚拟机教程
- java url接口_javaweb 后台使用url接口
- 计算机网络-第2章 数据通信基础
- vod系统必须要用服务器吗,架设美萍VOD点播系统服务器
- 微信小程序云开发实现一对一聊天
- linux/android中aplay/arecord用法以及命令
- matlab 行 读取文件 跳过_matlab中textscan跳行使用
- Ubuntu Server 21.10静态IP地址设置
- 围棋大师阿里,产品经理腾讯
- python画多边形太阳花
- 分享一些嵌入式相关的开源项目
- 股票交易接口实现方式
- win10如何修改dns服务器地址,win10如何修改dns服务器地址
- Verilog 代码编写 DDS信号发生器(幅频相可调正弦波、方波、三角波、锯齿波)纯VIVADO编写仿真
- 《瘗旅文》 作者:王阳明(正德四年己巳作)
热门文章
- 师傅带徒弟学:Python正则表达式-关东升-专题视频课程
- Lotus Notes Domino 数据恢复案例记录
- 荐书:《计算机视觉:模型、学习和推理》
- Hulu推荐 | 传奇嘻哈音乐组合的美国梦:《武当帮成名录》
- 如何应对HR小姐姐的千年历史遗留问题:你为什么从上家公司离职?
- 辽宁省哪所大学计算机专业好,「毕业之家」辽宁省最好的大学排名以及强势专业,你知道几所?...
- 区块链在人力资源领域的应用
- NVIC_EnableIRQ使能无法进行的原因
- css权重,权值与优先级解析
- R语言 mac X11 library is missing: install XQuartz from xquartz.macosforge.org