修改: bug
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 4m47s

This commit is contained in:
sexygoat
2026-02-27 17:40:02 +08:00
parent f1cb1e53c8
commit 4470a4ef04
17 changed files with 908 additions and 544 deletions

View File

@@ -37,12 +37,21 @@
:marginTop="10"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
@row-contextmenu="handleRowContextMenu"
>
<template #default>
<ElTableColumn v-for="col in columns" :key="col.prop || col.type" v-bind="col" />
</template>
</ArtTable>
<!-- 右键菜单 -->
<ArtMenuRight
ref="contextMenuRef"
:menu-items="contextMenuItems"
:menu-width="120"
@select="handleContextMenuSelect"
/>
<!-- 新增/编辑对话框 -->
<ElDialog
v-model="dialogVisible"
@@ -128,6 +137,8 @@
import { useCheckedColumns } from '@/composables/useCheckedColumns'
import { useAuth } from '@/composables/useAuth'
import ArtButtonTable from '@/components/core/forms/ArtButtonTable.vue'
import ArtMenuRight from '@/components/core/others/ArtMenuRight.vue'
import type { MenuItemType } from '@/components/core/others/ArtMenuRight.vue'
import { formatDateTime } from '@/utils/business/format'
import { RoutesAlias } from '@/router/routesAlias'
import {
@@ -149,6 +160,8 @@
const shopLoading = ref(false)
const tableRef = ref()
const formRef = ref<FormInstance>()
const contextMenuRef = ref<InstanceType<typeof ArtMenuRight>>()
const currentRow = ref<ShopPackageAllocationResponse | null>(null)
const packageOptions = ref<PackageResponse[]>([])
const shopOptions = ref<ShopResponse[]>([])
const shopTreeData = ref<ShopResponse[]>([])
@@ -276,8 +289,7 @@
{ label: '分配者', prop: 'allocator_shop_name' },
{ label: '成本价', prop: 'cost_price' },
{ label: '状态', prop: 'status' },
{ label: '创建时间', prop: 'created_at' },
{ label: '操作', prop: 'operation' }
{ label: '创建时间', prop: 'created_at' }
]
// 表单验证规则
@@ -389,45 +401,35 @@
label: '创建时间',
width: 180,
formatter: (row: ShopPackageAllocationResponse) => formatDateTime(row.created_at)
},
{
prop: 'operation',
label: '操作',
width: 220,
fixed: 'right',
formatter: (row: ShopPackageAllocationResponse) => {
const buttons = []
buttons.push(
h(ArtButtonTable, {
text: '详情',
onClick: () => handleViewDetail(row)
})
)
if (hasAuth('package_assign:edit')) {
buttons.push(
h(ArtButtonTable, {
text: '编辑',
onClick: () => showDialog('edit', row)
})
)
}
if (hasAuth('package_assign:delete')) {
buttons.push(
h(ArtButtonTable, {
text: '删除',
onClick: () => deleteAllocation(row)
})
)
}
return h('div', { style: 'display: flex; gap: 8px;' }, buttons)
}
}
])
// 右键菜单项配置
const contextMenuItems = computed((): MenuItemType[] => {
const items: MenuItemType[] = []
items.push({
key: 'detail',
label: '详情'
})
if (hasAuth('package_assign:edit')) {
items.push({
key: 'edit',
label: '编辑'
})
}
if (hasAuth('package_assign:delete')) {
items.push({
key: 'delete',
label: '删除'
})
}
return items
})
// 构建树形结构数据
const buildTreeData = (items: ShopResponse[]) => {
const map = new Map<number, ShopResponse & { children?: ShopResponse[] }>()
@@ -478,7 +480,7 @@
}
const res = await PackageManageService.getPackages(params)
if (res.code === 0) {
packageOptions.value = res.data.items || []
packageOptions.value = res.data.items
}
} catch (error) {
console.error('加载套餐选项失败:', error)
@@ -497,7 +499,7 @@
page_size: 10000 // 使用较大的值获取所有店铺
})
if (res.code === 0) {
shopOptions.value = res.data.items || []
shopOptions.value = res.data.items
// 构建树形结构数据
shopTreeData.value = buildTreeData(shopOptions.value)
}
@@ -516,7 +518,7 @@
page_size: 10
})
if (res.code === 0) {
searchPackageOptions.value = res.data.items || []
searchPackageOptions.value = res.data.items
}
} catch (error) {
console.error('加载搜索栏套餐选项失败:', error)
@@ -528,7 +530,7 @@
try {
const res = await ShopService.getShops({ page: 1, page_size: 10 })
if (res.code === 0) {
searchShopOptions.value = res.data.items || []
searchShopOptions.value = res.data.items
}
} catch (error) {
console.error('加载搜索栏店铺选项失败:', error)
@@ -557,7 +559,7 @@
package_name: query
})
if (res.code === 0) {
searchPackageOptions.value = res.data.items || []
searchPackageOptions.value = res.data.items
}
} catch (error) {
console.error('搜索套餐失败:', error)
@@ -577,7 +579,7 @@
shop_name: query
})
if (res.code === 0) {
searchShopOptions.value = res.data.items || []
searchShopOptions.value = res.data.items
}
} catch (error) {
console.error('搜索店铺失败:', error)
@@ -589,7 +591,7 @@
try {
const res = await ShopService.getShops({ page: 1, page_size: 10 })
if (res.code === 0) {
searchAllocatorShopOptions.value = res.data.items || []
searchAllocatorShopOptions.value = res.data.items
}
} catch (error) {
console.error('加载搜索栏分配者店铺选项失败:', error)
@@ -609,7 +611,7 @@
shop_name: query
})
if (res.code === 0) {
searchAllocatorShopOptions.value = res.data.items || []
searchAllocatorShopOptions.value = res.data.items
}
} catch (error) {
console.error('搜索分配者店铺失败:', error)
@@ -624,7 +626,7 @@
page_size: 10
})
if (res.code === 0) {
searchSeriesAllocationOptions.value = res.data.items || []
searchSeriesAllocationOptions.value = res.data.items
}
} catch (error) {
console.error('加载搜索栏系列分配选项失败:', error)
@@ -644,7 +646,7 @@
series_name: query
})
if (res.code === 0) {
searchSeriesAllocationOptions.value = res.data.items || []
searchSeriesAllocationOptions.value = res.data.items
}
} catch (error) {
console.error('搜索系列分配失败:', error)
@@ -666,7 +668,7 @@
}
const res = await ShopPackageAllocationService.getShopPackageAllocations(params)
if (res.code === 0) {
allocationList.value = res.data.items || []
allocationList.value = res.data.items
pagination.total = res.data.total || 0
}
} catch (error) {
@@ -845,6 +847,31 @@
const handleViewDetail = (row: ShopPackageAllocationResponse) => {
router.push(`${RoutesAlias.PackageAssignDetail}/${row.id}`)
}
// 处理表格行右键菜单
const handleRowContextMenu = (row: ShopPackageAllocationResponse, column: any, event: MouseEvent) => {
event.preventDefault()
event.stopPropagation()
currentRow.value = row
contextMenuRef.value?.show(event)
}
// 处理右键菜单选择
const handleContextMenuSelect = (item: MenuItemType) => {
if (!currentRow.value) return
switch (item.key) {
case 'detail':
handleViewDetail(currentRow.value)
break
case 'edit':
showDialog('edit', currentRow.value)
break
case 'delete':
deleteAllocation(currentRow.value)
break
}
}
</script>
<style lang="scss" scoped>