Commit 2b477a4dfb67b2a0163445125ca21f84505e07e0

Authored by YunaiV
1 parent df5e6161

mp:实现 wx-msg 的消息列表的适配

yudao-ui-admin/src/views/mp/components/wx-msg/main.vue
@@ -5,66 +5,84 @@ @@ -5,66 +5,84 @@
5 <template> 5 <template>
6 <div class="msg-main" v-loading="mainLoading"> 6 <div class="msg-main" v-loading="mainLoading">
7 <div class="msg-div" :id="'msg-div'+nowStr"> 7 <div class="msg-div" :id="'msg-div'+nowStr">
  8 + <!-- 加载更多 -->
8 <div v-loading="tableLoading"></div> 9 <div v-loading="tableLoading"></div>
9 <div v-if="!tableLoading"> 10 <div v-if="!tableLoading">
10 <div class="el-table__empty-block" v-if="loadMore" @click="loadingMore"><span class="el-table__empty-text">点击加载更多</span></div> 11 <div class="el-table__empty-block" v-if="loadMore" @click="loadingMore"><span class="el-table__empty-text">点击加载更多</span></div>
11 <div class="el-table__empty-block" v-if="!loadMore"><span class="el-table__empty-text">没有更多了</span></div> 12 <div class="el-table__empty-block" v-if="!loadMore"><span class="el-table__empty-text">没有更多了</span></div>
12 </div> 13 </div>
  14 + <!-- 消息列表 -->
13 <div class="execution" v-for="item in tableData" :key='item.id'> 15 <div class="execution" v-for="item in tableData" :key='item.id'>
14 - <div class="avue-comment" :class="item.type == '2' ? 'avue-comment--reverse' : ''"> 16 + <div class="avue-comment" :class="item.sendFrom == '2' ? 'avue-comment--reverse' : ''">
15 <div class="avatar-div"> 17 <div class="avatar-div">
16 - <img :src="item.type == '1' ? item.headimgUrl : item.appLogo" class="avue-comment__avatar">  
17 - <div class="avue-comment__author">{{item.type == '1' ? item.nickName : item.appName}}</div> 18 + <img :src="item.sendFrom == '1' ? item.headimgUrl : item.appLogo" class="avue-comment__avatar">
  19 + <div class="avue-comment__author">{{item.sendFrom == '1' ? item.nickName : item.appName}}</div>
18 </div> 20 </div>
19 <div class="avue-comment__main"> 21 <div class="avue-comment__main">
20 <div class="avue-comment__header"> 22 <div class="avue-comment__header">
21 - <div class="avue-comment__create_time">{{item.createTime}}</div> 23 + <div class="avue-comment__create_time">{{ parseTime(item.createTime) }}</div>
22 </div> 24 </div>
23 - <div class="avue-comment__body" :style="item.type == '2' ? 'background: #6BED72;' : ''">  
24 - <div v-if="item.repType == 'event' && item.repEvent == 'subscribe'"><el-tag type="success" size="mini">关注</el-tag></div>  
25 - <div v-if="item.repType == 'event' && item.repEvent == 'unsubscribe'"><el-tag type="danger" size="mini">取消关注</el-tag></div>  
26 - <div v-if="item.repType == 'event' && item.repEvent == 'CLICK'"><el-tag size="mini">点击菜单</el-tag>:【{{item.repName}}】</div>  
27 - <div v-if="item.repType == 'event' && item.repEvent == 'VIEW'"><el-tag size="mini">点击菜单链接</el-tag>:【{{item.repUrl}}】</div>  
28 - <div v-if="item.repType == 'event' && item.repEvent == 'scancode_waitmsg'"><el-tag size="mini">扫码结果:</el-tag>:【{{item.repContent}}】</div>  
29 - <div v-if="item.repType == 'text'">{{item.repContent}}</div>  
30 - <div v-if="item.repType == 'image'">  
31 - <a target="_blank" :href="item.repUrl"><img :src="item.repUrl" style="width: 100px"></a> 25 + <div class="avue-comment__body" :style="item.sendFrom == '2' ? 'background: #6BED72;' : ''">
  26 + <!-- 【事件】区域 -->
  27 + <div v-if="item.type === 'event' && item.event === 'subscribe'">
  28 + <el-tag type="success" size="mini">关注</el-tag>
