// 外部系统连接管理:凭据只提交、不回显;查询能力在下一轮 build_agent 时按用户动态挂载。
import { $ } from "./dom.js";
import { api } from "./api.js";
import { escapeHtml, fmtTime } from "./format.js";
import { dialogConfirm, message } from "./dialog.js";
let editingId = "";
let providerReady = false;
let definitions = [];
function resetForm() {
editingId = "";
$("ext-form-title").textContent = "连接 Factory MES";
$("ext-name").value = "Factory MES";
$("ext-name").disabled = false;
$("ext-definition").disabled = false;
$("ext-username").value = "";
$("ext-password").value = "";
$("ext-err").textContent = "";
$("ext-save").textContent = "连接并验证";
$("ext-form-cancel").hidden = true;
}
export function closeExternalSystemsModal() {
$("external-modal").classList.remove("show");
resetForm();
}
async function openExternalSystemsModal() {
$("external-modal").classList.add("show");
resetForm();
await loadExternalSystems();
}
function cardHtml(item) {
const good = item.status === "active";
const badge = good ? "已连接" : (item.status === "disabled" ? "系统已停用" : "需更新凭据");
const checked = item.last_verified_at ? fmtTime(item.last_verified_at) : "尚未验证";
return `
${escapeHtml(item.name)}${badge}
${escapeHtml(item.system_name || "Factory MES")} · ${escapeHtml(item.username_masked || "***")} · 最近验证 ${escapeHtml(checked)}
`;
}
async function loadExternalSystems() {
const provider = $("ext-provider");
const list = $("ext-list");
provider.textContent = "加载中…";
list.innerHTML = '加载中…
';
try {
const [p, systems] = await Promise.all([
api("GET", "/v1/external-system-providers"),
api("GET", "/v1/external-systems"),
]);
const factory = (p.providers || []).find((x) => x.provider === "factory_mes");
definitions = (factory && factory.definitions) || [];
providerReady = !!(factory && factory.configured && definitions.length);
$("ext-definition").innerHTML = definitions.map(x =>
``
).join("");
if (!editingId && definitions.length) $("ext-name").value = definitions[0].name;
provider.textContent = providerReady
? `管理员已配置 ${definitions.length} 个 MES 系统,请选择后使用自己的 MES 账号连接`
: `暂没有可连接的 MES 系统${factory && factory.reason ? ":" + factory.reason : ",请联系管理员配置"}`;
$("ext-save").disabled = !providerReady;
const rows = systems.results || [];
list.innerHTML = rows.length
? rows.map(cardHtml).join("")
: '还没有外部系统连接。填写下方 MES 账号后,助手即可按你的 MES 权限查询。
';
} catch (e) {
providerReady = false;
provider.textContent = "加载失败";
list.innerHTML = `${escapeHtml(e.message)}
`;
$("ext-save").disabled = true;
}
}
$("hd-external").onclick = openExternalSystemsModal;
$("ext-close").onclick = closeExternalSystemsModal;
$("external-modal").addEventListener("click", (e) => {
if (e.target.id === "external-modal") closeExternalSystemsModal();
});
$("ext-form-cancel").onclick = resetForm;
$("ext-definition").onchange = () => {
if (editingId) return;
const selected = definitions.find(x => x.definition_id === $("ext-definition").value);
if (selected) $("ext-name").value = selected.name;
};
$("ext-form").addEventListener("submit", async (e) => {
e.preventDefault();
if (!providerReady) return;
const username = $("ext-username").value.trim();
const password = $("ext-password").value;
const name = $("ext-name").value.trim();
const definitionId = $("ext-definition").value;
if (!username || !password || (!editingId && (!name || !definitionId))) {
$("ext-err").textContent = "请填写连接名称、MES 用户名和密码";
return;
}
const btn = $("ext-save");
btn.disabled = true;
btn.textContent = "正在验证…";
$("ext-err").textContent = "";
try {
if (editingId) {
await api("PUT", `/v1/external-systems/${editingId}/credentials`, { username, password });
message("Factory MES 凭据已更新", "success");
} else {
await api("POST", "/v1/external-systems", {
definition_id: definitionId, name, username, password,
});
message("Factory MES 已连接;下一轮对话即可使用", "success");
}
resetForm();
await loadExternalSystems();
} catch (err) {
$("ext-err").textContent = err.message;
} finally {
btn.disabled = !providerReady;
btn.textContent = editingId ? "验证并更新" : "连接并验证";
}
});
$("ext-list").addEventListener("click", async (e) => {
const card = e.target.closest(".ext-card");
if (!card) return;
const id = card.dataset.id;
if (e.target.closest("[data-ext-edit]")) {
editingId = id;
$("ext-form-title").textContent = "更新 Factory MES 凭据";
$("ext-name").value = card.querySelector(".ext-card-name").textContent;
$("ext-name").disabled = true;
$("ext-definition").disabled = true;
$("ext-username").value = "";
$("ext-password").value = "";
$("ext-save").textContent = "验证并更新";
$("ext-form-cancel").hidden = false;
$("ext-username").focus();
return;
}
if (e.target.closest("[data-ext-test]")) {
const btn = e.target.closest("button");
btn.disabled = true;
try {
const result = await api("POST", `/v1/external-systems/${id}/test`);
message(result.ok ? `连接正常,可用接口 ${result.operation_count || 0} 个` : `连接失败:${result.error}`, result.ok ? "success" : "error");
await loadExternalSystems();
} catch (err) { message("测试失败:" + err.message, "error"); }
finally { btn.disabled = false; }
return;
}
if (e.target.closest("[data-ext-delete]")) {
const name = card.querySelector(".ext-card-name").textContent;
if (!await dialogConfirm({ title:"断开外部系统", message:`断开「${name}」?保存的 MES 密文凭据和连接配置将被清除。`, okText:"断开", danger:true })) return;
try {
await api("DELETE", `/v1/external-systems/${id}`);
message("外部系统已断开", "success");
resetForm();
await loadExternalSystems();
} catch (err) { message("断开失败:" + err.message, "error"); }
}
});