lrf402788946 5 vuotta sitten
vanhempi
commit
639fadafdb
5 muutettua tiedostoa jossa 179 lisäystä ja 47 poistoa
  1. 5 1
      src/App.vue
  2. 0 39
      src/store/chat.js
  3. 4 0
      src/store/index.js
  4. 36 7
      src/views/hall/dock/dockDetail.vue
  5. 134 0
      src/views/hall/dock/parts/chat.vue

+ 5 - 1
src/App.vue

@@ -4,4 +4,8 @@
   </div>
 </template>
 
-<style lang="less"></style>
+<style lang="less">
+body {
+  margin: 0;
+}
+</style>

+ 0 - 39
src/store/chat.js

@@ -1,39 +0,0 @@
-import Vue from 'vue';
-import Vuex from 'vuex';
-import _ from 'lodash';
-Vue.use(Vuex);
-const api = {
-  interface: `/api/live/chat`,
-};
-const state = () => ({});
-const mutations = {};
-
-const actions = {
-  async query({ commit }, { skip = 0, limit = undefined, ...info } = {}) {
-    const res = await this.$axios.$get(api.interface, { skip, limit, ...info });
-    return res;
-  },
-  async create({ commit }, payload) {
-    const res = await this.$axios.$post(`${api.interface}`, payload);
-    return res;
-  },
-  async fetch({ commit }, payload) {
-    const res = await this.$axios.$get(`${api.interface}/${payload}`);
-    return res;
-  },
-  async update({ commit }, { id, ...info } = {}) {
-    const res = await this.$axios.$post(`${api.interface}/${id}`, { ...info });
-    return res;
-  },
-  async delete({ commit }, payload) {
-    const res = await this.$axios.$delete(`${api.interface}/${payload}`);
-    return res;
-  },
-};
-
-export default {
-  namespaced: true,
-  state,
-  mutations,
-  actions,
-};

+ 4 - 0
src/store/index.js

@@ -11,6 +11,8 @@ import marketproduct from '@common/store/market/marketproduct';
 import talentExperts from '@common/store/market/talentExperts';
 import * as ustate from '@common/store/user/state';
 import * as umutations from '@common/store/user/mutations';
