fix(frontend): 代码对比改全屏模态——用户反馈860px侧抽屉太小看不清;版本历史和列表快照抽屉(el-drawer)统一改el-dialog fullscreen:版本列表改横向chip条(选中高亮)省纵向空间,diff区flex撑满calc(100vh-60px);Esc/关闭即走;dev实测dialog铺满视口2560x1177,diff左右各1262x1036(原抽屉内仅~400x460,面积扩大约7倍);MonacoDiff延迟挂载保留(模态动画后全宽创建) [nas]
CI/CD / test (push) Successful in 10s
CI/CD / nas-deploy (push) Successful in 27s
CI/CD / nas-verify (push) Successful in 10s

This commit is contained in:
2026-08-16 08:33:23 +08:00
parent 23e1beb177
commit 8ee513a17d
2 changed files with 64 additions and 50 deletions
+46 -32
View File
@@ -170,12 +170,14 @@ async function openVersions(): Promise<void> {
}
}
const activeVersion = ref('')
async function showDiff(h8: string): Promise<void> {
if (!active.value) return
diffReady.value = false
activeVersion.value = h8
try {
diffCode.value = await getCodeVersion(active.value.name, h8)
// 抽屉展开动画(~300ms)期间容器宽为 0,Monaco diff 在其中创建会把左右分栏算死
// 模态展开动画(~300ms)期间容器宽为 0,Monaco diff 在其中创建会把左右分栏算死
// (左栏被压扁且事后 layout() 救不回)。等动画结束容器全宽后再挂载组件。
setTimeout(() => { diffReady.value = true }, 360)
} catch {
@@ -245,31 +247,39 @@ async function showDiff(h8: string): Promise<void> {
</section>
</div>
<!-- §12.6 版本历史发起时快照列表 + 与当前代码 diff -->
<el-drawer :model-value="versionsOpen" size="860px" :with-header="false" append-to-body destroy-on-close @close="versionsOpen = false">
<div v-loading="versionsLoading" class="ver-drawer">
<div class="ver-head">
<div>
<div style="font-size:15px;font-weight:700;color:var(--text)">版本历史 · {{ activeName }}</div>
<div class="muted" style="font-size:11.5px;margin-top:2px">发起回测/模拟/实盘时的代码快照内容寻址去重对比查看与当前代码差异</div>
<!-- §12.6 版本历史全屏模态860px 抽屉太小看不清 difffullscreen 尽量吃满屏幕 -->
<el-dialog
:model-value="versionsOpen" fullscreen append-to-body destroy-on-close
class="ver-modal" :show-close="false" @close="versionsOpen = false"
>
<div v-loading="versionsLoading" class="ver-full">
<div class="ver-head">
<div>
<span style="font-size:15px;font-weight:700;color:var(--text)">版本历史 · {{ activeName }}</span>
<span class="muted" style="font-size:11.5px;margin-left:12px">发起回测/模拟/实盘时的代码快照 · 点版本卡片对比当前</span>
</div>
<button class="term-btn sm" @click="versionsOpen = false">关闭 (Esc)</button>
</div>
<button class="term-btn sm" @click="versionsOpen = false">关闭</button>
<div v-if="!versions.length && !versionsLoading" class="muted" style="padding:40px 0;text-align:center;font-size:13px">
还没有快照从策略档案发起过回测/模拟/实盘后自动生成
</div>
<div v-else class="ver-chips">
<button
v-for="v in versions" :key="v.code_version"
class="ver-chip" :class="{ on: diffCode != null && activeVersion === v.code_version }"
@click="showDiff(v.code_version)"
>
<span class="mono" style="color:var(--brand)">v{{ v.code_version }}</span>
<span class="muted mono" style="font-size:10.5px">{{ v.saved_at }}</span>
<span class="muted mono" style="font-size:10px">{{ (v.size / 1024).toFixed(1) }} KB</span>
</button>
</div>
<div v-if="diffCode != null && diffReady" class="ver-diff-full">
<MonacoDiff :original="diffCode" :modified="code" />
</div>
<div v-else-if="diffCode == null" class="ver-empty muted">选择上方版本开始对比 · =快照 =当前 滚动联动</div>
</div>
<div v-if="!versions.length && !versionsLoading" class="muted" style="padding:20px 0;text-align:center;font-size:12.5px">
还没有快照从策略档案发起过回测/模拟/实盘后自动生成
</div>
<div v-for="v in versions" :key="v.code_version" class="ver-row">
<span class="mono" style="color:var(--brand)">v{{ v.code_version }}</span>
<span class="muted mono" style="font-size:11px">{{ v.saved_at }}</span>
<span class="muted mono" style="font-size:11px">{{ (v.size / 1024).toFixed(1) }} KB</span>
<button class="term-btn sm" style="margin-left:auto" @click="showDiff(v.code_version)">对比当前</button>
</div>
<div v-if="diffCode != null && diffReady" class="ver-diff">
<div class="muted mono" style="font-size:11px;margin-bottom:6px">左右滚动联动 · 快照 vs 当前</div>
<MonacoDiff :original="diffCode" :modified="code" />
</div>
</div>
</el-drawer>
</el-dialog>
</div>
</template>
@@ -402,13 +412,17 @@ async function showDiff(h8: string): Promise<void> {
background: #05080d;
}
/* 版本历史抽屉 */
.ver-drawer { display: flex; flex-direction: column; gap: 10px; padding: 4px 2px; }
.ver-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; }
.ver-row {
display: flex; align-items: center; gap: 12px; padding: 8px 10px;
border: 1px solid var(--border-2); border-radius: var(--r-sm);
/* 版本历史:全屏模态 */
.ver-full { display: flex; flex-direction: column; gap: 10px; height: calc(100vh - 60px); padding: 4px 2px; }
.ver-head { display: flex; justify-content: space-between; align-items: center; gap: 10px; }
.ver-chips { display: flex; gap: 8px; flex-wrap: wrap; }
.ver-chip {
display: inline-flex; align-items: center; gap: 10px; padding: 6px 12px;
border: 1px solid var(--border-2); border-radius: var(--r-sm); background: transparent;
cursor: pointer; transition: border-color 0.12s var(--ease);
}
.ver-row:hover { background: var(--bg-hover); }
.ver-diff { height: 460px; border: 1px solid var(--border-2); border-radius: var(--r-sm); overflow: hidden; }
.ver-chip:hover { border-color: rgba(0, 229, 255, 0.5); }
.ver-chip.on { border-color: var(--brand); background: rgba(0, 229, 255, 0.08); }
.ver-diff-full { flex: 1; min-height: 0; border: 1px solid var(--border-2); border-radius: var(--r-sm); overflow: hidden; }
.ver-empty { flex: 1; display: flex; align-items: center; justify-content: center; font-size: 12.5px; }
</style>
@@ -43,30 +43,30 @@ onMounted(load)
</script>
<template>
<el-drawer :model-value="true" size="860px" :with-header="false" append-to-body destroy-on-close @close="emit('close')">
<div v-loading="loading" class="snap">
<el-dialog
:model-value="true" fullscreen append-to-body destroy-on-close
:show-close="false" @close="emit('close')"
>
<div v-loading="loading" class="snap-full">
<div class="snap-head">
<div>
<div style="font-size:15px;font-weight:700;color:var(--text)">代码快照 · {{ label }}</div>
<div class="mono muted" style="font-size:11px;margin-top:2px">
{{ codeFile || '…' }} · 发起版本 v{{ codeHash.slice(0, 8) }}
</div>
<span style="font-size:15px;font-weight:700;color:var(--text)">代码快照 · {{ label }}</span>
<span class="mono muted" style="font-size:11.5px;margin-left:12px">
{{ codeFile || '…' }} · 发起版本 v{{ codeHash.slice(0, 8) }} · =发起时快照 =当前 滚动联动
</span>
</div>
<button class="term-btn sm" @click="emit('close')">关闭</button>
<button class="term-btn sm" @click="emit('close')">关闭 (Esc)</button>
</div>
<div v-if="err" class="muted" style="flex:1;display:flex;align-items:center;justify-content:center;font-size:13px">{{ err }}</div>
<div v-else-if="diffReady && snapCode != null && curCode != null" class="snap-diff-full">
<MonacoDiff :original="snapCode" :modified="curCode" />
</div>
<div v-if="err" class="muted" style="padding:24px 0;text-align:center;font-size:12.5px">{{ err }}</div>
<template v-else-if="diffReady && snapCode != null && curCode != null">
<div class="muted mono" style="font-size:11px;margin:6px 0">=发起时快照 · =当前代码 · 滚动联动</div>
<div class="snap-diff">
<MonacoDiff :original="snapCode" :modified="curCode" />
</div>
</template>
</div>
</el-drawer>
</el-dialog>
</template>
<style scoped>
.snap { display: flex; flex-direction: column; gap: 8px; padding: 4px 2px; }
.snap-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; }
.snap-diff { height: 520px; border: 1px solid var(--border-2); border-radius: var(--r-sm); overflow: hidden; }
.snap-full { display: flex; flex-direction: column; gap: 10px; height: calc(100vh - 60px); padding: 4px 2px; }
.snap-head { display: flex; justify-content: space-between; align-items: center; gap: 10px; }
.snap-diff-full { flex: 1; min-height: 0; border: 1px solid var(--border-2); border-radius: var(--r-sm); overflow: hidden; }
</style>