32 </div> 29 </div>
33 - <div v-if="item.repType == 'voice'">  
34 - <WxVoicePlayer :objData="item"></WxVoicePlayer> 30 + <div v-else-if="item.type === 'event' && item.event === 'unsubscribe'">
  31 + <el-tag type="danger" size="mini">取消关注</el-tag>
35 </div> 32 </div>
36 - <div v-if="item.repType == 'video'" style="text-align: center">  
37 - <WxVideoPlayer :objData="item"></WxVideoPlayer> 33 + <div v-else-if="item.type === 'event' && item.event === 'CLICK'">
  34 + <el-tag size="mini">点击菜单</el-tag>【{{ item.eventKey }}】
38 </div> 35 </div>
39 - <div v-if="item.repType == 'shortvideo'" style="text-align: center">  
40 - <WxVideoPlayer :objData="item"></WxVideoPlayer> 36 + <div v-else-if="item.type === 'event' && item.event === 'VIEW'">
  37 + <el-tag size="mini">点击菜单链接</el-tag>【{{ item.eventKey }}】
41 </div> 38 </div>
42 - <div v-if="item.repType == 'location'">  
43 - <el-link type="primary" target="_blank" :href="'https://map.qq.com/?type=marker&isopeninfowin=1&markertype=1&pointx='+item.repLocationY+'&pointy='+item.repLocationX+'&name='+item.repContent+'&ref=joolun'">  
44 - <img :src="'https://apis.map.qq.com/ws/staticmap/v2/?zoom=10&markers=color:blue|label:A|'+item.repLocationX+','+item.repLocationY+'&key='+qqMapKey+'&size=250*180'">  
45 - <p/><i class="el-icon-map-location"></i>{{item.repContent}}  
46 - </el-link> 39 + <div v-else-if="item.type === 'event' && item.event === 'scancode_waitmsg'"> <!-- TODO 芋艿:需要测试下 -->
  40 + <el-tag size="mini">扫码结果</el-tag>【{{ item.eventKey }}】
47 </div> 41 </div>
48 - <div v-if="item.repType == 'link'" class="avue-card__detail">  
49 - <el-link type="success" :underline="false" target="_blank" :href="item.repUrl">  
50 - <div class="avue-card__title"><i class="el-icon-link"></i>{{item.repName}}</div>  
51 - </el-link>  
52 - <div class="avue-card__info" style="height: unset">{{item.repDesc}}</div> 42 + <div v-else-if="item.type === 'event'">
  43 + <el-tag type="danger" size="mini">未知事件类型</el-tag>
  44 + </div>
  45 + <!-- 【消息】区域 -->
  46 + <div v-else-if="item.type === 'text'">{{ item.content }}</div>
  47 + <div v-else-if="item.type === 'voice'">
  48 + <wx-voice-player :url="item.mediaUrl" :content="item.recognition" />
53 </div> 49 </div>
54 - <div v-if="item.repType == 'news'" style="width: 300px">  
55 - <WxNews :objData="item.content.articles"></WxNews> 50 + <div v-else-if="item.type === 'image'">
  51 + <a target="_blank" :href="item.mediaUrl">
  52 + <img :src="item.mediaUrl" style="width: 100px">
  53 + </a>
56 </div> 54 </div>
57 - <div v-if="item.repType == 'music'">  
58 - <el-link type="success" :underline="false" target="_blank" :href="item.repUrl">  
59 - <div class="avue-card__body" style="padding:10px;background-color: #fff;border-radius: 5px">  
60 - <div class="avue-card__avatar"><img :src="item.repThumbUrl" alt=""></div>  
61 - <div class="avue-card__detail">  
62 - <div class="avue-card__title" style="margin-bottom:unset">{{item.repName}}</div>  
63 - <div class="avue-card__info" style="height: unset">{{item.repDesc}}</div>  
64 - </div>  
65 - </div> 55 + <div v-else-if="item.type === 'video' || item.type === 'shortvideo'" style="text-align: center">
  56 + <wx-video-player :url="item.mediaUrl" />
  57 + </div>
  58 + <div v-if="item.type === 'link'" class="avue-card__detail">
  59 + <el-link type="success" :underline="false" target="_blank" :href="item.url">
  60 + <div class="avue-card__title"><i class="el-icon-link"></i>{{ item.title }}</div>
