李红攀:V2.6.976,添加采购询比、采购统计
This commit is contained in:
218
src/pages-erp/purchase-inquiry/publish/index.vue
Normal file
218
src/pages-erp/purchase-inquiry/publish/index.vue
Normal file
@@ -0,0 +1,218 @@
|
||||
<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>
|
||||
Reference in New Issue
Block a user