完善权限监控与安全中心

This commit is contained in:
Cheng Zhou
2026-06-17 17:21:48 +08:00
parent 1886765db8
commit 061792c73f
15 changed files with 2837 additions and 160 deletions
@@ -57,6 +57,16 @@ describe("PermissionAccessLogs", () => {
expect(source).not.toContain("筛选范围内行为总量");
});
it("keeps audit grid widths consistent with SecurityCenter", () => {
const source = readSource();
expect(source).toContain("grid-template-columns: minmax(320px, 1fr) minmax(0, 1.35fr);");
expect(source).toContain("@media (max-width: 1100px)");
expect(source).toContain("grid-template-columns: repeat(2, minmax(0, 1fr));");
expect(source).toContain("@media (max-width: 720px)");
expect(source).toContain("grid-template-columns: 1fr;");
});
it("removes the duplicated audit hero copy", () => {
const source = readSource();
@@ -65,6 +75,7 @@ describe("PermissionAccessLogs", () => {
expect(source).not.toContain("权限监控 / 访问日志");
expect(source).not.toContain("用户行为审计");
expect(source).not.toContain("按用户行为聚合访问记录,接口访问细节保留在终端式流水中");
expect(source).not.toContain("查看详细的接口访问与安全事件记录");
});
it("streams terminal logs from top to bottom and refreshes in realtime", () => {
@@ -85,14 +96,56 @@ describe("PermissionAccessLogs", () => {
expect(source).toContain("ip=${ip}");
expect(source).toContain("user.sample_ip_address || \"未知 IP\"");
expect(source).toContain("ipRankingItems");
expect(source).toContain("IP访问排行");
expect(source).toContain("账号");
expect(source).toContain("rank-location");
expect(source).not.toContain("TOP {{ userStats.length }}");
expect(source).not.toContain("rank-ip-line");
expect(source).not.toContain("来源IP");
expect(source).not.toContain("去重IP");
});
it("merges abnormal security IPs into the IP ranking and limits the list to top 10", () => {
const source = readSource();
expect(source).toContain("const IP_RANKING_LIMIT = 10;");
expect(source).toContain("const SECURITY_RANKING_PAGE_SIZE = 200;");
expect(source).toContain("const ipRankingItems = computed<IpRankingItem[]>(() =>");
expect(source).toContain("securityLogs.value.forEach((event) =>");
expect(source).toContain('const isAbnormal = event.category === "ABNORMAL_IP";');
expect(source).toContain('ABNORMAL_IP: "异常IP"');
expect(source).toContain(".slice(0, IP_RANKING_LIMIT)");
expect(source).toContain("TOP {{ ipRankingItems.length }}");
expect(source).toContain('v-for="(item, index) in ipRankingItems"');
expect(source).toContain("异常IP</el-tag>");
});
it("sorts IP ranking by overall access total before risk labels", () => {
const source = readSource();
expect(source).toContain("existing.total += user.total_count;");
expect(source).toContain("existing.riskCount += user.denied_count;");
expect(source).toContain("if (b.total !== a.total) return b.total - a.total;");
expect(source.indexOf("if (b.total !== a.total) return b.total - a.total;")).toBeLessThan(
source.indexOf("if (b.riskCount !== a.riskCount) return b.riskCount - a.riskCount;"),
);
expect(source.indexOf("if (b.total !== a.total) return b.total - a.total;")).toBeLessThan(
source.indexOf("if (b.isAbnormal !== a.isAbnormal) return Number(b.isAbnormal) - Number(a.isAbnormal);"),
);
});
it("loads all security pages for complete abnormal IP ranking data", () => {
const source = readSource();
expect(source).toContain("const first = await fetchSecurityAccessLogs({ status_min: 400, page: 1, page_size: SECURITY_RANKING_PAGE_SIZE });");
expect(source).toContain("const totalPages = Math.ceil(first.data.total / SECURITY_RANKING_PAGE_SIZE);");
expect(source).toContain("for (let nextPage = 2; nextPage <= totalPages; nextPage += 1)");
expect(source).toContain("allItems.push(...res.data.items);");
expect(source).toContain("securityLogs.value = allItems;");
expect(source).not.toContain("page_size: 80");
});
it("renders low-level security access logs for anonymous and invalid requests", () => {
const source = readSource();
@@ -111,6 +164,16 @@ describe("PermissionAccessLogs", () => {
expect(source).not.toContain("记录匿名、无效令牌、拒绝和异常状态请求,用于排查未知 IP 攻击");
});
it("shows interface audit log total instead of current page line count", () => {
const source = readSource();
expect(source).toContain("{{ formatNumber(total) }} 条");
expect(source).toContain("共 {{ formatNumber(total) }} 条");
expect(source).toContain(":total=\"total\"");
expect(source).not.toContain("{{ terminalLines.length }} 条");
expect(source).not.toContain("最近 {{ terminalLines.length }} 条");
});
it("opens both audit logs in realtime downloadable dialogs", () => {
const source = readSource();