Pārlūkot izejas kodu

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

YunaiV 2 gadi atpakaļ
vecāks
revīzija
2b477a4dfb

+ 84 - 124
yudao-ui-admin/src/views/mp/components/wx-msg/main.vue

@@ -5,66 +5,84 @@
 <template>
   <div class="msg-main" v-loading="mainLoading">
     <div class="msg-div" :id="'msg-div'+nowStr">
+      <!-- 加载更多 -->
       <div v-loading="tableLoading"></div>
       <div v-if="!tableLoading">
         <div class="el-table__empty-block" v-if="loadMore" @click="loadingMore"><span class="el-table__empty-text">点击加载更多</span></div>
         <div class="el-table__empty-block" v-if="!loadMore"><span class="el-table__empty-text">没有更多了</span></div>
       </div>
+      <!-- 消息列表 -->
       <div class="execution" v-for="item in tableData" :key='item.id'>
-        <div class="avue-comment" :class="item.type == '2' ? 'avue-comment--reverse' : ''">
+        <div class="avue-comment" :class="item.sendFrom == '2' ? 'avue-comment--reverse' : ''">
           <div class="avatar-div">
-            <img :src="item.type == '1' ? item.headimgUrl : item.appLogo" class="avue-comment__avatar">
-            <div class="avue-comment__author">{{item.type == '1' ? item.nickName : item.appName}}</div>
+            <img :src="item.sendFrom == '1' ? item.headimgUrl : item.appLogo" class="avue-comment__avatar">
+            <div class="avue-comment__author">{{item.sendFrom == '1' ? item.nickName : item.appName}}</div>
           </div>
           <div class="avue-comment__main">
             <div class="avue-comment__header">
-              <div class="avue-comment__create_time">{{item.createTime}}</div>
+              <div class="avue-comment__create_time">{{ parseTime(item.createTime) }}</div>
             </div>
-            <div class="avue-comment__body" :style="item.type == '2' ? 'background: #6BED72;' : ''">
-              <div v-if="item.repType == 'event' && item.repEvent == 'subscribe'"><el-tag type="success" size="mini">关注</el-tag></div>
-              <div v-if="item.repType == 'event' && item.repEvent == 'unsubscribe'"><el-tag type="danger" size="mini">取消关注</el-tag></div>
-              <div v-if="item.repType == 'event' && item.repEvent == 'CLICK'"><el-tag size="mini">点击菜单</el-tag>:【{{item.repName}}】</div>
-              <div v-if="item.repType == 'event' && item.repEvent == 'VIEW'"><el-tag size="mini">点击菜单链接</el-tag>:【{{item.repUrl}}】</div>
-              <div v-if="item.repType == 'event' && item.repEvent == 'scancode_waitmsg'"><el-tag size="mini">扫码结果:</el-tag>:【{{item.repContent}}】</div>
-              <div v-if="item.repType == 'text'">{{item.repContent}}</div>
-              <div v-if="item.repType == 'image'">
-                <a target="_blank" :href="item.repUrl"><img :src="item.repUrl" style="width: 100px"></a>
+            <div class="avue-comment__body" :style="item.sendFrom == '2' ? 'background: #6BED72;' : ''">
+              <!-- 【事件】区域 -->
+              <div v-if="item.type === 'event' && item.event === 'subscribe'">
+                <el-tag type="success" size="mini">关注</el-tag>
               </div>
-              <div v-if="item.repType == 'voice'">
-                <WxVoicePlayer :objData="item"></WxVoicePlayer>
+              <div v-else-if="item.type === 'event' && item.event === 'unsubscribe'">
+                <el-tag type="danger" size="mini">取消关注</el-tag>
               </div>
-              <div v-if="item.repType == 'video'" style="text-align: center">
-                <WxVideoPlayer :objData="item"></WxVideoPlayer>
+              <div v-else-if="item.type === 'event' && item.event === 'CLICK'">
+                <el-tag size="mini">点击菜单</el-tag>【{{ item.eventKey }}】
               </div>
-              <div v-if="item.repType == 'shortvideo'" style="text-align: center">
-                <WxVideoPlayer :objData="item"></WxVideoPlayer>
+              <div v-else-if="item.type === 'event' && item.event === 'VIEW'">
+                <el-tag size="mini">点击菜单链接</el-tag>【{{ item.eventKey }}】
               </div>
-              <div v-if="item.repType == 'location'">
-                <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'">
-                  <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'">
-                  <p/><i class="el-icon-map-location"></i>{{item.repContent}}
-                </el-link>
+              <div v-else-if="item.type === 'event' && item.event === 'scancode_waitmsg'"> <!-- TODO 芋艿:需要测试下 -->
+                <el-tag size="mini">扫码结果</el-tag>【{{ item.eventKey }}】
               </div>
