Files
dvcp_v2_wechat_app/src/project/weiyang/AppResidentFile/AppResidentFile.vue
2024-07-16 10:12:00 +08:00

697 lines
19 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="AppResidentFile">
<u-navbar back-icon-color="#000" title="居民信息管理" title-color="#000" title-width="300" title-size="32"
:title-bold="true" :background="backgroundNavbar" :is-fixed="true" height="44"></u-navbar>
<div class="header-content-bg">
<img src="https://cdn.sinoecare.com/i/2024/07/12/6690a1303d423.png" alt="">
</div>
<div class="statistics-content" v-if="currentTabBar == 0">
<div class="top-tabs">
<u-tabs :list="tabList" :is-scroll="false" :current="currentTabs" height="96" bg-color="#fff" inactive-color="#222"
active-color="#1D2229" :bar-style="barStyle" font-size="34" @change="change"></u-tabs>
</div>
<div class="statistics-chart" v-if="currentTabs == 0">
<div class="statistics-num">
<div class="item">
<div class="total color-026AF2">{{ groupSum }}</div>
<div class="label">群聊总数</div>
</div>
<div class="item">
<div class="total color-5476A2">{{ todayList1.total }}</div>
<div class="label">群成员</div>
</div>
<div class="item">
<div class="total color-4AC98E">{{ todayList1.increase }}</div>
<div class="label">今日入群</div>
</div>
<div class="item">
<div class="total color-026AF2">{{ todayList1.decrease }}</div>
<div class="label">今日退群</div>
</div>
</div>
<div class="echartes">
<canvas
canvas-id="qtjid"
id="qtjid"
class="e-canvas"
@tap="chartClick"
/>
</div>
</div>
<div class="statistics-chart" v-if="currentTabs == 1">
<div class="statistics-num">
<div class="item">
<div class="total color-026AF2">{{ todayList2.total }}</div>
<div class="label">居民总数</div>
</div>
<div class="item">
<div class="total color-4AC98E">{{ todayList2.increase }}</div>
<div class="label">今日新增</div>
</div>
<div class="item">
<div class="total color-FF8002">{{ todayList2.decrease }}</div>
<div class="label">今日流失</div>
</div>
</div>
<div class="echartes">
<canvas
canvas-id="tjid"
id="tjid"
class="e-canvas"
@tap="chartClick"
/>
</div>
</div>
</div>
<div class="list-content" v-if="currentTabBar == 1">
<!-- <AiTopFixed>
<u-search
placeholder="请输入昵称、姓名"
:show-action="false"
search-icon-color="#ccc"
v-model="search.name"
@search="(page1.current = 1), getList()"
/>
<AiCell>
<b slot="label" class="title"
><i v-html="page1.total || 0" />个居民</b
>
</AiCell>
</AiTopFixed> -->
<div class="search-top">
<u-search placeholder="姓名/联系方式/身份证后6位" v-model="search.name" :show-action="false" bg-color="#F4F5FA" search-icon-color="#F4F5FA"
color="#666" height="72" @search="(page1.current = 1), getList()" ></u-search>
</div>
<div class="user-list-content">
<!-- <AiCell
v-for="item in data"
:key="item.id"
@click.native="showResident(item)"
>
<template #label>
<AiImage :src="item.avatar" preview />
</template>
<div class="card wrap start" flex>
<b>{{ item.name }}</b>
<div flex class="tag" v-for="(tag, j) in item.tags" :key="j">
{{ tag.tagName }}
</div>
<div
class="realName"
shrink
v-html="`真实姓名:${item.realName || '-'}`"
/>
</div>
</AiCell> -->
<div class="item" v-for="item in data" :key="item.id" @click.native="showResident(item)">
<div class="left-img">
<img :src="item.avatar" alt="">
</div>
<div class="right-info">
<div class="name-flex">
<div>{{ item.name }}</div>
<p>
<span flex class="tag" v-for="(tag, j) in item.tags" :key="j">
{{ tag.tagName }}
</span>
</p>
</div>
<p class="item-idnumber">真实姓名{{ item.idNumber }} {{item.realName }}</p>
</div>
</div>
</div>
</div>
<div class="list-content" v-if="currentTabBar == 2">
<!-- <AiTopFixed>
<u-search
placeholder="请输入群名、群主名"
:show-action="false"
search-icon-color="#ccc"
v-model="search.name"
@search="(page2.current = 1), getList()"
/>
<AiCell>
<b slot="label" class="title"
><i v-html="page2.total || 0" />个居民群</b
>
</AiCell>
</AiTopFixed> -->
<div class="search-top">
<u-search placeholder="请输入群名、群主名" v-model="search.name" :show-action="false" bg-color="#F4F5FA" search-icon-color="#F4F5FA"
color="#666" height="72" @search="(page2.current = 1), getList()" ></u-search>
</div>
<!-- <div class="mainPane">
<AiCell
v-for="(item, i) in list"
:key="i"
@click.native="toGroupList(item)"
>
<template #label>
<AiImage :src="item.avatar" preview />
</template>
<div class="card column start" flex>
<div flex class="groupName">
<b>{{ item.name || "群聊" }}</b>
<div class="personCount" v-if="item.personCount">
({{ item.personCount }})
</div>
</div>
<div class="owner" v-html="`群主:${item.ownerName}`" />
<div flex class="trends">
<div flex v-html="`今日入群:<em>${item.increase || 0}</em>`" />
<div flex v-html="`今日退群:<p>${item.decrease || 0}</p>`" />
</div>
</div>
</AiCell>
</div> -->
<div class="user-list-content">
<div class="item group-item" v-for="item in list" :key="item.id" @click.native="toGroupList(item)">
<div class="left-img">
<img src="https://cdn.sinoecare.com/i/2024/07/12/66908ea79780f.png" alt="">
</div>
<div class="right-info">
<div class="name-flex">
<div>{{ item.name || "群聊" }}</div>
</div>
<p class="item-idnumber">{{ item.personCount }} | 群主:{{ item.ownerName }}</p>
</div>
</div>
</div>
</div>
<div class="footer-tabs">
<div class="item" @click="changeTab(index)" v-for="(item, index) in lists" :key="index">
<img :src="currentTabBar == index ? item.selectedIconPath : item.iconPath" alt=""/>
<p :class="currentTabBar == index ? 'color-3267F0' : ''">{{ item.text }}</p>
</div>
</div>
</div>
</template>
<script>
import uCharts from "./components/echarts/u-charts.min.js";
var uChartsInstance = {};
import { mapState } from "vuex";
export default {
name: "AppResidentFile",
appName: "居民信息管理",
customNavigation: true,
data() {
return {
backgroundNavbar: {
background: 'url(https://cdn.sinoecare.com/i/2024/07/12/6690a1309c7d3.png) no-repeat',
backgroundSize: 'cover',
},
lists: [
{
iconPath: "https://cdn.sinoecare.com/i/2024/07/10/668dec966fb64.png",
selectedIconPath:
"https://cdn.sinoecare.com/i/2024/07/10/668dec96d5b3a.png",
text: "统计分析",
customIcon: false,
},
{
iconPath: "https://cdn.sinoecare.com/i/2024/07/10/668dec9437d53.png",
selectedIconPath:
"https://cdn.sinoecare.com/i/2024/07/10/668dec960242f.png",
text: "居民列表",
customIcon: false,
},
{
iconPath: "https://cdn.sinoecare.com/i/2024/07/10/668dec94c98d4.png",
selectedIconPath:
"https://cdn.sinoecare.com/i/2024/07/10/668dec957e497.png",
text: "居民群列表",
customIcon: false,
},
],
currentTabBar: 0,
currentTabs: 0,
tabList: [
{
name: "居民群统计",
},
{
name: "居民统计",
},
],
barStyle: {
'width': '20px',
'height': '4px',
'border-radius': '3px',
'bottom': '-4px',
'background': '#026AF2'
},
Echarts1: null,
Echarts2: null,
areaId: "",
current: 1,
keyword: "",
data: [],
search: { name: "" },
list: [],
weekList: [],
groupSum: "",
todayList1: [],
todayList2: [],
counts1: "",
counts2: "",
page2: { current: 1, size: 10, total: 0 },
search2: { name: "" },
page1: { current: 1, size: 10, total: 0 },
search1: { name: "" },
cWidth: 750,
cHeight: 500,
};
},
computed: {
...mapState(["user", "global"]),
},
onLoad() {
//this.Echarts1 = echarts.init(this.$refs.echarts1)
// this.getServerData()
this.areaId = this.user.areaId;
this.getEchart1();
this.page1.current == 1;
this.getList();
},
onShow() {
uni.setNavigationBarColor({
frontColor: 'black',
backgroundColor: '#ffffff'
})
},
methods: {
drawCharts(id, data) {
const ctx = uni.createCanvasContext(id, this);
uChartsInstance[id] = new uCharts({
type: "line",
context: ctx,
width: 346,
height: 232,
categories: data.categories,
series: data.series,
animation: true,
background: "#FFFFFF",
color: ["#4B87FE", "#4AC98E", "#FF8002"],
padding: [15, 10, 0, 15],
enableScroll: false,
legend: {},
xAxis: {
disableGrid: true,
},
yAxis: {
gridType: "dash",
dashLength: 2,
},
extra: {
line: {
type: "straight",
width: 2,
activeType: "hollow",
},
},
});
},
chartClick(e) {
uChartsInstance[e.target.id].showToolTip(e);
},
// 居民列表
getList() {
this.$instance
.post("/app/wxcp/wxcustomer/list", null, {
params: { ...this.page1, ...this.search, type: 1 },
})
.then((res) => {
if (res?.data) {
if (this.page1.current > 1) {
this.data = [...this.data, ...res.data.records];
} else this.data = res.data.records;
this.page1.total = res.data.total;
}
});
},
// reachBottom() {
// if (this.page1.total > this.list.length) {
// this.page1.current++
// this.getList()
// }
// },
showResident({ id }) {
id &&
uni.navigateTo({
url: "./resident?id=" + id,
});
},
// 居民群列表
getList2() {
this.$instance
.post("/app/wxcp/wxgroup/list", null, {
params: { ...this.page2, ...this.search },
})
.then((res) => {
if (res?.data) {
let meta = res.data.records?.map((e) => ({
...e,
avatar: e?.avatar || this.$cdn + "groupAvatar.png",
}));
if (this.page2.current > 1) {
this.list = [...this.list, ...meta];
} else this.list = meta;
this.page2.total = res.data.total;
}
});
},
// reachBottom() {
// if (this.page2.total > this.list.length) {
// this.page2.current = this.page2.current + 1
// this.getList2()
// }
// },
toGroupList(item) {
uni.navigateTo({
url: `./GroupList?id=${item.id}`,
});
},
// 居民群统计
getEchart1() {
this.$instance.post(`/app/wxcp/wxgroup/groupStatistic`).then((res) => {
if (res.code === 0) {
this.weekList = res.data.list;
this.groupSum = res.data.groupSum;
this.todayList1 = res.data.today;
var chartData = {
categories: Object.keys(this.weekList).map((e) =>
e.substring(e.length - 5, e.length)
),
series: [
{
name: "居民总数",
data: Object.values(this.weekList).map((e) => e.total),
},
{
name: "入群人数",
data: Object.values(this.weekList).map((e) => e.increase),
},
{
name: "退群人数",
data: Object.values(this.weekList).map((e) => e.decrease),
},
],
};
this.drawCharts("qtjid", chartData);
}
});
},
// 居民统计
getEchart2() {
this.$instance
.post(
`/app/wxcp/wxcustomerlog/customerStatistic?areaId=${this.user.areaId}`
)
.then((res) => {
if (res.code === 0) {
this.todayList2 = res.data.today;
var chartData = {
categories: Object.keys(res.data.list).map((e) =>
e.substring(e.length - 5, e.length)
),
series: [
{
name: "居民总数",
data: Object.values(res.data.list).map((e) => e.total),
},
{
name: "新增居民数",
data: Object.values(res.data.list).map((e) => e.increase),
},
{
name: "流失居民数",
data: Object.values(res.data.list).map((e) => e.decrease),
},
],
};
console.log(chartData);
this.drawCharts("tjid", chartData);
}
});
},
changeTab(e) {
this.currentTabBar = e;
if (this.currentTabBar == 0) {
this.getList();
this.$nextTick(() => {
if (this.currentTabs == 0) {
this.getEchart1();
}
if (this.currentTabs == 1) {
this.getEchart2();
}
});
}
if (this.currentTabBar == 1) {
this.page1.current == 1;
this.getList();
}
if (this.currentTabBar == 2) {
this.page2.current == 1;
this.getList2();
}
},
change(index) {
this.currentTabs = index;
this.$nextTick(() => {
if (index == 0) {
this.getEchart1();
} else {
this.getEchart2();
}
});
},
},
onReachBottom() {
if (this.currentTabBar == 1) {
this.page1.current++;
this.getList();
}
if (this.currentTabBar == 2) {
this.page2.current++;
this.getList2();
}
},
};
</script>
<style scoped lang="scss">
uni-page-body {
height: 100%;
}
.AppResidentFile {
height: 100%;
.header-content-bg {
width: 100%;
position: relative;
img {
width: 100%;
height: 592px;
position: absolute;
z-index: -1;
}
}
.statistics-content {
padding-bottom: 216px;
.top-tabs {
padding: 32px;
box-sizing: border-box;
::v-deep .u-tabs {
border-radius: 16px;
}
}
.statistics-chart {
padding: 0 32px;
.statistics-num {
display: flex;
background: #fff;
width: 100%;
padding: 36px 0;
border-radius: 16px;
.item {
flex: 1;
text-align: center;
.total {
line-height: 56px;
font-family: DINAlternate-Bold;
font-weight: 700;
font-size: 48px;
margin-bottom: 10px;
}
.label {
line-height: 40px;
font-family: PingFangSC-Regular;
font-size: 28px;
color: #666;
}
.color-026AF2{
color: #026AF2;
}
.color-5476A2{
color: #5476A2;
}
.color-4AC98E{
color: #4AC98E;
}
.color-FF8002{
color: #FF8002;
}
}
}
.echartes {
background: #fff;
box-sizing: border-box;
width: 686px;
height: 528px;
background: #fff;
border-radius: 16px;
margin: 32px 0 0 0;
padding: 32px 32px 32px 0;
box-sizing: border-box;
.e-canvas {
width: 100%;
height: 100%;
}
}
}
}
.list-content {
width: 686px;
height: calc(100% - 216px);
background: #FFF;
border-radius: 16px;
margin: 32px 0 0 32px;
position: relative;
.search-top {
position: absolute;
top: 0;
left: 0;
padding: 28px 32px;
width: 686px;
box-sizing: border-box;
background-color: #fff;
z-index: 99;
}
.user-list-content {
background-color: #fff;
padding-top: 128px;
.item {
display: flex;
padding: 24px 32px 0;
box-sizing: border-box;
.left-img {
width: 112px;
img {
width: 80px;
height: 80px;
border-radius: 50%;
}
}
.right-info {
width: calc(100% - 112px);
padding-bottom: 24px;
border-bottom: 1px solid #eee;
.name-flex {
display: flex;
justify-content: space-between;
margin-bottom: 8px;
div {
font-family: PingFangSC-Medium;
font-weight: 500;
font-size: 32px;
color: #333;
line-height: 44px;
}
p {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
width: 252px;
line-height: 44px;
font-family: PingFangSC-Regular;
font-size: 28px;
color: #999;
text-align: right;
}
}
.item-idnumber {
line-height: 36px;
font-family: PingFangSC-Regular;
font-size: 26px;
color: #999;
}
}
}
.group-item {
.left-img {
width: 136px;
img {
width: 112px;
height: 112px;
border-radius: 4px;
}
}
.right-info {
width: calc(100% - 136px);
}
}
}
}
.footer-tabs {
width: 100%;
height: 168px;
background: #fff;
border-top: 1px solid #ddd;
position: fixed;
bottom: 0;
left: 0;
display: flex;
.item {
flex: 1;
text-align: center;
img {
width: 56px;
height: 56px;
margin-top: 8px;
}
p {
font-size: 22px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #c4cad4;
line-height: 8px;
}
.color-3267F0 {
color: #3267f0;
}
}
}
}
</style>