目录代码整合
This commit is contained in:
		
							
								
								
									
										68
									
								
								packages/grid/AppBuildManage/AppBuildManage.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								packages/grid/AppBuildManage/AppBuildManage.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,68 @@ | ||||
| <template> | ||||
|   <div class="AppBuildManage"> | ||||
|     <keep-alive :include="['List']"> | ||||
|       <component ref="component" :is="component" @change="onChange" :params="params" :instance="instance" :dict="dict"></component> | ||||
|     </keep-alive> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import List from './components/List' | ||||
| import Add from './components/Add' | ||||
| import BuildMsg from './components/BuildMsg' | ||||
|  | ||||
| export default { | ||||
|   label: '楼栋管理', | ||||
|   name: 'AppBuildManage', | ||||
|   props: { | ||||
|     instance: Function, | ||||
|     dict: Object, | ||||
|   }, | ||||
|  | ||||
|   data() { | ||||
|     return { | ||||
|       component: 'List', | ||||
|       params: {}, | ||||
|       include: [], | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   components: { | ||||
|     Add, | ||||
|     List, | ||||
|     BuildMsg, | ||||
|   }, | ||||
|   methods: { | ||||
|     onChange(data) { | ||||
|       if (data.type === 'add') { | ||||
|         this.component = 'Add' | ||||
|         this.params = data.params | ||||
|       } | ||||
|  | ||||
|       if (data.type === 'buildmsg') { | ||||
|         this.component = 'BuildMsg' | ||||
|         this.params = { ...data.params } | ||||
|       } | ||||
|  | ||||
|       if (data.type == 'list') { | ||||
|         this.component = 'List' | ||||
|         this.params = data.params | ||||
|  | ||||
|         this.$nextTick(() => { | ||||
|           if (data.isRefresh) { | ||||
|             this.$refs.component.getList() | ||||
|           } | ||||
|         }) | ||||
|       } | ||||
|     }, | ||||
|   }, | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss"> | ||||
| .AppBuildManage { | ||||
|   height: 100%; | ||||
|   background: #f3f6f9; | ||||
|   overflow: auto; | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										402
									
								
								packages/grid/AppBuildManage/components/Add.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										402
									
								
								packages/grid/AppBuildManage/components/Add.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,402 @@ | ||||
| <template> | ||||
|   <section style="height: 100%" class="AppBuildManage"> | ||||
|     <ai-detail class="Add"> | ||||
|       <!-- 返回按钮 --> | ||||
|       <template #title> | ||||
|         <ai-title :title="isEdit ? '编辑楼栋信息' : '添加楼栋'" isShowBack isShowBottomBorder @onBackClick="cancel(false)"></ai-title> | ||||
|       </template> | ||||
|  | ||||
|       <template #content> | ||||
|         <el-form :model="formData" :rules="formRules" ref="ruleForm" label-width="150px" label-suffix=":" align-items="center"> | ||||
|           <!-- 小区名称 --> | ||||
|           <ai-bar title="基础信息"></ai-bar> | ||||
|           <el-form-item label="小区名称" prop="communityName" class="line" ref="communityNameContent"> | ||||
|             <!-- 选择小区 --> | ||||
|             <ai-select v-if="instance" :instance="instance" v-model="formData.communityId" action="/app/appcommunityinfo/listAll" :prop="{ label: 'communityName' }"></ai-select> | ||||
|           </el-form-item> | ||||
|  | ||||
|           <div class="flex"> | ||||
|             <!-- 楼栋号 --> | ||||
|             <el-form-item label="楼栋号" prop="buildingNumber" :rules="[{ required: true, message: '请输入楼栋号', trigger: 'blur' }]"> | ||||
|               <el-input size="small" v-model="formData.buildingNumber" placeholder="请输入" clearable :disabled="isEdit" /> | ||||
|             </el-form-item> | ||||
|  | ||||
|             <!-- 单元数 --> | ||||
|             <el-form-item label="单元数" prop="unitNumber"> | ||||
|               <el-input size="small" v-model.number="formData.unitNumber" placeholder="请输入" clearable :disabled="isEdit" /> | ||||
|             </el-form-item> | ||||
|  | ||||
|             <!-- 起始计数层数 --> | ||||
|             <el-form-item label="起始计数层数" prop="layerStart"> | ||||
|               <el-input size="small" v-model.number="formData.layerStart" placeholder="请输入" clearable :disabled="isEdit"></el-input> | ||||
|             </el-form-item> | ||||
|  | ||||
|             <!-- 最高层数 --> | ||||
|             <el-form-item label="最高层数" prop="layerNumber"> | ||||
|               <el-input size="small" v-model.number="formData.layerNumber" placeholder="请输入" clearable :disabled="isEdit"></el-input> | ||||
|             </el-form-item> | ||||
|  | ||||
|             <!-- 起始计数户数 --> | ||||
|             <el-form-item label="起始计数户数" prop="householdStart"> | ||||
|               <el-input size="small" v-model.number="formData.householdStart" placeholder="请输入" clearable :disabled="isEdit"></el-input> | ||||
|             </el-form-item> | ||||
|  | ||||
|             <!-- 每层户数 --> | ||||
|             <el-form-item label="每层户数" prop="householdNumber"> | ||||
|               <el-input size="small" v-model.number="formData.householdNumber" placeholder="请输入" clearable :disabled="isEdit"></el-input> | ||||
|             </el-form-item> | ||||
|  | ||||
|             <!-- 楼栋长姓名 --> | ||||
|             <el-form-item label="楼栋长姓名" prop="managerName"> | ||||
|               <el-input size="small" v-model="formData.managerName" placeholder="请输入" clearable></el-input> | ||||
|             </el-form-item> | ||||
|  | ||||
|             <!-- 楼栋长联系方式 --> | ||||
|             <el-form-item label="楼栋长联系方式" prop="managerPhone"> | ||||
|               <el-input size="small" v-model.number="formData.managerPhone" placeholder="请输入" clearable></el-input> | ||||
|             </el-form-item> | ||||
|  | ||||
|             <!-- 房屋类别 --> | ||||
|             <el-form-item label="房屋类别" prop="buildingType" class="buildingTypes"> | ||||
|               <el-radio-group v-model="formData.buildingType"> | ||||
|                 <el-radio label="0">单元(公寓)楼</el-radio> | ||||
|                 <el-radio label="1">筒子楼</el-radio> | ||||
|                 <el-radio label="2">别墅</el-radio> | ||||
|  | ||||
|                 <el-radio label="3">自建楼</el-radio> | ||||
|                 <el-radio label="4">平房</el-radio> | ||||
|                 <el-radio label="5">高层公共建筑</el-radio> | ||||
|  | ||||
|                 <el-radio label="6">商住两用</el-radio> | ||||
|                 <el-radio label="7">其它</el-radio> | ||||
|               </el-radio-group> | ||||
|             </el-form-item> | ||||
|  | ||||
|             <!-- 楼栋经度坐标 --> | ||||
|             <el-form-item label="楼栋经度坐标" prop="lng"> | ||||
|               <el-input size="small" v-model="formData.lng" placeholder="请输入" clearable></el-input> | ||||
|             </el-form-item> | ||||
|  | ||||
|             <!-- 楼栋纬度坐标 --> | ||||
|             <el-form-item label="楼栋纬度坐标" prop="lat"> | ||||
|               <el-input size="small" v-model="formData.lat" placeholder="请输入" clearable></el-input> | ||||
|             </el-form-item> | ||||
|  | ||||
|             <!-- 地图位置 --> | ||||
|             <el-form-item label="地图位置" prop="lat"> | ||||
|               <el-button @click="showMap = true">地图标绘</el-button> | ||||
|             </el-form-item> | ||||
|           </div> | ||||
|         </el-form> | ||||
|       </template> | ||||
|  | ||||
|       <!-- 底部按钮 --> | ||||
|       <template #footer> | ||||
|         <el-button @click="cancel">取消</el-button> | ||||
|         <el-button type="primary" @click="confirm()">提交</el-button> | ||||
|       </template> | ||||
|     </ai-detail> | ||||
|     <ai-dialog title="地图" :visible.sync="showMap" @opened="getCorpLocation" width="800px" class="mapDialog" @onConfirm="selectMap"> | ||||
|       <div id="map"></div> | ||||
|       <el-form label-width="80px" style="padding: 10px 20px 0 20px;"> | ||||
|         <el-row type="flex" justify="space-between"> | ||||
|           <el-form-item label="经度"> | ||||
|             <el-input disabled size="small" v-model="placeDetail.lng"></el-input> | ||||
|           </el-form-item> | ||||
|           <el-form-item label="纬度"> | ||||
|             <el-input disabled size="small" v-model="placeDetail.lat"></el-input> | ||||
|           </el-form-item> | ||||
|         </el-row> | ||||
|       </el-form> | ||||
|       <el-input id="searchPlaceInput" size="medium" class="searchPlaceInput" clearable v-model="searchPlace" autocomplete="on" @change="placeSearch.search(searchPlace)" placeholder="请输入关键字"> | ||||
|         <el-button type="primary" slot="append" @click="placeSearch.search(searchPlace)">搜索</el-button> | ||||
|       </el-input> | ||||
|       <div id="searchPlaceOutput" /> | ||||
|     </ai-dialog> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import { mapState } from 'vuex' | ||||
| import AMapLoader from '@amap/amap-jsapi-loader' | ||||
|  | ||||
| export default { | ||||
|   name: 'Add', | ||||
|   components: {}, | ||||
|   props: { | ||||
|     dict: Object, | ||||
|     params: Object, | ||||
|     instance: Function, | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       formData: { | ||||
|         communityName: '', | ||||
|         buildingNumber: '', | ||||
|         unitNumber: '', | ||||
|         layerStart: '1', | ||||
|         layerNumber: '', | ||||
|         householdStart: '1', | ||||
|         householdNumber: '', | ||||
|         managerName: '', | ||||
|         managerPhone: '', | ||||
|         lng: '', | ||||
|         lat: '', | ||||
|         id: '', // 小区编号 | ||||
|         buildingType: '0', | ||||
|         communityId: '', | ||||
|       }, | ||||
|       formRules: { | ||||
|         unitNumber: [ | ||||
|           { required: true, message: '请输入单元数', trigger: 'change' }, | ||||
|           { | ||||
|             validator: (r, v, cb) => (!v || /^[1-9]\d*|0$/g.test(v) ? cb() : cb('请输入正整数')), | ||||
|           }, | ||||
|         ], | ||||
|         layerStart: [ | ||||
|           { required: true, message: '请输入起始计数层数', trigger: 'change' }, | ||||
|           { | ||||
|             validator: (r, v, cb) => (!v || /^[1-9]\d*|0$/g.test(v) ? cb() : cb('请输入正整数')), | ||||
|           }, | ||||
|         ], | ||||
|  | ||||
|         layerNumber: [ | ||||
|           { required: true, message: '请输入最高层数', trigger: 'change' }, | ||||
|           { | ||||
|             validator: (r, v, cb) => (!v || /^[1-9]\d*|0$/g.test(v) ? cb() : cb('请输入正整数')), | ||||
|           }, | ||||
|         ], | ||||
|         householdStart: [ | ||||
|           { required: true, message: '请输入起始计数户数', trigger: 'change' }, | ||||
|           { | ||||
|             validator: (r, v, cb) => (!v || /^[1-9]\d*|0$/g.test(v) ? cb() : cb('请输入正整数')), | ||||
|           }, | ||||
|         ], | ||||
|  | ||||
|         householdNumber: [ | ||||
|           { required: true, message: '请输入每层户数', trigger: 'change' }, | ||||
|           { | ||||
|             validator: (r, v, cb) => (!v || /^[1-9]\d*|0$/g.test(v) ? cb() : cb('请输入正整数')), | ||||
|           }, | ||||
|         ], | ||||
|       }, | ||||
|       plot: [], | ||||
|       dialogVisible: false, | ||||
|       treeData: [], | ||||
|       map: null, | ||||
|       placeDetail: { | ||||
|         lng: '', | ||||
|         lat: '', | ||||
|       }, | ||||
|       showMap: false, | ||||
|       searchPlace: '', | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
|     ...mapState(['user']), | ||||
|  | ||||
|     isEdit() { | ||||
|       return !!this.params.id | ||||
|     }, | ||||
|   }, | ||||
|   created() { | ||||
|     this.formData.communityId = this.params.communityId | ||||
|     this.getListinfo() | ||||
|   }, | ||||
|   methods: { | ||||
|     selectMap() { | ||||
|       this.formData.lng = this.placeDetail.lng | ||||
|       this.formData.lat = this.placeDetail.lat | ||||
|       this.showMap = false | ||||
|     }, | ||||
|     getCorpLocation() { | ||||
|       this.instance.post('/app/appdvcpconfig/getCorpLocation').then((res) => { | ||||
|         if (res.code == 0) { | ||||
|           this.initMap(res.data) | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     initMap({ lng, lat }) { | ||||
|       AMapLoader.load({ | ||||
|         key: 'b553334ba34f7ac3cd09df9bc8b539dc', | ||||
|         version: '2.0', | ||||
|         plugins: ['AMap.PlaceSearch', 'AMap.AutoComplete', 'AMap.Geocoder'], | ||||
|       }).then((AMap) => { | ||||
|         this.placeDetail.lng = this.formData.lng | ||||
|         this.placeDetail.lat = this.formData.lat | ||||
|         this.map = new AMap.Map('map', { | ||||
|           resizeEnable: true, | ||||
|           zooms: [6, 20], | ||||
|           center: [lng, lat], | ||||
|           zoom: 11, | ||||
|         }) | ||||
|         this.placeSearch = new AMap.PlaceSearch({ map: this.map }) | ||||
|         new AMap.AutoComplete({ | ||||
|           input: 'searchPlaceInput', | ||||
|           output: 'searchPlaceOutput', | ||||
|         }).on('select', (e) => { | ||||
|           if (e?.poi) { | ||||
|             this.placeSearch.setCity(e.poi.adcode) | ||||
|             this.movePosition(e.poi.location) | ||||
|           } | ||||
|         }) | ||||
|         this.map.on('click', (e) => { | ||||
|           new AMap.Geocoder().getAddress(e.lnglat, (sta, res) => { | ||||
|             if (res?.regeocode) { | ||||
|               this.placeDetail = { | ||||
|                 lng: e.lnglat?.lng, | ||||
|                 lat: e.lnglat?.lat, | ||||
|                 address: res.regeocode.formattedAddress, | ||||
|               } | ||||
|             } | ||||
|           }) | ||||
|           this.movePosition(e.lnglat) | ||||
|         }) | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     movePosition(center) { | ||||
|       if (this.map) { | ||||
|         this.map.clearMap() | ||||
|         this.map.panTo(center) | ||||
|         this.map.add([ | ||||
|           new AMap.Marker({ | ||||
|             position: center, | ||||
|             clickable: true, | ||||
|           }), | ||||
|         ]) | ||||
|         this.map.setFitView() | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     getListinfo() { | ||||
|       return this.instance | ||||
|         .post('/app/appcommunitybuildinginfo/queryDetailById', null, { | ||||
|           params: { | ||||
|             id: this.params.id, | ||||
|           }, | ||||
|         }) | ||||
|         .then((res) => { | ||||
|           if (res.data) { | ||||
|             this.formData = res.data | ||||
|           } | ||||
|         }) | ||||
|     }, | ||||
|  | ||||
|     confirm() { | ||||
|       this.$refs['ruleForm'].validate((valid) => { | ||||
|         if (valid) { | ||||
|           this.instance | ||||
|             .post(`/app/appcommunitybuildinginfo/addOrUpdate`, { | ||||
|               ...this.formData, | ||||
|             }) | ||||
|             .then((res) => { | ||||
|               if (res.code == 0) { | ||||
|                 this.$message.success('提交成功') | ||||
|                 setTimeout(() => { | ||||
|                   this.cancel(true) | ||||
|                 }, 1000) | ||||
|               } | ||||
|             }) | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     // 返回按钮 | ||||
|     cancel(isRefresh) { | ||||
|       this.$emit('change', { | ||||
|         type: 'list', | ||||
|         isRefresh: !!isRefresh, | ||||
|       }) | ||||
|     }, | ||||
|   }, | ||||
|   watch: { | ||||
|     communityNameContent: { | ||||
|       deep: true, | ||||
|     }, | ||||
|   }, | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .AppBuildManage { | ||||
|   ::v-deep .amap-logo { | ||||
|     display: none!important; | ||||
|   } | ||||
|   ::v-deep .amap-copyright { | ||||
|     display: none!important; | ||||
|   } | ||||
| } | ||||
| .Add { | ||||
|   height: 100%; | ||||
|   .ai-detail__title { | ||||
|     background-color: #fff; | ||||
|   } | ||||
|   .ai-detail__content { | ||||
|     .ai-detail__content--wrapper { | ||||
|       .el-form { | ||||
|         background-color: #fff; | ||||
|         padding: 0 60px; | ||||
|         .flex { | ||||
|           display: flex; | ||||
|           flex-wrap: wrap; | ||||
|           justify-content: space-between; | ||||
|           .el-form-item { | ||||
|             width: 48%; | ||||
|           } | ||||
|           .buildingTypes { | ||||
|             width: 100%; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| ::v-deep .mapDialog { | ||||
|   .el-dialog__body { | ||||
|     padding: 0; | ||||
|  | ||||
|     .ai-dialog__content { | ||||
|       padding: 0; | ||||
|     } | ||||
|  | ||||
|     .ai-dialog__content--wrapper { | ||||
|       padding: 0 !important; | ||||
|       position: relative; | ||||
|     } | ||||
|  | ||||
|     #map { | ||||
|       width: 100%; | ||||
|       height: 420px; | ||||
|     } | ||||
|  | ||||
|     .searchPlaceInput { | ||||
|       position: absolute; | ||||
|       width: 250px; | ||||
|       top: 30px; | ||||
|       left: 25px; | ||||
|     } | ||||
|  | ||||
|     #searchPlaceOutput { | ||||
|       position: absolute; | ||||
|       width: 250px; | ||||
|       left: 25px; | ||||
|       height: initial; | ||||
|       top: 80px; | ||||
|       background: white; | ||||
|       z-index: 250; | ||||
|       max-height: 300px; | ||||
|       overflow-y: auto; | ||||
|  | ||||
|       .auto-item { | ||||
|         text-align: left; | ||||
|         font-size: 14px; | ||||
|         padding: 8px; | ||||
|         box-sizing: border-box; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										750
									
								
								packages/grid/AppBuildManage/components/BuildMsg.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										750
									
								
								packages/grid/AppBuildManage/components/BuildMsg.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,750 @@ | ||||
| <template> | ||||
|   <ai-list class="BuildMsg"> | ||||
|     <!-- 标题 --> | ||||
|     <template #title> | ||||
|       <ai-title :title="params.communityName + '-' + params.buildingNumber + '号楼房屋信息'" isShowBack isShowBottomBorder | ||||
|                 @onBackClick="cancel(false)"></ai-title> | ||||
|     </template> | ||||
|     <template #content> | ||||
|       <!-- 性别下拉选择框 --> | ||||
|       <ai-search-bar> | ||||
|         <template #left> | ||||
|           <ai-select v-model="search.livingStatus" placeholder="房屋状态" clearable @change=";(page.current = 1), getList()" | ||||
|                      :selectList="dict.getDict('houselivingStatus')"></ai-select> | ||||
|  | ||||
|           <ai-select v-model="search.existFlow" placeholder="有无流动人口" clearable @change=";(page.current = 1), getList()" | ||||
|                      :selectList="dict.getDict('yesOrNo')"></ai-select> | ||||
|         </template> | ||||
|  | ||||
|         <template #right> | ||||
|           <el-input v-model="search.houseCode" size="small" placeholder="请输入户号/户主" clearable | ||||
|                     v-throttle="() => {page.current = 1, getList()}" | ||||
|                     @clear=";(page.current = 1), (search.houseCode = ''), getList()" suffix-icon="iconfont iconSearch"/> | ||||
|         </template> | ||||
|       </ai-search-bar> | ||||
|  | ||||
|       <ai-search-bar> | ||||
|         <template #left> | ||||
|           <div style="height: 32px"/> | ||||
|         </template> | ||||
|  | ||||
|         <template #right> | ||||
|           <ai-import :instance="instance" :dict="dict" type="appcommunityhouseinfo" :importParams="houseImpParam" name="房屋信息" | ||||
|                      @success="getList()"> | ||||
|             <el-button icon="iconfont iconImport">导入房屋信息</el-button> | ||||
|           </ai-import> | ||||
|           <ai-download :instance="instance" url="/app/appcommunityhouseinfo/listExport" :params="houseExpParam" | ||||
|                        fileName="房屋信息" style="margin-right: 10px"> | ||||
|             <el-button icon="iconfont iconExported">导出房屋信息</el-button> | ||||
|           </ai-download> | ||||
|           <ai-import :instance="instance" :dict="dict" type="appcommunityhouseresident" :importParams="houseImpParam" name="人口信息" | ||||
|                      @success="getList()"> | ||||
|             <el-button icon="iconfont iconImport">导入人口信息</el-button> | ||||
|           </ai-import> | ||||
|           <ai-download :instance="instance" url="/app/appcommunityhouseresident/listExport" :params="houseExpParam" | ||||
|                        fileName="人口信息"> | ||||
|             <el-button icon="iconfont iconExported">导出人口信息</el-button> | ||||
|           </ai-download> | ||||
|         </template> | ||||
|       </ai-search-bar> | ||||
|  | ||||
|       <ai-table :tableData="tableData" :col-configs="colConfigs" :total="total" ref="aitableex" | ||||
|                 :current.sync="page.current" :size.sync="page.size" @getList="getList" | ||||
|                 @selection-change="(v) => (ids = v.map((e) => e.id))"> | ||||
|         <el-table-column slot="owner" label="房主" align="center"> | ||||
|           <template slot-scope="{ row }"> | ||||
|             <span v-for="(item, i) in row.owner" :key="i" v-if="item.name"> | ||||
|               <span v-if="i < 2" style="margin-right: 5px;"> | ||||
|                 {{ item.name }} | ||||
|               </span> | ||||
|             </span> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|  | ||||
|         <el-table-column slot="owner" label="联系方式" align="center"> | ||||
|           <template slot-scope="{ row }"> | ||||
|             <span v-for="(item, i) in row.owner" :key="i" v-if="item.phone"> | ||||
|               <span v-if="i < 1"> | ||||
|                 {{ item.phone }} | ||||
|               </span> | ||||
|             </span> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|  | ||||
|         <el-table-column slot="livingStatus" label="房屋状态" align="center"> | ||||
|           <template slot-scope="{ row }"> | ||||
|             {{ dict.getLabel('houselivingStatus', row.livingStatus) }} | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|  | ||||
|         <el-table-column slot="owner" label="流动人口" align="center"> | ||||
|           <template slot-scope="{ row }"> | ||||
|             <span>{{ row.existFlow == 1 ? '有' : '无' }}</span> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|  | ||||
|         <el-table-column slot="options" label="操作" align="center" fixed="right" width="140"> | ||||
|           <div class="table-options" slot-scope="{ row }"> | ||||
|             <el-button type="text" @click="toEdit(row.id, 'edit')">编辑</el-button> | ||||
|             <el-button type="text" @click="toEdit(row.id, 'detail')">详情</el-button> | ||||
|           </div> | ||||
|         </el-table-column> | ||||
|       </ai-table> | ||||
|  | ||||
|       <ai-dialog :title="isEdit ? '编辑居民户' : '居民户详情'" :visible.sync="dialogVisible" width="800px" customFooter> | ||||
|         <ai-wrapper label> | ||||
|           <div class="bulidmsg"> | ||||
|             <span class="icon"></span> | ||||
|             <span class="bulidtext">房屋信息</span> | ||||
|           </div> | ||||
|  | ||||
|           <ai-info-item label="所属社区"> | ||||
|             {{ forms.areaName }} | ||||
|           </ai-info-item> | ||||
|  | ||||
|           <ai-info-item label="房屋地址"> | ||||
|             {{ forms.createAddress }} | ||||
|           </ai-info-item> | ||||
|  | ||||
|           <ai-info-item label="房屋类型"> | ||||
|             {{ dict.getLabel('communityBuildingType', forms.buildingType) }} | ||||
|           </ai-info-item> | ||||
|  | ||||
|           <template v-if="!isEdit"> | ||||
|             <ai-info-item label="房屋面积" prop="houseArea" class="line"> | ||||
|               <span>{{ forms.houseArea }}</span | ||||
|               > <span v-if="forms.houseArea">m²</span> | ||||
|             </ai-info-item> | ||||
|  | ||||
|             <ai-info-item label="居住现状" prop="livingStatus"> | ||||
|               <span>{{ dict.getLabel('houselivingStatus', forms.livingStatus) }}</span> | ||||
|             </ai-info-item> | ||||
|  | ||||
|             <ai-info-item label="房屋用途" prop="houseUse"> | ||||
|               <span>{{ dict.getLabel('houseUseStatus', forms.houseUse) }}</span> | ||||
|             </ai-info-item> | ||||
|  | ||||
|             <ai-info-item label="承租情况" prop="leaseSituation"> | ||||
|               <span>{{ dict.getLabel('houseLeaseSituation', forms.leaseSituation) }}</span> | ||||
|             </ai-info-item> | ||||
|  | ||||
|             <ai-info-item label="起租日期" prop="startDate"> | ||||
|               {{ $dateFormat(forms.startDate) }} | ||||
|             </ai-info-item> | ||||
|  | ||||
|             <ai-info-item label="备案证明" prop="isFilingCertificate"> | ||||
|               <span>{{ dict.getLabel('isFilingCertificateStatus', forms.isFilingCertificate) }}</span> | ||||
|             </ai-info-item> | ||||
|           </template> | ||||
|         </ai-wrapper> | ||||
|  | ||||
|         <el-form v-if="isEdit" :model="forms" ref="ruleForm" label-width="100px" label-suffix=":" align-items="center" | ||||
|                  size="small"> | ||||
|           <template> | ||||
|             <el-form-item label="房屋面积" prop="houseArea" class="house"> | ||||
|               <el-input v-model="forms.houseArea" type="text" size="small" placeholder="请输入" suffix="m²"> | ||||
|                 <template slot="suffix">m²</template> | ||||
|               </el-input> | ||||
|             </el-form-item> | ||||
|  | ||||
|             <div class="family-hose"> | ||||
|               <el-form-item label="居住现状"> | ||||
|                 <el-radio-group v-model="forms.livingStatus"> | ||||
|                   <el-radio label="0">自用</el-radio> | ||||
|                   <el-radio label="1">出租</el-radio> | ||||
|                   <el-radio label="2">闲置</el-radio> | ||||
|                 </el-radio-group> | ||||
|               </el-form-item> | ||||
|  | ||||
|               <el-form-item label="房屋用途"> | ||||
|                 <el-radio-group v-model="forms.houseUse"> | ||||
|                   <el-radio label="0">居住</el-radio> | ||||
|                   <el-radio label="1">闲置</el-radio> | ||||
|                   <el-radio label="2">经营</el-radio> | ||||
|                 </el-radio-group> | ||||
|               </el-form-item> | ||||
|             </div> | ||||
|  | ||||
|             <div class="family-hose"> | ||||
|               <el-form-item label="承租情况" prop="leaseSituation"> | ||||
|                 <ai-select v-model="forms.leaseSituation" placeholder="请选择" clearable | ||||
|                            @change=";(page.current = 1), getList()" :selectList="dict.getDict('houseLeaseSituation')" | ||||
|                            size="small"></ai-select> | ||||
|               </el-form-item> | ||||
|  | ||||
|               <el-form-item label="起租日期" prop="startDate"> | ||||
|                 <el-date-picker v-model="forms.startDate" type="date" placeholder="选择日期" size="small" | ||||
|                                 value-format="yyyy-MM-dd HH:mm:ss"></el-date-picker> | ||||
|               </el-form-item> | ||||
|             </div> | ||||
|  | ||||
|             <el-form-item label="备案证明" prop="isFilingCertificate"> | ||||
|               <el-radio-group v-model="forms.isFilingCertificate"> | ||||
|                 <el-radio label="0">有租赁房备案证明</el-radio> | ||||
|                 <el-radio label="1">无租赁房备案证明</el-radio> | ||||
|               </el-radio-group> | ||||
|             </el-form-item> | ||||
|           </template> | ||||
|         </el-form> | ||||
|         <!-- 房主信息 --> | ||||
|         <div class="table"> | ||||
|           <div class="msg"> | ||||
|             <b class="house-msg"> | ||||
|               <span class="icon"></span> | ||||
|               <span class="msg">房主信息</span> | ||||
|             </b> | ||||
|  | ||||
|             <div class="button"> | ||||
|               <ai-person-select :instance="instance" @selectPerson="getOwners" ref="getOwner" :chooseUserList="owners" | ||||
|                                 :isMultiple="true" v-if="isEdit"/> | ||||
|             </div> | ||||
|           </div> | ||||
|  | ||||
|           <ai-table :tableData="owners" :col-configs="owner" ref="aitableex"> | ||||
|             <el-table-column slot="owner" label="居民类型" align="center"> | ||||
|               <template slot-scope="{ row }"> | ||||
|                 {{ dict.getLabel('BulidResidentType', row.residentType) }} | ||||
|               </template> | ||||
|             </el-table-column> | ||||
|  | ||||
|             <el-table-column slot="owner" label="特殊人群" align="center" v-if="!isEdit"> | ||||
|               <template slot-scope="{ row }"> | ||||
|                 {{ row.tips }} | ||||
|               </template> | ||||
|             </el-table-column> | ||||
|  | ||||
|             <el-table-column slot="owner" label="与户主关系" align="center" v-if="isEdit"> | ||||
|               <template slot-scope="{ row }"> | ||||
|                 <ai-select v-model="row.relation" placeholder="与户主关系" clearable | ||||
|                            :selectList="$dict.getDict('householdRelation')"></ai-select> | ||||
|               </template> | ||||
|             </el-table-column> | ||||
|  | ||||
|             <el-table-column slot="owner" label="与户主关系" align="center" v-if="!isEdit"> | ||||
|               <template slot-scope="{ row }"> | ||||
|                 {{ dict.getLabel('householdRelation', row.relation) }} | ||||
|               </template> | ||||
|             </el-table-column> | ||||
|  | ||||
|             <el-table-column slot="options" label="操作" align="center" v-if="isEdit"> | ||||
|               <template slot-scope="scope"> | ||||
|                 <el-button type="text" @click="remove(scope.$index, 'owners')">删除</el-button> | ||||
|               </template> | ||||
|             </el-table-column> | ||||
|           </ai-table> | ||||
|         </div> | ||||
|  | ||||
|         <!-- 承租人信息 --> | ||||
|         <div class="table"> | ||||
|           <div class="msg"> | ||||
|             <b class="house-msg"> | ||||
|               <span class="icon"></span> | ||||
|               <span class="msg">承租人信息</span> | ||||
|             </b> | ||||
|  | ||||
|             <div class="button"> | ||||
|               <ai-person-select :instance="instance" @selectPerson="getRenters" :chooseUserList="renters" | ||||
|                                 :isMultiple="true" v-if="isEdit"/> | ||||
|             </div> | ||||
|           </div> | ||||
|  | ||||
|           <ai-table :tableData="renters" :col-configs="renter" ref="aitableex"> | ||||
|             <el-table-column slot="renters" label="居民类型" align="center"> | ||||
|               <template slot-scope="{ row }"> | ||||
|                 {{ dict.getLabel('BulidResidentType', row.residentType) }} | ||||
|               </template> | ||||
|             </el-table-column> | ||||
|  | ||||
|             <el-table-column slot="renters" label="特殊人群" align="center" v-if="!isEdit"> | ||||
|               <template slot-scope="{ row }"> | ||||
|                 {{ row.tips }} | ||||
|               </template> | ||||
|             </el-table-column> | ||||
|  | ||||
|             <el-table-column slot="renters" label="与户主关系" align="center" v-if="isEdit"> | ||||
|               <template slot-scope="{ row }"> | ||||
|                 <ai-select v-model="row.relation" placeholder="与户主关系" clearable | ||||
|                            :selectList="$dict.getDict('householdRelation')"></ai-select> | ||||
|               </template> | ||||
|             </el-table-column> | ||||
|  | ||||
|             <el-table-column slot="renters" label="与户主关系" align="center" v-if="!isEdit"> | ||||
|               <template slot-scope="{ row }"> | ||||
|                 {{ dict.getLabel('householdRelation', row.relation) }} | ||||
|               </template> | ||||
|             </el-table-column> | ||||
|  | ||||
|             <el-table-column slot="options" label="操作" align="center" v-if="isEdit"> | ||||
|               <template slot-scope="scope"> | ||||
|                 <el-button type="text" @click="remove(scope.$index, 'renters')">删除</el-button> | ||||
|               </template> | ||||
|             </el-table-column> | ||||
|           </ai-table> | ||||
|         </div> | ||||
|  | ||||
|         <!-- 实际居住人员 --> | ||||
|         <div class="table"> | ||||
|           <div class="msg"> | ||||
|             <b class="house-msg"> | ||||
|               <span class="icon"></span> | ||||
|               <span class="msg">实际居住人员</span> | ||||
|             </b> | ||||
|  | ||||
|             <div class="button" v-if="isEdit"> | ||||
|               <ai-person-select :instance="instance" @selectPerson="getLives" :isMultiple="true" | ||||
|                                 :chooseUserList="lives"/> | ||||
|             </div> | ||||
|           </div> | ||||
|  | ||||
|           <ai-table :tableData="lives" :col-configs="live" ref="aitableex"> | ||||
|             <el-table-column slot="lives" label="居民类型" align="center"> | ||||
|               <template slot-scope="{ row }"> | ||||
|                 {{ dict.getLabel('BulidResidentType', row.residentType) }} | ||||
|               </template> | ||||
|             </el-table-column> | ||||
|  | ||||
|             <el-table-column slot="lives" label="特殊人群" align="center" v-if="!isEdit"> | ||||
|               <template slot-scope="{ row }"> | ||||
|                 {{ row.tips }} | ||||
|               </template> | ||||
|             </el-table-column> | ||||
|  | ||||
|             <el-table-column slot="lives" label="与户主关系" align="center" v-if="isEdit"> | ||||
|               <template slot-scope="{ row }"> | ||||
|                 <ai-select v-model="row.relation" placeholder="与户主关系" clearable | ||||
|                            :selectList="$dict.getDict('householdRelation')"></ai-select> | ||||
|               </template> | ||||
|             </el-table-column> | ||||
|  | ||||
|             <el-table-column slot="lives" label="与户主关系" align="center" v-if="!isEdit"> | ||||
|               <template slot-scope="{ row }"> | ||||
|                 {{ dict.getLabel('householdRelation', row.relation) }} | ||||
|               </template> | ||||
|             </el-table-column> | ||||
|  | ||||
|             <el-table-column slot="options" label="操作" align="center" v-if="isEdit"> | ||||
|               <template slot-scope="scope"> | ||||
|                 <el-button type="text" @click="remove(scope.$index, 'lives')">删除</el-button> | ||||
|               </template> | ||||
|             </el-table-column> | ||||
|           </ai-table> | ||||
|         </div> | ||||
|  | ||||
|         <span slot="footer" class="dialog-footer"> | ||||
|           <el-button @click="dialogVisible = false">{{ isEdit ? '取消' : '关闭' }}</el-button> | ||||
|           <el-button type="primary" @click="report" v-if="isEdit">确认</el-button> | ||||
|         </span> | ||||
|       </ai-dialog> | ||||
|     </template> | ||||
|   </ai-list> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| export default { | ||||
|   name: 'BuildMsg', | ||||
|   components: {}, | ||||
|   props: { | ||||
|     dict: Object, | ||||
|     params: Object, | ||||
|     instance: Function, | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       id: '', | ||||
|       page: { | ||||
|         current: 1, | ||||
|         size: 10, | ||||
|       }, | ||||
|       total: 0, | ||||
|       search: { | ||||
|         livingStatus: '', | ||||
|         houseCode: '', | ||||
|       }, | ||||
|       colConfigs: [ | ||||
|         {prop: 'unitNumber', label: '单元', align: 'center'}, | ||||
|         {prop: 'houseCode', label: '户号', align: 'center'}, | ||||
|         {prop: 'livingNumber', label: '住户数', align: 'center'}, | ||||
|         {slot: 'owner', label: '户主', align: 'center'}, | ||||
|         {slot: 'livingStatus', align: 'center'}, | ||||
|         {slot: 'options', label: '操作', align: 'center'}, | ||||
|       ], | ||||
|       tableData: [], | ||||
|       dialogVisible: false, | ||||
|       forms: { | ||||
|         houseArea: '', | ||||
|         livingStatus: 0, | ||||
|         houseUse: 0, | ||||
|         leaseSituation: '', | ||||
|         isFilingCertificate: '', | ||||
|       }, | ||||
|       owners: [], | ||||
|       owner: [ | ||||
|         {prop: 'name', label: '姓名', align: 'center'}, | ||||
|         {prop: 'idNumber', label: '身份证号', align: 'center'}, | ||||
|         {prop: 'phone', label: '联系方式', align: 'center'}, | ||||
|         {slot: 'owner', align: 'center'}, | ||||
|         { | ||||
|           slot: 'relation', | ||||
|           align: 'center', | ||||
|         }, | ||||
|         {slot: 'options', label: '操作', align: 'center'}, | ||||
|       ], | ||||
|       renters: [], | ||||
|       renter: [ | ||||
|         {prop: 'name', label: '姓名', align: 'center'}, | ||||
|         {prop: 'idNumber', label: '身份证号', align: 'center'}, | ||||
|         {prop: 'phone', label: '联系方式', align: 'center'}, | ||||
|         { | ||||
|           slot: 'relation', | ||||
|           align: 'center', | ||||
|         }, | ||||
|         {slot: 'renters', align: 'center'}, | ||||
|         {slot: 'options', label: '操作', align: 'center'}, | ||||
|       ], | ||||
|       lives: [], | ||||
|       live: [ | ||||
|         {prop: 'name', label: '姓名', align: 'center'}, | ||||
|         {prop: 'idNumber', label: '身份证号', align: 'center'}, | ||||
|         {prop: 'phone', label: '联系方式', align: 'center'}, | ||||
|         { | ||||
|           slot: 'relation', | ||||
|           align: 'center', | ||||
|         }, | ||||
|         {slot: 'lives', align: 'center'}, | ||||
|         {slot: 'options', label: '操作', align: 'center'}, | ||||
|       ], | ||||
|       type: '', | ||||
|       ids: '', | ||||
|       buildingId: '', | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
|     houseImpParam() { | ||||
|       return { | ||||
|         buildingId: this.params.id, | ||||
|       } | ||||
|     }, | ||||
|     houseExpParam() { | ||||
|       return { | ||||
|         buildingId: this.params.id, | ||||
|       } | ||||
|     }, | ||||
|     isEdit() { | ||||
|       return this.type == 'edit' | ||||
|     }, | ||||
|   }, | ||||
|   watch: {}, | ||||
|   created() { | ||||
|     this.dict.load('yesOrNo', 'houselivingStatus', 'houseLeaseSituation', 'isFilingCertificateStatus', 'houseUseStatus', 'BulidResidentType', 'communityBuildingType', 'householdRelation').then(() => { | ||||
|       this.getList() | ||||
|     }) | ||||
|   }, | ||||
|   mounted() { | ||||
|   }, | ||||
|   methods: { | ||||
|     getList() { | ||||
|       this.instance | ||||
|       .post(`/app/appcommunityhouseinfo/list`, null, { | ||||
|         params: { | ||||
|           ...this.page, | ||||
|           ...this.search, | ||||
|           buildingId: this.params.id, | ||||
|         }, | ||||
|       }) | ||||
|       .then((res) => { | ||||
|         if (res.code == 0) { | ||||
|           this.tableData = res.data.records | ||||
|           this.total = res.data.total | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     // 返回按钮 | ||||
|     cancel(isRefresh) { | ||||
|       this.$emit('change', { | ||||
|         type: 'list', | ||||
|         isRefresh: !!isRefresh, | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     // 确认增加和编辑 | ||||
|     report() { | ||||
|       this.instance | ||||
|       .post(`/app/appcommunityhouseinfo/update`, { | ||||
|         ...this.forms, | ||||
|         id: this.id, | ||||
|         owner: this.owners, | ||||
|         renter: this.renters, | ||||
|         live: this.lives, | ||||
|       }) | ||||
|       .then((res) => { | ||||
|         if (res.code == 0) { | ||||
|           this.$message.success('提交成功') | ||||
|  | ||||
|           this.dialogVisible = false | ||||
|           this.getList() | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     // 详情 和 编辑 | ||||
|     toEdit(id, type) { | ||||
|       this.id = id | ||||
|       this.type = type | ||||
|       this.instance.post(`/app/appcommunityhouseinfo/queryDetailById?&id=${id}`).then((res) => { | ||||
|         if (res.code == 0) { | ||||
|           this.forms = res.data | ||||
|  | ||||
|           this.owners = this.forms.owner | ||||
|           this.renters = this.forms.renter | ||||
|           this.lives = this.forms.live | ||||
|         } | ||||
|       }) | ||||
|       this.dialogVisible = true | ||||
|     }, | ||||
|  | ||||
|     // 删除 | ||||
|     remove(index, source) { | ||||
|       this.$confirm('确定删除该数据?').then(() => { | ||||
|         this[source].splice(index, 1) | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     // 选择人员 | ||||
|     getOwners(val) { | ||||
|       let listNew = [] | ||||
|       let newName = [] | ||||
|       for (var i = 0; i < val.length; i++) { | ||||
|         if (newName.indexOf(val[i].name) == -1) { | ||||
|           newName.push(val[i].name) | ||||
|           listNew.push(val[i]) | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       this.owners = listNew | ||||
|     }, | ||||
|  | ||||
|     getRenters(val) { | ||||
|       let listNew = [] | ||||
|       let newName = [] | ||||
|       for (var i = 0; i < val.length; i++) { | ||||
|         if (newName.indexOf(val[i].name) == -1) { | ||||
|           newName.push(val[i].name) | ||||
|           listNew.push(val[i]) | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       this.renters = listNew | ||||
|     }, | ||||
|  | ||||
|     getLives(val) { | ||||
|       let listNew = [] | ||||
|       let newName = [] | ||||
|       for (var i = 0; i < val.length; i++) { | ||||
|         if (newName.indexOf(val[i].name) == -1) { | ||||
|           newName.push(val[i].name) | ||||
|           listNew.push(val[i]) | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       this.lives = listNew | ||||
|     }, | ||||
|   }, | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .BuildMsg { | ||||
|   ::v-deep .ai-list__title { | ||||
|     background-color: #fff; | ||||
|     margin: 0 !important; | ||||
|     padding-left: 20px; | ||||
|   } | ||||
|  | ||||
|   ::v-deep .ai-list__content { | ||||
|     .ai-list__content--right { | ||||
|       .ai-list__content--right-wrapper { | ||||
|         .search-select { | ||||
|           display: flex; | ||||
|           justify-content: space-between; | ||||
|           border-bottom: 1px solid #eee; | ||||
|           padding-bottom: 10px; | ||||
|  | ||||
|           .left { | ||||
|             width: 30%; | ||||
|  | ||||
|             .ai-select { | ||||
|               display: inline-block; | ||||
|             } | ||||
|  | ||||
|             .ai-select:first-child { | ||||
|               margin-right: 15px; | ||||
|             } | ||||
|           } | ||||
|  | ||||
|           .right { | ||||
|             width: 20%; | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         .bar { | ||||
|           display: flex; | ||||
|           justify-content: space-between; | ||||
|           margin-top: 10px; | ||||
|  | ||||
|           .export { | ||||
|             .ai-import { | ||||
|               display: inline-block; | ||||
|               margin-right: 10px; | ||||
|             } | ||||
|  | ||||
|             .ai-download { | ||||
|               display: inline-block; | ||||
|             } | ||||
|           } | ||||
|  | ||||
|           .import { | ||||
|             .ai-import { | ||||
|               display: inline-block; | ||||
|               margin-right: 10px; | ||||
|             } | ||||
|  | ||||
|             .ai-download { | ||||
|               display: inline-block; | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         .ai-dialog__wrapper { | ||||
|           background-color: #fff; | ||||
|  | ||||
|           .el-dialog__wrapper { | ||||
|             .el-dialog__body { | ||||
|               .ai-dialog__content { | ||||
|                 .ai-dialog__content--wrapper { | ||||
|                   .ai-wrapper { | ||||
|                     padding-left: 0 !important; | ||||
|  | ||||
|                     .bulidmsg { | ||||
|                       height: 32px; | ||||
|                       line-height: 32px; | ||||
|                       width: 100%; | ||||
|                       margin: 0 0 15px 20px; | ||||
|  | ||||
|                       .icon { | ||||
|                         border-left: 2px solid #2266ff; | ||||
|                       } | ||||
|  | ||||
|                       .bulidtext { | ||||
|                         display: inline-block; | ||||
|                         margin-left: 9px; | ||||
|                         color: #222; | ||||
|                         font-size: 15px; | ||||
|                         font-weight: 800; | ||||
|                       } | ||||
|                     } | ||||
|  | ||||
|                     .create { | ||||
|                       width: 100% !important; | ||||
|  | ||||
|                       .ai-info-item__left { | ||||
|                         width: 78px; | ||||
|                         margin-right: 22px; | ||||
|                       } | ||||
|                     } | ||||
|  | ||||
|                     .Address { | ||||
|                       .ai-info-item__left { | ||||
|                         width: 78px; | ||||
|                         margin-right: 22px; | ||||
|                       } | ||||
|                     } | ||||
|  | ||||
|                     .building { | ||||
|                       padding-left: 40px; | ||||
|  | ||||
|                       .ai-info-item__left { | ||||
|                         width: 78px; | ||||
|                         margin-right: 22px; | ||||
|                       } | ||||
|                     } | ||||
|                   } | ||||
|  | ||||
|                   .el-form { | ||||
|                     padding: 20px 0 0 0; | ||||
|  | ||||
|                     .house { | ||||
|                       width: 50%; | ||||
|  | ||||
|                       .el-form-item__content { | ||||
|                         width: 63%; | ||||
|                       } | ||||
|                     } | ||||
|  | ||||
|                     .family-hose { | ||||
|                       display: flex; | ||||
|                       justify-content: space-between; | ||||
|                     } | ||||
|  | ||||
|                     .line { | ||||
|                       width: 50% !important; | ||||
|                       padding-right: 40px; | ||||
|  | ||||
|                       .el-form-item__content { | ||||
|                         .el-input { | ||||
|                           .el-input__suffix { | ||||
|                             color: #666; | ||||
|                             margin-right: 5px; | ||||
|                           } | ||||
|                         } | ||||
|                       } | ||||
|                     } | ||||
|                   } | ||||
|  | ||||
|                   .table { | ||||
|                     padding: 20px 20px 0 20px; | ||||
|  | ||||
|                     .msg { | ||||
|                       display: flex; | ||||
|                       justify-content: space-between; | ||||
|  | ||||
|                       .house-msg { | ||||
|                         height: 32px; | ||||
|                         line-height: 32px; | ||||
|  | ||||
|                         .icon { | ||||
|                           border-left: 2px solid #2266ff; | ||||
|                         } | ||||
|  | ||||
|                         .msg { | ||||
|                           display: inline-block; | ||||
|                           color: #222; | ||||
|                           font-size: 15px; | ||||
|                           font-weight: 800; | ||||
|                           margin-left: 9px; | ||||
|                         } | ||||
|                       } | ||||
|  | ||||
|                       // .button { | ||||
|                       // } | ||||
|                     } | ||||
|  | ||||
|                     .ai-table { | ||||
|                       margin-top: 10px; | ||||
|                       // .el-table { | ||||
|                       // } | ||||
|                       .pagination { | ||||
|                         display: none; | ||||
|                       } | ||||
|                     } | ||||
|                   } | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										319
									
								
								packages/grid/AppBuildManage/components/List.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										319
									
								
								packages/grid/AppBuildManage/components/List.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,319 @@ | ||||
| <template> | ||||
|   <section class="AppPetitionManage"> | ||||
|     <ai-detail> | ||||
|       <!-- 标题 --> | ||||
|       <ai-title slot="title" title="楼栋管理" isShowBottomBorder /> | ||||
|       <template #content> | ||||
|         <ai-tree-menu title="楼栋管理" @search="(v) => $refs.gridTree.filter(v)"> | ||||
|           <el-tree :data="treeData" ref="gridTree" :filter-node-method="handleTreeFilter" @node-click="handleSelectGrid" highlight-current node-key="id" :props="{ label: 'name', children: 'children' }" :default-expanded-keys="[defaultShowNodes]" /> | ||||
|         </ai-tree-menu> | ||||
|  | ||||
|         <div class="flex"> | ||||
|           <ai-search-bar bottomBorder> | ||||
|             <template slot="left"> | ||||
|               <!-- 定位状态 --> | ||||
|               <ai-select v-model="search.locationStatus" placeholder="定位状态" clearable :selectList="$dict.getDict('BuildLocationStatus')" @change=";(page.current = 1), getList()"></ai-select> | ||||
|             </template> | ||||
|  | ||||
|             <!-- 搜索 --> | ||||
|             <template slot="right"> | ||||
|               <el-input | ||||
|                 v-model="search.managerName" | ||||
|                 size="small" | ||||
|                 placeholder="楼栋号/楼长/联系方式" | ||||
|                 clearable | ||||
|                 v-throttle="() => {page.current = 1, getList()}" | ||||
|                 @clear=";(page.current = 1), (search.managerName = ''), getList()" | ||||
|                 suffix-icon="iconfont iconSearch" /> | ||||
|             </template> | ||||
|           </ai-search-bar> | ||||
|  | ||||
|           <ai-search-bar class="ai-search-ba"> | ||||
|             <template slot="left"> | ||||
|               <el-button icon="iconfont iconAdd" type="primary" size="small" @click="onAdd('')" :disabled="!isAdd">添加 </el-button> | ||||
|               <el-button icon="iconfont iconDelete" size="small" @click="removeAll" :disabled="ids.length == 0">删除 </el-button> | ||||
|             </template> | ||||
|  | ||||
|             <!-- 导入导出 --> | ||||
|             <template #right> | ||||
|               <ai-import :instance="instance" :dict="dict" type="appcommunitybuildinginfo" :importParams="{ areaId: user.info && user.info.areaId }" name="楼栋管理" @success="getList()"> | ||||
|                 <el-button icon="iconfont iconImport">导入</el-button> | ||||
|               </ai-import> | ||||
|               <ai-download :instance="instance" url="/app/appcommunitybuildinginfo/listExport" :params="param" fileName="楼栋管理模板" :disabled="tableData.length == 0"> | ||||
|                 <el-button icon="iconfont iconExported" :disabled="tableData.length == 0">导出</el-button> | ||||
|               </ai-download> | ||||
|             </template> | ||||
|           </ai-search-bar> | ||||
|  | ||||
|           <ai-table :tableData="tableData" :col-configs="colConfigs" :total="total" ref="aitableex" style="margin-top: 20px;" :current.sync="page.current" :size.sync="page.size" @getList="getList" @selection-change="(v) => (ids = v.map((e) => e.id))"> | ||||
|             <el-table-column slot="locationStatus" label="定位状态" align="center"> | ||||
|               <template slot-scope="{ row }"> | ||||
|                 <span style="color:red" v-if="row.locationStatus == 0">{{ dict.getLabel('BuildLocationStatus', row.locationStatus) }}</span> | ||||
|                 <span style="color:green" v-if="row.locationStatus == 1">{{ dict.getLabel('BuildLocationStatus', row.locationStatus) }}</span> | ||||
|               </template> | ||||
|             </el-table-column> | ||||
|  | ||||
|             <el-table-column slot="options" label="操作" align="center" width="240px" fixed="right"> | ||||
|               <div class="table-options" slot-scope="{ row }"> | ||||
|                 <el-button type="text" @click="onAdd(row.id)">编辑</el-button> | ||||
|                 <el-button type="text" @click="remove(row.id)">删除</el-button> | ||||
|                 <el-button type="text" @click="toBuildMsg(row)">房屋信息</el-button> | ||||
|                 <el-button type="text" @click="$router.push({ name: '63', query: { communityId: row.communityId, buildingId: row.id, unitNum: 1, buildingNumber: row.buildingNumber } })"> | ||||
|                   楼栋模型 | ||||
|                 </el-button> | ||||
|               </div> | ||||
|             </el-table-column> | ||||
|           </ai-table> | ||||
|         </div> | ||||
|       </template> | ||||
|     </ai-detail> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import { mapState } from 'vuex' | ||||
|  | ||||
| export default { | ||||
|   name: 'List', | ||||
|   props: { | ||||
|     dict: Object, | ||||
|     instance: Function, | ||||
|     params: Object, | ||||
|   }, | ||||
|  | ||||
|   data() { | ||||
|     return { | ||||
|       isAdd: false, | ||||
|       page: { | ||||
|         current: 1, | ||||
|         size: 10, | ||||
|       }, | ||||
|       total: 0, | ||||
|       search: { | ||||
|         locationStatus: '', | ||||
|         managerName: '', | ||||
|       }, | ||||
|       id: '', | ||||
|       ids: [], | ||||
|       colConfigs: [ | ||||
|         { type: 'selection' }, | ||||
|         { | ||||
|           prop: 'communityName', | ||||
|           label: '小区名称', | ||||
|         }, | ||||
|         { | ||||
|           prop: 'buildingNumber', | ||||
|           label: '楼栋号', | ||||
|           align: 'center', | ||||
|         }, | ||||
|         { prop: 'unitNumber', label: '单元数', align: 'center' }, | ||||
|         { | ||||
|           prop: 'layerNumber', | ||||
|           label: '最高层数', | ||||
|           align: 'center', | ||||
|         }, | ||||
|         { prop: 'householdNumber', label: '每层户数', align: 'center' }, | ||||
|         { | ||||
|           prop: 'houseNum', | ||||
|           label: '实有户数', | ||||
|           align: 'center', | ||||
|         }, | ||||
|         { prop: 'residentNum', label: '实有人口', align: 'center' }, | ||||
|         { | ||||
|           prop: 'managerName', | ||||
|           label: '楼栋长名', | ||||
|           align: 'center', | ||||
|         }, | ||||
|         { prop: 'managerPhone', label: '楼栋长联系方式', align: 'center', width: '150' }, | ||||
|         { slot: 'locationStatus' }, | ||||
|         { | ||||
|           slot: 'options', | ||||
|           label: '操作', | ||||
|           align: 'center', | ||||
|         }, | ||||
|       ], | ||||
|       tableData: [], | ||||
|       organizationId: '', | ||||
|       meta: [], | ||||
|       treeData: [], | ||||
|       areaId: '', | ||||
|       communityId: null, | ||||
|       buildingTypeStatus: '', | ||||
|       defaultShowNodes: [], | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   computed: { | ||||
|     ...mapState(['user']), | ||||
|  | ||||
|     param() { | ||||
|       return { | ||||
|         ...this.search, | ||||
|         communityId: this.communityId, | ||||
|         areaId: this.user.info?.areaId, | ||||
|         ids: this.ids, | ||||
|       } | ||||
|     }, | ||||
|   }, | ||||
|  | ||||
|   created() { | ||||
|     this.dict.load('BuildLocationStatus').then(() => { | ||||
|       this.getList() | ||||
|       this.getListinfo() | ||||
|     }) | ||||
|   }, | ||||
|  | ||||
|   mounted() {}, | ||||
|  | ||||
|   methods: { | ||||
|     getListinfo() { | ||||
|       return this.instance.post(`/app/appcommunityinfo/queryCommunityTree?id=${this.user.info?.areaId}`).then((res) => { | ||||
|         if (res.data) { | ||||
|           this.treeData = [res.data] | ||||
|           this.$nextTick(() => { | ||||
|             this.defaultShowNodes = this.treeData[0].id | ||||
|           }) | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     getList() { | ||||
|       this.instance | ||||
|         .post(`/app/appcommunitybuildinginfo/list`, null, { | ||||
|           params: { | ||||
|             ...this.page, | ||||
|             ...this.search, | ||||
|             communityId: this.communityId, | ||||
|             areaId: this.areaId, | ||||
|           }, | ||||
|         }) | ||||
|         .then((res) => { | ||||
|           if (res.code == 0) { | ||||
|             this.tableData = res.data.records | ||||
|             this.total = res.data.total | ||||
|           } | ||||
|         }) | ||||
|     }, | ||||
|  | ||||
|     // 添加 | ||||
|     onAdd(id) { | ||||
|       this.$emit('change', { | ||||
|         type: 'add', | ||||
|         params: { | ||||
|           id: id || '', | ||||
|           bulidId: this.id, | ||||
|           communityId: this.communityId, | ||||
|         }, | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     // 房屋信息 | ||||
|     toBuildMsg(row) { | ||||
|       this.$emit('change', { | ||||
|         type: 'buildmsg', | ||||
|         params: { | ||||
|           ...row, | ||||
|         }, | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     // 删除 | ||||
|     remove(id) { | ||||
|       this.$confirm('确定删除该数据?').then(() => { | ||||
|         this.instance.post(`/app/appcommunitybuildinginfo/delete?ids=${id}`).then((res) => { | ||||
|           if (res.code == 0) { | ||||
|             this.$message.success('删除成功!') | ||||
|             this.getList() | ||||
|           } | ||||
|         }) | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     removeAll() { | ||||
|       var id = this.ids.join(',') | ||||
|       this.remove(id) | ||||
|     }, | ||||
|  | ||||
|     handleTreeFilter(v, data) { | ||||
|       return data?.name.indexOf(v) > -1 | ||||
|     }, | ||||
|  | ||||
|     handleSelectGrid(data) { | ||||
|       this.isAdd = false | ||||
|       if (data.type == 1) { | ||||
|         this.isAdd = true | ||||
|         this.communityId = data.id | ||||
|         this.areaId = null | ||||
|       } else if (data.type == 0) { | ||||
|         this.communityId = null | ||||
|         this.areaId = data.id | ||||
|       } | ||||
|       this.getList() | ||||
|     }, | ||||
|   }, | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .AppPetitionManage { | ||||
|   height: 100%; | ||||
|  | ||||
|   .ai-detail { | ||||
|     ::v-deep .ai-detail__content { | ||||
|       .ai-detail__content--wrapper { | ||||
|         display: flex; | ||||
|         justify-content: space-between; | ||||
|         height: 100%; | ||||
|         max-width: 100%; | ||||
|         padding: 15px; | ||||
|  | ||||
|         .AiTreeMenu { | ||||
|           width: 22%; | ||||
|         } | ||||
|  | ||||
|         .flex { | ||||
|           width: 78%; | ||||
|           margin-left: 10px; | ||||
|           padding: 15px; | ||||
|           background-color: #fff; | ||||
|  | ||||
|           .ai-search-ba { | ||||
|             margin-top: 10px; | ||||
|           } | ||||
|  | ||||
|           .ai-table { | ||||
|             margin-top: 0 !important; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   ::v-deep .el-tree { | ||||
|     .el-tree-node__content { | ||||
|       display: inline-flex; | ||||
|       min-width: 100%; | ||||
|  | ||||
|       &:hover { | ||||
|         background: #e8efff; | ||||
|         color: #222222; | ||||
|         border-radius: 2px; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .is-current > .el-tree-node__content { | ||||
|       background: #2266ff; | ||||
|  | ||||
|       &:hover { | ||||
|         background: #2266ff; | ||||
|         color: #fff; | ||||
|       } | ||||
|  | ||||
|       span { | ||||
|         color: #fff; | ||||
|         font-weight: bold; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										1252
									
								
								packages/grid/AppBuildMap/AppBuildMap.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1252
									
								
								packages/grid/AppBuildMap/AppBuildMap.vue
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										443
									
								
								packages/grid/AppBuildMap/buildingStatistics.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										443
									
								
								packages/grid/AppBuildMap/buildingStatistics.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,443 @@ | ||||
| <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=''"/> | ||||
|     <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> | ||||
							
								
								
									
										95
									
								
								packages/grid/AppBuildMap/buildingToolBar.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								packages/grid/AppBuildMap/buildingToolBar.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,95 @@ | ||||
| <template> | ||||
|   <section class="buildingToolBar"> | ||||
|     <div class="toolBar"> | ||||
|       <div class="nav" v-for="(op,i) in navs" :key="i" :class="{selected:i==active}" @click="active=i"> | ||||
|         <ai-icon :icon="op.icon"/> | ||||
|         <div>{{ op.name }}</div> | ||||
|       </div> | ||||
|     </div> | ||||
|     <component :is="currentNav.comp" class="toolPane"/> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import BuildingInfo from "./toolBar/buildingInfo"; | ||||
| import CommunityOverview from "./toolBar/communityOverview"; | ||||
| // import NearbyGCS from "./toolBar/nearbyGCS"; | ||||
| import RecentEvents from "./toolBar/recentEvents"; | ||||
|  | ||||
| export default { | ||||
|   name: "buildingToolBar", | ||||
|   components: {RecentEvents, CommunityOverview, BuildingInfo}, | ||||
|   computed: { | ||||
|     navs() { | ||||
|       return [ | ||||
|         {icon: 'icondanweiguanli', name: "单元统计", comp: BuildingInfo}, | ||||
|         {icon: 'icondanweiguanli', name: "单元切换", comp: CommunityOverview}, | ||||
|         // {icon: 'icondanweiguanli', name: "网格员", comp: NearbyGCS}, | ||||
|         // {icon: 'icondanweiguanli', name: "近期事件", comp: RecentEvents}, | ||||
|       ] | ||||
|     }, | ||||
|     currentNav() { | ||||
|       return this.navs[this.active] | ||||
|     } | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       active: 0 | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .buildingToolBar { | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|   gap: 10px; | ||||
|  | ||||
|   .toolBar { | ||||
|     height: 40px; | ||||
|     background: #FFFFFF; | ||||
|     box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.2); | ||||
|     border-radius: 4px; | ||||
|     padding: 4px; | ||||
|     width: 400px; | ||||
|     display: flex; | ||||
|     gap: 8px; | ||||
|     box-sizing: border-box; | ||||
|     align-self: flex-end; | ||||
|  | ||||
|     .nav { | ||||
|       flex: 1; | ||||
|       height: 32px; | ||||
|       color: #3A3A3A; | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|       justify-content: center; | ||||
|       font-size: 12px; | ||||
|       cursor: pointer; | ||||
|  | ||||
|       .AiIcon { | ||||
|         width: 16px; | ||||
|         height: 16px; | ||||
|         margin-right: 4px; | ||||
|       } | ||||
|  | ||||
|       &:hover { | ||||
|         color: #2266FF; | ||||
|       } | ||||
|  | ||||
|       &.selected { | ||||
|         background: #E4F0FF; | ||||
|         color: #2266FF; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .toolPane { | ||||
|     background: #FFFFFF; | ||||
|     box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.1); | ||||
|     border-radius: 4px; | ||||
|     overflow: hidden; | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										239
									
								
								packages/grid/AppBuildMap/toolBar/buildingInfo.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										239
									
								
								packages/grid/AppBuildMap/toolBar/buildingInfo.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,239 @@ | ||||
| <template> | ||||
|   <section class="buildingInfo"> | ||||
|     <ai-title title="人口信息"/> | ||||
|     <div class="infoPane"> | ||||
|       <div class="staZone"> | ||||
|         <div v-for="(value, name) in staData" :key="name"> | ||||
|           <b>{{ value }}</b> | ||||
|           <span>{{ name }}</span> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|     <ai-title title="房屋信息"/> | ||||
|     <div class="infoPane"> | ||||
|       <el-row type="flex" justify="space-between" class="info-item"> | ||||
|         <span>所属社区</span> | ||||
|         <span>{{build.areaName}}</span> | ||||
|       </el-row> | ||||
|       <el-row type="flex" justify="space-between" class="info-item"> | ||||
|         <span>所属小区</span> | ||||
|         <span>{{build.communityName}}</span> | ||||
|       </el-row> | ||||
|       <el-row type="flex" justify="space-between" class="info-item"> | ||||
|         <span>房屋类型</span> | ||||
|         <span>{{root.dict.getLabel("communityBuildingType",build.buildingType)}}</span> | ||||
|       </el-row> | ||||
|       <el-row type="flex" justify="space-between" class="info-item"> | ||||
|         <span>楼长姓名</span> | ||||
|         <span>{{build.managerName}}</span> | ||||
|       </el-row> | ||||
|       <el-row type="flex" justify="space-between" class="info-item"> | ||||
|         <span>联系方式</span> | ||||
|         <span>{{build.managerPhone}}</span> | ||||
|       </el-row> | ||||
|     </div> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import * as echarts from 'echarts' | ||||
|  | ||||
| export default { | ||||
|   name: "buildingInfo", | ||||
|   inject: ['root', 'sta'], | ||||
|   computed: { | ||||
|     chartData() { | ||||
|       return this.root.dict.getDict("residentTipType").map(e => ({ | ||||
|         name: e.dictName, | ||||
|         key: e.dictValue, | ||||
|         color: e.dictColor, | ||||
|         v1: 0 | ||||
|       })) | ||||
|     }, | ||||
|     colConfigs() { | ||||
|       return [ | ||||
|         {prop:"areaName",label:"所属社区"} | ||||
|       ]; | ||||
|     } | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       chart: null, | ||||
|       staData: {}, | ||||
|       tag:{}, | ||||
|       color:{}, | ||||
|       build:{}, | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     initChart(data) { | ||||
|       this.chart = echarts.init(document.getElementById("PersonStaChart")) | ||||
|       let selected = {}, color = [] | ||||
|       this.chartData.map(e => { | ||||
|         selected[e.name] = false | ||||
|         color.push(e.color) | ||||
|       }) | ||||
|       this.chart.setOption({ | ||||
|         grid: {top: 31, right: 0, height: 135}, | ||||
|         tooltip: {}, | ||||
|         legend: { | ||||
|           top: 185, | ||||
|           left: 0, | ||||
|           orient: "vertical", | ||||
|           selected, | ||||
|           itemWidth: 14, | ||||
|           itemHeight: 14, | ||||
|           itemGap: 12, | ||||
|           icon: "rect", | ||||
|           formatter: name => { | ||||
|             let item = data.find(e => this.root.dict.getLabel('residentTipType', e.name) == name) | ||||
|             return `{a|${name}}  {b|${item.v1}}` | ||||
|           }, | ||||
|           textStyle: { | ||||
|             rich: { | ||||
|               a: {color: "#666", width: 123}, | ||||
|               b: {color: "#333", fontWeight: 'bold', align: 'right'} | ||||
|             } | ||||
|           } | ||||
|         }, color, | ||||
|         yAxis: {type: 'value', min: 0, minInterval: 1, axisTick: false, axisLine: false, axisLabel: {color: "#666"}}, | ||||
|         xAxis: {type: 'category', axisTick: false, axisLine: false, axisLabel: false}, | ||||
|         series: data.map(e => ({ | ||||
|           type: 'bar', | ||||
|           barWidth: 8, | ||||
|           barGap: '250%', | ||||
|           name: this.root.dict.getLabel('residentTipType', e.name) | ||||
|         })) | ||||
|       }) | ||||
|       this.chart.on('legendselectchanged', ({selected}) => { | ||||
|         let tips = Object.keys(selected)?.filter(e => selected[e])?.map(e => this.root.dict.getValue('residentTipType', e)) | ||||
|         this.sta?.selectedTips(tips) | ||||
|       }) | ||||
|       this.getChartData(data) | ||||
|     }, | ||||
|     getChartData(data) { | ||||
|       this.chart?.setOption({ | ||||
|         series: data.map(e => ({data: [e.v1]})) | ||||
|       }) | ||||
|     } | ||||
|   }, | ||||
|   created(){ | ||||
|     this.root.dict?.load("communityBuildingType") | ||||
|   }, | ||||
|   mounted() { | ||||
|     this.root.instance.post("/app/appcommunitybuildinginfo/statistics", null, { | ||||
|       params: { | ||||
|         id: this.root.isFormDv ? this.root.info.id : this.$route.query.buildingId, | ||||
|         unitNum: this.root.isFormDv ? this.root.info.unitNumber : this.$route.query.unitNum, | ||||
|       } | ||||
|     }).then(res => { | ||||
|       if (res?.data) { | ||||
|         this.staData = res.data.unit; | ||||
|         this.tag = res.data.tag; | ||||
|         this.color = res.data.color; | ||||
|         this.build = res.data.build; | ||||
|         // this.root.dict.load('residentTipType').then(() => { | ||||
|         //   this.initChart(res.data.lx) | ||||
|         // }) | ||||
|       } | ||||
|     }) | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .buildingInfo { | ||||
|   ::v-deep .infoPane { | ||||
|     box-sizing: border-box; | ||||
|     padding: 10px 20px; | ||||
|  | ||||
|     .info-item{ | ||||
|       height: 32px; | ||||
|       box-sizing: border-box; | ||||
|       padding: 0 12px; | ||||
|       font-size: 12px; | ||||
|       color: #666666; | ||||
|       align-items: center; | ||||
|  | ||||
|       span:last-child{ | ||||
|         color: #333333; | ||||
|       } | ||||
|  | ||||
|       &:nth-child(2n-1){ | ||||
|         background-color: #F3F6F9; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .static-wrap{ | ||||
|       width: 360px; | ||||
|       box-sizing: border-box; | ||||
|       padding-top: 20px; | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|       justify-content: space-between; | ||||
|       flex-wrap: wrap; | ||||
|  | ||||
|       .sta-item{ | ||||
|         width: 46%; | ||||
|         display: flex; | ||||
|         align-items: center; | ||||
|         justify-content: space-between; | ||||
|         margin-bottom: 8px; | ||||
|  | ||||
|         .sta-left{ | ||||
|           display: flex; | ||||
|           align-items: center; | ||||
|           .tag{ | ||||
|             width: 14px; | ||||
|             height: 14px; | ||||
|             background: #DC1739; | ||||
|             border-radius: 2px; | ||||
|             margin-right: 3px; | ||||
|           } | ||||
|           & > label{ | ||||
|             font-size: 12px; | ||||
|             color: #666666; | ||||
|           } | ||||
|         } | ||||
|         .num{ | ||||
|           font-size: 12px; | ||||
|           color: #333333; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     .staZone { | ||||
|       height: 80px; | ||||
|       background: #F5F7F9; | ||||
|       border-radius: 4px; | ||||
|       overflow: hidden; | ||||
|       display: flex; | ||||
|  | ||||
|       & > div { | ||||
|         flex: 1; | ||||
|         min-width: 0; | ||||
|         display: flex; | ||||
|         flex-direction: column; | ||||
|         justify-content: center; | ||||
|         align-items: center; | ||||
|         height: 100%; | ||||
|         font-size: 12px; | ||||
|         color: #333; | ||||
|  | ||||
|         b { | ||||
|           font-size: 24px; | ||||
|           font-family: DINAlternate-Bold, DINAlternate,serif; | ||||
|           color: #2266FF; | ||||
|           margin-bottom: 4px; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|     #PersonStaChart { | ||||
|       width: 100%; | ||||
|       height: 350px; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										116
									
								
								packages/grid/AppBuildMap/toolBar/communityOverview.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								packages/grid/AppBuildMap/toolBar/communityOverview.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,116 @@ | ||||
| <template> | ||||
|   <section class="communityOverview"> | ||||
|     <ai-title title="小区总览"/> | ||||
|     <div class="units" v-if="Object.keys(buildingUnits).length>0"> | ||||
|       <div class="building" v-for="(value,name) in buildingUnits" :key="name"> | ||||
|         <div class="unit" v-for="(op,j) in value" :key="j" @click="sta.selectedBuilding(op,j+1)" | ||||
|              :class="{selected:sta.unitNumber==j+1 && sta.currentBuilding.buildingNumber==name}"> | ||||
|           <b>{{ name}}栋</b> | ||||
|           <div>{{ j+1 }}单元</div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|     <AiEmpty v-else>暂无楼栋信息,请进入【楼栋管理】添加</AiEmpty> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| export default { | ||||
|   name: "communityOverview", | ||||
|   inject: ['root', 'sta'], | ||||
|   computed: { | ||||
|     buildingUnits() { | ||||
|       let obj = {} | ||||
|       this.units.map(e => { | ||||
|         for(let i=0;i<e.unitNumber;i++){ | ||||
|           obj[e.buildingNumber]?.push(e) || (obj[e.buildingNumber] = [e]) | ||||
|         } | ||||
|       }) | ||||
|       return obj; | ||||
|     } | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       units: [] | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     getUnits(communityId) { | ||||
|       this.root.instance.post("/app/appcommunitybuildinginfo/list", null, { | ||||
|         params: { | ||||
|           communityId, | ||||
|           size: 999 | ||||
|         } | ||||
|       }).then(res => { | ||||
|         if (res?.data) { | ||||
|           this.units = res.data.records | ||||
|         } | ||||
|       }) | ||||
|     } | ||||
|   }, | ||||
|   created() { | ||||
|     this.getUnits(this.root.isFormDv ? this.root.info.communityId : this.$route.query.communityId) | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .communityOverview { | ||||
|   max-width: 400px; | ||||
|  | ||||
|   .units { | ||||
|     display: flex; | ||||
|     flex-wrap: wrap; | ||||
|     padding: 0 20px 20px; | ||||
|     align-items: flex-start; | ||||
|  | ||||
|     .building { | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|       height: auto; | ||||
|       flex-wrap: wrap;  | ||||
|  | ||||
|       .unit { | ||||
|         margin-right: 10px; | ||||
|         margin-bottom: 10px; | ||||
|  | ||||
|         &:nth-of-type(5) { | ||||
|           margin-right: 0; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .unit { | ||||
|       width: 64px; | ||||
|       height: 56px; | ||||
|       background: #F8FBFF; | ||||
|       border-radius: 2px 0 0 2px; | ||||
|       border: 1px solid #829CCF; | ||||
|       display: flex; | ||||
|       flex-direction: column; | ||||
|       justify-content: center; | ||||
|       align-items: center; | ||||
|       font-size: 12px; | ||||
|       color: #999; | ||||
|       cursor: pointer; | ||||
|  | ||||
|       b { | ||||
|         color: #424242; | ||||
|       } | ||||
|  | ||||
|       &.selected { | ||||
|         color: #fff; | ||||
|         background: #2266FF; | ||||
|  | ||||
|         b { | ||||
|           color: #fff; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .ai-empty { | ||||
|     height: 240px; | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										129
									
								
								packages/grid/AppBuildMap/toolBar/nearbyGCS.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								packages/grid/AppBuildMap/toolBar/nearbyGCS.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,129 @@ | ||||
| <template> | ||||
|   <section class="nearbyGCS"> | ||||
|     <ai-title title="全部网格员"/> | ||||
|     <div class="radarPane"> | ||||
|       <div class="radar"> | ||||
|         <div class="indicator"/> | ||||
|       </div> | ||||
|       <div class="gcsItem" v-for="(op,i) in userList" :key="i" :style="op.style"> | ||||
|         <i class="dot" :class="{offline:op.offline}"/> | ||||
|         <span>{{ op.name }}</span> | ||||
|         <ai-icon icon="iconIM"/> | ||||
|       </div> | ||||
|     </div> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| export default { | ||||
|   name: "nearbyGCS", | ||||
|   inject: ['root', 'sta'], | ||||
|  | ||||
|   data () { | ||||
|     return { | ||||
|       userList: [] | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   mounted () { | ||||
|     this.getInfo() | ||||
|   }, | ||||
|  | ||||
|   methods: { | ||||
|     getInfo () { | ||||
|       this.root.instance.post('/app/appgirdmemberinfo/queryGirdMemberByBuilding', null, { | ||||
|         params: {buildingId: this.$route.query.buildingId} | ||||
|       }).then(res => { | ||||
|         if (res?.data) { | ||||
|           this.gcsList(res.data) | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     gcsList (data) { | ||||
|       this.userList = data.map(e => ({ | ||||
|         ...e, | ||||
|         style: { | ||||
|           transform: `translate( | ||||
|         ${Math.round(160 * (Math.random() - 0.5))}px, | ||||
|         ${Math.round(160 * (Math.random() - 0.5))}px)`} | ||||
|       })) | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .nearbyGCS { | ||||
|   .radarPane { | ||||
|     width: 100%; | ||||
|     height: 360px; | ||||
|     display: flex; | ||||
|     justify-content: center; | ||||
|     align-items: center; | ||||
|     position: relative; | ||||
|  | ||||
|     .gcsItem { | ||||
|       position: absolute; | ||||
|       width: 92px; | ||||
|       height: 28px; | ||||
|       background: #FFFFFF; | ||||
|       box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1); | ||||
|       border-radius: 16px; | ||||
|       font-size: 12px; | ||||
|       color: #333333; | ||||
|       display: flex; | ||||
|       justify-content: center; | ||||
|       align-items: center; | ||||
|       z-index: 3; | ||||
|       gap: 8px; | ||||
|  | ||||
|       .AiIcon { | ||||
|         width: 16px; | ||||
|         height: 16px; | ||||
|       } | ||||
|  | ||||
|       .dot { | ||||
|         width: 4px; | ||||
|         height: 4px; | ||||
|         background: #30BC77; | ||||
|  | ||||
|         &.offline { | ||||
|           background: #FF4466; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .radar { | ||||
|     width: 320px; | ||||
|     height: 320px; | ||||
|     position: relative; | ||||
|     border-radius: 50%; | ||||
|     overflow: hidden; | ||||
|     background-image: url("https://cdn.cunwuyun.cn/buildSta/radarBg.png"); | ||||
|  | ||||
|     .indicator { | ||||
|       position: absolute; | ||||
|       width: 160px; | ||||
|       height: 160px; | ||||
|       top: 0; | ||||
|       left: 0; | ||||
|       transform-origin: 100% 100%; | ||||
|       background: linear-gradient(190deg, rgba(162, 255, 182, 0.5) 0%, rgba(162, 255, 215, 0) 100%); | ||||
|       border-right: 1px solid #A2FFB6; | ||||
|       animation: radar 5s linear infinite; | ||||
|       z-index: 2; | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| @keyframes radar { | ||||
|   0% { | ||||
|     transform: rotate(0deg) | ||||
|   } | ||||
|   100% { | ||||
|     transform: rotate(360deg) | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										81
									
								
								packages/grid/AppBuildMap/toolBar/recentEvents.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								packages/grid/AppBuildMap/toolBar/recentEvents.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,81 @@ | ||||
| <template> | ||||
|   <section class="recentEvents"> | ||||
|     <ai-title title="楼栋近期相关事件"/> | ||||
|     <div class="recentEvents-list"> | ||||
|       <div class="recentEvents-item" v-for="(item, index) in 4" :key="index"> | ||||
|         <div class="recentEvents-item__top"> | ||||
|           <i>[已解决]</i> | ||||
|           <span>102室与402室矛盾纠纷</span> | ||||
|         </div> | ||||
|         <div class="recentEvents-item__middle"> | ||||
|           <span>102室与402室矛盾纠纷</span> | ||||
|           <em>[张三]</em> | ||||
|           <span>接到了</span> | ||||
|           <em>[矛盾调解]</em> | ||||
|           <span>任务,事件目前</span> | ||||
|           <i>[已完成]</i> | ||||
|         </div> | ||||
|         <div class="recentEvent-item__bottom">2019-06-18 13:35:45</div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| export default { | ||||
|   name: "recentEvents" | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .recentEvents { | ||||
|   font-size: 14px; | ||||
|   width: 100%; | ||||
|  | ||||
|   .recentEvents-list { | ||||
|     .recentEvents-item { | ||||
|       border-bottom: 1px solid #E6E8EE; | ||||
|       background: transparent; | ||||
|       padding: 10px; | ||||
|       box-sizing: border-box; | ||||
|       .recentEvent-item__bottom { | ||||
|         color: #999; | ||||
|         font-size: 12px; | ||||
|       } | ||||
|  | ||||
|       &:first-child { | ||||
|         background: #EFF6FF; | ||||
|         border-bottom: none; | ||||
|       } | ||||
|  | ||||
|       &:last-child { | ||||
|         border-bottom: none; | ||||
|       } | ||||
|  | ||||
|       .recentEvents-item__top { | ||||
|         display: flex; | ||||
|       } | ||||
|  | ||||
|       .recentEvents-item__middle { | ||||
|         margin: 6px 0 10px; | ||||
|       } | ||||
|  | ||||
|       span { | ||||
|         color: #666666; | ||||
|       } | ||||
|  | ||||
|       em { | ||||
|         color: #2266FF; | ||||
|         font-style: normal; | ||||
|       } | ||||
|  | ||||
|       i { | ||||
|         font-style: normal; | ||||
|         color: #2EA222; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|  | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										59
									
								
								packages/grid/AppCommunityManage/AppCommunityManage.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								packages/grid/AppCommunityManage/AppCommunityManage.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | ||||
| <template> | ||||
|   <section class="AppCommunityManage ailist-wrapper"> | ||||
|     <component ref="component" :is="component" @change="onChange" :params="params" :instance="instance" :dict="dict" /> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import List from './components/List' | ||||
| import Add from './components/Add' | ||||
|  | ||||
| export default { | ||||
|   name: 'AppCommunityManage', | ||||
|   label: '小区管理', | ||||
|  | ||||
|   props: { | ||||
|     instance: Function, | ||||
|     dict: Object, | ||||
|   }, | ||||
|  | ||||
|   data() { | ||||
|     return { | ||||
|       component: 'List', | ||||
|       params: {}, | ||||
|       include: [], | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   components: { | ||||
|     Add, | ||||
|     List, | ||||
|   }, | ||||
|  | ||||
|   methods: { | ||||
|     onChange(data) { | ||||
|       if (data.type === 'add') { | ||||
|         this.component = 'Add' | ||||
|         this.params = data.params | ||||
|       } | ||||
|  | ||||
|       if (data.type === 'list') { | ||||
|         this.component = 'List' | ||||
|         this.params = data.params | ||||
|  | ||||
|         this.$nextTick(() => { | ||||
|           if (data.isRefresh) { | ||||
|             this.$refs.component.getList() | ||||
|           } | ||||
|         }) | ||||
|       } | ||||
|     }, | ||||
|   }, | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss"> | ||||
| .AppCommunityManage { | ||||
|   height: 100%; | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										283
									
								
								packages/grid/AppCommunityManage/components/Add.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										283
									
								
								packages/grid/AppCommunityManage/components/Add.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,283 @@ | ||||
| <template> | ||||
|   <ai-detail showFooter class="add-detail"> | ||||
|     <template slot="title"> | ||||
|       <ai-title :title="isEdit ? '编辑小区信息' : '添加小区'" :isShowBack="true" @onBackClick="cancel()" | ||||
|                 :isShowBottomBorder="true"></ai-title> | ||||
|     </template> | ||||
|     <template slot="content"> | ||||
|       <div class="add-form"> | ||||
|         <ai-bar title="基础信息"></ai-bar> | ||||
|         <el-form label-width="110px" style="padding-bottom: 80px;" :model="form" ref="form"> | ||||
|           <el-form-item label="小区名称" prop="communityName" | ||||
|                         :rules="[{ required: true, message: '请输入小区名称', trigger: 'blur' }]"> | ||||
|             <el-input size="small" v-model="form.communityName" :maxlength="50" placeholder="请输入小区名称"></el-input> | ||||
|           </el-form-item> | ||||
|           <el-form-item label="行政归属" prop="areaId" :rules="[ | ||||
|               { required: true, message: '请选择行政归属', trigger: 'blur' }, | ||||
|               { pattern:/[^0]0{0,2}$/g, message: '请选择到村/社区' }]"> | ||||
|             <ai-area-get :instance="instance" v-model="form.areaId" :root="user.info.areaId" | ||||
|                          @select="handleAreaSelect"/> | ||||
|           </el-form-item> | ||||
|           <el-form-item label="小区地址" prop="address" :rules="[{ required: true, message: '请输入小区地址', trigger: 'blur' }]"> | ||||
|             <el-input size="small" v-model="form.address" placeholder="请输入小区地址" clearable/> | ||||
|           </el-form-item> | ||||
|  | ||||
|           <el-form-item label="所属网格" prop="girdInfoList" style="margin-top: 8px;" | ||||
|                         :rules="[{ required: true, message: '请选择所属网格', trigger: 'blur' }]"> | ||||
|             <el-tag | ||||
|                 :key="index" | ||||
|                 v-for="(tag,index) in form.girdInfoList" | ||||
|                 closable | ||||
|                 style="margin-right: 16px;" | ||||
|                 :disable-transitions="false" | ||||
|                 @close="handleClose(tag)"> | ||||
|               {{ tag.girdName }} | ||||
|             </el-tag> | ||||
|             <el-button size="small" @click="showGrid=true">选择网格</el-button> | ||||
|           </el-form-item> | ||||
|         </el-form> | ||||
|       </div> | ||||
|       <ai-dialog title="选择网格" :visible.sync="showGrid" :customFooter="true" :destroyOnClose="true" | ||||
|                  @opened="beforeSelectTree" border width="720px"> | ||||
|         <div class="grid"> | ||||
|           <el-tree :data="treeObj.treeList" :props="treeObj.defaultProps" node-key="id" ref="tree" | ||||
|                    :check-strictly="true" show-checkbox | ||||
|                    :default-checked-keys="treeObj.checkedKeys" default-expand-all | ||||
|             @check="onCheckChange"> | ||||
|           </el-tree> | ||||
|         </div> | ||||
|         <div class="dialog-footer" slot="footer"> | ||||
|           <el-button size="medium" @click="showGrid=false">取消</el-button> | ||||
|           <el-button type="primary" size="medium" @click="getCheckedTree()">确认</el-button> | ||||
|         </div> | ||||
|       </ai-dialog> | ||||
|     </template> | ||||
|     <template slot="footer" class="footer"> | ||||
|       <el-button class="delete-btn footer-btn" @click="cancel(false)">取消</el-button> | ||||
|       <el-button class="footer-btn" type="primary" @click="onSubmit('0')">保存</el-button> | ||||
|     </template> | ||||
|   </ai-detail> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import {mapState} from 'vuex' | ||||
|  | ||||
| export default { | ||||
|   name: 'Add', | ||||
|  | ||||
|   props: { | ||||
|     dict: Object, | ||||
|     params: Object, | ||||
|     instance: Function, | ||||
|   }, | ||||
|  | ||||
|   data() { | ||||
|     return { | ||||
|       gridList: [], | ||||
|       girdId: '', | ||||
|       subGridId: '', | ||||
|       subGridList: [], | ||||
|       sonGridList: [], | ||||
|       form: { | ||||
|         communityName: '', | ||||
|         areaName: '', | ||||
|         areaId: '', | ||||
|         girdId: '', | ||||
|         dealOpinion: '', | ||||
|         recordUser: '', | ||||
|         address: '', | ||||
|         girdInfoList: [], | ||||
|         girdName: '', | ||||
|       }, | ||||
|       showGrid: false, | ||||
|       treeObj: { | ||||
|         treeList: [], | ||||
|         defaultProps: { | ||||
|           children: "girdList", | ||||
|           label: "girdName", | ||||
|         }, | ||||
|         checkedKeys: [], | ||||
|       }, | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   computed: { | ||||
|     ...mapState(['user']), | ||||
|  | ||||
|     isEdit() { | ||||
|       return !!this.params.id | ||||
|     }, | ||||
|   }, | ||||
|  | ||||
|   created() { | ||||
|     this.dict.load('cardType', 'sex', 'nation').then(() => { | ||||
|       if (this.params && this.params.id) { | ||||
|         this.getInfo(this.params.id) | ||||
|       } | ||||
|     }) | ||||
|   }, | ||||
|   methods: { | ||||
|     beforeSelectTree() { | ||||
|       this.treeObj.checkedKeys = []; | ||||
|       this.instance.post(`/app/appgirdinfo/listAll`, null, null).then((res) => { | ||||
|         if (res.code == 0) { | ||||
|           this.treeObj.treeList = this.format(res.data) | ||||
|           if (this.form.girdInfoList.length) { | ||||
|             this.form.girdInfoList.map((e) => { | ||||
|               this.treeObj.checkedKeys.push(e.id); | ||||
|             }); | ||||
|           } | ||||
|         } | ||||
|       }); | ||||
|     }, | ||||
|  | ||||
|     onCheckChange (e) { | ||||
|       this.$nextTick(() => { | ||||
|         this.$refs.tree.getCheckedKeys().forEach(v => { | ||||
|           this.$refs.tree.setChecked(v, false) | ||||
|         }) | ||||
|         this.$refs.tree.setChecked(e.id, true) | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     format (list) { | ||||
|       return list.map(item => { | ||||
|         if (item.girdLevel !== '2') { | ||||
|           item.disabled = true | ||||
|         } | ||||
|  | ||||
|         if (item.girdList && item.girdList.length) { | ||||
|           item.girdList = this.format(item.girdList) | ||||
|         } | ||||
|  | ||||
|         return item | ||||
|       }) | ||||
|     }, | ||||
|     getCheckedTree() { | ||||
|       if (this.$refs.tree.getCheckedNodes().length > 1) { | ||||
|         return this.$message.error('不能绑定多个网格') | ||||
|       } | ||||
|       this.form.girdInfoList = this.$refs.tree.getCheckedNodes(); | ||||
|       this.showGrid = false; | ||||
|     }, | ||||
|     handleClose(tag) { | ||||
|       this.form.girdInfoList.splice(this.form.girdInfoList.indexOf(tag), 1); | ||||
|     }, | ||||
|     getInfo(id) { | ||||
|       this.instance.post(`/app/appcommunityinfo/queryDetailById?id=${id}`).then((res) => { | ||||
|         if (res.code === 0) { | ||||
|           this.girdId = res.data.girdId0 | ||||
|           this.form.communityName = res.data.communityName | ||||
|           this.form.address = res.data.address | ||||
|           this.form.areaName = res.data.areaName | ||||
|           this.form.girdId = res.data.girdId | ||||
|           this.form.girdName = res.data.girdName | ||||
|           this.form.girdInfoList = [{id: res.data.girdId, girdName: res.data.girdName}] | ||||
|           this.$set(this.form, 'areaId', res.data.areaId) | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     onSubmit() { | ||||
|       this.$refs.form.validate((valid) => { | ||||
|         if (valid) { | ||||
|           if (this.form.girdInfoList.length > 1) { | ||||
|             return this.$message.error('不能绑定多个网格') | ||||
|           } | ||||
|  | ||||
|           this.form.girdName = this.form.girdInfoList[0].girdName | ||||
|           this.form.girdId = this.form.girdInfoList[0].id | ||||
|           this.instance | ||||
|           .post(`/app/appcommunityinfo/addOrUpdate`, { | ||||
|             ...this.form, | ||||
|             id: this.params ? this.params.id : '', | ||||
|           }) | ||||
|           .then((res) => { | ||||
|             if (res.code === 0) { | ||||
|               this.$message.success('提交成功') | ||||
|               setTimeout(() => { | ||||
|                 this.cancel(true) | ||||
|               }, 800) | ||||
|             } | ||||
|           }) | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     cancel(isRefresh) { | ||||
|       this.$emit('change', { | ||||
|         type: 'list', | ||||
|         isRefresh: !!isRefresh, | ||||
|       }) | ||||
|     }, | ||||
|     handleAreaSelect(v) { | ||||
|       this.form.areaName = v?.[0]?.label | ||||
|     }, | ||||
|   }, | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .add-detail { | ||||
|   height: 100%; | ||||
|   overflow: hidden; | ||||
|   background: #f2f4f6 !important; | ||||
|  | ||||
|   .add-form__item { | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|   } | ||||
|  | ||||
|   ::v-deep .el-form-item__label { | ||||
|     padding-right: 40px; | ||||
|   } | ||||
|  | ||||
|   ::v-deep .ai-detail__footer { | ||||
|     background: #fff !important; | ||||
|   } | ||||
|  | ||||
|   ::v-deep .ai-detail__content--active { | ||||
|     padding: 20px; | ||||
|  | ||||
|     .ai-detail__content--wrapper { | ||||
|       width: 100%; | ||||
|     } | ||||
|  | ||||
|     .aibar { | ||||
|       padding: 0 16px; | ||||
|     } | ||||
|  | ||||
|     .el-form { | ||||
|       padding: 0 96px 0 50px; | ||||
|     } | ||||
|  | ||||
|     .add-form { | ||||
|       background: #fff; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   ::v-deep .ai-wrapper { | ||||
|     align-items: inherit !important; | ||||
|   } | ||||
|  | ||||
|   .user-wrapper { | ||||
|     display: flex; | ||||
|     justify-content: space-between; | ||||
|   } | ||||
|  | ||||
|   .avatar { | ||||
|     width: 100px; | ||||
|     height: 100px; | ||||
|     object-fit: contain; | ||||
|     border-radius: 10px; | ||||
|   } | ||||
|  | ||||
|   .footer-btn { | ||||
|     width: 130px; | ||||
|   } | ||||
|  | ||||
|   .el-form { | ||||
|     padding-bottom: 80px; | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										202
									
								
								packages/grid/AppCommunityManage/components/List.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										202
									
								
								packages/grid/AppCommunityManage/components/List.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,202 @@ | ||||
| <template> | ||||
|   <ai-list class="AppPetitionManage"> | ||||
|     <template slot="title"> | ||||
|       <ai-title title="小区管理" isShowBottomBorder /> | ||||
|     </template> | ||||
|     <template slot="content"> | ||||
|       <ai-search-bar class="search-bar" bottomBorder> | ||||
|         <template slot="left"> | ||||
|           <el-button icon="iconfont iconAdd" type="primary" size="small" @click="onAdd('')">添加</el-button> | ||||
|           <el-button :disabled="!ids.length" icon="iconfont iconDelete" size="small" @click="removeAll">删除</el-button> | ||||
|         </template> | ||||
|         <template slot="right"> | ||||
|           <el-input @clear=";(search.current = 1), (search.communityName = ''), getList()" v-throttle="() => {search.current=1,getList()}" v-model="search.communityName" class="search-input" size="small" placeholder="小区名称" suffix-icon="iconfont iconSearch" clearable /> | ||||
|         </template> | ||||
|       </ai-search-bar> | ||||
|  | ||||
|       <ai-search-bar style="margin-top: 15px;"> | ||||
|         <template #right> | ||||
|           <!-- :importParams="{ areaId: user.info && user.info.areaId }" --> | ||||
|           <ai-import :instance="instance" :dict="dict" type="appcommunityinfo" name="小区管理" @success="getList()"> | ||||
|             <el-button icon="iconfont iconImport">导入</el-button> | ||||
|           </ai-import> | ||||
|           <ai-download :instance="instance" url="/app/appcommunityinfo/listExport" :params="param" fileName="小区管理模板" :disabled="tableData.length == 0"> | ||||
|             <el-button icon="iconfont iconExported" :disabled="tableData.length == 0">导出</el-button> | ||||
|           </ai-download> | ||||
|         </template> | ||||
|       </ai-search-bar> | ||||
|       <!-- <ai-table :tableData="tableData" :col-configs="colConfigs" :total="total" ref="aitableex" :current.sync="search.current" @selection-change="handleSelectionChange"> --> | ||||
|       <ai-table :tableData="tableData" :col-configs="colConfigs" :total="total" ref="aitableex" :current.sync="search.current" @selection-change="(v) => (ids = v.map((e) => e.id))" :size.sync="search.size" @getList="getList"> | ||||
|         <el-table-column slot="options" label="操作" align="center"> | ||||
|           <template slot-scope="{ row }"> | ||||
|             <span class="table-btn" title="编辑" @click="toEdit(row.id)">编辑</span> | ||||
|             <span class="table-btn table-btn__remove" title="删除" @click="remove(row.id)">删除</span> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|       </ai-table> | ||||
|     </template> | ||||
|   </ai-list> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| export default { | ||||
|   name: 'List', | ||||
|  | ||||
|   props: { | ||||
|     instance: Function, | ||||
|     dict: Object, | ||||
|   }, | ||||
|  | ||||
|   data() { | ||||
|     return { | ||||
|       search: { | ||||
|         current: 1, | ||||
|         size: 10, | ||||
|         communityName: '', | ||||
|       }, | ||||
|       ids: [], | ||||
|       total: 0, | ||||
|       colConfigs: [ | ||||
|         { type: 'selection' }, | ||||
|         { prop: 'communityName', label: '小区名称', align: 'center', width: '200' }, | ||||
|         { prop: 'areaName', label: '行政划分' }, | ||||
|         { prop: 'address', label: '小区地址' }, | ||||
|         { prop: 'girdName', label: '所属网格' }, | ||||
|         { prop: 'buildingNumber', label: '总楼栋数(栋)', align: 'center' }, | ||||
|         { prop: 'createUserName', label: '创建人', align: 'center' }, | ||||
|         { prop: 'createTime', label: '创建时间', align: 'center' }, | ||||
|         { slot: 'options', label: '操作', align: 'center' }, | ||||
|       ], | ||||
|       tableData: [], | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   computed: { | ||||
|     importParams() { | ||||
|       return { | ||||
|         name: this.search.name, | ||||
|         ids: this.ids.map((v) => v.id).join(','), | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     param() { | ||||
|       let params = {} | ||||
|  | ||||
|       if (this.ids.length) { | ||||
|         params = { | ||||
|           ...params, | ||||
|           ids: this.ids, | ||||
|         } | ||||
|       } else { | ||||
|         params = { | ||||
|           ...params, | ||||
|           ...this.search, | ||||
|           ids: this.ids, | ||||
|         } | ||||
|       } | ||||
|       return params | ||||
|     }, | ||||
|   }, | ||||
|  | ||||
|   created() { | ||||
|     this.getList() | ||||
|   }, | ||||
|  | ||||
|   methods: { | ||||
|     getList() { | ||||
|       this.instance | ||||
|         .post(`/app/appcommunityinfo/list`, null, { | ||||
|           params: { | ||||
|             ...this.search, | ||||
|           }, | ||||
|         }) | ||||
|         .then((res) => { | ||||
|           if (res?.data) { | ||||
|             this.tableData = res.data.records | ||||
|             this.total = res.data.total | ||||
|           } | ||||
|         }) | ||||
|     }, | ||||
|     handleSelectionChange(e) { | ||||
|       this.ids = e | ||||
|     }, | ||||
|  | ||||
|     toEdit(id) { | ||||
|       this.$emit('change', { | ||||
|         type: 'add', | ||||
|         params: { | ||||
|           id: id, | ||||
|         }, | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     removeAll() { | ||||
|       // this.remove(this.ids.map((v) => v.id).join(',')) | ||||
|       var id = this.ids.join(',') | ||||
|       this.remove(id) | ||||
|     }, | ||||
|  | ||||
|     remove(id) { | ||||
|       this.$confirm('确定删除该数据?').then(() => { | ||||
|         this.instance.post(`/app/appcommunityinfo/delete?ids=${id}`).then((res) => { | ||||
|           if (res.code == 0) { | ||||
|             this.$message.success('删除成功!') | ||||
|             this.getList() | ||||
|           } | ||||
|         }) | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     onReset() { | ||||
|       this.search.current = 1 | ||||
|       this.search.communityName = '' | ||||
|  | ||||
|       this.getList() | ||||
|     }, | ||||
|  | ||||
|     onAdd(id) { | ||||
|       this.$emit('change', { | ||||
|         type: 'add', | ||||
|         params: { | ||||
|           id: id, | ||||
|         }, | ||||
|       }) | ||||
|     }, | ||||
|   }, | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .AppPetitionManage { | ||||
|   ::v-deep th { | ||||
|     font-weight: bold !important; | ||||
|   } | ||||
|  | ||||
|   .table-btn { | ||||
|     color: #2266ff; | ||||
|     font-size: 14px; | ||||
|     cursor: pointer; | ||||
|  | ||||
|     &:last-child:hover { | ||||
|       color: #f46; | ||||
|     } | ||||
|  | ||||
|     &:first-child { | ||||
|       margin-right: 16px; | ||||
|  | ||||
|       &:hover { | ||||
|         opacity: 0.6; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .icon-color89B { | ||||
|     margin-right: 8px; | ||||
|     cursor: pointer; | ||||
|  | ||||
|     &:last-child { | ||||
|       margin-right: 0; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </style> | ||||
| @@ -0,0 +1,61 @@ | ||||
| <template> | ||||
|   <div class="AppHomesteadManagement"> | ||||
|     <keep-alive :include="['List']"> | ||||
|       <component ref="component" :is="component" @change="onChange" :params="params" :instance="instance" :dict="dict"></component> | ||||
|     </keep-alive> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import List from './components/List' | ||||
| import Add from './components/Add' | ||||
|  | ||||
| export default { | ||||
|   label: '宅基地管理', | ||||
|   name: 'AppHomesteadManagement', | ||||
|   props: { | ||||
|     instance: Function, | ||||
|     dict: Object, | ||||
|   }, | ||||
|  | ||||
|   data() { | ||||
|     return { | ||||
|       component: 'List', | ||||
|       params: {}, | ||||
|       include: [], | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   components: { | ||||
|     Add, | ||||
|     List, | ||||
|   }, | ||||
|   methods: { | ||||
|     onChange(data) { | ||||
|       if (data.type === 'add') { | ||||
|         this.component = 'Add' | ||||
|         this.params = data.params | ||||
|       } | ||||
|  | ||||
|       if (data.type == 'list') { | ||||
|         this.component = 'List' | ||||
|         this.params = data.params | ||||
|  | ||||
|         this.$nextTick(() => { | ||||
|           if (data.isRefresh) { | ||||
|             this.$refs.component.getList() | ||||
|           } | ||||
|         }) | ||||
|       } | ||||
|     }, | ||||
|   }, | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss"> | ||||
| .AppHomesteadManagement { | ||||
|   height: 100%; | ||||
|   background: #f3f6f9; | ||||
|   overflow: auto; | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										475
									
								
								packages/grid/AppHomesteadManagement/components/Add.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										475
									
								
								packages/grid/AppHomesteadManagement/components/Add.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,475 @@ | ||||
| <template> | ||||
|   <section style="height: 100%" class="AppHomesteadManagement"> | ||||
|     <ai-detail class="Add"> | ||||
|       <!-- 返回按钮 --> | ||||
|       <template #title> | ||||
|         <ai-title :title="isEdit ? '编辑宅基地信息' : '添加宅基地'" isShowBack isShowBottomBorder @onBackClick="cancel(false)"></ai-title> | ||||
|       </template> | ||||
|       <template #content> | ||||
|         <el-form :model="formData" :rules="formRules" ref="ruleForm" label-width="150px" label-suffix=":" align-items="center"> | ||||
|           <ai-card title="户主信息" > | ||||
|             <template slot="content"> | ||||
|               <div class="flex"> | ||||
|                 <el-form-item label="姓名" prop="name"> | ||||
|                   <el-input size="small" class="user-selecter" v-model="formData.name" placeholder="请输入" clearable> | ||||
|                     <template slot="append"> | ||||
|                       <ai-person-select :instance="instance" @selectPerson="checkName"> | ||||
|                       </ai-person-select> | ||||
|                     </template> | ||||
|                   </el-input> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="身份证号码" prop="idNumber"> | ||||
|                   <ai-id size="small" v-model="formData.idNumber" @change="IdCard(formData.idNumber)"/> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="性别" prop="sex"> | ||||
|                   <ai-select v-model="formData.sex" placeholder="请选择" :selectList="dict.getDict('sex')" disabled /> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="年龄" prop="age"> | ||||
|                   <el-input size="small" v-model="formData.age" placeholder="请输入" clearable disabled></el-input> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="联系电话"> | ||||
|                   <el-input size="small" v-model="formData.phone" placeholder="请输入" clearable :maxlength="20"></el-input> | ||||
|                 </el-form-item> | ||||
|               </div> | ||||
|               <el-form-item label="所属村" prop="areaId"> | ||||
|                 <ai-area-get :instance="instance" v-model="formData.areaId" :name.sync="formData.areaName" /> | ||||
|               </el-form-item> | ||||
|             </template> | ||||
|           </ai-card> | ||||
|           <ai-card title="宅基地情况" > | ||||
|             <template slot="content"> | ||||
|               <div class="flex"> | ||||
|                 <el-form-item label="宅基地面积"> | ||||
|                   <el-input size="small" v-model="formData.homesteadArea" placeholder="请输入" clearable maxlength="10"> | ||||
|                     <template slot="append">m²</template> | ||||
|                   </el-input> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="房基占地面积"> | ||||
|                   <el-input size="small" v-model="formData.houseArea" placeholder="请输入" clearable maxlength="10"> | ||||
|                     <template slot="append">m²</template> | ||||
|                   </el-input> | ||||
|                 </el-form-item> | ||||
|               </div> | ||||
|               <el-form-item label="宅基地地址"> | ||||
|                 <el-input size="small" v-model="formData.homesteadAddress" placeholder="请输入" clearable maxlength="20"></el-input> | ||||
|               </el-form-item> | ||||
|               <div class="flex"> | ||||
|                 <el-form-item label="四至-东至"> | ||||
|                   <el-input size="small" v-model="formData.eastTo" placeholder="请输入" clearable maxlength="20"></el-input> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="四至-南至"> | ||||
|                   <el-input size="small" v-model="formData.southTo" placeholder="请输入" clearable maxlength="20"></el-input> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="四至-西至"> | ||||
|                   <el-input size="small" v-model="formData.westTo" placeholder="请输入" clearable maxlength="20"></el-input> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="四至-北至"> | ||||
|                   <el-input size="small" v-model="formData.northTo" placeholder="请输入" clearable maxlength="20"></el-input> | ||||
|                 </el-form-item> | ||||
|               </div> | ||||
|               <el-form-item label="地类" class="buildingTypes"> | ||||
|                 <el-radio-group v-model="formData.landType"> | ||||
|                   <el-radio :label="item.dictValue" v-for="(item, index) in dict.getDict('homesteadLandType')" :key="index">{{item.dictName}}</el-radio> | ||||
|                 </el-radio-group> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="性质" class="buildingTypes"> | ||||
|                 <el-radio-group v-model="formData.houseType"> | ||||
|                   <el-radio :label="item.dictValue" v-for="(item, index) in dict.getDict('homesteadHouseType')" :key="index">{{item.dictName}}</el-radio> | ||||
|                 </el-radio-group> | ||||
|               </el-form-item> | ||||
|               <div class="flex"> | ||||
|                 <el-form-item label="住宅建筑面积"> | ||||
|                   <el-input size="small" v-model="formData.liveBuildingArea" placeholder="请输入" clearable maxlength="10"> | ||||
|                     <template slot="append">m²</template> | ||||
|                   </el-input> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="建筑层数"> | ||||
|                   <el-input size="small" v-model="formData.buildingFloorNumber" placeholder="请输入" clearable maxlength="10"> | ||||
|                     <template slot="append">层</template> | ||||
|                   </el-input> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="建筑高度"> | ||||
|                   <el-input size="small" v-model="formData.buildingHeight" placeholder="请输入" clearable maxlength="10"> | ||||
|                     <template slot="append">m</template> | ||||
|                   </el-input> | ||||
|                 </el-form-item> | ||||
|               </div> | ||||
|             </template> | ||||
|           </ai-card> | ||||
|           <ai-card title="位置信息" > | ||||
|             <template slot="content"> | ||||
|               <div class="flex"> | ||||
|                 <el-form-item label="楼栋经度"> | ||||
|                   <el-input size="small" v-model="formData.lng" placeholder="请输入" clearable maxlength="10"></el-input> | ||||
|                 </el-form-item> | ||||
|                 <el-form-item label="楼栋纬度"> | ||||
|                   <el-input size="small" v-model="formData.lat" placeholder="请输入" clearable maxlength="10"></el-input> | ||||
|                 </el-form-item> | ||||
|               </div> | ||||
|               <el-form-item label="地图位置"> | ||||
|                 <el-button @click="showMap = true">地图标绘</el-button> | ||||
|               </el-form-item> | ||||
|             </template> | ||||
|           </ai-card> | ||||
|         </el-form> | ||||
|       </template> | ||||
|       <!-- 底部按钮 --> | ||||
|       <template #footer> | ||||
|         <el-button @click="cancel">取消</el-button> | ||||
|         <el-button type="primary" @click="confirm()">提交</el-button> | ||||
|       </template> | ||||
|     </ai-detail> | ||||
|     <ai-dialog title="地图" :visible.sync="showMap" @opened="getCorpLocation" width="800px" class="mapDialog" @onConfirm="selectMap"> | ||||
|       <div id="map"></div> | ||||
|       <el-form label-width="80px" style="padding: 10px 20px 0 20px;"> | ||||
|         <el-row type="flex" justify="space-between"> | ||||
|           <el-form-item label="经度"> | ||||
|             <el-input disabled size="small" v-model="placeDetail.lng"></el-input> | ||||
|           </el-form-item> | ||||
|           <el-form-item label="纬度"> | ||||
|             <el-input disabled size="small" v-model="placeDetail.lat"></el-input> | ||||
|           </el-form-item> | ||||
|         </el-row> | ||||
|       </el-form> | ||||
|       <el-input id="searchPlaceInput" size="medium" class="searchPlaceInput" clearable v-model="searchPlace" autocomplete="on" @change="placeSearch.search(searchPlace)" placeholder="请输入关键字"> | ||||
|         <el-button type="primary" slot="append" @click="placeSearch.search(searchPlace)">搜索</el-button> | ||||
|       </el-input> | ||||
|       <div id="searchPlaceOutput" /> | ||||
|     </ai-dialog> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import { mapState } from 'vuex' | ||||
| import AMapLoader from '@amap/amap-jsapi-loader' | ||||
|  | ||||
| export default { | ||||
|   name: 'Add', | ||||
|   props: { | ||||
|     dict: Object, | ||||
|     params: Object, | ||||
|     instance: Function, | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       formData: { | ||||
|         name: '', | ||||
|         idNumber: '', | ||||
|         age: '', | ||||
|         sex: '', | ||||
|         phone: '', | ||||
|         areaId: '', | ||||
|         homesteadArea: '', | ||||
|         houseArea: '', | ||||
|         homesteadAddress: '', | ||||
|         eastTo: '', | ||||
|         southTo: '', | ||||
|         westTo: '', | ||||
|         northTo: '', | ||||
|         landType: '0', | ||||
|         houseType: '0', | ||||
|         liveBuildingArea: '', | ||||
|         buildingFloorNumber: '', | ||||
|         buildingHeight: '', | ||||
|         lng: '', | ||||
|         lat: '', | ||||
|         id: '', | ||||
|         areaName: '' | ||||
|       }, | ||||
|       formRules: { | ||||
|         name: [ | ||||
|           { required: true, message: '请选择人员', trigger: 'change' }, | ||||
|         ], | ||||
|         age: [ | ||||
|           { required: true, message: '请输入年龄', trigger: 'change' }, | ||||
|         ], | ||||
|         sex: [ | ||||
|           { required: true, message: '请选择性别', trigger: 'change' }, | ||||
|         ], | ||||
|         idNumber: [ | ||||
|           { required: true, message: '请输入身份证号码', trigger: 'change' }, | ||||
|         ], | ||||
|         areaId: [ | ||||
|           { required: true, message: '请选择所属村', trigger: 'change' }, | ||||
|         ] | ||||
|       }, | ||||
|       map: null, | ||||
|       placeDetail: { | ||||
|         lng: '', | ||||
|         lat: '', | ||||
|       }, | ||||
|       showMap: false, | ||||
|       searchPlace: '', | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
|     ...mapState(['user']), | ||||
|  | ||||
|     isEdit() { | ||||
|       return !!this.params.id | ||||
|     }, | ||||
|   }, | ||||
|   mounted() { | ||||
|     this.dict.load('homesteadLocationStatus', 'homesteadHouseType', 'homesteadLandType', 'sex').then(() => { | ||||
|       if(this.params.id) { | ||||
|         this.getListinfo() | ||||
|       } | ||||
|     }) | ||||
|  | ||||
|   }, | ||||
|   methods: { | ||||
|     checkName(e) { | ||||
|       this.formData.name = e.name | ||||
|       this.formData.idNumber = e.idNumber | ||||
|       this.formData.phone = e.phone | ||||
|       this.formData.areaId = e.householdAreaId | ||||
|     }, | ||||
|     IdCard(UUserCard) { | ||||
|       if (UUserCard) { | ||||
|         let arr = []; | ||||
|         if (parseInt(UUserCard.substr(16, 1)) % 2 == 1) { | ||||
|           arr.push("1"); | ||||
|         } else { | ||||
|           arr.push("0"); | ||||
|         } | ||||
|  | ||||
|         const myDate = new Date(); | ||||
|         const month = myDate.getMonth() + 1; | ||||
|         const day = myDate.getDate(); | ||||
|         let age = myDate.getFullYear() - UUserCard.substring(6, 10) - 1; | ||||
|         if ( | ||||
|             UUserCard.substring(10, 12) < month || | ||||
|             (UUserCard.substring(10, 12) == month && | ||||
|                 UUserCard.substring(12, 14) <= day) | ||||
|         ) { | ||||
|           age++; | ||||
|         } | ||||
|         arr.push(age); | ||||
|         this.formData.sex = arr[0]; | ||||
|         this.formData.age = arr[1]; | ||||
|       } | ||||
|     }, | ||||
|     decimalInput(name) { | ||||
|       if(!/^(([1-9]{1}\d*)|(0{1}))(\.\d{1,2})?$/g.test(this.formData[name])){ | ||||
|         this.formData[name] = '' | ||||
|         return this.$message.error('最多只保留两位小数点') | ||||
|       } | ||||
|     }, | ||||
|     numberInput(name) { | ||||
|       if(!/^[1-9]\d*|0$/g.test(this.formData[name])){ | ||||
|         this.formData[name] = '' | ||||
|         return this.$message.error('请输入正整数') | ||||
|       } | ||||
|     }, | ||||
|     selectMap() { | ||||
|       this.formData.lng = this.placeDetail.lng | ||||
|       this.formData.lat = this.placeDetail.lat | ||||
|       this.showMap = false | ||||
|     }, | ||||
|     getCorpLocation() { | ||||
|       this.instance.post('/app/appdvcpconfig/getCorpLocation').then((res) => { | ||||
|         if (res.code == 0) { | ||||
|           this.initMap(res.data) | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|     initMap({ lng, lat }) { | ||||
|       AMapLoader.load({ | ||||
|         key: 'b553334ba34f7ac3cd09df9bc8b539dc', | ||||
|         version: '2.0', | ||||
|         plugins: ['AMap.PlaceSearch', 'AMap.AutoComplete', 'AMap.Geocoder'], | ||||
|       }).then((AMap) => { | ||||
|         this.placeDetail.lng = this.formData.lng | ||||
|         this.placeDetail.lat = this.formData.lat | ||||
|         this.map = new AMap.Map('map', { | ||||
|           resizeEnable: true, | ||||
|           zooms: [6, 20], | ||||
|           center: [lng, lat], | ||||
|           zoom: 11, | ||||
|         }) | ||||
|         this.placeSearch = new AMap.PlaceSearch({ map: this.map }) | ||||
|         new AMap.AutoComplete({ | ||||
|           input: 'searchPlaceInput', | ||||
|           output: 'searchPlaceOutput', | ||||
|         }).on('select', (e) => { | ||||
|           if (e?.poi) { | ||||
|             this.placeSearch.setCity(e.poi.adcode) | ||||
|             this.movePosition(e.poi.location) | ||||
|           } | ||||
|         }) | ||||
|         this.map.on('click', (e) => { | ||||
|           new AMap.Geocoder().getAddress(e.lnglat, (sta, res) => { | ||||
|             if (res?.regeocode) { | ||||
|               this.placeDetail = { | ||||
|                 lng: e.lnglat?.lng, | ||||
|                 lat: e.lnglat?.lat, | ||||
|                 address: res.regeocode.formattedAddress, | ||||
|               } | ||||
|             } | ||||
|           }) | ||||
|           this.movePosition(e.lnglat) | ||||
|         }) | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     movePosition(center) { | ||||
|       if (this.map) { | ||||
|         this.map.clearMap() | ||||
|         this.map.panTo(center) | ||||
|         this.map.add([ | ||||
|           new AMap.Marker({ | ||||
|             position: center, | ||||
|             clickable: true, | ||||
|           }), | ||||
|         ]) | ||||
|         this.map.setFitView() | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     getListinfo() { | ||||
|       return this.instance | ||||
|         .post('/app/apphomesteadinfo/queryDetailById', null, { | ||||
|           params: { | ||||
|             id: this.params.id, | ||||
|           }, | ||||
|         }) | ||||
|         .then((res) => { | ||||
|           if (res.data) { | ||||
|             this.formData = res.data | ||||
|           } | ||||
|         }) | ||||
|     }, | ||||
|  | ||||
|     confirm() { | ||||
|       this.$refs['ruleForm'].validate((valid) => { | ||||
|         if (valid) { | ||||
|           this.instance | ||||
|             .post(`/app/apphomesteadinfo/addOrUpdate`, { | ||||
|               ...this.formData, | ||||
|             }) | ||||
|             .then((res) => { | ||||
|               if (res.code == 0) { | ||||
|                 this.$message.success('提交成功') | ||||
|                 setTimeout(() => { | ||||
|                   this.cancel(true) | ||||
|                 }, 1000) | ||||
|               } | ||||
|             }) | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     // 返回按钮 | ||||
|     cancel(isRefresh) { | ||||
|       this.$emit('change', { | ||||
|         type: 'list', | ||||
|         isRefresh: !!isRefresh, | ||||
|       }) | ||||
|     }, | ||||
|   }, | ||||
|   watch: { | ||||
|     communityNameContent: { | ||||
|       deep: true, | ||||
|     }, | ||||
|   }, | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
|   .AppHomesteadManagement { | ||||
|     ::v-deep .amap-logo { | ||||
|       display: none!important; | ||||
|     } | ||||
|     ::v-deep .amap-copyright { | ||||
|       display: none!important; | ||||
|     } | ||||
|   } | ||||
|  | ||||
| .Add { | ||||
|   height: 100%; | ||||
|   .ai-detail__title { | ||||
|     background-color: #fff; | ||||
|   } | ||||
|   .ai-detail__content { | ||||
|     .ai-detail__content--wrapper { | ||||
|       .el-form { | ||||
|         // background-color: #fff; | ||||
|         // padding: 0 60px; | ||||
|         .flex { | ||||
|           display: flex; | ||||
|           flex-wrap: wrap; | ||||
|           justify-content: space-between; | ||||
|           .el-form-item { | ||||
|             width: 48%; | ||||
|           } | ||||
|           .buildingTypes { | ||||
|             width: 100%; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .user-selecter { | ||||
|     ::v-deep .el-input-group__append { | ||||
|       width: 68px; | ||||
|       background: transparent; | ||||
|     } | ||||
|  | ||||
|     ::v-deep .el-button { | ||||
|       color: #fff; | ||||
|  | ||||
|       &:hover { | ||||
|         opacity: 0.8; | ||||
|         background: linear-gradient(90deg, #299FFF 0%, #0C61FF 100%); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| ::v-deep .mapDialog { | ||||
|   .el-dialog__body { | ||||
|     padding: 0; | ||||
|  | ||||
|     .ai-dialog__content { | ||||
|       padding: 0; | ||||
|     } | ||||
|  | ||||
|     .ai-dialog__content--wrapper { | ||||
|       padding: 0 !important; | ||||
|       position: relative; | ||||
|     } | ||||
|  | ||||
|     #map { | ||||
|       width: 100%; | ||||
|       height: 420px; | ||||
|     } | ||||
|  | ||||
|     .searchPlaceInput { | ||||
|       position: absolute; | ||||
|       width: 250px; | ||||
|       top: 30px; | ||||
|       left: 25px; | ||||
|     } | ||||
|  | ||||
|     #searchPlaceOutput { | ||||
|       position: absolute; | ||||
|       width: 250px; | ||||
|       left: 25px; | ||||
|       height: initial; | ||||
|       top: 80px; | ||||
|       background: white; | ||||
|       z-index: 250; | ||||
|       max-height: 300px; | ||||
|       overflow-y: auto; | ||||
|  | ||||
|       .auto-item { | ||||
|         text-align: left; | ||||
|         font-size: 14px; | ||||
|         padding: 8px; | ||||
|         box-sizing: border-box; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										204
									
								
								packages/grid/AppHomesteadManagement/components/List.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										204
									
								
								packages/grid/AppHomesteadManagement/components/List.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,204 @@ | ||||
| <template> | ||||
|   <section class="AppPetitionManage"> | ||||
|     <ai-list> | ||||
|       <!-- 标题 --> | ||||
|       <ai-title slot="title" title="宅基地管理" isShowBottomBorder  isShowArea v-model="areaId" :instance="instance" @change="page.current=1,getList()"/> | ||||
|       <template #content> | ||||
|         <ai-search-bar bottomBorder> | ||||
|           <template slot="left"> | ||||
|             <!-- 定位状态 --> | ||||
|             <ai-select v-model="search.locationStatus" placeholder="定位状态" clearable :selectList="$dict.getDict('homesteadLocationStatus')" @change=";(page.current = 1), getList()"></ai-select> | ||||
|           </template> | ||||
|  | ||||
|           <!-- 搜索 --> | ||||
|           <template slot="right"> | ||||
|             <el-input v-model="search.name" size="small" | ||||
|               v-throttle="() => {page.current = 1, getList()}" placeholder="户主/联系电话" clearable @clear=";(page.current = 1), (search.name = ''), getList()" suffix-icon="iconfont iconSearch" /> | ||||
|           </template> | ||||
|         </ai-search-bar> | ||||
|  | ||||
|         <ai-search-bar class="ai-search-ba mar-t10"> | ||||
|           <template slot="left"> | ||||
|             <el-button icon="iconfont iconAdd" type="primary" size="small" @click="onAdd('')">添加 </el-button> | ||||
|             <el-button icon="iconfont iconDelete" size="small" @click="removeAll" :disabled="ids.length == 0">删除 </el-button> | ||||
|           </template> | ||||
|  | ||||
|           <!-- 导入导出 --> | ||||
|           <template #right> | ||||
|             <ai-import :instance="instance" :dict="dict" type="apphomesteadinfo" :importParams="{ areaId: user.info && user.info.areaId }" name="宅基地管理" @success="getList()"> | ||||
|               <el-button icon="iconfont iconImport">导入</el-button> | ||||
|             </ai-import> | ||||
|             <ai-download :instance="instance" url="/app/apphomesteadinfo/export" :params="param" fileName="宅基地管理模板" :disabled="tableData.length == 0"> | ||||
|               <el-button icon="iconfont iconExported" :disabled="tableData.length == 0">导出</el-button> | ||||
|             </ai-download> | ||||
|           </template> | ||||
|         </ai-search-bar> | ||||
|  | ||||
|         <ai-table :tableData="tableData" :col-configs="colConfigs" :total="total" ref="aitableex" :current.sync="page.current" :size.sync="page.size" @getList="getList" @selection-change="(v) => (ids = v.map((e) => e.id))"> | ||||
|           <el-table-column slot="locationStatus" label="定位状态" align="center"> | ||||
|             <template slot-scope="{ row }"> | ||||
|               <span style="color:red" v-if="row.locationStatus == 0">{{ dict.getLabel('homesteadLocationStatus', row.locationStatus) }}</span> | ||||
|               <span style="color:green" v-if="row.locationStatus == 1">{{ dict.getLabel('homesteadLocationStatus', row.locationStatus) }}</span> | ||||
|             </template> | ||||
|           </el-table-column> | ||||
|  | ||||
|           <el-table-column slot="options" label="操作" align="center" width="180" fixed="right"> | ||||
|             <template slot-scope="{ row }"> | ||||
|               <el-button type="text" @click="onAdd(row.id)">编辑</el-button> | ||||
|               <el-button type="text" @click="remove(row.id)">删除</el-button> | ||||
|             </template> | ||||
|           </el-table-column> | ||||
|         </ai-table> | ||||
|       </template> | ||||
|     </ai-list> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import { mapState } from 'vuex' | ||||
|  | ||||
| export default { | ||||
|   name: 'List', | ||||
|   props: { | ||||
|     dict: Object, | ||||
|     instance: Function, | ||||
|     params: Object, | ||||
|   }, | ||||
|  | ||||
|   data() { | ||||
|     return { | ||||
|       isAdd: false, | ||||
|       page: { | ||||
|         current: 1, | ||||
|         size: 10, | ||||
|       }, | ||||
|       total: 0, | ||||
|       search: { | ||||
|         locationStatus: '', | ||||
|         name: '', | ||||
|       }, | ||||
|       id: '', | ||||
|       ids: [], | ||||
|       colConfigs: [ | ||||
|         { type: 'selection', width: 100,  align: 'center'}, | ||||
|         { | ||||
|           prop: 'areaName', | ||||
|           label: '村/社区', | ||||
|         }, | ||||
|         { | ||||
|           prop: 'name', | ||||
|           label: '户主', | ||||
|           align: 'center', | ||||
|         }, | ||||
|         { prop: 'phone', label: '联系电话', align: 'center' }, | ||||
|         { | ||||
|           prop: 'sex', | ||||
|           label: '性别', | ||||
|           width: '100', | ||||
|           align: 'center', | ||||
|           render: (h, { row }) => { | ||||
|             return h('span', null, this.dict.getLabel('sex', row.sex)) | ||||
|           }, | ||||
|         }, | ||||
|         { prop: 'age', label: '年龄', align: 'center' }, | ||||
|         { | ||||
|           prop: 'idNumber', | ||||
|           label: '身份证号', | ||||
|           align: 'center', | ||||
|         }, | ||||
|         { prop: 'liveBuildingArea', label: '建筑面积(m²)', align: 'center',width: 120 }, | ||||
|         { | ||||
|           slot: 'locationStatus' | ||||
|         }, | ||||
|         { | ||||
|           slot: 'options', | ||||
|           label: '操作', | ||||
|           align: 'center', | ||||
|         }, | ||||
|       ], | ||||
|       tableData: [], | ||||
|       areaId: '', | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   computed: { | ||||
|     ...mapState(['user']), | ||||
|  | ||||
|     param() { | ||||
|       return { | ||||
|         ...this.search, | ||||
|         areaId: this.user.info?.areaId, | ||||
|         ids: this.ids, | ||||
|       } | ||||
|     }, | ||||
|   }, | ||||
|  | ||||
|   mounted() { | ||||
|     this.areaId = this.user.info.areaId | ||||
|     this.dict.load('homesteadLocationStatus', 'homesteadHouseType', 'homesteadLandType', 'sex').then(() => { | ||||
|       this.getList() | ||||
|     }) | ||||
|   }, | ||||
|  | ||||
|   methods: { | ||||
|     getList() { | ||||
|       this.instance | ||||
|         .post(`/app/apphomesteadinfo/list`, null, { | ||||
|           params: { | ||||
|             ...this.page, | ||||
|             ...this.search, | ||||
|             areaId: this.areaId, | ||||
|           }, | ||||
|         }) | ||||
|         .then((res) => { | ||||
|           if (res.code == 0) { | ||||
|             if(res.data.records.length) { | ||||
|               res.data.records.map((item) => { | ||||
|                 item.idNumber = item.idNumber.substring(0,10) +  '****' + item.idNumber.substring(13,17) | ||||
|               }) | ||||
|             } | ||||
|             this.tableData = res.data.records | ||||
|             this.total = res.data.total | ||||
|           } | ||||
|         }) | ||||
|     }, | ||||
|  | ||||
|     // 添加 | ||||
|     onAdd(id) { | ||||
|       this.$emit('change', { | ||||
|         type: 'add', | ||||
|         params: { | ||||
|           id: id || '', | ||||
|           areaId: this.areaId, | ||||
|         }, | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     // 删除 | ||||
|     remove(id) { | ||||
|       this.$confirm('确定删除该数据?').then(() => { | ||||
|         this.instance.post(`/app/apphomesteadinfo/delete?ids=${id}`).then((res) => { | ||||
|           if (res.code == 0) { | ||||
|             this.$message.success('删除成功!') | ||||
|             this.getList() | ||||
|           } | ||||
|         }) | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     removeAll() { | ||||
|       var id = this.ids.join(',') | ||||
|       this.remove(id) | ||||
|     }, | ||||
|   }, | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .AppPetitionManage { | ||||
|   height: 100%; | ||||
|   .mar-t10{ | ||||
|     margin-top: 10px; | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										1344
									
								
								packages/grid/AppHouseMap/AppHouseMap.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1344
									
								
								packages/grid/AppHouseMap/AppHouseMap.vue
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1429
									
								
								packages/grid/AppHouseMap/AppPopulationDV.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1429
									
								
								packages/grid/AppHouseMap/AppPopulationDV.vue
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										443
									
								
								packages/grid/AppHouseMap/buildingStatistics.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										443
									
								
								packages/grid/AppHouseMap/buildingStatistics.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,443 @@ | ||||
| <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> | ||||
							
								
								
									
										95
									
								
								packages/grid/AppHouseMap/buildingToolBar.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								packages/grid/AppHouseMap/buildingToolBar.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,95 @@ | ||||
| <template> | ||||
|   <section class="buildingToolBar"> | ||||
|     <div class="toolBar"> | ||||
|       <div class="nav" v-for="(op,i) in navs" :key="i" :class="{selected:i==active}" @click="active=i"> | ||||
|         <ai-icon :icon="op.icon"/> | ||||
|         <div>{{ op.name }}</div> | ||||
|       </div> | ||||
|     </div> | ||||
|     <component :is="currentNav.comp" class="toolPane"/> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import BuildingInfo from "./toolBar/buildingInfo"; | ||||
| import CommunityOverview from "./toolBar/communityOverview"; | ||||
| // import NearbyGCS from "./toolBar/nearbyGCS"; | ||||
| import RecentEvents from "./toolBar/recentEvents"; | ||||
|  | ||||
| export default { | ||||
|   name: "buildingToolBar", | ||||
|   components: {RecentEvents, CommunityOverview, BuildingInfo}, | ||||
|   computed: { | ||||
|     navs() { | ||||
|       return [ | ||||
|         {icon: 'icondanweiguanli', name: "单元统计", comp: BuildingInfo}, | ||||
|         {icon: 'icondanweiguanli', name: "单元切换", comp: CommunityOverview}, | ||||
|         // {icon: 'icondanweiguanli', name: "网格员", comp: NearbyGCS}, | ||||
|         // {icon: 'icondanweiguanli', name: "近期事件", comp: RecentEvents}, | ||||
|       ] | ||||
|     }, | ||||
|     currentNav() { | ||||
|       return this.navs[this.active] | ||||
|     } | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       active: 0 | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .buildingToolBar { | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|   gap: 10px; | ||||
|  | ||||
|   .toolBar { | ||||
|     height: 40px; | ||||
|     background: #FFFFFF; | ||||
|     box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.2); | ||||
|     border-radius: 4px; | ||||
|     padding: 4px; | ||||
|     width: 400px; | ||||
|     display: flex; | ||||
|     gap: 8px; | ||||
|     box-sizing: border-box; | ||||
|     align-self: flex-end; | ||||
|  | ||||
|     .nav { | ||||
|       flex: 1; | ||||
|       height: 32px; | ||||
|       color: #3A3A3A; | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|       justify-content: center; | ||||
|       font-size: 12px; | ||||
|       cursor: pointer; | ||||
|  | ||||
|       .AiIcon { | ||||
|         width: 16px; | ||||
|         height: 16px; | ||||
|         margin-right: 4px; | ||||
|       } | ||||
|  | ||||
|       &:hover { | ||||
|         color: #2266FF; | ||||
|       } | ||||
|  | ||||
|       &.selected { | ||||
|         background: #E4F0FF; | ||||
|         color: #2266FF; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .toolPane { | ||||
|     background: #FFFFFF; | ||||
|     box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.1); | ||||
|     border-radius: 4px; | ||||
|     overflow: hidden; | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										239
									
								
								packages/grid/AppHouseMap/toolBar/buildingInfo.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										239
									
								
								packages/grid/AppHouseMap/toolBar/buildingInfo.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,239 @@ | ||||
| <template> | ||||
|   <section class="buildingInfo"> | ||||
|     <ai-title title="人口信息"/> | ||||
|     <div class="infoPane"> | ||||
|       <div class="staZone"> | ||||
|         <div v-for="(value, name) in staData" :key="name"> | ||||
|           <b>{{ value }}</b> | ||||
|           <span>{{ name }}</span> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|     <ai-title title="房屋信息"/> | ||||
|     <div class="infoPane"> | ||||
|       <el-row type="flex" justify="space-between" class="info-item"> | ||||
|         <span>所属社区</span> | ||||
|         <span>{{build.areaName}}</span> | ||||
|       </el-row> | ||||
|       <el-row type="flex" justify="space-between" class="info-item"> | ||||
|         <span>所属小区</span> | ||||
|         <span>{{build.communityName}}</span> | ||||
|       </el-row> | ||||
|       <el-row type="flex" justify="space-between" class="info-item"> | ||||
|         <span>房屋类型</span> | ||||
|         <span>{{root.dict.getLabel("communityBuildingType",build.buildingType)}}</span> | ||||
|       </el-row> | ||||
|       <el-row type="flex" justify="space-between" class="info-item"> | ||||
|         <span>楼长姓名</span> | ||||
|         <span>{{build.managerName}}</span> | ||||
|       </el-row> | ||||
|       <el-row type="flex" justify="space-between" class="info-item"> | ||||
|         <span>联系方式</span> | ||||
|         <span>{{build.managerPhone}}</span> | ||||
|       </el-row> | ||||
|     </div> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import * as echarts from 'echarts' | ||||
|  | ||||
| export default { | ||||
|   name: "buildingInfo", | ||||
|   inject: ['root', 'sta'], | ||||
|   computed: { | ||||
|     chartData() { | ||||
|       return this.root.dict.getDict("residentTipType").map(e => ({ | ||||
|         name: e.dictName, | ||||
|         key: e.dictValue, | ||||
|         color: e.dictColor, | ||||
|         v1: 0 | ||||
|       })) | ||||
|     }, | ||||
|     colConfigs() { | ||||
|       return [ | ||||
|         {prop:"areaName",label:"所属社区"} | ||||
|       ]; | ||||
|     } | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       chart: null, | ||||
|       staData: {}, | ||||
|       tag:{}, | ||||
|       color:{}, | ||||
|       build:{}, | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     initChart(data) { | ||||
|       this.chart = echarts.init(document.getElementById("PersonStaChart")) | ||||
|       let selected = {}, color = [] | ||||
|       this.chartData.map(e => { | ||||
|         selected[e.name] = false | ||||
|         color.push(e.color) | ||||
|       }) | ||||
|       this.chart.setOption({ | ||||
|         grid: {top: 31, right: 0, height: 135}, | ||||
|         tooltip: {}, | ||||
|         legend: { | ||||
|           top: 185, | ||||
|           left: 0, | ||||
|           orient: "vertical", | ||||
|           selected, | ||||
|           itemWidth: 14, | ||||
|           itemHeight: 14, | ||||
|           itemGap: 12, | ||||
|           icon: "rect", | ||||
|           formatter: name => { | ||||
|             let item = data.find(e => this.root.dict.getLabel('residentTipType', e.name) == name) | ||||
|             return `{a|${name}}  {b|${item.v1}}` | ||||
|           }, | ||||
|           textStyle: { | ||||
|             rich: { | ||||
|               a: {color: "#666", width: 123}, | ||||
|               b: {color: "#333", fontWeight: 'bold', align: 'right'} | ||||
|             } | ||||
|           } | ||||
|         }, color, | ||||
|         yAxis: {type: 'value', min: 0, minInterval: 1, axisTick: false, axisLine: false, axisLabel: {color: "#666"}}, | ||||
|         xAxis: {type: 'category', axisTick: false, axisLine: false, axisLabel: false}, | ||||
|         series: data.map(e => ({ | ||||
|           type: 'bar', | ||||
|           barWidth: 8, | ||||
|           barGap: '250%', | ||||
|           name: this.root.dict.getLabel('residentTipType', e.name) | ||||
|         })) | ||||
|       }) | ||||
|       this.chart.on('legendselectchanged', ({selected}) => { | ||||
|         let tips = Object.keys(selected)?.filter(e => selected[e])?.map(e => this.root.dict.getValue('residentTipType', e)) | ||||
|         this.sta?.selectedTips(tips) | ||||
|       }) | ||||
|       this.getChartData(data) | ||||
|     }, | ||||
|     getChartData(data) { | ||||
|       this.chart?.setOption({ | ||||
|         series: data.map(e => ({data: [e.v1]})) | ||||
|       }) | ||||
|     } | ||||
|   }, | ||||
|   created(){ | ||||
|     this.root.dict?.load("communityBuildingType") | ||||
|   }, | ||||
|   mounted() { | ||||
|     this.root.instance.post("/app/appcommunitybuildinginfo/statistics", null, { | ||||
|       params: { | ||||
|         id: this.root.isFormDv ? this.root.info.id : this.$route.query.buildingId, | ||||
|         unitNum: this.root.isFormDv ? this.root.info.unitNumber : this.$route.query.unitNum, | ||||
|       } | ||||
|     }).then(res => { | ||||
|       if (res?.data) { | ||||
|         this.staData = res.data.unit; | ||||
|         this.tag = res.data.tag; | ||||
|         this.color = res.data.color; | ||||
|         this.build = res.data.build; | ||||
|         // this.root.dict.load('residentTipType').then(() => { | ||||
|         //   this.initChart(res.data.lx) | ||||
|         // }) | ||||
|       } | ||||
|     }) | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .buildingInfo { | ||||
|   ::v-deep .infoPane { | ||||
|     box-sizing: border-box; | ||||
|     padding: 10px 20px; | ||||
|  | ||||
|     .info-item{ | ||||
|       height: 32px; | ||||
|       box-sizing: border-box; | ||||
|       padding: 0 12px; | ||||
|       font-size: 12px; | ||||
|       color: #666666; | ||||
|       align-items: center; | ||||
|  | ||||
|       span:last-child{ | ||||
|         color: #333333; | ||||
|       } | ||||
|  | ||||
|       &:nth-child(2n-1){ | ||||
|         background-color: #F3F6F9; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .static-wrap{ | ||||
|       width: 360px; | ||||
|       box-sizing: border-box; | ||||
|       padding-top: 20px; | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|       justify-content: space-between; | ||||
|       flex-wrap: wrap; | ||||
|  | ||||
|       .sta-item{ | ||||
|         width: 46%; | ||||
|         display: flex; | ||||
|         align-items: center; | ||||
|         justify-content: space-between; | ||||
|         margin-bottom: 8px; | ||||
|  | ||||
|         .sta-left{ | ||||
|           display: flex; | ||||
|           align-items: center; | ||||
|           .tag{ | ||||
|             width: 14px; | ||||
|             height: 14px; | ||||
|             background: #DC1739; | ||||
|             border-radius: 2px; | ||||
|             margin-right: 3px; | ||||
|           } | ||||
|           & > label{ | ||||
|             font-size: 12px; | ||||
|             color: #666666; | ||||
|           } | ||||
|         } | ||||
|         .num{ | ||||
|           font-size: 12px; | ||||
|           color: #333333; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     .staZone { | ||||
|       height: 80px; | ||||
|       background: #F5F7F9; | ||||
|       border-radius: 4px; | ||||
|       overflow: hidden; | ||||
|       display: flex; | ||||
|  | ||||
|       & > div { | ||||
|         flex: 1; | ||||
|         min-width: 0; | ||||
|         display: flex; | ||||
|         flex-direction: column; | ||||
|         justify-content: center; | ||||
|         align-items: center; | ||||
|         height: 100%; | ||||
|         font-size: 12px; | ||||
|         color: #333; | ||||
|  | ||||
|         b { | ||||
|           font-size: 24px; | ||||
|           font-family: DINAlternate-Bold, DINAlternate,serif; | ||||
|           color: #2266FF; | ||||
|           margin-bottom: 4px; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|     #PersonStaChart { | ||||
|       width: 100%; | ||||
|       height: 350px; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										116
									
								
								packages/grid/AppHouseMap/toolBar/communityOverview.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								packages/grid/AppHouseMap/toolBar/communityOverview.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,116 @@ | ||||
| <template> | ||||
|   <section class="communityOverview"> | ||||
|     <ai-title title="小区总览"/> | ||||
|     <div class="units" v-if="Object.keys(buildingUnits).length>0"> | ||||
|       <div class="building" v-for="(value,name) in buildingUnits" :key="name"> | ||||
|         <div class="unit" v-for="(op,j) in value" :key="j" @click="sta.selectedBuilding(op,j+1)" | ||||
|              :class="{selected:sta.unitNumber==j+1 && sta.currentBuilding.buildingNumber==name}"> | ||||
|           <b>{{ name}}栋</b> | ||||
|           <div>{{ j+1 }}单元</div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|     <AiEmpty v-else>暂无楼栋信息,请进入【楼栋管理】添加</AiEmpty> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| export default { | ||||
|   name: "communityOverview", | ||||
|   inject: ['root', 'sta'], | ||||
|   computed: { | ||||
|     buildingUnits() { | ||||
|       let obj = {} | ||||
|       this.units.map(e => { | ||||
|         for(let i=0;i<e.unitNumber;i++){ | ||||
|           obj[e.buildingNumber]?.push(e) || (obj[e.buildingNumber] = [e]) | ||||
|         } | ||||
|       }) | ||||
|       return obj; | ||||
|     } | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       units: [] | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     getUnits(communityId) { | ||||
|       this.root.instance.post("/app/appcommunitybuildinginfo/list", null, { | ||||
|         params: { | ||||
|           communityId, | ||||
|           size: 999 | ||||
|         } | ||||
|       }).then(res => { | ||||
|         if (res?.data) { | ||||
|           this.units = res.data.records | ||||
|         } | ||||
|       }) | ||||
|     } | ||||
|   }, | ||||
|   created() { | ||||
|     this.getUnits(this.root.isFormDv ? this.root.info.communityId : this.$route.query.communityId) | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .communityOverview { | ||||
|   max-width: 400px; | ||||
|  | ||||
|   .units { | ||||
|     display: flex; | ||||
|     flex-wrap: wrap; | ||||
|     padding: 0 20px 20px; | ||||
|     align-items: flex-start; | ||||
|  | ||||
|     .building { | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|       height: auto; | ||||
|       flex-wrap: wrap;  | ||||
|  | ||||
|       .unit { | ||||
|         margin-right: 10px; | ||||
|         margin-bottom: 10px; | ||||
|  | ||||
|         &:nth-of-type(5) { | ||||
|           margin-right: 0; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .unit { | ||||
|       width: 64px; | ||||
|       height: 56px; | ||||
|       background: #F8FBFF; | ||||
|       border-radius: 2px 0 0 2px; | ||||
|       border: 1px solid #829CCF; | ||||
|       display: flex; | ||||
|       flex-direction: column; | ||||
|       justify-content: center; | ||||
|       align-items: center; | ||||
|       font-size: 12px; | ||||
|       color: #999; | ||||
|       cursor: pointer; | ||||
|  | ||||
|       b { | ||||
|         color: #424242; | ||||
|       } | ||||
|  | ||||
|       &.selected { | ||||
|         color: #fff; | ||||
|         background: #2266FF; | ||||
|  | ||||
|         b { | ||||
|           color: #fff; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .ai-empty { | ||||
|     height: 240px; | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										129
									
								
								packages/grid/AppHouseMap/toolBar/nearbyGCS.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								packages/grid/AppHouseMap/toolBar/nearbyGCS.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,129 @@ | ||||
| <template> | ||||
|   <section class="nearbyGCS"> | ||||
|     <ai-title title="全部网格员"/> | ||||
|     <div class="radarPane"> | ||||
|       <div class="radar"> | ||||
|         <div class="indicator"/> | ||||
|       </div> | ||||
|       <div class="gcsItem" v-for="(op,i) in userList" :key="i" :style="op.style"> | ||||
|         <i class="dot" :class="{offline:op.offline}"/> | ||||
|         <span>{{ op.name }}</span> | ||||
|         <ai-icon icon="iconIM"/> | ||||
|       </div> | ||||
|     </div> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| export default { | ||||
|   name: "nearbyGCS", | ||||
|   inject: ['root', 'sta'], | ||||
|  | ||||
|   data () { | ||||
|     return { | ||||
|       userList: [] | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   mounted () { | ||||
|     this.getInfo() | ||||
|   }, | ||||
|  | ||||
|   methods: { | ||||
|     getInfo () { | ||||
|       this.root.instance.post('/app/appgirdmemberinfo/queryGirdMemberByBuilding', null, { | ||||
|         params: {buildingId: this.$route.query.buildingId} | ||||
|       }).then(res => { | ||||
|         if (res?.data) { | ||||
|           this.gcsList(res.data) | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
|  | ||||
|     gcsList (data) { | ||||
|       this.userList = data.map(e => ({ | ||||
|         ...e, | ||||
|         style: { | ||||
|           transform: `translate( | ||||
|         ${Math.round(160 * (Math.random() - 0.5))}px, | ||||
|         ${Math.round(160 * (Math.random() - 0.5))}px)`} | ||||
|       })) | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .nearbyGCS { | ||||
|   .radarPane { | ||||
|     width: 100%; | ||||
|     height: 360px; | ||||
|     display: flex; | ||||
|     justify-content: center; | ||||
|     align-items: center; | ||||
|     position: relative; | ||||
|  | ||||
|     .gcsItem { | ||||
|       position: absolute; | ||||
|       width: 92px; | ||||
|       height: 28px; | ||||
|       background: #FFFFFF; | ||||
|       box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1); | ||||
|       border-radius: 16px; | ||||
|       font-size: 12px; | ||||
|       color: #333333; | ||||
|       display: flex; | ||||
|       justify-content: center; | ||||
|       align-items: center; | ||||
|       z-index: 3; | ||||
|       gap: 8px; | ||||
|  | ||||
|       .AiIcon { | ||||
|         width: 16px; | ||||
|         height: 16px; | ||||
|       } | ||||
|  | ||||
|       .dot { | ||||
|         width: 4px; | ||||
|         height: 4px; | ||||
|         background: #30BC77; | ||||
|  | ||||
|         &.offline { | ||||
|           background: #FF4466; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .radar { | ||||
|     width: 320px; | ||||
|     height: 320px; | ||||
|     position: relative; | ||||
|     border-radius: 50%; | ||||
|     overflow: hidden; | ||||
|     background-image: url("https://cdn.cunwuyun.cn/buildSta/radarBg.png"); | ||||
|  | ||||
|     .indicator { | ||||
|       position: absolute; | ||||
|       width: 160px; | ||||
|       height: 160px; | ||||
|       top: 0; | ||||
|       left: 0; | ||||
|       transform-origin: 100% 100%; | ||||
|       background: linear-gradient(190deg, rgba(162, 255, 182, 0.5) 0%, rgba(162, 255, 215, 0) 100%); | ||||
|       border-right: 1px solid #A2FFB6; | ||||
|       animation: radar 5s linear infinite; | ||||
|       z-index: 2; | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| @keyframes radar { | ||||
|   0% { | ||||
|     transform: rotate(0deg) | ||||
|   } | ||||
|   100% { | ||||
|     transform: rotate(360deg) | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										81
									
								
								packages/grid/AppHouseMap/toolBar/recentEvents.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								packages/grid/AppHouseMap/toolBar/recentEvents.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,81 @@ | ||||
| <template> | ||||
|   <section class="recentEvents"> | ||||
|     <ai-title title="楼栋近期相关事件"/> | ||||
|     <div class="recentEvents-list"> | ||||
|       <div class="recentEvents-item" v-for="(item, index) in 4" :key="index"> | ||||
|         <div class="recentEvents-item__top"> | ||||
|           <i>[已解决]</i> | ||||
|           <span>102室与402室矛盾纠纷</span> | ||||
|         </div> | ||||
|         <div class="recentEvents-item__middle"> | ||||
|           <span>102室与402室矛盾纠纷</span> | ||||
|           <em>[张三]</em> | ||||
|           <span>接到了</span> | ||||
|           <em>[矛盾调解]</em> | ||||
|           <span>任务,事件目前</span> | ||||
|           <i>[已完成]</i> | ||||
|         </div> | ||||
|         <div class="recentEvent-item__bottom">2019-06-18 13:35:45</div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </section> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| export default { | ||||
|   name: "recentEvents" | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| .recentEvents { | ||||
|   font-size: 14px; | ||||
|   width: 100%; | ||||
|  | ||||
|   .recentEvents-list { | ||||
|     .recentEvents-item { | ||||
|       border-bottom: 1px solid #E6E8EE; | ||||
|       background: transparent; | ||||
|       padding: 10px; | ||||
|       box-sizing: border-box; | ||||
|       .recentEvent-item__bottom { | ||||
|         color: #999; | ||||
|         font-size: 12px; | ||||
|       } | ||||
|  | ||||
|       &:first-child { | ||||
|         background: #EFF6FF; | ||||
|         border-bottom: none; | ||||
|       } | ||||
|  | ||||
|       &:last-child { | ||||
|         border-bottom: none; | ||||
|       } | ||||
|  | ||||
|       .recentEvents-item__top { | ||||
|         display: flex; | ||||
|       } | ||||
|  | ||||
|       .recentEvents-item__middle { | ||||
|         margin: 6px 0 10px; | ||||
|       } | ||||
|  | ||||
|       span { | ||||
|         color: #666666; | ||||
|       } | ||||
|  | ||||
|       em { | ||||
|         color: #2266FF; | ||||
|         font-style: normal; | ||||
|       } | ||||
|  | ||||
|       i { | ||||
|         font-style: normal; | ||||
|         color: #2EA222; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|  | ||||
| } | ||||
| </style> | ||||
		Reference in New Issue
	
	Block a user