feat(filter): 将发件人黑白名单拆分为独立设置菜单并解耦日志页面
Some checks are pending
Security Checks / security (push) Waiting to run

This commit is contained in:
smail 2026-09-13 08:21:49 +08:00
parent a717183e55
commit 946fdbbe55
4 changed files with 102 additions and 84 deletions

View File

@ -1,5 +1,5 @@
import {EpMenu} from "vue-icons-plus/ep";
import { Lock, Connection, Setting, FolderOpened, Filter, User, Grid, Document } from '@element-plus/icons-vue';
import {EpMenu} from "vue-icons-plus/ep";
import { Lock, Connection, Setting, FolderOpened, Filter, User, Grid, Document, Checked } from '@element-plus/icons-vue';
import {computed, ref, onMounted, onUnmounted, defineAsyncComponent} from 'vue'
import SettingsPageStatus from '../SettingsPageStatus/SettingsPageStatus.vue'
@ -25,6 +25,7 @@ const GroupSettings = lazySettings(() => import('../GroupSettings/GroupSettings.
const RuleSettings = lazySettings(() => import('../RuleSettings/RuleSettings.vue'))
const UserManagement = lazySettings(() => import('../UserManagement/UserManagement.vue'))
const PluginSettings = lazySettings(() => import('../PluginSettings/PluginSettings.vue'))
const SenderFilterManagement = lazySettings(() => import('../SenderFilterManagement/SenderFilterManagement.vue'))
const LogSettings = lazySettings(() => import('../LogSettings/LogSettings.vue'))
export function usePage() {
@ -54,6 +55,7 @@ export function usePage() {
{ key: 'rule', label: lang.rule_setting, hint: '邮件处理规则', icon: Filter, component: RuleSettings, capability: 'user.read' },
{ key: 'users', label: lang.user_management, hint: '账号与权限管理', icon: User, component: UserManagement, capability: 'user.manage' },
{ key: 'plugins', label: lang.plugin_settings, hint: '扩展功能管理', icon: Grid, component: PluginSettings, capability: 'plugin.read' },
{ key: 'sender-filter', label: '黑白名单', hint: '发件人信任与拦截', icon: Checked, component: SenderFilterManagement, capability: 'user.read' },
{ key: 'logs', label: '日志', hint: '操作、收发信与运行记录', icon: Document, component: LogSettings, capability: 'audit.read' },
].filter(item => {
// 日志数据范围由服务端强制过滤;菜单只决定入口是否可见。
@ -117,5 +119,6 @@ export {
GroupSettings,
RuleSettings,
UserManagement,
PluginSettings
PluginSettings,
SenderFilterManagement
}

View File

@ -1,8 +1,5 @@
<template>
<template>
<div class="log-settings-container">
<!-- 日志上方:发件人黑白名单管理(支持添加、删除、拉黑/转白,仅当前用户维护自身名单) -->
<SenderFilterManagement />
<section class="log-settings">
<header class="log-heading">
<h2>日志记录</h2>
@ -173,7 +170,6 @@
<script setup>
import { useLogs } from './LogSettings.js'
import SenderFilterManagement from '../SenderFilterManagement/SenderFilterManagement.vue'
const {
category, categories, loading, error, items, offset,

View File

@ -1,45 +1,58 @@
.sender-filter-management {
background: var(--el-bg-color-overlay, #ffffff);
border: 1px solid var(--el-border-color-light, #e4e7ed);
border-radius: 8px;
padding: 16px;
margin-bottom: 20px;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
.sender-filter-card {
padding: 0;
display: flex;
flex-direction: column;
gap: 16px;
}
.sf-header {
.settings-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 14px;
align-items: flex-start;
gap: 16px;
margin-bottom: 0;
}
.sf-title-group {
display: flex;
align-items: center;
gap: 12px;
}
.sf-title {
margin: 0;
font-size: 16px;
.header-main h3 {
margin: 0 0 6px 0;
font-size: 18px;
font-weight: 600;
color: var(--el-text-color-primary, #303133);
color: var(--pm-text-primary, #303133);
}
.settings-desc {
margin: 0;
font-size: 13px;
color: var(--pm-text-secondary, #909399);
line-height: 1.5;
}
.sf-badges {
display: flex;
gap: 8px;
flex-shrink: 0;
}
.sf-badge {
font-size: 12px;
}
.sf-quick-add {
.sf-quick-add-box {
display: flex;
align-items: center;
gap: 8px;
gap: 10px;
padding: 12px 16px;
background-color: var(--el-fill-color-light, #f8fafc);
border: 1px solid var(--el-border-color-lighter, #ebeef5);
border-radius: 8px;
}
.sf-input-email {
width: 320px;
}
.sf-select-type {
width: 130px;
}
.sf-toolbar {
@ -47,7 +60,6 @@
justify-content: space-between;
align-items: center;
gap: 12px;
margin-bottom: 12px;
flex-wrap: wrap;
}
@ -60,7 +72,9 @@
}
.sf-table-wrapper {
margin-bottom: 12px;
border: 1px solid var(--el-border-color-lighter, #ebeef5);
border-radius: 6px;
overflow: hidden;
}
.sf-table {
@ -69,6 +83,7 @@
.sf-actions {
display: flex;
justify-content: center;
align-items: center;
gap: 8px;
}
@ -76,20 +91,21 @@
.sf-pagination {
display: flex;
justify-content: flex-end;
margin-top: 8px;
margin-top: 4px;
}
@media (max-width: 768px) {
.sf-header {
.settings-header {
flex-direction: column;
align-items: flex-start;
gap: 12px;
gap: 8px;
}
.sf-quick-add {
width: 100%;
flex-wrap: wrap;
.sf-quick-add-box {
flex-direction: column;
align-items: stretch;
}
.sf-quick-add .el-input {
.sf-input-email,
.sf-select-type {
width: 100% !important;
}
.sf-toolbar {

View File

@ -1,46 +1,50 @@
<template>
<div class="sender-filter-management" v-loading="loading">
<!-- 面板标题与快捷操作栏 -->
<div class="sf-header">
<div class="sf-title-group">
<h3 class="sf-title">发件人黑白名单管理</h3>
<div class="sf-badges">
<el-tag type="success" effect="plain" class="sf-badge">
信任白名单: {{ whitelistCount }}
</el-tag>
<el-tag type="danger" effect="plain" class="sf-badge">
拦截黑名单: {{ blacklistCount }}
</el-tag>
</div>
<template>
<div class="settings-card sender-filter-card" v-loading="loading">
<div class="settings-header">
<div class="header-main">
<h3>发件人黑白名单</h3>
<p class="settings-desc">
管理受信任的白名单与受拦截的黑名单发件人。白名单邮件不提示风险,黑名单发件人邮件将强行标记风险警示。
</p>
</div>
<div class="sf-quick-add">
<el-input
v-model="addForm.email"
placeholder="输入发件人邮箱 (如 friend@example.com)"
clearable
size="default"
style="width: 280px"
@keyup.enter="handleAdd"
/>
<el-select
v-model="addForm.filter_type"
size="default"
style="width: 120px"
>
<el-option label="信任白名单" value="whitelist" />
<el-option label="拦截黑名单" value="blacklist" />
</el-select>
<el-button
type="primary"
size="default"
:loading="addLoading"
@click="handleAdd"
>
添加名单
</el-button>
<div class="sf-badges">
<el-tag type="success" effect="plain" class="sf-badge">
信任白名单: {{ whitelistCount }}
</el-tag>
<el-tag type="danger" effect="plain" class="sf-badge">
拦截黑名单: {{ blacklistCount }}
</el-tag>
</div>
</div>
<!-- 快捷添加区域 -->
<div class="sf-quick-add-box">
<el-input
v-model="addForm.email"
placeholder="输入发件人邮箱 (如 friend@example.com)"
clearable
size="default"
class="sf-input-email"
@keyup.enter="handleAdd"
/>
<el-select
v-model="addForm.filter_type"
size="default"
class="sf-select-type"
>
<el-option label="信任白名单" value="whitelist" />
<el-option label="拦截黑名单" value="blacklist" />
</el-select>
<el-button
type="primary"
size="default"
:loading="addLoading"
@click="handleAdd"
>
添加名单
</el-button>
</div>
<!-- 筛选与搜索工具条 -->
<div class="sf-toolbar">
<el-radio-group
@ -75,12 +79,12 @@
<el-table
:data="filterList"
stripe
size="small"
size="default"
class="sf-table"
empty-text="暂无匹配的发件人规则"
empty-text="暂无匹配的发件人名单"
>
<el-table-column prop="email" label="发件人邮箱" min-width="200" show-overflow-tooltip />
<el-table-column label="名单类型" width="130" align="center">
<el-table-column prop="email" label="发件人邮箱" min-width="220" show-overflow-tooltip />
<el-table-column label="名单属性" width="130" align="center">
<template #default="{ row }">
<el-tag
v-if="row.filter_type === 'whitelist'"
@ -100,7 +104,7 @@
</el-tag>
</template>
</el-table-column>
<el-table-column label="更新/添加时间" width="160" align="center">
<el-table-column label="更新时间" width="160" align="center">
<template #default="{ row }">
<span>{{ formatDate(row.updated_at || row.created_at) }}</span>
</template>
@ -170,7 +174,6 @@ const {
currentTab,
addForm,
addLoading,
loadFilters,
handleSearch,
handleTabChange,
handlePageChange,