hookehuyr

fix(预约提交): 添加提交状态检查防止重复提交并优化支付流程

添加 is_submitting 状态防止重复提交订单
优化支付流程的错误处理和状态重置
提取刷新参观者列表为独立函数复用逻辑
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-16 17:38:55 4 + * @LastEditTime: 2026-01-16 18:01:23
5 * @FilePath: /xyxBooking-weapp/src/pages/submit/index.vue 5 * @FilePath: /xyxBooking-weapp/src/pages/submit/index.vue
6 * @Description: 预约人员信息 6 * @Description: 预约人员信息
7 --> 7 -->
...@@ -100,6 +100,7 @@ const RESERVE_STATUS = { ...@@ -100,6 +100,7 @@ const RESERVE_STATUS = {
100 } 100 }
101 101
102 const checked_visitors = ref([]); 102 const checked_visitors = ref([]);
103 +const is_submitting = ref(false); // 是否正在提交订单
103 const addVisitor = (item) => { 104 const addVisitor = (item) => {
104 if (item.is_reserve === RESERVE_STATUS.ENABLE) { // 今天已经预约 105 if (item.is_reserve === RESERVE_STATUS.ENABLE) { // 今天已经预约
105 Taro.showToast({ title: '已预约过参观,请不要重复预约', icon: 'none' }) 106 Taro.showToast({ title: '已预约过参观,请不要重复预约', icon: 'none' })
...@@ -128,43 +129,74 @@ const pending_pay_id = ref(null); ...@@ -128,43 +129,74 @@ const pending_pay_id = ref(null);
128 // 待支付订单是否需要支付 129 // 待支付订单是否需要支付
129 const pending_need_pay = ref(null); 130 const pending_need_pay = ref(null);
130 131
132 +/**
133 + * 刷新参观者列表
134 + */
135 +
136 +const refreshVisitorList = async (options) => {
137 + if (!date.value || !time.value) return;
138 + const res = await personListAPI({
139 + reserve_date: date.value,
140 + begin_time: time.value.split('-')[0],
141 + end_time: time.value.split('-')[1],
142 + period_type: period_type.value
143 + });
144 + if (res && res.code) {
145 + visitorList.value = res.data || [];
146 + if (options?.reset_checked) {
147 + checked_visitors.value = [];
148 + }
149 + }
150 +}
151 +
131 const submitBtn = async () => { 152 const submitBtn = async () => {
153 + if (is_submitting.value) return;
132 if (!checked_visitors.value.length) { 154 if (!checked_visitors.value.length) {
133 Taro.showToast({ title: '请先添加参观者', icon: 'none' }) 155 Taro.showToast({ title: '请先添加参观者', icon: 'none' })
134 return; 156 return;
135 } 157 }
136 158
159 + is_submitting.value = true;
160 + try {
137 let pay_id = pending_pay_id.value; 161 let pay_id = pending_pay_id.value;
138 let need_pay = pending_need_pay.value; 162 let need_pay = pending_need_pay.value;
139 163
140 if (!pay_id) { // TAG: 提交订单, 如果没有待支付订单ID, 则创建一个新的订单 164 if (!pay_id) { // TAG: 提交订单, 如果没有待支付订单ID, 则创建一个新的订单
141 Taro.showLoading({ title: '提交中...' }); 165 Taro.showLoading({ title: '提交中...' });
142 - const { code, data, msg } = await addReserveAPI({ 166 + let reserve_res = null;
167 + try {
168 + reserve_res = await addReserveAPI({
143 reserve_date: date.value, 169 reserve_date: date.value,
144 begin_time: time.value.split('-')[0], 170 begin_time: time.value.split('-')[0],
145 end_time: time.value.split('-')[1], 171 end_time: time.value.split('-')[1],
146 person_id_list: JSON.stringify(checked_visitors.value), 172 person_id_list: JSON.stringify(checked_visitors.value),
147 period_type: period_type.value 173 period_type: period_type.value
148 }); 174 });
149 - 175 + } finally {
150 Taro.hideLoading(); 176 Taro.hideLoading();
177 + }
151 178
152 - if (code != 1) { 179 + if (!reserve_res || reserve_res.code != 1) {
153 return; 180 return;
154 } 181 }
155 - pay_id = data.pay_id; 182 + pay_id = reserve_res.data.pay_id;
156 pending_pay_id.value = pay_id; 183 pending_pay_id.value = pay_id;
157 - need_pay = data?.need_pay; 184 + need_pay = reserve_res.data?.need_pay;
158 pending_need_pay.value = need_pay; 185 pending_need_pay.value = need_pay;
186 + await refreshVisitorList({ reset_checked: true });
159 } 187 }
160 188
161 // 以接口返回的 need_pay 为准:1=需要支付,0=不需要支付 189 // 以接口返回的 need_pay 为准:1=需要支付,0=不需要支付
162 if (Number(need_pay) === 1 || need_pay === true) { 190 if (Number(need_pay) === 1 || need_pay === true) {
163 Taro.showLoading({ title: '支付准备中...' }); 191 Taro.showLoading({ title: '支付准备中...' });
164 - const payParams = await wxPayAPI({ pay_id }); // 参数接口 192 + let payParams = null;
193 + try {
194 + payParams = await wxPayAPI({ pay_id }); // 参数接口
195 + } finally {
165 Taro.hideLoading(); 196 Taro.hideLoading();
197 + }
166 198
167 - if (payParams.code) { 199 + if (payParams && payParams.code == 1) {
168 let pay_params = payParams.data; 200 let pay_params = payParams.data;
169 Taro.requestPayment({ 201 Taro.requestPayment({
170 timeStamp: pay_params.timeStamp, 202 timeStamp: pay_params.timeStamp,
...@@ -178,21 +210,22 @@ const submitBtn = async () => { ...@@ -178,21 +210,22 @@ const submitBtn = async () => {
178 go('/success', { pay_id }); 210 go('/success', { pay_id });
179 }, 211 },
180 fail(res) { 212 fail(res) {
181 - // 支付取消或失败,保留 pending_pay_id,允许用户再次点击按钮尝试支付同一订单 213 + refreshVisitorList({ reset_checked: true }).catch(() => {});
182 - // 只有当 wxPayAPI 获取支付参数失败时(如下面的 else 分支),才重置 ID 以便重新创建订单 214 + Taro.showToast({ title: '支付未完成,可再次点击提交订单继续支付', icon: 'none' });
183 - Taro.showToast({ title: '支付失败,请重试', icon: 'none' });
184 } 215 }
185 }) 216 })
186 } else { 217 } else {
187 - pending_pay_id.value = null; // 支付参数获取失败,重置订单ID 218 + refreshVisitorList({ reset_checked: true }).catch(() => {});
188 - pending_need_pay.value = null; // 支付参数获取失败,重置是否需要支付标志 219 + Taro.showToast({ title: payParams?.msg || '获取支付信息失败', icon: 'none' });
189 - Taro.showToast({ title: payParams.msg || '获取支付信息失败', icon: 'none' });
190 } 220 }
191 } else { 221 } else {
192 - pending_pay_id.value = null; // 不需要支付,重置订单ID 222 + pending_pay_id.value = null;
193 - pending_need_pay.value = null; // 不需要支付,重置是否需要支付标志 223 + pending_need_pay.value = null;
194 go('/success', { pay_id }); 224 go('/success', { pay_id });
195 } 225 }
226 + } finally {
227 + is_submitting.value = false;
228 + }
196 } 229 }
197 230
198 useDidShow(async () => { 231 useDidShow(async () => {
...@@ -202,12 +235,7 @@ useDidShow(async () => { ...@@ -202,12 +235,7 @@ useDidShow(async () => {
202 price.value = params.price || 0; 235 price.value = params.price || 0;
203 period_type.value = params.period_type || ''; 236 period_type.value = params.period_type || '';
204 237
205 - if (date.value && time.value) { 238 + await refreshVisitorList();
206 - const { code, data } = await personListAPI({ reserve_date: date.value, begin_time: time.value.split('-')[0], end_time: time.value.split('-')[1], period_type: period_type.value });
207 - if (code) {
208 - visitorList.value = data || [];
209 - }
210 - }
211 }); 239 });
212 </script> 240 </script>
213 241
......