除地图和对接数据外已完成

This commit is contained in:
aixianling
2023-10-23 16:32:13 +08:00
parent 1420676c7c
commit 4ec643dd1a
9 changed files with 323 additions and 28 deletions

View File

@@ -14,7 +14,7 @@
</div> </div>
<div class="chart"> <div class="chart">
<div class="title">群活跃率7</div> <div class="title">群活跃率7</div>
<ai-echart :ops="chart" :data="calcProgress()"> <ai-echart :ops="chart" :data="calcProgress(chartData)">
<div class="legend"> <div class="legend">
<ai-highlight v-for="item in chartData" :key="item.name" :content="`@v${item.value}`" <ai-highlight v-for="item in chartData" :key="item.name" :content="`@v${item.value}`"
:value="item.name" color="#9BB7D4" class="flex center mar-b8"/> :value="item.name" color="#9BB7D4" class="flex center mar-b8"/>
@@ -23,9 +23,9 @@
</div> </div>
<div class="chart"> <div class="chart">
<div class="title">人员活跃7</div> <div class="title">人员活跃7</div>
<ai-echart :ops="chart" :data="calcProgress()"> <ai-echart :ops="chart" :data="calcProgress(chartData2)">
<div class="legend"> <div class="legend">
<ai-highlight v-for="item in chartData" :key="item.name" :content="`@v${item.value}`" <ai-highlight v-for="item in chartData2" :key="item.name" :content="`@v${item.value}`"
:value="item.name" color="#9BB7D4" class="flex center mar-b8"/> :value="item.name" color="#9BB7D4" class="flex center mar-b8"/>
</div> </div>
</ai-echart> </ai-echart>
@@ -62,8 +62,8 @@
<div class="right"> <div class="right">
<fd-card label="功德银行"> <fd-card label="功德银行">
<template #right> <template #right>
<div class="shortcut" v-for="(v,k) in shortcuts" :key="k" @click="shortcut=k" <div class="shortcut" v-for="cut in shortcuts" :key="cut.k" @click="shortcut=cut.k"
:class="{active:shortcut==k}" v-text="v"/> :class="{active:shortcut==cut.k}" v-text="cut.v"/>
</template> </template>
<div class="boxSta flex"> <div class="boxSta flex">
<div class="flex text"> <div class="flex text">
@@ -101,6 +101,22 @@
</fd-card> </fd-card>
</div> </div>
</ai-dv-wrapper> </ai-dv-wrapper>
<fd-dialog v-model="dialog" :title="detail.eventType">
<div v-if="detail.header" class="contentHead" v-html="detail.header"/>
<el-row type="flex" class="fill">
<el-carousel v-if="detail.imgs" class="fill">
<el-carousel-item v-for="(img,i) in detail.imgs" :key="i">
<el-image :src="img" :preview-src-list="detail.imgs"/>
</el-carousel-item>
</el-carousel>
<fd-scrollbar v-if="detail.form" class="fill mar-l24">
<fd-item v-for="(v,k) in detail.form" :key="k" :label="k" :value="v"/>
</fd-scrollbar>
<fd-scrollbar v-if="detail.content" class="fill mar-l14">
<div v-html="detail.content"/>
</fd-scrollbar>
</el-row>
</fd-dialog>
</ai-fit-view> </ai-fit-view>
</section> </section>
</template> </template>
@@ -115,11 +131,17 @@ import AiWrapper from "dui/packages/basic/AiWrapper.vue";
import Vue from "vue"; import Vue from "vue";
import {scrollBoard} from "@jiaminghi/data-view" import {scrollBoard} from "@jiaminghi/data-view"
import FdMap from "./components/fdMap.vue"; import FdMap from "./components/fdMap.vue";
import FdDialog from "./components/fdDialog.vue";
import FdItem from "./components/fdItem.vue";
import FdScrollbar from "./components/fdScrollbar.vue";
export default { export default {
name: "AppBIBoard", name: "AppBIBoard",
label: "丰都指挥舱", label: "丰都指挥舱",
components: {FdMap, AiWrapper, AiInfoItem, AiHighlight, AiEchart, FdCard, FengduHead, AiFitView}, components: {
FdScrollbar,
FdItem, FdDialog, FdMap, AiWrapper, AiInfoItem, AiHighlight, AiEchart, FdCard, FengduHead, AiFitView
},
props: { props: {
instance: Function, instance: Function,
dict: Object dict: Object
@@ -129,12 +151,7 @@ export default {
areaId: '', areaId: '',
scale: 1, scale: 1,
fullscreen: false, fullscreen: false,
sta: { sta: {},
群总数: 5118,
群主人数: 956,
'活跃群成员(30天)': '214,098',
'群消息(30天)': '1,214,098',
},
chart: { chart: {
legend: {show: false}, legend: {show: false},
series: { series: {
@@ -186,9 +203,10 @@ export default {
}, },
}, },
chartData: [ chartData: [
{name: "活跃居民群", value: 3502}, // {name: "活跃居民群", value: 3502},
{name: "全部居民群", value: 5118}, // {name: "全部居民群", value: 5118},
], ],
chartData2: [],
volunteers: { volunteers: {
团队数量: 125, 团队数量: 125,
志愿者数量: 13, 志愿者数量: 13,
@@ -257,18 +275,28 @@ export default {
// ['<div class="timeRow">2023-10-18 14:55:32</div>', '三角路社区居民-陈思宇在丰收号小程序中进行了物品兑换'], // ['<div class="timeRow">2023-10-18 14:55:32</div>', '三角路社区居民-陈思宇在丰收号小程序中进行了物品兑换'],
] ]
}, },
shortcut: 0, shortcut: 3,
GongdeBank: {}, GongdeBank: {},
map: null map: null,
dialog: false,
detail: {}
} }
}, },
computed: { computed: {
tablePages: v => Math.ceil(v.volunteerConfig.data.length / v.volunteerConfig.rowNum) || 0, tablePages: v => Math.ceil(v.volunteerConfig.data.length / v.volunteerConfig.rowNum) || 0,
shortcuts: () => Object.assign({0: '昨日', 1: '近七天', 2: '近30天', 3: '近一年'}) shortcuts: () => [
{k: '3', v: '昨日'},
{k: '0', v: '近七天'},
{k: '1', v: '近30天'},
{k: '2', v: '近一年'},
]
}, },
watch: { watch: {
shortcut() { shortcut() {
this.getGdyh(this.areaId) this.getGdyh(this.areaId)
},
dialog(v) {
!v && (this.detail = {})
} }
}, },
methods: { methods: {
@@ -278,8 +306,8 @@ export default {
handleSetting(v) { handleSetting(v) {
this.$refs.fddv.dialog = v this.$refs.fddv.dialog = v
}, },
calcProgress() { calcProgress(data = []) {
const value = (this.chartData[0].value / this.chartData.at(-1).value * 100).toFixed(0) const value = data.length > 0 ? (data[0].value / data.at(-1).value * 100).toFixed(0) : 0
return [{value}] return [{value}]
}, },
watchTablePageChange(c = 0) { watchTablePageChange(c = 0) {
@@ -312,15 +340,29 @@ export default {
getRealTimeDynamic(areaId) { getRealTimeDynamic(areaId) {
this.instance.post("/app/fdDiy/realTimeDynamic", null, {params: {areaId}}).then(res => { this.instance.post("/app/fdDiy/realTimeDynamic", null, {params: {areaId}}).then(res => {
if (res?.data) { if (res?.data) {
const data = res.data.map(e => [`<div class="timeRow">${e.eventTime}</div>`, `<div class="flex">${e.bizId ? e.description.replace(e.type, `<div class="blue">${e.type}</div>`) : e.description}</div>`]) const meta = res.data,
this.realtimeEvents = {...this.realtimeEvents, data, meta: res.data} data = meta.map(e => [`<div class="timeRow">${e.eventTime}</div>`, `<div class="flex">${e.bizId ? e.description.replace(e.type, `<div class="blue">${e.type}</div>`) : e.description}</div>`])
this.realtimeEvents = {...this.realtimeEvents, data, meta}
} }
}) })
}, },
getWxGroupOverview(areaId) { getWxGroupOverview(areaId) {
this.instance.post("/app/fdDiy/wxGroupOverview", null, {params: {areaId}}).then(res => { this.instance.post("/app/fdDiy/wxGroupOverview", null, {params: {areaId}}).then(res => {
if (res?.data) { if (res?.data) {
const {群数量 = 0, 群主人数 = 0, 群成员数量 = 0} = res.data
this.sta = {
群数量, 群主人数,
'群人员活跃数(30天)': Number(res.data['群人员活跃数(30天)']).toLocaleString(),
'群消息数(30天)': Number(res.data['群消息数(30天)']).toLocaleString(),
}
this.chartData = [
{name: "活跃居民群", value: Math.ceil(res.data["活跃居民群数量(7天)"] / 7)},
{name: "全部居民群", value: 群数量},
]
this.chartData2 = [
{name: "活跃居民数", value: res.data["活跃群成员数量(7天)"]},
{name: "群成员数量", value: 群成员数量},
]
} }
}) })
}, },
@@ -360,22 +402,83 @@ export default {
const row = this.realtimeEvents.meta[rowIndex] const row = this.realtimeEvents.meta[rowIndex]
if (row.bizId) { if (row.bizId) {
const action = { const action = {
积分申请: "", 积分申请: "/app/appintegraluserapply/queryDetailById",
物品兑换: "", 物品兑换: "/app/appintegralsupermarketorder/queryDetailById",
精选动态: "", 精选动态: "/app/appcontentinfo/queryDetailById",
}[row.type] }[row.type]
this.instance.post(action, null, {params: {id: row.bizId}}).then(res => { this.instance.post(action, null, {params: {id: row.bizId}}).then(res => {
if (res?.data) { if (res?.data) {
this.dialog = true
if (row.type == '积分申请') {
const {
applyItemName: 事件类型,
integralUserName: 申请人,
areaName: 所属地区,
createTime: 申请时间,
girdName: 所属网格,
content: 事件描述,
applyIntegral: 积分值,
phone: 手机号,
status,
files
} = res.data
this.detail.imgs = files?.map(e => e.accessUrl)
this.detail.form = {
事件类型,
申请人,
所属地区,
申请时间,
事件描述,
积分值,
手机号,
所属网格,
状态: `<div class="statusTag ${status > 0 ? 'success' : ''}">${this.dict.getLabel('appIntegralApplyEventStatus', status)}</div>`
}
} else if (row.type == '物品兑换') {
const {
status,
examineUserName: 核销人,
examineTime: 核销时间,
goodsPicUrl,
integralUserName: 兑换人,
goodsTitle: 兑换商品,
quantity: 数量,
usedIntegral: 消耗积分,
createTime: 兑换时间,
agentOrder
} = res.data
this.detail.imgs = [goodsPicUrl].flat().filter(Boolean) || []
this.detail.form = {
兑换人,
兑换商品,
数量,
消耗积分,
是否代兑换: this.dict.getLabel("yesOrNo", agentOrder),
兑换时间,
状态: `<div class="statusTag ${status > 0 ? 'success' : ''}">${this.dict.getLabel('appIntegralApplyEventStatus', status)}</div>`,
核销人,
核销时间
}
} else if (row.type == '精选动态') {
const {content, files, title, createUserName, girdName} = res.data
this.detail.imgs = files?.map(e => e.accessUrl)
this.detail.content = content
this.detail.header = ` <b>${title}</b>
<div class="flex normal mar-t8">
<div>${girdName}</div>
<div class="mar-l8">${createUserName}</div>
</div>`
}
this.detail = {eventType: row.type, ...this.detail}
} }
}) })
} }
console.log(row)
} }
}, },
created() { created() {
Vue.use(scrollBoard) Vue.use(scrollBoard)
this.getData() this.getData()
this.dict.load('appIntegralApplyEventStatus', 'yesOrNo')
}, },
mounted() { mounted() {
this.watchTablePageChange() this.watchTablePageChange()
@@ -602,5 +705,32 @@ export default {
} }
} }
} }
:deep(.statusTag ) {
padding: 2px 8px;
color: #FFB300;
background: #ffcb5224;
&.success {
color: #07B794;
background: #13f6c924;
}
}
:deep(.contentHead) {
width: 100%;
height: 89px;
background: url("./assets/contentHead.png") no-repeat;
margin-top: 16px;
margin-bottom: 14px;
padding: 16px;
background-size: 100% 89px;
& > b {
font-size: 16px;
color: #02FEFF;
letter-spacing: 0;
}
}
} }
</style> </style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -0,0 +1,71 @@
<template>
<section class="fdDialog">
<div class="dialog" v-if="visible">
<div class="header mar-b8" v-text="title"/>
<div class="closeIcon" @click="$emit('visible',false)"/>
<div class="content">
<slot/>
</div>
</div>
</section>
</template>
<script>
export default {
name: "fdDialog",
model: {
event: "visible",
prop: "visible"
},
props: {
visible: Boolean,
title: {default: "弹窗标题"}
},
data() {
return {}
},
methods: {},
}
</script>
<style scoped lang="scss">
.fdDialog {
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
z-index: 202310231147;
.dialog {
position: relative;
background: url("../assets/dialogBg.png") no-repeat;
background-size: 100% 100%;
width: 577px;
padding: 0 24px 24px;
.closeIcon {
background: url("../assets/closeIcon.png") no-repeat;
width: 24px;
height: 24px;
position: absolute;
right: 13px;
top: 30px;
cursor: pointer;
}
.header {
height: 54px;
display: flex;
line-height: 54px;
font-weight: 600;
font-size: 16px;
color: #FFFFFF;
letter-spacing: 0;
}
.content {
height: calc(100% - 54px);
display: flex;
flex-direction: column;
}
}
}
</style>

