guhongwei 3 年 前
コミット
f73363692a
10 ファイル変更173 行追加32 行削除
  1. 5 0
      package-lock.json
  2. 1 0
      package.json
  3. 60 26
      src/components/chat.vue
  4. 2 0
      src/main.js
  5. 1 1
      src/plugins/stomp.js
  6. 42 0
      src/store/chat.js
  7. 42 0
      src/store/clientApply.js
  8. 3 1
      src/store/index.js
  9. 11 2
      src/views/index.vue
  10. 6 2
      vue.config.js

+ 5 - 0
package-lock.json

@@ -1240,6 +1240,11 @@
       "integrity": "sha1-pTUV2yXYA4N0OBtzryC7Ty5QjYc=",
       "dev": true
     },
+    "@stomp/stompjs": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/@stomp/stompjs/-/stompjs-6.1.0.tgz",
+      "integrity": "sha512-Bt+whL0V51rSKP35OkgM1yeVu/usunpz5l1VYuoWw8mGsDMNd3W3FpWa4/4eis6QfXO3uteNGfyE21XWn0pGAQ=="
+    },
     "@types/body-parser": {
       "version": "1.19.1",
       "resolved": "https://registry.nlark.com/@types/body-parser/download/@types/body-parser-1.19.1.tgz?cache=0&sync_timestamp=1625595908991&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fbody-parser%2Fdownload%2F%40types%2Fbody-parser-1.19.1.tgz",

+ 1 - 0
package.json

@@ -8,6 +8,7 @@
     "lint": "vue-cli-service lint"
   },
   "dependencies": {
+    "@stomp/stompjs": "^6.1.0",
     "axios": "^0.21.1",
     "core-js": "^3.6.5",
     "element-ui": "^2.15.3",

+ 60 - 26
src/components/chat.vue

@@ -37,7 +37,7 @@
             <el-input v-model="content"></el-input>
           </el-col>
           <el-col :span="4" class="two_2">
-            <el-button type="primary">发送</el-button>
+            <el-button type="primary" @click="send">发送</el-button>
           </el-col>
         </el-col>
       </el-col>
@@ -47,46 +47,80 @@
 
 <script>
 import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: clientApply } = createNamespacedHelpers('clientApply');
+const { mapActions: mapChat } = createNamespacedHelpers('chat');
 export default {
   name: 'chat',
-  props: {},
+  props: {
+    userInfo: { type: Object },
+  },
   components: {},
   data: function () {
     return {
       content: '',
-      list: [
-        {
-          id: '客服',
-          sender_name: '客服',
-          content: '信息内容1',
-        },
-        {
-          id: '用户',
-          sender_name: '用户',
-          content: '信息内容2',
-        },
-        {
-          id: '客服',
-          sender_name: '客服',
-          content: '信息内容3',
-        },
-        {
-          id: '用户',
-          sender_name: '用户',
-          content: '信息内容4',
-        },
-      ],
+      list: [],
       // 客服头像
       leftIcon: require('@a/leftIcon.png'),
       // 用户头像
       rightIcon: require('@a/rightIcon.png'),
+      // 请求客服
+      customer: {},
     };
   },
-  created() {},
+  created() {
+    this.search();
+  },
   methods: {
+    ...clientApply(['query']),
+    ...mapChat(['create']),
+    async search() {
+      let res = await this.query({ ...this.userInfo });
+      if (this.$checkRes(res)) {
+        this.$set(this, `customer`, res.data);
+        this.channel();
+      }
+    },
     // 区分发言人
     isSender(data) {
-      return data.id == '客服';
+      return data.customer_id != this.customer.customer_id;
+    },
+    // 发言
+    async send() {
+      if (!this.content) {
+        this.$message({
+          message: '发言内容不能为空',
+          type: 'warning',
+        });
+      } else {
+        let data = {
+          _tenant: this.customer._tenant,
+          client_id: this.customer.client_id,
+          customer_id: this.customer.customer_id,
+          sender_id: this.customer.client_id,
+          sender_name: this.customer.client_name,
+          content: this.content,
+        };
+        let res = await this.create(data);
+        if (this.$checkRes(res)) {
+          this.$message({
+            message: '消息发送成功',
+            type: 'success',
+          });
+          this.content = '';
+        }
+      }
+    },
+    channel() {
+      this.$stomp({
+        [`/exchange/platform/customer.${this.customer.client_id}.${this.customer.customer_id}`]: this.onMessage,
+      });
+    },
+    onMessage(message) {
+      let body = _.get(message, 'body');
+      if (body) {
+        body = JSON.parse(body);
+        this.list.push(body);
+      }
     },
   },
   computed: {

+ 2 - 0
src/main.js

@@ -11,12 +11,14 @@ import '@/plugins/loading';
 import '@/plugins/var';
 import '@/plugins/methods';
 import '@/plugins/setting';
+import InitStomp from '@/plugins/stomp';
 Vue.config.productionTip = false;
 new Vue({
   router,
   store,
   render: (h) => h(App),
 }).$mount('#app');
+InitStomp();
 window.vm = new Vue({
   router,
 });

+ 1 - 1
src/plugins/stomp.js

@@ -5,7 +5,7 @@
 import Vue from 'vue';
 import _ from 'lodash';
 import assert from 'assert';
-import { Client } from '@stomp/stompjs/esm5/client';
+import { Client } from '@stomp/stompjs/esm6/client';
 
 const Plugin = {
   install(Vue, options) {

+ 42 - 0
src/store/chat.js

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

+ 42 - 0
src/store/clientApply.js

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

+ 3 - 1
src/store/index.js

@@ -1,5 +1,7 @@
 import Vue from 'vue';
 import Vuex from 'vuex';
+import clientApply from './clientApply';
+import chat from './chat';
 
 Vue.use(Vuex);
 
@@ -7,5 +9,5 @@ export default new Vuex.Store({
   state: {},
   mutations: {},
   actions: {},
-  modules: {},
+  modules: { clientApply, chat },
 });

+ 11 - 2
src/views/index.vue

@@ -8,7 +8,7 @@
       </el-col>
     </el-row>
     <el-dialog title="在线聊天" :visible.sync="show" width="40%" :before-close="close" :close-on-click-modal="false" :close-on-press-escape="false">
-      <chat-frame></chat-frame>
+      <chat-frame :userInfo="userInfo"></chat-frame>
     </el-dialog>
   </div>
 </template>
@@ -16,6 +16,7 @@
 <script>
 import chatFrame from '@c/chat.vue';
 import { mapState, createNamespacedHelpers } from 'vuex';
+var moment = require('moment');
 export default {
   name: 'index',
   props: {},
@@ -24,13 +25,21 @@ export default {
   },
   data: function () {
     return {
-      show: true,
+      show: false,
+      userInfo: {},
     };
   },
   created() {},
   methods: {
     // 打开在线聊天
     openBtn() {
+      // 创建用户
+      let data = {
+        _tenant: 'platform',
+        client_id: '5fa34a8e3849fd0eecf7f1c6',
+        client_name: '顾红伟',
+      };
+      this.$set(this, `userInfo`, data);
       this.show = true;
     },
     // 关闭在线聊天

+ 6 - 2
vue.config.js

@@ -20,11 +20,15 @@ module.exports = {
       '/files': {
         target: 'http://broadcast.waityou24.cn',
       },
-      '/api': {
-        target: 'http://127.0.0.1:9001',
+      '/capi': {
+        target: 'http://192.168.1.19:9106',
         changeOrigin: true,
         ws: false,
       },
+      '/ws': {
+        target: 'http://192.168.1.19:15674',
+        ws: true,
+      },
     },
   },
 };