<template>
|
<div class="product-table-container">
|
<el-table
|
:data="list"
|
v-loading="loading"
|
size="small"
|
border
|
class="custom-table"
|
:height="tableHeight"
|
>
|
<el-table-column label="合同号" prop="salesContractNo" width="160" show-overflow-tooltip>
|
<template #default="{ row }">
|
<span class="contract-no">{{ row.salesContractNo || '--' }}</span>
|
</template>
|
</el-table-column>
|
<el-table-column label="产品名称" prop="productName" min-width="180" show-overflow-tooltip />
|
<el-table-column label="规格型号" prop="model" width="140" show-overflow-tooltip>
|
<template #default="{ row }">
|
<span class="model-text">{{ row.model || '--' }}</span>
|
</template>
|
</el-table-column>
|
<el-table-column label="单位" prop="unit" width="80" align="center" />
|
<el-table-column label="合同数量" prop="contractQuantity" align="right" width="100">
|
<template #default="{ row }">
|
<span class="quantity">{{ formatNumber(row.contractQuantity) }}</span>
|
</template>
|
</el-table-column>
|
<el-table-column label="合同单价" prop="taxInclusiveUnitPrice" align="right" width="110">
|
<template #default="{ row }">
|
<span class="price">¥{{ formatMoney(row.taxInclusiveUnitPrice) }}</span>
|
</template>
|
</el-table-column>
|
<el-table-column label="合同金额" prop="contractAmount" align="right" width="130">
|
<template #default="{ row }">
|
<span class="amount">¥{{ formatMoney(row.contractAmount) }}</span>
|
</template>
|
</el-table-column>
|
<el-table-column label="已发货数量" prop="shippedQuantity" align="right" width="100">
|
<template #default="{ row }">
|
<span class="shipped-qty">{{ formatNumber(row.shippedQuantity) }}</span>
|
</template>
|
</el-table-column>
|
<el-table-column label="已发货金额" prop="shippedAmount" align="right" width="130">
|
<template #default="{ row }">
|
<span class="shipped-amt">¥{{ formatMoney(row.shippedAmount) }}</span>
|
</template>
|
</el-table-column>
|
<el-table-column label="发货进度" width="180" align="center">
|
<template #default="{ row }">
|
<div class="progress-cell">
|
<el-progress
|
:percentage="calcPercent(row.shippedQuantity, row.contractQuantity)"
|
:stroke-width="8"
|
:show-text="false"
|
:color="getProgressColor(calcPercent(row.shippedQuantity, row.contractQuantity))"
|
/>
|
<span class="progress-text">{{ calcPercent(row.shippedQuantity, row.contractQuantity) }}%</span>
|
</div>
|
</template>
|
</el-table-column>
|
</el-table>
|
|
<div class="pagination-wrapper">
|
<pagination
|
v-show="total > 0"
|
:total="total"
|
:page="queryParams.pageNum"
|
:limit="queryParams.pageSize"
|
@pagination="handlePagination"
|
/>
|
</div>
|
</div>
|
</template>
|
|
<script setup>
|
import { ref, watch, computed } from 'vue'
|
import { customerTransactionsProducts } from '@/api/salesManagement/indicatorStats.js'
|
import Pagination from '@/components/PIMTable/Pagination.vue'
|
|
const props = defineProps({
|
customerId: {
|
type: [Number, String],
|
required: true
|
}
|
})
|
|
const loading = ref(false)
|
const list = ref([])
|
const total = ref(0)
|
const queryParams = ref({
|
pageNum: 1,
|
pageSize: 10,
|
customerId: null
|
})
|
|
const tableHeight = computed(() => `calc(100vh - 32em)`)
|
|
const getList = () => {
|
loading.value = true
|
queryParams.value.customerId = props.customerId
|
customerTransactionsProducts(queryParams.value)
|
.then(res => {
|
if (res.code === 200) {
|
list.value = res.data?.records || []
|
total.value = res.data?.total || 0
|
}
|
})
|
.finally(() => {
|
loading.value = false
|
})
|
}
|
|
const handlePagination = ({ page, limit }) => {
|
queryParams.value.pageNum = page
|
queryParams.value.pageSize = limit
|
getList()
|
}
|
|
const formatMoney = (value) => {
|
if (!value) return '0.00'
|
return Number(value).toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })
|
}
|
|
const formatNumber = (value) => {
|
if (!value) return '0'
|
return Number(value).toLocaleString('zh-CN')
|
}
|
|
const calcPercent = (shipped, total) => {
|
if (!total || total === 0) return 0
|
return Math.min(100, Math.round((shipped / total) * 100))
|
}
|
|
const getProgressColor = (percent) => {
|
if (percent < 30) return '#f56c6c'
|
if (percent < 60) return '#e6a23c'
|
if (percent < 80) return '#409eff'
|
return '#67c23a'
|
}
|
|
watch(() => props.customerId, (val) => {
|
if (val) {
|
queryParams.value.pageNum = 1
|
getList()
|
}
|
}, { immediate: true })
|
</script>
|
|
<style scoped lang="scss">
|
.product-table-container {
|
.custom-table {
|
border-radius: 8px;
|
overflow: hidden;
|
|
:deep(.el-table__header-wrapper) {
|
th {
|
background: #f8f9fb !important;
|
font-weight: 600;
|
color: #303133;
|
}
|
}
|
|
:deep(.el-table__row) {
|
transition: all 0.2s;
|
|
&:hover > td {
|
background: #f5f7fa !important;
|
}
|
}
|
|
.contract-no {
|
color: #409eff;
|
font-weight: 500;
|
}
|
|
.model-text {
|
color: #606266;
|
}
|
|
.quantity {
|
font-weight: 500;
|
color: #303133;
|
}
|
|
.price {
|
color: #606266;
|
}
|
|
.amount {
|
font-weight: 600;
|
color: #303133;
|
}
|
|
.shipped-qty {
|
color: #67c23a;
|
font-weight: 500;
|
}
|
|
.shipped-amt {
|
color: #67c23a;
|
font-weight: 500;
|
}
|
|
.progress-cell {
|
display: flex;
|
align-items: center;
|
gap: 8px;
|
padding: 0 10px;
|
|
.el-progress {
|
flex: 1;
|
}
|
|
.progress-text {
|
font-size: 12px;
|
color: #606266;
|
min-width: 32px;
|
text-align: right;
|
}
|
}
|
}
|
}
|
|
.pagination-wrapper {
|
padding: 16px 0 0;
|
display: flex;
|
justify-content: flex-end;
|
}
|
</style>
|