<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" 
 | 
                                :picker-options="pickerOptions" 
 | 
                                @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: [], 
 | 
        pickerOptions: {}, 
 | 
        agentList: [], 
 | 
  
 | 
        receivable: '', 
 | 
        meet: '', 
 | 
         
 | 
        loading: false 
 | 
      } 
 | 
    }, 
 | 
    methods: { 
 | 
      open (title, info) { 
 | 
        this.title = title 
 | 
        this.info = info 
 | 
        this.pickerOptions = { 
 | 
          disabledDate(time) { 
 | 
            // 如果没有后面的 -8.64e7 就是不可以选择今天的 
 | 
            const beginDate = new Date(info.startDate).getTime() - 8.64e7 
 | 
            const endDate = new Date(info.endDate).getTime() 
 | 
            return beginDate > time.getTime() || endDate < time.getTime() 
 | 
          } 
 | 
        } 
 | 
        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> 
 |