import React, { useState } from 'react';
|
import { Input, DatePicker, Button, Spin, Pagination, Select, Modal } from 'antd';
|
import { SearchOutlined, RedoOutlined } from '@ant-design/icons';
|
import { mockCaseList } from '../../mocks/caseMocks';
|
import TypicalCaseDetailContent from './TypicalCaseDetailContent';
|
import './TypicalCaseSearch.css';
|
|
const { RangePicker } = DatePicker;
|
|
/**
|
* 典型案例查询内容组件 - 与原型 case_search.html 保持一致
|
*/
|
const CaseSearchContent = () => {
|
const [loading, setLoading] = useState(false);
|
const [list, setList] = useState(mockCaseList.list);
|
const [keyword, setKeyword] = useState('');
|
const [disputeType, setDisputeType] = useState(undefined);
|
const [detailVisible, setDetailVisible] = useState(false);
|
const [selectedCase, setSelectedCase] = useState(null);
|
const [currentPage, setCurrentPage] = useState(1);
|
|
// 模拟筛选器状态
|
const [caseTypeFilters, setCaseTypeFilters] = useState([
|
{ label: '判决文书', count: 1221120, checked: true },
|
{ label: '调解案例', count: 332526, checked: false },
|
]);
|
|
const [yearFilters, setYearFilters] = useState([
|
{ label: '2021年', count: 1221120, checked: false },
|
{ label: '2022年', count: 332526, checked: false },
|
{ label: '2023年', count: 62221, checked: true },
|
{ label: '2024年', count: 32212, checked: false },
|
]);
|
|
const [regionFilters, setRegionFilters] = useState([
|
{ label: '全部', count: 462100, checked: true },
|
{ label: '广东省', count: 62201, checked: false, isSub: true, children: [
|
{ label: '广州市', count: 10221, checked: false },
|
{ label: '深圳市', count: 20001, checked: false },
|
{ label: '中山市', count: 9632, checked: false },
|
]},
|
{ label: '广西省', count: 44552, checked: false, isSub: true },
|
{ label: '湖南省', count: 83001, checked: false, isSub: true },
|
{ label: '湖北省', count: 98745, checked: false, isSub: true },
|
{ label: '浙江省', count: 30021, checked: false, isSub: true },
|
]);
|
|
const handleSearch = () => {
|
setLoading(true);
|
setTimeout(() => {
|
setList(mockCaseList.list);
|
setLoading(false);
|
}, 300);
|
};
|
|
const handleReset = () => {
|
setKeyword('');
|
setDisputeType(undefined);
|
setCaseTypeFilters(caseTypeFilters.map((f, i) => ({ ...f, checked: i === 0 })));
|
setYearFilters(yearFilters.map((f, i) => ({ ...f, checked: i === 2 })));
|
setRegionFilters(regionFilters.map((f, i) => ({ ...f, checked: i === 0 })));
|
};
|
|
const handleCaseClick = (item) => {
|
setSelectedCase(item);
|
setDetailVisible(true);
|
};
|
|
const toggleFilter = (filters, setFilters, index, isChild = false, parentIndex = null) => {
|
const newFilters = [...filters];
|
if (isChild) {
|
newFilters[parentIndex].children = [...newFilters[parentIndex].children];
|
newFilters[parentIndex].children[index] = {
|
...newFilters[parentIndex].children[index],
|
checked: !newFilters[parentIndex].children[index].checked
|
};
|
} else {
|
newFilters[index] = { ...newFilters[index], checked: !newFilters[index].checked };
|
// 如果选中"全部",取消其他
|
if (newFilters[index].label === '全部' && newFilters[index].checked) {
|
newFilters.forEach((f, i) => { if (i !== index) f.checked = false; });
|
} else if (newFilters[index].checked) {
|
const allIdx = newFilters.findIndex(f => f.label === '全部');
|
if (allIdx !== -1) newFilters[allIdx].checked = false;
|
}
|
}
|
setFilters(newFilters);
|
};
|
|
return (
|
<div className="case-search-container">
|
<h1 className="case-search-content-title">
|
<i className="fas fa-folder-open"></i>
|
典型案例
|
</h1>
|
|
{/* 查询条件区域 */}
|
<div className="case-search-query-conditions">
|
<h2 className="case-search-query-title">
|
<i className="fas fa-search"></i>
|
查询条件
|
</h2>
|
<div className="case-search-query-form">
|
<div className="case-search-form-group">
|
<label className="case-search-form-label">关键词</label>
|
<Input
|
placeholder="请填写"
|
value={keyword}
|
onChange={e => setKeyword(e.target.value)}
|
/>
|
</div>
|
<div className="case-search-form-group">
|
<label className="case-search-form-label">纠纷类型</label>
|
<Select
|
style={{ width: '100%' }}
|
placeholder="请选择"
|
value={disputeType}
|
onChange={setDisputeType}
|
allowClear
|
>
|
<Select.Option value="邻里纠纷">邻里纠纷</Select.Option>
|
<Select.Option value="劳动争议">劳动争议</Select.Option>
|
<Select.Option value="合同纠纷">合同纠纷</Select.Option>
|
</Select>
|
</div>
|
<div className="case-search-form-group">
|
<label className="case-search-form-label">纠纷发生时间</label>
|
<RangePicker style={{ width: '100%' }} />
|
</div>
|
<div className="case-search-form-group case-search-button-group">
|
<Button type="primary" icon={<SearchOutlined />} onClick={handleSearch} loading={loading} style={{ height: 46 }}>
|
查询
|
</Button>
|
<Button icon={<RedoOutlined />} onClick={handleReset} style={{ height: 46 }}>
|
重置条件
|
</Button>
|
</div>
|
</div>
|
</div>
|
|
{/* 筛选器区域 */}
|
<div className="case-search-filters-section">
|
{/* 案例类型 */}
|
<div className="case-search-filter-category">
|
<h3 className="case-search-filter-title">案例类型</h3>
|
<div className="case-search-filter-list">
|
{caseTypeFilters.map((item, index) => (
|
<div
|
key={index}
|
className={`case-search-filter-item ${item.checked ? 'active' : ''}`}
|
onClick={() => toggleFilter(caseTypeFilters, setCaseTypeFilters, index)}
|
>
|
<div className={`case-search-filter-checkbox ${item.checked ? 'checked' : ''}`}>
|
{item.checked && <i className="fas fa-check"></i>}
|
</div>
|
<span>{item.label}</span>
|
<span className="case-search-filter-count">{item.count.toLocaleString()}</span>
|
</div>
|
))}
|
</div>
|
</div>
|
|
{/* 发生时间 */}
|
<div className="case-search-filter-category">
|
<h3 className="case-search-filter-title">发生时间</h3>
|
<div className="case-search-filter-list">
|
{yearFilters.map((item, index) => (
|
<div
|
key={index}
|
className={`case-search-filter-item ${item.checked ? 'active' : ''}`}
|
onClick={() => toggleFilter(yearFilters, setYearFilters, index)}
|
>
|
<div className={`case-search-filter-checkbox ${item.checked ? 'checked' : ''}`}>
|
{item.checked && <i className="fas fa-check"></i>}
|
</div>
|
<span>{item.label}</span>
|
<span className="case-search-filter-count">{item.count.toLocaleString()}</span>
|
</div>
|
))}
|
</div>
|
</div>
|
|
{/* 纠纷发生地 */}
|
<div className="case-search-filter-category">
|
<h3 className="case-search-filter-title">纠纷发生地</h3>
|
<div className="case-search-filter-list">
|
{regionFilters.map((item, index) => (
|
<React.Fragment key={index}>
|
<div
|
className={`${item.isSub ? 'case-search-sub-filter-item' : 'case-search-filter-item'} ${item.checked ? 'active' : ''}`}
|
onClick={() => toggleFilter(regionFilters, setRegionFilters, index)}
|
style={item.isSub ? { marginLeft: 20 } : {}}
|
>
|
<div className={`case-search-filter-checkbox ${item.checked ? 'checked' : ''}`}>
|
{item.checked && <i className="fas fa-check"></i>}
|
</div>
|
<span>{item.label}</span>
|
<span className="case-search-filter-count">{item.count.toLocaleString()}</span>
|
</div>
|
{item.children && (
|
<div className="case-search-sub-filter-list" style={{ marginLeft: 40 }}>
|
{item.children.map((child, cIdx) => (
|
<div
|
key={cIdx}
|
className={`case-search-sub-filter-item ${child.checked ? 'active' : ''}`}
|
onClick={(e) => {
|
e.stopPropagation();
|
toggleFilter(regionFilters, setRegionFilters, cIdx, true, index);
|
}}
|
>
|
<div className={`case-search-filter-checkbox ${child.checked ? 'checked' : ''}`}>
|
{child.checked && <i className="fas fa-check"></i>}
|
</div>
|
<span>{child.label}</span>
|
<span className="case-search-filter-count">{child.count.toLocaleString()}</span>
|
</div>
|
))}
|
</div>
|
)}
|
</React.Fragment>
|
))}
|
</div>
|
</div>
|
</div>
|
|
{/* 查询结果区域 */}
|
<div className="case-search-results-section">
|
<div className="case-search-results-header">
|
<h2 className="case-search-results-title">查询结果</h2>
|
<div className="case-search-total-count">记录总数:{mockCaseList.pageInfo.total}条</div>
|
</div>
|
|
<Spin spinning={loading}>
|
<div className="case-search-cases-list">
|
{list.map((item) => (
|
<div
|
key={item.id}
|
className="case-search-case-item"
|
onClick={() => handleCaseClick(item)}
|
>
|
<h3 className="case-search-case-title">{item.caseTitle}</h3>
|
<div className="case-search-case-meta">
|
<div className="case-search-case-meta-item">
|
<i className="far fa-calendar-alt"></i>
|
<span>发生时间:{item.judgmentDate}</span>
|
</div>
|
<div className="case-search-case-meta-item">
|
<i className="fas fa-map-marker-alt"></i>
|
<span>发生地点:{item.region}</span>
|
</div>
|
<div className="case-search-case-meta-item">
|
<i className="fas fa-balance-scale"></i>
|
<span>纠纷类型:{item.disputeType}</span>
|
</div>
|
</div>
|
<div className={`case-search-case-type-badge ${item.caseType === '调解' ? 'mediation' : 'judgment'}`}>
|
{item.caseType === '调解' ? '调解案例' : '判决文书'}
|
</div>
|
</div>
|
))}
|
</div>
|
</Spin>
|
|
{/* 分页 */}
|
<div className="case-search-pagination">
|
<Pagination
|
current={currentPage}
|
total={mockCaseList.pageInfo.total}
|
pageSize={10}
|
onChange={setCurrentPage}
|
showSizeChanger={false}
|
/>
|
</div>
|
</div>
|
|
{/* 案例详情弹窗 */}
|
<Modal
|
title={
|
<div className="case-detail-modal-header-custom">
|
<h2>
|
<i className="fas fa-folder-open"></i>
|
典型案例详情
|
</h2>
|
</div>
|
}
|
visible={detailVisible}
|
onCancel={() => setDetailVisible(false)}
|
footer={null}
|
width={1000}
|
bodyStyle={{ padding: 0, height: '85vh', overflowY: 'auto', backgroundColor: '#f5f7fa' }}
|
centered
|
destroyOnClose
|
className="case-detail-antd-modal"
|
closeIcon={<span className="case-detail-modal-close-custom">×</span>}
|
>
|
<TypicalCaseDetailContent caseData={selectedCase} />
|
</Modal>
|
</div>
|
);
|
};
|
|
export default CaseSearchContent;
|