1067 lines
		
	
	
		
			35 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			1067 lines
		
	
	
		
			35 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
|  <template>
 | ||
|   <ai-list v-loading="isLoading" class="detail">
 | ||
|     <template slot="title">
 | ||
|       <ai-title title="详情" isShowBack isShowBottomBorder @onBackClick="cancel(false)"></ai-title>
 | ||
|     </template>
 | ||
|     <template #left>
 | ||
|       <div class="addressBook-left">
 | ||
|         <div class="addressBook-left__title">
 | ||
|           <h2 :class="[tabIndex == 1 ? 'tab-active' : '']" @click="typeClick(1)">群聊会话</h2>
 | ||
|           <h2 :class="[tabIndex == 0 ? 'tab-active' : '']" @click="typeClick(0)">私聊会话</h2>
 | ||
|         </div>
 | ||
|         <div class="addressBook-left__list--title">
 | ||
|           <el-input
 | ||
|             size="mini"
 | ||
|             :placeholder="tabIndex == 1 ? '请输入群名称' : '请输入昵称'"
 | ||
|             v-model="searchName"
 | ||
|             clearable
 | ||
|             @clear="current = 1, searchName = '', getListInit()"
 | ||
|             v-throttle="() => {(current = 1), getListInit();}"
 | ||
|             suffix-icon="iconfont iconSearch">
 | ||
|           </el-input>
 | ||
|         </div>
 | ||
|         <div class="addressBook-left__list--wrapper">
 | ||
|           <div class="addressBook-left__list--item" v-for="(item, index) in list" :key="index" :class="leftActiveIndex == index ? 'active' : ''" @click="leftClick(index)">
 | ||
|             <div v-if="tabIndex == 1" class="flex-left">
 | ||
|               <img src="./img/group-img.png" alt="">{{item.roomName}}
 | ||
|             </div>
 | ||
|             <div v-else>
 | ||
|               <img :src="item.toUserAvatar" alt="">{{item.toUserName}}
 | ||
|             </div>
 | ||
|             <div class="flex-right" :class="`type`+item.roomType" v-if="tabIndex == 1 && item.roomType > 0">{{item.roomType == 1 ? '内部' : '外部'}}</div>
 | ||
|             <div class="flex-right" :class="`type`+item.toUserType" v-if="tabIndex != 1 && item.toUserType > 0">{{item.toUserType == 1 ? '内部' : '外部'}}</div>
 | ||
|           </div>
 | ||
|           <AiEmpty v-if="!list.length"></AiEmpty>
 | ||
|         </div>
 | ||
|         <el-pagination class="pagination"
 | ||
|           layout="prev, pager, next"
 | ||
|           :total="total" @current-change="currentChange" :current-page="current" :page-size="20">
 | ||
|         </el-pagination>
 | ||
|       </div>
 | ||
|     </template>
 | ||
|     <template slot="content">
 | ||
|       <div class="content-right-title">
 | ||
|         <div class="tab-content">
 | ||
|           <h2 v-for="(item, index) in msgTypeList" :key="index" :class="msgType == index ? 'tab-active' : ''" @click="msgTypeClick(index)">{{item.name}}</h2>
 | ||
|         </div>
 | ||
|         <div class="search-content">
 | ||
|           <el-date-picker v-model="time" size="small" type="daterange" value-format="yyyy-MM-dd"
 | ||
|             range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" @change="onChange">
 | ||
|           </el-date-picker>
 | ||
|           <el-input size="small" placeholder="输入搜索内容" v-model="searchMsg" clearable
 | ||
|             @clear="msgCurrent = 1, searchMsg = '', getMsgListInit()" suffix-icon="iconfont iconSearch"
 | ||
|           v-throttle="() => {(msgCurrent = 1), getMsgListInit();}"/>
 | ||
|           <!-- <ai-download :instance="instance" url="/app/appconvenientaddressbook/export" :params="search" fileName="会话存档"
 | ||
|                        :disabled="msgList.length == 0">
 | ||
|             <el-button icon="iconfont iconExported" :disabled="msgList.length == 0">导出</el-button>
 | ||
|           </ai-download> -->
 | ||
|           <el-button
 | ||
|             icon="iconfont iconExported"
 | ||
|             :disabled="msgList.length == 0"
 | ||
|             style="margin-left: 8px"
 | ||
|             @click="handleExport"
 | ||
|             >导出</el-button
 | ||
|           >
 | ||
|         </div>
 | ||
|       </div>
 | ||
|       <div class="content-right-info" @scroll='msgScroll'>
 | ||
|         <div ref="pdf">
 | ||
|           <div v-for="(item, index) in msgList" :key="index">
 | ||
|             <div class="item" :class="item.userId == id ? 'item-right' : 'item-left'">
 | ||
|               <!-- <p class="time" v-if="index == 0">{{item.msgSendTime}}</p> -->
 | ||
|               <p class="user-name">{{item.userName}}<span>{{item.msgSendTime}}</span></p>
 | ||
|               <div class="item-content-flex">
 | ||
|                 <i class="el-icon-warning" v-if="item.userId == id && item.isKeyword == 1"></i>
 | ||
|                 <img :src="item.userAvatar" alt="" class="user-img" v-if="item.userId != id && item.userAvatar">
 | ||
|                 <img src="./img/user-img.png" alt="" class="user-img" v-if="item.userId != id && !item.userAvatar">
 | ||
| 
 | ||
|                 <div class="content" v-if="item.msgType == 'text'">
 | ||
|                   <span></span>
 | ||
|                   <p>{{item.content}}</p>
 | ||
|                 </div>
 | ||
| 
 | ||
|                 <div class="img-list" v-if="item.msgType == 'image'">
 | ||
|                   <img :src="item.sdkFileUrl" alt="" v-viewer>
 | ||
|                 </div>
 | ||
| 
 | ||
|                 <div class="voice-info" v-if="item.msgType == 'voice'">
 | ||
|                   <ai-audio :src="item.sdkFileUrl" skin="flat" />
 | ||
|                 </div>
 | ||
| 
 | ||
