hookehuyr

feat(支付): 添加微信支付接口并实现支付流程

添加 WX_PAY 接口并实现小程序支付功能,当金额大于零时调用微信支付,否则直接跳转成功页
同时新增 API 文档转换功能,将原始文档转换为可用的 API 接口文件
更新首页轮播图图片
1 +# 可预约时段列表
2 +
3 +## OpenAPI Specification
4 +
5 +```yaml
6 +openapi: 3.0.1
7 +info:
8 + title: ''
9 + version: 1.0.0
10 +paths:
11 + /srv/:
12 + get:
13 + summary: 可预约时段列表
14 + deprecated: false
15 + description: ''
16 + tags:
17 + - 西园寺预约
18 + parameters:
19 + - name: f
20 + in: query
21 + description: ''
22 + required: true
23 + example: reserve
24 + schema:
25 + type: string
26 + - name: a
27 + in: query
28 + description: ''
29 + required: true
30 + example: api
31 + schema:
32 + type: string
33 + - name: t
34 + in: query
35 + description: ''
36 + required: true
37 + example: can_reserve_time_list
38 + schema:
39 + type: string
40 + - name: client_name
41 + in: query
42 + description: 主体客户名称,测试环境和正式环境保持一致
43 + required: true
44 + example: 西园寺
45 + schema:
46 + type: string
47 + - name: month_date
48 + in: query
49 + description: 日期,格式yyyy-mm-dd
50 + required: true
51 + example: '2024-01-17'
52 + schema:
53 + type: string
54 + responses:
55 + '200':
56 + description: ''
57 + content:
58 + application/json:
59 + schema:
60 + type: object
61 + properties:
62 + code:
63 + type: integer
64 + msg:
65 + type: string
66 + data:
67 + type: array
68 + items:
69 + type: object
70 + properties:
71 + month_date:
72 + type: string
73 + title: 日期
74 + begin_time:
75 + type: string
76 + title: 时段起始时间
77 + end_time:
78 + type: string
79 + title: 时段结束时间
80 + price:
81 + type: string
82 + title: 价格
83 + rest_qty:
84 + type: string
85 + title: 余量
86 + description: 说明: >0表示有余量,可约;=0表示没有余量,约满不可约;<0表示不限,无需续约;
87 + x-apifox-orders:
88 + - month_date
89 + - begin_time
90 + - end_time
91 + - price
92 + - rest_qty
93 + required:
94 + - code
95 + - msg
96 + - data
97 + x-apifox-orders:
98 + - code
99 + - msg
100 + - data
101 + headers: {}
102 + x-apifox-name: 成功
103 + x-apifox-ordering: 0
104 + security: []
105 + x-apifox-folder: 西园寺预约
106 + x-apifox-status: tested
107 + x-run-in-apifox: https://app.apifox.com/web/project/1753326/apis/api-140900863-run
108 +components:
109 + schemas: {}
110 + responses: {}
111 + securitySchemes: {}
112 +servers:
113 + - url: https://oa.jcedu.org
114 + description: 西园
115 +security: []
116 +
117 +```
1 +读取原始接口文档, 参考原始文档的参数和返回值, 根据 index.js 接口文档编写方式, 把原始文档转换之后写到 test.js 里面.
1 /* 1 /*
2 * @Date: 2023-08-24 09:42:27 2 * @Date: 2023-08-24 09:42:27
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2026-01-07 17:43:26 4 + * @LastEditTime: 2026-01-12 18:38:52
5 * @FilePath: /xyxBooking-weapp/src/api/index.js 5 * @FilePath: /xyxBooking-weapp/src/api/index.js
6 * @Description: 文件描述 6 * @Description: 文件描述
7 */ 7 */
...@@ -26,6 +26,7 @@ const Api = { ...@@ -26,6 +26,7 @@ const Api = {
26 BILL_PAY_STATUS: '/srv/?a=api&t=bill_pay_status', 26 BILL_PAY_STATUS: '/srv/?a=api&t=bill_pay_status',
27 QUERY_QR_CODE: '/srv/?a=api&t=id_number_query_qr_code', 27 QUERY_QR_CODE: '/srv/?a=api&t=id_number_query_qr_code',
28 ICBC_ORDER_QRY: '/srv/?a=icbc_orderqry', 28 ICBC_ORDER_QRY: '/srv/?a=icbc_orderqry',
29 + WX_PAY: '/srv/?a=icbc_pay_wxamp',
29 VOLUNTEER_LOGIN: '/srv/?a=api&t=volunteer_login', 30 VOLUNTEER_LOGIN: '/srv/?a=api&t=volunteer_login',
30 VERIFY_TICKET: '/srv/?a=api&t=verify_ticket', 31 VERIFY_TICKET: '/srv/?a=api&t=verify_ticket',
31 GET_USER_INFO: '/srv/?a=api&t=get_user_info', 32 GET_USER_INFO: '/srv/?a=api&t=get_user_info',
...@@ -215,3 +216,10 @@ export const queryQrCodeAPI = (params) => fn(fetch.get(Api.QUERY_QR_CODE, params ...@@ -215,3 +216,10 @@ export const queryQrCodeAPI = (params) => fn(fetch.get(Api.QUERY_QR_CODE, params
215 * @returns {String} 216 * @returns {String}
216 */ 217 */
217 export const icbcOrderQryAPI = (params) => fn(fetch.get(Api.ICBC_ORDER_QRY, params)); 218 export const icbcOrderQryAPI = (params) => fn(fetch.get(Api.ICBC_ORDER_QRY, params));
219 +
220 +/**
221 + * @description: 微信支付接口
222 + * @param {*} pay_id 预约单支付凭证
223 + * @returns {*} 微信支付参数
224 + */
225 +export const wxPayAPI = (params) => fn(fetch.post(Api.WX_PAY, params));
......
1 +/*
2 + * @Date: 2026-01-10
3 + * @Description: 从原始文档转换生成的 API 接口文件
4 + */
5 +import { fn, fetch } from '@/api/fn';
6 +
7 +const Api = {
8 + CAN_RESERVE_DATE_LIST: '/srv/?a=api&t=can_reserve_date_list',
9 + CAN_RESERVE_TIME_LIST: '/srv/?a=api&t=can_reserve_time_list',
10 +};
11 +
12 +/**
13 + * @description: 可预约日期列表
14 + * @param {String} month 月份,格式yyyy-mm
15 + * @returns {Promise<{
16 + * code: number,
17 + * msg: string,
18 + * data: Array<{
19 + * month_date: string, // 日期,格式yyyy-mm-dd
20 + * week_day: string, // 星期几
21 + * full: string, // 是否约满,1=约满,0=未约满
22 + * }>
23 + * }>}
24 + */
25 +export const canReserveDateListAPI = (params) => fn(fetch.get(Api.CAN_RESERVE_DATE_LIST, params));
26 +
27 +/**
28 + * @description: 可预约时段列表
29 + * @param {String} month_date 日期,格式yyyy-mm-dd
30 + * @returns {Promise<{
31 + * code: number,
32 + * msg: string,
33 + * data: Array<{
34 + * month_date: string, // 日期
35 + * begin_time: string, // 时段起始时间
36 + * end_time: string, // 时段结束时间
37 + * price: string, // 价格
38 + * rest_qty: string // 余量 说明: >0表示有余量,可约;=0表示没有余量,约满不可约;<0表示不限,无需续约;
39 + * }>
40 + * }>}
41 + */
42 +export const canReserveTimeListAPI = (params) => fn(fetch.get(Api.CAN_RESERVE_TIME_LIST, params));
1 <!-- 1 <!--
2 * @Date: 2023-06-21 10:23:09 2 * @Date: 2023-06-21 10:23:09
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2026-01-09 18:06:06 4 + * @LastEditTime: 2026-01-09 18:08:03
5 * @FilePath: /xyxBooking-weapp/src/pages/index/index.vue 5 * @FilePath: /xyxBooking-weapp/src/pages/index/index.vue
6 * @Description: 预约页首页 6 * @Description: 预约页首页
7 --> 7 -->
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
11 <view style="height: 28vh;"> 11 <view style="height: 28vh;">
12 <swiper class="my-swipe" :autoplay="true" :interval="3000" indicator-dots indicator-color="white" :circular="true"> 12 <swiper class="my-swipe" :autoplay="true" :interval="3000" indicator-dots indicator-color="white" :circular="true">
13 <swiper-item> 13 <swiper-item>
14 - <image style="height: 28vh; width: 100vw;" src="https://cdn.ipadbiz.cn/xys/booking/banner02.png?imageMogr2/thumbnail/500x/strip/quality/100" /> 14 + <image style="height: 28vh; width: 100vw;" src="https://cdn.ipadbiz.cn/xys/booking/banner01.png?imageMogr2/thumbnail/500x/strip/quality/100" />
15 </swiper-item> 15 </swiper-item>
16 </swiper> 16 </swiper>
17 </view> 17 </view>
......
1 <!-- 1 <!--
2 * @Date: 2024-01-15 16:25:51 2 * @Date: 2024-01-15 16:25:51
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2026-01-06 21:22:54 4 + * @LastEditTime: 2026-01-12 18:42:42
5 - * @FilePath: /git/xyxBooking-weapp/src/pages/submit/index.vue 5 + * @FilePath: /xyxBooking-weapp/src/pages/submit/index.vue
6 * @Description: 预约人员信息 6 * @Description: 预约人员信息
7 --> 7 -->
8 <template> 8 <template>
...@@ -53,7 +53,7 @@ import { IconFont } from '@nutui/icons-vue-taro' ...@@ -53,7 +53,7 @@ import { IconFont } from '@nutui/icons-vue-taro'
53 import { useGo } from '@/hooks/useGo' 53 import { useGo } from '@/hooks/useGo'
54 import icon_check1 from '@/assets/images/多选01@2x.png' 54 import icon_check1 from '@/assets/images/多选01@2x.png'
55 import icon_check2 from '@/assets/images/多选02@2x.png' 55 import icon_check2 from '@/assets/images/多选02@2x.png'
56 -import { personListAPI, addReserveAPI } from '@/api/index' 56 +import { personListAPI, addReserveAPI, wxPayAPI } from '@/api/index'
57 57
58 const router = useTaroRouter(); 58 const router = useTaroRouter();
59 const go = useGo(); 59 const go = useGo();
...@@ -129,37 +129,28 @@ const submitBtn = async () => { ...@@ -129,37 +129,28 @@ const submitBtn = async () => {
129 Taro.hideLoading(); 129 Taro.hideLoading();
130 130
131 if (code) { 131 if (code) {
132 - // H5 逻辑: const pay_url = `/srv/?f=reserve&a=icbc_pay&pay_id=${data.pay_id}`; location.href = pay_url; 132 + // 如果金额大于零, 走微信支付, 如果等于零直接跳转成功页
133 - // 小程序逻辑: 133 + if (total.value > 0) {
134 - // 1. 如果支持小程序支付,应该调用获取支付参数接口 134 + const payParams = await wxPayAPI({ pay_id: data.pay_id }); // 参数接口
135 - // 2. 暂时提示不支持,或尝试模拟
136 135
137 - // 假设 payPrepareAPI 可用 136 + if (payParams.code) {
138 - // const payParams = await payPrepareAPI({ bill_id: data.pay_id }); // 假设接口 137 + let pay = payParams.data;
139 -
140 - Taro.showModal({
141 - title: '提示',
142 - content: '订单提交成功。由于小程序支付暂未配置,请联系管理员或前往H5完成支付。',
143 - showCancel: false,
144 - success: () => {
145 - go('/bookingList');
146 - }
147 - });
148 -
149 - // 如果后端有返回支付参数,可以使用 requestPayment
150 - /*
151 Taro.requestPayment({ 138 Taro.requestPayment({
152 - timeStamp: '', 139 + timeStamp: pay.timeStamp,
153 - nonceStr: '', 140 + nonceStr: pay.nonceStr,
154 - package: '', 141 + package: pay.package,
155 - signType: 'MD5', 142 + signType: pay.signType,
156 - paySign: '', 143 + paySign: pay.paySign,
157 success (res) { 144 success (res) {
158 - go('/success'); 145 + go('/success', { pay_id: data.pay_id });
159 }, 146 },
160 fail (res) { } 147 fail (res) { }
161 }) 148 })
162 - */ 149 + }
150 + } else {
151 + // 金额等于零, 直接跳转成功页
152 + go('/success', { pay_id: data.pay_id });
153 + }
163 } 154 }
164 } 155 }
165 } 156 }
......