zen-gitsync 2.0.5 → 2.0.7

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,7 +1,7 @@
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 } from "@element-plus/icons-vue";
4
+ import { Setting, Edit, Check, Upload, RefreshRight, Delete, Position } from "@element-plus/icons-vue";
5
5
  import { useGitLogStore } from "../stores/gitLogStore";
6
6
  import { useGitStore } from "../stores/gitStore";
7
7
 
@@ -10,6 +10,8 @@ const gitStore = useGitStore();
10
10
  const commitMessage = ref("");
11
11
  const isPushing = ref(false);
12
12
  // 添加提交并推送的状态变量
13
+ const showPushSuccess = ref(false);
14
+ // 添加placeholder变量
13
15
  const placeholder = ref("输入提交信息...");
14
16
  // 添加默认提交信息变量
15
17
  const defaultCommitMessage = ref("");
@@ -539,6 +541,14 @@ async function commitChanges() {
539
541
  }
540
542
  }
541
543
 
544
+ // 显示推送成功提示
545
+ function showPushSuccessIndicator() {
546
+ showPushSuccess.value = true;
547
+ setTimeout(() => {
548
+ showPushSuccess.value = false;
549
+ }, 2000);
550
+ }
551
+
542
552
  // 推送到远程 (git push)
543
553
  async function pushToRemote() {
544
554
  try {
@@ -550,13 +560,16 @@ async function pushToRemote() {
550
560
  // 触发成功事件
551
561
  gitStore.getCurrentBranch();
552
562
  gitLogStore.fetchLog();
563
+
564
+ // 显示成功动画
565
+ isPushing.value = false
566
+ showPushSuccessIndicator();
553
567
  }
554
568
  } catch (error) {
555
569
  ElMessage({
556
570
  message: `推送失败: ${(error as Error).message}`,
557
571
  type: "error",
558
572
  });
559
- } finally {
560
573
  isPushing.value = false
561
574
  }
562
575
  }
@@ -599,22 +612,28 @@ async function addCommitAndPush() {
599
612
  }
600
613
 
601
614
  try {
615
+ isPushing.value = true
602
616
  await gitLogStore.addCommitAndPush(finalCommitMessage.value, skipHooks.value);
603
617
 
604
-
605
618
  // 清空提交信息
606
619
  clearCommitFields();
607
620
 
608
621
  // 触发成功事件
609
622
  gitStore.getCurrentBranch();
623
+
624
+ // 确保通过fetchLog获取的是最新的第1页数据
610
625
  gitLogStore.fetchLog();
626
+
627
+ // 显示成功动画
628
+ isPushing.value = false
629
+ showPushSuccessIndicator();
611
630
 
612
631
  } catch (error) {
613
632
  ElMessage({
614
633
  message: `暂存、提交并推送失败: ${(error as Error).message}`,
615
634
  type: "error",
616
635
  });
617
- } finally {
636
+ isPushing.value = false
618
637
  }
619
638
  }
620
639
 
