From 46129c53af55a7ca2640e9e0b11c88de3e31e515 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Tue, 25 Nov 2025 18:22:00 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E3=80=90antd=E3=80=91=E3=80=90mal?= =?UTF-8?q?l=E3=80=91=20=E4=BC=98=E5=8C=96=E7=A7=AF=E5=88=86=E5=95=86?= =?UTF-8?q?=E5=9F=8E=E6=B4=BB=E5=8A=A8=E8=A1=A8=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/spu/components/spu-select.vue | 104 ++++++++---------- .../mall/promotion/point/activity/data.ts | 1 + .../promotion/point/activity/modules/form.vue | 64 ++++++----- 3 files changed, 87 insertions(+), 82 deletions(-) diff --git a/apps/web-antd/src/views/mall/product/spu/components/spu-select.vue b/apps/web-antd/src/views/mall/product/spu/components/spu-select.vue index 236cc4cd4..153d11ca7 100644 --- a/apps/web-antd/src/views/mall/product/spu/components/spu-select.vue +++ b/apps/web-antd/src/views/mall/product/spu/components/spu-select.vue @@ -5,7 +5,7 @@ import type { VxeTableGridOptions } from '#/adapter/vxe-table'; import type { MallCategoryApi } from '#/api/mall/product/category'; import type { MallSpuApi } from '#/api/mall/product/spu'; -import { computed, onMounted, ref } from 'vue'; +import { computed, nextTick, onMounted, ref } from 'vue'; import { useVbenModal } from '@vben/common-ui'; import { handleTree } from '@vben/utils'; @@ -86,34 +86,21 @@ function selectSku(val: MallSpuApi.Sku[]) { } /** 处理 SPU 选择变化 */ -function selectSpu(val: MallSpuApi.Spu[]) { - if (val.length === 0) { +function selectSpu(row: MallSpuApi.Spu) { + if (!row) { selectedSpuId.value = 0; return; } - // 只选择一个 - const firstId = val[0]?.id; - if (firstId !== undefined) { - selectedSpuId.value = firstId; - } + selectedSpuId.value = row.id!; + // 切换选择 spu 如果有选择的 sku 则清空,确保选择的 sku 是对应的 spu 下面的 if (selectedSkuIds.value.length > 0) { selectedSkuIds.value = []; } - // 如果大于1个 - if (val.length > 1) { - // 清空选择 - gridApi.grid.clearCheckboxRow(); - // 变更为最后一次选择的 - const lastRow = val.pop(); - if (lastRow) { - gridApi.grid.setCheckboxRow(lastRow, true); - } - return; - } + // 自动展开选中的 SPU - if (props.isSelectSku && val[0]) { - expandChange(val[0], [val[0]]); + if (props.isSelectSku) { + expandChange(row, [row]); } } @@ -181,33 +168,20 @@ async function expandChange( isExpand.value = true; } -/** 确认选择时的触发事件 */ -function confirm() { - if (selectedSpuId.value === 0) { - message.warning('没有选择任何商品'); - return; - } - if (props.isSelectSku && selectedSkuIds.value.length === 0) { - message.warning('没有选择任何商品属性'); - return; - } - // 返回各自 id 列表 - props.isSelectSku - ? emit('confirm', selectedSpuId.value, selectedSkuIds.value) - : emit('confirm', selectedSpuId.value); - // 关闭弹窗 - modalApi.close(); - selectedSpuId.value = 0; - selectedSkuIds.value = []; -} - /** 搜索表单 Schema */ const formSchema = computed(() => useGridFormSchema(categoryTreeList)); /** 表格列配置 */ -const gridColumns = computed(() => - useGridColumns(props.isSelectSku), -); +const gridColumns = computed(() => { + const columns = useGridColumns(props.isSelectSku); + // 将 checkbox 替换为 radio + return columns?.map((col) => { + if (col.type === 'checkbox') { + return { ...col, type: 'radio' }; + } + return col; + }); +}); /** 初始化列表 */ const [Grid, gridApi] = useVbenVxeGrid({ @@ -218,10 +192,11 @@ const [Grid, gridApi] = useVbenVxeGrid({ }, gridOptions: { columns: gridColumns.value, - height: 500, + height: 800, border: true, - checkboxConfig: { + radioConfig: { reserve: true, + highlight: true, }, rowConfig: { keyField: 'id', @@ -247,8 +222,8 @@ const [Grid, gridApi] = useVbenVxeGrid({ }, }, gridEvents: { - checkboxChange: ({ records }: { records: unknown[] }) => { - selectSpu(records as MallSpuApi.Spu[]); + radioChange: ({ row }: { row: MallSpuApi.Spu }) => { + selectSpu(row); }, toggleRowExpand: ({ row, @@ -269,15 +244,27 @@ const [Grid, gridApi] = useVbenVxeGrid({ /** 初始化弹窗 */ const [Modal, modalApi] = useVbenModal({ destroyOnClose: true, - onConfirm: confirm, + onConfirm: () => { + if (selectedSpuId.value === 0) { + message.warning('没有选择任何商品'); + return; + } + if (props.isSelectSku && selectedSkuIds.value.length === 0) { + message.warning('没有选择任何商品属性'); + return; + } + // 返回各自 id 列表 + props.isSelectSku + ? emit('confirm', selectedSpuId.value, selectedSkuIds.value) + : emit('confirm', selectedSpuId.value); + + // 重置选中状态 + selectedSpuId.value = 0; + selectedSkuIds.value = []; + modalApi.close(); + }, async onOpenChange(isOpen: boolean) { if (!isOpen) { - await gridApi.grid.clearCheckboxRow(); - // 关闭所有展开的行 - const tableData = gridApi.grid.getTableData().fullData; - tableData.forEach((row: MallSpuApi.Spu) => { - gridApi.grid.setRowExpand(row, false); - }); selectedSpuId.value = 0; selectedSkuIds.value = []; spuData.value = undefined; @@ -285,8 +272,11 @@ const [Modal, modalApi] = useVbenModal({ isExpand.value = false; return; } - // 打开时查询数据 - await gridApi.query(); + // 等待 Grid 组件完全初始化后再查询数据 + await nextTick(); + if (gridApi.grid) { + await gridApi.query(); + } }, }); diff --git a/apps/web-antd/src/views/mall/promotion/point/activity/data.ts b/apps/web-antd/src/views/mall/promotion/point/activity/data.ts index e65e58b0b..4ad792388 100644 --- a/apps/web-antd/src/views/mall/promotion/point/activity/data.ts +++ b/apps/web-antd/src/views/mall/promotion/point/activity/data.ts @@ -113,6 +113,7 @@ export function useFormSchema(): VbenFormSchema[] { placeholder: '请输入排序', class: '!w-full', }, + defaultValue: 0, rules: 'required', }, { diff --git a/apps/web-antd/src/views/mall/promotion/point/activity/modules/form.vue b/apps/web-antd/src/views/mall/promotion/point/activity/modules/form.vue index 174871b10..9804d7d3f 100644 --- a/apps/web-antd/src/views/mall/promotion/point/activity/modules/form.vue +++ b/apps/web-antd/src/views/mall/promotion/point/activity/modules/form.vue @@ -1,4 +1,5 @@