558 lines
20 KiB
JavaScript
558 lines
20 KiB
JavaScript
|
/**
|
|||
|
* 对话框处理模块
|
|||
|
* @type {module}
|
|||
|
*/
|
|||
|
import { isValidElementName } from './utils.js';
|
|||
|
import { addElement, deleteElement, updateElementByPath } from './xml-handler.js';
|
|||
|
import { createNewConfig, saveFileAs } from './api.js';
|
|||
|
|
|||
|
/**
|
|||
|
* 显示添加元素对话框
|
|||
|
* @param {Element} parentElement - 父元素
|
|||
|
* @param {string} parentPath - 父元素路径
|
|||
|
* @param {Document} xmlDoc - XML文档对象
|
|||
|
* @param {Function} onSuccess - 成功回调函数
|
|||
|
* @param {Element} context - 组件上下文,用于访问shadowRoot
|
|||
|
*/
|
|||
|
export function showAddElementDialog(parentElement, parentPath, xmlDoc, onSuccess, context) {
|
|||
|
// 创建模态框
|
|||
|
const modal = document.createElement('div');
|
|||
|
modal.className = 'modal';
|
|||
|
modal.id = 'addElementModal';
|
|||
|
|
|||
|
modal.innerHTML = `
|
|||
|
<div class="modal-content">
|
|||
|
<div class="modal-header">
|
|||
|
<div class="modal-title">添加元素</div>
|
|||
|
<span class="close">×</span>
|
|||
|
</div>
|
|||
|
<div class="modal-body">
|
|||
|
<div class="form-group">
|
|||
|
<label for="elementName">元素名称</label>
|
|||
|
<input type="text" id="elementName" class="form-control" placeholder="输入元素名称" />
|
|||
|
<div id="elementNameError" class="error-message" style="display: none; font-size: 12px; margin-top: 5px;"></div>
|
|||
|
</div>
|
|||
|
<div class="form-group">
|
|||
|
<label for="elementValue">元素值 <small>(如果需要)</small></label>
|
|||
|
<input type="text" id="elementValue" class="form-control" placeholder="输入元素值" />
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
<div class="modal-footer">
|
|||
|
<button id="cancelAddElement" class="action-button secondary">取消</button>
|
|||
|
<button id="confirmAddElement" class="action-button">添加</button>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
`;
|
|||
|
|
|||
|
// 获取shadowRoot
|
|||
|
const shadowRoot = context.shadowRoot;
|
|||
|
shadowRoot.appendChild(modal);
|
|||
|
modal.style.display = 'block';
|
|||
|
|
|||
|
// 事件处理
|
|||
|
const closeBtn = modal.querySelector('.close');
|
|||
|
const cancelBtn = modal.querySelector('#cancelAddElement');
|
|||
|
const confirmBtn = modal.querySelector('#confirmAddElement');
|
|||
|
const nameInput = modal.querySelector('#elementName');
|
|||
|
const valueInput = modal.querySelector('#elementValue');
|
|||
|
const errorDiv = modal.querySelector('#elementNameError');
|
|||
|
|
|||
|
// 实时验证元素名称
|
|||
|
nameInput.addEventListener('input', () => {
|
|||
|
const name = nameInput.value.trim();
|
|||
|
const isValid = isValidElementName(name);
|
|||
|
|
|||
|
if (!name) {
|
|||
|
errorDiv.textContent = '元素名称不能为空';
|
|||
|
errorDiv.style.display = 'block';
|
|||
|
confirmBtn.disabled = true;
|
|||
|
} else if (!isValid) {
|
|||
|
errorDiv.textContent = '无效的元素名称。元素名称必须以字母或下划线开头,不能包含空格或特殊字符。';
|
|||
|
errorDiv.style.display = 'block';
|
|||
|
confirmBtn.disabled = true;
|
|||
|
} else {
|
|||
|
errorDiv.style.display = 'none';
|
|||
|
confirmBtn.disabled = false;
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
const closeModal = () => {
|
|||
|
modal.style.display = 'none';
|
|||
|
shadowRoot.removeChild(modal);
|
|||
|
};
|
|||
|
|
|||
|
closeBtn.addEventListener('click', closeModal);
|
|||
|
cancelBtn.addEventListener('click', closeModal);
|
|||
|
|
|||
|
confirmBtn.addEventListener('click', () => {
|
|||
|
const name = nameInput.value.trim();
|
|||
|
const value = valueInput.value;
|
|||
|
|
|||
|
if (!name) {
|
|||
|
alert('元素名称不能为空');
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
if (!isValidElementName(name)) {
|
|||
|
alert('无效的元素名称。元素名称必须以字母或下划线开头,不能包含空格或特殊字符。');
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// 添加元素
|
|||
|
addElement(xmlDoc, parentElement, name, value);
|
|||
|
|
|||
|
// 调用成功回调
|
|||
|
if (onSuccess && typeof onSuccess === 'function') {
|
|||
|
onSuccess();
|
|||
|
}
|
|||
|
|
|||
|
closeModal();
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 显示编辑元素对话框
|
|||
|
* @param {Element} element - 要编辑的元素
|
|||
|
* @param {string} elementPath - 元素路径
|
|||
|
* @param {Document} xmlDoc - XML文档对象
|
|||
|
* @param {Function} onSuccess - 成功回调函数
|
|||
|
* @param {Element} context - 组件上下文,用于访问shadowRoot
|
|||
|
*/
|
|||
|
export function showEditElementDialog(element, elementPath, xmlDoc, onSuccess, context) {
|
|||
|
// 创建模态框
|
|||
|
const modal = document.createElement('div');
|
|||
|
modal.className = 'modal';
|
|||
|
modal.id = 'editElementModal';
|
|||
|
|
|||
|
modal.innerHTML = `
|
|||
|
<div class="modal-content">
|
|||
|
<div class="modal-header">
|
|||
|
<div class="modal-title">编辑元素</div>
|
|||
|
<span class="close">×</span>
|
|||
|
</div>
|
|||
|
<div class="modal-body">
|
|||
|
<div class="form-group">
|
|||
|
<label for="elementPath">元素路径</label>
|
|||
|
<input type="text" id="elementPath" class="form-control" value="${elementPath}" readonly />
|
|||
|
</div>
|
|||
|
<div class="form-group">
|
|||
|
<label for="elementValue">元素值</label>
|
|||
|
<input type="text" id="elementValue" class="form-control" value="${element.textContent}" placeholder="输入元素值" />
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
<div class="modal-footer">
|
|||
|
<button id="cancelEditElement" class="action-button secondary">取消</button>
|
|||
|
<button id="confirmEditElement" class="action-button">保存</button>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
`;
|
|||
|
|
|||
|
// 获取shadowRoot
|
|||
|
const shadowRoot = context.shadowRoot;
|
|||
|
shadowRoot.appendChild(modal);
|
|||
|
modal.style.display = 'block';
|
|||
|
|
|||
|
// 事件处理
|
|||
|
const closeBtn = modal.querySelector('.close');
|
|||
|
const cancelBtn = modal.querySelector('#cancelEditElement');
|
|||
|
const confirmBtn = modal.querySelector('#confirmEditElement');
|
|||
|
const valueInput = modal.querySelector('#elementValue');
|
|||
|
|
|||
|
const closeModal = () => {
|
|||
|
modal.style.display = 'none';
|
|||
|
shadowRoot.removeChild(modal);
|
|||
|
};
|
|||
|
|
|||
|
closeBtn.addEventListener('click', closeModal);
|
|||
|
cancelBtn.addEventListener('click', closeModal);
|
|||
|
|
|||
|
confirmBtn.addEventListener('click', () => {
|
|||
|
const value = valueInput.value;
|
|||
|
|
|||
|
// 更新元素值
|
|||
|
updateElementByPath(xmlDoc, elementPath, value);
|
|||
|
|
|||
|
// 调用成功回调
|
|||
|
if (onSuccess && typeof onSuccess === 'function') {
|
|||
|
onSuccess();
|
|||
|
}
|
|||
|
|
|||
|
closeModal();
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 显示新建配置对话框
|
|||
|
* @param {Function} onSuccess - 成功回调函数
|
|||
|
* @param {Element} context - 上下文元素,用于获取shadowRoot
|
|||
|
*/
|
|||
|
export function showNewConfigDialog(onSuccess, context) {
|
|||
|
// 创建模态框
|
|||
|
const modal = document.createElement('div');
|
|||
|
modal.className = 'modal';
|
|||
|
modal.id = 'newConfigModal';
|
|||
|
|
|||
|
modal.innerHTML = `
|
|||
|
<div class="modal-content">
|
|||
|
<div class="modal-header">
|
|||
|
<div class="modal-title">创建新模型配置</div>
|
|||
|
<span class="close">×</span>
|
|||
|
</div>
|
|||
|
<div class="modal-body">
|
|||
|
<div class="form-group">
|
|||
|
<label for="newFileName">文件名</label>
|
|||
|
<input type="text" id="newFileName" class="form-control" placeholder="输入文件名 (例如: mymodel.mcfg)" />
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
<div class="modal-footer">
|
|||
|
<button id="cancelNewConfig" class="action-button secondary">取消</button>
|
|||
|
<button id="confirmNewConfig" class="action-button">创建</button>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
`;
|
|||
|
|
|||
|
// 获取shadowRoot
|
|||
|
const shadowRoot = context.shadowRoot;
|
|||
|
shadowRoot.appendChild(modal);
|
|||
|
modal.style.display = 'block';
|
|||
|
|
|||
|
// 事件处理
|
|||
|
const closeBtn = modal.querySelector('.close');
|
|||
|
const cancelBtn = modal.querySelector('#cancelNewConfig');
|
|||
|
const confirmBtn = modal.querySelector('#confirmNewConfig');
|
|||
|
|
|||
|
const closeModal = () => {
|
|||
|
modal.style.display = 'none';
|
|||
|
shadowRoot.removeChild(modal);
|
|||
|
};
|
|||
|
|
|||
|
closeBtn.addEventListener('click', closeModal);
|
|||
|
cancelBtn.addEventListener('click', closeModal);
|
|||
|
|
|||
|
confirmBtn.addEventListener('click', async () => {
|
|||
|
let fileName = modal.querySelector('#newFileName').value.trim();
|
|||
|
|
|||
|
if (!fileName) {
|
|||
|
alert('文件名不能为空');
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// 如果文件名不以.mcfg结尾,自动添加
|
|||
|
if (!fileName.endsWith('.mcfg')) {
|
|||
|
fileName += '.mcfg';
|
|||
|
}
|
|||
|
|
|||
|
try {
|
|||
|
const result = await createNewConfig(fileName);
|
|||
|
if (onSuccess && typeof onSuccess === 'function') {
|
|||
|
onSuccess(result);
|
|||
|
}
|
|||
|
closeModal();
|
|||
|
} catch (error) {
|
|||
|
if (error.message.includes('文件已存在')) {
|
|||
|
if (confirm('文件已存在,是否覆盖?')) {
|
|||
|
try {
|
|||
|
const result = await createNewConfig(fileName, true);
|
|||
|
if (onSuccess && typeof onSuccess === 'function') {
|
|||
|
onSuccess(result);
|
|||
|
}
|
|||
|
closeModal();
|
|||
|
} catch (retryError) {
|
|||
|
alert('创建文件失败: ' + retryError.message);
|
|||
|
}
|
|||
|
}
|
|||
|
} else {
|
|||
|
alert('创建文件失败: ' + error.message);
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 显示另存为对话框
|
|||
|
* @param {string} xmlContent - XML内容
|
|||
|
* @param {string} selectedFile - 当前选中的文件
|
|||
|
* @param {Function} onSuccess - 成功回调函数
|
|||
|
* @param {Element} context - 上下文元素,用于获取shadowRoot
|
|||
|
*/
|
|||
|
export function showSaveAsDialog(xmlContent, selectedFile, onSuccess, context) {
|
|||
|
// 创建模态框
|
|||
|
const modal = document.createElement('div');
|
|||
|
modal.className = 'modal';
|
|||
|
modal.id = 'saveAsModal';
|
|||
|
|
|||
|
modal.innerHTML = `
|
|||
|
<div class="modal-content">
|
|||
|
<div class="modal-header">
|
|||
|
<div class="modal-title">另存为</div>
|
|||
|
<span class="close">×</span>
|
|||
|
</div>
|
|||
|
<div class="modal-body">
|
|||
|
<div class="form-group">
|
|||
|
<label for="saveAsFileName">文件名</label>
|
|||
|
<input type="text" id="saveAsFileName" class="form-control" placeholder="输入文件名 (例如: mymodel.mcfg)" />
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
<div class="modal-footer">
|
|||
|
<button id="cancelSaveAs" class="action-button secondary">取消</button>
|
|||
|
<button id="confirmSaveAs" class="action-button">保存</button>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
`;
|
|||
|
|
|||
|
// 获取shadowRoot
|
|||
|
const shadowRoot = context.shadowRoot;
|
|||
|
shadowRoot.appendChild(modal);
|
|||
|
modal.style.display = 'block';
|
|||
|
|
|||
|
// 事件处理
|
|||
|
const closeBtn = modal.querySelector('.close');
|
|||
|
const cancelBtn = modal.querySelector('#cancelSaveAs');
|
|||
|
const confirmBtn = modal.querySelector('#confirmSaveAs');
|
|||
|
|
|||
|
const closeModal = () => {
|
|||
|
modal.style.display = 'none';
|
|||
|
shadowRoot.removeChild(modal);
|
|||
|
};
|
|||
|
|
|||
|
closeBtn.addEventListener('click', closeModal);
|
|||
|
cancelBtn.addEventListener('click', closeModal);
|
|||
|
|
|||
|
confirmBtn.addEventListener('click', async () => {
|
|||
|
let fileName = modal.querySelector('#saveAsFileName').value.trim();
|
|||
|
|
|||
|
if (!fileName) {
|
|||
|
alert('文件名不能为空');
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// 如果文件名不以.mcfg结尾,自动添加
|
|||
|
if (!fileName.endsWith('.mcfg')) {
|
|||
|
fileName += '.mcfg';
|
|||
|
}
|
|||
|
|
|||
|
try {
|
|||
|
const result = await saveFileAs(fileName, xmlContent, selectedFile);
|
|||
|
if (onSuccess && typeof onSuccess === 'function') {
|
|||
|
onSuccess(result);
|
|||
|
}
|
|||
|
closeModal();
|
|||
|
} catch (error) {
|
|||
|
if (error.message.includes('文件已存在')) {
|
|||
|
if (confirm('文件已存在,是否覆盖?')) {
|
|||
|
try {
|
|||
|
const result = await saveFileAs(fileName, xmlContent, selectedFile, true);
|
|||
|
if (onSuccess && typeof onSuccess === 'function') {
|
|||
|
onSuccess(result);
|
|||
|
}
|
|||
|
closeModal();
|
|||
|
} catch (retryError) {
|
|||
|
alert('保存失败: ' + retryError.message);
|
|||
|
}
|
|||
|
}
|
|||
|
} else {
|
|||
|
alert('保存失败: ' + error.message);
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 显示添加命令对话框
|
|||
|
* @param {Element} rootElement - XML根元素
|
|||
|
* @param {Document} xmlDoc - XML文档对象
|
|||
|
* @param {Function} onSuccess - 成功回调函数
|
|||
|
* @param {Element} context - 上下文元素,用于获取shadowRoot
|
|||
|
*/
|
|||
|
export function showAddCommandDialog(rootElement, xmlDoc, onSuccess, context) {
|
|||
|
// 创建模态框
|
|||
|
const modal = document.createElement('div');
|
|||
|
modal.className = 'modal';
|
|||
|
modal.id = 'addCommandModal';
|
|||
|
|
|||
|
modal.innerHTML = `
|
|||
|
<div class="modal-content">
|
|||
|
<div class="modal-header">
|
|||
|
<div class="modal-title">添加命令</div>
|
|||
|
<span class="close">×</span>
|
|||
|
</div>
|
|||
|
<div class="modal-body">
|
|||
|
<div class="form-group">
|
|||
|
<label for="commandName">命令名称</label>
|
|||
|
<input type="text" id="commandName" class="form-control" placeholder="输入命令名称" />
|
|||
|
</div>
|
|||
|
<div class="form-group">
|
|||
|
<label for="commandCall">命令调用</label>
|
|||
|
<input type="text" id="commandCall" class="form-control" placeholder="输入命令调用" />
|
|||
|
</div>
|
|||
|
<div class="form-group">
|
|||
|
<label for="commandDescription">命令描述</label>
|
|||
|
<input type="text" id="commandDescription" class="form-control" placeholder="输入命令描述" />
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
<div class="modal-footer">
|
|||
|
<button id="cancelAddCommand" class="action-button secondary">取消</button>
|
|||
|
<button id="confirmAddCommand" class="action-button">添加</button>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
`;
|
|||
|
|
|||
|
// 获取shadowRoot
|
|||
|
const shadowRoot = context.shadowRoot;
|
|||
|
shadowRoot.appendChild(modal);
|
|||
|
modal.style.display = 'block';
|
|||
|
|
|||
|
// 事件处理
|
|||
|
const closeBtn = modal.querySelector('.close');
|
|||
|
const cancelBtn = modal.querySelector('#cancelAddCommand');
|
|||
|
const confirmBtn = modal.querySelector('#confirmAddCommand');
|
|||
|
|
|||
|
const closeModal = () => {
|
|||
|
modal.style.display = 'none';
|
|||
|
shadowRoot.removeChild(modal);
|
|||
|
};
|
|||
|
|
|||
|
closeBtn.addEventListener('click', closeModal);
|
|||
|
cancelBtn.addEventListener('click', closeModal);
|
|||
|
|
|||
|
confirmBtn.addEventListener('click', () => {
|
|||
|
const name = modal.querySelector('#commandName').value.trim();
|
|||
|
const call = modal.querySelector('#commandCall').value.trim();
|
|||
|
const description = modal.querySelector('#commandDescription').value.trim();
|
|||
|
|
|||
|
if (!name) {
|
|||
|
alert('命令名称不能为空');
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
if (!call) {
|
|||
|
alert('命令调用不能为空');
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
try {
|
|||
|
// 查找或创建CommandList元素
|
|||
|
let commandListElement = rootElement.querySelector('CommandList');
|
|||
|
if (!commandListElement) {
|
|||
|
commandListElement = xmlDoc.createElement('CommandList');
|
|||
|
rootElement.appendChild(commandListElement);
|
|||
|
}
|
|||
|
|
|||
|
// 创建新Command元素
|
|||
|
const commandElement = xmlDoc.createElement('Command');
|
|||
|
commandElement.setAttribute('Name', name);
|
|||
|
commandElement.setAttribute('Call', call);
|
|||
|
commandElement.setAttribute('Description', description || `${name}描述`);
|
|||
|
|
|||
|
// 添加到CommandList
|
|||
|
commandListElement.appendChild(commandElement);
|
|||
|
|
|||
|
// 调用成功回调
|
|||
|
if (onSuccess && typeof onSuccess === 'function') {
|
|||
|
onSuccess();
|
|||
|
}
|
|||
|
|
|||
|
closeModal();
|
|||
|
} catch (error) {
|
|||
|
console.error('添加命令失败:', error);
|
|||
|
alert('添加命令失败: ' + error.message);
|
|||
|
}
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 显示编辑命令对话框
|
|||
|
* @param {Element} commandElement - 命令元素
|
|||
|
* @param {number} index - 命令索引
|
|||
|
* @param {Function} onSuccess - 成功回调函数
|
|||
|
* @param {Element} context - 上下文元素,用于获取shadowRoot
|
|||
|
*/
|
|||
|
export function showEditCommandDialog(commandElement, index, onSuccess, context) {
|
|||
|
// 获取当前命令属性
|
|||
|
const name = commandElement.getAttribute('Name') || '';
|
|||
|
const call = commandElement.getAttribute('Call') || '';
|
|||
|
const description = commandElement.getAttribute('Description') || '';
|
|||
|
|
|||
|
// 创建模态框
|
|||
|
const modal = document.createElement('div');
|
|||
|
modal.className = 'modal';
|
|||
|
modal.id = 'editCommandModal';
|
|||
|
|
|||
|
modal.innerHTML = `
|
|||
|
<div class="modal-content">
|
|||
|
<div class="modal-header">
|
|||
|
<div class="modal-title">编辑命令</div>
|
|||
|
<span class="close">×</span>
|
|||
|
</div>
|
|||
|
<div class="modal-body">
|
|||
|
<div class="form-group">
|
|||
|
<label for="commandName">命令名称</label>
|
|||
|
<input type="text" id="commandName" class="form-control" value="${name}" placeholder="输入命令名称" />
|
|||
|
</div>
|
|||
|
<div class="form-group">
|
|||
|
<label for="commandCall">命令调用</label>
|
|||
|
<input type="text" id="commandCall" class="form-control" value="${call}" placeholder="输入命令调用" />
|
|||
|
</div>
|
|||
|
<div class="form-group">
|
|||
|
<label for="commandDescription">命令描述</label>
|
|||
|
<input type="text" id="commandDescription" class="form-control" value="${description}" placeholder="输入命令描述" />
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
<div class="modal-footer">
|
|||
|
<button id="cancelEditCommand" class="action-button secondary">取消</button>
|
|||
|
<button id="confirmEditCommand" class="action-button">保存</button>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
`;
|
|||
|
|
|||
|
// 获取shadowRoot
|
|||
|
const shadowRoot = context.shadowRoot;
|
|||
|
shadowRoot.appendChild(modal);
|
|||
|
modal.style.display = 'block';
|
|||
|
|
|||
|
// 事件处理
|
|||
|
const closeBtn = modal.querySelector('.close');
|
|||
|
const cancelBtn = modal.querySelector('#cancelEditCommand');
|
|||
|
const confirmBtn = modal.querySelector('#confirmEditCommand');
|
|||
|
|
|||
|
const closeModal = () => {
|
|||
|
modal.style.display = 'none';
|
|||
|
shadowRoot.removeChild(modal);
|
|||
|
};
|
|||
|
|
|||
|
closeBtn.addEventListener('click', closeModal);
|
|||
|
cancelBtn.addEventListener('click', closeModal);
|
|||
|
|
|||
|
confirmBtn.addEventListener('click', () => {
|
|||
|
const newName = modal.querySelector('#commandName').value.trim();
|
|||
|
const newCall = modal.querySelector('#commandCall').value.trim();
|
|||
|
const newDescription = modal.querySelector('#commandDescription').value.trim();
|
|||
|
|
|||
|
if (!newName) {
|
|||
|
alert('命令名称不能为空');
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
if (!newCall) {
|
|||
|
alert('命令调用不能为空');
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
try {
|
|||
|
// 更新命令属性
|
|||
|
commandElement.setAttribute('Name', newName);
|
|||
|
commandElement.setAttribute('Call', newCall);
|
|||
|
commandElement.setAttribute('Description', newDescription || `${newName}描述`);
|
|||
|
|
|||
|
// 调用成功回调
|
|||
|
if (onSuccess && typeof onSuccess === 'function') {
|
|||
|
onSuccess();
|
|||
|
}
|
|||
|
|
|||
|
closeModal();
|
|||
|
} catch (error) {
|
|||
|
console.error('编辑命令失败:', error);
|
|||
|
alert('编辑命令失败: ' + error.message);
|
|||
|
}
|
|||
|
});
|
|||
|
}
|