guhongwei 4 lat temu
rodzic
commit
089033eded

+ 114 - 0
src/components/chat.vue

@@ -0,0 +1,114 @@
+<template>
+  <div id="chat">
+    <el-row>
+      <el-col :span="24" class="chat">
+        <el-col :span="24" class="top">
+          <el-col :span="24" v-for="(i, index) in chatList" :key="index">
+            <span v-if="isSender(i, index)">
+              <el-col :span="24" class="sender">
+                <p>[{{ i.send_time }}]{{ i.sender_name }}</p>
+                <p>{{ i.content }}</p>
+              </el-col>
+            </span>
+            <span v-else>
+              <el-col :span="24" class="receiver">
+                <p>{{ i.receiver_name }}[{{ i.send_time }}]</p>
+                <p>{{ i.content }}</p>
+              </el-col>
+            </span>
+          </el-col>
+        </el-col>
+        <el-col :span="24" class="down">
+          <el-col :span="20">
+            <el-input v-model="contInput"></el-input>
+          </el-col>
+          <el-col :span="4">
+            <el-button type="primary" size="mini" @click="speak">发送</el-button>
+          </el-col>
+        </el-col>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'chat',
+  props: {
+    chatList: { type: Array },
+  },
+  components: {},
+  data: function() {
+    return {
+      contInput: '',
+    };
+  },
+  created() {},
+  methods: {
+    // 当前用户为发言人
+    isSender(data) {
+      return this.user.userid == data.sender_id;
+    },
+    // 发言提交
+    speak() {
+      this.$emit('speak', this.contInput);
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+p {
+  padding: 0;
+  margin: 0;
+}
+.chat {
+  position: relative;
+  min-height: 620px;
+  .top {
+    padding: 10px;
+    height: 580px;
+    overflow: auto;
+    // 发言人
+    .sender {
+      float: right;
+      width: 100;
+      text-align: right;
+      p:first-child {
+        font-size: 18px;
+        font-weight: bold;
+      }
+    }
+    // 接收人
+    .receiver {
+      float: left;
+      width: 100;
+      text-align: left;
+      p:first-child {
+        font-size: 18px;
+        font-weight: bold;
+      }
+    }
+  }
+  .down {
+    position: absolute;
+    bottom: 0;
+    /deep/.el-button {
+      width: 100%;
+      height: 40px;
+      padding: 0;
+      font-size: 18px;
+    }
+  }
+}
+</style>

+ 5 - 0
src/router/index.js

@@ -166,6 +166,11 @@ const routes = [
     meta: { title: '课后答疑', isleftarrow: true },
     meta: { title: '课后答疑', isleftarrow: true },
     component: () => import('../views/user/afterClass.vue'),
     component: () => import('../views/user/afterClass.vue'),
   },
   },
+  {
+    path: '/user/afterClassChat',
+    meta: { title: '答疑聊天', isleftarrow: true },
+    component: () => import('../views/user/afterClassChat.vue'),
+  },
   // 积分榜
   // 积分榜
   {
   {
     path: '/user/league',
     path: '/user/league',

+ 5 - 1
src/views/user/afterClass.vue

@@ -19,7 +19,7 @@
               <el-col :span="24" class="sub"> 答疑科目:{{ item.subid }} </el-col>
               <el-col :span="24" class="sub"> 答疑科目:{{ item.subid }} </el-col>
               <el-col :span="24" class="teacher"> 答疑教师:{{ item.teacher }} </el-col>
               <el-col :span="24" class="teacher"> 答疑教师:{{ item.teacher }} </el-col>
               <el-col :span="24" class="btn">
               <el-col :span="24" class="btn">
-                <el-button type="primary" size="mini">申请答疑</el-button>
+                <el-button type="primary" size="mini" @click="applyBtn(item.id)">申请答疑</el-button>
               </el-col>
               </el-col>
             </el-col>
             </el-col>
           </el-col>
           </el-col>
@@ -91,6 +91,10 @@ export default {
         }
         }
       }
       }
     },
     },
