/*
|
* @Author: 韩天尊大人专属AI
|
* @Date: 2025-05-20
|
* @Version: 1.0.0
|
* @Description: 登记历史页面
|
*/
|
import React, { useState, useEffect, useRef } from 'react';
|
import { useHistory } from 'react-router-dom';
|
import { Button, Modal, InputItem, Picker } from 'dingtalk-design-mobile';
|
import { Scrollbars } from 'react-custom-scrollbars';
|
import NavBarPage from '../../components/NavBarPage';
|
import MyList from '../../components/MyList';
|
import CalendarRangeTwoDay from '../../components/CalendarRangeTwoDay';
|
import * as $$ from '../../utils/utility';
|
import caseTypeSelect from '../../utils/caseTypeSelect';
|
import selectOption from '../../utils/selectOption';
|
import { workStatistics_5 } from '../../assets/img';
|
import { SearchOutlined, CloseOutlined } from 'dd-icons';
|
import './index.less';
|
|
// 登记历史接口
|
function registerHistoryApi(data) {
|
return $$.ax.request({
|
url: 'caseRegisterInfo/pageQuery',
|
type: 'get',
|
data,
|
service: 'mediate',
|
});
|
}
|
|
// 时间类型选项
|
const dateTypeOptions = [
|
{ value: 'custom', label: '自定义' },
|
{ value: 'lastMonth', label: '上月' },
|
{ value: 'lastWeek', label: '上周' },
|
{ value: 'thisMonth', label: '本月' },
|
{ value: 'thisWeek', label: '本周' },
|
{ value: 'thisYear', label: '本年度' },
|
{ value: 'lastYear', label: '上年度' },
|
];
|
|
const RegisterHis = () => {
|
const history = useHistory();
|
// 搜索关键词
|
const [keyword, setKeyword] = useState('');
|
// 列表数据和分页状态
|
const [listData, setListData] = useState([]);
|
const [loading, setLoading] = useState(false);
|
const [hasMore, setHasMore] = useState(true);
|
const [page, setPage] = useState(1);
|
const [totalCount, setTotalCount] = useState(0);
|
// 筛选弹窗
|
const [filterVisible, setFilterVisible] = useState(false);
|
// 日期选择弹窗
|
const [datePickerVisible, setDatePickerVisible] = useState(false);
|
const [currentDateType, setCurrentDateType] = useState('');
|
const [dateTypeTarget, setDateTypeTarget] = useState('');
|
const [dateTypeModalVisible, setDateTypeModalVisible] = useState(false);
|
// 查询参数
|
const [queryParams, setQueryParams] = useState({
|
page: 1,
|
size: 10,
|
sortColmn: 1,
|
sortType: 2,
|
keyword: '',
|
createStart: '',
|
createEnd: '',
|
caseType: '',
|
plaintiffs: '',
|
defendants: '',
|
canal: '',
|
status: '',
|
mediResult: '',
|
caseLevel: '',
|
});
|
// 高级筛选参数
|
const [advancedParams, setAdvancedParams] = useState({
|
createStart: '',
|
createEnd: '',
|
caseType: '',
|
plaintiffs: '',
|
defendants: '',
|
canal: '',
|
status: '',
|
mediResult: '',
|
caseLevel: '',
|
});
|
// 是否已搜索
|
const [hasSearched, setHasSearched] = useState(false);
|
|
// 计算时间范围
|
const getDateRangeByType = (type) => {
|
const now = new Date();
|
let start, end;
|
switch (type) {
|
case 'lastMonth': {
|
const year = now.getMonth() === 0 ? now.getFullYear() - 1 : now.getFullYear();
|
const month = now.getMonth() === 0 ? 11 : now.getMonth() - 1;
|
start = new Date(year, month, 1);
|
end = new Date(year, month + 1, 0);
|
break;
|
}
|
case 'thisMonth': {
|
start = new Date(now.getFullYear(), now.getMonth(), 1);
|
end = new Date(now.getFullYear(), now.getMonth() + 1, 0);
|
break;
|
}
|
case 'lastWeek': {
|
const day = now.getDay() || 7;
|
end = new Date(now.getFullYear(), now.getMonth(), now.getDate() - day);
|
start = new Date(now.getFullYear(), now.getMonth(), now.getDate() - day - 6);
|
break;
|
}
|
case 'thisWeek': {
|
const day = now.getDay() || 7;
|
start = new Date(now.getFullYear(), now.getMonth(), now.getDate() - day + 1);
|
end = new Date(now.getFullYear(), now.getMonth(), now.getDate() - day + 7);
|
break;
|
}
|
case 'thisYear': {
|
start = new Date(now.getFullYear(), 0, 1);
|
end = new Date(now.getFullYear(), 11, 31);
|
break;
|
}
|
case 'lastYear': {
|
start = new Date(now.getFullYear() - 1, 0, 1);
|
end = new Date(now.getFullYear() - 1, 11, 31);
|
break;
|
}
|
default:
|
start = end = now;
|
}
|
// 日期格式化
|
const format = (date) => `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
|
return [format(start), format(end)];
|
};
|
|
// 选择时间类型
|
const handleDateTypeSelect = (type) => {
|
setDateTypeModalVisible(false);
|
if (type === 'custom') {
|
setCurrentDateType(dateTypeTarget);
|
setDatePickerVisible(true);
|
} else {
|
const [start, end] = getDateRangeByType(type);
|
if (dateTypeTarget === 'create') {
|
setAdvancedParams((prev) => ({ ...prev, createStart: start, createEnd: end }));
|
}
|
}
|
};
|
|
// 日历组件操作处理(可选,和综合查询保持一致)
|
const handleCalendarClick = (type, action) => {
|
if (action === 'onClose') {
|
setDatePickerVisible(false);
|
} else if (action === 'submit') {
|
setDatePickerVisible(false);
|
}
|
};
|
|
// 获取列表数据
|
const fetchListData = async (currentPage, params = {}) => {
|
setLoading(true);
|
try {
|
const requestParams = {
|
...queryParams,
|
...advancedParams,
|
...params,
|
page: currentPage,
|
size: 10,
|
sortColmn: 1,
|
sortType: 2,
|
keyword,
|
};
|
// 打印请求参数检查
|
console.log('请求参数:', requestParams);
|
const res = await registerHistoryApi(requestParams);
|
if (res.type) {
|
const { content, totalElements, totalPages, last } = res.data;
|
|
// 确保返回的数据不为空
|
const dataList = content || [];
|
|
if (currentPage === 1) {
|
// 第一页数据,直接设置
|
setListData(dataList);
|
} else {
|
// 加载更多数据
|
setListData((prev) => [...prev, ...dataList]);
|
}
|
|
setTotalCount(totalElements);
|
setHasMore(!last);
|
setPage(currentPage);
|
setQueryParams({ ...requestParams });
|
setHasSearched(true);
|
}
|
|
} catch (error) {
|
$$.infoError('获取数据失败,请稍后重试');
|
setHasSearched(true);
|
} finally {
|
setLoading(false);
|
}
|
};
|
|
// 搜索
|
const handleSearch = () => {
|
setPage(1);
|
fetchListData(1);
|
};
|
|
// 加载更多
|
const loadMoreData = () => {
|
if (loading || !hasMore) return;
|
fetchListData(page + 1);
|
};
|
|
// 打开筛选弹窗
|
const handleOpenFilter = () => {
|
setFilterVisible(true);
|
};
|
// 关闭筛选弹窗
|
const handleCloseFilter = () => {
|
setFilterVisible(false);
|
};
|
|
// 打开时间类型弹窗
|
const handleOpenDateTypeModal = (target) => {
|
setDateTypeTarget(target);
|
setDateTypeModalVisible(true);
|
};
|
|
// 重置筛选
|
const handleResetFilter = () => {
|
setAdvancedParams({
|
createStart: '',
|
createEnd: '',
|
caseType: '',
|
plaintiffs: '',
|
defendants: '',
|
canal: '',
|
status: '',
|
mediResult: '',
|
caseLevel: '',
|
});
|
};
|
|
|
// 新增:时间类型选择弹窗渲染
|
const renderDateTypeModal = () => (
|
<Modal
|
visible={dateTypeModalVisible}
|
onClose={() => setDateTypeModalVisible(false)}
|
className="date-type-modal"
|
position="bottom"
|
maskClosable={true}
|
popup
|
transparent={false}
|
>
|
<div className="modal-header">
|
<div className="modal-title">选择时间类型</div>
|
<span className="modal-close" onClick={() => setDateTypeModalVisible(false)}>
|
×
|
</span>
|
</div>
|
<div className="date-type-modal-content">
|
{dateTypeOptions.map((opt) => (
|
<div key={opt.value} className="date-type-modal-item" onClick={() => handleDateTypeSelect(opt.value)}>
|
{opt.label}
|
</div>
|
))}
|
</div>
|
</Modal>
|
);
|
|
// 新增:自定义时间选择弹窗渲染
|
const renderDatePickerModal = () => (
|
<Modal
|
visible={datePickerVisible}
|
onClose={() => setDatePickerVisible(false)}
|
className="date-picker-modal"
|
position="bottom"
|
maskClosable={true}
|
popup
|
transparent={false}
|
>
|
<div className="modal-header">
|
<div className="modal-title">选择日期范围</div>
|
<span className="modal-close" onClick={() => setDatePickerVisible(false)}>
|
×
|
</span>
|
</div>
|
<CalendarRangeTwoDay CalendaronClick={handleCalendarClick} onClickDate={handleDateChange} />
|
</Modal>
|
);
|
|
// 应用筛选
|
const handleApplyFilter = () => {
|
setPage(1);
|
fetchListData(1);
|
setFilterVisible(false);
|
};
|
// 处理日期选择
|
const handleOpenDatePicker = (type) => {
|
setCurrentDateType(type);
|
setDatePickerVisible(true);
|
};
|
const handleDateChange = (dates) => {
|
if (!dates || dates.length !== 2) return;
|
const formatDate = (date) => (date && date.key ? date.key : '');
|
const formattedStart = formatDate(dates[0]);
|
const formattedEnd = formatDate(dates[1]);
|
setAdvancedParams((prev) => ({
|
...prev,
|
createStart: currentDateType === 'create' ? formattedStart : prev.createStart,
|
createEnd: currentDateType === 'create' ? formattedEnd : prev.createEnd,
|
}));
|
setDatePickerVisible(false);
|
};
|
|
// 渲染列表项
|
const renderListItem = (item) => {
|
// 格式化时间
|
const formatTime = (time) => {
|
if (!time) return '';
|
const date = new Date(time);
|
const year = date.getFullYear();
|
const month = String(date.getMonth() + 1).padStart(2, '0');
|
const day = String(date.getDate()).padStart(2, '0');
|
const hour = String(date.getHours()).padStart(2, '0');
|
const min = String(date.getMinutes()).padStart(2, '0');
|
return `${year}-${month}-${day} ${hour}:${min}`;
|
};
|
// 化解结果样式
|
const getResultStyle = (result) => {
|
if (result === '化解成功') return 'registerhis-result-success';
|
if (result === '化解不成功') return 'registerhis-result-fail';
|
return '';
|
};
|
return (
|
<div className="registerhis-list-item" onClick={() => history.push(`/gzdyh/flow?caseTaskId=${item.caseTaskId}&caseId=${item.caseId}&editShow=true`)}>
|
<div className="registerhis-list-header">
|
<div className="registerhis-list-title">
|
<span>{item.plaintiffs}</span>
|
{item.defendants && <><span className="registerhis-list-separator">、</span><span>{item.defendants}</span></>}
|
<span className="registerhis-list-arrow">></span>
|
</div>
|
<div className="registerhis-list-status">{item.statusName}</div>
|
</div>
|
<div className="registerhis-list-content">
|
<div className="registerhis-list-row">
|
<div className="registerhis-list-label">登记时间</div>
|
<div className="registerhis-list-value">{formatTime(item.createTime)}</div>
|
</div>
|
<div className="registerhis-list-row">
|
<div className="registerhis-list-label">纠纷类型</div>
|
<div className="registerhis-list-value">{item.caseTypeName}</div>
|
</div>
|
<div className="registerhis-list-row">
|
<div className="registerhis-list-label">承办部门</div>
|
<div className="registerhis-list-value">{item.mediateUnitName}</div>
|
</div>
|
<div className="registerhis-list-row">
|
<div className="registerhis-list-label">事项编号</div>
|
<div className="registerhis-list-value">{item.caseTaskId}</div>
|
</div>
|
<div className="registerhis-list-row">
|
<div className="registerhis-list-label">化解结果</div>
|
<div className={`registerhis-list-value ${getResultStyle(item.mediResultName)}`}>{item.mediResultName}</div>
|
</div>
|
</div>
|
</div>
|
);
|
};
|
|
// 渲染无数据
|
const renderEmptyState = () => (
|
<div className="registerhis-empty-state">
|
<img src={require('../../assets/img/caseQuery_2.png')} alt="暂无数据" className="registerhis-empty-image" />
|
<div className="registerhis-empty-text">暂无数据</div>
|
</div>
|
);
|
|
// 渲染内容
|
const renderContent = () => {
|
if (loading && page === 1) {
|
return <div className="registerhis-loading"><div className="registerhis-loading-text">加载中...</div></div>;
|
}
|
if (hasSearched && listData.length === 0 && !loading) {
|
return renderEmptyState();
|
}
|
return (
|
<Scrollbars style={{ height: 'calc(100vh - 155px)' }}>
|
<MyList
|
data={listData}
|
dataTotal={totalCount}
|
hasMore={hasMore}
|
loadMore={loadMoreData}
|
itemDom={renderListItem}
|
threshold={100}
|
showBottomText={true}
|
/>
|
</Scrollbars>
|
);
|
};
|
|
// 筛选弹窗
|
const renderFilterModal = () => (
|
<Modal
|
visible={filterVisible}
|
onClose={handleCloseFilter}
|
className="registerhis-filter-modal"
|
position="bottom"
|
maskClosable={true}
|
popup
|
transparent={false}
|
>
|
<div className="registerhis-filter-content">
|
<div className="registerhis-filter-item">
|
<div className="registerhis-filter-label">登记时间</div>
|
<div className="registerhis-filter-selector" onClick={() => handleOpenDateTypeModal('create')}>
|
{advancedParams.createStart && advancedParams.createEnd
|
? <span style={{color: '#171A1D'}}>{`${advancedParams.createStart}-${advancedParams.createEnd}`}</span>
|
: '请选择'}
|
</div>
|
|
</div>
|
<div className="registerhis-filter-item">
|
<div className="registerhis-filter-label">纠纷类型</div>
|
<Picker
|
data={caseTypeSelect.caseTypeSelect}
|
cols={2}
|
cascade={true}
|
title="纠纷类型"
|
value={advancedParams.caseType ? [advancedParams.caseType] : []}
|
okText="确定"
|
onOk={valArr => {
|
const value = valArr.filter(Boolean).slice(-1)[0];
|
setAdvancedParams(prev => ({ ...prev, caseType: value }));
|
}}
|
>
|
<div className="registerhis-filter-selector">
|
{(() => {
|
let label = '';
|
caseTypeSelect.caseTypeSelect.forEach((item) => {
|
if (item.value === advancedParams.caseType) {
|
label = item.label;
|
} else if (item.children) {
|
const child = item.children.find((child) => child.value === advancedParams.caseType);
|
if (child) label = child.label;
|
}
|
});
|
return label || '请选择';
|
})()}
|
<div className="filter-arrow"></div>
|
</div>
|
</Picker>
|
|
</div>
|
|
<div className="registerhis-filter-item">
|
<div className="registerhis-filter-label">申请方</div>
|
<div className="registerhis-filter-input">
|
<InputItem
|
placeholder="请填写"
|
value={advancedParams.plaintiffs}
|
onChange={val => setAdvancedParams(prev => ({ ...prev, plaintiffs: val }))}
|
clear
|
/>
|
</div>
|
</div>
|
<div className="registerhis-filter-item">
|
<div className="registerhis-filter-label">被申请方</div>
|
<div className="registerhis-filter-input">
|
<InputItem
|
placeholder="请填写"
|
value={advancedParams.defendants}
|
onChange={val => setAdvancedParams(prev => ({ ...prev, defendants: val }))}
|
clear
|
/>
|
</div>
|
</div>
|
<div className="registerhis-filter-item">
|
<div className="registerhis-filter-label">事项来源</div>
|
<Picker
|
data={selectOption.caseCanal}
|
cols={1}
|
title="事项来源"
|
value={advancedParams.canal ? [advancedParams.canal] : []}
|
okText="确定"
|
onOk={valArr => setAdvancedParams(prev => ({ ...prev, canal: valArr[0] }))}
|
>
|
<div className="registerhis-filter-selector">
|
{selectOption.caseCanal.find(i => i.value === advancedParams.canal)?.label || '请选择'}
|
<div className="filter-arrow"></div>
|
</div>
|
</Picker>
|
</div>
|
<div className="registerhis-filter-item">
|
<div className="registerhis-filter-label">事项状态</div>
|
<Picker
|
data={selectOption.caseStatus}
|
cols={1}
|
title="事项状态"
|
value={advancedParams.status ? [advancedParams.status] : []}
|
okText="确定"
|
onOk={valArr => setAdvancedParams(prev => ({ ...prev, status: valArr[0] }))}
|
>
|
<div className="registerhis-filter-selector">
|
{selectOption.caseStatus.find(i => i.value === advancedParams.status)?.label || '请选择'}
|
<div className="filter-arrow"></div>
|
</div>
|
</Picker>
|
</div>
|
<div className="registerhis-filter-item">
|
<div className="registerhis-filter-label">事项等级</div>
|
<Picker
|
data={selectOption.caseLevelList}
|
cols={1}
|
title="事项等级"
|
value={advancedParams.caseLevel ? [advancedParams.caseLevel] : []}
|
okText="确定"
|
onOk={valArr => setAdvancedParams(prev => ({ ...prev, caseLevel: valArr[0] }))}
|
>
|
<div className="registerhis-filter-selector">
|
{selectOption.caseLevelList.find(i => i.value === advancedParams.caseLevel)?.label || '请选择'}
|
<div className="filter-arrow"></div>
|
</div>
|
</Picker>
|
</div>
|
<div className="registerhis-filter-item">
|
<div className="registerhis-filter-label">化解结果</div>
|
<Picker
|
data={selectOption.mediResult}
|
cols={1}
|
title="化解结果"
|
value={advancedParams.mediResult ? [advancedParams.mediResult] : []}
|
okText="确定"
|
onOk={valArr => setAdvancedParams(prev => ({ ...prev, mediResult: valArr[0] }))}
|
>
|
<div className="registerhis-filter-selector">
|
{selectOption.mediResult.find(i => i.value === advancedParams.mediResult)?.label || '请选择'}
|
<div className="filter-arrow"></div>
|
</div>
|
</Picker>
|
</div>
|
</div>
|
<div className="registerhis-filter-buttons">
|
<Button className="registerhis-filter-reset" onClick={handleResetFilter}>重置</Button>
|
<Button className="registerhis-filter-apply" type="primary" onClick={handleApplyFilter}>查询</Button>
|
</div>
|
{/* 日期选择弹窗 */}
|
<Modal
|
visible={datePickerVisible}
|
onClose={() => setDatePickerVisible(false)}
|
className="registerhis-date-picker-modal"
|
position="bottom"
|
maskClosable={true}
|
popup
|
transparent={false}
|
>
|
<div className="registerhis-modal-header">
|
<div className="registerhis-modal-title">选择日期范围</div>
|
<CloseOutlined className="registerhis-modal-close" onClick={() => setDatePickerVisible(false)} />
|
</div>
|
<CalendarRangeTwoDay CalendaronClick={() => setDatePickerVisible(false)} onClickDate={handleDateChange} />
|
</Modal>
|
</Modal>
|
);
|
|
// 页面加载自动请求一次
|
useEffect(() => {
|
fetchListData(1);
|
// eslint-disable-next-line
|
}, []);
|
|
return (
|
<NavBarPage title="登记历史" showBackArrow={true}>
|
<div className="registerhis-container">
|
<div className="registerhis-header">
|
<div className="registerhis-search">
|
<SearchOutlined style={{ color: '#bfc2cc', marginRight: 6, fontSize: 18 }} />
|
<InputItem
|
placeholder="申请方/被申请方/事项编号"
|
clear
|
maxLength={50}
|
value={keyword}
|
onChange={val => setKeyword(val)}
|
className="registerhis-search-input"
|
style={{ flex: 1, background: 'transparent', border: 'none', fontSize: 15 }}
|
/>
|
<button className="registerhis-action-btn" onClick={handleSearch}>查询</button>
|
</div>
|
<div className="registerhis-actions">
|
<button className="registerhis-action-btn" onClick={handleOpenFilter}>
|
<img src={workStatistics_5} alt="" className="registerhis-settings-icon" />
|
<span>更多</span>
|
</button>
|
</div>
|
</div>
|
{hasSearched && listData.length > 0 && (
|
<div className="registerhis-total-count">
|
共<span className="registerhis-total-count-number">{totalCount}</span>条记录
|
</div>
|
)}
|
<div className="registerhis-content">{renderContent()}</div>
|
{renderFilterModal()}
|
{renderDateTypeModal()}
|
{renderDatePickerModal()}
|
</div>
|
</NavBarPage>
|
);
|
};
|
|
export default RegisterHis;
|