/*
|
* @Company: hugeInfo
|
* @Author: lwh
|
* @Date: 2025-04-08 09:28:00
|
* @LastEditTime: 2025-04-15 11:12:35
|
* @LastEditors: lwh
|
* @Version: 1.0.0
|
* @Description: 督办催办组件
|
*/
|
import React, { useState, useEffect, useRef } from 'react';
|
import { useLocation, useHistory } from 'react-router-dom';
|
import { Tabs, Badge, Button, Modal, Empty, Toast, PullToRefresh } from 'dingtalk-design-mobile';
|
import { cbdb_1,caseQuery_2 } from '../../../../assets/img';
|
import { Scrollbars } from 'react-custom-scrollbars';
|
import * as $$ from '../../../../utils/utility';
|
import DingUpload from '../../../../components/DingUpload';
|
import './index.less';
|
|
// 获取督办列表数据API
|
function getSuperviseListApi(caseId, supStatus, page = 1, size = 10, type = 0) {
|
return $$.ax.request({
|
url: `caseSupervise/pageCaseSupervise?page=${page}&size=${size}&caseId=${caseId}&supStatus=${supStatus}&type=${type}`,
|
type: 'get',
|
service: 'mediate',
|
});
|
}
|
|
// 获取未回复督办数量API
|
function getUnreadSuperviseCountApi(caseId) {
|
return $$.ax.request({
|
url: `caseSupervise/pageCaseSupervise?page=1&size=1&caseId=${caseId}&supStatus=0&type=1`,
|
type: 'get',
|
service: 'mediate',
|
});
|
}
|
|
// 获取未回复催办数量API
|
function getUnreadUrgingCountApi(caseId) {
|
return $$.ax.request({
|
url: `caseUrging/pageQuery?page=1&size=1&caseId=${caseId}&urgingStatus=0`,
|
type: 'get',
|
service: 'mediate',
|
});
|
}
|
|
// 获取催办列表API
|
function getUrgingListApi(caseId, urgingStatus, page = 1, size = 10) {
|
// 使用新的催办列表接口
|
return $$.ax.request({
|
url: `caseUrging/pageQuery?page=${page}&size=${size}&caseId=${caseId}&urgingStatus=${urgingStatus}`,
|
type: 'get',
|
service: 'mediate',
|
});
|
}
|
|
// 日期格式化函数
|
function formatDateTime(dateString) {
|
if (!dateString) return '';
|
|
try {
|
let date;
|
if (dateString.includes('T')) {
|
// ISO格式: 2025-04-09T17:14:00
|
date = new Date(dateString);
|
} else if (dateString.includes('-')) {
|
// 普通格式: 2025-04-09 17:14
|
const [datePart, timePart] = dateString.split(' ');
|
const [year, month, day] = datePart.split('-');
|
const [hour, minute] = timePart.split(':');
|
date = new Date(year, parseInt(month) - 1, day, hour, minute);
|
} else {
|
return dateString;
|
}
|
|
const year = date.getFullYear();
|
const month = String(date.getMonth() + 1).padStart(2, '0');
|
const day = String(date.getDate()).padStart(2, '0');
|
const hours = String(date.getHours()).padStart(2, '0');
|
const minutes = String(date.getMinutes()).padStart(2, '0');
|
|
return `${year}-${month}-${day} ${hours}:${minutes}`;
|
} catch (error) {
|
console.error('日期格式化出错', error);
|
return dateString;
|
}
|
}
|
|
// 回复督办API
|
function replyCaseSuperviseApi(data) {
|
return $$.ax.request({
|
url: 'caseSupervise/replyCaseSupervise',
|
type: 'post',
|
data,
|
service: 'mediate',
|
});
|
}
|
|
// 回复催办API
|
function replyCaseUrgingApi(data) {
|
return $$.ax
|
.request({
|
url: 'caseUrging/replyCaseUrging',
|
type: 'post',
|
data,
|
service: 'mediate',
|
})
|
.catch((error) => {
|
console.error('催办回复API调用失败', error);
|
// 返回一个标准格式的错误响应,避免后续处理时出错
|
return { type: false, message: '网络异常,请稍后再试', code: -1 };
|
});
|
}
|
|
const Dbcb = () => {
|
const history = useHistory();
|
const location = useLocation();
|
const caseId = $$.getQueryString('caseId');
|
const scrollbarsRef = useRef(null);
|
|
const [activeType, setActiveType] = useState('supervision'); // 'supervision'督办 或 'urging'催办
|
const [activeStatus, setActiveStatus] = useState('unread'); // 'unread'未回复(0) 或 'read'已回复(1)
|
const [detailVisible, setDetailVisible] = useState(false);
|
const [currentDetail, setCurrentDetail] = useState(null);
|
const [currentItem, setCurrentItem] = useState(null);
|
|
// 回复相关状态
|
const [replyVisible, setReplyVisible] = useState(false);
|
const [replyContent, setReplyContent] = useState('');
|
const [attachments, setAttachments] = useState([]);
|
|
// 分页数据
|
const [supervisionList, setSupervisionList] = useState([]);
|
const [urgingList, setUrgingList] = useState([]);
|
const [loading, setLoading] = useState(false);
|
const [refreshing, setRefreshing] = useState(false);
|
const [hasMore, setHasMore] = useState(true);
|
const [page, setPage] = useState(1);
|
const [totalCount, setTotalCount] = useState(0);
|
const [totalPages, setTotalPages] = useState(1);
|
const [unreadSuperviseCount, setUnreadSuperviseCount] = useState(0);
|
const [unreadUrgingCount, setUnreadUrgingCount] = useState(0);
|
const isInitialMount = useRef(true);
|
|
// 初始化加载数据和未回复督办数量
|
useEffect(() => {
|
if (caseId) {
|
// 首次加载时,仅获取一次未回复督办数量和当前状态的列表数据
|
fetchData(1);
|
// fetchUnreadSuperviseCount();
|
// fetchUnreadUrgingCount();
|
isInitialMount.current = false;
|
}
|
}, [caseId]);
|
|
// 切换标签时加载对应的数据
|
useEffect(() => {
|
// 跳过首次加载,避免重复请求
|
if (!isInitialMount.current && caseId) {
|
fetchData(1);
|
}
|
}, [activeStatus]);
|
|
// 点击督办按钮时,重新获取未回复督办数量
|
useEffect(() => {
|
// 跳过首次加载,避免重复请求
|
if (!isInitialMount.current && caseId) {
|
if (activeType === 'supervision') {
|
fetchUnreadSuperviseCount();
|
} else {
|
fetchUnreadUrgingCount();
|
}
|
// 切换督办/催办时,重新加载列表数据
|
fetchData(1);
|
}
|
}, [activeType]);
|
|
// 获取未回复督办数量
|
const fetchUnreadSuperviseCount = async () => {
|
if (!caseId) return;
|
|
try {
|
const res = await getUnreadSuperviseCountApi(caseId);
|
if (res.type) {
|
setUnreadSuperviseCount(res.data.totalElements || 0);
|
}
|
} catch (error) {
|
console.error('获取未回复督办数量失败', error);
|
}
|
};
|
|
// 获取未回复催办数量
|
const fetchUnreadUrgingCount = async () => {
|
if (!caseId) return;
|
|
try {
|
const res = await getUnreadUrgingCountApi(caseId);
|
if (res.type) {
|
setUnreadUrgingCount(res.data.totalElements || 0);
|
}
|
} catch (error) {
|
console.error('获取未回复催办数量失败', error);
|
}
|
};
|
|
// 获取数据
|
const fetchData = async (currentPage, preservePosition = false) => {
|
if (!caseId) return;
|
|
if (!preservePosition) {
|
setLoading(true);
|
} else {
|
// 记录当前滚动位置
|
const currentScrollTop = scrollbarsRef.current?.getScrollTop() || 0;
|
setLoading(true);
|
|
// 数据加载后恢复滚动位置
|
const restoreScrollPosition = () => {
|
if (scrollbarsRef.current) {
|
setTimeout(() => {
|
scrollbarsRef.current.scrollTop(currentScrollTop);
|
}, 0);
|
}
|
};
|
|
// 使用Promise.finally来确保在数据加载后恢复滚动位置
|
setTimeout(() => restoreScrollPosition(), 100);
|
}
|
|
try {
|
const supStatus = activeStatus === 'unread' ? 0 : 1;
|
let res;
|
|
if (activeType === 'supervision') {
|
res = await getSuperviseListApi(caseId, supStatus, currentPage, 10, 1);
|
} else {
|
res = await getUrgingListApi(caseId, supStatus, currentPage, 10);
|
}
|
|
if (res.type) {
|
const { content, totalElements, totalPages, last } = res.data;
|
|
// 确保返回的数据不为空
|
const dataList = content || [];
|
|
if (currentPage === 1) {
|
// 第一页数据,直接设置
|
if (activeType === 'supervision') {
|
setSupervisionList(dataList);
|
} else {
|
setUrgingList(dataList);
|
}
|
} else {
|
// 加载更多数据,需要过滤掉已有的数据
|
if (activeType === 'supervision') {
|
// 获取已有数据的ID集合
|
const existingIds = new Set(supervisionList.map((item) => item.id));
|
// 过滤掉已有的数据
|
const newItems = dataList.filter((item) => !existingIds.has(item.id));
|
// 合并新数据
|
setSupervisionList((prev) => [...prev, ...newItems]);
|
} else {
|
// 获取已有数据的ID集合
|
const existingIds = new Set(urgingList.map((item) => item.id));
|
// 过滤掉已有的数据
|
const newItems = dataList.filter((item) => !existingIds.has(item.id));
|
// 合并新数据
|
setUrgingList((prev) => [...prev, ...newItems]);
|
}
|
}
|
|
setTotalCount(totalElements);
|
setTotalPages(totalPages);
|
setHasMore(!last);
|
setPage(currentPage);
|
}
|
} catch (error) {
|
console.error('获取数据失败', error);
|
$$.showToast({ content: '获取数据失败,请稍后重试' });
|
} finally {
|
setLoading(false);
|
setRefreshing(false);
|
}
|
};
|
|
// 下拉刷新
|
const handleRefresh = () => {
|
setRefreshing(true);
|
fetchData(1);
|
};
|
|
// 加载更多
|
const loadMoreData = () => {
|
if (loading || !hasMore) return;
|
fetchData(page + 1, true); // 传入true表示保持滚动位置
|
};
|
|
// 获取列表数据
|
const getListData = () => {
|
if (activeType === 'supervision') {
|
return supervisionList;
|
} else {
|
return urgingList;
|
}
|
};
|
|
// 查看详情
|
const handleViewDetail = (item) => {
|
setCurrentItem(item);
|
// 这里可以根据实际情况调用API获取详情
|
if (activeType === 'supervision') {
|
if (activeStatus === 'unread') {
|
setCurrentDetail({
|
supervisionTime: item.supTime,
|
supervisionPerson: `${item.supUserName} (${item.supUnitName})`,
|
supervisionContent: item.supContent,
|
// 处理督办附件,只保留ownerType=22_00018-506的
|
attachments: (item.fileInfoList || []).filter((file) => file.ownerType === '22_00018-506'),
|
});
|
} else {
|
setCurrentDetail({
|
supervisionTime: item.supTime,
|
supervisionPerson: `${item.supUserName} (${item.supUnitName})`,
|
supervisionContent: item.supContent,
|
replyTime: item.replyTime,
|
replyPerson: `${item.replyUserName} (${item.quiltUnitName})`,
|
replyContent: item.replyContent,
|
// 处理督办附件,只保留ownerType=22_00018-506的
|
attachments: (item.fileInfoList || []).filter((file) => file.ownerType === '22_00018-506'),
|
// 处理回复附件,只保留ownerType=22_00018-507的
|
replyAttachments: (item.replyFileInfoList || []).filter((file) => file.ownerType === '22_00018-507'),
|
});
|
}
|
} else if (activeType === 'urging') {
|
if (activeStatus === 'unread') {
|
setCurrentDetail({
|
urgingTime: item.urgingTime,
|
urgingPerson: `${item.urgingUserName} (${item.urgingUnitName})`,
|
urgingContent: item.supContent,
|
// 处理催办附件,只保留ownerType=22_00018-506的
|
attachments: (item.fileInfoList || []).filter((file) => file.ownerType === '22_00018-506'),
|
});
|
} else {
|
setCurrentDetail({
|
urgingTime: item.urgingTime,
|
urgingPerson: `${item.urgingUserName} (${item.urgingUnitName})`,
|
urgingContent: item.supContent,
|
replyTime: item.replyTime,
|
replyPerson: `${item.replyUserName} (${item.quiltUnitName})`,
|
replyContent: item.replyContent,
|
// 处理催办附件,只保留ownerType=22_00018-506的
|
attachments: (item.fileInfoList || []).filter((file) => file.ownerType === '22_00018-506'),
|
// 处理回复附件,只保留ownerType=22_00018-507的
|
replyAttachments: (item.replyFileInfoList || []).filter((file) => file.ownerType === '22_00018-507'),
|
});
|
}
|
}
|
setDetailVisible(true);
|
};
|
|
// 回复督办
|
const handleReply = (item) => {
|
// 设置当前选中的督办项
|
setCurrentItem(item);
|
// 清空回复内容和附件
|
setReplyContent('');
|
setAttachments([]);
|
// 打开回复弹窗
|
setReplyVisible(true);
|
};
|
|
// 关闭详情弹窗
|
const handleCloseDetail = () => {
|
setDetailVisible(false);
|
setCurrentDetail(null);
|
setCurrentItem(null);
|
};
|
|
// 关闭回复弹窗
|
const handleCloseReply = () => {
|
setReplyVisible(false);
|
setReplyContent('');
|
setAttachments([]);
|
};
|
|
// 提交回复
|
const handleSubmitReply = async () => {
|
const requestData = {
|
id: currentItem.id,
|
caseId: caseId,
|
replyContent: replyContent,
|
};
|
if (!replyContent.trim()) {
|
$$.showToast({ content: '请填写' });
|
return;
|
}
|
global.setSpinning(true);
|
|
let res;
|
if (activeType === 'supervision') {
|
// 调用督办回复接口
|
res = await replyCaseSuperviseApi(requestData);
|
} else {
|
// 调用催办回复接口
|
res = await replyCaseUrgingApi(requestData);
|
}
|
|
global.setSpinning(false);
|
if (res.type) {
|
// 关闭回复弹窗
|
setReplyVisible(false);
|
// 清空回复内容和附件
|
setReplyContent('');
|
setAttachments([]);
|
// 刷新列表数据
|
fetchData(1); // 刷新列表
|
// 如果是从未回复列表回复的,那么需要更新未回复数量
|
if (activeStatus === 'unread') {
|
if (activeType === 'supervision') {
|
fetchUnreadSuperviseCount();
|
} else {
|
fetchUnreadUrgingCount();
|
}
|
}
|
// 提示用户回复成功
|
$$.showToast({ content: '回复成功' });
|
}
|
};
|
|
// 使用模板
|
const handleUseTemplate = () => {
|
setReplyContent('双方当事人于xx时间xx地址已达成xx协议,纠纷已化解。');
|
};
|
|
// OCR识别材料
|
const handleOcrRecognize = () => {
|
// 实际项目中应当调用OCR识别API或文件上传API
|
Toast.show({
|
content: '正在识别材料...',
|
position: 'bottom',
|
});
|
|
// 模拟识别结果
|
setTimeout(() => {
|
setReplyContent(replyContent + (replyContent ? '\n\n' : '') + '通过识别,确认双方当事人已达成和解协议,纠纷已妥善处理。');
|
Toast.show({
|
content: '识别完成',
|
position: 'bottom',
|
});
|
}, 1000);
|
};
|
|
// 渲染主要内容区域
|
const renderContent = () => {
|
const listData = getListData();
|
|
if (loading && page === 1) {
|
return (
|
<div className="dbcb-loading">
|
<div className="dbcb-loading-text">加载中...</div>
|
</div>
|
);
|
}
|
|
if (!loading && listData.length === 0) {
|
return (
|
<div className="dbcb-empty-state">
|
<img src={caseQuery_2} alt="暂无数据" className="dbcb-empty-image" />
|
<div className="dbcb-empty-text">暂无数据</div>
|
{/* <Empty description="暂无数据" /> */}
|
</div>
|
);
|
}
|
|
// 检查是否超时或即将超时的函数
|
const checkTimeout = (item) => {
|
if (!item.supTime) return { isTimeout: false, isAboutToTimeout: false };
|
|
try {
|
// 解析督办时间,处理不同格式的日期
|
let supTime;
|
if (item.supTime.includes('T')) {
|
// ISO格式: 2025-04-09T17:14:00
|
supTime = new Date(item.supTime);
|
} else if (item.supTime.includes('-')) {
|
// 普通格式: 2025-04-09 17:14
|
const [datePart, timePart] = item.supTime.split(' ');
|
const [year, month, day] = datePart.split('-');
|
const [hour, minute] = timePart.split(':');
|
supTime = new Date(year, parseInt(month) - 1, day, hour, minute);
|
} else {
|
// 无法解析的格式
|
return { isTimeout: false, isAboutToTimeout: false };
|
}
|
|
const now = new Date();
|
const diffHours = Math.floor((now - supTime) / (1000 * 60 * 60));
|
|
return {
|
isTimeout: diffHours >= 12,
|
isAboutToTimeout: diffHours >= 11 && diffHours < 12,
|
};
|
} catch (error) {
|
console.error('解析日期时间出错', error);
|
return { isTimeout: false, isAboutToTimeout: false };
|
}
|
};
|
|
console.log('dbcb');
|
|
return (
|
<div className="dbcb-list">
|
{listData.map((item) => {
|
const { isTimeout, isAboutToTimeout } = activeStatus === 'unread' ? checkTimeout(item) : { isTimeout: false, isAboutToTimeout: false };
|
|
return (
|
<div className="dbcb-item" key={item.id}>
|
<div className="dbcb-item-header">
|
<div className="dbcb-item-unit-container">
|
{activeType === 'supervision' ? (
|
<div className="dbcb-item-unit">{item.supUnitName}</div>
|
) : (
|
<div className="dbcb-item-unit">当事人{item.urgingUserName}向你发出了一条催办提醒</div>
|
)}
|
{activeStatus === 'unread' && activeType === 'supervision' && (
|
<>
|
{isTimeout && <div className="dbcb-item-timeout">已超时</div>}
|
{isAboutToTimeout && <div className="dbcb-item-about-to-timeout">即将超时</div>}
|
</>
|
)}
|
</div>
|
</div>
|
{activeType === 'supervision' && <div className="dbcb-item-content">{item.supContent}</div>}
|
<div className="dbcb-item-footer">
|
{activeStatus === 'unread' ? (
|
<>
|
<div className="dbcb-item-time">
|
{activeType === 'supervision' ? `督办时间:${item.supTime}` : `催办时间:${formatDateTime(item.urgingTime)}`}
|
</div>
|
<div className="dbcb-item-actions">
|
<Button className="dbcb-item-btn dbcb-item-detail-btn" size="small" onClick={() => handleViewDetail(item)}>
|
详情
|
</Button>
|
<Button className="dbcb-item-btn dbcb-item-reply-btn" size="small" type="primary" onClick={() => handleReply(item)}>
|
回复
|
</Button>
|
</div>
|
</>
|
) : (
|
<>
|
<div className="dbcb-item-time">
|
{activeType === 'supervision' ? `回复时间:${item.replyTime}` : `回复时间:${formatDateTime(item.replyTime)}`}
|
</div>
|
<div className="dbcb-item-actions">
|
<Button className="dbcb-item-btn dbcb-item-detail-btn" size="small" onClick={() => handleViewDetail(item)}>
|
详情
|
</Button>
|
</div>
|
</>
|
)}
|
</div>
|
</div>
|
);
|
})}
|
|
{loading && page > 1 && <div className="dbcb-loading-more">加载更多...</div>}
|
|
{!hasMore && listData.length > 0 && <div className="dbcb-no-more">已加载全部</div>}
|
</div>
|
);
|
};
|
|
// 渲染详情弹窗
|
const renderDetailDialog = () => {
|
if (!currentDetail) return null;
|
|
// 检查当前项是否超时或即将超时
|
const getTimeoutStatus = (item) => {
|
if (activeStatus !== 'unread' || !item || !item.supTime) return null;
|
|
try {
|
// 解析督办时间,处理不同格式的日期
|
let supTime;
|
if (item.supTime.includes('T')) {
|
// ISO格式: 2025-04-09T17:14:00
|
supTime = new Date(item.supTime);
|
} else if (item.supTime.includes('-')) {
|
// 普通格式: 2025-04-09 17:14
|
const [datePart, timePart] = item.supTime.split(' ');
|
const [year, month, day] = datePart.split('-');
|
const [hour, minute] = timePart.split(':');
|
supTime = new Date(year, parseInt(month) - 1, day, hour, minute);
|
} else {
|
// 无法解析的格式
|
return null;
|
}
|
|
const now = new Date();
|
const diffHours = Math.floor((now - supTime) / (1000 * 60 * 60));
|
|
if (diffHours >= 12) {
|
return <span style={{ color: '#FF4D4F' }}>已超时</span>;
|
} else if (diffHours >= 11 && diffHours < 12) {
|
return <span style={{ color: '#FAAD14' }}>即将超时</span>;
|
}
|
return null;
|
} catch (error) {
|
console.error('解析日期时间出错', error);
|
return null;
|
}
|
};
|
|
const timeoutStatus = getTimeoutStatus(currentItem);
|
|
return (
|
<Modal
|
visible={detailVisible}
|
onClose={handleCloseDetail}
|
title={
|
<div className="dbcb-detail-header">
|
<div className="dbcb-detail-title">
|
{activeType === 'supervision'
|
? activeStatus === 'unread'
|
? '督办详情'
|
: '督办回复详情'
|
: activeStatus === 'unread'
|
? '催办详情'
|
: '催办回复详情'}
|
</div>
|
<div className="dbcb-detail-timeout-status">{timeoutStatus}</div>
|
</div>
|
}
|
className="dbcb-detail-dialog"
|
maskClosable={true}
|
closable={true}
|
position="bottom"
|
>
|
<div className="dbcb-detail-content">
|
<div className="dbcb-detail-section">
|
<div className="dbcb-detail-label">{activeType === 'supervision' ? '督办时间' : '催办时间'}</div>
|
<div className="dbcb-detail-value">
|
{activeType === 'supervision' ? currentDetail.supervisionTime : formatDateTime(currentDetail.urgingTime)}
|
</div>
|
</div>
|
|
<div className="dbcb-detail-section">
|
<div className="dbcb-detail-label">{activeType === 'supervision' ? '督办人' : '催办人'}</div>
|
<div className="dbcb-detail-value">
|
{
|
activeType === 'supervision' ? currentDetail.supervisionPerson : currentDetail.urgingPerson.split(' ')[0] // 只取人名,不显示单位
|
}
|
</div>
|
</div>
|
|
{activeType === 'supervision' && (
|
<div className="dbcb-detail-section">
|
<div className="dbcb-detail-label">督办内容</div>
|
<div className="dbcb-detail-value">{currentDetail.supervisionContent}</div>
|
</div>
|
)}
|
|
{currentDetail.attachments && currentDetail.attachments.length > 0 && (
|
<div className="dbcb-detail-section">
|
<DingUpload
|
fileList={currentDetail.attachments.map((file) => ({
|
id: file.id || Date.now().toString(),
|
name: file.name || '附件',
|
size: file.size || '0KB',
|
showUrl: file.url || '',
|
}))}
|
viewOnly={true}
|
title={activeType === 'supervision' ? '督办附件' : '催办附件'}
|
/>
|
</div>
|
)}
|
|
{/* 已回复详情的额外信息 */}
|
{activeStatus === 'read' && (
|
<>
|
<div className="dbcb-detail-section">
|
<div className="dbcb-detail-label">回复时间</div>
|
<div className="dbcb-detail-value">{currentDetail.replyTime}</div>
|
</div>
|
|
<div className="dbcb-detail-section">
|
<div className="dbcb-detail-label">回复人</div>
|
<div className="dbcb-detail-value">{currentDetail.replyPerson}</div>
|
</div>
|
|
<div className="dbcb-detail-section">
|
<div className="dbcb-detail-label">回复内容</div>
|
<div className="dbcb-detail-value">{currentDetail.replyContent}</div>
|
</div>
|
|
{currentDetail.replyAttachments && currentDetail.replyAttachments.length > 0 && (
|
<div className="dbcb-detail-section">
|
<div className="dbcb-detail-label">回复附件</div>
|
<DingUpload
|
fileList={currentDetail.replyAttachments.map((file) => ({
|
id: file.id || Date.now().toString(),
|
name: file.name || '附件',
|
size: file.size || '0KB',
|
showUrl: file.url || '',
|
}))}
|
viewOnly={true}
|
title="回复附件"
|
/>
|
</div>
|
)}
|
</>
|
)}
|
</div>
|
|
{activeStatus === 'unread' && (
|
<div className="dbcb-detail-footer">
|
<Button
|
type="primary"
|
className="dbcb-detail-reply-btn"
|
onClick={() => {
|
// 关闭详情弹窗,打开回复弹窗
|
setDetailVisible(false);
|
// 延迟一点打开回复弹窗,避免两个弹窗切换过快
|
setTimeout(() => {
|
if (currentItem) {
|
handleReply(currentItem);
|
}
|
}, 300);
|
}}
|
>
|
回复
|
</Button>
|
</div>
|
)}
|
|
{activeStatus === 'read' && (
|
<div className="dbcb-detail-footer">
|
<Button type="primary" className="dbcb-detail-close-btn" onClick={handleCloseDetail}>
|
关闭
|
</Button>
|
</div>
|
)}
|
</Modal>
|
);
|
};
|
|
// 渲染回复弹窗
|
const renderReplyModal = () => {
|
if (!currentItem) return null;
|
|
return (
|
<Modal
|
visible={replyVisible}
|
onClose={handleCloseReply}
|
title={
|
<div className="dbcb-reply-header">
|
<div className="dbcb-reply-title">{activeType === 'supervision' ? '督办回复' : '催办回复'}</div>
|
<div className="dbcb-reply-close-btn" onClick={handleCloseReply}>
|
<img src={cbdb_1} width={20} height={20} alt="关闭" />
|
</div>
|
</div>
|
}
|
className="dbcb-detail-dialog dbcb-reply-dialog"
|
maskClosable={true}
|
closable={false}
|
position="bottom"
|
>
|
<div className="dbcb-reply-wrapper">
|
<div className="dbcb-reply-content">
|
{/* 督办详情信息 */}
|
<div className="dbcb-reply-detail">
|
<div className="dbcb-reply-section">
|
<div className="dbcb-reply-label">{activeType === 'supervision' ? '督办时间' : '催办时间'}</div>
|
<div className="dbcb-reply-value">{activeType === 'supervision' ? currentItem.supTime : formatDateTime(currentItem.urgingTime)}</div>
|
</div>
|
|
<div className="dbcb-reply-section">
|
<div className="dbcb-reply-label">{activeType === 'supervision' ? '督办人' : '催办人'}</div>
|
<div className="dbcb-reply-value">
|
{activeType === 'supervision'
|
? `${currentItem.supUserName} (${currentItem.supUnitName}) ${currentItem.supUserPhone || ''}`
|
: `${currentItem.urgingUserName}`}
|
</div>
|
</div>
|
|
{activeType === 'supervision' && (
|
<div className="dbcb-reply-section">
|
<div className="dbcb-reply-label">督办内容</div>
|
<div className="dbcb-reply-value">{currentItem.supContent}</div>
|
</div>
|
)}
|
|
{activeType === 'supervision' &&
|
currentItem.fileInfoList &&
|
currentItem.fileInfoList.filter((file) => file.ownerType === '22_00018-506').length > 0 && (
|
<div className="dbcb-reply-section">
|
<div className="dbcb-reply-label">督办附件</div>
|
<DingUpload
|
fileList={(currentItem.fileInfoList || [])
|
.filter((file) => file.ownerType === '22_00018-506')
|
.map((file) => ({
|
id: file.id || Date.now().toString(),
|
name: file.name || '附件',
|
size: file.size || '12.3K',
|
showUrl: file.url || '',
|
}))}
|
viewOnly={true}
|
title="督办附件"
|
/>
|
</div>
|
)}
|
|
{activeType === 'urging' && currentItem.fileInfoList && currentItem.fileInfoList.length > 0 && (
|
<div className="dbcb-reply-section">
|
<div className="dbcb-reply-label">催办附件</div>
|
<DingUpload
|
fileList={(currentItem.fileInfoList || []).map((file) => ({
|
id: file.id || Date.now().toString(),
|
name: file.name || '附件',
|
size: file.size || '12.3K',
|
showUrl: file.url || '',
|
}))}
|
viewOnly={true}
|
title="催办附件"
|
/>
|
</div>
|
)}
|
</div>
|
|
{/* 回复内容区域 */}
|
<div className="dbcb-reply-section">
|
<div className="dbcb-reply-label">
|
<span className="dbcb-reply-label-text">回复内容</span>
|
<div className="dbcb-reply-btn-group">
|
{/* <div className="dbcb-reply-ocr-btn" onClick={handleOcrRecognize}>
|
<svg viewBox="0 0 1024 1024" width="20" height="20">
|
<path
|
d="M832 128H192c-35.2 0-64 28.8-64 64v640c0 35.2 28.8 64 64 64h640c35.2 0 64-28.8 64-64V192c0-35.2-28.8-64-64-64z m0 704H192V192h640v640z"
|
fill="#1A6FB8"
|
></path>
|
<path
|
d="M696.9 298.1H584.1c-12.3 0-22.3 10-22.3 22.3s10 22.3 22.3 22.3h69l-155.8 155.8c-8.7 8.7-8.7 22.8 0 31.5 4.4 4.4 10.1 6.5 15.7 6.5s11.4-2.2 15.7-6.5l155.8-155.8v69c0 12.3 10 22.3 22.3 22.3s22.3-10 22.3-22.3V320.4c0.1-12.3-9.9-22.3-22.2-22.3z"
|
fill="#1A6FB8"
|
></path>
|
<path
|
d="M428.5 685.5c4.4 4.4 10.1 6.5 15.7 6.5s11.4-2.2 15.7-6.5c8.7-8.7 8.7-22.8 0-31.5L303.2 497.3v-69c0-12.3-10-22.3-22.3-22.3s-22.3 10-22.3 22.3v112.8c0 12.3 10 22.3 22.3 22.3h112.8c12.3 0 22.3-10 22.3-22.3s-10-22.3-22.3-22.3h-69L428.5 654c8.6 8.7 8.6 22.8 0 31.5z"
|
fill="#1A6FB8"
|
></path>
|
</svg>
|
识别材料
|
</div> */}
|
<div
|
className="dbcb-reply-template-btn"
|
onClick={() =>
|
setReplyContent(
|
activeType === 'supervision' ? '双方当事人于xx时间xx地址已达成xx协议,纠纷已化解。' : '已认真制定方案,并同当事人进行了沟通'
|
)
|
}
|
>
|
<svg viewBox="0 0 1024 1024" width="20" height="20">
|
<path
|
d="M832 64H192C121.6 64 64 121.6 64 192v640c0 70.4 57.6 128 128 128h640c70.4 0 128-57.6 128-128V192c0-70.4-57.6-128-128-128zM192 128h640c35.2 0 64 28.8 64 64v256h-768V192c0-35.2 28.8-64 64-64z m640 768H192c-35.2 0-64-28.8-64-64V512h768v320c0 35.2-28.8 64-64 64z"
|
fill="#1A6FB8"
|
></path>
|
<path d="M672 320H544V192h128v128zM672 832H544V704h128v128z" fill="#1A6FB8"></path>
|
</svg>
|
选择模板
|
</div>
|
</div>
|
</div>
|
<textarea
|
className="dbcb-reply-textarea"
|
placeholder="请填写"
|
value={replyContent}
|
onChange={(e) => setReplyContent(e.target.value)}
|
rows={5}
|
></textarea>
|
</div>
|
|
{/* 附件区域 */}
|
<div className="dbcb-reply-section">
|
<DingUpload
|
fileList={attachments}
|
onChange={(info) => {
|
if (info.fileList) {
|
setAttachments(info.fileList);
|
}
|
}}
|
ownerId={currentItem.id}
|
ownerType={activeType === 'supervision' ? '22_00018-507' : '23_00018-507'}
|
disabled={false}
|
viewOnly={false}
|
accept="image/*, .pdf, .doc, .docx, .xls, .xlsx, .ppt, .pptx, .txt"
|
tipText="支持扩展名:.doc .docx .pdf .jpg 等,30M以内"
|
btnText="添加附件"
|
subtitle="请上传与内容相关的附件材料"
|
title="附件材料"
|
/>
|
</div>
|
</div>
|
|
{/* 底部按钮 */}
|
<div className="dbcb-reply-footer">
|
<Button type="primary" className="dbcb-reply-submit-btn" onClick={handleSubmitReply}>
|
提交
|
</Button>
|
</div>
|
</div>
|
</Modal>
|
);
|
};
|
|
return (
|
<div className="dbcb-container">
|
{/* 督办/催办切换 */}
|
<div className="dbcb-type-tabs">
|
<div className={`dbcb-type-tab ${activeType === 'supervision' ? 'dbcb-type-tab-active' : ''}`} onClick={() => setActiveType('supervision')}>
|
督办({unreadSuperviseCount || 0})
|
</div>
|
<div className={`dbcb-type-tab ${activeType === 'urging' ? 'dbcb-type-tab-active' : ''}`} onClick={() => setActiveType('urging')}>
|
催办({unreadUrgingCount || 0})
|
</div>
|
</div>
|
|
{/* 未回复/已回复切换 */}
|
<div className="dbcb-status-tabs">
|
<div className={`dbcb-status-tab ${activeStatus === 'unread' ? 'dbcb-status-tab-active' : ''}`} onClick={() => setActiveStatus('unread')}>
|
未回复
|
</div>
|
<div className={`dbcb-status-tab ${activeStatus === 'read' ? 'dbcb-status-tab-active' : ''}`} onClick={() => setActiveStatus('read')}>
|
已回复
|
</div>
|
</div>
|
|
{/* 内容区域 */}
|
<PullToRefresh onRefresh={handleRefresh} refreshing={refreshing}>
|
<Scrollbars
|
ref={scrollbarsRef}
|
style={{ height: 'calc(100vh - 206px)' }}
|
autoHide
|
onScroll={(e) => {
|
// 滚动到底部加载更多数据
|
const { scrollTop, scrollHeight, clientHeight } = e.target;
|
if (scrollHeight - scrollTop - clientHeight < 50 && !loading && hasMore) {
|
loadMoreData();
|
}
|
}}
|
>
|
{renderContent()}
|
</Scrollbars>
|
</PullToRefresh>
|
|
{/* 详情弹窗 */}
|
{renderDetailDialog()}
|
|
{/* 回复弹窗 */}
|
{renderReplyModal()}
|
</div>
|
);
|
};
|
|
export default Dbcb;
|