| <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.code}} | 
|                             </template> | 
|                         </el-table-column> | 
|                         <el-table-column label="租赁面积(㎡)" show-overflow-tooltip> | 
|                             <template slot-scope="{row}"> | 
|                                 {{row.area}}㎡ | 
|                             </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 | 
|                     label="费用类型"> | 
|                     <template slot-scope="{row}"> | 
|                         <span v-if="row.costType === 0">租赁费</span> | 
|                         <span v-if="row.costType === 1">物业费</span> | 
|                         <span v-if="row.costType === 4">水电费</span> | 
|                         <span v-if="row.costType === 5">杂项费</span> | 
|                         <span v-if="row.costType === 6">其他</span> | 
|                     </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="width: 90px;"></el-input> | 
|                             <span style="margin: 0 10px;">/</span> | 
|                             {{row.receivableFeeCopy}} | 
|                         </div> | 
|                     </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="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> | 
|                 <el-table-column | 
|                     prop="receivableFee" | 
|                     label="应收金额"> | 
|                 </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 } 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 | 
|       } | 
|     }, | 
|     watch: { | 
|       // info: { | 
|       //   deep: true, | 
|       //   immediate: true, | 
|       //   handler(news, olds) { | 
|       //     const arr = [...this.info.terminateList, ...this.info.depositList] | 
|       //     let total1 = 0 | 
|       //     let total2 = 0 | 
|       //     arr.forEach(item => { | 
|       //       if (item.billType === 0) { | 
|       //         total1 += Number(item.price) | 
|       //       } else if (item.billType === 1) { | 
|       //         total2 += Number(item.price) | 
|       //       } | 
|       //     }) | 
|       //     this.receivable = total1 | 
|       //     this.meet = total2 | 
|       //   } | 
|       // } | 
|     }, | 
|     methods: { | 
|       open (title, info) { | 
|         this.title = title | 
|         this.info = info | 
|         this.form.id = info.id | 
|         this.form.btSignDate = this.getDay() | 
|         console.log(this.userInfo) | 
|         this.form.btUserId = this.userInfo.id | 
|         this.$nextTick(() => { | 
|           this.$refs.form.resetFields() | 
|         }) | 
|         this.info.canBackRentBills.forEach(item => { | 
|           this.$set(item, 'receivableFeeCopy', item.receivableFee) | 
|           this.$set(item, 'receivableFee', item.needReceivableFee) | 
|           if ([2,3,7].includes(item.costType)) { | 
|             this.$set(item, 'billType', 1) | 
|             this.$set(item, 'price', item.actReceivableFee) | 
|           } else { | 
|             this.$set(item, 'price', item.needReceivableFee) | 
|           } | 
|         }) | 
|         this.info.terminateList = this.info.canBackRentBills.filter(item => { | 
|           if ([0,1,4,5,6].includes(item.costType)) { | 
|             item.billTypeCopy = JSON.parse(JSON.stringify(item.billType)) | 
|             return item | 
|           } | 
|         }) | 
|         this.info.depositList = this.info.canBackRentBills.filter(item => { | 
|           if ([2,3,7].includes(item.costType)) { | 
|             item.billTypeCopy = JSON.parse(JSON.stringify(item.billType)) | 
|             return item | 
|           } | 
|         }) | 
|         this.countData() | 
|         this.getUser() | 
|         this.visible = true | 
|       }, | 
|       countData () { | 
|         const arr = [...this.info.terminateList, ...this.info.depositList] | 
|         let total1 = 0 | 
|         let total2 = 0 | 
|         arr.forEach(item => { | 
|           if (item.billType === 0) { | 
|             total1 += Number(item.price) | 
|           } else if (item.billType === 1) { | 
|             total2 += Number(item.price) | 
|           } | 
|         }) | 
|         this.receivable = total1 | 
|         this.meet = total2 | 
|       }, | 
|       getDay () { | 
|         const today = new Date(); | 
|         const year = today.getFullYear(); | 
|         const month = today.getMonth() + 1; // 月份是从 0 开始的,因此需要加 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 (planPayDateEnd) { | 
|         this.loading = true | 
|         getCanBackBill({ | 
|           contractId: this.info.id, | 
|           planPayDateEnd | 
|         }).then(res => { | 
|           res.forEach(item => { | 
|             this.$set(item, 'receivableFeeCopy', item.receivableFee) | 
|             this.$set(item, 'receivableFee', item.needReceivableFee) | 
|             this.$set(item, 'price', item.needReceivableFee) | 
|           }) | 
|           this.info.terminateList = res.filter(item => { | 
|             if ([0,1,4,5,6].includes(item.costType)) { | 
|               item.billTypeCopy = JSON.parse(JSON.stringify(item.billType)) | 
|               return item | 
|             } | 
|           }) | 
|           this.countData() | 
|         }).finally(() => { | 
|           this.loading = false | 
|         }) | 
|       }, | 
|       getObjS (obj) { | 
|         this.info.terminateList.push(obj) | 
|         // this.info.terminateList.forEach(item => { | 
|         //   item.receivableFee = Number(item.receivableFee) + 1 | 
|         //   item.receivableFee = Number(item.receivableFee) - 1 | 
|         // }) | 
|         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; | 
|             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> |