/** * 服务配置组件 - 主入口文件 * @type {module} */ import { FileOperations } from './service-config/file-operations.js'; import { XmlUtils } from './service-config/xml-utils.js'; import { CommandDialog } from './service-config/command-dialog.js'; import { DateTimeDialog } from './service-config/date-time-dialog.js'; import { VisualEditor } from './service-config/visual-editor.js'; class ServiceConfig extends HTMLElement { constructor() { super(); this.attachShadow({ mode: 'open' }); this.selectedFile = null; this.xmlContent = ''; this.xmlDoc = null; this.isEdited = false; this.serviceFiles = []; this.isActive = true; // 添加活动状态标记 } async connectedCallback() { this.isActive = true; this.render(); await this.loadServiceFiles(); this.setupEventListeners(); // 延迟调用renderComplete,确保DOM已更新 setTimeout(() => { this.renderComplete(); }, 100); } disconnectedCallback() { this.isActive = false; } // 在组件完成渲染后恢复状态 renderComplete() { // 在DOM渲染完成后更新文件选择器 setTimeout(() => { // 如果有选中的文件,尝试恢复它 if (this.selectedFile && (this.xmlContent || this.xmlDoc)) { const fileSelector = this.shadowRoot.getElementById('fileSelector'); if (fileSelector) { // 确认文件在列表中 const fileExists = Array.from(fileSelector.options).some(opt => opt.value === this.selectedFile); if (fileExists) { // 设置选中的文件 fileSelector.value = this.selectedFile; // 更新内容显示 const contentArea = this.shadowRoot.querySelector('#contentArea'); if (contentArea && this.xmlDoc) { contentArea.innerHTML = `
`; const visualEditor = this.shadowRoot.querySelector('#visualEditor'); if (visualEditor) { VisualEditor.render(visualEditor, this.xmlDoc, () => { this.updateXmlFromEditor(); this.markEdited(); }); // 恢复编辑状态标记 if (this.isEdited) { this.markEdited(); } } } else { console.log('ServiceConfig: 无法找到内容区域或XML文档不存在'); } } else { // 文件不存在,清除状态 this.selectedFile = null; this.xmlContent = ''; this.xmlDoc = null; this.isEdited = false; } } else { console.log('ServiceConfig: 未找到文件选择器'); } } }, 50); // 增加延迟确保DOM已完全加载 } // 重新激活组件的方法(当标签页重新被选中时调用) async reactivate() { if (this.isActive) { return; } this.isActive = true; try { // 先重新渲染一次UI以确保Shadow DOM结构完整 this.render(); // 加载文件列表 await this.loadServiceFiles(); // 设置事件监听器 this.setupEventListeners(); // 调用renderComplete来恢复状态 this.renderComplete(); } catch (error) { console.error('ServiceConfig: 重新激活组件时出错:', error); } } async loadServiceFiles() { this.serviceFiles = await FileOperations.loadServiceFiles(); this.updateFileSelector(); } updateFileSelector() { const fileSelector = this.shadowRoot.getElementById('fileSelector'); if (!fileSelector) return; // 清空现有选项 fileSelector.innerHTML = ''; // 按修改时间排序,最新的在前面 const sortedFiles = [...this.serviceFiles].sort((a, b) => new Date(b.mtime) - new Date(a.mtime) ); // 添加文件到选择器 sortedFiles.forEach(file => { const option = document.createElement('option'); option.value = file.path; option.textContent = file.name; fileSelector.appendChild(option); }); } async loadFileContent(filePath) { const result = await FileOperations.loadFileContent(filePath); if (result.error) { const configContent = this.shadowRoot.querySelector('.config-content'); configContent.innerHTML = `

加载失败

${result.error}

${result.content ? `
${XmlUtils.escapeHtml(result.content)}
` : ''}
`; return; } this.selectedFile = filePath; this.xmlContent = result.content; this.xmlDoc = result.xmlDoc; this.updateFileContent(); this.resetEditState(); } updateFileContent() { const contentArea = this.shadowRoot.querySelector('#contentArea'); if (!this.xmlDoc || !this.selectedFile) { contentArea.innerHTML = `
请选择一个服务配置文件查看内容
`; return; } contentArea.innerHTML = `
`; const visualEditor = this.shadowRoot.querySelector('#visualEditor'); if (visualEditor) { VisualEditor.render(visualEditor, this.xmlDoc, () => { this.updateXmlFromEditor(); this.markEdited(); }); } } render() { this.shadowRoot.innerHTML = `
服务配置文件:
请选择一个服务配置文件查看内容
`; } // 检查是否需要保存当前更改 async checkSaveNeeded() { if (this.isEdited) { // 使用自定义对话框替代简单的confirm const dialogResult = await new Promise(resolve => { // 创建模态框 const modal = document.createElement('div'); modal.className = 'modal'; modal.id = 'saveConfirmModal'; modal.innerHTML = ` `; document.body.appendChild(modal); // 添加事件监听 const saveBtn = modal.querySelector('#saveBtn'); const dontSaveBtn = modal.querySelector('#dontSaveBtn'); const cancelBtn = modal.querySelector('#cancelBtn'); const closeModal = () => { document.body.removeChild(modal); }; saveBtn.addEventListener('click', () => { closeModal(); resolve('save'); }); dontSaveBtn.addEventListener('click', () => { closeModal(); resolve('dont-save'); }); cancelBtn.addEventListener('click', () => { closeModal(); resolve('cancel'); }); // 点击模态窗口外部也取消 modal.addEventListener('click', (event) => { if (event.target === modal) { closeModal(); resolve('cancel'); } }); }); // 根据对话框结果执行相应操作 if (dialogResult === 'save') { try { // 确保获取当前可视化编辑器的所有值更新到XML文档 this.updateXmlFromEditor(); // 保存文件 await FileOperations.saveFileContent(this.selectedFile, this.xmlContent); this.resetEditState(); return true; // 继续执行后续操作 } catch (error) { console.error('保存出错:', error); alert('保存失败: ' + error.message); return false; // 保存失败,不继续执行 } } else if (dialogResult === 'dont-save') { // 不保存,但继续执行后续操作 return true; } else { // 用户取消,不执行后续操作 return false; } } // 没有编辑状态,直接返回true允许继续操作 return true; } setupEventListeners() { // 文件选择器 const fileSelector = this.shadowRoot.getElementById('fileSelector'); fileSelector.addEventListener('change', async (e) => { const filePath = e.target.value; if (filePath) { // 检查是否需要保存当前文件 if (await this.checkSaveNeeded()) { this.loadFileContent(filePath); } else { // 如果用户取消或保存失败,恢复选择器的值 fileSelector.value = this.selectedFile || ''; } } }); // 刷新文件列表 const refreshButton = this.shadowRoot.getElementById('refreshFiles'); refreshButton.addEventListener('click', async () => { // 检查是否需要保存当前文件 if (await this.checkSaveNeeded()) { refreshButton.classList.add('refreshing'); try { // 重新加载文件列表 await this.loadServiceFiles(); // 清除编辑状态和内容 this.resetEditState(); // 清空内容区域 this.xmlContent = ''; this.xmlDoc = null; const contentArea = this.shadowRoot.querySelector('#contentArea'); if (contentArea) { contentArea.innerHTML = `
请选择一个服务配置文件查看内容
`; } // 清空文件选择 const fileSelector = this.shadowRoot.getElementById('fileSelector'); if (fileSelector) { fileSelector.value = ''; } // 重置选中的文件 this.selectedFile = null; } catch (error) { console.error('刷新文件列表失败:', error); alert('刷新文件列表失败: ' + error.message); } finally { // 无论成功失败,都移除刷新动画 setTimeout(() => { refreshButton.classList.remove('refreshing'); }, 500); } } // 如果用户点击取消,什么也不做,保留当前内容 }); // 新建配置 const newButton = this.shadowRoot.getElementById('newConfig'); newButton.addEventListener('click', async () => { // 检查是否需要保存当前文件 if (await this.checkSaveNeeded()) { CommandDialog.showNewConfigDialog(async (fileName) => { try { const result = await FileOperations.createNewConfig(fileName); await this.loadServiceFiles(); await this.loadFileContent(result.path); } catch (error) { alert('创建失败: ' + error.message); } }); } }); // 保存配置 const saveButton = this.shadowRoot.getElementById('saveConfig'); saveButton.addEventListener('click', async () => { if (!this.selectedFile) { alert('请先选择一个文件或创建新文件'); return; } try { // 确保获取当前可视化编辑器的所有值更新到XML文档 this.updateXmlFromEditor(); // 保存文件 await FileOperations.saveFileContent(this.selectedFile, this.xmlContent); this.resetEditState(); alert('保存成功'); } catch (error) { console.error('保存出错:', error); alert('保存失败: ' + error.message); } }); // 另存为 const saveAsButton = this.shadowRoot.getElementById('saveAsConfig'); saveAsButton.addEventListener('click', () => { if (!this.xmlContent) { alert('没有内容可保存'); return; } CommandDialog.showSaveAsDialog(this.selectedFile, async (fileName) => { try { const result = await FileOperations.saveFileAs(fileName, this.xmlContent, this.selectedFile); if (!result.success) { if (result.data && result.data.code === 'FILE_EXISTS') { if (confirm('文件已存在,是否覆盖?')) { const retryResult = await FileOperations.saveFileAs(fileName, this.xmlContent, this.selectedFile, true); if (retryResult.success) { this.selectedFile = retryResult.data.path; this.resetEditState(); await this.loadServiceFiles(); } else { alert('保存失败: ' + retryResult.error); } } } else { alert('保存失败: ' + result.error); } } else { this.selectedFile = result.data.path; this.resetEditState(); await this.loadServiceFiles(); } } catch (error) { alert('保存失败: ' + error.message); } }); }); } // 标记编辑状态 markEdited() { this.isEdited = true; // 更新保存按钮样式 const saveButton = this.shadowRoot.querySelector('.save-button'); if (saveButton) { saveButton.classList.add('modified'); saveButton.title = '文件已修改,请保存'; } } // 重置编辑状态 resetEditState() { this.isEdited = false; // 更新保存按钮样式 const saveButton = this.shadowRoot.querySelector('.save-button'); if (saveButton) { saveButton.classList.remove('modified'); saveButton.title = '保存'; } } // 更新XML updateXmlFromEditor() { if (!this.xmlDoc) return; // 从可视化编辑器中获取所有输入字段的值并更新到XML文档 // 这部分逻辑已经在VisualEditor中处理,这里只需序列化XML即可 // 重新序列化XML内容 const serializer = new XMLSerializer(); this.xmlContent = XmlUtils.formatXml(serializer.serializeToString(this.xmlDoc)); } } customElements.define('service-config', ServiceConfig);