优化: 前端扫描文案 i18n + parseStack 抽公共 + alert/confirm 换组件
- 扫描/目录状态文案走 $t(Projects/ProjectDetail,zh-CN+en 同步) - parseStack 抽公共到 src/utils/project.ts(删两份本地实现) - 8 处原生 alert/confirm 全换(confirm→ConfirmDialog / alert→Arco Message),控制流语义不变 Sprint 20 审查 ⑥⑦⑧。vue-tsc 0 error,验证 safe 0 issue
This commit is contained in:
@@ -90,7 +90,7 @@
|
||||
<div class="info-item" v-if="currentProject.path">
|
||||
<span class="label">{{ $t('projectDetail.dirStatusLabel') }}</span>
|
||||
<span :class="pathExists === false ? 'path-missing' : 'path-ok'">
|
||||
{{ pathExists === null ? '检测中…' : pathExists ? '✓ 目录存在' : '⚠ 目录已移走,建议重定位' }}
|
||||
{{ pathExists === null ? $t('projectDetail.dirChecking') : pathExists ? $t('projectDetail.dirExists') : $t('projectDetail.dirMissing') }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -193,6 +193,9 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 确认弹层(删除/重定位确认,替代原生 window.confirm/alert) -->
|
||||
<ConfirmDialog :visible="confirmState.visible" :msg="confirmState.msg" @result="answerConfirm" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -200,11 +203,14 @@
|
||||
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { Message } from '@arco-design/web-vue'
|
||||
import { open } from '@tauri-apps/plugin-dialog'
|
||||
import { useProjectStore } from '../stores/project'
|
||||
import { projectApi } from '../api'
|
||||
import { formatDate } from '../utils/time'
|
||||
import { parseStack } from '../utils/project'
|
||||
import { projectStatusLabel, projectStageInfo, taskStatusLabel, taskStatusClass } from '../constants/project'
|
||||
import ConfirmDialog from '../components/ConfirmDialog.vue'
|
||||
import type { WorkflowEventPayload } from '../api/types'
|
||||
|
||||
const route = useRoute()
|
||||
@@ -215,6 +221,21 @@ const logListRef = ref<HTMLElement | null>(null)
|
||||
const showApprovalDialog = ref(false)
|
||||
let unlisten: (() => void) | null = null
|
||||
|
||||
// ── 确认弹层(替代原生 window.confirm,后者在 Tauri webview 带 localhost 来源信息无法去除) ──
|
||||
const confirmState = ref({ visible: false, msg: '', resolve: null as null | ((v: boolean) => void) })
|
||||
function confirmDialog(msg: string): Promise<boolean> {
|
||||
return new Promise(resolve => {
|
||||
confirmState.value.msg = msg
|
||||
confirmState.value.visible = true
|
||||
confirmState.value.resolve = resolve
|
||||
})
|
||||
}
|
||||
function answerConfirm(ok: boolean) {
|
||||
confirmState.value.visible = false
|
||||
confirmState.value.resolve?.(ok)
|
||||
confirmState.value.resolve = null
|
||||
}
|
||||
|
||||
// ── 阶段定义(labelKey 对应 i18n projectDetail.stage*) ──
|
||||
const stages = [
|
||||
{ key: 'idea', labelKey: 'stageIdea' },
|
||||
@@ -317,17 +338,6 @@ async function handleSync() {
|
||||
// ── 代码目录绑定 ──
|
||||
const pathExists = ref<boolean | null>(null)
|
||||
|
||||
// 解析技术栈 JSON 数组字符串(防崩)
|
||||
function parseStack(stack: string | null): string[] {
|
||||
if (!stack) return []
|
||||
try {
|
||||
const arr = JSON.parse(stack)
|
||||
return Array.isArray(arr) ? arr : []
|
||||
} catch {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
// 检查绑定目录是否存在(详情页「目录是否还在」)
|
||||
async function checkPath() {
|
||||
const p = currentProject.value
|
||||
@@ -351,16 +361,19 @@ async function relocateDir() {
|
||||
try {
|
||||
const conflict = await projectApi.checkBinding(dir, p.id)
|
||||
if (conflict) {
|
||||
alert(`该目录已被项目「${conflict.name}」绑定`)
|
||||
Message.warning(t('projectDetail.dirConflict', { name: conflict.name }))
|
||||
return
|
||||
}
|
||||
} catch { /* ignore */ }
|
||||
if (!confirm(`将项目目录${currentProject.value?.path ? '重定位' : '绑定'}到:\n${dir}\n\n技术栈将重新探测。确认?`)) return
|
||||
const confirmMsg = p.path
|
||||
? t('projectDetail.relocateConfirmRelocate', { dir })
|
||||
: t('projectDetail.relocateConfirmBind', { dir })
|
||||
if (!await confirmDialog(confirmMsg)) return
|
||||
await store.relocateProjectPath(p.id, dir)
|
||||
await checkPath()
|
||||
} catch (e: any) {
|
||||
console.error('重定位失败:', e)
|
||||
alert('重定位失败: ' + (e?.toString() ?? '未知错误'))
|
||||
Message.error(t('projectDetail.relocateFailed', { msg: e?.toString() ?? '未知错误' }))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,7 +387,7 @@ async function handleApproval(decision: string) {
|
||||
async function handleDelete() {
|
||||
const p = currentProject.value
|
||||
if (!p) return
|
||||
if (!confirm(t('projectDetail.confirmDelete', { name: p.name }))) return
|
||||
if (!await confirmDialog(t('projectDetail.confirmDelete', { name: p.name }))) return
|
||||
await store.deleteProject(p.id)
|
||||
router.push('/projects')
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user