feat: enhance contract review with semantic search and legal citations
Phase15 optimization: - Add semantic search fallback in _attach_legal_article_refs() - Expand LEGAL_ARTICLE_REFERENCE_RULES from 12 to 30+ scenarios - Add LEGAL_SOURCE_ALIAS_MAP for 35+ legal sources Contract review enhancement: - Cover labor, corporate, investment, procurement, construction - Add IP, data privacy, franchise, real estate scenarios - Enable vector semantic search as final fallback Legal citation visualization: - Create LegalArticlePreview component with hover tooltip - Support compact/full display modes - Add copy and detail link features Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -464,6 +464,7 @@ RELATION_STATUS_ATTENTION = "attention"
|
||||
RELATION_CONFIDENCE_HIGH = "high"
|
||||
RELATION_CONFIDENCE_WEAK = "weak"
|
||||
LEGAL_ARTICLE_REFERENCE_RULES = [
|
||||
# 民法典通用条款
|
||||
{
|
||||
"triggers": ["违约金"],
|
||||
"targets": [("LAW-CIVIL-CODE-2020", "第五百八十五条"), ("LAW-CIVIL-CODE-2020", "第五百七十七条")],
|
||||
@@ -496,6 +497,11 @@ LEGAL_ARTICLE_REFERENCE_RULES = [
|
||||
"triggers": ["电子签名", "签名", "盖章"],
|
||||
"targets": [("LAW-CIVIL-CODE-2020", "第四百九十条"), ("LAW-E-SIGNATURE-2019", "第十三条"), ("LAW-E-SIGNATURE-2019", "第十四条")],
|
||||
},
|
||||
{
|
||||
"triggers": ["保密", "商业秘密"],
|
||||
"targets": [("LAW-CIVIL-CODE-2020", "第五百零九条"), ("LAW-CIVIL-CODE-2020", "第五百七十七条")],
|
||||
},
|
||||
# 个人信息与数据安全
|
||||
{
|
||||
"triggers": ["个人信息", "隐私", "敏感个人信息", "告知同意"],
|
||||
"targets": [("LAW-PIPL-2021", "第十三条"), ("LAW-PIPL-2021", "第十四条"), ("LAW-PIPL-2021", "第十七条"), ("LAW-PIPL-2021", "第二十八条")],
|
||||
@@ -505,13 +511,148 @@ LEGAL_ARTICLE_REFERENCE_RULES = [
|
||||
"targets": [("LAW-DATA-SECURITY-2021", "第二十七条"), ("LAW-DATA-SECURITY-2021", "第二十九条"), ("LAW-DATA-SECURITY-2021", "第三十一条")],
|
||||
},
|
||||
{
|
||||
"triggers": ["保密", "商业秘密"],
|
||||
"targets": [("LAW-CIVIL-CODE-2020", "第五百零九条"), ("LAW-CIVIL-CODE-2020", "第五百七十七条")],
|
||||
"triggers": ["数据出境", "跨境传输", "境外"],
|
||||
"targets": [("LAW-DATA-EXPORT-SECURITY-2022", "第二条"), ("LAW-PI-EXPORT-CONTRACT-2023", "第二条"), ("LAW-DATA-SECURITY-2021", "第三十一条")],
|
||||
},
|
||||
# 劳动用工
|
||||
{
|
||||
"triggers": ["竞业限制", "劳动合同", "服务期"],
|
||||
"targets": [("LAW-LABOR-CONTRACT-2012", "第二十三条"), ("LAW-LABOR-CONTRACT-2012", "第二十四条"), ("LAW-LABOR-CONTRACT-2012", "第二十二条")],
|
||||
},
|
||||
{
|
||||
"triggers": ["试用期", "试用期限"],
|
||||
"targets": [("LAW-LABOR-CONTRACT-2012", "第十九条"), ("LAW-LABOR-CONTRACT-2012", "第二十条")],
|
||||
},
|
||||
{
|
||||
"triggers": ["社会保险", "社保", "五险一金"],
|
||||
"targets": [("LAW-SOCIAL-INSURANCE-2018", "第五十八条"), ("LAW-SOCIAL-INSURANCE-2018", "第六十条"), ("LAW-LABOR-CONTRACT-2012", "第三十八条")],
|
||||
},
|
||||
{
|
||||
"triggers": ["工伤", "职业病", "工伤认定"],
|
||||
"targets": [("LAW-WORK-INJURY-2010", "第十四条"), ("LAW-WORK-INJURY-2010", "第十五条"), ("LAW-WORK-INJURY-2010", "第二十条")],
|
||||
},
|
||||
{
|
||||
"triggers": ["解除劳动合同", "经济补偿", "赔偿金"],
|
||||
"targets": [("LAW-LABOR-CONTRACT-2012", "第三十九条"), ("LAW-LABOR-CONTRACT-2012", "第四十六条"), ("LAW-LABOR-CONTRACT-2012", "第四十七条")],
|
||||
},
|
||||
# 公司商事
|
||||
{
|
||||
"triggers": ["股权转让", "股东", "股权"],
|
||||
"targets": [("LAW-COMPANY-2023", "第八十四条"), ("LAW-COMPANY-2023", "第八十五条"), ("LAW-COMPANY-2023", "第八十六条")],
|
||||
},
|
||||
{
|
||||
"triggers": ["股东会", "股东大会", "决议"],
|
||||
"targets": [("LAW-COMPANY-2023", "第五十九条"), ("LAW-COMPANY-2023", "第六十条"), ("LAW-COMPANY-2023", "第六十一条")],
|
||||
},
|
||||
{
|
||||
"triggers": ["法定代表人", "董事", "监事"],
|
||||
"targets": [("LAW-COMPANY-2023", "第十条"), ("LAW-COMPANY-2023", "第六十七条"), ("LAW-COMPANY-2023", "第七十六条")],
|
||||
},
|
||||
{
|
||||
"triggers": ["注册资本", "出资", "增资"],
|
||||
"targets": [("LAW-COMPANY-2023", "第四十八条"), ("LAW-COMPANY-2023", "第四十九条"), ("LAW-COMPANY-2023", "第五十五条")],
|
||||
},
|
||||
# 投融资
|
||||
{
|
||||
"triggers": ["证券", "股票", "上市公司"],
|
||||
"targets": [("LAW-SECURITIES-2019", "第四条"), ("LAW-SECURITIES-2019", "第五条"), ("LAW-SECURITIES-2019", "第十九条")],
|
||||
},
|
||||
{
|
||||
"triggers": ["反垄断", "垄断协议", "滥用市场支配地位"],
|
||||
"targets": [("LAW-ANTI-MONOPOLY-2022", "第十三条"), ("LAW-ANTI-MONOPOLY-2022", "第二十二条"), ("LAW-ANTI-MONOPOLY-2022", "第二十三条")],
|
||||
},
|
||||
{
|
||||
"triggers": ["外商投资", "外资"],
|
||||
"targets": [("LAW-FOREIGN-INVEST-2019", "第二条"), ("LAW-FOREIGN-INVEST-2019", "第三条"), ("LAW-FOREIGN-INVEST-2019", "第四条")],
|
||||
},
|
||||
# 招投标采购
|
||||
{
|
||||
"triggers": ["招投标", "投标", "中标"],
|
||||
"targets": [("LAW-TENDER-2017", "第三条"), ("LAW-TENDER-2017", "第四条"), ("LAW-TENDER-2017", "第三十七条")],
|
||||
},
|
||||
{
|
||||
"triggers": ["政府采购", "采购"],
|
||||
"targets": [("LAW-GOVERNMENT-PROCUREMENT-2014", "第二条"), ("LAW-GOVERNMENT-PROCUREMENT-2014", "第三条"), ("LAW-GOVERNMENT-PROCUREMENT-2014", "第四条")],
|
||||
},
|
||||
# 建设工程
|
||||
{
|
||||
"triggers": ["建设工程", "工程质量", "验收"],
|
||||
"targets": [("LAW-CONSTRUCTION-2019", "第六十一条"), ("LAW-CONSTRUCTION-QUALITY-2019", "第三条"), ("LAW-CONSTRUCTION-QUALITY-2019", "第十六条")],
|
||||
},
|
||||
{
|
||||
"triggers": ["施工许可", "建筑许可"],
|
||||
"targets": [("LAW-CONSTRUCTION-2019", "第七条"), ("LAW-CONSTRUCTION-2019", "第八条")],
|
||||
},
|
||||
# 知识产权
|
||||
{
|
||||
"triggers": ["著作权", "版权", "软件著作权"],
|
||||
"targets": [("LAW-COPYRIGHT-2020", "第二条"), ("LAW-COPYRIGHT-2020", "第三条"), ("LAW-COPYRIGHT-2020", "第十条")],
|
||||
},
|
||||
{
|
||||
"triggers": ["专利", "专利权", "发明专利"],
|
||||
"targets": [("LAW-PATENT-2020", "第二条"), ("LAW-PATENT-2020", "第十条"), ("LAW-PATENT-2020", "第十一条")],
|
||||
},
|
||||
{
|
||||
"triggers": ["商标", "商标权", "注册商标"],
|
||||
"targets": [("LAW-TRADEMARK-2019", "第三条"), ("LAW-TRADEMARK-2019", "第四条"), ("LAW-TRADEMARK-2019", "第七条")],
|
||||
},
|
||||
# 担保
|
||||
{
|
||||
"triggers": ["担保", "保证", "抵押", "质押"],
|
||||
"targets": [("LAW-CIVIL-CODE-2020", "第三百八十六条"), ("LAW-CIVIL-CODE-2020", "第三百八十七条"), ("LAW-CIVIL-CODE-GUARANTEE-INTERP-2020", "第一条")],
|
||||
},
|
||||
# 借款
|
||||
{
|
||||
"triggers": ["借款", "借贷", "利息"],
|
||||
"targets": [("LAW-CIVIL-CODE-2020", "第六百六十七条"), ("LAW-CIVIL-CODE-2020", "第六百七十四条"), ("LAW-PRIVATE-LENDING-INTERP-2020", "第一条")],
|
||||
},
|
||||
# 争议解决
|
||||
{
|
||||
"triggers": ["仲裁", "仲裁协议"],
|
||||
"targets": [("LAW-ARBITRATION-2017", "第四条"), ("LAW-ARBITRATION-2017", "第五条"), ("LAW-ARBITRATION-2017", "第六条")],
|
||||
},
|
||||
{
|
||||
"triggers": ["管辖", "诉讼", "法院"],
|
||||
"targets": [("LAW-CIVIL-CODE-2020", "第四百六十五条"), ("LAW-CIVIL-CODE-CONTRACT-INTERP-2023", "第一条")],
|
||||
},
|
||||
# 特许经营
|
||||
{
|
||||
"triggers": ["特许经营", "加盟", "连锁"],
|
||||
"targets": [("LAW-FRANCHISE-MGMT-2007", "第三条"), ("LAW-FRANCHISE-MGMT-2007", "第七条"), ("LAW-FRANCHISE-MGMT-2007", "第八条")],
|
||||
},
|
||||
{
|
||||
"triggers": ["信息披露", "特许经营信息"],
|
||||
"targets": [("LAW-FRANCHISE-DISCLOSURE-2012", "第四条"), ("LAW-FRANCHISE-DISCLOSURE-2012", "第五条")],
|
||||
},
|
||||
# 房地产
|
||||
{
|
||||
"triggers": ["房地产", "土地使用权", "建设用地"],
|
||||
"targets": [("LAW-REAL-ESTATE-MGMT-2019", "第二条"), ("LAW-LAND-MGMT-2019", "第二条"), ("LAW-LAND-MGMT-2019", "第九条")],
|
||||
},
|
||||
{
|
||||
"triggers": ["物业", "物业管理", "物业费"],
|
||||
"targets": [("LAW-PROPERTY-MGMT-2018", "第二条"), ("LAW-PROPERTY-MGMT-2018", "第三十五条"), ("LAW-PROPERTY-MGMT-2018", "第三十六条")],
|
||||
},
|
||||
# 技术合同
|
||||
{
|
||||
"triggers": ["技术服务", "技术开发", "技术转让"],
|
||||
"targets": [("LAW-CIVIL-CODE-2020", "第八百四十三条"), ("LAW-CIVIL-CODE-2020", "第八百四十五条"), ("LAW-TECH-CONTRACT-INTERP-2020", "第一条")],
|
||||
},
|
||||
# 反不正当竞争
|
||||
{
|
||||
"triggers": ["不正当竞争", "虚假宣传", "商业贿赂"],
|
||||
"targets": [("LAW-ANTI-UNFAIR-COMP-2019", "第二条"), ("LAW-ANTI-UNFAIR-COMP-2019", "第八条"), ("LAW-ANTI-UNFAIR-COMP-2019", "第七条")],
|
||||
},
|
||||
# 电子商务
|
||||
{
|
||||
"triggers": ["电子商务", "平台", "网络交易"],
|
||||
"targets": [("LAW-E-COMMERCE-2018", "第二条"), ("LAW-E-COMMERCE-2018", "第九条"), ("LAW-E-COMMERCE-2018", "第十条")],
|
||||
},
|
||||
# 消费者权益
|
||||
{
|
||||
"triggers": ["消费者", "消费者权益", "退货"],
|
||||
"targets": [("LAW-CONSUMER-2013", "第二条"), ("LAW-CONSUMER-2013", "第二十四条"), ("LAW-CONSUMER-2013", "第二十五条")],
|
||||
},
|
||||
]
|
||||
LEGAL_SOURCE_ALIAS_MAP = {
|
||||
"LAW-CIVIL-CODE-2020": ["民法典", "中华人民共和国民法典"],
|
||||
@@ -520,6 +661,35 @@ LEGAL_SOURCE_ALIAS_MAP = {
|
||||
"LAW-LABOR-CONTRACT-2012": ["劳动合同法", "中华人民共和国劳动合同法"],
|
||||
"LAW-DATA-SECURITY-2021": ["数据安全法", "中华人民共和国数据安全法"],
|
||||
"LAW-COMPANY-2023": ["公司法", "中华人民共和国公司法"],
|
||||
"LAW-LABOR-2018": ["劳动法", "中华人民共和国劳动法"],
|
||||
"LAW-CYBERSECURITY-2016": ["网络安全法", "中华人民共和国网络安全法"],
|
||||
"LAW-PATENT-2020": ["专利法", "中华人民共和国专利法"],
|
||||
"LAW-TRADEMARK-2019": ["商标法", "中华人民共和国商标法"],
|
||||
"LAW-COPYRIGHT-2020": ["著作权法", "中华人民共和国著作权法"],
|
||||
"LAW-ANTI-UNFAIR-COMP-2019": ["反不正当竞争法", "中华人民共和国反不正当竞争法"],
|
||||
"LAW-ARBITRATION-2017": ["仲裁法", "中华人民共和国仲裁法"],
|
||||
"LAW-E-COMMERCE-2018": ["电子商务法", "中华人民共和国电子商务法"],
|
||||
"LAW-CONSUMER-2013": ["消费者权益保护法", "中华人民共和国消费者权益保护法"],
|
||||
"LAW-FOREIGN-INVEST-2019": ["外商投资法", "中华人民共和国外商投资法"],
|
||||
"LAW-ANTI-MONOPOLY-2022": ["反垄断法", "中华人民共和国反垄断法"],
|
||||
"LAW-SECURITIES-2019": ["证券法", "中华人民共和国证券法"],
|
||||
"LAW-TENDER-2017": ["招标投标法", "中华人民共和国招标投标法"],
|
||||
"LAW-GOVERNMENT-PROCUREMENT-2014": ["政府采购法", "中华人民共和国政府采购法"],
|
||||
"LAW-CONSTRUCTION-2019": ["建筑法", "中华人民共和国建筑法"],
|
||||
"LAW-CONSTRUCTION-QUALITY-2019": ["建设工程质量管理条例"],
|
||||
"LAW-SOCIAL-INSURANCE-2018": ["社会保险法", "中华人民共和国社会保险法"],
|
||||
"LAW-WORK-INJURY-2010": ["工伤保险条例"],
|
||||
"LAW-PROPERTY-MGMT-2018": ["物业管理条例"],
|
||||
"LAW-LAND-MGMT-2019": ["土地管理法", "中华人民共和国土地管理法"],
|
||||
"LAW-REAL-ESTATE-MGMT-2019": ["城市房地产管理法", "中华人民共和国城市房地产管理法"],
|
||||
"LAW-FRANCHISE-MGMT-2007": ["商业特许经营管理条例"],
|
||||
"LAW-FRANCHISE-DISCLOSURE-2012": ["商业特许经营信息披露管理办法"],
|
||||
"LAW-PRIVATE-LENDING-INTERP-2020": ["民间借贷司法解释"],
|
||||
"LAW-TECH-CONTRACT-INTERP-2020": ["技术合同纠纷司法解释"],
|
||||
"LAW-CIVIL-CODE-GUARANTEE-INTERP-2020": ["担保制度解释", "民法典担保制度解释"],
|
||||
"LAW-CIVIL-CODE-CONTRACT-INTERP-2023": ["合同编通则司法解释", "民法典合同编通则解释"],
|
||||
"LAW-DATA-EXPORT-SECURITY-2022": ["数据出境安全评估办法"],
|
||||
"LAW-PI-EXPORT-CONTRACT-2023": ["个人信息出境标准合同办法"],
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1458,6 +1458,22 @@ class ReviewService:
|
||||
limit=5,
|
||||
)
|
||||
refs = [self._legal_article_ref_payload(article, match_reason="runtime_search") for article in articles]
|
||||
# Semantic search fallback: when rule-based and legal_basis matching both fail,
|
||||
# use vector semantic search to find relevant legal articles
|
||||
if not refs and combined_text:
|
||||
try:
|
||||
from app.services.legal_article_service import LegalArticleService
|
||||
legal_article_service = LegalArticleService(self.db)
|
||||
query_text = (item_text + " " + source_text[:500]) if source_text else item_text
|
||||
semantic_results = legal_article_service.search_runtime_sources(
|
||||
{"tenant_id": tenant_id, "role": "system"},
|
||||
query_text,
|
||||
limit=3,
|
||||
)
|
||||
if semantic_results:
|
||||
refs = [self._legal_article_ref_payload(r, match_reason="semantic_search") for r in semantic_results]
|
||||
except Exception:
|
||||
pass # Semantic search is best-effort; do not break review flow on failure
|
||||
next_item["legal_article_refs"] = refs
|
||||
enriched.append(next_item)
|
||||
return enriched
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { Modal, Typography, Space, Tag, Button, Divider, Tooltip, message } from "antd";
|
||||
import { CopyOutlined, FileTextOutlined, LinkOutlined } from "@ant-design/icons";
|
||||
import Link from "next/link";
|
||||
|
||||
const { Text, Paragraph } = Typography;
|
||||
|
||||
interface LegalArticleRef {
|
||||
id: string;
|
||||
source_id: string;
|
||||
source_title: string;
|
||||
article_no: string;
|
||||
chapter_title?: string;
|
||||
section_title?: string;
|
||||
authority?: string;
|
||||
effective_date?: string;
|
||||
validity_status?: string;
|
||||
region?: string;
|
||||
tags?: string[];
|
||||
article_excerpt?: string;
|
||||
article_text?: string;
|
||||
knowledge_base_id?: string;
|
||||
knowledge_document_id?: string;
|
||||
detail_path?: string;
|
||||
match_reason?: string;
|
||||
updated_at?: string;
|
||||
}
|
||||
|
||||
interface LegalArticlePreviewProps {
|
||||
ref: LegalArticleRef;
|
||||
children?: React.ReactNode;
|
||||
showMatchReason?: boolean;
|
||||
compact?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* 法条引用预览组件
|
||||
*
|
||||
* 功能:
|
||||
* 1. 悬停显示法条摘要
|
||||
* 2. 点击打开详情弹窗
|
||||
* 3. 支持一键复制法条文本
|
||||
* 4. 显示匹配原因
|
||||
*/
|
||||
export default function LegalArticlePreview({
|
||||
ref: legalRef,
|
||||
children,
|
||||
showMatchReason = true,
|
||||
compact = false,
|
||||
}: LegalArticlePreviewProps) {
|
||||
const [modalVisible, setModalVisible] = useState(false);
|
||||
const [copied, setCopied] = useState(false);
|
||||
|
||||
const handleCopy = async () => {
|
||||
const text = [
|
||||
legalRef.source_title,
|
||||
legalRef.article_no,
|
||||
legalRef.article_text || legalRef.article_excerpt || "",
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join("\n");
|
||||
|
||||
try {
|
||||
await navigator.clipboard.writeText(text);
|
||||
setCopied(true);
|
||||
message.success("法条已复制到剪贴板");
|
||||
setTimeout(() => setCopied(false), 2000);
|
||||
} catch {
|
||||
message.error("复制失败");
|
||||
}
|
||||
};
|
||||
|
||||
// 紧凑模式:只显示法条名称和条款号
|
||||
if (compact) {
|
||||
return (
|
||||
<>
|
||||
<Tooltip
|
||||
title={
|
||||
<div style={{ maxWidth: 400 }}>
|
||||
<div style={{ fontWeight: 600, marginBottom: 4 }}>
|
||||
{legalRef.source_title} {legalRef.article_no}
|
||||
</div>
|
||||
<div style={{ fontSize: 12 }}>
|
||||
{(legalRef.article_text || legalRef.article_excerpt || "").slice(0, 150)}
|
||||
...
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<a onClick={() => setModalVisible(true)} style={{ cursor: "pointer" }}>
|
||||
{children || `${legalRef.source_title} ${legalRef.article_no}`}
|
||||
</a>
|
||||
</Tooltip>
|
||||
|
||||
<Modal
|
||||
title={
|
||||
<Space>
|
||||
<FileTextOutlined />
|
||||
{legalRef.source_title} {legalRef.article_no}
|
||||
</Space>
|
||||
}
|
||||
open={modalVisible}
|
||||
onCancel={() => setModalVisible(false)}
|
||||
footer={[
|
||||
<Button key="copy" icon={<CopyOutlined />} onClick={handleCopy}>
|
||||
{copied ? "已复制" : "复制法条"}
|
||||
</Button>,
|
||||
legalRef.detail_path ? (
|
||||
<Link key="detail" href={legalRef.detail_path} target="_blank">
|
||||
<Button icon={<LinkOutlined />}>查看完整法条</Button>
|
||||
</Link>
|
||||
) : null,
|
||||
<Button key="close" onClick={() => setModalVisible(false)}>
|
||||
关闭
|
||||
</Button>,
|
||||
]}
|
||||
width={720}
|
||||
>
|
||||
<Space direction="vertical" style={{ width: "100%" }} size="middle">
|
||||
{/* 法条元数据 */}
|
||||
<Space wrap>
|
||||
<Tag color="blue">{legalRef.source_title}</Tag>
|
||||
{legalRef.article_no && <Tag>{legalRef.article_no}</Tag>}
|
||||
{legalRef.authority && <Tag color="green">{legalRef.authority}</Tag>}
|
||||
{legalRef.validity_status && <Tag color="cyan">{legalRef.validity_status}</Tag>}
|
||||
{showMatchReason && legalRef.match_reason && (
|
||||
<Tag color="purple">匹配方式: {legalRef.match_reason}</Tag>
|
||||
)}
|
||||
</Space>
|
||||
|
||||
{/* 章节信息 */}
|
||||
{(legalRef.chapter_title || legalRef.section_title) && (
|
||||
<div>
|
||||
{legalRef.section_title && (
|
||||
<Text type="secondary" style={{ fontSize: 12 }}>
|
||||
节:{legalRef.section_title}
|
||||
</Text>
|
||||
)}
|
||||
{legalRef.chapter_title && (
|
||||
<Text type="secondary" style={{ fontSize: 12, marginLeft: 8 }}>
|
||||
章:{legalRef.chapter_title}
|
||||
</Text>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<Divider style={{ margin: "8px 0" }} />
|
||||
|
||||
{/* 法条全文 */}
|
||||
<Paragraph style={{ fontSize: 14, lineHeight: 1.8, whiteSpace: "pre-wrap" }}>
|
||||
{legalRef.article_text || legalRef.article_excerpt || "法条全文暂无"}
|
||||
</Paragraph>
|
||||
|
||||
{/* 生效日期 */}
|
||||
{legalRef.effective_date && (
|
||||
<Text type="secondary" style={{ fontSize: 12 }}>
|
||||
生效日期:{legalRef.effective_date}
|
||||
</Text>
|
||||
)}
|
||||
</Space>
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
// 完整模式:显示卡片式预览
|
||||
return (
|
||||
<div
|
||||
className="legal-article-preview-card"
|
||||
style={{
|
||||
padding: 12,
|
||||
border: "1px solid #e8e8e8",
|
||||
borderRadius: 8,
|
||||
marginBottom: 8,
|
||||
background: "#fafafa",
|
||||
}}
|
||||
>
|
||||
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start" }}>
|
||||
<Space direction="vertical" size={4}>
|
||||
<Space>
|
||||
<Tag color="blue">{legalRef.source_title}</Tag>
|
||||
{legalRef.article_no && <Tag>{legalRef.article_no}</Tag>}
|
||||
</Space>
|
||||
{showMatchReason && legalRef.match_reason && (
|
||||
<Text type="secondary" style={{ fontSize: 12 }}>
|
||||
匹配方式: {legalRef.match_reason}
|
||||
</Text>
|
||||
)}
|
||||
</Space>
|
||||
<Space>
|
||||
<Button size="small" icon={<CopyOutlined />} onClick={handleCopy}>
|
||||
复制
|
||||
</Button>
|
||||
{legalRef.detail_path && (
|
||||
<Link href={legalRef.detail_path} target="_blank">
|
||||
<Button size="small" icon={<LinkOutlined />}>
|
||||
详情
|
||||
</Button>
|
||||
</Link>
|
||||
)}
|
||||
</Space>
|
||||
</div>
|
||||
|
||||
{/* 法条摘要 */}
|
||||
<div style={{ marginTop: 8 }}>
|
||||
<Paragraph
|
||||
ellipsis={{ rows: 2, expandable: true, symbol: "展开" }}
|
||||
style={{ fontSize: 13, marginBottom: 0 }}
|
||||
>
|
||||
{legalRef.article_text || legalRef.article_excerpt || "法条全文暂无"}
|
||||
</Paragraph>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user