feat(rvw): Complete Phase 4-5 - Bug fixes and Word export
Summary: - Fix methodology score display issue in task list (show score instead of 'warn') - Add methodology_score field to database schema - Fix report display when only methodology agent is selected - Implement Word document export using docx library - Update documentation to v3.0/v3.1 Backend changes: - Add methodologyScore to Prisma schema and TaskSummary type - Update reviewWorker to save methodologyScore - Update getTaskList to return methodologyScore Frontend changes: - Install docx and file-saver libraries - Implement handleExportReport with Word generation - Fix activeTab auto-selection based on available data - Add proper imports for docx components Documentation: - Update RVW module status to 90% (Phase 1-5 complete) - Update system status document to v3.0 Tested: All review workflows verified, Word export functional
This commit is contained in:
123
frontend-v2/src/modules/rvw/components/AgentModal.tsx
Normal file
123
frontend-v2/src/modules/rvw/components/AgentModal.tsx
Normal file
@@ -0,0 +1,123 @@
|
||||
/**
|
||||
* 智能体选择弹窗
|
||||
*/
|
||||
import { useState } from 'react';
|
||||
import { PlayCircle, X } from 'lucide-react';
|
||||
import type { AgentType } from '../types';
|
||||
|
||||
interface AgentModalProps {
|
||||
visible: boolean;
|
||||
taskCount: number;
|
||||
onClose: () => void;
|
||||
onConfirm: (agents: AgentType[]) => void;
|
||||
}
|
||||
|
||||
export default function AgentModal({ visible, taskCount, onClose, onConfirm }: AgentModalProps) {
|
||||
const [selectedAgents, setSelectedAgents] = useState<AgentType[]>(['editorial']);
|
||||
|
||||
const toggleAgent = (agent: AgentType) => {
|
||||
if (selectedAgents.includes(agent)) {
|
||||
// 至少保留一个
|
||||
if (selectedAgents.length > 1) {
|
||||
setSelectedAgents(selectedAgents.filter(a => a !== agent));
|
||||
}
|
||||
} else {
|
||||
setSelectedAgents([...selectedAgents, agent]);
|
||||
}
|
||||
};
|
||||
|
||||
const handleConfirm = () => {
|
||||
// 只调用onConfirm,让调用方控制关闭时机
|
||||
onConfirm(selectedAgents);
|
||||
};
|
||||
|
||||
if (!visible) return null;
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 bg-slate-900/50 z-50 flex items-center justify-center backdrop-blur-sm">
|
||||
<div className="bg-white rounded-2xl shadow-2xl w-[400px] overflow-hidden transform transition-all scale-100 fade-in">
|
||||
{/* 头部 */}
|
||||
<div className="bg-slate-900 p-5 text-white flex items-center justify-between">
|
||||
<h3 className="font-bold text-lg flex items-center gap-2">
|
||||
<PlayCircle className="w-5 h-5 text-indigo-400" />
|
||||
发起智能审稿
|
||||
</h3>
|
||||
<button onClick={onClose} className="text-slate-400 hover:text-white transition-colors">
|
||||
<X className="w-5 h-5" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* 内容 */}
|
||||
<div className="p-6 space-y-4">
|
||||
<p className="text-sm text-slate-600 mb-4">
|
||||
{taskCount > 1 ? `已选择 ${taskCount} 个稿件,请选择审稿维度:` : '请选择审稿维度:'}
|
||||
</p>
|
||||
|
||||
{/* 规范性智能体 */}
|
||||
<label
|
||||
className={`flex items-start gap-3 p-4 border rounded-xl cursor-pointer transition-all ${
|
||||
selectedAgents.includes('editorial')
|
||||
? 'border-indigo-500 bg-indigo-50'
|
||||
: 'border-gray-200 hover:border-indigo-300'
|
||||
}`}
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={selectedAgents.includes('editorial')}
|
||||
onChange={() => toggleAgent('editorial')}
|
||||
className="mt-1 w-4 h-4 text-indigo-600 rounded border-gray-300 focus:ring-indigo-500"
|
||||
/>
|
||||
<div className="flex-1">
|
||||
<span className="block font-bold text-slate-800 text-sm">稿约规范性智能体</span>
|
||||
<span className="block text-xs text-slate-500 mt-0.5">
|
||||
检查格式、参考文献、图片、伦理声明等11项标准
|
||||
</span>
|
||||
</div>
|
||||
<span className="tag tag-blue">快速</span>
|
||||
</label>
|
||||
|
||||
{/* 方法学智能体 */}
|
||||
<label
|
||||
className={`flex items-start gap-3 p-4 border rounded-xl cursor-pointer transition-all ${
|
||||
selectedAgents.includes('methodology')
|
||||
? 'border-indigo-500 bg-indigo-50'
|
||||
: 'border-gray-200 hover:border-indigo-300'
|
||||
}`}
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={selectedAgents.includes('methodology')}
|
||||
onChange={() => toggleAgent('methodology')}
|
||||
className="mt-1 w-4 h-4 text-indigo-600 rounded border-gray-300 focus:ring-indigo-500"
|
||||
/>
|
||||
<div className="flex-1">
|
||||
<span className="block font-bold text-slate-800 text-sm">方法学统计智能体</span>
|
||||
<span className="block text-xs text-slate-500 mt-0.5">
|
||||
深度推理检验方法、统计逻辑、研究设计等20项评估
|
||||
</span>
|
||||
</div>
|
||||
<span className="tag tag-purple">深度</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{/* 底部按钮 */}
|
||||
<div className="p-4 bg-slate-50 flex justify-end gap-3 border-t border-gray-100">
|
||||
<button
|
||||
onClick={onClose}
|
||||
className="px-4 py-2 text-sm text-slate-600 hover:bg-gray-200 rounded-lg transition-colors"
|
||||
>
|
||||
取消
|
||||
</button>
|
||||
<button
|
||||
onClick={handleConfirm}
|
||||
disabled={selectedAgents.length === 0}
|
||||
className="px-4 py-2 bg-indigo-600 hover:bg-indigo-700 text-white text-sm font-bold rounded-lg shadow-sm transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
>
|
||||
立即运行
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user