444 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			444 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| <template>
 | |
|   <section class="buildingStatistics">
 | |
|     <ai-title v-if="!isFormDv" title="楼栋统计" isShowBack isShowBottomBorder @onBackClick="$router.push({query:{}}),$parent.info={},$parent.isShowInfo=false,$parent.house=null,$parent.chooseBuildId='',$parent.showStatistics=false, $parent.type='0'"/>
 | |
|     <div class="buildingPane">
 | |
|       <div class="bgItem tree"/>
 | |
|         <div class="building">
 | |
|           <template v-if="floorRooms.length>0">
 | |
|             <div class="buildingSignboard">{{ `${currentBuilding.buildingNumber}栋 ${unitNumber}单元` }}
 | |
|             </div>
 | |
|             <el-scrollbar class="floors">
 | |
|               <div class="floor" v-for="(fl,j) in floorRooms" :key="j">
 | |
|                 <div class="room" v-for="(op,i) in fl" :key="op.id" @click="handleSelectRoom(op,$event)" @touchstart="handleSelectRoom(op,$event)" :class="[{none:op.livingNumber==0,selected:selected.houseCode==op.houseCode},handleTipsHighlight(op.tips)]">
 | |
|                   {{ op.houseCode }}
 | |
|                   <div v-if="op.livingNumber==0">无人</div>
 | |
|                   <div v-show="op.id==selected.id" class="detail" @click.stop :style="{left:position.x,top:position.y}">
 | |
|                     <el-row class="popupHeader" type="flex" justify="space-between" align="middle">
 | |
|                       <span>{{selected.houseCode}}详情</span>
 | |
|                       <ai-icon icon="iconClean" @click.native.stop="selected={}"/>
 | |
|                     </el-row>
 | |
|                     <div class="family-member">
 | |
|                       <h2>房主信息</h2>
 | |
|                       <div v-for="(item,index) in selected.owner" :key="item.id">
 | |
|                         <div class="family-member__item">
 | |
|                           <div class="member-left">
 | |
|                             <label>{{item.name}}</label>
 | |
|                           </div>
 | |
|                           <span style="color: #2266FF">{{root.dict.getLabel("houseLivingType",item.livingType)}}</span>
 | |
|                         </div>
 | |
|                         <div class="family-member__item">
 | |
|                           <div class="member-left">
 | |
|                             <label>联系方式</label>
 | |
|                           </div>
 | |
|                           <span style="color: #2266FF;">{{item.phone}}</span>
 | |
|                         </div>
 | |
|                       </div>
 | |
| 
 | |
|                       <h2>承租人信息</h2>
 | |
|                       <div v-for="(item,index) in selected.renter" :key="item.id">
 | |
|                         <div class="family-member__item" >
 | |
|                           <div class="member-left">
 | |
|                             <label>{{item.name}}</label>
 | |
|                           </div>
 | |
|                           <span style="color: #2266FF">{{root.dict.getLabel("houseLivingType",item.livingType)}}</span>
 | |
|                         </div>
 | |
|                         <div class="family-member__item">
 | |
|                           <div class="member-left">
 | |
|                             <label>联系方式</label>
 | |
|                           </div>
 | |
|                           <span>{{item.phone}}</span>
 | |
|                         </div>
 | |
|                       </div>
 | |
| 
 | |
|                       <h2>实际居住人员</h2>
 | |
|                       <div v-for="(item,index) in selected.live" :key="item.id">
 | |
|                         <div class="family-member__item">
 | |
|                           <div class="member-left">
 | |
|                             <label>{{item.name}}</label>
 | |
|                           </div>
 | |
|                           <span>{{root.dict.getLabel("householdRelation",item.relation)}}</span>
 | |
|                         </div>
 | |
|                       </div>
 | |
|                     </div>
 | |
|                   </div>
 | |
|                 </div>
 | |
|               </div>
 | |
|             </el-scrollbar>
 | |
|           </template>
 | |
|           <ai-empty v-else>请在【<b>小区总览</b>】中选取【楼栋单元】</ai-empty>
 | |
|           <div class="bottom"/>
 | |
|         </div>
 | |
|       <building-tool-bar></building-tool-bar>
 | |
|     </div>
 | |
|   </section>
 | |
| </template>
 | |
| 
 | |
| <script>
 | |
