266 lines
7.6 KiB
Vue
266 lines
7.6 KiB
Vue
<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> |