wansfa 1 년 전
부모
커밋
8e83387677

+ 1 - 1
package.json

@@ -42,7 +42,7 @@
     "compression-webpack-plugin": "^5.0.1",
     "compression-webpack-plugin": "^5.0.1",
     "core-js": "3.6.5",
     "core-js": "3.6.5",
     "echarts": "4.2.1",
     "echarts": "4.2.1",
-    "element-ui": "2.15.5",
+    "element-ui": "^2.15.5",
     "file-saver": "2.0.1",
     "file-saver": "2.0.1",
     "form-making": "^1.2.9",
     "form-making": "^1.2.9",
     "fuse.js": "3.4.4",
     "fuse.js": "3.4.4",

+ 10 - 0
src/api/qw/im.js

@@ -64,4 +64,14 @@ export function sendImageMsg(data) {
 }
 }
 
 
 
 
+export function getRoomInfo(roomId) {
+  return request({
+    url: '/qw/room/roomDetail/'+roomId,
+    method: 'get'
+  })
+}
+
+
+
+
 
 

BIN
src/assets/image/play_icon.png


BIN
src/assets/image/video.png


+ 27 - 20
src/components/LemonUI/components/index.vue

@@ -102,6 +102,7 @@ export default {
     return {
     return {
       drawerVisible: !this.hideDrawer,
       drawerVisible: !this.hideDrawer,
       currentContactId: null,
       currentContactId: null,
+      currentNewContactId: null,
       currentMessages: [],
       currentMessages: [],
       activeSidebar: DEFAULT_MENU_LASTMESSAGES,
       activeSidebar: DEFAULT_MENU_LASTMESSAGES,
       contacts: [],
       contacts: [],
@@ -132,14 +133,12 @@ export default {
   },
   },
   computed: {
   computed: {
     currentContact() {
     currentContact() {
-      // return this.conversations.find(function(item,index,arr){
-      //           if(!!item.conversationId){
-      //               return item.conversationId == this.currentContactId;
-      //           }
-      //           return item.id == this.currentContactId;
-      // },this.conversations) || {};
        return this.conversations.find(item =>  item.conversationId == this.currentContactId) || {};
        return this.conversations.find(item =>  item.conversationId == this.currentContactId) || {};
     },
     },
+    //获取当前联系人
+    currentNewContact() {
+       return this.contacts.find(item =>  item.id == this.currentNewContactId) || {};
+    },
     currentMenu() {
     currentMenu() {
       return this.menus.find(item => item.name == this.activeSidebar) || {};
       return this.menus.find(item => item.name == this.activeSidebar) || {};
     },
     },
@@ -431,7 +430,7 @@ export default {
       return (
       return (
         <lemon-contact
         <lemon-contact
           class={{
           class={{
-            "lemon-contact--active": this.currentContactId == props.contact.conversationId,
+            "lemon-contact--active":this._menuIsMessages()?this.currentContactId == props.contact.conversationId:(this._menuIsContacts()?this.currentNewContactId == props.contact.id:false)
           }}
           }}
           v-lemon-contextmenu_contact={this.contactContextmenu}
           v-lemon-contextmenu_contact={this.contactContextmenu}
           props={props}
           props={props}
@@ -458,7 +457,9 @@ export default {
                   simple: true,
                   simple: true,
                 },
                 },
                 () => {
                 () => {
-                  this.changeContact(contact.conversationId);
+                  console.log("qxj contact click");
+                  this.currentNewContactId=contact.id;
+                  //this.changeContact(contact.id);
                 },
                 },
                 this.$scopedSlots["sidebar-contact"],
                 this.$scopedSlots["sidebar-contact"],
               ),
               ),
@@ -504,6 +505,7 @@ export default {
       const nodes = [];
       const nodes = [];
       const cls = "lemon-container";
       const cls = "lemon-container";
       const curact = this.currentContact;
       const curact = this.currentContact;
+      const curactNew = this.currentNewContact;
       let defIsShow = true;
       let defIsShow = true;
       for (const name in this.CacheContactContainer.get()) {
       for (const name in this.CacheContactContainer.get()) {
         const show = curact.id == name && this.currentIsDefSidebar;
         const show = curact.id == name && this.currentIsDefSidebar;
@@ -524,7 +526,8 @@ export default {
           </div>,
           </div>,
         );
         );
       }
       }
-
+      
+      //聊天消息View
       nodes.push(
       nodes.push(
         <div
         <div
           class={cls}
           class={cls}
@@ -574,31 +577,32 @@ export default {
           {this.$slots.cover}
           {this.$slots.cover}
         </div>,
         </div>,
       );
       );
+
+      //联系人View
       nodes.push(
       nodes.push(
         <div
         <div
           class={cls}
           class={cls}
-          v-show={this._menuIsContacts() && defIsShow && curact.id}
-        >
+          v-show={this._menuIsContacts() && defIsShow && curactNew.id}>
           {useScopedSlot(
           {useScopedSlot(
             this.$scopedSlots["contact-info"],
             this.$scopedSlots["contact-info"],
             <div class="lemon-contact-info">
             <div class="lemon-contact-info">
-              <lemon-avatar src={curact.avatar} size={90} />
-              <h4>{curact.displayName}</h4>
+              <lemon-avatar src={curactNew.avatar} size={90} />
+              <h4>{curactNew.displayName}</h4>
               <lemon-button
               <lemon-button
                 on-click={() => {
                 on-click={() => {
-                  if (isEmpty(curact.lastContent)) {
+                  if (isEmpty(curactNew.lastContent)) {
                     this.updateContact({
                     this.updateContact({
-                      id: curact.id,
+                      id: curactNew.id,
                       lastContent: " ",
                       lastContent: " ",
                     });
                     });
                   }
                   }
-                  this.changeContact(curact.conversationId, DEFAULT_MENU_LASTMESSAGES);
+                  this.changeContact(curactNew.conversationId, DEFAULT_MENU_LASTMESSAGES);
                 }}
                 }}
               >
               >
                 发送消息
                 发送消息
               </lemon-button>
               </lemon-button>
             </div>,
             </div>,
-            curact,
+            curactNew,
           )}
           )}
         </div>,
         </div>,
       );
       );
@@ -716,6 +720,7 @@ export default {
      * @param contactId 联系人 id
      * @param contactId 联系人 id
      */
      */
     async changeContact(contactId, menuName) {
     async changeContact(contactId, menuName) {
+      console.log("qxj changeContact");
       if (menuName) {
       if (menuName) {
            this.changeMenu(menuName);
            this.changeMenu(menuName);
       } else {
       } else {
@@ -736,7 +741,7 @@ export default {
 
 
       this.currentContactId = contactId;
       this.currentContactId = contactId;
       if (!this.currentContactId) return false;
       if (!this.currentContactId) return false;
-      this.$emit("change-contact", this.currentContact, this);
+      this.$emit("change-conversation", this.currentContact, this);
       if (isFunction(this.currentContact.renderContainer) || this.activeSidebar == DEFAULT_MENU_CONTACTS) {
       if (isFunction(this.currentContact.renderContainer) || this.activeSidebar == DEFAULT_MENU_CONTACTS) {
           return;
           return;
       }
       }
@@ -817,6 +822,7 @@ export default {
      * @param {String} name 按钮 name
      * @param {String} name 按钮 name
      */
      */
     changeMenu(name) {
     changeMenu(name) {
+      console.log("qxj name:"+name);
       this.$emit("change-menu", name);
       this.$emit("change-menu", name);
       this.activeSidebar = name;
       this.activeSidebar = name;
     },
     },
@@ -885,7 +891,6 @@ export default {
               ...{ renderContainer: null },
               ...{ renderContainer: null },
             };
             };
           }
           }
-
           if (item.renderContainer) {
           if (item.renderContainer) {
             this._customContainerReady(
             this._customContainerReady(
               item.renderContainer,
               item.renderContainer,
@@ -898,7 +903,6 @@ export default {
       } else {
       } else {
         menus = defaultMenus;
         menus = defaultMenus;
       }
       }
-
       this.menus = menus;
       this.menus = menus;
     },
     },
     /**
     /**
@@ -908,6 +912,9 @@ export default {
     initContacts(data) {
     initContacts(data) {
       this.contacts = data;
       this.contacts = data;
       this.sortContacts();
       this.sortContacts();
+      if(!!this.contacts>0){
+          this.currentNewContactId=(this.contacts[0]).id;
+      }
     },
     },
       /**
       /**
      * 初始化会话数据
      * 初始化会话数据

+ 4 - 2
src/components/LemonUI/components/message/image.vue

@@ -23,8 +23,10 @@ export default {
       padding 0
       padding 0
       cursor pointer
       cursor pointer
       overflow hidden
       overflow hidden
+      max-width 20%
+      min-width 100px
       img
       img
-        max-width 100%
-        min-width 100px
+        width: 100%
+        height: auto
         display block
         display block
 </style>
 </style>

+ 61 - 0
src/components/LemonUI/components/message/video.vue

@@ -0,0 +1,61 @@
+<script>
+export default {
+  name: "lemonMessageVideo",
+  inheritAttrs: false,
+  inject: ["IMUI"],
+  data() {
+    return {
+         url:require('@/assets/image/video.png')
+    };
+  },
+  created() {
+    
+  },
+  render() {
+    return (
+      <lemon-message-basic
+        class="lemon-message-video"
+        props={{ ...this.$attrs }}
+        scopedSlots={{
+           content: props => {
+              return  this.renderHtml(props);
+          }
+        }}
+      />
+    );
+  },
+   methods: {
+      renderHtml(data){       
+        return <div><img class="imgc" src={data.imageUrl} /><img class="btnPlay" src={this.url} /> </div>;  
+        // return <span>{props.content}&nbsp;🔈</span>;
+      }
+  }
+};
+</script>
+<style lang="stylus">
+@import '../../styles/utils/index'
++b(lemon-message-video)
+  +b(lemon-message)
+    +e(content)
+      padding 0
+      cursor pointer
+      overflow hidden
+      max-width 20%
+      min-width 100px
+      background: rgba(0,0,0,0)
+      .btnPlay
+        width :40px
+        height: 40px
+        align-items: center
+        justify-content: center
+        z-index 10
+        position: absolute
+        left: calc(50% - 20px)
+        top: calc(50% - 30px)
+        background: rgba(0,0,0,0)
+      .imgc
+        width: 100%
+        height: auto
+        display block
+        background: rgba(0,0,0,0)
+</style>

+ 6 - 126
src/components/LemonUI/components/message/voice.vue

@@ -5,14 +5,12 @@ export default {
   inject: ["IMUI"],
   inject: ["IMUI"],
   data() {
   data() {
     return {
     return {
-        context: null,
-				duration: 100,
-				status: false,
+       
     };
     };
   },
   },
-  	created() {
-			
-		},
+  created() {
+    
+  },
   render() {
   render() {
     return (
     return (
       <lemon-message-basic
       <lemon-message-basic
@@ -20,7 +18,6 @@ export default {
         props={{ ...this.$attrs }}
         props={{ ...this.$attrs }}
         scopedSlots={{
         scopedSlots={{
           content: props => {
           content: props => {
-            console.log("qxj props:"+JSON.stringify(props));
             return  this.renderHtml(props);
             return  this.renderHtml(props);
           }
           }
         }}
         }}
@@ -28,49 +25,10 @@ export default {
     );
     );
   },
   },
    methods: {
    methods: {
-      renderHtml(data){  
-               
+      renderHtml(data){       
         return <audio block="true" showDuration='false' duration={data.duration} controls src={data.content}  ></audio>;
         return <audio block="true" showDuration='false' duration={data.duration} controls src={data.content}  ></audio>;
         // return <span>{props.content}&nbsp;🔈</span>;
         // return <span>{props.content}&nbsp;🔈</span>;
-      },
-
-      renderNew(data){
-       //this.context.src = data.url;
-       return  <view  class='flex audio active'  style='width:520rpx,  background:#5ba5ef'  click='play(1)' >
-                    <view class='mr-3' >
-                      <view class='wifi-symbol status'>
-                            <view class="wifi-circle first"></view>
-                            <view class="wifi-circle second"></view>
-                            <view class="wifi-circle third"></view>
-                        </view>
-                    </view>
-                 <view class='ml-3'>{data.duration ? data.duration + 's' : ''}</view>
-             </view>
-      },
-      play(id) { //点击播放
-        console.log("qxj play:"+id);
-				if(this.status) {
-					this.context.pause();
-					this.status = !this.status;
-				}else {
-					uni.$emit('stop',id)
-					this.context.play()
-					this.status = !this.status;
-				}
-			},
-			onEnded() { //播放结束
-				this.context.onEnded(()=> {
-					this.status = false;
-				})
-			},
-      getWith(s){
-        if(s){
-          const w = s *10 + 150
-           return  w > 520?'520rpx' :(s *10 + 150)+'rpx'
-        }
-      },
-
-
+      }
   }
   }
 };
 };
 </script>
 </script>
@@ -86,82 +44,4 @@ export default {
     &::before
     &::before
       display none
       display none
 
 
-
-
-      .audio 
-          background #68d7bb
-          height 58rpx
-          border-radius 50rpx
-          width 200rpx
-          align-items center
-        
-          
-      .flex 
-        display flex
-        flex-direction row
-        justify-content space-between
-        
-        .flex-1 
-          flex 1
-        
-        .ml-3 
-          margin-right 30rpx
-          color #fff
-        
-        .mr-3 
-          margin-left 30rpx
-        
-        .wifi-symbol 
-            width 50rpx
-            height 50rpx
-            box-sizing border-box
-            overflow hidden
-            transform rotate(135deg) translate3d(0, 0, 0)
-            -webkit-transform rotate(135deg) translate3d(0, 0, 0)
-            backface-visibility hidden
-            -webkit-backface-visibility hidden
-        
-        .wifi-circle 
-            border 5rpx solid #fff
-            border-radius 50%
-            position absolute
-        
-        .first 
-            width 5rpx
-            height 5rpx
-            background #fff
-            top 45rpx
-            left 45rpx
-        
-        .second 
-            width 25rpx
-            height 25rpx
-            top 35rpx
-            left 35rpx
-        
-        .third 
-            width 40rpx
-            height 40rpx
-            top 25rpx
-            left 25rpx
-        
-        .active 
-          .second 
-              animation fadeInOut 1s infinite 0.2s
-            -webkit-animation fadeInOut 1s infinite 0.2s
-          
-
-          .third 
-              animation fadeInOut 1s infinite 0.4s
-              -webkit-animation fadeInOut 1s infinite 0.4s
-    
-  
-  @keyframes fadeInOut 
-      0% 
-        opacity 0 
-      
-      100% 
-        opacity 1
-      
-
 </style>
 </style>

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
src/components/LemonUI/index.css


+ 3 - 1
src/components/LemonUI/index.js

@@ -13,6 +13,7 @@ import lemonMessageImage from "./components/message/image";
 import lemonMessageFile from "./components/message/file";
 import lemonMessageFile from "./components/message/file";
 import lemonMessageEvent from "./components/message/event";
 import lemonMessageEvent from "./components/message/event";
 import LemonMessageVoice from "./components/message/voice";
 import LemonMessageVoice from "./components/message/voice";
+import LemonMessageVideo from "./components/message/video";
 
 
 
 
 import LemonIMUI from "./components/index";
 import LemonIMUI from "./components/index";
@@ -33,7 +34,8 @@ const components = [
   lemonMessageImage,
   lemonMessageImage,
   lemonMessageFile,
   lemonMessageFile,
   lemonMessageEvent,
   lemonMessageEvent,
-  LemonMessageVoice
+  LemonMessageVoice,
+  LemonMessageVideo
 ];
 ];
 const install = (Vue) => {
 const install = (Vue) => {
   Vue.directive("LemonContextmenu", Contextmenu);
   Vue.directive("LemonContextmenu", Contextmenu);

+ 717 - 0
src/components/VideoPlayer/VueAliplayer.vue

@@ -0,0 +1,717 @@
+<template>
+  <div class="prism-player" :id="playerId" :style="playStyle"></div>
+</template>
+
+<script>
+  export default {
+    name: "Aliplayer",
+    props: {
+      source: {
+        type: String,
+        default: ""
+      },
+      //媒体转码服务的媒体Id。
+      vid: {
+        type: String,
+        default: ""
+      },
+      //播放权证
+      playauth: {
+        type: String,
+        default: ""
+      },
+      //容器的大小
+      height: {
+        type: String,
+        default: "320px"
+      },
+      //容器的大小
+      width: {
+        type: String,
+        default: "100%"
+      },
+      //视频的高度大小
+      videoWidth: {
+        type: String,
+        default: "100%"
+      },
+      //视频的宽度大小
+      videoHeight: {
+        type: String,
+        default: "320px"
+      },
+      //播放器自动加载,目前仅h5可用
+      preload: {
+        type: Boolean,
+        default: false
+      },
+      //播放器默认封面图片,请填写正确的图片url地址。需要autoplay为’false’时,才生效
+      cover: {
+        type: String,
+        default: ""
+      },
+      //播放内容是否为直播,直播时会禁止用户拖动进度条。
+      isLive: {
+        type: Boolean,
+        default: false
+      },
+      //播放器是否自动播放,在移动端autoplay属性会失效。
+      autoplay: {
+        type: Boolean,
+        default: false
+      },
+      //播放器自动循环播放。
+      rePlay: {
+        type: Boolean,
+        default: false
+      },
+      //指定使用H5播放器。
+      useH5Prism: {
+        type: Boolean,
+        default: false
+      },
+      //指定使用Flash播放器。
+      useFlashPrism: {
+        type: Boolean,
+        default: false
+      },
+      //H5是否内置播放,有的Android浏览器不起作用。
+      playsinline: {
+        type: Boolean,
+        default: false
+      },
+      //显示播放时缓冲图标,默认true。
+      showBuffer: {
+        type: Boolean,
+        default: true
+      },
+      //URL 皮肤图片,不建议随意修改该字段,如要修改,请参照皮肤定制。
+      skinRes: {
+        type: String,
+        default: ""
+      },
+
+      skinLayout: {
+        type: Array,
+        default: function () {
+          return []
+        }
+      },
+      //默认为‘hover’。可选的值为:‘click’、‘hover’、‘always’。
+      controlBarVisibility: {
+        type: String,
+        default: "hover"
+      },
+      //控制栏自动隐藏时间(ms)
+      showBarTime: {
+        type: String,
+        default: ""
+      },
+      /***
+       * JSON串用于定制性接口参数,目前支持:
+       1.“fullTitle”:“测试页面”
+       全屏时显示视频标题(仅flash支持)。
+       2. “m3u8BufferLength”:“30”
+       播放m3u8时加载缓存ts文件长度单位(秒)(仅flash支持)。
+       3. “liveStartTime”:“2016/08/17 12:00:00”
+       直播开始时间,用于提示直播未开始(仅flash支持)。
+       4. “liveOverTime”:“2016/08/17 14:00:00”
+       直播结束时间,用于提示直播结束(仅flash支持)。
+       */
+      extraInfo: {
+        type: String,
+        default: ""
+      },
+
+      /**
+       *是否允许系统右键菜单显示,默认为false。
+       */
+      enableSystemMenu: {
+        type: Boolean,
+        default: false
+      },
+
+      /***
+       *
+       *指定播放地址格式,只有使用vid的播放方式时支持
+       可选值为’mp4’、’m3u8’、’flv’、’mp3’,默认为空,仅H5支持。
+       * */
+      format: {
+        type: String,
+        default: "mp4"
+      },
+      /***
+       *
+       * 指定返回音频还是视频,只有使用vid的播放方式时支持。
+       可选值为’video’和’audio’,默认为’video’
+       ‘audio’主要是针对只包含音频的视频格式,比如音频的mp4,仅H5支持。
+       * */
+      mediaType: {
+        type: String,
+        default: "video"
+      },
+      /***
+       * 指定排序方式,只有使用vid + plauth播放方式时支持。
+       ‘desc’表示按倒序排序(即:从大到小排序)
+       ‘asc’表示按正序排序(即:从小到大排序)
+       默认值:‘asc’,仅H5支持。
+       * */
+      qualitySort: {
+        type: String,
+        default: "asc"
+      },
+      /***
+       * 显示视频清晰度,多个用逗号分隔,比如:’FD,LD’,此值是vid对应流清晰度的一个子集,
+       取值范围:FD(流畅)LD(标清)SD(高清)HD(超清)OD(原画)2K(2K)4K(4K),仅H5支持。
+       * */
+      definition: {
+        type: String,
+        default: ""
+      },
+      /**
+       * 默认视频清晰度,此值是vid对应流的一个清晰度,
+       取值范围:FD(流畅)LD(标清)SD(高清)HD(超清)OD(原画)2K(2K)4K(4K),仅H5支持。
+       * */
+      defaultDefinition: {
+        type: String,
+        default: ""
+      },
+      /**
+       * 声明启用同层H5播放器,启用时设置的值为‘h5’
+       * */
+      x5_type: {
+        type: String,
+        default: "h5"
+      },
+      /**
+       * 声明视频播放时是否进入到TBS的全屏模式,默认为false。
+       当需要把视频做为背景时,设置为true
+       * */
+      x5_fullscreen: {
+        type: Boolean,
+        default: false
+      },
+      /**
+       * 声明视频播在界面上的位置,默认为“center”。
+       可选值为:“top”,“center”
+       * */
+      x5_video_position: {
+        type: String,
+        default: "center"
+      },
+      /**
+       * 声明 TBS 播放器支持的方向,可选值:
+       landscape:横屏)
+       portraint:竖屏
+       landscape
+       * */
+      x5_orientation: {
+        type: String,
+        default: "portraint"
+      },
+      /**
+       * 声明TBS全屏播放是否横屏,默认值为true。
+       * */
+      x5LandscapeAsFullScreen: {
+        type: String,
+        default: "true"
+      },
+      /**
+       * 延迟播放时间,单位为秒。
+       * */
+      autoPlayDelay: {
+        type: Number,
+        default: 0
+      },
+      /**
+       * 延迟播放提示文本
+       * */
+      autoPlayDelayDisplayText: {
+        type: String,
+        default: "正在转码,请稍后......"
+      },
+      /**
+       * 国际化,默认为‘zh-cn’。
+       如果未设置,则采用浏览器语言。
+       可选值为‘zh-cn’、‘en-us’或其它值。
+       * */
+      language: {
+        type: String,
+        default: "zh-cn"
+      },
+      /**
+       * 自定义国际化文本json结构,key的值需要和language属性值对应起来。
+       例子:{jp:{Play:”Play”}}
+       * */
+      languageTexts: {
+        type: Object,
+        default: function () {
+          return {}
+        }
+      },
+      /**
+       * flash启用截图功能
+       * */
+      snapshot: {
+        type: Boolean,
+        default: false
+      },
+      /**
+       * H5设置截图水印。
+       * */
+      snapshotWatermark: {
+        type: Object,
+        default: function () {
+          return {}
+        }
+      },
+      /**
+       * Safari浏览器可以启用Hls插件播放,Safari 11除外。
+       * */
+      useHlsPluginForSafari: {
+        type: Boolean,
+        default: false
+      },
+      /**
+       * H5播放flv时,设置是否启用播放缓存,只在直播下起作用。
+       * */
+      enableStashBufferForFlv: {
+        type: Boolean,
+        default: false
+      },
+      /**
+       * H5播放flv时,初始缓存大小,只在直播下起作用。
+       * */
+      stashInitialSizeForFlv: {
+        type: Number,
+        default: 10
+      },
+      /**
+       * 缓冲多长时间后,提示用户切换低清晰度,默认:20秒。
+       * */
+      loadDataTimeout: {
+        type: Number,
+        default: 20
+      },
+      /**
+       *最大缓冲超时时间,超过这个时间会有错误提示,默认:60秒。
+       * */
+      waitingTimeout: {
+        type: Number,
+        default: 60
+      },
+      /**
+       * 直播开始时间,直播时移功能使用,格式为:“2018/01/04 12:00:00”。
+       * */
+      liveStartTime: {
+        type: String,
+        default: ""
+      },
+      /**
+       * 直播结束时间,直播时移功能使用,格式为:“2018/01/04 12:00:00”。
+       * */
+      liveOverTime: {
+        type: String,
+        default: ""
+      },
+      /**
+       * 直播可用时移查询地址,详情参见直播时移。
+       * https://help.aliyun.com/document_detail/65129.html?spm=a2c4g.11186623.2.28.3603bf80LR74sS
+       * */
+      liveTimeShiftUrl: {
+        type: String,
+        default: ""
+      },
+      /**
+       * flv直播和hls时移切换是,重新创建播放器方法,详情参见直播时移。
+       * https://help.aliyun.com/document_detail/65129.html?spm=a2c4g.11186623.2.28.3603bf80LR74sS
+       * */
+      recreatePlayer: {
+        type: Function,
+        default: function () {
+        }
+      },
+      /**
+       *是否显示检测按钮,默认为true。
+       * */
+      diagnosisButtonVisible: {
+        type: Boolean,
+        default: true
+      },
+      /**
+       * 禁用进度条的Seek,默认为false,仅Flash支持。
+       * */
+      disableSeek: {
+        type: Boolean,
+        default: false
+      },
+      /**
+       * 加密类型,播放点播私有加密视频时,设置值为1,默认值为0。
+       * */
+      encryptType: {
+        type: Number,
+        default: 0
+      },
+      /**
+       * 进度条打点内容数组,详情参见进度条打点。
+       * [
+       {offset:0,text:'阿里视频云端到云到端服务的重要一环'},
+       {offset:10,text:'除了支持点播和直播的基础播放功能外'},
+       {offset:20,text:'深度融合视频云业务'},
+       {offset:30,text:'为用户提供简单、快速、安全、稳定的视频播放服务'},
+       {offset:40,text:'安装播放器Demo进行体验'},
+       {offset:50,text:'开发人员请点击SDK下载'}
+       ]
+       * https://yq.aliyun.com/articles/686043?spm=a2c4g.11186623.2.31.3603bf80LR74sS
+       * */
+      progressMarkers: {
+        type: Array,
+        default: function () {
+          return []
+        }
+      },
+      /**
+       * 点播失败重试次数,默认3次
+       * */
+      vodRetry: {
+        type: Number,
+        default: 3
+      },
+      /**
+       * 直播播放失败重试次数,默认5次
+       * */
+      liveRetry: {
+        type: Number,
+        default: 5
+      },
+
+      playStyle: {
+        type: String,
+        default: ""
+      },
+      aliplayerSdkPath: {
+        // Aliplayer 代码的路径
+        type: String,
+        default: "//g.alicdn.com/de/prismplayer/2.8.2/aliplayer-min.js"
+      },
+
+
+    },
+    data() {
+      return {
+        playerId: "aliplayer_" + Math.random().toString(36).substr(2),
+        scriptTagStatus: 0,
+        isReload: false,
+        instance: null
+      };
+    },
+    created() {
+      if (window.Aliplayer !== undefined) {
+        // 如果全局对象存在,说明编辑器代码已经初始化完成,直接加载编辑器
+        this.scriptTagStatus = 2;
+        this.initAliplayer();
+      } else {
+        // 如果全局对象不存在,说明编辑器代码还没有加载完成,需要加载编辑器代码
+        this.insertScriptTag();
+      }
+    },
+    mounted() {
+      if (window.Aliplayer !== undefined) {
+        // 如果全局对象存在,说明编辑器代码已经初始化完成,直接加载编辑器
+        this.scriptTagStatus = 2;
+        this.initAliplayer();
+      } else {
+        // 如果全局对象不存在,说明编辑器代码还没有加载完成,需要加载编辑器代码
+        this.insertScriptTag();
+      }
+    },
+    methods: {
+      insertScriptTag() {
+        const _this = this;
+        let playerScriptTag = document.getElementById("playerScriptTag");
+        // 如果这个tag不存在,则生成相关代码tag以加载代码
+        if (playerScriptTag === null) {
+          playerScriptTag = document.createElement("script");
+          playerScriptTag.type = "text/javascript";
+          playerScriptTag.src = this.aliplayerSdkPath;
+          playerScriptTag.id = "playerScriptTag";
+          let s = document.getElementsByTagName("head")[0];
+          s.appendChild(playerScriptTag);
+        }
+        if (playerScriptTag.loaded) {
+          _this.scriptTagStatus++;
+        } else {
+          playerScriptTag.addEventListener("load", () => {
+            _this.scriptTagStatus++;
+            playerScriptTag.loaded = true;
+            _this.initAliplayer();
+          });
+        }
+        _this.initAliplayer();
+      },
+      initAliplayer() {
+        const _this = this;
+        // scriptTagStatus 为 2 的时候,说明两个必需引入的 js 文件都已经被引入,且加载完成
+        if (
+          _this.scriptTagStatus === 2 &&
+          (_this.instance === null || _this.reloadPlayer)
+        ) {
+          _this.instance && _this.instance.dispose();
+
+          //document.querySelector("#" + _this.playerId).innerHTML = "";
+
+          // Vue 异步执行 DOM 更新,这样一来代码执行到这里的时候可能 template 里面的 script 标签还没真正创建
+          // 所以,我们只能在 nextTick 里面初始化 Aliplayer
+          _this.$nextTick(() => {
+            _this.instance = window.Aliplayer({
+              id: _this.playerId,
+              source: _this.source,
+              vid: _this.vid,
+              playauth: _this.playauth,
+              width: _this.width,
+              height: _this.height,
+              videoWidth: _this.videoWidth,
+              videoHeight: _this.videoHeight,
+              preload: _this.preload,
+              cover: _this.cover,
+              isLive: _this.isLive,
+              autoplay: _this.autoplay,
+              rePlay: _this.rePlay,
+              useH5Prism: _this.useH5Prism,
+              useFlashPrism: _this.useFlashPrism,
+              playsinline: _this.playsinline,
+              showBuffer: _this.showBuffer,
+              skinRes: _this.skinRes,
+              skinLayout: _this.skinLayout,
+              controlBarVisibility: _this.controlBarVisibility,
+              showBarTime: _this.showBarTime,
+              extraInfo: _this.extraInfo,
+              enableSystemMenu: _this.enableSystemMenu,
+              format: _this.format,
+              mediaType: _this.mediaType,
+              qualitySort: _this.qualitySort,
+              definition: _this.definition,
+              defaultDefinition: _this.defaultDefinition,
+              x5_type: _this.x5_type,
+              x5_fullscreen: _this.x5_fullscreen,
+              x5_video_position: _this.x5_video_position,
+              x5_orientation: _this.x5_orientation,
+              x5LandscapeAsFullScreen: _this.x5LandscapeAsFullScreen,
+              autoPlayDelay: _this.autoPlayDelay,
+              autoPlayDelayDisplayText: _this.autoPlayDelayDisplayText,
+              language: _this.language,
+              languageTexts: _this.languageTexts,
+              snapshot: _this.snapshot,
+              snapshotWatermark: _this.snapshotWatermark,
+              useHlsPluginForSafari: _this.useHlsPluginForSafari,
+              enableStashBufferForFlv: _this.enableStashBufferForFlv,
+              stashInitialSizeForFlv: _this.stashInitialSizeForFlv,
+              loadDataTimeout: _this.loadDataTimeout,
+              waitingTimeout: _this.waitingTimeout,
+              liveStartTime: _this.liveStartTime,
+              liveTimeShiftUrl: _this.liveTimeShiftUrl,
+              liveShiftSource: _this.liveShiftSource,
+              recreatePlayer: _this.recreatePlayer,
+              diagnosisButtonVisible: _this.diagnosisButtonVisible,
+              disableSeek: _this.disableSeek,
+              encryptType: _this.encryptType,
+              progressMarkers: _this.progressMarkers,
+              vodRetry: _this.vodRetry,
+              liveRetry: _this.liveRetry,
+            });
+
+            // 绑定事件,当 AliPlayer 初始化完成后,将编辑器实例通过自定义的 ready 事件交出去
+            _this.instance.on("ready", () => {
+              this.$emit("ready", _this.instance);
+            });
+
+            _this.instance.on("play", () => {
+              this.$emit("play", _this.instance);
+            });
+
+            _this.instance.on("pause", () => {
+              this.$emit("pause", _this.instance);
+            });
+
+            _this.instance.on("ended", () => {
+              this.$emit("ended", _this.instance);
+            });
+
+            _this.instance.on("liveStreamStop", () => {
+              this.$emit("liveStreamStop", _this.instance);
+            });
+
+            _this.instance.on("m3u8Retry", () => {
+              this.$emit("m3u8Retry", _this.instance);
+            });
+
+            _this.instance.on("hideBar", () => {
+              this.$emit("hideBar", _this.instance);
+            });
+
+            _this.instance.on("waiting", () => {
+              this.$emit("waiting", _this.instance);
+            });
+
+            _this.instance.on("snapshoted", () => {
+              this.$emit("snapshoted", _this.instance);
+            });
+
+            _this.instance.on("timeupdate", () => {
+              this.$emit("timeupdate", _this.instance);
+            });
+
+            _this.instance.on("requestFullScreen", () => {
+              this.$emit("requestFullScreen", _this.instance);
+            });
+
+            _this.instance.on("cancelFullScreen", () => {
+              this.$emit("cancelFullScreen", _this.instance);
+            });
+
+            _this.instance.on("error", () => {
+              this.$emit("error", _this.instance);
+            });
+
+            _this.instance.on("startSeek", () => {
+              this.$emit("startSeek", _this.instance);
+            });
+
+            _this.instance.on("completeSeek", () => {
+              this.$emit("completeSeek", _this.instance);
+            });
+          });
+        }
+      },
+      /**
+       * 播放视频
+       */
+      play: function () {
+        this.instance.play();
+      },
+      /**
+       * 暂停视频
+       */
+      pause: function () {
+        this.instance.pause();
+      },
+      /**
+       * 重播视频
+       */
+      replay: function () {
+        this.instance.replay();
+      },
+      /**
+       * 跳转到某个时刻进行播放
+       * @argument time 的单位为秒
+       */
+      seek: function (time) {
+        this.instance.seek(time);
+      },
+      /**
+       * 获取当前时间 单位秒
+       */
+      getCurrentTime: function () {
+        return this.instance.getCurrentTime();
+      },
+      /**
+       *获取视频总时长,返回的单位为秒
+       * @returns 返回的单位为秒
+       */
+      getDuration: function () {
+        return this.instance.getDuration();
+      },
+      /**
+       获取当前的音量,返回值为0-1的实数ios和部分android会失效
+       */
+      getVolume: function () {
+        return this.instance.getVolume();
+      },
+      /**
+       设置音量,vol为0-1的实数,ios和部分android会失效
+       */
+      setVolume: function (vol) {
+        this.instance.setVolume(vol);
+      },
+      /**
+       *直接播放视频url,time为可选值(单位秒)目前只支持同种格式(mp4/flv/m3u8)之间切换暂不支持直播rtmp流切换
+       *@argument url 视频地址
+       *@argument time 跳转到多少秒
+       */
+      loadByUrl: function (url, time) {
+        this.instance.loadByUrl(url, time);
+      },
+      /**
+       * 设置播放速度
+       *@argument speed 速度
+       */
+      setSpeed: function (speed) {
+        this.instance.setSpeed(speed);
+      },
+      /**
+       * 设置播放器大小w,h可分别为400px像素或60%百分比chrome浏览器下flash播放器分别不能小于397x297
+       *@argument w 播放器宽度
+       *@argument h 播放器高度
+       */
+      setPlayerSize: function (w, h) {
+        this.instance.setPlayerSize(w, h);
+      },
+      /**
+       *目前只支持H5播放器。
+       暂不支持不同格式视频间的之间切换。
+       暂不支持直播rtmp流切换。
+       */
+      replayByVidAndPlayAuth: function (vid, accId, accSecret, stsToken, authInfo, domainRegion) {
+        this.instance.replayByVidAndPlayAuth(vid, accId, accSecret, stsToken, authInfo, domainRegion);
+      },
+
+      /***
+       * 重新设置vid和权限,目前只支持H5播放器。
+       暂不支持不同格式视频间的之间切换。
+       暂不支持直播rtmp流切换。
+       * @param vid 视频ID
+       * @param playauth 播放权限
+       */
+      replayByVidAndAuthInfo: function (vid, playauth) {
+        this.instance.replayByVidAndAuthInfo(vid, playauth);
+      },
+
+      /**
+       * 目前只支持HTML5界面上的重载功能,暂不支持直播rtmp流切换m3u8)之间切换,暂不支持直播rtmp流切换
+       *@argument vid 视频id
+       *@argument playauth 播放凭证
+       */
+      reloaduserPlayInfoAndVidRequestMts: function (vid, playauth) {
+        this.instance.reloaduserPlayInfoAndVidRequestMts(vid, playauth);
+      },
+
+      /***
+       *设置截图参数
+       * @param width 宽度
+       * @param height 高度
+       * @param rate 截图质量
+       */
+      setSanpshotProperties: function (width, height, rate) {
+        this.instance.setSanpshotProperties(width, height, rate);
+      },
+      /**
+       * 设置封面地址
+       * @param cover 封面地址
+       */
+      setCover: function (cover) {
+        this.instance.setCover(cover);
+      },
+
+
+      reloadPlayer: function () {
+        this.isReload = true;
+        this.initAliplayer();
+        this.isReload = false;
+      }
+    }
+  };
+</script>
+
+<style>
+  @import url(//g.alicdn.com/de/prismplayer/2.8.2/skins/default/aliplayer-min.css);
+</style>

+ 2 - 0
src/layout/index.vue

@@ -216,6 +216,8 @@ export default {
       background: #fff;
       background: #fff;
       box-shadow:0px 0px 2px rgb(175, 175, 175);
       box-shadow:0px 0px 2px rgb(175, 175, 175);
       font-size: 24px;
       font-size: 24px;
+
+     
     }
     }
   }
   }
 }
 }

+ 3 - 1
src/main.js

@@ -28,15 +28,17 @@ import Pagination from "@/components/Pagination";
 import RightToolbar from "@/components/RightToolbar"
 import RightToolbar from "@/components/RightToolbar"
 import FormMaking from 'form-making'
 import FormMaking from 'form-making'
 import 'form-making/dist/FormMaking.css'
 import 'form-making/dist/FormMaking.css'
-
 Vue.use(VueClipboard)
 Vue.use(VueClipboard)
 
 
 Vue.use(FormMaking)
 Vue.use(FormMaking)
 // 全局方法挂载
 // 全局方法挂载
 Vue.component('ImageUpload',ImageUpload)
 Vue.component('ImageUpload',ImageUpload)
+
 import audio from 'vue-mobile-audio'
 import audio from 'vue-mobile-audio'
 Vue.use(audio)
 Vue.use(audio)
 
 
+
+
 Vue.prototype.callNumber = callNumber
 Vue.prototype.callNumber = callNumber
 Vue.prototype.callOff = callOff
 Vue.prototype.callOff = callOff
 Vue.prototype.callMobile = callMobile
 Vue.prototype.callMobile = callMobile

+ 73 - 11
src/views/qw/qwChat/qq.vue

@@ -17,6 +17,8 @@
           @change-menu="handleChangeMenu"
           @change-menu="handleChangeMenu"
           @pull-messages="handlePullMessages"
           @pull-messages="handlePullMessages"
           @change-contact="handleChangeContact"
           @change-contact="handleChangeContact"
+          @change-conversation="handleChangeConversation"
+          
           @message-click="handleMessageClick"
           @message-click="handleMessageClick"
           @menu-avatar-click="handleMenuAvatarClick"
           @menu-avatar-click="handleMenuAvatarClick"
           @pick-image="handleImageClick"
           @pick-image="handleImageClick"
@@ -97,11 +99,21 @@
    
    
 
 
        <el-dialog :visible.sync="dialogVisible">
        <el-dialog :visible.sync="dialogVisible">
-         <img width="100%" :src="dialogImageUrl" alt="">
+         <img width="100%" :src="dialogImageUrl" alt="" />
       </el-dialog>
       </el-dialog>
 
 
-       <Material ref="material" @pickImageData="handlePickImageDone"  v-model="imageArr" type="image" :num="1" :width="150" :height="150" />
+       <el-dialog :visible.sync="dialogVideoVisible"
+               :close-on-click-modal="false"
+               :destroy-on-close="true"
+               @close="dialogVideoVisible=false"
+               ref="player"
+               >
+          <videoPlayer :width="aplayer.width" :height="aplayer.height"  :vid="aplayer.vid"  :autoplay="true" 
+            :source="dialogVideoUrl" :cover="dialogVideoCover" ref="player"></videoPlayer>
+      </el-dialog>
 
 
+       <Material ref="material" @pickImageData="handlePickImageDone"  v-model="imageArr" type="image" :num="1" :width="150" :height="150" />
+       
 
 
   </div>
   </div>
 </template>
 </template>
@@ -112,19 +124,21 @@ import store from "@/store";
 import { getQrCode } from '@/api/qw/login';
 import { getQrCode } from '@/api/qw/login';
 import { getDeviceId} from '@/api/qw/account';
 import { getDeviceId} from '@/api/qw/account';
 import LemonMessageVoice from "@/components/LemonUI/components/message/voice";
 import LemonMessageVoice from "@/components/LemonUI/components/message/voice";
-import { getContactsByUser,getConversations,getMessageList,getConversation,sendTextMsg,sendImageMsg} from '@/api/qw/im';
+import { getContactsByUser,getConversations,getMessageList,getConversation,sendTextMsg,sendImageMsg,getRoomInfo} from '@/api/qw/im';
 import ContactsData from "@/components/LemonUI/database/contacts";
 import ContactsData from "@/components/LemonUI/database/contacts";
 import MessagesData from "@/components/LemonUI/database/messages";
 import MessagesData from "@/components/LemonUI/database/messages";
 import Conversations from "@/components/LemonUI/database/conversations";
 import Conversations from "@/components/LemonUI/database/conversations";
 import EmojiData from "@/components/LemonUI/database/emoji";
 import EmojiData from "@/components/LemonUI/database/emoji";
 import '@/components/LemonUI/index.css';
 import '@/components/LemonUI/index.css';
 import Material from '@/components/Material/index'
 import Material from '@/components/Material/index'
+import VideoPlayer from '@/components/VideoPlayer/VueAliplayer'
 
 
 let pages = {};
 let pages = {};
 export default {
 export default {
   name: "qqChat",
   name: "qqChat",
   components: {   
   components: {   
     Material,
     Material,
+    VideoPlayer
   },
   },
   data() {
   data() {
     return {
     return {
@@ -268,8 +282,20 @@ export default {
       isFromLogin:false,
       isFromLogin:false,
       dialogImageUrl: '',
       dialogImageUrl: '',
       dialogVisible: false,
       dialogVisible: false,
+      dialogVideoVisible:false, 
+      dialogVideoUrl:'',
+      dialogVideoCover:'',
       imageArr:[],
       imageArr:[],
       pickUploadImgData:null,
       pickUploadImgData:null,
+      aplayer: {
+        vid: "bf9b7e4a36d84aea8cee769765fbc28b",
+        videoHeight:"1000px",
+        videoWidth:"800px"
+      },
+      player: null,
+      roomMembers:[],
+      roomAdmins:[],
+      roomInfo:null,
       windowWidth: document.documentElement.clientWidth*0.65,  //实时屏幕宽度
       windowWidth: document.documentElement.clientWidth*0.65,  //实时屏幕宽度
       windowHeight: document.documentElement.clientHeight*0.7,   //实时屏幕高度
       windowHeight: document.documentElement.clientHeight*0.7,   //实时屏幕高度
       queryParams: {
       queryParams: {
@@ -478,6 +504,13 @@ export default {
                   };
                   };
               }
               }
     },
     },
+    getRoomInfo(roomId){
+        getRoomInfo(roomId).then(response => {
+             this.roomMembers=response.members;
+             this.admins=response.members;
+             this.roomInfo=response.detail;
+        });
+    },
   
   
     getContacts(){  
     getContacts(){  
       getContactsByUser(this.qwUser.userId).then(response => {
       getContactsByUser(this.qwUser.userId).then(response => {
@@ -554,16 +587,20 @@ export default {
       // }, 2000);
       // }, 2000);
 
 
     },
     },
-    handleChangeContact(contact, instance) {
-        //console.log("qxj contact:"+JSON.stringify(contact));
+    handleChangeConversation(contact, instance) {
+        console.log("qxj ChangeConversation:"+JSON.stringify(contact));
         if (!pages[contact.conversationId]){
         if (!pages[contact.conversationId]){
             pages[contact.conversationId] =1;
             pages[contact.conversationId] =1;
         }
         }
        this.queryParams.pageNum=pages[contact.conversationId];
        this.queryParams.pageNum=pages[contact.conversationId];
        this.queryParams.conversationId=contact.conversationId;
        this.queryParams.conversationId=contact.conversationId;
         //instance.updateContact(contact);
         //instance.updateContact(contact);
+        
         instance.closeDrawer();
         instance.closeDrawer();
     },
     },
+    handleChangeContact(contact, instance) {
+        
+    },
     
     
     //收到消息后添加消息显示
     //收到消息后添加消息显示
     appendMessageAction(msgData){
     appendMessageAction(msgData){
@@ -581,6 +618,20 @@ export default {
               };
               };
               this.appendRemoteMessage(message);
               this.appendRemoteMessage(message);
            }
            }
+           else if(msgData.type=="file"){
+               const message = {
+                    id: msgData.id,
+                    status: msgData.status,
+                    type: msgData.type,
+                    sendTime: msgData.sendTime,
+                    content: msgData.content,
+                    toContactId: msgData.toContactId,
+                    fromUser: msgData.fromUser,
+                    fileName:msgData.fileName,
+                    fileSize:msgData.fileSize
+              };
+              this.appendRemoteMessage(message);
+           }
            else{
            else{
               const message = {
               const message = {
                     id: msgData.id,
                     id: msgData.id,
@@ -593,10 +644,7 @@ export default {
               };
               };
               this.appendRemoteMessage(message);
               this.appendRemoteMessage(message);
            }
            }
-
-           
     },
     },
-
     //发送消息
     //发送消息
     handleSend(message, next, file) {
     handleSend(message, next, file) {
       const IMUI = this.$refs.IMUI;
       const IMUI = this.$refs.IMUI;
@@ -626,7 +674,6 @@ export default {
               }
               }
           });
           });
       }
       }
-
       // setTimeout(() => {
       // setTimeout(() => {
       //   next();
       //   next();
       // }, 1000);
       // }, 1000);
@@ -645,7 +692,13 @@ export default {
         this.pickUploadImgData=data;
         this.pickUploadImgData=data;
         const IMUI = this.$refs.IMUI;
         const IMUI = this.$refs.IMUI;
         IMUI._handleRemoteImage(data.url);
         IMUI._handleRemoteImage(data.url);
-
+    },
+    tooglePlayVideo(data){
+       this.dialogVideoVisible=true;
+       this.dialogVideoUrl=data.content;
+       this.dialogVideoCover=data.url;
+       const player = this.$refs.player.instance
+       player && player.play()
     },
     },
     handleMessageClick(e, key, message, instance) {
     handleMessageClick(e, key, message, instance) {
       console.log("点击了消息", e, key, message);
       console.log("点击了消息", e, key, message);
@@ -653,6 +706,12 @@ export default {
       if(message.type=="image"){
       if(message.type=="image"){
            var url=!!message.url?message.url:message.content;
            var url=!!message.url?message.url:message.content;
            this.handlePicturePreview(url);
            this.handlePicturePreview(url);
+      }
+      else if(message.type=="video"){  
+           this.tooglePlayVideo(message);
+      }
+      else if(message.type=="file"){  
+           
       }
       }
       if (key == "status") {
       if (key == "status") {
         instance.updateMessage({
         instance.updateMessage({
@@ -760,7 +819,6 @@ export default {
         const { IMUI } = this.$refs;
         const { IMUI } = this.$refs;
         IMUI.appendMessage(message, true);
         IMUI.appendMessage(message, true);
     },
     },
-
     updateContact() {
     updateContact() {
       this.$refs.IMUI.updateContact({
       this.$refs.IMUI.updateContact({
         id: "contact-3",
         id: "contact-3",
@@ -818,6 +876,10 @@ export default {
         background: #111;
         background: #111;
         padding: 0 8px;
         padding: 0 8px;
     }
     }
+
+    /deep/.el-dialog__headerbtn{
+         top:10px;
+    }
     
     
 </style>
 </style>
 
 

BIN
static/video.png


이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.