66 </el-link> 61 </el-link>
  62 + <div class="avue-card__info" style="height: unset">{{item.description}}</div>
67 </div> 63 </div>
  64 +<!-- <div v-if="item.repType == 'location'">-->
  65 +<!-- <el-link type="primary" target="_blank" :href="'https://map.qq.com/?type=marker&isopeninfowin=1&markertype=1&pointx='+item.repLocationY+'&pointy='+item.repLocationX+'&name='+item.repContent+'&ref=joolun'">-->
  66 +<!-- <img :src="'https://apis.map.qq.com/ws/staticmap/v2/?zoom=10&markers=color:blue|label:A|'+item.repLocationX+','+item.repLocationY+'&key='+qqMapKey+'&size=250*180'">-->
  67 +<!-- <p/><i class="el-icon-map-location"></i>{{item.repContent}}-->
  68 +<!-- </el-link>-->
  69 +<!-- </div>-->
  70 +
  71 +<!-- <div v-if="item.repType == 'news'" style="width: 300px">-->
  72 +<!-- <WxNews :objData="item.content.articles"></WxNews>-->
  73 +<!-- </div>-->
  74 +
  75 +<!-- <div v-if="item.repType == 'music'">-->
  76 +<!-- <el-link type="success" :underline="false" target="_blank" :href="item.repUrl">-->
  77 +<!-- <div class="avue-card__body" style="padding:10px;background-color: #fff;border-radius: 5px">-->
  78 +<!-- <div class="avue-card__avatar"><img :src="item.repThumbUrl" alt=""></div>-->
  79 +<!-- <div class="avue-card__detail">-->
  80 +<!-- <div class="avue-card__title" style="margin-bottom:unset">{{item.repName}}</div>-->
  81 +<!-- <div class="avue-card__info" style="height: unset">{{item.repDesc}}</div>-->
  82 +<!-- </div>-->
  83 +<!-- </div>-->
  84 +<!-- </el-link>-->
  85 +<!-- </div>-->
68 </div> 86 </div>
69 </div> 87 </div>
70 </div> 88 </div>
@@ -78,26 +96,24 @@ @@ -78,26 +96,24 @@
78 </template> 96 </template>
79 97
80 <script> 98 <script>
81 - import { getPage, addObj, putObj } from '@/api/wxmp/wxmsg'  
82 - import SockJS from 'sockjs-client';  
83 - import Stomp from 'stompjs';  
84 - import { getToken } from '@/utils/auth'  
85 - import WxReplySelect from '@/components/wx-reply/main.vue'  
86 - import WxNews from '@/components/wx-news/main.vue'  
87 - import WxVideoPlayer from '@/components/wx-video-play/main.vue'  
88 - import WxVoicePlayer from '@/components/wx-voice-play/main.vue' 99 + // import { getMessagePage, addObj } from '@/api/mp/message'
  100 + import { getMessagePage } from '@/api/mp/message'
  101 + // import WxReplySelect from '@/components/wx-reply/main.vue'
  102 + // import WxNews from '@/components/wx-news/main.vue'
  103 + import WxVideoPlayer from '@/views/mp/components/wx-video-play/main.vue';
  104 + import WxVoicePlayer from '@/views/mp/components/wx-voice-play/main.vue';
