feat(compliance): add content compliance detection across tenant, ops, and clients

Implements the Revision 8/9 compliance design: tenant + ops backends, ops-web
content-safety pages, admin-web editor/publish gate integration, desktop publish
block surfacing, and supporting migrations / shared types / config plumbing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-05 20:48:14 +08:00
parent 81577b6154
commit 745cdd79cf
73 changed files with 12747 additions and 1892 deletions
+43 -1
View File
@@ -48,11 +48,16 @@
<script setup lang="ts">
import {
AuditOutlined,
BookOutlined,
ControlOutlined,
CrownOutlined,
FileSearchOutlined,
GlobalOutlined,
LineChartOutlined,
SafetyCertificateOutlined,
SettingOutlined,
TeamOutlined,
UserSwitchOutlined,
} from '@ant-design/icons-vue'
import type { ItemType } from 'ant-design-vue'
import { computed, h, onMounted, ref } from 'vue'
@@ -76,6 +81,11 @@ const menuLeaves: MenuLeaf[] = [
{ key: '/admin-users', label: '用户管理', path: '/admin-users' },
{ key: '/kol-subscriptions', label: '订阅包审批', path: '/kol-subscriptions' },
{ key: '/site-domain-mappings', label: '站点映射', path: '/site-domain-mappings' },
{ key: '/compliance/policy', label: '全局策略', path: '/compliance/policy' },
{ key: '/compliance/dictionaries', label: '合规词库', path: '/compliance/dictionaries' },
{ key: '/compliance/manual-reviews', label: '人工审阅', path: '/compliance/manual-reviews' },
{ key: '/compliance/records', label: '检测记录', path: '/compliance/records' },
{ key: '/compliance/stats', label: '合规统计', path: '/compliance/stats' },
{ key: '/accounts', label: '操作员管理', path: '/accounts' },
{ key: '/audits', label: '审计日志', path: '/audits' },
]
@@ -96,6 +106,38 @@ const menuItems = computed<ItemType[]>(() => [
label: '站点映射',
icon: () => h(GlobalOutlined),
},
{
key: 'compliance',
label: '内容安全',
icon: () => h(SafetyCertificateOutlined),
children: [
{
key: '/compliance/policy',
label: '全局策略',
icon: () => h(ControlOutlined),
},
{
key: '/compliance/dictionaries',
label: '合规词库',
icon: () => h(BookOutlined),
},
{
key: '/compliance/manual-reviews',
label: '人工审阅',
icon: () => h(UserSwitchOutlined),
},
{
key: '/compliance/records',
label: '检测记录',
icon: () => h(FileSearchOutlined),
},
{
key: '/compliance/stats',
label: '合规统计',
icon: () => h(LineChartOutlined),
},
],
},
{
key: 'system',
label: '系统设置',
@@ -115,7 +157,7 @@ const menuItems = computed<ItemType[]>(() => [
},
])
const openKeys = ref<string[]>(['system'])
const openKeys = ref<string[]>(['compliance', 'system'])
function onOpenKeysChange(keys: string[]) {
openKeys.value = keys