Files
crm_uiapp/src/pages-erp/purchase-inquiry/publish/index.vue

219 lines
8.5 KiB
Vue

<template>
<view class="yd-page-container erp-page">
<wd-navbar title="询比邀请" left-arrow placeholder safe-area-inset-top fixed @click-left="handleBack" />
<view class="erp-page__body">
<view class="erp-section">
<view class="erp-section__title">询比信息</view>
<view class="erp-field-row"><text>询比单号</text><text>{{ inquiry?.no || '-' }}</text></view>
<view class="erp-field-row"><text>产品</text><text>{{ inquiry?.productName || '-' }}</text></view>
<view class="erp-field-row"><text>状态</text><text>{{ getStatusText(inquiry?.status) }}</text></view>
<view class="erp-field-row"><text>截止时间</text><text>{{ formatDateTime(inquiry?.deadline) }}</text></view>
</view>
<view class="erp-section">
<view class="erp-section__title">邀请设置</view>
<wd-cell-group border>
<wd-cell title="链接失效时间" title-width="180rpx" center>
<wd-datetime-picker v-model="formData.linkExpireTime" type="datetime" label="" placeholder="请选择链接失效时间" />
</wd-cell>
</wd-cell-group>
<view class="mt-24rpx text-26rpx text-[#666]">邀请供应商</view>
<view class="mt-16rpx">
<wd-checkbox-group v-model="formData.supplierIds" cell shape="button">
<wd-checkbox v-for="item in supplierList" :key="item.id" :model-value="item.id">
{{ item.name }}
</wd-checkbox>
</wd-checkbox-group>
</view>
<view class="mt-24rpx">
<wd-button type="primary" block :loading="submitting" @click="handleSubmit">发布 / 重新生成链接</wd-button>
</view>
</view>
<view class="erp-section">
<view class="erp-section__title">邀请概览</view>
<view class="grid grid-cols-2 gap-16rpx">
<view class="erp-metric-card">
<view class="erp-metric-card__label">已邀请</view>
<view class="erp-metric-card__value">{{ invitationList.length }}</view>
</view>
<view class="erp-metric-card">
<view class="erp-metric-card__label">已查看</view>
<view class="erp-metric-card__value">{{ summary.viewedCount }}</view>
</view>
<view class="erp-metric-card">
<view class="erp-metric-card__label">已报价</view>
<view class="erp-metric-card__value">{{ summary.quotedCount }}</view>
</view>
<view class="erp-metric-card">
<view class="erp-metric-card__label">待报价</view>
<view class="erp-metric-card__value">{{ summary.pendingCount }}</view>
</view>
</view>
</view>
<view class="erp-section">
<view class="erp-section__title">邀请记录</view>
<view v-if="invitationList.length">
<view v-for="item in invitationList" :key="item.id" class="erp-form-item-card erp-form-item-card--padded">
<view class="mb-12rpx flex items-center justify-between">
<text class="erp-card-title">{{ item.supplierName || '-' }}</text>
<text class="text-24rpx" :class="getInvitationStatusClass(item.status)">{{ getInvitationStatusText(item.status) }}</text>
</view>
<view class="erp-field-row"><text>报价单价</text><text>{{ item.unitPrice != null ? `¥${Number(item.unitPrice).toFixed(2)}` : '-' }}</text></view>
<view class="erp-field-row"><text>报价总额</text><text>{{ item.totalPrice != null ? `¥${Number(item.totalPrice).toFixed(2)}` : '-' }}</text></view>
<view class="erp-field-row"><text>预计到货</text><text>{{ formatDateTime(item.expectedArrivalDate) }}</text></view>
<view class="erp-field-row"><text>报价时间</text><text>{{ formatDateTime(item.quoteDate) }}</text></view>
<view class="erp-field-row"><text>首次查看</text><text>{{ formatDateTime(item.firstViewTime) }}</text></view>
<view class="erp-field-row"><text>提交来源</text><text>{{ item.submitSource || '-' }}</text></view>
<view class="mt-16rpx flex gap-12rpx">
<wd-button size="small" plain @click="copyLink(item.portalUrl)">复制链接</wd-button>
<wd-button v-if="item.qualificationFile" size="small" type="primary" plain @click="copyLink(item.qualificationFile)">复制附件地址</wd-button>
</view>
</view>
</view>
<view v-else class="erp-empty">暂无邀请记录</view>
</view>
</view>
</view>
</template>
<script lang="ts" setup>
import type { PurchaseInquiry, PurchaseInquiryInvitation, PurchaseInquiryPublishReq } from '@/api/erp/purchase-inquiry'
import type { SupplierSimple } from '@/api/erp/supplier'
import { computed, onMounted, reactive, ref } from 'vue'
import { useToast } from 'wot-design-uni'
import { getPurchaseInquiry, getPurchaseInquiryInvitationList, publishPurchaseInquiry } from '@/api/erp/purchase-inquiry'
import { getSupplierSimpleList } from '@/api/erp/supplier'
import { navigateBackPlus } from '@/utils'
const props = defineProps<{ id?: number | any }>()
definePage({
style: {
navigationBarTitleText: '',
navigationStyle: 'custom',
},
})
const toast = useToast()
const inquiry = ref<PurchaseInquiry>()
const supplierList = ref<SupplierSimple[]>([])
const invitationList = ref<PurchaseInquiryInvitation[]>([])
const submitting = ref(false)
type PublishFormModel = Omit<PurchaseInquiryPublishReq, 'linkExpireTime'> & {
linkExpireTime?: string | number
}
const formData = reactive<PublishFormModel>({
inquiryId: 0,
supplierIds: [],
linkExpireTime: undefined,
})
const summary = computed(() => {
const viewedCount = invitationList.value.filter(v => [20, 30].includes(Number(v.status))).length
const quotedCount = invitationList.value.filter(v => !!v.quoteId || Number(v.status) === 30).length
const pendingCount = invitationList.value.filter(v => Number(v.status) === 10).length
return { viewedCount, quotedCount, pendingCount }
})
function getStatusText(status?: number) {
switch (status) {
case 10: return '待询价'
case 20: return '询价中'
case 30: return '已完成'
default: return '-'
}
}
function getInvitationStatusText(status?: number) {
switch (status) {
case 10: return '待报价'
case 20: return '已查看'
case 30: return '已报价'
case 40: return '已失效'
case 50: return '已作废'
default: return '-'
}
}
function getInvitationStatusClass(status?: number) {
switch (status) {
case 20: return 'text-[#d48806]'
case 30: return 'text-[#52c41a]'
case 40: return 'text-[#f5222d]'
default: return 'text-[#999]'
}
}
function formatDateTime(value?: string | number | Date) {
if (!value) return '-'
const date = new Date(value)
if (Number.isNaN(date.getTime())) return String(value)
const month = `${date.getMonth() + 1}`.padStart(2, '0')
const day = `${date.getDate()}`.padStart(2, '0')
const hour = `${date.getHours()}`.padStart(2, '0')
const minute = `${date.getMinutes()}`.padStart(2, '0')
return `${date.getFullYear()}-${month}-${day} ${hour}:${minute}`
}
function handleBack() {
navigateBackPlus(`/pages-erp/purchase-inquiry/detail/index?id=${props.id}`)
}
async function loadData() {
if (!props.id) return
formData.inquiryId = Number(props.id)
const [detail, suppliers, invitations] = await Promise.all([
getPurchaseInquiry(Number(props.id)),
getSupplierSimpleList(),
getPurchaseInquiryInvitationList(Number(props.id)),
])
inquiry.value = detail
supplierList.value = suppliers || []
invitationList.value = invitations || []
formData.supplierIds = invitationList.value.map(v => Number(v.supplierId)).filter(Boolean)
formData.linkExpireTime = (invitationList.value[0]?.linkExpireTime || detail?.deadline) as string | number | undefined
}
async function handleSubmit() {
if (!formData.supplierIds.length) {
toast.warning('请至少选择一个供应商')
return
}
submitting.value = true
try {
await publishPurchaseInquiry({
inquiryId: formData.inquiryId,
supplierIds: formData.supplierIds,
linkExpireTime: formData.linkExpireTime,
} as PurchaseInquiryPublishReq)
toast.success('询比邀请已发布')
await loadData()
} finally {
submitting.value = false
}
}
function copyLink(url?: string) {
if (!url) {
toast.warning('暂无可复制链接')
return
}
uni.setClipboardData({
data: url,
success: () => toast.success('链接已复制'),
})
}
onMounted(() => {
loadData()
})
</script>
<style lang="scss" scoped>
</style>