89 105
90 export default { 106 export default {
91 name: "wxMsg", 107 name: "wxMsg",
92 components: { 108 components: {
93 - WxReplySelect,  
94 - WxNews, 109 + // WxReplySelect,
  110 + // WxNews,
95 WxVideoPlayer, 111 WxVideoPlayer,
96 WxVoicePlayer 112 WxVoicePlayer
97 }, 113 },
98 props: { 114 props: {
99 - wxUserId:{  
100 - type:String 115 + wxUserId: {
  116 + type: String
101 } 117 }
102 }, 118 },
103 data() { 119 data() {
@@ -110,10 +126,10 @@ @@ -110,10 +126,10 @@
110 sendLoading:false, 126 sendLoading:false,
111 tableLoading:false, 127 tableLoading:false,
112 loadMore: true, 128 loadMore: true,
113 - tableData: [], 129 + tableData: [], // 消息列表
114 page: { 130 page: {
115 total: 0, // 总页数 131 total: 0, // 总页数
116 - currentPage: 1, // 当前页数 132 + pageNo: 1, // 当前页数
117 pageSize: 14, // 每页显示多少条 133 pageSize: 14, // 每页显示多少条
118 ascs:[],//升序字段 134 ascs:[],//升序字段
119 descs:'create_time'//降序字段 135 descs:'create_time'//降序字段
@@ -130,69 +146,7 @@ @@ -130,69 +146,7 @@
130 created() { 146 created() {
131 this.refreshChange() 147 this.refreshChange()
132 }, 148 },
133 - destroyed: function() {  
134 - this.disconnect()  
135 - },  
136 - mounted(){  
137 - //开源版接口没有实现websocket,固隐藏  
138 - // this.initWebSocket()  
139 - },  
140 - beforeDestroy() {  
141 - // 页面离开时断开连接,清除定时器  
142 - this.disconnect();  
143 - clearInterval(this.timer);  
144 - },  
145 - computed: {  
146 -  
147 - },  
148 methods:{ 149 methods:{
149 - initWebSocket() {  
150 - this.connection();  
151 - let self = this;  
152 - //断开重连机制,尝试发送消息,捕获异常发生时重连  
153 - this.timer = setInterval(() => {  
154 - try {  
155 - self.stompClient.send("test");  
156 - } catch (err) {  
157 - console.log("断线了: " + err);  
158 - self.connection();  
159 - }  
160 - }, 5000);  
161 - },  
162 - connection() {  
163 - let token = getToken()  
164 - let headers = {  
165 - 'Authorization': 'Bearer ' + token  
166 - }  
167 - // 建立连接对象  
168 - this.socket = new SockJS('/weixin/ws');//连接服务端提供的通信接口,连接以后才可以订阅广播消息和个人消息  
169 - // 获取STOMP子协议的客户端对象  
170 - this.stompClient = Stomp.over(this.socket);  
171 -  
172 - // 向服务器发起websocket连接  
173 - this.stompClient.connect(headers, () => {  
174 - this.stompClient.subscribe('/weixin/wx_msg'+this.wxUserId, (msg) => { // 订阅服务端提供的某个topic;  
175 - let data = JSON.parse(msg.body)  
176 - this.tableData = [...this.tableData , ...[data]]//刷新消息  
177 - this.scrollToBottom()  
178 - //标记为已读  
179 - if(data.type == '1'){  
180 - putObj({  
181 - id: data.id,  
182 - readFlag: '0'  
183 - }).then(data => {})  
184 - }  
185 - });  
186 - }, (err) => {  
187 -  
188 - });  
189 - },  
190 - disconnect() {  
191 - if (this.stompClient != null) {  
192 - this.stompClient.disconnect();  
193 - console.log("Disconnected");  
194 - }  
195 - },  
196 sendMsg(){ 150 sendMsg(){
197 if(this.objData){ 151 if(this.objData){
198 if(this.objData.repType == 'news'){ 152 if(this.objData.repType == 'news'){
@@ -226,14 +180,14 @@ @@ -226,14 +180,14 @@
226 }) 180 })
227 }, 181 },
228 loadingMore(){ 182 loadingMore(){
229 - this.page.currentPage++ 183 + this.page.pageNo++
230 this.getPage(this.page) 184 this.getPage(this.page)
231 }, 185 },
232 getPage(page, params) { 186 getPage(page, params) {
233 this.tableLoading = true 187 this.tableLoading = true
234 - getPage(Object.assign({  
235 - current: page.currentPage,  
236 - size: page.pageSize, 188 + getMessagePage(Object.assign({
  189 + pageNo: page.pageNo,
  190 + pageSize: page.pageSize,
237 descs:page.descs, 191 descs:page.descs,
238 ascs: page.ascs, 192 ascs: page.ascs,
239 wxUserId: this.wxUserId 193 wxUserId: this.wxUserId
@@ -243,14 +197,14 @@ @@ -243,14 +197,14 @@
243 if(msgDiv){ 197 if(msgDiv){
244 scrollHeight = msgDiv.scrollHeight 198 scrollHeight = msgDiv.scrollHeight
245 } 199 }
246 - let data = response.data.records.reverse() 200 + let data = response.data.list.reverse()
247 this.tableData = [...data , ...this.tableData] 201 this.tableData = [...data , ...this.tableData]
248 this.page.total = response.data.total 202 this.page.total = response.data.total
249 this.tableLoading = false 203 this.tableLoading = false
250 - if(data.length < this.page.pageSize || data.length == 0){ 204 + if(data.length < this.page.pageSize || data.length === 0){
251 this.loadMore = false 205 this.loadMore = false
252 } 206 }
253 - if(this.page.currentPage == 1){//定位到消息底部 207 + if(this.page.pageNo == 1){//定位到消息底部
254 this.scrollToBottom() 208 this.scrollToBottom()
255 }else{ 209 }else{
256 if(data.length != 0){ 210 if(data.length != 0){
@@ -261,7 +215,7 @@ @@ -261,7 +215,7 @@
261 }) 215 })
262 } 216 }
263 } 217 }
264 - this.page.currentPage = page.currentPage 218 + this.page.pageNo = page.pageNo
265 this.page.pageSize = page.pageSize 219 this.page.pageSize = page.pageSize
266 }) 220 })
267 }, 221 },
@@ -293,6 +247,12 @@ @@ -293,6 +247,12 @@
293 border-radius: 5px!important; 247 border-radius: 5px!important;
294 margin: 0 8px!important; 248 margin: 0 8px!important;
295 } 249 }
  250 + .avue-comment--reverse {
  251 + -webkit-box-orient: horizontal;
  252 + -webkit-box-direction: reverse;
  253 + -ms-flex-direction: row-reverse;
  254 + flex-direction: row-reverse;
  255 + }
296 .avue-comment__header{ 256 .avue-comment__header{
297 border-top-left-radius: 5px; 257 border-top-left-radius: 5px;
298 border-top-right-radius: 5px; 258 border-top-right-radius: 5px;
yudao-ui-admin/src/views/mp/message/index.vue
@@ -29,11 +29,6 @@ @@ -29,11 +29,6 @@
29 29
30 <!-- 操作工具栏 --> 30 <!-- 操作工具栏 -->
31 <el-row :gutter="10" class="mb8"> 31 <el-row :gutter="10" class="mb8">
32 - <el-col :span="1.5">  
33 - <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"  
34 - v-hasPermi="['mp:message:create']">新增  
35 - </el-button>  
36 - </el-col>  
37 <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> 32 <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
38 </el-row> 33 </el-row>
39 34
@@ -102,68 +97,25 @@ @@ -102,68 +97,25 @@
102 <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize" 97 <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
103 @pagination="getList"/> 98 @pagination="getList"/>
104 99
105 - <!-- 对话框(添加 / 修改) -->  
106 - <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>  
107 - <el-form ref="form" :model="form" :rules="rules" label-width="80px">  
108 - <el-form-item label="用户标识" prop="openid">  
109 - <el-input v-model="form.openid" placeholder="请输入用户标识"/>  
110 - </el-form-item>  
111 - <el-form-item label="昵称" prop="nickname">  
112 - <el-input v-model="form.nickname" placeholder="请输入昵称"/>  
113 - </el-form-item>  
114 - <el-form-item label="头像地址" prop="headimgUrl">  
115 - <el-input v-model="form.headimgUrl" placeholder="请输入头像地址"/>  
116 - </el-form-item>  
117 - <el-form-item label="微信账号ID" prop="wxAccountId">  
118 - <el-input v-model="form.wxAccountId" placeholder="请输入微信账号ID"/>  
119 - </el-form-item>  
120 - <el-form-item label="消息类型" prop="msgType">  
121 - <el-select v-model="form.msgType" placeholder="请选择消息类型">  
122 - <el-option label="请选择字典生成" value=""/>  
123 - </el-select>  
124 - </el-form-item>  
125 - <el-form-item label="内容">  
126 - <editor v-model="form.content" :min-height="192"/>  
127 - </el-form-item>  
128 - <el-form-item label="最近一条回复内容">  
129 - <editor v-model="form.resContent" :min-height="192"/>  
130 - </el-form-item>  
131 - <el-form-item label="是否已回复" prop="isRes">  
132 - <el-input v-model="form.isRes" placeholder="请输入是否已回复"/>  
133 - </el-form-item>  
134 - <el-form-item label="微信素材ID" prop="mediaId">  
135 - <el-input v-model="form.mediaId" placeholder="请输入微信素材ID"/>  
136 - </el-form-item>  
137 - <el-form-item label="微信图片URL" prop="picUrl">  
138 - <el-input v-model="form.picUrl" placeholder="请输入微信图片URL"/>  
139 - </el-form-item>  
140 - <el-form-item label="本地图片路径" prop="picPath">  
141 - <el-input v-model="form.picPath" placeholder="请输入本地图片路径"/>  
142 - </el-form-item>  
143 - </el-form>  
144 - <div slot="footer" class="dialog-footer">  
145 - <el-button type="primary" @click="submitForm">确 定</el-button>  
146 - <el-button @click="cancel">取 消</el-button>  
147 - </div> 100 + <el-dialog title="用户消息" :visible.sync="open" width="40%">
  101 + <wx-msg wxUserId="1" v-if="true" />
148 </el-dialog> 102 </el-dialog>
  103 +
149 </div> 104 </div>
150 </template> 105 </template>
151 106
152 <script> 107 <script>
153 -import {  
154 - createWxFansMsg,  
155 - getMessagePage,  
156 -} from "@/api/mp/message";  
157 -import Editor from '@/components/Editor/index.vue'; 108 +import { getMessagePage } from "@/api/mp/message";
158 import WxVideoPlayer from '@/views/mp/components/wx-video-play/main.vue'; 109 import WxVideoPlayer from '@/views/mp/components/wx-video-play/main.vue';
159 import WxVoicePlayer from '@/views/mp/components/wx-voice-play/main.vue'; 110 import WxVoicePlayer from '@/views/mp/components/wx-voice-play/main.vue';
  111 +import WxMsg from '@/views/mp/components/wx-msg/main.vue';
160 112
161 export default { 113 export default {
162 name: "WxFansMsg", 114 name: "WxFansMsg",
163 components: { 115 components: {
164 - Editor,  
165 WxVideoPlayer, 116 WxVideoPlayer,
166 - WxVoicePlayer 117 + WxVoicePlayer,
  118 + WxMsg
167 }, 119 },
168 data() { 120 data() {
169 return { 121 return {
@@ -180,9 +132,9 @@ export default { @@ -180,9 +132,9 @@ export default {
180 // 弹出层标题 132 // 弹出层标题
181 title: "", 133 title: "",
182 // 是否显示弹出层 134 // 是否显示弹出层
183 - open: false,  
184 - dateRangeCreateTime: [], 135 + open: true,
185 // 查询参数 136 // 查询参数
  137 + dateRangeCreateTime: [],
186 queryParams: { 138 queryParams: {
187 pageNo: 1, 139 pageNo: 1,
188 pageSize: 10, 140 pageSize: 10,
@@ -258,26 +210,6 @@ export default { @@ -258,26 +210,6 @@ export default {
258 this.resetForm("queryForm"); 210 this.resetForm("queryForm");
259 this.handleQuery(); 211 this.handleQuery();
260 }, 212 },
261 - /** 新增按钮操作 */  
262 - handleAdd() {  
263 - this.reset();  
264 - this.open = true;  
265 - this.title = "添加粉丝消息表 ";  
266 - },  
267 - /** 提交按钮 */  
268 - submitForm() {  
269 - this.$refs["form"].validate(valid => {  
270 - if (!valid) {  
271 - return;  
272 - }  
273 - // 添加的提交  
274 - createWxFansMsg(this.form).then(response => {  
275 - this.$modal.msgSuccess("新增成功");  
276 - this.open = false;  
277 - this.getList();  
278 - });  
279 - });  
280 - },  
281 } 213 }
282 }; 214 };
283 </script> 215 </script>