|                 <video style="width: 300px; object-fit: fill;" controls :src="item.sdkFileUrl" v-if="item.msgType == 'video'"></video>
 | ||
| 
 | ||
|                 <ai-file-list v-if="item.msgType == 'file'"
 | ||
|                   :fileList="item.files"
 | ||
|                   :fileOps="{ name: 'name', size: 'fileSizeStr' }"
 | ||
|                 ></ai-file-list>
 | ||
| 
 | ||
|                 <div class="revoke-text" v-if="item.msgType == 'revoke'">{{item.userName}}撤回了一条消息</div>
 | ||
| 
 | ||
|                 <div class="revoke-text" v-if="item.msgType == 'disagree'">对方不同意会话存档内容,你将无法继续提供服务</div>
 | ||
| 
 | ||
|                 <div class="revoke-text" v-if="item.msgType == 'agree'">对方同意会话存档内容,你可以继续提供服务</div>
 | ||
| 
 | ||
|                 <div class="card-info" v-if="item.msgType == 'card'">
 | ||
|                   <div class="top">
 | ||
|                     <div class="card-left">
 | ||
|                       <h3>{{item.cardCorpName}}</h3>
 | ||
|                       <p>{{item.cardUserName}}</p>
 | ||
|                       <!-- <div>{{item.cardUserId}}</div> -->
 | ||
|                     </div>
 | ||
|                     <div class="card-right">
 | ||
|                       <img :src="item.cardUserAvatar" alt="" v-if="item.cardUserAvatar">
 | ||
|                       <img src="./img/user-img.png" alt="" v-else>
 | ||
|                     </div>
 | ||
|                   </div>
 | ||
|                   <div class="bottom">个人名片</div>
 | ||
|                 </div>
 | ||
| 
 | ||
|                 <img :src="item.sdkFileUrl" alt="" v-if="item.msgType == 'emotion'" :style="[{width: item.width/2+'px'}, {height: item.height/2+'px'}]">
 | ||
| 
 | ||
|                 <div class="map-info" v-if="item.msgType == 'location'">
 | ||
|                   <div :id="item.mapId" class="map-content"></div>
 | ||
|                   <div class="address-text">
 | ||
|                     <p>{{item.title}}</p>
 | ||
|                     <p>{{item.address}}</p>
 | ||
|                   </div>
 | ||
|                 </div>
 | ||
| 
 | ||
|                 <div class="card-info" v-if="item.msgType == 'weapp'">
 | ||
|                   <div class="top">
 | ||
|                     <div class="card-left">
 | ||
|                       <h3>{{item.displayName}}</h3>
 | ||
|                       <p>{{item.title}}</p>
 | ||
|                     </div>
 | ||
|                     <div class="card-right">
 | ||
|                       <img src="./img/app-icon.png" alt="" >
 | ||
|                     </div>
 | ||
|                   </div>
 | ||
|                   <div class="bottom"><img src="./img/app-mini-icon.png" alt="" >小程序</div>
 | ||
|                 </div>
 | ||
| 
 | ||
|                 <div class="card-info pointer" v-if="item.msgType == 'link'" @click="openLink(item)">
 | ||
|                   <div class="top">
 | ||
|                     <div class="card-left">
 | ||
|                       <p>{{item.title}}</p>
 | ||
|                       <div>{{item.username}}</div>
 | ||
|                     </div>
 | ||
|                     <div class="card-right" v-if="item.imageUrl">
 | ||
|                       <img :src="item.imageUrl" alt="" >
 | ||
|                     </div>
 | ||
|                   </div>
 | ||
|                   <div class="bottom">分享链接</div>
 | ||
|                 </div>
 | ||
| 
 | ||
|                 <img :src="item.userAvatar" alt="" class="user-img" v-if="item.userId == id">
 | ||
|                 <i class="el-icon-warning" v-if="item.userId != id && item.isKeyword == 1"></i>
 | ||
|               </div>
 | ||
|             </div>
 | ||
|           </div>
 | ||
|         </div>
 | ||
|         <AiEmpty v-if="!msgList.length"></AiEmpty>
 | ||
|       </div>
 | ||
|       <!-- <el-pagination class="msg-list-pagination"
 | ||
|         layout="prev, pager, next"
 | ||
|         :total="msgTotal" @current-change="msgCurrentChange" :current-page="msgCurrent" :page-size="20">
 | ||
|       </el-pagination> -->
 | ||
|     </template>
 | ||
|   </ai-list>
 | ||
| </template>
 | ||
| 
 | ||
| <script>
 | ||
|   import { mapState } from 'vuex'
 | ||
|   import AMapLoader from '@amap/amap-jsapi-loader'
 | ||
|   import html2canvas from "html2canvas";
 | ||
|   import jsPDF from "jspdf";
 | ||
|   import { Loading } from "element-ui";
 | ||
| 
 | ||
