From 3c154d69eef0a496b72c034f3106264802e21586 Mon Sep 17 00:00:00 2001 From: wuzilong <704541015@qq.com> Date: Sun, 18 Oct 2026 16:32:35 +0800 Subject: [PATCH] fix(web-admin): restore category parent tree-select and delete tip. Keep Vant sheet/form shell while fixing parent UX and creator-delete feedback. Co-authored-by: Cursor --- .../src/views/m/crm/product/categories.vue | 156 ++++++++---------- 1 file changed, 71 insertions(+), 85 deletions(-) diff --git a/web-admin/src/views/m/crm/product/categories.vue b/web-admin/src/views/m/crm/product/categories.vue index 244b0b405..c199078e8 100644 --- a/web-admin/src/views/m/crm/product/categories.vue +++ b/web-admin/src/views/m/crm/product/categories.vue @@ -17,7 +17,10 @@
正在加载分类
- + 新增分类
@@ -77,6 +80,7 @@ v-model:show="actionOpen" teleport="body" :actions="actionSheetActions" + :description="actionSheetDescription" cancel-text="取消" close-on-click-action @select="onActionSelect" @@ -101,14 +105,23 @@ />
- + + + - + + +
- - - - - - - -
@@ -224,9 +228,7 @@ const formTitle = ref('') const submitLoading = ref(false) const nameError = ref('') - const parentPickerOpen = ref(false) - const statusPickerOpen = ref(false) - const flatParentOptions = ref>([]) + const categoryTreeOptions = ref([]) const formData = reactive({ id: '', parentId: '' as string, @@ -247,6 +249,10 @@ canDeleteByCreator(actionNode.value as Record | null) ) + const actionSheetDescription = computed(() => + canDeleteActionNode.value ? undefined : CREATOR_DELETE_TIP + ) + const actionSheetActions = computed(() => [ { name: '新增子级', value: 'add' }, { name: '编辑', value: 'edit' }, @@ -258,28 +264,6 @@ } ]) - const parentPickerColumns = computed(() => [ - { text: '顶级分类', value: '0' }, - ...flatParentOptions.value - ]) - - const statusPickerColumns = computed(() => - dictStore.getOptions('sys_normal_disable').map((o) => ({ - text: o.label, - value: String(o.value) - })) - ) - - const parentLabel = computed(() => { - const id = formData.parentId || '0' - if (id === '0' || !id) return '顶级分类' - return parentPickerColumns.value.find((c) => c.value === id)?.text || id - }) - - const statusLabel = computed(() => { - return dictStore.getLabel('sys_normal_disable', formData.status) || '' - }) - const flatNodes = computed((): FlatItem[] => { const out: FlatItem[] = [] const walk = (nodes: CategoryNode[], depth: number) => { @@ -300,14 +284,6 @@ return 'success' } - function flattenParents(nodes: CategoryNode[], parents: string[] = []): Array<{ text: string; value: string }> { - return nodes.flatMap((node) => { - const path = [...parents, String(node.categoryName || '')].filter(Boolean) - const current = node.id ? [{ text: path.join(' / '), value: String(node.id) }] : [] - return current.concat(flattenParents(node.children || [], path)) - }) - } - const expandAllLabel = computed(() => areAllExpandableExpanded(tree.value, expandedIds.value) ? '全部折叠' : '全部展开' ) @@ -332,10 +308,17 @@ } } - async function refreshParentOptions() { + async function getCategoryTreeSelect() { const res = await fetchCategoryTree({}) const data = ((res as { data?: CategoryNode[] }).data || res || []) as CategoryNode[] - flatParentOptions.value = flattenParents(Array.isArray(data) ? data : []) + categoryTreeOptions.value = [ + { + id: '0', + categoryName: '顶级分类', + parentId: '0', + children: Array.isArray(data) ? data : [] + } + ] } function toggleExpand(id: string) { @@ -366,7 +349,7 @@ async function openAdd(parentRow?: CategoryNode) { actionOpen.value = false resetForm() - await refreshParentOptions() + await getCategoryTreeSelect() if (parentRow?.id) formData.parentId = parentRow.id formTitle.value = '新增产品分类' formOpen.value = true @@ -375,7 +358,7 @@ async function openEdit(node: CategoryNode) { actionOpen.value = false resetForm() - await refreshParentOptions() + await getCategoryTreeSelect() formData.id = node.id formData.parentId = node.parentId || '' formData.categoryName = node.categoryName || '' @@ -391,12 +374,24 @@ actionOpen.value = true } - function onActionSelect(action: { value?: string }) { + function onActionSelect(action: { value?: string; disabled?: boolean }) { const node = actionNode.value if (!node) return - if (action.value === 'add') void openAdd(node) - else if (action.value === 'edit') void openEdit(node) - else if (action.value === 'delete') void onActionDelete() + if (action.value === 'add') { + void openAdd(node) + return + } + if (action.value === 'edit') { + void openEdit(node) + return + } + if (action.value === 'delete') { + if (!canDeleteActionNode.value || action.disabled) { + showFailToast(CREATOR_DELETE_TIP) + return + } + void onActionDelete() + } } async function onActionDelete() { @@ -428,15 +423,6 @@ function closeForm() { if (!submitLoading.value) formOpen.value = false } - function onParentConfirm({ selectedValues }: { selectedValues: string[] }) { - const v = selectedValues[0] || '0' - formData.parentId = v === '0' ? '' : v - parentPickerOpen.value = false - } - function onStatusConfirm({ selectedValues }: { selectedValues: string[] }) { - formData.status = selectedValues[0] || '0' - statusPickerOpen.value = false - } async function submitForm() { if (!formData.categoryName.trim()) {