多语言首页
This commit is contained in:
@@ -999,6 +999,10 @@
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.execution-log-item.assistant .log-content.structured-content {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.execution-log-item.assistant .log-content.short-content {
|
||||
font-size: 13px;
|
||||
}
|
||||
@@ -1366,11 +1370,13 @@
|
||||
|
||||
<el-divider style="margin: 12px 0;"></el-divider>
|
||||
|
||||
<div style="padding:10px; background:#fff; border:1px solid #dcdfe6; border-radius:0px;">
|
||||
<div @dragover.prevent @drop.prevent="handleLightweightExtensionFolderDrop($event)"
|
||||
style="padding:10px; background:#fff; border:1px dashed #409EFF; border-radius:0px;">
|
||||
<div style="display:flex; align-items:center; justify-content:space-between; gap:8px; margin-bottom:8px;">
|
||||
<el-tooltip content="上传已跑通过的代码和测试数据;执行通过自然语言触发。" placement="top">
|
||||
<h4 style="margin:0; color:#303133; cursor:help;">{{ t('拓展分析阶段') }}</h4>
|
||||
</el-tooltip>
|
||||
<el-button size="small" @click="loadExtensionRuns(); extensionResultDialogVisible = true">{{ t('运行结果') }}</el-button>
|
||||
</div>
|
||||
<div style="display:grid; grid-template-columns:72px 1fr; gap:7px; align-items:center; font-size:12px;">
|
||||
<span>{{ t('已写阶段') }}</span>
|
||||
@@ -1431,7 +1437,6 @@
|
||||
<el-button v-if="isLightweightExtensionSelected" size="small" type="success" @click="openLightweightRuntimeCard()">
|
||||
{{ t('运行已发布') }}
|
||||
</el-button>
|
||||
<el-button size="small" @click="loadExtensionRuns(); extensionResultDialogVisible = true">{{ t('运行结果') }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1780,6 +1785,20 @@
|
||||
📂 Select
|
||||
</el-button>
|
||||
</div>
|
||||
<!-- lightWeightExtensionTest:start -->
|
||||
<div id="lightweight-extension-test-drop-zone"
|
||||
style="display:none;margin-top:8px;border:1px dashed #409EFF;padding:10px;font-size:12px;color:#606266;background:#f8fbff;"
|
||||
@dragover.prevent
|
||||
@drop.prevent="handleLightweightExtensionFolderDrop($event)">
|
||||
<div style="font-weight:600;color:#303133;">拖入固定结构拓展包</div>
|
||||
<div style="margin-top:4px;line-height:1.5;">要求包含 raw_code/run.sh 与 raw_test_data/,系统会自动创建 Job、解析环境并开始 lightweight upload。</div>
|
||||
<input id="lightweight-extension-test-folder-input" type="file" webkitdirectory directory multiple style="display:none" @change="handleLightweightExtensionFolderPick($event)">
|
||||
<div style="display:flex;justify-content:space-between;align-items:center;gap:8px;margin-top:8px;">
|
||||
<span>{{ lightweightExtensionTestStatus }}</span>
|
||||
<el-button size="small" type="success" @click="openLightweightExtensionFolderPicker">选择文件夹</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- lightWeightExtensionTest:end -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -7825,6 +7844,7 @@ RNA-seq KEGG/fgsea 会优先使用物种级 KEGG gene set;没有物种级缓
|
||||
});
|
||||
const activeRnaseqScopeId = ref('');
|
||||
const activeGenotypeScopeId = ref('');
|
||||
const lightweightExtensionTestStatus = ref('拖入固定结构文件夹,系统将自动创建 Job、解析环境并开始 upload。');
|
||||
|
||||
// 对话消息
|
||||
const messages = ref([]);
|
||||
@@ -19304,6 +19324,10 @@ compare: [[flesh, peel]]`;
|
||||
};
|
||||
|
||||
const extensionFileKey = (file) => `${file?.name || ''}::${file?.size || 0}::${file?.lastModified || 0}`;
|
||||
const extensionUploadPath = (file) => {
|
||||
const relative = String(file?.lightweightRelativePath || '').trim().replace(/^\/+/, '');
|
||||
return relative || String(file?.name || '').trim();
|
||||
};
|
||||
const appendExtensionFiles = (target, files) => {
|
||||
const current = Array.isArray(target) ? target : [];
|
||||
const merged = [...current];
|
||||
@@ -19329,6 +19353,53 @@ compare: [[flesh, peel]]`;
|
||||
if (selected.length) ElMessage.success(`已选择 ${selected.length} 个测试数据文件`);
|
||||
event.target.value = '';
|
||||
};
|
||||
const handleLightweightExtensionFolderDrop = (event) => {
|
||||
const droppedFiles = Array.from(event?.dataTransfer?.files || []);
|
||||
if (!droppedFiles.length) {
|
||||
ElMessage.warning('未检测到可用文件');
|
||||
return;
|
||||
}
|
||||
|
||||
const codeExtPattern = /\.(py|r|sh|bash|pl|js|ts|java|c|cc|cpp|go|rs|jl|rb|m|smk|nf|ipynb)$/i;
|
||||
const dataExtPattern = /\.(fastq|fq|gz|fa|fasta|fna|faa|pep|cds|gff|gff3|gtf|csv|tsv|txt|xlsx|xls|vcf|sam|bam)$/i;
|
||||
|
||||
const normalized = droppedFiles.map((file) => {
|
||||
const relativePath = file.webkitRelativePath || file.name;
|
||||
if (!file.lightweightRelativePath) {
|
||||
Object.defineProperty(file, 'lightweightRelativePath', {
|
||||
value: relativePath,
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
return file;
|
||||
});
|
||||
|
||||
const codeFiles = [];
|
||||
const dataFiles = [];
|
||||
normalized.forEach((file) => {
|
||||
const filePath = extensionUploadPath(file).toLowerCase();
|
||||
if (codeExtPattern.test(filePath)) {
|
||||
codeFiles.push(file);
|
||||
} else if (dataExtPattern.test(filePath)) {
|
||||
dataFiles.push(file);
|
||||
} else {
|
||||
codeFiles.push(file);
|
||||
}
|
||||
});
|
||||
|
||||
extensionBuild.codeFiles = appendExtensionFiles(extensionBuild.codeFiles, codeFiles);
|
||||
extensionBuild.dataFiles = appendExtensionFiles(extensionBuild.dataFiles, dataFiles);
|
||||
|
||||
if (!extensionBuild.displayName) {
|
||||
const firstPath = normalized[0]?.webkitRelativePath || normalized[0]?.name || '';
|
||||
const folder = firstPath.includes('/') ? firstPath.split('/')[0] : '';
|
||||
if (folder) {
|
||||
extensionBuild.displayName = folder.replace(/[^a-zA-Z0-9_-]+/g, '_');
|
||||
}
|
||||
}
|
||||
|
||||
ElMessage.success(`已拖入 ${normalized.length} 个文件,已自动填充拓展包`);
|
||||
};
|
||||
const removeExtensionFile = (kind, file) => {
|
||||
const key = extensionFileKey(file);
|
||||
if (kind === 'code') {
|
||||
@@ -19363,7 +19434,7 @@ compare: [[flesh, peel]]`;
|
||||
const value = String(path || '');
|
||||
if (!value.startsWith('/api/extension-stages') && !value.startsWith('/api/extension-stage-runs')) return value;
|
||||
const host = window.location.hostname || '127.0.0.1';
|
||||
return `${window.location.protocol}//${host}:7880${value}`;
|
||||
return `${window.location.protocol}//${host}:${window.location.port}${value}`;
|
||||
};
|
||||
const extensionApiFetch = async (path, options = {}) => fetch(extensionApiUrl(path), options);
|
||||
const pushExtensionStatus = (message, type = 'info', showDialog = false) => {
|
||||
@@ -19724,8 +19795,8 @@ compare: [[flesh, peel]]`;
|
||||
form.append('extension_id', extensionId);
|
||||
if (hasCommand) form.append('original_command', extensionBuild.command);
|
||||
form.append('operation_token', token);
|
||||
extensionBuild.codeFiles.forEach(file => form.append('raw_code_files', file));
|
||||
extensionBuild.dataFiles.forEach(file => form.append('raw_data_files', file));
|
||||
extensionBuild.codeFiles.forEach(file => form.append('raw_code_files', file, extensionUploadPath(file)));
|
||||
extensionBuild.dataFiles.forEach(file => form.append('raw_data_files', file, extensionUploadPath(file)));
|
||||
if (hasDataPaths) form.append('raw_data_paths', extensionBuild.dataPaths);
|
||||
const response = await extensionApiFetch('/api/lightweight-extension-stages/upload', { method: 'POST', body: form });
|
||||
if (!response.ok) throw new Error(await extensionApiError(response, '原始包可复现检查提交失败'));
|
||||
@@ -22289,7 +22360,7 @@ compare: [[flesh, peel]]`;
|
||||
addMessage('user', userInput);
|
||||
ragHistory.value.push({ role: 'user', content: userInput, time: new Date().toLocaleTimeString() });
|
||||
|
||||
// 调用当前 bbav5 后端 RAG 代理,随页面端口走同源地址(例如 7880)
|
||||
// 调用当前 bbav5 后端 RAG 代理,随页面端口走同源地址
|
||||
const data = await fetchJsonWithTimeout('/api/agent/rag', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
@@ -23523,6 +23594,25 @@ compare: [[flesh, peel]]`;
|
||||
runExtensionStageFromIntent,
|
||||
extensionOutputIcon,
|
||||
openExtensionOutput,
|
||||
// lightWeightExtensionTest
|
||||
lightweightExtensionTestStatus,
|
||||
handleLightweightExtensionFolderDrop: (event) => window.LightWeightExtensionTest && window.LightWeightExtensionTest.handleDrop({
|
||||
jobInfo,
|
||||
extensionBuild,
|
||||
createNewJob,
|
||||
appendExtensionFiles,
|
||||
buildLightweightExtensionStage,
|
||||
lightweightExtensionTestStatus,
|
||||
}, event),
|
||||
handleLightweightExtensionFolderPick: (event) => window.LightWeightExtensionTest && window.LightWeightExtensionTest.handlePick({
|
||||
jobInfo,
|
||||
extensionBuild,
|
||||
createNewJob,
|
||||
appendExtensionFiles,
|
||||
buildLightweightExtensionStage,
|
||||
lightweightExtensionTestStatus,
|
||||
}, event),
|
||||
openLightweightExtensionFolderPicker: () => window.LightWeightExtensionTest && window.LightWeightExtensionTest.openPicker(),
|
||||
methodologyPaperId,
|
||||
methodologyFamily,
|
||||
methodologyBatchDir,
|
||||
@@ -23761,6 +23851,9 @@ compare: [[flesh, peel]]`;
|
||||
document.getElementById('app').style.display = 'block';
|
||||
console.log('App mounted successfully');
|
||||
</script>
|
||||
<!-- lightWeightExtensionTest:wiring:start -->
|
||||
<script src="/lightWeightExtensionTest.js"></script>
|
||||
<!-- lightWeightExtensionTest:wiring:end -->
|
||||
<!-- 深度解读弹窗样式 -->
|
||||
<style>
|
||||
.interpretation-dialog .el-dialog__body { padding: 0; max-height: 70vh; overflow-y: auto; }
|
||||
|
||||
Reference in New Issue
Block a user