zen-gitsync 2.0.4 → 2.0.5
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.
- package/package.json +1 -1
- package/src/ui/client/components.d.ts +1 -0
- package/src/ui/client/src/App.vue +214 -68
- package/src/ui/client/src/components/CommitForm.vue +399 -365
- package/src/ui/client/src/components/GitStatus.vue +46 -65
- package/src/ui/client/src/components/LogList.vue +42 -0
- package/src/ui/client/src/stores/gitLogStore.ts +126 -126
- package/src/ui/client/src/stores/gitStore.ts +86 -1
- package/src/ui/client/stats.html +1 -1
- package/src/ui/public/assets/index-CALk9kKc.js +9 -0
- package/src/ui/public/assets/index-D3zIiSNw.css +1 -0
- package/src/ui/public/assets/vendor-BfXVsoKv.js +45 -0
- package/src/ui/public/index.html +3 -3
- package/src/ui/server/index.js +88 -4
- package/src/ui/public/assets/index-D5irnfho.css +0 -1
- package/src/ui/public/assets/index-DBck3u67.js +0 -8
- package/src/ui/public/assets/vendor-CdJ34PvS.js +0 -45
|
@@ -1,17 +1,15 @@
|
|
|
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,
|
|
4
|
+
import { Setting, Edit } from "@element-plus/icons-vue";
|
|
5
5
|
import { useGitLogStore } from "../stores/gitLogStore";
|
|
6
6
|
import { useGitStore } from "../stores/gitStore";
|
|
7
7
|
|
|
8
8
|
const gitLogStore = useGitLogStore();
|
|
9
9
|
const gitStore = useGitStore();
|
|
10
|
-
const emit = defineEmits(["commit-success", "push-success", "status-update"]);
|
|
11
10
|
const commitMessage = ref("");
|
|
12
11
|
const isPushing = ref(false);
|
|
13
12
|
// 添加提交并推送的状态变量
|
|
14
|
-
const isCommitAndPushing = ref(false);
|
|
15
13
|
const placeholder = ref("输入提交信息...");
|
|
16
14
|
// 添加默认提交信息变量
|
|
17
15
|
const defaultCommitMessage = ref("");
|
|
@@ -94,12 +92,12 @@ const finalCommitMessage = computed(() => {
|
|
|
94
92
|
const gitCommandPreview = computed(() => {
|
|
95
93
|
// 基本命令
|
|
96
94
|
let command = `git commit -m "${finalCommitMessage.value}"`
|
|
97
|
-
|
|
95
|
+
|
|
98
96
|
// 如果跳过钩子开关打开,添加 --no-verify 参数
|
|
99
97
|
if (skipHooks.value) {
|
|
100
98
|
command += ' --no-verify'
|
|
101
99
|
}
|
|
102
|
-
|
|
100
|
+
|
|
103
101
|
return command
|
|
104
102
|
});
|
|
105
103
|
|
|
@@ -200,10 +198,10 @@ async function updateDescriptionTemplate() {
|
|
|
200
198
|
// 保存原模板和新模板
|
|
201
199
|
const oldTemplate = originalDescriptionTemplate.value;
|
|
202
200
|
const newTemplate = newTemplateName.value;
|
|
203
|
-
|
|
201
|
+
|
|
204
202
|
// 更新本地数组
|
|
205
203
|
descriptionTemplates.value[editingDescriptionIndex.value] = newTemplate;
|
|
206
|
-
|
|
204
|
+
|
|
207
205
|
// 调用API更新服务器
|
|
208
206
|
const response = await fetch("/api/config/update-template", {
|
|
209
207
|
method: "POST",
|
|
@@ -216,14 +214,14 @@ async function updateDescriptionTemplate() {
|
|
|
216
214
|
type: "description",
|
|
217
215
|
}),
|
|
218
216
|
});
|
|
219
|
-
|
|
217
|
+
|
|
220
218
|
const result = await response.json();
|
|
221
219
|
if (result.success) {
|
|
222
220
|
ElMessage({
|
|
223
221
|
message: "模板更新成功!",
|
|
224
222
|
type: "success",
|
|
225
223
|
});
|
|
226
|
-
|
|
224
|
+
|
|
227
225
|
// 重置编辑状态
|
|
228
226
|
isEditingDescription.value = false;
|
|
229
227
|
originalDescriptionTemplate.value = "";
|
|
@@ -331,10 +329,10 @@ async function updateScopeTemplate() {
|
|
|
331
329
|
// 保存原模板和新模板
|
|
332
330
|
const oldTemplate = originalScopeTemplate.value;
|
|
333
331
|
const newTemplate = newScopeTemplate.value;
|
|
334
|
-
|
|
332
|
+
|
|
335
333
|
// 更新本地数组
|
|
336
334
|
scopeTemplates.value[editingScopeIndex.value] = newTemplate;
|
|
337
|
-
|
|
335
|
+
|
|
338
336
|
// 调用API更新服务器
|
|
339
337
|
const response = await fetch("/api/config/update-template", {
|
|
340
338
|
method: "POST",
|
|
@@ -347,14 +345,14 @@ async function updateScopeTemplate() {
|
|
|
347
345
|
type: "scope",
|
|
348
346
|
}),
|
|
349
347
|
});
|
|
350
|
-
|
|
348
|
+
|
|
351
349
|
const result = await response.json();
|
|
352
350
|
if (result.success) {
|
|
353
351
|
ElMessage({
|
|
354
352
|
message: "作用域模板更新成功!",
|
|
355
353
|
type: "success",
|
|
356
354
|
});
|
|
357
|
-
|
|
355
|
+
|
|
358
356
|
// 重置编辑状态
|
|
359
357
|
isEditingScope.value = false;
|
|
360
358
|
originalScopeTemplate.value = "";
|
|
@@ -501,7 +499,7 @@ async function addToStage() {
|
|
|
501
499
|
const result = await gitLogStore.addToStage();
|
|
502
500
|
if (result) {
|
|
503
501
|
// 触发状态更新事件
|
|
504
|
-
|
|
502
|
+
gitLogStore.fetchStatus();
|
|
505
503
|
}
|
|
506
504
|
} catch (error) {
|
|
507
505
|
ElMessage({
|
|
@@ -524,15 +522,14 @@ async function commitChanges() {
|
|
|
524
522
|
try {
|
|
525
523
|
// 使用Store提交更改
|
|
526
524
|
const result = await gitLogStore.commitChanges(finalCommitMessage.value, skipHooks.value);
|
|
527
|
-
|
|
525
|
+
|
|
528
526
|
if (result) {
|
|
529
527
|
// 清空提交信息
|
|
530
528
|
clearCommitFields();
|
|
531
|
-
|
|
529
|
+
|
|
532
530
|
// 触发成功事件
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
emit("status-update");
|
|
531
|
+
gitLogStore.fetchStatus();
|
|
532
|
+
gitLogStore.fetchLog();
|
|
536
533
|
}
|
|
537
534
|
} catch (error) {
|
|
538
535
|
ElMessage({
|
|
@@ -548,12 +545,11 @@ async function pushToRemote() {
|
|
|
548
545
|
isPushing.value = true
|
|
549
546
|
// 使用Store推送更改
|
|
550
547
|
const result = await gitLogStore.pushToRemote();
|
|
551
|
-
|
|
548
|
+
|
|
552
549
|
if (result) {
|
|
553
550
|
// 触发成功事件
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
emit("status-update");
|
|
551
|
+
gitStore.getCurrentBranch();
|
|
552
|
+
gitLogStore.fetchLog();
|
|
557
553
|
}
|
|
558
554
|
} catch (error) {
|
|
559
555
|
ElMessage({
|
|
@@ -569,24 +565,21 @@ async function pushToRemote() {
|
|
|
569
565
|
async function addAndCommit() {
|
|
570
566
|
if (!finalCommitMessage.value.trim()) {
|
|
571
567
|
ElMessage({
|
|
572
|
-
message: "提交信息不能为空",
|
|
568
|
+
message: "提交信息不能为空",
|
|
573
569
|
type: "warning",
|
|
574
570
|
});
|
|
575
571
|
return;
|
|
576
572
|
}
|
|
577
573
|
|
|
578
574
|
try {
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
// 触发状态更新事件
|
|
588
|
-
emit("status-update");
|
|
589
|
-
}
|
|
575
|
+
await gitLogStore.addAndCommit(finalCommitMessage.value, skipHooks.value);
|
|
576
|
+
|
|
577
|
+
// 清空提交信息
|
|
578
|
+
clearCommitFields();
|
|
579
|
+
|
|
580
|
+
// 触发成功事件
|
|
581
|
+
gitLogStore.fetchStatus();
|
|
582
|
+
gitLogStore.fetchLog();
|
|
590
583
|
} catch (error) {
|
|
591
584
|
ElMessage({
|
|
592
585
|
message: `暂存并提交失败: ${(error as Error).message}`,
|
|
@@ -606,60 +599,22 @@ async function addCommitAndPush() {
|
|
|
606
599
|
}
|
|
607
600
|
|
|
608
601
|
try {
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
// 添加小延迟后再触发推送成功事件,确保提交历史能够刷新
|
|
620
|
-
setTimeout(() => {
|
|
621
|
-
emit("push-success");
|
|
622
|
-
}, 300);
|
|
623
|
-
|
|
624
|
-
// 触发状态更新事件
|
|
625
|
-
emit("status-update");
|
|
626
|
-
}
|
|
602
|
+
await gitLogStore.addCommitAndPush(finalCommitMessage.value, skipHooks.value);
|
|
603
|
+
|
|
604
|
+
|
|
605
|
+
// 清空提交信息
|
|
606
|
+
clearCommitFields();
|
|
607
|
+
|
|
608
|
+
// 触发成功事件
|
|
609
|
+
gitStore.getCurrentBranch();
|
|
610
|
+
gitLogStore.fetchLog();
|
|
611
|
+
|
|
627
612
|
} catch (error) {
|
|
628
613
|
ElMessage({
|
|
629
614
|
message: `暂存、提交并推送失败: ${(error as Error).message}`,
|
|
630
615
|
type: "error",
|
|
631
616
|
});
|
|
632
617
|
} finally {
|
|
633
|
-
isCommitAndPushing.value = false
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
// 重置暂存区 (git reset HEAD)
|
|
638
|
-
async function resetHead() {
|
|
639
|
-
try {
|
|
640
|
-
await ElMessageBox.confirm(
|
|
641
|
-
'确定要重置暂存区吗?这将取消所有已暂存的更改,但不会影响工作区的文件。',
|
|
642
|
-
'重置暂存区',
|
|
643
|
-
{
|
|
644
|
-
confirmButtonText: '确定',
|
|
645
|
-
cancelButtonText: '取消',
|
|
646
|
-
type: 'warning'
|
|
647
|
-
}
|
|
648
|
-
);
|
|
649
|
-
|
|
650
|
-
const result = await gitLogStore.resetHead();
|
|
651
|
-
if (result) {
|
|
652
|
-
// 触发状态更新事件
|
|
653
|
-
emit("status-update");
|
|
654
|
-
}
|
|
655
|
-
} catch (error) {
|
|
656
|
-
// 用户取消操作,不显示错误
|
|
657
|
-
if ((error as any) !== 'cancel') {
|
|
658
|
-
ElMessage({
|
|
659
|
-
message: `重置暂存区失败: ${(error as Error).message}`,
|
|
660
|
-
type: 'error'
|
|
661
|
-
});
|
|
662
|
-
}
|
|
663
618
|
}
|
|
664
619
|
}
|
|
665
620
|
|
|
@@ -675,11 +630,13 @@ async function resetToRemote() {
|
|
|
675
630
|
type: 'warning'
|
|
676
631
|
}
|
|
677
632
|
);
|
|
678
|
-
|
|
633
|
+
|
|
679
634
|
const result = await gitLogStore.resetToRemote(gitStore.currentBranch);
|
|
680
635
|
if (result) {
|
|
681
636
|
// 触发状态更新事件
|
|
682
|
-
|
|
637
|
+
gitLogStore.fetchStatus();
|
|
638
|
+
// 更新提交历史
|
|
639
|
+
gitLogStore.fetchLog();
|
|
683
640
|
}
|
|
684
641
|
} catch (error) {
|
|
685
642
|
// 用户取消操作,不显示错误
|
|
@@ -702,13 +659,13 @@ function clearCommitFields() {
|
|
|
702
659
|
|
|
703
660
|
onMounted(() => {
|
|
704
661
|
loadConfig();
|
|
705
|
-
|
|
662
|
+
|
|
706
663
|
// 从 localStorage 中获取标准化提交设置
|
|
707
664
|
const savedStandardCommit = localStorage.getItem("zen-gitsync-standard-commit");
|
|
708
665
|
if (savedStandardCommit !== null) {
|
|
709
666
|
isStandardCommit.value = savedStandardCommit === "true";
|
|
710
667
|
}
|
|
711
|
-
|
|
668
|
+
|
|
712
669
|
// 从 localStorage 中获取跳过钩子设置
|
|
713
670
|
const savedSkipHooks = localStorage.getItem("zen-gitsync-skip-hooks");
|
|
714
671
|
if (savedSkipHooks !== null) {
|
|
@@ -721,239 +678,200 @@ onMounted(() => {
|
|
|
721
678
|
<div class="card">
|
|
722
679
|
<h2>提交更改</h2>
|
|
723
680
|
|
|
724
|
-
<div class="
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
</el-tooltip>
|
|
738
|
-
</div>
|
|
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>
|
|
739
694
|
</div>
|
|
740
|
-
|
|
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>
|
|
741
705
|
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
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>
|
|
710
|
+
</div>
|
|
711
|
+
</div>
|
|
712
|
+
</div>
|
|
746
713
|
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
v-model="commitType"
|
|
752
|
-
placeholder="提交类型"
|
|
753
|
-
class="type-select"
|
|
754
|
-
clearable
|
|
755
|
-
>
|
|
756
|
-
<el-option
|
|
757
|
-
v-for="item in commitTypeOptions"
|
|
758
|
-
:key="item.value"
|
|
759
|
-
:label="item.label"
|
|
760
|
-
:value="item.value"
|
|
761
|
-
/>
|
|
762
|
-
</el-select>
|
|
763
|
-
|
|
764
|
-
<div class="scope-container">
|
|
765
|
-
<el-input
|
|
766
|
-
v-model="commitScope"
|
|
767
|
-
placeholder="作用域(可选)"
|
|
768
|
-
class="scope-input"
|
|
769
|
-
clearable
|
|
770
|
-
/>
|
|
771
|
-
<el-button
|
|
772
|
-
type="primary"
|
|
773
|
-
:icon="Setting"
|
|
774
|
-
circle
|
|
775
|
-
size="small"
|
|
776
|
-
class="settings-button"
|
|
777
|
-
@click="openScopeSettings"
|
|
778
|
-
>
|
|
779
|
-
</el-button>
|
|
780
|
-
</div>
|
|
714
|
+
<!-- 普通提交表单 -->
|
|
715
|
+
<div v-if="!isStandardCommit" class="commit-form">
|
|
716
|
+
<el-input v-model="commitMessage" :placeholder="placeholder" clearable />
|
|
717
|
+
</div>
|
|
781
718
|
|
|
782
|
-
|
|
783
|
-
<
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
@click="openDescriptionSettings"
|
|
796
|
-
>
|
|
797
|
-
</el-button>
|
|
798
|
-
</div>
|
|
799
|
-
</div>
|
|
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>
|
|
800
732
|
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
/>
|
|
809
|
-
|
|
810
|
-
<el-input
|
|
811
|
-
v-model="commitFooter"
|
|
812
|
-
placeholder="页脚(可选):如 Closes #123"
|
|
813
|
-
class="footer-input"
|
|
814
|
-
clearable
|
|
815
|
-
/>
|
|
816
|
-
|
|
817
|
-
<div class="preview-section">
|
|
818
|
-
<div class="preview-title">提交信息预览:</div>
|
|
819
|
-
<pre class="preview-content">{{ finalCommitMessage }}</pre>
|
|
820
|
-
|
|
821
|
-
<div class="preview-title" style="margin-top: 10px;">Git命令预览:</div>
|
|
822
|
-
<pre class="preview-content code-command">{{ gitCommandPreview }}</pre>
|
|
823
|
-
</div>
|
|
824
|
-
</div>
|
|
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>
|
|
738
|
+
</div>
|
|
739
|
+
</div>
|
|
825
740
|
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
741
|
+
<el-input v-model="commitBody" type="textarea" :rows="4" placeholder="正文(可选):详细描述本次提交的内容和原因" class="body-input"
|
|
742
|
+
clearable />
|
|
743
|
+
|
|
744
|
+
<el-input v-model="commitFooter" placeholder="页脚(可选):如 Closes #123" class="footer-input" clearable />
|
|
745
|
+
|
|
746
|
+
<div class="preview-section">
|
|
747
|
+
<div class="preview-title">提交信息预览:</div>
|
|
748
|
+
<pre class="preview-content">{{ finalCommitMessage }}</pre>
|
|
749
|
+
|
|
750
|
+
<div class="preview-title" style="margin-top: 10px;">Git命令预览:</div>
|
|
751
|
+
<pre class="preview-content code-command">{{ gitCommandPreview }}</pre>
|
|
752
|
+
</div>
|
|
753
|
+
</div>
|
|
754
|
+
</div>
|
|
755
|
+
|
|
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>
|
|
792
|
+
</div>
|
|
793
|
+
</div>
|
|
794
|
+
|
|
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>
|
|
817
|
+
</div>
|
|
818
|
+
</div>
|
|
819
|
+
|
|
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>
|
|
844
|
+
</div>
|
|
845
|
+
</div>
|
|
846
|
+
</div>
|
|
847
|
+
</template>
|
|
891
848
|
</div>
|
|
892
849
|
|
|
893
850
|
<!-- 简短描述设置弹窗 -->
|
|
894
|
-
<el-dialog
|
|
895
|
-
title="简短描述模板设置"
|
|
896
|
-
v-model="descriptionDialogVisible"
|
|
897
|
-
width="80vw"
|
|
898
|
-
style="height: 80vh"
|
|
899
|
-
>
|
|
851
|
+
<el-dialog title="简短描述模板设置" v-model="descriptionDialogVisible" width="80vw" style="height: 80vh">
|
|
900
852
|
<div class="template-container">
|
|
901
853
|
<div class="template-form">
|
|
902
|
-
<el-input
|
|
903
|
-
|
|
904
|
-
:placeholder="isEditingDescription ? '编辑模板内容' : '输入新模板内容'"
|
|
905
|
-
class="template-input"
|
|
906
|
-
clearable
|
|
907
|
-
/>
|
|
854
|
+
<el-input v-model="newTemplateName" :placeholder="isEditingDescription ? '编辑模板内容' : '输入新模板内容'"
|
|
855
|
+
class="template-input" clearable />
|
|
908
856
|
<div class="template-form-buttons">
|
|
909
|
-
<el-button
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
>取消</el-button
|
|
913
|
-
>
|
|
914
|
-
<el-button
|
|
915
|
-
type="primary"
|
|
916
|
-
@click="saveDescriptionTemplate"
|
|
917
|
-
:disabled="!newTemplateName.trim()"
|
|
918
|
-
>{{ isEditingDescription ? '更新模板' : '添加模板' }}</el-button
|
|
919
|
-
>
|
|
857
|
+
<el-button v-if="isEditingDescription" @click="cancelEditDescriptionTemplate">取消</el-button>
|
|
858
|
+
<el-button type="primary" @click="saveDescriptionTemplate" :disabled="!newTemplateName.trim()">{{
|
|
859
|
+
isEditingDescription ? '更新模板' : '添加模板' }}</el-button>
|
|
920
860
|
</div>
|
|
921
861
|
</div>
|
|
922
862
|
|
|
923
863
|
<div class="template-list">
|
|
924
864
|
<h3>已保存模板</h3>
|
|
925
|
-
<el-empty
|
|
926
|
-
|
|
927
|
-
description="暂无保存的模板"
|
|
928
|
-
/>
|
|
929
|
-
<el-card
|
|
930
|
-
v-for="(template, index) in descriptionTemplates"
|
|
931
|
-
:key="index"
|
|
932
|
-
class="template-item"
|
|
933
|
-
>
|
|
865
|
+
<el-empty v-if="descriptionTemplates.length === 0" description="暂无保存的模板" />
|
|
866
|
+
<el-card v-for="(template, index) in descriptionTemplates" :key="index" class="template-item">
|
|
934
867
|
<!-- 两端对齐 -->
|
|
935
868
|
<el-row justify="space-between" align="middle" style="width: 100%">
|
|
936
869
|
<div class="template-content">{{ template }}</div>
|
|
937
870
|
<div class="template-actions">
|
|
938
|
-
<el-button
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
>使用</el-button
|
|
943
|
-
>
|
|
944
|
-
<el-button
|
|
945
|
-
type="warning"
|
|
946
|
-
size="small"
|
|
947
|
-
:icon="Edit"
|
|
948
|
-
@click="startEditDescriptionTemplate(template, index)"
|
|
949
|
-
>编辑</el-button
|
|
950
|
-
>
|
|
951
|
-
<el-button
|
|
952
|
-
type="danger"
|
|
953
|
-
size="small"
|
|
954
|
-
@click="deleteDescriptionTemplate(template)"
|
|
955
|
-
>删除</el-button
|
|
956
|
-
>
|
|
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>
|
|
957
875
|
</div>
|
|
958
876
|
</el-row>
|
|
959
877
|
</el-card>
|
|
@@ -962,68 +880,29 @@ onMounted(() => {
|
|
|
962
880
|
</el-dialog>
|
|
963
881
|
|
|
964
882
|
<!-- 作用域设置弹窗 -->
|
|
965
|
-
<el-dialog
|
|
966
|
-
title="作用域模板设置"
|
|
967
|
-
v-model="scopeDialogVisible"
|
|
968
|
-
width="80%"
|
|
969
|
-
style="height: 80vh"
|
|
970
|
-
>
|
|
883
|
+
<el-dialog title="作用域模板设置" v-model="scopeDialogVisible" width="80%" style="height: 80vh">
|
|
971
884
|
<div class="template-container">
|
|
972
885
|
<div class="template-form">
|
|
973
|
-
<el-input
|
|
974
|
-
|
|
975
|
-
:placeholder="isEditingScope ? '编辑作用域模板内容' : '输入新作用域模板'"
|
|
976
|
-
class="template-input"
|
|
977
|
-
clearable
|
|
978
|
-
/>
|
|
886
|
+
<el-input v-model="newScopeTemplate" :placeholder="isEditingScope ? '编辑作用域模板内容' : '输入新作用域模板'"
|
|
887
|
+
class="template-input" clearable />
|
|
979
888
|
<div class="template-form-buttons">
|
|
980
|
-
<el-button
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
>取消</el-button
|
|
984
|
-
>
|
|
985
|
-
<el-button
|
|
986
|
-
type="primary"
|
|
987
|
-
@click="saveScopeTemplate"
|
|
988
|
-
:disabled="!newScopeTemplate.trim()"
|
|
989
|
-
>{{ isEditingScope ? '更新模板' : '添加模板' }}</el-button
|
|
990
|
-
>
|
|
889
|
+
<el-button v-if="isEditingScope" @click="cancelEditScopeTemplate">取消</el-button>
|
|
890
|
+
<el-button type="primary" @click="saveScopeTemplate" :disabled="!newScopeTemplate.trim()">{{ isEditingScope
|
|
891
|
+
? '更新模板' : '添加模板' }}</el-button>
|
|
991
892
|
</div>
|
|
992
893
|
</div>
|
|
993
894
|
|
|
994
895
|
<div class="template-list">
|
|
995
896
|
<h3>已保存作用域</h3>
|
|
996
|
-
<el-empty
|
|
997
|
-
|
|
998
|
-
description="暂无保存的作用域"
|
|
999
|
-
/>
|
|
1000
|
-
<el-card
|
|
1001
|
-
v-for="(template, index) in scopeTemplates"
|
|
1002
|
-
:key="index"
|
|
1003
|
-
class="template-item"
|
|
1004
|
-
>
|
|
897
|
+
<el-empty v-if="scopeTemplates.length === 0" description="暂无保存的作用域" />
|
|
898
|
+
<el-card v-for="(template, index) in scopeTemplates" :key="index" class="template-item">
|
|
1005
899
|
<el-row justify="space-between" align="middle" style="width: 100%">
|
|
1006
900
|
<div class="template-content">{{ template }}</div>
|
|
1007
901
|
<div class="template-actions">
|
|
1008
|
-
<el-button
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
>使用</el-button
|
|
1013
|
-
>
|
|
1014
|
-
<el-button
|
|
1015
|
-
type="warning"
|
|
1016
|
-
size="small"
|
|
1017
|
-
:icon="Edit"
|
|
1018
|
-
@click="startEditScopeTemplate(template, index)"
|
|
1019
|
-
>编辑</el-button
|
|
1020
|
-
>
|
|
1021
|
-
<el-button
|
|
1022
|
-
type="danger"
|
|
1023
|
-
size="small"
|
|
1024
|
-
@click="deleteScopeTemplate(template)"
|
|
1025
|
-
>删除</el-button
|
|
1026
|
-
>
|
|
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>
|
|
1027
906
|
</div>
|
|
1028
907
|
</el-row>
|
|
1029
908
|
</el-card>
|
|
@@ -1037,11 +916,36 @@ onMounted(() => {
|
|
|
1037
916
|
.card {
|
|
1038
917
|
background-color: white;
|
|
1039
918
|
border-radius: 5px;
|
|
1040
|
-
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
|
|
919
|
+
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
|
1041
920
|
margin-bottom: 20px;
|
|
1042
921
|
padding: 20px;
|
|
1043
922
|
}
|
|
1044
923
|
|
|
924
|
+
.layout-container {
|
|
925
|
+
display: flex;
|
|
926
|
+
gap: 20px;
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
.commit-section {
|
|
930
|
+
flex: 1;
|
|
931
|
+
min-width: 0; /* 防止子元素撑开 */
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
.actions-section {
|
|
935
|
+
width: 300px;
|
|
936
|
+
flex-shrink: 0;
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
.actions-section h3 {
|
|
940
|
+
margin-top: 0;
|
|
941
|
+
margin-bottom: 15px;
|
|
942
|
+
padding-bottom: 10px;
|
|
943
|
+
border-bottom: 1px solid #dcdfe6;
|
|
944
|
+
font-size: 18px;
|
|
945
|
+
color: #303133;
|
|
946
|
+
font-weight: 500;
|
|
947
|
+
}
|
|
948
|
+
|
|
1045
949
|
.commit-form {
|
|
1046
950
|
display: flex;
|
|
1047
951
|
margin-bottom: 15px;
|
|
@@ -1050,19 +954,99 @@ onMounted(() => {
|
|
|
1050
954
|
|
|
1051
955
|
.git-actions {
|
|
1052
956
|
margin-top: 20px;
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
.action-groups {
|
|
1053
960
|
display: flex;
|
|
1054
961
|
flex-direction: column;
|
|
1055
|
-
gap:
|
|
962
|
+
gap: 15px;
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
.action-group {
|
|
966
|
+
background-color: #f9f9f9;
|
|
967
|
+
border-radius: 8px;
|
|
968
|
+
padding: 12px 15px;
|
|
969
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
|
|
970
|
+
border-left: 4px solid #409EFF;
|
|
971
|
+
overflow: hidden; /* 确保子元素不会溢出 */
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
.action-group:nth-child(2) {
|
|
975
|
+
border-left-color: #E6A23C;
|
|
1056
976
|
}
|
|
1057
977
|
|
|
1058
|
-
.action-
|
|
978
|
+
.action-group:nth-child(3) {
|
|
979
|
+
border-left-color: #909399;
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
.group-title {
|
|
983
|
+
font-size: 14px;
|
|
984
|
+
font-weight: bold;
|
|
985
|
+
margin-bottom: 10px;
|
|
986
|
+
color: #606266;
|
|
987
|
+
text-align: left;
|
|
988
|
+
display: block;
|
|
989
|
+
position: relative;
|
|
990
|
+
padding-left: 10px;
|
|
991
|
+
border-bottom: 1px solid rgba(0, 0, 0, 0.06);
|
|
992
|
+
padding-bottom: 8px;
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
.group-buttons {
|
|
1059
996
|
display: flex;
|
|
1060
|
-
|
|
1061
|
-
|
|
997
|
+
flex-direction: column;
|
|
998
|
+
gap: 8px;
|
|
999
|
+
padding: 0 2px;
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
.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;
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
.action-button:hover {
|
|
1018
|
+
transform: translateY(-2px);
|
|
1019
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
1062
1020
|
}
|
|
1063
1021
|
|
|
1064
|
-
.
|
|
1065
|
-
|
|
1022
|
+
.action-button:active {
|
|
1023
|
+
transform: translateY(0);
|
|
1024
|
+
}
|
|
1025
|
+
|
|
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
|
+
.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;
|
|
1049
|
+
|
|
1066
1050
|
}
|
|
1067
1051
|
|
|
1068
1052
|
.standard-commit-form {
|
|
@@ -1074,21 +1058,20 @@ onMounted(() => {
|
|
|
1074
1058
|
|
|
1075
1059
|
.standard-commit-header {
|
|
1076
1060
|
display: flex;
|
|
1061
|
+
flex-direction: column;
|
|
1077
1062
|
gap: 10px;
|
|
1078
1063
|
width: 100%;
|
|
1079
1064
|
}
|
|
1080
1065
|
|
|
1081
1066
|
.type-select {
|
|
1082
|
-
width:
|
|
1083
|
-
flex-shrink: 0;
|
|
1067
|
+
width: 100%;
|
|
1084
1068
|
}
|
|
1085
1069
|
|
|
1086
1070
|
.scope-container {
|
|
1087
1071
|
display: flex;
|
|
1088
1072
|
align-items: center;
|
|
1089
1073
|
gap: 5px;
|
|
1090
|
-
|
|
1091
|
-
width: 200px;
|
|
1074
|
+
width: 100%;
|
|
1092
1075
|
}
|
|
1093
1076
|
|
|
1094
1077
|
.scope-input {
|
|
@@ -1099,12 +1082,11 @@ onMounted(() => {
|
|
|
1099
1082
|
display: flex;
|
|
1100
1083
|
align-items: center;
|
|
1101
1084
|
gap: 5px;
|
|
1102
|
-
|
|
1085
|
+
width: 100%;
|
|
1103
1086
|
}
|
|
1104
1087
|
|
|
1105
1088
|
.description-input {
|
|
1106
1089
|
flex-grow: 1;
|
|
1107
|
-
min-width: 200px;
|
|
1108
1090
|
}
|
|
1109
1091
|
|
|
1110
1092
|
.settings-button {
|
|
@@ -1197,9 +1179,61 @@ onMounted(() => {
|
|
|
1197
1179
|
}
|
|
1198
1180
|
|
|
1199
1181
|
@media (max-width: 768px) {
|
|
1200
|
-
.
|
|
1182
|
+
.layout-container {
|
|
1201
1183
|
flex-direction: column;
|
|
1202
1184
|
}
|
|
1185
|
+
|
|
1186
|
+
.actions-section {
|
|
1187
|
+
width: 100%;
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
.group-buttons {
|
|
1191
|
+
flex-direction: row;
|
|
1192
|
+
flex-wrap: wrap;
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
.action-button {
|
|
1196
|
+
flex: 1;
|
|
1197
|
+
min-width: 120px;
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
.git-config-warning {
|
|
1202
|
+
width: 100%;
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
.config-command {
|
|
1206
|
+
background-color: #2d2d2d;
|
|
1207
|
+
color: #f8f8f2;
|
|
1208
|
+
font-family: 'Courier New', Courier, monospace;
|
|
1209
|
+
padding: 10px;
|
|
1210
|
+
border-radius:
|
|
1211
|
+
4px;
|
|
1212
|
+
margin-top: 10px;
|
|
1213
|
+
white-space: pre;
|
|
1203
1214
|
}
|
|
1204
|
-
</style>
|
|
1205
1215
|
|
|
1216
|
+
/* 特定按钮样式 */
|
|
1217
|
+
.push-button {
|
|
1218
|
+
background-color: #67c23a;
|
|
1219
|
+
border-color: #67c23a;
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
.push-button:hover {
|
|
1223
|
+
background-color: #85ce61;
|
|
1224
|
+
border-color: #85ce61;
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
.reset-button {
|
|
1228
|
+
background-color: #909399;
|
|
1229
|
+
border-color: #909399;
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
.reset-button:hover {
|
|
1233
|
+
background-color: #a6a9ad;
|
|
1234
|
+
border-color: #a6a9ad;
|
|
1235
|
+
}
|
|
1236
|
+
.el-button+.el-button {
|
|
1237
|
+
margin-left: 0;
|
|
1238
|
+
}
|
|
1239
|
+
</style>
|