为了给用户提供便利,使得患者能够在对自己的病情有疑问时,进行一个咨询。我们在此处提供了一个问答页面,接入了后端的大语言模型接口,来模拟医生为患者提供答案。
前端:
<view class="container">
<scroll-view scroll-y scroll-into-view="{{toView}}" class="scroll-container">
<view class="top">——您正在与在线医生进行通话——</view>
<block wx:key="index" wx:for="{{msgList}}" wx:for-index="index" wx:for-item="item">
<!-- 单个消息1 客服发出(左) -->
<view wx:if="{{item.speaker=='server'}}" id="msg-{{index}}" class="message server">
<image class="avatar-left" src="/images/medical640.png"></image>
<view class="message-bubble server">{{item.content}}</view>
</view>
<!-- 单个消息2 用户发出(右) -->
<view wx:else id="msg-{{index}}" class="message customer">
<view class="message-bubble customer">{{item.content}}</view>
<image class="avatar-right" src="/images/animal640.png"></image>
</view>
</block>
<!-- 占位 -->
<!-- <view style="width: 100%; height: 18vw;"></view> -->
</scroll-view>
<view class="inputRoom" style="bottom: {{inputBottom}};">
<image class="home-icon" src="/images/home.png" mode="widthFix"></image>
<view class="input-container">
<textarea class="input" placeholder="请输入消息" value="{{inputVal}}" bindinput="onInputChange" bindfocus="focus" bindblur="blur" bindconfirm="sendOnEnter" bindkeydown="onKeyDown"></textarea>
<button class="send-button" bindtap="sendClick">发送</button>
</view>
</view>
</view>
.page {
height: 100%;
}
.container {
display: flex;
flex-direction: column;
height: 100vh;
background-color: #fff;
}
.header {
width: 100%;
height: 80rpx;
background-color: #3b6ba5;
display: flex;
justify-content: center;
align-items: center;
box-shadow: 0 2rpx 5rpx rgba(160, 158, 158, 0.1);
}
.header-title {
font-size: 40rpx;
font-weight: bold;
color: #fff;
}
.ss {
margin-top: 20rpx;
/* text-align: center; */
margin-bottom: 20rpx;
}
.scroll-container {
flex: 1;
padding: 10rpx;
background-color: #fff;
border-top-left-radius: 20rpx;
border-top-right-radius: 20rpx;
box-shadow: 0 -5rpx 10rpx rgba(0, 0, 0, 0.1);
overflow-y: scroll;
}
.top {
width: 80%;
position: relative;
/* top: 38rpx; */
text-align: center;
margin: 0 auto;
font-size: 30rpx;
color: #555151;
background-color: #fff; /* 使背景透明 */
border: none; /* 移除边框 */
margin-bottom: 20rpx;
}
.message {
display: flex;
padding: 20rpx;
align-items: center;
}
.server {
justify-content: flex-start;
}
.customer {
justify-content: flex-end;
}
.avatar-left {
width: 80rpx;
height: 80rpx;
border-radius: 50%;
margin-right: 20rpx;
}
.avatar-right {
width: 80rpx;
height: 80rpx;
border-radius: 50%;
margin-left: 20rpx;
}
.message-bubble {
max-width: 70%;
padding: 20rpx;
border-radius: 20rpx;
font-size: 30rpx;
line-height: 40rpx;
box-shadow: 0 2rpx 5rpx rgba(0, 0, 0, 0.1);
word-break: break-all; /* 添加这一行 */
}
.server .message-bubble {
background-color: #e0e0e0;
color: #333;
}
.customer .message-bubble {
background-color: #007aff;
color: #fff;
}
.inputRoom {
height: 180rpx;
width: 100%;
height: auto; /* 自动高度 */
display: flex;
align-items: center;
padding: 20rpx;
background-color: #fff;
border-top: 1rpx solid #e0e0e0;
box-shadow: 0 -2rpx 5rpx rgba(0, 0, 0, 0.1);
}
.home-icon {
margin-left: 20rpx;
width: 40rpx;
height: 40rpx;
}
.input-container {
flex: 1;
display: flex;
align-items: center;
flex-direction: column;
margin-left: 20rpx;
margin-right: 20rpx;
background-color: #f0f0f0;
border-radius: 20rpx;
padding: 10rpx;
position: relative;
height: 200rpx;
}
.input {
flex: 1;
margin-top: 10rpx;
margin-left: 20rpx;
font-size: 30rpx;
border: none;
background-color: transparent;
resize: none; /* 禁用手动调整大小 */
width: 100%;
height: 100%;
line-height: 40rpx; /* 行高 */
overflow-y: auto; /* 自动换行 */
}
.send-button {
z-index: 999;
margin-left: 30rpx;
position: absolute;
bottom: 20rpx;
right: 20rpx;
width: 100rpx !important; /* 调整宽度 */
height: 60rpx; /* 调整高度 */
padding: 0;
background-color: #9adf91;
color: white;
border: none;
border-radius: 10rpx;
font-size: 24rpx; /* 调整字体大小 */
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
后端请求:
// pages/contact/contact.js
const app = getApp();
var inputVal = '';
var msgList = [];
var windowWidth = wx.getSystemInfoSync().windowWidth;
var windowHeight = wx.getSystemInfoSync().windowHeight;
var keyHeight = 0;
/**
* 初始化数据
*/
function initData(that) {
inputVal = '';
msgList = [{
speaker: 'server',
contentType: 'text',
content: 'Hi!我是您的专属在线医生!不管您有什么问题都可以告诉我,我会尽心为您解答~'
},
{
speaker: 'customer',
contentType: 'text',
content: '111'
}
]
that.setData({
msgList,
inputVal
})
}
Page({
/**
* 页面的初始数据
*/
data: {
scrollHeight: '100vh',
inputBottom: 0,
inputVal: '' // 确保inputVal在data中初始化
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function(options) {
initData(this);
this.initWebSocket();
},
initWebSocket: function() {
this.socketTask = wx.connectSocket({
url: 'ws://localhost:8000/call'
});
this.socketTask.onMessage(this.onSocketMessage);
},
onSocketMessage: function(res) {
console.log('收到服务器消息:', res.data);
const message = res.data;
this.setData({
msgList: [...this.data.msgList, {speaker: 'server', contentType: 'text', content: message}]
});
},
// 发送消息到服务器
sendSocketMessage: function(message) {
if (this.socketTask) {
this.socketTask.send({
data: message
});
}
},
/**
* 获取聚焦
*/
focus: function(e) {
keyHeight = e.detail.height;
this.setData({
scrollHeight: (windowHeight - keyHeight) + 'px'
});
this.setData({
toView: 'msg-' + (msgList.length - 1),
inputBottom: keyHeight + 'px'
})
},
//失去聚焦(软键盘消失)
blur: function(e) {
this.setData({
scrollHeight: '100vh',
inputBottom: 0
})
this.setData({
toView: 'msg-' + (msgList.length - 1)
})
},
/**
* 发送点击监听
*/
sendClick: function(e) {
console.log("发送按钮被点击")
if (!this.data.inputVal.trim()) return; // 确保输入框不为空
this.sendSocketMessage(this.data.inputVal);
msgList.push({
speaker: 'customer',
contentType: 'text',
content: this.data.inputVal
});
this.setData({
msgList: msgList,
inputVal: '',
toView: 'msg-' + (msgList.length - 1) // 滚动到最新消息
});
},
sendOnEnter: function(e) {
if (e.detail.value.trim() !== '') {
this.sendClick(); // 调用发送消息的函数
}
},
/**
* 输入框内容变化时更新inputVal
*/
onInputChange: function(e) {
this.setData({
inputVal: e.detail.value
});
},
onKeyDown: function(e) {
if (e.keyCode === 13) { // 按下 Enter 键
e.preventDefault(); // 阻止默认行为(换行)
if (e.detail.value.trim() !== '') {
this.sendClick(); // 调用发送消息的函数
}
}
},
/**
* 退回上一页
*/
toBackClick: function() {
wx.navigateBack({})
}
})
效果: