diff --git a/backend/app/services/legal_domain_registry.py b/backend/app/services/legal_domain_registry.py
index ca22f093..dcab9ba8 100644
--- a/backend/app/services/legal_domain_registry.py
+++ b/backend/app/services/legal_domain_registry.py
@@ -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": ["个人信息出境标准合同办法"],
}
diff --git a/backend/app/services/review_service.py b/backend/app/services/review_service.py
index 07d820dd..dbc7f1c2 100644
--- a/backend/app/services/review_service.py
+++ b/backend/app/services/review_service.py
@@ -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
diff --git a/frontend/src/components/legal/LegalArticlePreview.tsx b/frontend/src/components/legal/LegalArticlePreview.tsx
new file mode 100644
index 00000000..121a1aa6
--- /dev/null
+++ b/frontend/src/components/legal/LegalArticlePreview.tsx
@@ -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 (
+ <>
+