| web-app/0415备份.zip | patch | view | raw | blame | history | |
| web-app/build.zip | patch | view | raw | blame | history | |
| web-app/build0310.zip | patch | view | raw | blame | history | |
| web-app/build0312.zip | patch | view | raw | blame | history | |
| web-app/build0312v2.zip | patch | view | raw | blame | history | |
| web-app/package-lock.json | ●●●●● patch | view | raw | blame | history | |
| web-app/public.zip | patch | view | raw | blame | history | |
| web-app/src/components/common/OutboundCallWidget.jsx | ●●●●● patch | view | raw | blame | history | |
| web-app/src/components/dashboard/TabContainer.jsx | ●●●●● patch | view | raw | blame | history | |
| web-app/src/config/env.js | ●●●●● patch | view | raw | blame | history | |
| web-app/src/contexts/CaseDataContext.jsx | ●●●●● patch | view | raw | blame | history | |
| web-app/src/services/OutboundBotAPIService.js | ●●●●● patch | view | raw | blame | history | |
| web-app/v1备份从这里回退.zip | patch | view | raw | blame | history | |
| web-app/yarn.lock | ●●●●● patch | view | raw | blame | history |
web-app/0415备份.zipBinary files differ
web-app/build.zipBinary files differ
web-app/build0310.zipBinary files differ
web-app/build0312.zipBinary files differ
web-app/build0312v2.zipBinary files differ
web-app/package-lock.json
@@ -17976,23 +17976,6 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "license": "ISC" }, "node_modules/yaml": { "version": "2.8.2", "resolved": "https://registry.npmmirror.com/yaml/-/yaml-2.8.2.tgz", "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", "license": "ISC", "optional": true, "peer": true, "bin": { "yaml": "bin.mjs" }, "engines": { "node": ">= 14.6" }, "funding": { "url": "https://github.com/sponsors/eemeli" } }, "node_modules/yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", web-app/public.zipBinary files differ
web-app/src/components/common/OutboundCallWidget.jsx
@@ -28,15 +28,19 @@ * @param {Function} props.onRefreshData - 数据刷新回调 */ const OutboundCallWidget = ({ onSwitchTab, onRefreshData }) => { const { caseData } = useCaseData(); const { caseData, refreshNodeData } = useCaseData(); const [isVisible, setIsVisible] = useState(false); // 默认隐藏 const [isMinimized, setIsMinimized] = useState(false); // 默认展开(非最小化) const [calls, setCalls] = useState([]); const [mediationRecords, setMediationRecords] = useState([]); // AI调解记录 const [aiProcessingTasks, setAiProcessingTasks] = useState([]); // AI处理中任务 const isMountedRef = useRef(true); // 轮询间隔(毫秒) const POLL_INTERVAL = 10000; // 10秒 const POLL_INTERVAL = 2000; // 2秒 // 节点数据轻量刷新间隔(毫秒)—— 与主轮询对齐,避免节点进度延迟 const NODE_REFRESH_INTERVAL = 2000; // 2秒 // 最大重试次数 const MAX_RETRY_COUNT = 10; @@ -165,57 +169,26 @@ }; /** * 批量更新通话状态到后端 * @param {Array} jobsToUpdate - 需要更新的任务列表 * @returns {Promise<boolean>} 是否有成功的更新 * [已废弃] 批量更新通话状态到后端 * 改造后状态更新由后端回调驱动,前端不再调用 update-status API */ const updateCallStatusToBackend = async (jobsToUpdate) => { if (!jobsToUpdate || jobsToUpdate.length === 0) return false; try { // 并行调用所有任务的更新API const results = await Promise.all( jobsToUpdate.map(async (job) => { try { const statusToUpdate = job.backendStatus || job.newStatus; if (!statusToUpdate) { return { success: false, job }; } await OutboundBotAPIService.updateCallStatus({ jobId: job.jobId, callStatus: statusToUpdate }); console.log(`状态更新成功: ${job.jobId} -> ${statusToUpdate}`); return { success: true, job }; } catch (err) { console.error(`状态更新失败: ${job.jobId}`, err); return { success: false, job }; } }) ); // 检查是否有成功的更新 const hasSuccess = results.some(r => r.success); return hasSuccess; } catch (err) { console.error('批量更新状态失败:', err); return false; } }; // const updateCallStatusToBackend = async (jobsToUpdate) => { ... 已移除 }; /** * 触发页面更新(刷新数据 + 切换Tab) * 触发页面更新(轻量刷新节点数据 + 切换Tab) * 不调用 onRefreshData(全量刷新会重复触发外呼/OCR),改用轻量级 refreshNodeData */ const triggerPageUpdate = useCallback(() => { // 刷新案件数据 if (onRefreshData) { onRefreshData(); // 轻量刷新节点数据(仅 timeline + processNodes,不触发外呼等副作用) if (refreshNodeData) { console.log('[Widget] 终态检测 → 立即轻量刷新节点数据'); refreshNodeData(); } // 切换到AI调解实时看板 if (onSwitchTab) { onSwitchTab('mediation-board'); } }, [onRefreshData, onSwitchTab]); }, [refreshNodeData, onSwitchTab]); /** * 移除终态或超时的任务 @@ -243,7 +216,39 @@ * 查询通话状态 */ const fetchCallStatus = useCallback(async () => { // 从 localStorage 读取任务 // ── Step 1: 从后端补充活跃记录(解决后端创建任务前端不知情的问题)── if (mediationId) { try { const backendResp = await OutboundBotAPIService.getActiveRecords({ mediation_id: mediationId }); const backendJobs = backendResp?.data || []; if (backendJobs.length > 0) { const storedRaw = localStorage.getItem(OUTBOUND_JOBS_KEY); const storedJobs = storedRaw ? JSON.parse(storedRaw) : []; const storedJobIds = new Set(storedJobs.map(j => j.jobId)); let changed = false; backendJobs.forEach(bj => { if (!storedJobIds.has(bj.jobId)) { const createTs = bj.createTime ? new Date(bj.createTime).getTime() : Date.now(); storedJobs.push({ ...bj, startTime: createTs, pollStartTime: Date.now(), retryCount: 0, }); changed = true; console.log('[Widget] 从后端补充活跃外呼任务:', bj.jobId, bj.perTypeName, bj.callStatus); } }); if (changed) { localStorage.setItem(OUTBOUND_JOBS_KEY, JSON.stringify(storedJobs)); } } } catch (e) { console.warn('[Widget] 从后端获取活跃记录失败:', e); } } // ── Step 2: 从 localStorage 读取任务(与原逻辑一致)── const storedJobs = loadJobsFromStorage(); // 分离成功任务和失败任务 @@ -337,14 +342,13 @@ // 清理超时任务 const cleanedJobs = cleanupJobs(filteredJobs); // 如果有需要更新到后端的任务,批量调用更新API if (jobsNeedBackendUpdate.length > 0) { const hasUpdateSuccess = await updateCallStatusToBackend(jobsNeedBackendUpdate); // 轮询仅用于 UI 展示,不再调用后端 update-status API // 状态更新已由后端回调驱动,前端不再触发推进 // 如果有成功的更新,触发页面更新 if (hasUpdateSuccess) { // 如果有终态任务,触发页面更新 const hasTerminalJobs = jobsNeedBackendUpdate.length > 0; if (hasTerminalJobs) { triggerPageUpdate(); } } // 保存到 localStorage @@ -361,7 +365,38 @@ setIsVisible(true); } } }, [isVisible, triggerPageUpdate]); }, [isVisible, triggerPageUpdate, mediationId]); // 记录上一次 AI 处理任务数,用于检测 "处理中→完成" 变化 const prevAiTaskCountRef = useRef(0); // 轮询 AI 处理状态 const fetchAiProcessingStatus = useCallback(async () => { if (!mediationId) return; try { const resp = await OutboundBotAPIService.getAiProcessingStatus({ mediation_id: mediationId }); const tasks = resp?.data || []; if (isMountedRef.current) { const prevCount = prevAiTaskCountRef.current; prevAiTaskCountRef.current = tasks.length; setAiProcessingTasks(tasks); // AI 任务从 "有" → "无"(处理完成),立即刷新节点数据以感知新节点推进 if (prevCount > 0 && tasks.length === 0) { console.log('[Widget] AI处理全部完成 → 立即刷新节点数据'); if (refreshNodeData) refreshNodeData(); } // 如果有 AI 处理中任务,确保悬浮窗可见 if (tasks.length > 0 && !isVisible) { setIsVisible(true); } } } catch (e) { // 不影响主流程,静默失败 console.warn('[Widget] 查询AI处理状态失败:', e); } }, [mediationId, isVisible, refreshNodeData]); // 定时轮询通话状态 useEffect(() => { @@ -372,10 +407,14 @@ fetchCallStatus(); loadMediationRecords(); // 初始加载调解记录 // AI 处理状态初始加载 fetchAiProcessingStatus(); // 设置轮询定时器(10秒间隔) const interval = setInterval(() => { fetchCallStatus(); loadMediationRecords(); // 每10秒加载一次AI调解记录 fetchAiProcessingStatus(); // 每10秒查询AI处理状态 }, POLL_INTERVAL); // 监听外呼任务更新事件(立即刷新) @@ -403,7 +442,24 @@ window.removeEventListener('mediation-terminated', handleMediationTerminated); isMountedRef.current = false; }; }, [fetchCallStatus, loadMediationRecords]); }, [fetchCallStatus, loadMediationRecords, fetchAiProcessingStatus]); // 独立定时器:周期性轻量刷新 timeline + processNodes(不依赖闭包变量,避免过期状态问题) useEffect(() => { const mediationState = caseData?.mediation?.state; // 仅在调解进行中时启动周期性刷新 if (mediationState !== 1) return; console.log('[Widget] 启动节点数据周期性轻量刷新,间隔:', NODE_REFRESH_INTERVAL, 'ms'); const nodeRefreshTimer = setInterval(() => { if (isMountedRef.current && refreshNodeData) { console.log('[Widget] 执行节点数据轻量刷新'); refreshNodeData(); } }, NODE_REFRESH_INTERVAL); return () => clearInterval(nodeRefreshTimer); }, [caseData?.mediation?.state, refreshNodeData]); // 关闭气泡 const handleClose = (e) => { @@ -442,8 +498,8 @@ return true; }); // 如果没有活跃任务且不可见,不渲染任何内容 if (activeCalls.length === 0 && !isVisible) { // 如果没有活跃任务且没有AI处理中任务且不可见,不渲染任何内容 if (activeCalls.length === 0 && aiProcessingTasks.length === 0 && !isVisible) { return null; } @@ -482,8 +538,8 @@ color: 'white', }} /> {/* 红点提示有通话 */} {activeCalls.length > 0 && ( {/* 红点提示有通话或AI处理中 */} {(activeCalls.length + aiProcessingTasks.length) > 0 && ( <div style={{ position: 'absolute', @@ -492,7 +548,7 @@ width: 16, height: 16, borderRadius: '50%', background: '#ff4d4f', background: aiProcessingTasks.length > 0 ? '#722ED1' : '#ff4d4f', display: 'flex', alignItems: 'center', justifyContent: 'center', @@ -501,7 +557,7 @@ fontWeight: 'bold', }} > {activeCalls.length} {activeCalls.length + aiProcessingTasks.length} </div> )} </div> @@ -648,8 +704,97 @@ </div> ))} {/* AI 处理中加载态卡片 */} {aiProcessingTasks.map((task, index) => ( <div key={`ai-${task.jobId || index}`} style={{ background: 'linear-gradient(135deg, #722ED1 0%, #531DAB 100%)', borderRadius: 12, padding: '16px 20px', color: 'white', boxShadow: '0 4px 16px rgba(114, 46, 209, 0.3)', position: 'relative', minWidth: 280, }} > {/* 头部 - AI 分析中 */} <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 12, }} > <div style={{ width: 36, height: 36, borderRadius: '50%', background: 'rgba(255,255,255,0.2)', display: 'flex', alignItems: 'center', justifyContent: 'center', }} > <i className="fas fa-brain" style={{ fontSize: 18, animation: 'pulse 1.5s infinite' }} /> </div> <div style={{ flex: 1 }}> <div style={{ fontSize: 16, fontWeight: 600, display: 'flex', alignItems: 'center', gap: 8, }} > AI 分析中 <span style={{ width: 8, height: 8, borderRadius: '50%', background: '#B37FEB', animation: 'pulse 1.5s infinite', }} /> </div> </div> </div> {/* 分析信息 */} <div style={{ marginBottom: 10 }}> <div style={{ fontSize: 14, opacity: 0.95, lineHeight: 1.6 }}> <span>{task.personName || '当事人'} 通话分析</span> </div> <div style={{ fontSize: 12, opacity: 0.75, marginTop: 6, display: 'flex', flexDirection: 'column', gap: 4 }}> {(task.steps || []).includes('summary') && ( <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}> <i className="fas fa-file-alt" style={{ fontSize: 11 }} /> <span>对话总结生成中...</span> </div> )} {(task.steps || []).includes('emotion') && ( <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}> <i className="fas fa-heart" style={{ fontSize: 11 }} /> <span>情绪识别中...</span> </div> )} {(task.steps || []).includes('success_rate') && ( <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}> <i className="fas fa-chart-line" style={{ fontSize: 11 }} /> <span>成功率评估中...</span> </div> )} </div> </div> </div> ))} {/* 无通话时的占位提示 */} {activeCalls.length === 0 && isVisible && ( {activeCalls.length === 0 && aiProcessingTasks.length === 0 && isVisible && ( <div style={{ background: 'linear-gradient(135deg, #1A6FB8 0%, #0d4a8a 100%)', web-app/src/components/dashboard/TabContainer.jsx
@@ -1,4 +1,4 @@ import React, { useState, useEffect, forwardRef, useImperativeHandle } from 'react'; import React, { useState, useEffect, useCallback, useRef, forwardRef, useImperativeHandle } from 'react'; import { useCaseData } from '../../contexts/CaseDataContext'; import { formatDuration, formatSuccessRate } from '../../utils/stateTranslator'; import ProcessAPIService from '../../services/ProcessAPIService'; @@ -273,16 +273,23 @@ })); }; // 获取调解记录数据 const loadMediationRecords = async () => { // 看板轮询间隔(毫秒) const BOARD_POLL_INTERVAL = 5000; // 5秒 const isBoardMountedRef = useRef(true); // 获取调解记录数据(首次加载带 loading,后续静默刷新) const loadMediationRecords = useCallback(async (silent = false) => { if (!silent) { setLoading(true); } setError(null); try { // 从timeline中获取mediation_id const mediationId = timeline.mediation?.id; if (!mediationId) { throw new Error('未找到调解ID'); if (!silent) throw new Error('未找到调解ID'); return; } // 调用API获取记录列表 @@ -292,23 +299,50 @@ // 格式化数据 const formattedRecords = formatRecordData(response.data || []); if (isBoardMountedRef.current) { setRecords(formattedRecords); } } catch (err) { if (!silent) { setError(err.message); console.error('获取调解记录失败:', err); message.error(`获取调解记录失败: ${err.message}`); } else { console.warn('[MediationBoard] 静默刷新失败:', err.message); } } finally { if (!silent) { setLoading(false); } }; // 监听Tab切换 useEffect(() => { if (activeTab === 'mediation-board') { loadMediationRecords(); } }, [activeTab]); }, [timeline.mediation?.id]); // Tab激活时:首次加载 + 启动周期性轮询 useEffect(() => { isBoardMountedRef.current = true; if (activeTab === 'mediation-board') { // 首次加载(带 loading 效果) loadMediationRecords(false); // 周期性静默刷新(不显示 loading) const pollTimer = setInterval(() => { if (isBoardMountedRef.current) { loadMediationRecords(true); } }, BOARD_POLL_INTERVAL); console.log('[MediationBoard] 启动周期轮询,间隔:', BOARD_POLL_INTERVAL, 'ms'); return () => { clearInterval(pollTimer); isBoardMountedRef.current = false; }; } return () => { isBoardMountedRef.current = false; }; }, [activeTab, loadMediationRecords]); // 如果还在加载中,显示Loading状态 if (loading) { web-app/src/config/env.js
@@ -12,7 +12,7 @@ }; // 当前环境,默认为SIT测试环境 const CURRENT_ENV = process.env.REACT_APP_ENV || ENV_TYPES.SIT; const CURRENT_ENV = process.env.REACT_APP_ENV || ENV_TYPES.DEV; // 环境配置映射 const ENV_CONFIG = { web-app/src/contexts/CaseDataContext.jsx
@@ -90,7 +90,12 @@ }; /** * 触发智能外呼 * [已废弃] 触发智能外呼(前端直接调用) * 改造后由后端 /trigger API 驱动,前端不再直接发起外呼 */ /** * 触发后端外呼(通过 MQ 异步处理) * @param {Object} timeline - 案件时间线数据 */ const triggerOutboundCall = async (timeline) => { @@ -105,11 +110,6 @@ console.warn('调解状态已结束,mediation.state:', state); return; } // 检查是否已有活跃任务,如有则跳过 if (hasActiveOutboundJobs()) { console.log('检测到活跃外呼任务,跳过发起新外呼'); return; } const mediationId = timeline.id; const caseId = timeline.case_id; @@ -119,107 +119,25 @@ return; } console.log('发起智能外呼,mediationId:', mediationId, ', caseId:', caseId); console.log('触发后端外呼,mediationId:', mediationId, ', caseId:', caseId); // 调用外呼API const response = await OutboundBotAPIService.makeCallV2({ // 调用后端 /trigger API(由后端校验状态 + 防重复 + MQ 异步处理) const response = await OutboundBotAPIService.triggerOutbound({ mediationId: String(mediationId), caseId: String(caseId), callAuto: 0, callPersonId: '' }); // 处理响应 if (response?.data && Array.isArray(response.data)) { const successJobs = []; const failedJobs = []; // 分类成功和失败的记录 response.data.forEach(item => { if (item.errorCode === 0 && item.jobId) { successJobs.push({ jobId: item.jobId, callStatus: item.callStatus || 'Scheduling', personId: item.personId, mediationId: item.mediationId, caseId: String(caseId), // 添加 caseId 字段用于轮询 perTypeName: item.perTypeName || '', // 当事人类型名称(申请方当事人/被申请方当事人) perClassName: item.perClassName || '', // 添加人员类型名称 trueName: item.trueName || '', // 添加真实姓名 startTime: item.createTime || item.createdTime || item.start_time, // 兼容 createTime 和 createdTime pollStartTime: Date.now(), retryCount: 0 }); } else if (item.errorCode > 0) { failedJobs.push({ personId: item.personId, message: item.message || '未知错误', perTypeName: item.perTypeName || '', // 当事人类型名称(申请方当事人/被申请方当事人) perClassName: item.perClassName || '', // 添加人员类型名称 trueName: item.trueName || '', // 添加真实姓名 errorCode: item.errorCode, // 添加错误码 startTime: new Date(item.startTime || item.start_time).getTime() // 转换为时间戳 }); } }); // 存储成功的任务到 localStorage if (successJobs.length > 0) { // 新任务发起时,先清除所有旧的成功任务(替换而不是追加) localStorage.setItem(OUTBOUND_JOBS_KEY, JSON.stringify(successJobs)); console.log('存储外呼任务成功,数量:', successJobs.length); // 外呼成功后,清除所有失败记录(新任务开始时应清空旧记录) localStorage.removeItem(`${OUTBOUND_JOBS_KEY}_failed`); console.log('外呼成功后清除所有失败记录'); // 触发自定义事件,通知 OutboundCallWidget 组件立即刷新 setTimeout(() => { window.dispatchEvent(new CustomEvent('outbound-jobs-updated')); }, 300); } // 存储失败的任务到 localStorage(用于气泡显示) if (failedJobs.length > 0) { console.log('准备存储失败任务:', failedJobs); // 读取现有的失败任务 const storedFailedJobs = JSON.parse(localStorage.getItem(`${OUTBOUND_JOBS_KEY}_failed`) || '[]'); // 去重:按 personId 去重,保留最新的错误信息 const uniqueFailedJobs = [...storedFailedJobs]; failedJobs.forEach(newJob => { const existingIndex = uniqueFailedJobs.findIndex(job => job.personId === newJob.personId); if (existingIndex >= 0) { // 更新已存在的失败任务 uniqueFailedJobs[existingIndex] = newJob; } else { // 添加新的失败任务 uniqueFailedJobs.push(newJob); } }); // 清理超过24小时的失败任务 const now = Date.now(); const cleanedFailedJobs = uniqueFailedJobs.filter(job => { return (now - job.startTime) < 24 * 60 * 60 * 1000; // 24小时 }); localStorage.setItem(`${OUTBOUND_JOBS_KEY}_failed`, JSON.stringify(cleanedFailedJobs)); console.log('存储外呼失败任务,数量:', cleanedFailedJobs.length); } // 提示失败的任务 if (failedJobs.length > 0) { const failedMsg = failedJobs .map(job => `${job.personId}(${job.message})`) .join('、'); message.warning(`部分联系人外呼失败:${failedMsg}`); console.warn('部分外呼失败:', failedJobs); if (response?.data) { console.log('后端外呼触发结果:', response.data); if (response.data.queued) { console.log('外呼任务已提交到队列,等待后端处理'); } } } catch (err) { console.error('智能外呼发起失败:', err); message.error('智能外呼发起失败,请检查网络后重试'); console.error('后端外呼触发失败:', err); // 不显示错误提示,后端已有降级处理 } }; @@ -467,10 +385,40 @@ }; /** * 刷新数据(强制从API获取) * 刷新数据(强制从API获取,含全部副作用) */ const refreshData = () => { loadCaseData(true); }; /** * 轻量级刷新:仅更新 timeline + processNodes,不触发外呼/OCR等副作用 * 适用于周期性轮询场景,避免重复触发外呼任务 */ const refreshNodeData = async () => { try { const params = getMergedParams(); if (!params.caseId) return; const response = await ProcessAPIService.getCaseProcessInfo( params.caseId, { caseTypeFirst: params.caseTypeFirst, platform_code: params.platform_code, authorization: params.auth_token || params.authorization || '' } ); const timelineData = response.timeline || response.data?.timeline || response; const nodesData = response.data?.nodeList || response.data?.nodes || response.nodes || []; // 仅更新数据状态,不触发任何副作用 setCaseData(timelineData); setProcessNodes(Array.isArray(nodesData) ? nodesData : []); console.log('[refreshNodeData] 轻量刷新完成, current_node:', timelineData.current_node?.node_name); } catch (err) { console.warn('[refreshNodeData] 轻量刷新失败:', err); } }; // 防止重复加载的引用标识 @@ -503,6 +451,7 @@ loading, error, refreshData, refreshNodeData, // 轻量级刷新(仅 timeline + nodes) loadCaseData, taskStartTime, // 任务开始时间 isTaskTimeFallback, // 是否降级模式 web-app/src/services/OutboundBotAPIService.js
@@ -50,7 +50,33 @@ } /** * 触发外呼任务(后端驱动,MQ异步处理) * POST /api/v1/outbound-bot/trigger * @param {Object} data - 请求数据 * @param {string} data.mediationId - 调解反馈表ID * @param {string} data.caseId - 案件ID * @param {number} data.callAuto - 呼叫模式 (0:自动, 1:手动) * @param {string} data.callPersonId - 手动模式指定当事人ID * @returns {Promise} 触发结果 */ static triggerOutbound(data = {}) { return request.post('/api/v1/outbound-bot/trigger', data); } /** * 获取当前节点活跃外呼记录(后端驱动模式下补充 localStorage) * GET /api/v1/outbound-bot/active-records * @param {Object} params * @param {string} params.mediationId - 调解反馈表ID * @returns {Promise} 活跃外呼记录列表 */ static getActiveRecords(params = {}) { return request.get('/api/v1/outbound-bot/active-records', params); } /** * 更新呼叫状态 * [已废弃] 状态更新现由后端回调驱动,前端不再调用 * POST /api/v1/outbound-bot/update-status * @param {Object} data - 请求数据 * @param {string} data.jobId - 工作ID @@ -70,6 +96,17 @@ } /** * 查询AI处理状态(摘要生成/情绪识别是否进行中) * GET /api/v1/outbound-bot/ai-processing-status * @param {Object} params * @param {string} params.mediation_id - 调解反馈表ID * @returns {Promise} AI处理状态列表 */ static getAiProcessingStatus(params = {}) { return request.get('/api/v1/outbound-bot/ai-processing-status', params); } /** * 获取通话录音文件 * GET /api/v1/outbound-bot/file-play * @param {string} recordUrl - 录音文件相对路径 web-app/v1备份从这里回退.zipBinary files differ
web-app/yarn.lock
@@ -10356,11 +10356,6 @@ resolved "https://registry.npmmirror.com/yaml/-/yaml-1.10.2.tgz" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== yaml@^2.4.2: version "2.8.2" resolved "https://registry.npmmirror.com/yaml/-/yaml-2.8.2.tgz" integrity sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A== yargs-parser@^20.2.2: version "20.2.9" resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz"