功能补齐、查看git提交历史

This commit is contained in:
2026-06-12 09:21:37 +08:00
parent fba3a14367
commit 2a9661a6ef
12 changed files with 329 additions and 9 deletions
+8
View File
@@ -94,3 +94,11 @@ export interface CommitBody {
export interface CommitResp {
sha: string
}
export interface CommitLog {
hash: string
author: string
email: string
date: string
subject: string
}
+5
View File
@@ -10,6 +10,7 @@ import type {
CreateWorktreeBody,
CommitBody,
CommitResp,
CommitLog,
} from './types'
const enc = (v: string) => encodeURIComponent(v)
@@ -63,10 +64,14 @@ export const workspacesApi = {
request<CommitResp>(`/api/v1/workspaces/${enc(wsID)}/main/commit`, { method: 'POST', body }),
pushOnMain: (wsID: string) =>
request<void>(`/api/v1/workspaces/${enc(wsID)}/main/push`, { method: 'POST' }),
logOnMain: (wsID: string, n = 50) =>
request<CommitLog[]>(`/api/v1/workspaces/${enc(wsID)}/main/log?n=${n}`),
statusOnWorktree: (wtID: string) =>
request<FileStatus[]>(`/api/v1/worktrees/${enc(wtID)}/status`),
commitOnWorktree: (wtID: string, body: CommitBody) =>
request<CommitResp>(`/api/v1/worktrees/${enc(wtID)}/commit`, { method: 'POST', body }),
pushOnWorktree: (wtID: string) =>
request<void>(`/api/v1/worktrees/${enc(wtID)}/push`, { method: 'POST' }),
logOnWorktree: (wtID: string, n = 50) =>
request<CommitLog[]>(`/api/v1/worktrees/${enc(wtID)}/log?n=${n}`),
}
+11 -1
View File
@@ -34,6 +34,15 @@
:ws="store.current"
/>
</NTabPane>
<NTabPane
name="commits"
tab="Commits"
>
<CommitHistoryTab
v-if="store.current"
:ws="store.current"
/>
</NTabPane>
<NTabPane
name="runs"
tab="Run"
@@ -66,13 +75,14 @@ import { useWorkspacesStore } from '@/stores/workspaces'
import SyncBar from './components/SyncBar.vue'
import WorktreesTab from './components/WorktreesTab.vue'
import MainTab from './components/MainTab.vue'
import CommitHistoryTab from './components/CommitHistoryTab.vue'
import SettingsTab from './components/SettingsTab.vue'
import RunsTab from './components/RunsTab.vue'
const route = useRoute()
const store = useWorkspacesStore()
const msg = useMessage()
const tab = ref<'worktrees' | 'main' | 'settings' | 'runs'>('worktrees')
const tab = ref<'worktrees' | 'main' | 'commits' | 'settings' | 'runs'>('worktrees')
const projectSlug = computed(() => route.params.slug as string)
const wsSlug = computed(() => route.params.wsSlug as string)
@@ -0,0 +1,127 @@
<template>
<div class="space-y-4">
<!-- 目标选择main 或某个 worktree -->
<div class="flex items-center gap-3">
<span class="text-sm text-gray-500">查看目标</span>
<NSelect
v-model:value="target"
:options="targetOptions"
size="small"
class="w-64"
/>
<NButton
size="small"
:loading="loading"
@click="refresh"
>
刷新
</NButton>
</div>
<NDataTable
:columns="columns"
:data="commits"
:loading="loading"
size="small"
:scroll-x="800"
/>
</div>
</template>
<script setup lang="ts">
import { computed, h, onMounted, ref, watch } from 'vue'
import { NButton, NDataTable, NSelect, NTag, NTooltip } from 'naive-ui'
import type { DataTableColumns } from 'naive-ui'
import { workspacesApi } from '@/api/workspaces'
import { useWorkspacesStore } from '@/stores/workspaces'
import type { CommitLog, Workspace } from '@/api/types'
const props = defineProps<{ ws: Workspace }>()
const store = useWorkspacesStore()
const target = ref<string>('main')
const commits = ref<CommitLog[]>([])
const loading = ref(false)
const targetOptions = computed(() => {
const opts = [{ label: `Main (${props.ws.default_branch})`, value: 'main' }]
for (const wt of store.worktrees) {
opts.push({ label: wt.branch, value: wt.id })
}
return opts
})
function formatDate(d: string) {
return new Date(d).toLocaleString('zh-CN', { hour12: false })
}
function shortHash(hash: string) {
return hash.slice(0, 8)
}
const columns = computed<DataTableColumns<CommitLog>>(() => [
{
title: 'Commit',
key: 'hash',
width: 100,
fixed: 'left',
render(row: CommitLog) {
return h(
NTag,
{ size: 'tiny', type: 'default' },
{ default: () => shortHash(row.hash) },
)
},
},
{
title: '提交信息',
key: 'subject',
ellipsis: { tooltip: true },
},
{
title: '作者',
key: 'author',
width: 140,
render(row: CommitLog) {
return h(
NTooltip,
{},
{
trigger: () => h('span', row.author),
default: () => row.email,
},
)
},
},
{
title: '时间',
key: 'date',
width: 160,
render(row: CommitLog) {
return h('span', { class: 'text-xs text-gray-500' }, formatDate(row.date))
},
},
])
async function refresh() {
loading.value = true
try {
if (target.value === 'main') {
commits.value = await workspacesApi.logOnMain(props.ws.id)
} else {
commits.value = await workspacesApi.logOnWorktree(target.value)
}
} catch (e: unknown) {
commits.value = []
} finally {
loading.value = false
}
}
watch(target, refresh)
onMounted(() => {
refresh()
})
</script>