1
0

chore: 强化代码质量与风格检查体系

ESLint 升级到 recommended-type-checked + stylistic-type-checked,
引入 perfectionist 导入排序和 import 插件导入验证。

Prettier 显式声明全部格式化参数,消除跨环境差异。
TypeScript 启用 noUnusedLocals 和 noPropertyAccessFromIndexSignature。
完善 ignore 列表,排除 .agents/、bun.lock、data/ 等。
引入 husky + lint-staged(pre-commit)+ commitlint(commit-msg)。
更新 DEVELOPMENT.md 代码质量章节。
修复所有新增规则检测到的类型和风格违规。
This commit is contained in:
2026-05-12 18:44:59 +08:00
parent ce8baae3d1
commit a5cf6065c2
83 changed files with 2654 additions and 1824 deletions

View File

@@ -1,89 +1,92 @@
import type { PrimaryTableCol, PrimaryTableCellParams } from "tdesign-react";
import { Tag, Progress } from "tdesign-react";
import type { TargetStatus } from "../../shared/api";
import { StatusDot } from "../components/StatusDot";
import { StatusBar } from "../components/StatusBar";
import { getTargetTypeDisplay } from "./target-type-display";
import { getAvailabilityProgressColor } from "./color-threshold";
import { availabilitySorter, latencySorter, nameSorter } from "./target-table-sorters";
import { statusFilter, typeFilter } from "./target-table-filters";
import type { PrimaryTableCellParams, PrimaryTableCol } from "tdesign-react";
export const TARGET_TABLE_COLUMNS: PrimaryTableCol<TargetStatus>[] = [
import { Progress, Tag } from "tdesign-react";
import type { TargetStatus } from "../../shared/api";
import { StatusBar } from "../components/StatusBar";
import { StatusDot } from "../components/StatusDot";
import { getAvailabilityProgressColor } from "./color-threshold";
import { statusFilter, typeFilter } from "./target-table-filters";
import { availabilitySorter, latencySorter, nameSorter } from "./target-table-sorters";
import { getTargetTypeDisplay } from "./target-type-display";
export const TARGET_TABLE_COLUMNS: Array<PrimaryTableCol<TargetStatus>> = [
{
align: "center",
cell: ({ row }: PrimaryTableCellParams<TargetStatus>) => <StatusDot up={!!row.latestCheck?.matched} />,
colKey: "latestCheck.matched",
filter: statusFilter,
fixed: "left",
title: "#",
width: 60,
fixed: "left",
align: "center",
filter: statusFilter,
cell: ({ row }: PrimaryTableCellParams<TargetStatus>) => <StatusDot up={!!row.latestCheck?.matched} />,
},
{
colKey: "name",
title: "名称",
ellipsis: true,
sorter: nameSorter,
sortType: "all",
title: "名称",
},
{
colKey: "type",
title: "类型",
width: 80,
filter: typeFilter,
cell: ({ row }: PrimaryTableCellParams<TargetStatus>) => (
<Tag size="small" theme="primary" variant="light-outline">
{getTargetTypeDisplay(row.type)}
</Tag>
),
colKey: "type",
filter: typeFilter,
title: "类型",
width: 80,
},
{
colKey: "stats.availability",
title: "可用率",
width: 160,
sorter: availabilitySorter,
sortType: "all",
cell: ({ row }: PrimaryTableCellParams<TargetStatus>) => {
const availability = row.stats?.availability;
if (availability === undefined || availability === null) return "-";
const color = getAvailabilityProgressColor(availability);
return (
<Progress
theme="line"
size="small"
percentage={availability}
color={color}
label={`${availability.toFixed(1)}%`}
percentage={availability}
size="small"
theme="line"
/>
);
},
colKey: "stats.availability",
sorter: availabilitySorter,
sortType: "all",
title: "可用率",
width: 160,
},
{
cell: ({ row }: PrimaryTableCellParams<TargetStatus>) => <StatusBar samples={row.recentSamples} />,
colKey: "recentSamples",
title: "最近状态",
width: 220,
cell: ({ row }: PrimaryTableCellParams<TargetStatus>) => <StatusBar samples={row.recentSamples} />,
},
{
colKey: "latestCheck.durationMs",
title: "延迟",
width: 80,
align: "right",
sorter: latencySorter,
sortType: "all",
cell: ({ row }: PrimaryTableCellParams<TargetStatus>) => {
const ms = row.latestCheck?.durationMs;
if (ms === null || ms === undefined) return <span className="text-disabled">-</span>;
const colorClass = ms <= 100 ? "latency-ok" : ms <= 500 ? "latency-warn" : "latency-error";
return <span className={`${colorClass} tabular-nums`}>{Math.round(ms)}ms</span>;
},
colKey: "latestCheck.durationMs",
sorter: latencySorter,
sortType: "all",
title: "延迟",
width: 80,
},
{
align: "center",
colKey: "interval",
title: "间隔",
width: 72,
align: "center",
},
];
export { statusSorter, availabilitySorter, latencySorter, nameSorter } from "./target-table-sorters";
export { statusFilter, typeFilter } from "./target-table-filters";
export { availabilitySorter, latencySorter, nameSorter, statusSorter } from "./target-table-sorters";

View File

@@ -1,19 +1,19 @@
import type { PrimaryTableCol } from "tdesign-react";
export const statusFilter: PrimaryTableCol["filter"] = {
type: "single",
list: [
{ label: "全部", value: "" },
{ label: "UP", value: "up" },
{ label: "DOWN", value: "down" },
],
type: "single",
};
export const typeFilter: PrimaryTableCol["filter"] = {
type: "single",
list: [
{ label: "全部", value: "" },
{ label: "HTTP", value: "http" },
{ label: "CMD", value: "command" },
],
type: "single",
};

View File

@@ -5,15 +5,6 @@ const STATUS_ORDER: Record<string, number> = {
up: 1,
};
function getStatusRank(target: TargetStatus): number {
if (!target.latestCheck) return 2;
return target.latestCheck.matched ? STATUS_ORDER["up"]! : STATUS_ORDER["down"]!;
}
export function statusSorter(a: TargetStatus, b: TargetStatus): number {
return getStatusRank(a) - getStatusRank(b);
}
export function availabilitySorter(a: TargetStatus, b: TargetStatus): number {
return (a.stats?.availability ?? 0) - (b.stats?.availability ?? 0);
}
@@ -25,3 +16,12 @@ export function latencySorter(a: TargetStatus, b: TargetStatus): number {
export function nameSorter(a: TargetStatus, b: TargetStatus): number {
return a.name.localeCompare(b.name, "zh-CN");
}
export function statusSorter(a: TargetStatus, b: TargetStatus): number {
return getStatusRank(a) - getStatusRank(b);
}
function getStatusRank(target: TargetStatus): number {
if (!target.latestCheck) return 2;
return target.latestCheck.matched ? STATUS_ORDER["up"]! : STATUS_ORDER["down"]!;
}

View File

@@ -1,6 +1,6 @@
export const TARGET_TYPE_DISPLAY = {
http: "HTTP",
command: "CMD",
http: "HTTP",
} as const;
export type TargetType = keyof typeof TARGET_TYPE_DISPLAY;