| | |
| | | import React, { useState } from 'react'; |
| | | import { Modal, message } from 'antd'; |
| | | import { Modal, message, Input } from 'antd'; |
| | | import { useCaseData } from '../../contexts/CaseDataContext'; |
| | | import { translateMediationState } from '../../utils/stateTranslator'; |
| | | import { useTaskTimer } from '../../hooks/useTaskTimer'; |
| | | import ProcessAPIService from '../../services/ProcessAPIService'; |
| | | import { getMergedParams } from '../../utils/urlParams'; |
| | | |
| | | const { TextArea } = Input; |
| | | |
| | | // 终态状态(不显示人工接管按钮) |
| | | const TERMINAL_STATES = [2, 3]; // 调解成功、调解失败 |
| | | const TAKEOVER_STATE = 4; // 人工接管 |
| | | const PAUSED_STATE = 5; // 已终止/暂停状态 |
| | | |
| | | /** |
| | | * 获取案件ID |
| | |
| | | const [takeoverLoading, setTakeoverLoading] = useState(false); |
| | | const [confirmVisible, setConfirmVisible] = useState(false); |
| | | |
| | | // 状态控制相关状态 |
| | | const [controlLoading, setControlLoading] = useState(false); |
| | | const [controlConfirmVisible, setControlConfirmVisible] = useState(false); |
| | | const [controlAction, setControlAction] = useState(null); // 'terminate' or 'resume' |
| | | const [remark, setRemark] = useState(''); |
| | | |
| | | const timeline = caseData || {}; |
| | | const state = timeline.mediation?.state; |
| | | const nodeName = timeline.current_node?.node_name || ''; |
| | |
| | | const { formattedTime } = useTaskTimer(taskStartTime, isTaskTimeFallback); |
| | | |
| | | // 生成状态文本 |
| | | const statusText = state === 1 |
| | | ? `调解进行中-阶段${orderNo}:${nodeName}` |
| | | : (translateMediationState(state) || '调解进行中'); |
| | | const getStatusText = () => { |
| | | const stateNum = Number(state); |
| | | if (stateNum === 1) { |
| | | return `调解进行中-阶段${orderNo}:${nodeName}`; |
| | | } |
| | | return translateMediationState(state) || '调解进行中'; |
| | | }; |
| | | |
| | | const statusText = getStatusText(); |
| | | |
| | | // ==================== 状态控制按钮逻辑 ==================== |
| | | |
| | | /** |
| | | * 判断是否显示状态控制按钮 |
| | | * 状态为0(未开始)、1(进行中)、5(已终止)时显示 |
| | | */ |
| | | const shouldShowControlButton = () => { |
| | | const stateNum = Number(state); |
| | | // 进行中(1)显示终止按钮,已终止(5)显示恢复按钮 |
| | | return stateNum === 1 || stateNum === 5; |
| | | }; |
| | | |
| | | /** |
| | | * 获取状态控制按钮属性 |
| | | */ |
| | | const getControlButtonProps = () => { |
| | | const stateNum = Number(state); |
| | | |
| | | if (stateNum === 1) { |
| | | return { |
| | | text: '终止', |
| | | style: 'terminate', |
| | | action: 'terminate' |
| | | }; |
| | | } else if (stateNum === 5) { |
| | | return { |
| | | text: '恢复', |
| | | style: 'resume', |
| | | action: 'resume' |
| | | }; |
| | | } |
| | | |
| | | return null; |
| | | }; |
| | | |
| | | /** |
| | | * 处理状态控制按钮点击 |
| | | */ |
| | | const handleControlButtonClick = () => { |
| | | const buttonProps = getControlButtonProps(); |
| | | if (!buttonProps) return; |
| | | |
| | | setControlAction(buttonProps.action); |
| | | setControlConfirmVisible(true); |
| | | }; |
| | | |
| | | /** |
| | | * 处理状态控制确认 |
| | | */ |
| | | const handleControlConfirmOk = async () => { |
| | | if (!controlAction) return; |
| | | |
| | | setControlLoading(true); |
| | | try { |
| | | const params = getMergedParams(); |
| | | const actionCode = controlAction === 'terminate' ? 0 : 1; |
| | | |
| | | if (!params.caseId) { |
| | | throw new Error('案件ID不能为空'); |
| | | } |
| | | |
| | | await ProcessAPIService.updateMediationState(params.caseId, { |
| | | action: actionCode, |
| | | userName: localStorage.getItem('userName') || '调解员', |
| | | remark: remark || '' |
| | | }); |
| | | |
| | | message.success(controlAction === 'terminate' ? '调解已终止' : '调解已恢复'); |
| | | setControlConfirmVisible(false); |
| | | setRemark(''); |
| | | setControlAction(null); |
| | | |
| | | // 如果是终止操作,触发事件关闭外呼气泡 |
| | | if (controlAction === 'terminate') { |
| | | window.dispatchEvent(new CustomEvent('mediation-terminated')); |
| | | console.log('调解终止,触发外呼气泡关闭事件'); |
| | | } |
| | | |
| | | refreshData(); |
| | | } catch (error) { |
| | | console.error('状态更新失败:', error); |
| | | message.error(error.message || '状态更新失败,请稍后重试'); |
| | | } finally { |
| | | setControlLoading(false); |
| | | } |
| | | }; |
| | | |
| | | /** |
| | | * 处理状态控制取消 |
| | | */ |
| | | const handleControlConfirmCancel = () => { |
| | | setControlConfirmVisible(false); |
| | | setRemark(''); |
| | | setControlAction(null); |
| | | }; |
| | | |
| | | // ==================== 人工接管逻辑 ==================== |
| | | |
| | | /** |
| | | * 处理接管API调用 |
| | |
| | | }; |
| | | |
| | | /** |
| | | * 渲染状态控制按钮(终止/恢复) |
| | | */ |
| | | const renderStateControlButton = () => { |
| | | if (!shouldShowControlButton()) return null; |
| | | |
| | | const buttonProps = getControlButtonProps(); |
| | | if (!buttonProps) return null; |
| | | |
| | | const isTerminate = buttonProps.style === 'terminate'; |
| | | |
| | | return ( |
| | | <button |
| | | className={`state-control-btn ${isTerminate ? 'state-control-btn--terminate' : 'state-control-btn--resume'}`} |
| | | onClick={handleControlButtonClick} |
| | | disabled={controlLoading} |
| | | > |
| | | {controlLoading ? ( |
| | | <><i className="fas fa-spinner fa-spin"></i>处理中...</> |
| | | ) : ( |
| | | <><i className={isTerminate ? "fas fa-pause-circle" : "fas fa-play-circle"}></i>{buttonProps.text}</> |
| | | )} |
| | | </button> |
| | | ); |
| | | }; |
| | | |
| | | /** |
| | | * 渲染控制区域(按钮或印章) |
| | | */ |
| | | const renderControlAction = () => { |
| | | const stateNum = Number(state); |
| | | |
| | | // 终态状态(调解成功/失败/人工接管):显示印章 |
| | | if (TERMINAL_STATES.includes(state) || state === TAKEOVER_STATE) { |
| | | return <TakeoverStamp state={state} />; |
| | | if (TERMINAL_STATES.includes(stateNum) || stateNum === TAKEOVER_STATE) { |
| | | return <TakeoverStamp state={stateNum} />; |
| | | } |
| | | |
| | | // 调解中:显示接管按钮 |
| | | return <TakeoverButton loading={takeoverLoading} onClick={handleTakeover} />; |
| | | // 已终止/暂停状态(5):显示恢复按钮和人工接管按钮 |
| | | if (stateNum === PAUSED_STATE) { |
| | | return ( |
| | | <> |
| | | {renderStateControlButton()} |
| | | <TakeoverButton loading={takeoverLoading} onClick={handleTakeover} /> |
| | | </> |
| | | ); |
| | | } |
| | | |
| | | // 调解中(1):显示终止按钮和人工接管按钮 |
| | | return ( |
| | | <> |
| | | {renderStateControlButton()} |
| | | <TakeoverButton loading={takeoverLoading} onClick={handleTakeover} /> |
| | | </> |
| | | ); |
| | | }; |
| | | |
| | | return ( |
| | |
| | | <div className="floating-control-panel"> |
| | | <div className="control-status"> |
| | | <div className="status-indicator"> |
| | | <span className="status-dot"></span> |
| | | <span className="status-dot" style={Number(state) === 5 ? { background: '#e63946' } : {}}></span> |
| | | <span className="status-text"> |
| | | {statusText}{' '} |
| | | <span style={{ color: 'gray' }}> |
| | |
| | | </div> |
| | | </div> |
| | | |
| | | {/* 状态控制确认对话框(终止/恢复) */} |
| | | <Modal |
| | | title={controlAction === 'terminate' ? '确认终止调解' : '确认恢复调解'} |
| | | visible={controlConfirmVisible} |
| | | onOk={handleControlConfirmOk} |
| | | onCancel={handleControlConfirmCancel} |
| | | okText="确定" |
| | | cancelText="取消" |
| | | confirmLoading={controlLoading} |
| | | > |
| | | <p> |
| | | {controlAction === 'terminate' |
| | | ? '确定要终止当前AI调解流程吗?终止后调解将暂停,可在适当时机恢复。' |
| | | : '确定要恢复AI调解流程吗?恢复后将从当前位置继续调解。'} |
| | | </p> |
| | | <div style={{ marginTop: 15 }}> |
| | | <label style={{ display: 'block', marginBottom: 5, fontWeight: 500 }}> |
| | | 备注(可选): |
| | | </label> |
| | | <TextArea |
| | | value={remark} |
| | | onChange={(e) => setRemark(e.target.value)} |
| | | placeholder="请输入操作备注..." |
| | | rows={3} |
| | | /> |
| | | </div> |
| | | </Modal> |
| | | |
| | | {/* 人工接管确认对话框 */} |
| | | <Modal |
| | | title="人工接管确认" |