Browse Source

发现页和公告页发送消息可以跳转,切屏滚动可以滚动到底部,安卓端虚拟键盘上推输入框,苹果端还推不上去,背景图需要修改

hxl
hongxilin 3 months ago
parent
commit
a54430ce8a
  1. 3
      package-lock.json
  2. 10
      src/views/AIchat.vue
  3. 283
      src/views/homePage.vue

3
package-lock.json

@ -7177,8 +7177,9 @@
},
"node_modules/vconsole": {
"version": "3.15.1",
"resolved": "https://registry.npmmirror.com/vconsole/-/vconsole-3.15.1.tgz",
"resolved": "https://mirrors.huaweicloud.com/repository/npm/vconsole/-/vconsole-3.15.1.tgz",
"integrity": "sha512-KH8XLdrq9T5YHJO/ixrjivHfmF2PC2CdVoK6RWZB4yftMykYIaXY1mxZYAic70vADM54kpMQF+dYmvl5NRNy1g==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.17.2",
"copy-text-to-clipboard": "^3.0.1",

10
src/views/AIchat.vue

@ -180,12 +180,20 @@ const hasValidData = ref(false)
//
const chartInstancesMap = {};
// length
const previousMessagesLength = ref(0);
watch(
() => props.messages,
async (newVal, oldVal) => {
console.log(newVal, 'newVal')
console.log(oldVal, 'oldVal')
console.log(previousMessagesLength.value, 'previousMessagesLength')
console.log(newVal.length, 'newVal.length')
//
if (!newVal?.length || newVal === oldVal) return;
if (!newVal?.length || newVal === previousMessagesLength.value) return;
previousMessagesLength.value = newVal.length;
if (newVal.length > 0) {
console.log("消息列表已更新,最新消息:", newVal[newVal.length - 1])
chatStore.messages.push(newVal[newVal.length - 1])

283
src/views/homePage.vue

@ -24,6 +24,9 @@ import voiceNoActive from "../assets/img/homePage/tail/voice-no-active.png";
import sendBtn from "../assets/img/homePage/tail/send.png";
import msgBtn from "../assets/img/homePage/tail/msg.png";
import VConsole from 'vconsole';
const vConsole = new VConsole();
// import { useUserStore } from "../store/userPessionCode.js";
const { getQueryVariable, setActiveTabIndex } = useDataStore()
@ -126,28 +129,32 @@ const sendMessage = async () => {
isScrolling.value = false;
// ensureAIchat AIchat
ensureAIchat();
console.log(chatStore.isLoading, 'isLoading.value1111');
if (!message.value) return;
if (chatStore.isLoading) return;
chatStore.setLoading(true);
console.log(chatStore.isLoading, 'isLoading.value2222');
// isLoading true
messages.value = [
...messages.value,
{
sender: "user",
content: message.value,
timestamp: new Date().toISOString(),
}
];
// console.log(messages.value, 'messages.value');
const messageContent = message.value;
//
message.value = "";
setTimeout(() => {
console.log("延时后添加消息", messageContent);
// isLoading true
messages.value = [
...messages.value,
{
sender: "user",
content: messageContent,
timestamp: new Date().toISOString(),
}
];
console.log(messages.value, 'messages.value');
}, 200);
};
//
@ -219,8 +226,9 @@ watch(
async () => {
// console.log('activeTab', activeTab.value)
isScrolling.value = false; //
await nextTick(); // DOM
throttledSmoothScrollToBottom();
setTimeout(() => {
throttledSmoothScrollToBottom();
}, 100)
// setTimeout(throttledSmoothScrollToBottom, 100);
},
{ deep: true, immediate: true }
@ -319,6 +327,107 @@ const heightListener = () => {
const throttledHeightListener = _.throttle(heightListener, 500, { trailing: false });
//
const handleInputFocus = () => {
console.log('设置输入框焦点监听');
const inputElement = document.querySelector('#input');
if (!inputElement) return;
//
const isMobileDevice = /phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone/i.test(
navigator.userAgent
);
if (isMobileDevice) {
console.log('检测到移动设备,应用键盘适配');
//
const meta = document.querySelector('meta[name="viewport"]');
if (!meta) {
const newMeta = document.createElement('meta');
newMeta.name = 'viewport';
newMeta.content = 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover';
document.getElementsByTagName('head')[0].appendChild(newMeta);
} else {
meta.content = 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover';
}
//
updateAppHeight();
// iOS
const isIOS = /iPhone|iPad|iPod/i.test(navigator.userAgent);
if (isIOS) {
console.log('iOS设备特殊处理');
// iOS
const msgInput = document.querySelector('.msg-input');
if (msgInput) {
//
const originalHeight = window.innerHeight;
//
msgInput.addEventListener('focus', () => {
console.log('iOS输入框获得焦点');
//
setTimeout(() => {
//
const keyboardHeight = originalHeight - window.innerHeight;
console.log('键盘高度:', keyboardHeight);
//
document.documentElement.style.setProperty('--app-height', `${window.innerHeight}px`);
//
const tabContentElement = document.querySelector('.tab-content');
if (tabContentElement) {
tabContentElement.scrollTop = tabContentElement.scrollHeight;
}
//
inputElement.scrollIntoView({ block: 'end', behavior: 'smooth' });
}, 300);
});
//
msgInput.addEventListener('blur', () => {
console.log('iOS输入框失去焦点');
//
setTimeout(() => {
//
document.documentElement.style.setProperty('--app-height', `${originalHeight}px`);
}, 300);
});
}
} else {
// Android
window.addEventListener('resize', _.debounce(() => {
console.log('窗口大小改变:', window.innerHeight);
updateAppHeight();
//
const msgInput = document.querySelector('.msg-input');
if (document.activeElement === msgInput) {
setTimeout(() => {
console.log('滚动到输入框位置');
inputElement.scrollIntoView({ block: 'end', behavior: 'smooth' });
const tabContentElement = document.querySelector('.tab-content');
if (tabContentElement) {
tabContentElement.scrollTop = tabContentElement.scrollHeight;
}
}, 200);
}
}, 100));
}
}
};
function updateAppHeight() {
const vh = window.innerHeight;
document.documentElement.style.setProperty('--app-height', `${vh}px`);
}
onMounted(async () => {
const isPhone =
/phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone/i.test(
@ -330,7 +439,12 @@ onMounted(async () => {
await chatStore.getUserCount();
throttledSmoothScrollToBottom();
throttledHeightListener();
//
handleInputFocus();
//
updateAppHeight();
})
</script>
@ -371,7 +485,7 @@ onMounted(async () => {
</div>
</el-main>
<!-- 尾部 问题输入框 深度思考 多语言 语音播报 -->
<el-footer class="homepage-footer">
<el-footer class="homepage-footer" id="input">
<!-- 第一行按钮 -->
<div class="footer-first-line">
<div class="left-group">
@ -409,7 +523,7 @@ onMounted(async () => {
</template>
<!-- 中间内容部分 -->
<p>
活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则
活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则活动规则
</p>
<template #footer>
<!-- 添加一个div来包裹按钮并设置样式使其居中 -->
@ -454,10 +568,10 @@ onMounted(async () => {
}
.tab-content {
/* height: 100%; */
overflow-y: auto;
overflow-x: hidden;
scroll-behavior: smooth;
height: 100%;
/* 添加平滑滚动效果 */
}
@ -476,55 +590,72 @@ onMounted(async () => {
<style scoped>
.homepage {
height: 100vh;
height: var(--app-height, 100vh);
margin: 0 auto;
background-image: url(src/assets/img/homePage/bk.png);
background-size: 100% 100%;
background-repeat: no-repeat;
background-position: center;
display: flex;
overflow: auto;
overflow: hidden;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
/* 添加iOS设备特殊处理 */
-webkit-overflow-scrolling: touch;
}
.homepage .el-container {
height: 100%;
flex-direction: column;
/* 明确纵向排列 */
display: flex;
overflow: auto;
width: 100%;
overflow: hidden; /* 防止容器滚动 */
}
.el-container .el-header {
height: 10%;
/* 设置头部高度 */
margin-top: 5px;
flex-shrink: 0; /* 防止头部压缩 */
height: auto;
min-height: 60px;
padding: 5px 0;
position: sticky;
top: 0;
z-index: 10;
background-color: rgba(255, 255, 255, 0.9);
}
.el-container .el-main {
overflow-y: hidden;
overflow-x: hidden;
/* 新增滚动条 */
flex: 1 1 0%;
min-height: 0;
scrollbar-width: thin;
scrollbar-color: #888 transparent;
flex: 1; /* 自动占据剩余空间 */
overflow: hidden; /* 主容器不滚动 */
display: flex;
flex-direction: column;
min-height: 0; /* 允许内容区域缩小 */
position: relative;
}
.el-container .el-footer {
/* height: 11%; */
flex-shrink: 0;
height: auto;
min-height: 70px;
gap: 5px;
margin-top: 0;
position: sticky;
bottom: 0;
z-index: 20;
background-color: rgba(255, 255, 255, 0.97);
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.05);
/* 添加iOS设备特殊处理 */
-webkit-transform: translateZ(0);
transform: translateZ(0);
}
.homepage-head {
padding: 0px;
/* 启用 flex 布局 */
display: flex;
position: relative;
/* 左右分开布局 */
justify-content: space-between;
width: 100%;
}
.homepage-right-group {
@ -558,58 +689,49 @@ onMounted(async () => {
transition: transform 0.3s;
}
/* @keyframes tilt {
0% { transform: rotate(0deg); }
50% { transform: rotate(10deg); }
100% { transform: rotate(-10deg); }
130% { transform: rotate(0deg); }
} */
.homepage-right-group .announcement-btn:hover {
transform: scale(1.3);
/* animation: tilt 1s ease-in-out; */
}
.homepage-body {
padding: 0px;
height: calc(100% - 70px);
/* 根据底部高度调整 */
display: flex;
flex-direction: column;
flex: 1;
min-height: 0; /* 允许内容区域缩小 */
overflow: hidden;
}
.main-wrapper {
height: 100%;
display: flex;
flex-direction: column;
flex: 1;
min-height: 0; /* 允许内容区域缩小 */
}
.tab-section {
flex-shrink: 0;
/* 禁止伸缩 */
flex-shrink: 0; /* 禁止伸缩 */
}
.tab-content {
flex: 1;
overflow-y: auto;
min-height: 0;
/* 关键:允许内容收缩 */
min-height: 0; /* 关键:允许内容收缩 */
}
.homepage-logo {
height: 100%;
/* 改为根据内容自适应 */
width: fit-content;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
/* 固定左间距 */
margin-left: 20px;
margin-right: auto;
/* 新增相对定位 */
position: relative;
}
/* 新增媒体查询适配小屏幕 */
@media (max-width: 768px) {
.homepage-logo {
margin-left: 10px;
@ -619,15 +741,12 @@ onMounted(async () => {
.logo1 {
width: 120px;
/* 固定 logo1 尺寸 */
height: auto;
margin-bottom: 8px;
/* 添加间距 */
}
.logo2 {
width: 80px;
/* 缩小 logo2 尺寸 */
height: auto;
}
@ -636,17 +755,16 @@ onMounted(async () => {
display: flex;
flex-direction: column;
gap: 5px;
/* margin-top: auto; */
margin-bottom: 20px;
flex-shrink: 0;
height: auto;
width: 100%;
background-color: #fff;
}
.footer-first-line {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: auto;
padding: 5px 15px;
flex-shrink: 0;
}
@ -673,16 +791,14 @@ onMounted(async () => {
.footer-second-line {
position: relative;
display: flex;
height: auto;
align-items: flex-end;
flex: 1;
margin-top: auto;
min-height: 34px;
align-items: center;
padding: 5px 15px 10px;
flex-shrink: 0;
}
.msg-icon {
position: absolute;
left: 12px;
left: 25px;
top: 50%;
transform: translateY(-50%);
width: 24px;
@ -693,31 +809,26 @@ onMounted(async () => {
border: none !important;
box-shadow: none !important;
overflow-y: auto !important;
/* 强制显示滚动条 */
transition: all 0.2s ease-out;
/* 添加过渡效果 */
padding: 8px 20px 8px 45px !important;
resize: none !important;
line-height: 1.5 !important;
max-height: 100px !important;
}
/* .msg-input:deep(.el-textarea__inner:focus) {
border: none !important;
box-shadow: 0 4px 12px rgba(89, 24, 241, 0.3) !important;
} */
.msg-input {
min-height: 34px;
max-height: 120px;
width: calc(100% - 65px);
width: 100%;
border-radius: 20px;
padding: 0px 20px 0 45px;
font-size: 16px;
transition: height 0.2s ease-out;
/* 添加高度过渡效果 */
transition: all 0.3s ease-out;
overflow-y: hidden;
/* 隐藏垂直滚动条 */
box-shadow: 0 4px 12px rgba(89, 24, 241, 0.3);
background: #fff;
z-index: 5;
/* 添加iOS设备特殊处理 */
-webkit-appearance: none;
appearance: none;
}
.msg-input:focus {
@ -730,7 +841,7 @@ onMounted(async () => {
}
.footer-second-line {
height: 50px;
padding: 5px 10px 10px;
}
.msg-input {

Loading…
Cancel
Save