Compare commits
	
		
			3 Commits
		
	
	
		
			ba52f9a576
			...
			d7c813977d
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| d7c813977d | |||
| 2642a885f0 | |||
| 026e4fa3e6 | 
| @ -45,3 +45,12 @@ export const ServeTalkDate = (data) => { | ||||
|     data, | ||||
|   }) | ||||
| } | ||||
| 
 | ||||
| //获取会话Id
 | ||||
| export const ServeGetSessionId = (data) => { | ||||
|   return request({ | ||||
|     url: '/api/v1/talk/session/getId', | ||||
|     method: 'POST', | ||||
|     data, | ||||
|   }) | ||||
| } | ||||
| @ -21,9 +21,20 @@ | ||||
| <script setup> | ||||
| import { defineProps, defineEmits, reactive, watch } from 'vue' | ||||
| const props = defineProps({ | ||||
|   searchText: String, | ||||
|   first_talk_record_infos: Object, | ||||
|   disabled: Boolean, | ||||
|   searchText: { | ||||
|     type: String, | ||||
|     default: '' | ||||
|   }, | ||||
|   first_talk_record_infos: { | ||||
|     type: Object, | ||||
|     default(){ | ||||
|       return {} | ||||
|     } | ||||
|   }, | ||||
|   disabled: { | ||||
|     type: Boolean, | ||||
|     default: false | ||||
|   }, | ||||
| }) | ||||
| const state = reactive({ | ||||
|   searchText: '', //搜索内容 | ||||
|  | ||||
| @ -25,33 +25,33 @@ const getFileTypeIMG = computed(() => { | ||||
|   let objT = { | ||||
|     finishedImg: '', | ||||
|     blankImg: '', | ||||
|     progressColor: '' | ||||
|   }; | ||||
|     progressColor: '', | ||||
|   } | ||||
| 
 | ||||
|   switch (suffix) { | ||||
|     case 'pdf': | ||||
|       objT.finishedImg = filePaperPDF | ||||
|       objT.blankImg = filePaperPDFBlank | ||||
|       objT.progressColor = '#DE4E4E' | ||||
|       break; | ||||
|       break | ||||
|     case 'doc': | ||||
|     case 'docx': | ||||
|       objT.finishedImg = filePaperWord | ||||
|       objT.blankImg = filePaperWordBlank | ||||
|       objT.progressColor = '#2750B2' | ||||
|       break; | ||||
|       break | ||||
|     case 'xls': | ||||
|     case 'xlsx': | ||||
|       objT.finishedImg = filePaperExcel | ||||
|       objT.blankImg = filePaperExcelBlank | ||||
|       objT.progressColor = '#3C7F4B' | ||||
|       break; | ||||
|       break | ||||
|     case 'ppt': | ||||
|     case 'pptx': | ||||
|       objT.finishedImg = filePaperPPT | ||||
|       objT.blankImg = filePaperPPTBlank | ||||
|       objT.progressColor = '#B74B2B' | ||||
|       break; | ||||
|       break | ||||
|     default: | ||||
|       objT.finishedImg = filePaperOther | ||||
|       objT.blankImg = filePaperOtherBlank | ||||
| @ -60,22 +60,78 @@ const getFileTypeIMG = computed(() => { | ||||
|   return objT | ||||
| }) | ||||
| 
 | ||||
| const previewPDF = () => { | ||||
|   if (typeof plus !== 'undefined') { | ||||
|     downloadAndOpenFile() | ||||
|   } else { | ||||
|     document.addEventListener('plusready', () => { | ||||
|       downloadAndOpenFile() | ||||
|     }) | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| const downloadAndOpenFile = () => { | ||||
|   uni.showLoading({ title: '加载中...', mask: true }) | ||||
|   const downloadUrl = props?.extra?.path | ||||
|   if (!downloadUrl) { | ||||
|     uni.hideLoading() | ||||
|     uni.showToast({ title: '文件路径无效', icon: 'none' }) | ||||
|     return | ||||
|   } | ||||
|   const options = { | ||||
|     filename: '_doc/downloads/', // 保存路径 | ||||
|   } | ||||
|   const dtask = plus.downloader.createDownload(downloadUrl, options, function ( | ||||
|     d, | ||||
|     status, | ||||
|   ) { | ||||
|     if (status === 200) { | ||||
|       uni.hideLoading() | ||||
|       const filePath = d.filename | ||||
|       if (filePath) { | ||||
|         plus.runtime.openFile(filePath, {}, function () {}) | ||||
|       } else { | ||||
|         uni.showToast({ title: '文件路径无效', icon: 'none' }) | ||||
|       } | ||||
|     } else { | ||||
|       uni.hideLoading() | ||||
|     } | ||||
|   }) | ||||
|   dtask.start() | ||||
| } | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|   <section | ||||
|     class="file-message" | ||||
|     @click="previewPDF" | ||||
|     :class="{ left: data.float === 'left', right: data.float === 'right' }" | ||||
|   > | ||||
|     <div class="flex justify-between"> | ||||
|       <div class="w-[228rpx] text-[32rpx] text-[#1A1A1A] h-[88rpx] leading-[44rpx] textEllipsis file_name"> | ||||
|       <div | ||||
|         class="w-[228rpx] text-[32rpx] text-[#1A1A1A] h-[88rpx] leading-[44rpx] textEllipsis file_name" | ||||
|       > | ||||
|         {{ extra.name }} | ||||
|       </div> | ||||
|       <div v-if="data.uploadStatus === 2 || !data.uploadStatus" class="w-[95rpx]"> | ||||
|         <tm-image :width="95" :height="95" :src="getFileTypeIMG.finishedImg"></tm-image> | ||||
|       <div | ||||
|         v-if="data.uploadStatus === 2 || !data.uploadStatus" | ||||
|         class="w-[95rpx]" | ||||
|       > | ||||
|         <tm-image | ||||
|           :width="95" | ||||
|           :height="95" | ||||
|           :src="getFileTypeIMG.finishedImg" | ||||
|         ></tm-image> | ||||
|       </div> | ||||
|       <div v-if="data.uploadStatus === 1 || data.uploadStatus === 3"  class="w-[95rpx]"> | ||||
|         <tm-image :width="95" :height="95" :src="getFileTypeIMG.blankImg"></tm-image> | ||||
|       <div | ||||
|         v-if="data.uploadStatus === 1 || data.uploadStatus === 3" | ||||
|         class="w-[95rpx]" | ||||
|       > | ||||
|         <tm-image | ||||
|           :width="95" | ||||
|           :height="95" | ||||
|           :src="getFileTypeIMG.blankImg" | ||||
|         ></tm-image> | ||||
|         <wd-circle | ||||
|           customClass="circleProgress" | ||||
|           :modelValue="data.uploadCurrent" | ||||
| @ -87,7 +143,9 @@ const getFileTypeIMG = computed(() => { | ||||
|       </div> | ||||
|     </div> | ||||
|     <div class="divider mt-[28rpx]"></div> | ||||
|     <div class="text-[24rpx] text-[#747474] mt-[10rpx]">{{ fileFormatSize(extra.size) }}</div> | ||||
|     <div class="text-[24rpx] text-[#747474] mt-[10rpx]"> | ||||
|       {{ fileFormatSize(extra.size) }} | ||||
|     </div> | ||||
|     <!-- <div class="main"> | ||||
|       <div class="ext">{{ getFileNameSuffix(extra.name) }}</div> | ||||
|       <div class="file-box"> | ||||
| @ -124,7 +182,7 @@ const getFileTypeIMG = computed(() => { | ||||
|     border-radius: 16rpx 0 16rpx 16rpx; | ||||
|   } | ||||
| 
 | ||||
|   .file_name{ | ||||
|   .file_name { | ||||
|     word-break: break-all; /* 在任意字符间断行 */ | ||||
|     word-wrap: break-word; /* 允许长单词换行到下一行 */ | ||||
|   } | ||||
| @ -217,7 +275,7 @@ const getFileTypeIMG = computed(() => { | ||||
| } | ||||
| 
 | ||||
| .divider { | ||||
|   background-color: #E7E7E7; | ||||
|   background-color: #e7e7e7; | ||||
|   height: 1rpx; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -379,6 +379,12 @@ const handleClickItem = (item) => { | ||||
|     } | ||||
|     return | ||||
|   } | ||||
|   if(props?.manageType === 'searchRecord'){ | ||||
|     uni.navigateTo({ | ||||
|       url: '/pages/search/searchByCondition/index?condition=member' | ||||
|     }) | ||||
|     return | ||||
|   } | ||||
|   let itemList = dialogueParams.memberList | ||||
|   if ( | ||||
|     props?.manageType === 'admin' && | ||||
|  | ||||
| @ -96,7 +96,9 @@ | ||||
|             </div> | ||||
|           </div> | ||||
|           <div class="chat-records-search chat-settings-card"> | ||||
|             <div @click="toSearchPage"> | ||||
|               <customInput :disabled="true"></customInput> | ||||
|             </div> | ||||
|             <div class="record-search-types"> | ||||
|               <div | ||||
|                 class="record-search-types-each" | ||||
| @ -151,8 +153,10 @@ | ||||
|               @click="showConfirmPrompt(2)" | ||||
|               class="clear-chat-record-btn-each" | ||||
|               v-if=" | ||||
|                 groupParams?.groupInfo?.is_manager && dialogueParams.type === 2 | ||||
|                 && (groupParams?.groupInfo?.group_type === 1 || groupParams?.groupInfo?.group_type === 3) | ||||
|                 groupParams?.groupInfo?.is_manager && | ||||
|                 dialogueParams.type === 2 && | ||||
|                 (groupParams?.groupInfo?.group_type === 1 || | ||||
|                   groupParams?.groupInfo?.group_type === 3) | ||||
|               " | ||||
|             > | ||||
|               <span class="text-[32rpx] font-regular"> | ||||
| @ -163,8 +167,10 @@ | ||||
|               @click="showConfirmPrompt(3)" | ||||
|               class="clear-chat-record-btn-each" | ||||
|               v-if=" | ||||
|                 groupParams?.groupInfo?.is_manager && dialogueParams.type === 2 | ||||
|                 && (groupParams?.groupInfo?.group_type === 1 || groupParams?.groupInfo?.group_type === 3) | ||||
|                 groupParams?.groupInfo?.is_manager && | ||||
|                 dialogueParams.type === 2 && | ||||
|                 (groupParams?.groupInfo?.group_type === 1 || | ||||
|                   groupParams?.groupInfo?.group_type === 3) | ||||
|               " | ||||
|             > | ||||
|               <span class="text-[32rpx] font-regular"> | ||||
| @ -499,10 +505,7 @@ const toSearchByConditionPage = (flag) => { | ||||
|     } | ||||
|     uni.navigateTo({ | ||||
|       url: | ||||
|         '/pages/search/searchByCondition/index?condition=' + | ||||
|         condition + | ||||
|         '&receiver_id=' + | ||||
|         state.groupId, | ||||
|         '/pages/search/searchByCondition/index?condition=' + condition | ||||
|     }) | ||||
|   } | ||||
| } | ||||
| @ -629,6 +632,21 @@ const inviteMembersInGroup = async (memberList) => { | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| //点击跳转到搜索页面 | ||||
| const toSearchPage = () => { | ||||
|   // uni.navigateTo({ | ||||
|   //   url: | ||||
|   //     '/pages/search/searchByCondition/index?condition=text' | ||||
|   // }) | ||||
|   uni.navigateTo({ | ||||
|     url: | ||||
|       '/pages/search/moreResult/moreResultDetail?talk_type=' + | ||||
|       dialogueParams.type + | ||||
|       '&receiver_id=' + | ||||
|       dialogueParams.receiver_id, | ||||
|   }) | ||||
| } | ||||
| </script> | ||||
| <style scoped lang="scss"> | ||||
| .outer-layer { | ||||
|  | ||||
| @ -1,25 +1,39 @@ | ||||
| <template> | ||||
|   <div class="emojiRoot"> | ||||
|     <div @click="()=>photoActionsSelect(0)" class="flex flex-col items-center"> | ||||
|       <div class="w-[106rpx] h-[106rpx] bg-[#F9F9F9] rounded-[60rpx] flex-center"> | ||||
|     <div | ||||
|       @click="() => photoActionsSelect(0)" | ||||
|       class="flex flex-col items-center" | ||||
|     > | ||||
|       <div | ||||
|         class="w-[106rpx] h-[106rpx] bg-[#F9F9F9] rounded-[60rpx] flex-center" | ||||
|       > | ||||
|         <tm-image :width="53" :height="44" :src="photoAlbum"></tm-image> | ||||
|       </div> | ||||
|       <div class="mt-[6rpx] text-[#666666] text-[24rpx]">照片</div> | ||||
|     </div> | ||||
|     <div @click="()=>photoActionsSelect(1)" class="flex flex-col items-center"> | ||||
|       <div class="w-[106rpx] h-[106rpx] bg-[#F9F9F9] rounded-[60rpx] flex-center"> | ||||
|     <div | ||||
|       @click="() => photoActionsSelect(1)" | ||||
|       class="flex flex-col items-center" | ||||
|     > | ||||
|       <div | ||||
|         class="w-[106rpx] h-[106rpx] bg-[#F9F9F9] rounded-[60rpx] flex-center" | ||||
|       > | ||||
|         <tm-image :width="53" :height="44" :src="videoImg"></tm-image> | ||||
|       </div> | ||||
|       <div class="mt-[6rpx] text-[#666666] text-[24rpx]">视频</div> | ||||
|     </div> | ||||
|     <div @click="takePhoto" class="flex flex-col items-center"> | ||||
|       <div class="w-[106rpx] h-[106rpx] bg-[#F9F9F9] rounded-[60rpx] flex-center"> | ||||
|       <div | ||||
|         class="w-[106rpx] h-[106rpx] bg-[#F9F9F9] rounded-[60rpx] flex-center" | ||||
|       > | ||||
|         <tm-image :width="53" :height="44" :src="photoGraph"></tm-image> | ||||
|       </div> | ||||
|       <div class="mt-[6rpx] text-[#666666] text-[24rpx]">拍摄</div> | ||||
|     </div> | ||||
|     <div @click="chooseFile" class="flex flex-col items-center"> | ||||
|       <div class="w-[106rpx] h-[106rpx] bg-[#F9F9F9] rounded-[60rpx] flex-center"> | ||||
|       <div | ||||
|         class="w-[106rpx] h-[106rpx] bg-[#F9F9F9] rounded-[60rpx] flex-center" | ||||
|       > | ||||
|         <tm-image :width="53" :height="44" :src="folder"></tm-image> | ||||
|       </div> | ||||
|       <div class="mt-[6rpx] text-[#666666] text-[24rpx]">文件</div> | ||||
| @ -27,10 +41,15 @@ | ||||
|   </div> | ||||
| </template> | ||||
| <script setup> | ||||
| import { ref, reactive, defineProps, defineEmits } from "vue" | ||||
| import dayjs from "dayjs"; | ||||
| import { ref, reactive, defineProps, defineEmits } from 'vue' | ||||
| import dayjs from 'dayjs' | ||||
| import { beautifyTime } from '@/utils/datetime' | ||||
| import { useDialogueListStore, useDialogueStore, useUserStore,useUploadsStore } from '@/store' | ||||
| import { | ||||
|   useDialogueListStore, | ||||
|   useDialogueStore, | ||||
|   useUserStore, | ||||
|   useUploadsStore, | ||||
| } from '@/store' | ||||
| import { useSessionMenu } from '@/hooks' | ||||
| import photoAlbum from '@/static/image/chatList/photoAlbum.png' | ||||
| import photoGraph from '@/static/image/chatList/photoGraph.png' | ||||
| @ -43,26 +62,34 @@ const props = defineProps({ | ||||
|   sendUserInfo: { | ||||
|     type: Object, | ||||
|     default: {}, | ||||
|     required: true | ||||
|     required: true, | ||||
|   }, | ||||
|   talkParams: { | ||||
|     type: Object, | ||||
|     default: {}, | ||||
|     required: true | ||||
|   } | ||||
| }); | ||||
|     required: true, | ||||
|   }, | ||||
| }) | ||||
| 
 | ||||
| const state = reactive({ | ||||
|   base64Url: '' | ||||
| }) | ||||
| 
 | ||||
| const uploadsStore = useUploadsStore() | ||||
| const { addDialogueRecord, virtualList, updateUploadProgress } = useDialogueListStore() | ||||
| const { | ||||
|   addDialogueRecord, | ||||
|   virtualList, | ||||
|   updateUploadProgress, | ||||
| } = useDialogueListStore() | ||||
| const dialogueStore = useDialogueStore() | ||||
| const userStore = useUserStore() | ||||
| 
 | ||||
| const emit = defineEmits(['selectImg']) | ||||
| 
 | ||||
| const onProgressFn = (progress, id) => { | ||||
|   console.log(progress.loaded / progress.total * 100, 'progress'); | ||||
|   console.log((progress.loaded / progress.total) * 100, 'progress') | ||||
| 
 | ||||
|   updateUploadProgress(id, progress.loaded / progress.total * 100) | ||||
|   updateUploadProgress(id, (progress.loaded / progress.total) * 100) | ||||
| } | ||||
| 
 | ||||
| const photoActionsSelect = (index) => { | ||||
| @ -71,28 +98,31 @@ const photoActionsSelect = (index) => { | ||||
|       sourceType: ['album'], | ||||
|       count: 9, | ||||
|       success: async (res) => { | ||||
|         console.log(res,'res'); | ||||
|         console.log(res, 'res') | ||||
|         res.tempFiles.forEach(async (file) => { | ||||
|           let data = await onUploadImageVideo(file, 'image') | ||||
|           emit('selectImg', data, data.file_num) | ||||
|         }) | ||||
|       } | ||||
|       }, | ||||
|     }) | ||||
|   }else{ | ||||
|   } else { | ||||
|     uni.chooseVideo({ | ||||
|       sourceType: ['album'], | ||||
|       success: async (res) => { | ||||
|         console.log(res,'res'); | ||||
|         let data = await onUploadImageVideo(res.tempFile, 'video',res.tempFilePath) | ||||
|         console.log(res, 'res') | ||||
|         let data = await onUploadImageVideo( | ||||
|           res.tempFile, | ||||
|           'video', | ||||
|           res.tempFilePath, | ||||
|         ) | ||||
|         emit('selectImg', data, data.file_num) | ||||
|       } | ||||
|       }, | ||||
|     }) | ||||
|   } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| const onUploadImageVideo = async (file, type = 'image',fileUrl) => { | ||||
|   console.log(file, 'file'); | ||||
| const onUploadImageVideo = async (file, type = 'image', fileUrl) => { | ||||
|   console.log(file, 'file') | ||||
|   return new Promise(async (resolve) => { | ||||
|     if (type === 'image') { | ||||
|       let image = new Image() | ||||
| @ -100,20 +130,20 @@ const onUploadImageVideo = async (file, type = 'image',fileUrl) => { | ||||
|       image.onload = () => { | ||||
|         const form = new FormData() | ||||
|         form.append('file', file) | ||||
|         form.append("source", "fonchain-chat"); | ||||
|         form.append("urlParam", `width=${image.width}&height=${image.height}`); | ||||
|         form.append('source', 'fonchain-chat') | ||||
|         form.append('urlParam', `width=${image.width}&height=${image.height}`) | ||||
|         let randomId = uniqueId() | ||||
|         let newItem = { | ||||
|           avatar: userStore.avatar, | ||||
|           created_at: dayjs().format('YYYY-MM-DD HH:mm:ss'), | ||||
|           extra: { | ||||
|             height: image.height, | ||||
|             name: "", | ||||
|             name: '', | ||||
|             size: 0, | ||||
|             url: image.src, | ||||
|             width: image.width | ||||
|             width: image.width, | ||||
|           }, | ||||
|           float: "right", | ||||
|           float: 'right', | ||||
|           isCheck: false, | ||||
|           is_mark: 0, | ||||
|           is_read: 0, | ||||
| @ -131,7 +161,8 @@ const onUploadImageVideo = async (file, type = 'image',fileUrl) => { | ||||
|         } | ||||
| 
 | ||||
|         virtualList.value.unshift(newItem) | ||||
|         uploadImg(form, (e) => onProgressFn(e, randomId)).then(({ status, data, msg }) => { | ||||
|         uploadImg(form, (e) => onProgressFn(e, randomId)).then( | ||||
|           ({ status, data, msg }) => { | ||||
|             if (status == 0) { | ||||
|               resolve({ | ||||
|                 type: 'image', | ||||
| @ -145,17 +176,18 @@ const onUploadImageVideo = async (file, type = 'image',fileUrl) => { | ||||
|               resolve('') | ||||
|               message.error(msg) | ||||
|             } | ||||
|         }) | ||||
|           }, | ||||
|         ) | ||||
|       } | ||||
|     } else { | ||||
|       uni.getVideoInfo({ | ||||
|         src:fileUrl, | ||||
|         success:(resp)=>{ | ||||
|         console.log(resp); | ||||
|         src: fileUrl, | ||||
|         success: (resp) => { | ||||
|           console.log(resp) | ||||
|           form.append('file', file) | ||||
|         form.append("source", "fonchain-chat"); | ||||
|         form.append("type", "video"); | ||||
|         form.append("urlParam", `width=${resp.width}&height=${resp.height}`); | ||||
|           form.append('source', 'fonchain-chat') | ||||
|           form.append('type', 'video') | ||||
|           form.append('urlParam', `width=${resp.width}&height=${resp.height}`) | ||||
|           let randomId = uniqueId() | ||||
|           let newItem = { | ||||
|             avatar: userStore.avatar, | ||||
| @ -163,11 +195,11 @@ const onUploadImageVideo = async (file, type = 'image',fileUrl) => { | ||||
|             extra: { | ||||
|               duration: parseInt(resp.duration), | ||||
|               height: resp.height, | ||||
|             name: "", | ||||
|               name: '', | ||||
|               url: fileUrl, | ||||
|             width: resp.width | ||||
|               width: resp.width, | ||||
|             }, | ||||
|           float: "right", | ||||
|             float: 'right', | ||||
|             isCheck: false, | ||||
|             is_mark: 0, | ||||
|             is_read: 0, | ||||
| @ -184,9 +216,10 @@ const onUploadImageVideo = async (file, type = 'image',fileUrl) => { | ||||
|             uploadStatus: 1, // 1 上传中 2 上传成功 3 上传失败 | ||||
|           } | ||||
|           virtualList.value.unshift(newItem) | ||||
|         uploadImg(form, (e) => onProgressFn(e, randomId)).then(({ status, data, msg }) => { | ||||
|           uploadImg(form, (e) => onProgressFn(e, randomId)).then( | ||||
|             ({ status, data, msg }) => { | ||||
|               if (status == 0) { | ||||
|             console.log(data); | ||||
|                 console.log(data) | ||||
|                 resolve({ | ||||
|                   type: 'video', | ||||
|                   url: data.ori_url, | ||||
| @ -199,8 +232,9 @@ const onUploadImageVideo = async (file, type = 'image',fileUrl) => { | ||||
|                 // resolve('') | ||||
|                 // message.error(msg) | ||||
|               } | ||||
|         }) | ||||
|         } | ||||
|             }, | ||||
|           ) | ||||
|         }, | ||||
|       }) | ||||
|       const form = new FormData() | ||||
|     } | ||||
| @ -209,58 +243,59 @@ const onUploadImageVideo = async (file, type = 'image',fileUrl) => { | ||||
| 
 | ||||
| const base64ToFile = (base64) => { | ||||
|   // base64转file | ||||
|   const [header, base64String] = base64.split(";base64,"); | ||||
|   const imageType = header.split(":")[1]; | ||||
|   const byteCharacters = atob(base64String); | ||||
|   const [header, base64String] = base64.split(';base64,') | ||||
|   const imageType = header.split(':')[1] | ||||
|   const byteCharacters = atob(base64String) | ||||
|   const byteArray = new Uint8Array( | ||||
|     Array.from(byteCharacters, (char) => char.charCodeAt(0)) | ||||
|   ); | ||||
|   return new File( | ||||
|     [new Blob([byteArray], { type: imageType })], | ||||
|     "example.png", | ||||
|     { type: imageType } | ||||
|   ); | ||||
|     Array.from(byteCharacters, (char) => char.charCodeAt(0)), | ||||
|   ) | ||||
|   return new File([new Blob([byteArray], { type: imageType })], 'example.png', { | ||||
|     type: imageType, | ||||
|   }) | ||||
| } | ||||
| 
 | ||||
| const choosePhoto = (filter = 'none', maximum = 9, multiple = true) => { | ||||
|   window.plus?.gallery.pick((res) => { | ||||
|     console.log(res); | ||||
|   window.plus?.gallery.pick( | ||||
|     (res) => { | ||||
|       console.log(res) | ||||
|       res.files.reverse() | ||||
|       res.files.forEach(async (filePath) => { | ||||
|         const suffix = filePath.split('.').pop()?.toLowerCase() || '' | ||||
|         if (['jpg', 'png'].includes(suffix)) { | ||||
|         console.log("进入图片") | ||||
|         window.plus?.io?.resolveLocalFileSystemURL(filePath, async (entry) => { | ||||
|           console.log('进入图片') | ||||
|           window.plus?.io?.resolveLocalFileSystemURL( | ||||
|             filePath, | ||||
|             async (entry) => { | ||||
|               entry.file((file) => { | ||||
|             const fileReader = new plus.io.FileReader(); | ||||
|             fileReader.readAsDataURL(file); | ||||
|                 const fileReader = new plus.io.FileReader() | ||||
|                 fileReader.readAsDataURL(file) | ||||
|                 fileReader.onloadend = async (e) => { | ||||
|               const base64Url = e.target.result; | ||||
|               const fileObj = base64ToFile(base64Url); | ||||
|                   const base64Url = e.target.result | ||||
|                   const fileObj = base64ToFile(base64Url) | ||||
|                   let data = await onUploadImageVideo(fileObj, 'image') | ||||
|                   emit('selectImg', data) | ||||
|             }; | ||||
|                 } | ||||
|               }) | ||||
|             }, | ||||
|             (err) => { | ||||
|             console.log(err); | ||||
|           } | ||||
|               console.log(err) | ||||
|             }, | ||||
|           ) | ||||
|         } | ||||
|         if (['mp4', 'flv'].includes(suffix)) { | ||||
|         console.log(filePath,"进入视频") | ||||
|           console.log(filePath, '进入视频') | ||||
|           // const localUrl = plus.io.convertLocalFileSystemURL(filePath) | ||||
|           // console.log(localUrl); | ||||
| 
 | ||||
|           plus.io.getVideoInfo({ | ||||
|           filePath:filePath, | ||||
|           success:(event)=>{ | ||||
|           console.log(event); | ||||
|             filePath: filePath, | ||||
|             success: (event) => { | ||||
|               console.log(event) | ||||
|             }, | ||||
|         fail:(err)=>{ | ||||
|           console.log(err); | ||||
|         } | ||||
|         }); | ||||
|             fail: (err) => { | ||||
|               console.log(err) | ||||
|             }, | ||||
|           }) | ||||
|           // window.plus?.io?.resolveLocalFileSystemURL(localUrl, async (entry) => { | ||||
|           //   entry.file((file) => { | ||||
|           //     console.log(file,'file'); | ||||
| @ -280,26 +315,77 @@ const choosePhoto = (filter = 'none', maximum = 9, multiple = true) => { | ||||
|           // ) | ||||
|         } | ||||
|       }) | ||||
|   }, (err) => { | ||||
|     console.log(err); | ||||
|     }, | ||||
|     (err) => { | ||||
|       console.log(err) | ||||
|     }, | ||||
|     { | ||||
|       filter: filter, | ||||
|       maximum: maximum, | ||||
|       multiple: multiple, | ||||
|     } | ||||
|     }, | ||||
|   ) | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| const takePhoto = () => { | ||||
| 
 | ||||
|   if (typeof plus !== 'undefined') { | ||||
|     getCamera() | ||||
|   } else { | ||||
|     document.addEventListener('plusready', () => { | ||||
|       getCamera() | ||||
|     }) | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| const getCamera = () => { | ||||
|   const cmr = plus.camera.getCamera() | ||||
|   cmr.captureImage( | ||||
|     (p) => { | ||||
|       plus.io.resolveLocalFileSystemURL( | ||||
|         p, | ||||
|         (entry) => { | ||||
|           compressAndShowImage(entry.toLocalURL(), entry.name) | ||||
|         }, | ||||
|         (err) => { | ||||
|           console.log(err) | ||||
|         }, | ||||
|       ) | ||||
|     }, | ||||
|     () => {}, | ||||
|     { index: '2' }, | ||||
|   ) | ||||
| } | ||||
| 
 | ||||
| const compressAndShowImage = (url, filename) => { | ||||
|   const dst = `_doc/upload/${filename}` | ||||
|   plus.zip.compressImage( | ||||
|     { src: url, dst, quality: 10, overwrite: true }, | ||||
|     (zip) => displayImage(zip.target), | ||||
|     (err) => { | ||||
|       console.log(err) | ||||
|     }, | ||||
|   ) | ||||
| } | ||||
| 
 | ||||
| const displayImage = (url) => { | ||||
|   plus.io.resolveLocalFileSystemURL(url, (entry) => { | ||||
|     entry.file((file) => { | ||||
|       const fileReader = new plus.io.FileReader() | ||||
|       fileReader.readAsDataURL(file) | ||||
|       fileReader.onloadend = async (e) => { | ||||
|         state.base64Url = e.target.result | ||||
|         const imageFile = base64ToFile(state.base64Url) | ||||
|         let data = await onUploadImageVideo(imageFile, 'image') | ||||
|         emit('selectImg', data, data.file_num) | ||||
|       } | ||||
|     }) | ||||
|   }) | ||||
| } | ||||
| 
 | ||||
| const chooseFile = () => { | ||||
|   uni.chooseFile({ | ||||
|     count: 1, | ||||
|     extension:[''], | ||||
|     extension: [''], | ||||
|     success: (res) => { | ||||
|       let randomId = uniqueId() | ||||
|       let newItem = { | ||||
| @ -311,7 +397,7 @@ const chooseFile = () => { | ||||
|           size: res.tempFiles[0].size, | ||||
|           path: res.tempFilePaths[0], | ||||
|         }, | ||||
|           float: "right", | ||||
|         float: 'right', | ||||
|         isCheck: false, | ||||
|         is_mark: 0, | ||||
|         is_read: 0, | ||||
| @ -328,13 +414,10 @@ const chooseFile = () => { | ||||
|         uploadStatus: 1, // 1 上传中 2 上传成功 3 上传失败 | ||||
|       } | ||||
|       virtualList.value.unshift(newItem) | ||||
|       uploadsStore.initUploadFile(res.tempFiles[0], props.talkParams,randomId) | ||||
|     } | ||||
|       uploadsStore.initUploadFile(res.tempFiles[0], props.talkParams, randomId) | ||||
|     }, | ||||
|   }) | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| </script> | ||||
| <style lang="scss" scoped> | ||||
| .emojiRoot { | ||||
|  | ||||
| @ -493,7 +493,12 @@ import useZPaging from '@/uni_modules/z-paging/components/z-paging/js/hooks/useZ | ||||
| import emojiPanel from './components/emojiPanel.vue' | ||||
| import filePanel from './components/filePanel.vue' | ||||
| import lodash from 'lodash' | ||||
| import { ServePublishMessage,detailGetRecordsContext,ServeClearTalkUnreadNum } from '@/api/chat' | ||||
| import { | ||||
|   ServePublishMessage, | ||||
|   detailGetRecordsContext, | ||||
|   ServeClearTalkUnreadNum, | ||||
|   ServeTalkRecords, | ||||
| } from '@/api/chat' | ||||
| import copy07 from '@/static/image/chatList/copy07@2x.png' | ||||
| import multipleChoices from '@/static/image/chatList/multipleChoices@2x.png' | ||||
| import cite from '@/static/image/chatList/cite@2x.png' | ||||
| @ -545,10 +550,7 @@ const state = ref({ | ||||
|   isOpenFilePanel: false, | ||||
|   showWin: false, | ||||
|   onfocusItem: null, | ||||
|   sessionId: '', | ||||
|   talkType: '', | ||||
|   receiverId: '', | ||||
|   indexName: '', | ||||
|   sessionId: '', //会话Id | ||||
|   localPageLoadDone: true, //分页加载缓存中的聊天记录是否完毕 | ||||
|   quoteInfo: null, //引用信息 | ||||
|   mentionIsMulSelect: false, //是否是多选提醒的人 | ||||
| @ -557,15 +559,14 @@ const state = ref({ | ||||
|   selectAreaHeight: 0, //选择要提醒人的可选人员列表区域高度 | ||||
|   isShowMentionSelect: false, //是否显示要提醒人的选择区域 | ||||
|   useCustomLoadMore: false, //是否使用自定义加载更多事件(下拉刷新、上拉加载) | ||||
|   recordDate: '', //按日期查询聊天记录的开始日期 | ||||
|   serveFindRecord: [], //调用接口查找到的聊天记录 | ||||
| }) | ||||
| 
 | ||||
| uniOnload((options) => { | ||||
|   console.log('onLoad'+ options) | ||||
| uniOnload(async (options) => { | ||||
|   console.log('onLoad' + options) | ||||
|   if (options.sessionId) { | ||||
|     state.value.sessionId = options.sessionId | ||||
|     state.value.talkType = options.talkType | ||||
|     state.value.receiverId = options.receiverId | ||||
|     state.value.indexName = options.indexName | ||||
|   } | ||||
|   if (options.msgInfo) { | ||||
|     const msgInfo = JSON.parse(decodeURIComponent(options.msgInfo)) | ||||
| @ -573,18 +574,23 @@ uniOnload((options) => { | ||||
|     state.value.useCustomLoadMore = true | ||||
|     return | ||||
|   } | ||||
|   if (options.recordDate) { | ||||
|     state.value.recordDate = options.recordDate | ||||
|     const msgInfo = await findTalkRecords(options.recordDate, true) | ||||
|     queryRecordsByMsgInfo(msgInfo) | ||||
|     state.value.useCustomLoadMore = true | ||||
|     return | ||||
|   } | ||||
|   initData() | ||||
| }) | ||||
| uniOnUnload(() => { | ||||
|   console.log('onUnload') | ||||
|   console.log(state.value.talkType) | ||||
|   console.log(state.value.receiverId) | ||||
|   ServeClearTalkUnreadNum({ | ||||
|     talk_type: Number(state.value.talkType), | ||||
|     receiver_id: Number(state.value.receiverId) | ||||
|     talk_type: Number(talkParams.type), | ||||
|     receiver_id: Number(talkParams.receiver_id), | ||||
|   }).then(() => { | ||||
|     talkStore.updateItem({ | ||||
|       index_name: state.value.indexNamee, | ||||
|       index_name: talkParams.index_name, | ||||
|       unread_num: 0, | ||||
|     }) | ||||
|   }) | ||||
| @ -804,7 +810,7 @@ const onEditorChange = () => { | ||||
|   // emit('editor-event', emitCall('input_event', text)) | ||||
|   // 清理过期的撤回消息(超过5分钟) | ||||
|   const now = new Date().getTime() | ||||
|   Object.keys(state.value.revokedMessages).forEach((msgId) => { | ||||
|   Object.keys(state.value.revokedMessages || {}).forEach((msgId) => { | ||||
|     if (now - state.value.revokedMessages[msgId].revokeTime > 5 * 60 * 1000) { | ||||
|       delete state.value.revokedMessages[msgId] | ||||
|     } | ||||
| @ -1089,9 +1095,13 @@ watch( | ||||
|     if (newValue) { | ||||
|       const dialogueList = getDialogueList(talkParams.index_name) | ||||
|       // console.log(newValue[newValue.length - 1]?.sequence, dialogueList?.records?.[0]?.sequence) | ||||
|       if (!dialogueList || dialogueList?.length === 0) { | ||||
|         state.value.localPageLoadDone = true | ||||
|         return | ||||
|       } | ||||
|       if ( | ||||
|         newValue[newValue.length - 1]?.sequence === | ||||
|         dialogueList.records?.[0]?.sequence | ||||
|         dialogueList?.records?.[0]?.sequence | ||||
|       ) { | ||||
|         //相同意味着分页加载缓存中的聊天记录完毕 | ||||
|         state.value.localPageLoadDone = true | ||||
| @ -1105,14 +1115,28 @@ watch( | ||||
|   }, | ||||
| ) | ||||
| 
 | ||||
| const onScrollToLower = () => { | ||||
| const onScrollToLower = async () => { | ||||
|   if (state.value.useCustomLoadMore) { | ||||
|     const tempVirtualList = lodash.cloneDeep(virtualList.value).reverse() | ||||
|     const dialogueList = getDialogueList(talkParams.index_name) | ||||
|     const recordIndex = dialogueList.records.findIndex( | ||||
|     const recordIndex = dialogueList?.records?.findIndex( | ||||
|       (record) => record.msg_id === tempVirtualList[0].msg_id, | ||||
|     ) | ||||
|     if (recordIndex === -1) { | ||||
|     if (!recordIndex || recordIndex === -1) { | ||||
|       const moreRecords = await findTalkRecords( | ||||
|         '', | ||||
|         false, | ||||
|         tempVirtualList[0].sequence, | ||||
|         { | ||||
|           direction: 'up', | ||||
|           sort_sequence: '', | ||||
|         }, | ||||
|       ) | ||||
|       console.log(moreRecords) | ||||
| 
 | ||||
|       virtualList.value = moreRecords.concat(tempVirtualList).reverse() | ||||
| 
 | ||||
|       console.log(virtualList.value) | ||||
|     } else { | ||||
|       if (tempVirtualList[0].sequence > dialogueList.records[0].sequence) { | ||||
|         virtualList.value = dialogueList.records | ||||
| @ -1139,15 +1163,32 @@ const onScrollToLower = () => { | ||||
| } | ||||
| 
 | ||||
| //本来的下拉刷新——列表倒置后为上拉加载 | ||||
| const onScrollToUpper = () => { | ||||
| const onScrollToUpper = async () => { | ||||
|   if (state.value.useCustomLoadMore) { | ||||
|     const tempVirtualList = lodash.cloneDeep(virtualList.value).reverse() | ||||
|     const dialogueList = getDialogueList(talkParams.index_name) | ||||
|     const recordIndex = dialogueList.records.findIndex( | ||||
|     const recordIndex = dialogueList?.records?.findIndex( | ||||
|       (record) => | ||||
|         record.msg_id === tempVirtualList[tempVirtualList.length - 1].msg_id, | ||||
|     ) | ||||
|     if (recordIndex === -1) { | ||||
|     console.log(recordIndex) | ||||
|     if (!recordIndex || recordIndex === -1) { | ||||
|       // 记住加载更多前消息的ID | ||||
|       const currentMsgId = tempVirtualList[tempVirtualList.length - 1].msg_id | ||||
|       const moreRecords = await findTalkRecords( | ||||
|         '', | ||||
|         false, | ||||
|         tempVirtualList[tempVirtualList.length - 1].sequence, | ||||
|       ) | ||||
|       console.log(moreRecords) | ||||
|       virtualList.value = tempVirtualList.concat(moreRecords.reverse()).reverse() | ||||
| 
 | ||||
|       console.log(virtualList.value) | ||||
| 
 | ||||
|       // 数据更新后,滚动到之前的位置 | ||||
|       nextTick(() => { | ||||
|         zpagingRef.value?.scrollIntoViewById('zp-id-' + currentMsgId) | ||||
|       }) | ||||
|     } else { | ||||
|       if ( | ||||
|         tempVirtualList[tempVirtualList.length - 1].sequence < | ||||
| @ -1266,26 +1307,27 @@ const getMentionSelectLists = (mentionSelectList) => { | ||||
| } | ||||
| 
 | ||||
| //根据msg信息找到对应的聊天记录,并根据sequence等查看上下文 | ||||
| const queryRecordsByMsgInfo = (msgInfo) => { | ||||
| const queryRecordsByMsgInfo = async (msgInfo) => { | ||||
|   console.log(msgInfo) | ||||
|   const dialogueList = getDialogueList(talkParams.index_name) | ||||
|   const recordIndex = dialogueList.records.findIndex( | ||||
|   const recordIndex = dialogueList?.records?.findIndex( | ||||
|     (record) => record.msg_id === msgInfo.msg_id, | ||||
|   ) | ||||
|   if (recordIndex === -1) { | ||||
|   let recordsList = [] | ||||
|   console.log(recordIndex) | ||||
|   if (!recordIndex || recordIndex === -1) { | ||||
|     recordsList = await findTalkRecords('', true, msgInfo.sequence) | ||||
|   } else { | ||||
|     // console.log(recordIndex) | ||||
|     const startRecordIndex = Math.max(0, recordIndex - 10) | ||||
|     const endRecordIndex = Math.max(0, recordIndex + 10) | ||||
|     // console.log(dialogueList.records.slice(startRecordIndex, endRecordIndex)) | ||||
|     // console.log(recordIndex-startRecordIndex) | ||||
|     const recordsList = dialogueList.records.slice( | ||||
|       startRecordIndex, | ||||
|       endRecordIndex, | ||||
|     ) | ||||
|     recordsList = dialogueList.records.slice(startRecordIndex, endRecordIndex) | ||||
|   } | ||||
|   nextTick(() => { | ||||
|     zpagingRef.value.complete(recordsList.reverse()) | ||||
|       loadConfig.status = dialogueList.records?.[0]?.sequence > 1 ? 1 : 2 | ||||
|     loadConfig.status = dialogueList?.records?.[0]?.sequence > 1 ? 1 : 2 | ||||
|     nextTick(() => { | ||||
|       let offset = uni.getSystemInfoSync().windowHeight | ||||
|       const navBarAreaQuery = uni.createSelectorQuery() | ||||
| @ -1316,7 +1358,71 @@ const queryRecordsByMsgInfo = (msgInfo) => { | ||||
|       }, 1000) | ||||
|     }) | ||||
|   }) | ||||
| } | ||||
| 
 | ||||
| //查找聊天记录 | ||||
| const findTalkRecords = (record, isMiddle, sequence, appointParams) => { | ||||
|   return new Promise((resolve, reject) => { | ||||
|     let params = { | ||||
|       talk_type: talkParams.type, //1私聊;2群聊 | ||||
|       receiver_id: talkParams.receiver_id, //目标用户id或群聊id | ||||
|       no_limit: '', //1不限制 | ||||
|       file_name: '', | ||||
|       msg_type: 0, //消息类型:0:全部;2:代码;3:图片;4:音频;5:视频;6:文件;7:位置;9:会话;11群投票;12图文混合 | ||||
|       cursor: sequence || 0, //上次查询的游标 | ||||
|       limit: 10, //数据行数 | ||||
|       direction: 'down', //down向下查最新,up向上查老数据 | ||||
|       start_time: '', | ||||
|       end_time: '', | ||||
|       group_member_user_id: 0, //群成员id,当查询群历史消息的时候,需要指定群成员的时候送 | ||||
|       sort_sequence: 'asc', | ||||
|     } | ||||
|     if (record) { | ||||
|       params = Object.assign({}, params, { | ||||
|         start_time: record, | ||||
|         end_time: record, | ||||
|         limit: 1, | ||||
|         direction: '', | ||||
|       }) | ||||
|     } | ||||
|     if (appointParams) { | ||||
|       params = Object.assign({}, params, appointParams) | ||||
|     } | ||||
|     console.log(params) | ||||
|     const resp = ServeTalkRecords(params) | ||||
|     console.log(resp) | ||||
|     resp.then(({ code, data }) => { | ||||
|       console.log(data) | ||||
|       if (code == 200) { | ||||
|         if (data?.items.length > 0) { | ||||
|           if (record) { | ||||
|             resolve(data?.items[0]) | ||||
|             return | ||||
|           } | ||||
|           if (isMiddle) { | ||||
|             state.value.serveFindRecord = JSON.parse( | ||||
|               JSON.stringify(data?.items), | ||||
|             ) | ||||
|             return findTalkRecords('', false, sequence + 1, { | ||||
|               direction: 'up', | ||||
|               sort_sequence: '', | ||||
|             }).then((finalResult) => { | ||||
|               console.log(finalResult) | ||||
|               resolve(finalResult) | ||||
|             }) | ||||
|           } else { | ||||
|             state.value.serveFindRecord = data?.items | ||||
|               .reverse() | ||||
|               .concat(state.value.serveFindRecord) | ||||
|             resolve(JSON.parse(JSON.stringify(state.value.serveFindRecord))) | ||||
|             state.value.serveFindRecord = [] | ||||
|           } | ||||
|         } | ||||
|       } else { | ||||
|       } | ||||
|     }) | ||||
|     resp.catch(() => {}) | ||||
|   }) | ||||
| } | ||||
| 
 | ||||
| //是否是管理员 | ||||
| @ -1368,7 +1474,9 @@ const rpxToPx = (rpx) => { | ||||
| } | ||||
| 
 | ||||
| onUnmounted(() => { | ||||
|   if (!state.value.recordDate) { | ||||
|     dialogueStore.setDialogue({}) | ||||
|   } | ||||
|   clearMultiSelect() | ||||
| }) | ||||
| </script> | ||||
|  | ||||
| @ -136,7 +136,7 @@ const cellClick = () => { | ||||
| 		}); | ||||
| 	} | ||||
| 	uni.navigateTo({ | ||||
| 		url: `/pages/dialog/index?sessionId=${props.data.id}&talkType=${props.data.talk_type}&receiverId=${props.data.receiver_id}&indexName=${props.data.index_name}`, | ||||
| 		url: `/pages/dialog/index?sessionId=${props.data.id}`, | ||||
| 	}); | ||||
| }; | ||||
| 
 | ||||
|  | ||||
| @ -250,7 +250,7 @@ onLoad((options) => { | ||||
|             }) | ||||
|           } | ||||
|           uni.navigateTo({ | ||||
|             url: `/pages/dialog/index?sessionId=${openSession.id}&talkType=${openSession.talk_type}&receiverId=${openSession.receiver_id}&indexName=${openSession.index_name}`, | ||||
|             url: `/pages/dialog/index?sessionId=${openSession.id}`, | ||||
|           }) | ||||
|         } | ||||
|       }) | ||||
|  | ||||
| @ -99,11 +99,26 @@ import { beautifyTime } from '@/utils/datetime' | ||||
| const { t } = useI18n() | ||||
| const props = defineProps({ | ||||
|   searchItem: Object | Number, | ||||
|   searchResultKey: String, | ||||
|   searchText: String, //搜索内容 | ||||
|   searchRecordDetail: Boolean, //是否是搜索聊天记录详情 | ||||
|   pointerIconSrc: String, //箭头图标 | ||||
|   conditionType: Number, //搜索类型 | ||||
|   searchResultKey: { | ||||
|     type: String, | ||||
|     default: '', | ||||
|   }, | ||||
|   searchText: { | ||||
|     type: String, | ||||
|     default: '', | ||||
|   }, //搜索内容 | ||||
|   searchRecordDetail: { | ||||
|     type: Boolean, | ||||
|     default: false, | ||||
|   }, //是否是搜索聊天记录详情 | ||||
|   pointerIconSrc: { | ||||
|     type: String, | ||||
|     default: '', | ||||
|   }, //箭头图标 | ||||
|   conditionType: { | ||||
|     type: Number, | ||||
|     default: 0, | ||||
|   }, //搜索类型 | ||||
| }) | ||||
| // 映射表-查找对应结构下的属性名 | ||||
| const keyMapping = { | ||||
| @ -193,10 +208,8 @@ const imgText = computed(() => { | ||||
| }) | ||||
| // 映射表-根据groupType设置对应值 | ||||
| const groupTypeMapping = { | ||||
|   0: { | ||||
|   }, | ||||
|   1: { | ||||
|   }, | ||||
|   0: {}, | ||||
|   1: {}, | ||||
|   2: { | ||||
|     result_type: t('index.mine.department'), | ||||
|     result_type_color: '#377EC6', | ||||
|  | ||||
| @ -19,6 +19,7 @@ | ||||
|         'font-size': '28rpx', | ||||
|         'font-weight': 400, | ||||
|       }" | ||||
|       :refresher-enabled="false" | ||||
|     > | ||||
|       <template #top> | ||||
|         <div class="searchRoot"> | ||||
| @ -139,14 +140,37 @@ const state = reactive({ | ||||
| }) | ||||
| 
 | ||||
| const props = defineProps({ | ||||
|   searchResultPageSize: Number, //搜索结果每页数据量 | ||||
|   listLimit: Boolean, //是否限制列表内数据数量 | ||||
|   apiParams: String, //请求参数 | ||||
|   searchResultPageSize: { | ||||
|     type: Number, | ||||
|     default: 0, | ||||
|   }, //搜索结果每页数据量 | ||||
|   listLimit: { | ||||
|     type: Boolean, | ||||
|     default: false, | ||||
|   }, //是否限制列表内数据数量 | ||||
|   apiParams: { | ||||
|     type: String, | ||||
|     default: '', | ||||
|   }, //请求参数 | ||||
|   apiRequest: Function, //请求 | ||||
|   searchText: String, //搜索内容 | ||||
|   isPagination: Boolean, //是否分页 | ||||
|   searchRecordDetail: Boolean, //是否是搜索聊天记录的详情 | ||||
|   first_talk_record_infos: Object, //接受者信息 | ||||
|   searchText: { | ||||
|     type: String, | ||||
|     default: '', | ||||
|   }, //搜索内容 | ||||
|   isPagination: { | ||||
|     type: Boolean, | ||||
|     default: false, | ||||
|   }, //是否分页 | ||||
|   searchRecordDetail: { | ||||
|     type: Boolean, | ||||
|     default: false, | ||||
|   }, //是否是搜索聊天记录的详情 | ||||
|   first_talk_record_infos: { | ||||
|     type: Object, | ||||
|     default() { | ||||
|       return {} | ||||
|     }, | ||||
|   }, //接受者信息 | ||||
| }) | ||||
| 
 | ||||
| const { t } = useI18n() | ||||
| @ -276,8 +300,12 @@ const queryAllSearch = (pageNum, searchResultPageSize) => { | ||||
|           ) | ||||
|           let total = data.count | ||||
|           if (props.searchRecordDetail) { | ||||
|             if(state?.first_talk_record_infos?.talk_type === 1){ | ||||
|               total = data.user_record_count | ||||
|             } else if (state?.first_talk_record_infos?.talk_type === 2){ | ||||
|               total = data.group_record_count | ||||
|             } | ||||
|           } | ||||
|           zPaging.value?.completeByTotal([data], total) | ||||
|         } else { | ||||
|           zPaging.value?.complete([data]) | ||||
| @ -366,6 +394,12 @@ const getHasMoreResult = (searchResultKey) => { | ||||
|       } | ||||
|       break | ||||
|     case 'general_infos': | ||||
|     if ( | ||||
|         state.searchResult['record_count'] && | ||||
|         state.searchResult['record_count'] > 3 | ||||
|       ) { | ||||
|         has_more_result = t('has_more') + t('chat.type.record') | ||||
|       } | ||||
|       break | ||||
|     default: | ||||
|   } | ||||
| @ -379,12 +413,40 @@ const toMoreResultPage = (searchResultKey) => { | ||||
| 
 | ||||
| //点击了搜索结果项 | ||||
| const clickSearchItem = (searchResultKey, searchItem) => { | ||||
|   console.log(searchResultKey, searchItem) | ||||
|   let talk_type = searchItem.talk_type | ||||
|   let receiver_id = searchItem.receiver_id | ||||
|   if (searchResultKey === 'user_infos') { | ||||
|     talk_type = 1 | ||||
|     receiver_id = searchItem.id | ||||
|   } else if (searchResultKey === 'combinedGroup') { | ||||
|     talk_type = searchItem.type || 2 | ||||
|     receiver_id = searchItem.group_id || searchItem.id | ||||
|   } else if (searchResultKey === 'general_infos') { | ||||
|     if (searchItem.talk_type === 1) { | ||||
|       if (searchItem.user_id === state.uid) { | ||||
|         //发送人是自己,接收人不需要变 | ||||
|       } | ||||
|       if (searchItem.receiver_id === state.uid) { | ||||
|         //接收人是自己,这里需要变成对方 | ||||
|         let temp_id = searchItem.receiver_id | ||||
|         let temp_name = searchItem.receiver_name | ||||
|         let temp_avatar = searchItem.receiver_avatar | ||||
|         searchItem.receiver_id = searchItem.user_id | ||||
|         searchItem.receiver_name = searchItem.user_name | ||||
|         searchItem.receiver_avatar = searchItem.user_avatar | ||||
|         searchItem.user_id = temp_id | ||||
|         searchItem.user_name = temp_name | ||||
|         searchItem.user_avatar = temp_avatar | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   emits( | ||||
|     'clickSearchItem', | ||||
|     state.searchText, | ||||
|     searchResultKey, | ||||
|     searchItem.talk_type, | ||||
|     searchItem.receiver_id, | ||||
|     talk_type, | ||||
|     receiver_id, | ||||
|     encodeURIComponent(JSON.stringify(searchItem)), | ||||
|   ) | ||||
| } | ||||
|  | ||||
| @ -13,7 +13,7 @@ | ||||
| </template> | ||||
| <script setup> | ||||
| import searchList from './components/searchList.vue' | ||||
| import { ServeSeachQueryAll } from '@/api/search/index' | ||||
| import { ServeSeachQueryAll, ServeGetSessionId } from '@/api/search/index' | ||||
| import { onMounted } from 'vue' | ||||
| import { handleSetWebviewStyle } from '@/utils/common' | ||||
| 
 | ||||
| @ -37,7 +37,7 @@ const toMoreResultPage = (searchResultKey, searchText) => { | ||||
| } | ||||
| 
 | ||||
| //点击了搜索结果项 | ||||
| const clickSearchItem = ( | ||||
| const clickSearchItem = async ( | ||||
|   searchText, | ||||
|   searchResultKey, | ||||
|   talk_type, | ||||
| @ -47,17 +47,25 @@ const clickSearchItem = ( | ||||
|   console.log(searchResultKey) | ||||
|   const result = JSON.parse(decodeURIComponent(res)) | ||||
|   console.log(result) | ||||
|   console.log(talk_type, receiver_id) | ||||
|   const sessionId = await getSessionId(talk_type, receiver_id) | ||||
|   if (searchResultKey === 'user_infos') { | ||||
| 
 | ||||
| 
 | ||||
|     dialogueStore.setDialogue({ | ||||
|       name: result.nickname, | ||||
|       talk_type: 1, | ||||
|       receiver_id: receiver_id, | ||||
|     }) | ||||
|     uni.navigateTo({ | ||||
|       url: '/pages/dialog/index?sessionId=' + sessionId, | ||||
|     }) | ||||
|   } else if (searchResultKey === 'combinedGroup') { | ||||
|     dialogueStore.setDialogue({ | ||||
|       name: result.name || result.group_name, | ||||
|       talk_type: result.type || 2, | ||||
|       receiver_id: result.id || result.group_id, | ||||
|       receiver_id: result.group_id || result.id, | ||||
|     }) | ||||
|     uni.navigateTo({ | ||||
|       url: '/pages/dialog/index', | ||||
|       url: '/pages/dialog/index?sessionId=' + sessionId | ||||
|     }) | ||||
|   } else if (searchResultKey === 'general_infos') { | ||||
|     uni.navigateTo({ | ||||
| @ -71,5 +79,25 @@ const clickSearchItem = ( | ||||
|     }) | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| //获取会话Id | ||||
| const getSessionId = (talk_type, receiver_id) => { | ||||
|   return new Promise((resolve, reject) => { | ||||
|     let params = { | ||||
|       talkType: talk_type, | ||||
|       receiverId: receiver_id, | ||||
|     } | ||||
|     const resp = ServeGetSessionId(params) | ||||
|     console.log(resp) | ||||
|     resp.then(({ code, data }) => { | ||||
|       console.log(data) | ||||
|       if (code == 200) { | ||||
|         resolve(data?.sessionId) | ||||
|       } else { | ||||
|       } | ||||
|     }) | ||||
|     resp.catch(() => {}) | ||||
|   }) | ||||
| } | ||||
| </script> | ||||
| <style scoped lang="scss"></style> | ||||
|  | ||||
| @ -21,6 +21,7 @@ import { | ||||
|   ServeQueryUser, | ||||
|   ServeQueryGroup, | ||||
|   ServeTalkRecord, | ||||
|   ServeGetSessionId, | ||||
| } from '@/api/search/index' | ||||
| import { reactive } from 'vue' | ||||
| 
 | ||||
| @ -30,9 +31,9 @@ const dialogueStore = useDialogueStore() | ||||
| 
 | ||||
| const state = reactive({ | ||||
|   apiRequest: Function, | ||||
|   apiParams: String, | ||||
|   searchText: String, | ||||
|   searchResultKey: String, | ||||
|   apiParams: '', | ||||
|   searchText: '', | ||||
|   searchResultKey: '', | ||||
| }) | ||||
| 
 | ||||
| onLoad((options) => { | ||||
| @ -90,7 +91,7 @@ const lastIdChange = (last_id, last_group_id, last_member_id) => { | ||||
| } | ||||
| 
 | ||||
| //点击了搜索结果项 | ||||
| const clickSearchItem = ( | ||||
| const clickSearchItem = async ( | ||||
|   searchText, | ||||
|   searchResultKey, | ||||
|   talk_type, | ||||
| @ -100,21 +101,57 @@ const clickSearchItem = ( | ||||
|   console.log(state.searchResultKey) | ||||
|   const result = JSON.parse(decodeURIComponent(res)) | ||||
|   console.log(result) | ||||
|   console.log(talk_type, receiver_id) | ||||
|   const sessionId = await getSessionId(talk_type, receiver_id) | ||||
|   if (state.searchResultKey === 'user_infos') { | ||||
|     dialogueStore.setDialogue({ | ||||
|       name: result.nickname, | ||||
|       talk_type: 1, | ||||
|       receiver_id: receiver_id, | ||||
|     }) | ||||
|     uni.navigateTo({ | ||||
|       url: '/pages/dialog/index?sessionId=' + sessionId, | ||||
|     }) | ||||
|   } else if (state.searchResultKey === 'combinedGroup') { | ||||
|     dialogueStore.setDialogue({ | ||||
|       name: result.name || result.group_name, | ||||
|       talk_type: result.type || 2, | ||||
|       receiver_id: result.id || result.group_id, | ||||
|       receiver_id: result.group_id || result.id, | ||||
|     }) | ||||
|     uni.navigateTo({ | ||||
|       url: '/pages/dialog/index', | ||||
|       url: '/pages/dialog/index?sessionId=' + sessionId, | ||||
|     }) | ||||
|   } else if (state.searchResultKey === 'general_infos') { | ||||
|     uni.navigateTo({ | ||||
|       url: '/pages/search/moreResult/moreResultDetail?searchText=' + searchText, | ||||
|       url: | ||||
|         '/pages/search/moreResult/moreResultDetail?searchText=' + | ||||
|         searchText + | ||||
|         '&talk_type=' + | ||||
|         talk_type + | ||||
|         '&receiver_id=' + | ||||
|         receiver_id, | ||||
|     }) | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| //获取会话Id | ||||
| const getSessionId = (talk_type, receiver_id) => { | ||||
|   return new Promise((resolve, reject) => { | ||||
|     let params = { | ||||
|       talkType: talk_type, | ||||
|       receiverId: receiver_id, | ||||
|     } | ||||
|     const resp = ServeGetSessionId(params) | ||||
|     console.log(resp) | ||||
|     resp.then(({ code, data }) => { | ||||
|       console.log(data) | ||||
|       if (code == 200) { | ||||
|         resolve(data?.sessionId) | ||||
|       } else { | ||||
|       } | ||||
|     }) | ||||
|     resp.catch(() => {}) | ||||
|   }) | ||||
| } | ||||
| </script> | ||||
| <style scoped lang="scss"></style> | ||||
|  | ||||
| @ -27,8 +27,8 @@ const dialogueStore = useDialogueStore() | ||||
| const userStore = useUserStore() | ||||
| 
 | ||||
| const state = reactive({ | ||||
|   apiParams: String, | ||||
|   searchText: String, | ||||
|   apiParams: '', | ||||
|   searchText: '', | ||||
|   uid: computed(() => userStore.uid), //当前用户id | ||||
| }) | ||||
| 
 | ||||
|  | ||||
| @ -64,7 +64,8 @@ | ||||
|           v-if=" | ||||
|             state.condition === 'imgAndVideo' || | ||||
|             state.condition === 'file' || | ||||
|             state.condition === 'link' | ||||
|             state.condition === 'link' || | ||||
|             state.condition === 'member' | ||||
|           " | ||||
|           :style="{ | ||||
|             padding: state.condition === 'imgAndVideo' ? '0 27rpx' : '', | ||||
| @ -72,7 +73,11 @@ | ||||
|         > | ||||
|           <div | ||||
|             class="search-by-condition-input" | ||||
|             v-if="state.condition === 'file' || state.condition === 'link'" | ||||
|             v-if=" | ||||
|               state.condition === 'file' || | ||||
|               state.condition === 'link' || | ||||
|               state.condition === 'member' | ||||
|             " | ||||
|           > | ||||
|             <customInput | ||||
|               :searchText="state.searchText" | ||||
| @ -173,6 +178,7 @@ | ||||
|                     </div> | ||||
|                     <div | ||||
|                       class="condition-each-result-attachments" | ||||
|                       @click="previewPDF(item)" | ||||
|                       v-if=" | ||||
|                         state.condition === 'file' || state.condition === 'link' | ||||
|                       " | ||||
| @ -255,7 +261,7 @@ import useZPaging from '@/uni_modules/z-paging/components/z-paging/js/hooks/useZ | ||||
| import { parseTime } from '@/utils/datetime' | ||||
| import { onMounted, reactive, computed, ref } from 'vue' | ||||
| import { onLoad } from '@dcloudio/uni-app' | ||||
| import { ServeTalkDate } from '@/api/search/index' | ||||
| import { ServeTalkDate, ServeGetSessionId } from '@/api/search/index' | ||||
| import { ServeFindTalkRecords } from '@/api/chat/index' | ||||
| import { useDialogueStore } from '@/store' | ||||
| import { useI18n } from 'vue-i18n' | ||||
| @ -273,7 +279,6 @@ const dialogueParams = reactive({ | ||||
| let nowDay = new Date().setHours(0, 0, 0, 0) | ||||
| 
 | ||||
| const state = reactive({ | ||||
|   receiver_id: '', //目标人id | ||||
|   pageTitle: '', //页面标题 | ||||
|   dateStyle: [], //日期样式 | ||||
|   nowDate: new Date(nowDay), //当前时间 | ||||
| @ -289,16 +294,16 @@ const state = reactive({ | ||||
|   searchResultList: [], //搜索结果列表 | ||||
|   cursor: 0, //上次查询的游标 | ||||
|   msg_type: 0, //查询的消息类型 | ||||
|   group_member_id: 0, //群成员id | ||||
| }) | ||||
| 
 | ||||
| onLoad((options) => { | ||||
|   console.log(options) | ||||
|   if (options.receiver_id) { | ||||
|     state.receiver_id = Number(options.receiver_id) | ||||
|   } | ||||
|   if (options.condition) { | ||||
|     state.condition = options.condition | ||||
|     if (options.condition === 'date') { | ||||
|     if (options.condition === 'member') { | ||||
|       // queryAllSearch() | ||||
|     } else if (options.condition === 'date') { | ||||
|       state.showPageTitle = true | ||||
|       state.pageTitle = t('search.condition.date') | ||||
|       ServeQueryTalkDate(parseTime(state.nowDate, '{y}{m}')) | ||||
| @ -352,7 +357,7 @@ const ServeQueryTalkDate = (month) => { | ||||
|   let params = { | ||||
|     month: month, | ||||
|     talk_type: dialogueParams.talk_type, //1私聊2群聊 | ||||
|     receiver_id: state.receiver_id, //目标人id | ||||
|     receiver_id: dialogueParams.receiver_id, //目标人id | ||||
|   } | ||||
|   const resp = ServeTalkDate(params) | ||||
|   console.log(resp) | ||||
| @ -387,7 +392,7 @@ const ServeQueryTalkDate = (month) => { | ||||
| } | ||||
| 
 | ||||
| //点击选择日期 | ||||
| const selectDate = (e) => { | ||||
| const selectDate = async (e) => { | ||||
|   if (e == parseTime(state.nowDate, '{y}/{m}/{d}')) { | ||||
|     console.log('==今日') | ||||
|     state.dateStyle = [ | ||||
| @ -413,6 +418,37 @@ const selectDate = (e) => { | ||||
|       }, | ||||
|     ] | ||||
|   } | ||||
|   const sessionId = await getSessionId( | ||||
|     dialogueParams.talk_type, | ||||
|     dialogueParams.receiver_id, | ||||
|   ) | ||||
|   uni.navigateTo({ | ||||
|     url: | ||||
|       '/pages/dialog/index?sessionId=' + | ||||
|       sessionId + | ||||
|       '&recordDate=' + | ||||
|       parseTime(e, '{y}-{m}-{d}'), | ||||
|   }) | ||||
| } | ||||
| 
 | ||||
| //获取会话Id | ||||
| const getSessionId = (talk_type, receiver_id) => { | ||||
|   return new Promise((resolve, reject) => { | ||||
|     let params = { | ||||
|       talkType: talk_type, | ||||
|       receiverId: receiver_id, | ||||
|     } | ||||
|     const resp = ServeGetSessionId(params) | ||||
|     console.log(resp) | ||||
|     resp.then(({ code, data }) => { | ||||
|       console.log(data) | ||||
|       if (code == 200) { | ||||
|         resolve(data?.sessionId) | ||||
|       } else { | ||||
|       } | ||||
|     }) | ||||
|     resp.catch(() => {}) | ||||
|   }) | ||||
| } | ||||
| 
 | ||||
| //点击确认选择月份 | ||||
| @ -466,7 +502,7 @@ const queryAllSearch = () => { | ||||
|     direction: 'up', //down向下查最新,up向上查老数据 | ||||
|     start_time: '', | ||||
|     end_time: '', | ||||
|     group_member_user_id: 0, //群成员id,当查询群历史消息的时候,需要指定群成员的时候送 | ||||
|     group_member_user_id: state.group_member_id, //群成员id,当查询群历史消息的时候,需要指定群成员的时候送 | ||||
|     file_name: state.msg_type === 6 ? state.searchText : '', | ||||
|   } | ||||
|   console.log(params) | ||||
| @ -564,6 +600,43 @@ const fileTypeAvatar = (fileType) => { | ||||
|   } | ||||
|   return file_type_avatar | ||||
| } | ||||
| 
 | ||||
| const previewPDF = (item) => { | ||||
|   console.log(item) | ||||
|   if (typeof plus !== 'undefined') { | ||||
|     downloadAndOpenFile(item) | ||||
|   } else { | ||||
|     document.addEventListener('plusready', () => { | ||||
|       downloadAndOpenFile(item) | ||||
|     }) | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| const downloadAndOpenFile = (item) => { | ||||
|   uni.showLoading({ title: '加载中...', mask: true }) | ||||
|   const downloadUrl = item?.extra?.path | ||||
|   const options = { | ||||
|     filename: '_doc/downloads/', // 保存路径 | ||||
|   } | ||||
|   const dtask = plus.downloader.createDownload(downloadUrl, options, function ( | ||||
|     d, | ||||
|     status, | ||||
|   ) { | ||||
|     if (status === 200) { | ||||
|       uni.hideLoading() | ||||
|       const filePath = d.filename | ||||
|       plus.runtime.openFile( | ||||
|         filePath, | ||||
|         {}, | ||||
|         function () {}, | ||||
|         function (error) {}, | ||||
|       ) | ||||
|     } else { | ||||
|       uni.hideLoading() | ||||
|     } | ||||
|   }) | ||||
|   dtask.start() | ||||
| } | ||||
| </script> | ||||
| <style scoped lang="scss"> | ||||
| .search-by-date { | ||||
| @ -670,6 +743,7 @@ body::v-deep .round-3 { | ||||
|                   span { | ||||
|                     line-height: 40rpx; | ||||
|                     color: $theme-text; | ||||
|                     word-break: break-all; | ||||
|                   } | ||||
|                 } | ||||
|                 .attachment-sub-info { | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user