zen-gitsync 2.0.8 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,12 +1,14 @@
1
1
  <script setup lang="ts">
2
2
  import { ref, onMounted, computed, watch } from "vue";
3
3
  import { ElMessage, ElMessageBox } from "element-plus";
4
- import { Setting, Edit, Check, Upload, RefreshRight, Delete, Position, Download, Connection } from "@element-plus/icons-vue";
4
+ import { Setting, Edit, Check, Upload, RefreshRight, Delete, Position, Download, Connection, ArrowDown } from "@element-plus/icons-vue";
5
5
  import { useGitLogStore } from "../stores/gitLogStore";
6
6
  import { useGitStore } from "../stores/gitStore";
7
+ import { useConfigStore } from "../stores/configStore";
7
8
 
8
9
  const gitLogStore = useGitLogStore();
9
10
  const gitStore = useGitStore();
11
+ const configStore = useConfigStore();
10
12
  const commitMessage = ref("");
11
13
  const isPushing = ref(false);
12
14
  // 添加提交并推送的状态变量
@@ -51,6 +53,9 @@ const newDefaultMessage = ref("");
51
53
  // 跳过钩子
52
54
  const skipHooks = ref(false);
53
55
 
56
+ // 添加控制正文和页脚显示的状态变量
57
+ const showAdvancedFields = ref(false);
58
+
54
59
  // 提交类型选项