-              <div v-if="item.repType == 'link'" class="avue-card__detail">
-                <el-link type="success" :underline="false" target="_blank" :href="item.repUrl">
-                  <div class="avue-card__title"><i class="el-icon-link"></i>{{item.repName}}</div>
-                </el-link>
-                <div class="avue-card__info" style="height: unset">{{item.repDesc}}</div>
+              <div v-else-if="item.type === 'event'">
+                <el-tag type="danger" size="mini">未知事件类型</el-tag>
+              </div>
+              <!-- 【消息】区域 -->
+              <div v-else-if="item.type === 'text'">{{ item.content }}</div>
+              <div v-else-if="item.type === 'voice'">
+                <wx-voice-player :url="item.mediaUrl" :content="item.recognition" />
               </div>
-              <div v-if="item.repType == 'news'" style="width: 300px">
-                <WxNews :objData="item.content.articles"></WxNews>
+              <div v-else-if="item.type === 'image'">
+                <a target="_blank" :href="item.mediaUrl">
+                  <img :src="item.mediaUrl" style="width: 100px">
+                </a>
               </div>
-              <div v-if="item.repType == 'music'">
-                <el-link type="success" :underline="false" target="_blank" :href="item.repUrl">
-                  <div class="avue-card__body" style="padding:10px;background-color: #fff;border-radius: 5px">
-                    <div class="avue-card__avatar"><img :src="item.repThumbUrl" alt=""></div>
-                    <div class="avue-card__detail">
-                      <div class="avue-card__title" style="margin-bottom:unset">{{item.repName}}</div>
-                      <div class="avue-card__info" style="height: unset">{{item.repDesc}}</div>
-                    </div>
-                  </div>
+              <div v-else-if="item.type === 'video' || item.type === 'shortvideo'" style="text-align: center">
+                <wx-video-player :url="item.mediaUrl" />
+              </div>
+              <div v-if="item.type === 'link'" class="avue-card__detail">
+                <el-link type="success" :underline="false" target="_blank" :href="item.url">
+                  <div class="avue-card__title"><i class="el-icon-link"></i>{{ item.title }}</div>
                 </el-link>
+                <div class="avue-card__info" style="height: unset">{{item.description}}</div>
               </div>
+<!--              <div v-if="item.repType == 'location'">-->
+<!--                <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'">-->
+<!--                  <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'">-->
+<!--                  <p/><i class="el-icon-map-location"></i>{{item.repContent}}-->
+<!--                </el-link>-->
+<!--              </div>-->
+
+<!--              <div v-if="item.repType == 'news'" style="width: 300px">-->
+<!--                <WxNews :objData="item.content.articles"></WxNews>-->
+<!--              </div>-->
+
+<!--              <div v-if="item.repType == 'music'">-->
+<!--                <el-link type="success" :underline="false" target="_blank" :href="item.repUrl">-->
+<!--                  <div class="avue-card__body" style="padding:10px;background-color: #fff;border-radius: 5px">-->
+<!--                    <div class="avue-card__avatar"><img :src="item.repThumbUrl" alt=""></div>-->
+<!--                    <div class="avue-card__detail">-->
+<!--                      <div class="avue-card__title" style="margin-bottom:unset">{{item.repName}}</div>-->
+<!--                      <div class="avue-card__info" style="height: unset">{{item.repDesc}}</div>-->
+<!--                    </div>-->
+<!--                  </div>-->
+<!--                </el-link>-->
+<!--              </div>-->
             </div>
           </div>
         </div>
@@ -78,26 +96,24 @@
 </template>
 
 <script>
