import React, { useEffect, useState, useRef } from 'react';
|
import NewTableSearch from '@/components/NewTableSearch';
|
import * as $$ from '@/utils/utility';
|
import { Form, Space } from 'antd';
|
import { Divider, Pagination, Spin, Tree, Tooltip } from '@arco-design/web-react';
|
import { IconDown, IconClose } from '@arco-design/web-react/icon';
|
import { useNavigate, useLocation } from 'react-router-dom';
|
import { Scrollbars } from "react-custom-scrollbars";
|
import { getOffset, getSize } from '@/utils/utility';
|
|
const TreeNode = Tree.Node;
|
|
//判决列表
|
function getPageQuery(data) {
|
return $$.ax.request({ url: 'cpwsCaseInfo/pageQuery', type: 'get', data, service: 'know' });
|
}
|
|
//判决统计
|
function getJudgmentCount(data) {
|
return $$.ax.request({ url: 'cpwsCaseInfo/categoryCount', type: 'get', data, service: 'know' });
|
}
|
|
//调解案例列表
|
function getCasePageQuery(data) {
|
return $$.ax.request({ url: 'dyhCaseInfo/pageQuery', type: 'get', data, service: 'know' });
|
}
|
|
//调解案统计
|
function getCategoryCount(data) {
|
return $$.ax.request({ url: 'dyhCaseInfo/categoryCount', type: 'get', data, service: 'know' });
|
}
|
|
//统计判决案例和调解案例数量
|
function getTypeCount(data) {
|
return $$.ax.request({ url: 'cpwsCaseInfo/typeCount', type: 'get', data, service: 'know' });
|
}
|
|
export default function KnowledgeBase(props) {
|
const [form] = Form.useForm();
|
const navigate = useNavigate();
|
let location = useLocation();
|
const scrollRef = useRef(null);
|
const dict = {
|
'发生时间': 'judgmentTime',
|
'纠纷发生地': 'courtName',
|
'judgmentTime': '发生时间',
|
'keyword': '关键词',
|
'dyhCauseId': '纠纷类型',
|
'courtName': '纠纷发生地'
|
}
|
|
const [knowSearchList, setKnowSearchList] = useState([]);//左侧知识库分类
|
const [tableList, setTableList] = useState([])//列表
|
const [searchData, setSearchData] = useState({});//查询数据
|
const [pageData, setPageData] = useState({
|
page: 1,
|
size: 10,
|
});//页码
|
const [total, setTotal] = useState(0);//列表总数
|
const [loading, setLoading] = useState(false);//表格请求
|
const [height, setHeight] = useState(500);//滚动高度
|
const [exampleList, setExampleList] = useState([]);//案例类型列表
|
const [example, setExample] = useState('判决文书');//案例类型选中
|
const [leftLoading, setLeftLoading] = useState(false);//左侧loading
|
|
useEffect(() => {
|
getTypeCountData()
|
|
//缓存处理
|
let returnRouteData = $$.getSessionStorage(location.pathname);
|
if (returnRouteData && returnRouteData.mediateTab === '2') {
|
getCount(returnRouteData.example, true)
|
let obj = { ...returnRouteData.searchData };
|
form.setFieldsValue(obj)
|
setSearchData(returnRouteData.searchData)
|
setPageData(returnRouteData.pageData)
|
setExample(returnRouteData.example)
|
getTableData(returnRouteData.example, { ...returnRouteData.searchData }, returnRouteData.pageData)
|
$$.clearSessionStorage(location.pathname);
|
} else {
|
getCount(example)
|
}
|
|
onWindowResize()
|
window.addEventListener("resize", onWindowResize);
|
// 返回一个函数,该函数会在组件卸载前执行
|
return () => {
|
// 组件销毁时执行
|
window.removeEventListener("resize", onWindowResize);
|
};
|
}, [])
|
|
const onWindowResize = () => {
|
let offsetTop = 0;
|
if (scrollRef.current.container) {
|
offsetTop = getOffset(scrollRef.current.container).top;
|
}
|
setHeight(getSize().windowH - offsetTop - 72)
|
};
|
|
//重置表格请求
|
const handleTableReset = (name) => {
|
form.resetFields()
|
setSearchData({})
|
setPageData({
|
...pageData,
|
page: 1,
|
})
|
getTableData(name || example, {}, { page: 1, size: 10 })
|
}
|
|
//获取统计
|
const getCount = async (name, flag) => {
|
!flag && handleTableReset(name)
|
setLeftLoading(true)
|
const getPageData = name == '判决文书' ? getJudgmentCount : getCategoryCount;
|
const res = await getPageData()
|
if (res.type) {
|
setKnowSearchList(res.data)
|
setLeftLoading(false)
|
}
|
}
|
|
//获取统计判决案例和调解案例数量
|
const getTypeCountData = async () => {
|
const res = await getTypeCount()
|
if (res.type) {
|
setExampleList(res.data)
|
}
|
}
|
|
//获取数据
|
const getTableData = async (name, searchData, pageData) => {
|
const getPageData = name == '判决文书' ? getPageQuery : getCasePageQuery;
|
setLoading(true)
|
searchData.dyhCauseId = searchData.dyhCauseId?.length > 0 ? searchData.dyhCauseId[1] : '';
|
$$.changeTimNeweFormat(searchData, 'judgmentTime', 'judgmentStart', 'judgmentEnd');
|
const res = await getPageData({
|
...searchData,
|
...pageData
|
})
|
if (res.type) {
|
setLoading(false)
|
setTableList(res.data.content)
|
setTotal(res.data.totalElements)
|
}
|
}
|
|
//命中词条高亮
|
const handleText = (text) => {
|
let keyword = searchData.keyword || ''
|
// 如果没有关键字,则直接渲染文本
|
if (!keyword) {
|
return <span>{text}</span>;
|
}
|
|
// 使用正则表达式查找所有匹配的关键字(不区分大小写)
|
const regex = new RegExp(`(${keyword})`, 'gi');
|
|
// 使用一个数组来存储片段
|
const parts = [];
|
let lastIndex = 0;
|
let match;
|
|
// 遍历所有匹配项,并将文本拆分为片段
|
while ((match = regex.exec(text)) !== null) {
|
// 添加非匹配文本到片段数组
|
if (match.index > lastIndex) {
|
parts.push(text.slice(lastIndex, match.index));
|
}
|
// 添加匹配文本(带有高亮样式)到片段数组
|
parts.push(
|
<span style={{ color: '#1A6FB8' }}>
|
{match[0]}
|
</span>
|
);
|
lastIndex = regex.lastIndex;
|
}
|
|
// 添加剩余的文本(如果有)
|
if (lastIndex < text.length) {
|
parts.push(text.slice(lastIndex));
|
}
|
|
// 返回包含所有片段的 JSX 元素
|
return <span>{parts}</span>;
|
}
|
|
//左侧查询
|
const searchTotal = (data, children) => {
|
const name = dict[data.name];
|
let newData = searchData;
|
if (name == 'judgmentTime') {
|
newData[name] = [children[0] + '-01-01', children[0] + '-12-31']
|
setSearchData({
|
...newData
|
})
|
getTableData(example, { ...newData }, pageData)
|
} else {
|
//获取层级
|
const courtLevel = findLevelInTree(data, children[0])
|
const leftSearch = {
|
...newData,
|
[name]: children[0],
|
courtLevel: courtLevel
|
}
|
setSearchData(leftSearch)
|
getTableData(example, { ...leftSearch }, pageData)
|
}
|
}
|
|
//获取层级
|
const findLevelInTree = (root, name) => {
|
// 定义一个辅助函数来进行递归搜索
|
function search(node, level) {
|
// 如果当前节点的名字匹配,则返回当前层级
|
if (node.name === name) {
|
return level;
|
}
|
|
// 遍历当前节点的所有子节点
|
if (node.children && node.children.length != 0) {
|
for (let child of node.children) {
|
// 递归调用 search 函数,层级加 1
|
let result = search(child, level + 1);
|
// 如果找到了匹配的节点,则返回结果
|
if (result !== undefined) {
|
return result;
|
}
|
}
|
}
|
|
// 如果没有找到匹配的节点,则返回 undefined
|
return undefined;
|
}
|
|
// 从根节点开始搜索,初始层级为 0
|
return search(root, 0);
|
}
|
|
//查询
|
const handleSearch = () => {
|
let values = form.getFieldsValue(true);
|
let filterValues = {...values}
|
Object.keys(values).map(item => {
|
if (values[item] === '' || values[item] === undefined) {
|
delete filterValues[item]
|
}
|
})
|
const search = {
|
...searchData,
|
...filterValues
|
}
|
const pData = {
|
...pageData,
|
page: 1
|
}
|
setSearchData(search)
|
setPageData(pData)
|
getTableData(example, { ...search }, { ...pData })
|
};
|
|
//数据 转换
|
const handleMapData = (tree) => {
|
return tree?.map(item => {
|
const text = item.name + '(' + item.count + ')'
|
return <TreeNode
|
title={<Tooltip trigger='hover' content={text}>
|
{text}
|
</Tooltip>}
|
key={item.name}
|
>
|
{(item.children && item.children.length != 0) && handleMapData(item.children)}
|
</TreeNode>
|
})
|
}
|
|
//点击切换案例类型
|
const changeType = (data) => {
|
getCount(data.name)
|
setExample(data.name)
|
}
|
|
//缓存
|
const handleCache = () => {
|
$$.setSessionStorage(location.pathname, {
|
searchData: searchData,
|
pageData: pageData,
|
mediateTab: props.mediateTab,
|
example: example
|
});
|
}
|
|
//根据id递归查找联级树
|
const loopName = (data, id) => {
|
for (const node of data) {
|
if (node.value === id) {
|
return node.label;
|
}
|
if (node.children) {
|
const result = loopName(node.children, id);
|
if (result) {
|
return result;
|
}
|
}
|
}
|
return '';
|
}
|
|
return (
|
<div>
|
<div className="myMediation-search" style={{ marginTop: '15px' }}>
|
<div style={{ fontSize: '16px', marginBottom: '10px' }}>查询条件</div>
|
<NewTableSearch
|
exportButtonShow={false}
|
labelLength={4}
|
rowNum={2}
|
form={form}
|
itemData={[
|
{ type: 'Input', name: 'keyword', label: '关键词' },
|
{ type: 'Cascader', name: 'dyhCauseId', label: '纠纷类型', placeholder: '请选择', span: 8, changeSelect: true, allowClear: false, treedata: $$.caseTypeSelect.caseTypeSelect },
|
{ type: 'RangePicker', name: 'judgmentTime', label: '判决时间', shortcutsPlacementLeft: true, shortcuts: $$.shortcutsList(), span: 8 },
|
]}
|
handleReset={() => {
|
form.resetFields()
|
const newSearch = searchData
|
const resetList = ['keyword', 'judgmentStart', 'judgmentEnd', 'dyhCauseId']
|
resetList.forEach(key => {
|
delete newSearch[key];
|
});
|
setSearchData({
|
...newSearch
|
})
|
setPageData({
|
...pageData,
|
page: 1
|
})
|
getTableData(example, { ...newSearch }, { ...pageData, page: 1 })
|
}}
|
handleSearch={() => { handleSearch() }}
|
/>
|
</div>
|
<div className='knowledgeBase'>
|
<div className='knowLeft'>
|
<Spin loading={leftLoading} style={{ width: '100%', height: '100%' }}>
|
<Scrollbars style={{ height: height + 68 + 'px' }} autoHide ref={scrollRef}>
|
<div
|
style={{
|
padding: '8px',
|
background: '#fff',
|
marginBottom: '12px'
|
}}
|
>
|
<div className='knowTitle'>案例类型</div>
|
<Divider />
|
{exampleList?.map((res, index) => {
|
return <div
|
className='knowList'
|
key={index}
|
onClick={() => { changeType(res) }}
|
style={{ color: example == res.name ? '#1A6FB8' : '' }}
|
>{res.name + '(' + res.count + ')'}</div>
|
})}
|
</div>
|
{knowSearchList?.map((item, index) => {
|
return <div
|
style={{
|
padding: '8px',
|
background: '#fff',
|
marginBottom: knowSearchList.length - 1 === index ? '0' : '12px'
|
}}
|
key={index}
|
className={item.name != '纠纷发生地' ? 'treeFeel' : ''}
|
>
|
<div className='knowTitle'>{item.name}</div>
|
<Divider />
|
<Tree
|
onSelect={(keys) => { searchTotal(item, keys) }}
|
autoExpandParent={false}
|
selectedKeys={item.name != '纠纷发生地' ? [searchData.judgmentTime ? searchData.judgmentTime[0].slice(0, 4) : ''] : [searchData.courtName]}
|
>
|
{handleMapData(item.children)}
|
</Tree>
|
</div>
|
})}
|
</Scrollbars>
|
</Spin>
|
</div>
|
<div className='knowRight'>
|
<Spin loading={loading} style={{ width: '100%', height: '100%' }}>
|
<Scrollbars style={{ height: height + 'px' }} autoHide ref={scrollRef}>
|
<div style={{ fontSize: "16px" }}>查询结果</div>
|
{Object.keys(searchData).length !== 0 && <>
|
<div className='rightSearch'>
|
查询条件:{Object.keys(searchData).filter(item => item != 'courtLevel').length}项
|
<span onClick={() => {
|
handleTableReset()
|
}}>清空条件</span>
|
</div>
|
<div className='rightTag'>
|
{Object.keys(searchData).map(item => {
|
let keyName = dict[item]
|
let value = searchData[item]
|
if (item == 'judgmentTime') {
|
//时间
|
value = searchData[item][0] + ' ~ ' + searchData[item][1]
|
}
|
if (item == 'dyhCauseId') {
|
//纠纷类型
|
let id = value[value.length - 1]
|
value = loopName($$.caseTypeSelect.caseTypeSelect, id)
|
}
|
if (item == 'courtLevel') {
|
return
|
}
|
return <div>{keyName}:{value}
|
<IconClose
|
style={{ cursor: 'pointer' }}
|
onClick={() => {
|
let newData = { ...searchData }
|
delete newData[item]
|
form.setFieldValue(item, undefined)
|
setSearchData({
|
...newData
|
})
|
getTableData(example, { ...newData }, pageData)
|
}}
|
/>
|
</div>
|
})}
|
</div>
|
</>}
|
<div>
|
{tableList.map((item, index) => {
|
return <div key={item.id || item.cpwsCaseInfoId}>
|
<div className='knowTableList'>
|
<div className='knowData'>
|
<div
|
className='knowTopTitle'
|
onClick={() => {
|
handleCache()
|
navigate(`/mediate/knowledgeBase/caseDetail/${item.cpwsCaseTextId || item.id}/${example}/${searchData.keyword}`)
|
}}
|
>{handleText(item.caseName || item.caseTitle || '无')}</div>
|
<div style={{ lineHeight: '18px', marginTop: '5px' }}>{`判决时间:${$$.dateFormat(item.judgmentDate || item.occurTime) || '无'} | 判决地点:${item.court || item.addr || '无'} | 纠纷类型:${item.caseReason || item.caseTypeName || '无'} | 案例类型:${example}`}</div>
|
</div>
|
<div className='knowAction'>
|
<Space style={{ color: '#1A6FB8' }}>
|
<div className='pointer' onClick={() => {
|
handleCache()
|
navigate(`/mediate/knowledgeBase/caseDetail/${item.cpwsCaseTextId || item.id}/${example}/${searchData.keyword}`)
|
}}>详情</div>
|
<div className='pointer' style={{ color: '#ccc' }} onClick={() => { }}>修改</div>
|
<div className='pointer' style={{ color: '#ccc' }} onClick={() => { }}>删除</div>
|
</Space>
|
</div>
|
</div>
|
<Divider />
|
</div>
|
})}
|
{tableList.length === 0 && <div style={{ textAlign: 'center', marginTop: '50px' }}>{$$.MyNewEmpty({ description: '暂无数据' })}</div>}
|
</div>
|
</Scrollbars>
|
<Pagination
|
showTotal
|
total={total}
|
showJumper
|
sizeCanChange
|
style={{ margin: '12px 12px 0 12px', justifyContent: 'end' }}
|
current={pageData.page}
|
pageSize={pageData.size}
|
onChange={(page, size) => {
|
setPageData({ page, size });
|
getTableData(example, {...searchData}, { page, size })
|
}}
|
/>
|
</Spin>
|
</div>
|
</div>
|
</div>
|
)
|
}
|