|   const PdfLoader = (ele, pdfFileName) => {
 | ||
|     let loadingInstance = Loading.service({ fullscreen: true, text: '正在导出(请勿刷新/关闭页面)' });
 | ||
|     ele.style.fontFamily = "宋体";
 | ||
|     ele.style.fontSize = "16px";
 | ||
|     ele.style.padding = "0 20px";
 | ||
|     // 预留一定的时间给dom页面渲染完成 (如果你能保证dom已经渲染完成了包括图片 才去进行下面转化操作那就可以不用这个延迟器)
 | ||
|     setTimeout(() => {
 | ||
|       html2canvas(ele, {
 | ||
|         // dpi: 300, // 清晰度
 | ||
|         scale: 1, // 将Canvas放大倍数 可以获得更具清晰的图片内容
 | ||
|         // !!!注意如果你生成的元素内容非常多是一个非常长列表 建议scale不要写太高或者删除这个属性 ,因为html2canvas会吧内容转成
 | ||
|         // base64 会有一定的内容上限 最终返回没有base64编码(目前我尝试过生成55页的PDF,估计上限在70-100页)
 | ||
|         useCORS: true, //是否允许跨域
 | ||
|         allowTaint: false,
 | ||
|         height: ele.offsetHeight,
 | ||
|         width: ele.offsetWidth,
 | ||
|         windowWidth: document.body.scrollWidth,
 | ||
|         windowHeight: document.body.scrollHeight,
 | ||
|       }).then((canvas) => {
 | ||
|         //未生成pdf的html页面高度
 | ||
|         var leftHeight = canvas.height;
 | ||
|         var a4Width = 595.28;
 | ||
|         var a4Height = 841.89;
 | ||
|         //一页pdf显示html页面生成的canvas高度;
 | ||
|         var a4HeightRef = Math.floor((canvas.width / a4Width) * a4Height);
 | ||
|         //pdf页面偏移
 | ||
|         var position = 0;
 | ||
|         var pageData = canvas.toDataURL("image/jpeg", 1.0); // 生成的base64 如果你只是要图片 到这里就可以拿到base64图片编码(可以查一下base64转二进制 使用new FormData对象传给后端到服务器)
 | ||
| 
 | ||
|         var pdf = new jsPDF("x", "pt", "a4"); //生成A4内容大小的pdf每页 更多参数配置可以看看下面的网站
 | ||
|         // https://blog.csdn.net/weixin_42333548/article/details/107630706
 | ||
|         var index = 1,
 | ||
|           canvas1 = document.createElement("canvas"),
 | ||
|           height;
 | ||
|         pdf.setDisplayMode("fullwidth", "continuous", "FullScreen");
 | ||
|         // 处理 pdf 上一页 与 下一页内容之间交叉不好看的断点样式
 | ||
|         // 并且把内容转成二进制 生成pdf文件
 | ||
|         function createImpl(canvas) {
 | ||
|           if (leftHeight > 0) {
 | ||
|             index++;
 | ||
|             var checkCount = 0;
 | ||
|             if (leftHeight > a4HeightRef) {
 | ||
|               var i = position + a4HeightRef;
 | ||
|               for (i = position + a4HeightRef; i >= position; i--) {
 | ||
|                 var isWrite = true;
 | ||
|                 for (var j = 0; j < canvas.width; j++) {
 | ||
|                   var c = canvas.getContext("2d").getImageData(j, i, 1, 1).data;
 | ||
|                   if (c[0] != 0xff || c[1] != 0xff || c[2] != 0xff) {
 | ||
|                     isWrite = false;
 | ||
|                     break;
 | ||
|                   }
 | ||
|                 }
 | ||
|                 if (isWrite) {
 | ||
|                   checkCount++;
 | ||
|                   if (checkCount >= 10) {
 | ||
|                     break;
 | ||
|                   }
 | ||
|                 } else {
 | ||
|                   checkCount = 0;
 | ||
|                 }
 | ||
|               }
 | ||
|               height =
 | ||
|                 Math.round(i - position) || Math.min(leftHeight, a4HeightRef);
 | ||
|               if (height <= 0) {
 | ||
|                 height = a4HeightRef;
 | ||
|               }
 | ||
|             } else {
 | ||
|               height = leftHeight;
 | ||
|             }
 | ||
| 
 | ||
|             canvas1.width = canvas.width;
 | ||
|             canvas1.height = height;
 | ||
|             var ctx = canvas1.getContext("2d");
 | ||
|             ctx.drawImage(
 | ||
|               canvas,
 | ||
|               0,
 | ||
|               position,
 | ||
|               canvas.width,
 | ||
|               height,
 | ||
|               0,
 | ||
|               0,
 | ||
|               canvas.width,
 | ||
|               height
 | ||
|             );
 | ||
| 
 | ||
|             if (position != 0) {
 | ||
|               pdf.addPage();
 | ||
|             }
 | ||
|             pdf.addImage(
 | ||
|               canvas1.toDataURL("image/jpeg", 1.0),
 | ||
|               "JPEG",
 | ||
|               0,
 | ||
|               0,
 | ||
|               a4Width,
 | ||
|               (a4Width / canvas1.width) * height
 | ||
|             );
 | ||
|             leftHeight -= height;
 | ||
|             position += height;
 | ||
|             if (leftHeight > 0) {
 | ||
|               //给pdf文件 添加全屏水印
 | ||
|               // const base64 = '';  // 吧你要添加的水印内容搞成一张小图片 然后手动去转成base64编码 放在这里就可以了
 | ||
|               // for (let i = 0; i < 6; i++) {
 | ||
|               //     for (let j = 0; j < 5; j++) {
 | ||
|               //         const left = (j * 120) + 20;
 | ||
|               //         pdf.addImage(base64, 'JPEG', left, i * 150, 20, 30);
 | ||
|               //     };
 | ||
|               // };
 | ||
|               pdf.addImage(pageData, "JPEG", 0, i * 150, 20, 30);
 | ||
|               setTimeout(createImpl, 500, canvas);
 | ||
|             } else {
 | ||
|               pdfSave();
 | ||
|             }
 | ||
|           }
 | ||
|         }
 | ||
| 
 | ||
|         //当内容未超过pdf一页显示的范围,无需分页
 | ||
|         if (leftHeight < a4HeightRef) {
 | ||
|           pdf.addImage(
 | ||
|             pageData,
 | ||
|             "JPEG",
 | ||
|             0,
 | ||
|             0,
 | ||
|             a4Width,
 | ||
|             (a4Width / canvas.width) * leftHeight
 | ||
|           );
 | ||
| 
 | ||
|           pdfSave();
 | ||
|         } else {
 | ||
|           try {
 | ||
|             pdf.deletePage(0);
 | ||
|             setTimeout(createImpl, 500, canvas);
 | ||
|           } catch (err) {
 | ||
|             console.log(err);
 | ||
|           }
 | ||
|         }
 | ||
| 
 | ||
|         function pdfSave() {
 | ||
|           // pdf文件生成完毕 自动下载到客户本地
 | ||
|           pdf.save(pdfFileName + ".pdf");
 | ||
|           loadingInstance.close();
 | ||
|         }
 | ||
|       });
 | ||
|     }, 500);
 | ||
|   };
 | ||
| 
 | ||
