Files
AIclinicalresearch/frontend-v2/src/modules/ssa/components/SSACodeModal.tsx

109 lines
3.0 KiB
TypeScript

/**
* SSACodeModal - V11 R代码模态框
*
* 100% 还原 V11 原型图
* 调用后端 API 获取真实执行代码
*/
import React, { useEffect, useState } from 'react';
import { X, Download, Loader2 } from 'lucide-react';
import { useSSAStore } from '../stores/ssaStore';
import { useAnalysis } from '../hooks/useAnalysis';
export const SSACodeModal: React.FC = () => {
const { codeModalVisible, setCodeModalVisible, executionResult, addToast } = useSSAStore();
const { downloadCode } = useAnalysis();
const [code, setCode] = useState<string>('');
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
if (codeModalVisible) {
loadCode();
}
}, [codeModalVisible]);
const loadCode = async () => {
setIsLoading(true);
try {
const result = await downloadCode();
const text = await result.blob.text();
setCode(text);
} catch (error) {
if (executionResult?.reproducibleCode) {
setCode(executionResult.reproducibleCode);
} else {
setCode('# 暂无可用代码\n# 请先执行分析');
}
} finally {
setIsLoading(false);
}
};
if (!codeModalVisible) return null;
const handleClose = () => {
setCodeModalVisible(false);
};
const handleDownload = async () => {
try {
const result = await downloadCode();
const url = URL.createObjectURL(result.blob);
const a = document.createElement('a');
a.href = url;
a.download = result.filename;
a.click();
URL.revokeObjectURL(url);
addToast('R 脚本已下载', 'success');
handleClose();
} catch (error) {
addToast('下载失败', 'error');
}
};
const handleCopy = () => {
navigator.clipboard.writeText(code);
addToast('代码已复制', 'success');
};
return (
<div className="code-modal-overlay" onClick={handleClose}>
<div className="code-modal pop-in" onClick={(e) => e.stopPropagation()}>
<header className="code-modal-header">
<h3 className="code-modal-title">
<span className="r-icon">R</span>
R
</h3>
<button className="code-modal-close" onClick={handleClose}>
<X size={16} />
</button>
</header>
<div className="code-modal-body">
{isLoading ? (
<div className="code-loading">
<Loader2 size={24} className="spin" />
<span>...</span>
</div>
) : (
<pre className="code-block">
<code>{code}</code>
</pre>
)}
</div>
<footer className="code-modal-footer">
<button className="copy-btn" onClick={handleCopy} disabled={isLoading}>
</button>
<button className="download-btn" onClick={handleDownload} disabled={isLoading}>
<Download size={14} />
.R
</button>
</footer>
</div>
</div>
);
};
export default SSACodeModal;