hookehuyr

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

添加 WX_PAY 接口并实现小程序支付功能,当金额大于零时调用微信支付,否则直接跳转成功页
同时新增 API 文档转换功能,将原始文档转换为可用的 API 接口文件
更新首页轮播图图片
# 可预约时段列表
## OpenAPI Specification
```yaml
openapi: 3.0.1
info:
title: ''
version: 1.0.0
paths:
/srv/:
get:
summary: 可预约时段列表
deprecated: false
description: ''
tags:
- 西园寺预约
parameters:
- name: f
in: query
description: ''
required: true
example: reserve
schema:
type: string
- name: a
in: query
description: ''
required: true
example: api
schema:
type: string
- name: t
in: query
description: ''
required: true
example: can_reserve_time_list
schema:
type: string
- name: client_name
in: query
description: 主体客户名称,测试环境和正式环境保持一致
required: true
example: 西园寺
schema:
type: string
- name: month_date
in: query
description: 日期,格式yyyy-mm-dd
required: true
example: '2024-01-17'
schema:
type: string
responses:
'200':
description: ''
content:
application/json:
schema:
type: object
properties:
code:
type: integer
msg:
type: string
data:
type: array
items:
type: object
properties:
month_date:
type: string
title: 日期
begin_time:
type: string
title: 时段起始时间
end_time:
type: string
title: 时段结束时间
price:
type: string
title: 价格
rest_qty:
type: string
title: 余量
description: 说明: >0表示有余量,可约;=0表示没有余量,约满不可约;<0表示不限,无需续约;
x-apifox-orders:
- month_date
- begin_time
- end_time
- price
- rest_qty
required:
- code
- msg
- data
x-apifox-orders:
- code
- msg
- data
headers: {}
x-apifox-name: 成功
x-apifox-ordering: 0
security: []
x-apifox-folder: 西园寺预约
x-apifox-status: tested
x-run-in-apifox: https://app.apifox.com/web/project/1753326/apis/api-140900863-run
components:
schemas: {}
responses: {}
securitySchemes: {}
servers:
- url: https://oa.jcedu.org
description: 西园
security: []
```
读取原始接口文档, 参考原始文档的参数和返回值, 根据 index.js 接口文档编写方式, 把原始文档转换之后写到 test.js 里面.
/*
* @Date: 2023-08-24 09:42:27
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2026-01-07 17:43:26
* @LastEditTime: 2026-01-12 18:38:52
* @FilePath: /xyxBooking-weapp/src/api/index.js
* @Description: 文件描述
*/
......@@ -26,6 +26,7 @@ const Api = {
BILL_PAY_STATUS: '/srv/?a=api&t=bill_pay_status',
QUERY_QR_CODE: '/srv/?a=api&t=id_number_query_qr_code',
ICBC_ORDER_QRY: '/srv/?a=icbc_orderqry',
WX_PAY: '/srv/?a=icbc_pay_wxamp',
VOLUNTEER_LOGIN: '/srv/?a=api&t=volunteer_login',
VERIFY_TICKET: '/srv/?a=api&t=verify_ticket',
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
* @returns {String}
*/
export const icbcOrderQryAPI = (params) => fn(fetch.get(Api.ICBC_ORDER_QRY, params));
/**
* @description: 微信支付接口
* @param {*} pay_id 预约单支付凭证
* @returns {*} 微信支付参数
*/
export const wxPayAPI = (params) => fn(fetch.post(Api.WX_PAY, params));
......
/*
* @Date: 2026-01-10
* @Description: 从原始文档转换生成的 API 接口文件
*/
import { fn, fetch } from '@/api/fn';
const Api = {
CAN_RESERVE_DATE_LIST: '/srv/?a=api&t=can_reserve_date_list',
CAN_RESERVE_TIME_LIST: '/srv/?a=api&t=can_reserve_time_list',
};
/**
* @description: 可预约日期列表
* @param {String} month 月份,格式yyyy-mm
* @returns {Promise<{
* code: number,
* msg: string,
* data: Array<{
* month_date: string, // 日期,格式yyyy-mm-dd
* week_day: string, // 星期几
* full: string, // 是否约满,1=约满,0=未约满
* }>
* }>}
*/
export const canReserveDateListAPI = (params) => fn(fetch.get(Api.CAN_RESERVE_DATE_LIST, params));
/**
* @description: 可预约时段列表
* @param {String} month_date 日期,格式yyyy-mm-dd
* @returns {Promise<{
* code: number,
* msg: string,
* data: Array<{
* month_date: string, // 日期
* begin_time: string, // 时段起始时间
* end_time: string, // 时段结束时间
* price: string, // 价格
* rest_qty: string // 余量 说明: >0表示有余量,可约;=0表示没有余量,约满不可约;<0表示不限,无需续约;
* }>
* }>}
*/
export const canReserveTimeListAPI = (params) => fn(fetch.get(Api.CAN_RESERVE_TIME_LIST, params));
<!--
* @Date: 2023-06-21 10:23:09
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2026-01-09 18:06:06
* @LastEditTime: 2026-01-09 18:08:03
* @FilePath: /xyxBooking-weapp/src/pages/index/index.vue
* @Description: 预约页首页
-->
......@@ -11,7 +11,7 @@
<view style="height: 28vh;">
<swiper class="my-swipe" :autoplay="true" :interval="3000" indicator-dots indicator-color="white" :circular="true">
<swiper-item>
<image style="height: 28vh; width: 100vw;" src="https://cdn.ipadbiz.cn/xys/booking/banner02.png?imageMogr2/thumbnail/500x/strip/quality/100" />
<image style="height: 28vh; width: 100vw;" src="https://cdn.ipadbiz.cn/xys/booking/banner01.png?imageMogr2/thumbnail/500x/strip/quality/100" />
</swiper-item>
</swiper>
</view>
......
<!--
* @Date: 2024-01-15 16:25:51
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2026-01-06 21:22:54
* @FilePath: /git/xyxBooking-weapp/src/pages/submit/index.vue
* @LastEditTime: 2026-01-12 18:42:42
* @FilePath: /xyxBooking-weapp/src/pages/submit/index.vue
* @Description: 预约人员信息
-->
<template>
......@@ -53,7 +53,7 @@ import { IconFont } from '@nutui/icons-vue-taro'
import { useGo } from '@/hooks/useGo'
import icon_check1 from '@/assets/images/多选01@2x.png'
import icon_check2 from '@/assets/images/多选02@2x.png'
import { personListAPI, addReserveAPI } from '@/api/index'
import { personListAPI, addReserveAPI, wxPayAPI } from '@/api/index'
const router = useTaroRouter();
const go = useGo();
......@@ -129,37 +129,28 @@ const submitBtn = async () => {
Taro.hideLoading();
if (code) {
// H5 逻辑: const pay_url = `/srv/?f=reserve&a=icbc_pay&pay_id=${data.pay_id}`; location.href = pay_url;
// 小程序逻辑:
// 1. 如果支持小程序支付,应该调用获取支付参数接口
// 2. 暂时提示不支持,或尝试模拟
// 假设 payPrepareAPI 可用
// const payParams = await payPrepareAPI({ bill_id: data.pay_id }); // 假设接口
Taro.showModal({
title: '提示',
content: '订单提交成功。由于小程序支付暂未配置,请联系管理员或前往H5完成支付。',
showCancel: false,
success: () => {
go('/bookingList');
}
});
// 如果后端有返回支付参数,可以使用 requestPayment
/*
Taro.requestPayment({
timeStamp: '',
nonceStr: '',
package: '',
signType: 'MD5',
paySign: '',
success (res) {
go('/success');
},
fail (res) { }
})
*/
// 如果金额大于零, 走微信支付, 如果等于零直接跳转成功页
if (total.value > 0) {
const payParams = await wxPayAPI({ pay_id: data.pay_id }); // 参数接口
if (payParams.code) {
let pay = payParams.data;
Taro.requestPayment({
timeStamp: pay.timeStamp,
nonceStr: pay.nonceStr,
package: pay.package,
signType: pay.signType,
paySign: pay.paySign,
success (res) {
go('/success', { pay_id: data.pay_id });
},
fail (res) { }
})
}
} else {
// 金额等于零, 直接跳转成功页
go('/success', { pay_id: data.pay_id });
}
}
}
}
......