|   export default {
 | ||
|     name: 'Detail',
 | ||
|     props: {
 | ||
|       instance: Function,
 | ||
|       dict: Object,
 | ||
|       params: Object
 | ||
|     },
 | ||
|     data () {
 | ||
|       return {
 | ||
|         isLoading: false,
 | ||
|         tabIndex: 1,
 | ||
|         searchName: '',
 | ||
|         time: [],
 | ||
|         search: {
 | ||
|           name: ''
 | ||
|         },
 | ||
|         current: 1,
 | ||
|         total: 0,
 | ||
|         list: [],
 | ||
|         leftActiveIndex: 0,
 | ||
|         msgCurrent: 0,
 | ||
|         msgPreCurrent: 0,
 | ||
|         msgTotal: 0,
 | ||
|         msgPages: 2,
 | ||
|         msgList: [],
 | ||
|         msgType: 0,
 | ||
|         msgTypeList: [
 | ||
|           {name: '全部', value: ''},
 | ||
|           {name: '图片/视频', value: 'imagevideo'},
 | ||
|           {name: '语音', value: 'voice'},
 | ||
|           {name: '文件', value: 'file'},
 | ||
|         ],
 | ||
|         searchMsg: '',
 | ||
|         listInfo: {},
 | ||
|         id: '',
 | ||
| 
 | ||
|         // userId: 'ChenChen',
 | ||
|         // toUserId: 'LiuYe',
 | ||
|         // toName: '刘烨',
 | ||
|         // type: '0',
 | ||
|         // seq: '12659'
 | ||
| 
 | ||
|       }
 | ||
|     },
 | ||
|     computed: {
 | ||
|       ...mapState(['user']),
 | ||
|     },
 | ||
|     created () {
 | ||
|       this.isLoading = true
 | ||
|       if (this.params && this.params.userId) {
 | ||
|         this.listInfo = {...this.params}
 | ||
|         this.id = this.params.userId
 | ||
|         this.searchName = this.listInfo.toName
 | ||
|         this.tabIndex = this.listInfo.type
 | ||
|         this.getList()
 | ||
|       }
 | ||
| 
 | ||
|       // this.listInfo = {
 | ||
|       //   userId: 'ChenChen',
 | ||
|       //   toUserId: 'LiuYe',
 | ||
|       //   toName: '刘烨',
 | ||
|       //   type: '0',
 | ||
|       //   seq: '12481'
 | ||
|       // }
 | ||
|       // this.searchName = this.listInfo.toName
 | ||
|       // this.id = this.listInfo.userId
 | ||
|       // this.tabIndex = this.listInfo.type
 | ||
|       // this.getList()
 | ||
| 
 | ||
|     },
 | ||
| 
 | ||
|     methods: {
 | ||
|       msgScroll(e) {
 | ||
|         if(e.target.offsetHeight + e.target.scrollTop == e.target.scrollHeight && this.msgPreCurrent > 1) { //往下拉加载上一页
 | ||
|           this.msgPreCurrent --
 | ||
|           this.getMsgListPre()
 | ||
|         }
 | ||
|         if(e.target.scrollTop == 0) {
 | ||
|           if(this.msgCurrent > this.msgPages) {
 | ||
|             return this.$message('已加载完成,没有更多数据');
 | ||
|           }else {
 | ||
|             this.msgCurrent ++
 | ||
|             this.isLoading = true
 | ||
|             this.getMsgList()
 | ||
|           }
 | ||
|         }
 | ||
|       },
 | ||
|       getListInit() {
 | ||
|         this.isLoading = true
 | ||
|         this.current = 1
 | ||
|         this.leftActiveIndex = 0
 | ||
|         this.getList()
 | ||
|       },
 | ||
|       getList () {
 | ||
|         this.instance.post(`/app/appsessionarchiveindex/list`, null, {
 | ||
|           params: {
 | ||
|             userId: this.id,
 | ||
|             type: this.tabIndex,
 | ||
|             size: 20,
 | ||
|             current: this.current,
 | ||
|             toUserName: this.tabIndex == 1 ? '' : this.searchName,
 | ||
|             roomName: this.tabIndex == 1 ? this.searchName : '',
 | ||
|           }
 | ||
|         }).then(res => {
 | ||
|           if (res.code === 0) {
 | ||
|             this.list = res.data.records
 | ||
|             this.total = res.data.total || 0
 | ||
|             // this.getMsgList()
 | ||
|             this.getKeyWordList()
 | ||
|           }
 | ||
|           this.isLoading = false
 | ||
|         }).catch(() => {
 | ||
|           this.isLoading = false
 | ||
|         })
 | ||
|       },
 | ||
|       getMsgListInit() {
 | ||
|         this.isLoading = true
 | ||
|         this.msgCurrent = 1
 | ||
|         this.msgPages = 2
 | ||
|         this.getMsgList()
 | ||
|       },
 | ||
|       getKeyWordList() {
 | ||
|         var url = this.listInfo.seq ? `/app/appsessionarchiveinfo/listByKeywordRecord?seq=${this.listInfo.seq}`
 | ||
|                   : `/app/appsessionarchiveinfo/listByKeywordRecord?msgId=${this.params.msgId}`
 | ||
|         this.instance.post(url, null, {
 | ||
|           params: {
 | ||
|             userId: this.id,
 | ||
|             type: this.tabIndex,
 | ||
|             size: 8,
 | ||
|             current: this.msgCurrent == 0 ? '' : this.msgCurrent,
 | ||
|             msgType: this.msgTypeList[this.msgType].value,
 | ||
|             // msgType: 'webapp',
 | ||
|             toUserId: this.list[this.leftActiveIndex].type == 1 ? '' : this.list[this.leftActiveIndex].toUserId,
 | ||
|             roomId: this.list[this.leftActiveIndex].type == 1 ? this.list[this.leftActiveIndex].roomId : '',
 | ||
|             content: this.searchMsg,
 | ||
|             startTime: this.time ? this.time[0] : '',
 | ||
|             endTime: this.time ? this.time[1] : '',
 | ||
|             // seq: this.listInfo.seq,
 | ||
|             // msgId: !this.listInfo.seq ?  this.params.msgId : ''
 | ||
|           }
 | ||
|         }).then(res => {
 | ||
|           if (res.code === 0) {
 | ||
|             this.msgCurrent = res.data.current
 | ||
|             this.msgPreCurrent = res.data.current
 | ||
|             res.data.records.map((item, index) => {
 | ||
|               if(item.msgType == 'file') {
 | ||
|                 item.files = [{url: item.sdkFileUrl, accessUrl: item.sdkFileUrl, name: item.sdkFileName, fileSizeStr: item.fileSizeStr}]
 | ||
|               }
 | ||
|               // if(item.msgType == 'location') {
 | ||
|               //   this.initMap(item.lng, item.lat, item.zoom, index)
 | ||
|               // }
 | ||
|             })
 | ||
|             this.msgList = res.data.records
 | ||
|             this.msgList.map((item, index) => {
 | ||
|               if (item.msgType == "location") {
 | ||
|                 item.mapId = `map${index}`
 | ||
|                 this.initMap(item.lng, item.lat, item.zoom, item.mapId);
 | ||
|               }
 | ||
|             })
 | ||
|             this.msgPages = res.data.pages || 2
 | ||
|             this.$nextTick(() => {
 | ||
|               var height = document.querySelector('.content-right-info').scrollHeight
 | ||
|               document.querySelector('.content-right-info').scrollTop = height
 | ||
|             })
 | ||
|           }
 | ||
|           this.isLoading = false
 | ||
|         }).catch(() => {
 | ||
|           this.isLoading = false
 | ||
|         })
 | ||
|       },
 | ||
|       getMsgList() {
 | ||
|         var preveHeight = document.querySelector('.content-right-info').scrollHeight
 | ||
|         this.instance.post(`/app/appsessionarchiveinfo/list`, null, {
 | ||
|           params: {
 | ||
|             userId: this.id,
 | ||
|             type: this.tabIndex,
 | ||
|             size: 8,
 | ||
|             current: this.msgCurrent,
 | ||
|             msgType: this.msgTypeList[this.msgType].value,
 | ||
|             // msgType: 'file',
 | ||
|             toUserId: this.list[this.leftActiveIndex].type == 1 ? '' : this.list[this.leftActiveIndex].toUserId,
 | ||
|             roomId: this.list[this.leftActiveIndex].type == 1 ? this.list[this.leftActiveIndex].roomId : '',
 | ||
|             type: this.list[this.leftActiveIndex].type,
 | ||
|             content: this.searchMsg,
 | ||
|             startTime: this.time ? this.time[0] : '',
 | ||
|             endTime: this.time ? this.time[1] : '',
 | ||
|             msgId: this.params.msgId
 | ||
|           }
 | ||
|         }).then(res => {
 | ||
|           if (res.code === 0) {
 | ||
|             res.data.records.map((item, index) => {
 | ||
|               if(item.msgType == 'file') {
 | ||
|                 item.files = [{url: item.sdkFileUrl, accessUrl: item.sdkFileUrl, name: item.sdkFileName, fileSizeStr: item.fileSizeStr}]
 | ||
|               }
 | ||
|               // if(item.msgType == 'location') {
 | ||
|               //   this.initMap(item.lng, item.lat, item.zoom, index)
 | ||
|               // }
 | ||
|               if (item.msgType == "image") {
 | ||
|                 var image = new Image();
 | ||
|                 image.crossOrigin = '';
 | ||
|                 image.src = item.sdkFileUrl
 | ||
|                 image.onload = ()=>{
 | ||
|                   this.$set(this.msgList[index], 'src', this.getBase64Image(image))
 | ||
|                 }
 | ||
|               }
 | ||
|             })
 | ||
|             this.msgList = this.msgCurrent > 1 ? [ ...res.data.records, ...this.msgList]: res.data.records
 | ||
|             this.msgList.map((item, index) => {
 | ||
|               if (item.msgType == "location") {
 | ||
|                 item.mapId = `map${index}`
 | ||
|                 this.initMap(item.lng, item.lat, item.zoom, item.mapId);
 | ||
|               }
 | ||
|             })
 | ||
|             this.msgPages = res.data.pages || 2
 | ||
|             this.$nextTick(() => {
 | ||
|               if(this.msgCurrent == 1) {
 | ||
|                 document.querySelector('.content-right-info').scrollTo(0, 999999999)
 | ||
|               }else {
 | ||
|                 var height = document.querySelector('.content-right-info').scrollHeight - preveHeight
 | ||
|                 document.querySelector('.content-right-info').scrollTop = height
 | ||
|               }
 | ||
| 
 | ||
|             })
 | ||
| 
 | ||
|           }
 | ||
|           this.isLoading = false
 | ||
|         }).catch(() => {
 | ||
|           this.isLoading = false
 | ||
|         })
 | ||
|       },
 | ||
|       getBase64Image(img) {
 | ||
|         var canvas = document.createElement("canvas");
 | ||
|         canvas.width = img.width;
 | ||
|         canvas.height = img.height;
 | ||
| 
 | ||
|         var ctx = canvas.getContext("2d");
 | ||
|         ctx.drawImage(img, 0, 0, img.width, img.height);
 | ||
|         var ext = img.src.substring(img.src.lastIndexOf(".")+1).toLowerCase();
 | ||
|         var dataURL = canvas.toDataURL("image/"+ext);
 | ||
|         return dataURL;
 | ||
|       },
 | ||
|       getMsgListPre() { //下拉加载上一页
 | ||
|         this.instance.post(`/app/appsessionarchiveinfo/list`, null, {
 | ||
|           params: {
 | ||
|             userId: this.id,
 | ||
|             type: this.tabIndex,
 | ||
|             size: 8,
 | ||
|             current: this.msgPreCurrent,
 | ||
|             msgType: this.msgTypeList[this.msgType].value,
 | ||
|             // msgType: 'file',
 | ||
|             toUserId: this.list[this.leftActiveIndex].type == 1 ? '' : this.list[this.leftActiveIndex].toUserId,
 | ||
|             roomId: this.list[this.leftActiveIndex].type == 1 ? this.list[this.leftActiveIndex].roomId : '',
 | ||
|             type: this.list[this.leftActiveIndex].type,
 | ||
|             content: this.searchMsg,
 | ||
|             startTime: this.time ? this.time[0] : '',
 | ||
|             endTime: this.time ? this.time[1] : ''
 | ||
|           }
 | ||
|         }).then(res => {
 | ||
|           if (res.code === 0) {
 | ||
|             res.data.records.map((item, index) => {
 | ||
|               if(item.msgType == 'file') {
 | ||
|                 item.files = [{url: item.sdkFileUrl, accessUrl: item.sdkFileUrl, name: item.sdkFileName, fileSizeStr: item.fileSizeStr}]
 | ||
|               }
 | ||
|               // if(item.msgType == 'location') {
 | ||
|               //   this.initMap(item.lng, item.lat, item.zoom, index)
 | ||
|               // }
 | ||
|             })
 | ||
|             this.msgList = [...this.msgList, ...res.data.records]
 | ||
|             this.msgList.map((item, index) => {
 | ||
|               if (item.msgType == "location") {
 | ||
|                 item.mapId = `map${index}`
 | ||
|                 this.initMap(item.lng, item.lat, item.zoom, item.mapId);
 | ||
|               }
 | ||
|             })
 | ||
|             this.msgPages = res.data.pages || 2
 | ||
|             this.$nextTick(() => {
 | ||
|               if(this.msgCurrent == 1) {
 | ||
|                 document.querySelector('.content-right-info').scrollTo(0, 999999999)
 | ||
|               }else {
 | ||
|                 var height = document.querySelector('.content-right-info').scrollHeight - preveHeight
 | ||
|                 document.querySelector('.content-right-info').scrollTop = height
 | ||
|               }
 | ||
| 
 | ||
|             })
 | ||
|           }
 | ||
|           this.isLoading = false
 | ||
|         }).catch(() => {
 | ||
|           this.isLoading = false
 | ||
|         })
 | ||
|       },
 | ||
|       initMap(lng, lat, zoom, mapId) {
 | ||
|         AMapLoader.load({
 | ||
|           key: '54a02a43d9828a8f9cd4f26fe281e74e',
 | ||
|           version: '2.0',
 | ||
|         }).then((AMap) => {
 | ||
|           this.map = new AMap.Map(`${mapId}`, {
 | ||
|             resizeEnable: true,
 | ||
|             zooms: [6, 20],
 | ||
|             center: [lng, lat],
 | ||
|             zoom: zoom,
 | ||
|             scrollWheel: false,
 | ||
|           })
 | ||
|         })
 | ||
|       },
 | ||
|       typeClick(index) {
 | ||
|         this.tabIndex = index
 | ||
|         this.msgType = 0
 | ||
|         this.getListInit()
 | ||
|       },
 | ||
|       onChange() {
 | ||
|         this.getMsgListInit()
 | ||
|       },
 | ||
|       currentChange(e) {
 | ||
|         this.current = e
 | ||
|         this.getList()
 | ||
|       },
 | ||
|       msgCurrentChange(e) {
 | ||
|         this.msgCurrent = e
 | ||
|         this.getMsgList()
 | ||
|       },
 | ||
|       leftClick(index) {
 | ||
|         this.leftActiveIndex = index
 | ||
|         this.msgType = 0
 | ||
|         this.getMsgListInit()
 | ||
|       },
 | ||
|       msgTypeClick(index) {
 | ||
|         this.msgType = index
 | ||
|         this.getMsgListInit()
 | ||
|       },
 | ||
|       openLink(row) {
 | ||
|         document.write('<a href="" target="new"></a>');
 | ||
|         window.open(row.linkUrl, "new");
 | ||
|       },
 | ||
|       cancel () {
 | ||
|         this.$emit('change', {
 | ||
|           type: 'List',
 | ||
|           isRefresh: true
 | ||
|         })
 | ||
|       },
 | ||
|       handleExport() {
 | ||
|         var fileName =
 | ||
|           this.tabIndex == 1
 | ||
|             ? this.list[this.leftActiveIndex].roomName
 | ||
|             : this.list[this.leftActiveIndex].toUserName;
 | ||
|         PdfLoader(this.$refs.pdf, fileName);
 | ||
|       },
 | ||
|     }
 | ||
|   }
 | ||
