feat: 支持删除项目并增强项目列表健壮性

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
liumangmang
2026-02-09 17:36:19 +08:00
parent ef412da82c
commit 08ecd023c7
2 changed files with 43 additions and 11 deletions

View File

@@ -63,13 +63,22 @@ function statusLabel(status) {
<div class="project-name">{{ p.name }}</div>
<div class="project-path">{{ p.path }}</div>
</div>
<button
class="btn-edit"
title="修改项目"
@click="openEdit(p, $event)"
>
<i class="fas fa-pen"></i>
</button>
<div class="project-actions">
<button
class="btn-icon"
title="修改项目"
@click="openEdit(p, $event)"
>
<i class="fas fa-pen"></i>
</button>
<button
class="btn-icon btn-danger"
title="删除项目"
@click.stop="store.deleteProject(p.id)"
>
<i class="fas fa-trash"></i>
</button>
</div>
</div>
<div class="project-status-row">
<span class="status-badge" :class="statusClass(p.status)">{{ statusLabel(p.status) }}</span>
@@ -156,8 +165,12 @@ function statusLabel(status) {
border-left-color: var(--accent-blue);
}
.project-info { display: flex; align-items: center; gap: 0.5rem; }
.btn-edit {
.project-actions {
display: flex;
gap: 0.25rem;
flex-shrink: 0;
}
.btn-icon {
width: 1.5rem;
height: 1.5rem;
padding: 0;
@@ -172,7 +185,9 @@ function statusLabel(status) {
font-size: 0.75rem;
opacity: 0.7;
}
.btn-edit:hover { color: var(--accent-blue); background: var(--bg-secondary); opacity: 1; }
.btn-icon:hover { color: var(--accent-blue); background: var(--bg-secondary); opacity: 1; }
.btn-danger { color: #f97373; }
.btn-danger:hover { color: #f97373; background: rgba(248, 113, 113, 0.12); }
.folder-icon { color: var(--accent-blue); font-size: 0.875rem; }
.project-meta { flex: 1; min-width: 0; }
.project-name { font-size: 0.875rem; font-weight: 500; color: var(--text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

View File

@@ -34,7 +34,10 @@ export const useProjectsStore = defineStore('projects', () => {
const selectedFilePath = ref(null)
const fileContent = ref(null)
const current = computed(() => list.value.find(p => p.id === currentId.value) || null)
const current = computed(() => {
if (!Array.isArray(list.value)) return null
return list.value.find(p => p.id === currentId.value) || null
})
const rawFileTree = computed(() => statusData.value?.fileTree || null)
const currentFileTree = computed(() => {
const tree = rawFileTree.value
@@ -48,7 +51,7 @@ export const useProjectsStore = defineStore('projects', () => {
error.value = null
try {
const res = await projectsApi.list()
list.value = res.data || []
list.value = Array.isArray(res.data) ? res.data : []
if (list.value.length && !currentId.value) {
currentId.value = list.value[0].id
await refreshStatus()
@@ -72,6 +75,19 @@ export const useProjectsStore = defineStore('projects', () => {
return res.data
}
async function deleteProject(id) {
if (!id) return
await projectsApi.delete(id)
// 重新加载列表并重置当前项目
await loadProjects()
if (!list.value.length) {
currentId.value = null
statusData.value = null
selectedFilePath.value = null
fileContent.value = null
}
}
async function refreshStatus() {
if (!currentId.value) return
loading.value = true
@@ -169,6 +185,7 @@ export const useProjectsStore = defineStore('projects', () => {
loadProjects,
addProject,
updateProject,
deleteProject,
refreshStatus,
updateSvn,
commit,