优化财务与管理页视觉 Wave4(05-27-pc-finance-admin-visual-wave4)
这个提交包含在:
@@ -16,7 +16,7 @@ import {
|
||||
type NotificationChannelWriteConfig,
|
||||
} from "../api/notificationChannels";
|
||||
import { isApiError } from "../api/types";
|
||||
import { PageHeader } from "../components/common/PageHeader";
|
||||
import { ListWorkspace, WorkspaceHeader } from "../components/patterns/ListWorkspace";
|
||||
import { TableSkeleton } from "../components/common/TableSkeleton";
|
||||
import { Button } from "../components/ui/button";
|
||||
import { Input } from "../components/ui/input";
|
||||
@@ -325,14 +325,22 @@ export function NotificationChannelsPage() {
|
||||
}
|
||||
|
||||
const channels = channelsQuery.data?.items ?? [];
|
||||
const deliveryItems = deliveriesQuery.data?.items ?? [];
|
||||
const channelStats = {
|
||||
total: channels.length,
|
||||
enabled: channels.filter((item) => item.enabled).length,
|
||||
appMessage: channels.filter((item) => item.configJson.mode === "wecom_app_message").length,
|
||||
failedDeliveries: deliveryItems.filter((item) => item.status === "failed").length,
|
||||
pendingDeliveries: deliveryItems.filter((item) => item.status === "pending").length,
|
||||
};
|
||||
const isWebhookMode = form.mode === "wecom_webhook";
|
||||
const isAppMessageMode = form.mode === "wecom_app_message";
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<PageHeader
|
||||
<ListWorkspace>
|
||||
<WorkspaceHeader
|
||||
title="通知渠道"
|
||||
subtitle="维护企微通知渠道、业务域路由、测试发送与最近投递记录。目标业务通知会在提交后同步尝试外推。"
|
||||
subtitle="渠道、路由、测试发送和投递追踪集中治理。"
|
||||
actions={
|
||||
<Button type="button" variant="secondary" onClick={startCreate} data-testid="notification-channels-create">
|
||||
新建渠道
|
||||
@@ -344,7 +352,15 @@ export function NotificationChannelsPage() {
|
||||
<p className="rounded-lg border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-600">{error}</p>
|
||||
) : null}
|
||||
|
||||
<div className="card-std space-y-4 p-6">
|
||||
<div className="finance-status-strip" data-testid="notification-channels-summary">
|
||||
<div className="finance-metric-card"><div className="finance-metric-card__label">渠道总数</div><div className="finance-metric-card__value">{channelStats.total}</div></div>
|
||||
<div className="finance-metric-card"><div className="finance-metric-card__label">启用渠道</div><div className="finance-metric-card__value">{channelStats.enabled}</div></div>
|
||||
<div className="finance-metric-card"><div className="finance-metric-card__label">应用消息</div><div className="finance-metric-card__value">{channelStats.appMessage}</div></div>
|
||||
<div className="finance-metric-card"><div className="finance-metric-card__label">失败投递</div><div className="finance-metric-card__value">{channelStats.failedDeliveries}</div></div>
|
||||
<div className="finance-metric-card"><div className="finance-metric-card__label">处理中</div><div className="finance-metric-card__value">{channelStats.pendingDeliveries}</div></div>
|
||||
</div>
|
||||
|
||||
<div className="admin-command-panel space-y-4">
|
||||
<div className="flex items-center justify-between gap-3">
|
||||
<h3 className="text-base font-semibold text-zinc-900">渠道列表</h3>
|
||||
<p className="text-sm text-zinc-500">当前共 {channels.length} 条渠道配置</p>
|
||||
@@ -359,7 +375,7 @@ export function NotificationChannelsPage() {
|
||||
) : null}
|
||||
|
||||
{!channelsQuery.isLoading && !channelsQuery.isError ? (
|
||||
<div className="rounded-lg border border-zinc-200">
|
||||
<div className="ops-table-focus overflow-x-auto">
|
||||
<Table data-testid="notification-channels-table">
|
||||
<TableHeader>
|
||||
<tr>
|
||||
@@ -428,7 +444,7 @@ export function NotificationChannelsPage() {
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
<div className="card-std space-y-4 p-6">
|
||||
<div className="admin-command-panel space-y-4">
|
||||
<div className="flex flex-wrap items-start justify-between gap-4">
|
||||
<div>
|
||||
<h3 className="text-base font-semibold text-zinc-900">最近投递记录</h3>
|
||||
@@ -474,7 +490,7 @@ export function NotificationChannelsPage() {
|
||||
) : null}
|
||||
|
||||
{!deliveriesQuery.isLoading && !deliveriesQuery.isError ? (
|
||||
<div className="rounded-lg border border-zinc-200">
|
||||
<div className="ops-table-focus overflow-x-auto">
|
||||
<Table data-testid="notification-deliveries-table">
|
||||
<TableHeader>
|
||||
<tr>
|
||||
@@ -520,7 +536,7 @@ export function NotificationChannelsPage() {
|
||||
</div>
|
||||
|
||||
<div className="grid gap-6 xl:grid-cols-[minmax(0,2fr)_minmax(320px,1fr)]">
|
||||
<div className="card-std space-y-4 p-6">
|
||||
<div className="admin-command-panel space-y-4">
|
||||
<div className="flex items-center justify-between gap-3">
|
||||
<div>
|
||||
<h3 className="text-base font-semibold text-zinc-900">
|
||||
@@ -818,7 +834,7 @@ export function NotificationChannelsPage() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="card-std space-y-4 p-6">
|
||||
<div className="admin-command-panel space-y-4">
|
||||
<div>
|
||||
<h3 className="text-base font-semibold text-zinc-900">测试发送</h3>
|
||||
<p className="text-sm text-zinc-500">仅对已保存渠道执行同步测试,不写业务 Outbox。</p>
|
||||
@@ -866,6 +882,6 @@ export function NotificationChannelsPage() {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ListWorkspace>
|
||||
);
|
||||
}
|
||||
|
||||
在新工单中引用
屏蔽一个用户