import React, { useState, useEffect } from 'react';
|
import { Spin, message } from 'antd';
|
import LawAPIService from '../../services/LawAPIService';
|
import './LawDetailContent.css';
|
|
/**
|
* 格式化日期为 YYYY年MM月DD日 格式
|
* @param {string} dateStr - 日期字符串 YYYY-MM-DD
|
* @returns {string} 格式化后的日期
|
*/
|
const formatDate = (dateStr) => {
|
if (!dateStr) return '-';
|
try {
|
const date = new Date(dateStr);
|
const year = date.getFullYear();
|
const month = date.getMonth() + 1;
|
const day = date.getDate();
|
return `${year}年${month}月${day}日`;
|
} catch (error) {
|
return dateStr;
|
}
|
};
|
|
/**
|
* 从 provision_text 中提取章节列表
|
* @param {string} provisionText - 法律原文纯文本
|
* @returns {Array} 章节对象数组 [{id, title}, ...]
|
*/
|
const extractChapters = (provisionText) => {
|
if (!provisionText) return [];
|
|
const startMarker = "\n\n目 录\n";
|
const endMarker = "\n\n第一章 总则\n\n";
|
|
const startIndex = provisionText.indexOf(startMarker);
|
const endIndex = provisionText.indexOf(endMarker);
|
|
if (startIndex === -1 || endIndex === -1) {
|
console.warn('未找到章节目录标记,跳过章节提取');
|
return [];
|
}
|
|
const tocContent = provisionText.substring(
|
startIndex + startMarker.length,
|
endIndex
|
);
|
|
const lines = tocContent.split('\n').filter(line => line.trim());
|
|
return lines.map((line, index) => ({
|
id: `chapter-${index + 1}`,
|
title: line.trim()
|
}));
|
};
|
|
const LawDetailContent = ({ lawId }) => {
|
const [loading, setLoading] = useState(false);
|
const [activeChapter, setActiveChapter] = useState(null);
|
const [lawDetail, setLawDetail] = useState(null);
|
const [chapters, setChapters] = useState([]);
|
|
useEffect(() => {
|
const loadDetail = async () => {
|
if (!lawId) return;
|
|
setLoading(true);
|
try {
|
const response = await LawAPIService.getLawOriginalDetail(lawId);
|
const detailData = response.data;
|
|
// 从 provision_text 提取章节
|
const extractedChapters = extractChapters(detailData.provision_text || '');
|
|
setLawDetail(detailData);
|
setChapters(extractedChapters);
|
|
// 设置默认激活第一个章节
|
if (extractedChapters.length > 0) {
|
setActiveChapter(extractedChapters[0].id);
|
}
|
} catch (error) {
|
message.error('详情加载失败');
|
console.error('详情加载失败:', error);
|
} finally {
|
setLoading(false);
|
}
|
};
|
|
loadDetail();
|
}, [lawId]);
|
|
if (loading) {
|
return (
|
<div className="law-detail-loading" style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '400px' }}>
|
<Spin size="large" tip="加载中..." />
|
</div>
|
);
|
}
|
|
if (!lawDetail) {
|
return <div className="law-detail-loading">暂无数据</div>;
|
}
|
|
const handleChapterClick = (chapterId) => {
|
setActiveChapter(chapterId);
|
const element = document.getElementById(chapterId);
|
if (element) {
|
element.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
}
|
};
|
|
return (
|
<div className="law-detail-modal-body">
|
{/* 章节导航 */}
|
{chapters.length > 0 && (
|
<div className="law-detail-chapter-nav">
|
<h3 className="law-detail-chapter-nav-title">
|
<i className="fas fa-list-ol"></i>
|
章节导航
|
</h3>
|
<div className="law-detail-chapter-list">
|
{chapters.map((chapter) => (
|
<a
|
key={chapter.id}
|
href={`#${chapter.id}`}
|
className={`law-detail-chapter-link ${activeChapter === chapter.id ? 'active' : ''}`}
|
onClick={(e) => {
|
e.preventDefault();
|
handleChapterClick(chapter.id);
|
}}
|
>
|
{chapter.title}
|
</a>
|
))}
|
</div>
|
</div>
|
)}
|
|
{/* 法律详情容器 */}
|
<div className="law-detail-main-container">
|
<div className="law-detail-header">
|
<h2 className="law-detail-title">{lawDetail.title || '未命名法律'}</h2>
|
<div className="law-detail-meta-grid">
|
<div className="law-detail-meta-item">
|
<span className="law-detail-meta-label">时效性:</span>
|
<span className="law-detail-meta-value status-effective">{lawDetail.validity_name || '其他'}</span>
|
</div>
|
<div className="law-detail-meta-item">
|
<span className="law-detail-meta-label">法律效力位阶:</span>
|
<span className="law-detail-meta-value">{lawDetail.law_nature_name || '-'}</span>
|
</div>
|
<div className="law-detail-meta-item">
|
<span className="law-detail-meta-label">制定机关:</span>
|
<span className="law-detail-meta-value">{lawDetail.authority_name || '-'}</span>
|
</div>
|
<div className="law-detail-meta-item">
|
<span className="law-detail-meta-label">公布日期:</span>
|
<span className="law-detail-meta-value">{formatDate(lawDetail.publish_time)}</span>
|
</div>
|
<div className="law-detail-meta-item">
|
<span className="law-detail-meta-label">实施日期:</span>
|
<span className="law-detail-meta-value">{formatDate(lawDetail.implementation_time)}</span>
|
</div>
|
</div>
|
</div>
|
|
<div className="law-detail-content-area">
|
{lawDetail.provision_text ? (
|
<div className="law-detail-provision-text">
|
{lawDetail.provision_text.split('\n').map((line, index) => (
|
<React.Fragment key={index}>
|
{line}
|
{index < lawDetail.provision_text.split('\n').length - 1 && <br />}
|
</React.Fragment>
|
))}
|
</div>
|
) : (
|
<div className="law-detail-no-content">暂无详细内容</div>
|
)}
|
</div>
|
</div>
|
</div>
|
);
|
};
|
|
export default LawDetailContent;
|