当前位置:网站首页>Day118. Shangyitong: order list, details, payment
Day118. Shangyitong: order list, details, payment
2022-08-04 23:19:00 【Firework Youth·】
一、订单列表
You need to log in before making a query(先获取userId),List query with pagination and conditions
1、后端接口
1. 需求分析
*参数:page,limit,OrderQueryVo,请求对象(userId)
*返回值:Page<OrderInfo>
2. order模块 添加分页插件
@Configuration
@EnableTransactionManagement
public class OrderConfig {
//分页插件
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}
3. controller
@ApiOperation(value = "Query order list with conditional pagination")
@GetMapping("auth/{page}/{limit}")
public R list(@PathVariable Long page,
@PathVariable Long limit,
OrderQueryVo orderQueryVo, HttpServletRequest request) {
//1.获取userId,存入orderQueryVo
Long userId = AuthContextHolder.getUserId(request);
orderQueryVo.setUserId(userId);
//2.封装分页参数(苞米豆)
Page<OrderInfo> pageParams = new Page<>(page,limit);
//3.调用方法查询
Page<OrderInfo> pageModel = orderService.selectPage(pageParams,orderQueryVo);
return R.ok().data("pageModel",pageModel);
}
@ApiOperation(value = "获取订单状态")//下拉列选
@GetMapping("auth/getStatusList")
public R getStatusList() {
return R.ok().data("statusList", OrderStatusEnum.getStatusList());
}
4. service
//Query order list with conditional pagination
@Override
public Page<OrderInfo> selectPage(Page<OrderInfo> pageParams, OrderQueryVo orderQueryVo) {
//1.取出参数
Long userId = orderQueryVo.getUserId();
String name = orderQueryVo.getKeyword(); //医院名称
Long patientId = orderQueryVo.getPatientId(); //就诊人名称
String orderStatus = orderQueryVo.getOrderStatus(); //订单状态
String reserveDate = orderQueryVo.getReserveDate();//安排时间
String createTimeBegin = orderQueryVo.getCreateTimeBegin();
String createTimeEnd = orderQueryVo.getCreateTimeEnd();
//2.验空,Spelling filter
QueryWrapper<OrderInfo> wrapper = new QueryWrapper<>();
if(!StringUtils.isEmpty(userId)){
wrapper.eq("user_id",userId);
}
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);
}
//3.分页查询
Page<OrderInfo> pageModel = baseMapper.selectPage(pageParams, wrapper);
//4.Translation status(根据枚举,No cross-module calls are involved)
pageModel.getRecords().stream().forEach(item->{
this.packOrderInfo(item);
});
return pageModel;
}
//Translate the state according to the enum class
private OrderInfo packOrderInfo(OrderInfo orderInfo) {
orderInfo.getParam().put("orderStatusString", OrderStatusEnum.getStatusNameByStatus(orderInfo.getOrderStatus()));
return orderInfo;
}
2、前端对接
1 确认入口,添加页面
2. 添加API
在api/orderinfo.js 新增方法
//订单列表
getPageList(page, limit, searchObj) {
return request({
url: `${api_name}/auth/${page}/${limit}`,
method: `get`,
params: searchObj
})
},
//订单状态
getStatusList() {
return request({
url: `${api_name}/auth/getStatusList`,
method: 'get'
})
},
3. 添加页面元素
<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="window.location='/user'">实名认证 </span>
</div>
<div class="nav-item selected">
<span class="v-link selected dark" onclick="window.location='/order'"> 挂号订单 </span>
</div>
<div class="nav-item ">
<span class="v-link clickable dark" onclick="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-option v-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-option v-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" stripe style="width: 100%">
<el-table-column label="就诊时间" width="120">
<template slot-scope="scope">
{
{ scope.row.reserveDate }} {
{ scope.row.reserveTime === 0 ? '上午' : '下午' }}
</template>
</el-table-column>
<el-table-column prop="hosname" label="医院" width="100">
</el-table-column>
<el-table-column prop="depname" label="科室">
</el-table-column>
<el-table-column prop="title" label="医生">
</el-table-column>
<el-table-column prop="amount" label="医事服务费">
</el-table-column>
<el-table-column prop="patientName" label="就诊人">
</el-table-column>
<el-table-column prop="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-pagination class="pagination" layout="prev, pager, next" :current-page="page" :total="total"
:page-size="limit" @current-change="fetchData">
</el-pagination>
</div>
</div>
<!-- 右侧内容 #end -->
</div>
<!-- footer -->
</template>
4. 实现JS
<script>
import '~/assets/css/hospital_personal.css'
import '~/assets/css/hospital.css'
import patientApi from '@/api/patient'
import orderInfoApi from '@/api/orderinfo'
export default {
data() {
return {
list: [], // banner列表
total: 0, // 数据库中的总记录数
page: 1, // 默认页码
limit: 10, // 每页记录数
searchObj: {}, // 查询表单对象
patientList: [], //Patient collection
statusList: [] //Collection of order status
}
},
created() {
this.orderId = this.$route.query.orderId
//Patient initialization
this.findPatientList()
//状态初始化
this.getStatusList()
//列表数据初始化
this.fetchData()
},
methods: {
findPatientList() {
patientApi.findList().then(response => {
this.patientList = response.data.list
})
},
getStatusList() {
orderInfoApi.getStatusList().then(response => {
this.statusList = response.data.statusList
})
},
fetchData(page = 1) {
this.page = page
orderInfoApi.getPageList(this.page, this.limit, this.searchObj).then(response => {
console.log(response.data);
this.list = response.data.pageModel.records
this.total = response.data.pageModel.total
})
},
//查看详情
show(id) {
window.location.href = '/order/show?orderId=' + id
}
}
}
</script>
5. 测试
二、订单详情
1. controller
@ApiOperation(value = "根据订单id查询订单详情")
@GetMapping("auth/getOrders/{orderId}")
public R getOrders(@PathVariable Long orderId) {
OrderInfo orderInfo = orderService.getOrderById(orderId);
return R.ok().data("orderInfo",orderInfo);
}
2. service
//根据订单id查询订单详情
@Override
public OrderInfo getOrderById(Long orderId) {
//Translate fields and return
OrderInfo orderInfo = this.packOrderInfo(baseMapper.selectById(orderId));
return this.packOrderInfo(orderInfo);
}
3. 确认入口,创建页面,添加页面元素
<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="window.location='/user'">实名认证 </span>
</div>
<div class="nav-item selected">
<span class="v-link selected dark" onclick="window.location='/order'"> 挂号订单 </span>
</div>
<div class="nav-item ">
<span class="v-link clickable dark" onclick="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="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>
4. API
//订单详情
getOrders(orderId) {
return request({
url: `${api_name}/auth/getOrders/${orderId}`,
method: `get`
})
},
5. JS实现,添加CSS
<script>
import '~/assets/css/hospital_personal.css'
import '~/assets/css/hospital.css'
import orderInfoApi from '@/api/orderinfo'
export default {
data() {
return {
orderId: null,
orderInfo: { //对象套对象,The objects inside also need to be initialized
param: {}
},
dialogPayVisible: false,
payObj: {},
timer: null // 定时器名称
}
},
created() {
this.orderId = this.$route.query.orderId
this.getOrderInfo()
},
methods: {
getOrderInfo() {
orderInfoApi.getOrders(this.orderId)
.then(response => {
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>
6. 测试
三、订单支付 -- 微信支付
一、微信扫码支付申请
在线微信支付开发文档:https://pay.weixin.qq.com/wiki/doc/api/index.html
1、微信扫码支付申请
微信扫码支付是商户系统按微信支付协议生成支付二维码,用户再用微信“扫一扫”完成支付的模式.该模式适用于PC网站支付、实体店单品或订单支付、媒体广告支付等场景.
申请步骤:(了解)
第一步:注册公众号(类型须为:服务号)
请根据营业执照类型选择以下主体注册:个体工商户| 企业/公司| 政府| 媒体| 其他类型.
第二步:认证公众号
公众号认证后才可申请微信支付,认证费:300元/年.
第三步:提交资料申请微信支付
登录公众平台,点击左侧菜单【微信支付】,开始填写资料等待审核,审核时间为1-5个工作日内.
第四步:开户成功,登录商户平台进行验证
资料审核通过后,请登录联系人邮箱查收商户号和密码,并登录商户平台填写财付通备付金打的小额资金数额,完成账户验证.
第五步:在线签署协议
本协议为线上电子协议,签署后方可进行交易及资金结算,签署完立即生效.
2、WeChat Pay provides tools
(1) 获取随机字符串:WXPayUtil.generateNonceStr()
(2) MAP转换为XML字符串(自动添加签名): WXPayUtil.generateSignedXml(param, partnerkey)
(3) XML字符串转换为MAP:WXPayUtil.xmlToMap(result)
二、获取二维码
1、准备工作
1. service_orders 引入依赖
<!--微信支付-->
<dependency>
<groupId>com.github.wxpay</groupId>
<artifactId>wxpay-sdk</artifactId>
<version>0.0.3</version>
</dependency>
2. 添加配置
#redis
spring.redis.host=192.168.86.86
spring.redis.port=6379
spring.redis.database= 0
spring.redis.timeout=1800000
spring.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
#关联的公众号appid
weixin.pay.appid=wx74862e0dfcf69954
#商户号
weixin.pay.partner=1558950191
#商户key
weixin.pay.partnerkey=T6m9iK73b0kn9g5v426MKfHQH7X8rKwb
3. Add a tool class to read configuration information,注释属性 cert
2、添加交易记录接口
payment_info
1. 确认表
2. 搭建 payment接口、类
*参数:订单id,交易类型
*返回值:无
public interface PaymentService extends IService<PaymentInfo> {
/**
* 保存交易记录
* @param orderInfo
* @param paymentType 支付类型(1:支付宝 2:微信)
*/
void savePaymentInfo(OrderInfo orderInfo, Integer paymentType);
}
@Service
public class PaymentServiceImpl extends
ServiceImpl<PaymentMapper, PaymentInfo> implements PaymentService {
//保存交易记录
@Override
public void savePaymentInfo(OrderInfo orderInfo, Integer paymentType) {
//1.根据order订单id+交易类型,查询交易记录
QueryWrapper<PaymentInfo> wrapper = new QueryWrapper<>();
wrapper.eq("order_id", orderInfo.getId());
wrapper.eq("payment_type", paymentType);
Integer count = baseMapper.selectCount(wrapper);
if(count>0) return;
//2.Add a new transaction if there is no transaction
PaymentInfo paymentInfo = new PaymentInfo();
paymentInfo.setCreateTime(new Date());
paymentInfo.setOrderId(orderInfo.getId());
paymentInfo.setPaymentType(paymentType);
paymentInfo.setOutTradeNo(orderInfo.getOutTradeNo());
paymentInfo.setPaymentStatus(PaymentStatusEnum.UNPAID.getStatus());
String subject = new DateTime(orderInfo.getReserveDate()).toString("yyyy-MM-dd")+"|"+orderInfo.getHosname()+"|"+orderInfo.getDepname()+"|"+orderInfo.getTitle();
paymentInfo.setSubject(subject);
paymentInfo.setTotalAmount(orderInfo.getAmount());
baseMapper.insert(paymentInfo);
}
}
3、生成二维码接口
边栏推荐
猜你喜欢
Bidding Announcement | Operation and Maintenance Project of Haina Baichuang Official Account
4-《PyTorch深度学习实践》-反向传播
地面高度检测/平面提取与检测(Fast Plane Extraction in Organized Point Clouds Using Agglomerative Hierarchical Clu)
【SSR服务端渲染+CSR客户端渲染+post请求+get请求+总结】
The market value of 360 has evaporated by 390 billion in four years. Can government and enterprise security save lives?
OPENCV学习DAY8
postman接口测试
[Cultivation of internal skills of string functions] strlen + strstr + strtok + strerror (3)
MySQL基础篇【聚合函数】
应用联合、体系化推进。集团型化工企业数字化转型路径
随机推荐
亿流量大考(3):不加机器,如何抗住每天百亿级高并发流量?
[QNX Hypervisor 2.2用户手册]10.4 vdev hpet
2022年华数杯数学建模
未上市就“一举成名”,空间媲美途昂,安全、舒适一个不落
enumerate()函数
Bidding Announcement | Operation and Maintenance Project of Haina Baichuang Official Account
软件测试技术之如何编写测试用例(4)
Pytest learning - fixtures
【手撕AHB-APB Bridge】~ AMBA总线 之 AHB
招标公告 | 海纳百创公众号运维项目
一点点读懂cpufreq(一)
【3D建模制作技巧分享】ZBrush纹理贴图怎么导入
Uniapp dynamic sliding navigation effect demo (finishing)
uniapp横向选项卡(水平滚动导航栏)效果demo(整理)
【字符串函数内功修炼】strcpy + strcat + strcmp(一)
【游戏建模模型制作全流程】ZBrush蜥蜴模型雕刻教程
轮播图动态渲染
Will we still need browsers in the future?(feat. Maple words Maple language)
【内存操作函数内功修炼】memcpy + memmove + memcmp + memset(四)
零基础如何入门软件测试?再到测开(小编心得)