Some checks failed
CI / Test (ubuntu-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / Lint (ubuntu-latest) (push) Has been cancelled
CI / Lint (windows-latest) (push) Has been cancelled
CI / Check (ubuntu-latest) (push) Has been cancelled
CI / Check (windows-latest) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
Deploy Website on push / Deploy Push Playground Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Docs Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Antd Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Element Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Naive Ftp (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
CI / CI OK (push) Has been cancelled
Deploy Website on push / Rerun on failure (push) Has been cancelled
Lock Threads / action (push) Has been cancelled
Issue Close Require / close-issues (push) Has been cancelled
Close stale issues / stale (push) Has been cancelled
212 lines
5.6 KiB
Vue
212 lines
5.6 KiB
Vue
<script lang="ts" setup>
|
|
import { onMounted, ref } from 'vue';
|
|
|
|
import { Page, useVbenDrawer, useVbenModal } from '@vben/common-ui';
|
|
|
|
import { Spin, Tag } from 'ant-design-vue';
|
|
|
|
import { useCrudTable } from '#/components/crud';
|
|
import UserDetailModal from '#/components/customer/user-detail-modal.vue';
|
|
import { Icon } from '#/components/icon';
|
|
import { TableAction } from '#/components/table-action';
|
|
|
|
import { getOrderStat, orderApi } from './api';
|
|
import CustomerOrderDetailDrawer from './components/detail-drawer.vue';
|
|
import CustomerOrderFormModal from './components/modal.vue';
|
|
import {
|
|
ORDER_PAY_STATUS_TEXT,
|
|
ORDER_STATUS_COLOR,
|
|
ORDER_STATUS_TEXT,
|
|
} from './config/constants';
|
|
import { formOptions } from './config/search';
|
|
import { gridOptions } from './config/table';
|
|
|
|
defineOptions({
|
|
name: 'CustomerOrder',
|
|
});
|
|
|
|
const { FormModal, Grid, gridApi, removeRows, showModal } = useCrudTable({
|
|
api: orderApi,
|
|
formOptions,
|
|
gridOptions,
|
|
modalComponent: CustomerOrderFormModal,
|
|
toFormValues: (row) => ({
|
|
id: row.id,
|
|
receiver_name: row.receiver_name,
|
|
receiver_phone: row.receiver_phone,
|
|
receiver_address: row.receiver_address,
|
|
delivery_type: row.delivery_type,
|
|
remark: row.remark,
|
|
}),
|
|
});
|
|
|
|
const [DetailDrawer, detailDrawerApi] = useVbenDrawer({
|
|
connectedComponent: CustomerOrderDetailDrawer,
|
|
});
|
|
|
|
const [UserModal, userModalApi] = useVbenModal({
|
|
connectedComponent: UserDetailModal,
|
|
});
|
|
|
|
/** 顶部统计:后端 order/stat 返回各状态数量与总金额 */
|
|
const statLoading = ref(false);
|
|
const stat = ref<{
|
|
amount: number;
|
|
amount_text: string;
|
|
auditing: number;
|
|
status: { amount: number; count: number; status: number }[];
|
|
total: number;
|
|
}>({ total: 0, amount: 0, amount_text: '0', auditing: 0, status: [] });
|
|
|
|
async function loadStat() {
|
|
statLoading.value = true;
|
|
try {
|
|
stat.value = (await getOrderStat()) ?? stat.value;
|
|
} finally {
|
|
statLoading.value = false;
|
|
}
|
|
}
|
|
|
|
const statCards = [
|
|
{
|
|
key: 'total',
|
|
label: '订单总数',
|
|
icon: 'lucide:receipt',
|
|
getValue: (s: typeof stat.value) => String(s.total),
|
|
},
|
|
{
|
|
key: 'amount',
|
|
label: '订单总额',
|
|
icon: 'lucide:circle-dollar-sign',
|
|
getValue: (s: typeof stat.value) => `¥${s.amount_text}`,
|
|
},
|
|
{
|
|
key: 'auditing',
|
|
label: '待审凭证',
|
|
icon: 'lucide:badge-check',
|
|
getValue: (s: typeof stat.value) => String(s.auditing),
|
|
},
|
|
{
|
|
key: 'pending',
|
|
label: '待付款',
|
|
icon: 'lucide:clock',
|
|
getValue: (s: typeof stat.value) =>
|
|
String(s.status.find((i) => i.status === 0)?.count ?? 0),
|
|
},
|
|
];
|
|
|
|
onMounted(loadStat);
|
|
|
|
function openDetail(row: Record<string, any>) {
|
|
detailDrawerApi.setData({ record: row, gridApi });
|
|
detailDrawerApi.open();
|
|
}
|
|
|
|
function openUser(row: Record<string, any>) {
|
|
userModalApi.setData({ record: { id: row.user_id } });
|
|
userModalApi.open();
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<Page
|
|
auto-content-height
|
|
content-class="flex flex-col gap-3"
|
|
title="订单管理"
|
|
>
|
|
<FormModal />
|
|
<DetailDrawer />
|
|
<UserModal />
|
|
|
|
<!-- 顶部统计条 -->
|
|
<Spin :spinning="statLoading">
|
|
<div class="grid grid-cols-2 gap-3 lg:grid-cols-4">
|
|
<div
|
|
v-for="card in statCards"
|
|
:key="card.key"
|
|
class="bg-card flex items-center gap-3 rounded-lg p-3"
|
|
>
|
|
<div
|
|
class="bg-primary/10 text-primary flex h-10 w-10 shrink-0 items-center justify-center rounded-lg"
|
|
>
|
|
<Icon :icon="card.icon" :size="20" />
|
|
</div>
|
|
<div class="min-w-0">
|
|
<div class="text-muted-foreground text-xs">{{ card.label }}</div>
|
|
<div class="truncate text-lg font-semibold">
|
|
{{ card.getValue(stat) }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</Spin>
|
|
|
|
<Grid>
|
|
<template #toolbar-actions>
|
|
<TableAction
|
|
:actions="[
|
|
{
|
|
label: '批量删除',
|
|
danger: true,
|
|
icon: 'ant-design:delete-outlined',
|
|
popConfirm: {
|
|
title: '确定删除勾选的订单吗?',
|
|
confirm: () => removeRows(),
|
|
},
|
|
},
|
|
{
|
|
label: '刷新统计',
|
|
icon: 'lucide:refresh-cw',
|
|
onClick: loadStat,
|
|
},
|
|
]"
|
|
/>
|
|
</template>
|
|
<template #user="{ row }">
|
|
<a class="text-primary" @click="openUser(row)">
|
|
{{ row.user_name || '-' }}
|
|
</a>
|
|
</template>
|
|
<template #payStatus="{ row }">
|
|
<Tag>{{ ORDER_PAY_STATUS_TEXT[row.pay_status] ?? '-' }}</Tag>
|
|
</template>
|
|
<template #status="{ row }">
|
|
<Tag :color="ORDER_STATUS_COLOR[row.status] ?? 'default'">
|
|
{{ ORDER_STATUS_TEXT[row.status] ?? '-' }}
|
|
</Tag>
|
|
</template>
|
|
<template #action="{ row }">
|
|
<TableAction
|
|
:actions="[
|
|
{
|
|
label: '详情',
|
|
type: 'link',
|
|
icon: 'uil:eye',
|
|
size: 'small',
|
|
onClick: () => openDetail(row),
|
|
},
|
|
{
|
|
label: '编辑',
|
|
type: 'link',
|
|
icon: 'uil:edit',
|
|
size: 'small',
|
|
onClick: () => showModal(row, true),
|
|
},
|
|
{
|
|
label: '删除',
|
|
type: 'link',
|
|
danger: true,
|
|
icon: 'ant-design:delete-outlined',
|
|
size: 'small',
|
|
popConfirm: {
|
|
title: '确定删除该订单吗?',
|
|
confirm: () => removeRows(row.id),
|
|
},
|
|
},
|
|
]"
|
|
/>
|
|
</template>
|
|
</Grid>
|
|
</Page>
|
|
</template>
|