feat:【mall 商城】交易订单(100% ele 部分)
This commit is contained in:
@@ -345,7 +345,7 @@ onMounted(async () => {
|
||||
<div>
|
||||
<OperateLogGrid table-title="操作日志">
|
||||
<template #userType="{ row }">
|
||||
<Tag v-if="row.userId === 0" color="default"> 系统 </Tag>
|
||||
<Tag v-if="row.userType === 0" color="default"> 系统 </Tag>
|
||||
<DictTag :type="DICT_TYPE.USER_TYPE" :value="row.userType" />
|
||||
</template>
|
||||
</OperateLogGrid>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||
import type { MallOrderApi } from '#/api/mall/trade/order';
|
||||
import type { DescriptionItemSchema } from '#/components/description';
|
||||
|
||||
import { h } from 'vue';
|
||||
|
||||
@@ -9,7 +10,7 @@ import { fenToYuan, formatDateTime } from '@vben/utils';
|
||||
import { DictTag } from '#/components/dict-tag';
|
||||
|
||||
/** 订单基础信息 schema */
|
||||
export function useOrderInfoSchema() {
|
||||
export function useOrderInfoSchema(): DescriptionItemSchema[] {
|
||||
return [
|
||||
{
|
||||
field: 'no',
|
||||
@@ -22,7 +23,7 @@ export function useOrderInfoSchema() {
|
||||
{
|
||||
field: 'type',
|
||||
label: '订单类型',
|
||||
render: (data: MallOrderApi.Order) =>
|
||||
content: (data: MallOrderApi.Order) =>
|
||||
h(DictTag, {
|
||||
type: DICT_TYPE.TRADE_ORDER_TYPE,
|
||||
value: data?.type,
|
||||
@@ -31,7 +32,7 @@ export function useOrderInfoSchema() {
|
||||
{
|
||||
field: 'terminal',
|
||||
label: '订单来源',
|
||||
render: (data: MallOrderApi.Order) =>
|
||||
content: (data: MallOrderApi.Order) =>
|
||||
h(DictTag, {
|
||||
type: DICT_TYPE.TERMINAL,
|
||||
value: data?.terminal,
|
||||
@@ -52,7 +53,7 @@ export function useOrderInfoSchema() {
|
||||
{
|
||||
field: 'payChannelCode',
|
||||
label: '付款方式',
|
||||
render: (data: MallOrderApi.Order) =>
|
||||
content: (data: MallOrderApi.Order) =>
|
||||
h(DictTag, {
|
||||
type: DICT_TYPE.PAY_CHANNEL_CODE,
|
||||
value: data?.payChannelCode,
|
||||
@@ -66,12 +67,12 @@ export function useOrderInfoSchema() {
|
||||
}
|
||||
|
||||
/** 订单状态信息 schema */
|
||||
export function useOrderStatusSchema() {
|
||||
export function useOrderStatusSchema(): DescriptionItemSchema[] {
|
||||
return [
|
||||
{
|
||||
field: 'status',
|
||||
label: '订单状态',
|
||||
render: (data: MallOrderApi.Order) =>
|
||||
content: (data: MallOrderApi.Order) =>
|
||||
h(DictTag, {
|
||||
type: DICT_TYPE.TRADE_ORDER_STATUS,
|
||||
value: data?.status,
|
||||
@@ -80,7 +81,7 @@ export function useOrderStatusSchema() {
|
||||
{
|
||||
field: 'reminder',
|
||||
label: '提醒',
|
||||
render: () =>
|
||||
content: () =>
|
||||
h('div', { class: 'space-y-1' }, [
|
||||
h('div', '买家付款成功后,货款将直接进入您的商户号(微信、支付宝)'),
|
||||
h('div', '请及时关注你发出的包裹状态,确保可以配送至买家手中'),
|
||||
@@ -94,30 +95,30 @@ export function useOrderStatusSchema() {
|
||||
}
|
||||
|
||||
/** 订单金额信息 schema */
|
||||
export function useOrderPriceSchema() {
|
||||
export function useOrderPriceSchema(): DescriptionItemSchema[] {
|
||||
return [
|
||||
{
|
||||
field: 'totalPrice',
|
||||
label: '商品总额',
|
||||
render: (data: MallOrderApi.Order) =>
|
||||
content: (data: MallOrderApi.Order) =>
|
||||
`${fenToYuan(data?.totalPrice ?? 0)} 元`,
|
||||
},
|
||||
{
|
||||
field: 'deliveryPrice',
|
||||
label: '运费金额',
|
||||
render: (data: MallOrderApi.Order) =>
|
||||
content: (data: MallOrderApi.Order) =>
|
||||
`${fenToYuan(data?.deliveryPrice ?? 0)} 元`,
|
||||
},
|
||||
{
|
||||
field: 'adjustPrice',
|
||||
label: '订单调价',
|
||||
render: (data: MallOrderApi.Order) =>
|
||||
content: (data: MallOrderApi.Order) =>
|
||||
`${fenToYuan(data?.adjustPrice ?? 0)} 元`,
|
||||
},
|
||||
{
|
||||
field: 'couponPrice',
|
||||
label: '优惠劵优惠',
|
||||
render: (data: MallOrderApi.Order) =>
|
||||
content: (data: MallOrderApi.Order) =>
|
||||
h(
|
||||
'span',
|
||||
{ class: 'text-red-500' },
|
||||
@@ -127,7 +128,7 @@ export function useOrderPriceSchema() {
|
||||
{
|
||||
field: 'vipPrice',
|
||||
label: 'VIP 优惠',
|
||||
render: (data: MallOrderApi.Order) =>
|
||||
content: (data: MallOrderApi.Order) =>
|
||||
h(
|
||||
'span',
|
||||
{ class: 'text-red-500' },
|
||||
@@ -137,7 +138,7 @@ export function useOrderPriceSchema() {
|
||||
{
|
||||
field: 'discountPrice',
|
||||
label: '活动优惠',
|
||||
render: (data: MallOrderApi.Order) =>
|
||||
content: (data: MallOrderApi.Order) =>
|
||||
h(
|
||||
'span',
|
||||
{ class: 'text-red-500' },
|
||||
@@ -147,7 +148,7 @@ export function useOrderPriceSchema() {
|
||||
{
|
||||
field: 'pointPrice',
|
||||
label: '积分抵扣',
|
||||
render: (data: MallOrderApi.Order) =>
|
||||
content: (data: MallOrderApi.Order) =>
|
||||
h(
|
||||
'span',
|
||||
{ class: 'text-red-500' },
|
||||
@@ -157,19 +158,19 @@ export function useOrderPriceSchema() {
|
||||
{
|
||||
field: 'payPrice',
|
||||
label: '应付金额',
|
||||
render: (data: MallOrderApi.Order) =>
|
||||
content: (data: MallOrderApi.Order) =>
|
||||
`${fenToYuan(data?.payPrice ?? 0)} 元`,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
/** 收货信息 schema */
|
||||
export function useDeliveryInfoSchema() {
|
||||
export function useDeliveryInfoSchema(): DescriptionItemSchema[] {
|
||||
return [
|
||||
{
|
||||
field: 'deliveryType',
|
||||
label: '配送方式',
|
||||
render: (data: MallOrderApi.Order) =>
|
||||
content: (data: MallOrderApi.Order) =>
|
||||
h(DictTag, {
|
||||
type: DICT_TYPE.TRADE_DELIVERY_TYPE,
|
||||
value: data?.deliveryType,
|
||||
@@ -186,14 +187,14 @@ export function useDeliveryInfoSchema() {
|
||||
{
|
||||
field: 'receiverAddress',
|
||||
label: '收货地址',
|
||||
render: (data: MallOrderApi.Order) =>
|
||||
content: (data: MallOrderApi.Order) =>
|
||||
`${data?.receiverAreaName} ${data?.receiverDetailAddress}`.trim(),
|
||||
},
|
||||
{
|
||||
field: 'deliveryTime',
|
||||
label: '发货时间',
|
||||
render: (data: MallOrderApi.Order) =>
|
||||
formatDateTime(data?.deliveryTime || '') as string,
|
||||
content: (data: MallOrderApi.Order) =>
|
||||
formatDateTime(data?.deliveryTime) as string,
|
||||
},
|
||||
];
|
||||
}
|
||||
@@ -274,4 +275,4 @@ export function useOperateLogColumns(): VxeTableGridOptions['columns'] {
|
||||
minWidth: 200,
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,14 +14,14 @@ import {
|
||||
TradeOrderStatusEnum,
|
||||
} from '@vben/constants';
|
||||
import { useTabs } from '@vben/hooks';
|
||||
import { fenToYuan, formatDateTime } from '@vben/utils';
|
||||
|
||||
import { ElCard, ElMessage, ElTag } from 'element-plus';
|
||||
import { ElCard, ElLoading, ElMessage, ElTag } from 'element-plus';
|
||||
|
||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import * as DeliveryExpressApi from '#/api/mall/trade/delivery/express';
|
||||
import * as DeliveryPickUpStoreApi from '#/api/mall/trade/delivery/pickUpStore';
|
||||
import * as TradeOrderApi from '#/api/mall/trade/order';
|
||||
import { useDescription } from '#/components/description';
|
||||
import { DictTag } from '#/components/dict-tag';
|
||||
import { TableAction } from '#/components/table-action';
|
||||
|
||||
@@ -30,8 +30,12 @@ import DeliveryForm from '../modules/delivery-form.vue';
|
||||
import PriceForm from '../modules/price-form.vue';
|
||||
import RemarkForm from '../modules/remark-form.vue';
|
||||
import {
|
||||
useDeliveryInfoSchema,
|
||||
useExpressTrackColumns,
|
||||
useOperateLogColumns,
|
||||
useOrderInfoSchema,
|
||||
useOrderPriceSchema,
|
||||
useOrderStatusSchema,
|
||||
useProductColumns,
|
||||
} from './data';
|
||||
|
||||
@@ -52,6 +56,42 @@ const deliveryExpressList = ref<MallDeliveryExpressApi.SimpleDeliveryExpress[]>(
|
||||
const expressTrackList = ref<any[]>([]);
|
||||
const pickUpStore = ref<MallDeliveryPickUpStoreApi.PickUpStore | undefined>();
|
||||
|
||||
const [OrderInfoDescriptions] = useDescription({
|
||||
componentProps: {
|
||||
title: '订单信息',
|
||||
border: false,
|
||||
column: 3,
|
||||
},
|
||||
schema: useOrderInfoSchema(),
|
||||
});
|
||||
|
||||
const [OrderStatusDescriptions] = useDescription({
|
||||
componentProps: {
|
||||
title: '订单状态',
|
||||
border: false,
|
||||
column: 1,
|
||||
},
|
||||
schema: useOrderStatusSchema(),
|
||||
});
|
||||
|
||||
const [OrderPriceDescriptions] = useDescription({
|
||||
componentProps: {
|
||||
title: '费用信息',
|
||||
border: false,
|
||||
column: 4,
|
||||
},
|
||||
schema: useOrderPriceSchema(),
|
||||
});
|
||||
|
||||
const [DeliveryInfoDescriptions] = useDescription({
|
||||
componentProps: {
|
||||
title: '收货信息',
|
||||
border: false,
|
||||
column: 3,
|
||||
},
|
||||
schema: useDeliveryInfoSchema(),
|
||||
});
|
||||
|
||||
const [ProductGrid, productGridApi] = useVbenVxeGrid({
|
||||
gridOptions: {
|
||||
cellConfig: {
|
||||
@@ -180,10 +220,8 @@ const handleUpdatePrice = () => {
|
||||
/** 核销 */
|
||||
const handlePickUp = async () => {
|
||||
await confirm('确认核销订单吗?');
|
||||
const loadingInstance = ElMessage({
|
||||
message: '正在处理中...',
|
||||
duration: 0,
|
||||
type: 'info',
|
||||
const loadingInstance = ElLoading.service({
|
||||
text: '正在处理中...',
|
||||
});
|
||||
try {
|
||||
await TradeOrderApi.pickUpOrder(order.value.id!);
|
||||
@@ -265,75 +303,12 @@ onMounted(async () => {
|
||||
|
||||
<!-- 订单信息 -->
|
||||
<ElCard class="mb-4">
|
||||
<template #header>
|
||||
<span class="font-bold">订单信息</span>
|
||||
</template>
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-3">
|
||||
<div class="flex">
|
||||
<span class="mr-2 min-w-fit text-gray-600">订单号:</span>
|
||||
<span>{{ order.no }}</span>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<span class="mr-2 min-w-fit text-gray-600">买家:</span>
|
||||
<span>{{ order.user?.nickname }}</span>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<span class="mr-2 min-w-fit text-gray-600">订单类型:</span>
|
||||
<DictTag :type="DICT_TYPE.TRADE_ORDER_TYPE" :value="order.type" />
|
||||
</div>
|
||||
<div class="flex">
|
||||
<span class="mr-2 min-w-fit text-gray-600">订单来源:</span>
|
||||
<DictTag :type="DICT_TYPE.TERMINAL" :value="order.terminal" />
|
||||
</div>
|
||||
<div class="flex">
|
||||
<span class="mr-2 min-w-fit text-gray-600">买家留言:</span>
|
||||
<span>{{ order.userRemark }}</span>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<span class="mr-2 min-w-fit text-gray-600">商家备注:</span>
|
||||
<span>{{ order.remark }}</span>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<span class="mr-2 min-w-fit text-gray-600">支付单号:</span>
|
||||
<span>{{ order.payOrderId }}</span>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<span class="mr-2 min-w-fit text-gray-600">付款方式:</span>
|
||||
<DictTag
|
||||
:type="DICT_TYPE.PAY_CHANNEL_CODE"
|
||||
:value="order.payChannelCode"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<span class="mr-2 min-w-fit text-gray-600">推广用户:</span>
|
||||
<span>{{ order.brokerageUser?.nickname }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<OrderInfoDescriptions :data="order" />
|
||||
</ElCard>
|
||||
|
||||
<!-- 订单状态 -->
|
||||
<ElCard class="mb-4">
|
||||
<template #header>
|
||||
<span class="font-bold">订单状态</span>
|
||||
</template>
|
||||
<div class="space-y-2">
|
||||
<div class="flex">
|
||||
<span class="mr-2 min-w-fit text-gray-600">订单状态:</span>
|
||||
<DictTag :type="DICT_TYPE.TRADE_ORDER_STATUS" :value="order.status" />
|
||||
</div>
|
||||
<div class="flex">
|
||||
<span class="mr-2 min-w-fit text-gray-600">提醒:</span>
|
||||
<div class="space-y-1">
|
||||
<div>买家付款成功后,货款将直接进入您的商户号(微信、支付宝)</div>
|
||||
<div>请及时关注你发出的包裹状态,确保可以配送至买家手中</div>
|
||||
<div>
|
||||
如果买家表示没收到货或货物有问题,请及时联系买家处理,友好协商
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<OrderStatusDescriptions :data="order" />
|
||||
</ElCard>
|
||||
|
||||
<!-- 商品信息 -->
|
||||
<div class="mb-4">
|
||||
<ProductGrid table-title="商品信息">
|
||||
@@ -342,8 +317,8 @@ onMounted(async () => {
|
||||
<span class="text-sm">{{ row.spuName }}</span>
|
||||
<div class="flex flex-wrap gap-1">
|
||||
<ElTag
|
||||
v-for="(property, index) in row.properties"
|
||||
:key="index"
|
||||
v-for="property in row.properties"
|
||||
:key="property.propertyId!"
|
||||
size="small"
|
||||
>
|
||||
{{ property.propertyName }}: {{ property.valueName }}
|
||||
@@ -353,91 +328,23 @@ onMounted(async () => {
|
||||
</template>
|
||||
</ProductGrid>
|
||||
</div>
|
||||
|
||||
<!-- 费用信息 -->
|
||||
<ElCard class="mb-4">
|
||||
<template #header>
|
||||
<span class="font-bold">费用信息</span>
|
||||
</template>
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-4">
|
||||
<div class="flex">
|
||||
<span class="mr-2 min-w-fit text-gray-600">商品总额:</span>
|
||||
<span>{{ fenToYuan(order.totalPrice ?? 0) }} 元</span>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<span class="mr-2 min-w-fit text-gray-600">运费金额:</span>
|
||||
<span>{{ fenToYuan(order.deliveryPrice ?? 0) }} 元</span>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<span class="mr-2 min-w-fit text-gray-600">订单调价:</span>
|
||||
<span>{{ fenToYuan(order.adjustPrice ?? 0) }} 元</span>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<span class="mr-2 min-w-fit text-gray-600">优惠劵优惠:</span>
|
||||
<span class="text-red-500">{{ fenToYuan(order.couponPrice ?? 0) }} 元</span>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<span class="mr-2 min-w-fit text-gray-600">VIP 优惠:</span>
|
||||
<span class="text-red-500">{{ fenToYuan(order.vipPrice ?? 0) }} 元</span>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<span class="mr-2 min-w-fit text-gray-600">活动优惠:</span>
|
||||
<span class="text-red-500">{{ fenToYuan(order.discountPrice ?? 0) }} 元</span>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<span class="mr-2 min-w-fit text-gray-600">积分抵扣:</span>
|
||||
<span class="text-red-500">{{ fenToYuan(order.pointPrice ?? 0) }} 元</span>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<span class="mr-2 min-w-fit text-gray-600">应付金额:</span>
|
||||
<span>{{ fenToYuan(order.payPrice ?? 0) }} 元</span>
|
||||
</div>
|
||||
</div>
|
||||
<OrderPriceDescriptions :data="order" />
|
||||
</ElCard>
|
||||
|
||||
<!-- 收货信息 -->
|
||||
<ElCard class="mb-4">
|
||||
<template #header>
|
||||
<span class="font-bold">收货信息</span>
|
||||
</template>
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-3">
|
||||
<div class="flex">
|
||||
<span class="mr-2 min-w-fit text-gray-600">配送方式:</span>
|
||||
<DictTag
|
||||
:type="DICT_TYPE.TRADE_DELIVERY_TYPE"
|
||||
:value="order.deliveryType"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<span class="mr-2 min-w-fit text-gray-600">收货人:</span>
|
||||
<span>{{ order.receiverName }}</span>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<span class="mr-2 min-w-fit text-gray-600">联系电话:</span>
|
||||
<span>{{ order.receiverMobile }}</span>
|
||||
</div>
|
||||
<div class="flex md:col-span-3">
|
||||
<span class="mr-2 min-w-fit text-gray-600">收货地址:</span>
|
||||
<span>{{ order.receiverAreaName }}
|
||||
{{ order.receiverDetailAddress }}</span>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<span class="mr-2 min-w-fit text-gray-600">发货时间:</span>
|
||||
<span>{{ formatDateTime(order.deliveryTime || '') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<DeliveryInfoDescriptions :data="order" />
|
||||
</ElCard>
|
||||
|
||||
<!-- 物流详情 -->
|
||||
<div v-if="expressTrackList.length > 0" class="mt-4">
|
||||
<ExpressTrackGrid table-title="物流详情" />
|
||||
</div>
|
||||
|
||||
<!-- 操作日志 -->
|
||||
<div>
|
||||
<OperateLogGrid table-title="操作日志">
|
||||
<template #userType="{ row }">
|
||||
<ElTag v-if="row.userId === 0" type="info"> 系统 </ElTag>
|
||||
<ElTag v-if="row.userType === 0" type="info"> 系统 </ElTag>
|
||||
<DictTag v-else :type="DICT_TYPE.USER_TYPE" :value="row.userType" />
|
||||
</template>
|
||||
</OperateLogGrid>
|
||||
|
||||
@@ -108,27 +108,33 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
||||
<RemarkFormModal @success="handleRefresh" />
|
||||
<Grid table-title="订单列表">
|
||||
<template #expand_content="{ row }">
|
||||
<div class="order-items">
|
||||
<div v-for="item in row.items" :key="item.id!" class="order-item">
|
||||
<div class="order-item-image">
|
||||
<div class="py-2">
|
||||
<div
|
||||
v-for="item in row.items"
|
||||
:key="item.id!"
|
||||
class="flex items-start border-b border-gray-100 py-2 last:border-b-0"
|
||||
>
|
||||
<div class="mr-3 flex-shrink-0">
|
||||
<ElImage :src="item.picUrl" class="h-10 w-10" />
|
||||
</div>
|
||||
<div class="order-item-content">
|
||||
<div class="order-item-name">
|
||||
<div class="flex-1">
|
||||
<div class="mb-1 font-medium">
|
||||
{{ item.spuName }}
|
||||
<ElTag
|
||||
v-for="property in item.properties"
|
||||
:key="property.id!"
|
||||
:key="property.id"
|
||||
class="ml-1"
|
||||
size="small"
|
||||
>
|
||||
{{ property.propertyName }}: {{ property.valueName }}
|
||||
</ElTag>
|
||||
</div>
|
||||
<div class="order-item-info">
|
||||
<div
|
||||
class="flex items-center justify-between text-xs text-gray-500"
|
||||
>
|
||||
<span>
|
||||
原价:{{ fenToYuan(item.price || 0) }} 元 / 数量:{{
|
||||
item.count || 0
|
||||
原价:{{ fenToYuan(item.price) }} 元 / 数量:{{
|
||||
item.count
|
||||
}}个
|
||||
</span>
|
||||
<DictTag
|
||||
@@ -174,42 +180,3 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
||||
</Grid>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.order-items {
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
.order-item {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
padding: 8px 0;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
|
||||
.order-item-image {
|
||||
flex-shrink: 0;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.order-item-content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.order-item-name {
|
||||
margin-bottom: 4px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.order-item-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-size: 13px;
|
||||
color: #666;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user