chore: initialize qiming workspace repository

This commit is contained in:
Codex
2026-05-29 14:22:48 +08:00
commit bfd67a0f2c
10750 changed files with 1885711 additions and 0 deletions

View File

@@ -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);
}
}