-  import { getPage, addObj, putObj } from '@/api/wxmp/wxmsg'
-  import SockJS from 'sockjs-client';
-  import Stomp from 'stompjs';
-  import { getToken } from '@/utils/auth'
-  import WxReplySelect from '@/components/wx-reply/main.vue'
-  import WxNews from '@/components/wx-news/main.vue'
-  import WxVideoPlayer from '@/components/wx-video-play/main.vue'
-  import WxVoicePlayer from '@/components/wx-voice-play/main.vue'
+  // import { getMessagePage, addObj } from '@/api/mp/message'
+  import { getMessagePage } from '@/api/mp/message'
+  // import WxReplySelect from '@/components/wx-reply/main.vue'
+  // import WxNews from '@/components/wx-news/main.vue'
+  import WxVideoPlayer from '@/views/mp/components/wx-video-play/main.vue';
+  import WxVoicePlayer from '@/views/mp/components/wx-voice-play/main.vue';
 
   export default {
     name: "wxMsg",
     components: {
-      WxReplySelect,
-      WxNews,
+      // WxReplySelect,
+      // WxNews,
       WxVideoPlayer,
       WxVoicePlayer
     },
     props: {
-      wxUserId:{
-        type:String
+      wxUserId: {
+        type: String
       }
     },
     data() {
@@ -110,10 +126,10 @@
         sendLoading:false,
         tableLoading:false,
         loadMore: true,
-        tableData: [],
+        tableData: [], // 消息列表
         page: {
           total: 0, // 总页数
-          currentPage: 1, // 当前页数
+          pageNo: 1, // 当前页数
           pageSize: 14, // 每页显示多少条
           ascs:[],//升序字段
           descs:'create_time'//降序字段
@@ -129,70 +145,8 @@
     },
     created() {
       this.refreshChange()
-    },
-    destroyed: function() {
-      this.disconnect()
-    },
-    mounted(){
-      //开源版接口没有实现websocket,固隐藏
-      // this.initWebSocket()
-    },
-    beforeDestroy() {
-      // 页面离开时断开连接,清除定时器
-      this.disconnect();
-      clearInterval(this.timer);
-    },
-    computed: {
-
     },
     methods:{
-      initWebSocket() {
-        this.connection();
-        let self = this;
-        //断开重连机制,尝试发送消息,捕获异常发生时重连
-        this.timer = setInterval(() => {
-          try {
-            self.stompClient.send("test");
-          } catch (err) {
-            console.log("断线了: " + err);
-            self.connection();
-          }
-        }, 5000);
-      },
-      connection() {
-        let token = getToken()
-        let headers = {
-          'Authorization': 'Bearer ' + token
-        }
-        // 建立连接对象
-        this.socket = new SockJS('/weixin/ws');//连接服务端提供的通信接口,连接以后才可以订阅广播消息和个人消息
-        // 获取STOMP子协议的客户端对象
-        this.stompClient = Stomp.over(this.socket);
-
-        // 向服务器发起websocket连接
-        this.stompClient.connect(headers, () => {
-          this.stompClient.subscribe('/weixin/wx_msg'+this.wxUserId, (msg) => { // 订阅服务端提供的某个topic;
-            let data = JSON.parse(msg.body)
-            this.tableData = [...this.tableData , ...[data]]//刷新消息
-            this.scrollToBottom()
-            //标记为已读
-            if(data.type == '1'){
-              putObj({
-                id: data.id,
-                readFlag: '0'
-              }).then(data => {})
-            }
-          });
-        }, (err) => {
-
-        });
-      },
-      disconnect() {
-        if (this.stompClient != null) {
-          this.stompClient.disconnect();
-          console.log("Disconnected");
-        }
-      },
       sendMsg(){
         if(this.objData){
           if(this.objData.repType == 'news'){
@@ -226,14 +180,14 @@
         })
       },
       loadingMore(){
-        this.page.currentPage++
+        this.page.pageNo++
         this.getPage(this.page)
       },
       getPage(page, params) {
         this.tableLoading = true
-        getPage(Object.assign({
-          current: page.currentPage,
-          size: page.pageSize,
+        getMessagePage(Object.assign({
+          pageNo: page.pageNo,
+          pageSize: page.pageSize,
           descs:page.descs,
           ascs: page.ascs,
           wxUserId: this.wxUserId
@@ -243,14 +197,14 @@
           if(msgDiv){
             scrollHeight = msgDiv.scrollHeight
           }
-          let data = response.data.records.reverse()
+          let data = response.data.list.reverse()
           this.tableData = [...data , ...this.tableData]
           this.page.total = response.data.total
           this.tableLoading = false
-          if(data.length < this.page.pageSize || data.length == 0){
+          if(data.length < this.page.pageSize || data.length === 0){
             this.loadMore = false
           }
-          if(this.page.currentPage == 1){//定位到消息底部
+          if(this.page.pageNo == 1){//定位到消息底部
             this.scrollToBottom()
           }else{
             if(data.length != 0){
@@ -261,7 +215,7 @@
               })
             }
           }
-          this.page.currentPage = page.currentPage
+          this.page.pageNo = page.pageNo
           this.page.pageSize = page.pageSize
         })
       },
@@ -293,6 +247,12 @@
     border-radius: 5px!important;
     margin: 0 8px!important;
   }
+  .avue-comment--reverse {
+    -webkit-box-orient: horizontal;
+    -webkit-box-direction: reverse;
+    -ms-flex-direction: row-reverse;
+    flex-direction: row-reverse;
+  }
   .avue-comment__header{
     border-top-left-radius: 5px;
     border-top-right-radius: 5px;

+ 9 - 77
yudao-ui-admin/src/views/mp/message/index.vue

@@ -29,11 +29,6 @@
 
     <!-- 操作工具栏 -->
     <el-row :gutter="10" class="mb8">
-      <el-col :span="1.5">
-        <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
-                   v-hasPermi="['mp:message:create']">新增
-        </el-button>
-      </el-col>
       <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
     </el-row>
 
@@ -102,68 +97,25 @@
     <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
                 @pagination="getList"/>
 
-    <!-- 对话框(添加 / 修改) -->
-    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
-      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
-        <el-form-item label="用户标识" prop="openid">
-          <el-input v-model="form.openid" placeholder="请输入用户标识"/>
-        </el-form-item>
-        <el-form-item label="昵称" prop="nickname">
-          <el-input v-model="form.nickname" placeholder="请输入昵称"/>
-        </el-form-item>
-        <el-form-item label="头像地址" prop="headimgUrl">
-          <el-input v-model="form.headimgUrl" placeholder="请输入头像地址"/>
-        </el-form-item>
-        <el-form-item label="微信账号ID" prop="wxAccountId">
-          <el-input v-model="form.wxAccountId" placeholder="请输入微信账号ID"/>
-        </el-form-item>
-        <el-form-item label="消息类型" prop="msgType">
-          <el-select v-model="form.msgType" placeholder="请选择消息类型">
-            <el-option label="请选择字典生成" value=""/>
-          </el-select>
-        </el-form-item>
-        <el-form-item label="内容">
-          <editor v-model="form.content" :min-height="192"/>
-        </el-form-item>
-        <el-form-item label="最近一条回复内容">
-          <editor v-model="form.resContent" :min-height="192"/>
-        </el-form-item>
-        <el-form-item label="是否已回复" prop="isRes">
-          <el-input v-model="form.isRes" placeholder="请输入是否已回复"/>
-        </el-form-item>
-        <el-form-item label="微信素材ID" prop="mediaId">
-          <el-input v-model="form.mediaId" placeholder="请输入微信素材ID"/>
-        </el-form-item>
-        <el-form-item label="微信图片URL" prop="picUrl">
-          <el-input v-model="form.picUrl" placeholder="请输入微信图片URL"/>
-        </el-form-item>
-        <el-form-item label="本地图片路径" prop="picPath">
-          <el-input v-model="form.picPath" placeholder="请输入本地图片路径"/>
-        </el-form-item>
-      </el-form>
-      <div slot="footer" class="dialog-footer">
-        <el-button type="primary" @click="submitForm">确 定</el-button>
-        <el-button @click="cancel">取 消</el-button>
-      </div>
+    <el-dialog title="用户消息" :visible.sync="open" width="40%">
+      <wx-msg wxUserId="1" v-if="true" />
     </el-dialog>
+
   </div>
 </template>
 
 <script>
-import {
-  createWxFansMsg,
-  getMessagePage,
-} from "@/api/mp/message";
-import Editor from '@/components/Editor/index.vue';
+import { getMessagePage } from "@/api/mp/message";
 import WxVideoPlayer from '@/views/mp/components/wx-video-play/main.vue';
 import WxVoicePlayer from '@/views/mp/components/wx-voice-play/main.vue';
+import WxMsg from '@/views/mp/components/wx-msg/main.vue';
 
 export default {
   name: "WxFansMsg",
   components: {
-    Editor,
     WxVideoPlayer,
-    WxVoicePlayer
+    WxVoicePlayer,
+    WxMsg
   },
   data() {
     return {
@@ -180,9 +132,9 @@ export default {
       // 弹出层标题
       title: "",
       // 是否显示弹出层
-      open: false,
-      dateRangeCreateTime: [],
+      open: true,
       // 查询参数
+      dateRangeCreateTime: [],
       queryParams: {
         pageNo: 1,
         pageSize: 10,
@@ -258,26 +210,6 @@ export default {
       this.resetForm("queryForm");
       this.handleQuery();
     },
-    /** 新增按钮操作 */
-    handleAdd() {
-      this.reset();
-      this.open = true;
-      this.title = "添加粉丝消息表 ";
-    },
-    /** 提交按钮 */
-    submitForm() {
-      this.$refs["form"].validate(valid => {
-        if (!valid) {
-          return;
-        }
-        // 添加的提交
-        createWxFansMsg(this.form).then(response => {
-          this.$modal.msgSuccess("新增成功");
-          this.open = false;
-          this.getList();
-        });
-      });
-    },
   }
 };
 </script>