/*
|
* @Company: hugeInfo
|
* @Author: ldh
|
* @Date: 2022-07-27 15:27:24
|
* @LastEditTime: 2022-12-05 11:58:20
|
* @LastEditors: ldh
|
* @Version: 1.0.0
|
* @Description: 司法确认视窗
|
*/
|
import React, { useState, useEffect } from 'react';
|
import { useSearchParams, useNavigate } from 'react-router-dom';
|
import { Tooltip, Popconfirm, Space, Popover, Descriptions, Typography, Button, Dropdown, Menu } from 'antd';
|
import { LeftOutlined, QrcodeOutlined, CloseCircleOutlined, ProfileOutlined, CheckCircleFilled } from '@ant-design/icons';
|
import * as $$ from '../../utils/utility';
|
import timer from '../../utils/timer';
|
import { MediateDynamic, ActionModal } from './component';
|
import Page from '../../components/Page';
|
import NameCard from '../../components/NameCard';
|
import FilesDrawer from '../../components/FilesDrawer';
|
import {
|
documentMaking,
|
documentMaking_active,
|
mediationSetting,
|
mediationSetting_active,
|
mediationMsg,
|
mediationMsg_active,
|
startJudicial,
|
funnel,
|
clock,
|
clock_active,
|
camera,
|
End,
|
applyMsg,
|
applyMsg_active,
|
promptArrow,
|
judicialWindow_fileBox,
|
} from '../../assets/images/icon';
|
import MyModal from '../../components/MyModal';
|
|
const { Text } = Typography;
|
|
// 获取司法确认案件数据
|
function getJudicialDataApi(submitData) {
|
return $$.ax.request({ url: `judicInfo/pcWindowCaseInfo?id=${submitData}`, type: 'get', service: 'mediate' });
|
}
|
|
// 获取任务信息
|
function getTaskInfoApi(taskId) {
|
return $$.ax.request({ url: 'judicTask/getTaskInfo?taskId=' + taskId, type: 'get', service: 'mediate' });
|
}
|
|
// 开始司法确认
|
function startMediationApi(submitData) {
|
return $$.ax.request({ url: `judicInfo/pcWindowStartJudic`, type: 'post', service: 'mediate', data: submitData });
|
}
|
|
const JudicialWindow = () => {
|
const [searchParams] = useSearchParams();
|
|
const navigate = useNavigate();
|
|
const back = searchParams.get('back');
|
|
const caseId = searchParams.get('caseId');
|
|
const judicialId = searchParams.get('judicialId');
|
|
const taskId = searchParams.get('taskId');
|
|
// 纠纷案件数据
|
const [disputeData, setDisputeData] = useState({});
|
|
// 司法确认开始时间
|
const [judicialStartTime, setJudicialStartTime] = useState();
|
|
// 预约时间提醒
|
const [orderVisible, setOrderVisible] = useState(false);
|
|
// 语音转文字是否开启
|
const [voiceVisible, setVoiceVisible] = useState(false);
|
|
// 任务信息是否查看
|
const [task, setTask] = useState({ visible: false });
|
|
// 操作modal
|
const [modal, setModal] = useState({ visible: null });
|
|
// 司法确认开始提示显示
|
const [successVisible, setSuccessVisible] = useState(false);
|
|
// 人民调解协议书选择下标
|
const [docxIndex, setDocxIndex] = useState(0);
|
|
// 底部操作数据
|
const operation = [
|
{ icon: documentMaking, iconActive: documentMaking_active, title: '文书制作', actionType: 'documentMaking' },
|
{ icon: applyMsg, iconActive: applyMsg_active, title: '申请信息', actionType: 'applyMsg' },
|
{ icon: startJudicial, iconActive: funnel, title: '开始确认', actionType: 'mediationStart' },
|
{ icon: mediationMsg, iconActive: mediationMsg_active, title: '案件信息', actionType: 'caseCheck' },
|
{ icon: mediationSetting, iconActive: mediationSetting_active, title: '其他功能', actionType: 'setting' },
|
];
|
|
// 底部操作区和左侧card点击
|
function handleClickBottomAction(type) {
|
let visible = modal.actionType === type ? !modal.visible : true;
|
setModal({ visible, actionType: visible ? type : '' });
|
}
|
|
// 左侧底部操作区点击
|
function handleClickLeftAction(type) {
|
if (type === '1') {
|
// 预约司法确认
|
let visible = modal.actionType === type ? !modal.visible : true;
|
setModal({ visible, actionType: visible ? 'orderMediation' : '' });
|
}
|
if (type === '3') {
|
// 开启视频会议
|
window.open(disputeData.meetCloud.pcJoinUrl);
|
}
|
}
|
|
// 调解开始后回调
|
function onStartMediation() {
|
setSuccessVisible(true);
|
setJudicialStartTime(new Date());
|
}
|
|
// 开始调解
|
async function handleStartMediate(type) {
|
let meetInfo = disputeData.meetInfo;
|
if (
|
meetInfo &&
|
$$.timeFormat(meetInfo.orderStartTime) <= $$.timeFormat(new Date()) &&
|
$$.timeFormat(meetInfo.orderEndTime) >= $$.timeFormat(new Date())
|
) {
|
// 在预约时间内立即开始
|
global.setSpinning(true);
|
const res = await startMediationApi({ caseId, startType: '1' });
|
global.setSpinning(false);
|
if (res.type) {
|
onStartMediation();
|
}
|
return;
|
}
|
// 预约时间外则打开modal
|
handleClickBottomAction(type);
|
}
|
|
// 获取纠纷信息
|
async function getDisputeData(isNoLoading) {
|
if (!isNoLoading) global.setSpinning(true);
|
const res = await getJudicialDataApi(caseId);
|
global.setSpinning(false, 'only');
|
if (res.type) {
|
setDisputeData(res.data || {});
|
if (res.data?.judicStartTime) {
|
setJudicialStartTime($$.timeFormat(res.data?.judicStartTime, 'isValue'));
|
}
|
}
|
}
|
|
// 获取任务信息
|
async function getTaskInfo() {
|
if (task.visible) {
|
setTask({ visible: false });
|
return;
|
}
|
global.setSpinning(true);
|
const res = await getTaskInfoApi(taskId);
|
global.setSpinning(false);
|
if (res.type) {
|
setTask({ visible: true, contentData: res.data || {} });
|
}
|
}
|
|
// 初始化
|
useEffect(() => {
|
getDisputeData();
|
}, []);
|
|
// 定时器触发预约时间提醒
|
let orderStartTime = disputeData?.meetInfo?.orderStartTime || '';
|
useEffect(() => {
|
if (orderStartTime) {
|
let startTime = new Date(orderStartTime).getTime() - 15 * 60 * 1000;
|
let nowTime = new Date().getTime();
|
if (startTime > nowTime) {
|
let second = parseInt(startTime - nowTime);
|
timer.setTimeout(
|
'orderVisible',
|
() => {
|
if (window.location.hash.indexOf('judicialWindow') !== -1) setOrderVisible(true);
|
},
|
second
|
);
|
}
|
}
|
return () => {
|
timer.clearTimeOut('orderVisible');
|
};
|
}, [orderStartTime]);
|
|
// 暂停,结束司法确认dom
|
const stopMediate = (
|
<Space size={32}>
|
<div className="mediationWindow-stopMediate" onClick={() => handleClickBottomAction('mediationOver')}>
|
<End />
|
<span>结束司法确认</span>
|
</div>
|
</Space>
|
);
|
|
// 人民调解协议书
|
const docxArr = disputeData.fileInfoList?.filter((item) => item.ownerType === '22_00018-302')[0]?.fileList || [];
|
|
return (
|
<Page>
|
<div className="mediationWindow">
|
<div className="mediationWindow-header">
|
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
<Tooltip title="返回">
|
<div onClick={() => navigate(`${back}?isBack=true`)} className="mediationWindow-header-returnIcon">
|
<LeftOutlined />
|
</div>
|
</Tooltip>
|
<h5 className="mediationWindow-noMargin">
|
{disputeData.caseTitle}
|
{disputeData.caseNo}
|
</h5>
|
<Button onClick={getTaskInfo} className="public-mainBtn" size="small">
|
任务信息
|
</Button>
|
</div>
|
<Tooltip title="司法确认邀请码" placement="topLeft">
|
<QrcodeOutlined onClick={() => setModal({ visible: true, actionType: 'qrCode' })} style={{ fontSize: '34px', cursor: 'pointer' }} />
|
</Tooltip>
|
</div>
|
{/* center */}
|
<div className="mediationWindow-main">
|
<div className="mediationWindow-main-left">
|
{voiceVisible ? (
|
<MediateDynamic />
|
) : (
|
<Space direction="vertical" className="animated faster flipInY">
|
<div className="mediationWindow-card" style={{ paddingRight: '8px' }}>
|
<h5>已达成的调解协议</h5>
|
<pre className="mediationWindow-top-pre">{disputeData.agreeContent || '-'}</pre>
|
</div>
|
<div className="mediationWindow-card" style={{ paddingRight: '8px' }}>
|
<h5>纠纷描述</h5>
|
<pre className="mediationWindow-top-pre">{disputeData.caseDes}</pre>
|
</div>
|
<div className="mediationWindow-card">
|
<Space size={4}>
|
<h5 className="mediationWindow-noMargin">申请人-</h5>
|
<div>
|
{(disputeData.plaintiffList || [])[0]?.trueName || '-'}
|
{`( 共${disputeData.plaintiffList?.length || 0}方 )`}
|
</div>
|
</Space>
|
</div>
|
<div className="mediationWindow-card">
|
<Space size={4}>
|
<h5 className="mediationWindow-noMargin">被申请人-</h5>
|
<div>
|
{(disputeData.defendantList || [])[0]?.trueName || '-'}
|
{`( 共${disputeData.defendantList?.length || 0}方 )`}
|
</div>
|
</Space>
|
</div>
|
<div className="mediationWindow-card mediationWindow-material" onClick={() => handleClickBottomAction('materialCheck')}>
|
<div className="mediationWindow-material-item">
|
<h5 className="mediationWindow-noMargin">申请人材料</h5>
|
<div>{disputeData.plaintiffFileNum || 0}</div>
|
</div>
|
<div className="mediationWindow-material-item">
|
<h5 className="mediationWindow-noMargin">被申请人材料</h5>
|
<div>{disputeData.defendantFileNum || 0}</div>
|
</div>
|
</div>
|
</Space>
|
)}
|
<div className="mediationWindow-main-left-action" style={!voiceVisible ? { flex: 1 } : {}}>
|
<Space size={66}>
|
<Tooltip
|
title={
|
orderVisible ? (
|
<Space>
|
<span>15分钟后开始司法确认</span>
|
<CloseCircleOutlined onClick={() => setOrderVisible(false)} style={{ fontSize: 20 }} />
|
</Space>
|
) : (
|
'预约设置'
|
)
|
}
|
visible={orderVisible || undefined}
|
>
|
<img onClick={() => handleClickLeftAction('1')} src={modal.actionType === 'orderMediation' ? clock_active : clock} alt="" />
|
</Tooltip>
|
{/* TODO:暂无此功能开放 */}
|
{/* <Popconfirm
|
title={voiceVisible ? '是否关闭语音转文字功能?' : '是否开启语音转文字功能?'}
|
onConfirm={() => setVoiceVisible(!voiceVisible)}
|
okText={voiceVisible ? '关闭转写' : '开启转写'}
|
cancelText={voiceVisible ? '保持开启' : '稍后再说'}
|
>
|
<Tooltip title="语音转文字">
|
<img src={voiceVisible ? microphone_active : microphone} alt="" />
|
</Tooltip>
|
</Popconfirm> */}
|
<Popconfirm
|
title="是否跳转到视频会议房间?"
|
onConfirm={() => {
|
if (!disputeData.meetCloud?.pcJoinUrl) {
|
$$.info({ type: 'warning', content: '抱歉!视频会议房间暂未创建,请先开始司法确认' });
|
return;
|
}
|
handleClickLeftAction('3');
|
}}
|
>
|
<Tooltip title="视频会议">
|
<img src={camera} alt="" />
|
</Tooltip>
|
</Popconfirm>
|
</Space>
|
</div>
|
</div>
|
<div className="mediationWindow-card mediationWindow-pdfDom">
|
<div className="mediationWindow-pdfDom-title">{docxArr[docxIndex]?.name}</div>
|
<div className="mediationWindow-pdfDom-main">
|
<iframe
|
name={docxArr[docxIndex]?.name}
|
title={docxArr[docxIndex]?.name}
|
src={`${$$.appUrl.fileUrl}${$$.appUrl.fileShowUrl}${docxArr[docxIndex]?.id}`}
|
height="100%"
|
width="100%"
|
frameBorder="0"
|
srcDoc={
|
docxArr[docxIndex]?.cat === '22_00017-6' || docxArr[docxIndex]?.cat === '22_00017-3'
|
? null
|
: !docxArr[docxIndex]?.id
|
? '无文件展示'
|
: `暂不支持${$$.fileType(docxArr[docxIndex]?.cat, 'name')}格式`
|
}
|
>
|
{docxArr[docxIndex]?.name}
|
</iframe>
|
{docxArr.length > 1 && (
|
<div className="mediationWindow-pdfDom-main-box">
|
<Dropdown
|
overlay={
|
<Menu onClick={({ key }) => setDocxIndex(key)}>
|
{docxArr.map((x, t) => (
|
<Menu.Item key={t}>
|
<Text style={{ maxWidth: '300px' }} className={t == docxIndex ? 'public-color' : ''} ellipsis>
|
{x.name}
|
</Text>
|
</Menu.Item>
|
))}
|
</Menu>
|
}
|
placement="topRight"
|
>
|
<img src={judicialWindow_fileBox} alt="" />
|
</Dropdown>
|
</div>
|
)}
|
</div>
|
</div>
|
</div>
|
{/* bottom */}
|
<div className="mediationWindow-bottom">
|
{operation.map((x, t) => {
|
if (x.actionType === 'mediationStart') {
|
return (
|
<div className="mediationWindow-bottom-item" key={x.actionType}>
|
{!judicialStartTime ? (
|
<Popconfirm
|
title="确定开始司法确认吗?"
|
onConfirm={() => handleStartMediate(x.actionType)}
|
okText="开始司法确认"
|
cancelText="稍后再说"
|
>
|
<div className="mediationWindow-bottom-mediate">
|
<Space direction="vertical" size={2}>
|
<img className="mediationWindow-bottom-icon" src={x.icon} alt="" />
|
<div>{x.title}</div>
|
</Space>
|
</div>
|
</Popconfirm>
|
) : (
|
<Popover content={stopMediate}>
|
<div className="mediationWindow-bottom-mediate">
|
<Space direction="vertical" size={2}>
|
<img className="mediationWindow-bottom-icon" src={x.iconActive} alt="" />
|
<Timer judicialStartTime={judicialStartTime} />
|
</Space>
|
</div>
|
</Popover>
|
)}
|
</div>
|
);
|
}
|
return (
|
<div
|
className={`mediationWindow-bottom-item ${modal.actionType === x.actionType ? 'mediationWindow-bottom-item-active' : ''}`}
|
key={x.actionType}
|
>
|
<Space direction="vertical" size={4} onClick={() => handleClickBottomAction(x.actionType)}>
|
<img className="mediationWindow-bottom-icon" src={modal.actionType === x.actionType ? x.iconActive : x.icon} alt="" />
|
<div>{x.title}</div>
|
</Space>
|
</div>
|
);
|
})}
|
</div>
|
{modal.visible !== null && (
|
<ActionModal
|
caseId={caseId}
|
judicialId={judicialId}
|
taskId={taskId}
|
disputeData={disputeData}
|
visible={modal.visible}
|
actionType={modal.actionType}
|
getDisputeData={getDisputeData}
|
onClose={() => setModal({ visible: false })}
|
onStartMediation={onStartMediation} // 开始司法确认回调
|
/>
|
)}
|
{/* 任务信息 */}
|
<JudicialTask visible={task.visible} onClose={() => setTask({ visible: false })} contentData={task.contentData || {}} />
|
{/* 司法确认开始后的一个浮窗显示 */}
|
<MyModal visible={successVisible} footer={false} width={374} centered onCancel={() => setSuccessVisible(false)}>
|
<div style={{ padding: '12px 16px 16px' }}>
|
<Space direction="vertical" align="center" size="large">
|
<Space>
|
<CheckCircleFilled style={{ color: '#52c41a' }} />
|
<h4 style={{ margin: 0 }}>司法确认开始提示</h4>
|
</Space>
|
<div>司法确认已经开始!线上司法确认时,可点击工作台右上方二维码查看或复制「在线视频司法确认房间号」</div>
|
<Button type="primary" onClick={() => setSuccessVisible(false)}>
|
我知道了
|
</Button>
|
</Space>
|
</div>
|
<div className="mediationWindow-start-tips">
|
<QrcodeOutlined style={{ fontSize: '34px' }} />
|
<div className="mediationWindow-start-arrow">
|
<img src={promptArrow} alt="" />
|
</div>
|
</div>
|
</MyModal>
|
</div>
|
</Page>
|
);
|
};
|
|
// 任务信息
|
const JudicialTask = ({ visible, onClose, contentData }) => {
|
// 处理时限,暂时取消,后续可根据需求改动
|
// const expireHours = $$.getHours(contentData.expireTime);
|
|
return (
|
<>
|
{visible && <div onClick={onClose} className="mediationWindow-task-box" />}
|
<div className="mediationWindow-task caseDetail-headerCard" style={{ top: visible ? undefined : '-200px' }}>
|
<div className="caseDetail-cardTitle">
|
<Space size="small">
|
<div className="caseDetail-cardTitle-icon caseDetail-cardTitle-iconGreen">
|
<ProfileOutlined />
|
</div>
|
<h5>任务信息</h5>
|
</Space>
|
</div>
|
<div className="caseDetail-descriptions">
|
<Descriptions size="small">
|
<Descriptions.Item label="任务名称">{contentData.taskNodeName || '-'}</Descriptions.Item>
|
<Descriptions.Item label="任务下达时间">{$$.timeFormat(contentData.createTime)}</Descriptions.Item>
|
{/* TODO:暂时取消,后续可根据需求改动 <Descriptions.Item label="处理时限">
|
<span className={expireHours.isNegativeNum ? 'public-danger' : ''}>{expireHours.hours}小时</span>
|
</Descriptions.Item> */}
|
<Descriptions.Item label="上一级处理人">
|
{contentData.lastUserName ? <NameCard name={contentData.lastUserName} userId={contentData.lastUserId} /> : <div>-</div>}
|
</Descriptions.Item>
|
<Descriptions.Item label="上一级处理说明">
|
<Text className="public-fontBg" ellipsis={{ tooltip: contentData.lastContent || '-' }}>
|
{contentData.lastContent || '-'}
|
</Text>
|
</Descriptions.Item>
|
<Descriptions.Item label="上一级处理附件">
|
<FilesDrawer filesData={contentData.lastFileInfoList} />
|
</Descriptions.Item>
|
</Descriptions>
|
</div>
|
</div>
|
</>
|
);
|
};
|
|
// 计时器
|
const Timer = ({ judicialStartTime }) => {
|
const [time, setTime] = useState('00:00:00');
|
|
function uninstall() {
|
timer.clearInterval('mediationWindowTimer');
|
}
|
|
useEffect(() => {
|
let seconds = 0;
|
if (judicialStartTime) {
|
seconds = $$.getFunnel(judicialStartTime);
|
if (seconds > 345600) {
|
// 大于4天时显示
|
setTime('99:99:99:99');
|
} else {
|
let duration = $$.getDuration(seconds);
|
setTime(duration);
|
}
|
} else {
|
setTime('00:00:00');
|
}
|
timer.setInterval(
|
'mediationWindowTimer',
|
() => {
|
if (seconds > 345600) {
|
setTime('99:99:99:99');
|
uninstall();
|
return;
|
}
|
seconds = seconds + 1;
|
setTime($$.getDuration(seconds));
|
},
|
1000
|
);
|
return uninstall;
|
}, [judicialStartTime]);
|
|
return <div>{time}</div>;
|
};
|
|
export default JudicialWindow;
|