guhongwei 5 роки тому
батько
коміт
1baf90c214

+ 22 - 1
src/layout/userCenter/menuInfo.vue

@@ -23,7 +23,7 @@
             <el-menu-item index="2">
               <template slot="title">
                 <i class="el-icon-chat-dot-square"></i>
-                <span>消息管理</span>
+                <span :style="`color:${haveMsg ? 'red' : ''}`">消息管理</span>
               </template>
             </el-menu-item>
             <el-menu-item index="3">
@@ -66,6 +66,7 @@
 <script>
 import { mapState, createNamespacedHelpers } from 'vuex';
 const { mapActions: login } = createNamespacedHelpers('login');
+const { mapActions: personalChat } = createNamespacedHelpers('personalchat');
 export default {
   name: 'menuInfo',
   props: {},
@@ -74,13 +75,33 @@ export default {
     return {
       topUrl: require('@/assets/live/square_big.png'),
       num: '1',
+      haveMsg: false,
     };
   },
   created() {
     this.$set(this, `num`, this.$route.query.num);
+    this.onMessage();
+  },
+  mounted() {
+    this.channel();
   },
   methods: {
     ...login({ logout: 'logout', transactiondtetle: 'delete' }),
+    ...personalChat({ getChatList: 'query' }),
+    // 查询是否新消息
+    async onMessage(message) {
+      let res = await this.getChatList({ status: 0, receiver_id: this.user.uid });
+      console.log(res.data);
+      if (this.$checkRes(res)) {
+        this.$set(this, `haveMsg`, res.data.length > 0);
+      }
+    },
+    channel() {
+      this.$stomp({
+        [`/exchange/chat_message/${this.user.uid}`]: this.onMessage,
+      });
+    },
+    // 菜单跳转
     selectMenu(key) {
       if (key == '7') {
         this.logout();

+ 80 - 11
src/views/userCenter/message/index.vue

@@ -1,14 +1,13 @@
 <template>
   <div id="index">
     <el-row>
-      <el-col :span="24">
-        <span v-if="display">
-          <p>消息管理</p>
-          <el-button @click="display = false">添加</el-button>
+      <el-col :span="24" class="leftTop"> <span>|</span> <span>消息管理</span> </el-col>
+      <el-col :span="24" class="info">
+        <span v-if="view == 'room'">
+          <rooms :list="list" @toChat="toChat"></rooms>
         </span>
         <span v-else>
-          <p>消息管理添加</p>
-          <el-button @click="display = true">返回</el-button>
+          <chat :room="room" @toRoom="toRoom"></chat>
         </span>
       </el-col>
     </el-row>
@@ -16,18 +15,72 @@
 </template>
 
 <script>
+import _ from 'lodash';
+import rooms from './parts/room.vue';
+import chat from './parts/chat.vue';
 import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions } = createNamespacedHelpers('personalroom');
+const { mapActions: personalChat } = createNamespacedHelpers('personalchat');
 export default {
   name: 'index',
   props: {},
-  components: {},
+  components: {
+    rooms,
+    chat,
+  },
   data: function() {
     return {
-      display: true,
+      view: 'room',
+      list: [],
+      room: {},
     };
   },
-  created() {},
-  methods: {},
+  created() {
+    this.search();
+  },
+  mounted() {
+    this.channel();
+  },
+  methods: {
+    ...mapActions(['query', 'fetch']),
+    ...personalChat({ getChatList: 'query' }),
+    async search() {
+      let res = await this.query({ receiver_id: this.user.uid });
+      if (this.$checkRes(res)) {
+        this.$set(this, `list`, res.data);
+        this.onMessage();
+      }
+    },
+    async toChat(data) {
+      let res = await this.fetch(data.id);
+      if (this.$checkRes(res)) {
+        this.$set(this, `room`, res.data);
+        this.view = 'chat';
+      }
+    },
+    toRoom() {
+      this.view = 'room';
+      this.onMessage();
+      // window.location.reload();
+    },
+    channel() {
+      this.$stomp({
+        [`/exchange/chat_message/${this.user.uid}`]: this.onMessage,
+      });
+    },
+    async onMessage(message) {
+      let res = await this.getChatList({ status: 0, receiver_id: this.user.uid });
+      if (this.$checkRes(res)) {
+        let arr = this.list.map(i => {
+          i.needRead ? '' : (i.needRead = 0);
+          // let findRes = res.data.filter(f => i.sender_id == f.sender_id);
+          i.needRead = res.data.length || 0;
+          return i;
+        });
+        this.$set(this, `list`, arr);
+      }
+    },
+  },
   computed: {
     ...mapState(['user']),
     pageTitle() {
@@ -40,4 +93,20 @@ export default {
 };
 </script>
 
-<style lang="less" scoped></style>
+<style lang="less" scoped>
+.info {
+  padding: 0 40px 20px 10px;
+}
+.leftTop {
+  font-size: 18px;
+  width: 96%;
+  height: 41px;
+  line-height: 35px;
+  border-bottom: 1px solid #e5e5e5;
+  position: relative;
+  bottom: 1px;
+  margin: 10px;
+  font-weight: 600;
+  color: #22529a;
+}
+</style>

+ 179 - 0
src/views/userCenter/message/parts/chat.vue

@@ -0,0 +1,179 @@
+<template>
+  <div id="chats">
+    <el-row :span="24" class="chat">
+      <el-col :span="24" style="padding-bottom:5px;text-align: right;">
+        <el-button size="mini" @click="$emit('toRoom')" icon="el-icon-arrow-left" type="primary">返回</el-button>
+      </el-col>
+      <el-col :span="24" class="chatInfo" id="chatBorder" ref="chatBorder">
+        <template v-for="(i, index) in talk">
+          <template v-if="isSender(i, index)">
+            <el-col :span="24" class="senderTime" :key="`div${i.id}${index}`">
+              <span :key="`senderTime${i.id}${index}`">[{{ i.send_time }}] {{ i.sender_name }}1</span>
+              <span v-html="i.content" :key="`senderContent${i.id}${index}`"></span>
+            </el-col>
+          </template>
+          <template v-else>
+            <el-col :span="24" class="receverTime" :key="`div${i.id}${index}`">
+              <!-- {{ i.receiver_name }} -->
+              <span :key="`receverTime${i.id}${index}`"> {{ i.sender_name }}2 [{{ i.send_time }}]</span>
+              <span v-html="i.content" :key="`receverContent${i.id}${index}`"></span>
+            </el-col>
+          </template>
+        </template>
+      </el-col>
+      <el-col :span="24" class="chatBtn">
+        <wang-editor v-model="content" style="height:130px;padding-bottom:120px" ref="editor"></wang-editor>
+        <el-button type="primary" @click="chatClick">发送</el-button>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import _ from 'lodash';
+import { mapState, createNamespacedHelpers } from 'vuex';
+import wangEditor from '@/components/wang-editor.vue';
+const { mapActions: personalChat } = createNamespacedHelpers('personalchat');
+export default {
+  name: 'chats',
+  props: {
+    room: { type: Object, default: () => {} },
+  },
+  components: {
+    wangEditor,
+  },
+  data: () => {
+    return {
+      content: '',
+      talk: [],
+    };
+  },
+  created() {},
+  mounted() {
+    this.channel();
+  },
+  methods: {
+    ...personalChat(['create', 'query', 'update', 'isRead']),
+    async search() {
+      let res = await this.query({ personroom_id: this.room.id });
+      if (this.$checkRes(res)) {
+        this.$set(this, `talk`, res.data);
+        console.log(this.talk);
+        this.turnBottom();
+        this.toAlreadyRead();
+      }
+    },
+    async chatClick() {
+      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.find(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('请输入信息后发送');
+    },
+    turnBottom() {
+      this.$nextTick(() => {
+        document.getElementById('chatBorder').scrollTop = document.getElementById('chatBorder').scrollHeight + 150;
+      });
+    },
+    isSender(data) {
+      return this.user.uid == data.sender_id;
+    },
+    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) {
+        if (body == '消息已查收') return;
+        body = JSON.parse(body);
+        this.talk.push(body);
+        this.turnBottom();
+        this.toAlreadyRead();
+      }
+    },
+    async toAlreadyRead() {
+      let ids = this.talk.filter(f => f.status == 0 && f.receiver_id == this.user.uid);
+      ids = ids.map(i => i.id);
+      let res = await this.isRead({ ids, sender_id: this.room.buyer_id, receiver_id: this.user.uid, personroom_id: this.room.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>
+p {
+  padding: 0;
+  margin: 0;
+}
+.chat .chatInfo {
+  float: left;
+  width: 100%;
+  height: 280px;
+  overflow: hidden;
+  border: 1px solid #ccc;
+  margin: 0 0 30px 0;
+  overflow-y: auto;
+}
+.chatBtn {
+  float: left;
+  width: 100%;
+  text-align: center;
+}
+/deep/.chatBtn .el-button {
+  padding: 10px 80px;
+  font-size: 20px;
+}
+.senderTime {
+  float: left;
+  width: 100%;
+}
+.receverTime {
+  float: right;
+  width: 100%;
+}
+.receverTime span:first-child {
+  float: right;
+  width: 100%;
+  text-align: right;
+}
+.receverTime span:last-child {
+  float: right;
+  width: 100%;
+  text-align: right;
+}
+</style>

+ 62 - 0
src/views/userCenter/message/parts/room.vue

@@ -0,0 +1,62 @@
+<template>
+  <div id="room">
+    <el-table :data="list" border stripe :show-header="false" @row-click="toChat">
+      <!-- <el-table-column prop="buyer_name" align="center"></el-table-column> -->
+      <el-table-column align="center">
+        <template slot-scope="scope">
+          <span v-if="user.uid == scope.row.seller_id">
+            {{ scope.row.buyer_name }}
+          </span>
+          <span v-else>
+            {{ scope.row.seller_name }}
+          </span>
+        </template>
+      </el-table-column>
+      <el-table-column align="center">
+        <template v-slot="{ row }">
+          <template v-if="row.needRead == 0">
+            暂无未读消息
+          </template>
+          <template v-if="row.needRead > 0">
+            <span style="color:red">您有{{ row.needRead }}条未读消息 </span>
+          </template>
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'room',
+  props: {
+    list: { type: Array, default: () => [] },
+  },
+  components: {},
+  data: () => {
+    return {};
+  },
+  created() {},
+  methods: {
+    toChat(row) {
+      this.$emit('toChat', row);
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-table--border td {
+  cursor: pointer;
+}
+</style>