@@ -675,255 +694,357 @@ onMounted(() => {
675
694
  </script>
676
695
 
677
696
  <template>
678
- <div class="card">
679
- <h2>提交更改</h2>
680
-
681
- <div class="layout-container">
682
- <!-- 如果没有配置Git用户信息,显示提示 -->
683
- <div v-if="gitStore.userName === '' || gitStore.userEmail === ''" class="git-config-warning">
684
- <el-alert
685
- title="Git用户信息未配置"
686
- type="warning"
687
- :closable="false"
688
- show-icon
689
- >
690
- <p>您需要配置Git用户名和邮箱才能提交代码。请使用以下命令配置:</p>
691
- <pre class="config-command">git config --global user.name "Your Name"
692
- git config --global user.email "your.email@example.com"</pre>
693
- </el-alert>
697
+ <div class="card" :class="{ 'is-pushing': gitLogStore.isPushing || isPushing }">
698
+ <div class="card-header">
699
+ <h2>提交更改</h2>
700
+ </div>
701
+
702
+ <!-- 添加推送中指示器 -->
703
+ <transition name="el-fade-in-linear">
704
+ <div v-if="isPushing" class="pushing-indicator">
705
+ <div class="pushing-spinner">
706
+ <svg viewBox="0 0 50 50" class="circular">
707
+ <circle class="path" cx="25" cy="25" r="20" fill="none" />
708
+ </svg>
709
+ </div>
710
+ <div class="pushing-text">正在推送...</div>
694
711
  </div>
695
-
696
- <!-- 正常的提交区域,仅在Git用户信息已配置时显示 -->
697
- <template v-else>
698
- <!-- 左侧:提交表单 -->
699
- <div class="commit-section">
700
- <div class="commit-options">
701
- <div class="options-row">
702
- <div class="commit-mode-toggle">
703
- <el-switch v-model="isStandardCommit" active-text="标准化提交" inactive-text="普通提交" />
704
- </div>
712
+ </transition>
705
713
 
706
- <div class="no-verify-toggle">
707
- <el-tooltip content="跳过 Git 钩子检查 (--no-verify)" placement="top">
708
- <el-switch v-model="skipHooks" active-text="跳过钩子 (--no-verify)" />
709
- </el-tooltip>
714
+ <!-- 添加推送成功指示器 -->
715
+ <transition name="el-fade-in-linear">
716
+ <div v-if="showPushSuccess" class="push-success-indicator">
717
+ <el-icon class="push-success-icon"><Check /></el-icon>
718
+ <div class="push-success-text">推送成功!</div>
719
+ </div>
720
+ </transition>
721
+
722
+ <div class="card-content">
723
+ <div class="layout-container">
724
+ <!-- 如果没有配置Git用户信息,显示提示 -->
725
+ <div v-if="gitStore.userName === '' || gitStore.userEmail === ''" class="git-config-warning">
726
+ <el-alert
727
+ title="Git用户信息未配置"
728
+ type="warning"
729
+ :closable="false"
730
+ show-icon
731
+ >
732
+ <p>您需要配置Git用户名和邮箱才能提交代码。请使用以下命令配置:</p>
733
+ <pre class="config-command">git config --global user.name "Your Name"
734
+ git config --global user.email "your.email@example.com"</pre>
735
+ </el-alert>
736
+ </div>
737
+
738
+ <!-- 正常的提交区域,仅在Git用户信息已配置时显示 -->
739
+ <template v-else>
740
+ <!-- 左侧:提交表单 -->
741
+ <div class="commit-section">
742
+ <div class="commit-options">
743
+ <div class="options-row">
744
+ <div class="commit-mode-toggle">
745
+ <el-switch v-model="isStandardCommit" active-text="标准化提交" inactive-text="普通提交" />
746
+ </div>
747
+
748
+ <div class="no-verify-toggle">
749
+ <el-tooltip content="跳过 Git 钩子检查 (--no-verify)" placement="top">
750
+ <el-switch v-model="skipHooks" active-text="跳过钩子 (--no-verify)" />
751
+ </el-tooltip>
752
+ </div>
710
753
  </div>
711
754
  </div>
712
- </div>
713
-
714
- <!-- 普通提交表单 -->
715
- <div v-if="!isStandardCommit" class="commit-form">
716
- <el-input v-model="commitMessage" :placeholder="placeholder" clearable />
717
- </div>
718
755
 
719
- <!-- 标准化提交表单 -->
720
- <div v-else class="standard-commit-form">
721
- <div class="standard-commit-header">
722
- <el-select v-model="commitType" placeholder="提交类型" class="type-select" clearable>
723
- <el-option v-for="item in commitTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
724
- </el-select>
725
-
726
- <div class="scope-container">
727
- <el-input v-model="commitScope" placeholder="作用域(可选)" class="scope-input" clearable />
728
- <el-button type="primary" :icon="Setting" circle size="small" class="settings-button"
729
- @click="openScopeSettings">
730
- </el-button>
731
- </div>
756
+ <!-- 普通提交表单 -->
757
+ <div v-if="!isStandardCommit" class="commit-form">
758
+ <el-input v-model="commitMessage" :placeholder="placeholder" clearable />
759
+ </div>
732
760
 
733
- <div class="description-container">
734
- <el-input v-model="commitDescription" placeholder="简短描述(必填)" class="description-input" clearable />
735
- <el-button type="primary" :icon="Setting" circle size="small" class="settings-button"
736
- @click="openDescriptionSettings">
737
- </el-button>
761
+ <!-- 标准化提交表单 -->
762
+ <div v-else class="standard-commit-form">
763
+ <div class="standard-commit-header">
764
+ <el-select v-model="commitType" placeholder="提交类型" class="type-select" clearable>
765
+ <el-option v-for="item in commitTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
766
+ </el-select>
767
+
768
+ <div class="scope-container">
769
+ <el-input v-model="commitScope" placeholder="作用域(可选)" class="scope-input" clearable />
770
+ <el-button type="primary" :icon="Setting" circle size="small" class="settings-button"
771
+ @click="openScopeSettings">
772
+ </el-button>
773
+ </div>
774
+
775
+ <div class="description-container">
776
+ <el-input v-model="commitDescription" placeholder="简短描述(必填)" class="description-input" clearable />
777
+ <el-button type="primary" :icon="Setting" circle size="small" class="settings-button"
778
+ @click="openDescriptionSettings">
779
+ </el-button>
780
+ </div>
738
781
  </div>
739
- </div>
740
782
 
741
- <el-input v-model="commitBody" type="textarea" :rows="4" placeholder="正文(可选):详细描述本次提交的内容和原因" class="body-input"
742
- clearable />
783
+ <el-input v-model="commitBody" type="textarea" :rows="4" placeholder="正文(可选):详细描述本次提交的内容和原因" class="body-input"
784
+ clearable />
743
785
 
744
- <el-input v-model="commitFooter" placeholder="页脚(可选):如 Closes #123" class="footer-input" clearable />
786
+ <el-input v-model="commitFooter" placeholder="页脚(可选):如 Closes #123" class="footer-input" clearable />
745
787
 
746
- <div class="preview-section">
747
- <div class="preview-title">提交信息预览:</div>
748
- <pre class="preview-content">{{ finalCommitMessage }}</pre>
788
+ <div class="preview-section">
789
+ <div class="preview-title">提交信息预览:</div>
790
+ <pre class="preview-content">{{ finalCommitMessage }}</pre>
749
791
 
750
- <div class="preview-title" style="margin-top: 10px;">Git命令预览:</div>
751
- <pre class="preview-content code-command">{{ gitCommandPreview }}</pre>
792
+ <div class="preview-title" style="margin-top: 10px;">Git命令预览:</div>
793
+ <pre class="preview-content code-command">{{ gitCommandPreview }}</pre>
794
+ </div>
752
795
  </div>
753
796
  </div>
754
- </div>
755
797
 
756
- <!-- 右侧:操作区域 -->
757
- <div class="actions-section">
758
- <h3>Git 操作</h3>
759
- <div class="action-groups">
760
- <div class="action-group">
761
- <div class="group-title">基础操作</div>
762
- <div class="group-buttons">
763
- <el-button
764
- type="primary"
765
- @click="addToStage"
766
- :loading="gitLogStore.isAddingFiles"
767
- class="action-button"
768
- >
769
- 暂存更改
770
- <span class="command-text">git add .</span>
771
- </el-button>
772
-
773
- <el-button
774
- type="primary"
775
- @click="commitChanges"
776
- :loading="gitLogStore.isLoadingStatus"
777
- class="action-button"
778
- >
779
- 提交
780
- <span class="command-text">git commit</span>
781
- </el-button>
782
-
783
- <el-button
784
- type="success"
785
- @click="pushToRemote"
786
- :loading="gitLogStore.isPushing"
787
- class="action-button push-button"
788
- >
789
- 推送
790
- <span class="command-text">git push</span>
791
- </el-button>
798
+ <!-- 右侧:操作区域 -->
799
+ <div class="actions-section">
800
+ <h3>Git 操作</h3>
801
+ <div class="action-groups">
802
+ <div class="operations-wrapper">
803
+ <!-- 基础操作 -->
804
+ <div class="action-group">
805
+ <div class="group-title">基础操作</div>
806
+ <div class="group-buttons">
807
+ <el-tooltip content="git add ." placement="top" effect="light" popper-class="git-cmd-tooltip">
808
+ <el-button
809
+ type="primary"
810
+ @click="addToStage"
811
+ :loading="gitLogStore.isAddingFiles"
812
+ class="action-button"
813
+ >
814
+ 暂存更改
815
+ </el-button>
816
+ </el-tooltip>
817
+
818
+ <el-tooltip content="git commit" placement="top" effect="light" popper-class="git-cmd-tooltip">
819
+ <el-button
820
+ type="primary"
821
+ @click="commitChanges"
822
+ :loading="gitLogStore.isLoadingStatus"
823
+ class="action-button"
824
+ >
825
+ 提交
826
+ </el-button>
827
+ </el-tooltip>
828
+
829
+ <el-tooltip content="git push" placement="top" effect="light" popper-class="git-cmd-tooltip">
830
+ <el-button
831
+ type="primary"
832
+ :icon="Upload"
833
+ @click="pushToRemote"
834
+ :loading="gitLogStore.isPushing"
835
+ :class="['action-button', 'push-button', { 'is-loading': gitLogStore.isPushing || isPushing }]"
836
+ >
837
+ 推送
838
+ </el-button>
839
+ </el-tooltip>
840
+ </div>
841
+ </div>
842
+
843
+ <!-- 组合操作 -->
844
+ <div class="action-group">
845
+ <div class="group-title">组合操作</div>
846
+ <div class="group-buttons">
847
+ <el-tooltip content="git add + git commit" placement="top" effect="light" popper-class="git-cmd-tooltip">
848
+ <el-button
849
+ type="primary"
850
+ :icon="Edit"
851
+ @click="addAndCommit"
852
+ :loading="gitLogStore.isAddingFiles || gitLogStore.isCommiting"
853
+ class="action-button"
854
+ >
855
+ 暂存并提交
856
+ </el-button>
857
+ </el-tooltip>
858
+
859
+ <el-tooltip content="git add + git commit + git push" placement="top" effect="light" popper-class="git-cmd-tooltip">
860
+ <el-button
861
+ type="success"
862
+ :icon="Position"
863
+ @click="addCommitAndPush"
864
+ :loading="gitLogStore.isAddingFiles || gitLogStore.isCommiting || gitLogStore.isPushing"
865
+ :class="['action-button', 'one-click-push', { 'is-loading': gitLogStore.isAddingFiles || gitLogStore.isCommiting || gitLogStore.isPushing }]"
866
+ >
867
+ 一键推送
868
+ </el-button>
869
+ </el-tooltip>
870
+ </div>
871
+ </div>
792
872
  </div>
793
- </div>
794
873
 
795
- <div class="action-group">
796
- <div class="group-title">组合操作</div>
797
- <div class="group-buttons">
798
- <el-button
799
- type="warning"
800
- @click="addAndCommit"
801
- :loading="gitLogStore.isAddingFiles || gitLogStore.isCommiting"
802
- class="action-button"
803
- >
804
- 暂存并提交
805
- <span class="command-text">git add + commit</span>
806
- </el-button>
807
-
808
- <el-button
809
- type="danger"
810
- @click="addCommitAndPush"
811
- :loading="gitLogStore.isAddingFiles || gitLogStore.isCommiting || gitLogStore.isPushing"
812
- class="action-button"
813
- >
814
- 一键推送
815
- <span class="command-text command-text-long">git add + commit + push</span>
816
- </el-button>
874
+ <!-- 重置操作 -->
875
+ <div class="action-group reset-group">
876
+ <div class="group-title">重置操作</div>
877
+ <div class="group-buttons">
878
+ <el-tooltip content="git reset HEAD" placement="top" effect="light" popper-class="git-cmd-tooltip">
879
+ <el-button
880
+ type="warning"
881
+ :icon="RefreshRight"
882
+ @click="gitLogStore.resetHead"
883
+ :loading="gitLogStore.isResetting"
884
+ class="action-button reset-button"
885
+ >
886
+ 重置暂存区
887
+ </el-button>
888
+ </el-tooltip>
889
+
890
+ <el-tooltip content="git reset --hard origin/branch" placement="top" effect="light" popper-class="git-cmd-tooltip">
891
+ <el-button
892
+ type="danger"
893
+ :icon="Delete"
894
+ @click="resetToRemote"
895
+ :loading="gitLogStore.isResetting"
896
+ class="action-button danger-button"
897
+ >
898
+ 重置到远程
899
+ </el-button>
900
+ </el-tooltip>
901
+ </div>
817
902
  </div>
818
903
  </div>
904
+ </div>
905
+ </template>
906
+ </div>
819
907
 
820
- <div class="action-group">
821
- <div class="group-title">重置操作</div>
822
- <div class="group-buttons">
823
- <!-- <el-button
824
- type="info"
825
- @click="resetHead"
826
- :loading="gitLogStore.isResetting"
827
- :icon="Refresh"
828
- class="action-button reset-button"
829
- >
830
- 重置暂存区
831
- <span class="command-text">git reset HEAD</span>
832
- </el-button> -->
833
-
834
- <el-button
835
- type="info"
836
- @click="resetToRemote"
837
- :loading="gitLogStore.isResetting"
838
- class="action-button reset-button"
839
- >
840
- 重置到远程
841
- <span class="command-text command-text-long">git reset --hard origin/branch</span>
842
- </el-button>
843
- </div>
908
+ <!-- 简短描述设置弹窗 -->
909
+ <el-dialog title="简短描述模板设置" v-model="descriptionDialogVisible" width="80vw" style="height: 80vh">
910
+ <div class="template-container">
911
+ <div class="template-form">
912
+ <el-input v-model="newTemplateName" :placeholder="isEditingDescription ? '编辑模板内容' : '输入新模板内容'"
913
+ class="template-input" clearable />
914
+ <div class="template-form-buttons">
915
+ <el-button v-if="isEditingDescription" @click="cancelEditDescriptionTemplate">取消</el-button>
916
+ <el-button type="primary" @click="saveDescriptionTemplate" :disabled="!newTemplateName.trim()">{{
917
+ isEditingDescription ? '更新模板' : '添加模板' }}</el-button>
844
918
  </div>
845
919
  </div>
846
- </div>
847
- </template>
848
- </div>
849
920
 
850
- <!-- 简短描述设置弹窗 -->
851
- <el-dialog title="简短描述模板设置" v-model="descriptionDialogVisible" width="80vw" style="height: 80vh">
852
- <div class="template-container">
853
- <div class="template-form">
854
- <el-input v-model="newTemplateName" :placeholder="isEditingDescription ? '编辑模板内容' : '输入新模板内容'"
855
- class="template-input" clearable />
856
- <div class="template-form-buttons">
857
- <el-button v-if="isEditingDescription" @click="cancelEditDescriptionTemplate">取消</el-button>
858
- <el-button type="primary" @click="saveDescriptionTemplate" :disabled="!newTemplateName.trim()">{{
859
- isEditingDescription ? '更新模板' : '添加模板' }}</el-button>
921
+ <div class="template-list">
922
+ <h3>已保存模板</h3>
923
+ <el-empty v-if="descriptionTemplates.length === 0" description="暂无保存的模板" />
924
+ <el-card v-for="(template, index) in descriptionTemplates" :key="index" class="template-item">
925
+ <!-- 两端对齐 -->
926
+ <el-row justify="space-between" align="middle" style="width: 100%">
927
+ <div class="template-content">{{ template }}</div>
928
+ <div class="template-actions">
929
+ <el-button type="primary" size="small" @click="useTemplate(template)">使用</el-button>
930
+ <el-button type="warning" size="small" :icon="Edit"
931
+ @click="startEditDescriptionTemplate(template, index)">编辑</el-button>
932
+ <el-button type="danger" size="small" @click="deleteDescriptionTemplate(template)">删除</el-button>
933
+ </div>
934
+ </el-row>
935
+ </el-card>
860
936
  </div>
861
937
  </div>
862
-
863
- <div class="template-list">
864
- <h3>已保存模板</h3>
865
- <el-empty v-if="descriptionTemplates.length === 0" description="暂无保存的模板" />
866
- <el-card v-for="(template, index) in descriptionTemplates" :key="index" class="template-item">
867
- <!-- 两端对齐 -->
868
- <el-row justify="space-between" align="middle" style="width: 100%">
869
- <div class="template-content">{{ template }}</div>
870
- <div class="template-actions">
871
- <el-button type="primary" size="small" @click="useTemplate(template)">使用</el-button>
872
- <el-button type="warning" size="small" :icon="Edit"
873
- @click="startEditDescriptionTemplate(template, index)">编辑</el-button>
874
- <el-button type="danger" size="small" @click="deleteDescriptionTemplate(template)">删除</el-button>
875
- </div>
876
- </el-row>
877
- </el-card>
878
- </div>
879
- </div>
880
- </el-dialog>
881
-
882
- <!-- 作用域设置弹窗 -->
883
- <el-dialog title="作用域模板设置" v-model="scopeDialogVisible" width="80%" style="height: 80vh">
884
- <div class="template-container">
885
- <div class="template-form">
886
- <el-input v-model="newScopeTemplate" :placeholder="isEditingScope ? '编辑作用域模板内容' : '输入新作用域模板'"
887
- class="template-input" clearable />
888
- <div class="template-form-buttons">
889
- <el-button v-if="isEditingScope" @click="cancelEditScopeTemplate">取消</el-button>
890
- <el-button type="primary" @click="saveScopeTemplate" :disabled="!newScopeTemplate.trim()">{{ isEditingScope
891
- ? '更新模板' : '添加模板' }}</el-button>
938
+ </el-dialog>
939
+
940
+ <!-- 作用域设置弹窗 -->
941
+ <el-dialog title="作用域模板设置" v-model="scopeDialogVisible" width="80%" style="height: 80vh">
942
+ <div class="template-container">
943
+ <div class="template-form">
944
+ <el-input v-model="newScopeTemplate" :placeholder="isEditingScope ? '编辑作用域模板内容' : '输入新作用域模板'"
945
+ class="template-input" clearable />
946
+ <div class="template-form-buttons">
947
+ <el-button v-if="isEditingScope" @click="cancelEditScopeTemplate">取消</el-button>
948
+ <el-button type="primary" @click="saveScopeTemplate" :disabled="!newScopeTemplate.trim()">{{ isEditingScope
949
+ ? '更新模板' : '添加模板' }}</el-button>
950
+ </div>
892
951
  </div>
893
- </div>
894
952
 
895
- <div class="template-list">
896
- <h3>已保存作用域</h3>
897
- <el-empty v-if="scopeTemplates.length === 0" description="暂无保存的作用域" />
898
- <el-card v-for="(template, index) in scopeTemplates" :key="index" class="template-item">
899
- <el-row justify="space-between" align="middle" style="width: 100%">
900
- <div class="template-content">{{ template }}</div>
901
- <div class="template-actions">
902
- <el-button type="primary" size="small" @click="useScopeTemplate(template)">使用</el-button>
903
- <el-button type="warning" size="small" :icon="Edit"
904
- @click="startEditScopeTemplate(template, index)">编辑</el-button>
905
- <el-button type="danger" size="small" @click="deleteScopeTemplate(template)">删除</el-button>
906
- </div>
907
- </el-row>
908
- </el-card>
953
+ <div class="template-list">
954
+ <h3>已保存作用域</h3>
955
+ <el-empty v-if="scopeTemplates.length === 0" description="暂无保存的作用域" />
956
+ <el-card v-for="(template, index) in scopeTemplates" :key="index" class="template-item">
957
+ <el-row justify="space-between" align="middle" style="width: 100%">
958
+ <div class="template-content">{{ template }}</div>
959
+ <div class="template-actions">
960
+ <el-button type="primary" size="small" @click="useScopeTemplate(template)">使用</el-button>
961
+ <el-button type="warning" size="small" :icon="Edit"
962
+ @click="startEditScopeTemplate(template, index)">编辑</el-button>
963
+ <el-button type="danger" size="small" @click="deleteScopeTemplate(template)">删除</el-button>
964
+ </div>
965
+ </el-row>
966
+ </el-card>
967
+ </div>
909
968
  </div>
910
- </div>
911
- </el-dialog>
969
+ </el-dialog>
970
+ </div>
912
971
  </div>
913
972
  </template>
914
973
 
915
974
  <style scoped>
975
+ /* 添加动画相关的CSS */
976
+ @keyframes snakeBorder {
977
+ 0%, 100% {
978
+ border-top: 2px solid #409EFF;
979
+ border-right: 2px solid transparent;
980
+ border-bottom: 2px solid transparent;
981
+ border-left: 2px solid transparent;
982
+ }
983
+ 25% {
984
+ border-top: 2px solid #409EFF;
985
+ border-right: 2px solid #67C23A;
986
+ border-bottom: 2px solid transparent;
987
+ border-left: 2px solid transparent;
988
+ }
989
+ 50% {
990
+ border-top: 2px solid transparent;
991
+ border-right: 2px solid #67C23A;
992
+ border-bottom: 2px solid #409EFF;
993
+ border-left: 2px solid transparent;
994
+ }
995
+ 75% {
996
+ border-top: 2px solid transparent;
997
+ border-right: 2px solid transparent;
998
+ border-bottom: 2px solid #409EFF;
999
+ border-left: 2px solid #67C23A;
1000
+ }
1001
+ }
1002
+
1003
+ @keyframes glowPulse {
1004
+ 0%, 100% { box-shadow: 0 0 8px rgba(64, 158, 255, 0.4); }
1005
+ 50% { box-shadow: 0 0 12px rgba(103, 194, 58, 0.5); }
1006
+ }
1007
+
916
1008
  .card {
917
1009
  background-color: white;
918
- border-radius: 5px;
919
- box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
920
- margin-bottom: 20px;
921
- padding: 20px;
1010
+ border-radius: 8px;
1011
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.03);
1012
+ border: 1px solid rgba(0, 0, 0, 0.03);
1013
+ height: 100%;
1014
+ width: 100%;
1015
+ display: flex;
1016
+ flex-direction: column;
1017
+ overflow: hidden;
1018
+ position: relative;
1019
+ }
1020
+
1021
+ .card-header {
1022
+ padding: 8px 16px;
1023
+ border-bottom: 1px solid #f0f0f0;
1024
+ display: flex;
1025
+ justify-content: space-between;
1026
+ align-items: center;
1027
+ height: 36px;
1028
+ }
1029
+
1030
+ .card-header h2 {
1031
+ margin: 0;
1032
+ font-size: 16px;
1033
+ font-weight: 500;
1034
+ color: #303133;
1035
+ }
1036
+
1037
+ .card-content {
1038
+ padding: 15px;
1039
+ overflow-y: auto;
1040
+ flex: 1;
922
1041
  }
923
1042
 
924
1043
  .layout-container {
925
1044
  display: flex;
926
- gap: 20px;
1045
+ flex-direction: column;
1046
+ gap: 15px;
1047
+ height: 100%;
927
1048
  }
928
1049
 
929
1050
  .commit-section {
@@ -932,45 +1053,41 @@ git config --global user.email "your.email@example.com"</pre>
932
1053
  }
933
1054
 
934
1055
  .actions-section {
935
- width: 300px;
1056
+ width: 100%;
936
1057
  flex-shrink: 0;
937
1058
  }
938
1059
 
939
1060
  .actions-section h3 {
940
1061
  margin-top: 0;
941
- margin-bottom: 15px;
942
- padding-bottom: 10px;
1062
+ margin-bottom: 10px;
1063
+ padding-bottom: 8px;
943
1064
  border-bottom: 1px solid #dcdfe6;
944
- font-size: 18px;
1065
+ font-size: 16px;
945
1066
  color: #303133;
946
1067
  font-weight: 500;
947
1068
  }
948
1069
 
949
- .commit-form {
1070
+ .operations-wrapper {
950
1071
  display: flex;
951
- margin-bottom: 15px;
952
1072
  gap: 10px;
953
1073
  }
954
1074
 
955
- .git-actions {
956
- margin-top: 20px;
957
- }
958
-
959
1075
  .action-groups {
960
1076
  display: flex;
961
1077
  flex-direction: column;
962
- gap: 15px;
1078
+ gap: 12px;
963
1079
  }
964
1080
 
965
1081
  .action-group {
966
1082
  background-color: #f9f9f9;
967
- border-radius: 8px;
968
- padding: 12px 15px;
1083
+ border-radius: 6px;
1084
+ padding: 8px 10px;
969
1085
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
970
- border-left: 4px solid #409EFF;
971
- overflow: hidden; /* 确保子元素不会溢出 */
1086
+ border-left: 3px solid #409EFF;
1087
+ flex: 1;
972
1088
  }
973
1089
 
1090
+
974
1091
  .action-group:nth-child(2) {
975
1092
  border-left-color: #E6A23C;
976
1093
  }
@@ -980,73 +1097,51 @@ git config --global user.email "your.email@example.com"</pre>
980
1097
  }
981
1098
 
982
1099
  .group-title {
983
- font-size: 14px;
1100
+ font-size: 13px;
984
1101
  font-weight: bold;
985
- margin-bottom: 10px;
1102
+ margin-bottom: 8px;
986
1103
  color: #606266;
987
1104
  text-align: left;
988
1105
  display: block;
989
1106
  position: relative;
990
- padding-left: 10px;
1107
+ padding-left: 6px;
991
1108
  border-bottom: 1px solid rgba(0, 0, 0, 0.06);
992
- padding-bottom: 8px;
1109
+ padding-bottom: 6px;
993
1110
  }
994
1111
 
995
1112
  .group-buttons {
996
1113
  display: flex;
997
- flex-direction: column;
1114
+ flex-direction: row;
1115
+ flex-wrap: wrap;
998
1116
  gap: 8px;
999
- padding: 0 2px;
1117
+ padding: 0;
1000
1118
  }
1001
1119
 
1002
1120
  .action-button {
1003
- position: relative;
1004
- padding: 14px 0 24px 0;
1005
- width: 100%;
1006
- display: flex;
1007
- flex-direction: column;
1008
- align-items: center;
1009
- justify-content: center;
1010
- height: auto;
1011
- text-align: center;
1012
- font-size: 16px;
1013
- border-radius: 6px;
1014
- border: none;
1121
+ font-size: 14px;
1122
+ font-weight: 500;
1123
+ flex: 1;
1124
+ min-width: 100px;
1125
+ border-radius: 4px;
1126
+ height: 36px;
1127
+ padding: 0 10px;
1015
1128
  }
1016
1129
 
1017
1130
  .action-button:hover {
1018
- transform: translateY(-2px);
1019
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
1131
+ transform: translateY(-1px);
1132
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15);
1020
1133
  }