+    // 申请答疑
+    applyBtn(id) {
+      this.$router.push({ path: '/user/afterClassChat', query: { id: id } });
+    },
   },
   },
   computed: { ...mapState(['user']) },
   computed: { ...mapState(['user']) },
   mounted() {
   mounted() {

+ 135 - 0
src/views/user/afterClassChat.vue

@@ -0,0 +1,135 @@
+<template>
+  <div id="afterClassChat">
+    <el-row>
+      <el-col :span="24" class="style">
+        <el-col :span="24" class="top">
+          <NavBar v-show="navShow" :title="title" :isleftarrow="isleftarrow"> </NavBar>
+        </el-col>
+        <el-col :span="24" class="main">
+          <chat :chatList="chatList" @speak="speak"></chat>
+        </el-col>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import _ from 'lodash';
+import moment from 'moment';
+import chat from '@/components/chat.vue';
+import NavBar from '@/layout/common/topTitle.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: answerapply } = createNamespacedHelpers('answerapply');
+const { mapActions: answerchat } = createNamespacedHelpers('answerchat');
+export default {
+  metaInfo: { title: '请假管理' },
+  name: 'afterClassChat',
+  props: {},
+  components: {
+    NavBar, //头部导航
+    chat, //聊天
+  },
+  data: function() {
+    return {
+      title: '',
+      isleftarrow: '',
+      transitionName: 'fade',
+      navShow: true,
+      // 聊天列表
+      chatList: [],
+      // 房间信息
+      room: {},
+    };
+  },
+  async created() {
+    await this.searchInfo();
+    await this.search();
+  },
+  methods: {
+    ...answerchat(['query', 'fetch', 'create']),
+    ...answerapply({ answerapplyFetch: 'fetch' }),
+    async searchInfo() {
+      if (this.id) {
+        // 房间详情
+        let res = await this.answerapplyFetch(this.id);
+        if (this.$checkRes(res)) {
+          this.$set(this, `room`, res.data);
+          this.channel();
+        }
+      }
+    },
+    // 房间聊天列表
+    async search() {
+      let res = await this.query({ room: this.room._id });
+      if (this.$checkRes(res)) {
+        this.$set(this, `chatList`, res.data);
+      }
+    },
+    channel() {
+      //TODO 修改订阅地址
+      if (!this.room.id) {
+        console.warn('未获取到房间id,无法进行订阅');
+        return;
+      }
+      this.$stomp({
+        [`/exchange/answerchat/${this.room.id}`]: this.onMessage,
+      });
+    },
+    onMessage(message) {
+      let body = _.get(message, 'body');
+      if (body) {
+        if (body == '消息已查收') return;
+        body = JSON.parse(body);
+        this.chatList.push(body);
+      }
+    },
+    // 发言提交
+    async speak(content) {
+      let data = {
+        sender_id: this.user.userid,
+        sender_name: this.user.name,
+        content: content,
+        receiver_id: this.room.teacherid,
+        receiver_name: this.room.teacher,
+        room: this.room._id,
+      };
+      let res = await this.create(data);
+      if (this.$checkRes(res)) {
+        console.log(res.data);
+      }
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    id() {
+      return this.$route.query.id;
+    },
+  },
+  mounted() {
+    this.title = this.$route.meta.title;
+    this.isleftarrow = this.$route.meta.isleftarrow;
+  },
+  watch: {
+    $route(to, from) {
+      this.title = to.meta.title;
+      this.isleftarrow = to.meta.isleftarrow;
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.style {
+  width: 100%;
+  min-height: 667px;
+  position: relative;
+  background-color: #f9fafc;
+}
+.top {
+  height: 46px;
+  overflow: hidden;
+}
+.main {
+  min-height: 620px;
+}
+</style>