hookehuyr

feat(订单): 添加业务类型参数并实现认证订单支付流程

在创建订单API中添加business_type参数区分买车和认证订单
在商品详情页和认证页中分别传入对应的业务类型
完善支付组件的支付成功和失败处理逻辑
1 /* 1 /*
2 * @Date: 2025-07-03 17:21:45 2 * @Date: 2025-07-03 17:21:45
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-07-28 11:51:11 4 + * @LastEditTime: 2025-07-31 15:50:33
5 * @FilePath: /jgdl/src/api/orders.js 5 * @FilePath: /jgdl/src/api/orders.js
6 * @Description: 文件描述 6 * @Description: 文件描述
7 */ 7 */
...@@ -39,6 +39,7 @@ export const getOrderDetailAPI = (params) => fn(fetch.get(Api.GET_ORDER_DETAIL, ...@@ -39,6 +39,7 @@ export const getOrderDetailAPI = (params) => fn(fetch.get(Api.GET_ORDER_DETAIL,
39 * @description: 创建订单 39 * @description: 创建订单
40 * @param vehicle_id 车辆ID 40 * @param vehicle_id 车辆ID
41 * @param total_amount 总价 41 * @param total_amount 总价
42 + * @param business_type 业务类型(sell=买车订单, verification=认证订单)
42 * @returns data{ id } 43 * @returns data{ id }
43 */ 44 */
44 export const createOrderAPI = (params) => fn(fetch.post(Api.CREATE_ORDER, params)); 45 export const createOrderAPI = (params) => fn(fetch.post(Api.CREATE_ORDER, params));
......
1 <!-- 1 <!--
2 * @Date: 2023-12-20 14:11:11 2 * @Date: 2023-12-20 14:11:11
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-07-16 18:20:38 4 + * @LastEditTime: 2025-07-31 15:30:59
5 * @FilePath: /jgdl/src/components/payCard.vue 5 * @FilePath: /jgdl/src/components/payCard.vue
6 * @Description: 文件描述 6 * @Description: 文件描述
7 --> 7 -->
...@@ -135,6 +135,20 @@ const goToPay = async () => { ...@@ -135,6 +135,20 @@ const goToPay = async () => {
135 url: '/pages/myOrders/index', 135 url: '/pages/myOrders/index',
136 }); 136 });
137 } 137 }
138 + if (current_page === 'pages/setAuthCar/index') { // 发布认证页打开
139 + // 发出支付成功事件,通知父组件更新订单状态
140 + emit('paySuccess', { orderId: id.value });
141 + }
142 + }
143 + },
144 + fail: () => {
145 + let current_page = getCurrentPageUrl();
146 + if (current_page === 'pages/setAuthCar/index') { // 发布认证页打开
147 + Taro.showModal({
148 + title: '温馨提示',
149 + content: '需要付费才能认证',
150 + showCancel: false,
151 + });
138 } 152 }
139 } 153 }
140 }); 154 });
......
1 <!-- 1 <!--
2 * @Date: 2022-09-19 14:11:06 2 * @Date: 2022-09-19 14:11:06
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-07-30 14:48:32 4 + * @LastEditTime: 2025-07-31 15:29:14
5 * @FilePath: /jgdl/src/pages/productDetail/index.vue 5 * @FilePath: /jgdl/src/pages/productDetail/index.vue
6 * @Description: 商品详情页 6 * @Description: 商品详情页
7 --> 7 -->
...@@ -485,6 +485,7 @@ const handlePurchase = async () => { ...@@ -485,6 +485,7 @@ const handlePurchase = async () => {
485 const onPay = async ({ id, remain_time, price }) => { 485 const onPay = async ({ id, remain_time, price }) => {
486 try { 486 try {
487 const { code, data } = await createOrderAPI({ 487 const { code, data } = await createOrderAPI({
488 + business_type: 'sell',
488 vehicle_id: id, 489 vehicle_id: id,
489 total_amount: price 490 total_amount: price
490 }) 491 })
......
1 <!-- 1 <!--
2 * @Date: 2022-09-19 14:11:06 2 * @Date: 2022-09-19 14:11:06
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-07-17 14:31:55 4 + * @LastEditTime: 2025-08-01 14:19:54
5 * @FilePath: /jgdl/src/pages/setAuthCar/index.vue 5 * @FilePath: /jgdl/src/pages/setAuthCar/index.vue
6 * @Description: 申请认证 6 * @Description: 申请认证
7 --> 7 -->
...@@ -90,8 +90,10 @@ ...@@ -90,8 +90,10 @@
90 <nut-form-item label-position="top" label="品牌型号选择" prop="brandModel" required 90 <nut-form-item label-position="top" label="品牌型号选择" prop="brandModel" required
91 :rules="[{ required: true, message: '请选择品牌型号' }]"> 91 :rules="[{ required: true, message: '请选择品牌型号' }]">
92 <view class="form-item-content" @click="showBrandModelPicker"> 92 <view class="form-item-content" @click="showBrandModelPicker">
93 - <text class="form-value" :class="{ 'form-value-selected': formData.brand && formData.model, 'form-value-placeholder': !(formData.brand && formData.model) }"> 93 + <text class="form-value"
94 - {{ formData.brand && formData.model ? `${formData.brand} ${formData.model}` : '请选择品牌型号' }} 94 + :class="{ 'form-value-selected': formData.brand && formData.model, 'form-value-placeholder': !(formData.brand && formData.model) }">
95 + {{ formData.brand && formData.model ? `${formData.brand} ${formData.model}` : '请选择品牌型号'
96 + }}
95 </text> 97 </text>
96 <Right class="arrow-icon" /> 98 <Right class="arrow-icon" />
97 </view> 99 </view>
...@@ -99,7 +101,8 @@ ...@@ -99,7 +101,8 @@
99 101
100 <!-- 续航里程 --> 102 <!-- 续航里程 -->
101 <nut-form-item label="续航里程" prop="range_km"> 103 <nut-form-item label="续航里程" prop="range_km">
102 - <nut-input v-model="formData.range_km" placeholder="请输入" type="number" input-align="right" @input="validateRangeInput"> 104 + <nut-input v-model="formData.range_km" placeholder="请输入" type="number" input-align="right"
105 + @input="validateRangeInput">
103 <template #right> 106 <template #right>
104 <text class="unit">公里</text> 107 <text class="unit">公里</text>
105 </template> 108 </template>
...@@ -108,7 +111,8 @@ ...@@ -108,7 +111,8 @@
108 111
109 <!-- 最高时速 --> 112 <!-- 最高时速 -->
110 <nut-form-item label="最高时速" prop="max_speed_kmh"> 113 <nut-form-item label="最高时速" prop="max_speed_kmh">
111 - <nut-input v-model="formData.max_speed_kmh" placeholder="请输入" type="number" input-align="right" @input="validateMaxSpeedInput"> 114 + <nut-input v-model="formData.max_speed_kmh" placeholder="请输入" type="number" input-align="right"
115 + @input="validateMaxSpeedInput">
112 <template #right> 116 <template #right>
113 <text class="unit">km/h</text> 117 <text class="unit">km/h</text>
114 </template> 118 </template>
...@@ -135,6 +139,9 @@ ...@@ -135,6 +139,9 @@
135 <!-- 品牌型号选择器 --> 139 <!-- 品牌型号选择器 -->
136 <BrandModelPicker ref="brandModelPickerRef" :brand-options="brandOptions" @confirm="onBrandModelConfirm" 140 <BrandModelPicker ref="brandModelPickerRef" :brand-options="brandOptions" @confirm="onBrandModelConfirm"
137 @cancel="onBrandModelCancel" /> 141 @cancel="onBrandModelCancel" />
142 +
143 + <!-- 支付组件 -->
144 + <payCard :visible="show_pay" :data="payData" @close="onPayClose" @paySuccess="onPaySuccess" />
138 </view> 145 </view>
139 </template> 146 </template>
140 147
...@@ -145,10 +152,12 @@ import Taro from '@tarojs/taro' ...@@ -145,10 +152,12 @@ import Taro from '@tarojs/taro'
145 import './index.less' 152 import './index.less'
146 import BASE_URL from '@/utils/config'; 153 import BASE_URL from '@/utils/config';
147 import BrandModelPicker from '@/components/BrandModelPicker.vue' 154 import BrandModelPicker from '@/components/BrandModelPicker.vue'
155 +import payCard from '@/components/payCard.vue'
148 156
149 // 导入接口 157 // 导入接口
150 import { getBrandsModelsAPI } from '@/api/other'; 158 import { getBrandsModelsAPI } from '@/api/other';
151 import { addVehicleAPI, editVehicleAPI, getVehicleDetailAPI } from '@/api/car'; 159 import { addVehicleAPI, editVehicleAPI, getVehicleDetailAPI } from '@/api/car';
160 +import { createOrderAPI } from '@/api/orders'
152 161
153 // 获取页面参数 162 // 获取页面参数
154 const instance = Taro.getCurrentInstance() 163 const instance = Taro.getCurrentInstance()
...@@ -195,7 +204,78 @@ const brandModelPickerRef = ref(null) ...@@ -195,7 +204,78 @@ const brandModelPickerRef = ref(null)
195 // 品牌型号选项数据 204 // 品牌型号选项数据
196 const brandOptions = ref([]) 205 const brandOptions = ref([])
197 206
207 +/**
208 + * 支付模块
209 + */
210 +const show_pay = ref(false)
211 +const payData = ref({
212 + id: '',
213 + price: 0,
214 + remain_time: 0
215 +})
198 216
217 +/**
218 + * 发送订单支付信息到支付组件
219 + * @param {Object} payInfo - 支付信息
220 + * @param {string} payInfo.id - 订单ID
221 + * @param {number} payInfo.remain_time - 剩余时间
222 + * @param {number} payInfo.price - 价格
223 + */
224 +const onPay = async ({ id, remain_time, price }) => {
225 + try {
226 + const { code, data } = await createOrderAPI({
227 + business_type: 'verification',
228 + vehicle_id: id,
229 + total_amount: price
230 + })
231 + if (code) {
232 + show_pay.value = true
233 + payData.value.id = data.id
234 + payData.value.price = price
235 + payData.value.remain_time = remain_time
236 + }
237 + } catch (error) {
238 + console.error('创建订单失败:', error)
239 + }
240 +}
241 +
242 +/**
243 + * 关闭支付弹框
244 + */
245 +const onPayClose = () => {
246 + show_pay.value = false
247 +}
248 +
249 +/**
250 + * 处理支付成功事件
251 + * @param {Object} data - 支付成功数据
252 + * @param {string} data.orderId - 订单ID
253 + */
254 +const onPaySuccess = ({ orderId }) => {
255 + if (isEditMode.value) {
256 + Taro.showToast({
257 + title: '保存成功',
258 + icon: 'success',
259 + duration: 2000,
260 + complete: () => {
261 + // 保存成功后返回上一页
262 + Taro.navigateBack()
263 + }
264 + })
265 + } else {
266 + Taro.showModal({
267 + title: '温馨提示',
268 + content: '认证提交成功,我们会尽快审核',
269 + showCancel: false,
270 + confirmText: '知道了',
271 + success: function (res) {
272 + if (res.confirm) {
273 + Taro.navigateBack()
274 + }
275 + }
276 + })
277 + }
278 +}
199 279
200 /** 280 /**
201 * 触发图片上传 281 * 触发图片上传
...@@ -469,47 +549,26 @@ const onSubmit = async () => { ...@@ -469,47 +549,26 @@ const onSubmit = async () => {
469 if (isEditMode.value) { 549 if (isEditMode.value) {
470 // 编辑车辆,且认证时,op=verification,表示申请认证 550 // 编辑车辆,且认证时,op=verification,表示申请认证
471 const { code } = await editVehicleAPI({ id: carId.value, ...formData, op: 'verification' }) 551 const { code } = await editVehicleAPI({ id: carId.value, ...formData, op: 'verification' })
472 - if (!code) { 552 + if (code) {
473 - throw new Error('更新失败') 553 + onPay({
554 + id: data.id,
555 + remain_time: data.remain_time || 1800, // 30分钟
556 + price: data.verification_price
557 + })
474 } 558 }
475 } else { 559 } else {
476 // 新增车辆,且认证时,op=verification,表示只申请认证 560 // 新增车辆,且认证时,op=verification,表示只申请认证
477 - const { code } = await addVehicleAPI({ ...formData, op: 'verification' }) 561 + const { code, data } = await addVehicleAPI({ ...formData, op: 'verification' })
478 - if (!code) { 562 + if (code) {
479 - throw new Error('提交失败') 563 + onPay({
564 + id: data.id,
565 + remain_time: data.remain_time || 1800, // 30分钟
566 + price: data.verification_price
567 + })
480 } 568 }
481 } 569 }
482 570
483 Taro.hideLoading() 571 Taro.hideLoading()
484 - // 提交成功提示
485 - if (isEditMode.value) {
486 - Taro.showToast({
487 - title: '保存成功',
488 - icon: 'success',
489 - duration: 2000,
490 - complete: () => {
491 - // 保存成功后返回上一页
492 - Taro.navigateBack()
493 - }
494 - })
495 - } else {
496 - Taro.showModal({
497 - title: '温馨提示',
498 - content: '认证提交成功,我们会尽快审核',
499 - showCancel: false,
500 - confirmText: '知道了',
501 - success: function (res) {
502 - if (res.confirm) {
503 - Taro.navigateBack()
504 - }
505 - }
506 - })
507 - }
508 -
509 - // 返回上一页
510 - // setTimeout(() => {
511 - // Taro.navigateBack()
512 - // }, 1500)
513 } catch (error) { 572 } catch (error) {
514 console.error('提交失败:', error) 573 console.error('提交失败:', error)
515 Taro.hideLoading() 574 Taro.hideLoading()
......