ccy_DIB/pages/index/index.vue
ylj20011123 ad1b7773d5 update
2025-08-27 09:06:31 +08:00

1660 lines
66 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>
<page-meta :page-style="'overflow:visible'"></page-meta>
<view class="main" :style="{ paddingTop: (menu.bottom + 14) + 'px' }">
<!-- 顶部固定的内容 -->
<view class="topBox" :style="{ height: menu.bottom + 8 + 'px' }">
<view class="topContent" :style="{ paddingTop: menu.top + 'px', height: menu.height + 'px' }">
<view class="topLeft">
<image class="YDIcon" src="/static/images/home/yunnanLogo.svg" />
</view>
<view class="topRight" @click="handleGoMap">
<image class="searchIcon" src="/static/images/home/searchIcon.svg" />
<span class="searchText">请输入服务区</span>
</view>
</view>
</view>
<!-- 月份的轮播框 -->
<!-- :style="{ paddingTop: menu.bottom + 8 + 'px' }" -->
<view class="monthListBox">
<swiper class="swiperBox" previous-margin="40rpx" next-margin="40rpx" :current="selectIndex"
@animationfinish="handleChangeSwiper" :disable-programmatic-animation="false" :duration="300"
:easing-function="ease - out">
<swiper-item class="swiperItem" v-for="(item, index) in monthList" :key="index">
<view class="swiperItemContent"
:class="{ 'is-first': index === 0, 'is-last': index === monthList.length - 1 }">
<view class="swiperItemContentBox">
<!-- 轮播框里面的实际内容 写在这个里面 -->
<view class="swiperItemContentMonth">
{{ selectIndex === index ? currentMonthData.monthText : '-月对客营收' }}
<span class="swiperItemContentUnit">/万元</span>
</view>
<!-- 月度营收的值 -->
<view class="swiperItemContentMonthRevenueBox">
<view class="leftRevenueValue">{{ selectIndex === index ?
currentRevenueData.cashPayChange : '-' }}
</view>
<view class="rightRevenueValue">
<text v-if="selectIndex === index && hasCurrentMonthData" class="addValue"
:style="revenueChangeStyle">
{{ revenueChangeText }}
</text>
<text class="rightNav">同比</text>
</view>
</view>
<view class="monthRevenueBox" v-if="selectIndex === index && hasCurrentMonthData">
<view class="leftBox" @click="handleShowYDModal">
<view class="rateChartsBox" v-if="moneyRateList && moneyRateList.length > 0">
<rateCharts :success="moneyRateList"
:colorList="['#1677FE', '#456497', '#97A9C6']"
:name="`${selectIndex}rate`" />
</view>
<view class="haveNoticeBox"
v-if="ydModal && modalRateList && modalRateList.length > 0"
@click.stop="handleShowYDModal">
<view class="field">
<view class="label">自营:</view>
<view class="value">{{ modalRateList[0] }}%</view>
</view>
<view class="field">
<view class="label">外包:</view>
<view class="value">{{ modalRateList[1] }}%</view>
</view>
</view>
</view>
<view class="newRightBox">
<view class="newRightItem" v-for="(subItem, subIndex) in profitSharingList"
:key="subIndex">
<view class="itemLeft">
<view class="itemIcon" :style="{
background:
subIndex === 0
? '#1677FE'
: subIndex === 1
? '#456497'
: subIndex === 2
? '#97A9C6'
: '',
}"></view>
<span class="itemName">{{ subItem.name }}</span>
</view>
<view class="itemCenter">
{{ subItem.value ? $util.getMoney(subItem.value / 10000) : "" }}
</view>
<view class="itemRight" :style="{
color:
subItem.addQOQ > 0
? '#E83944'
: subItem.addQOQ < 0
? '#0E9976'
: '',
}">{{ subItem.addQOQ ? `${subItem.addQOQ}` : "" }}</view>
</view>
</view>
</view>
<!-- 年度标题 -->
<view class="yearAccountItem" style="margin-bottom: 24rpx">
<view class="itemTop">
<view class="itemName">{{ (Math.floor(index / 12) + 2024).toString().slice(2, 4)
}}年累计对客销售<span class="unit">/亿元</span></view>
</view>
<view class="itemBottom">
<span class="revenueNum" v-if="selectIndex === index && hasCurrentMonthData">{{
topShowData && topShowData.MonthRevenueModel &&
topShowData.MonthRevenueModel.YearRevenueAmount ?
$util.getMoney(topShowData.MonthRevenueModel.YearRevenueAmount / 100000000) : ""
}}</span>
<span class="revenueAdd" v-if="selectIndex === index && hasCurrentMonthData" :style="{
color:
topShowData && topShowData.MonthRevenueModel && topShowData.MonthRevenueModel.YearRevenueAddNumber > 0
? '#E83944'
: topShowData && topShowData.MonthRevenueModel && topShowData.MonthRevenueModel.YearRevenueAddNumber < 0
? '#0E9976'
: '',
}">
<span class="revenueAddNotice">{{ topShowData && topShowData.MonthRevenueModel
&& topShowData.MonthRevenueModel.YearRevenueAddNumber > 0 ? "增长" :
topShowData && topShowData.MonthRevenueModel &&
topShowData.MonthRevenueModel.YearRevenueAddNumber < 0 ? "下降" : "" }}</span>
{{ topShowData && topShowData.MonthRevenueModel &&
topShowData.MonthRevenueModel.YearRevenueAddNumber ?
$util.getMoney(topShowData && topShowData.MonthRevenueModel &&
topShowData.MonthRevenueModel.YearRevenueAddNumber / 100000000) : "" }}
</span>
<span class="revenueAdd" v-if="selectIndex === index && hasCurrentMonthData"
:style="{
color:
topShowData && topShowData.MonthRevenueModel && topShowData.MonthRevenueModel.YearRevenueAdd > 0
? '#E83944'
: topShowData && topShowData.MonthRevenueModel && topShowData.MonthRevenueModel.YearRevenueAdd < 0
? '#0E9976'
: '',
}"><span class="revenueAddNotice">{{ topShowData &&
topShowData.MonthRevenueModel
&& topShowData.MonthRevenueModel.YearRevenueAdd > 0 ? "增幅" : topShowData
&& topShowData.MonthRevenueModel &&
topShowData.MonthRevenueModel.YearRevenueAdd < 0 ? "降幅" : "" }}</span>
{{ topShowData && topShowData.MonthRevenueModel &&
topShowData.MonthRevenueModel.YearRevenueAdd ?
`${topShowData.MonthRevenueModel.YearRevenueAdd > 0 ? "+" :
""}${topShowData.MonthRevenueModel.YearRevenueAdd}%` : "-" }}</span>
</view>
</view>
</view>
</view>
</swiper-item>
</swiper>
</view>
<!-- 实时数据统计 -->
<view class="thingBox">
<!-- 实时营收 -->
<view class="revenue-banner" @click="handlePage">
<view class="revenue-header">
<view class="revenue-title">
<text>💰 今日实时营收</text>
</view>
<image class="right" src="https://eshangtech.com/ShopICO/ahyd-BID/newIndex3/goMore.svg" />
</view>
<view
style="width: 100%;display: flex;align-items: center;justify-content: space-between;margin-top: 8rpx;">
<view class="revenue-content">
<view class="revenue-amount">{{ currentMoney }}</view>
<view class="revenue-label">元</view>
</view>
<view class="revenue-date">{{ $util.handleGetMonthDay(nowDay) }}/{{ howDay }}</view>
</view>
</view>
<!-- 其他实时数据 -->
<view class="data-grid" v-if="otherRealData && otherRealData.length > 0">
<view class="data-item" v-for="(subItem, subIndex) in otherRealData" :key="subIndex">
<view class="data-icon">
<image class="icon" :src="subItem.icon" />
</view>
<view class="data-info">
<view class="data-label">{{ subItem.label || "" }}</view>
<view class="data-value">
<span class="value">{{ subItem.value || "" }}</span>
<span class="unit">/{{ subItem.unit || "" }}</span>
</view>
</view>
</view>
</view>
</view>
<!-- 底部的跳转 -->
<view class="funBox">
<!-- 经营报表-->
<view class="funItem" @click="handleGoOperate">
<view class="funItemContent">
<view class="funIconBox">
<image class="funIcon"
src="https://eshangtech.com/ShopICO/ahyd-BID/newIndex3/operatStatement.svg" />
</view>
<text class="funText">经营报表</text>
</view>
</view>
<view class="funItem" @click="handleGoAttendanceStatus">
<view class="funItemContent">
<view class="funIconBox">
<image class="funIcon"
src="https://eshangtech.com/ShopICO/ahyd-BID/warning/operateWarning.svg" />
</view>
<text class="funText">现场管理</text>
</view>
</view>
</view>
<Tabbar ref="tabbar" :page="page"></Tabbar>
</view>
</template>
<script>
import request from "@/util/index.js";
import RateCharts from "./components/rateCharts.vue";
import NumberScroll from "./components/numberScroll.vue";
import Tabbar from "../../components/tabbar/tabbar.vue";
import { timestampToTimeMonth } from "../../util/dateTime";
import { mapState, mapGetters } from 'vuex'
export default {
data() {
const lastDay = this.$util.cutDate(new Date(), 'YYYY-MM-DD', -1) // 有数据的最近日期 即昨天
const nowDay = this.$util.cutDate(new Date(), 'YYYY-MM-DD') // 有数据的最近日期
return {
menu: {},// 拿到微信胶囊按钮的一些定位数据
startDate: "2024-01-01",// 数据开始的时间 用于判断出现几个 滚动框
lastDay: lastDay,
nowDay: nowDay,
monthList: [], // 当前的月份列表数据
selectIndex: 0,// 当前选中的月份
topShowData: {},// 顶部显示的类型
moneyRateList: [],// 顶部的圆环图的数据
profitSharingList: [],// 顶部圆环图右边的数据
howDay: "", // 星期几
currentMoney: "",// 实时营收
page: "/pages/index/index",
otherRealData: [],// 其他的实时数据
single: "",
ydModal: false, // 显示驿达百分比的具体值
modalRateList: [],// 点击圆环图出现的白色悬浮框的数据
useInfo: {},
isReturn: true,
// 新增缓存相关数据
monthDataCache: {}, // 月份数据缓存
loadingMap: {}, // 加载状态映射
swiperTransition: false, // swiper过渡状态
}
},
components: {
RateCharts,
NumberScroll,
Tabbar,
},
computed: {
...mapGetters({ user: "getUser" }),
// 为uniapp小程序兼容性使用简单的computed属性
currentMonthData() {
if (this.selectIndex >= 0 && this.monthList[this.selectIndex]) {
return {
month: this.monthList[this.selectIndex].month || "-",
monthText: (this.monthList[this.selectIndex].month || "-") + "月对客营收"
};
}
return {
month: "-",
monthText: "-月对客营收"
};
},
currentRevenueData() {
if (this.topShowData && this.topShowData.MonthRevenueModel) {
return {
cashPayChange: this.topShowData.MonthRevenueModel.CashPayChange || "-",
addNumber: this.topShowData.MonthRevenueModel.addNumber || 0,
hasData: true
};
}
return {
cashPayChange: "-",
addNumber: 0,
hasData: false
};
},
// 收益变化颜色样式
revenueChangeStyle() {
const addNumber = this.currentRevenueData.addNumber;
let color = '';
if (addNumber > 0) {
color = '#E83944';
} else if (addNumber < 0) {
color = '#0E9976';
}
return { color: color };
},
// 收益变化文字
revenueChangeText() {
const addNumber = this.currentRevenueData.addNumber;
return addNumber ? `${addNumber}%` : "-";
},
// 判断是否有当前月份数据
hasCurrentMonthData() {
return this.topShowData && this.topShowData.MonthRevenueModel;
}
},
watch: {
user: {
handler(newValue, value) {
console.log('watchwatchwatchwatchwatch');
let _this = this
console.log('newValuenewValuenewValue', newValue);
let userInfo = JSON.parse(JSON.stringify(newValue));
_this.useInfo = JSON.parse(JSON.stringify(newValue));
if (userInfo && userInfo.WeChat_UserId && userInfo.AuthorityInfo["89a1f248-2113-4d57-84b1-c2e6edb9e8ee"] === 1) {
_this.isReturn = false;
} else if (userInfo && userInfo.WeChat_UserId && userInfo.AuthorityInfo["89a1f248-2113-4d57-84b1-c2e6edb9e8ee"] !== 1) {
uni.redirectTo({
url: `/pages/commercialBI/noData?type=homeIndex`,
});
} else {
_this.topShowData = null
_this.moneyRateList = []
_this.profitSharingList = []
_this.modalRateList = []
}
console.log('userInfouserInfouserInfo', _this.useInfo);
console.log('userInfouserisReturnisReturnisReturnisReturnInfouserInfo', _this.isReturn);
if (!_this.isReturn) {
_this.handleGetOnLoad()
}
}
}
},
onLoad() {
let _this = this
this.menu = uni.getMenuButtonBoundingClientRect();
uni.getLocation({
type: "gcj02",
altitude: true,
success: (res) => {
let seatInfo = {
latitude: res.latitude,
longitude: res.longitude,
};
uni.setStorageSync("seatInfo", JSON.stringify(seatInfo));
_this.handleGetNearService(seatInfo.latitude, seatInfo.longitude)
},
fail: (err) => {
},
});
this.single = timestampToTimeMonth(new Date(this.lastDay).getTime());
console.log('this.singlethis.singlethis.single', this.single);
uni.setStorageSync("lastDay", this.lastDay);
console.log('useruseruseruser', this.user);
// 小程序进来存起来的用户信息
// let userInfo = uni.getStorageSync("vuex");
let userInfo = JSON.parse(JSON.stringify(this.user));
_this.useInfo = JSON.parse(JSON.stringify(this.user));
// console.log('userInfouserInfo', userInfo);
console.log('userInfouserInfo', userInfo);
if (userInfo && userInfo.WeChat_UserId && userInfo.AuthorityInfo["89a1f248-2113-4d57-84b1-c2e6edb9e8ee"] === 1) {
_this.isReturn = false;
} else if (userInfo && userInfo.WeChat_UserId && userInfo.AuthorityInfo["89a1f248-2113-4d57-84b1-c2e6edb9e8ee"] !== 1) {
uni.redirectTo({
url: `/pages/commercialBI/noData?type=homeIndex`,
});
}
console.log('userInfouserInfouserInfo', _this.useInfo);
console.log('userInfouserisReturnisReturnisReturnisReturnInfouserInfo', _this.isReturn);
if (!_this.isReturn) {
_this.handleGetOnLoad()
}
},
onShow() {
// 隐藏掉小程序本身自带的 tabbar 让自定义的tabbar出现
uni.hideTabBar();
},
onPullDownRefresh: function () {
let _this = this;
let userInfo = JSON.parse(JSON.stringify(this.user));
if (userInfo && userInfo.WeChat_UserId && userInfo.AuthorityInfo["89a1f248-2113-4d57-84b1-c2e6edb9e8ee"] === 1) {
_this.isReturn = false;
} else if (userInfo && userInfo.WeChat_UserId && userInfo.AuthorityInfo["89a1f248-2113-4d57-84b1-c2e6edb9e8ee"] !== 1) {
uni.redirectTo({
url: `/pages/commercialBI/noData?type=homeIndex`,
});
}
if (!_this.isReturn) {
// 下拉刷新时清空缓存,确保数据最新
_this.monthDataCache = {};
_this.loadingMap = {};
_this.handleGetOnLoad();
// 更新一下定位
uni.getLocation({
type: "gcj02",
altitude: true,
success: (res) => {
let seatInfo = {
latitude: res.latitude,
longitude: res.longitude,
};
uni.setStorageSync("seatInfo", JSON.stringify(seatInfo));
_this.handleGetNearService(seatInfo.latitude, seatInfo.longitude)
},
fail: (err) => {
},
});
}
uni.stopPullDownRefresh();
},
methods: {
// 在onLoad里面调用的 请求整个页面的数据
async handleGetOnLoad() {
// 拿到首页的一些基本信息
this.handleGetIndexInfo();
// 并行请求数据,提升加载速度
const promises = [
this.handleGetTopData(),
this.handleRealRevenue(),
this.handleGetYNRealData()
];
// 预加载相邻月份数据,提升切换体验
const currentIndex = this.selectIndex;
if (currentIndex > 0) {
promises.push(this.preloadMonthData(currentIndex - 1));
}
if (currentIndex < this.monthList.length - 1) {
promises.push(this.preloadMonthData(currentIndex + 1));
}
await Promise.allSettled(promises);
},
// 预加载月份数据
async preloadMonthData(index) {
if (index < 0 || index >= this.monthList.length) return;
const monthKey = this.monthList[index]?.realFull;
if (!monthKey || this.monthDataCache[monthKey] || this.loadingMap[monthKey]) {
return;
}
// 后台预加载,不影响当前显示
setTimeout(async () => {
try {
await this.handleGetTopData(index);
} catch (error) {
console.log('预加载数据失败:', error);
}
}, 500);
},
handleShowYDModal() {
this.ydModal = !this.ydModal;
},
goToRobot() {
if (this.isReturn) {
let _this = this
uni.showModal({
title: '温馨提示',
content: '请您授权登录后再操作。',
success(res) {
if (res.confirm) {
_this.$util.toNextRoute('redirectTo', '/pages/register/register')
}
}
})
return
}
this.$util.toNextRoute("navigateTo", `/pages/robot/index`);
// this.$util.toNextRoute("navigateTo", `/pages/testPage/index`);
},
// 跳转去出勤情况
handleGoAttendanceStatus() {
if (this.isReturn) {
let _this = this
uni.showModal({
title: '温馨提示',
content: '请您授权登录后再操作。',
success(res) {
if (res.confirm) {
_this.$util.toNextRoute('redirectTo', '/pages/register/register')
}
}
})
return
}
this.$util.toNextRoute(
"navigateTo",
`/pages/attendanceStatus/index`
);
},
// 跳转到经营报表
handleGoOperate() {
if (this.isReturn) {
let _this = this
uni.showModal({
title: '温馨提示',
content: '请您授权登录后再操作。',
success(res) {
if (res.confirm) {
_this.$util.toNextRoute('redirectTo', '/pages/register/register')
}
}
})
return
}
this.$util.toNextRoute(
"navigateTo",
`/pages/operatingStatements/index?time=${this.single}`
);
},
handlePage() {
this.$util.toNextRoute(
"navigateTo",
`/pages/everdayRenven/index?time=${this.lastDay}&GroupType=1000&ProvinceCode=530000&ServerpartIds=`
);
},
handleGoMap() {
if (this.isReturn) {
let _this = this
uni.showModal({
title: '温馨提示',
content: '请您授权登录后再操作。',
success(res) {
if (res.confirm) {
_this.$util.toNextRoute('redirectTo', '/pages/register/register')
}
}
})
return
}
this.$util.toNextRoute("navigateTo", "/pages/map/index?type=index");
},
// 拿到云南 油水电等数据
async handleGetYNRealData() {
try {
let req = {
serverPartId: ""
};
const res = await request.$webJava("partner/today/data/statistics", req);
console.log('handleGetYNRealDatahandleGetYNRealDatahandleGetYNRealData', res);
let list = res.Result_Data;
let result = [];
// 数据类型映射配置
const dataTypeMap = {
2000: {
label: '油品',
icon: 'https://eshangtech.com/cyy_DIB/oilIcon.png',
valueKey: 'totalCount',
unitKey: 'totalCountUnit'
},
3000: {
label: '加水',
icon: 'https://eshangtech.com/cyy_DIB/addWaterIcon.png',
valueKey: 'totalCount',
unitKey: 'totalCountUnit'
},
4000: {
label: '尿素',
icon: 'https://eshangtech.com/cyy_DIB/ureaIcon.png',
valueKey: 'totalCount',
unitKey: 'totalCountUnit'
},
5000: {
label: '充电',
icon: 'https://eshangtech.com/cyy_DIB/chargeIcon.png',
valueKey: 'totalTicket',
unitKey: 'totalTicketUnit'
}
};
if (list && list.length > 0) {
list.forEach((item) => {
const config = dataTypeMap[item.dataType];
if (config) {
result.push({
label: config.label,
value: this.$util.fmoney(item[config.valueKey]),
unit: item[config.unitKey],
icon: config.icon
});
}
});
}
this.otherRealData = result;
} catch (error) {
console.error('获取实时数据失败:', error);
this.otherRealData = [];
}
},
// 切换轮播框的方法
async handleChangeSwiper(e) {
console.log('e', e);
const currentIndex = e.target.current;
// 防抖处理,避免快速切换时重复加载
if (this.swiperTransition) return;
this.swiperTransition = true;
this.selectIndex = currentIndex;
// 检查是否有缓存数据
const monthKey = this.monthList[currentIndex]?.realFull;
if (this.monthDataCache[monthKey]) {
// 使用缓存数据
const cachedData = this.monthDataCache[monthKey];
this.topShowData = cachedData.topShowData;
this.moneyRateList = cachedData.moneyRateList;
this.profitSharingList = cachedData.profitSharingList;
this.modalRateList = cachedData.modalRateList;
} else {
// 清空数据并加载新数据
this.topShowData = null;
this.moneyRateList = [];
this.profitSharingList = [];
this.modalRateList = [];
await this.handleGetTopData(currentIndex);
}
// 重置过渡状态
setTimeout(() => {
this.swiperTransition = false;
}, 100);
},
formatThousand(num) {
if (num === null || num === undefined) return '0';
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
},
// 实时营收
async handleRealRevenue() {
try {
let req = {
pushProvinceCode: "530000",
StatisticsDate: this.nowDay,
};
const res = await request.$webGet("CommercialApi/Revenue/GetCurRevenue", req);
// this.currentMoney = res.Result_Data.CurRevenueAmount.toFixed(2);
// this.currentMoney = res.Result_Data.CurRevenueAmount.toLocaleString('zh-CN');
this.currentMoney = this.formatThousand(res.Result_Data.CurRevenueAmount)
} catch (error) {
console.error('获取实时营收数据失败:', error);
this.currentMoney = '暂无数据';
}
},
// 拿到顶部轮播框的数据
async handleGetTopData(index) {
let nowMonth = index !== undefined ? this.monthList[index] : this.monthList[this.selectIndex];
const monthKey = nowMonth.realFull;
// 检查是否正在加载,避免重复请求
if (this.loadingMap[monthKey]) {
return;
}
// 检查缓存
if (this.monthDataCache[monthKey]) {
const cachedData = this.monthDataCache[monthKey];
this.topShowData = cachedData.topShowData;
this.moneyRateList = cachedData.moneyRateList;
this.profitSharingList = cachedData.profitSharingList;
this.modalRateList = cachedData.modalRateList;
return;
}
// 设置加载状态
this.loadingMap[monthKey] = true;
try {
const req = {
pushProvinceCode: "530000",
StatisticsMonth: nowMonth.realFull,
StatisticsDate: this.lastDay
};
const data = await request.$webGet("CommercialApi/Revenue/GetSummaryRevenueMonth", req);
// 保留接口返回 完全不处理的
let dataObj = data.Result_Data;
// 深拷贝一份 用于处理数据
let resObj = JSON.parse(JSON.stringify(data.Result_Data));
console.log('dataObjdataObjdataObj', dataObj);
// 拿到月度对客营收
resObj.MonthRevenueModel.CashPayChange = this.$util.fmoney(this.$util.getMoney(resObj.MonthRevenueModel.CashPay / 10000), 2);
// 拿到月度对客营收的同比增长
let addNumber = resObj.MonthRevenueModel.RevenueYOY ? Number((((resObj.MonthRevenueModel.CashPay - resObj.MonthRevenueModel.RevenueYOY) / resObj.MonthRevenueModel.RevenueYOY) * 100).toFixed(2)) : 0;
resObj.MonthRevenueModel.add = addNumber === 0 ? '' : addNumber > 0 ? "+" + addNumber : addNumber;
resObj.MonthRevenueModel.addNumber = addNumber;
// 拿到年度的对客营收
resObj.MonthRevenueModel.YearRevenueAddNumber = resObj.MonthRevenueModel.YearRevenueAmount - resObj.MonthRevenueModel.YearRevenueYOY;
resObj.MonthRevenueModel.YearRevenueAdd = resObj.MonthRevenueModel.YearRevenueYOY ? (((resObj.MonthRevenueModel.YearRevenueAmount - resObj.MonthRevenueModel.YearRevenueYOY) / resObj.MonthRevenueModel.YearRevenueYOY) * 100).toFixed(2) : 0;
// 顶部的 自营、外包 的数据
let shareList = [{}, {}];
// 自营、外包 的数据合计
let sum = 0;
resObj.BusinessTypeList.forEach((item) => {
// 同比
if (item.data) {
let number = Number(item.data) ? ((item.value - item.data) / item.data) * 100 : 0;
if (number > 0) {
item.add = "+" + number.toFixed(2);
} else if (number < 0) {
item.add = number.toFixed(2);
} else {
item.add = null;
}
}
// 环比
if (item.key) {
let number = Number(item.key) ? ((item.value - item.key) / item.key) * 100 : 0;
if (number > 0) {
item.addQOQ = "+" + number.toFixed(2) + "%";
} else if (number < 0) {
item.addQOQ = number.toFixed(2) + "%";
} else {
item.addQOQ = null;
}
}
// 分润占比
if (item.name === "自营") {
shareList[0] = item;
sum += Number(item.value);
} else if (item.name === "外包") {
shareList[1] = item;
sum += Number(item.value);
}
});
console.log('sum', sum);
console.log('shareListshareListshareList', shareList);
let modalListRate = [];
if (shareList && shareList.length > 0) {
shareList.forEach((item) => {
modalListRate.push((Number(item.value) / sum * 100).toFixed(2));
});
}
const moneyRateList = [
Number(shareList[0].value),
Number(shareList[1].value)
];
// 缓存数据
this.monthDataCache[monthKey] = {
topShowData: resObj,
moneyRateList: moneyRateList,
profitSharingList: shareList,
modalRateList: modalListRate
};
// 设置当前数据
this.modalRateList = modalListRate;
this.moneyRateList = moneyRateList;
this.profitSharingList = shareList;
console.log('profitSharingListprofitSharingListprofitSharingList', this.profitSharingList);
console.log('moneyRateListmoneyRateListmoneyRateList', this.moneyRateList);
console.log('resObjresObjresObjresObjresObj', resObj);
this.topShowData = resObj;
} catch (error) {
console.error('获取数据失败:', error);
} finally {
// 清除加载状态
delete this.loadingMap[monthKey];
}
},
// 拿到首页的一些基本信息
handleGetIndexInfo() {
// 拿到现在有多少个轮播框
let count = this.$util.getMonthDiff(this.startDate, this.lastDay)
console.log('countcountcountcountcountcount', count);
this.selectIndex = count
let monthList = this.$util.generateMonthList(this.startDate, count + 1)
console.log('monthListmonthListmonthList', monthList);
this.monthList = monthList
const nowDate = new Date(this.nowDay);
let holiday = nowDate.getDay();
this.howDay = [
"星期日",
"星期一",
"星期二",
"星期三",
"星期四",
"星期五",
"星期六",
][holiday];
},
// 拿一个最近的服务区 当默认服务区
async handleGetNearService(latitude, longitude) {
// let req = {
// Province_Code: "530000",
// longitude: latitude,
// latitude: longitude,
// ShowService: true,
// PageIndex: 1,
// PageSize: 1
// }
// const data = await request.$webGet('CommercialApi/BaseInfo/GetServerpartList', req)
// console.log('sdjkajdas', data);
// let list = data.Result_Data.List
// // 存第一个做为默认服务区
// // uni.setStorageSync('currentService', list[0]);
// let nearObj = list[0]
// console.log('nearObjnearObjnearObj', nearObj);
let YNList = await this.handleGetYNServiceList()
console.log('YNListYNList', YNList);
if (YNList && YNList.length > 0) {
let nearList = []
YNList.forEach((item) => {
let obj = JSON.parse(JSON.stringify(item))
obj.SERVERPART_DISTANCE = this.haversineDistance({ lat: latitude, lng: longitude }, { lat: obj.latitude, lng: obj.longitude })
obj.fileId = obj.fileId ? JSON.parse(obj.fileId) : []
obj.businessModel = obj.businessModel ? JSON.parse(obj.businessModel) : []
nearList.push(obj)
})
nearList = nearList.sort((a, b) => {
const da = parseFloat(a.SERVERPART_DISTANCE) || 0;
const db = parseFloat(b.SERVERPART_DISTANCE) || 0;
return da - db;
});
uni.setStorageSync('currentService', nearList[0]);
// 存一下 全部的服务区 主要是拿个距离字段
uni.setStorageSync('ServerpartList', nearList)
}
},
// 算经纬度的之间距离的方法
haversineDistance({ lat: lat1, lng: lon1 }, { lat: lat2, lng: lon2 }) {
const toRad = (d) => d * Math.PI / 180;
const R = 6378137; // 地球半径(米) WGS84 椭球近似为球
const φ1 = toRad(lat1);
const φ2 = toRad(lat2);
const Δφ = toRad(lat2 - lat1);
const Δλ = toRad(lon2 - lon1);
const a = Math.sin(Δφ / 2) ** 2 +
Math.cos(φ1) * Math.cos(φ2) * Math.sin(Δλ / 2) ** 2;
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
const distanceMeters = R * c;
return (distanceMeters / 1000).toFixed(2); // 返回 km字符串
},
// 请求一下云南那边的 服务区数据
async handleGetYNServiceList() {
let req = {
bsessionKey: "46BC6D5E069411B39C215C8A3B474B31",
pageNum: 1,
pageSize: 500
}
const data = await new Promise((resolve, reject) => {
uni.request({
url: "https://fwqznxj.yciccloud.com:9081/ynjt/pushManage/getSaMsgAll",
method: "POST",
data: req,
header: {
"content-type": "application/x-www-form-urlencoded",
},
success(res) {
resolve(res.data.data)
},
});
});
// 这个是云南那边给来的数据 根据 云南的数据 把我们算的距离补给他们的数据里面
// let YNList = data.data
return data.data
},
// uniapp小程序兼容性方法保留作为备用
getCurrentMonthText(index) {
if (this.selectIndex === index && this.monthList[index]) {
return (this.monthList[index].month || "-") + "月对客营收";
}
return "-月对客营收";
}
}
}
</script>
<style scoped lang="less">
@bg: #f8f9fa;
@muted: #666;
@card: #fff;
@shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
@primary: #27B25F;
@primary2: #4CCC7F;
@success: #2ed573;
@warning: #ff9f43;
@danger: #ff4757;
@info: #3742fa;
.main {
width: 100vw;
min-height: 100vh;
box-sizing: border-box;
background-image: url("https://eshangtech.com/minTestImg/pageBg.png");
background-size: 100% 100%;
background-repeat: no-repeat;
.topBox {
width: 100%;
box-sizing: border-box;
padding: 0 32rpx;
position: fixed;
top: 0;
left: 0;
z-index: 99;
background-image: url("https://eshangtech.com/minTestImg/pageBg.png");
.topContent {
display: flex;
align-items: center;
.topLeft {
display: flex;
align-items: center;
.YDIcon {
width: 176rpx;
height: 48rpx;
margin-right: 8rpx;
}
}
.topRight {
width: 310rpx;
height: 56rpx;
background: #f6f8fa;
border-radius: 36rpx;
margin-left: 16rpx;
box-sizing: border-box;
padding: 8rpx 16rpx;
display: flex;
align-items: center;
.searchIcon {
width: 28rpx;
height: 28rpx;
}
.searchText {
font-family: 'PingFangSC';
font-weight: 400;
font-size: 24rpx;
color: #9fa1aa;
line-height: 40rpx;
text-align: left;
font-style: normal;
margin-left: 8rpx;
}
}
}
}
.monthListBox {
width: 100%;
height: 460rpx;
margin-top: 8rpx;
.swiperBox {
width: 100%;
height: 100%;
.swiperItem {
width: 100%;
height: 100%;
.swiperItemContent {
height: 100%;
padding: 0 10rpx;
box-shadow: 0 8rpx 20rpx rgba(0, 0, 0, .06);
.swiperItemContentBox {
height: 100%;
background: linear-gradient(180deg, #F0E4ED 0%, #F0E8F1 18%, #FFFFFF 100%);
border-radius: 32rpx;
border: 4rpx solid #fff;
box-sizing: border-box;
padding: 20rpx 28rpx;
.swiperItemContentMonth {
font-family: 'PingFangSC';
font-weight: 400;
font-size: 28rpx;
color: #160002;
line-height: 40rpx;
text-align: left;
font-style: normal;
.swiperItemContentUnit {
font-family: 'PingFangSC';
font-weight: 400;
font-size: 24rpx;
color: #A69E9F;
line-height: 40rpx;
text-align: left;
font-style: normal;
margin-left: 4rpx;
}
}
.swiperItemContentMonthRevenueBox {
width: 100%;
margin-top: 12rpx;
display: flex;
align-items: center;
justify-content: space-between;
.leftRevenueValue {
font-family: 'DINAlternate';
font-weight: bold;
font-size: 30rpx;
color: #160002;
line-height: 40rpx;
text-align: left;
font-style: normal;
}
.rightRevenueValue {
display: flex;
align-items: center;
.addValue {
font-family: 'DINAlternate';
font-weight: bold;
font-size: 28rpx;
line-height: 40rpx;
text-align: left;
font-style: normal;
}
.rightNav {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 24rpx;
color: #A69E9F;
line-height: 40rpx;
text-align: left;
font-style: normal;
margin-left: 4rpx;
}
}
}
.monthRevenueBox {
width: 100%;
box-sizing: border-box;
margin-top: 16rpx;
height: 144rpx;
display: flex;
align-items: center;
.leftBox {
width: 144rpx;
height: 144rpx;
margin-right: 16rpx;
position: relative;
.rateChartsBox {
width: 144rpx;
height: 144rpx;
}
.haveNoticeBox {
position: absolute;
bottom: 0;
left: 0;
transform: translateY(80%);
display: inline-block;
padding: 5px 10px;
background: #fff;
border-radius: 10rpx;
box-shadow: 0rpx 0rpx 40rpx 0rpx rgba(244, 138, 143, 0.21);
z-index: 9;
.field {
display: flex;
align-items: center;
.label {
width: 140rpx;
text-align: left;
}
.value {
width: 100rpx;
font-family: DINAlternate-Bold, DINAlternate;
text-align: right;
}
}
}
}
.newRightBox {
flex: 1;
.newRightItem {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
margin: 8rpx 0;
.itemLeft {
display: flex;
align-items: center;
width: 33%;
.itemIcon {
width: 12rpx;
height: 12rpx;
margin-right: 12rpx;
border-radius: 50%;
}
.itemName {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 28rpx;
color: #160002;
line-height: 40rpx;
text-align: left;
font-style: normal;
display: inline-block;
width: 120rpx;
}
}
.itemCenter {
display: inline-block;
width: 33%;
font-family: DINAlternate-Bold, DINAlternate;
font-weight: bold;
font-size: 28rpx;
color: #160002;
line-height: 40rpx;
text-align: right;
font-style: normal;
}
.itemRight {
display: inline-block;
width: 33%;
font-family: DINAlternate-Bold, DINAlternate;
font-weight: bold;
font-size: 28rpx;
color: #e83944;
line-height: 40rpx;
text-align: right;
font-style: normal;
}
}
}
}
.yearAccountItem {
width: 100%;
box-sizing: border-box;
margin-top: 48rpx;
.itemTop {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 8rpx;
.itemName {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 28rpx;
color: #160002;
line-height: 40rpx;
text-align: left;
font-style: normal;
.unit {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 24rpx;
color: #9a9a9a;
line-height: 36rpx;
text-align: left;
font-style: normal;
margin-left: 4rpx;
}
}
}
.itemBottom {
display: flex;
align-items: center;
justify-content: space-between;
.revenueNum {
font-family: DINAlternate-Bold, DINAlternate;
font-weight: bold;
font-size: 28rpx;
color: #160002;
line-height: 44rpx;
text-align: left;
font-style: normal;
}
.revenueAdd {
font-family: DINAlternate-Bold, DINAlternate;
font-weight: bold;
font-size: 28rpx;
color: #e83944;
line-height: 44rpx;
text-align: left;
font-style: normal;
.revenueAddNotice {
font-size: 24rpx;
font-weight: 400;
color: #a69e9f;
margin-right: 4px;
}
}
}
}
}
}
.swiperItemContent.is-first {
padding-left: 20rpx;
}
}
}
}
.thingBox {
width: 100%;
box-sizing: border-box;
padding: 0 32rpx;
margin-top: 24rpx;
.revenue-banner {
background: #ffffff;
color: #160002;
padding: 24rpx 24rpx 8rpx;
border-radius: 16rpx;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
margin-bottom: 24rpx;
border: 2rpx solid #f0f0f0;
.revenue-header {
display: flex;
align-items: center;
justify-content: space-between;
.revenue-title {
font-weight: 400;
font-size: 28rpx;
color: #160002;
}
.right {
width: 32rpx;
height: 32rpx;
}
}
.revenue-content {
display: flex;
align-items: baseline;
.revenue-amount {
font-family: DINAlternate-Bold, DINAlternate;
font-size: 36rpx;
font-weight: 600;
margin-right: 12rpx;
color: #27B25F;
}
.revenue-label {
font-size: 24rpx;
color: #666;
}
}
.revenue-date {
font-size: 24rpx;
color: #999;
}
}
.data-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 16rpx;
margin-bottom: 24rpx;
.data-item {
background: #fff;
padding: 24rpx;
border-radius: 16rpx;
box-shadow: @shadow;
display: flex;
align-items: center;
.data-icon {
width: 64rpx;
height: 64rpx;
background: linear-gradient(135deg, #DCE6FF, #EEF3FF);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-right: 16rpx;
.icon {
width: 32rpx;
height: 32rpx;
}
}
.data-info {
flex: 1;
.data-label {
font-size: 24rpx;
color: @muted;
margin-bottom: 8rpx;
}
.data-value {
.value {
font-size: 28rpx;
font-weight: 600;
color: #160002;
}
.unit {
font-size: 20rpx;
color: #A69E9F;
margin-left: 4rpx;
}
}
}
}
}
}
.thingBox {
width: 100%;
box-sizing: border-box;
padding: 0 32rpx;
margin-top: 24rpx;
.data-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 16rpx;
.data-item {
background: #fff;
padding: 24rpx;
border-radius: 16rpx;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
display: flex;
align-items: center;
.data-icon {
width: 64rpx;
height: 64rpx;
background: linear-gradient(135deg, #DCE6FF, #EEF3FF);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-right: 16rpx;
.icon {
width: 32rpx;
height: 32rpx;
}
}
.data-info {
flex: 1;
.data-label {
font-size: 24rpx;
color: #666;
margin-bottom: 8rpx;
}
.data-value {
.value {
font-size: 28rpx;
font-weight: 600;
color: #160002;
}
.unit {
font-size: 20rpx;
color: #A69E9F;
margin-left: 4rpx;
}
}
}
}
}
}
// 即时营收
.instantRevenue {
width: calc(100% - 80rpx);
box-sizing: border-box;
padding: 2rpx;
background: #fff;
border-radius: 16rpx;
margin-left: 40rpx;
margin-bottom: 24rpx;
.revenue {
width: 100%;
height: 100%;
box-sizing: border-box;
padding: 24rpx 24rpx;
background: linear-gradient(180deg, #F0E4ED 0%, #F0E8F1 18%, #FFFFFF 100%);
border-radius: 16rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
.revenueTop {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
.revenyeTopLeft {
display: flex;
align-items: center;
.monthIcon {
width: 48rpx;
height: 48rpx;
}
.dateText {
font-size: 28rpx;
font-family: PingFangSC, PingFang SC;
font-weight: 500;
color: #fc2e20;
line-height: 40rpx;
margin: 0 8rpx;
}
.day {
font-size: 24rpx;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
color: #a69e9f;
line-height: 40rpx;
}
}
.revenyeTopRight {
width: 100px;
display: flex;
justify-content: flex-end;
align-items: center;
.right {
width: 32rpx;
height: 32rpx;
}
}
}
.revenueMoney {
height: 70rpx;
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 4rpx;
.moneyText {
display: inline-flex;
font-family: DINAlternate-Bold, DINAlternate;
font-weight: bold;
font-size: 36rpx;
color: #160002;
line-height: 40rpx;
text-align: right;
font-style: normal;
}
.moneyLabel {
height: 100%;
font-size: 24rpx;
font-family: DINAlternate-Bold, DINAlternate;
font-weight: 400;
color: #a69e9f;
display: inline-flex;
align-items: center;
}
}
.otherRealDataBox {
width: 100%;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
.revenueMoneyItem {
width: 50%;
display: flex;
align-items: center;
.revenueMoneyItemLeft {
width: 88rpx;
height: 88rpx;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-right: 16rpx;
background: linear-gradient(180deg, #DCE6FF 0%, #EEF3FF 100%);
.leftIcon {
width: 40rpx;
height: 40rpx;
}
}
.revenueMoneyItemRight {
width: calc(100% - 86rpx);
.moneyLabel {
font-size: 28rpx;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
color: #000;
line-height: 30rpx;
}
.moneyText {
width: 100%;
margin-top: 12rpx;
display: flex;
align-items: center;
justify-content: space-between;
.money {
font-size: 28rpx;
font-family: DINAlternate-Bold, DINAlternate;
font-weight: bold;
color: #160002;
line-height: 32rpx;
text-align: left;
display: inline-block;
width: 110rpx;
}
.moneyUnit {
width: 70rpx;
font-size: 24rpx;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
color: #a69e9f;
line-height: 30rpx;
margin-left: 8rpx;
white-space: nowrap;
}
}
}
}
}
}
.revenueOther {
background: #fff !important;
}
}
.funBox {
width: calc(100% - 64rpx);
margin-left: 32rpx;
margin-bottom: calc(100rpx + env(safe-area-inset-bottom));
background: #ffffff;
border-radius: 16rpx;
box-sizing: border-box;
padding: 32rpx 24rpx;
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 24rpx;
box-shadow: @shadow;
.funItem {
display: flex;
justify-content: center;
.funItemContent {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.funIconBox {
width: 88rpx;
height: 88rpx;
overflow: hidden;
margin-bottom: 16rpx;
.funIcon {
width: 100%;
height: 100%;
}
}
.funText {
font-size: 28rpx;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
color: #160002;
line-height: 30rpx;
}
}
}
}
}
</style>