diff --git a/WordFormatUI/index.html b/WordFormatUI/index.html
index e193111..c239904 100644
--- a/WordFormatUI/index.html
+++ b/WordFormatUI/index.html
@@ -5,10 +5,6 @@
-
-
+
+
+
+
+
+
+
-
-
+
+
-
-
+
+
+
@@ -62,6 +69,7 @@ import {ref, onMounted} from 'vue';
import GlobalToast from "./components/GlobalToast.vue";
import DocTagChecker from "./components/DocTagChecker.vue";
import ConfigGenerator from "./config-generator/ConfigGenerator.vue";
+import ConfigSidebar from "./components/ConfigSidebar.vue";
import SettingsPage from "./components/SettingsPage.vue";
import yaml from 'js-yaml';
import {defaultConfig, mergeWithDefaults} from "./config-generator/utils";
@@ -149,6 +157,45 @@ const onConfigFileSelected = async (e) => {
}
};
+// 保存配置到服务器 configs 目录
+const API_BASE = window.__API_BASE__ || '';
+const saveConfigToServer = async () => {
+ if (!generatedConfig.value) return;
+ try {
+ const yamlContent = yaml.dump(generatedConfig.value, { indent: 2, skipInvalid: true });
+ const fn = prompt('请输入配置文件名(如 my-thesis.yaml):', 'custom.yaml');
+ if (!fn) return;
+ const res = await fetch(`${API_BASE}/configs/save`, {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({ filename: fn, content: yamlContent }),
+ });
+ const json = await res.json();
+ if (json.code === 200) {
+ toastRef.value?.toast.success(json.msg);
+ } else {
+ toastRef.value?.toast.error(json.msg || '保存失败');
+ }
+ } catch (error) {
+ toastRef.value?.toast.error('保存配置失败:' + error.message);
+ }
+};
+
+// 从服务器侧边栏加载配置
+const onServerConfigSelected = ({ filename, content }) => {
+ try {
+ const config = yaml.load(content);
+ const merged = mergeWithDefaults(config, defaultConfig);
+ generatedConfig.value = merged;
+ if (configGeneratorRef.value) {
+ configGeneratorRef.value.importConfig(merged);
+ }
+ toastRef.value?.toast.success(`已加载配置: ${filename}`);
+ } catch (error) {
+ toastRef.value?.toast.error('解析配置失败:' + error.message);
+ }
+};
+
diff --git a/WordFormatUI/src/components/DocTagChecker.vue b/WordFormatUI/src/components/DocTagChecker.vue
index 4f3fa69..f421b3c 100644
--- a/WordFormatUI/src/components/DocTagChecker.vue
+++ b/WordFormatUI/src/components/DocTagChecker.vue
@@ -442,7 +442,7 @@ watch(isFileLoaded, (loaded) => {
.header-bar { background-color: #1e293b; border-bottom: 1px solid #334155; padding: 0.75rem 1.5rem; }
.header-content { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 1rem; max-width: 1280px; margin: 0 auto; width: 100%; }
.header-left { display: flex; flex-direction: column; gap: 0.25rem; }
-.tool-title { font-size: 1.15rem; font-weight: 600; color: #f1f5f9; margin: 0; font-family: 'Crimson Pro', serif; }
+.tool-title { font-size: 1.15rem; font-weight: 600; color: #f1f5f9; margin: 0; font-family: 'Georgia, Times New Roman', serif; }
.stats-info { font-size: 0.8125rem; color: #64748b; }
.stats-info span { font-weight: 600; color: #22c55e; }
.header-right { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; }
diff --git a/WordFormatUI/src/components/SettingsPage.vue b/WordFormatUI/src/components/SettingsPage.vue
index 8d6a1a6..3d21b37 100644
--- a/WordFormatUI/src/components/SettingsPage.vue
+++ b/WordFormatUI/src/components/SettingsPage.vue
@@ -57,7 +57,7 @@ function resetDefaults() { resetSettings(); host.value = backendSettings.host; p
diff --git a/WordFormatUI/src/config-generator/components/TablesConfig.vue b/WordFormatUI/src/config-generator/components/TablesConfig.vue
index ab299d9..5ce59e9 100644
--- a/WordFormatUI/src/config-generator/components/TablesConfig.vue
+++ b/WordFormatUI/src/config-generator/components/TablesConfig.vue
@@ -5,10 +5,17 @@
+