update
This commit is contained in:
parent
1c3ce342ac
commit
5e82193c4d
@ -43,7 +43,7 @@ const tabList: any = [
|
||||
{ label: "客单量", value: 2 },
|
||||
{ label: "客单均价", value: 3 },
|
||||
]
|
||||
let selectTab = ref<number>(1)
|
||||
let selectTab = ref<number>(3)
|
||||
|
||||
|
||||
|
||||
@ -236,10 +236,10 @@ const handleGetBottomData = async () => {
|
||||
|
||||
// 切换显示的数据源 营收特征分析的
|
||||
const handleShowData = async (value: number) => {
|
||||
console.log('valuevaluevaluevaluevaluevalue', value);
|
||||
|
||||
let data = realData.value[value]
|
||||
|
||||
|
||||
|
||||
const chartDom = document.getElementById('featureAnalysis');
|
||||
if (!chartDom) return;
|
||||
|
||||
@ -273,7 +273,7 @@ const handleShowData = async (value: number) => {
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
name: `${selectTab.value === 1 ? '营收金额(万元)' : selectTab.value === 2 ? '客单量(万笔)' : selectTab.value === 3 ? '客单均价(元)' : ''}`,
|
||||
name: `${value === 1 ? '营收金额(万元)' : value === 2 ? '客单量(万笔)' : value === 3 ? '客单均价(元)' : ''}`,
|
||||
splitLine: { show: false }, // 隐藏网格线
|
||||
axisLine: {
|
||||
show: true, // 显示Y轴线
|
||||
|
||||
@ -228,12 +228,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]
|
||||
}
|
||||
|
||||
@ -243,7 +243,7 @@ const handleSetConfig = (res: any) => {
|
||||
let str: string = ''
|
||||
if (params && params.length > 0) {
|
||||
params.forEach((item: any) => {
|
||||
str += item.seriesName + item.value + '%'
|
||||
str += item.seriesName + item.value + '笔'
|
||||
})
|
||||
}
|
||||
return `
|
||||
|
||||
@ -117,7 +117,6 @@ const handleGetMapRealData = async () => {
|
||||
// value: item.totalAmount.toString().length > 8 ? Number((item.totalAmount / 10000).toFixed(2)).toLocaleString() : Number(item.totalAmount).toLocaleString(),
|
||||
// unit: item.totalAmount.toString().length > 8 ? '万元' : '元'
|
||||
// }
|
||||
console.log('objobjobjobjobj', obj);
|
||||
|
||||
aiObj["门店营收"] = `${item.totalAmount}${item.totalAmountUnit}`
|
||||
revenueAmonut.value = obj
|
||||
@ -184,7 +183,6 @@ const handleGetMapRealData = async () => {
|
||||
// unit: item.totalTicket.toString().length > 8 ? '万单' : '单'
|
||||
// }
|
||||
aiObj["充电次数"] = `${item.totalTicket}${item.totalTicketUnit}`
|
||||
console.log('objobjobjobj', obj);
|
||||
|
||||
chargingCycles.value = obj
|
||||
// 启动滚动动画
|
||||
@ -307,7 +305,6 @@ const updateRevenue = () => {
|
||||
const unit = revenueAmonut.value.unit || ''
|
||||
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笔
|
||||
@ -315,7 +312,6 @@ const updateRevenue = () => {
|
||||
const unit = revenueAmonut.value.totalCountUnit || ''
|
||||
const actualAmount = unit === '万笔' ? orders / 10000 : orders
|
||||
revenueAmonut.value.totalCount = (currentValue + actualAmount)
|
||||
console.log('💰 门店营收数量增加:', actualAmount + unit, `(${orders}笔)`, '当前总值:', revenueAmonut.value.totalCount)
|
||||
}
|
||||
}
|
||||
|
||||
@ -331,14 +327,12 @@ const updateCharging = () => {
|
||||
const unit = chargingCycles.value.unit || ''
|
||||
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 = Number((currentValue + actualAmount).toFixed(2)) // 留两位小数
|
||||
console.log('⚡ 充电数量增加:', actualAmount + unit, `(${orders}笔)`, '当前总值:', chargingCycles.value.totalCount)
|
||||
}
|
||||
}
|
||||
|
||||
@ -354,14 +348,12 @@ const updateWater = () => {
|
||||
const unit = waterAddition.value.unit || ''
|
||||
const actualAmount = unit.includes('万元') ? revenueAmount / 10000 : revenueAmount
|
||||
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 = Number((currentValue + actualAmount).toFixed(2)) // 留两位小数
|
||||
console.log('💧 加水数量增加:', actualAmount + unit, '(原始值:', randomAmount.toFixed(2) + '吨)', '当前总值:', waterAddition.value.totalCount)
|
||||
}
|
||||
}
|
||||
|
||||
@ -377,14 +369,12 @@ const updateUrea = () => {
|
||||
const unit = urea.value.unit || ''
|
||||
const actualAmount = unit.includes('万元') ? revenueAmount / 10000 : revenueAmount
|
||||
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 = Number((currentValue + actualAmount).toFixed(2)) // 留两位小数
|
||||
console.log('🧪 尿素数量增加:', actualAmount + unit, '(原始值:', randomAmount.toFixed(3) + '吨)', '当前总值:', urea.value.totalCount)
|
||||
}
|
||||
}
|
||||
|
||||
@ -400,20 +390,17 @@ const updateOil = () => {
|
||||
const unit = oilConsumption.value.unit || ''
|
||||
const actualAmount = unit.includes('万元') ? revenueAmount / 10000 : revenueAmount
|
||||
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 = Number((currentValue + actualAmount).toFixed(3)) // 留三位小数
|
||||
console.log('⛽ 油品数量增加:', actualAmount + unit, '(原始值:', randomAmount.toFixed(3) + '吨)', '当前总值:', oilConsumption.value.totalCount)
|
||||
}
|
||||
}
|
||||
|
||||
// 统一更新所有业务数据的函数
|
||||
const updateAllBusinessData = () => {
|
||||
console.log('🔄 更新所有业务数据')
|
||||
|
||||
// 随机决定哪些数据需要更新(模拟真实业务中不是所有数据都会同时变化)
|
||||
const updateProbability = 0.6 // 60%概率更新某个业务数据
|
||||
@ -440,8 +427,6 @@ const updateAllBusinessData = () => {
|
||||
const startDisplaySwitch = () => {
|
||||
displaySwitchTimer = setInterval(() => {
|
||||
isShowingAmount.value = !isShowingAmount.value
|
||||
console.log(`🔄 切换显示模式: ${isShowingAmount.value ? '金额' : '数量'}`)
|
||||
|
||||
// 在切换显示模式时更新所有数据
|
||||
updateAllBusinessData()
|
||||
}, 5000) // 每5秒切换一次
|
||||
|
||||
@ -131,9 +131,9 @@ const handleGetData = async () => {
|
||||
|
||||
})
|
||||
}
|
||||
category.push('美丽公路项目')
|
||||
lengedData.push({ name: '美丽公路项目', value: 0 })
|
||||
pieData.push({ value: 0, name: '美丽公路项目' })
|
||||
category.push('美丽公路')
|
||||
lengedData.push({ name: '美丽公路', value: 0 })
|
||||
pieData.push({ value: 0, name: '美丽公路' })
|
||||
|
||||
let res: any = {
|
||||
category: category,// x轴的内容
|
||||
|
||||
@ -367,7 +367,7 @@ const handleGetSectionFlowCount = async () => {
|
||||
|
||||
const req: any = {
|
||||
StartDate: moment().startOf('y').format('YYYY-MM-DD'),
|
||||
EndDate: moment().subtract(1, 'd').format('YYYY-MM-DD'),
|
||||
EndDate: moment().subtract(1, 'M').format('YYYY-MM-DD'),
|
||||
ProvinceCode: 530000
|
||||
// Serverpart_ID: props.currentService?.SERVERPART_ID || "1143,1144,1186,1188,1189,1190,1191,1192,1193,979,999,1023,1029,1030,1031,1033,1037,1041,1078,1087,1095,1137,1141,1147,1157,1159,1164,1165,1170,1174,981,985,987,994,1007,1009,1010,1012,1016,971,996,1002,1017,1018,1022,1027,1032,1073,1076,1099,1118,1122,1140,1142,1150,1171,970,969,978,1001,1005,1015,1050,1051,1052,1053,1064,1066,1096,1097,1101,1103,1104,1105,1106,1109,1112,1114,1115,1116,1117,991,995,1039,1080,1094,1100,1107,1123,1127,1133,1154,1155,1161,1163,1179,1180,1019,1021,1048,1049,1056,1059,1062,1063,1069,1093,1067,1228,1008,1070,1072,1166,1113,1148,1153,986,1086,1075,1182,1068,1226,1218,1088,1090,1058,1044,1084,1077,1089,1081,1091,1083,1162,1036,1092,988,993,1111,1158,1194,1202,1230,1198,1207,1216,1221,1203,1206,1209,1215,1227,1201,1205,1208,1214,1217,1229,1212,1065,1085,1055,1071,982,1168,1185,1110,977,1169,973,974,1011,1151,1121,1046,1045,1172,1146,976,1187,1156,1181,1136,1138,1211,983,1195,1131,1176,1167,1223,997,1252,1225,1043,1129,992,1149,975,1382,989,1047,1197,1025,1199,1183,1222,1178,1003,1013,1224,1139,1125,1173,1135,1038,1177,1060,1175,1184,1035,1026,1028,1079,1119,1120,1489"
|
||||
}
|
||||
@ -385,7 +385,8 @@ const handleGetSectionFlowCount = async () => {
|
||||
|
||||
const yesReq: any = {
|
||||
StartDate: moment().subtract(1, 'y').startOf('y').format('YYYY-MM-DD'),
|
||||
EndDate: moment().subtract(1, 'y').endOf('y').format('YYYY-MM-DD'),
|
||||
// EndDate: moment().subtract(1, 'y').endOf('y').format('YYYY-MM-DD'),
|
||||
EndDate: moment().subtract(1, 'M').subtract(1, 'y').format('YYYY-MM-DD'), // 找到当前月份对应的去年
|
||||
ProvinceCode: 530000
|
||||
// Serverpart_ID: props.currentService?.SERVERPART_ID || "1143,1144,1186,1188,1189,1190,1191,1192,1193,979,999,1023,1029,1030,1031,1033,1037,1041,1078,1087,1095,1137,1141,1147,1157,1159,1164,1165,1170,1174,981,985,987,994,1007,1009,1010,1012,1016,971,996,1002,1017,1018,1022,1027,1032,1073,1076,1099,1118,1122,1140,1142,1150,1171,970,969,978,1001,1005,1015,1050,1051,1052,1053,1064,1066,1096,1097,1101,1103,1104,1105,1106,1109,1112,1114,1115,1116,1117,991,995,1039,1080,1094,1100,1107,1123,1127,1133,1154,1155,1161,1163,1179,1180,1019,1021,1048,1049,1056,1059,1062,1063,1069,1093,1067,1228,1008,1070,1072,1166,1113,1148,1153,986,1086,1075,1182,1068,1226,1218,1088,1090,1058,1044,1084,1077,1089,1081,1091,1083,1162,1036,1092,988,993,1111,1158,1194,1202,1230,1198,1207,1216,1221,1203,1206,1209,1215,1227,1201,1205,1208,1214,1217,1229,1212,1065,1085,1055,1071,982,1168,1185,1110,977,1169,973,974,1011,1151,1121,1046,1045,1172,1146,976,1187,1156,1181,1136,1138,1211,983,1195,1131,1176,1167,1223,997,1252,1225,1043,1129,992,1149,975,1382,989,1047,1197,1025,1199,1183,1222,1178,1003,1013,1224,1139,1125,1173,1135,1038,1177,1060,1175,1184,1035,1026,1028,1079,1119,1120,1489"
|
||||
}
|
||||
|
||||
@ -21,16 +21,18 @@
|
||||
height: 20px;
|
||||
overflow: hidden;
|
||||
|
||||
.noticeList {
|
||||
.noticeListContent {
|
||||
display: flex;
|
||||
white-space: nowrap;
|
||||
transition: none;
|
||||
position: relative;
|
||||
will-change: transform; // 优化性能
|
||||
|
||||
.noticeItem {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-right: 15px; // 调整item之间的间距
|
||||
flex-shrink: 0; // 防止item被压缩
|
||||
|
||||
.icon {
|
||||
width: 3px;
|
||||
@ -38,6 +40,7 @@
|
||||
background: #1989FA;
|
||||
border-radius: 50%;
|
||||
margin-right: 5px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.contentMessage {
|
||||
@ -48,27 +51,13 @@
|
||||
color: #FFFFFF;
|
||||
text-align: left;
|
||||
font-style: normal;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
// 实现无缝滚动
|
||||
&.scrolling {
|
||||
animation: scrollNotice var(--scroll-duration, 10s) linear infinite;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 关键帧动画
|
||||
@keyframes scrollNotice {
|
||||
0% {
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translateX(-VAR_PX);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 纵向滚动
|
||||
|
||||
@ -1,22 +1,29 @@
|
||||
<script setup lang="ts">
|
||||
import './noticeListBox.less'
|
||||
import noticeIcon from '../../../../assets/image/noticeIcon.png'
|
||||
import { nextTick, onMounted, onUnmounted, reactive, ref, watch } from 'vue'
|
||||
import { onMounted, onUnmounted, reactive, ref, watch, nextTick } from 'vue'
|
||||
import { handleGetGDNearServiceList } from '../../service'
|
||||
|
||||
|
||||
// 消息播报列表
|
||||
let noticeList = reactive<any>([]);
|
||||
// 当前滚动到的消息索引
|
||||
let currentIndex = ref<number>(0)
|
||||
// 滚动的计时器
|
||||
let scrollInterval = ref<any>(null)
|
||||
let isScrolling = ref<boolean>(false);
|
||||
let scrollDuration = ref('10s'); // 动态动画时长
|
||||
let isScrolling = ref<boolean>(true);
|
||||
// 当前全部服务区的id
|
||||
let serverpartId = ref<number[]>([])
|
||||
// 播报数据
|
||||
let noticeMessageObj = ref<any>()
|
||||
// 滚动位置
|
||||
let scrollPosition = ref<number>(0);
|
||||
// 动画帧ID
|
||||
let animationFrameId = ref<number | null>(null);
|
||||
// 内容总宽度
|
||||
let totalContentWidth = ref<number>(0);
|
||||
// 滚动速度(每秒100px)
|
||||
const SCROLL_SPEED = 100; // pixels per second
|
||||
// 上次更新时间
|
||||
let lastTime = ref<number>(0);
|
||||
// 滚动容器引用
|
||||
let scrollContainer = ref<HTMLElement>();
|
||||
|
||||
onMounted(async () => {
|
||||
// 获取播报数据
|
||||
@ -38,7 +45,7 @@ const emit = defineEmits<{
|
||||
// 监听传入的选中服务区
|
||||
watch(
|
||||
() => props.currentService,
|
||||
(newVal, oldVal) => {
|
||||
(_newVal, _oldVal) => {
|
||||
// 获取播报数据
|
||||
handleGetNoticeList()
|
||||
},
|
||||
@ -47,7 +54,7 @@ watch(
|
||||
// 监听传入的选中服务区
|
||||
watch(
|
||||
() => props.selectPageTab,
|
||||
(newVal, oldVal) => {
|
||||
(_newVal, _oldVal) => {
|
||||
// 获取播报数据
|
||||
handleGetNoticeList()
|
||||
// 获取播报数据
|
||||
@ -56,6 +63,16 @@ watch(
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
// 监听noticeList数据变化,重新计算内容宽度
|
||||
watch(
|
||||
() => noticeList.length,
|
||||
(newVal, _oldVal) => {
|
||||
if (newVal > 0) {
|
||||
calculateContentWidth();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
// 获取播报数据
|
||||
const handleGetNoticeList = async () => {
|
||||
@ -81,119 +98,8 @@ const handleGetNoticeList = async () => {
|
||||
sessionStorage.setItem("noticeListBox", JSON.stringify(data))
|
||||
}
|
||||
console.log('11121', data);
|
||||
// let list: any = data
|
||||
let list: any = data
|
||||
|
||||
let list: any = [
|
||||
{
|
||||
NOTICEINFO_TITLE: "云南省蒙新高速蒙自服务区(下行)招商信息公告",
|
||||
SERVERPART_ID: 1187,
|
||||
NOTICEINFO_CONTENT: `【合作模式】保底收益或提点取高
|
||||
【运营方式】餐饮、小吃加盟“滇食坊”品牌,商超加盟“彩云驿购”品牌 ,供应链统一供货
|
||||
【周边资源及优势】地处昆河高速与蒙文砚高速交汇处,是连接昆明、文山、河口的重要交通枢纽,周边拥有碧色寨火车站、西南联大蒙自分校旧址等历史文化资源,以及南湖公园、长桥海国家级湿地公园等自然景观,同时依托蒙自石榴、枇杷等特色农产品,发展潜力巨大
|
||||
【招商范围】综合楼(普通餐饮、地方特色小吃、便利店)、汽修
|
||||
【面积】实际面积存在差异,具体以现场测量为准
|
||||
综合楼285㎡、汽修225㎡`
|
||||
},
|
||||
{
|
||||
NOTICEINFO_TITLE: "云南省景海高速景洪服务区(双侧)招商信息公告",
|
||||
SERVERPART_ID: 1176,
|
||||
NOTICEINFO_CONTENT: `【合作模式】保底收益或提点取高
|
||||
【运营方式】餐饮、小吃加盟“滇食坊”品牌,商超加盟“彩云驿购”品牌 ,供应链统一供货
|
||||
【周边资源及优势】位于西双版纳州景洪市,靠近中国-东盟自由贸易区的重要节点,是中老、中缅贸易的交通枢纽,进出口货物运输频繁,为服务区带来大量人流、物流和商机。周边有热带雨林、傣族村寨等独特风光,可感受东南亚风情。附近的告庄西双景、曼听公园等特色景点,展示了傣族文化和边境地区的发展成果
|
||||
【招商范围】综合楼(地方特色餐饮、地方特色小吃、便利店)
|
||||
【面积】实际面积存在差异,具体以现场测量为准
|
||||
景洪服务区(上行):综合楼1410㎡
|
||||
景洪服务区(下行):综合楼1410㎡`
|
||||
},
|
||||
{
|
||||
NOTICEINFO_TITLE: "云南省景海高速勐海服务区(双侧)招商信息公告",
|
||||
SERVERPART_ID: 1177,
|
||||
NOTICEINFO_CONTENT: `【合作模式】保底收益或提点取高
|
||||
【运营方式】餐饮、小吃加盟“滇食坊”品牌,商超加盟“彩云驿购”品牌 ,供应链统一供货
|
||||
【周边资源及优势】位于西双版纳州勐海县,靠近打洛口岸,是中国与缅甸边境贸易的重要通道,进出口货物运输频繁,为服务区带来大量人流、物流和商机。周边有独特的边境风光,可感受中缅边境的异域风情。附近的勐景来景区、独树成林等特色景点,展示了傣族文化和边境地区的发展成果,吸引众多游客前来观光体验。
|
||||
【招商范围】综合楼(普通餐饮、普通小吃、便利店)
|
||||
【面积】实际面积存在差异,具体以现场测量为准
|
||||
勐海服务区(上行):综合楼50㎡
|
||||
勐海服务区(下行):综合楼1391㎡`
|
||||
},
|
||||
{
|
||||
NOTICEINFO_TITLE: "云南省大南高速大仓服务区(双侧)招商信息公告",
|
||||
SERVERPART_ID: 971,
|
||||
NOTICEINFO_CONTENT: `【合作模式】保底收益或提点取高
|
||||
【运营方式】餐饮、小吃加盟“滇食坊”品牌,商超加盟“彩云驿购”品牌 ,供应链统一供货
|
||||
【周边资源及优势】位于大理州巍山县,地处大理至临沧高速沿线,是大理通往滇西南地区的重要交通节点,车流量大,区位优势明显。周边有巍山古城、巍宝山等历史文化景点,可感受南诏文化和彝族风情。附近的特色农产品和民族手工艺品资源丰富,为服务区带来商机,同时展示了当地民族文化和经济发展成果
|
||||
【招商范围】综合楼(普通餐饮、普通小吃、便利店)
|
||||
【面积】实际面积存在差异,具体以现场测量为准
|
||||
大仓服务区(上行):综合楼254㎡
|
||||
大仓服务区(下行):综合楼254㎡`
|
||||
},
|
||||
{
|
||||
NOTICEINFO_TITLE: "云南省大南高速巍山服务区(双侧)招商信息公告",
|
||||
SERVERPART_ID: 973,
|
||||
NOTICEINFO_CONTENT: `【合作模式】保底收益或提点取高
|
||||
【运营方式】餐饮、小吃加盟“滇食坊”品牌,商超加盟“彩云驿购”品牌 ,供应链统一供货
|
||||
【周边资源及优势】位于大理州巍山县,地处大理至南涧高速沿线,地理位置优越,毗邻大理、丽江等旅游热点,交通便利,辐射滇西经济圈。周边自然资源丰富,民族文化独特,巍山古城为南诏文化发源地,具备深厚的历史底蕴与旅游吸引力。服务区可依托区域特色及高速路网优势,发展文旅、物流等产业,助力区域经济协同发展
|
||||
【招商范围】综合楼(普通餐饮、普通小吃、便利店)、汽修
|
||||
【面积】实际面积存在差异,具体以现场测量为准
|
||||
巍山服务区(上行):综合楼979㎡
|
||||
巍山服务区(下行):综合楼1183㎡,汽修127㎡`
|
||||
},
|
||||
{
|
||||
NOTICEINFO_TITLE: "云南省南景高速拥翠服务区(双侧)招商信息公告",
|
||||
SERVERPART_ID: 970,
|
||||
NOTICEINFO_CONTENT: `【合作模式】保底收益或提点取高
|
||||
【运营方式】餐饮、小吃加盟“滇食坊”品牌,商超加盟“彩云驿购”品牌 ,供应链统一供货
|
||||
【周边资源及优势】位于大理白族自治州南涧县,地处G5611大临高速沿线。周边生态环境优越,毗邻无量山国家级自然保护区,自然资源丰富,适宜发展生态旅游及康养产业。区域民族文化特色鲜明,彝族文化底蕴深厚,具备文旅融合潜力。服务区可依托高速交通优势,结合生态与人文资源,推动特色农产品、文化旅游及物流产业发展,促进区域经济多元化升级
|
||||
【招商范围】综合楼(普通餐饮、普通小吃、便利店)、汽修
|
||||
【面积】实际面积存在差异,具体以现场测量为准
|
||||
拥翠服务区(上行):综合楼951㎡,汽修198㎡
|
||||
拥翠服务区(下行):综合楼951㎡,汽修198㎡`
|
||||
},
|
||||
{
|
||||
NOTICEINFO_TITLE: "云南省南景高速三岔河服务区(双侧)招商信息公告",
|
||||
SERVERPART_ID: 1109,
|
||||
NOTICEINFO_CONTENT: `【合作模式】保底收益或提点取高
|
||||
【运营方式】餐饮、小吃加盟“滇食坊”品牌,商超加盟“彩云驿购”品牌 ,供应链统一供货
|
||||
【周边资源及优势】地处滇西南交通枢纽。周边自然资源丰富,毗邻无量山、哀牢山国家级自然保护区,生态环境优越。景东县为普洱茶核心产区之一,茶文化底蕴深厚,具备特色农业及文旅开发潜力。服务区可依托高速交通优势及区域资源,发展生态旅游、茶产业及物流服务,助力区域经济可持续发展
|
||||
【招商范围】综合楼(普通餐饮、普通小吃、便利店)、汽修
|
||||
【面积】实际面积存在差异,具体以现场测量为准。
|
||||
三岔河服务区(上行):综合楼828㎡,汽修198㎡
|
||||
三岔河服务区(下行):综合楼828㎡,汽修198㎡`
|
||||
},
|
||||
{
|
||||
NOTICEINFO_TITLE: "云南省南景高速景东北停车区(双侧)招商信息公告",
|
||||
SERVERPART_ID: 1110,
|
||||
NOTICEINFO_CONTENT: `【合作模式】保底收益或提点取高
|
||||
【运营方式】餐饮、小吃加盟“滇食坊”品牌,商超加盟“彩云驿购”品牌 ,供应链统一供货
|
||||
【周边资源及优势】位于普洱市景东彝族自治县,地处G5611大临高速沿线。周边自然资源丰富,毗邻无量山、哀牢山国家级自然保护区,生态环境优越,生物多样性显著。景东县为普洱茶主产区之一,茶文化底蕴深厚,具备特色农业开发潜力。停车区可依托高速交通优势及生态资源,发展生态旅游、茶产业及物流服务,助力区域经济可持续发展
|
||||
【招商范围】综合楼(普通餐饮、普通小吃、便利店)
|
||||
【面积】实际面积存在差异,具体以现场测量为准
|
||||
景东北服务区(上行):综合楼846㎡
|
||||
景东北服务区(下行):综合楼846㎡`
|
||||
},
|
||||
{
|
||||
NOTICEINFO_TITLE: "云南省思澜高速龙潭服务区(双侧)招商信息公告",
|
||||
SERVERPART_ID: 1161,
|
||||
NOTICEINFO_CONTENT: `【合作模式】保底收益或提点取高
|
||||
【运营方式】餐饮、小吃加盟“滇食坊”品牌,商超加盟“彩云驿购”品牌 ,供应链统一供货
|
||||
【周边资源及优势】思澜高速全长约131.5公里,设计时速80公里,双向四车道。茫茫龙潭大山植被丰富,有热带雨林植物花卉。服务区按花园式景区建设,有傣族、拉祜族、佤族建筑样式等。能为过往驾乘人员提供舒适的休憩环境。
|
||||
【招商范围】综合楼(普通餐饮、普通小吃、便利店)、汽修
|
||||
【面积】实际面积存在差异,具体以现场测量为准
|
||||
龙潭服务区(上行):综合楼1499㎡、汽修210㎡
|
||||
龙潭服务区(下行):综合楼1597㎡、汽修210㎡`
|
||||
},
|
||||
{
|
||||
NOTICEINFO_TITLE: "云南省思澜高速糯扎渡服务区(双侧)招商信息公告",
|
||||
SERVERPART_ID: 1163,
|
||||
NOTICEINFO_CONTENT: `【合作模式】保底收益或提点取高
|
||||
【运营方式】餐饮、小吃加盟“滇食坊”品牌,商超加盟“彩云驿购”品牌 ,供应链统一供货
|
||||
【周边资源及优势】思澜高速全长约131.5公里,设计时速80公里,双向四车道,位于昆磨高速等重要交通干道上,是连接昆明、普洱、西双版纳等城市的关键节点,车流量大,客源稳定
|
||||
【招商范围】综合楼(普通餐饮、普通小吃、便利店)、汽修
|
||||
【面积】实际面积存在差异,具体以现场测量为准
|
||||
糯扎渡服务区(上行):综合楼2735㎡、汽修167㎡
|
||||
糯扎渡服务区(下行):综合楼2010㎡、汽修167㎡`
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
let allServerpartId: number[] = []
|
||||
@ -210,70 +116,98 @@ const handleGetNoticeList = async () => {
|
||||
|
||||
|
||||
noticeMessageObj.value = obj
|
||||
nextTick(() => {
|
||||
// 数据加载完成后启动滚动
|
||||
// 数据加载完成后计算内容宽度并启动滚动
|
||||
await nextTick();
|
||||
setTimeout(() => {
|
||||
calculateContentWidth();
|
||||
}, 50); // 给DOM一点时间完全渲染
|
||||
}
|
||||
|
||||
// 计算内容宽度
|
||||
const calculateContentWidth = () => {
|
||||
if (scrollContainer.value && noticeList.length > 0) {
|
||||
const items = scrollContainer.value.querySelectorAll('.noticeItem');
|
||||
let width = 0;
|
||||
|
||||
// 只计算原始数据的宽度
|
||||
const originalItemCount = noticeList.length;
|
||||
|
||||
items.forEach((item, index) => {
|
||||
if (index < originalItemCount) {
|
||||
width += (item as HTMLElement).offsetWidth;
|
||||
}
|
||||
});
|
||||
|
||||
totalContentWidth.value = width;
|
||||
console.log('noticeList数据长度:', originalItemCount);
|
||||
console.log('计算的内容宽度:', totalContentWidth.value, 'px');
|
||||
console.log('滚动容器是否存在:', !!scrollContainer.value);
|
||||
|
||||
// 计算完宽度后立即启动滚动
|
||||
if (width > 0 && !animationFrameId.value) {
|
||||
startScrolling();
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 滚动动画函数
|
||||
const animateScroll = (currentTime: number) => {
|
||||
if (!isScrolling.value || totalContentWidth.value === 0) {
|
||||
animationFrameId.value = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (lastTime.value === 0) {
|
||||
lastTime.value = currentTime;
|
||||
}
|
||||
|
||||
const deltaTime = (currentTime - lastTime.value) / 1000; // 转换为秒
|
||||
lastTime.value = currentTime;
|
||||
|
||||
// 按固定速度更新滚动位置
|
||||
scrollPosition.value += SCROLL_SPEED * deltaTime;
|
||||
|
||||
// 当滚动超过内容宽度时,重置到开始位置
|
||||
if (scrollPosition.value >= totalContentWidth.value) {
|
||||
scrollPosition.value = scrollPosition.value % totalContentWidth.value;
|
||||
}
|
||||
|
||||
// 应用滚动位置
|
||||
if (scrollContainer.value) {
|
||||
scrollContainer.value.style.transform = `translateX(-${scrollPosition.value}px)`;
|
||||
}
|
||||
|
||||
// 继续动画
|
||||
animationFrameId.value = requestAnimationFrame(animateScroll);
|
||||
}
|
||||
|
||||
// 开始滚动的方法
|
||||
const startScrolling = () => {
|
||||
isScrolling.value = false;
|
||||
nextTick(() => {
|
||||
const listEl = document.querySelector(`.noticeList${props.selectPageTab}`) as HTMLElement;
|
||||
if (listEl) {
|
||||
const originWidth = listEl.scrollWidth / 2;
|
||||
const speed = 100; // px/s
|
||||
const duration = originWidth / speed;
|
||||
scrollDuration.value = duration + 's';
|
||||
|
||||
// 动态插入 keyframes
|
||||
const styleId = 'dynamic-scroll-keyframes';
|
||||
let styleEl = document.getElementById(styleId) as HTMLStyleElement;
|
||||
if (!styleEl) {
|
||||
styleEl = document.createElement('style');
|
||||
styleEl.id = styleId;
|
||||
document.head.appendChild(styleEl);
|
||||
}
|
||||
styleEl.innerHTML = `
|
||||
@keyframes scrollNotice {
|
||||
0% { transform: translateX(0); }
|
||||
100% { transform: translateX(-${originWidth}px); }
|
||||
}`;
|
||||
// 重新设置 isScrolling 为 true,确保动画生效
|
||||
isScrolling.value = true;
|
||||
// 重置滚动状态
|
||||
scrollPosition.value = 0;
|
||||
lastTime.value = 0;
|
||||
|
||||
// 如果已经有动画在运行,先取消
|
||||
if (animationFrameId.value !== null) {
|
||||
cancelAnimationFrame(animationFrameId.value);
|
||||
animationFrameId.value = null;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// stopScrolling();
|
||||
// if (noticeList.length <= 1) return;
|
||||
// const duration = 3000;
|
||||
// scrollInterval.value = setInterval(() => {
|
||||
// currentIndex.value++;
|
||||
// if (currentIndex.value >= noticeList.length) {
|
||||
// setTimeout(() => {
|
||||
// const container = document.querySelector('.noticeContainer') as HTMLElement;
|
||||
// if (container) container.style.transition = 'none';
|
||||
// currentIndex.value = 0;
|
||||
// setTimeout(() => {
|
||||
// if (container) container.style.transition = '';
|
||||
// }, 50);
|
||||
// }, 500);
|
||||
// }
|
||||
// }, duration);
|
||||
// 启动新的动画
|
||||
if (totalContentWidth.value > 0) {
|
||||
animationFrameId.value = requestAnimationFrame(animateScroll);
|
||||
}
|
||||
}
|
||||
|
||||
// 停止滚动的方法
|
||||
const stopScrolling = () => {
|
||||
isScrolling.value = false;
|
||||
if (scrollInterval.value) {
|
||||
clearInterval(scrollInterval.value)
|
||||
scrollInterval.value = null
|
||||
if (animationFrameId.value !== null) {
|
||||
cancelAnimationFrame(animationFrameId.value);
|
||||
animationFrameId.value = null;
|
||||
}
|
||||
// if (scrollInterval.value) {
|
||||
// clearInterval(scrollInterval.value)
|
||||
// scrollInterval.value = null
|
||||
// }
|
||||
}
|
||||
|
||||
// 点击了这个
|
||||
@ -283,18 +217,8 @@ const handleClickBigBox = () => {
|
||||
}
|
||||
|
||||
onUnmounted(() => {
|
||||
// // 清理定时器等资源
|
||||
// if (scrollTimer) {
|
||||
// clearInterval(scrollTimer)
|
||||
// }
|
||||
// 停止滚动
|
||||
stopScrolling();
|
||||
|
||||
// 清除动态添加的样式标签
|
||||
const styleEl = document.getElementById('dynamic-scroll-keyframes');
|
||||
if (styleEl) {
|
||||
styleEl.remove();
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
@ -304,8 +228,7 @@ onUnmounted(() => {
|
||||
<div class="noticeListBigBox" @click="handleClickBigBox">
|
||||
<img class="noticeIcon" :src="noticeIcon" />
|
||||
<div class="noticeListBox">
|
||||
<div :class="['noticeList', `noticeList${props.selectPageTab}`, { 'scrolling': isScrolling }]"
|
||||
:style="{ '--scroll-duration': scrollDuration }">
|
||||
<div ref="scrollContainer" class="noticeListContent">
|
||||
<div class="noticeItem" v-for="(item, index) in noticeList.concat(noticeList)" :key="index">
|
||||
<div class="icon"></div>
|
||||
<div class="contentMessage">
|
||||
|
||||
@ -80,11 +80,11 @@ let FestivalOptions = [
|
||||
]
|
||||
|
||||
const tabList: any = [
|
||||
{ label: "营收金额", value: 1 },
|
||||
{ label: "客单量", value: 2 },
|
||||
{ label: "客单均价", value: 3 },
|
||||
// { label: "营收金额", value: 1 },
|
||||
// { label: "客单量", value: 2 },
|
||||
// { label: "客单均价", value: 3 },
|
||||
]
|
||||
let selectTab = ref<number>(1)
|
||||
let selectTab = ref<number>(3)
|
||||
|
||||
const iframeLoaded = ref<boolean>(false);
|
||||
// 选中的节日
|
||||
@ -1048,7 +1048,7 @@ const handleGetHighWayData = async () => {
|
||||
<div class="content1694st" v-if="selectPageTab === 4">
|
||||
<div class="content1694stItem">
|
||||
<!-- 消息轮播框 -->
|
||||
<NoticeListBox v-show="showBatch1" :selectPageTab="selectPageTab" />
|
||||
<NoticeListBox v-show="showBatch1" :currentService="currentService" :selectPageTab="selectPageTab" />
|
||||
|
||||
<NewBigTitleBox :title="'会员商城'" style="margin-top: 29px;" />
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user