@@ -63,13 +63,22 @@ function statusLabel(status) {
|
||||
<div class="project-name">{{ p.name }}</div>
|
||||
<div class="project-path">{{ p.path }}</div>
|
||||
</div>
|
||||
<div class="project-actions">
|
||||
<button
|
||||
class="btn-edit"
|
||||
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; }
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user