R96 U1-U7 精简页面设计与文案
这个提交包含在:
@@ -238,7 +238,7 @@ export function ErpIntegrationPage() {
|
||||
queryClient.invalidateQueries({ queryKey: ["integration-outbox-stats"] }),
|
||||
queryClient.invalidateQueries({ queryKey: ["integration-outbox-detail"] }),
|
||||
]);
|
||||
toast.success("Outbox 事件已重置为待处理");
|
||||
toast.success("同步任务已重置为待处理");
|
||||
},
|
||||
onError: (mutationError) => {
|
||||
const message = resolveError(mutationError);
|
||||
@@ -262,7 +262,7 @@ export function ErpIntegrationPage() {
|
||||
<div className="space-y-6">
|
||||
<PageHeader
|
||||
title="ERP 集成"
|
||||
subtitle="管理主数据同步、Outbox 队列和本地与 ERP 的 ID 映射。报销、采购和资产的具体同步动作仍保留在业务详情区。"
|
||||
subtitle="主数据同步、业务同步队列和 ID 映射。"
|
||||
actions={
|
||||
tab === "master-data" ? (
|
||||
<Button onClick={() => syncMutation.mutate(undefined)} disabled={syncMutation.isPending}>
|
||||
@@ -279,7 +279,7 @@ export function ErpIntegrationPage() {
|
||||
<Tabs value={tab} onValueChange={(value) => setTab(value as ErpTab)}>
|
||||
<TabsList className="flex w-full justify-start gap-1">
|
||||
<TabsTrigger value="master-data">主数据同步</TabsTrigger>
|
||||
<TabsTrigger value="outbox">Outbox 队列</TabsTrigger>
|
||||
<TabsTrigger value="outbox">同步队列</TabsTrigger>
|
||||
<TabsTrigger value="bindings">ID 映射</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
@@ -303,14 +303,14 @@ export function ErpIntegrationPage() {
|
||||
<div className="text-xs text-zinc-500">{formatGateReason(gate.effectiveReason)}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-zinc-500">Provider / 主数据端点</div>
|
||||
<div className="text-zinc-500">同步服务 / 主数据端点</div>
|
||||
<div className="font-medium">{gate.provider}</div>
|
||||
<div className="text-xs text-zinc-500">
|
||||
{gate.masterDataEndpointConfigured ? "主数据端点已配置" : "主数据端点未配置"}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-zinc-500">凭证端点 / Cron</div>
|
||||
<div className="text-zinc-500">凭证端点 / 自动同步</div>
|
||||
<div className="font-medium">
|
||||
{gate.journalEndpointConfigured ? "凭证端点已配置" : "凭证端点未配置"}
|
||||
</div>
|
||||
@@ -372,9 +372,9 @@ export function ErpIntegrationPage() {
|
||||
|
||||
<div className="card-std space-y-2 p-5 text-sm text-zinc-600">
|
||||
<h3 className="text-base font-semibold text-zinc-900">说明</h3>
|
||||
<p>- 本页只负责 ERP 主数据同步、Outbox 队列和 ID 映射,不承担业务单据本身的录入。</p>
|
||||
<p>- 报销、采购和资产的 ERP 同步动作请前往对应业务详情区执行。</p>
|
||||
<p>- 当前阶段不接入真实 ERP Provider,仍以 mock Provider 为准。</p>
|
||||
<p>- 本页只负责主数据同步、业务同步队列和 ID 映射。</p>
|
||||
<p>- 报销、采购和资产的同步动作在对应业务详情区执行。</p>
|
||||
<p>- 当前仍使用演示同步服务。</p>
|
||||
</div>
|
||||
</TabsContent>
|
||||
|
||||
@@ -410,8 +410,8 @@ export function ErpIntegrationPage() {
|
||||
<div className="card-std space-y-4 p-5">
|
||||
<div className="flex flex-col gap-3 lg:flex-row lg:items-end lg:justify-between">
|
||||
<div>
|
||||
<h3 className="text-base font-semibold text-zinc-900">Outbox 事件列表</h3>
|
||||
<p className="text-sm text-zinc-500">支持按状态和事件类型筛选,失败和死信事件可在此重试。</p>
|
||||
<h3 className="text-base font-semibold text-zinc-900">同步任务列表</h3>
|
||||
<p className="text-sm text-zinc-500">失败任务可重试。</p>
|
||||
</div>
|
||||
<div className="flex flex-col gap-3 md:flex-row">
|
||||
<label className="space-y-1 text-sm text-zinc-600">
|
||||
@@ -520,7 +520,7 @@ export function ErpIntegrationPage() {
|
||||
) : (
|
||||
<TableRow>
|
||||
<TableCell colSpan={8} className="py-6 text-center text-zinc-500">
|
||||
当前筛选下暂无 Outbox 事件
|
||||
当前筛选下暂无同步任务
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)}
|
||||
@@ -542,7 +542,7 @@ export function ErpIntegrationPage() {
|
||||
</div>
|
||||
<div className="flex flex-col gap-3 md:flex-row">
|
||||
<label className="space-y-1 text-sm text-zinc-600">
|
||||
<span>Provider</span>
|
||||
<span>同步服务</span>
|
||||
<select
|
||||
className="select-std min-w-40"
|
||||
value={bindingProvider}
|
||||
@@ -551,7 +551,7 @@ export function ErpIntegrationPage() {
|
||||
setBindingsPage(1);
|
||||
}}
|
||||
>
|
||||
<option value="">全部 Provider</option>
|
||||
<option value="">全部同步服务</option>
|
||||
<option value="erp">erp</option>
|
||||
</select>
|
||||
</label>
|
||||
@@ -587,7 +587,7 @@ export function ErpIntegrationPage() {
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>Provider</TableHead>
|
||||
<TableHead>同步服务</TableHead>
|
||||
<TableHead>实体类型</TableHead>
|
||||
<TableHead>本地 ID</TableHead>
|
||||
<TableHead>外部 ID</TableHead>
|
||||
@@ -636,8 +636,8 @@ export function ErpIntegrationPage() {
|
||||
>
|
||||
<DialogContent className="max-h-[85vh] max-w-4xl overflow-y-auto">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Outbox 事件详情</DialogTitle>
|
||||
<DialogDescription>查看完整 payload、错误摘要和当前队列状态。</DialogDescription>
|
||||
<DialogTitle>同步任务详情</DialogTitle>
|
||||
<DialogDescription>查看数据内容、错误摘要和当前队列状态。</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
{outboxDetailQuery.isLoading ? <p className="text-sm text-zinc-500">详情加载中...</p> : null}
|
||||
@@ -650,7 +650,7 @@ export function ErpIntegrationPage() {
|
||||
{outboxDetailQuery.data ? (
|
||||
<div className="space-y-4">
|
||||
<div className="grid gap-3 rounded-lg border border-zinc-200 bg-zinc-50 p-4 text-sm text-zinc-700 md:grid-cols-2">
|
||||
<div>Outbox ID:{outboxDetailQuery.data.id}</div>
|
||||
<div>队列 ID:{outboxDetailQuery.data.id}</div>
|
||||
<div>事件类型:{outboxDetailQuery.data.eventType}</div>
|
||||
<div>状态:{outboxStatusLabel(outboxDetailQuery.data.status)}</div>
|
||||
<div>尝试次数:{outboxDetailQuery.data.attempts} / {outboxDetailQuery.data.maxAttempts}</div>
|
||||
@@ -668,7 +668,7 @@ export function ErpIntegrationPage() {
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<div className="text-sm font-medium text-zinc-900">Payload</div>
|
||||
<div className="text-sm font-medium text-zinc-900">数据内容</div>
|
||||
<pre className="max-h-[45vh] overflow-auto rounded-lg border border-zinc-200 bg-zinc-950 p-4 text-xs text-zinc-100">
|
||||
{JSON.stringify(outboxDetailQuery.data.payload ?? null, null, 2)}
|
||||
</pre>
|
||||
|
||||
在新工单中引用
屏蔽一个用户