import { computed, defineAsyncComponent, nextTick, ref, watch } from 'vue' import { fetchGetMenuCodes } from '@/api/auth' export const ContractDetailDialogAsync = defineAsyncComponent( () => import('@/views/crm/contract/components/ContractDetailDialog.vue') ) /** 运输管理四页:合同详情弹窗展示产品单价/金额 */ export const PL_CONTRACT_VIEW_PRODUCT_PRICE_PERM = 'pl:contract:view-product-price' type ContractDetailDialogExpose = { open: (id: string | number) => Promise } export function useContractDetailDialog(options?: { /** * 为 true 时:无 pl:contract:view-product-price(或自定义 productPricePerm)则隐藏产品价格。 * 默认 false(CRM 等场景仍展示价格)。 */ gateProductPriceByPerm?: boolean productPricePerm?: string }) { const contractDetailRef = ref() const permCode = options?.productPricePerm || PL_CONTRACT_VIEW_PRODUCT_PRICE_PERM const canViewProductPrice = ref(!options?.gateProductPriceByPerm) const hideProductPrice = computed(() => options?.gateProductPriceByPerm ? !canViewProductPrice.value : false ) let loadPromise: Promise | null = null async function loadProductPricePermission() { if (!options?.gateProductPriceByPerm) return if (loadPromise) { await loadPromise return } loadPromise = (async () => { try { const perm = await fetchGetMenuCodes() canViewProductPrice.value = !!perm?.all || !!perm?.isSuperAdmin || (perm?.menuCodes || []).includes(permCode) } catch { canViewProductPrice.value = false } finally { loadPromise = null } })() await loadPromise } // setup 阶段立即拉取(避免仅依赖 onMounted:本地 HMR/缓存页可能导致权限一直为默认隐藏) if (options?.gateProductPriceByPerm) { void loadProductPricePermission() } async function waitForContractDetailDialog() { if (contractDetailRef.value) return contractDetailRef.value await nextTick() if (contractDetailRef.value) return contractDetailRef.value return new Promise((resolve) => { const stop = watch( contractDetailRef, (val) => { if (val) { stop() resolve(val) } }, { flush: 'post' } ) }) } async function openContractDetail(contractId: string | number | undefined | null) { const id = String(contractId ?? '').trim() if (!id) { ElMessage.warning('暂无关联合同') return } if (options?.gateProductPriceByPerm) { await loadProductPricePermission() } const dialog = await waitForContractDetailDialog() await dialog.open(id) } return { ContractDetailDialog: ContractDetailDialogAsync, contractDetailRef, openContractDetail, hideProductPrice, canViewProductPrice, loadProductPricePermission } }