View File

@@ -0,0 +1,50 @@
<template>
<section class="fdItem">
<label v-text="label"/>
<div class="content fill">
<slot v-if="$slots.default"/>
<div v-else-if="value" v-html="value"/>
</div>
</section>
</template>
<script>
export default {
name: "fdItem",
props: {
label: String,
value: {default: null}
},
}
</script>
<style scoped lang="scss">
.fdItem {
display: flex;
justify-content: space-between;
align-items: baseline;
font-size: 14px;
margin-bottom: 8px;
&:last-of-type {
margin-bottom: 0;
}
& > label {
flex-shrink: 0;
color: #FFFFFF;
text-align: right;
&:after {
content: "";
}
}
.content {
display: flex;
align-items: center;
justify-content: flex-end;
text-align: right;
margin-left: 8px;
color: #FFD324;
}
}
</style>

View File

@@ -38,7 +38,9 @@ export default {
}, },
label: { label: {
show: true, show: true,
color: '#02FEFF' color: '#02FEFF',
fontSize: 16,
fontFamily: 'PingFang-SC'
}, },
emphasis: { emphasis: {
disabled: true disabled: true

View File

@@ -0,0 +1,38 @@
<template>
<section class="fdScrollbar">
<slot/>
</section>
</template>
<script>
export default {
name: "fdScrollbar",
data() {
return {}
},
methods: {},
}
</script>
<style scoped lang="scss">
.fdScrollbar {
overflow-x: hidden;
overflow-y: auto;
scrollbar-width: none;
margin-right: -5px;
position: relative;
&::-webkit-scrollbar {
background: transparent;
position: absolute;
right: 0;
top: 0;
bottom: 0;
width: 6px;
border-radius: 6px;
}
&:hover::-webkit-scrollbar-thumb {
border-radius: 10px;
background: #0C3A55;
}
}
</style>

View File

@@ -318,6 +318,10 @@ div[flex], .flex {
&.center { &.center {
justify-content: center; justify-content: center;
} }
&.normal {
align-items: unset;
}
} }
.fill { .fill {