优化后端和前端
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
};
|
||||
|
||||
let reasoningPickerControl = null;
|
||||
let validatedCommandsVisible = false;
|
||||
|
||||
function make(tag, className, html) {
|
||||
const node = document.createElement(tag);
|
||||
@@ -61,8 +62,13 @@
|
||||
const target = normalizedCanTarget(operation.target);
|
||||
const onOff = normalizedOnOff(parameters.state ?? parameters.power);
|
||||
const hyphenated = (value) => String(value || "").replaceAll("_", "-");
|
||||
const parseSource = String(operation.parse_source || "");
|
||||
const command = (category, text, channel = "CAN1", frame = "") => ({
|
||||
channel, category, command: text, ...(frame ? { frame } : {}),
|
||||
channel,
|
||||
category,
|
||||
command: text,
|
||||
...(frame ? { frame } : {}),
|
||||
...(parseSource ? { parseSource } : {}),
|
||||
});
|
||||
const hexByte = (value) => Number(value).toString(16).padStart(2, "0").toUpperCase();
|
||||
const otaCan0Frame = (opcode, selector, argument) => {
|
||||
@@ -271,7 +277,15 @@
|
||||
if (item) commands.push(item);
|
||||
});
|
||||
});
|
||||
return [...new Map(commands.map((item) => [`${item.channel}:${item.command}`, item])).values()];
|
||||
const unique = new Map();
|
||||
commands.forEach((item) => {
|
||||
const key = `${item.channel}:${item.command}`;
|
||||
const previous = unique.get(key);
|
||||
if (!previous || (previous.parseSource !== "local_rule" && item.parseSource === "local_rule")) {
|
||||
unique.set(key, item);
|
||||
}
|
||||
});
|
||||
return [...unique.values()];
|
||||
}
|
||||
|
||||
function renderParsedCanCommands(result, { message = "" } = {}) {
|
||||
@@ -285,7 +299,11 @@
|
||||
if (commands.length) {
|
||||
list.innerHTML = `<ol>${commands.map((item) => `
|
||||
<li data-can-channel="${escapeHtml(item.channel)}">
|
||||
<span><b class="v2-can-command-channel">${escapeHtml(item.channel)}</b>${escapeHtml(item.category)}</span>
|
||||
<span>
|
||||
<b class="v2-can-command-channel">${escapeHtml(item.channel)}</b>
|
||||
${item.parseSource ? `<b class="v2-can-command-source" data-parse-source="${escapeHtml(item.parseSource)}">${item.parseSource === "local_rule" ? "本地规则" : "云端模型"}</b>` : ""}
|
||||
${escapeHtml(item.category)}
|
||||
</span>
|
||||
<code>${escapeHtml(item.command)}</code>
|
||||
${item.frame ? `<small class="v2-can-command-frame">seat-ota · ${escapeHtml(item.frame)}</small>` : ""}
|
||||
</li>`).join("")}</ol>`;
|
||||
@@ -1348,10 +1366,19 @@
|
||||
});
|
||||
$("#v2LogFilter")?.addEventListener("change", renderSyncLogs);
|
||||
$("#requestForm")?.addEventListener("submit", () => {
|
||||
validatedCommandsVisible = false;
|
||||
renderParsedCanCommands(null, { message: "正在解析自然语言并生成 CAN 控制指令…" });
|
||||
});
|
||||
window.addEventListener("cognitive-agent:validated-can-commands", (event) => {
|
||||
const result = event.detail || {};
|
||||
validatedCommandsVisible = parsedCanCommands(result).length > 0;
|
||||
renderParsedCanCommands(result, {
|
||||
message: "已完成白名单校验,正在下发控制指令…",
|
||||
});
|
||||
});
|
||||
window.addEventListener("cognitive-agent:result", (event) => {
|
||||
const result = event.detail || {};
|
||||
validatedCommandsVisible = parsedCanCommands(result).length > 0;
|
||||
renderParsedCanCommands(result);
|
||||
appendSyncLog({
|
||||
key: result.request_id ? `result:${result.request_id}` : "",
|
||||
@@ -1375,8 +1402,10 @@
|
||||
});
|
||||
renderSyncedDevices();
|
||||
}
|
||||
if (event.detail?.error) {
|
||||
if (event.detail?.error && !validatedCommandsVisible) {
|
||||
renderParsedCanCommands(null, { message: "本次请求未生成 CAN 控制指令" });
|
||||
}
|
||||
if (event.detail?.error) {
|
||||
appendSyncLog({ category: "task", title: "编排任务执行失败", detail: event.detail.error.message || "请求失败", status: "error" });
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user