chore: initialize qiming workspace repository
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
import { nextTick } from "vue";
|
||||
import AgentDetailData from "./AgentDetailData.uts";
|
||||
|
||||
/**
|
||||
* 滚动管理层:专门处理滚动相关的逻辑
|
||||
* 兼容微信小程序和 H5/App
|
||||
*/
|
||||
export default class ScrollManager {
|
||||
private data: AgentDetailData;
|
||||
// 记录上次滚动位置,用于判断滚动方向
|
||||
private lastScrollTop: number = 0;
|
||||
|
||||
constructor(private data: AgentDetailData) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 滚动到最后一条消息
|
||||
* 使用 scroll-into-view 方式,兼容所有平台
|
||||
*/
|
||||
scrollToLastMsg(userClick: boolean): void {
|
||||
this.data.autoToLastMsg.value = true;
|
||||
this.data.scrollIntoView.value = "";
|
||||
this.data.scrollWithAnimation.value = userClick;
|
||||
nextTick(() => {
|
||||
this.data.scrollIntoView.value = "last-msg";
|
||||
this.data.scrollInBottom.value = true;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置是否在滚动底部
|
||||
* 使用 scroll 事件参数,兼容微信小程序
|
||||
*/
|
||||
setIsInScrollBottom(e: UniScrollEvent): void {
|
||||
nextTick(() => {
|
||||
// 使用事件参数获取滚动信息,兼容微信小程序
|
||||
const scrollTop = e?.detail?.scrollTop ?? 0;
|
||||
const scrollHeight = e?.detail?.scrollHeight ?? 0;
|
||||
// #ifdef MP-WEIXIN
|
||||
// 微信小程序需要通过其他方式获取容器高度,这里使用估算值
|
||||
const offsetHeight = 600; // 默认视窗高度估算
|
||||
// #endif
|
||||
// #ifndef MP-WEIXIN
|
||||
const scrollList = uni.getElementById("msg-list");
|
||||
const offsetHeight = scrollList?.offsetHeight ?? 600;
|
||||
// #endif
|
||||
|
||||
const diff: number = scrollHeight - scrollTop - offsetHeight;
|
||||
const isInBottom = diff < 50;
|
||||
this.data.scrollInBottom.value = isInBottom;
|
||||
|
||||
// 如果滑到底部,自动恢复自动滚动
|
||||
if (isInBottom) {
|
||||
this.data.autoToLastMsg.value = true;
|
||||
}
|
||||
|
||||
// 只有在用户主动滚动(触摸或鼠标)时才可能禁用自动滚动
|
||||
// 且只在向上滚动(远离底部)时禁用
|
||||
const isScrollingUp = scrollTop < this.lastScrollTop;
|
||||
this.lastScrollTop = scrollTop;
|
||||
|
||||
if (
|
||||
(this.data.scrollTouch.value || this.data.mouseScroll.value) &&
|
||||
isScrollingUp && !isInBottom
|
||||
) {
|
||||
// 用户向上滚动时,立即禁用自动滚动,不需要等待滚动到一定距离
|
||||
// 这样用户可以更容易地中断快速消息流带来的自动滚动
|
||||
this.data.autoToLastMsg.value = false;
|
||||
// 同时显示"滚动到底部"按钮
|
||||
this.data.scrollInBottom.value = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 锁定自动滚动到底部
|
||||
* 修复:不再过早禁用自动滚动,仅在特殊情况下处理
|
||||
*/
|
||||
lockAutoToLastMsg(): void {
|
||||
// 如果已经处理过或不需要锁定,直接返回
|
||||
if (!this.data.needSetLockAutoToLastMsg.value) return;
|
||||
|
||||
// 简化逻辑:只有当消息列表为空时才禁用
|
||||
// 其他情况保持 autoToLastMsg 的当前状态
|
||||
if (this.data.messageList.value.length === 0) {
|
||||
this.data.autoToLastMsg.value = false;
|
||||
this.data.needSetLockAutoToLastMsg.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 滚动事件处理
|
||||
* 修复:不再错误地设置 mouseScroll,让触摸和鼠标滚动分开处理
|
||||
*/
|
||||
onScroll(e: UniScrollEvent): void {
|
||||
// mouseScroll 只在 H5 平台由 wheel 事件设置,这里不设置
|
||||
// 触摸滚动由 touchstart/touchend 事件控制 scrollTouch
|
||||
this.setIsInScrollBottom(e);
|
||||
this.data.scrolling.value = true;
|
||||
if (this.data.scrollingT.value != 0) {
|
||||
clearTimeout(this.data.scrollingT.value);
|
||||
}
|
||||
this.data.scrollingT.value = setTimeout(() => {
|
||||
this.data.scrolling.value = false;
|
||||
}, 500);
|
||||
}
|
||||
|
||||
/**
|
||||
* 滚动到指定消息位置
|
||||
* 用于加载更多历史消息后保持滚动位置
|
||||
*/
|
||||
scrollToMessage(messageId: string | number): void {
|
||||
this.data.scrollWithAnimation.value = false;
|
||||
this.data.scrollIntoView.value = "";
|
||||
// 延迟设置,确保微信小程序 DOM 渲染完成后再触发定位
|
||||
setTimeout(() => {
|
||||
this.data.scrollIntoView.value = `msg-wrapper-${messageId}`;
|
||||
}, 150);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user