545 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			545 lines
		
	
	
		
			15 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="请输入联系人姓名"
 | |
|             v-model="searchName"
 | |
|             clearable
 | |
|             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">
 | |
|               <img src="./img/group-img.png" alt="">{{item.roomName}}
 | |
|             </div>
 | |
|             <div v-else>
 | |
|               <img :src="item.toUserAvatar" alt="">{{item.toUserName}}
 | |
|             </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> -->
 | |
|         </div>
 | |
|       </div>
 | |
|       <div class="content-right-info">
 | |
|         <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">
 | |
|               <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}}{{item.msgSendTime.substring(0, 16)}}撤回了一条消息</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>
 | |
|         <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 Vue from 'vue'
 | |
|   Vue.use(Viewer);
 | |
|   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,
 | |
|         msgList: [],
 | |
|         msgType: 0,
 | |
|         msgTypeList: [
 | |
|           {name: '全部', value: ''},
 | |
|           {name: '图片/视频', value: 'imagevideo'},
 | |
|           {name: '语音', value: 'voice'},
 | |
|           {name: '文件', value: 'file'},
 | |
|         ],
 | |
|         searchMsg: '',
 | |
|         id: ''
 | |
|       }
 | |
|     },
 | |
|     computed: {
 | |
|       ...mapState(['user']),
 | |
|     },
 | |
|     created () {
 | |
|       this.isLoading = true
 | |
|       if (this.params && this.params.id) {
 | |
|         this.id = this.params.id
 | |
|         this.getList()
 | |
|       }
 | |
|       // this.getList()
 | |
|     },
 | |
| 
 | |
|     methods: {
 | |
|       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.getMsgListInit()
 | |
|           }
 | |
|           this.isLoading = false
 | |
|         }).catch(() => {
 | |
|           this.isLoading = false
 | |
|         })
 | |
|       },
 | |
|       getMsgListInit() {
 | |
|         this.isLoading = true
 | |
|         this.msgCurrent = 1
 | |
|         this.getMsgList()
 | |
|       },
 | |
|       getMsgList() {
 | |
|         this.instance.post(`/app/appsessionarchiveinfo/list`, null, {
 | |
|           params: {
 | |
|             userId: this.id,
 | |
|             type: this.tabIndex,
 | |
|             size: 20,
 | |
|             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] : ''
 | |
|           }
 | |
|         }).then(res => {
 | |
|           if (res.code === 0) {
 | |
|             res.data.records.map((item) => {
 | |
|               if(item.msgType == 'file') {
 | |
|                 item.files = [{url: item.sdkFileUrl, accessUrl: item.sdkFileUrl, name: item.sdkFileName, fileSizeStr: item.fileSizeStr}]
 | |
|               }
 | |
|             })
 | |
|             this.msgList = res.data.records
 | |
|             this.msgTotal = res.data.total || 0
 | |
|           }
 | |
|           this.isLoading = false
 | |
|         }).catch(() => {
 | |
|           this.isLoading = false
 | |
|         })
 | |
|       },
 | |
|       typeClick(index) {
 | |
|         this.tabIndex = index
 | |
|         this.msgType = 0
 | |
|         this.getListInit()
 | |
|       },
 | |
|       onChange() {
 | |
|         this.getMsgListInit()
 | |
|       },
 | |
|       currentChange(e) {
 | |
|         console.log(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()
 | |
|       },
 | |
|       cancel () {
 | |
|         this.$emit('change', {
 | |
|           type: 'List',
 | |
|           isRefresh: true
 | |
|         })
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| </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;
 | |
|         overflow-y: scroll;
 | |
|         .addressBook-left__list--item {
 | |
|           line-height: 44px;
 | |
|           font-size: 16px;
 | |
|           color: #333;
 | |
|           margin-bottom: 8px;
 | |
|           padding: 8px;
 | |
|           cursor: pointer;
 | |
|           img {
 | |
|             width: 44px;
 | |
|             height: 44px;
 | |
|             border-radius: 50%;
 | |
|             margin-right: 8px;
 | |
|             vertical-align: middle;
 | |
|           }
 | |
|         }
 | |
|         .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 {
 | |
|               width: 200px;
 | |
|               height: 200px;
 | |
|             }
 | |
|           }
 | |
|           .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;
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|       .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>
 |