优化:重新设计不同订单状态下的按钮

This commit is contained in:
2025-08-10 22:32:12 +08:00
parent f413d19076
commit 40b46545b3
9 changed files with 1512 additions and 64 deletions

View File

@@ -13,29 +13,95 @@
>
<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="form.payStatus === 1 && form.deliveryStatus === 10"
type="primary"
@click="handleDelivery"
v-if="canApplyRefund(form)"
@click="handleApplyRefund"
:loading="loading"
>
发货
申请退款
</a-button>
<!-- 取消订单按钮完成且未取消时显示 -->
<!-- 删除订单完成已取消退款成功 -->
<a-button
v-if="form.orderStatus === 0"
@click="handleCancelOrder"
danger
:loading="loading"
>
取消订单
</a-button>
<!-- 删除订单按钮已取消或已完成时显示 -->
<a-button
v-if="form.orderStatus === 1 || form.orderStatus === 2"
v-if="canDeleteOrder(form)"
@click="handleDeleteOrder"
danger
:loading="loading"
@@ -692,10 +758,14 @@ const handleDelivery = () => {
onOk: async () => {
try {
loading.value = true;
// 格式化日期为后端期望的格式
const now = new Date();
const deliveryTime = toDateString(now, 'yyyy-MM-dd HH:mm:ss');
await updateShopOrder({
...form,
deliveryStatus: 20, // 已发货
deliveryTime: new Date().toISOString()
deliveryTime: deliveryTime
});
message.success('发货成功');
emit('done');
@@ -756,6 +826,167 @@ const handleDeleteOrder = () => {
});
};
/* 辅助判断函数 */
// 判断是否为取消状态
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) => {
// 已完成、已取消、退款成功的订单可以删除
return [1, 2, 6].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 = () => {
// 保留原有的保存功能

View File

@@ -1,18 +1,18 @@
<!-- 搜索表单 -->
<template>
<a-space :size="10" style="flex-wrap: wrap">
<a-button
danger
type="primary"
class="ele-btn-icon"
:disabled="selection?.length === 0"
@click="removeBatch"
>
<template #icon>
<DeleteOutlined/>
</template>
<span>批量删除</span>
</a-button>
<!-- <a-button-->
<!-- danger-->
<!-- type="primary"-->
<!-- class="ele-btn-icon"-->
<!-- :disabled="selection?.length === 0"-->
<!-- @click="removeBatch"-->
<!-- >-->
<!-- <template #icon>-->
<!-- <DeleteOutlined/>-->
<!-- </template>-->
<!-- <span>批量删除</span>-->
<!-- </a-button>-->
<a-select
v-model:value="where.type"
style="width: 150px"

View File

@@ -16,9 +16,10 @@
<a-tab-pane key="undelivered" tab="待发货"/>
<a-tab-pane key="unreceived" tab="待收货"/>
<a-tab-pane key="completed" tab="已完成"/>
<a-tab-pane key="deleted" tab="已取消"/>
<a-tab-pane key="cancelled" tab="已取消"/>
<!-- <a-tab-pane key="unevaluated" tab="待评价"/>-->
<!-- <a-tab-pane key="refunded" tab="已退款"/>-->
<a-tab-pane key="refunded" tab="已退款"/>
<!-- <a-tab-pane key="deleted" tab="已删除"/>-->
</a-tabs>
<ele-pro-table
ref="tableRef"
@@ -26,7 +27,6 @@
:columns="columns"
:datasource="datasource"
:customRow="customRow"
v-model:selection="selection"
:toolbar="false"
tool-class="ele-toolbar-form"
class="sys-org-table"
@@ -63,10 +63,10 @@
</template>
</template>
<template v-if="column.key === 'payStatus'">
<a-tag v-if="record.payStatus == 1" color="green" @click.stop="updatePayStatus(record)"
<a-tag v-if="record.payStatus" color="green" @click.stop="updatePayStatus(record)"
class="cursor-pointer">已付款
</a-tag>
<a-tag v-if="record.payStatus == 0" @click.stop="updatePayStatus(record)" class="cursor-pointer">未付款
<a-tag v-if="!record.payStatus" @click.stop="updatePayStatus(record)" class="cursor-pointer">未付款
</a-tag>
<a-tag v-if="record.payStatus == 3">未付款,占场中</a-tag>
</template>
@@ -78,9 +78,9 @@
<a-tag v-if="record.sex === 2"></a-tag>
</template>
<template v-if="column.key === 'deliveryStatus'">
<a-tag v-if="record.deliveryStatus == 10">核销</a-tag>
<a-tag v-if="record.deliveryStatus == 20" color="green">核销</a-tag>
<a-tag v-if="record.deliveryStatus == 30" color="bule">部分核销</a-tag>
<a-tag v-if="record.deliveryStatus == 10">发货</a-tag>
<a-tag v-if="record.deliveryStatus == 20" color="green">发货</a-tag>
<a-tag v-if="record.deliveryStatus == 30" color="bule">部分发货</a-tag>
</template>
<template v-if="column.key === 'orderStatus'">
<a-tag v-if="record.orderStatus === 0">未完成</a-tag>
@@ -102,16 +102,92 @@
<a-tag v-if="record.status === 1" color="red">隐藏</a-tag>
</template>
<template v-if="column.key === 'action'">
<a-space>
<a @click.stop="openEdit(record)">修改</a>
<a-divider type="vertical"/>
<a-popconfirm
title="确定要删除此记录吗?"
@confirm.stop="remove(record)"
>
<a class="ele-text-danger">删除</a>
</a-popconfirm>
</a-space>
<!-- 查看详情 - 所有状态都可以查看 -->
<a @click.stop="openEdit(record)">
<EyeOutlined /> 详情
</a>
<!-- 未付款状态的操作 -->
<template v-if="!record.payStatus && record.orderStatus === 0">
<a-divider type="vertical"/>
<a @click.stop="handleEditOrder(record)">
<EditOutlined /> 修改
</a>
<a-divider type="vertical"/>
<a
@click.stop="openEdit(record)"
>
<a class="ele-text-warning">
<CloseOutlined /> 取消
</a>
</a>
</template>
<!-- 已付款未发货状态的操作 -->
<template v-if="record.payStatus && record.deliveryStatus === 10 && !isCancelledStatus(record.orderStatus)">
<a-divider type="vertical"/>
<a @click.stop="handleDelivery(record)" class="ele-text-primary">
<SendOutlined /> 发货
</a>
<a-divider type="vertical"/>
<a @click.stop="handleApplyRefund(record)">
<UndoOutlined /> 退款
</a>
</template>
<!-- 已发货未完成状态的操作 -->
<template v-if="record.payStatus && record.deliveryStatus === 20 && record.orderStatus === 0">
<a-divider type="vertical"/>
<a @click.stop="handleConfirmReceive(record)" class="ele-text-primary">
<CheckOutlined /> 确认收货
</a>
<a-divider type="vertical"/>
<a @click.stop="handleApplyRefund(record)">
<UndoOutlined /> 退款
</a>
</template>
<!-- 退款相关状态的操作 -->
<template v-if="isRefundStatus(record.orderStatus)">
<template v-if="record.orderStatus === 4 || record.orderStatus === 7">
<a-divider type="vertical"/>
<a @click.stop="handleApproveRefund(record)" class="ele-text-success">
<CheckCircleOutlined /> 同意退款
</a>
<a-divider type="vertical"/>
<a @click.stop="handleRejectRefund(record)" class="ele-text-danger">
<CloseCircleOutlined /> 拒绝退款
</a>
</template>
<template v-if="record.orderStatus === 5">
<a-divider type="vertical"/>
<a @click.stop="handleRetryRefund(record)">
<RedoOutlined /> 重新处理
</a>
</template>
</template>
<!-- 已完成状态的操作 -->
<template v-if="record.orderStatus === 1">
<a-divider type="vertical"/>
<a @click.stop="handleApplyRefund(record)">
<UndoOutlined /> 申请退款
</a>
</template>
<!-- 删除操作 - 已完成已取消退款成功的订单可以删除 -->
<template v-if="canDeleteOrder(record)">
<a-divider type="vertical"/>
<a-popconfirm
title="确定要删除此订单吗?删除后无法恢复。"
@confirm.stop="remove(record)"
>
<a class="ele-text-danger">
<DeleteOutlined /> 删除
</a>
</a-popconfirm>
</template>
</template>
</template>
</ele-pro-table>
@@ -130,14 +206,24 @@ import type {
ColumnItem
} from 'ele-admin-pro/es/ele-pro-table/types';
import {
ExclamationCircleOutlined
ExclamationCircleOutlined,
EyeOutlined,
EditOutlined,
CloseOutlined,
SendOutlined,
UndoOutlined,
CheckOutlined,
CheckCircleOutlined,
CloseCircleOutlined,
RedoOutlined,
DeleteOutlined
} from '@ant-design/icons-vue';
import Search from './components/search.vue';
import {getPageTitle} from "@/utils/common";
import {toDateString} from 'ele-admin-pro';
import OrderInfo from './components/orderInfo.vue';
import {ShopOrder, ShopOrderParam} from "@/api/shop/shopOrder/model";
import {pageShopOrder, repairOrder, removeShopOrder, removeBatchShopOrder} from "@/api/shop/shopOrder";
import {pageShopOrder, repairOrder, removeShopOrder, removeBatchShopOrder, updateShopOrder} from "@/api/shop/shopOrder";
import {updateUser} from "@/api/system/user";
import {getPayType} from '@/utils/shop';
import {message, Modal} from 'ant-design-vue';
@@ -189,7 +275,7 @@ const columns = ref<ColumnItem[]>([
title: '商品信息',
dataIndex: 'orderGoods',
key: 'orderGoods',
width: 400,
width: 360,
},
{
title: '实付金额',
@@ -211,7 +297,7 @@ const columns = ref<ColumnItem[]>([
align: 'center'
},
{
title: '核销状态',
title: '发货状态',
dataIndex: 'deliveryStatus',
key: 'deliveryStatus',
align: 'center',
@@ -229,6 +315,12 @@ const columns = ref<ColumnItem[]>([
align: 'center',
},
// {
// title: '备注',
// dataIndex: 'comments',
// key: 'comments',
// align: 'center',
// },
// {
// title: '支付时间',
// dataIndex: 'payTime',
// key: 'payTime',
@@ -246,15 +338,15 @@ const columns = ref<ColumnItem[]>([
sorter: true,
ellipsis: true,
customRender: ({text}) => toDateString(text)
},
{
title: '操作',
key: 'action',
width: 280,
fixed: 'right',
align: 'center',
hideInSetting: true
}
// {
// title: '操作',
// key: 'action',
// width: 180,
// fixed: 'right',
// align: 'center',
// hideInSetting: true
// }
]);
/* 搜索 */
@@ -298,6 +390,10 @@ const onTabs = () => {
// 已完成order_status = 1
filterParams.statusFilter = 5;
break;
case 'cancelled':
// 已取消order_status = 2
filterParams.statusFilter = 8;
break;
case 'refunded':
// 已退款order_status = 6
filterParams.statusFilter = 6;
@@ -351,6 +447,183 @@ const query = () => {
loading.value = true;
};
/* 辅助判断函数 */
// 判断是否为取消状态
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) => {
// 已完成、已取消、退款成功的订单可以删除
return [1, 2, 6].includes(order.orderStatus || 0);
};
/* 订单操作方法 */
// 修改订单
const handleEditOrder = (record: ShopOrder) => {
message.info('订单修改功能开发中...');
// TODO: 实现订单修改功能
};
// 取消订单
const handleCancelOrder = (record: ShopOrder) => {
Modal.confirm({
title: '确认取消订单',
content: '确定要取消此订单吗?取消后无法恢复。',
onOk: async () => {
try {
await updateShopOrder({
...record,
orderStatus: 2 // 已取消
});
message.success('订单已取消');
reload();
} catch (error: any) {
message.error(error.message || '取消订单失败');
}
}
});
};
// 发货处理
const handleDelivery = (record: ShopOrder) => {
Modal.confirm({
title: '确认发货',
content: '确定要将此订单标记为已发货吗?',
onOk: async () => {
try {
const now = new Date();
const deliveryTime = toDateString(now, 'yyyy-MM-dd HH:mm:ss');
await updateShopOrder({
...record,
deliveryStatus: 20, // 已发货
deliveryTime: deliveryTime
});
message.success('发货成功');
reload();
} catch (error: any) {
message.error(error.message || '发货失败');
}
}
});
};
// 确认收货
const handleConfirmReceive = (record: ShopOrder) => {
Modal.confirm({
title: '确认收货',
content: '确定要将此订单标记为已收货并完成吗?',
onOk: async () => {
try {
await updateShopOrder({
...record,
deliveryStatus: 30, // 已收货
orderStatus: 1 // 已完成
});
message.success('确认收货成功');
reload();
} catch (error: any) {
message.error(error.message || '确认收货失败');
}
}
});
};
// 同意退款
const handleApproveRefund = (record: ShopOrder) => {
Modal.confirm({
title: '同意退款',
content: '确定要同意此订单的退款申请吗?',
onOk: async () => {
try {
const now = new Date();
const refundTime = toDateString(now, 'yyyy-MM-dd HH:mm:ss');
await updateShopOrder({
...record,
orderStatus: 6, // 退款成功
refundTime: refundTime
});
message.success('退款处理成功');
reload();
} catch (error: any) {
message.error(error.message || '退款处理失败');
}
}
});
};
// 拒绝退款
const handleRejectRefund = (record: ShopOrder) => {
Modal.confirm({
title: '拒绝退款',
content: '确定要拒绝此订单的退款申请吗?',
onOk: async () => {
try {
await updateShopOrder({
...record,
orderStatus: 5 // 退款被拒绝
});
message.success('已拒绝退款申请');
reload();
} catch (error: any) {
message.error(error.message || '操作失败');
}
}
});
};
// 重新处理退款
const handleRetryRefund = (record: ShopOrder) => {
Modal.confirm({
title: '重新处理退款',
content: '确定要重新处理此订单的退款吗?',
onOk: async () => {
try {
await updateShopOrder({
...record,
orderStatus: 4 // 退款申请中
});
message.success('已重新提交退款申请');
reload();
} catch (error: any) {
message.error(error.message || '操作失败');
}
}
});
};
// 申请退款
const handleApplyRefund = (record: ShopOrder) => {
Modal.confirm({
title: '申请退款',
content: '确定要为此订单申请退款吗?',
onOk: async () => {
try {
const now = new Date();
const refundApplyTime = toDateString(now, 'yyyy-MM-dd HH:mm:ss');
await updateShopOrder({
...record,
orderStatus: 4, // 退款申请中
refundApplyTime: refundApplyTime
});
message.success('退款申请已提交');
reload();
} catch (error: any) {
message.error(error.message || '申请退款失败');
}
}
});
};
/* 删除单个订单 */
const remove = (row: ShopOrder) => {
removeShopOrder(row.orderId)

View File

@@ -165,11 +165,11 @@ function OrderList(props: OrderListProps) {
statusParams,
searchConditions
});
try {
const res = await pageShopOrder(searchConditions);
let newList: OrderWithGoods[] = [];
if (res?.list && res?.list.length > 0) {
// 为每个订单获取商品信息
const ordersWithGoods = await Promise.all(
@@ -197,7 +197,7 @@ function OrderList(props: OrderListProps) {
newList = [];
setHasMore(false);
}
setList(newList || []);
setPage(currentPage);
setLoading(false);
@@ -212,6 +212,11 @@ function OrderList(props: OrderListProps) {
reload();
};
// 格式化日期为后端期望的格式
const formatDateForBackend = (date: Date) => {
return dayjs(date).format('YYYY-MM-DD HH:mm:ss');
};
// 确认收货
const confirmReceive = async (order: ShopOrder) => {
try {