<template>
|
<GlobalWindow
|
:title="title"
|
width="100%"
|
:visible.sync="visible"
|
:confirm-working="isWorking"
|
@close="close"
|
@confirm="confirm">
|
<div class="main">
|
<div class="main_head">
|
<span>租客:{{ info.renterName }}</span>
|
<span>合同编号:{{ info.code }}</span>
|
</div>
|
<div class="title">退租信息</div>
|
<div class="main_box">
|
<div class="main_box_form">
|
<el-form :inline="true" label-position="top" :model="form" ref="form" :rules="rules" class="demo-form-inline">
|
<el-form-item label="退租类型" prop="btType" style="width: 33%;">
|
<el-select v-model="form.btType" placeholder="请选择">
|
<el-option label="到期退租" :value="0"></el-option>
|
<el-option label="换房退租" :value="1"></el-option>
|
<el-option label="违约退租" :value="2"></el-option>
|
<el-option label="协商退租" :value="3"></el-option>
|
</el-select>
|
</el-form-item>
|
<el-form-item label="退租日期" prop="btDate" style="width: 33%;">
|
<el-date-picker
|
v-model="form.btDate"
|
type="date"
|
@change="changeBtDate"
|
value-format="yyyy-MM-dd"
|
placeholder="请选择">
|
</el-date-picker>
|
</el-form-item>
|
<el-form-item label="经办人" prop="btUserId" style="width: 30%;">
|
<el-select v-model="form.btUserId" placeholder="请选择">
|
<el-option v-for="(item, index) in agentList" :key="index" :value="item.id" :label="item.realname"></el-option>
|
</el-select>
|
</el-form-item>
|
<el-form-item label="协议签订日期" prop="btSignDate" style="width: 33%;">
|
<el-date-picker
|
v-model="form.btSignDate"
|
type="date"
|
value-format="yyyy-MM-dd"
|
placeholder="请选择">
|
</el-date-picker>
|
</el-form-item>
|
<el-form-item label="退租原因" prop="btInfo" style="width: 60%;">
|
<el-input v-model="form.btInfo" placeholder="请输入"></el-input>
|
</el-form-item>
|
</el-form>
|
</div>
|
<div class="main_box_list">
|
<div class="main_box_list_title">已选房源</div>
|
<el-table :data="info.roomList" stripe>
|
<el-table-column prop="projectName" label="项目名称" show-overflow-tooltip />
|
<el-table-column label="房源名称" show-overflow-tooltip>
|
<template slot-scope="{row}">
|
{{row.buildingName}}/{{row.roomNum}}
|
</template>
|
</el-table-column>
|
<el-table-column label="租赁面积(㎡)" show-overflow-tooltip>
|
<template slot-scope="{row}">
|
{{row.rentArea}}㎡
|
</template>
|
</el-table-column>
|
</el-table>
|
</div>
|
</div>
|
<div class="title">
|
<span>账单结算</span>
|
<div style="display: flex; align-items: center;">
|
<el-button type="primary" @click="addZD">添加收款</el-button>
|
<el-button type="primary" @click="addFK">添加付款</el-button>
|
</div>
|
</div>
|
<el-table
|
:data="info.terminateList"
|
border
|
v-loading="loading"
|
style="width: 100%; margin-bottom: 15px;">
|
<el-table-column
|
prop="code"
|
label="账单编号">
|
</el-table-column>
|
<el-table-column
|
width="100"
|
label="费用类型">
|
<template slot-scope="scope">
|
<div style="display: flex; align-items: center;">
|
<span v-if="scope.row.costType === 0">租赁费</span>
|
<span v-if="scope.row.costType === 1">物业费</span>
|
<span v-if="scope.row.costType === 4">水电费</span>
|
<span v-if="scope.row.costType === 5">杂项费</span>
|
<span v-if="scope.row.costType === 6">其他</span>
|
<i class="el-icon-delete"
|
style="color: red; margin-left: 10px; font-size: 18px; cursor: pointer;"
|
@click="deleRow(scope.$index)"
|
v-if="scope.row.isDele">
|
</i>
|
</div>
|
</template>
|
</el-table-column>
|
<el-table-column
|
label="计费周期">
|
<template slot-scope="{row}">
|
{{row.startDate}} ~ {{row.endDate}}
|
</template>
|
</el-table-column>
|
<el-table-column
|
label="应收付金额/原始应收付">
|
<template v-slot="{row}">
|
<div style="display: flex; align-items: center;">
|
<el-input v-model="row.receivableFee" @input="changeReceivableFee($event, row)" placeholder="请输入内容" style="flex: 1;"></el-input>
|
<span style="margin: 0 10px;">/</span>
|
{{row.receivableFeeCopy}}
|
</div>
|
</template>
|
</el-table-column>
|
<el-table-column
|
width="120"
|
prop="actReceivableFee"
|
label="实收/付金额">
|
</el-table-column>
|
<el-table-column
|
label="需收/付金额">
|
<template slot-scope="{row}">
|
<div style="display: flex; align-items: center;">
|
<el-tag type="success" v-if="row.billType === 0">收</el-tag>
|
<el-tag type="warning" v-if="row.billType === 1">付</el-tag>
|
<span style="margin-left: 10px;">{{Math.abs(row.price)}}</span>
|
</div>
|
</template>
|
</el-table-column>
|
<el-table-column
|
label="应收/付日期">
|
<template slot-scope="{row}">
|
<el-date-picker v-model="row.planPayDate" value-format="yyyy-MM-dd" type="date" placeholder="选择日期"></el-date-picker>
|
</template>
|
</el-table-column>
|
</el-table>
|
<div class="title">押金</div>
|
<el-table
|
:data="info.depositList"
|
border
|
style="width: 100%; margin-bottom: 15px;">
|
<el-table-column
|
prop="code"
|
label="账单编号">
|
</el-table-column>
|
<el-table-column
|
label="费用类型">
|
<template slot-scope="{row}">
|
<span v-if="row.costType === 2">租赁押金</span>
|
<span v-if="row.costType === 3">物业押金</span>
|
<span v-if="row.costType === 7">保证金</span>
|
</template>
|
</el-table-column>
|
<el-table-column
|
label="计费周期">
|
<template slot-scope="{row}">
|
{{row.startDate}} ~ {{row.endDate}}
|
</template>
|
</el-table-column>
|
<!-- prop="receivableFee"-->
|
<el-table-column
|
label="应收金额">
|
<template slot-scope="{row}">
|
0
|
</template>
|
</el-table-column>
|
<el-table-column
|
prop="actReceivableFee"
|
label="实收/付金额">
|
</el-table-column>
|
<el-table-column
|
label="应退金额">
|
<template slot-scope="{row}">
|
<div style="display: flex; align-items: center;">
|
<el-tag type="success" v-if="row.billType === 0">收</el-tag>
|
<el-tag type="warning" v-if="row.billType === 1">付</el-tag>
|
<span style="margin-left: 10px;">{{row.price}}</span>
|
</div>
|
</template>
|
</el-table-column>
|
<el-table-column
|
label="应退日期">
|
<template slot-scope="{row}">
|
<el-date-picker v-model="row.planPayDate" value-format="yyyy-MM-dd" type="date" placeholder="选择日期"></el-date-picker>
|
</template>
|
</el-table-column>
|
</el-table>
|
<div class="footer">
|
合计应收:<span>{{receivable}}</span>元, 合计应付:<span>{{meet}}</span>元
|
</div>
|
</div>
|
<!-- 创建收款账单 -->
|
<AddCollectionBill ref="addCollectionBill" @getVal="getObjS" />
|
<!-- 创建付款账单 -->
|
<AddPaymentBill ref="AddPaymentBill" @getVal="getObjS" />
|
</GlobalWindow>
|
</template>
|
|
<script>
|
import GlobalWindow from '@/components/common/GlobalWindow'
|
import BaseOpera from '@/components/base/BaseOpera'
|
import AddCollectionBill from './addCollectionBill'
|
import AddPaymentBill from './addPaymentBill'
|
import { getUserList } from '@/api/system/user'
|
import { backRent, getCanBackBill, findForBills } from '@/api/contract'
|
import { mapState } from 'vuex'
|
export default {
|
name: "terminateLease",
|
components: {
|
GlobalWindow,
|
AddCollectionBill,
|
AddPaymentBill
|
},
|
computed: {
|
...mapState(['userInfo'])
|
},
|
extends: BaseOpera,
|
data() {
|
return {
|
info: {},
|
form: {
|
id: null,
|
btType: '',
|
btDate: '',
|
btUserId: '',
|
btSignDate: '',
|
btInfo: ''
|
},
|
rules: {
|
btType: [
|
{ required: true, message: '请选择', trigger: 'blur' }
|
],
|
btDate: [
|
{ required: true, message: '请选择', trigger: 'blur' }
|
],
|
btUserId: [
|
{ required: true, message: '请选择', trigger: 'blur' }
|
],
|
signDate: [
|
{ required: true, message: '请选择', trigger: 'blur' }
|
],
|
btInfo: [
|
{ required: true, message: '请输入', trigger: 'blur' }
|
]
|
},
|
|
list: [],
|
|
agentList: [],
|
|
receivable: '',
|
meet: '',
|
|
loading: false
|
}
|
},
|
methods: {
|
open (title, info) {
|
this.title = title
|
this.info = info
|
this.form.id = info.id
|
this.form.btSignDate = this.getDay()
|
this.form.btUserId = this.userInfo.id
|
this.$nextTick(() => {
|
this.$refs.form.resetFields()
|
})
|
this.info.terminateList = []
|
this.info.depositList = []
|
this.form.btDate = this.getDay()
|
this.countData()
|
this.getUser()
|
this.changeBtDate(this.form.btDate)
|
this.visible = true
|
},
|
deleRow(index) {
|
this.info.terminateList.splice(index, 1)
|
this.countData()
|
},
|
getDayTime () {
|
const today = new Date();
|
const year = today.getFullYear();
|
const month = today.getMonth() + 1;
|
const day = today.getDate();
|
return `${year}-${month < 10 ? '0' + month : month}-${day < 10 ? '0' + day : day}`;
|
},
|
countData () {
|
const arr = [...this.info.terminateList, ...this.info.depositList]
|
let total1 = 0
|
let total2 = 0
|
arr.forEach(item => {
|
if (item.billType === 0) {
|
total1 += Math.abs(Number(item.price))
|
} else if (item.billType === 1) {
|
total2 += Math.abs(Number(item.price))
|
}
|
})
|
this.receivable = total1.toFixed(2)
|
this.meet = total2.toFixed(2)
|
},
|
getDay () {
|
const today = new Date();
|
const year = today.getFullYear();
|
const month = today.getMonth() + 1;
|
const day = today.getDate();
|
return `${year}-${month < 10 ? '0' + month : month}-${day < 10 ? '0' + day : day}`;
|
},
|
addZD () {
|
if (!this.form.btDate) return this.$message.warning('请选择退租日期')
|
this.$refs.addCollectionBill.open('创建收款账单', {
|
contractCode: this.info.code,
|
contractId: this.info.id,
|
renterName: this.info.renterName,
|
renterId: this.info.renterId,
|
billType: 0,
|
billTypeCopy: 0,
|
feeType: 0
|
}, { startDate: this.info.startDate, endDate: this.form.btDate })
|
},
|
addFK () {
|
if (!this.form.btDate) return this.$message.warning('请选择退租日期')
|
this.$refs.AddPaymentBill.open('创建付款账单', {
|
contractCode: this.info.code,
|
contractId: this.info.id,
|
renterName: this.info.renterName,
|
renterId: this.info.renterId,
|
billType: 1,
|
feeType: 0,
|
billTypeCopy: 1
|
}, { startDate: this.info.startDate, endDate: this.form.btDate })
|
},
|
changeBtDate (btDate) {
|
this.loading = true
|
findForBills({
|
id: this.info.id,
|
btDate
|
}).then(res => {
|
res.canBackRentBills.forEach(item => {
|
if ([2,3,7].includes(item.costType)) {
|
this.$set(item, 'billType', 1)
|
this.$set(item, 'price', item.actReceivableFee)
|
} else {
|
this.$set(item, 'receivableFeeCopy', item.receivableFee)
|
this.$set(item, 'receivableFee', item.needReceivableFee)
|
this.$set(item, 'price', (item.needReceivableFee - item.actReceivableFee).toFixed(2))
|
}
|
})
|
this.info.terminateList = res.canBackRentBills.filter(item => {
|
if ([0,1,4,5,6].includes(item.costType)) {
|
item.billTypeCopy = JSON.parse(JSON.stringify(item.billType))
|
if (Number(item.price) < 0) {
|
item.billType = 1
|
}
|
return item
|
}
|
})
|
this.info.depositList = res.canBackRentBills.filter(item => {
|
if ([2,3,7].includes(item.costType)) {
|
item.billTypeCopy = JSON.parse(JSON.stringify(item.billType))
|
return item
|
}
|
})
|
this.countData()
|
}).finally(() => {
|
this.loading = false
|
})
|
},
|
getObjS (obj) {
|
obj.startDate = obj.startDate.substring(0, 10)
|
obj.endDate = obj.endDate.substring(0, 10)
|
obj.isDele = true
|
this.info.terminateList.push(obj)
|
this.countData()
|
},
|
confirm () {
|
this.$refs.form.validate((valid) => {
|
if (!valid) {
|
return
|
}
|
this.isWorking = true
|
let canBackRentBills = []
|
let addBillList = []
|
this.info.terminateList.forEach(item => {
|
if (item.rowType && item.rowType === 1) {
|
addBillList.push(item)
|
} else {
|
canBackRentBills.push(item)
|
}
|
})
|
backRent({
|
...this.form,
|
canBackRentBills: [...canBackRentBills, ...this.info.depositList],
|
addBillList
|
})
|
.then(res => {
|
this.visible = false
|
this.$tip.apiSuccess('操作成功')
|
this.$emit('success')
|
})
|
.finally(() => {
|
this.isWorking = false
|
})
|
})
|
},
|
getUser () {
|
getUserList({})
|
.then(res => {
|
this.agentList = res
|
})
|
},
|
changeReceivableFee (num, row) {
|
if (Number(num) > row.receivableFeeCopy) {
|
row.receivableFee = ''
|
row.price = 0
|
this.countData()
|
this.$message.warning('不能大于原始应收付金额')
|
} else {
|
if (num) {
|
row.price = Number(num) - row.actReceivableFee
|
// 收
|
if (row.billTypeCopy === 0) {
|
if (row.price > 0) {
|
row.billType = 0
|
} else if (row.price < 0) {
|
row.billType = 1
|
} else {
|
row.billType = 0
|
}
|
} else {
|
if (row.price > 0) {
|
row.billType = 1
|
} else if (row.price < 0) {
|
row.billType = 0
|
} else {
|
row.billType = 1
|
}
|
}
|
} else {
|
row.price = 0
|
row.billType = row.billTypeCopy
|
}
|
row.price = Math.abs(row.price);
|
this.countData()
|
}
|
}
|
}
|
}
|
</script>
|
|
<style lang="scss" scoped>
|
@import '@/assets/style/variables.scss';
|
.main {
|
width: 100%;
|
.footer {
|
width: 100%;
|
display: flex;
|
align-items: center;
|
font-size: 14px;
|
color: black;
|
span {
|
font-size: 14px;
|
color: $primary-color;
|
}
|
}
|
.main_head {
|
width: 100%;
|
padding: 10px 5px;
|
box-sizing: border-box;
|
display: flex;
|
flex-direction: column;
|
border-bottom: 1px solid #ececec;
|
margin-bottom: 15px;
|
position: sticky;
|
top: 0;
|
left: 0;
|
z-index: 999;
|
background: #ffffff;
|
span {
|
color: black;
|
font-size: 16px;
|
font-weight: 500;
|
margin-bottom: 8px;
|
&:last-child {
|
margin: 0 !important;
|
}
|
}
|
}
|
.title {
|
font-weight: 500;
|
font-size: 16px;
|
color: $primary-color;
|
margin-bottom: 15px;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
span {
|
font-weight: 500;
|
font-size: 16px;
|
color: $primary-color;
|
}
|
}
|
.main_box {
|
width: 100%;
|
display: flex;
|
align-items: start;
|
margin-bottom: 15px;
|
justify-content: space-between;
|
.main_box_form {
|
flex: 1;
|
margin-right: 20px;
|
}
|
.main_box_list {
|
width: 500px;
|
flex-shrink: 0;
|
.main_box_list_title {
|
font-size: 16px;
|
font-weight: 500;
|
color: $primary-color;
|
margin-bottom: 15px;
|
}
|
}
|
}
|
}
|
</style>
|