| </script>
 | ||
| 
 | ||
| <style scoped lang="scss">
 | ||
|   .detail {
 | ||
|     .addressBook-left {
 | ||
|       width: 100%;
 | ||
|       height: auto;
 | ||
|       background: #FAFAFB;
 | ||
|       position: relative;
 | ||
| 
 | ||
|       .addressBook-left__title {
 | ||
|         display: flex;
 | ||
|         align-items: center;
 | ||
|         width: 100%;
 | ||
|         height: 40px;
 | ||
|         background: #ffffff;
 | ||
| 
 | ||
|         h2 {
 | ||
|           flex: 1;
 | ||
|           height: 100%;
 | ||
|           line-height: 40px;
 | ||
|           color: #222;
 | ||
|           font-size: 14px;
 | ||
|           text-align: center;
 | ||
|           cursor: pointer;
 | ||
|           border-bottom: 2px solid transparent;
 | ||
| 
 | ||
|           &.tab-active {
 | ||
|             color: #2266FF;
 | ||
|             border-bottom: 2px solid #2266FF;
 | ||
|           }
 | ||
|         }
 | ||
|       }
 | ||
| 
 | ||
|       .addressBook-left__list--wrapper {
 | ||
|         height: calc(100% - 110px);
 | ||
|         padding: 8px;
 | ||
|         width: 100%;
 | ||
|         box-sizing: border-box;
 | ||
|         overflow-y: scroll;
 | ||
|         .addressBook-left__list--item {
 | ||
|           width: 100%;
 | ||
|           line-height: 44px;
 | ||
|           font-size: 16px;
 | ||
|           color: #333;
 | ||
|           margin-bottom: 8px;
 | ||
|           padding: 8px;
 | ||
|           display: flex;
 | ||
|           justify-content: space-between;
 | ||
|           cursor: pointer;
 | ||
|           img {
 | ||
|             width: 44px;
 | ||
|             height: 44px;
 | ||
|             border-radius: 50%;
 | ||
|             margin-right: 8px;
 | ||
|             vertical-align: middle;
 | ||
|           }
 | ||
|           .flex-left {
 | ||
|             padding-right: 8px;
 | ||
|             box-sizing: border-box;
 | ||
|           }
 | ||
|           .flex-right {
 | ||
|             font-size: 12px;
 | ||
|             margin-top: 8px;
 | ||
|             border-radius: 4px;
 | ||
|             width: 56px;
 | ||
|             height: 28px;
 | ||
|             line-height: 28px;
 | ||
|             text-align: center;
 | ||
|             border-radius: 4px;
 | ||
|           }
 | ||
|           .type1 {
 | ||
|             background-color: #EAF4FF;
 | ||
|             color: #267EF0;
 | ||
|           }
 | ||
|           .type2 {
 | ||
|             background-color: #FDEEE1;
 | ||
|             color: #FB7D29;
 | ||
|           }
 | ||
|         }
 | ||
|         .addressBook-left__list--item:hover {
 | ||
|           background-color: #E8EFFF;
 | ||
|         }
 | ||
|         .active {
 | ||
|           background-color: #E8EFFF;
 | ||
|           color: #26f;
 | ||
|         }
 | ||
|       }
 | ||
|       .addressBook-left__list--title {
 | ||
|         display: flex;
 | ||
|         align-items: center;
 | ||
|         margin: 8px 8px 0;
 | ||
| 
 | ||
|         .addressBook-left__list--search {
 | ||
|           flex: 1;
 | ||
| 
 | ||
|           :deep( input ){
 | ||
|             width: 100%;
 | ||
|           }
 | ||
|         }
 | ||
| 
 | ||
|         .el-button {
 | ||
|           width: 84px;
 | ||
|           flex-shrink: 1;
 | ||
|           margin-right: 8px;
 | ||
|         }
 | ||
|       }
 | ||
|       .pagination {
 | ||
|         position: absolute;
 | ||
|         bottom: 0;
 | ||
|         width: 100%;
 | ||
|         text-align: center;
 | ||
|         background-color: #fff;
 | ||
|       }
 | ||
|     }
 | ||
| 
 | ||
|     :deep( .ai-list__content--right ){
 | ||
|       flex: 1;
 | ||
|       min-width: 0;
 | ||
|       margin-left: 1px;
 | ||
|       box-shadow: none;
 | ||
| 
 | ||
|       .ai-list__content--right-wrapper {
 | ||
|         width: 100%;
 | ||
|         position: relative;
 | ||
|         padding: 0!important;
 | ||
|         height: 100%;
 | ||
|       }
 | ||
|     }
 | ||
| 
 | ||
|     .content-right-title {
 | ||
|       height: 40px;
 | ||
|       border-bottom: 1px solid #ddd;
 | ||
|       display: flex;
 | ||
|       justify-content: space-between;
 | ||
|       box-sizing: content-box;
 | ||
|       .tab-content {
 | ||
|         display: flex;
 | ||
|         align-items: center;
 | ||
|         width: 300px;
 | ||
|         height: 40px;
 | ||
|         background: #ffffff;
 | ||
| 
 | ||
|         h2 {
 | ||
|           flex: 1;
 | ||
|           height: 100%;
 | ||
|           line-height: 40px;
 | ||
|           color: #222;
 | ||
|           font-size: 14px;
 | ||
|           text-align: center;
 | ||
|           cursor: pointer;
 | ||
|           border-bottom: 2px solid transparent;
 | ||
| 
 | ||
|           &.tab-active {
 | ||
|             color: #2266FF;
 | ||
|             border-bottom: 2px solid #2266FF;
 | ||
|           }
 | ||
|         }
 | ||
|       }
 | ||
|       .search-content {
 | ||
|         display: flex;
 | ||
|         padding: 4px 8px 4px 0;
 | ||
|         .ai-download,
 | ||
|         .el-input {
 | ||
|           margin-left: 8px;
 | ||
|         }
 | ||
|         .el-input {
 | ||
|           width: 240px;
 | ||
|         }
 | ||
|         .el-date-editor--daterange {
 | ||
|           width: 240px;
 | ||
|         }
 | ||
|         :deep .el-date-editor .el-range-separator {
 | ||
|           width: 30px;
 | ||
|         }
 | ||
|       }
 | ||
|     }
 | ||
|     .content-right-info {
 | ||
|       padding: 24px 16px;
 | ||
|       height: calc(100% - 80px);
 | ||
|       overflow-y: scroll;
 | ||
|       .item {
 | ||
|         margin-bottom: 48px;
 | ||
|         .user-name {
 | ||
|           color: #666;
 | ||
|           font-size: 12px;
 | ||
|           line-height: 20px;
 | ||
|           padding:0 0 0 64px;
 | ||
|           span {
 | ||
|             display: inline-block;
 | ||
|             margin: 0 12px;
 | ||
|             color: #999;
 | ||
|           }
 | ||
|         }
 | ||
|         .item-content-flex {
 | ||
|           display: flex;
 | ||
|           .user-img {
 | ||
|             width: 44px;
 | ||
|             height: 44px;
 | ||
|             border-radius: 50%;
 | ||
|             margin-right: 8px;
 | ||
|           }
 | ||
|           .content {
 | ||
|             max-width: calc(100% - 144px);
 | ||
|             position: relative;
 | ||
|             background-color: #f3f6f9;
 | ||
| 
 | ||
|             span {
 | ||
|               width: 0px;
 | ||
|               height: 0px;
 | ||
|               border: 10px solid transparent;
 | ||
|               position: absolute;
 | ||
|               top: 50%;
 | ||
|               margin-top: -10px;
 | ||
|             }
 | ||
|             p {
 | ||
|               display: inline-block;
 | ||
|               padding: 8px;
 | ||
|               line-height: 28px;
 | ||
|               font-family: PingFangSC-Regular;
 | ||
|               font-size: 16px;
 | ||
|               color: #333;
 | ||
|               word-break: break-all;
 | ||
|             }
 | ||
|           }
 | ||
|           .img-list {
 | ||
|             img {
 | ||
|               max-width: 400px;
 | ||
|             }
 | ||
|           }
 | ||
|           .voice-info {
 | ||
|             .ai-audio {
 | ||
|               margin-top: 8px;
 | ||
|             }
 | ||
|           }
 | ||
|           .el-icon-warning {
 | ||
|             font-size: 32px;
 | ||
|             color: #f46;
 | ||
|             margin-top: 8px;
 | ||
|           }
 | ||
|           .revoke-text {
 | ||
|             line-height: 44px;
 | ||
|             padding: 0 6px;
 | ||
|             border-radius: 4px;
 | ||
|             background-color: #EEE;
 | ||
|             color: #999;
 | ||
|             margin-top: 4px;
 | ||
|           }
 | ||
|           .card-info {
 | ||
|             width: 300px;
 | ||
|             position: relative;
 | ||
|             border-radius: 8px;
 | ||
|             background-color: #fff;
 | ||
|             border: 1px solid #eee;
 | ||
| 
 | ||
|             .top {
 | ||
|               display: flex;
 | ||
|               padding: 16px;
 | ||
|               .card-left {
 | ||
|                 width: calc(100% - 60px);
 | ||
|                 h3 {
 | ||
|                   line-height: 60px;
 | ||
|                   font-size: 22px;
 | ||
|                   color: #333;
 | ||
|                   margin-bottom: 10px;
 | ||
|                 }
 | ||
|                 p {
 | ||
|                   color: #000;
 | ||
|                   line-height: 24px;
 | ||
|                   font-size: 16px;
 | ||
|                 }
 | ||
|                 div {
 | ||
|                   color: #666;
 | ||
|                   font-size: 14px;
 | ||
|                   line-height: 24px;
 | ||
|                 }
 | ||
|               }
 | ||
|               .card-right {
 | ||
|                 img {
 | ||
|                   width: 50px;
 | ||
|                   height: 50px;
 | ||
|                   border-radius: 4px;
 | ||
|                 }
 | ||
|               }
 | ||
|             }
 | ||
|             .bottom {
 | ||
|               padding-left: 16px;
 | ||
|               line-height: 44px;
 | ||
|               font-size: 16px;
 | ||
|               color: #666;
 | ||
|               border-top: 1px solid #eee;
 | ||
|               img {
 | ||
|                 width: 16px;
 | ||
|                 height: 16px;
 | ||
|                 margin-right: 8px;
 | ||
|               }
 | ||
|             }
 | ||
|           }
 | ||
|           .pointer {
 | ||
|             cursor: pointer;
 | ||
|           }
 | ||
|           .map-info {
 | ||
|             width: 600px;
 | ||
|             height: 400px;
 | ||
|             position: relative;
 | ||
|             .map-content {
 | ||
|               width: 600px;
 | ||
|               height: 400px;
 | ||
|             }
 | ||
|             .address-text {
 | ||
|               position: absolute;
 | ||
|               bottom: 0;
 | ||
|               left: 0;
 | ||
|               z-index: 9999;
 | ||
|               width: 600px;
 | ||
|               background-color: rgba(0, 0, 0, .7);
 | ||
|               p {
 | ||
|                 color: #fff;
 | ||
|                 line-height: 34px;
 | ||
|                 font-size: 16px;
 | ||
|                 padding-left: 16px;
 | ||
|                 word-break: break-all;
 | ||
|               }
 | ||
|             }
 | ||
|           }
 | ||
|         }
 | ||
|       }
 | ||
|       .item-left {
 | ||
|         .item-content-flex {
 | ||
|           .user-img {
 | ||
|             margin: 0 20px 0 0;
 | ||
|           }
 | ||
|           .content {
 | ||
|             span {
 | ||
|               left: -18px;
 | ||
|               border-right-color: #f3f6f9;
 | ||
|             }
 | ||
|           }
 | ||
|           .el-icon-warning {
 | ||
|             margin-left: 16px;
 | ||
|           }
 | ||
|         }
 | ||
| 
 | ||
|       }
 | ||
|       .item-right {
 | ||
|         width: 100%;
 | ||
|         justify-content: right;
 | ||
|         .user-name {
 | ||
|           text-align: right;
 | ||
|           padding: 0 52px 0 0;
 | ||
|         }
 | ||
|         .item-content-flex {
 | ||
|           justify-content: end;
 | ||
|           .user-img {
 | ||
|             margin: 0 0 0 20px;
 | ||
|           }
 | ||
|           .content {
 | ||
|             background-color: #90e287;
 | ||
|             span {
 | ||
|               border-left-color:#90e287;
 | ||
|               right: -18px;
 | ||
|             }
 | ||
|           }
 | ||
|           .el-icon-warning {
 | ||
|             margin-right: 16px;
 | ||
|           }
 | ||
|           .voice-info {
 | ||
|             text-align: right;
 | ||
|           }
 | ||
|         }
 | ||
| 
 | ||
|       }
 | ||
|     }
 | ||
|     .addressBook-left__list--wrapper::-webkit-scrollbar,
 | ||
|     .content-right-info::-webkit-scrollbar {
 | ||
|       width: 4px;
 | ||
|     }
 | ||
|     .addressBook-left__list--wrapper::-webkit-scrollbar-thumb,
 | ||
|     .content-right-info::-webkit-scrollbar-thumb {
 | ||
|       border-radius: 10px;
 | ||
|       background: rgba(0,0,0,0.2);
 | ||
|     }
 | ||
|     .addressBook-left__list--wrapper::-webkit-scrollbar-track
 | ||
|     .content-right-info::-webkit-scrollbar-track {
 | ||
|       border-radius: 0;
 | ||
|       background: rgba(0,0,0,0.1);
 | ||
|     }
 | ||
|     .msg-list-pagination {
 | ||
|       position: absolute;
 | ||
|       bottom: 0;
 | ||
|       width: calc(100% - 32px);
 | ||
|       text-align: center;
 | ||
|     }
 | ||
|   }
 | ||
| 
 | ||
| </style>
 |