feat(web-admin): add mp webview CRM quote version history page.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
wuzilongandCursor committed 2026-10-15 16:04:06 +08:00
1 parent b9e44bd697
commit d0241ddbd4
1 file changed
+139 -5
+139 -5
View File
@@ -1,17 +1,151 @@
<template>
<MpWebviewShell>
<MpWebviewShell @ready="onShellReady">
<header class="mp-wv-header">
<div class="mp-wv-header__row">
<h1 class="mp-wv-header__title">{{ title }}</h1>
<button class="mp-wv-header__back" type="button" aria-label="返回详情" @click="goBack">
←
</button>
<h1 class="mp-wv-header__title">版本历史</h1>
</div>
<div v-if="quoteNo" class="mp-wv-header__sub">{{ quoteNo }}</div>
</header>
<div
v-if="loading"
class="mp-plan-form-loading mp-plan-form-loading--page"
role="status"
aria-live="polite"
aria-busy="true"
>
<div class="mp-plan-form-loading__orb" aria-hidden="true">
<span class="mp-plan-form-loading__dot" />
</div>
<p class="mp-plan-form-loading__title">正在加载版本历史</p>
<p class="mp-plan-form-loading__desc">请稍候…</p>
</div>
<div v-else-if="errorText" class="mp-wv-empty">{{ errorText }}</div>
<div v-else-if="!versions.length" class="mp-wv-empty">
<div class="mp-wv-empty__title">暂无版本历史</div>
</div>
<div v-else class="mp-wv-detail-body">
<article
v-for="item in versions"
:key="String(item.id)"
class="mp-wv-card"
@click="goView(item)"
>
<div class="mp-wv-card__tags">
<el-tag v-if="Number(item.isLatest) === 1" type="success" size="small">当前版本</el-tag>
<el-tag v-else type="info" size="small">历史版本</el-tag>
<el-tag :type="statusTagType(item.status)" size="small">{{ statusLabel(item.status) }}</el-tag>
</div>
<div class="mp-wv-card__title">{{ item.version || '—' }}</div>
<div class="mp-wv-card__meta">{{ item.customerName || '—' }}</div>
<div class="mp-wv-card__meta">
{{ formatQuoteMoney(item.finalAmount ?? item.totalAmount) }} ·
{{ item.createTime || item.quoteDate || '—' }}
</div>
</article>
</div>
</MpWebviewShell>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import { useRoute } from 'vue-router'
import { ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import MpWebviewShell from '@/layouts/MpWebviewShell.vue'
import { getQuote, queryVersions } from '@/api/crm/quote'
import { formatQuoteMoney } from '@/utils/mp-crm-quote-card'
import { useDictStore } from '@/store/modules/dict'
import '@/styles/mp-webview.scss'
const route = useRoute()
const title = computed(() => String(route.meta.title || ''))
const router = useRouter()
const dictStore = useDictStore()
const loading = ref(true)
const errorText = ref('')
const quoteNo = ref('')
const versions = ref<any[]>([])
function statusLabel(status?: string) {
const raw = status || ''
return dictStore.getLabel('crm_quote_status', raw) || raw || '—'
}
function statusTagType(status?: string) {
return dictStore.getTagType('crm_quote_status', status || '') as
| 'success'
| 'warning'
| 'info'
| 'primary'
| 'danger'
}
async function loadVersions() {
const id = String(route.params.id || '').trim()
if (!id) {
errorText.value = '缺少报价单 ID'
loading.value = false
return
}
loading.value = true
try {
const detailRes = await getQuote(id)
const detail = ((detailRes as any)?.data ?? detailRes) || {}
quoteNo.value = String(detail.quoteNo || '')
if (!quoteNo.value) {
errorText.value = '无法获取报价单号'
versions.value = []
return
}
const verRes = await queryVersions(quoteNo.value)
const data = (verRes as any)?.data ?? verRes
versions.value = Array.isArray(data) ? data : data?.list || data?.rows || []
errorText.value = ''
} catch (error) {
versions.value = []
errorText.value = error instanceof Error ? error.message : '加载失败'
} finally {
loading.value = false
}
}
function goBack() {
const id = String(route.params.id || '').trim()
if (id) {
void router.push({ path: `/m/crm/quote/${id}`, query: { from: 'manage' } })
return
}
void router.back()
}
function goView(item: { id?: string | number }) {
const vid = String(item.id || '').trim()
if (!vid) return
void router.push({ path: `/m/crm/quote/${vid}`, query: { from: 'manage' } })
}
function onShellReady() {
void loadVersions()
}
</script>
<style scoped lang="scss">
.mp-wv-card {
margin-bottom: 10px;
}
.mp-wv-card__tags {
display: flex;
flex-wrap: wrap;
gap: 6px;
margin-bottom: 6px;
}
.mp-wv-card__title {
font-size: 15px;
font-weight: 700;
color: #087f57;
}
</style>