hookehuyr

feat(订单): 重构订单模块,实现真实API对接

- 修改订单API接口,简化并适配后端接口
- 商品详情页增加卖家判断逻辑,隐藏不相关操作
- 订单列表页重构,对接真实数据并优化分页加载
- 实现订单评价功能,对接真实API
- 优化订单详情展示,显示更多真实数据
/*
* @Date: 2024-01-01 00:00:00
* @Date: 2025-07-03 17:21:45
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-07-09 15:00:24
* @LastEditTime: 2025-07-14 09:34:58
* @FilePath: /jgdl/src/api/orders.js
* @Description: 车辆订单相关API接口
* @Description: 文件描述
*/
import { fn, fetch } from './fn';
import { fn, fetch } from '@/api/fn';
// API 端点定义
const OrderApi = {
// 获取我的订单列表
GET_MY_ORDERS: '/api/orders/my-orders',
// 获取订单详情
GET_ORDER_DETAIL: '/api/orders/detail',
// 删除订单
DELETE_ORDER: '/api/orders/delete',
// 取消订单
CANCEL_ORDER: '/api/orders/cancel',
// 确认收货
CONFIRM_ORDER: '/api/orders/confirm',
// 提交评价
SUBMIT_REVIEW: '/api/orders/review',
// 申请退款
REQUEST_REFUND: '/api/orders/refund',
};
const Api = {
GET_ORDER_LIST: '/srv/?a=order&t=list',
GET_ORDER_DETAIL: '/srv/?a=order&t=detail',
CREATE_ORDER: '/srv/?a=order&t=add',
REVIEW_ORDER: '/srv/?a=order&t=review',
DELETE_ORDER: '/srv/?a=order&t=del',
}
/**
* @description: 获取我的订单列表
* @param {Object} params
* @param {string} params.type - 订单类型 'bought' | 'sold'
* @param {number} params.page - 页码
* @param {number} params.limit - 每页数量
* @param {string} params.status - 订单状态筛选(可选)
* @returns {Promise}
* @description: 获取订单列表
* @param page 页码,从0开始
* @param page_size 每页数量
* @param type 列表类型。buy=我买的,sell=我卖的
* @param status 订单状态(3=待支付, 5=已完成, 7=已取消)
* @returns data{ list[{ id, title, total_amount, status, create_time, payment_time, details{ id, vehicle_id, quantity, vehicle{} } }] }
*/
export const getMyOrdersAPI = (params) => {
// TODO: 替换为真实的API调用
return fn(fetch.get(OrderApi.GET_MY_ORDERS, params));
};
export const getOrderListAPI = (params) => fn(fetch.get(Api.GET_ORDER_LIST, params));
/**
* @description: 获取订单详情
* @param {Object} params
* @param {string} params.orderId - 订单ID
* @returns {Promise}
* @param id 订单ID
* @returns data{ id, title, total_amount, status, create_time, payment_time, details{ id, vehicle_id, quantity, vehicle{ id, title, price, cover_image } } }
*/
export const getOrderDetailAPI = (params) => {
// TODO: 替换为真实的API调用
return fn(fetch.get(OrderApi.GET_ORDER_DETAIL, params));
};
export const getOrderDetailAPI = (params) => fn(fetch.get(Api.GET_ORDER_DETAIL, params));
/**
* @description: 删除订单
* @param {Object} params
* @param {string} params.orderId - 订单ID
* @returns {Promise}
*
* @example
* // 使用示例:
* try {
* const response = await deleteOrderAPI({ orderId: 'ORDER_123' });
* if (response.success) {
* console.log('删除成功:', response.message);
* }
* } catch (error) {
* console.error('删除失败:', error.message);
* }
*
* @apiResponse
* {
* success: true,
* message: '订单删除成功',
* data: null
* }
* @description: 创建订单
* @param vehicle_id 车辆ID
* @param total_amount 总价
* @returns data{ id }
*/
export const deleteOrderAPI = (params) => {
// TODO: 替换为真实的API调用
// 当集成真实API时,请确保:
// 1. 处理网络错误和超时
// 2. 验证用户权限(只能删除自己的订单)
// 3. 检查订单状态(只有特定状态的订单才能删除)
// 4. 返回统一的响应格式
return fn(fetch.delete(OrderApi.DELETE_ORDER, params));
};
export const createOrderAPI = (params) => fn(fetch.post(Api.CREATE_ORDER, params));
/**
* @description: 取消订单
* @param {Object} params
* @param {string} params.orderId - 订单ID
* @param {string} params.reason - 取消原因(可选)
* @returns {Promise}
* @description: 订单评价
* @param detail_id 订单ID
* @param rating 评级(1到5分)
* @param note 评价内容
* @returns data{}
*/
export const cancelOrderAPI = (params) => {
// TODO: 替换为真实的API调用
return fn(fetch.post(OrderApi.CANCEL_ORDER, params));
};
export const reviewOrderAPI = (params) => fn(fetch.post(Api.REVIEW_ORDER, params));
/**
* @description: 确认收货/完成交易
* @param {Object} params
* @param {string} params.orderId - 订单ID
* @returns {Promise}
*/
export const confirmOrderAPI = (params) => {
// TODO: 替换为真实的API调用
return fn(fetch.post(OrderApi.CONFIRM_ORDER, params));
};
/**
* @description: 提交订单评价
* @param {Object} params
* @param {string} params.orderId - 订单ID
* @param {number} params.rating - 评分 (1-5)
* @param {string} params.comment - 评价内容
* @param {Array} params.images - 评价图片(可选)
* @returns {Promise}
*
* @example
* // 使用示例:
* try {
* const response = await submitReviewAPI({
* orderId: 'ORDER_123',
* rating: 5,
* comment: '车况很好,卖家服务态度也很棒!',
* images: ['image1.jpg', 'image2.jpg'] // 可选
* });
* if (response.success) {
* console.log('评价提交成功:', response.message);
* }
* } catch (error) {
* console.error('评价提交失败:', error.message);
* }
*
* @apiResponse
* {
* success: true,
* message: '评价提交成功',
* data: {
* reviewId: 'REVIEW_123',
* createdAt: '2024-01-01T12:00:00Z'
* }
* }
*/
export const submitReviewAPI = (params) => {
// TODO: 替换为真实的API调用
// 当集成真实API时,请确保:
// 1. 验证评分范围(1-5)
// 2. 验证评价内容长度限制
// 3. 处理图片上传(如果有)
// 4. 检查订单状态(只有已完成的订单才能评价)
// 5. 防止重复评价
return fn(fetch.post(OrderApi.SUBMIT_REVIEW, params));
};
/**
* @description: 申请退款
* @param {Object} params
* @param {string} params.orderId - 订单ID
* @param {string} params.reason - 退款原因
* @param {number} params.amount - 退款金额
* @param {Array} params.evidence - 退款凭证(可选)
* @returns {Promise}
* @description: 删除订单
* @param order_id 订单ID
* @returns data{}
*/
export const requestRefundAPI = (params) => {
// TODO: 替换为真实的API调用
return fn(fetch.post(OrderApi.REQUEST_REFUND, params));
};
// 导出所有API
export default {
getMyOrdersAPI,
getOrderDetailAPI,
deleteOrderAPI,
cancelOrderAPI,
confirmOrderAPI,
submitReviewAPI,
requestRefundAPI,
};
export const deleteOrderAPI = (params) => fn(fetch.post(Api.DELETE_ORDER, params));
......
This diff is collapsed. Click to expand it.
<!--
* @Date: 2022-09-19 14:11:06
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-07-11 14:56:02
* @LastEditTime: 2025-07-14 09:34:00
* @FilePath: /jgdl/src/pages/productDetail/index.vue
* @Description: 商品详情页
-->
......@@ -136,7 +136,7 @@
</view>
<!-- 卖家信息 -->
<view class="seller-info bg-white mt-2 p-4 mb-2">
<view v-if="!isCurrentUserSeller" class="seller-info bg-white mt-2 p-4 mb-2">
<text class="text-lg font-medium mb-3 block">卖家信息</text>
<view class="flex items-center justify-between">
<view class="flex items-center">
......@@ -167,7 +167,7 @@
</view>
<!-- 底部按钮 -->
<view class="bottom-actions">
<view v-if="!isCurrentUserSeller" class="bottom-actions">
<nut-row :gutter="10">
<nut-col :span="12">
<nut-button @click="handleContactSeller" block type="default" shape="round"
......@@ -245,17 +245,20 @@
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { ref, onMounted, computed } from 'vue'
import Taro, { useShareAppMessage } from '@tarojs/taro'
import { Share, Heart1, HeartFill, Message } from '@nutui/icons-vue-taro'
import payCard from '@/components/payCard.vue'
import { useFavorite } from '@/composables/useFavorite'
import avatarImg from '@/assets/images/avatar.png'
// import avatarImg from '@/assets/images/avatar.png'
import { getCurrentPageParam } from "@/utils/weapp"
import { checkPermission, PERMISSION_TYPES } from '@/utils/permission'
// 导入接口
import { getVehicleDetailAPI } from '@/api/car'
import { createOrderAPI } from '@/api/orders'
import { DEFAULT_COVER_IMG } from '@/utils/config'
// 导入用户 store
import { useUserStore } from '@/stores/user'
// 默认头像
const defaultAvatar = 'https://cdn.ipadbiz.cn/mlaj/images/icon_1.jpeg'
......@@ -288,14 +291,14 @@ const quickTags = ref([
])
// 备用图片数组
const fallbackImages = ref([
avatarImg,
avatarImg,
avatarImg,
avatarImg,
avatarImg
])
const imageLoadErrors = ref(new Set())
// const fallbackImages = ref([
// avatarImg,
// avatarImg,
// avatarImg,
// avatarImg,
// avatarImg
// ])
// const imageLoadErrors = ref(new Set())
// 模拟商品数据
const product = ref({})
......@@ -304,13 +307,23 @@ const product = ref({})
* 轮播图切换事件
* @param {number} index - 当前图片索引
*/
// const onSwiperChange = (index) => {
// currentImageIndex.value = index
// }
const onSwiperChange = (index) => {
currentImageIndex.value = index
}
// 使用收藏功能composables
const { toggleFavorite } = useFavorite()
// 使用用户 store
const userStore = useUserStore()
/**
* 判断当前用户是否为卖家
*/
const isCurrentUserSeller = computed(() => {
return product.value.seller?.id && userStore.userInfo.id && product.value.seller.id === userStore.userInfo.id
})
/**
* 显示微信号弹框
*/
......@@ -406,11 +419,21 @@ const handlePurchase = async () => {
* @param {number} payInfo.remain_time - 剩余时间
* @param {number} payInfo.price - 价格
*/
const onPay = ({ id, remain_time, price }) => {
show_pay.value = true
payData.value.id = id
payData.value.price = price
payData.value.remain_time = remain_time
const onPay = async ({ id, remain_time, price }) => {
try {
const { code, data } = await createOrderAPI({
vehicle_id: id,
total_amount: price
})
if (code) {
show_pay.value = true
payData.value.id = data.id
payData.value.price = price
payData.value.remain_time = remain_time
}
} catch (error) {
console.error('创建订单失败:', error)
}
}
/**
......@@ -471,6 +494,9 @@ function filterEmptyValues(arr) {
}
onMounted(async () => {
// 获取用户信息
await userStore.fetchUserInfo()
// 获取商品详情
let params = getCurrentPageParam();
const { code, data } = await getVehicleDetailAPI({ id: params.id })
......