修改: 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

@@ -36,12 +36,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"
@@ -101,6 +110,54 @@
/>
</ElSelect>
</ElFormItem>
<ElFormItem label="套餐周期类型" prop="calendar_type">
<ElSelect
v-model="form.calendar_type"
placeholder="请选择套餐周期类型"
style="width: 100%"
clearable
>
<ElOption label="自然月" value="natural_month" />
<ElOption label="按天" value="by_day" />
</ElSelect>
</ElFormItem>
<ElFormItem label="有效期(月)" prop="duration_months">
<ElInputNumber
v-model="form.duration_months"
:min="1"
:max="120"
:controls="false"
style="width: 100%"
placeholder="请输入有效期(月)"
/>
</ElFormItem>
<ElFormItem
v-if="form.calendar_type === 'by_day'"
label="套餐天数"
prop="duration_days"
>
<ElInputNumber
v-model="form.duration_days"
:min="1"
:max="3650"
:controls="false"
style="width: 100%"
placeholder="请输入套餐天数"
/>
</ElFormItem>
<ElFormItem label="流量重置周期" prop="data_reset_cycle">
<ElSelect
v-model="form.data_reset_cycle"
placeholder="请选择流量重置周期"
style="width: 100%"
clearable
>
<ElOption label="每日" value="daily" />
<ElOption label="每月" value="monthly" />
<ElOption label="每年" value="yearly" />
<ElOption label="不重置" value="none" />
</ElSelect>
</ElFormItem>
<ElFormItem label="真流量额度(MB)" prop="real_data_mb">
<ElInputNumber
v-model="form.real_data_mb"
@@ -130,13 +187,11 @@
placeholder="请输入虚流量额度"
/>
</ElFormItem>
<ElFormItem label="有效期(月)" prop="duration_months">
<ElInputNumber
v-model="form.duration_months"
:min="1"
:max="120"
:controls="false"
style="width: 100%"
<ElFormItem label="启用实名激活">
<ElSwitch
v-model="form.enable_realname_activation"
active-text="启用"
inactive-text="不启用"
/>
</ElFormItem>
<ElFormItem label="成本价(元)" prop="cost_price">
@@ -197,6 +252,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 {
@@ -221,6 +278,8 @@
const seriesLoading = ref(false)
const tableRef = ref()
const formRef = ref<FormInstance>()
const contextMenuRef = ref<InstanceType<typeof ArtMenuRight>>()
const currentRow = ref<PackageResponse | null>(null)
const seriesOptions = ref<SeriesSelectOption[]>([])
const searchSeriesOptions = ref<SeriesSelectOption[]>([])
@@ -327,8 +386,7 @@
{ label: '建议售价', prop: 'suggested_retail_price' },
{ label: '上架状态', prop: 'shelf_status' },
{ label: '状态', prop: 'status' },
{ label: '创建时间', prop: 'created_at' },
{ label: '操作', prop: 'operation' }
{ label: '创建时间', prop: 'created_at' }
]
// 表单验证规则
@@ -355,6 +413,14 @@
baseRules.virtual_data_mb = [{ required: true, message: '请输入虚流量额度', trigger: 'blur' }]
}
// 如果套餐周期类型是按天,则套餐天数为必填
if (form.calendar_type === 'by_day') {
baseRules.duration_days = [
{ required: true, message: '请输入套餐天数', trigger: 'blur' },
{ type: 'number', min: 1, max: 3650, message: '套餐天数范围 1-3650 天', trigger: 'blur' }
]
}
return baseRules
})
@@ -365,10 +431,14 @@
package_name: '',
series_id: undefined,
package_type: '',
calendar_type: undefined,
duration_days: undefined,
duration_months: 1,
data_reset_cycle: undefined,
enable_virtual_data: false,
enable_realname_activation: false,
real_data_mb: 0,
virtual_data_mb: 0,
duration_months: 1,
cost_price: 0,
suggested_retail_price: undefined,
description: ''
@@ -388,12 +458,14 @@
{
prop: 'package_name',
label: '套餐名称',
minWidth: 160
minWidth: 160,
showOverflowTooltip: true
},
{
prop: 'series_name',
label: '所属系列',
width: 120
width: 160,
showOverflowTooltip: true
},
{
prop: 'package_type',
@@ -476,45 +548,35 @@
label: '创建时间',
width: 180,
formatter: (row: PackageResponse) => formatDateTime(row.created_at)
},
{
prop: 'operation',
label: '操作',
width: 220,
fixed: 'right',
formatter: (row: PackageResponse) => {
const buttons = []
buttons.push(
h(ArtButtonTable, {
text: '详情',
onClick: () => handleViewDetail(row)
})
)
if (hasAuth('package:edit')) {
buttons.push(
h(ArtButtonTable, {
text: '编辑',
onClick: () => showDialog('edit', row)
})
)
}
if (hasAuth('package:delete')) {
buttons.push(
h(ArtButtonTable, {
text: '删除',
onClick: () => deletePackage(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:edit')) {
items.push({
key: 'edit',
label: '编辑'
})
}
if (hasAuth('package:delete')) {
items.push({
key: 'delete',
label: '删除'
})
}
return items
})
// 监听虚流量开关变化,关闭时重置虚流量额度
watch(
() => form.enable_virtual_data,
@@ -545,7 +607,7 @@
}
const res = await PackageSeriesService.getPackageSeries(params)
if (res.code === 0) {
seriesOptions.value = res.data.items || []
seriesOptions.value = res.data.items
}
} catch (error) {
console.error('加载系列选项失败:', error)
@@ -567,7 +629,7 @@
}
const res = await PackageSeriesService.getPackageSeries(params)
if (res.code === 0) {
searchSeriesOptions.value = res.data.items || []
searchSeriesOptions.value = res.data.items
}
} catch (error) {
console.error('加载搜索栏系列选项失败:', error)
@@ -607,8 +669,8 @@
}
const res = await PackageManageService.getPackages(params)
if (res.code === 0) {
packageList.value = res.data.items || []
pagination.total = res.data.total || 0
packageList.value = res.data.items
pagination.total = res.data.total
}
} catch (error) {
console.error(error)
@@ -658,10 +720,14 @@
form.package_name = row.package_name
form.series_id = row.series_id
form.package_type = row.package_type
form.calendar_type = row.calendar_type || undefined
form.duration_days = row.duration_days || undefined
form.duration_months = row.duration_months
form.data_reset_cycle = row.data_reset_cycle || undefined
form.enable_virtual_data = row.enable_virtual_data || false
form.enable_realname_activation = row.enable_realname_activation || false
form.real_data_mb = row.real_data_mb || 0
form.virtual_data_mb = row.virtual_data_mb || 0
form.duration_months = row.duration_months
form.cost_price = row.cost_price / 100 // 分转换为元显示
form.suggested_retail_price = row.suggested_retail_price
? row.suggested_retail_price / 100
@@ -673,10 +739,14 @@
form.package_name = ''
form.series_id = undefined
form.package_type = ''
form.calendar_type = undefined
form.duration_days = undefined
form.duration_months = 1
form.data_reset_cycle = undefined
form.enable_virtual_data = false
form.enable_realname_activation = false
form.real_data_mb = 0
form.virtual_data_mb = 0
form.duration_months = 1
form.cost_price = 0
form.suggested_retail_price = undefined
form.description = ''
@@ -708,10 +778,14 @@
form.package_name = ''
form.series_id = undefined
form.package_type = ''
form.calendar_type = undefined
form.duration_days = undefined
form.duration_months = 1
form.data_reset_cycle = undefined
form.enable_virtual_data = false
form.enable_realname_activation = false
form.real_data_mb = 0
form.virtual_data_mb = 0
form.duration_months = 1
form.cost_price = 0
form.suggested_retail_price = undefined
form.description = ''
@@ -758,13 +832,23 @@
package_type: form.package_type,
duration_months: form.duration_months,
cost_price: costPriceInCents,
enable_virtual_data: form.enable_virtual_data
enable_virtual_data: form.enable_virtual_data || false,
enable_realname_activation: form.enable_realname_activation || false
}
// 可选字段
if (form.series_id) {
data.series_id = form.series_id
}
if (form.calendar_type) {
data.calendar_type = form.calendar_type
}
if (form.calendar_type === 'by_day' && form.duration_days) {
data.duration_days = form.duration_days
}
if (form.data_reset_cycle) {
data.data_reset_cycle = form.data_reset_cycle
}
if (suggestedRetailPriceInCents !== undefined) {
data.suggested_retail_price = suggestedRetailPriceInCents
}
@@ -826,6 +910,31 @@
const handleViewDetail = (row: PackageResponse) => {
router.push(`${RoutesAlias.PackageDetail}/${row.id}`)
}
// 处理表格行右键菜单
const handleRowContextMenu = (row: PackageResponse, 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':
deletePackage(currentRow.value)
break
}
}
</script>
<style lang="scss" scoped>