+import personalchat from '@common/store/live/personalchat';
+import personalroom from '@common/store/live/personalroom';
 Vue.use(Vuex);
 
 export default new Vuex.Store({
@@ -27,5 +29,7 @@ export default new Vuex.Store({
     apply,
     news,
     login,
+    personalchat,
+    personalroom,
   },
 });

+ 36 - 7
src/views/hall/dock/dockDetail.vue

@@ -15,7 +15,7 @@
                   <el-button type="primary" icon="el-icon-tickets" @click="btnInfo">项目信息</el-button>
                 </el-col>
                 <el-col :span="24">
-                  <el-button type="danger" icon="el-icon-phone-outline" @click="btnPhone">线下对接</el-button>
+                  <el-button type="danger" icon="el-icon-phone-outline" @click="btnPhone">对接</el-button>
                 </el-col>
               </el-col>
               <el-col :span="18" class="mainInfo">
@@ -41,12 +41,13 @@
                   </p>
                 </el-col>
                 <el-col :span="24" v-if="display === '2'" class="contact">
-                  <p>
+                  <!-- <p>
                     联系人姓名:<span style="color:red;">{{ productInfo.contact_user }}</span>
                   </p>
                   <p>
                     联系人电话:<span style="color:red;">{{ productInfo.contact_tel }}</span>
-                  </p>
+                  </p> -->
+                  <chat :room="room"></chat>
                 </el-col>
               </el-col>
             </el-col>
@@ -59,15 +60,18 @@
 
 <script>
 import { mapState, createNamespacedHelpers } from 'vuex';
+import chat from './parts/chat.vue';
 const { mapActions: mapProduct } = createNamespacedHelpers('marketproduct');
+const { mapActions: personalRoom } = createNamespacedHelpers('personalroom');
 export default {
   name: 'dockDetail',
   props: {},
-  components: {},
+  components: { chat }, //
   data: () => ({
     beijingPic: require('@a/live/top_3.png'),
     display: '1',
     productInfo: {},
+    room: {},
   }),
   created() {
     if (this.$route.query.id) {
@@ -76,6 +80,7 @@ export default {
   },
   methods: {
     ...mapProduct(['fetch']),
+    ...personalRoom(['create']),
     async searchInfo() {
       let res = await this.fetch(this.$route.query.id);
       if (res.errcode === 0) {
@@ -87,7 +92,30 @@ export default {
       this.display = '1';
     },
     // 线下对接
-    btnPhone() {
+    async btnPhone() {
+      if (!this.room.id) {
+        //TODO 请求房间号
+        let obj = {};
+        if (!this.user.uid) {
+          this.$message.error('游客身份无法与卖家对话,请先注册');
+          return;
+        } else {
+          obj.buyer_id = this.user.uid;
+          obj.buyer_name = this.user.name;
+        }
+        if (!this.productInfo.userid) {
+          this.$message.error('缺少卖家信息,请联系卖家或管理员');
+          return;
+        } else {
+          obj.seller_id = this.productInfo.userid;
+          obj.seller_name = this.productInfo.contact_user;
+        }
+
+        let res = await this.create(obj);
+        if (this.$checkRes(res)) {
+          this.$set(this, `room`, res.data);
+        }
+      }
       this.display = '2';
     },
   },
@@ -140,11 +168,12 @@ p {
   top: 170px;
 }
 .style .main {
-  height: 670px;
+  height: 740px;
   border: 1px solid red;
   background: #fff;
   overflow: hidden;
   padding: 30px 20px;
+  margin-bottom: 10px;
 }
 .main .btn div {
   padding: 30px 0 0px 0;
@@ -156,7 +185,7 @@ p {
 }
 .main .mainInfo {
   border: 1px solid red;
-  height: 610px;
+  height: 680px;
 }
 .mainInfo .name {
   font-size: 25px;

+ 134 - 0
src/views/hall/dock/parts/chat.vue

@@ -0,0 +1,134 @@
+<template>
+  <div id="chat">
+    <el-row>
+      <el-col :span="24" class="info chat_frame" id="chat">
+        <template v-for="(i, index) in talk">
+          <template v-if="isSender(i, index)">
+            <span :key="`senderTime${i.id}${index}`">[{{ i.send_time }}] {{ i.sender_name }}</span>
+            <span v-html="i.content" :key="`senderContent${i.id}${index}`"></span>
+          </template>
+          <template v-else>
+            <span :key="`receverTime${i.id}${index}`">[{{ i.send_time }}] {{ i.receiver_name }}</span>
+            <span v-html="i.content" :key="`receverContent${i.id}${index}`"></span>
+          </template>
+        </template>
+      </el-col>
+      <el-col :span="24" style="text-align:right">
+        <el-button type="primary" size="mini" @click="sendMessage" style="margin-bottom:10px">发送</el-button>
+        <wang-editor v-model="content" ref="editor"></wang-editor>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import wangEditor from '@/components/wang-editor.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: personalChat } = createNamespacedHelpers('personalchat');
+export default {
+  name: 'chat',
+  props: {
+    room: { type: Object },
+  },
+  components: { wangEditor },
+  data: () => {
+    return {
+      content: '',
+      talk: [],
+    };
+  },
+  created() {},
+  mounted() {
+    this.channel();
+  },
+  methods: {
+    ...personalChat(['create', 'query']),
+    async search() {
+      let res = await this.query({ personroom_id: this.room.id });
+      if (this.$checkRes(res)) {
+        this.$set(this, `talk`, res.data);
+        this.turnBottom();
+      }
+    },
+    async sendMessage() {
+      if (this.content != '') {
+        let obj = { personroom_id: this.room.id, content: this.content, sender_id: this.user.uid, sender_name: this.user.name, send_time: '13:00' };
+        let keys = Object.keys(this.room);
+        let fres = keys.filter(f => this.room[f] == this.user.uid);
+        obj.receiver_id = fres === 'buyer_id' ? this.room['seller_id'] : this.room['buyer_id'];
+        obj.receiver_name = fres === 'buyer_id' ? this.room['seller_name'] : this.room['buyer_name'];
+        let res = await this.create(obj);
+        this.$refs.editor.setContent();
+        this.$set(this, `content`, '');
+        this.$forceUpdate();
+        if (this.$checkRes(res, null, res.errmsg || '发言失败')) {
+          this.talk.push(res.data);
+          this.turnBottom();
+        }
+      } else this.$message.error('请输入信息后发送');
+    },
+    channel() {
+      //TODO 修改订阅地址
+      if (!this.room.id) {
+        console.warn('未获取到房间id,无法进行订阅');
+        return;
+      }
+      this.$stomp({
+        [`/exchange/person_chat/${this.room.id}_${this.user.uid}`]: this.onMessage,
+      });
+    },
+    onMessage(message) {
+      let body = _.get(message, 'body');
+      if (body) {
+        body = JSON.parse(body);
+        console.log(body);
+        // let is_seller = this.sellerList.find(f => f.user_id == body.sender_id);
+        // if (is_seller) this.mainTalk.push({ id: body._id, sender_name: body.sender_name, send_time: body.send_time, content: body.content });
+        // else this.otherTalk.push({ id: body._id, sender_name: body.sender_name, send_time: body.send_time, content: body.content });
+        this.$nextTick(() => {
+          // document.getElementById('chatBuy').scrollTop = document.getElementById('chatBuy').scrollHeight + 150;
+          // document.getElementById('chat').scrollTop = document.getElementById('chat').scrollHeight + 150;
+        });
+      }
+    },
+    turnBottom() {
+      this.$nextTick(() => {
+        document.getElementById('chat').scrollTop = document.getElementById('chat').scrollHeight;
+      });
+    },
+    isSender(data) {
+      return this.user.uid == data.sender_id;
+    },
+  },
+  watch: {
+    room: {
+      handler(val) {
+        if (val.id) this.search();
+      },
+      immediate: true,
+      deep: true,
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.chat_frame {
+  height: 360px;
+  border: 1px solid #ccc;
+  margin-bottom: 10px;
+  overflow-y: auto;
+}
+p {
+  margin-bottom: 10px;
+}
+</style>