ylj20011123 5e82193c4d update
2025-11-18 17:52:47 +08:00

266 lines
7.6 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.

<script setup lang="ts">
import './noticeListBox.less'
import noticeIcon from '../../../../assets/image/noticeIcon.png'
import { onMounted, onUnmounted, reactive, ref, watch, nextTick } from 'vue'
import { handleGetGDNearServiceList } from '../../service'
// 消息播报列表
let noticeList = reactive<any>([]);
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 () => {
// 获取播报数据
handleGetNoticeList()
})
// 传入的数据
const props = defineProps<{
currentService?: any;
selectPageTab?: number
}>();
// 改变页面显示状态
const emit = defineEmits<{
(e: "handelGetNoticeListAllId", idList: number[], type: string, obj: any): void; // 切换页面分区
}>();
// 监听传入的选中服务区
watch(
() => props.currentService,
(_newVal, _oldVal) => {
// 获取播报数据
handleGetNoticeList()
},
{ deep: true }
);
// 监听传入的选中服务区
watch(
() => props.selectPageTab,
(_newVal, _oldVal) => {
// 获取播报数据
handleGetNoticeList()
// 获取播报数据
startScrolling()
},
{ deep: true }
);
// 监听noticeList数据变化重新计算内容宽度
watch(
() => noticeList.length,
(newVal, _oldVal) => {
if (newVal > 0) {
calculateContentWidth();
}
}
);
// 获取播报数据
const handleGetNoticeList = async () => {
const req = {
SearchParameter: {
PROVINCE_CODE: "530000",
NOTICEINFO_STATE: 1,
SERVERPART_IDS: props.currentService?.SERVERPART_ID || ""
},
PageIndex: 1,
PageSize: 10,
appId: "wxee018fb96955552a"
}
let noticeListBox = sessionStorage.getItem('noticeListBox')
let data: any = []
if (noticeListBox) {
data = JSON.parse(noticeListBox)
console.log('11121');
} else {
data = await handleGetGDNearServiceList(req)
sessionStorage.setItem("noticeListBox", JSON.stringify(data))
}
console.log('11121', data);
let list: any = data
let allServerpartId: number[] = []
let obj: any = {}
noticeList.length = 0;
list && list.forEach((item: any) => {
noticeList.push(item)
allServerpartId.push(item.SERVERPART_ID)
obj[Number(item.SERVERPART_ID)] = item.NOTICEINFO_CONTENT
});
serverpartId.value = allServerpartId
console.log('noticeList:', noticeList); // 添加这行
noticeMessageObj.value = obj
// 数据加载完成后计算内容宽度并启动滚动
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 为 true确保动画生效
isScrolling.value = true;
// 重置滚动状态
scrollPosition.value = 0;
lastTime.value = 0;
// 如果已经有动画在运行,先取消
if (animationFrameId.value !== null) {
cancelAnimationFrame(animationFrameId.value);
animationFrameId.value = null;
}
// 启动新的动画
if (totalContentWidth.value > 0) {
animationFrameId.value = requestAnimationFrame(animateScroll);
}
}
// 停止滚动的方法
const stopScrolling = () => {
isScrolling.value = false;
if (animationFrameId.value !== null) {
cancelAnimationFrame(animationFrameId.value);
animationFrameId.value = null;
}
}
// 点击了这个
const handleClickBigBox = () => {
console.log('serverpartId.valueserverpartId.valueserverpartId.value', serverpartId.value);
emit('handelGetNoticeListAllId', serverpartId.value, 'notice', noticeMessageObj.value)
}
onUnmounted(() => {
// 停止滚动
stopScrolling();
})
</script>
<template>
<!-- 横向滚动 -->
<div class="noticeListBigBox" @click="handleClickBigBox">
<img class="noticeIcon" :src="noticeIcon" />
<div class="noticeListBox">
<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">
{{ item.NOTICEINFO_TITLE || '-' }}
</div>
</div>
</div>
</div>
</div>
<!-- 纵向滚动 -->
<!-- <div class="noticeListBigBox">
<img class="noticeIcon" :src="noticeIcon" />
<div class="noticeListBox">
<div :class="noticeList.length > 1 ? 'noticeList scrolling' : 'noticeList'">
<template v-if="noticeList.length > 1">
<div class="noticeItem" v-for="(item, index) in noticeList.concat(noticeList)" :key="index">
<div class="icon"></div>
<div class="contentMessage">
{{ item.NOTICEINFO_TITLE || '-' }}
</div>
</div>
</template>
<template v-else>
<div class="noticeItem" v-for="(item, index) in noticeList" :key="index">
<div class="icon"></div>
<div class="contentMessage">
{{ item.NOTICEINFO_TITLE || '-' }}
</div>
</div>
</template>
</div>
</div>
</div> -->
</template>