Files
mp-10584/src/views/shop/shopOrder/components/orderInfo.vue
赵忠林 e015eaef9e feat(order): 添加订单退款功能并优化用户票券页面显示
- 新增 refundShopOrder API 接口用于处理订单退款申请
- 在 shopOrder 页面添加退款相关操作按钮和逻辑
- 修改用户票券页面表格列配置,添加订单号和数量字段
- 更新订单详情页面商品数量字段映射关系
- 启用开发环境 API 地址配置
2026-02-04 17:38:51 +08:00

1114 lines
34 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!-- 用户编辑弹窗 -->
<template>
<a-drawer
:width="`65%`"
:visible="visible"
:confirm-loading="loading"
:maxable="maxAble"
:title="isUpdate ? '编辑订单' : '订单详情'"
:body-style="{ paddingBottom: '8px', background: '#f3f3f3' }"
@update:visible="updateVisible"
:footer="null"
@ok="save"
>
<template #extra>
<a-space>
<!-- 未付款状态的操作 -->
<template v-if="!form.payStatus">
<!-- 取消订单未完成且未付款 -->
<a-button
v-if="form.orderStatus === 0"
@click="handleCancelOrder"
danger
:loading="loading"
>
取消订单
</a-button>
<!-- 修改订单未完成且未付款 -->
<a-button
v-if="form.orderStatus === 0"
@click="handleEditOrder"
:loading="loading"
>
修改订单
</a-button>
</template>
<!-- 已付款状态的操作 -->
<template v-if="form.payStatus">
<!-- 发货按钮已付款且未发货且未取消 -->
<a-button
v-if="
form.deliveryStatus === 10 && !isCancelledStatus(form.orderStatus)
"
type="primary"
@click="handleDelivery"
:loading="loading"
>
发货
</a-button>
<!-- 确认收货:已发货且未完成 -->
<a-button
v-if="form.deliveryStatus === 20 && form.orderStatus === 0"
type="primary"
@click="handleConfirmReceive"
:loading="loading"
>
确认收货
</a-button>
</template>
<!-- 退款相关操作 -->
<template v-if="isRefundStatus(form.orderStatus)">
<!-- 同意退款:退款申请中或客户端申请退款 -->
<a-button
v-if="form.orderStatus === 4 || form.orderStatus === 7"
type="primary"
@click="handleApproveRefund"
:loading="loading"
>
同意退款
</a-button>
<!-- 拒绝退款:退款申请中或客户端申请退款 -->
<a-button
v-if="form.orderStatus === 4 || form.orderStatus === 7"
danger
@click="handleRejectRefund"
:loading="loading"
>
拒绝退款
</a-button>
<!-- 重新处理:退款被拒绝 -->
<a-button
v-if="form.orderStatus === 5"
@click="handleRetryRefund"
:loading="loading"
>
重新处理
</a-button>
</template>
<!-- 申请退款:已完成或已发货的订单 -->
<a-button
v-if="canApplyRefund(form)"
@click="handleApplyRefund"
:loading="loading"
>
申请退款
</a-button>
<!-- 删除订单:已完成、已取消、退款成功 -->
<a-button
v-if="canDeleteOrder(form)"
@click="handleDeleteOrder"
danger
:loading="loading"
>
删除订单
</a-button>
<!-- 关闭按钮 -->
<a-button @click="updateVisible(false)"> 关闭 </a-button>
</a-space>
</template>
<a-card title="基本信息" style="margin-bottom: 20px" :bordered="false">
<a-descriptions :column="3">
<!-- 第一排-->
<a-descriptions-item
label="订单编号"
:span="3"
:labelStyle="{ width: '90px', color: '#808080' }"
>
<span @click="copyText(form.orderNo)">{{ form.orderNo }}</span>
</a-descriptions-item>
<!-- 第二排-->
<a-descriptions-item
label="买家信息"
:labelStyle="{ width: '90px', color: '#808080' }"
>
<a-space class="flex items-center">
<a-tooltip :title="`${form.userId}`">
<a-avatar :src="form.avatar" size="small" />
</a-tooltip>
{{ form.realName }}
</a-space>
</a-descriptions-item>
<a-descriptions-item
label="订单金额"
:labelStyle="{ width: '90px', color: '#808080' }"
>
¥{{ form.totalPrice }}
</a-descriptions-item>
<a-descriptions-item
label="订单状态"
:labelStyle="{ width: '90px', color: '#808080' }"
>
<a-tag v-if="form.orderStatus === 0">未完成</a-tag>
<a-tag v-if="form.orderStatus === 1" color="green">已完成</a-tag>
<a-tag v-if="form.orderStatus === 2" color="red">已取消</a-tag>
<a-tag v-if="form.orderStatus === 3" color="red">取消中</a-tag>
<a-tag v-if="form.orderStatus === 4" color="red">退款申请中</a-tag>
<a-tag v-if="form.orderStatus === 5" color="red">退款被拒绝</a-tag>
<a-tag v-if="form.orderStatus === 6" color="orange">退款成功</a-tag>
<a-tag v-if="form.orderStatus === 7" color="pink"
>客户端申请退款</a-tag
>
</a-descriptions-item>
<!-- 第三排-->
<a-descriptions-item
label="手机号码"
:labelStyle="{ width: '90px', color: '#808080' }"
>
{{ form.phone }}
</a-descriptions-item>
<a-descriptions-item
label="实付金额"
:labelStyle="{ width: '90px', color: '#808080' }"
>
¥{{ form.payPrice }}
</a-descriptions-item>
<a-descriptions-item
label="支付状态"
:labelStyle="{ width: '90px', color: '#808080' }"
>
<a-tag v-if="form.payStatus == 1" color="green">已付款</a-tag>
<a-tag v-if="form.payStatus == 0">未付款</a-tag>
<a-tag v-if="form.payStatus == 3">未付款,占场中</a-tag>
</a-descriptions-item>
<!-- 第四排-->
<a-descriptions-item
label="下单时间"
:labelStyle="{ width: '90px', color: '#808080' }"
>
{{ toDateString(form.createTime, 'yyyy-MM-dd HH:mm') }}
</a-descriptions-item>
<a-descriptions-item
label="减少的金额"
:labelStyle="{ width: '90px', color: '#808080' }"
>
¥{{ form.reducePrice }}
</a-descriptions-item>
<a-descriptions-item
label="核销状态"
:labelStyle="{ width: '90px', color: '#808080' }"
>
<a-tag v-if="form.deliveryStatus == 10">未核销</a-tag>
<a-tag v-if="form.deliveryStatus == 20" color="green">
<a-tooltip :title="form.deliveryTime"> 已核销 </a-tooltip>
</a-tag>
<a-tag v-if="form.deliveryStatus == 30" color="blue">部分核销</a-tag>
</a-descriptions-item>
<!-- 第五排-->
<a-descriptions-item
label="交易流水号"
:labelStyle="{ width: '90px', color: '#808080' }"
>
{{ form.transactionId }}
</a-descriptions-item>
<a-descriptions-item
label="支付方式"
:labelStyle="{ width: '90px', color: '#808080' }"
>
<a-tooltip :title="`支付时间:${form.payTime || ''}`">
<template v-if="form.payStatus == 1">
<a-tag v-if="form.payType == 0">余额支付</a-tag>
<a-tag v-if="form.payType == 1">
<WechatOutlined class="tag-icon" />
微信支付
</a-tag>
<a-tag v-if="form.payType == 2">积分</a-tag>
<a-tag v-if="form.payType == 3">
<AlipayCircleOutlined class="tag-icon" />
支付宝
</a-tag>
<a-tag v-if="form.payType == 4">
<IdcardOutlined class="tag-icon" />
现金
</a-tag>
<a-tag v-if="form.payType == 5">
<IdcardOutlined class="tag-icon" />
POS机
</a-tag>
<a-tag v-if="form.payType == 6">
<IdcardOutlined class="tag-icon" />
VIP月卡
</a-tag>
<a-tag v-if="form.payType == 7">
<IdcardOutlined class="tag-icon" />
VIP年卡
</a-tag>
<a-tag v-if="form.payType == 8">
<IdcardOutlined class="tag-icon" />
VIP次卡
</a-tag>
<a-tag v-if="form.payType == 9">
<IdcardOutlined class="tag-icon" />
IC月卡
</a-tag>
<a-tag v-if="form.payType == 10">
<IdcardOutlined class="tag-icon" />
IC年卡
</a-tag>
<a-tag v-if="form.payType == 11">
<IdcardOutlined class="tag-icon" />
IC次卡
</a-tag>
<a-tag v-if="form.payType == 12">
<IdcardOutlined class="tag-icon" />
免费
</a-tag>
<a-tag v-if="form.payType == 13">
<IdcardOutlined class="tag-icon" />
VIP充值卡
</a-tag>
<a-tag v-if="form.payType == 14">
<IdcardOutlined class="tag-icon" />
IC充值卡
</a-tag>
<a-tag v-if="form.payType == 15">
<IdcardOutlined class="tag-icon" />
积分支付
</a-tag>
<a-tag v-if="form.payType == 16">
<IdcardOutlined class="tag-icon" />
VIP季卡
</a-tag>
<a-tag v-if="form.payType == 17">
<IdcardOutlined class="tag-icon" />
IC季卡
</a-tag>
<a-tag v-if="form.payType == 18">
<IdcardOutlined class="tag-icon" />
代付
</a-tag>
</template>
<template v-else>
<span class="text-gray-400">未支付</span>
</template>
</a-tooltip>
</a-descriptions-item>
<a-descriptions-item
label="开票状态"
:labelStyle="{ width: '90px', color: '#808080' }"
>
<a-tag v-if="form.isInvoice == 0">未开具</a-tag>
<a-tag v-if="form.isInvoice == 1" color="green">已开具</a-tag>
<a-tag v-if="form.isInvoice == 2" color="blue">不能开具</a-tag>
</a-descriptions-item>
<!-- 第六排-->
<!-- <a-descriptions-item-->
<!-- label="结算状态"-->
<!-- :labelStyle="{ width: '90px', color: '#808080' }"-->
<!-- >-->
<!-- <a-tag v-if="form.isSettled == 0">未结算</a-tag>-->
<!-- <a-tag v-if="form.isSettled == 1" color="green">已结算</a-tag>-->
<!-- </a-descriptions-item>-->
<!-- 第七排 -->
<!-- <a-descriptions-item-->
<!-- label="备注信息"-->
<!-- :span="3"-->
<!-- :labelStyle="{ width: '90px', color: '#808080' }"-->
<!-- >-->
<!-- {{ form.comments }}-->
<!-- </a-descriptions-item>-->
</a-descriptions>
</a-card>
<a-card title="收货信息" style="margin-bottom: 20px" :bordered="false">
<a-spin :spinning="loading">
<a-descriptions :column="2">
<a-descriptions-item
label="收货人"
:labelStyle="{ width: '90px', color: '#808080' }"
>
{{ form.realName || '未填写' }}
</a-descriptions-item>
<a-descriptions-item
label="联系电话"
:labelStyle="{ width: '90px', color: '#808080' }"
>
{{ form.phone || form.mobile || '未填写' }}
</a-descriptions-item>
<a-descriptions-item
label="收货地址"
:labelStyle="{ width: '90px', color: '#808080' }"
:span="2"
>
{{ form.address || '未填写' }}
</a-descriptions-item>
<a-descriptions-item
label="配送方式"
:labelStyle="{ width: '90px', color: '#808080' }"
>
<a-tag v-if="form.deliveryType === 0">快递配送</a-tag>
<a-tag v-else-if="form.deliveryType === 1" color="blue"
>无需发货</a-tag
>
<a-tag v-else-if="form.deliveryType === 2" color="purple"
>商家送货</a-tag
>
<a-tag v-else>未设置</a-tag>
</a-descriptions-item>
<a-descriptions-item
label="配送时间"
:labelStyle="{ width: '90px', color: '#808080' }"
>
<div v-if="form.sendStartTime && form.sendEndTime">
{{ form.sendStartTime }} - {{ form.sendEndTime }}
</div>
<span v-else class="text-gray-400">未设置</span>
</a-descriptions-item>
<a-descriptions-item
v-if="form.deliveryType === 1 && form.selfTakeMerchantName"
label="关联店铺"
:labelStyle="{ width: '90px', color: '#808080' }"
:span="2"
>
{{ form.selfTakeMerchantName || '未设置' }}
</a-descriptions-item>
<a-descriptions-item
v-if="form.deliveryType === 0 || form.deliveryType === 2"
label="发货店铺"
:labelStyle="{ width: '90px', color: '#808080' }"
:span="2"
>
{{ form.expressMerchantName || '未设置' }}
</a-descriptions-item>
<a-descriptions-item
v-if="form.deliveryType === 1 && form.deliveryNote"
label="无需发货备注"
:labelStyle="{ width: '90px', color: '#808080' }"
:span="2"
>
{{ form.deliveryNote }}
</a-descriptions-item>
<a-descriptions-item
v-if="form.selfTakeCode"
label="自提码"
:labelStyle="{ width: '90px', color: '#808080' }"
>
<a-tag
color="orange"
@click="copyText(form.selfTakeCode)"
class="cursor-pointer"
>
{{ form.selfTakeCode }}
</a-tag>
</a-descriptions-item>
</a-descriptions>
</a-spin>
</a-card>
<a-card
v-if="form.shopOrderDelivery"
title="发货信息"
style="margin-bottom: 20px"
:bordered="false"
>
<a-spin :spinning="loading">
<a-descriptions :column="2">
<a-descriptions-item
label="发货人"
:labelStyle="{ width: '90px', color: '#808080' }"
>
{{ form.shopOrderDelivery.sendName || '未填写' }}
</a-descriptions-item>
<a-descriptions-item
label="联系电话"
:labelStyle="{ width: '90px', color: '#808080' }"
>
{{ form.shopOrderDelivery.sendPhone || '未填写' }}
</a-descriptions-item>
<a-descriptions-item
label="发货地址"
:labelStyle="{ width: '90px', color: '#808080' }"
:span="2"
>
{{ form.shopOrderDelivery.sendAddress || '未填写' }}
</a-descriptions-item>
<a-descriptions-item
label="快递公司"
:labelStyle="{ width: '90px', color: '#808080' }"
>
{{ form.shopOrderDelivery.expressName || '未填写' }}
</a-descriptions-item>
<a-descriptions-item
label="物流单号"
:labelStyle="{ width: '90px', color: '#808080' }"
>
{{ form.shopOrderDelivery.expressNo || '未填写' }}
</a-descriptions-item>
</a-descriptions>
</a-spin>
</a-card>
<a-card title="商品信息" style="margin-bottom: 20px" :bordered="false">
<a-spin :spinning="loading">
<a-table
:data-source="orderGoods"
:columns="columns"
:pagination="false"
>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'goodsName'">
<div style="display: flex; align-items: center; gap: 12px">
<a-avatar
:src="record.image || record.goodsImage"
shape="square"
:size="50"
style="flex-shrink: 0"
/>
<span style="flex: 1">{{
record.goodsName || '未知商品'
}}</span>
</div>
</template>
</template>
</a-table>
</a-spin>
</a-card>
<a-card title="买家留言" style="margin-bottom: 20px" :bordered="false">
<a-spin :spinning="loading">
{{ form.buyerRemarks || '-' }}
</a-spin>
</a-card>
<a-card title="商家备注" style="margin-bottom: 20px" :bordered="false">
<a-spin :spinning="loading">
{{ form.merchantRemarks || '-' }}
</a-spin>
</a-card>
<!-- 发货弹窗 -->
<DeliveryModal
v-model:visible="showDelivery"
:data="form"
@done="handleDeliveryDone"
/>
</a-drawer>
</template>
<script lang="ts" setup>
import { ref, reactive, watch } from 'vue';
import { Form } from 'ant-design-vue';
import { assignObject } from 'ele-admin-pro';
import {
WechatOutlined,
AlipayCircleOutlined,
IdcardOutlined
} from '@ant-design/icons-vue';
import { ShopOrder } from '@/api/shop/shopOrder/model';
import { BszxPay } from '@/api/bszx/bszxPay/model';
import { toDateString } from 'ele-admin-pro';
import { copyText } from '@/utils/common';
import { listShopOrderGoods } from '@/api/shop/shopOrderGoods';
import { updateShopOrder, removeShopOrder } from '@/api/shop/shopOrder';
import { message, Modal } from 'ant-design-vue';
import DeliveryModal from './deliveryModal.vue';
const useForm = Form.useForm;
const props = defineProps<{
// 弹窗是否打开
visible: boolean;
// 修改回显的数据
data?: ShopOrder | null;
}>();
interface Step {
title?: string | undefined;
subTitle?: string | undefined;
description?: string | undefined;
}
// 是否是修改
const isUpdate = ref(false);
// 是否显示最大化切换按钮
const maxAble = ref(true);
// 订单信息
const orderGoods = ref<BszxPay[]>([]);
// 是否显示发货弹窗
const showDelivery = ref(false);
// 步骤条
const steps = ref<Step[]>([
{
title: '报餐',
description: undefined
},
{
title: '付款',
description: undefined
},
{
title: '发餐',
description: undefined
},
{
title: '取餐',
description: undefined
},
{
title: '完成',
description: undefined
}
]);
const active = ref(2);
const emit = defineEmits<{
(e: 'done'): void;
(e: 'update:visible', visible: boolean): void;
}>();
// 订单信息
const form = reactive<ShopOrder>({
// 订单号
orderId: undefined,
// 订单编号
orderNo: undefined,
// 订单类型0商城订单 1预定订单/外卖 2会员卡
type: undefined,
// 快递/自提
deliveryType: undefined,
// 下单渠道0小程序预定 1俱乐部训练场 3活动订场
channel: undefined,
// 微信支付订单号
transactionId: undefined,
// 微信退款订单号
refundOrder: undefined,
// 商户ID
merchantId: undefined,
// 商户名称
merchantName: undefined,
// 商户编号
merchantCode: undefined,
// 使用的优惠券id
couponId: undefined,
// 使用的会员卡id
cardId: undefined,
// 关联管理员id
adminId: undefined,
// 核销管理员id
confirmId: undefined,
// IC卡号
icCard: undefined,
// 头像
avatar: undefined,
// 真实姓名
realName: undefined,
// 手机号码
phone: undefined,
// 收货地址
address: undefined,
//
addressLat: undefined,
//
addressLng: undefined,
// 自提店铺id
selfTakeMerchantId: undefined,
// 自提店铺
selfTakeMerchantName: undefined,
// 配送开始时间
sendStartTime: undefined,
// 配送结束时间
sendEndTime: undefined,
// 发货店铺id
expressMerchantId: undefined,
// 发货店铺
expressMerchantName: undefined,
// 订单总额
totalPrice: undefined,
// 减少的金额使用VIP会员折扣、优惠券抵扣、优惠券折扣后减去的价格
reducePrice: undefined,
// 实际付款
payPrice: undefined,
// 用于统计
price: undefined,
// 价钱,用于积分赠送
money: undefined,
// 退款金额
refundMoney: undefined,
// 教练价格
coachPrice: undefined,
// 购买数量
totalNum: undefined,
// 教练id
coachId: undefined,
// 支付的用户id
payUserId: undefined,
// 0余额支付, 1微信支付102微信Native2会员卡支付3支付宝4现金5POS机6VIP月卡7VIP年卡8VIP次卡9IC月卡10IC年卡11IC次卡12免费13VIP充值卡14IC充值卡15积分支付16VIP季卡17IC季卡18代付
payType: undefined,
// 代付支付方式,0余额支付, 1微信支付102微信Native2会员卡支付3支付宝4现金5POS机6VIP月卡7VIP年卡8VIP次卡9IC月卡10IC年卡11IC次卡12免费13VIP充值卡14IC充值卡15积分支付16VIP季卡17IC季卡18代付
friendPayType: undefined,
// 0未付款1已付款
payStatus: undefined,
// 0未使用1已完成2已取消3取消中4退款申请中5退款被拒绝6退款成功7客户端申请退款
orderStatus: undefined,
// 发货状态(10未发货 20已发货 30部分发货)
deliveryStatus: undefined,
// 发货时间
deliveryTime: undefined,
// 无需发货备注
deliveryNote: undefined,
// 优惠类型0无、1抵扣优惠券、2折扣优惠券、3、VIP月卡、4VIP年卡5VIP次卡、6VIP会员卡、7IC月卡、8IC年卡、9IC次卡、10IC会员卡、11免费订单、12VIP充值卡、13IC充值卡、14VIP季卡、15IC季卡
couponType: undefined,
// 优惠说明
couponDesc: undefined,
// 二维码地址,保存订单号,支付成功后才生成
qrcode: undefined,
// vip月卡年卡、ic月卡年卡回退次数
returnNum: undefined,
// vip充值回退金额
returnMoney: undefined,
// 预约详情开始时间数组
startTime: undefined,
// 是否已开具发票0未开发票1已开发票2不能开具发票
isInvoice: undefined,
// 发票流水号
invoiceNo: undefined,
// 支付时间
payTime: undefined,
// 退款时间
refundTime: undefined,
// 申请退款时间
refundApplyTime: undefined,
// 过期时间
expirationTime: undefined,
// 对账情况0=未对账1=已对账3=已对账金额对不上4=未查询到该订单
checkBill: undefined,
// 订单是否已结算(0未结算 1已结算)
isSettled: undefined,
// 系统版本号 0当前版本 value=其他版本
version: undefined,
// 用户id
userId: undefined,
// 备注
comments: undefined,
// 买家备注
buyerRemarks: undefined,
// 商家备注
merchantRemarks: undefined,
// 排序号
sortNumber: undefined,
// 是否删除, 0否, 1是
deleted: undefined,
// 租户id
tenantId: undefined,
// 修改时间
updateTime: undefined,
// 创建时间
createTime: undefined,
// 自提码
selfTakeCode: undefined,
// 是否已收到赠品
hasTakeGift: undefined,
// 发货信息
shopOrderDelivery: undefined
});
// 请求状态
const loading = ref(true);
const { resetFields } = useForm(form);
/* 更新visible */
const updateVisible = (value: boolean) => {
emit('update:visible', value);
};
const columns = ref([
{
title: '商品名称',
dataIndex: 'goodsName',
key: 'goodsName',
width: 280
},
{
title: '金额',
dataIndex: 'price',
align: 'center' as const,
customRender: ({ record }: { record: any }) => {
return `¥${record.price || 0}`;
}
},
{
title: '数量',
dataIndex: 'totalNum',
align: 'center' as const,
customRender: ({ record }: { record: any }) => {
return record.totalNum || 1;
}
},
{
title: '备注',
dataIndex: 'comments',
key: 'comments',
align: 'center' as const
},
{
title: '是否免费',
dataIndex: 'isFree',
align: 'center' as const,
customRender: ({ record }: { record: any }) => {
return record.isFree ? '是' : '否';
}
}
]);
/* 制作步骤条 */
const loadSteps = (order: ShopOrder) => {
steps.value = [
{
title: '下单',
description: order.createTime
? toDateString(order.createTime, 'MM-dd HH:mm')
: undefined
},
{
title: '付款',
description: undefined
},
{
title: '发货',
description: undefined
},
{
title: '收货',
description: undefined
},
{
title: '完成',
description: undefined
}
];
// 根据订单状态设置当前步骤
if (order.orderStatus === 2) {
// 已取消
active.value = -1;
steps.value = [
{
title: '下单',
description: order.createTime
? toDateString(order.createTime, 'MM-dd HH:mm')
: undefined
},
{
title: '已取消',
description: '订单已取消'
}
];
} else if (order.payStatus === 0) {
// 未付款
active.value = 0;
} else if (order.payStatus === 1) {
// 已付款
active.value = 1;
steps.value[1].description = order.payTime
? toDateString(order.payTime, 'MM-dd HH:mm')
: '已付款';
if (order.deliveryStatus === 20) {
// 已发货
active.value = 2;
steps.value[2].description = order.deliveryTime
? toDateString(order.deliveryTime, 'MM-dd HH:mm')
: '已发货';
if (order.orderStatus === 1) {
// 已完成
active.value = 4;
steps.value[3].description = '已收货';
steps.value[4].description = '订单完成';
}
}
}
};
// const getOrderInfo = () => {
// const orderId = props.data?.orderId;
// listOrderInfo({ orderId }).then((data) => {
// orderGoods.value = data.filter((d) => d.totalNum > 0);
// });
// };
/* 发货处理 */
const handleDelivery = () => {
showDelivery.value = true;
};
/* 发货完成回调 */
const handleDeliveryDone = () => {
showDelivery.value = false;
emit('done');
// 重新加载订单数据以更新显示
if (props.data?.orderId) {
// 这里可以重新获取订单数据,或者直接关闭弹窗让父组件刷新
updateVisible(false);
}
};
/* 取消订单 */
const handleCancelOrder = () => {
Modal.confirm({
title: '确认取消订单',
content: '确定要取消此订单吗?取消后无法恢复。',
onOk: async () => {
try {
loading.value = true;
await updateShopOrder({
...form,
orderStatus: 2 // 已取消
});
message.success('订单已取消');
emit('done');
updateVisible(false);
} catch (error: any) {
message.error(error.message || '取消订单失败');
} finally {
loading.value = false;
}
}
});
};
/* 删除订单 */
const handleDeleteOrder = () => {
Modal.confirm({
title: '确认删除订单',
content: '确定要删除此订单吗?删除后无法恢复。',
onOk: async () => {
try {
loading.value = true;
if (form.orderId) {
await removeShopOrder(form.orderId);
message.success('订单已删除');
emit('done');
updateVisible(false);
}
} catch (error: any) {
message.error(error.message || '删除订单失败');
} finally {
loading.value = false;
}
}
});
};
/* 辅助判断函数 */
// 判断是否为取消状态
const isCancelledStatus = (orderStatus?: number) => {
return [2, 3].includes(orderStatus || 0);
};
// 判断是否为退款相关状态
const isRefundStatus = (orderStatus?: number) => {
return [4, 5, 6, 7].includes(orderStatus || 0);
};
// 判断是否可以删除订单
const canDeleteOrder = (order: ShopOrder) => {
// 已完成、已取消、退款成功的订单可以删除 (原来是[1, 2, 6],后面改成只有取消的订单能删除)
return [2].includes(order.orderStatus || 0);
};
// 判断是否可以申请退款
const canApplyRefund = (order: ShopOrder) => {
// 已完成或已发货且未申请退款的订单可以申请退款
return (
order.orderStatus === 1 ||
(order.payStatus === 1 &&
order.deliveryStatus === 20 &&
order.orderStatus === 0)
);
};
/* 确认收货(管理员代操作) */
const handleConfirmReceive = () => {
Modal.confirm({
title: '确认收货',
content: '确定要将此订单标记为已收货并完成吗?',
onOk: async () => {
try {
loading.value = true;
await updateShopOrder({
...form,
deliveryStatus: 30, // 已收货
orderStatus: 1 // 已完成
});
message.success('确认收货成功');
emit('done');
updateVisible(false);
} catch (error: any) {
message.error(error.message || '确认收货失败');
} finally {
loading.value = false;
}
}
});
};
/* 同意退款 */
const handleApproveRefund = () => {
Modal.confirm({
title: '同意退款',
content: '确定要同意此订单的退款申请吗?',
onOk: async () => {
try {
loading.value = true;
// 格式化日期为后端期望的格式
const now = new Date();
const refundTime = toDateString(now, 'yyyy-MM-dd HH:mm:ss');
await updateShopOrder({
...form,
orderStatus: 6, // 退款成功
refundTime: refundTime
});
message.success('退款处理成功');
emit('done');
updateVisible(false);
} catch (error: any) {
message.error(error.message || '退款处理失败');
} finally {
loading.value = false;
}
}
});
};
/* 拒绝退款 */
const handleRejectRefund = () => {
Modal.confirm({
title: '拒绝退款',
content: '确定要拒绝此订单的退款申请吗?',
onOk: async () => {
try {
loading.value = true;
await updateShopOrder({
...form,
orderStatus: 5 // 退款被拒绝
});
message.success('已拒绝退款申请');
emit('done');
updateVisible(false);
} catch (error: any) {
message.error(error.message || '操作失败');
} finally {
loading.value = false;
}
}
});
};
/* 重新处理退款 */
const handleRetryRefund = () => {
Modal.confirm({
title: '重新处理退款',
content: '确定要重新处理此订单的退款吗?',
onOk: async () => {
try {
loading.value = true;
await updateShopOrder({
...form,
orderStatus: 4 // 退款申请中
});
message.success('已重新提交退款申请');
emit('done');
updateVisible(false);
} catch (error: any) {
message.error(error.message || '操作失败');
} finally {
loading.value = false;
}
}
});
};
/* 申请退款 */
const handleApplyRefund = () => {
Modal.confirm({
title: '申请退款',
content: '确定要为此订单申请退款吗?',
onOk: async () => {
try {
loading.value = true;
// 格式化日期为后端期望的格式
const now = new Date();
const refundApplyTime = toDateString(now, 'yyyy-MM-dd HH:mm:ss');
await updateShopOrder({
...form,
orderStatus: 4, // 退款申请中
refundApplyTime: refundApplyTime
});
message.success('退款申请已提交');
emit('done');
updateVisible(false);
} catch (error: any) {
message.error(error.message || '申请退款失败');
} finally {
loading.value = false;
}
}
});
};
/* 修改订单 */
const handleEditOrder = () => {
message.info('订单修改功能开发中...');
// TODO: 实现订单修改功能
};
/* 保存编辑 */
const save = () => {
// 保留原有的保存功能
};
watch(
() => props.visible,
(visible) => {
if (visible) {
if (props.data) {
loading.value = true;
assignObject(form, props.data);
// 加载订单商品
if (form.orderId) {
listShopOrderGoods({ orderId: form.orderId })
.then((data) => {
orderGoods.value = data || [];
})
.catch((error) => {
console.error('加载订单商品失败:', error);
orderGoods.value = [];
})
.finally(() => {
loading.value = false;
});
} else {
loading.value = false;
}
loadSteps(props.data);
}
} else {
resetFields();
orderGoods.value = [];
}
}
);
</script>
<script lang="ts">
import * as MenuIcons from '@/layout/menu-icons';
export default {
name: 'BszxOrderInfo',
components: MenuIcons
};
</script>