ahyd_DIB/pages/commercialBI/guestPortrait.vue
2023-04-13 20:55:51 +08:00

475 lines
18 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="main">
<header-top :bgUrl="bgUrl" :menu="menu" :topBg="topBg" :bgColor="bgColor" :title="title" :page="page" :backType="backType" :analyseInfo="analyseInfo"
:serverpartName="serviceInfo.SERVERPART_NAME" :spregionTypeName="serviceInfo.SPREGIONTYPE_NAME" :serviceInfo="serviceInfo"/>
<div class="charts">
<div class="chartsItem">
<div style="display: flex;align-items: center;justify-content: space-between">
<p class="title">{{thisMonth?thisMonth:'-'}}月客单分析</p>
<div class="item">
<text class="value">{{time}}</text>
</div>
</div>
<div v-if="customer">
<customer-first :analyseInfo="{analysisins_type: 1202,analysisins_format: 2000}" :data="customer" />
</div>
<no-data v-else />
</div>
<div class="chartsItem" style="margin-top: 32px">
<div class="time">
<div class="select">
<picker mode="date" fields="month" :value="single" :end="endData" @change="bindDateChange" >
<view class="time">
<view class="uni-input" style="background: transparent;padding: 0;height:100%">{{ single }}</view>
<image class="icon" src="/static/images/index/arrow_bottom.svg"></image>
</view>
</picker>
</div>
<p class="title">{{thisMonth?thisMonth:'-'}}月客群特征分析</p>
<div v-if="genderBubbleList.res.length>0">
<customer-second :data="genderBubbleList" />
<analyse :analyseInfo="{analysisins_type: 1203,analysisins_format: 2000}" />
</div>
<no-data v-else />
</div>
<div class="chartsItem" style="margin-top: 32px">
</div>
<p class="title">{{thisMonth?thisMonth:'-'}}月客群消费偏好</p>
<div v-if="consterPreferList.series.length>0">
<consum-prefer :data="consterPreferList" />
<analyse :analyseInfo="{analysisins_type: 1204,analysisins_format: 2000}" />
</div>
<no-data v-else/>
</div>
<div class="chartsItem" style="margin-top: 32px">
<p class="title">{{thisMonth?thisMonth:'-'}}月客群消费水平</p>
<div v-if="consumptionLevelList.length>0">
<consumption-level :data="consumptionLevelList"/>
<analyse :analyseInfo="{analysisins_type: 1205,analysisins_format: 2000}" />
</div>
<no-data v-else />
</div>
<div class="chartsItem" style="margin-top: 32px">
<p class="title">{{thisMonth?thisMonth:'-'}}月业态客单偏好</p>
<div v-if="businessTypeList.length>0">
<business-type :data="businessTypeList"></business-type>
<analyse :analyseInfo="{analysisins_type: 1206,analysisins_format: 2000}" />
</div>
<no-data v-else />
</div>
</div>
</div>
</template>
<script>
import request from '@/util/index.js'
import headerTop from "./components/headerTop.vue";
import customerFirst from "./components/guest/customerFirst.vue";
import customerSecond from "./components/guest/customerSecond.vue";
import analyse from "./components/analyse.vue";
import ConsumPrefer from "./components/guest/consumPrefer.vue";
import ConsumptionLevel from "./components/guest/consumptionLevel.vue";
import BusinessType from "./components/guest/businessType.vue";
import NoData from "./components/noData.vue";
export default {
name: "guestPortrait",
components:{NoData, BusinessType, ConsumptionLevel, ConsumPrefer, analyse, headerTop,customerFirst,customerSecond},
data() {
return {
topBg:'linear-gradient(180deg, #A1D0C1 0%, #B1D9CD 100%);',//顶部组件的悬浮背景色
labelList:['女性','高消费','喜爱奶茶','浙江','20-30岁','江苏'],//标签
title:'客群画像',//页面标题
bgColor:'180deg, #30C8ED 0%, #0B9353 100%',//标签背景颜色
bgUrl:'https://eshangtech.com/ShopICO/ahyd-BID/commercial/guestPortraitBg.svg',//背景图片路径
page:'/pages/commercialBI/guestPortrait',
time:'',//跳转携带的时间
menu:{},//手机配置信息
customer:{}, // 客群分析第一个
genderBubbleList:[],//男女的气泡图
consterPreferList:{},//客群消费偏好
consumptionLevelList:[],//客群消费水平
businessTypeList:[],//业态偏好
serviceInfo:{}, //当前服务区信息
backType:'',//返回的页面类型
analyseInfo:{
analysisins_type: 1201,
},
single:'',//显示时间
thisMonth:'',//几月
endData:'', // 结束时间
}
},
onLoad(option){
let serviceInfo = JSON.parse(option.serviceInfo)
this.backType = option.type
this.serviceInfo = serviceInfo
//跳转的时候带上时间
this.time = option.time
this.endData = new Date()
},
onShow(){
let storeTime = uni.getStorageSync('lastDay')
if (storeTime){
this.time = storeTime
}
this.single = this.$util.getThisMonthHave(this.time)
const date = new Date(this.single)
//设置日期选择器的开始时间和结束时间
let m = date.getMonth() + 1
if (m<10){
m = '0' + m
}
this.thisMonth = m
let storeServiceInfo = uni.getStorageSync('currentService')
if (storeServiceInfo){
this.serviceInfo = storeServiceInfo
}
// 获取手机参数对页面进行适配
let systemInfo = uni.getSystemInfoSync()
// 把获取到的手机参数保存
uni.setStorageSync('phoneInfo',systemInfo)
this.statusBarHeight = Number(systemInfo.statusBarHeight)
this.menu = uni.getMenuButtonBoundingClientRect()
// 把获取图表数据的方法统一放在一起 然后去请求接口拿到数据 再分批传到相对应的图标组件
// 每个图表都是用组件的方式引入的 数据是通过prop传入的
// 每个组件需要的数据格式都注释在方法的下面 方便修改接口拿到数据之后 就是对数据进行处理 普通的遍历数组和遍历对象的方法
if (!storeServiceInfo){
this.nearestService()
}
//customer
this.getCustomer()
//客群分析男女的气泡图
this.getGenderBubbleList()
//客群消费偏好
this.getConsterPreferList()
//客群消费水平
this.getConsumptionLevelList()
//业态偏好
this.getBusinessTypeList()
},
methods:{
bindDateChange(e){
const date = new Date(e.detail.value)
let m = date.getMonth() + 1
if (m<10){
m = '0' + m
}
this.thisMonth = m
this.single = e.detail.value
let d = this.$util.getThisMonthDay(e.detail.value)
this.endTime = e.detail.value + '-' + d
this.onRefresh()
},
//重新调一遍页面数据的方法
onRefresh(){
//客群分析男女的气泡图
this.getGenderBubbleList()
//客群消费偏好
this.getConsterPreferList()
//客群消费水平
this.getConsumptionLevelList()
//业态偏好
this.getBusinessTypeList()
},
//当前最近的服务区数据
async nearestService(){
let seat = uni.getStorageSync('seatInfo');
let req = {
longitude:seat.longitude,
Province_Code:'340000',
latitude:seat.latitude,
}
console.log('req',req)
const data = await request.$webGet('CommercialApi/BaseInfo/GetServerpartList',req)
console.log('nearestService',data)
let res = {
SERVERPART_NAME:data.Result_Data.List[0].SERVERPART_NAME,//服务区
SPREGIONTYPE_NAME:data.Result_Data.List[0].SPREGIONTYPE_NAME,//片区
Serverpart_ID:data.Result_Data.List[0].SERVERPART_ID,
longitude:data.Result_Data.List[0].SERVERPART_X,
latitude:data.Result_Data.List[0].SERVERPART_Y,
}
uni.setStorageSync('currentService',res)
},
//customer
// 用async await直接等待接口数据返回之后再对数据直接进行处理 节约时间
async getCustomer(){
let time = ''
const date = new Date(this.single)
let y = date.getFullYear()
let m = date.getMonth() + 1
const nowDate = new Date()
let nowYear = nowDate.getFullYear()
let nowMonth = nowDate.getMonth() + 1
if (y===nowYear && m===nowMonth){
time = this.time
}else{
time = this.endTime
}
const req = {
Province_Code:'340000',
Statistics_Date:time,
Serverpart_ID:this.serviceInfo.Serverpart_ID,
ShowConsumptionLevel:true,
ShowConvertRate:true
}
console.log('req2222',req)
let totalData = await request.$webGet('CommercialApi/Revenue/GetTransactionAnalysis',req)
this.customer = totalData.Result_Data?totalData.Result_Data:{}
},
//客群分析男女的气泡图
async getGenderBubbleList(){
let time = ''
const date = new Date(this.single)
let y = date.getFullYear()
let m = date.getMonth() + 1
const nowDate = new Date()
let nowYear = nowDate.getFullYear()
let nowMonth = nowDate.getMonth() + 1
if (y===nowYear && m===nowMonth){
time = this.time
}else{
time = this.endTime
}
let result = {
man:'',
woman:'',
res:[]
}
const req = {
statisticsType:2,
provinceCode:'340000',
serverpartId:this.serviceInfo.Serverpart_ID,
statisticsMonth:this.$util.getThisMonth(time)
}
let totalData = await request.$webGet('CommercialApi/Customer/GetCustomerRatio',req)
totalData.Result_Data.List.forEach(item=>{
// 判断男性和女性 然后赋值
if (item.name === '男性'){
result.man = item.data[0]
}else if(item.name === '女性'){
result.woman = item.data[0]
}
})
const bubbleReq = {
provinceCode:'340000',
serverpartId:this.serviceInfo.Serverpart_ID,
statisticsMonth:this.$util.getThisMonth(time)
}
let bubbleData = await request.$webGet('CommercialApi/Customer/GetCustomerGroupRatio',bubbleReq)
result.res = bubbleData.Result_Data.List
// let res = [
// {
// name: "男",
// data: [[25,60,30],[40,35,17]]
// },
// {
// name: "女",
// data: [[25,35,17],[35,15,15]]
// }
// ]
this.genderBubbleList = result
},
//客群消费偏好
async getConsterPreferList(){
let time = ''
const date = new Date(this.single)
let y = date.getFullYear()
let m = date.getMonth() + 1
const nowDate = new Date()
let nowYear = nowDate.getFullYear()
let nowMonth = nowDate.getMonth() + 1
if (y===nowYear && m===nowMonth){
time = this.time
}else{
time = this.endTime
}
const req = {
statisticsType:1,
startMonth:this.$util.getThisMonth(time),
endMonth:this.$util.getThisMonth(time),
provinceCode: '340000',
serverpartId: this.serviceInfo.Serverpart_ID
}
const data = await request.$webGet('CommercialApi/Customer/GetCustomerSaleRatio',req)
let res = {
categories:[],
series:[
{name: "男", data: []},
{name: "女", data: []}
],
max:''
}
data.Result_Data.CustomerSaleList.forEach(item=>{
res.categories.push(item.BusinessTradeName)
res.series[0].data.push(item.MaleRatio)
res.series[1].data.push(item.FemaleRatio)
})
res.max = data.Result_Data.MaxSexRatio
// let res = {
// categories: ['餐饮','商超','水果饮品','连锁品牌','粽子','小吃'],
// series: [
// {name: "男", data: [90,110,165,195,187,172]},
// {name: "女", data: [190,210,105,35,27,102]}
// ]
// }
console.log('res',res)
this.consterPreferList = res
},
//客群消费水平
async getConsumptionLevelList(){
let time = ''
const date = new Date(this.single)
let y = date.getFullYear()
let m = date.getMonth() + 1
const nowDate = new Date()
let nowYear = nowDate.getFullYear()
let nowMonth = nowDate.getMonth() + 1
if (y===nowYear && m===nowMonth){
time = this.time
}else{
time = this.endTime
}
const req = {
provinceCode:'340000',
serverpartId:this.serviceInfo.Serverpart_ID,
statisticsMonth:this.$util.getThisMonth(time)
}
const data = await request.$webGet('CommercialApi/Customer/GetCustomerConsumeRatio',req)
let res = []
data.Result_Data.List.forEach(item=>{
res.push({name:item.name,big:(item.data[3]+item.data[2]).toFixed(2),normal:(item.data[1]).toFixed(2),small:item.data[0].toFixed(2)})
})
// let res=[{name:'男',big:'14.8',normal:'41.7',small:'43.5'},
// {name:'女',big:'44.1',normal:'31.7',small:'24.2'}]
this.consumptionLevelList = res
},
//业态偏好
async getBusinessTypeList(){
let time = ''
const date = new Date(this.single)
let y = date.getFullYear()
let m = date.getMonth() + 1
const nowDate = new Date()
let nowYear = nowDate.getFullYear()
let nowMonth = nowDate.getMonth() + 1
if (y===nowYear && m===nowMonth){
time = this.time
}else{
time = this.endTime
}
const req = {
ProvinceCode:'340000',
StatisticsDate:time,
serverpartId:this.serviceInfo.Serverpart_ID
}
const data = await request.$webGet('CommercialApi/Revenue/GetBusinessTradeRevenue',req)
let res = []
let all = 0
if (data.Result_Data){
data.Result_Data.BusinessTradeRank.forEach((item,index)=>{
if (index<=4){
res.push({name:`${item.name} ${item.value}%`,value:Number(item.value)})
all+=Number(item.value)
}else if(index===5){
res.push({name:`其他${(100-all).toFixed(2)}%`,value:Number((100 - all).toFixed(2))})
}
})
let result = [
{
data:res
}
]
// let res=[
// {
// data: [{name:"餐饮 35.6%",value:35.6},
// {name:"小吃 22.5%",value:22.5},
// {name:"水果饮品 17.3%",value:17.3},
// {name:"粽子 15.2%",value:15.2},
// {name:"商超 5.8%",value:5.8},
// {name:"其他 3.6%",value:3.6}]
// }
// ]
this.businessTypeList = result
}
}
}
}
</script>
<style scoped lang="scss">
.main{
width: 100vw;
min-height: 100vh;
.charts{
width: 100%;
box-sizing: border-box;
padding: 14px 16px 24px;
background: #fff;
.time{
margin-bottom: 4px;
.thisTime{
font-size: 14px;
font-family: PingFangSC-Semibold, PingFang SC;
font-weight: 500;
color: #160002;
}
.select{
margin-left: 8px;
display: inline-block;
.time {
display: flex;
align-items: center;
margin-right: 4px;
.day {
font-size: 32rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #782717;
line-height: 44rpx;
margin-right: 4px;
}
.uni-input {
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #ae664e;
line-height: 36rpx;
}
.icon {
width: 24px;
height: 16px;
}
}
}
}
.chartsItem{
.title{
font-size: 17px;
font-family: PingFangSC-Semibold, PingFang SC;
font-weight: 600;
color: #160002;
line-height: 24px;
}
.item{
.value{
font-size: 14px;
font-family: PingFangSC-Semibold, PingFang SC;
font-weight: 400;
color: #160002;
line-height: 20px;
}
}
}
}
}
</style>