优化: 工程实体化(description/stack/status)+ 概览工程列表

- project_modules 加 description/status 列(V40 迁移,stack V34 已有)+ models/repo/INSERT/UPDATE/SELECT 映射

- FileExplorer 工程 CRUD 弹窗加 description(textarea)/stack(input)/status(select)输入,工程有完整身份

- ProjectDetail 概览工程列表升级:name+status badge+path + description 段(2行省略)+ stack tag

- 老工程兼容(None=active),update 部分更新语义,status 归一(active/archived)
This commit is contained in:
lxy
2026-08-05 22:10:07 +08:00
parent 8e4c7c68cf
commit ec9f0bf1ea
9 changed files with 551 additions and 47 deletions
+40 -4
View File
@@ -138,9 +138,28 @@
<input v-model="moduleFormPath" :placeholder="$t('fileExplorer.modulePathPlaceholder')" />
</div>
<div class="modal-field">
<label>{{ $t('fileExplorer.moduleGitUrl') }} <span class="opt-label">{{ $t('common.optional') }}</span></label>
<label>{{ $t('fileExplorer.moduleGitUrl') }} <span class="opt-label">{{ $t('fileExplorer.optSuffix') }}</span></label>
<input v-model="moduleFormGitUrl" :placeholder="$t('fileExplorer.moduleGitUrlPlaceholder')" />
</div>
<div class="modal-field">
<label>{{ $t('fileExplorer.moduleDescription') }} <span class="opt-label">{{ $t('fileExplorer.optSuffix') }}</span></label>
<textarea
v-model="moduleFormDescription"
:placeholder="$t('fileExplorer.moduleDescriptionPlaceholder')"
rows="2"
></textarea>
</div>
<div class="modal-field">
<label>{{ $t('fileExplorer.moduleStack') }} <span class="opt-label">{{ $t('fileExplorer.optSuffix') }}</span></label>
<input v-model="moduleFormStack" :placeholder="$t('fileExplorer.moduleStackPlaceholder')" />
</div>
<div class="modal-field">
<label>{{ $t('fileExplorer.moduleStatus') }}</label>
<select v-model="moduleFormStatus">
<option value="active">{{ $t('fileExplorer.moduleStatusActive') }}</option>
<option value="archived">{{ $t('fileExplorer.moduleStatusArchived') }}</option>
</select>
</div>
<div class="modal-actions">
<button class="btn btn-ghost" @click="showModuleModal = false">{{ $t('common.cancel') }}</button>
<button class="btn btn-primary" :disabled="savingModule || !moduleFormName.trim() || !moduleFormPath.trim()" @click="onSaveModule">
@@ -206,6 +225,10 @@ const savingModule = ref(false)
const moduleFormName = ref('')
const moduleFormPath = ref('')
const moduleFormGitUrl = ref('')
// V40 工程实体化:职责描述 / 技术栈(逗号分隔) / 状态(active/archived)
const moduleFormDescription = ref('')
const moduleFormStack = ref('')
const moduleFormStatus = ref<'active' | 'archived'>('active')
// 删除确认
const showRemoveConfirm = ref(false)
@@ -409,6 +432,9 @@ function openAddModule() {
moduleFormName.value = ''
moduleFormPath.value = ''
moduleFormGitUrl.value = ''
moduleFormDescription.value = ''
moduleFormStack.value = ''
moduleFormStatus.value = 'active'
showModuleModal.value = true
}
@@ -419,6 +445,10 @@ function openEditModule() {
moduleFormName.value = currentModule.value.name
moduleFormPath.value = currentModule.value.path
moduleFormGitUrl.value = currentModule.value.git_url ?? ''
moduleFormDescription.value = currentModule.value.description ?? ''
moduleFormStack.value = currentModule.value.stack ?? ''
// 老工程 status 为 null 时视作 active
moduleFormStatus.value = (currentModule.value.status === 'archived' ? 'archived' : 'active')
showModuleModal.value = true
}
@@ -439,6 +469,9 @@ async function onSaveModule() {
name: moduleFormName.value.trim(),
path: moduleFormPath.value.trim(),
gitUrl: moduleFormGitUrl.value.trim() || null,
description: moduleFormDescription.value.trim() || null,
stack: moduleFormStack.value.trim() || null,
status: moduleFormStatus.value,
})
} else {
await moduleApi.addProjectModule({
@@ -446,6 +479,9 @@ async function onSaveModule() {
name: moduleFormName.value.trim(),
path: moduleFormPath.value.trim(),
gitUrl: moduleFormGitUrl.value.trim() || null,
description: moduleFormDescription.value.trim() || null,
stack: moduleFormStack.value.trim() || null,
status: moduleFormStatus.value,
})
}
showModuleModal.value = false
@@ -594,7 +630,7 @@ async function onRemoveModule() {
.crumb {
cursor: pointer;
padding: 2px 6px;
border-radius: 3px;
border-radius: 4px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
@@ -682,11 +718,11 @@ async function onRemoveModule() {
min-width: 14px;
height: 14px;
padding: 0 4px;
border-radius: 7px;
border-radius: 6px;
background: var(--df-accent);
color: #fff;
font-size: 9px;
font-weight: 700;
font-weight: 500;
display: flex;
align-items: center;
justify-content: center;