课堂讨论对话实现

<template>
  <div class="discussContainer">
    <div ref="content" class="discussArea">
      <div v-for="(item,index) in msgList" :key="item.id" :class="item.hasMe?'me':'you'" class="itemBox">
        <div class="top">
          <span class="name">{{ item.teacherName }}</span>
          <span class="time">{{ item.createTime }}</span>
        </div>
        <div class="bottom">
          <span class="name">{{ item.teacherName }}</span>
          <div class="msg">{{ item.comment }}</div>
        </div>
      </div>
    </div>
    <div class="inputArea">
      <el-input
          v-model="iptVal"
          :autosize="{ minRows: 1, maxRows: 6}"
          placeholder="发表课堂言论,请注意言辞"
          resize="none"
          size="medium"
          type="textarea"
          @keydown.native="handleEnter($event)">
      </el-input>
      <span class="sendBox" @click="toSend">发送</span>
    </div>
  </div>

</template>
<script>
import WebSocket from '@/utils/websocket';
import {getDiscussionList, saveDiscussion} from "@/api/persional";

export default {
  props: {
    roomId: {
      type: [Number, String],
      default: ''
    },
    lessonId: {
      type: [Number, String],
      default: ''
    }
  },
  data() {
    return {
      iptVal: '',
      socket: null,
      pageNum: 1,
      msgList: []
    }
  },
  created() {
    this.initWs()
  },
  mounted() {
    // this.$nextTick(() => {
    //   this.$refs.content.addEventListener('scroll', this.handleScroll)
    // })
    console.log(this.$store.state.user.userInfo)
    this.getList(true)
  },
  beforeDestroy() {
    this.socket && this.socket.close()
  },
  methods: {
    handleEnter(e) {
      if (!e.shiftKey && e.keyCode == 13) {
        console.log(e, 'huiche回车', e.shiftKey);
        e.stopPropagation()
        e.preventDefault()
        this.toSend()
      }
    },
    initWs() {
      const options = {
        url: window.WEBSOCKET_URL,
        onmessage: this.receiveMsg,
        msgInfo: {
          type: 'SUPERVISE_TEACHER_CONNECT',
          roomId: this.roomId,
          lessonId: this.lessonId,
          id: this.$store.state.user.userInfo.id
        },
        // 保活周期 10s
        timer: 10000,
        // onclose: () => {
        //   this.socket&&this.socket.close()
        // }
      };
      console.log(options, '???')
      this.socket = new WebSocket(options);
    },
    receiveMsg(data) {
      console.log('===', data)
      this.getList()
    },
    async getList(toBottom = false) {
      let reachBottom //除第一次外 其余情况判断滚动条是否在最底部 在最底部时 最新消息来临时滚动到底部 反之不滚动到最底部
      if (!toBottom) {
        reachBottom = (this.$refs.content.clientHeight - 0 + this.$refs.content.scrollTop) == this.$refs.content.scrollHeight
      }
      let param = {
        lessonId: this.lessonId,
      }
      let res = await getDiscussionList(param)
      this.msgList = res.data
      this.$nextTick(() => {
        if (toBottom||reachBottom) {
          let dom = this.$refs.content
          dom.scrollTo({top: dom.scrollHeight, behavior: 'smooth'})
          console.log(this.$refs.content.scrollHeight, '内容高度');
        }

      })

    },
    toSend() {
      let param = {
        comment: this.iptVal,
        lessonId: this.lessonId
      }
      saveDiscussion(param).then(res => {
        if (res.code == 200) {
          this.iptVal = ''
          this.getList()
        }
      })
    },
    handleScroll() {
      console.log(this.$refs.content.scrollTop, '??????????????????')
      const scrollTop = this.$refs.content.scrollTop
      if (scrollTop === 0) {
        console.log('滚动到顶了');
      }

    }
  },
}
</script>
<style lang="scss" scoped>
::v-deep .el-textarea__inner {
  min-height: 40px !important;
}

.discussContainer {
  height: 100%;
  overflow: hidden;
  display: flex;
  flex-direction: column;

  .discussArea {
    min-height: 0;
    flex: 1;
    padding: 16px;
    overflow-y: overlay;

    .itemBox {
      display: flex;
      flex-direction: column;
      margin-bottom: 32px;

      .name {
        font-size: 16px;
        line-height: 22px;
      }

      &.me {
        align-items: flex-end;
        padding-left: 60px;

        .top, .bottom {
          display: flex;
          flex-direction: row-reverse;
        }

        .top .name {
          margin-left: 8px;
        }
      }

      &.you {
        align-items: flex-start;
        padding-right: 60px;

        .top .name {
          margin-right: 8px;
        }
      }

      .top {
        margin-bottom: 4px;

        .time {
          white-space: nowrap;
          font-size: 14px;
          color: #999999;
        }
      }

      .bottom {
        display: flex;
        flex-direction: row;

        .name {
          opacity: 0;
        }
      }

      &.me .bottom .msg, &.you .bottom .msg {
        flex: 1;
        word-break: break-all;
        line-height: 22px;
        font-size: 16px;
        padding: 8px;
        text-align: left;
        color: #333;
      }

      &.me .bottom .msg {
        background-color: #CDDCFD;
        border-radius: 12px 0px 12px 12px;

      }

      &.you .bottom .msg {
        background-color: #ECEEF2;
        border-radius: 0px 12px 12px 12px;
      }
    }

  }

  .inputArea {
    max-height: 210px;
    background: #F7F8FA;
    display: flex;
    flex-direction: row;
    padding: 18px 16px;
    align-items: center;

    .sendBox {
      width: 66px;
      height: 40px;
      line-height: 40px;
      border-radius: 2px;
      background: #1890ff;
      color: #fff;
      cursor: pointer;
      margin-left: 12px;
    }
  }

}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值