chore: capture V1 baseline and V2 rebuild plan
This commit is contained in:
@@ -574,7 +574,7 @@ export default function GeneratedContractDetailPage({ params }: { params: Promis
|
||||
: "";
|
||||
const auditTimelineItems = auditTimeline?.items ?? [];
|
||||
const auditActionSummaryItems = useMemo(
|
||||
() => Object.entries(auditTimeline?.summary.by_action ?? {})
|
||||
() => Object.entries(auditTimeline?.summary?.by_action ?? {})
|
||||
.sort(([, leftCount], [, rightCount]) => rightCount - leftCount)
|
||||
.slice(0, 6),
|
||||
[auditTimeline],
|
||||
@@ -597,8 +597,18 @@ export default function GeneratedContractDetailPage({ params }: { params: Promis
|
||||
const canCommentOnVersionDiff = !isObserverRole && Boolean(detail);
|
||||
const canSubmitApproval = Boolean(approvalSummary?.can_submit ?? (!pendingApproval && canEditCurrentContract));
|
||||
const shouldShowApprovalResubmit = approvalNextAction?.code === "revise_and_resubmit";
|
||||
const shouldShowApprovalSubmitButton = canSubmitApproval || Boolean(pendingApproval);
|
||||
const isApprovalRelevant = Boolean(pendingApproval || approvalHistory.length || shouldShowApprovalResubmit);
|
||||
const shouldPromoteApprovalAction = Boolean(
|
||||
pendingApproval
|
||||
|| shouldShowApprovalResubmit
|
||||
|| (canSubmitApproval && autoReview?.risk_level === "high")
|
||||
);
|
||||
const shouldShowApprovalSubmitButton = shouldPromoteApprovalAction;
|
||||
const shouldShowApprovalWorkbenchAction = Boolean(pendingApproval || approvalHistory.length || shouldShowApprovalResubmit);
|
||||
const visibleContractDetailAnchors = useMemo(
|
||||
() => contractDetailAnchors.filter((item) => item.href !== "#contract-approval" || isApprovalRelevant || shouldShowApprovalSubmitButton),
|
||||
[isApprovalRelevant, shouldShowApprovalSubmitButton],
|
||||
);
|
||||
const completedSignoffTask = useMemo(
|
||||
() => lifecycleTasks.find((task) => task.task_type === "signoff" && task.status === "completed")
|
||||
?? lifecycleTasks.find((task) => task.task_type === "signoff")
|
||||
@@ -620,7 +630,7 @@ export default function GeneratedContractDetailPage({ params }: { params: Promis
|
||||
? `${formatLifecycleStatus(detail.lifecycle?.status)} · ${formatDueStatus(detail.lifecycle)} · ${detail.lifecycle?.counterparty_name || "未记录相对方"}`
|
||||
: "暂无生命周期信息";
|
||||
const signoffSummaryText = `签署证据 ${signoffArchiveSummary?.signoff_evidence_count ?? 0} · 归档证据 ${signoffArchiveSummary?.archive_evidence_count ?? 0}`;
|
||||
const auditSummaryText = `留痕 ${auditTimeline?.summary.total ?? 0} 条${auditActionSummaryItems.length ? ` · ${auditActionSummaryItems.slice(0, 2).map(([action, count]) => `${formatAuditActionLabel(action)} ${count}`).join(" / ")}` : ""}`;
|
||||
const auditSummaryText = `留痕 ${auditTimeline?.summary?.total ?? 0} 条${auditActionSummaryItems.length ? ` · ${auditActionSummaryItems.slice(0, 2).map(([action, count]) => `${formatAuditActionLabel(action)} ${count}`).join(" / ")}` : ""}`;
|
||||
const versionSummaryText = `版本 ${versionRows.length} 个 · 最新 ${latestVersionLabel} · 差异 ${versionDiff?.summary.change_count ?? 0} 处`;
|
||||
const lifecycleTaskSummaryText = `履约任务 ${lifecycleTasks.length} 个 · 待处理 ${openLifecycleTasks.length} 个`;
|
||||
const isSignedLifecycle = ["signed", "effective", "expiring", "expired", "terminated", "archived"].includes(detail?.lifecycle?.status ?? "");
|
||||
@@ -666,7 +676,7 @@ export default function GeneratedContractDetailPage({ params }: { params: Promis
|
||||
? "先按退回意见修改合同,再重新提交审批,避免审批人重复退回。"
|
||||
: pendingApproval
|
||||
? "合同已进入审批流,可查看流转记录或进入审批工作台处理。"
|
||||
: "先确认正文和真实预览,再进入编辑、提交审批或下载归档。";
|
||||
: "先确认正文和真实预览,再进入编辑或下载;需要审批时可从更多入口提交。";
|
||||
const contractContentSection = (
|
||||
<div id="contract-content" className="contract-content-grid">
|
||||
<Card className="review-surface-card" loading={loading} title="真实预览">
|
||||
@@ -1535,6 +1545,11 @@ export default function GeneratedContractDetailPage({ params }: { params: Promis
|
||||
</div>
|
||||
<div className="contract-detail-more-action-group">
|
||||
<Text type="secondary">流转与材料</Text>
|
||||
{canSubmitApproval && !shouldShowApprovalSubmitButton ? (
|
||||
<Button block icon={<FileDoneOutlined />} onClick={handleOpenApprovalModal}>
|
||||
提交审批
|
||||
</Button>
|
||||
) : null}
|
||||
{canEditCurrentContract ? (
|
||||
<Popover
|
||||
trigger="click"
|
||||
@@ -1573,7 +1588,9 @@ export default function GeneratedContractDetailPage({ params }: { params: Promis
|
||||
<Button block>更新生命周期</Button>
|
||||
</Popover>
|
||||
) : null}
|
||||
{!shouldShowApprovalWorkbenchAction ? <Button block onClick={() => router.push("/contract-approvals")}>审批工作台</Button> : null}
|
||||
{shouldShowApprovalWorkbenchAction ? null : isLegalOperatorRole ? (
|
||||
<Button block onClick={() => router.push("/contract-approvals")}>审批工作台</Button>
|
||||
) : null}
|
||||
{isLegalOperatorRole && detail?.file_id ? <Button block onClick={() => router.push(`/files?highlight=${detail.file_id}`)}>查看文件资产</Button> : null}
|
||||
</div>
|
||||
</Space>
|
||||
@@ -1585,7 +1602,7 @@ export default function GeneratedContractDetailPage({ params }: { params: Promis
|
||||
</section>
|
||||
|
||||
<nav className="review-detail-anchor-nav contract-detail-anchor-nav" aria-label="合同详情分段导航">
|
||||
{contractDetailAnchors.map((item) => (
|
||||
{visibleContractDetailAnchors.map((item) => (
|
||||
<a className="review-detail-anchor-link" href={item.href} key={item.href}>
|
||||
{item.label}
|
||||
</a>
|
||||
@@ -1900,29 +1917,52 @@ export default function GeneratedContractDetailPage({ params }: { params: Promis
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card
|
||||
id="contract-approval"
|
||||
className="review-surface-card"
|
||||
title="审批流转"
|
||||
extra={
|
||||
<Space wrap>
|
||||
<Tag color={getContractApprovalStatusColor(approvalSummary?.status)}>
|
||||
{formatContractApprovalStatus(approvalSummary?.status)}
|
||||
</Tag>
|
||||
<Button size="small" disabled={!canSubmitApproval} onClick={handleOpenApprovalModal}>
|
||||
{pendingApproval ? "审批中" : shouldShowApprovalResubmit ? "重新提交" : "提交审批"}
|
||||
</Button>
|
||||
</Space>
|
||||
}
|
||||
>
|
||||
<Space direction="vertical" size="middle" style={{ width: "100%" }}>
|
||||
{approvalNextAction ? (
|
||||
<Alert
|
||||
showIcon
|
||||
type={shouldShowApprovalResubmit ? "warning" : pendingApproval ? "info" : approvalSummary?.status === "approved" ? "success" : "info"}
|
||||
title={approvalNextAction.label}
|
||||
description={approvalNextAction.description}
|
||||
action={shouldShowApprovalResubmit ? (
|
||||
{isApprovalRelevant || shouldShowApprovalSubmitButton ? (
|
||||
<Card
|
||||
id="contract-approval"
|
||||
className="review-surface-card"
|
||||
title="审批流转"
|
||||
extra={
|
||||
<Space wrap>
|
||||
<Tag color={getContractApprovalStatusColor(approvalSummary?.status)}>
|
||||
{formatContractApprovalStatus(approvalSummary?.status)}
|
||||
</Tag>
|
||||
<Button size="small" disabled={!canSubmitApproval} onClick={handleOpenApprovalModal}>
|
||||
{pendingApproval ? "审批中" : shouldShowApprovalResubmit ? "重新提交" : "提交审批"}
|
||||
</Button>
|
||||
</Space>
|
||||
}
|
||||
>
|
||||
<Space direction="vertical" size="middle" style={{ width: "100%" }}>
|
||||
{approvalNextAction ? (
|
||||
<Alert
|
||||
showIcon
|
||||
type={shouldShowApprovalResubmit ? "warning" : pendingApproval ? "info" : approvalSummary?.status === "approved" ? "success" : "info"}
|
||||
title={approvalNextAction.label}
|
||||
description={approvalNextAction.description}
|
||||
action={shouldShowApprovalResubmit ? (
|
||||
<Space wrap>
|
||||
{canEditCurrentContract ? (
|
||||
<Button size="small" icon={<EditOutlined />} onClick={handleOpenLatestVersionInEditor}>
|
||||
修改合同
|
||||
</Button>
|
||||
) : null}
|
||||
{canSubmitApproval ? (
|
||||
<Button size="small" type="primary" onClick={handleOpenApprovalModal}>
|
||||
重新提交
|
||||
</Button>
|
||||
) : null}
|
||||
</Space>
|
||||
) : null}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
{latestRejectedApproval ? (
|
||||
<div className="contract-approval-return-panel">
|
||||
<div>
|
||||
<Text strong>最近退回意见</Text>
|
||||
<Text type="secondary">{latestRejectedApproval.comment || "审批人未填写退回原因。"}</Text>
|
||||
</div>
|
||||
<Space wrap>
|
||||
{canEditCurrentContract ? (
|
||||
<Button size="small" icon={<EditOutlined />} onClick={handleOpenLatestVersionInEditor}>
|
||||
@@ -1931,106 +1971,85 @@ export default function GeneratedContractDetailPage({ params }: { params: Promis
|
||||
) : null}
|
||||
{canSubmitApproval ? (
|
||||
<Button size="small" type="primary" onClick={handleOpenApprovalModal}>
|
||||
重新提交
|
||||
重新提交审批
|
||||
</Button>
|
||||
) : null}
|
||||
</Space>
|
||||
) : null}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
{latestRejectedApproval ? (
|
||||
<div className="contract-approval-return-panel">
|
||||
<div>
|
||||
<Text strong>最近退回意见</Text>
|
||||
<Text type="secondary">{latestRejectedApproval.comment || "审批人未填写退回原因。"}</Text>
|
||||
</div>
|
||||
<Space wrap>
|
||||
{canEditCurrentContract ? (
|
||||
<Button size="small" icon={<EditOutlined />} onClick={handleOpenLatestVersionInEditor}>
|
||||
修改合同
|
||||
</Button>
|
||||
) : null}
|
||||
{canSubmitApproval ? (
|
||||
<Button size="small" type="primary" onClick={handleOpenApprovalModal}>
|
||||
重新提交审批
|
||||
</Button>
|
||||
) : null}
|
||||
</Space>
|
||||
</div>
|
||||
) : null}
|
||||
) : null}
|
||||
|
||||
{approvalHistory.length === 0 ? (
|
||||
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="暂无审批记录。提交后可在这里查看处理状态。" />
|
||||
) : (
|
||||
<>
|
||||
<Timeline
|
||||
className="contract-approval-timeline"
|
||||
items={approvalTimeline.map((item) => ({
|
||||
key: item.key,
|
||||
color: buildApprovalTimelineColor(item),
|
||||
content: (
|
||||
<div className="contract-approval-timeline-item">
|
||||
<div className="contract-approval-timeline-heading">
|
||||
<Space wrap>
|
||||
<Text strong>{item.title}</Text>
|
||||
{item.event === "pending" ? <Tag color="blue">待处理</Tag> : null}
|
||||
{item.event === "approved" ? <Tag color="green">通过</Tag> : null}
|
||||
{item.event === "rejected" ? <Tag color="red">退回</Tag> : null}
|
||||
</Space>
|
||||
<Text type="secondary">{formatDateTime(item.occurred_at)}</Text>
|
||||
{approvalHistory.length === 0 ? (
|
||||
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="暂无审批记录。提交后可在这里查看处理状态。" />
|
||||
) : (
|
||||
<>
|
||||
<Timeline
|
||||
className="contract-approval-timeline"
|
||||
items={approvalTimeline.map((item) => ({
|
||||
key: item.key,
|
||||
color: buildApprovalTimelineColor(item),
|
||||
content: (
|
||||
<div className="contract-approval-timeline-item">
|
||||
<div className="contract-approval-timeline-heading">
|
||||
<Space wrap>
|
||||
<Text strong>{item.title}</Text>
|
||||
{item.event === "pending" ? <Tag color="blue">待处理</Tag> : null}
|
||||
{item.event === "approved" ? <Tag color="green">通过</Tag> : null}
|
||||
{item.event === "rejected" ? <Tag color="red">退回</Tag> : null}
|
||||
</Space>
|
||||
<Text type="secondary">{formatDateTime(item.occurred_at)}</Text>
|
||||
</div>
|
||||
<Text type="secondary">
|
||||
{item.actor_name ? `操作人:${item.actor_name}` : "操作人未记录"}
|
||||
</Text>
|
||||
{item.description ? <Paragraph>{item.description}</Paragraph> : null}
|
||||
</div>
|
||||
<Text type="secondary">
|
||||
{item.actor_name ? `操作人:${item.actor_name}` : "操作人未记录"}
|
||||
</Text>
|
||||
{item.description ? <Paragraph>{item.description}</Paragraph> : null}
|
||||
</div>
|
||||
),
|
||||
}))}
|
||||
/>
|
||||
),
|
||||
}))}
|
||||
/>
|
||||
|
||||
<div className="contract-approval-history-list">
|
||||
{approvalHistory.map((record) => (
|
||||
<section className="contract-approval-history-item" key={record.id}>
|
||||
<div>
|
||||
<Space wrap>
|
||||
<Tag color={getContractApprovalStepTypeColor(record.step_type)}>{formatContractApprovalStepType(record.step_type)}</Tag>
|
||||
<Tag color={getContractApprovalStatusColor(record.status)}>{formatContractApprovalStatus(record.status)}</Tag>
|
||||
{record.audit_key ? <Tag>{record.audit_key}</Tag> : null}
|
||||
</Space>
|
||||
<Text strong>{record.title}</Text>
|
||||
{record.comment ? <Text type="secondary">{record.comment}</Text> : null}
|
||||
<Text type="secondary">
|
||||
提交人:{record.submitter_name || "-"} / 处理人:{record.assignee_name || "-"}
|
||||
{record.decided_by_name ? ` / 实际处理:${record.decided_by_name}` : ""}
|
||||
</Text>
|
||||
</div>
|
||||
{canDecideApproval(record) ? (
|
||||
<Space>
|
||||
<Button
|
||||
size="small"
|
||||
loading={approvalDecidingId === record.id}
|
||||
onClick={() => handleOpenApprovalDecisionModal(record, "approve")}
|
||||
>
|
||||
通过
|
||||
</Button>
|
||||
<Button
|
||||
danger
|
||||
size="small"
|
||||
loading={approvalDecidingId === record.id}
|
||||
onClick={() => handleOpenApprovalDecisionModal(record, "reject")}
|
||||
>
|
||||
退回
|
||||
</Button>
|
||||
</Space>
|
||||
) : null}
|
||||
</section>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</Space>
|
||||
</Card>
|
||||
<div className="contract-approval-history-list">
|
||||
{approvalHistory.map((record) => (
|
||||
<section className="contract-approval-history-item" key={record.id}>
|
||||
<div>
|
||||
<Space wrap>
|
||||
<Tag color={getContractApprovalStepTypeColor(record.step_type)}>{formatContractApprovalStepType(record.step_type)}</Tag>
|
||||
<Tag color={getContractApprovalStatusColor(record.status)}>{formatContractApprovalStatus(record.status)}</Tag>
|
||||
{record.audit_key ? <Tag>{record.audit_key}</Tag> : null}
|
||||
</Space>
|
||||
<Text strong>{record.title}</Text>
|
||||
{record.comment ? <Text type="secondary">{record.comment}</Text> : null}
|
||||
<Text type="secondary">
|
||||
提交人:{record.submitter_name || "-"} / 处理人:{record.assignee_name || "-"}
|
||||
{record.decided_by_name ? ` / 实际处理:${record.decided_by_name}` : ""}
|
||||
</Text>
|
||||
</div>
|
||||
{canDecideApproval(record) ? (
|
||||
<Space>
|
||||
<Button
|
||||
size="small"
|
||||
loading={approvalDecidingId === record.id}
|
||||
onClick={() => handleOpenApprovalDecisionModal(record, "approve")}
|
||||
>
|
||||
通过
|
||||
</Button>
|
||||
<Button
|
||||
danger
|
||||
size="small"
|
||||
loading={approvalDecidingId === record.id}
|
||||
onClick={() => handleOpenApprovalDecisionModal(record, "reject")}
|
||||
>
|
||||
退回
|
||||
</Button>
|
||||
</Space>
|
||||
) : null}
|
||||
</section>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</Space>
|
||||
</Card>
|
||||
) : null}
|
||||
|
||||
<Card
|
||||
id="contract-audit"
|
||||
|
||||
@@ -18,19 +18,12 @@ import {
|
||||
getStatusColor,
|
||||
} from "@/lib/format";
|
||||
|
||||
const memberQuickLinks = [
|
||||
{ href: "/contracts", label: "合同起草", description: "复用成熟模板快速起草合同,并衔接生成后的自动预审。", eyebrow: "Contract Drafting" },
|
||||
{ href: "/review", label: "上传审查", description: "上传合同文件或粘贴文本,立即进入审查主链路。", eyebrow: "Start Review" },
|
||||
{ href: "/documents/new", label: "文书起草", description: "从文书类型开始逐步填写要素,适合从 0 到 1 起草。", eyebrow: "Document Builder" },
|
||||
{ href: "/contract-ledger", label: "合同台账", description: "集中查看合同生命周期、预审风险、到期和逾期事项。", eyebrow: "Contract Ledger" },
|
||||
{ href: "/contract-approvals", label: "合同审批", description: "处理合同提交、通过、退回和签署前确认。", eyebrow: "Contract Approval" },
|
||||
{ href: "/reviews", label: "查看审查记录", description: "查看任务状态、风险等级,并进入详情页。", eyebrow: "Review History" },
|
||||
{ href: "/chat", label: "法律问答", description: "查询制度、法条和合同处理建议。", eyebrow: "Legal Chat" },
|
||||
];
|
||||
|
||||
const adminQuickLinks = [
|
||||
...memberQuickLinks,
|
||||
{ href: "/knowledge-bases", label: "知识库管理", description: "维护问答与审查共用的企业知识库。", eyebrow: "Knowledge Base" },
|
||||
const workspaceUtilityLinks = [
|
||||
{ href: "/files", label: "合同仓库", description: "查看文件、预览材料并关联合同。", eyebrow: "Files" },
|
||||
{ href: "/search", label: "统一搜索", description: "按合同、审查、文件和模板快速定位。", eyebrow: "Search" },
|
||||
{ href: "/reviews", label: "审查记录", description: "查看任务状态、风险等级,并进入详情页。", eyebrow: "Review History" },
|
||||
{ href: "/chat", label: "法律问答", description: "围绕法条、风险点和修改建议继续追问。", eyebrow: "Legal Chat" },
|
||||
{ href: "/contract-ledger", label: "合同台账", description: "集中查看生命周期、到期和逾期事项。", eyebrow: "Ledger" },
|
||||
];
|
||||
|
||||
const draftingFlowItems = ["选择模板", "填写关键内容", "生成合同", "自动预审"];
|
||||
@@ -186,7 +179,6 @@ export default function WorkspacePage() {
|
||||
const latestContract = recentContracts[0];
|
||||
const hasReviews = reviews.length > 0;
|
||||
const hasContracts = contracts.length > 0;
|
||||
const quickLinks = useMemo(() => (currentUser?.role === "admin" ? adminQuickLinks : memberQuickLinks), [currentUser?.role]);
|
||||
const priorityTasks = useMemo(() => buildPriorityTasks(reviews), [reviews]);
|
||||
const contractPriorityTasks = useMemo(() => buildContractPriorityTasks(contracts), [contracts]);
|
||||
const adminWorkbenchLinks = useMemo(() => {
|
||||
@@ -212,34 +204,26 @@ export default function WorkspacePage() {
|
||||
].slice(0, activeTask ? 3 : 4), [activeTask, contractPriorityTasks, priorityTasks, workspaceInsights]);
|
||||
const workflowLinks = useMemo(() => {
|
||||
if (hasContracts || hasReviews) {
|
||||
return quickLinks
|
||||
.filter((item) => item.href !== "/contracts")
|
||||
.slice(0, 4)
|
||||
.map((item) => ({ href: item.href, label: item.label, description: item.description, eyebrow: item.eyebrow }));
|
||||
return workspaceUtilityLinks.slice(0, 4);
|
||||
}
|
||||
return [
|
||||
...gettingStartedLinks.map((item) => ({ ...item, eyebrow: "Next Step" })),
|
||||
...quickLinks
|
||||
.filter((item) => item.href !== "/contracts" && item.href !== "/review")
|
||||
.slice(0, 2)
|
||||
.map((item) => ({ href: item.href, label: item.label, description: item.description, eyebrow: item.eyebrow })),
|
||||
].slice(0, 5);
|
||||
}, [gettingStartedLinks, hasContracts, hasReviews, quickLinks]);
|
||||
...gettingStartedLinks.slice(2).map((item) => ({ ...item, eyebrow: "Next Step" })),
|
||||
...workspaceUtilityLinks.slice(0, 2),
|
||||
].slice(0, 4);
|
||||
}, [gettingStartedLinks, hasContracts, hasReviews]);
|
||||
const primaryAction = { href: "/contracts", label: "起草合同", description: "从模板选择、关键内容填写开始,生成后自动预审。" };
|
||||
const secondaryAction = hasReviews || hasContracts
|
||||
? { href: "/review", label: "上传已有合同审查", description: "直接上传 PDF / DOCX / TXT 或粘贴正文,适合审核客户现有合同。" }
|
||||
: { href: "/review", label: "上传已有合同审查", description: "直接上传 PDF / DOCX / TXT 或粘贴正文,先跑通已有合同审查主链。" };
|
||||
: { href: "/review", label: "上传已有合同审查", description: "直接上传 PDF / DOCX / TXT 或粘贴正文,先完成一次审查闭环。" };
|
||||
const workspaceHeadline = activeTask
|
||||
? `你好,${currentUser?.display_name}。先从起草与预审主链路继续。`
|
||||
? `你好,${currentUser?.display_name}。先处理待办,再快速发起。`
|
||||
: `你好,${currentUser?.display_name}。先起草一份合同并启动自动预审。`;
|
||||
const workspaceSubtitle = activeTask
|
||||
? `当前优先任务:${activeTask.title}。也可以直接新建合同,完成选择模板、生成、自动预审和报告交付。`
|
||||
: "工作台优先引导合同起草;如果客户已经有合同原文,也可以直接上传 PDF / DOCX / TXT 进入审查主链。";
|
||||
: "工作台优先引导合同起草;如果客户已经有合同原文,也可以直接上传 PDF / DOCX / TXT 完成审查。";
|
||||
const workspacePrimaryActions = useMemo(() => [
|
||||
{ href: "/contracts", label: "合同起草", description: "选择模板、填写关键内容并生成合同。" },
|
||||
{ href: "/review", label: "发起审查", description: "上传已有合同或粘贴正文进入审查。" },
|
||||
{ href: "/files", label: "合同仓库", description: "查看文件、预览材料并关联合同。" },
|
||||
{ href: "/search", label: "统一搜索", description: "按合同、审查、文件和模板快速定位。" },
|
||||
], []);
|
||||
const workspaceFocusItems = activeTask
|
||||
? [
|
||||
@@ -380,8 +364,8 @@ export default function WorkspacePage() {
|
||||
|
||||
<div className="workspace-flow-column">
|
||||
<div className="workspace-column-head">
|
||||
<strong>主链路</strong>
|
||||
<Tag color="blue">3 步</Tag>
|
||||
<strong>快速发起</strong>
|
||||
<Tag color="blue">{workspacePrimaryActions.length} 个入口</Tag>
|
||||
</div>
|
||||
<div className="workspace-flow-list">
|
||||
{workspacePrimaryActions.map((item, index) => (
|
||||
@@ -401,7 +385,7 @@ export default function WorkspacePage() {
|
||||
<section className="landing-section workspace-tools-section">
|
||||
<div className="landing-section-header workspace-section-header-compact">
|
||||
<h2>常用入口</h2>
|
||||
<p>主流程之外的辅助能力集中放在这里。</p>
|
||||
<p>快速发起之外的资料、搜索和问答集中放在这里。</p>
|
||||
</div>
|
||||
<div className="workspace-tool-grid">
|
||||
{workflowLinks.map((item) => (
|
||||
@@ -418,7 +402,7 @@ export default function WorkspacePage() {
|
||||
<section className="landing-section workspace-admin-section">
|
||||
<div className="landing-section-header workspace-section-header-compact">
|
||||
<h2>管理员入口</h2>
|
||||
<p>后台治理入口保持可达,但不抢占业务主流程。</p>
|
||||
<p>后台治理入口保持可达,但不抢占日常业务操作。</p>
|
||||
</div>
|
||||
<div className="workspace-admin-strip">
|
||||
{adminWorkbenchLinks.map((item) => (
|
||||
|
||||
@@ -204,17 +204,6 @@ export function AppTopbar() {
|
||||
{item.label}
|
||||
</Link>
|
||||
))}
|
||||
{showAdminMenu ? (
|
||||
<Link
|
||||
className={isActive(pathname, "/pilot-readiness") ? "app-nav-link app-nav-link-active" : "app-nav-link"}
|
||||
href="/pilot-readiness"
|
||||
>
|
||||
<span className="app-nav-icon" aria-hidden="true">
|
||||
<ThunderboltOutlined />
|
||||
</span>
|
||||
试点交付
|
||||
</Link>
|
||||
) : null}
|
||||
{showAdminMenu ? (
|
||||
<Dropdown menu={{ items: adminMenuItems }} placement="bottomRight" trigger={["click"]}>
|
||||
<button
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,14 +1,19 @@
|
||||
# 契阅品牌方案设计 V2.0
|
||||
# 钰麒合同品牌方案设计 V3.0
|
||||
|
||||
## 一、核心定案
|
||||
|
||||
主品牌:**契阅**
|
||||
主品牌:**钰麒合同**
|
||||
|
||||
产品全称:**契阅合同起草与审阅工作台**
|
||||
功能说明:**起草与审阅工作台**
|
||||
|
||||
品牌背书:**钰麒科技出品**
|
||||
完整呈现:
|
||||
|
||||
法律主体:**内蒙古钰麒科技有限公司**
|
||||
**钰麒合同**
|
||||
**起草与审阅工作台**
|
||||
|
||||
公司主体:**内蒙古钰麒科技有限公司**
|
||||
|
||||
品牌背书:**内蒙古钰麒科技有限公司出品**
|
||||
|
||||
当前测试地址:**https://contact.yuqei.com/**
|
||||
|
||||
@@ -20,55 +25,59 @@
|
||||
|
||||
主宣传语:**让每一份合同,都阅得更明白。**
|
||||
|
||||
副宣传语:
|
||||
辅助宣传语:
|
||||
|
||||
- **起草有模板,审阅有依据,交付有留痕。**
|
||||
- **起草、审阅、报告交付一站完成。**
|
||||
- **把合同写清楚,把风险说明白。**
|
||||
- **合同处理,不止生成,更要看懂。**
|
||||
- **起草有模板,审阅有依据,交付有留痕。**
|
||||
|
||||
一句话定位:
|
||||
|
||||
**契阅是一套面向个人、团队与企业的合同起草与审阅工作台,围绕合同起草、自动审阅、风险说明、法条依据、报告交付和审计留痕,帮助用户把合同处理变得更清晰、更高效、更有依据。**
|
||||
**钰麒合同是一套面向个人、团队与企业的合同起草与审阅工作台,围绕合同起草、自动审阅、风险说明、法条依据、报告交付和审计留痕,帮助用户把合同处理变得更清晰、更高效、更有依据。**
|
||||
|
||||
## 二、为什么叫“契阅”
|
||||
## 二、为什么定为“钰麒合同”
|
||||
|
||||
这个名字的核心优点是短、稳、好记,也不会把门关死。
|
||||
此前讨论过“契阅”“钰麒合阅”“钰麒法契”等名称,但这些名称存在不同程度的问题:
|
||||
|
||||
- **契**:指向契约、合同、约定。
|
||||
- **阅**:指向阅读、审阅、看懂。
|
||||
- 合起来就是:**看懂契约,审阅合同。**
|
||||
- **契阅**:有品牌感,但单独使用时需要解释,且与“钰麒”连读时不够顺。
|
||||
- **钰麒契阅**:麒、契近音,读起来绕口。
|
||||
- **钰麒合阅**:比契阅顺,但“合阅合同”连读不自然。
|
||||
- **钰麒法契**:专业感强,但偏严肃,容易让个人用户觉得距离感重。
|
||||
- **钰麒法务工作台**:太宽,像企业内部法务部门系统,不够聚焦合同。
|
||||
|
||||
它比“助手”更正式,比“平台”更像品牌,比“风控”更舒服。
|
||||
最终选择 **钰麒合同**,原因是:
|
||||
|
||||
它也保留了足够的扩展空间:
|
||||
- **顺口**:销售、客服、用户都容易说。
|
||||
- **直观**:一听就知道是合同相关产品。
|
||||
- **不窄**:个人、团队、企业、律所、机构都能接受。
|
||||
- **不硬**:没有“风控”“系统”带来的压迫感。
|
||||
- **不俗套**:比“智能合同平台”“合同服务平台”更干净。
|
||||
- **可扩展**:未来可以覆盖模板、审阅、报告、台账、审批、电子签、私有部署。
|
||||
|
||||
- 个人可以用
|
||||
- 小团队可以用
|
||||
- 企业可以采购
|
||||
- 律所可以合作
|
||||
- 机构可以白标
|
||||
- 私有部署也说得通
|
||||
品牌结构建议:
|
||||
|
||||
**钰麒合同** 负责记忆和传播。
|
||||
**起草与审阅工作台** 负责解释产品用途。
|
||||
**内蒙古钰麒科技有限公司出品** 负责信任背书和法律主体。
|
||||
|
||||
## 三、品牌架构
|
||||
|
||||
建议采用这套结构:
|
||||
|
||||
| 层级 | 名称 | 用途 |
|
||||
| --- | --- | --- |
|
||||
| 主品牌 | 契阅 | 官网首屏、Logo、传播、用户记忆 |
|
||||
| 功能说明 | 合同起草与审阅工作台 | 解释产品用途,不抢品牌名 |
|
||||
| 公司背书 | 钰麒科技出品 | 提升信任感 |
|
||||
| 主品牌 | 钰麒合同 | 官网首屏、Logo、传播、用户记忆 |
|
||||
| 功能说明 | 起草与审阅工作台 | 解释产品用途 |
|
||||
| 法律主体 | 内蒙古钰麒科技有限公司 | 协议、备案、发票、商务合同 |
|
||||
| 产品线 | 契阅个人版 / 团队版 / 企业版 / 机构版 / 私有部署版 | 商业化分层 |
|
||||
| 产品线 | 个人版 / 团队版 / 企业版 / 机构版 / 私有部署版 | 商业化分层 |
|
||||
| 内容品牌 | 钰麒合同研究室 | 公众号、白皮书、案例拆解 |
|
||||
| 服务品牌 | 钰麒合同审阅服务 | 人工复核、顾问服务、机构交付 |
|
||||
|
||||
页面展示建议:
|
||||
页面呈现建议:
|
||||
|
||||
- Logo 区只写 **契阅**
|
||||
- Logo 下小字写 **合同起草与审阅工作台**
|
||||
- 页脚或关于页写 **钰麒科技出品**
|
||||
|
||||
不要把“钰麒”硬塞进主标题里。
|
||||
公司名负责背书,产品名负责传播。
|
||||
- Logo区:**钰麒合同**
|
||||
- 副标题:**起草与审阅工作台**
|
||||
- 页脚:**内蒙古钰麒科技有限公司出品**
|
||||
- 协议与发票:**内蒙古钰麒科技有限公司**
|
||||
|
||||
## 四、产品定位
|
||||
|
||||
@@ -78,7 +87,7 @@
|
||||
- 小团队:销售、采购、行政、人事协作
|
||||
- 企业客户:法务、合规、内控、管理层
|
||||
- 律所/机构:服务交付、模板沉淀、客户演示
|
||||
- 数据敏感客户:需要私有部署和留痕
|
||||
- 数据敏感客户:需要私有部署、权限隔离和审计留痕
|
||||
|
||||
### 核心场景
|
||||
|
||||
@@ -90,7 +99,7 @@
|
||||
- 软件开发和技术服务合同
|
||||
- 合同模板沉淀
|
||||
- 合同风险说明
|
||||
- 审查报告交付
|
||||
- 审阅报告交付
|
||||
|
||||
### 主链路
|
||||
|
||||
@@ -98,7 +107,7 @@
|
||||
|
||||
### 产品边界
|
||||
|
||||
契阅提供的是合同处理、风险提示、依据说明和报告交付。
|
||||
钰麒合同提供的是合同处理、风险提示、依据说明和审阅报告。
|
||||
它不是替代律师,也不直接输出正式法律意见。
|
||||
|
||||
## 五、产品矩阵
|
||||
@@ -135,10 +144,10 @@
|
||||
|
||||
原因:
|
||||
|
||||
- 合同起草和审阅更适合大屏
|
||||
- 企业客户更看重权限、留痕、私有化和数据隔离
|
||||
- 小程序适合获客和轻量查看,不适合复杂编辑
|
||||
- App 下载会增加试用阻力
|
||||
- 合同起草和审阅更适合大屏。
|
||||
- 企业客户更看重权限、留痕、私有化和数据隔离。
|
||||
- 小程序适合获客和轻量查看,不适合复杂编辑。
|
||||
- App 下载会增加试用阻力。
|
||||
|
||||
推荐路径:
|
||||
|
||||
@@ -160,9 +169,10 @@
|
||||
|
||||
推荐模块名称:
|
||||
|
||||
- 合同起草台
|
||||
- 合同审阅台
|
||||
- 合同风险报告
|
||||
- 合同起草
|
||||
- 合同审阅
|
||||
- 审阅记录
|
||||
- 合同报告
|
||||
- 法条全文库
|
||||
- 企业规则库
|
||||
- 行业模板库
|
||||
@@ -207,10 +217,10 @@
|
||||
|
||||
### Logo 方向
|
||||
|
||||
- 抽象 **契约折角 + 文档页角 + 勾选标记**
|
||||
- 适度融入 **阅** 的笔画结构
|
||||
- 不建议做成纯法务图标
|
||||
- 不建议只放“AI”字样
|
||||
- 主标识可以围绕 **钰麒 + 合同文档 + 审阅标记** 组合。
|
||||
- 图形可使用“文档页角”“段落线”“审阅勾选”“批注框”等元素。
|
||||
- 不建议直接画法槌,避免显得传统律所化。
|
||||
- 不建议只用“AI”字样,品牌寿命太短。
|
||||
|
||||
### 推荐色彩
|
||||
|
||||
@@ -233,20 +243,23 @@
|
||||
|
||||
### 界面气质
|
||||
|
||||
- 信息密度要高
|
||||
- 页面要像正式交付物
|
||||
- 风险项要分层显示
|
||||
- 业务结论要优先,技术信息要折叠
|
||||
- 信息密度要高。
|
||||
- 页面要像正式交付物。
|
||||
- 风险项要分层显示。
|
||||
- 业务结论要优先,技术信息要折叠。
|
||||
- 报告页面要像正式审阅报告,而不是聊天记录导出。
|
||||
|
||||
## 八、文案体系
|
||||
|
||||
### 官网首屏
|
||||
|
||||
标题:**契阅**
|
||||
标题:**钰麒合同**
|
||||
|
||||
副标题:**合同起草与审阅工作台**
|
||||
副标题:**起草与审阅工作台**
|
||||
|
||||
说明:**让每一份合同,都阅得更明白。**
|
||||
说明:**合同起草、智能审阅、风险提示、报告交付,一条主线完成。**
|
||||
|
||||
主宣传语:**让每一份合同,都阅得更明白。**
|
||||
|
||||
主按钮:**申请演示**
|
||||
|
||||
@@ -254,6 +267,7 @@
|
||||
|
||||
### 可用文案
|
||||
|
||||
- 起草、审阅、报告交付一站完成
|
||||
- 起草有模板,审阅有依据
|
||||
- 把合同写清楚,把风险说明白
|
||||
- 合同处理,不止生成,更要看懂
|
||||
@@ -261,11 +275,11 @@
|
||||
|
||||
### 避免使用
|
||||
|
||||
- 风控
|
||||
- 助手
|
||||
- 风控平台
|
||||
- AI合同
|
||||
- 官方认证
|
||||
- 合同神器
|
||||
- 替代律师
|
||||
- 官方认证
|
||||
- 保证通过
|
||||
- 100% 合规
|
||||
|
||||
@@ -288,14 +302,14 @@
|
||||
- 人工复核服务
|
||||
- 私有部署实施
|
||||
- 电子签 / OA / ERP 集成
|
||||
- 合同风控培训
|
||||
- 合同审阅培训
|
||||
|
||||
### 试点原则
|
||||
|
||||
- 免费试点必须限定周期和额度
|
||||
- 试点必须有复盘
|
||||
- 免费只做获客入口,不做长期交付形态
|
||||
- 真实业务量上来后必须转入收费
|
||||
- 免费试点必须限定周期和额度。
|
||||
- 试点必须有复盘。
|
||||
- 免费只做获客入口,不做长期交付形态。
|
||||
- 真实业务量上来后必须转入收费。
|
||||
|
||||
## 十、销售与运营
|
||||
|
||||
@@ -339,7 +353,7 @@
|
||||
- 演示脚本
|
||||
- 报价单
|
||||
- 试点确认单
|
||||
- 合同风险报告样例
|
||||
- 合同审阅报告样例
|
||||
- 隐私与安全说明
|
||||
- 常见问题 FAQ
|
||||
|
||||
@@ -347,7 +361,7 @@
|
||||
|
||||
必须明确:
|
||||
|
||||
**契阅输出的是合同风险识别、修改建议、法条参考和审阅报告,不替代企业法务、律师或管理层最终判断。**
|
||||
**钰麒合同输出的是合同风险识别、修改建议、法条参考和审阅报告,不替代企业法务、律师或管理层最终判断。**
|
||||
|
||||
必须上线:
|
||||
|
||||
@@ -375,9 +389,9 @@
|
||||
|
||||
### 第一阶段:品牌定案
|
||||
|
||||
- 确定主品牌为 **契阅**
|
||||
- 确定说明语为 **合同起草与审阅工作台**
|
||||
- 确定背书为 **钰麒科技出品**
|
||||
- 确定主品牌为 **钰麒合同**
|
||||
- 确定说明语为 **起草与审阅工作台**
|
||||
- 确定正式展示为 **钰麒合同 / 起草与审阅工作台**
|
||||
- 统一官网、登录页、导航、页脚和海报口径
|
||||
|
||||
### 第二阶段:试点包装
|
||||
@@ -409,19 +423,45 @@
|
||||
| 私有部署意向 | 2+ |
|
||||
| 内容发布 | 30+ |
|
||||
|
||||
## 十四、最终结论
|
||||
## 十四、需要立刻修改的产品口径
|
||||
|
||||
当前代码和旧文档中仍有“AI合同平台”“合同平台”“AI合同起草与审查平台”等旧称。正式上线前建议统一替换为:
|
||||
|
||||
- 对外主名:**钰麒合同**
|
||||
- 副标题:**起草与审阅工作台**
|
||||
- 官网标题:**钰麒合同**
|
||||
- 登录页标题:**登录钰麒合同**
|
||||
- 导航品牌:**钰麒合同**
|
||||
- 报告名称:**钰麒合同审阅报告**
|
||||
- 试点材料名称:**钰麒合同试点说明**
|
||||
|
||||
不建议继续使用:
|
||||
|
||||
- AI合同平台
|
||||
- AI合同风控平台
|
||||
- 契阅
|
||||
- 钰麒合阅
|
||||
- 钰麒法契
|
||||
- 合同神器
|
||||
|
||||
## 十五、最终结论
|
||||
|
||||
推荐最终对外名称:
|
||||
|
||||
**契阅**
|
||||
**钰麒合同**
|
||||
|
||||
推荐说明语:
|
||||
|
||||
**合同起草与审阅工作台**
|
||||
**起草与审阅工作台**
|
||||
|
||||
推荐背书:
|
||||
推荐完整展示:
|
||||
|
||||
**钰麒科技出品**
|
||||
**钰麒合同**
|
||||
**起草与审阅工作台**
|
||||
|
||||
推荐主宣传语:
|
||||
|
||||
**让每一份合同,都阅得更明白。**
|
||||
|
||||
推荐正式域名:
|
||||
|
||||
Reference in New Issue
Block a user