chat.vue 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. <template>
  2. <div id="chats">
  3. <el-row>
  4. <el-col :span="24" class="info chat_frame" id="chat">
  5. <template v-for="(i, index) in talk">
  6. <template v-if="isSender(i, index)">
  7. <el-col :span="24" class="senderTime" :key="`div${i.id}${index}`">
  8. <span :key="`senderTime${i.id}${index}`">[{{ i.send_time }}] {{ i.sender_name }}</span>
  9. <span v-html="i.content" :key="`senderContent${i.id}${index}`"></span>
  10. </el-col>
  11. </template>
  12. <template v-else>
  13. <el-col :span="24" class="receverTime" :key="`div${i.id}${index}`">
  14. <span :key="`receverTime${i.id}${index}`"> {{ i.sender_name }} [{{ i.send_time }}]</span>
  15. <span v-html="i.content" :key="`receverContent${i.id}${index}`"></span>
  16. </el-col>
  17. </template>
  18. </template>
  19. </el-col>
  20. <el-col :span="24" style="text-align:center">
  21. <el-input v-model="content" type="textarea"></el-input>
  22. <el-button type="primary" size="mini" @click="sendMessage" style="margin-top:10px">发送</el-button>
  23. </el-col>
  24. </el-row>
  25. </div>
  26. </template>
  27. <script>
  28. // import wangEditor from '@common/src/components/frame/wang-editor.vue';
  29. import { mapState, createNamespacedHelpers } from 'vuex';
  30. const { mapActions: personChat } = createNamespacedHelpers('personChat');
  31. const _ = require('lodash');
  32. export default {
  33. name: 'chats',
  34. props: {
  35. room: { type: Object },
  36. },
  37. components: {},
  38. data: () => {
  39. return {
  40. content: '',
  41. talk: [],
  42. };
  43. },
  44. created() {},
  45. async mounted() {
  46. this.channel();
  47. },
  48. methods: {
  49. ...personChat(['create', 'query']),
  50. async search() {
  51. let res = await this.query({ room_id: this.room.id });
  52. if (this.$checkRes(res)) {
  53. this.$set(this, `talk`, res.data);
  54. this.turnBottom();
  55. }
  56. },
  57. async sendMessage() {
  58. if (this.content != '') {
  59. let obj = { room_id: this.room.id, content: this.content, sender_id: this.user.id, sender_name: this.user.name };
  60. let pos = 'p1';
  61. if (_.get(this.room, 'p1_id') === this.user.id) pos = 'p2';
  62. obj.receiver_id = _.get(this.room, `${pos}_id`);
  63. obj.receiver_name = _.get(this.room, pos);
  64. let res = await this.create(obj);
  65. // this.$refs.editor.setContent();
  66. this.$set(this, `content`, '');
  67. this.$forceUpdate();
  68. if (this.$checkRes(res, null, res.errmsg || '发言失败')) {
  69. this.talk.push(res.data);
  70. this.turnBottom();
  71. }
  72. } else this.$message.error('请输入信息后发送');
  73. },
  74. channel() {
  75. //TODO 修改订阅地址
  76. if (!this.room.id) {
  77. console.warn('未获取到房间id,无法进行订阅');
  78. return;
  79. }
  80. // console.log(`/exchange/personChat/${this.room.id}/${this.user.id}`);
  81. this.$stomp({
  82. [`/exchange/personChat/${this.room.id}.${this.user.id}`]: this.onMessage,
  83. });
  84. },
  85. onMessage(message) {
  86. let body = _.get(message, 'body');
  87. if (body) {
  88. body = JSON.parse(body);
  89. this.talk.push(body);
  90. this.turnBottom();
  91. }
  92. },
  93. turnBottom() {
  94. this.$nextTick(() => {
  95. document.getElementById('chat').scrollTop = document.getElementById('chat').scrollHeight;
  96. });
  97. },
  98. isSender(data) {
  99. return this.user.id !== data.sender_id;
  100. },
  101. },
  102. watch: {
  103. room: {
  104. handler(val) {
  105. if (val.id) this.search();
  106. },
  107. immediate: true,
  108. deep: true,
  109. },
  110. },
  111. computed: {
  112. ...mapState(['user']),
  113. pageTitle() {
  114. return `${this.$route.meta.title}`;
  115. },
  116. },
  117. metaInfo() {
  118. return { title: this.$route.meta.title };
  119. },
  120. };
  121. </script>
  122. <style lang="less" scoped>
  123. .chat_frame {
  124. height: 350px;
  125. border: 1px solid #ccc;
  126. margin-bottom: 10px;
  127. overflow-y: auto;
  128. }
  129. .info {
  130. float: left;
  131. width: 100%;
  132. padding: 15px;
  133. }
  134. /deep/.info p {
  135. margin: 0 !important;
  136. padding: 0 !important;
  137. }
  138. .senderTime {
  139. float: left;
  140. width: 100%;
  141. text-align: left;
  142. }
  143. .receverTime {
  144. float: right;
  145. width: 100%;
  146. }
  147. .receverTime span:first-child {
  148. float: right;
  149. width: 100%;
  150. text-align: right;
  151. }
  152. .receverTime span:last-child {
  153. float: right;
  154. width: 100%;
  155. text-align: right;
  156. }
  157. </style>