278 lines
7.2 KiB
Plaintext
278 lines
7.2 KiB
Plaintext
<template>
|
|
<view class="temporary-session-container">
|
|
<custom-nav-bar :title="agentInfo?.name" show-back :icon="agentInfo?.icon">
|
|
</custom-nav-bar>
|
|
|
|
<!-- 主体区域:描述 -->
|
|
<scroll-view class="main-content" scroll-y>
|
|
<view class="main-content-inner">
|
|
<!-- 描述框 / 气泡样式 -->
|
|
<view class="agent-desc-box">
|
|
<text class="agent-desc-text">
|
|
{{agentInfo?.description || t("Mobile.TempSession.defaultDesc")}}
|
|
</text>
|
|
</view>
|
|
</view>
|
|
</scroll-view>
|
|
|
|
<!-- 底部输入栏,参考 chat-input-phone 样式实现 -->
|
|
<view
|
|
class="bottom-input-area"
|
|
v-if="showTextarea"
|
|
:style="{ paddingBottom: keyboardHeight > 0 ? '16rpx' : 'calc(32rpx + env(safe-area-inset-bottom))' }"
|
|
>
|
|
<view class="record-tip-container">
|
|
<view class="chat-input-container" :class="{ 'multi-line': isMultiLine }">
|
|
<textarea
|
|
class="input"
|
|
:class="{ 'input-text': inputValue?.length }"
|
|
placeholder-class="input-placeholder"
|
|
v-model="inputValue"
|
|
:auto-height="true"
|
|
@linechange="handleLineChange"
|
|
@keyboardheightchange="onKeyboardheightchange"
|
|
@confirm="handleSend"
|
|
:placeholder="t('Mobile.TempSession.inputPlaceholder')"
|
|
:show-confirm-bar="false"
|
|
:maxlength="-1"
|
|
:disable-default-padding="true"
|
|
></textarea>
|
|
|
|
<!-- 图标容器,当有输入内容时显示发送按钮 -->
|
|
<view class="icon-container" v-if="inputValue && inputValue.trim() !== ''">
|
|
<text class="iconfont icon-send icon-send-image" @click="handleSend" />
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<!-- 开启键盘时,底部垫高安全区域 -->
|
|
<view class="keyboard-cover" :style="{ height: keyboardHeight + 'px' }"></view>
|
|
</view>
|
|
|
|
<!-- 登录弹窗 -->
|
|
<auth-login-popup ref="loginPopupRef" />
|
|
</view>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref } from "vue";
|
|
import { onLoad, onReady } from "@dcloudio/uni-app";
|
|
import { useI18n } from "@/utils/i18n";
|
|
|
|
const { t } = useI18n();
|
|
|
|
// 缓存数据模型
|
|
interface TempAgentInfo {
|
|
name: string;
|
|
icon: string;
|
|
description: string;
|
|
}
|
|
|
|
// 变量定义
|
|
const agentInfo = ref<TempAgentInfo | null>(null);
|
|
const inputValue = ref("");
|
|
const isMultiLine = ref<boolean>(false);
|
|
const showTextarea = ref<boolean>(false);
|
|
const keyboardHeight = ref<number>(0);
|
|
const loginPopupRef = ref<any>(null);
|
|
|
|
// 页面加载时读取缓存
|
|
onLoad(() => {
|
|
try {
|
|
const cachedData = uni.getStorageSync("temp_agent_info");
|
|
if (cachedData) {
|
|
agentInfo.value = JSON.parse(cachedData) as TempAgentInfo;
|
|
}
|
|
} catch (err) {
|
|
console.error("解析缓存出的智能体出错", err);
|
|
}
|
|
});
|
|
|
|
// 等待页面过场动画完成之后,再将真正的原生 textarea 暴露出来,避免跳转闪烁
|
|
onReady(() => {
|
|
setTimeout(() => {
|
|
showTextarea.value = true;
|
|
}, 500);
|
|
});
|
|
|
|
// 发送消息逻辑: 未登录用户拦截,弹登录弹框
|
|
const handleSend = () => {
|
|
if (!inputValue.value.trim()) {
|
|
uni.showToast({ title: t("Mobile.Page.inputRequired"), icon: "none" });
|
|
return;
|
|
}
|
|
// 在临时会话页只负责拦截并让用户登录
|
|
if (loginPopupRef.value) {
|
|
loginPopupRef.value.open();
|
|
}
|
|
};
|
|
|
|
// 监听输入框行数变化
|
|
const handleLineChange = (e: UniTextareaLineChangeEvent) => {
|
|
isMultiLine.value = e.detail.lineCount > 1;
|
|
};
|
|
|
|
// 键盘高度变化
|
|
const onKeyboardheightchange = (res: UniInputKeyboardHeightChangeEvent) => {
|
|
// 微信小程序
|
|
// #ifdef MP-WEIXIN
|
|
if (res.detail.height > 31) {
|
|
keyboardHeight.value = 30; // 这里的 30 对应简单输入框起跳补偿
|
|
} else {
|
|
keyboardHeight.value = 0;
|
|
}
|
|
// #endif
|
|
|
|
// 非微信小程序
|
|
// #ifndef MP-WEIXIN
|
|
keyboardHeight.value = res.detail.height;
|
|
// #endif
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.temporary-session-container {
|
|
display: flex;
|
|
flex-direction: column;
|
|
width: 100vw;
|
|
height: 100vh;
|
|
background-color: #ffffff;
|
|
overflow: hidden; /* 保证整体不超高 */
|
|
|
|
/* 内容展示区 */
|
|
.main-content {
|
|
flex: 1;
|
|
height: 0; /* 这是让 scroll-view flex 布局下工作并自我滚动的核心 */
|
|
|
|
.main-content-inner {
|
|
padding: 32rpx;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.agent-desc-box {
|
|
align-self: flex-start;
|
|
padding: 24rpx 0;
|
|
margin-bottom: 40rpx;
|
|
|
|
.agent-desc-text {
|
|
font-size: 28rpx;
|
|
color: #333;
|
|
line-height: 1.5;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* 底部输入区 */
|
|
.bottom-input-area {
|
|
padding: 16rpx 32rpx; /* 下边距由动态 style 计算接管 */
|
|
background-color: #fff;
|
|
border-radius: 16rpx 16rpx 0 0;
|
|
position: relative;
|
|
}
|
|
|
|
/* 仿 chat-input-phone 容器 */
|
|
.record-tip-container {
|
|
display: flex;
|
|
flex-direction: column;
|
|
width: 100%;
|
|
border-radius: 24rpx;
|
|
box-shadow:
|
|
0 9rpx 45rpx 0 rgba(0, 0, 0, 0.08),
|
|
0 2rpx 10rpx 0 rgba(0, 0, 0, 0.08),
|
|
0 0 3rpx 0 rgba(0, 0, 0, 0.08);
|
|
position: relative;
|
|
}
|
|
|
|
.chat-input-container {
|
|
width: 100%;
|
|
position: relative;
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: center;
|
|
align-self: stretch;
|
|
min-height: 90rpx;
|
|
|
|
.input {
|
|
width: 100%; // 这里直接撑满,因为右边不常驻按钮
|
|
line-height: 44rpx;
|
|
max-height: 320rpx;
|
|
margin: 10rpx 0 10rpx 10rpx;
|
|
padding: 0 10rpx;
|
|
border: none;
|
|
font-size: 32rpx;
|
|
font-weight: 400;
|
|
color: #000;
|
|
box-sizing: border-box;
|
|
resize: none;
|
|
outline: none;
|
|
|
|
/* 给右侧图标预留空间 */
|
|
&.input-text {
|
|
width: 90%;
|
|
}
|
|
|
|
/* 隐藏滚动条 */
|
|
scrollbar-width: none;
|
|
-ms-overflow-style: none;
|
|
&::-webkit-scrollbar {
|
|
display: none;
|
|
width: 0;
|
|
height: 0;
|
|
}
|
|
}
|
|
|
|
.input-placeholder {
|
|
color: rgba(0, 0, 0, 0.25);
|
|
font-size: 28rpx;
|
|
font-weight: 400;
|
|
}
|
|
|
|
.icon-container {
|
|
position: absolute;
|
|
right: 0rpx;
|
|
bottom: 0rpx;
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: center;
|
|
flex-shrink: 0;
|
|
z-index: 50;
|
|
background-color: transparent; /* 为了保持与框体融合 */
|
|
|
|
.iconfont {
|
|
padding: 15rpx;
|
|
}
|
|
|
|
.icon-send-image {
|
|
color: #5147ff !important;
|
|
font-size: 48rpx;
|
|
}
|
|
}
|
|
}
|
|
|
|
.chat-input-container.multi-line {
|
|
flex-direction: column;
|
|
align-items: stretch;
|
|
gap: 16rpx;
|
|
|
|
.input {
|
|
width: 87%;
|
|
line-height: 44rpx;
|
|
}
|
|
|
|
.icon-container {
|
|
align-self: flex-end;
|
|
flex-direction: row;
|
|
justify-content: flex-end;
|
|
}
|
|
}
|
|
|
|
.keyboard-cover {
|
|
// #ifdef APP-ANDROID
|
|
margin-bottom: env(safe-area-inset-bottom);
|
|
// #endif
|
|
// #ifndef APP-ANDROID
|
|
padding-bottom: env(safe-area-inset-bottom);
|
|
// #endif
|
|
}
|
|
}
|
|
</style>
|