Files
shanxia2.0/web-admin/src/composables/useContractDetailDialog.ts
T
2026-09-29 07:07:51 +08:00

98 lines
2.9 KiB
TypeScript

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<void>
}
export function useContractDetailDialog(options?: {
/**
* 为 true 时:无 pl:contract:view-product-price(或自定义 productPricePerm)则隐藏产品价格。
* 默认 false(CRM 等场景仍展示价格)。
*/
gateProductPriceByPerm?: boolean
productPricePerm?: string
}) {
const contractDetailRef = ref<ContractDetailDialogExpose>()
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<void> | 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<ContractDetailDialogExpose>((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
}
}