update
This commit is contained in:
parent
8bf3bc669b
commit
1c3ce342ac
@ -14,6 +14,7 @@ import { onBeforeUnmount, onMounted, ref, watch } from 'vue';
|
||||
import { handleGetBrandStructureAnalysis, handleGetBusinessTradeTree, handleGetCombineBrandList, handleGetFieldEnumTree } from '../../service';
|
||||
import defaultImg from '../../../../assets/image/defaultImg.png'
|
||||
import brandTotalIcon from '../../../../assets/image/brandTotalIcon.png'
|
||||
import { el } from 'element-plus/es/locale';
|
||||
|
||||
// 注册组件
|
||||
echarts.use([
|
||||
@ -163,7 +164,12 @@ const handleBrandTabList = async () => {
|
||||
|
||||
if (listData && listData.length > 0) {
|
||||
listData.forEach((item: any) => {
|
||||
if (item.AUTOSTATISTICS_NAME === '其他') {
|
||||
|
||||
}
|
||||
else {
|
||||
tableList.push({ label: item.AUTOSTATISTICS_NAME, value: item.AUTOSTATISTICS_ID })
|
||||
}
|
||||
})
|
||||
}
|
||||
console.log('tableListtableListtableListtableListtableList', tableList);
|
||||
@ -202,7 +208,7 @@ const handleGetTableData = async (BRAND_INDUSTRY: number) => {
|
||||
const data = await handleGetCombineBrandList(req)
|
||||
// brandListData.value = data.slice(0, 6)
|
||||
|
||||
return data.slice(0, 6)
|
||||
return data.slice(0, 3)
|
||||
}
|
||||
|
||||
// 切换tab
|
||||
@ -251,7 +257,7 @@ const handleSetConfig = (res: any) => {
|
||||
// 找到对应的数据项
|
||||
const dataItem = res.pieData.find((item: any) => item.name === name);
|
||||
// 返回自定义格式
|
||||
return `${name} ${dataItem?.value}%`;
|
||||
return `${name}`;
|
||||
}
|
||||
},
|
||||
tooltip: { // 新增 tooltip 配置
|
||||
@ -261,7 +267,7 @@ const handleSetConfig = (res: any) => {
|
||||
},
|
||||
formatter: function (params: any) { // 自定义提示框内容
|
||||
return `
|
||||
<div style="font-weight:bold">${params.name} ${params?.percent}% </div>
|
||||
<div style="font-weight:bold">${params.name} ${params.value}家 ${params?.percent}% </div>
|
||||
`;
|
||||
}
|
||||
},
|
||||
|
||||
@ -41,12 +41,6 @@ let chargingCycles = ref<any>({
|
||||
|
||||
// 防止重复调用的标志
|
||||
let isFetching = ref<boolean>(false)
|
||||
// 定时器变量 - 为不同业务类型设置单独的定时器
|
||||
let revenueTimer: any = null // 门店营收定时器
|
||||
let chargingTimer: any = null // 充电定时器
|
||||
let waterTimer: any = null // 加水定时器
|
||||
let ureaTimer: any = null // 尿素定时器
|
||||
let oilTimer: any = null // 油品定时器
|
||||
|
||||
// 切换显示状态:true显示金额,false显示数量
|
||||
let isShowingAmount = ref<boolean>(true)
|
||||
@ -56,9 +50,7 @@ let displaySwitchTimer: any = null
|
||||
|
||||
onMounted(async () => {
|
||||
await handleGetMapRealData()
|
||||
// 启动定时更新,每5秒增加1000
|
||||
startPeriodicUpdate()
|
||||
// 启动显示切换定时器
|
||||
// 启动显示切换定时器(切换时会更新数据)
|
||||
startDisplaySwitch()
|
||||
})
|
||||
|
||||
@ -75,8 +67,6 @@ watch(
|
||||
// 只有当服务区真正发生变化时才重新获取数据
|
||||
if (newVal?.SERVERPART_ID !== oldVal?.SERVERPART_ID) {
|
||||
handleGetMapRealData()
|
||||
// 重启定时器,确保在新服务区下也能正常更新
|
||||
restartPeriodicUpdate()
|
||||
}
|
||||
},
|
||||
{ deep: true }
|
||||
@ -118,10 +108,10 @@ const handleGetMapRealData = async () => {
|
||||
// 门店营收
|
||||
if (item.dataType === 1000) {
|
||||
let obj: any = {
|
||||
value: parseFloat(handleGetPonitFixed(item.totalAmount)) || 0,
|
||||
value: handleGetPonitFixed(item.totalAmount) || 0,
|
||||
unit: item.totalAmountUnit || '',
|
||||
totalCount: parseFloat(handleGetPonitFixed(item.totalCount)) || 0,
|
||||
totalCountUnit: item.totalCountUnit || ''
|
||||
totalCount: handleGetPonitFixed(item.totalTicket) || 0,
|
||||
totalCountUnit: item.totalTicketUnit || ''
|
||||
}
|
||||
// let obj: any = {
|
||||
// value: item.totalAmount.toString().length > 8 ? Number((item.totalAmount / 10000).toFixed(2)).toLocaleString() : Number(item.totalAmount).toLocaleString(),
|
||||
@ -136,9 +126,9 @@ const handleGetMapRealData = async () => {
|
||||
} else if (item.dataType === 2000) {
|
||||
// 油品消耗
|
||||
let obj: any = {
|
||||
value: parseFloat(handleGetPonitFixed(item.totalAmount)) || 0,
|
||||
value: handleGetPonitFixed(item.totalAmount) || 0,
|
||||
unit: item.totalAmountUnit || '',
|
||||
totalCount: parseFloat(handleGetPonitFixed(item.totalCount)) || 0,
|
||||
totalCount: handleGetPonitFixed(item.totalCount) || 0,
|
||||
totalCountUnit: item.totalCountUnit || '',
|
||||
}
|
||||
// let obj: any = {
|
||||
@ -152,9 +142,9 @@ const handleGetMapRealData = async () => {
|
||||
} else if (item.dataType === 3000) {
|
||||
// 加水量
|
||||
let obj: any = {
|
||||
value: parseFloat(handleGetPonitFixed(item.totalAmount)) || 0,
|
||||
value: handleGetPonitFixed(item.totalAmount) || 0,
|
||||
unit: item.totalAmountUnit || '',
|
||||
totalCount: parseFloat(handleGetPonitFixed(item.totalCount)) || 0,
|
||||
totalCount: handleGetPonitFixed(item.totalCount) || 0,
|
||||
totalCountUnit: item.totalCountUnit || '',
|
||||
}
|
||||
// let obj: any = {
|
||||
@ -168,9 +158,9 @@ const handleGetMapRealData = async () => {
|
||||
} else if (item.dataType === 4000) {
|
||||
// 尿素
|
||||
let obj: any = {
|
||||
value: parseFloat(handleGetPonitFixed(item.totalAmount)) || 0,
|
||||
value: handleGetPonitFixed(item.totalAmount) || 0,
|
||||
unit: item.totalAmountUnit || '',
|
||||
totalCount: parseFloat(handleGetPonitFixed(item.totalCount)) || 0,
|
||||
totalCount: handleGetPonitFixed(item.totalCount) || 0,
|
||||
totalCountUnit: item.totalCountUnit || '',
|
||||
}
|
||||
// let obj: any = {
|
||||
@ -184,10 +174,10 @@ const handleGetMapRealData = async () => {
|
||||
} else if (item.dataType === 5000) {
|
||||
// 充电次数
|
||||
let obj: any = {
|
||||
value: parseFloat(handleGetPonitFixed(item.totalAmount)) || 0,
|
||||
value: handleGetPonitFixed(item.totalAmount) || 0,
|
||||
unit: item.totalAmountUnit || '',
|
||||
totalCount: parseFloat(handleGetPonitFixed(item.totalCount)) || 0,
|
||||
totalCountUnit: item.totalCountUnit || '',
|
||||
totalCount: handleGetPonitFixed(item.totalTicket) || 0,
|
||||
totalCountUnit: item.totalTicketUnit || '',
|
||||
}
|
||||
// let obj: any = {
|
||||
// value: item.totalTicket.toString().length > 8 ? Number((item.totalTicket / 10000).toFixed(2)).toLocaleString() : Number(item.totalCount).toLocaleString(),
|
||||
@ -307,177 +297,158 @@ const getRandomInterval = (minSeconds: number, maxSeconds: number): number => {
|
||||
return Math.floor(Math.random() * (maxSeconds - minSeconds + 1) + minSeconds) * 1000
|
||||
}
|
||||
|
||||
// 门店营收更新:1-5秒内金额随机1-100元(主区间15-25元,留1位小数)
|
||||
// 门店营收更新函数
|
||||
const updateRevenue = () => {
|
||||
const randomAmount = generateRandomValue(1, 100, 15, 25, 0.7)
|
||||
console.log('🔍 DEBUG randomAmount:', randomAmount)
|
||||
|
||||
// 根据当前显示模式更新不同的字段
|
||||
if (isShowingAmount.value) {
|
||||
// 显示金额模式 - 更新金额字段
|
||||
const randomAmount = generateRandomValue(1, 100, 15, 25, 0.7)
|
||||
const currentValue = parseFloat(revenueAmonut.value.value) || 0
|
||||
const unit = revenueAmonut.value.unit || ''
|
||||
const actualAmount = unit.includes('万元') ? randomAmount / 10000 : randomAmount
|
||||
const actualAmount = unit === '万元' ? randomAmount / 10000 : randomAmount
|
||||
revenueAmonut.value.value = (currentValue + actualAmount)
|
||||
console.log('💰 门店营收金额增加:', actualAmount + unit, '当前总值:', revenueAmonut.value.value)
|
||||
} else {
|
||||
// 显示数量模式 - 更新数量字段
|
||||
// 显示数量模式 - 更新数量字段(假设为订单数)
|
||||
const orders = Math.random() < 0.7 ? 1 : Math.floor(Math.random() * 4) // 主区间1笔
|
||||
const currentValue = parseFloat(revenueAmonut.value.totalCount) || 0
|
||||
const unit = revenueAmonut.value.totalCountUnit || ''
|
||||
const actualAmount = unit.includes('万单') ? randomAmount / 100 : randomAmount // 假设数量单位是万单
|
||||
const actualAmount = unit === '万笔' ? orders / 10000 : orders
|
||||
revenueAmonut.value.totalCount = (currentValue + actualAmount)
|
||||
console.log('💰 门店营收数量增加:', actualAmount + unit, '当前总值:', revenueAmonut.value.totalCount)
|
||||
console.log('💰 门店营收数量增加:', actualAmount + unit, `(${orders}笔)`, '当前总值:', revenueAmonut.value.totalCount)
|
||||
}
|
||||
}
|
||||
|
||||
// 1-5秒随机间隔
|
||||
revenueTimer = setTimeout(updateRevenue, getRandomInterval(1, 5))
|
||||
}
|
||||
|
||||
// 充电更新:1-5秒内,数量随机增加(0-3笔订单,主区间1笔),金额1-100元(主区间15-35元,留两位小数)
|
||||
// 充电更新函数
|
||||
const updateCharging = () => {
|
||||
const orders = Math.random() < 0.7 ? 1 : Math.floor(Math.random() * 4) // 主区间1笔
|
||||
const orders = Math.random() < 0.7 ? 1 : Math.floor(Math.random() * 4) // 主区间1笔,范围0-3笔
|
||||
|
||||
// 根据当前显示模式更新不同的字段
|
||||
if (isShowingAmount.value) {
|
||||
// 显示金额模式 - 更新金额字段
|
||||
const randomAmount = generateRandomValue(1, 100, 15, 35, 0.7)
|
||||
const randomAmount = generateRandomValue(1, 100, 15, 35, 0.7) // 金额1-100元,主区间15-35元
|
||||
const currentValue = parseFloat(chargingCycles.value.value) || 0
|
||||
const unit = chargingCycles.value.unit || ''
|
||||
const actualAmount = unit.includes('万元') ? randomAmount / 10000 : randomAmount
|
||||
chargingCycles.value.value = (currentValue + actualAmount)
|
||||
const actualAmount = unit === '万元' ? randomAmount / 10000 : randomAmount
|
||||
chargingCycles.value.value = Number((currentValue + actualAmount).toFixed(2)) // 留两位小数
|
||||
console.log('⚡ 充电金额增加:', actualAmount + unit, '当前总值:', chargingCycles.value.value)
|
||||
} else {
|
||||
// 显示数量模式 - 更新数量字段
|
||||
const currentValue = parseFloat(chargingCycles.value.totalCount) || 0
|
||||
const unit = chargingCycles.value.totalCountUnit || ''
|
||||
const actualAmount = unit.includes('万单') ? orders / 10000 : orders
|
||||
chargingCycles.value.totalCount = (currentValue + actualAmount)
|
||||
const actualAmount = unit.includes('万笔') ? orders / 10000 : orders
|
||||
chargingCycles.value.totalCount = Number((currentValue + actualAmount).toFixed(2)) // 留两位小数
|
||||
console.log('⚡ 充电数量增加:', actualAmount + unit, `(${orders}笔)`, '当前总值:', chargingCycles.value.totalCount)
|
||||
}
|
||||
|
||||
// 1-5秒随机间隔
|
||||
chargingTimer = setTimeout(updateCharging, getRandomInterval(1, 5))
|
||||
}
|
||||
|
||||
// 加水更新:1分钟内,加注吨数随机增加(0-1.2吨,主区间0.3-0.7吨,留两位小数)
|
||||
// 加水更新函数
|
||||
const updateWater = () => {
|
||||
const randomAmount = generateRandomValue(0, 1.2, 0.3, 0.7, 0.7) // 按吨数累加
|
||||
const randomAmount = generateRandomValue(0, 1.2, 0.3, 0.7, 0.7) // 加注吨数0-1.2吨,主区间0.3-0.7吨
|
||||
|
||||
// 根据当前显示模式更新不同的字段
|
||||
if (isShowingAmount.value) {
|
||||
// 显示金额模式 - 更新金额字段
|
||||
const revenueAmount = generateRandomValue(10, 500, 50, 150, 0.7) // 金额范围
|
||||
const revenueAmount = generateRandomValue(0, 50, 10, 30, 0.7) // 金额0-50元,主区间10-30元
|
||||
const currentValue = parseFloat(waterAddition.value.value) || 0
|
||||
const unit = waterAddition.value.unit || ''
|
||||
const actualAmount = unit.includes('万元') ? revenueAmount / 10000 : revenueAmount
|
||||
waterAddition.value.value = (currentValue + actualAmount)
|
||||
waterAddition.value.value = Number((currentValue + actualAmount).toFixed(2)) // 留两位小数
|
||||
console.log('💧 加水金额增加:', actualAmount + unit, '当前总值:', waterAddition.value.value)
|
||||
} else {
|
||||
// 显示数量模式 - 更新数量字段
|
||||
const currentValue = parseFloat(waterAddition.value.totalCount) || 0
|
||||
const unit = waterAddition.value.totalCountUnit || ''
|
||||
const actualAmount = unit.includes('万吨') ? randomAmount / 10000 : randomAmount
|
||||
waterAddition.value.totalCount = (currentValue + actualAmount)
|
||||
waterAddition.value.totalCount = Number((currentValue + actualAmount).toFixed(2)) // 留两位小数
|
||||
console.log('💧 加水数量增加:', actualAmount + unit, '(原始值:', randomAmount.toFixed(2) + '吨)', '当前总值:', waterAddition.value.totalCount)
|
||||
}
|
||||
|
||||
// 1分钟间隔
|
||||
waterTimer = setTimeout(updateWater, 60000)
|
||||
}
|
||||
|
||||
// 尿素更新:1分钟内,加注吨数随机增加(0-0.2吨,主区间0.06-0.10吨,留两位小数)
|
||||
// 尿素更新函数
|
||||
const updateUrea = () => {
|
||||
const randomAmount = generateRandomValue(0, 0.2, 0.06, 0.10, 0.7) // 按吨数累加
|
||||
const randomAmount = generateRandomValue(0, 0.2, 0.06, 0.10, 0.7) // 加注吨数0-0.2吨,主区间0.06-0.10吨
|
||||
|
||||
// 根据当前显示模式更新不同的字段
|
||||
if (isShowingAmount.value) {
|
||||
// 显示金额模式 - 更新金额字段
|
||||
const revenueAmount = generateRandomValue(20, 800, 80, 200, 0.7) // 金额范围
|
||||
const revenueAmount = generateRandomValue(0, 300, 120, 200, 0.7) // 金额0-300元,主区间120-200元
|
||||
const currentValue = parseFloat(urea.value.value) || 0
|
||||
const unit = urea.value.unit || ''
|
||||
const actualAmount = unit.includes('万元') ? revenueAmount / 10000 : revenueAmount
|
||||
urea.value.value = (currentValue + actualAmount)
|
||||
urea.value.value = Number((currentValue + actualAmount).toFixed(2)) // 留两位小数
|
||||
console.log('🧪 尿素金额增加:', actualAmount + unit, '当前总值:', urea.value.value)
|
||||
} else {
|
||||
// 显示数量模式 - 更新数量字段
|
||||
const currentValue = parseFloat(urea.value.totalCount) || 0
|
||||
const unit = urea.value.totalCountUnit || ''
|
||||
const actualAmount = unit.includes('万吨') ? randomAmount / 10000 : randomAmount
|
||||
urea.value.totalCount = (currentValue + actualAmount)
|
||||
urea.value.totalCount = Number((currentValue + actualAmount).toFixed(2)) // 留两位小数
|
||||
console.log('🧪 尿素数量增加:', actualAmount + unit, '(原始值:', randomAmount.toFixed(3) + '吨)', '当前总值:', urea.value.totalCount)
|
||||
}
|
||||
|
||||
// 1分钟间隔
|
||||
ureaTimer = setTimeout(updateUrea, 60000)
|
||||
}
|
||||
|
||||
// 油品更新:1-5秒内,加注吨数随机增加(0-0.1吨,主区间0.020-0.050吨,留三位小数)
|
||||
// 油品更新函数
|
||||
const updateOil = () => {
|
||||
const randomAmount = generateRandomValue(0, 0.1, 0.020, 0.050, 0.7) // 按吨数累加
|
||||
const randomAmount = generateRandomValue(0, 0.1, 0.020, 0.050, 0.7) // 加注吨数0-0.1吨,主区间0.020-0.050吨
|
||||
|
||||
// 根据当前显示模式更新不同的字段
|
||||
if (isShowingAmount.value) {
|
||||
// 显示金额模式 - 更新金额字段
|
||||
const revenueAmount = generateRandomValue(50, 1000, 100, 300, 0.7) // 金额范围
|
||||
const revenueAmount = generateRandomValue(200, 1000, 200, 500, 0.7) // 金额200-1000元,主区间200-500元
|
||||
const currentValue = parseFloat(oilConsumption.value.value) || 0
|
||||
const unit = oilConsumption.value.unit || ''
|
||||
const actualAmount = unit.includes('万元') ? revenueAmount / 10000 : revenueAmount
|
||||
oilConsumption.value.value = (currentValue + actualAmount)
|
||||
oilConsumption.value.value = (currentValue + actualAmount) // 油品金额不限制小数位数
|
||||
console.log('⛽ 油品金额增加:', actualAmount + unit, '当前总值:', oilConsumption.value.value)
|
||||
} else {
|
||||
// 显示数量模式 - 更新数量字段
|
||||
const currentValue = parseFloat(oilConsumption.value.totalCount) || 0
|
||||
const unit = oilConsumption.value.totalCountUnit || ''
|
||||
const actualAmount = unit.includes('万吨') ? randomAmount / 10000 : randomAmount
|
||||
oilConsumption.value.totalCount = (currentValue + actualAmount)
|
||||
oilConsumption.value.totalCount = Number((currentValue + actualAmount).toFixed(3)) // 留三位小数
|
||||
console.log('⛽ 油品数量增加:', actualAmount + unit, '(原始值:', randomAmount.toFixed(3) + '吨)', '当前总值:', oilConsumption.value.totalCount)
|
||||
}
|
||||
|
||||
// 1-5秒随机间隔
|
||||
oilTimer = setTimeout(updateOil, getRandomInterval(1, 5))
|
||||
}
|
||||
|
||||
// 启动所有定时器
|
||||
const startPeriodicUpdate = () => {
|
||||
// 清除所有现有定时器
|
||||
clearAllTimers()
|
||||
// 统一更新所有业务数据的函数
|
||||
const updateAllBusinessData = () => {
|
||||
console.log('🔄 更新所有业务数据')
|
||||
|
||||
console.log('🚀 启动业务数据实时更新')
|
||||
// 随机决定哪些数据需要更新(模拟真实业务中不是所有数据都会同时变化)
|
||||
const updateProbability = 0.6 // 60%概率更新某个业务数据
|
||||
|
||||
// 延迟启动,避免同时更新
|
||||
setTimeout(updateRevenue, 1000) // 1秒后启动营收更新
|
||||
setTimeout(updateCharging, 2000) // 2秒后启动充电更新
|
||||
setTimeout(updateWater, 10000) // 10秒后启动加水更新
|
||||
setTimeout(updateUrea, 15000) // 15秒后启动尿素更新
|
||||
setTimeout(updateOil, 3000) // 3秒后启动油品更新
|
||||
if (Math.random() < updateProbability) {
|
||||
updateRevenue()
|
||||
}
|
||||
if (Math.random() < updateProbability) {
|
||||
updateCharging()
|
||||
}
|
||||
if (Math.random() < updateProbability) {
|
||||
updateWater()
|
||||
}
|
||||
if (Math.random() < updateProbability) {
|
||||
updateUrea()
|
||||
}
|
||||
if (Math.random() < updateProbability) {
|
||||
updateOil()
|
||||
}
|
||||
}
|
||||
|
||||
// 清除所有定时器
|
||||
const clearAllTimers = () => {
|
||||
if (revenueTimer) { clearTimeout(revenueTimer); revenueTimer = null }
|
||||
if (chargingTimer) { clearTimeout(chargingTimer); chargingTimer = null }
|
||||
if (waterTimer) { clearTimeout(waterTimer); waterTimer = null }
|
||||
if (ureaTimer) { clearTimeout(ureaTimer); ureaTimer = null }
|
||||
if (oilTimer) { clearTimeout(oilTimer); oilTimer = null }
|
||||
}
|
||||
|
||||
// 重启定时器函数
|
||||
const restartPeriodicUpdate = () => {
|
||||
console.log('🔄 重启所有业务定时器')
|
||||
startPeriodicUpdate()
|
||||
}
|
||||
|
||||
// 启动显示切换定时器
|
||||
const startDisplaySwitch = () => {
|
||||
displaySwitchTimer = setInterval(() => {
|
||||
isShowingAmount.value = !isShowingAmount.value
|
||||
console.log(`🔄 切换显示模式: ${isShowingAmount.value ? '金额' : '数量'}`)
|
||||
|
||||
// 在切换显示模式时更新所有数据
|
||||
updateAllBusinessData()
|
||||
}, 5000) // 每5秒切换一次
|
||||
}
|
||||
|
||||
// 组件卸载时清除定时器
|
||||
onBeforeUnmount(() => {
|
||||
clearAllTimers()
|
||||
if (displaySwitchTimer) {
|
||||
clearInterval(displaySwitchTimer)
|
||||
displaySwitchTimer = null
|
||||
@ -567,11 +538,10 @@ defineExpose({
|
||||
|
||||
<div class="newCoreBusinessBox">
|
||||
<div class="newCoreBusinessItem">
|
||||
<div class="newCoreBusinessItemLabel">{{ getDisplayLabel('') }}</div>
|
||||
<div class="newCoreBusinessItemLabel">{{ getDisplayLabel('门店') }}</div>
|
||||
<div class="newCoreBusinessItemValueBox">
|
||||
<div class="newCoreBusinessItemValue">
|
||||
<NumberRoller :value="revenueDisplay.value" :duration="1800"
|
||||
:decimals="revenueDisplay.decimals" />
|
||||
<NumberRoller :value="revenueDisplay.value" :duration="1000" :decimals="2" />
|
||||
</div>
|
||||
<div class="newCoreBusinessItemUnit">{{ revenueDisplay.unit }}</div>
|
||||
|
||||
@ -587,7 +557,7 @@ defineExpose({
|
||||
<div class="newCoreBusinessItemLabel">{{ getDisplayLabel('油品') }}</div>
|
||||
<div class="newCoreBusinessItemValueBox">
|
||||
<div class="newCoreBusinessItemValue">
|
||||
<NumberRoller :value="oilDisplay.value" :duration="1500" :decimals="oilDisplay.decimals" />
|
||||
<NumberRoller :value="oilDisplay.value" :duration="1000" :decimals="2" />
|
||||
</div>
|
||||
<div class="newCoreBusinessItemUnit">{{ oilDisplay.unit }}</div>
|
||||
</div>
|
||||
@ -602,7 +572,7 @@ defineExpose({
|
||||
<div class="newCoreBusinessItemLabel">{{ getDisplayLabel('加水') }}</div>
|
||||
<div class="newCoreBusinessItemValueBox">
|
||||
<div class="newCoreBusinessItemValue">
|
||||
<NumberRoller :value="waterDisplay.value" :duration="1200" :decimals="waterDisplay.decimals" />
|
||||
<NumberRoller :value="waterDisplay.value" :duration="1000" :decimals="2" />
|
||||
</div>
|
||||
<div class="newCoreBusinessItemUnit">{{ waterDisplay.unit }}</div>
|
||||
</div>
|
||||
@ -617,7 +587,7 @@ defineExpose({
|
||||
<div class="newCoreBusinessItemLabel">{{ getDisplayLabel('尿素') }}</div>
|
||||
<div class="newCoreBusinessItemValueBox">
|
||||
<div class="newCoreBusinessItemValue">
|
||||
<NumberRoller :value="ureaDisplay.value" :duration="1000" :decimals="ureaDisplay.decimals" />
|
||||
<NumberRoller :value="ureaDisplay.value" :duration="1000" :decimals="2" />
|
||||
</div>
|
||||
<div class="newCoreBusinessItemUnit">{{ ureaDisplay.unit }}</div>
|
||||
</div>
|
||||
@ -632,8 +602,7 @@ defineExpose({
|
||||
<div class="newCoreBusinessItemLabel">{{ getDisplayLabel('充电') }}</div>
|
||||
<div class="newCoreBusinessItemValueBox">
|
||||
<div class="newCoreBusinessItemValue">
|
||||
<NumberRoller :value="chargingDisplay.value" :duration="800"
|
||||
:decimals="chargingDisplay.decimals" />
|
||||
<NumberRoller :value="chargingDisplay.value" :duration="1000" :decimals="2" />
|
||||
</div>
|
||||
<div class="newCoreBusinessItemUnit">{{ chargingDisplay.unit }}</div>
|
||||
</div>
|
||||
|
||||
@ -19,8 +19,10 @@
|
||||
}
|
||||
|
||||
.CoreCategory {
|
||||
width: 112px;
|
||||
height: 132px;
|
||||
width: 122px;
|
||||
height: 142px;
|
||||
padding-left: 10px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.CoreCategoryDataList {
|
||||
|
||||
@ -81,8 +81,8 @@ onMounted(async () => {
|
||||
{
|
||||
name: 'Access From',
|
||||
type: 'pie',
|
||||
radius: ['55%', '70%'],
|
||||
center: ['20%', '50%'], // 图形向左偏移
|
||||
radius: ['50%', '75%'],
|
||||
center: ['50%', '85%'], // 图形向左偏移
|
||||
avoidLabelOverlap: false,
|
||||
|
||||
itemStyle: {
|
||||
|
||||
@ -11,7 +11,7 @@ import {
|
||||
} from 'echarts/components';
|
||||
import { CanvasRenderer } from 'echarts/renderers';
|
||||
import { onBeforeUnmount, onMounted, watch } from 'vue';
|
||||
import { handleGetBusinessTradeRevenue, handleGetCustomerSaleRatio } from '../../service';
|
||||
import { handleGetBusinessTradeRevenue, handleGetCommodityTypeSummary, handleGetCustomerSaleRatio } from '../../service';
|
||||
import moment from 'moment';
|
||||
|
||||
// 注册组件
|
||||
@ -48,6 +48,7 @@ watch(
|
||||
// 初始运行的方法
|
||||
const handleGoMounted = async () => {
|
||||
const res = await handleGetData()
|
||||
console.log('res333333', res);
|
||||
|
||||
const chartDom = document.getElementById('CustomerConsumptionPreferencesCharts');
|
||||
if (!chartDom) return;
|
||||
@ -70,12 +71,18 @@ const handleGetData = async () => {
|
||||
// sortStr: 'TOTAL_COUNT desc'
|
||||
// }
|
||||
|
||||
// const req: any = {
|
||||
// ProvinceCode: '530000',
|
||||
// StatisticsDate: moment().subtract(1, 'd').format('YYYY-MM-DD'),
|
||||
// // StatisticsDate: '2025-04-30',
|
||||
// // BusinessTradeIds: -1,
|
||||
// ServerpartId: props.currentService?.SERVERPART_ID || ""
|
||||
// }
|
||||
|
||||
const req: any = {
|
||||
ProvinceCode: '530000',
|
||||
StatisticsDate: moment().subtract(1, 'd').format('YYYY-MM-DD'),
|
||||
// StatisticsDate: '2025-04-30',
|
||||
// BusinessTradeIds: -1,
|
||||
ServerpartId: props.currentService?.SERVERPART_ID || ""
|
||||
startDate: moment().subtract(10, 'd').format('YYYY-MM-DD'),
|
||||
endDate: moment().format('YYYY-MM-DD'),
|
||||
ServerpartShopIds: "5670,5527,5548,5519,5520,5547,5531,5546,7078,7248,5522,6974,5549,5529,5528,7069,5521,6033,5530,5502,6972,7092,7091,6971,5759,5760,6968,6969,7089,7088,6970,7090,5747,6044,6045,6046,6047,7156,5746,7160,6950,6952,6031,6026,5715,5716,6056,6052,6050,6053,6057,6051,6058,6054,6939,6940,7064,7065,6936,6937,6948,6949,5736,6954,7129,7134,7132,7133,5733,5735,7208,7212,5732,5740,5741,5742,7357,7356,5738,5739"
|
||||
}
|
||||
|
||||
|
||||
@ -84,11 +91,13 @@ const handleGetData = async () => {
|
||||
if (CustomerConsumptionPreferences) {
|
||||
data = JSON.parse(CustomerConsumptionPreferences)
|
||||
} else {
|
||||
// data = await handleGetCustomerSaleRatio(req)
|
||||
data = await handleGetBusinessTradeRevenue(req)
|
||||
// data = await handleGetBusinessTradeRevenue(req)
|
||||
data = await handleGetCommodityTypeSummary(req)
|
||||
sessionStorage.setItem("CustomerConsumptionPreferences", JSON.stringify(data))
|
||||
}
|
||||
|
||||
console.log('dasdasdas', data);
|
||||
|
||||
// const data = await handleGetCustomerSaleRatio(req)
|
||||
|
||||
|
||||
@ -99,15 +108,17 @@ const handleGetData = async () => {
|
||||
let aiObj: any = {}
|
||||
|
||||
// CustomerSaleList
|
||||
if (data.BusinessTradeRank && data.BusinessTradeRank.length > 0) {
|
||||
let list = data.BusinessTradeRank.slice(0, 10)
|
||||
// if (data.BusinessTradeRank && data.BusinessTradeRank.length > 0) {
|
||||
let list = data.slice(0, 10)
|
||||
if (list && list.length > 0) {
|
||||
list.forEach((item: any) => {
|
||||
category.push(item.name)
|
||||
seriesData.push(item.value)
|
||||
realData.push(item.value)
|
||||
aiObj[item.name] = `占比${item.value}%`
|
||||
category.push(item.CommodityType_Name)
|
||||
seriesData.push(item.Total_SellAmountRate)
|
||||
realData.push(item.Total_SellAmount)
|
||||
aiObj[item.name] = `占比${item.Total_SellAmountRate}%`
|
||||
})
|
||||
}
|
||||
// }
|
||||
|
||||
let CustomerConsumptionPreferencesAI = sessionStorage.getItem('CustomerConsumptionPreferencesAI')
|
||||
if (CustomerConsumptionPreferencesAI) { } else {
|
||||
@ -222,7 +233,7 @@ const handleSetConfig = (res: any) => {
|
||||
|
||||
return `
|
||||
<div style="font-weight:bold">${data.name}</div>
|
||||
<div>客单占比:${realData ? realData + '%' : data.value + '%'} </div>
|
||||
<div>营收占比:${data.value + '%'}${realData ? `,` + realData + '元' : ''} </div>
|
||||
`;
|
||||
}
|
||||
},
|
||||
@ -252,7 +263,8 @@ defineExpose({
|
||||
|
||||
<template>
|
||||
<div class="CustomerConsumptionPreferencesBox">
|
||||
<SmallTitle title="客群消费偏好" />
|
||||
<!-- <SmallTitle title="客群消费偏好" /> -->
|
||||
<SmallTitle title="近10日单品营收Top10" />
|
||||
|
||||
<div class="CustomerConsumptionPreferencesContent">
|
||||
<div class="CustomerConsumptionPreferencesCharts" id="CustomerConsumptionPreferencesCharts"></div>
|
||||
|
||||
@ -14,7 +14,8 @@
|
||||
margin-bottom: 10px;
|
||||
|
||||
.OverviewOfServiceAreaContentTopItem {
|
||||
width: calc((100% - 20px) / 2);
|
||||
// width: calc((100% - 20px) / 2);
|
||||
width: calc((100% - 30px) / 3);
|
||||
// width: 100%;
|
||||
min-height: 56px;
|
||||
display: flex;
|
||||
|
||||
@ -254,26 +254,33 @@ defineExpose({
|
||||
<div class="OverviewOfServiceAreaContentTopItemvalue" style="color: #1aba80;">{{
|
||||
serviceInfo?.WaterStationCount || "0" }}</div>
|
||||
</div>
|
||||
<div class="OverviewOfServiceAreaContentTopItem">
|
||||
<div class="OverviewOfServiceAreaContentTopItemLabel">加油站/座</div>
|
||||
<div class="OverviewOfServiceAreaContentTopItemvalue" style="color: #1aba80;">24</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="OverviewOfServiceAreaContentTop">
|
||||
|
||||
<div class="OverviewOfServiceAreaContentTopItem" style="width: calc((100% - 20px) / 3);">
|
||||
<div class="OverviewOfServiceAreaContentTopItem" style="width: calc((100% - 30px) / 4);">
|
||||
<div class="OverviewOfServiceAreaContentTopItemLabel">观景台/座</div>
|
||||
<div class="OverviewOfServiceAreaContentTopItemvalue" style="color: #f41a09;">{{
|
||||
serviceInfo?.ViewingDeckCount || "0" }}</div>
|
||||
</div>
|
||||
<div class="OverviewOfServiceAreaContentTopItem" style="width: calc((100% - 20px) / 3);">
|
||||
<div class="OverviewOfServiceAreaContentTopItem" style="width: calc((100% - 30px) / 4);">
|
||||
<div class="OverviewOfServiceAreaContentTopItemLabel">休息区/座</div>
|
||||
<div class="OverviewOfServiceAreaContentTopItemvalue" style="color: #b5ebf7;">{{
|
||||
serviceInfo?.RestAreaCount || "0" }}</div>
|
||||
</div>
|
||||
<div class="OverviewOfServiceAreaContentTopItem" style="width: calc((100% - 20px) / 3);">
|
||||
<div class="OverviewOfServiceAreaContentTopItem" style="width: calc((100% - 30px) / 4);">
|
||||
<div class="OverviewOfServiceAreaContentTopItemLabel">关停/座</div>
|
||||
<div class="OverviewOfServiceAreaContentTopItemvalue" style="color: #fff;">{{
|
||||
serviceInfo?.shutDown || "0" }}</div>
|
||||
</div>
|
||||
<div style="width: calc((100% - 30px) / 4);">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import SmallTitle from '../smallTitle/smallTitle.vue'
|
||||
import './PreferenceType.less'
|
||||
import { onMounted, onBeforeUnmount } from 'vue';
|
||||
import { onMounted, onBeforeUnmount, watch } from 'vue';
|
||||
import * as echarts from 'echarts/core';
|
||||
import { RadarChart } from 'echarts/charts';
|
||||
import {
|
||||
@ -25,7 +25,31 @@ echarts.use([
|
||||
]);
|
||||
|
||||
let myChart: echarts.ECharts;
|
||||
// 传入的数据
|
||||
const props = defineProps<{
|
||||
currentService?: any;
|
||||
}>();
|
||||
|
||||
// 监听传入的选中服务区
|
||||
watch(
|
||||
() => props.currentService,
|
||||
async (newVal, oldVal) => {
|
||||
const res: any = await handleGetSectionFlowCount()
|
||||
|
||||
const chartDom = document.getElementById('PreferenceType');
|
||||
if (!chartDom) return;
|
||||
|
||||
|
||||
myChart = echarts.init(chartDom);
|
||||
|
||||
const option = handleSetConfig(res)
|
||||
|
||||
myChart.setOption(option);
|
||||
myChart.resize();
|
||||
window.addEventListener('resize', resizeChart);
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
onMounted(async () => {
|
||||
|
||||
const res: any = await handleGetSectionFlowCount()
|
||||
@ -46,62 +70,68 @@ onMounted(async () => {
|
||||
// 拿到业态偏好数据
|
||||
const handleGetSectionFlowCount = async () => {
|
||||
|
||||
const req: any = {
|
||||
// ProvinceCode: '530000',
|
||||
// StatisticsDate: moment(moment().subtract(1, 'M')).format('YYYY-MM-DD'),
|
||||
// BusinessTradeIds: -1
|
||||
statisticsType: 1,
|
||||
startMonth: moment().startOf('y').format('YYYYMM'),
|
||||
endMonth: moment().format('YYYYMM'),
|
||||
provinceCode: '530000',
|
||||
showTradeLevel: 1,
|
||||
fromRedis: true
|
||||
// const req: any = {
|
||||
// // ProvinceCode: '530000',
|
||||
// // StatisticsDate: moment(moment().subtract(1, 'M')).format('YYYY-MM-DD'),
|
||||
// // BusinessTradeIds: -1
|
||||
// statisticsType: 1,
|
||||
// startMonth: moment().startOf('y').format('YYYYMM'),
|
||||
// endMonth: moment().format('YYYYMM'),
|
||||
// provinceCode: '530000',
|
||||
// showTradeLevel: 1,
|
||||
// fromRedis: true
|
||||
|
||||
// }
|
||||
const req: any = {
|
||||
ProvinceCode: '530000',
|
||||
StatisticsDate: moment().subtract(1, 'd').format('YYYY-MM-DD'),
|
||||
// StatisticsDate: '2025-04-30',
|
||||
// BusinessTradeIds: -1,
|
||||
ServerpartId: props.currentService?.SERVERPART_ID || ""
|
||||
}
|
||||
|
||||
|
||||
let PreferenceType = sessionStorage.getItem('PreferenceType')
|
||||
let data: any = []
|
||||
if (PreferenceType) {
|
||||
data = JSON.parse(PreferenceType)
|
||||
} else {
|
||||
data = await handleGetCustomerSaleRatio(req)
|
||||
data = await handleGetBusinessTradeRevenue(req)
|
||||
sessionStorage.setItem("PreferenceType", JSON.stringify(data))
|
||||
}
|
||||
|
||||
// const data = await handleGetBusinessTradeRevenue(req)
|
||||
|
||||
console.log('datadatadatadatadatadata22222', data);
|
||||
let category: any = []
|
||||
// 男
|
||||
let seriesData: any = []
|
||||
let realData: any = []
|
||||
// 女
|
||||
let seriesDataMan: any = []
|
||||
let realDataMan: any = []
|
||||
// let seriesDataMan: any = []
|
||||
// let realDataMan: any = []
|
||||
let aiObj: any = {}
|
||||
|
||||
let max: number = 0
|
||||
// let list: any = data.BusinessTradeRank
|
||||
let list: any = data.CustomerSaleList
|
||||
let list: any = data.BusinessTradeRank
|
||||
if (list && list.length > 0) {
|
||||
list.forEach((item: any) => {
|
||||
|
||||
if (item.FemaleRatio > max) {
|
||||
max = item.FemaleRatio
|
||||
}
|
||||
if (item.MaleRatio > max) {
|
||||
max = item.MaleRatio
|
||||
if (Number(item.value) > max) {
|
||||
max = Number(item.value)
|
||||
}
|
||||
|
||||
category.push({ name: `${item.BusinessTradeName}`, max: 100 })
|
||||
seriesData.push(Number(item.FemaleRatio))
|
||||
realData.push(item.FemaleRatio)
|
||||
category.push({ name: `${item.name}`, max: 100 })
|
||||
seriesData.push(Number(item.value))
|
||||
realData.push(Number(item.value))
|
||||
|
||||
seriesDataMan.push(Number(item.MaleRatio))
|
||||
realDataMan.push(item.MaleRatio)
|
||||
// seriesDataMan.push(Number(item.MaleRatio))
|
||||
// realDataMan.push(item.MaleRatio)
|
||||
|
||||
|
||||
aiObj[item.BusinessTradeName + '男性'] = item.FemaleRatio + '%'
|
||||
aiObj[item.BusinessTradeName + '女性'] = item.MaleRatio + '%'
|
||||
aiObj[item.name + '男性'] = Number(item.value) + '%'
|
||||
// aiObj[item.name + '女性'] = item.value + '%'
|
||||
|
||||
// category.push({ name: `${item.name}:${item.value}%`, max: 100 })
|
||||
// seriesData.push(Number(item.value))
|
||||
@ -120,12 +150,12 @@ const handleGetSectionFlowCount = async () => {
|
||||
category: category,// x轴的内容
|
||||
seriesData: [seriesData],// y轴的数据
|
||||
realData: realData,// 真实数据
|
||||
seriesDataMan: [seriesDataMan],
|
||||
realDataMan: realDataMan,
|
||||
// seriesDataMan: [seriesDataMan],
|
||||
// realDataMan: realDataMan,
|
||||
}
|
||||
|
||||
|
||||
console.log('resresresres', res);
|
||||
console.log('resresresres222222', res);
|
||||
|
||||
|
||||
let PreferenceTypeAI = sessionStorage.getItem('PreferenceTypeAI')
|
||||
@ -194,7 +224,7 @@ const handleSetConfig = (res: any) => {
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: "男性",
|
||||
name: "偏好类型",
|
||||
type: 'radar',
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
@ -208,22 +238,6 @@ const handleSetConfig = (res: any) => {
|
||||
areaStyle: {
|
||||
opacity: 0.1
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "女性",
|
||||
type: 'radar',
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
opacity: 0.5
|
||||
},
|
||||
data: res.seriesDataMan,
|
||||
symbol: 'none',
|
||||
itemStyle: {
|
||||
color: '#FF5E5E'
|
||||
},
|
||||
areaStyle: {
|
||||
opacity: 0.1
|
||||
}
|
||||
}
|
||||
],
|
||||
legend: {
|
||||
@ -260,7 +274,8 @@ defineExpose({
|
||||
<template>
|
||||
<div class="PreferenceTypeBox">
|
||||
<div class="PreferenceTypeBoxContent">
|
||||
<SmallTitle :title="'偏好类型'"></SmallTitle>
|
||||
<!-- <SmallTitle :title="'偏好类型'"></SmallTitle> -->
|
||||
<SmallTitle :title="'客群消费偏好'"></SmallTitle>
|
||||
</div>
|
||||
|
||||
<div class="PreferenceTypeCharts">
|
||||
|
||||
@ -80,8 +80,8 @@ const handleGoMounted = async () => {
|
||||
// 拿到数据
|
||||
const handleGetData = async () => {
|
||||
const req: any = {
|
||||
StartDate: "2025-04-01",
|
||||
EndDate: "2025-04-30",
|
||||
StartDate: "2025-10-01",
|
||||
EndDate: "2025-10-31",
|
||||
DataType: selectDataType.value,
|
||||
ServerpartIds: props.currentService?.SERVERPART_ID || allServiceId,
|
||||
DataSourceType: 1,
|
||||
@ -131,6 +131,9 @@ const handleGetData = async () => {
|
||||
|
||||
})
|
||||
}
|
||||
category.push('美丽公路项目')
|
||||
lengedData.push({ name: '美丽公路项目', value: 0 })
|
||||
pieData.push({ value: 0, name: '美丽公路项目' })
|
||||
|
||||
let res: any = {
|
||||
category: category,// x轴的内容
|
||||
@ -218,12 +221,12 @@ const handleSetConfig = (res: any) => {
|
||||
color: '#fff',
|
||||
rich: {
|
||||
name: {
|
||||
width: 90, // 固定名称宽度
|
||||
width: 50, // 固定名称宽度
|
||||
align: 'left',
|
||||
padding: [0, 10, 0, 0]
|
||||
},
|
||||
percent: {
|
||||
width: 50, // 固定百分比宽度
|
||||
width: 30, // 固定百分比宽度
|
||||
align: 'right',
|
||||
padding: [0, 10, 0, 0]
|
||||
}
|
||||
|
||||
@ -123,7 +123,7 @@ const handleSetConfig = (res: any) => {
|
||||
const height = rect.height;
|
||||
|
||||
// 计算center位置(20%,50%)对应的实际像素
|
||||
const centerX = width * 0.21;
|
||||
const centerX = width * 0.25;
|
||||
const centerY = height * 0.5;
|
||||
const option = {
|
||||
tooltip: { // 新增 tooltip 配置
|
||||
@ -140,7 +140,7 @@ const handleSetConfig = (res: any) => {
|
||||
legend: { // 新增图例配置
|
||||
show: true, // 显示图例
|
||||
orient: 'vertical', // 垂直排列
|
||||
left: 200, // 距离左侧的距离
|
||||
left: 240, // 距离左侧的距离
|
||||
top: 'center', // 顶部对齐
|
||||
// type: 'scroll',
|
||||
textStyle: { // 图例文字样式
|
||||
@ -176,7 +176,7 @@ const handleSetConfig = (res: any) => {
|
||||
name: 'Access From',
|
||||
type: 'pie',
|
||||
radius: ['55%', '70%'],
|
||||
center: ['21%', '50%'], // 图形向左偏移
|
||||
center: ['25%', '50%'], // 图形向左偏移
|
||||
avoidLabelOverlap: false,
|
||||
// itemStyle: {
|
||||
// color: function (params: any) {
|
||||
|
||||
@ -90,6 +90,14 @@ export async function handleGetBusinessTradeRevenue(params: any) {
|
||||
return data.Result_Data
|
||||
}
|
||||
|
||||
export async function handleGetCommodityTypeSummary(params: any) {
|
||||
const data: any = await request.get('/Sales/GetCommodityTypeSummary', params)
|
||||
if (data.Result_Code !== 100) {
|
||||
return data
|
||||
}
|
||||
return data.Result_Data.List
|
||||
}
|
||||
|
||||
// 今日走势图
|
||||
export async function handleGetTodaysTrend(params: any) {
|
||||
const data: any = await requestOld.get('', params)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user