删除多余代码

This commit is contained in:
sexygoat
2026-04-08 19:31:22 +08:00
parent b510b4539f
commit d1c6588d8f
110 changed files with 897 additions and 24613 deletions

View File

@@ -9,7 +9,9 @@
@refresh="handleRefresh"
>
<template #left>
<el-button type="primary" @click="showCreateDialog">新增规则</el-button>
<el-button type="primary" @click="showCreateDialog" v-if="hasAuth('alert_rules:create')"
>新增规则</el-button
>
</template>
</ArtTableHeader>
@@ -20,26 +22,13 @@
:loading="loading"
:data="tableData"
:marginTop="10"
:row-class-name="getRowClassName"
@row-contextmenu="handleRowContextMenu"
@cell-mouse-enter="handleCellMouseEnter"
@cell-mouse-leave="handleCellMouseLeave"
:actions="getActions"
:actionsWidth="160"
>
<template #default>
<el-table-column v-for="col in columns" :key="col.prop || col.type" v-bind="col" />
</template>
</ArtTable>
<!-- 鼠标悬浮提示 -->
<TableContextMenuHint :visible="showContextMenuHint" :position="hintPosition" />
<!-- 右键菜单 -->
<ArtMenuRight
ref="contextMenuRef"
:menu-items="contextMenuItems"
:menu-width="120"
@select="handleContextMenuSelect"
/>
</el-card>
<!-- 新增/编辑规则弹窗 -->
@@ -164,26 +153,16 @@
import { PollingAlertService } from '@/api/modules'
import type { PollingAlertRule, CreatePollingAlertRuleRequest } from '@/types/api'
import { formatDateTime } from '@/utils/business/format'
import { useTableContextMenu } from '@/composables/useTableContextMenu'
import { useCheckedColumns } from '@/composables/useCheckedColumns'
import type { MenuItemType } from '@/components/core/others/ArtMenuRight.vue'
import { useAuth } from '@/composables/useAuth'
const { hasAuth } = useAuth()
const loading = ref(false)
const tableData = ref<PollingAlertRule[]>([])
const dialogVisible = ref(false)
const dialogType = ref<'create' | 'edit'>('create')
const formRef = ref<FormInstance>()
const contextMenuRef = ref()
const currentRow = ref<PollingAlertRule | null>(null)
// 使用表格右键菜单功能
const {
showContextMenuHint,
hintPosition,
getRowClassName,
handleCellMouseEnter,
handleCellMouseLeave
} = useTableContextMenu()
const form = reactive<CreatePollingAlertRuleRequest & { id?: number }>({
rule_name: '',
@@ -301,14 +280,38 @@
}))
)
// 右键菜单项
const contextMenuItems = computed<MenuItemType[]>(() => {
return [
{ key: 'edit', label: '编辑' },
{ key: 'toggle', label: currentRow.value?.status === 1 ? '禁用' : '启用' },
{ key: 'delete', label: '删除' }
]
})
// 获取操作按钮
const getActions = (row: PollingAlertRule) => {
const actions: any[] = []
// 禁用/启用按钮直接显示
if (hasAuth('alert_rules:toggle')) {
actions.push({
label: row.status === 1 ? '禁用' : '启用',
handler: () => toggleStatus(row),
type: 'primary'
})
}
// 编辑和删除放到更多里
if (hasAuth('alert_rules:edit')) {
actions.push({
label: '编辑',
handler: () => showEditDialog(row),
type: 'primary'
})
}
if (hasAuth('alert_rules:delete')) {
actions.push({
label: '删除',
handler: () => handleDelete(row),
type: 'danger'
})
}
return actions
}
watch(dialogVisible, (val) => {
if (!val) {
@@ -444,31 +447,6 @@
})
}
// 处理表格行右键菜单
const handleRowContextMenu = (row: PollingAlertRule, 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 'edit':
showEditDialog(currentRow.value)
break
case 'toggle':
toggleStatus(currentRow.value)
break
case 'delete':
handleDelete(currentRow.value)
break
}
}
loadData()
</script>

View File

