zen-gitsync 2.0.6 → 2.0.8

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.
@@ -2,7 +2,7 @@
2
2
  import { ref, onMounted, computed, watch } from 'vue'
3
3
  import { ElMessage, ElMessageBox } from 'element-plus'
4
4
  // import { io } from 'socket.io-client'
5
- import { Refresh, ArrowLeft, ArrowRight, Folder, Document, ArrowUp, RefreshRight, Check, Close } from '@element-plus/icons-vue'
5
+ import { Refresh, ArrowLeft, ArrowRight, Folder, Document, ArrowUp, RefreshRight, Check, Close, Download, Connection } from '@element-plus/icons-vue'
6
6
  import { useGitLogStore } from '../stores/gitLogStore'
7
7
  import { useGitStore } from '../stores/gitStore'
8
8
 
@@ -38,6 +38,10 @@ const directoryItems = ref<{name: string, path: string, type: string}[]>([])
38
38
  const isBrowsing = ref(false)
39
39
  const browseErrorMessage = ref('')
40
40
 
41
+ // 添加git操作相关状态
42
+ const isGitPulling = ref(false)
43
+ const isGitFetching = ref(false)
44
+
41
45
  const currentDirectory = ref(props.initialDirectory || '');
42
46
  async function loadStatus() {
43
47
  try {
@@ -56,6 +60,9 @@ async function loadStatus() {
56
60
  // 使用gitLogStore获取Git状态
57
61
  await gitLogStore.fetchStatus()
58
62
 
63
+ // 同时刷新分支状态信息,确保显示最新的领先/落后提交数
64
+ await gitStore.getBranchStatus()
65
+
59
66
  ElMessage({
60
67
  message: 'Git 状态已刷新',
61
68
  type: 'success',
@@ -115,10 +122,41 @@ async function getFileDiff(filePath: string) {
115
122
  selectedFile.value = filePath
116
123
  // 设置当前文件索引
117
124
  currentFileIndex.value = gitLogStore.fileList.findIndex(file => file.path === filePath)
118
- const response = await fetch(`/api/diff?file=${encodeURIComponent(filePath)}`)
119
- const data = await response.json()
120
- diffContent.value = data.diff || '没有变更'
121
- diffDialogVisible.value = true
125
+
126
+ // 获取当前文件的状态类型
127
+ const currentFile = gitLogStore.fileList[currentFileIndex.value]
128
+
129
+ // 对未跟踪文件特殊处理
130
+ if (currentFile && currentFile.type === 'untracked') {
131
+ try {
132
+ // 获取未跟踪文件的内容
133
+ const response = await fetch(`/api/file-content?file=${encodeURIComponent(filePath)}`)
134
+ const data = await response.json()
135
+
136
+ if (data.success && data.content) {
137
+ // 构建一个类似diff的格式来显示新文件内容
138
+ diffContent.value = `diff --git a/${filePath} b/${filePath}\n` +
139
+ `新文件: ${filePath}\n` +
140
+ `--- /dev/null\n` +
141
+ `+++ b/${filePath}\n` +
142
+ `@@ -0,0 +1,${data.content.split('\n').length} @@\n` +
143
+ data.content.split('\n').map((line: string) => `+${line}`).join('\n')
144
+ } else {
145
+ diffContent.value = '这是一个新文件,尚未被Git跟踪。\n添加到暂存区后可以提交该文件。'
146
+ }
147
+ } catch (error) {
148
+ console.error('获取未跟踪文件内容失败:', error)
149
+ diffContent.value = '这是一个新文件,尚未被Git跟踪。\n添加到暂存区后可以提交该文件。'
150
+ }
151
+
152
+ diffDialogVisible.value = true
153
+ } else {
154
+ // 对于已跟踪的文件,获取常规差异
155
+ const response = await fetch(`/api/diff?file=${encodeURIComponent(filePath)}`)
156
+ const data = await response.json()
157
+ diffContent.value = data.diff || '没有变更'
158
+ diffDialogVisible.value = true
159
+ }
122
160
  } catch (error) {
123
161
  ElMessage({
124
162
  message: '获取文件差异失败: ' + (error as Error).message,
@@ -318,6 +356,30 @@ async function refreshStatus() {
318
356
  await loadStatus()
319
357
  }
320
358
 
359
+ // 添加git pull操作方法
360
+ async function handleGitPull() {
361
+ isGitPulling.value = true
362
+ try {
363
+ await gitStore.gitPull()
364
+ // 刷新Git状态
365
+ await loadStatus()
366
+ } finally {
367
+ isGitPulling.value = false
368
+ }
369
+ }
370
+
371
+ // 添加git fetch --all操作方法
372
+ async function handleGitFetchAll() {
373
+ isGitFetching.value = true
374
+ try {
375
+ await gitStore.gitFetchAll()
376
+ // 刷新Git状态
377
+ await loadStatus()
378
+ } finally {
379
+ isGitFetching.value = false
380
+ }
381
+ }
382
+
321
383
  // 添加撤回文件修改的方法
322
384
  async function revertFileChanges(filePath: string) {
323
385
  try {
@@ -387,6 +449,11 @@ onMounted(() => {
387
449
  // App.vue已经加载了Git相关数据,此时只需加载状态
388
450
  // 如果已有初始目录,则只需加载状态
389
451
  loadStatus()
452
+
453
+ // 如果是Git仓库,确保分支状态也被加载
454
+ if (gitStore.isGitRepo) {
455
+ gitStore.getBranchStatus()
456
+ }
390
457
  })
391
458
 
392
459
  // 监听autoUpdateEnabled的变化,手动调用toggleAutoUpdate
@@ -424,6 +491,32 @@ defineExpose({
424
491
  class="auto-update-switch"
425
492
  />
426
493
  </el-tooltip>
494
+
495
+ <!-- 添加Git Pull按钮 -->
496
+ <el-tooltip content="Git Pull (拉取远程更新)" placement="top" :hide-after="1000">
497
+ <el-button
498
+ type="primary"
499
+ :icon="Download"
500
+ circle
501
+ size="small"
502
+ @click="handleGitPull"
503
+ :loading="isGitPulling"
504
+ :disabled="!gitStore.hasUpstream"
505
+ />
506
+ </el-tooltip>
507
+
508
+ <!-- 添加Git Fetch All按钮 -->
509
+ <el-tooltip content="Git Fetch All (获取所有远程分支)" placement="top" :hide-after="1000">
510
+ <el-button
511
+ type="info"
512
+ :icon="Connection"
513
+ circle
514
+ size="small"
515
+ @click="handleGitFetchAll"
516
+ :loading="isGitFetching"
517
+ />
518
+ </el-tooltip>
519
+
427
520
  <el-tooltip content="刷新状态" placement="top" :hide-after="1000">
428
521
  <el-button
429
522
  type="primary"
@@ -447,125 +540,180 @@ defineExpose({
447
540
  </div>
448
541
 
449
542
  <div v-if="!gitStore.isGitRepo" class="status-box">
450
- 当前目录不是一个Git仓库
543
+ <div class="empty-status">
544
+ <p>当前目录不是Git仓库</p>
545
+ <el-button type="primary" size="small" @click="openDirectoryDialog">
546
+ 切换目录
547
+ </el-button>
548
+ </div>
451
549
  </div>
452
550
 
453
- <!-- 现代化、简洁的文件列表 -->
454
- <div v-if="gitLogStore.fileList.length" class="file-list-container">
455
- <!-- 分组显示文件 -->
456
- <div v-if="gitLogStore.fileList.some(f => f.type === 'added')" class="file-group">
457
- <div class="file-group-header">已暂存的更改</div>
458
- <div class="file-list">
459
- <div
460
- v-for="file in gitLogStore.fileList.filter(f => f.type === 'added')"
461
- :key="file.path"
462
- class="file-item"
463
- @click="handleFileClick(file)"
464
- >
465
- <div class="file-info">
466
- <div class="file-path-container">
467
- <span class="file-name">{{ getFileName(file.path) }}</span>
468
- <span class="file-directory">{{ getFileDirectory(file.path) }}</span>
469
- </div>
470
- </div>
471
- <div class="file-actions">
472
- <el-tooltip content="取消暂存" placement="top" :hide-after="1000">
473
- <el-button
474
- type="warning"
475
- size="small"
476
- circle
477
- @click.stop="unstageFile(file.path)"
478
- >-</el-button>
479
- </el-tooltip>
551
+ <div v-else>
552
+ <!-- 分支同步状态信息 -->
553
+ <div v-if="gitStore.hasUpstream && (gitStore.branchAhead > 0 || gitStore.branchBehind > 0)" class="branch-sync-status">
554
+ <div class="sync-status-content">
555
+ <el-tooltip content="本地分支与远程分支的状态对比" placement="top">
556
+ <div class="status-badges">
557
+ <el-tag v-if="gitStore.branchAhead > 0" size="small" type="warning" class="status-badge">
558
+ <template #default>
559
+ <span class="badge-content">
560
+ <el-icon><ArrowUp /></el-icon> 你的分支领先 'origin/{{ gitStore.currentBranch }}' {{ gitStore.branchAhead }} 个提交
561
+ </span>
562
+ </template>
563
+ </el-tag>
564
+ <el-tag v-if="gitStore.branchBehind > 0" size="small" type="info" class="status-badge">
565
+ <template #default>
566
+ <span class="badge-content">
567
+ <el-icon><ArrowDown /></el-icon> 你的分支落后 'origin/{{ gitStore.currentBranch }}' {{ gitStore.branchBehind }} 个提交
568
+ </span>
569
+ </template>
570
+ </el-tag>
480
571
  </div>
481
- </div>
572
+ </el-tooltip>
482
573
  </div>
483
574
  </div>
484
575
 
485
- <div v-if="gitLogStore.fileList.some(f => f.type === 'modified' || f.type === 'deleted')" class="file-group">
486
- <div class="file-group-header">未暂存的更改</div>
487
- <div class="file-list">
488
- <div
489
- v-for="file in gitLogStore.fileList.filter(f => f.type === 'modified' || f.type === 'deleted')"
490
- :key="file.path"
491
- class="file-item"
492
- @click="handleFileClick(file)"
493
- >
494
- <div class="file-info">
495
- <div class="file-status-indicator" :class="file.type"></div>
496
- <div class="file-path-container">
497
- <span class="file-name">{{ getFileName(file.path) }}</span>
498
- <span class="file-directory">{{ getFileDirectory(file.path) }}</span>
576
+ <!-- 默认状态信息 -->
577
+ <div v-if="!gitStore.hasUpstream || (gitStore.branchAhead === 0 && gitStore.branchBehind === 0)" class="git-status-message">
578
+ <p>当前工作在 <el-tag size="small" type="success">{{ gitStore.currentBranch }}</el-tag> 分支</p>
579
+ </div>
580
+
581
+ <!-- 现代化、简洁的文件列表 -->
582
+ <div v-if="gitLogStore.fileList.length" class="file-list-container">
583
+ <!-- 分组显示文件 -->
584
+ <div v-if="gitLogStore.fileList.some(f => f.type === 'added')" class="file-group">
585
+ <div class="file-group-header">已暂存的更改</div>
586
+ <div class="file-list">
587
+ <div
588
+ v-for="file in gitLogStore.fileList.filter(f => f.type === 'added')"
589
+ :key="file.path"
590
+ class="file-item"
591
+ @click="handleFileClick(file)"
592
+ >
593
+ <div class="file-info">
594
+ <div class="file-path-container">
595
+ <span class="file-name">{{ getFileName(file.path) }}</span>
596
+ <span class="file-directory">{{ getFileDirectory(file.path) }}</span>
597
+ </div>
598
+ </div>
599
+ <div class="file-actions">
600
+ <el-tooltip content="取消暂存" placement="top" :hide-after="1000">
601
+ <el-button
602
+ type="warning"
603
+ size="small"
604
+ circle
605
+ @click.stop="unstageFile(file.path)"
606
+ >-</el-button>
607
+ </el-tooltip>
499
608
  </div>
500
- </div>
501
- <div class="file-actions">
502
- <el-tooltip content="添加到暂存区" placement="top" :hide-after="1000">
503
- <el-button
504
- type="success"
505
- size="small"
506
- circle
507
- @click.stop="stageFile(file.path)"
508
- >+</el-button>
509
- </el-tooltip>
510
- <el-tooltip content="撤回修改" placement="top" :hide-after="1000">
511
- <el-button
512
- type="danger"
513
- size="small"
514
- :icon="RefreshRight"
515
- circle
516
- @click.stop="revertFileChanges(file.path)"
517
- />
518
- </el-tooltip>
519
609
  </div>
520
610
  </div>
521
611
  </div>
522
- </div>
523
-
524
- <div v-if="gitLogStore.fileList.some(f => f.type === 'untracked')" class="file-group">
525
- <div class="file-group-header">未跟踪的文件</div>
526
- <div class="file-list">
527
- <div
528
- v-for="file in gitLogStore.fileList.filter(f => f.type === 'untracked')"
529
- :key="file.path"
530
- class="file-item"
531
- @click="handleFileClick(file)"
532
- >
533
- <div class="file-info">
534
- <div class="file-status-indicator untracked"></div>
535
- <div class="file-path-container">
536
- <span class="file-name">{{ getFileName(file.path) }}</span>
537
- <span class="file-directory">{{ getFileDirectory(file.path) }}</span>
612
+
613
+ <div v-if="gitLogStore.fileList.some(f => f.type === 'modified' || f.type === 'deleted')" class="file-group">
614
+ <div class="file-group-header">未暂存的更改</div>
615
+ <div class="file-list">
616
+ <div
617
+ v-for="file in gitLogStore.fileList.filter(f => f.type === 'modified' || f.type === 'deleted')"
618
+ :key="file.path"
619
+ class="file-item"
620
+ @click="handleFileClick(file)"
621
+ >
622
+ <div class="file-info">
623
+ <div class="file-status-indicator" :class="file.type"></div>
624
+ <div class="file-path-container">
625
+ <span class="file-name">{{ getFileName(file.path) }}</span>
626
+ <span class="file-directory">{{ getFileDirectory(file.path) }}</span>
627
+ </div>
628
+ </div>
629
+ <div class="file-actions">
630
+ <el-tooltip content="添加到暂存区" placement="top" :hide-after="1000">
631
+ <el-button
632
+ type="success"
633
+ size="small"
634
+ circle
635
+ @click.stop="stageFile(file.path)"
636
+ >+</el-button>
637
+ </el-tooltip>
638
+ <el-tooltip content="撤回修改" placement="top" :hide-after="1000">
639
+ <el-button
640
+ type="danger"
641
+ size="small"
642
+ :icon="RefreshRight"
643
+ circle
644
+ @click.stop="revertFileChanges(file.path)"
645
+ />
646
+ </el-tooltip>
538
647
  </div>
539
648
  </div>
540
- <div class="file-actions">
541
- <el-tooltip content="添加到暂存区" placement="top" :hide-after="1000">
542
- <el-button
543
- type="success"
544
- size="small"
545
- circle
546
- @click.stop="stageFile(file.path)"
547
- >+</el-button>
548
- </el-tooltip>
549
- <el-tooltip content="删除文件" placement="top" :hide-after="1000">
550
- <el-button
551
- type="danger"
552
- size="small"
553
- :icon="Close"
554
- circle
555
- @click.stop="revertFileChanges(file.path)"
556
- />
557
- </el-tooltip>
649
+ </div>
650
+ </div>
651
+
652
+ <div v-if="gitLogStore.fileList.some(f => f.type === 'untracked')" class="file-group">
653
+ <div class="file-group-header">未跟踪的文件</div>
654
+ <div class="file-list">
655
+ <div
656
+ v-for="file in gitLogStore.fileList.filter(f => f.type === 'untracked')"
657
+ :key="file.path"
658
+ class="file-item"
659
+ @click="handleFileClick(file)"
660
+ >
661
+ <div class="file-info">
662
+ <div class="file-status-indicator untracked"></div>
663
+ <div class="file-path-container">
664
+ <span class="file-name">{{ getFileName(file.path) }}</span>
665
+ <span class="file-directory">{{ getFileDirectory(file.path) }}</span>
666
+ </div>
667
+ </div>
668
+ <div class="file-actions">
669
+ <el-tooltip content="添加到暂存区" placement="top" :hide-after="1000">
670
+ <el-button
671
+ type="success"
672
+ size="small"
673
+ circle
674
+ @click.stop="stageFile(file.path)"
675
+ >+</el-button>
676
+ </el-tooltip>
677
+ <el-tooltip content="删除文件" placement="top" :hide-after="1000">
678
+ <el-button
679
+ type="danger"
680
+ size="small"
681
+ :icon="Close"
682
+ circle
683
+ @click.stop="revertFileChanges(file.path)"
684
+ />
685
+ </el-tooltip>
686
+ </div>
558
687
  </div>
559
688
  </div>
560
689
  </div>
561
690
  </div>
562
- </div>
563
-
564
- <div v-else-if="gitStore.isGitRepo" class="empty-status">
565
- <div class="empty-icon">
566
- <el-icon><Document /></el-icon>
691
+
692
+ <div v-else-if="gitStore.isGitRepo" class="empty-status">
693
+ <div class="empty-icon">
694
+ <el-icon><Document /></el-icon>
695
+ </div>
696
+ <div class="empty-text">没有检测到任何更改</div>
697
+ <div class="empty-subtext">工作区是干净的</div>
698
+
699
+ <!-- 添加分支信息 -->
700
+ <div class="branch-info">
701
+ <p>当前工作在 <el-tag size="small" type="success">{{ gitStore.currentBranch }}</el-tag> 分支</p>
702
+
703
+ <!-- 显示分支同步状态 -->
704
+ <div v-if="gitStore.hasUpstream">
705
+ <span v-if="gitStore.branchAhead > 0" class="branch-sync-info warning">
706
+ <el-icon><ArrowUp /></el-icon> 你的分支领先 'origin/{{ gitStore.currentBranch }}' {{ gitStore.branchAhead }} 个提交
707
+ </span>
708
+ <span v-else-if="gitStore.branchBehind > 0" class="branch-sync-info info">
709
+ <el-icon><ArrowDown /></el-icon> 你的分支落后 'origin/{{ gitStore.currentBranch }}' {{ gitStore.branchBehind }} 个提交
710
+ </span>
711
+ <span v-else class="branch-sync-info success">
712
+ <el-icon><Check /></el-icon> 你的分支与 'origin/{{ gitStore.currentBranch }}' 同步
713
+ </span>
714
+ </div>
715
+ </div>
567
716
  </div>
568
- <div class="empty-text">没有检测到任何更改</div>
569
717
  </div>
570
718
  </div>
571
719
 
@@ -648,32 +796,72 @@ defineExpose({
648
796
  <!-- 文件差异对话框 -->
649
797
  <el-dialog
650
798
  v-model="diffDialogVisible"
651
- :title="`文件差异: ${selectedFile}`"
652
- width="80%"
799
+ width="80vw"
800
+ top="70px"
653
801
  destroy-on-close
654
802
  class="diff-dialog"
803
+ :show-close="false"
804
+ style="height: calc(100vh - 140px);"
805
+ :modal-append-to-body="false"
806
+ :close-on-click-modal="false"
655
807
  >
808
+ <template #header>
809
+ <div class="diff-dialog-header">
810
+ <div class="file-title">
811
+ <el-icon class="file-icon"><Document /></el-icon>
812
+ <span class="file-path">{{ selectedFile }}</span>
813
+ </div>
814
+ <div class="header-actions">
815
+ <el-button
816
+ @click="diffDialogVisible = false"
817
+ circle
818
+ size="small"
819
+ :icon="Close"
820
+ class="close-button"
821
+ />
822
+ </div>
823
+ </div>
824
+ </template>
825
+
656
826
  <div v-loading="isLoadingDiff" class="diff-content">
657
827
  <div v-if="diffContent" v-html="formatDiff(diffContent)" class="diff-formatted"></div>
658
828
  <div v-else class="no-diff">该文件没有差异或是新文件</div>
659
829
  </div>
660
830
 
661
- <!-- 添加文件导航按钮 -->
662
- <div class="file-navigation">
663
- <el-button
664
- :icon="ArrowLeft"
665
- @click="goToPreviousFile"
666
- :disabled="currentFileIndex <= 0 || gitLogStore.fileList.length === 0"
667
- circle
668
- />
669
- <span class="file-counter">{{ currentFileIndex + 1 }} / {{ gitLogStore.fileList.length }}</span>
670
- <el-button
671
- :icon="ArrowRight"
672
- @click="goToNextFile"
673
- :disabled="currentFileIndex >= gitLogStore.fileList.length - 1 || gitLogStore.fileList.length === 0"
674
- circle
675
- />
676
- </div>
831
+ <template #footer>
832
+ <div class="file-navigation">
833
+ <el-button
834
+ type="primary"
835
+ :icon="ArrowLeft"
836
+ @click="goToPreviousFile"
837
+ :disabled="currentFileIndex <= 0 || gitLogStore.fileList.length === 0"
838
+ plain
839
+ class="nav-button"
840
+ >
841
+ 上一个文件
842
+ </el-button>
843
+
844
+ <div class="file-counter">
845
+ <el-tag type="info" effect="plain" class="counter-tag">
846
+ {{ currentFileIndex + 1 }} / {{ gitLogStore.fileList.length }}
847
+ </el-tag>
848
+ </div>
849
+
850
+ <el-button
851
+ type="primary"
852
+ :icon="ArrowRight"
853
+ @click="goToNextFile"
854
+ :disabled="currentFileIndex >= gitLogStore.fileList.length - 1 || gitLogStore.fileList.length === 0"
855
+ plain
856
+ class="nav-button"
857
+ >
858
+ 下一个文件
859
+ <template #icon>
860
+ <el-icon class="el-icon--right"><ArrowRight /></el-icon>
861
+ </template>
862
+ </el-button>
863
+ </div>
864
+ </template>
677
865
  </el-dialog>
678
866
  </div>
679
867
  </template>
@@ -718,6 +906,7 @@ defineExpose({
718
906
  flex: 1;
719
907
  display: flex;
720
908
  flex-direction: column;
909
+ min-height: 300px; /* 确保内容区有最小高度 */
721
910
  }
722
911
 
723
912
  .current-directory {
@@ -764,7 +953,8 @@ defineExpose({
764
953
  flex-direction: column;
765
954
  margin-bottom: 0;
766
955
  gap: 12px;
767
- height: calc(100% - 70px); /* 给底部留出些空间 */
956
+ height: auto; /* 改为自适应高度,不固定高度 */
957
+ min-height: 100px; /* 设置最小高度 */
768
958
  }
769
959
 
770
960
  .file-group {
@@ -801,6 +991,7 @@ defineExpose({
801
991
  .file-list {
802
992
  overflow-y: auto;
803
993
  min-height: 40px; /* 最小高度 */
994
+ max-height: 200px; /* 最大高度限制,避免过长列表 */
804
995
  flex-grow: 1; /* 允许文件列表在文件组内扩展 */
805
996
  padding: 0;
806
997
  margin: 0;
@@ -946,9 +1137,10 @@ defineExpose({
946
1137
  .file-directory {
947
1138
  font-size: 12px;
948
1139
  color: #909399;
1140
+ max-width: 200px;
949
1141
  overflow: hidden;
1142
+ white-space: nowrap;
950
1143
  text-overflow: ellipsis;
951
- line-height: 1.2;
952
1144
  }
953
1145
 
954
1146
  .file-actions {
@@ -967,22 +1159,87 @@ defineExpose({
967
1159
  flex-direction: column;
968
1160
  align-items: center;
969
1161
  justify-content: center;
970
- height: calc(100% - 70px);
971
- background-color: #f8f9fa;
972
- border-radius: 6px;
973
- border: 1px solid #ebeef5;
974
- margin-top: 15px;
1162
+ padding: 40px 20px;
1163
+ text-align: center;
1164
+ background-color: #f9f9f9;
1165
+ border-radius: 8px;
1166
+ margin-top: 10px;
975
1167
  }
976
1168
 
977
1169
  .empty-icon {
978
- font-size: 32px;
979
- color: #c0c4cc;
980
- margin-bottom: 10px;
1170
+ width: 60px;
1171
+ height: 60px;
1172
+ display: flex;
1173
+ align-items: center;
1174
+ justify-content: center;
1175
+ background-color: #ebeef5;
1176
+ border-radius: 50%;
1177
+ margin-bottom: 15px;
1178
+ font-size: 24px;
1179
+ color: #909399;
1180
+ animation: pulse 2s infinite ease-in-out;
1181
+ }
1182
+
1183
+ @keyframes pulse {
1184
+ 0% { transform: scale(1); opacity: 0.7; }
1185
+ 50% { transform: scale(1.05); opacity: 1; }
1186
+ 100% { transform: scale(1); opacity: 0.7; }
981
1187
  }
982
1188
 
983
1189
  .empty-text {
1190
+ font-size: 16px;
1191
+ font-weight: 500;
1192
+ color: #606266;
1193
+ margin-bottom: 5px;
1194
+ }
1195
+
1196
+ .empty-subtext {
1197
+ font-size: 14px;
984
1198
  color: #909399;
1199
+ margin-bottom: 20px;
1200
+ }
1201
+
1202
+ /* 分支信息样式 */
1203
+ .branch-info {
1204
+ margin-top: 15px;
1205
+ padding: 10px 15px;
1206
+ background-color: #ebeef5;
1207
+ border-radius: 6px;
1208
+ text-align: left;
1209
+ width: 100%;
1210
+ max-width: 400px;
1211
+ }
1212
+
1213
+ .branch-info p {
1214
+ margin: 5px 0;
985
1215
  font-size: 14px;
1216
+ color: #606266;
1217
+ }
1218
+
1219
+ .branch-sync-info {
1220
+ display: flex;
1221
+ align-items: center;
1222
+ gap: 5px;
1223
+ font-size: 13px;
1224
+ margin-top: 5px;
1225
+ padding: 5px 8px;
1226
+ border-radius: 4px;
1227
+ background-color: #f5f7fa;
1228
+ }
1229
+
1230
+ .branch-sync-info.warning {
1231
+ color: #e6a23c;
1232
+ background-color: #fdf6ec;
1233
+ }
1234
+
1235
+ .branch-sync-info.info {
1236
+ color: #909399;
1237
+ background-color: #f4f4f5;
1238
+ }
1239
+
1240
+ .branch-sync-info.success {
1241
+ color: #67c23a;
1242
+ background-color: #f0f9eb;
986
1243
  }
987
1244
 
988
1245
  /* 添加针对空内容区域的样式 */
@@ -1101,6 +1358,186 @@ defineExpose({
1101
1358
  gap: 10px;
1102
1359
  margin-top: 10px;
1103
1360
  }
1361
+
1362
+ /* 添加分支状态样式 */
1363
+ .branch-sync-status {
1364
+ display: flex;
1365
+ align-items: center;
1366
+ padding: 12px 15px;
1367
+ background-color: #f8f9fa;
1368
+ border-radius: 4px;
1369
+ margin-bottom: 15px;
1370
+ border-left: 3px solid #e6a23c;
1371
+ }
1372
+
1373
+ /* 添加默认分支状态信息样式 */
1374
+ .git-status-message {
1375
+ padding: 12px 15px;
1376
+ background-color: #f8f9fa;
1377
+ border-radius: 4px;
1378
+ margin-bottom: 15px;
1379
+ border-left: 3px solid #67c23a;
1380
+ }
1381
+
1382
+ .git-status-message p {
1383
+ margin: 0;
1384
+ display: flex;
1385
+ align-items: center;
1386
+ gap: 8px;
1387
+ font-size: 14px;
1388
+ color: #606266;
1389
+ }
1390
+
1391
+ .sync-status-content {
1392
+ display: flex;
1393
+ align-items: center;
1394
+ flex-wrap: wrap;
1395
+ gap: 10px;
1396
+ }
1397
+
1398
+ .status-badges {
1399
+ display: flex;
1400
+ flex-direction: column;
1401
+ gap: 8px;
1402
+ width: 100%;
1403
+ }
1404
+
1405
+ .status-badge {
1406
+ display: flex;
1407
+ align-items: center;
1408
+ width: 100%;
1409
+ }
1410
+
1411
+ .status-badge.el-tag--warning {
1412
+ background-color: #fdf6ec;
1413
+ border-color: #faecd8;
1414
+ }
1415
+
1416
+ .status-badge.el-tag--info {
1417
+ background-color: #f4f4f5;
1418
+ border-color: #e9e9eb;
1419
+ }
1420
+
1421
+ .badge-content {
1422
+ display: flex;
1423
+ align-items: center;
1424
+ gap: 6px;
1425
+ font-size: 13px;
1426
+ }
1427
+ .diff-dialog {
1428
+ height: calc(100vh - 150px);
1429
+ }
1430
+
1431
+ .diff-dialog-header {
1432
+ display: flex;
1433
+ justify-content: space-between;
1434
+ align-items: center;
1435
+ padding: 16px 20px;
1436
+ border-bottom: 1px solid #ebeef5;
1437
+ background-color: #f9f9fb;
1438
+ }
1439
+
1440
+ .file-title {
1441
+ display: flex;
1442
+ align-items: center;
1443
+ font-size: 16px;
1444
+ font-weight: 500;
1445
+ color: #303133;
1446
+ gap: 10px;
1447
+ overflow: hidden;
1448
+ }
1449
+
1450
+ .file-icon {
1451
+ color: #409eff;
1452
+ font-size: 20px;
1453
+ }
1454
+
1455
+ .file-path {
1456
+ white-space: nowrap;
1457
+ overflow: hidden;
1458
+ text-overflow: ellipsis;
1459
+ font-family: monospace;
1460
+ }
1461
+
1462
+ .diff-content {
1463
+ flex: 1;
1464
+ overflow-y: auto;
1465
+ padding: 10px 20px;
1466
+ background-color: #fafafa;
1467
+ /* height: 100%;
1468
+ overflow: auto; */
1469
+ }
1470
+ :deep(.el-dialog__body) {
1471
+ height: calc(100vh - 320px);
1472
+ overflow: auto;
1473
+ }
1474
+ .diff-formatted {
1475
+ font-family: 'Consolas', 'Courier New', monospace;
1476
+ font-size: 14px;
1477
+ line-height: 1.5;
1478
+ white-space: pre-wrap;
1479
+ padding-bottom: 20px;
1480
+ }
1481
+
1482
+ .no-diff {
1483
+ display: flex;
1484
+ align-items: center;
1485
+ justify-content: center;
1486
+ height: 100%;
1487
+ color: #909399;
1488
+ font-size: 14px;
1489
+ }
1490
+
1491
+ .file-navigation {
1492
+ display: flex;
1493
+ justify-content: space-between;
1494
+ align-items: center;
1495
+ padding: 10px 20px;
1496
+ border-top: 1px solid #ebeef5;
1497
+ background-color: #f9f9fb;
1498
+ }
1499
+
1500
+ .counter-tag {
1501
+ font-family: monospace;
1502
+ font-size: 14px;
1503
+ padding: 6px 12px;
1504
+ min-width: 80px;
1505
+ text-align: center;
1506
+ }
1507
+
1508
+ .nav-button {
1509
+ min-width: 120px;
1510
+ }
1511
+
1512
+ /* 确保文件差异对话框里的内容滚动条样式一致 */
1513
+ .diff-formatted::-webkit-scrollbar,
1514
+ .diff-content::-webkit-scrollbar {
1515
+ width: 6px;
1516
+ height: 6px;
1517
+ }
1518
+
1519
+ .diff-formatted::-webkit-scrollbar-thumb,
1520
+ .diff-content::-webkit-scrollbar-thumb {
1521
+ background-color: rgba(144, 147, 153, 0.3);
1522
+ border-radius: 4px;
1523
+ }
1524
+
1525
+ .diff-formatted::-webkit-scrollbar-thumb:hover,
1526
+ .diff-content::-webkit-scrollbar-thumb:hover {
1527
+ background-color: rgba(144, 147, 153, 0.5);
1528
+ }
1529
+
1530
+ .diff-formatted::-webkit-scrollbar-track,
1531
+ .diff-content::-webkit-scrollbar-track {
1532
+ background-color: transparent;
1533
+ }
1534
+
1535
+ /* 兼容Firefox滚动条样式 */
1536
+ .diff-formatted,
1537
+ .diff-content {
1538
+ scrollbar-width: thin;
1539
+ scrollbar-color: rgba(144, 147, 153, 0.3) transparent;
1540
+ }
1104
1541
  </style>
1105
1542
 
1106
1543
  <!-- 非scoped样式,使diff格式化样式对动态内容生效 -->