55
60
  const commitTypeOptions = [
56
61
  { value: "feat", label: "feat: 新功能" },
@@ -119,28 +124,29 @@ const gitCommandPreview = computed(() => {
119
124
  // 加载配置
120
125
  async function loadConfig() {
121
126
  try {
122
- const response = await fetch("/api/config/getConfig");
123
- const config = await response.json();
124
- placeholder.value = `输入提交信息 (默认: ${config.defaultCommitMessage})`;
125
- // 保存默认提交信息到变量中,以便后续使用
126
- defaultCommitMessage.value = config.defaultCommitMessage || "";
127
-
128
- // 加载描述模板
129
- if (
130
- config.descriptionTemplates &&
131
- Array.isArray(config.descriptionTemplates)
132
- ) {
133
- descriptionTemplates.value = config.descriptionTemplates;
134
- }
127
+ const config = await configStore.loadConfig();
128
+ if (config) {
129
+ placeholder.value = `输入提交信息 (默认: ${config.defaultCommitMessage})`;
130
+ // 保存默认提交信息到变量中,以便后续使用
131
+ defaultCommitMessage.value = config.defaultCommitMessage || "";
132
+
133
+ // 加载描述模板
134
+ if (
135
+ config.descriptionTemplates &&
136
+ Array.isArray(config.descriptionTemplates)
137
+ ) {
138
+ descriptionTemplates.value = config.descriptionTemplates;
139
+ }
135
140
 
136
- // 加载作用域模板
137
- if (config.scopeTemplates && Array.isArray(config.scopeTemplates)) {
138
- scopeTemplates.value = config.scopeTemplates;
139
- }
140
-
141
- // 加载提交信息模板
142
- if (config.messageTemplates && Array.isArray(config.messageTemplates)) {
143
- messageTemplates.value = config.messageTemplates;
141
+ // 加载作用域模板
142
+ if (config.scopeTemplates && Array.isArray(config.scopeTemplates)) {
143
+ scopeTemplates.value = config.scopeTemplates;
144
+ }
145
+
146
+ // 加载提交信息模板
147
+ if (config.messageTemplates && Array.isArray(config.messageTemplates)) {
148
+ messageTemplates.value = config.messageTemplates;
149
+ }
144
150
  }
145
151
  } catch (error) {
146
152
  console.error("加载配置失败:", error);
@@ -173,90 +179,67 @@ async function saveDescriptionTemplate() {
173
179
  return;
174
180
  }
175
181
 
176
- // 添加到本地数组
177
- descriptionTemplates.value.push(newTemplateName.value);
178
-
179
- // 保存到服务器
180
- const response = await fetch("/api/config/save-template", {
181
- method: "POST",
182
- headers: {
183
- "Content-Type": "application/json",
184
- },
185
- body: JSON.stringify({
186
- template: newTemplateName.value,
187
- type: "description",
188
- }),
189
- });
190
-
191
- const result = await response.json();
192
- if (result.success) {
193
- ElMessage({
194
- message: "模板保存成功!",
195
- type: "success",
196
- });
197
- newTemplateName.value = "";
198
- } else {
199
- ElMessage({
200
- message: "模板保存失败: " + result.error,
201
- type: "error",
202
- });
182
+ // 使用 configStore 保存模板
183
+ const success = await configStore.saveTemplate(newTemplateName.value, 'description');
184
+
185
+ if (success) {
186
+ // 确保本地数组同步更新
187
+ if (!descriptionTemplates.value.includes(newTemplateName.value)) {
188
+ descriptionTemplates.value.push(newTemplateName.value);
189
+ }
190
+ // 强制更新视图
191
+ descriptionTemplates.value = [...descriptionTemplates.value];
192
+
193
+ // configStore已经显示了成功消息,这里不需要重复操作
194
+ newTemplateName.value = ""; // 清空输入框,但不关闭弹窗
203
195
  }
204
196
  }
205
197
  } catch (error) {
206
198
  ElMessage({
207
- message: "模板保存失败: " + (error as Error).message,
199
+ message: `保存模板失败: ${(error as Error).message}`,
208
200
  type: "error",
209
201
  });
210
202
  }
211
203
  }
212
204
 
213
- // 编辑描述模板
205
+ // 更新描述模板
214
206
  async function updateDescriptionTemplate() {
215
- try {
216
- // 先从本地数组中更新
217
- if (editingDescriptionIndex.value >= 0) {
218
- // 保存原模板和新模板
219
- const oldTemplate = originalDescriptionTemplate.value;
220
- const newTemplate = newTemplateName.value;
221
-
222
- // 更新本地数组
223
- descriptionTemplates.value[editingDescriptionIndex.value] = newTemplate;
224
-
225
- // 调用API更新服务器
226
- const response = await fetch("/api/config/update-template", {
227
- method: "POST",
228
- headers: {
229
- "Content-Type": "application/json",
230
- },
231
- body: JSON.stringify({
232
- oldTemplate,
233
- newTemplate,
234
- type: "description",
235
- }),
236
- });
207
+ if (!newTemplateName.value.trim()) {
208
+ ElMessage({
209
+ message: "请输入模板内容",
210
+ type: "warning",
211
+ });
212
+ return;
213
+ }
237
214
 
238
- const result = await response.json();
239
- if (result.success) {
240
- ElMessage({
241
- message: "模板更新成功!",
242
- type: "success",
243
- });
215
+ try {
216
+ // 使用 configStore 更新模板
217
+ const success = await configStore.updateTemplate(
218
+ originalDescriptionTemplate.value,
219
+ newTemplateName.value,
220
+ 'description'
221
+ );
244
222
 
245
- // 重置编辑状态
246
- isEditingDescription.value = false;
247
- originalDescriptionTemplate.value = "";
248
- editingDescriptionIndex.value = -1;
249
- newTemplateName.value = "";
250
- } else {
251
- ElMessage({
252
- message: "模板更新失败: " + result.error,
253
- type: "error",
254
- });
223
+ if (success) {
224
+ // 确保本地数组同步更新
225
+ const index = descriptionTemplates.value.indexOf(originalDescriptionTemplate.value);
226
+ if (index !== -1) {
227
+ descriptionTemplates.value[index] = newTemplateName.value;
255
228
  }
229
+ // 强制更新视图
230
+ descriptionTemplates.value = [...descriptionTemplates.value];
231
+
232
+ // configStore已经更新了本地数组并显示了成功消息,这里不需要重复操作
233
+
234
+ // 重置编辑状态
235
+ isEditingDescription.value = false;
236
+ originalDescriptionTemplate.value = "";
237
+ editingDescriptionIndex.value = -1;
238
+ newTemplateName.value = "";
256
239
  }
257
240
  } catch (error) {
258
241
  ElMessage({
259
- message: "模板更新失败: " + (error as Error).message,
242
+ message: `更新模板失败: ${(error as Error).message}`,
260
243
  type: "error",
261
244
  });
262
245
  }
@@ -304,38 +287,24 @@ async function saveScopeTemplate() {
304
287
  return;
305
288
  }
306
289
 
307
- // 添加到本地数组
308
- scopeTemplates.value.push(newScopeTemplate.value);
309
-
310
- // 保存到服务器
311
- const response = await fetch("/api/config/save-template", {
312
- method: "POST",
313
- headers: {
314
- "Content-Type": "application/json",
315
- },
316
- body: JSON.stringify({
317
- template: newScopeTemplate.value,
318
- type: "scope",
319
- }),
320
- });
321
-
322
- const result = await response.json();
323
- if (result.success) {
324
- ElMessage({
325
- message: "作用域模板保存成功!",
326
- type: "success",
327
- });
328
- newScopeTemplate.value = "";
329
- } else {
330
- ElMessage({
331
- message: "作用域模板保存失败: " + result.error,
332
- type: "error",
333
- });
290
+ // 使用 configStore 保存模板
291
+ const success = await configStore.saveTemplate(newScopeTemplate.value, 'scope');
292
+
293
+ if (success) {
294
+ // 确保本地数组同步更新
295
+ if (!scopeTemplates.value.includes(newScopeTemplate.value)) {
296
+ scopeTemplates.value.push(newScopeTemplate.value);
297
+ }
298
+ // 强制更新视图
299
+ scopeTemplates.value = [...scopeTemplates.value];
300
+
301
+ // configStore已经显示了成功消息,这里不需要重复操作
302
+ newScopeTemplate.value = ""; // 清空输入框,但不关闭弹窗
334
303
  }
335
304
  }
336
305
  } catch (error) {
337
306
  ElMessage({
338
- message: "作用域模板保存失败: " + (error as Error).message,
307
+ message: `保存模板失败: ${(error as Error).message}`,
339
308
  type: "error",
340
309
  });
341
310
  }
@@ -343,51 +312,42 @@ async function saveScopeTemplate() {
343
312
 
344
313
  // 更新作用域模板
345
314
  async function updateScopeTemplate() {
346
- try {
347
- // 先从本地数组中更新
348
- if (editingScopeIndex.value >= 0) {
349
- // 保存原模板和新模板
350
- const oldTemplate = originalScopeTemplate.value;
351
- const newTemplate = newScopeTemplate.value;
352
-
353
- // 更新本地数组
354
- scopeTemplates.value[editingScopeIndex.value] = newTemplate;
355
-
356
- // 调用API更新服务器
357
- const response = await fetch("/api/config/update-template", {
358
- method: "POST",
359
- headers: {
360
- "Content-Type": "application/json",
361
- },
362
- body: JSON.stringify({
363
- oldTemplate,
364
- newTemplate,
365
- type: "scope",
366
- }),
367
- });
315
+ if (!newScopeTemplate.value.trim()) {
316
+ ElMessage({
317
+ message: "请输入模板内容",
318
+ type: "warning",
319
+ });
320
+ return;
321
+ }
368
322
 
369
- const result = await response.json();
370
- if (result.success) {
371
- ElMessage({
372
- message: "作用域模板更新成功!",
373
- type: "success",
374
- });
323
+ try {
324
+ // 使用 configStore 更新模板
325
+ const success = await configStore.updateTemplate(
326
+ originalScopeTemplate.value,
327
+ newScopeTemplate.value,
328
+ 'scope'
329
+ );
375
330
 
376
- // 重置编辑状态
377
- isEditingScope.value = false;
378
- originalScopeTemplate.value = "";
379
- editingScopeIndex.value = -1;
380
- newScopeTemplate.value = "";
381
- } else {
382
- ElMessage({
383
- message: "作用域模板更新失败: " + result.error,
384
- type: "error",
385
- });
331
+ if (success) {
332
+ // 确保本地数组同步更新
333
+ const index = scopeTemplates.value.indexOf(originalScopeTemplate.value);
334
+ if (index !== -1) {
335
+ scopeTemplates.value[index] = newScopeTemplate.value;
386
336
  }
337
+ // 强制更新视图
338
+ scopeTemplates.value = [...scopeTemplates.value];
339
+
340
+ // configStore已经更新了本地数组并显示了成功消息,这里不需要重复操作
341
+
342
+ // 重置编辑状态
343
+ isEditingScope.value = false;
344
+ originalScopeTemplate.value = "";
345
+ editingScopeIndex.value = -1;
346
+ newScopeTemplate.value = "";
387
347
  }
388
348
  } catch (error) {
389
349
  ElMessage({
390
- message: "作用域模板更新失败: " + (error as Error).message,
350
+ message: `更新模板失败: ${(error as Error).message}`,
391
351
  type: "error",
392
352
  });
393
353
  }
@@ -412,39 +372,37 @@ function cancelEditScopeTemplate() {
412
372
  // 删除描述模板
413
373
  async function deleteDescriptionTemplate(template: string) {
414
374
  try {
415
- // 从本地数组中删除
416
- const index = descriptionTemplates.value.indexOf(template);
417
- if (index !== -1) {
418
- descriptionTemplates.value.splice(index, 1);
419
- }
420
-
421
- // 从服务器删除
422
- const response = await fetch("/api/config/delete-template", {
423
- method: "POST",
424
- headers: {
425
- "Content-Type": "application/json",
426
- },
427
- body: JSON.stringify({
428
- template,
429
- type: "description",
430
- }),
431
- });
375
+ // 确认删除
376
+ await ElMessageBox.confirm(
377
+ `确定要删除描述模板 "${template}" 吗?`,
378
+ "删除确认",
379
+ {
380
+ confirmButtonText: "确定",
381
+ cancelButtonText: "取消",
382
+ type: "warning",
383
+ }
384
+ );
432
385
 
433
- const result = await response.json();
434
- if (result.success) {
435
- ElMessage({
436
- message: "模板删除成功!",
437
- type: "success",
438
- });
439
- } else {
440
- ElMessage({
441
- message: "模板删除失败: " + result.error,
442
- type: "error",
443
- });
386
+ // 使用 configStore 删除模板
387
+ const success = await configStore.deleteTemplate(template, 'description');
388
+
389
+ if (success) {
390
+ // 确保本地数组同步更新
391
+ const index = descriptionTemplates.value.indexOf(template);
392
+ if (index !== -1) {
393
+ descriptionTemplates.value.splice(index, 1);
394
+ }
395
+ // 强制更新视图
396
+ descriptionTemplates.value = [...descriptionTemplates.value];
444
397
  }
445
398
  } catch (error) {
399
+ if (error === "cancel") {
400
+ // 用户取消删除,不做任何操作
401
+ return;
402
+ }
403
+
446
404
  ElMessage({
447
- message: "模板删除失败: " + (error as Error).message,
405
+ message: `删除模板失败: ${(error as Error).message}`,
448
406
  type: "error",
449
407
  });
450
408
  }
@@ -453,39 +411,37 @@ async function deleteDescriptionTemplate(template: string) {
453
411
  // 删除作用域模板
454
412
  async function deleteScopeTemplate(template: string) {
455
413
  try {
456
- // 从本地数组中删除
457
- const index = scopeTemplates.value.indexOf(template);
458
- if (index !== -1) {
459
- scopeTemplates.value.splice(index, 1);
460
- }
461
-
462
- // 从服务器删除
463
- const response = await fetch("/api/config/delete-template", {
464
- method: "POST",
465
- headers: {
466
- "Content-Type": "application/json",
467
- },
468
- body: JSON.stringify({
469
- template,
470
- type: "scope",
471
- }),
472
- });
414
+ // 确认删除
415
+ await ElMessageBox.confirm(
416
+ `确定要删除作用域模板 "${template}" 吗?`,
417
+ "删除确认",
418
+ {
419
+ confirmButtonText: "确定",
420
+ cancelButtonText: "取消",
421
+ type: "warning",
422
+ }
423
+ );
473
424
 
474
- const result = await response.json();
475
- if (result.success) {
476
- ElMessage({
477
- message: "作用域模板删除成功!",
478
- type: "success",
479
- });
480
- } else {
481
- ElMessage({
482
- message: "作用域模板删除失败: " + result.error,
483
- type: "error",
484
- });
425
+ // 使用 configStore 删除模板
426
+ const success = await configStore.deleteTemplate(template, 'scope');
427
+
428
+ if (success) {
429
+ // 确保本地数组同步更新
430
+ const index = scopeTemplates.value.indexOf(template);
431
+ if (index !== -1) {
432
+ scopeTemplates.value.splice(index, 1);
433
+ }
434
+ // 强制更新视图
435
+ scopeTemplates.value = [...scopeTemplates.value];
485
436
  }
486
437
  } catch (error) {
438
+ if (error === "cancel") {
439
+ // 用户取消删除,不做任何操作
440
+ return;
441
+ }
442
+
487
443
  ElMessage({
488
- message: "作用域模板删除失败: " + (error as Error).message,
444
+ message: `删除模板失败: ${(error as Error).message}`,
489
445
  type: "error",
490
446
  });
491
447
  }
@@ -746,39 +702,26 @@ async function saveDefaultMessage() {
746
702
  }
747
703
 
748
704
  try {
749
- // 保存到服务器
750
- const response = await fetch("/api/config/saveDefaultMessage", {
751
- method: "POST",
752
- headers: {
753
- "Content-Type": "application/json",
754
- },
755
- body: JSON.stringify({
756
- defaultCommitMessage: newDefaultMessage.value,
757
- }),
758
- });
759
-
760
- const result = await response.json();
761
- if (result.success) {
762
- // 更新本地状态
705
+ // 使用 configStore 保存默认提交信息
706
+ const success = await configStore.saveDefaultMessage(newDefaultMessage.value);
707
+
708
+ if (success) {
709
+ // 更新本地默认提交信息
763
710
  defaultCommitMessage.value = newDefaultMessage.value;
764
- placeholder.value = `输入提交信息 (默认: ${defaultCommitMessage.value})`;
711
+ placeholder.value = `输入提交信息 (默认: ${newDefaultMessage.value})`;
765
712
 
766
- ElMessage({
767
- message: "默认提交信息保存成功!",
768
- type: "success",
769
- });
713
+ // configStore 已经显示了成功消息,这里不需要重复显示
714
+ // ElMessage({
715
+ // message: "默认提交信息已保存",
716
+ // type: "success",
717
+ // });
770
718
 
771
- // 不再关闭弹窗,而是保留当前编辑状态
772
- // defaultMessageDialogVisible.value = false;
773
- } else {
774
- ElMessage({
775
- message: "保存失败: " + result.error,
776
- type: "error",
777
- });
719
+ // 关闭对话框
720
+ defaultMessageDialogVisible.value = false;
778
721
  }
779
722
  } catch (error) {
780
723
  ElMessage({
781
- message: "保存失败: " + (error as Error).message,
724
+ message: `保存默认提交信息失败: ${(error as Error).message}`,
782
725
  type: "error",
783
726
  });
784
727
  }
@@ -1026,8 +969,6 @@ onMounted(() => {
1026
969
  skipHooks.value = savedSkipHooks === "true";
1027
970
  }
1028
971
 
1029
- // 获取一次分支状态
1030
- gitStore.getBranchStatus();
1031
972
  });
1032
973
  </script>
1033
974
 
@@ -1119,15 +1060,17 @@ git config --global user.email "your.email@example.com"</pre>
1119
1060
  <!-- 标准化提交表单 -->
1120
1061
  <div v-else class="standard-commit-form">
1121
1062
  <div class="standard-commit-header">
1122
- <el-select v-model="commitType" placeholder="提交类型" class="type-select" clearable>
1123
- <el-option v-for="item in commitTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
1124
- </el-select>
1125
-
1126
- <div class="scope-container">
1127
- <el-input v-model="commitScope" placeholder="作用域(可选)" class="scope-input" clearable />
1128
- <el-button type="primary" :icon="Setting" circle size="small" class="settings-button"
1129
- @click="openScopeSettings">
1130
- </el-button>
1063
+ <div class="type-scope-container">
1064
+ <el-select v-model="commitType" placeholder="提交类型" class="type-select" clearable>
1065
+ <el-option v-for="item in commitTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
1066
+ </el-select>
1067
+
1068
+ <div class="scope-wrapper">
1069
+ <el-input v-model="commitScope" placeholder="作用域(可选)" class="scope-input" clearable />
1070
+ <el-button type="primary" :icon="Setting" circle size="small" class="settings-button"
1071
+ @click="openScopeSettings">
1072
+ </el-button>
1073
+ </div>
1131
1074
  </div>
1132
1075
 
1133
1076
  <div class="description-container">
@@ -1138,10 +1081,21 @@ git config --global user.email "your.email@example.com"</pre>
1138
1081
  </div>
1139
1082
  </div>
1140
1083
 
1141
- <el-input v-model="commitBody" type="textarea" :rows="4" placeholder="正文(可选):详细描述本次提交的内容和原因" class="body-input"
1142
- clearable />
1084
+ <!-- 添加展开/收起高级选项的控制按钮 -->
1085
+ <div class="advanced-options-toggle" @click="showAdvancedFields = !showAdvancedFields">
1086
+ <span>{{ showAdvancedFields ? '收起' : '正文及页脚' }}</span>
1087
+ <el-icon class="toggle-icon" :class="{ 'is-active': showAdvancedFields }">
1088
+ <arrow-down />
1089
+ </el-icon>
1090
+ </div>
1091
+
1092
+ <!-- 使用过渡效果包装高级字段 -->
1093
+ <div v-show="showAdvancedFields" class="advanced-fields">
1094
+ <el-input v-model="commitBody" type="textarea" :rows="4" placeholder="正文(可选):详细描述本次提交的内容和原因" class="body-input"
1095
+ clearable />
1143
1096
 
1144
- <el-input v-model="commitFooter" placeholder="页脚(可选):如 Closes #123" class="footer-input" clearable />
1097
+ <el-input v-model="commitFooter" placeholder="页脚(可选):如 Closes #123" class="footer-input" clearable />
1098
+ </div>
1145
1099
 
1146
1100
  <div class="preview-section">
1147
1101
  <div class="preview-title">提交信息预览:</div>
@@ -1631,19 +1585,22 @@ git config --global user.email "your.email@example.com"</pre>
1631
1585
  width: 100%;
1632
1586
  }
1633
1587
 
1634
- .type-select {
1588
+ .type-scope-container {
1589
+ display: flex;
1590
+ gap: 10px;
1635
1591
  width: 100%;
1592
+ margin-bottom: 10px;
1636
1593
  }
1637
1594
 
1638
- .scope-container {
1595
+ .type-select {
1596
+ width: 35%; /* 提交类型占35%宽度 */
1597
+ }
1598
+
1599
+ .scope-wrapper {
1639
1600
  display: flex;
1640
1601
  align-items: center;
1641
1602
  gap: 5px;
1642
- width: 100%;
1643
- }
1644
-
1645
- .scope-input {
1646
- flex-grow: 1;
1603
+ width: 65%; /* 作用域占65%宽度 */
1647
1604
  }
1648
1605
 
1649
1606
  .description-container {
@@ -1653,7 +1610,7 @@ git config --global user.email "your.email@example.com"</pre>
1653
1610
  width: 100%;
1654
1611
  }
1655
1612
 
1656
- .description-input {
1613
+ .scope-input, .description-input {
1657
1614
  flex-grow: 1;
1658
1615
  }
1659
1616
 
@@ -1665,7 +1622,6 @@ git config --global user.email "your.email@example.com"</pre>
1665
1622
  background-color: #f5f7fa;
1666
1623
  padding: 10px;
1667
1624
  border-radius: 4px;
1668
- margin-top: 10px;
1669
1625
  }
1670
1626
 
1671
1627
  .preview-title {
@@ -2091,6 +2047,51 @@ git config --global user.email "your.email@example.com"</pre>
2091
2047
  margin: 8px 0;
2092
2048
  line-height: 1.5;
2093
2049
  }
2050
+
2051
+ .advanced-options-toggle {
2052
+ display: flex;
2053
+ align-items: center;
2054
+ justify-content: center;
2055
+ padding: 8px 0;
2056
+ background-color: #f5f7fa;
2057
+ border-radius: 4px;
2058
+ cursor: pointer;
2059
+ transition: all 0.3s ease;
2060
+ user-select: none;
2061
+ }
2062
+
2063
+ .advanced-options-toggle:hover {
2064
+ background-color: #ebeef5;
2065
+ color: #409EFF;
2066
+ }
2067
+
2068
+ .toggle-icon {
2069
+ margin-left: 8px;
2070
+ transition: transform 0.3s ease;
2071
+ }
2072
+
2073
+ .toggle-icon.is-active {
2074
+ transform: rotate(180deg);
2075
+ }
2076
+
2077
+ .advanced-fields {
2078
+ margin-top: 10px;
2079
+ display: flex;
2080
+ flex-direction: column;
2081
+ gap: 15px;
2082
+ animation: fade-in 0.3s ease-in-out;
2083
+ }
2084
+
2085
+ @keyframes fade-in {
2086
+ from {
2087
+ opacity: 0;
2088
+ transform: translateY(-10px);
2089
+ }
2090
+ to {
2091
+ opacity: 1;
2092
+ transform: translateY(0);
2093
+ }
2094
+ }
2094
2095
  </style>
2095
2096
 
2096
2097
  <!-- 添加全局样式 -->