You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
290 lines
10 KiB
290 lines
10 KiB
document.addEventListener('DOMContentLoaded', async () => {
|
|
try {
|
|
const response = await fetch('/api/config/defaults');
|
|
const result = await response.json();
|
|
|
|
if (result.success && result.config) {
|
|
const config = result.config;
|
|
|
|
if (config.brain) {
|
|
if (config.brain.username) {
|
|
document.getElementById('brainUsername').value = config.brain.username;
|
|
}
|
|
if (config.brain.password) {
|
|
document.getElementById('brainPassword').value = config.brain.password;
|
|
}
|
|
}
|
|
|
|
if (config.llm) {
|
|
if (config.llm.api_key) {
|
|
document.getElementById('llmApiKey').value = config.llm.api_key;
|
|
}
|
|
if (config.llm.base_url) {
|
|
document.getElementById('llmBaseUrl').value = config.llm.base_url;
|
|
}
|
|
if (config.llm.model) {
|
|
document.getElementById('llmModel').value = config.llm.model;
|
|
}
|
|
}
|
|
|
|
if (config.transformer) {
|
|
if (config.transformer.top_n_datafield) {
|
|
document.getElementById('topNDatafield').value = config.transformer.top_n_datafield;
|
|
}
|
|
if (config.transformer.data_type) {
|
|
document.getElementById('dataType').value = config.transformer.data_type;
|
|
}
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.error('加载默认配置失败:', error);
|
|
}
|
|
});
|
|
|
|
const form = document.getElementById('transformerForm');
|
|
const submitBtn = document.getElementById('submitBtn');
|
|
const downloadBtn = document.getElementById('downloadBtn');
|
|
const loginAndFetchBtn = document.getElementById('loginAndFetchBtn');
|
|
const regionSelect = document.getElementById('region');
|
|
const delaySelect = document.getElementById('delay');
|
|
const universeSelect = document.getElementById('universe');
|
|
const dataTypeSelect = document.getElementById('dataType');
|
|
const categoryButtons = document.getElementById('category-buttons');
|
|
|
|
let optionsData = {};
|
|
|
|
dataTypeSelect.addEventListener('change', function() {
|
|
if (this.value === 'VECTOR') {
|
|
if (!confirm("请确保您输入的原型Alpha中正确地使用了vector operator,否则极容易造成数据类型错误!")) {
|
|
this.value = 'MATRIX';
|
|
}
|
|
}
|
|
});
|
|
|
|
loginAndFetchBtn.addEventListener('click', async () => {
|
|
const username = document.getElementById('brainUsername').value.trim();
|
|
const password = document.getElementById('brainPassword').value;
|
|
|
|
if (!username || !password) {
|
|
alert('请先填写BRAIN用户名和密码');
|
|
return;
|
|
}
|
|
|
|
loginAndFetchBtn.disabled = true;
|
|
loginAndFetchBtn.textContent = '正在登录...';
|
|
|
|
try {
|
|
const response = await fetch('/api/transformer/login-and-fetch-options', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ username, password })
|
|
});
|
|
|
|
const result = await response.json();
|
|
|
|
if (result.success) {
|
|
optionsData = result.options;
|
|
|
|
populateRegionSelect();
|
|
regionSelect.disabled = false;
|
|
|
|
if (result.categories) {
|
|
populateCategoryButtons(result.categories);
|
|
}
|
|
|
|
loginAndFetchBtn.textContent = '登录成功';
|
|
} else {
|
|
alert('登录失败: ' + result.error);
|
|
loginAndFetchBtn.disabled = false;
|
|
loginAndFetchBtn.textContent = '登录BRAIN并获取选项';
|
|
}
|
|
} catch (error) {
|
|
alert('登录出错: ' + error.message);
|
|
loginAndFetchBtn.disabled = false;
|
|
loginAndFetchBtn.textContent = '登录BRAIN并获取选项';
|
|
}
|
|
});
|
|
|
|
function populateRegionSelect() {
|
|
while (regionSelect.options.length > 1) {
|
|
regionSelect.remove(1);
|
|
}
|
|
|
|
const regions = Object.keys(optionsData);
|
|
regions.forEach(region => {
|
|
const option = document.createElement('option');
|
|
option.value = region;
|
|
option.textContent = region;
|
|
regionSelect.appendChild(option);
|
|
});
|
|
}
|
|
|
|
function populateCategoryButtons(categories) {
|
|
categories.forEach(category => {
|
|
const btn = document.createElement('button');
|
|
btn.type = 'button';
|
|
btn.dataset.value = category.id || category;
|
|
btn.textContent = category.name || category;
|
|
btn.onclick = function() { toggleCategory(this); };
|
|
btn.className = 'btn';
|
|
btn.style.cssText = 'padding: 4px 12px; font-size: 11px;';
|
|
categoryButtons.appendChild(btn);
|
|
});
|
|
}
|
|
|
|
function toggleCategory(btn) {
|
|
const allBtn = document.getElementById('cat-all');
|
|
const isAllBtn = (btn === allBtn);
|
|
|
|
if (isAllBtn) {
|
|
allBtn.style.backgroundColor = '#000080';
|
|
allBtn.style.color = 'white';
|
|
|
|
const otherBtns = categoryButtons.querySelectorAll('button:not(#cat-all)');
|
|
otherBtns.forEach(b => {
|
|
b.style.backgroundColor = '#c0c0c0';
|
|
b.style.color = 'black';
|
|
});
|
|
} else {
|
|
if (btn.style.backgroundColor === 'rgb(0, 0, 128)') {
|
|
btn.style.backgroundColor = '#c0c0c0';
|
|
btn.style.color = 'black';
|
|
} else {
|
|
btn.style.backgroundColor = '#000080';
|
|
btn.style.color = 'white';
|
|
}
|
|
|
|
const anySelected = categoryButtons.querySelectorAll('button:not(#cat-all)');
|
|
let hasSelected = false;
|
|
anySelected.forEach(b => {
|
|
if (b.style.backgroundColor === 'rgb(0, 0, 128)') {
|
|
hasSelected = true;
|
|
}
|
|
});
|
|
|
|
if (hasSelected) {
|
|
allBtn.style.backgroundColor = '#c0c0c0';
|
|
allBtn.style.color = 'black';
|
|
} else {
|
|
allBtn.style.backgroundColor = '#000080';
|
|
allBtn.style.color = 'white';
|
|
}
|
|
}
|
|
}
|
|
|
|
regionSelect.addEventListener('change', () => {
|
|
const selectedRegion = regionSelect.value;
|
|
|
|
delaySelect.innerHTML = '<option value="">-- 先选择地区 --</option>';
|
|
universeSelect.innerHTML = '<option value="">-- 先选择Delay --</option>';
|
|
delaySelect.disabled = true;
|
|
universeSelect.disabled = true;
|
|
|
|
if (selectedRegion && optionsData[selectedRegion]) {
|
|
const delays = Object.keys(optionsData[selectedRegion]);
|
|
delays.forEach(delay => {
|
|
const option = document.createElement('option');
|
|
option.value = delay;
|
|
option.textContent = delay;
|
|
delaySelect.appendChild(option);
|
|
});
|
|
delaySelect.disabled = false;
|
|
}
|
|
});
|
|
|
|
delaySelect.addEventListener('change', () => {
|
|
const selectedRegion = regionSelect.value;
|
|
const selectedDelay = delaySelect.value;
|
|
|
|
universeSelect.innerHTML = '<option value="">-- 先选择Delay --</option>';
|
|
universeSelect.disabled = true;
|
|
|
|
if (selectedRegion && selectedDelay && optionsData[selectedRegion][selectedDelay]) {
|
|
const universes = optionsData[selectedRegion][selectedDelay];
|
|
universes.forEach(universe => {
|
|
const option = document.createElement('option');
|
|
option.value = universe;
|
|
option.textContent = universe;
|
|
universeSelect.appendChild(option);
|
|
});
|
|
universeSelect.disabled = false;
|
|
}
|
|
});
|
|
|
|
form.addEventListener('submit', async (e) => {
|
|
e.preventDefault();
|
|
|
|
const formData = {
|
|
alpha_id: document.getElementById('alphaId').value.trim(),
|
|
llm_api_key: document.getElementById('llmApiKey').value.trim(),
|
|
llm_base_url: document.getElementById('llmBaseUrl').value.trim(),
|
|
llm_model: document.getElementById('llmModel').value.trim(),
|
|
brain_username: document.getElementById('brainUsername').value.trim(),
|
|
brain_password: document.getElementById('brainPassword').value.trim(),
|
|
top_n_datafield: parseInt(document.getElementById('topNDatafield').value) || 50,
|
|
data_type: document.getElementById('dataType').value || 'MATRIX'
|
|
};
|
|
|
|
const region = document.getElementById('region').value;
|
|
const delay = document.getElementById('delay').value;
|
|
const universe = document.getElementById('universe').value;
|
|
|
|
if (region) formData.user_region = region;
|
|
if (delay) formData.user_delay = parseInt(delay);
|
|
if (universe) formData.user_universe = universe;
|
|
|
|
const allBtn = document.getElementById('cat-all');
|
|
let selectedCategories = [];
|
|
|
|
if (allBtn.style.backgroundColor !== 'rgb(0, 0, 128)') {
|
|
const categoryBtns = categoryButtons.querySelectorAll('button:not(#cat-all)');
|
|
categoryBtns.forEach(btn => {
|
|
if (btn.style.backgroundColor === 'rgb(0, 0, 128)') {
|
|
selectedCategories.push(btn.dataset.value);
|
|
}
|
|
});
|
|
|
|
if (selectedCategories.length > 0) {
|
|
formData.user_category = selectedCategories;
|
|
}
|
|
}
|
|
|
|
submitBtn.disabled = true;
|
|
submitBtn.textContent = '处理中...';
|
|
|
|
try {
|
|
const response = await fetch('/api/generate', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify(formData)
|
|
});
|
|
|
|
const result = await response.json();
|
|
|
|
if (result.success) {
|
|
const successCount = result.expressions_success ? result.expressions_success.length : 0;
|
|
const candidateCount = result.candidates ? result.candidates.length : 0;
|
|
const errorCount = result.expressions_error ? result.expressions_error.length : 0;
|
|
alert('生成完成!成功: ' + successCount + ' 个, 候选: ' + candidateCount + ' 个, 错误: ' + errorCount + ' 个');
|
|
|
|
// 显示下载按钮
|
|
downloadBtn.style.display = 'block';
|
|
downloadBtn.onclick = function() {
|
|
const alphaId = document.getElementById('alphaId').value.trim();
|
|
window.location.href = '/api/download/' + alphaId;
|
|
};
|
|
} else {
|
|
alert('生成失败: ' + (result.error || '未知错误'));
|
|
downloadBtn.style.display = 'none';
|
|
}
|
|
|
|
} catch (error) {
|
|
alert('请求失败: ' + error.message);
|
|
downloadBtn.style.display = 'none';
|
|
} finally {
|
|
submitBtn.disabled = false;
|
|
submitBtn.textContent = '生成变种';
|
|
}
|
|
});
|
|
|