<template>
|
|
<view class="cu-page cu-page--with-footer" v-if="contract">
|
|
<view :class="['cu-detail-hero', contract.status === 1 ? 'cu-detail-hero--green' : '']">
|
|
<view class="cu-detail-hero__top">
|
|
<view>
|
|
<view class="cu-detail-hero__label">合同编号</view>
|
|
<view class="cu-detail-hero__code">{{ contract.code }}</view>
|
|
</view>
|
|
<text class="cu-status">{{ statusText(contract.status) }}</text>
|
|
</view>
|
|
<view class="cu-detail-hero__amount">
|
|
<text class="cu-detail-hero__amount-label">租赁面积</text>
|
|
<text class="cu-detail-hero__amount-value">{{ formatArea(contract.totalArea) }}</text>
|
|
</view>
|
|
</view>
|
|
|
|
<view v-if="contract.billStatusTip" :class="['cu-bill-tip', 'cu-bill-tip--inset', billTipClass(contract.billStatusType)]">
|
|
<text class="cu-bill-tip__icon">{{ billTipIcon(contract.billStatusType) }}</text>
|
|
<text class="cu-bill-tip__text">{{ contract.billStatusTip }}</text>
|
|
</view>
|
|
|
|
<view class="cu-segment">
|
|
<view :class="['cu-segment__item', tab === 0 ? 'cu-segment__item--active' : '']" @click="tab = 0">合同信息</view>
|
|
<view :class="['cu-segment__item', tab === 1 ? 'cu-segment__item--active' : '']" @click="tab = 1">关联账单</view>
|
|
</view>
|
|
|
|
<view v-if="tab === 0">
|
|
<view class="cu-panel">
|
|
<view class="cu-panel__title">房源信息</view>
|
|
<view v-if="contract.roomList && contract.roomList.length" class="cu-room-list">
|
|
<view v-for="(room, idx) in contract.roomList" :key="idx" class="cu-room-item">
|
|
<text class="cu-room-item__name">{{ formatRoomLine(room) }}</text>
|
|
<text class="cu-room-item__area">{{ formatArea(room.rentArea) }}</text>
|
|
</view>
|
|
</view>
|
|
<view v-else class="cu-kv__item">
|
|
<text class="cu-kv__value cu-kv__value--muted">{{ contract.roomInfo || '暂无房间信息' }}</text>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="cu-panel">
|
|
<view class="cu-panel__title">基本信息</view>
|
|
<view class="cu-kv__item">
|
|
<text class="cu-kv__label">开始日期</text>
|
|
<text class="cu-kv__value">{{ contract.startDate || '-' }}</text>
|
|
</view>
|
|
<view class="cu-kv__item">
|
|
<text class="cu-kv__label">结束日期</text>
|
|
<text class="cu-kv__value">{{ contract.endDate || '-' }}</text>
|
|
</view>
|
|
<view class="cu-kv__item">
|
|
<text class="cu-kv__label">签订日期</text>
|
|
<text class="cu-kv__value">{{ contract.signDate || '-' }}</text>
|
|
</view>
|
|
<view class="cu-kv__item">
|
|
<text class="cu-kv__label">付款方式</text>
|
|
<text class="cu-kv__value">{{ contract.payTypeText || '-' }}</text>
|
|
</view>
|
|
<view class="cu-kv__item">
|
|
<text class="cu-kv__label">免租期</text>
|
|
<text class="cu-kv__value">{{ contract.freeRentPeriod || '-' }}</text>
|
|
</view>
|
|
<view class="cu-kv__item">
|
|
<text class="cu-kv__label">租赁押金</text>
|
|
<text class="cu-kv__value">¥{{ contract.zlDeposit != null ? contract.zlDeposit : '-' }}</text>
|
|
</view>
|
|
<view class="cu-kv__item">
|
|
<text class="cu-kv__label">合同单价</text>
|
|
<text class="cu-kv__value cu-kv__value--danger">¥{{ contract.zlFirstPrice != null ? contract.zlFirstPrice : '-' }}/月</text>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="cu-panel">
|
|
<view class="cu-panel__title">合同附件</view>
|
|
<view v-if="contract.fileList && contract.fileList.length">
|
|
<view
|
|
v-for="file in contract.fileList"
|
|
:key="file.id"
|
|
class="cu-file-item"
|
|
@click="openFile(file)"
|
|
>
|
|
<text class="cu-file-item__icon">📎</text>
|
|
<view class="cu-file-item__main">
|
|
<text class="cu-file-item__name">{{ file.name || '附件' }}</text>
|
|
<text class="cu-file-item__time">{{ file.createDate || '' }}</text>
|
|
</view>
|
|
<text class="cu-file-item__action">下载</text>
|
|
</view>
|
|
</view>
|
|
<view v-else class="cu-kv__item">
|
|
<text class="cu-kv__value cu-kv__value--muted">暂无附件</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<template v-else>
|
|
<view class="cu-contract-bill-panel">
|
|
<view class="cu-contract-bill-switch">
|
|
<view
|
|
:class="['cu-contract-bill-switch__item', 'cu-contract-bill-switch__item--pay', billType === 0 ? 'cu-contract-bill-switch__item--active' : '']"
|
|
@click="switchBillType(0)"
|
|
>
|
|
<text class="cu-contract-bill-switch__icon">付</text>
|
|
<view class="cu-contract-bill-switch__text">
|
|
<text class="cu-contract-bill-switch__title">付款账单</text>
|
|
<text class="cu-contract-bill-switch__desc">需向物业缴纳</text>
|
|
</view>
|
|
</view>
|
|
<view
|
|
:class="['cu-contract-bill-switch__item', 'cu-contract-bill-switch__item--in', billType === 1 ? 'cu-contract-bill-switch__item--active' : '']"
|
|
@click="switchBillType(1)"
|
|
>
|
|
<text class="cu-contract-bill-switch__icon">收</text>
|
|
<view class="cu-contract-bill-switch__text">
|
|
<text class="cu-contract-bill-switch__title">收款账单</text>
|
|
<text class="cu-contract-bill-switch__desc">物业应退还/支付</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="cu-contract-bill-summary">
|
|
<text class="cu-contract-bill-summary__label">{{ billType === 0 ? '待缴账单' : '待收账单' }}</text>
|
|
<text class="cu-contract-bill-summary__count">{{ bills.length }} 笔</text>
|
|
</view>
|
|
|
|
<view v-if="billsLoading" class="cu-contract-bill-loading">
|
|
<text>加载中...</text>
|
|
</view>
|
|
|
|
<view v-else-if="bills.length" class="cu-contract-bill-list">
|
|
<view
|
|
v-for="b in bills"
|
|
:key="b.id"
|
|
:class="['cu-contract-bill-card', billType === 0 ? 'cu-contract-bill-card--pay' : 'cu-contract-bill-card--in']"
|
|
@click="goBillDetail(b.id)"
|
|
>
|
|
<view class="cu-contract-bill-card__top">
|
|
<view class="cu-contract-bill-card__title-wrap">
|
|
<text class="cu-contract-bill-card__type">{{ costTypeText(b.costType) }}</text>
|
|
<text class="cu-contract-bill-card__code">{{ b.code || '-' }}</text>
|
|
</view>
|
|
<text :class="['cu-contract-bill-card__status', billPayStatusClass(b.payStatus)]">{{ payStatusText(b.payStatus) }}</text>
|
|
</view>
|
|
|
|
<view class="cu-contract-bill-card__amounts">
|
|
<view class="cu-contract-bill-card__amount-item">
|
|
<text class="cu-contract-bill-card__amount-label">{{ receivableLabel }}</text>
|
|
<text class="cu-contract-bill-card__amount-value">¥{{ formatMoney(b.receivableFee) }}</text>
|
|
</view>
|
|
<view class="cu-contract-bill-card__amount-divider" />
|
|
<view class="cu-contract-bill-card__amount-item">
|
|
<text class="cu-contract-bill-card__amount-label">{{ receivedLabel }}</text>
|
|
<text class="cu-contract-bill-card__amount-value cu-contract-bill-card__amount-value--muted">¥{{ formatMoney(b.actReceivableFee) }}</text>
|
|
</view>
|
|
</view>
|
|
|
|
<view v-if="b.isOverdue === 1" class="cu-contract-bill-card__overdue">已逾期</view>
|
|
|
|
<view class="cu-contract-bill-card__meta">
|
|
<view class="cu-contract-bill-card__meta-row">
|
|
<text class="cu-contract-bill-card__meta-label">账单金额</text>
|
|
<text class="cu-contract-bill-card__meta-value">¥{{ formatMoney(b.totleFee) }}</text>
|
|
</view>
|
|
<view class="cu-contract-bill-card__meta-row">
|
|
<text class="cu-contract-bill-card__meta-label">计费周期</text>
|
|
<text class="cu-contract-bill-card__meta-value">{{ formatDate(b.startDate) || '-' }} ~ {{ formatDate(b.endDate) || '-' }}</text>
|
|
</view>
|
|
<view class="cu-contract-bill-card__meta-row">
|
|
<text class="cu-contract-bill-card__meta-label">{{ dueDateLabel }}</text>
|
|
<text class="cu-contract-bill-card__meta-value">{{ formatDate(b.planPayDate) || '-' }}</text>
|
|
</view>
|
|
<view class="cu-contract-bill-card__meta-row">
|
|
<text class="cu-contract-bill-card__meta-label">是否逾期</text>
|
|
<text :class="['cu-contract-bill-card__meta-value', b.isOverdue === 1 ? 'cu-contract-bill-card__meta-value--danger' : '']">
|
|
{{ overdueText(b) }}
|
|
</text>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="cu-contract-bill-card__foot">
|
|
<text>查看详情</text>
|
|
<text class="cu-contract-bill-card__arrow">→</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<u-empty v-else :text="billType === 0 ? '暂无付款账单' : '暂无收款账单'" margin-top="60" />
|
|
</view>
|
|
</template>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import { customerContractDetail } from '@/api'
|
|
const COST_TYPE_MAP = {
|
0: '租赁费',
|
1: '物业费',
|
2: '租赁押金',
|
3: '物业押金',
|
4: '水电费',
|
5: '杂项费',
|
6: '其他',
|
7: '保证金'
|
}
|
|
export default {
|
|
data () { return { id: null, contract: null, bills: [], tab: 0, billType: 0, billsLoading: false } },
|
|
computed: {
|
receivableLabel () { return this.billType === 0 ? '应付金额' : '应收金额' },
|
receivedLabel () { return this.billType === 0 ? '实付金额' : '实收金额' },
|
dueDateLabel () { return this.billType === 0 ? '应付日期' : '应收日期' }
|
},
|
|
onLoad (q) { this.id = q.id; this.load() },
|
|
methods: {
|
|
load (reloadContract = true) {
|
|
if (!reloadContract) this.billsLoading = true
|
|
customerContractDetail(this.id, this.billType).then(res => {
|
|
if (reloadContract) this.contract = res.data.contract
|
|
this.bills = res.data.bills || []
|
|
}).finally(() => {
|
|
this.billsLoading = false
|
|
})
|
|
},
|
|
switchBillType (type) {
|
|
if (this.billType === type) return
|
|
this.billType = type
|
|
this.bills = []
|
|
this.load(false)
|
|
},
|
|
costTypeText (type) { return COST_TYPE_MAP[type] || '账单' },
|
|
formatMoney (val) {
|
|
if (val === null || val === undefined || val === '') return '0.00'
|
|
return Number(val).toFixed(2)
|
|
},
|
|
formatDate (val) {
|
|
if (!val) return ''
|
|
return String(val).replace('T', ' ').substring(0, 10)
|
|
},
|
|
formatArea (area) {
|
|
if (area === null || area === undefined || area === '') return '-'
|
|
return `${area}㎡`
|
|
},
|
|
formatRoomLine (room) {
|
|
if (!room) return '-'
|
|
const parts = [room.projectName, room.buildingName, room.floorName, room.roomNum].filter(Boolean)
|
|
return parts.length ? parts.join('/') : '-'
|
|
},
|
|
statusText (s) { return { 0: '待执行', 1: '执行中', 2: '已到期', 3: '退租中', 4: '已退租' }[s] || '-' },
|
|
payStatusText (s) {
|
|
const common = { 1: '已结清', 2: '部分结清', 5: '已关闭' }
|
|
if (common[s]) return common[s]
|
|
if (this.billType === 0) {
|
|
return { 0: '待付款', 3: '待付款', 4: '待退款' }[s] || '-'
|
|
}
|
|
return { 0: '待收款', 3: '待收款', 4: '待退款' }[s] || '-'
|
|
},
|
|
billPayStatusClass (s) {
|
|
if (s === 1) return 'cu-contract-bill-card__status--ok'
|
|
if (s === 0 || s === 3) return 'cu-contract-bill-card__status--warn'
|
|
if (s === 4) return 'cu-contract-bill-card__status--bad'
|
|
return 'cu-contract-bill-card__status--muted'
|
|
},
|
|
overdueText (item) {
|
|
if (!item) return '-'
|
|
return item.isOverdue === 1 ? '是' : '否'
|
|
},
|
|
goBillDetail (id) { uni.navigateTo({ url: `/pages/customer/bill/detail?id=${id}` }) },
|
|
billTipClass (type) {
|
|
if (type === 'danger') return 'cu-bill-tip--danger'
|
|
if (type === 'warn') return 'cu-bill-tip--warn'
|
|
return 'cu-bill-tip--ok'
|
|
},
|
|
billTipIcon (type) {
|
|
if (type === 'danger') return '⚠️'
|
|
if (type === 'warn') return '⏰'
|
|
return '✅'
|
|
},
|
|
openFile (file) {
|
|
const url = file.fileurlFull || file.fileurl
|
|
if (!url) {
|
|
uni.showToast({ title: '附件地址无效', icon: 'none' })
|
|
return
|
|
}
|
|
// #ifdef H5
|
|
window.open(url, '_blank')
|
|
// #endif
|
|
// #ifndef H5
|
|
uni.showLoading({ title: '下载中' })
|
|
uni.downloadFile({
|
|
url,
|
|
success: (res) => {
|
|
if (res.statusCode === 200) {
|
|
uni.openDocument({ filePath: res.tempFilePath, showMenu: true })
|
|
} else {
|
|
uni.showToast({ title: '下载失败', icon: 'none' })
|
|
}
|
|
},
|
|
fail: () => uni.showToast({ title: '下载失败', icon: 'none' }),
|
|
complete: () => uni.hideLoading()
|
|
})
|
|
// #endif
|
|
}
|
|
}
|
|
}
|
|
</script>
|