| import BuildingToolBar from "./buildingToolBar";
 | |
| 
 | |
| export default {
 | |
|   name: "buildingStatistics",
 | |
|   components: {BuildingToolBar},
 | |
|   inject: ['root'],
 | |
|   provide() {
 | |
|     return {
 | |
|       sta: this
 | |
|     }
 | |
|   },
 | |
|   props: {
 | |
|     instance: Function,
 | |
|     dict: Object,
 | |
|     isFormDv: Boolean,
 | |
|     query: Object
 | |
|   },
 | |
|   data() {
 | |
|     return {
 | |
|       rooms: [],
 | |
|       selected: {},
 | |
|       currentBuilding: {},
 | |
|       unitNumber:1,
 | |
|       tips: [],
 | |
|       position:{
 | |
|         x:"",
 | |
|         y:""
 | |
|       },
 | |
|     }
 | |
|   },
 | |
|   computed: {
 | |
|     floorRooms() {
 | |
|       let obj = {}
 | |
|       this.rooms.map(e => {
 | |
|         e.none = e.isNone == 0
 | |
|         return obj[e.layerNumber]?.push(e) || (obj[e.layerNumber] = [e])
 | |
|       })
 | |
|       return Object.values(obj).reverse()
 | |
|     }
 | |
|   },
 | |
|   created() {
 | |
|     this.dict.load('householdRelation', 'residentTipType',"houseLivingType")
 | |
|     if (this.isFormDv && this.query.buildingId) {
 | |
|       this.getRoomsByBuilding(this.query.buildingId, this.query.unitNum)
 | |
|       this.currentBuilding = { buildingNumber: this.query.buildingNumber}
 | |
|       this.unitNumber = this.query.unitNum
 | |
| 
 | |
|       return false
 | |
|     }
 | |
|     this.getRoomsByBuilding(this.$route.query?.buildingId,this.$route.query?.unitNum)
 | |
|     this.currentBuilding = {buildingNumber: this.$route.query?.buildingNumber};
 | |
|     this.unitNumber = this.$route.query?.unitNum;
 | |
|   },
 | |
|   methods: {
 | |
|     handleSelectRoom(room, e) {
 | |
|       console.log(e)
 | |
|       if (room.livingNumber>0) {
 | |
|         this.$nextTick(()=>{
 | |
|           this.position.x = e.pageX + 40 + "px"
 | |
|           this.position.y = e.pageY + "px"
 | |
|           this.selected = room;
 | |
|           this.$forceUpdate()
 | |
|         })
 | |
|         // this.getRoomDetail(room.id)
 | |
|       }
 | |
|     },
 | |
|     selectedBuilding(building,unitNumber) {
 | |
|       this.selected = {}
 | |
|       this.tips = []
 | |
|       this.$router.push({query: {...this.$route.query, buildingId: building.id,unitNum:unitNumber}}).catch(e=>{e})
 | |
|       this.currentBuilding = building
 | |
|       this.unitNumber = unitNumber
 | |
|       this.getRoomsByBuilding(building.id,unitNumber)
 | |
|     },
 | |
|     getRoomsByBuilding(buildingId,unitNumber) {
 | |
|       this.root.instance.post("/app/appcommunityhouseinfo/list", null, {
 | |
|         params: {
 | |
|           unitNumber,
 | |
|           buildingId,
 | |
|           size: 999
 | |
|         }
 | |
|       }).then(res => {
 | |
|         if (res?.data) {
 | |
|           this.rooms = res.data.records
 | |
|         }
 | |
|       })
 | |
|     },
 | |
|     getRoomDetail(id) {
 | |
|       return this.root.instance.post("/app/appcommunityhouseinfo/queryDetailById", null, {
 | |
|         params: {id}
 | |
|       }).then(res => {
 | |
|         if (res?.data) {
 | |
|           let {residents} = res.data
 | |
|           this.selected = {
 | |
|             ...this.selected, ...res.data,
 | |
|             residents: residents.map(e => {
 | |
|               let {tips} = e
 | |
|               //显示为户主
 | |
|               let relationLabel = e.householdName == 1 ? "户主" : this.root.dict.getLabel("householdRelation", e.householdRelation)
 | |
|               return {...e, tips: tips ? tips.split("|") : [], relationLabel}
 | |
|             }
 | |
|             )
 | |
|           }
 | |
|         }
 | |
|       })
 | |
|     },
 | |
|     handleTipsHighlight(tip) {
 | |
|       let flag = this.tips.length > 0 && !this.tips.some(t => tip?.split("|").includes(t))
 | |
|       return flag ? 'tipsHighlight' : ''
 | |
|     },
 | |
|     selectedTips(tips) {
 | |
|       this.tips = tips
 | |
|     }
 | |
|   }
 | |
| }
 | |
