feat:【mall 商城】分销用户的 list modal 迁移(antd 100%)

This commit is contained in:
YunaiV
2025-10-10 09:30:52 +08:00
parent 94d0550ecc
commit 740da3f545
7 changed files with 206 additions and 254 deletions

View File

@@ -19,7 +19,6 @@ const [Grid] = useVbenVxeGrid({
columns: useGridColumns(),
height: 'auto',
keepSource: true,
showOverflow: 'tooltip',
proxyConfig: {
ajax: {
query: async ({ page }, formValues) => {

View File

@@ -2,6 +2,8 @@ import type { VbenFormSchema } from '#/adapter/form';
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { MallBrokerageUserApi } from '#/api/mall/trade/brokerage/user';
import { DICT_TYPE } from '@vben/constants';
import { getDictOptions } from '@vben/hooks';
import { fenToYuan } from '@vben/utils';
import { getRangePickerDefaultProps } from '#/utils';
@@ -180,3 +182,176 @@ export function useUpdateFormSchema(): VbenFormSchema[] {
},
];
}
/** 用户列表弹窗搜索表单配置 */
export function useUserListFormSchema(): VbenFormSchema[] {
return [
{
fieldName: 'level',
label: '用户类型',
component: 'Select',
componentProps: {
options: [
{ label: '全部', value: undefined },
{ label: '一级推广人', value: '1' },
{ label: '二级推广人', value: '2' },
],
},
},
{
fieldName: 'bindUserTime',
label: '绑定时间',
component: 'RangePicker',
componentProps: {
...getRangePickerDefaultProps(),
allowClear: true,
},
},
];
}
/** 用户列表弹窗表格列配置 */
export function useUserListColumns(): VxeTableGridOptions['columns'] {
return [
{
field: 'id',
title: '用户编号',
minWidth: 80,
},
{
field: 'avatar',
title: '头像',
minWidth: 70,
cellRender: {
name: 'CellImage',
props: {
width: 24,
height: 24,
shape: 'circle',
},
},
},
{
field: 'nickname',
title: '昵称',
minWidth: 80,
},
{
field: 'brokerageUserCount',
title: '推广人数',
minWidth: 80,
},
{
field: 'brokerageOrderCount',
title: '推广订单数量',
minWidth: 110,
},
{
field: 'brokerageEnabled',
title: '推广资格',
minWidth: 80,
cellRender: {
name: 'CellDict',
props: { type: DICT_TYPE.INFRA_BOOLEAN_STRING },
},
},
{
field: 'bindUserTime',
title: '绑定时间',
width: 180,
formatter: 'formatDateTime',
},
];
}
/** 推广订单列表弹窗搜索表单配置 */
export function useOrderListFormSchema(): VbenFormSchema[] {
return [
{
fieldName: 'sourceUserLevel',
label: '用户类型',
component: 'Select',
componentProps: {
options: [
{ label: '全部', value: 0 },
{ label: '一级推广人', value: 1 },
{ label: '二级推广人', value: 2 },
],
},
defaultValue: 0,
},
{
fieldName: 'status',
label: '状态',
component: 'Select',
componentProps: {
placeholder: '请选择状态',
allowClear: true,
options: getDictOptions(DICT_TYPE.BROKERAGE_RECORD_STATUS, 'number'),
},
},
{
fieldName: 'createTime',
label: '创建时间',
component: 'RangePicker',
componentProps: {
...getRangePickerDefaultProps(),
allowClear: true,
},
},
];
}
/** 推广订单列表弹窗表格列配置 */
export function useOrderListColumns(): VxeTableGridOptions['columns'] {
return [
{
field: 'bizId',
title: '订单编号',
minWidth: 80,
},
{
field: 'sourceUserId',
title: '用户编号',
minWidth: 80,
},
{
field: 'sourceUserAvatar',
title: '头像',
minWidth: 70,
cellRender: {
name: 'CellImage',
props: {
width: 24,
height: 24,
},
},
},
{
field: 'sourceUserNickname',
title: '昵称',
minWidth: 80,
},
{
field: 'price',
title: '佣金',
minWidth: 100,
formatter: ({ row }) => `${fenToYuan(row.price)}`,
},
{
field: 'status',
title: '状态',
minWidth: 85,
cellRender: {
name: 'CellDict',
props: { type: DICT_TYPE.BROKERAGE_RECORD_STATUS },
},
},
{
field: 'createTime',
title: '创建时间',
width: 180,
formatter: 'formatDateTime',
},
];
}

View File

@@ -4,6 +4,7 @@ import type { MallBrokerageUserApi } from '#/api/mall/trade/brokerage/user';
import { ref } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { DICT_TYPE } from '@vben/constants';
import { $t } from '@vben/locales';
import { formatDate, isEmpty } from '@vben/utils';
@@ -14,7 +15,6 @@ import {
Divider,
InputSearch,
message,
Tag,
} from 'ant-design-vue';
import { useVbenForm } from '#/adapter/form';
@@ -23,6 +23,7 @@ import {
getBrokerageUser,
} from '#/api/mall/trade/brokerage/user';
import { getUser } from '#/api/member/user';
import { DictTag } from '#/components/dict-tag';
import { useCreateFormSchema } from '../data';
@@ -154,8 +155,10 @@ async function handleSearchUser(id: number, userType: string) {
{{ bindUser?.nickname }}
</DescriptionsItem>
<DescriptionsItem label="分销资格">
<Tag v-if="bindUser?.brokerageEnabled" color="success"> </Tag>
<Tag v-else></Tag>
<DictTag
:type="DICT_TYPE.INFRA_BOOLEAN_STRING"
:value="bindUser?.brokerageEnabled"
/>
</DescriptionsItem>
<DescriptionsItem label="成为分销员的时间">
{{ formatDate(bindUser?.brokerageTime) }}

View File

@@ -1,150 +1,28 @@
<script lang="ts" setup>
import type { VbenFormSchema } from '#/adapter/form';
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { MallBrokerageRecordApi } from '#/api/mall/trade/brokerage/record';
import type { MallBrokerageUserApi } from '#/api/mall/trade/brokerage/user';
import { ref } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { BrokerageRecordBizTypeEnum, DICT_TYPE } from '@vben/constants';
import { getDictOptions } from '@vben/hooks';
import { fenToYuan } from '@vben/utils';
import { BrokerageRecordBizTypeEnum } from '@vben/constants';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { getBrokerageRecordPage } from '#/api/mall/trade/brokerage/record';
import { getRangePickerDefaultProps } from '#/utils';
import { useOrderListColumns, useOrderListFormSchema } from '../data';
/** 推广订单列表 */
defineOptions({ name: 'BrokerageOrderListModal' });
const userId = ref<number>();
const [Modal, modalApi] = useVbenModal({});
const [Modal, modalApi] = useVbenModal({
async onOpenChange(isOpen: boolean) {
if (!isOpen) {
userId.value = undefined;
return;
}
// 加载数据
const data = modalApi.getData<MallBrokerageUserApi.BrokerageUser>();
if (!data || !data.id) {
return;
}
modalApi.lock();
try {
userId.value = data.id;
// 等待弹窗打开后再查询
setTimeout(() => {
gridApi.query();
}, 100);
} finally {
modalApi.unlock();
}
},
});
/** 搜索表单配置 */
function useFormSchema(): VbenFormSchema[] {
return [
{
fieldName: 'sourceUserLevel',
label: '用户类型',
component: 'Select',
componentProps: {
options: [
{ label: '全部', value: 0 },
{ label: '一级推广人', value: 1 },
{ label: '二级推广人', value: 2 },
],
},
defaultValue: 0,
},
{
fieldName: 'status',
label: '状态',
component: 'Select',
componentProps: {
placeholder: '请选择状态',
allowClear: true,
options: getDictOptions(DICT_TYPE.BROKERAGE_RECORD_STATUS, 'number'),
},
},
{
fieldName: 'createTime',
label: '创建时间',
component: 'RangePicker',
componentProps: {
...getRangePickerDefaultProps(),
allowClear: true,
},
},
];
}
/** 表格列配置 */
function useColumns(): VxeTableGridOptions['columns'] {
return [
{
field: 'bizId',
title: '订单编号',
minWidth: 80,
},
{
field: 'sourceUserId',
title: '用户编号',
minWidth: 80,
},
{
field: 'sourceUserAvatar',
title: '头像',
minWidth: 70,
cellRender: {
name: 'CellImage',
props: {
width: 24,
height: 24,
},
},
},
{
field: 'sourceUserNickname',
title: '昵称',
minWidth: 80,
},
{
field: 'price',
title: '佣金',
minWidth: 100,
formatter: ({ row }) => `${fenToYuan(row.price)}`,
},
{
field: 'status',
title: '状态',
minWidth: 85,
cellRender: {
name: 'CellDict',
props: { type: DICT_TYPE.BROKERAGE_RECORD_STATUS },
},
},
{
field: 'createTime',
title: '创建时间',
width: 180,
formatter: 'formatDateTime',
},
];
}
const [Grid, gridApi] = useVbenVxeGrid({
const [Grid] = useVbenVxeGrid({
formOptions: {
schema: useFormSchema(),
schema: useOrderListFormSchema(),
},
gridOptions: {
columns: useColumns(),
columns: useOrderListColumns(),
height: '600',
keepSource: true,
showOverflow: 'tooltip',
proxyConfig: {
ajax: {
query: async ({ page }, formValues) => {
@@ -152,7 +30,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
const params = {
pageNo: page.currentPage,
pageSize: page.pageSize,
userId: userId.value,
userId: modalApi.getData()?.id,
bizType: BrokerageRecordBizTypeEnum.ORDER.type,
sourceUserLevel:
formValues.sourceUserLevel === 0
@@ -179,6 +57,6 @@ const [Grid, gridApi] = useVbenVxeGrid({
<template>
<Modal title="推广订单列表" class="w-3/5">
<Grid table-title="推广订单列表" />
<Grid />
</Modal>
</template>

View File

@@ -4,6 +4,7 @@ import type { MallBrokerageUserApi } from '#/api/mall/trade/brokerage/user';
import { ref } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { DICT_TYPE } from '@vben/constants';
import { $t } from '@vben/locales';
import { formatDate, isEmpty } from '@vben/utils';
@@ -14,7 +15,6 @@ import {
Divider,
InputSearch,
message,
Tag,
} from 'ant-design-vue';
import { useVbenForm } from '#/adapter/form';
@@ -22,6 +22,7 @@ import {
getBrokerageUser,
updateBindUser,
} from '#/api/mall/trade/brokerage/user';
import { DictTag } from '#/components/dict-tag';
import { useUpdateFormSchema } from '../data';
@@ -134,8 +135,10 @@ async function handleSearchUser(id: number, userType: string) {
{{ bindUser?.nickname }}
</DescriptionsItem>
<DescriptionsItem label="分销资格">
<Tag v-if="bindUser?.brokerageEnabled" color="success"> </Tag>
<Tag v-else></Tag>
<DictTag
:type="DICT_TYPE.INFRA_BOOLEAN_STRING"
:value="bindUser?.brokerageEnabled"
/>
</DescriptionsItem>
<DescriptionsItem label="成为分销员的时间">
{{ formatDate(bindUser?.brokerageTime) }}

View File

@@ -1,134 +1,33 @@
<script lang="ts" setup>
import type { VbenFormSchema } from '#/adapter/form';
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { MallBrokerageUserApi } from '#/api/mall/trade/brokerage/user';
import { ref } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { Tag } from 'ant-design-vue';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { getBrokerageUserPage } from '#/api/mall/trade/brokerage/user';
import { getRangePickerDefaultProps } from '#/utils';
import { useUserListColumns, useUserListFormSchema } from '../data';
defineOptions({ name: 'BrokerageUserListModal' });
const bindUserId = ref<number>();
const [Modal, modalApi] = useVbenModal({});
const [Modal, modalApi] = useVbenModal({
onOpenChange: async (isOpen: boolean) => {
if (!isOpen) {
bindUserId.value = undefined;
return;
}
const data = modalApi.getData<MallBrokerageUserApi.BrokerageUser>();
if (!data || !data.id) {
return;
}
bindUserId.value = data.id;
// 等待弹窗打开后再查询
setTimeout(() => {
gridApi.query();
}, 100);
},
});
/** 搜索表单配置 */
function useFormSchema(): VbenFormSchema[] {
return [
{
fieldName: 'level',
label: '用户类型',
component: 'Select',
componentProps: {
options: [
{ label: '全部', value: undefined },
{ label: '一级推广人', value: '1' },
{ label: '二级推广人', value: '2' },
],
},
},
{
fieldName: 'bindUserTime',
label: '绑定时间',
component: 'RangePicker',
componentProps: {
...getRangePickerDefaultProps(),
allowClear: true,
},
},
];
}
/** 表格列配置 */
function useColumns(): VxeTableGridOptions['columns'] {
return [
{
field: 'id',
title: '用户编号',
minWidth: 80,
},
{
field: 'avatar',
title: '头像',
minWidth: 70,
cellRender: {
name: 'CellImage',
props: {
width: 24,
height: 24,
shape: 'circle',
},
},
},
{
field: 'nickname',
title: '昵称',
minWidth: 80,
},
{
field: 'brokerageUserCount',
title: '推广人数',
minWidth: 80,
},
{
field: 'brokerageOrderCount',
title: '推广订单数量',
minWidth: 110,
},
{
field: 'brokerageEnabled',
title: '推广资格',
minWidth: 80,
slots: { default: 'brokerageEnabled' },
},
{
field: 'bindUserTime',
title: '绑定时间',
width: 180,
formatter: 'formatDateTime',
},
];
}
const [Grid, gridApi] = useVbenVxeGrid({
const [Grid] = useVbenVxeGrid({
formOptions: {
schema: useFormSchema(),
schema: useUserListFormSchema(),
},
gridOptions: {
columns: useColumns(),
columns: useUserListColumns(),
height: '600',
keepSource: true,
showOverflow: 'tooltip',
proxyConfig: {
ajax: {
query: async ({ page }, formValues) => {
return await getBrokerageUserPage({
pageNo: page.currentPage,
pageSize: page.pageSize,
bindUserId: bindUserId.value,
bindUserId: modalApi.getData().id,
...formValues,
});
},
@@ -148,11 +47,6 @@ const [Grid, gridApi] = useVbenVxeGrid({
<template>
<Modal title="推广人列表" class="w-3/5">
<Grid table-title="推广人列表">
<template #brokerageEnabled="{ row }">
<Tag v-if="row.brokerageEnabled" color="success"></Tag>
<Tag v-else></Tag>
</template>
</Grid>
<Grid />
</Modal>
</template>

View File

@@ -88,12 +88,12 @@ export function useGridColumns(): VxeTableGridOptions['columns'] {
},
{
field: 'userId',
title: '用户编号',
title: '用户编号',
minWidth: 80,
},
{
field: 'userNickname',
title: '用户昵称',
title: '用户昵称',
minWidth: 80,
},
{