161 lines
4.7 KiB
Vue
161 lines
4.7 KiB
Vue
<template>
|
|
<MpWebviewShell>
|
|
<header class="mp-wv-header">
|
|
<div class="mp-wv-header__row">
|
|
<button class="mp-wv-header__back" type="button" aria-label="返回列表" @click="goList">
|
|
←
|
|
</button>
|
|
<h1 class="mp-wv-header__title">{{ pageTitle }}</h1>
|
|
</div>
|
|
</header>
|
|
<div
|
|
v-if="contentLoading || bootLoading"
|
|
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">{{ loadingCopy.title }}</p>
|
|
<p class="mp-plan-form-loading__desc">{{ loadingCopy.desc }}</p>
|
|
<div class="mp-plan-form-loading__skel" aria-hidden="true">
|
|
<div class="mp-wv-skel mp-wv-skel--block" />
|
|
<div class="mp-wv-skel mp-wv-skel--mid" />
|
|
<div class="mp-wv-skel mp-wv-skel--line" />
|
|
<div class="mp-wv-skel mp-wv-skel--short" />
|
|
</div>
|
|
</div>
|
|
<div v-else-if="bootError" class="mp-wv-empty">{{ bootError }}</div>
|
|
<ContractFormDialog
|
|
v-if="formReady"
|
|
v-show="!contentLoading"
|
|
:key="formKey"
|
|
variant="page"
|
|
:visible="true"
|
|
:edit-id="editId"
|
|
:copy-source="copySource"
|
|
@loading-change="onLoadingChange"
|
|
@success="onSuccess"
|
|
@update:visible="onVisibleChange"
|
|
/>
|
|
</MpWebviewShell>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { computed, ref, watch } from 'vue'
|
|
import { useRoute, useRouter } from 'vue-router'
|
|
import MpWebviewShell from '@/layouts/MpWebviewShell.vue'
|
|
import ContractFormDialog from '@/views/crm/contract/components/ContractFormDialog.vue'
|
|
import { getContract, type ContractVO } from '@/api/crm/contract'
|
|
import { MP_CRM_CONTRACT_LIST_PATH } from '@/utils/mp-webview'
|
|
import '@/styles/mp-webview.scss'
|
|
|
|
const route = useRoute()
|
|
const router = useRouter()
|
|
const contentLoading = ref(true)
|
|
const bootLoading = ref(false)
|
|
const bootError = ref('')
|
|
const formReady = ref(false)
|
|
const copySource = ref<ContractVO | null>(null)
|
|
|
|
const pageMode = computed<'add' | 'edit' | 'copy'>(() => {
|
|
if (route.name === 'MpCrmContractEdit') return 'edit'
|
|
const copyFrom = String(route.query.copyFrom || '').trim()
|
|
if (copyFrom) return 'copy'
|
|
return 'add'
|
|
})
|
|
|
|
const pageTitle = computed(() => {
|
|
if (pageMode.value === 'copy') return '复制合同'
|
|
if (pageMode.value === 'edit') return '编辑合同'
|
|
return String(route.meta.title || '新增合同')
|
|
})
|
|
|
|
const editId = computed(() => {
|
|
if (pageMode.value !== 'edit') return null
|
|
const id = String(route.params.id || '').trim()
|
|
return id || null
|
|
})
|
|
|
|
const copyFromId = computed(() => {
|
|
if (pageMode.value !== 'copy') return null
|
|
const id = String(route.query.copyFrom || '').trim()
|
|
return id || null
|
|
})
|
|
|
|
const formKey = computed(
|
|
() =>
|
|
`${String(route.name || '')}-${pageMode.value}-${editId.value || ''}-${copyFromId.value || ''}`
|
|
)
|
|
|
|
const loadingCopy = computed(() => {
|
|
if (pageMode.value === 'edit') {
|
|
return { title: '正在加载合同', desc: '请稍候,正在获取合同详情…' }
|
|
}
|
|
if (pageMode.value === 'copy') {
|
|
return { title: '正在复制合同', desc: '请稍候,正在预填原单数据…' }
|
|
}
|
|
return { title: '正在准备表单', desc: '请稍候,正在初始化主数据…' }
|
|
})
|
|
|
|
async function bootForm() {
|
|
formReady.value = false
|
|
bootError.value = ''
|
|
copySource.value = null
|
|
contentLoading.value = true
|
|
|
|
if (pageMode.value === 'copy' && copyFromId.value) {
|
|
bootLoading.value = true
|
|
try {
|
|
const res = await getContract(copyFromId.value)
|
|
copySource.value = ((res as any)?.data ?? res) as ContractVO
|
|
formReady.value = true
|
|
} catch (error) {
|
|
bootError.value = error instanceof Error ? error.message : '加载复制来源失败'
|
|
} finally {
|
|
bootLoading.value = false
|
|
}
|
|
return
|
|
}
|
|
|
|
formReady.value = true
|
|
}
|
|
|
|
watch(
|
|
formKey,
|
|
() => {
|
|
void bootForm()
|
|
},
|
|
{ immediate: true }
|
|
)
|
|
|
|
function onLoadingChange(loading: boolean) {
|
|
contentLoading.value = loading
|
|
}
|
|
|
|
function goList() {
|
|
void router.replace(MP_CRM_CONTRACT_LIST_PATH)
|
|
}
|
|
|
|
function onVisibleChange(visible: boolean) {
|
|
if (!visible) goList()
|
|
}
|
|
|
|
function onSuccess() {
|
|
if (pageMode.value === 'edit' && editId.value) {
|
|
void router.replace(`/m/crm/contract/${editId.value}`)
|
|
return
|
|
}
|
|
goList()
|
|
}
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
:deep(.contract-form-dialog--page) {
|
|
position: relative;
|
|
z-index: 1;
|
|
}
|
|
</style>
|