| </script>
 | |
| 
 | |
| <style lang="scss" scoped>
 | |
| .buildingStatistics {
 | |
|   height: 100%;
 | |
|   display: flex;
 | |
|   flex-direction: column;
 | |
| 
 | |
|   ::v-deep .ailist-title{
 | |
|     margin: 0 20px;
 | |
|   }
 | |
| 
 | |
|   .family-member {
 | |
|     & > h2 {
 | |
|       height: 32px;
 | |
|       line-height: 32px;
 | |
|       margin: 0;
 | |
|       padding: 0 12px;
 | |
|       color: #333333;
 | |
|       font-size: 12px;
 | |
|       font-weight: 700;
 | |
|       text-align: left;
 | |
|       background: #E3E8F1;
 | |
|     }
 | |
| 
 | |
|     .family-member__item {
 | |
|       display: flex;
 | |
|       align-items: center;
 | |
|       justify-content: space-between;
 | |
|       height: 32px;
 | |
|       padding: 0 12px;
 | |
|       background: #F3F6F9;
 | |
| 
 | |
|       .member-left {
 | |
|         display: flex;
 | |
|         align-items: center;
 | |
|         gap: 4px;
 | |
|       }
 | |
| 
 | |
|       &:nth-of-type(2n) {
 | |
|         background: #fff;
 | |
|       }
 | |
| 
 | |
|       label {
 | |
|         font-weight: normal !important;
 | |
|         color: #333;
 | |
|         font-size: 12px;
 | |
|       }
 | |
| 
 | |
|       & > span {
 | |
|         color: #666666;
 | |
|         font-size: 12px;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     &:last-child {
 | |
|       label {
 | |
|         color: #666666;
 | |
|         font-weight: normal !important;
 | |
|         font-size: 12px;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   .buildingPane {
 | |
|     background-image: url("https://cdn.cunwuyun.cn/buildSta/cloud.png"), linear-gradient(3deg, #FFFFFF 0%, #3093FF 100%);
 | |
|     background-repeat: no-repeat;
 | |
|     background-position: 227px 43px, 100%;
 | |
|     background-size: 788px 112px, 100%;
 | |
|     position: relative;
 | |
|     box-sizing: border-box;
 | |
|     padding-right: 400px;
 | |
|     flex: 1;
 | |
|     min-height: 0;
 | |
|     display: flex;
 | |
|     flex-direction: column;
 | |
|     justify-content: flex-end;
 | |
|     align-items: flex-start;
 | |
| 
 | |
|     .bgItem {
 | |
|       position: absolute;
 | |
|       background-repeat: no-repeat;
 | |
|       pointer-events: none;
 | |
| 
 | |
|       &.tree {
 | |
|         left: calc(50% - 200px);
 | |
|         transform: translateX(-50%);
 | |
|         bottom: 0;
 | |
|         width: 580px;
 | |
|         height: 71px;
 | |
|         background-image: url("https://cdn.cunwuyun.cn/buildSta/tree.png");
 | |
|         z-index: 3;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     .building {
 | |
|       margin-left: 60px;
 | |
|       flex-shrink: 0;
 | |
|       height: auto;
 | |
|       width: auto;
 | |
|       box-sizing: border-box;
 | |
|       padding: 136px 0 0;
 | |
|       background-image: url("https://cdn.cunwuyun.cn/buildSta/roof.png"),
 | |
|       url("https://cdn.cunwuyun.cn/buildSta/chimney.png");
 | |
|       background-position: 0 121px, 70px 91px;
 | |
|       background-size: 100% 105px, 70px;
 | |
|       background-repeat: no-repeat;
 | |
|       display: flex;
 | |
|       flex-direction: column;
 | |
|       justify-content: flex-end;
 | |
|       align-items: center;
 | |
|       border-bottom: 10px solid #E9C28E;
 | |
| 
 | |
|       .buildingSignboard {
 | |
|         padding-top: 41px;
 | |
|         width: 200px;
 | |
|         height: 65px;
 | |
|         text-align: center;
 | |
|         background-image: url("https://cdn.cunwuyun.cn/buildSta/buildingSignboard.png");
 | |
|         background-repeat: no-repeat;
 | |
|         box-sizing: border-box;
 | |
|         font-size: 12px;
 | |
|         font-weight: bold;
 | |
|         color: #1D3296;
 | |
|         margin-bottom: 15px;
 | |
|       }
 | |
| 
 | |
|       .ai-empty {
 | |
|         background: #FFECD9;
 | |
|         margin: 90px 20px 0;
 | |
|         padding: 0 10px 90px;
 | |
|         font-size: 14px;
 | |
|         color: #666;
 | |
| 
 | |
|         b {
 | |
|           color: #26f
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       .bottom {
 | |
|         background: #FFECD9;
 | |
|         height: 50px;
 | |
|         width: calc(100% - 40px);
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     ::v-deep .floors {
 | |
|       max-height: 520px;
 | |
| 
 | |
|       .el-scrollbar__wrap {
 | |
|         overflow-x: hidden;
 | |
|         margin-bottom: 0 !important;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     .floor {
 | |
|       margin: 0 20px;
 | |
|       height: 105px;
 | |
|       flex-shrink: 0;
 | |
|       max-width: calc(100% - 40px);
 | |
|       display: flex;
 | |
|       align-items: center;
 | |
|       background-image: url("https://cdn.cunwuyun.cn/buildSta/floor.png");
 | |
|       background-size: 100% 105px;
 | |
|       padding: 0 30px;
 | |
|       box-sizing: border-box;
 | |
|       gap: 20px;
 | |
| 
 | |
|       .room {
 | |
|         width: 60px;
 | |
|         height: 72px;
 | |
|         background-image: url("https://cdn.cunwuyun.cn/buildSta/room.png");
 | |
|         text-align: center;
 | |
|         padding-top: 20px;
 | |
|         box-sizing: border-box;
 | |
|         font-size: 14px;
 | |
|         font-weight: bold;
 | |
|         color: #FFFFFF;
 | |
|         cursor: pointer;
 | |
|         position: relative;
 | |
| 
 | |
|         .detail {
 | |
|           position: fixed;
 | |
|           width: 320px;
 | |
|           background: #fff;
 | |
|           box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.1);
 | |
|           border-radius: 4px;
 | |
|           overflow: hidden;
 | |
|           display: flex;
 | |
|           flex-direction: column;
 | |
|           z-index: 11;
 | |
|           transform: translateY(-100%);
 | |
| 
 | |
|           .popupHeader {
 | |
|             background: #D42222;
 | |
|             padding: 0 12px;
 | |
|             height: 32px;
 | |
| 
 | |
|             .AiIcon {
 | |
|               width: 16px;
 | |
|               height: 16px;
 | |
|             }
 | |
|           }
 | |
| 
 | |
|           li {
 | |
|             list-style-type: none;
 | |
|             display: flex;
 | |
|             justify-content: space-between;
 | |
|             align-items: center;
 | |
|             padding: 0 12px;
 | |
|             font-size: 12px;
 | |
|             color: #333;
 | |
|             height: 32px;
 | |
| 
 | |
|             & > div {
 | |
| 
 | |
|             }
 | |
| 
 | |
|             &.title {
 | |
|               background: #E3E8F1;
 | |
|             }
 | |
| 
 | |
|             &.stretch {
 | |
|               background: #F3F6F9;
 | |
|             }
 | |
|           }
 | |
|         }
 | |
| 
 | |
|         &.none {
 | |
|           cursor: not-allowed;
 | |
|           color: #f46;
 | |
|           background-image: url("https://cdn.cunwuyun.cn/buildSta/roomNone.png");
 | |
|         }
 | |
| 
 | |
|         &.selected {
 | |
|           background-image: url("https://cdn.cunwuyun.cn/buildSta/roomSelected.png");
 | |
|         }
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     .buildingToolBar {
 | |
|       position: absolute;
 | |
|       right: 20px;
 | |
|       top: 20px;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   .tipsHighlight {
 | |
|     opacity: 0.6;
 | |
|   }
 | |
| }
 | |
| </style>
 |