1021
1134
 
1022
1135
  .action-button:active {
1023
1136
  transform: translateY(0);
1024
1137
  }
1025
1138
 
1026
- .action-button :deep(.el-button__content) {
1027
- display: flex;
1028
- flex-direction: column;
1029
- align-items: center;
1030
- justify-content: center;
1031
- width: 100%;
1032
- }
1033
-
1034
- .action-button :deep(.el-icon) {
1035
- margin-right: 0;
1036
- margin-bottom: 4px;
1037
- font-size: 18px;
1038
- }
1039
-
1040
1139
  .command-text {
1041
- position: absolute;
1042
- bottom: 6px;
1043
- font-size: 14px;
1044
- font-family: monospace;
1045
- width: 100%;
1046
- text-align: center;
1047
- left: 0;
1048
- white-space: nowrap;
1140
+ display: none;
1141
+ }
1049
1142
 
1143
+ .command-text-long {
1144
+ display: none;
1050
1145
  }
1051
1146
 
1052
1147
  .standard-commit-form {
@@ -1178,23 +1273,21 @@ git config --global user.email "your.email@example.com"</pre>
1178
1273
  font-size: 14px;
1179
1274
  }
1180
1275
 
1181
- @media (max-width: 768px) {
1276
+ @media (min-width: 768px) {
1182
1277
  .layout-container {
1183
- flex-direction: column;
1278
+ flex-direction: row;
1184
1279
  }
1185
1280
 
1186
- .actions-section {
1187
- width: 100%;
1281
+ .commit-section {
1282
+ flex: 3;
1188
1283
  }
1189
-
1190
- .group-buttons {
1191
- flex-direction: row;
1192
- flex-wrap: wrap;
1284
+
1285
+ .actions-section {
1286
+ width: 320px;
1193
1287
  }
1194
1288
 
1195
- .action-button {
1196
- flex: 1;
1197
- min-width: 120px;
1289
+ .operations-wrapper {
1290
+ flex-direction: column;
1198
1291
  }
1199
1292
  }
1200
1293
 
@@ -1213,7 +1306,25 @@ git config --global user.email "your.email@example.com"</pre>
1213
1306
  white-space: pre;
1214
1307
  }
1215
1308
 
1216
- /* 特定按钮样式 */
1309
+ /* 推送时的动画效果 */
1310
+ @keyframes pushing-pulse {
1311
+ 0% { box-shadow: 0 0 0 0 rgba(103, 194, 58, 0.4); }
1312
+ 70% { box-shadow: 0 0 0 15px rgba(103, 194, 58, 0); }
1313
+ 100% { box-shadow: 0 0 0 0 rgba(103, 194, 58, 0); }
1314
+ }
1315
+
1316
+ @keyframes pushing-border {
1317
+ 0% { border-color: #67c23a; }
1318
+ 50% { border-color: #85ce61; }
1319
+ 100% { border-color: #67c23a; }
1320
+ }
1321
+
1322
+ .card.is-pushing {
1323
+ animation: pushing-border 1.5s infinite ease-in-out;
1324
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
1325
+ transition: all 0.3s ease;
1326
+ }
1327
+
1217
1328
  .push-button {
1218
1329
  background-color: #67c23a;
1219
1330
  border-color: #67c23a;
@@ -1224,6 +1335,82 @@ git config --global user.email "your.email@example.com"</pre>
1224
1335
  border-color: #85ce61;
1225
1336
  }
1226
1337
 
1338
+ .push-button.is-loading,
1339
+ .push-button.is-loading:hover,
1340
+ .push-button.is-loading:focus {
1341
+ animation: pushing-pulse 1.5s infinite;
1342
+ background-color: #67c23a !important;
1343
+ border-color: #67c23a !important;
1344
+ }
1345
+
1346
+ .el-button.push-button.is-loading .el-loading-spinner {
1347
+ color: #fff !important;
1348
+ }
1349
+
1350
+ /* 一键推送按钮动画 */
1351
+ @keyframes one-click-push-glow {
1352
+ 0% { box-shadow: 0 0 5px rgba(103, 194, 58, 0.5); }
1353
+ 50% { box-shadow: 0 0 20px rgba(103, 194, 58, 0.8); }
1354
+ 100% { box-shadow: 0 0 5px rgba(103, 194, 58, 0.5); }
1355
+ }
1356
+
1357
+ .action-button.one-click-push {
1358
+ position: relative;
1359
+ overflow: hidden;
1360
+ }
1361
+
1362
+ .action-button.one-click-push.is-loading,
1363
+ .action-button.one-click-push.is-loading:hover {
1364
+ animation: one-click-push-glow 1.5s infinite;
1365
+ background-color: #67c23a !important;
1366
+ border-color: #67c23a !important;
1367
+ }
1368
+
1369
+ /* 推送成功动画 */
1370
+ @keyframes push-success {
1371
+ 0% { transform: scale(1); }
1372
+ 50% { transform: scale(1.1); }
1373
+ 100% { transform: scale(1); }
1374
+ }
1375
+
1376
+ .push-success-indicator {
1377
+ position: absolute;
1378
+ inset: 0; /* 同时设置top, right, bottom, left为0 */
1379
+ margin: auto;
1380
+ background-color: rgba(255, 255, 255, 0.95);
1381
+ border-radius: 12px;
1382
+ padding: 20px 30px;
1383
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
1384
+ display: flex;
1385
+ flex-direction: column;
1386
+ align-items: center;
1387
+ justify-content: center;
1388
+ animation: push-success 0.5s ease-out;
1389
+ z-index: 9999;
1390
+ width: 200px;
1391
+ height: 200px;
1392
+ }
1393
+
1394
+ .push-success-icon {
1395
+ font-size: 64px;
1396
+ color: #67c23a;
1397
+ margin-bottom: 16px;
1398
+ animation: bounce 0.8s ease-in-out;
1399
+ }
1400
+
1401
+ @keyframes bounce {
1402
+ 0%, 20%, 50%, 80%, 100% {transform: translateY(0);}
1403
+ 40% {transform: translateY(-20px);}
1404
+ 60% {transform: translateY(-10px);}
1405
+ }
1406
+
1407
+ .push-success-text {
1408
+ font-size: 20px;
1409
+ font-weight: bold;
1410
+ color: #303133;
1411
+ text-align: center;
1412
+ }
1413
+
1227
1414
  .reset-button {
1228
1415
  background-color: #909399;
1229
1416
  border-color: #909399;
@@ -1236,4 +1423,85 @@ git config --global user.email "your.email@example.com"</pre>
1236
1423
  .el-button+.el-button {
1237
1424
  margin-left: 0;
1238
1425
  }
1426
+
1427
+ /* 推送中动画样式 */
1428
+ .pushing-indicator {
1429
+ position: absolute;
1430
+ inset: 0;
1431
+ margin: auto;
1432
+ background-color: rgba(64, 158, 255, 0.95);
1433
+ border-radius: 12px;
1434
+ padding: 20px 30px;
1435
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
1436
+ display: flex;
1437
+ flex-direction: column;
1438
+ align-items: center;
1439
+ justify-content: center;
1440
+ z-index: 9999;
1441
+ width: 200px;
1442
+ height: 200px;
1443
+ color: white;
1444
+ }
1445
+
1446
+ .pushing-spinner {
1447
+ margin-bottom: 16px;
1448
+ }
1449
+
1450
+ .pushing-text {
1451
+ font-size: 20px;
1452
+ font-weight: bold;
1453
+ text-align: center;
1454
+ }
1455
+
1456
+ .circular {
1457
+ height: 64px;
1458
+ width: 64px;
1459
+ animation: pushing-rotate 2s linear infinite;
1460
+ }
1461
+
1462
+ .path {
1463
+ stroke: white;
1464
+ stroke-width: 4;
1465
+ stroke-linecap: round;
1466
+ stroke-dasharray: 90, 150;
1467
+ stroke-dashoffset: 0;
1468
+ animation: pushing-dash 1.5s ease-in-out infinite;
1469
+ }
1470
+
1471
+ @keyframes pushing-rotate {
1472
+ 100% {
1473
+ transform: rotate(360deg);
1474
+ }
1475
+ }
1476
+
1477
+ @keyframes pushing-dash {
1478
+ 0% {
1479
+ stroke-dasharray: 1, 150;
1480
+ stroke-dashoffset: 0;
1481
+ }
1482
+ 50% {
1483
+ stroke-dasharray: 90, 150;
1484
+ stroke-dashoffset: -35;
1485
+ }
1486
+ 100% {
1487
+ stroke-dasharray: 90, 150;
1488
+ stroke-dashoffset: -124;
1489
+ }
1490
+ }
1491
+ </style>
1492
+
1493
+ <!-- 添加全局样式 -->
1494
+ <style>
1495
+ /* Git命令tooltip样式 */
1496
+ .git-cmd-tooltip {
1497
+ font-family: 'Consolas', 'Courier New', monospace !important;
1498
+ font-size: 13px !important;
1499
+ font-weight: 500 !important;
1500
+ color: #303133 !important;
1501
+ background-color: #f5f7fa !important;
1502
+ border: 1px solid #dcdfe6 !important;
1503
+ border-radius: 4px !important;
1504
+ padding: 8px 12px !important;
1505
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1) !important;
1506
+ }
1239
1507
  </style>