运行
diff --git a/XNSimHtml/components/model-config.js b/XNSimHtml/components/model-config.js
deleted file mode 100644
index 051278e..0000000
--- a/XNSimHtml/components/model-config.js
+++ /dev/null
@@ -1,947 +0,0 @@
-/**
- * 模型配置组件
- * @type {module}
- */
-import {
- formatXml, escapeHtml, isValidElementName
-} from './model-config/utils.js';
-
-import {
- loadModelFiles as apiLoadModelFiles,
- loadFileContent as apiLoadFileContent,
- saveFileContent as apiSaveFileContent,
- createNewConfig as apiCreateNewConfig,
- saveFileAs as apiSaveFileAs
-} from './model-config/api.js';
-
-import {
- parseXmlContent, updateXmlFromVisualEditor, ensureCommandListFormat,
- updateElementByPath, updateElementValue, addElement, deleteElement
-} from './model-config/xml-handler.js';
-
-import {
- renderBasicInfoSection, renderAdvancedSection, renderElements, renderOtherSettingsSection
-} from './model-config/ui-elements.js';
-
-import {
- renderCommandListTable, renderCommandList
-} from './model-config/command-handler.js';
-
-import {
- showDateTimeDialog
-} from './model-config/datetime.js';
-
-import {
- showAddElementDialog, showEditElementDialog, showNewConfigDialog,
- showSaveAsDialog, showAddCommandDialog, showEditCommandDialog
-} from './model-config/dialogs.js';
-
-import {
- getStyles
-} from './model-config/styles.js';
-
-class ModelConfig extends HTMLElement {
- constructor() {
- super();
- this.attachShadow({ mode: 'open' });
- this.selectedFile = null;
- this.xmlContent = '';
- this.xmlDoc = null;
- this.isEdited = false;
- this.modelFiles = [];
- this.isActive = true; // 添加活动状态标记
- }
-
- async connectedCallback() {
- this.isActive = true;
- this.render();
- await this.loadModelFiles();
- this.setupEventListeners();
-
- // 延迟调用renderComplete,确保DOM已更新
- setTimeout(() => {
- this.renderComplete();
- }, 100);
- }
-
- disconnectedCallback() {
- this.isActive = false;
- }
-
- // 在组件完成渲染后恢复状态(与run-env-config组件一致)
- 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) {
- this.renderVisualEditor(visualEditor, this.xmlDoc);
-
- // 恢复编辑状态标记
- if (this.isEdited) {
- this.markEdited();
- }
- }
- } else {
- console.log('ModelConfig: 无法找到内容区域或XML文档不存在');
- }
- } else {
- // 文件不存在,清除状态
- this.selectedFile = null;
- this.xmlContent = '';
- this.xmlDoc = null;
- this.isEdited = false;
- }
- } else {
- console.log('ModelConfig: 未找到文件选择器');
- }
- }
- }, 50); // 增加延迟确保DOM已经完全加载
- }
-
- // 重新激活组件的方法(当标签页重新被选中时调用)
- async reactivate() {
- if (this.isActive) {
- return;
- }
-
- this.isActive = true;
-
- try {
- // 先重新渲染一次UI以确保Shadow DOM结构完整
- this.render();
-
- // 加载文件列表
- await this.loadModelFiles();
-
- // 设置事件监听器
- this.setupEventListeners();
-
- // 调用renderComplete来恢复状态(这是核心改进)
- this.renderComplete();
- } catch (error) {
- console.error('ModelConfig: 重新激活组件时出错:', error);
- }
- }
-
- async loadModelFiles() {
- try {
- this.modelFiles = await apiLoadModelFiles();
- this.updateFileSelector();
- } catch (error) {
- console.error('加载模型文件失败:', error);
-
- // 如果请求失败,可能是API不存在,等待一段时间后重试
- const retryLoadFiles = async () => {
- try {
- console.log('尝试重新加载模型文件列表...');
- this.modelFiles = await apiLoadModelFiles();
- this.updateFileSelector();
- } catch (retryError) {
- console.error('重试加载模型文件失败:', retryError);
- }
- };
-
- // 延迟3秒后重试
- setTimeout(retryLoadFiles, 3000);
- }
- }
-
- updateFileSelector() {
- const fileSelector = this.shadowRoot.getElementById('fileSelector');
- if (!fileSelector) return;
-
- // 清空现有选项
- fileSelector.innerHTML = '
';
-
- // 按修改时间排序,最新的在前面
- const sortedFiles = [...this.modelFiles].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) {
- try {
- const content = await apiLoadFileContent(filePath);
- this.selectedFile = filePath;
- this.xmlContent = content;
-
- // 解析XML内容
- const { xmlDoc, error, basicXml } = parseXmlContent(content);
-
- if (error && !basicXml) {
- // 显示错误信息
- const configContent = this.shadowRoot.querySelector('.config-content');
- configContent.innerHTML = `
-
-
XML解析错误
-
文件内容不是有效的XML格式。
-
${escapeHtml(content)}
-
- `;
- return;
- }
-
- this.xmlDoc = xmlDoc;
-
- if (basicXml) {
- this.xmlContent = basicXml;
- }
-
- // 特殊处理CommandList元素,确保命令以属性方式存储
- ensureCommandListFormat(this.xmlDoc);
-
- this.updateFileContent();
- this.resetEditState();
- } catch (error) {
- console.error('加载文件内容失败:', error);
- const configContent = this.shadowRoot.querySelector('.config-content');
- configContent.innerHTML = `
-
-
加载失败
-
${error.message}
-
- `;
- }
- }
-
- updateFileContent() {
- const contentArea = this.shadowRoot.querySelector('#contentArea');
-
- if (!this.xmlDoc || !this.selectedFile) {
- contentArea.innerHTML = `
请选择一个模型配置文件查看内容
`;
- return;
- }
-
- contentArea.innerHTML = `
-
- `;
-
- const visualEditor = this.shadowRoot.querySelector('#visualEditor');
- this.renderVisualEditor(visualEditor, this.xmlDoc);
- }
-
- render() {
- this.shadowRoot.innerHTML = `
-
-
- `;
- }
-
- 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.loadModelFiles();
-
- // 清除编辑状态和内容
- 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()) {
- showNewConfigDialog(async (result) => {
- await this.loadModelFiles();
- await this.loadFileContent(result.path);
- }, this);
- }
- });
-
- // 保存配置
- const saveButton = this.shadowRoot.getElementById('saveConfig');
- saveButton.addEventListener('click', async () => {
- if (!this.selectedFile) {
- alert('请先选择一个文件或创建新文件');
- return;
- }
-
- await this.saveCurrentFile();
- });
-
- // 另存为
- const saveAsButton = this.shadowRoot.getElementById('saveAsConfig');
- saveAsButton.addEventListener('click', () => {
- if (!this.xmlContent) {
- alert('没有内容可保存');
- return;
- }
-
- showSaveAsDialog(this.xmlContent, this.selectedFile, async (result) => {
- this.selectedFile = result.path;
- this.resetEditState();
- await this.loadModelFiles();
- }, this);
- });
- }
-
- renderVisualEditor(container, xmlDoc) {
- if (!xmlDoc || !container) return;
-
- // 添加样式
- const style = document.createElement('style');
- style.textContent = `
- .visual-editor {
- padding: 10px;
- }
-
- .section-title {
- font-size: 18px;
- font-weight: bold;
- margin-bottom: 10px;
- color: #333;
- border-bottom: 1px solid #e0e0e0;
- padding-bottom: 8px;
- }
-
- .section {
- margin-bottom: 20px;
- background-color: white;
- border: 1px solid #e0e0e0;
- border-radius: 4px;
- padding: 16px;
- }
-
- .property-row {
- display: flex;
- margin-bottom: 12px;
- align-items: center;
- }
-
- .property-label {
- width: 150px;
- font-weight: 500;
- color: #555;
- }
-
- .property-input {
- flex: 1;
- padding: 8px 10px;
- border: 1px solid #ddd;
- border-radius: 4px;
- font-size: 14px;
- }
-
- .property-input:focus {
- border-color: #7986E7;
- outline: none;
- box-shadow: 0 0 0 2px rgba(121, 134, 231, 0.2);
- }
-
- .section-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 15px;
- }
-
- .section-title-text {
- font-size: 18px;
- font-weight: bold;
- color: #333;
- }
-
- .section-buttons {
- display: flex;
- gap: 8px;
- }
-
- .section-button {
- background-color: #7986E7;
- color: white;
- border: none;
- border-radius: 4px;
- padding: 6px 12px;
- cursor: pointer;
- font-size: 14px;
- transition: background-color 0.3s;
- }
-
- .section-button:hover {
- background-color: #6875D6;
- }
-
- .error-message {
- color: #d32f2f;
- background-color: #ffebee;
- padding: 10px;
- border-radius: 4px;
- margin-bottom: 15px;
- }
- `;
-
- const visualEditor = document.createElement('div');
- visualEditor.className = 'visual-editor';
-
- // 获取根元素
- const rootElement = xmlDoc.documentElement;
-
- // 只处理Model根元素
- if (rootElement.nodeName === 'Model') {
- // 创建模态对话框容器
- const modalContainer = document.createElement('div');
- modalContainer.className = 'modal';
- modalContainer.id = 'propertyModal';
- container.appendChild(modalContainer);
-
- // 渲染基本信息部分
- renderBasicInfoSection(
- visualEditor,
- rootElement,
- xmlDoc,
- (inputElement) => this.showDateTimeDialogWrapper(inputElement),
- () => this.markEdited()
- );
-
- // 渲染高级设置部分
- renderAdvancedSection(
- visualEditor,
- rootElement,
- xmlDoc,
- (container, rootElement) => this.renderCommandListTableWrapper(container, rootElement),
- () => this.markEdited()
- );
-
- // 渲染其他设置部分
- renderOtherSettingsSection(
- visualEditor,
- rootElement,
- (container, parentElement, parentPath, level = 0) => this.renderElementsWrapper(
- container, parentElement, parentPath, level
- )
- );
- } else {
- // 不是Model根元素,显示错误信息
- visualEditor.innerHTML = `
- 无法编辑:XML文档的根元素不是Model。
- 请确保XML文档的根元素是Model。
-
`;
- }
-
- container.appendChild(style);
- container.appendChild(visualEditor);
-
- // 自动保存配置到XML
- this.autoSaveToXml();
- }
-
- // 自动保存表单内容到XML
- autoSaveToXml() {
- // 为所有输入框添加change事件
- const inputs = this.shadowRoot.querySelectorAll('.property-input');
- inputs.forEach(input => {
- input.addEventListener('change', () => {
- this.updateXmlFromVisualEditor(); // 更新XML
- this.markEdited(); // 标记已编辑
- });
- });
- }
-
- // 显示日期时间对话框包装方法
- showDateTimeDialogWrapper(inputElement) {
- showDateTimeDialog(inputElement, this.xmlDoc, () => this.markEdited(), this);
- }
-
- // 渲染命令列表表格包装方法
- renderCommandListTableWrapper(container, rootElement) {
- renderCommandListTable(
- container,
- rootElement,
- (rootElement) => this.showAddCommandDialogWrapper(rootElement),
- (command, index) => this.showEditCommandDialogWrapper(command, index),
- (command, index) => this.deleteCommandWrapper(command, index)
- );
- }
-
- // 渲染元素包装方法
- renderElementsWrapper(container, parentElement, parentPath, level = 0) {
- renderElements(
- container,
- parentElement,
- parentPath,
- level,
- isValidElementName,
- (path, value) => this.updateElementByPathWrapper(path, value),
- (element, elementPath) => this.deleteElementWrapper(element, elementPath),
- (parentElement, name, value) => this.addElementWrapper(parentElement, name, value),
- (parentElement, parentPath) => this.showAddElementDialogWrapper(parentElement, parentPath),
- (element, elementPath) => this.showEditElementDialogWrapper(element, elementPath)
- );
- }
-
- // 更新元素路径包装方法
- updateElementByPathWrapper(path, value) {
- if (updateElementByPath(this.xmlDoc, path, value)) {
- this.updateXmlFromVisualEditor();
- this.markEdited();
- return true;
- }
- return false;
- }
-
- // 删除元素包装方法
- deleteElementWrapper(element, elementPath) {
- // 确认删除
- if (!confirm(`确定要删除元素 ${element.nodeName} 吗?此操作不可撤销。`)) {
- return;
- }
-
- if (deleteElement(element)) {
- this.updateXmlFromVisualEditor();
- this.markEdited();
-
- // 重新渲染元素列表
- const container = this.shadowRoot.querySelector('#otherSettingsContainer');
- if (container) {
- container.innerHTML = '';
- this.renderElementsWrapper(container, this.xmlDoc.documentElement, '/' + this.xmlDoc.documentElement.nodeName);
- }
-
- return true;
- }
-
- return false;
- }
-
- // 添加元素包装方法
- addElementWrapper(parentElement, name, value) {
- const newElement = addElement(this.xmlDoc, parentElement, name, value);
- if (newElement) {
- this.updateXmlFromVisualEditor();
- this.markEdited();
- return true;
- }
- return false;
- }
-
- // 显示添加元素对话框包装方法
- showAddElementDialogWrapper(parentElement, parentPath) {
- showAddElementDialog(parentElement, parentPath, this.xmlDoc, () => {
- this.updateXmlFromVisualEditor();
- this.markEdited();
-
- // 重新渲染元素列表
- const container = this.shadowRoot.querySelector('#otherSettingsContainer');
- if (container) {
- container.innerHTML = '';
- this.renderElementsWrapper(container, this.xmlDoc.documentElement, '/' + this.xmlDoc.documentElement.nodeName);
- }
- }, this);
- }
-
- // 显示编辑元素对话框包装方法
- showEditElementDialogWrapper(element, elementPath) {
- showEditElementDialog(element, elementPath, this.xmlDoc, () => {
- this.updateXmlFromVisualEditor();
- this.markEdited();
-
- // 更新UI中的值
- const inputElement = this.shadowRoot.querySelector(`input[data-path="${elementPath}"]`);
- if (inputElement) {
- inputElement.value = element.textContent;
- }
- }, this);
- }
-
- // 显示添加命令对话框包装方法
- showAddCommandDialogWrapper(rootElement) {
- showAddCommandDialog(rootElement, this.xmlDoc, () => {
- this.updateXmlFromVisualEditor();
- this.markEdited();
-
- // 重新渲染命令列表
- const commandListContainer = this.shadowRoot.querySelector('#commandListContainer');
- const visualEditor = this.shadowRoot.querySelector('#visualEditor');
- if (commandListContainer && visualEditor) {
- // 清空当前渲染
- visualEditor.innerHTML = '';
- // 重新渲染整个编辑器
- this.renderVisualEditor(visualEditor, this.xmlDoc);
- }
- }, this);
- }
-
- // 显示编辑命令对话框包装方法
- showEditCommandDialogWrapper(commandElement, index) {
- showEditCommandDialog(commandElement, index, () => {
- this.updateXmlFromVisualEditor();
- this.markEdited();
-
- // 更新表格行
- const row = this.shadowRoot.querySelector(`.command-row[data-index="${index}"]`);
- if (row) {
- const name = commandElement.getAttribute('Name') || '';
- const call = commandElement.getAttribute('Call') || '';
- const description = commandElement.getAttribute('Description') || '';
-
- row.querySelectorAll('.command-cell')[0].textContent = name;
- row.querySelectorAll('.command-cell')[1].textContent = call;
- row.querySelectorAll('.command-cell')[2].textContent = description || `${name}描述`;
- } else {
- // 如果找不到行,重新渲染整个编辑器
- const visualEditor = this.shadowRoot.querySelector('#visualEditor');
- if (visualEditor) {
- visualEditor.innerHTML = '';
- this.renderVisualEditor(visualEditor, this.xmlDoc);
- }
- }
- }, this);
- }
-
- // 删除命令包装方法
- deleteCommandWrapper(commandElement, index) {
- if (!confirm('确定要删除此命令吗?此操作不可撤销。')) {
- return;
- }
-
- if (deleteElement(commandElement)) {
- this.updateXmlFromVisualEditor();
- this.markEdited();
-
- // 从表格中移除行
- const row = this.shadowRoot.querySelector(`.command-row[data-index="${index}"]`);
- if (row) {
- row.parentNode.removeChild(row);
-
- // 更新索引
- const rows = this.shadowRoot.querySelectorAll('.command-row');
- rows.forEach((r, i) => {
- r.dataset.index = i;
- });
- } else {
- // 如果找不到行,重新渲染整个编辑器
- const visualEditor = this.shadowRoot.querySelector('#visualEditor');
- if (visualEditor) {
- visualEditor.innerHTML = '';
- this.renderVisualEditor(visualEditor, this.xmlDoc);
- }
- }
-
- return true;
- }
-
- return false;
- }
-
- // 从可视化编辑器更新XML
- updateXmlFromVisualEditor() {
- if (!this.xmlDoc) return;
-
- this.xmlContent = updateXmlFromVisualEditor(this.xmlDoc);
- }
-
- // 标记为已编辑
- markEdited() {
- this.isEdited = true;
- // 更新保存按钮样式
- const saveButton = this.shadowRoot.getElementById('saveConfig');
- if (saveButton) {
- saveButton.classList.add('modified');
- }
- }
-
- // 重置编辑状态
- resetEditState() {
- this.isEdited = false;
- // 更新保存按钮样式
- const saveButton = this.shadowRoot.getElementById('saveConfig');
- if (saveButton) {
- saveButton.classList.remove('modified');
- }
- }
-
- // 更新命令列表部分
- updateCommandListSection() {
- if (!this.xmlDoc) return;
-
- const visualEditorContainer = document.getElementById('visualEditorContainer');
- if (!visualEditorContainer) return;
-
- // 移除已有的命令列表容器
- const existingContainer = document.getElementById('commandListContainer');
- if (existingContainer) {
- existingContainer.remove();
- }
-
- // 获取根元素和命令列表元素
- const rootElement = this.xmlDoc.documentElement;
- const commandListElement = ensureCommandListFormat(this.xmlDoc);
-
- // 渲染命令列表
- renderCommandList(
- visualEditorContainer,
- commandListElement,
- rootElement,
- (rootElement) => this.showAddCommandDialogWrapper(rootElement),
- (command, index) => this.showEditCommandDialogWrapper(command, index),
- (command, index) => this.deleteCommandWrapper(command, index)
- );
- }
-
- // 添加检查未保存更改的方法
- 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 {
- await this.saveCurrentFile();
- return true; // 继续执行后续操作
- } catch (error) {
- console.error('保存出错:', error);
- return false; // 保存失败,不继续执行
- }
- } else if (dialogResult === 'dont-save') {
- // 不保存,但继续执行后续操作
- return true;
- } else {
- // 用户取消,不执行后续操作
- return false;
- }
- }
-
- // 没有编辑状态,直接返回true允许继续操作
- return true;
- }
-
- // 检查未保存更改 (兼容旧版的使用)
- checkUnsavedChanges() {
- // 由于无法同步返回Promise结果,这个方法保留为返回布尔值
- // 但为了向前兼容,仍保留这个方法
- return this.isEdited;
- }
-
- // 保存当前文件
- async saveCurrentFile() {
- if (!this.selectedFile || !this.isEdited) return false;
-
- try {
- await apiSaveFileContent(this.selectedFile, this.xmlContent);
- this.resetEditState();
- return true;
- } catch (error) {
- alert('保存失败: ' + error.message);
- return false;
- }
- }
-}
-
-customElements.define('model-config', ModelConfig);
\ No newline at end of file
diff --git a/XNSimHtml/components/model-config/api.js b/XNSimHtml/components/model-config/api.js
deleted file mode 100644
index 1759d53..0000000
--- a/XNSimHtml/components/model-config/api.js
+++ /dev/null
@@ -1,133 +0,0 @@
-/**
- * API操作模块
- * @type {module}
- */
-
-/**
- * 加载模型文件列表
- * @returns {Promise
} 模型文件数组
- */
-export async function loadModelFiles() {
- try {
- const response = await fetch('/api/model-files');
- if (!response.ok) {
- throw new Error(`服务器响应错误: ${response.status}`);
- }
- return await response.json();
- } catch (error) {
- console.error('加载模型文件失败:', error);
- throw error;
- }
-}
-
-/**
- * 加载文件内容
- * @param {string} filePath - 文件路径
- * @returns {Promise} 文件内容
- */
-export async function loadFileContent(filePath) {
- try {
- const response = await fetch(`/api/model-file-content?path=${encodeURIComponent(filePath)}`);
- if (!response.ok) {
- throw new Error(`服务器响应错误: ${response.status}`);
- }
- return await response.text();
- } catch (error) {
- console.error('加载文件内容失败:', error);
- throw error;
- }
-}
-
-/**
- * 保存文件内容
- * @param {string} filePath - 文件路径
- * @param {string} content - 文件内容
- * @returns {Promise