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

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 class="chart">
<div class="title">群活跃率7</div>
<ai-echart :ops="chart" :data="calcProgress()">
<ai-echart :ops="chart" :data="calcProgress(chartData)">
<div class="legend">
<ai-highlight v-for="item in chartData" :key="item.name" :content="`@v${item.value}`"
:value="item.name" color="#9BB7D4" class="flex center mar-b8"/>
@@ -23,9 +23,9 @@
</div>
<div class="chart">
<div class="title">人员活跃7</div>
<ai-echart :ops="chart" :data="calcProgress()">
<ai-echart :ops="chart" :data="calcProgress(chartData2)">
<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"/>
</div>
</ai-echart>
@@ -62,8 +62,8 @@
<div class="right">
<fd-card label="功德银行">
<template #right>
<div class="shortcut" v-for="(v,k) in shortcuts" :key="k" @click="shortcut=k"
:class="{active:shortcut==k}" v-text="v"/>
<div class="shortcut" v-for="cut in shortcuts" :key="cut.k" @click="shortcut=cut.k"
:class="{active:shortcut==cut.k}" v-text="cut.v"/>
</template>
<div class="boxSta flex">
<div class="flex text">
@@ -101,6 +101,22 @@
</fd-card>
</div>
</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>
</section>
</template>
@@ -115,11 +131,17 @@ import AiWrapper from "dui/packages/basic/AiWrapper.vue";
import Vue from "vue";
import {scrollBoard} from "@jiaminghi/data-view"
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 {
name: "AppBIBoard",
label: "丰都指挥舱",
components: {FdMap, AiWrapper, AiInfoItem, AiHighlight, AiEchart, FdCard, FengduHead, AiFitView},
components: {
FdScrollbar,
FdItem, FdDialog, FdMap, AiWrapper, AiInfoItem, AiHighlight, AiEchart, FdCard, FengduHead, AiFitView
},
props: {
instance: Function,
dict: Object
@@ -129,12 +151,7 @@ export default {
areaId: '',
scale: 1,
fullscreen: false,
sta: {
群总数: 5118,
群主人数: 956,
'活跃群成员(30天)': '214,098',
'群消息(30天)': '1,214,098',
},
sta: {},
chart: {
legend: {show: false},
series: {
@@ -186,9 +203,10 @@ export default {
},
},
chartData: [
{name: "活跃居民群", value: 3502},
{name: "全部居民群", value: 5118},
// {name: "活跃居民群", value: 3502},
// {name: "全部居民群", value: 5118},
],
chartData2: [],
volunteers: {
团队数量: 125,
志愿者数量: 13,
@@ -257,18 +275,28 @@ export default {
// ['<div class="timeRow">2023-10-18 14:55:32</div>', '三角路社区居民-陈思宇在丰收号小程序中进行了物品兑换'],
]
},
shortcut: 0,
shortcut: 3,
GongdeBank: {},
map: null
map: null,
dialog: false,
detail: {}
}
},
computed: {
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: {
shortcut() {
this.getGdyh(this.areaId)
},
dialog(v) {
!v && (this.detail = {})
}
},
methods: {
@@ -278,8 +306,8 @@ export default {
handleSetting(v) {
this.$refs.fddv.dialog = v
},
calcProgress() {
const value = (this.chartData[0].value / this.chartData.at(-1).value * 100).toFixed(0)
calcProgress(data = []) {
const value = data.length > 0 ? (data[0].value / data.at(-1).value * 100).toFixed(0) : 0
return [{value}]
},
watchTablePageChange(c = 0) {
@@ -312,15 +340,29 @@ export default {
getRealTimeDynamic(areaId) {
this.instance.post("/app/fdDiy/realTimeDynamic", null, {params: {areaId}}).then(res => {
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>`])
this.realtimeEvents = {...this.realtimeEvents, data, meta: res.data}
const 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) {
this.instance.post("/app/fdDiy/wxGroupOverview", null, {params: {areaId}}).then(res => {
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]
if (row.bizId) {
const action = {
积分申请: "",
物品兑换: "",
精选动态: "",
积分申请: "/app/appintegraluserapply/queryDetailById",
物品兑换: "/app/appintegralsupermarketorder/queryDetailById",
精选动态: "/app/appcontentinfo/queryDetailById",
}[row.type]
this.instance.post(action, null, {params: {id: row.bizId}}).then(res => {
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() {
Vue.use(scrollBoard)
this.getData()
this.dict.load('appIntegralApplyEventStatus', 'yesOrNo')
},
mounted() {
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>

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: {
show: true,
color: '#02FEFF'
color: '#02FEFF',
fontSize: 16,
fontFamily: 'PingFang-SC'
},
emphasis: {
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>