156 lines
4.6 KiB
Vue
156 lines
4.6 KiB
Vue
|
<template>
|
||
|
<a-spin :loading="loading">
|
||
|
<div v-if="contractDetail">
|
||
|
<a-descriptions
|
||
|
:column="1"
|
||
|
size="medium"
|
||
|
:label-style="{ width: '120px' }"
|
||
|
>
|
||
|
<a-descriptions-item label="合同编号">
|
||
|
{{ contractDetail.code }}
|
||
|
</a-descriptions-item>
|
||
|
<a-descriptions-item label="项目名称">
|
||
|
{{ contractDetail.projectName }}
|
||
|
</a-descriptions-item>
|
||
|
<a-descriptions-item label="客户名称">
|
||
|
{{ contractDetail.customer }}
|
||
|
</a-descriptions-item>
|
||
|
<a-descriptions-item label="合同金额">
|
||
|
<span class="font-medium text-green-600">¥{{ (contractDetail.amount || 0).toLocaleString() }}</span>
|
||
|
</a-descriptions-item>
|
||
|
<a-descriptions-item label="已收款金额">
|
||
|
<span class="font-medium text-blue-600">¥{{ (contractDetail.receivedAmount || 0).toLocaleString() }}</span>
|
||
|
</a-descriptions-item>
|
||
|
<a-descriptions-item label="未收款金额">
|
||
|
<span class="font-medium text-orange-600">¥{{ (contractDetail.pendingAmount || 0).toLocaleString() }}</span>
|
||
|
</a-descriptions-item>
|
||
|
<a-descriptions-item label="签署日期">
|
||
|
{{ contractDetail.signDate }}
|
||
|
</a-descriptions-item>
|
||
|
<a-descriptions-item label="履约期限">
|
||
|
{{ contractDetail.performanceDeadline }}
|
||
|
</a-descriptions-item>
|
||
|
<a-descriptions-item label="付款日期">
|
||
|
{{ contractDetail.paymentDate }}
|
||
|
</a-descriptions-item>
|
||
|
<a-descriptions-item label="合同状态">
|
||
|
<a-tag :color="getStatusColor(contractDetail.contractStatus)">
|
||
|
{{ getStatusText(contractDetail.contractStatusLabel || contractDetail.contractStatus) }}
|
||
|
</a-tag>
|
||
|
</a-descriptions-item>
|
||
|
<a-descriptions-item label="销售人员">
|
||
|
{{ contractDetail.salespersonName }}
|
||
|
</a-descriptions-item>
|
||
|
<a-descriptions-item label="销售部门">
|
||
|
{{ contractDetail.salespersonDeptName }}
|
||
|
</a-descriptions-item>
|
||
|
<a-descriptions-item label="产品服务">
|
||
|
{{ contractDetail.productService }}
|
||
|
</a-descriptions-item>
|
||
|
<a-descriptions-item label="备注">
|
||
|
{{ contractDetail.notes }}
|
||
|
</a-descriptions-item>
|
||
|
</a-descriptions>
|
||
|
</div>
|
||
|
<div v-else-if="!loading" class="empty-container">
|
||
|
<a-empty description="暂无信息" />
|
||
|
</div>
|
||
|
</a-spin>
|
||
|
</template>
|
||
|
|
||
|
<script setup lang="ts">
|
||
|
import { ref, onMounted } from 'vue'
|
||
|
import http from '@/utils/http'
|
||
|
import { Message } from '@arco-design/web-vue'
|
||
|
|
||
|
interface ContractDetail {
|
||
|
contractId: string
|
||
|
customer: string
|
||
|
code: string
|
||
|
projectId: string
|
||
|
type: string
|
||
|
productService: string
|
||
|
paymentDate: string | null
|
||
|
performanceDeadline: string | null
|
||
|
paymentAddress: string
|
||
|
amount: number
|
||
|
accountNumber: string
|
||
|
notes: string
|
||
|
contractStatus: string
|
||
|
contractText: string | null
|
||
|
projectName: string
|
||
|
salespersonName: string | null
|
||
|
salespersonDeptName: string
|
||
|
settlementAmount: number | null
|
||
|
receivedAmount: number | null
|
||
|
contractStatusLabel: string | null
|
||
|
createBy: string | null
|
||
|
updateBy: string | null
|
||
|
createTime: string
|
||
|
updateTime: string
|
||
|
page: number
|
||
|
pageSize: number
|
||
|
signDate: string
|
||
|
duration: string
|
||
|
pendingAmount?: number
|
||
|
}
|
||
|
|
||
|
const props = defineProps({
|
||
|
contractId: {
|
||
|
type: String,
|
||
|
required: true
|
||
|
}
|
||
|
})
|
||
|
|
||
|
const contractDetail = ref<ContractDetail | null>(null)
|
||
|
const loading = ref(false)
|
||
|
|
||
|
const getStatusColor = (status: string) => {
|
||
|
const colorMap: Record<string, string> = {
|
||
|
未确认: 'gray',
|
||
|
待审批: 'orange',
|
||
|
已签署: 'blue',
|
||
|
执行中: 'cyan',
|
||
|
已完成: 'green',
|
||
|
已终止: 'red'
|
||
|
}
|
||
|
return colorMap[status] || 'gray'
|
||
|
}
|
||
|
|
||
|
const getStatusText = (status: string) => {
|
||
|
return status || '未知状态'
|
||
|
}
|
||
|
|
||
|
const fetchContractDetail = async () => {
|
||
|
try {
|
||
|
loading.value = true
|
||
|
const response = await http.get(`/contract/${props.contractId}`)
|
||
|
if (response.code === 200) {
|
||
|
contractDetail.value = response.data
|
||
|
// 计算未收款金额
|
||
|
if (contractDetail.value) {
|
||
|
contractDetail.value.pendingAmount = (contractDetail.value.amount || 0) - (contractDetail.value.receivedAmount || 0)
|
||
|
}
|
||
|
} else {
|
||
|
Message.error(response.msg || '获取合同详情失败')
|
||
|
}
|
||
|
} catch (error) {
|
||
|
console.error('获取合同详情失败:', error)
|
||
|
Message.error('获取合同详情失败')
|
||
|
} finally {
|
||
|
loading.value = false
|
||
|
}
|
||
|
}
|
||
|
|
||
|
onMounted(() => {
|
||
|
fetchContractDetail()
|
||
|
})
|
||
|
</script>
|
||
|
|
||
|
<style scoped>
|
||
|
.empty-container {
|
||
|
text-align: center;
|
||
|
padding: 40px 0;
|
||
|
}
|
||
|
</style>
|