@@ -27,9 +27,18 @@
@refresh="handleRefresh"
>
<template #left>
<ElButton type="primary" @click="showCreateDialog">新增配置</ElButton>
<ElButton @click="handlePreview">预览清理</ElButton>
<ElButton type="warning" @click="handleTriggerCleanup" :loading="triggering">
<ElButton type="primary" @click="showCreateDialog" v-if="hasAuth('data_cleanup:create')"
>新增配置</ElButton
>
<ElButton @click="handlePreview" v-if="hasAuth('data_cleanup:preview')"
>预览清理</ElButton
>
<ElButton
type="warning"
@click="handleTriggerCleanup"
:loading="triggering"
v-if="hasAuth('data_cleanup:trigger')"
>
手动清理
</ElButton>
</template>
@@ -42,28 +51,15 @@
:loading="loading"
:data="configList"
:marginTop="10"
:row-class-name="getRowClassName"
:show-pagination="false"
@row-contextmenu="handleRowContextMenu"
@cell-mouse-enter="handleCellMouseEnter"
@cell-mouse-leave="handleCellMouseLeave"
:actions="getActions"
:actionsWidth="180"
>
<template #default>
<ElTableColumn v-for="col in columns" :key="col.prop || col.type" v-bind="col" />
</template>
</ArtTable>
<!-- 鼠标悬浮提示 -->
<TableContextMenuHint :visible="showContextMenuHint" :position="hintPosition" />
<!-- 右键菜单 -->
<ArtMenuRight
ref="contextMenuRef"
:menu-items="contextMenuItems"
:menu-width="140"
@select="handleContextMenuSelect"
/>
<!-- 新增/编辑对话框 -->
<ElDialog
v-model="dialogVisible"
@@ -131,8 +127,8 @@
<ElTable :data="previewData" border>
<ElTableColumn prop="table_name" label="表名" width="150" />
<ElTableColumn prop="description" label="说明" min-width="180" />
<ElTableColumn prop="retention_days" label="保留天数" width="100" align="center" />
<ElTableColumn prop="record_count" label="待清理记录数" width="130" align="right">
<ElTableColumn prop="retention_days" label="保留天数" width="100" />
<ElTableColumn prop="record_count" label="待清理记录数" width="130">
<template #default="{ row }">
<span :class="{ 'text-danger': row.record_count > 10000 }">
{{ row.record_count.toLocaleString() }}
@@ -146,7 +142,7 @@
</ElDialog>
<!-- 清理日志对话框 -->
<ElDialog v-model="logVisible" title="清理日志" width="1000px">
<ElDialog v-model="logVisible" title="清理日志" width="60%">
<div style="margin-bottom: 16px">
<ElInput
v-model="logFilter.table_name"
@@ -183,14 +179,14 @@
</ElTag>
</template>
</ElTableColumn>
<ElTableColumn prop="retention_days" label="保留天数" width="100" align="center" />
<ElTableColumn prop="deleted_count" label="删除记录数" width="110" align="right">
<ElTableColumn prop="retention_days" label="保留天数" width="100" />
<ElTableColumn prop="deleted_count" label="删除记录数" width="110">
<template #default="{ row }">
{{ row.deleted_count.toLocaleString() }}
</template>
</ElTableColumn>
<ElTableColumn prop="duration_ms" label="耗时(ms)" width="100" align="right" />
<ElTableColumn prop="started_at" label="开始时间" width="160">
<ElTableColumn prop="duration_ms" label="耗时(ms)" width="100" />
<ElTableColumn prop="started_at" label="开始时间" width="180">
<template #default="{ row }">
{{ formatDateTime(row.started_at) }}
</template>
@@ -235,14 +231,13 @@
DataCleanupProgress
} from '@/types/api'
import { useCheckedColumns } from '@/composables/useCheckedColumns'
import { useTableContextMenu } from '@/composables/useTableContextMenu'
import ArtMenuRight from '@/components/core/others/ArtMenuRight.vue'
import TableContextMenuHint from '@/components/core/others/TableContextMenuHint.vue'
import type { MenuItemType } from '@/components/core/others/ArtMenuRight.vue'
import { formatDateTime } from '@/utils/business/format'
import { useAuth } from '@/composables/useAuth'
defineOptions({ name: 'DataCleanup' })
const { hasAuth } = useAuth()
const loading = ref(false)
const submitLoading = ref(false)
const triggering = ref(false)
@@ -253,10 +248,6 @@
const dialogType = ref<'add' | 'edit'>('add')
const formRef = ref<FormInstance>()
// 右键菜单
const contextMenuRef = ref<InstanceType<typeof ArtMenuRight>>()
const currentRow = ref<DataCleanupConfig | null>(null)
// 列配置
const columnOptions = [
{ label: '表名', prop: 'table_name' },
@@ -329,14 +320,12 @@
{
prop: 'retention_days',
label: '保留天数',
width: 100,
align: 'center'
width: 100
},
{
prop: 'batch_size',
label: '每批删除条数',
width: 130,
align: 'right',
formatter: (row: DataCleanupConfig) => row.batch_size.toLocaleString()
},
{
@@ -429,7 +418,7 @@
})
dialogType.value = 'edit'
dialogVisible.value = true
nextTick(() => {
await nextTick(() => {
formRef.value?.clearValidate()
})
}
@@ -537,14 +526,6 @@
}
}
// 查看日志
const handleViewLogs = () => {
logFilter.table_name = ''
logPagination.page = 1
logVisible.value = true
getCleanupLogs()
}
// 获取清理日志
const getCleanupLogs = async () => {
try {
@@ -562,51 +543,43 @@
}
}
// 右键菜单项
const contextMenuItems = computed((): MenuItemType[] => {
return [
{ key: 'edit', label: '编辑' },
{ key: 'logs', label: '查看日志' },
{ key: 'delete', label: '删除' }
]
})
// 获取操作按钮
const getActions = (row: DataCleanupConfig) => {
const actions: any[] = []
// 处理表格行右键菜单
const handleRowContextMenu = (row: DataCleanupConfig, 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 'edit':
showEditDialog(currentRow.value)
break
case 'logs':
logFilter.table_name = currentRow.value.table_name
logPagination.page = 1
logVisible.value = true
getCleanupLogs()
break
case 'delete':
handleDelete(currentRow.value)
break
// 查看日志按钮直接显示
if (hasAuth('data_cleanup:logs')) {
actions.push({
label: '查看日志',
handler: () => {
logFilter.table_name = row.table_name
logPagination.page = 1
logVisible.value = true
getCleanupLogs()
},
type: 'primary'
})
}
}
// 使用表格右键菜单功能
const {
showContextMenuHint,
hintPosition,
getRowClassName,
handleCellMouseEnter,
handleCellMouseLeave
} = useTableContextMenu()
// 编辑和删除放到更多里
if (hasAuth('data_cleanup:edit')) {
actions.push({
label: '编辑',
handler: () => showEditDialog(row),
type: 'primary'
})
}
if (hasAuth('data_cleanup:delete')) {
actions.push({
label: '删除',
handler: () => handleDelete(row),
type: 'danger'
})
}
return actions
}
</script>
<style scoped lang="scss">
@@ -614,10 +587,6 @@
height: 100%;
}
:deep(.el-table__row.table-row-with-context-menu) {
cursor: pointer;
}
.text-danger {
font-weight: 600;
color: var(--el-color-danger);

View File

@@ -1,81 +1,5 @@
<template>
<div class="polling-monitor-page">
<!-- 总览统计卡片 -->
<el-row :gutter="20" class="stats-row">
<el-col :xs="24" :sm="12" :md="8" :lg="24 / 5" :xl="24 / 5">
<el-card shadow="hover">
<div class="stat-card">
<div class="stat-icon total">
<el-icon :size="32"><Document /></el-icon>
</div>
<div class="stat-content">
<div class="stat-label">总卡数</div>
<div class="stat-value">{{ overviewStats?.total_cards || 0 }}</div>
</div>
</div>
</el-card>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="24 / 5" :xl="24 / 5">
<el-card shadow="hover">
<div class="stat-card">
<div class="stat-icon initialized">
<el-icon :size="32"><CircleCheck /></el-icon>
</div>
<div class="stat-content">
<div class="stat-label">已初始化</div>
<div class="stat-value">{{ overviewStats?.initialized_cards || 0 }}</div>
<el-progress
v-if="overviewStats"
:percentage="overviewStats.init_progress"
:stroke-width="6"
:show-text="false"
style="margin-top: 8px"
/>
</div>
</div>
</el-card>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="24 / 5" :xl="24 / 5">
<el-card shadow="hover">
<div class="stat-card">
<div class="stat-icon realname">
<el-icon :size="32"><User /></el-icon>
</div>
<div class="stat-content">
<div class="stat-label">实名队列</div>
<div class="stat-value">{{ overviewStats?.realname_queue_size || 0 }}</div>
</div>
</div>
</el-card>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="24 / 5" :xl="24 / 5">
<el-card shadow="hover">
<div class="stat-card">
<div class="stat-icon package">
<el-icon :size="32"><Box /></el-icon>
</div>
<div class="stat-content">
<div class="stat-label">套餐队列</div>
<div class="stat-value">{{ overviewStats?.package_queue_size || 0 }}</div>
</div>
</div>
</el-card>
</el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="24 / 5" :xl="24 / 5">
<el-card shadow="hover">
<div class="stat-card">
<div class="stat-icon carddata">
<el-icon :size="32"><DataLine /></el-icon>
</div>
<div class="stat-content">
<div class="stat-label">流量队列</div>
<div class="stat-value">{{ overviewStats?.carddata_queue_size || 0 }}</div>
</div>
</div>
</el-card>
</el-col>
</el-row>
<!-- 队列状态 -->
<el-card shadow="never" class="section-card">
<template #header>
@@ -173,33 +97,19 @@
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
import { ElMessage } from 'element-plus'
import { Document, CircleCheck, User, Box, DataLine } from '@element-plus/icons-vue'
import { PollingMonitorService } from '@/api/modules'
import type {
PollingOverviewStats,
PollingInitProgress,
PollingQueueStatus,
PollingTaskStats
} from '@/types/api'
import { formatDateTime } from '@/utils/business/format'
const overviewStats = ref<PollingOverviewStats>()
const initProgress = ref<PollingInitProgress>()
const queueStatusList = ref<PollingQueueStatus[]>([])
const taskStatsList = ref<PollingTaskStats[]>([])
let refreshTimer: NodeJS.Timeout | null = null
// 加载总览统计
const loadOverviewStats = async () => {
try {
const { data } = await PollingMonitorService.getOverviewStats()
overviewStats.value = data
} catch (error) {
ElMessage.error('加载总览统计失败')
}
}
// 加载初始化进度
const loadInitProgress = async (showMessage = false) => {
try {
@@ -244,7 +154,6 @@
// 加载所有数据
const loadAllData = () => {
loadOverviewStats()
loadInitProgress()
loadQueueStatus()
loadTaskStats()