新网格应用调整目录完成
This commit is contained in:
1344
project/grid/AppHouseMap/AppHouseMap.vue
Normal file
1344
project/grid/AppHouseMap/AppHouseMap.vue
Normal file
File diff suppressed because it is too large
Load Diff
1429
project/grid/AppHouseMap/AppPopulationDV.vue
Normal file
1429
project/grid/AppHouseMap/AppPopulationDV.vue
Normal file
File diff suppressed because it is too large
Load Diff
443
project/grid/AppHouseMap/buildingStatistics.vue
Normal file
443
project/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
project/grid/AppHouseMap/buildingToolBar.vue
Normal file
95
project/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
project/grid/AppHouseMap/toolBar/buildingInfo.vue
Normal file
239
project/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
project/grid/AppHouseMap/toolBar/communityOverview.vue
Normal file
116
project/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
project/grid/AppHouseMap/toolBar/nearbyGCS.vue
Normal file
129
project/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
project/grid/AppHouseMap/toolBar/recentEvents.vue
Normal file
81
project/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