创新项目实训(20)——在线医生

为了给用户提供便利,使得患者能够在对自己的病情有疑问时,进行一个咨询。我们在此处提供了一个问答页面,接入了后端的大语言模型接口,来模拟医生为患者提供答案。

前端:

<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({})
  }

})

效果:

在这里插入图片描述

  • 10
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值