1094 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			1094 lines
		
	
	
		
			31 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="item.roomAvatar ? item.roomAvatar : 'https://cdn.cunwuyun.cn/dvcp/group-img.png'" alt="">
 | ||
|               <p>{{ item.roomName }}</p>
 | ||
|             </div>
 | ||
|             <div v-else class="flex-left">
 | ||
|               <img :src="item.toUserAvatar" alt="" />
 | ||
|               <p>{{ item.toUserName }}</p>
 | ||
|             </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"></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"></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 Viewer from "v-viewer";
 | ||
| import AMapLoader from "@amap/amap-jsapi-loader";
 | ||
| import Vue from "vue";
 | ||
| Vue.use(Viewer);
 | ||
| 
 | ||
| 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: 1,
 | ||
|       msgTotal: 0,
 | ||
|       msgPages: 2,
 | ||
|       msgList: [],
 | ||
|       msgType: 0,
 | ||
|       msgTypeList: [
 | ||
|         { name: "全部", value: "" },
 | ||
|         { name: "图片/视频", value: "imagevideo" },
 | ||
|         { name: "语音", value: "voice" },
 | ||
|         { name: "文件", value: "file" },
 | ||
|       ],
 | ||
|       searchMsg: "",
 | ||
|       id: "", //YangFei
 | ||
|     };
 | ||
|   },
 | ||
|   computed: {
 | ||
|     ...mapState(["user"]),
 | ||
|   },
 | ||
|   created() {
 | ||
|     this.isLoading = true;
 | ||
|     if (this.params && this.params.id) {
 | ||
|       this.id = this.params.id;
 | ||
|       this.getList();
 | ||
|     }
 | ||
|   },
 | ||
| 
 | ||
|   methods: {
 | ||
|     msgScroll(e) {
 | ||
|       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/listForXbot`, 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.getMsgListInit();
 | ||
|           }
 | ||
|           this.isLoading = false;
 | ||
|         })
 | ||
|         .catch(() => {
 | ||
|           this.isLoading = false;
 | ||
|         });
 | ||
|     },
 | ||
|     getMsgListInit() {
 | ||
|       this.isLoading = true;
 | ||
|       this.msgCurrent = 1;
 | ||
|       this.msgPages = 2;
 | ||
|       this.getMsgList();
 | ||
|     },
 | ||
|     getMsgList() {
 | ||
|       var preveHeight = document.querySelector(
 | ||
|         ".content-right-info"
 | ||
|       ).scrollHeight;
 | ||
|       this.instance
 | ||
|         .post(`/app/appsessionarchiveinfo/listForXbot`, null, {
 | ||
|           params: {
 | ||
|             userId: this.id,
 | ||
|             type: this.tabIndex,
 | ||
|             size: 8,
 | ||
|             current: this.msgCurrent,
 | ||
|             msgType: this.msgTypeList[this.msgType].value,
 | ||
|             // msgType: 'weapp',
 | ||
|             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] : "",
 | ||
|           },
 | ||
|         })
 | ||
|         .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 == "image") {
 | ||
|                 var image = new Image();
 | ||
|                 image.crossOrigin = '';
 | ||
|                 image.src = item.sdkFileUrl
 | ||
|                 image.onload = ()=>{
 | ||
|                   this.$set(this.msgList[index], 'src', this.getBase64Image(image))
 | ||
|                   // item.src = this.getBase64Image(image);
 | ||
|                   // console.log(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.$forceUpdate()
 | ||
|           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;
 | ||
|     },
 | ||
|     
 | ||
|     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");
 | ||
|     },
 | ||
|     handleExport() {
 | ||
|       var fileName =
 | ||
|         this.tabIndex == 1
 | ||
|           ? this.list[this.leftActiveIndex].roomName
 | ||
|           : this.list[this.leftActiveIndex].toUserName;
 | ||
|       PdfLoader(this.$refs.pdf, fileName);
 | ||
|     },
 | ||
|     cancel() {
 | ||
|       this.$emit("change", {
 | ||
|         type: "List",
 | ||
|         isRefresh: true,
 | ||
|       });
 | ||
|     },
 | ||
|   },
 | ||
| };
 | ||
| </script>
 | ||
| 
 | ||
| <style scoped lang="scss">
 | ||
| .detail {
 | ||
|   .addressBook-left {
 | ||
|     width: 300px;
 | ||
|     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: top;
 | ||
|         }
 | ||
|         .flex-left {
 | ||
|           padding-right: 8px;
 | ||
|           box-sizing: border-box;
 | ||
|           width: calc(100% - 56px);
 | ||
|           p {
 | ||
|             display: inline-block;
 | ||
|             width: calc(100% - 52px);
 | ||
|             overflow: hidden;
 | ||
|             white-space: nowrap;
 | ||
|             text-overflow: ellipsis;
 | ||
|           }
 | ||
|         }
 | ||
|         .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, 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>
 |