feat: mall pickUpOrder

pull/135/head^2
xingyu4j 2025-06-09 17:16:22 +08:00
parent c6a627c95b
commit e2d1dacbf9
3 changed files with 227 additions and 33 deletions

View File

@ -176,13 +176,13 @@ export namespace MallOrderApi {
/** 交易订单统计 */ /** 交易订单统计 */
export interface OrderSummary { export interface OrderSummary {
/** 订单数量 */ /** 订单数量 */
orderCount?: number; orderCount: number;
/** 订单金额 */ /** 订单金额 */
orderPayPrice?: string; orderPayPrice: number;
/** 退款单数 */ /** 退款单数 */
afterSaleCount?: number; afterSaleCount: number;
/** 退款金额 */ /** 退款金额 */
afterSalePrice?: string; afterSalePrice: number;
} }
/** 订单发货请求 */ /** 订单发货请求 */

View File

@ -0,0 +1,126 @@
import type { VbenFormSchema } from '#/adapter/form';
import type { VxeGridPropTypes } from '#/adapter/vxe-table';
import type { MallDeliveryPickUpStoreApi } from '#/api/mall/trade/delivery/pickUpStore';
import { ref } from 'vue';
import { getSimpleDeliveryPickUpStoreList } from '#/api/mall/trade/delivery/pickUpStore';
import {
DeliveryTypeEnum,
DICT_TYPE,
getRangePickerDefaultProps,
} from '#/utils';
const pickUpStoreList = ref<MallDeliveryPickUpStoreApi.PickUpStore[]>([]);
getSimpleDeliveryPickUpStoreList().then((res) => {
pickUpStoreList.value = res;
});
/** 列表的搜索表单 */
export function useGridFormSchema(): VbenFormSchema[] {
return [
{
fieldName: 'createTime',
label: '创建时间',
component: 'RangePicker',
componentProps: {
...getRangePickerDefaultProps(),
allowClear: true,
},
},
{
fieldName: 'pickUpStoreId',
label: '自提门店',
component: 'ApiSelect',
componentProps: {
api: getSimpleDeliveryPickUpStoreList,
fieldNames: {
label: 'name',
value: 'id',
},
},
dependencies: {
triggerFields: ['deliveryType'],
show: (values) => values.deliveryType === DeliveryTypeEnum.PICK_UP.type,
},
},
];
}
/** 表格列配置 */
export function useGridColumns(): VxeGridPropTypes.Columns {
return [
{
field: 'no',
title: '订单号',
fixed: 'left',
minWidth: 180,
},
{
field: 'user.nickname',
title: '用户信息',
minWidth: 100,
},
{
field: 'brokerageUser.nickname',
title: '推荐人信息',
minWidth: 100,
},
{
field: 'spuName',
title: '商品信息',
minWidth: 100,
formatter: ({ row }) => {
if (row.items.length > 1) {
return row.items.map((item: any) => item.spuName).join(',');
}
},
},
{
field: 'payPrice',
title: '实付金额(元)',
formatter: 'formatAmount2',
minWidth: 180,
},
{
field: 'storeStaffName',
title: '核销员',
minWidth: 160,
},
{
field: 'pickUpStoreId',
title: '核销门店',
minWidth: 160,
formatter: ({ row }) => {
return pickUpStoreList.value.find(
(item) => item.id === row.pickUpStoreId,
)?.name;
},
},
{
field: 'payStatus',
title: '支付状态',
cellRender: {
name: 'CellDict',
props: { type: DICT_TYPE.INFRA_BOOLEAN_STRING },
},
minWidth: 80,
},
{
field: 'status',
title: '订单状态',
cellRender: {
name: 'CellDict',
props: { type: DICT_TYPE.TRADE_ORDER_STATUS },
},
minWidth: 80,
},
{
field: 'createTime',
title: '下单时间',
formatter: 'formatDateTime',
minWidth: 160,
},
];
}

View File

@ -1,38 +1,106 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { MallOrderApi } from '#/api/mall/trade/order';
import { onMounted, ref } from 'vue';
import { Page } from '@vben/common-ui'; import { Page } from '@vben/common-ui';
import { Button } from 'ant-design-vue'; import { Card } from 'ant-design-vue';
import { DocAlert } from '#/components/doc-alert'; import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { getOrderPage, getOrderSummary } from '#/api/mall/trade/order';
import { SummaryCard } from '#/components/summary-card';
import { DeliveryTypeEnum, fenToYuan } from '#/utils';
import { useGridColumns, useGridFormSchema } from './data';
const summary = ref<MallOrderApi.OrderSummary>();
async function getOrderSum() {
const query = await gridApi.formApi.getValues();
query.deliveryType = DeliveryTypeEnum.PICK_UP.type;
const res = await getOrderSummary(query as any);
summary.value = res;
}
const [Grid, gridApi] = useVbenVxeGrid({
formOptions: {
schema: useGridFormSchema(),
},
gridOptions: {
columns: useGridColumns(),
height: 'auto',
keepSource: true,
proxyConfig: {
ajax: {
query: async ({ page }, formValues) => {
return await getOrderPage({
pageNo: page.currentPage,
pageSize: page.pageSize,
deliveryType: DeliveryTypeEnum.PICK_UP.type,
...formValues,
});
},
},
},
rowConfig: {
keyField: 'id',
},
toolbarConfig: {
refresh: { code: 'query' },
search: true,
},
} as VxeTableGridOptions<MallOrderApi.Order>,
});
onMounted(() => {
getOrderSum();
});
</script> </script>
<template> <template>
<Page> <Page auto-content-height>
<DocAlert <Card class="mb-4 h-[10%]">
title="【交易】交易订单" <template class="flex flex-row gap-4">
url="https://doc.iocoder.cn/mall/trade-order/" <SummaryCard
class="flex flex-1"
title="订单数量"
icon="icon-park-outline:transaction-order"
icon-color="bg-blue-100"
icon-bg-color="text-blue-500"
:value="summary?.orderCount || 0"
/> />
<DocAlert <SummaryCard
title="【交易】购物车" class="flex flex-1"
url="https://doc.iocoder.cn/mall/trade-cart/" title="订单金额"
icon="streamline:money-cash-file-dollar-common-money-currency-cash-file"
icon-color="bg-purple-100"
icon-bg-color="text-purple-500"
prefix="¥"
:decimals="2"
:value="Number(fenToYuan(summary?.orderPayPrice || 0))"
/> />
<Button <SummaryCard
danger class="flex flex-1"
type="link" title="退款单数"
target="_blank" icon="heroicons:receipt-refund"
href="https://github.com/yudaocode/yudao-ui-admin-vue3" icon-color="bg-yellow-100"
> icon-bg-color="text-yellow-500"
该功能支持 Vue3 + element-plus 版本 :value="summary?.afterSaleCount || 0"
</Button> />
<br /> <SummaryCard
<Button class="flex flex-1"
type="link" title="退款金额"
target="_blank" icon="ri:refund-2-line"
href="https://github.com/yudaocode/yudao-ui-admin-vue3/blob/master/src/views/mall/trade/delivery/pickUpOrder/index" icon-color="bg-green-100"
> icon-bg-color="text-green-500"
可参考 prefix="¥"
https://github.com/yudaocode/yudao-ui-admin-vue3/blob/master/src/views/mall/trade/delivery/pickUpOrder/index :decimals="2"
代码pull request 贡献给我们 :value="Number(fenToYuan(summary?.afterSalePrice || 0))"
</Button> />
</template>
</Card>
<Grid class="h-[80%]" table-title="" />
</Page> </Page>
</template> </template>