处理解散群聊、退出群聊按钮的可视权限;使用naiveUI的infiniteScroll组件代替overflowY,并用自带的load事件代替v-loadmore指令,重新整理复用的搜索列表组件,整理传参、数据处理等,解决参数混乱、数据处理混乱问题
This commit is contained in:
parent
8694921f25
commit
41dbb8c872
1
components.d.ts
vendored
1
components.d.ts
vendored
@ -62,6 +62,7 @@ declare module 'vue' {
|
||||
NotificationApi: typeof import('./src/components/common/NotificationApi.vue')['default']
|
||||
NPopover: typeof import('naive-ui')['NPopover']
|
||||
NRadio: typeof import('naive-ui')['NRadio']
|
||||
NScrollbar: typeof import('naive-ui')['NScrollbar']
|
||||
NSpin: typeof import('naive-ui')['NSpin']
|
||||
NTag: typeof import('naive-ui')['NTag']
|
||||
NVirtualList: typeof import('naive-ui')['NVirtualList']
|
||||
|
@ -663,7 +663,10 @@ const handleEditGroupNameConfirm = () => {
|
||||
清空聊天记录
|
||||
</n-button>
|
||||
<n-button
|
||||
v-if="isAdmin || isLeader"
|
||||
v-if="
|
||||
(isAdmin || isLeader) &&
|
||||
(state.detail.group_type === 1 || state.detail.group_type === 3)
|
||||
"
|
||||
class="btn"
|
||||
type="error"
|
||||
ghost
|
||||
@ -671,7 +674,13 @@ const handleEditGroupNameConfirm = () => {
|
||||
>
|
||||
解散该群
|
||||
</n-button>
|
||||
<n-button class="btn" type="error" ghost @click="showChatSettingOperateModal('quit')">
|
||||
<n-button
|
||||
class="btn"
|
||||
type="error"
|
||||
ghost
|
||||
@click="showChatSettingOperateModal('quit')"
|
||||
v-if="state.detail.group_type === 1 || state.detail.group_type === 3"
|
||||
>
|
||||
退出群聊
|
||||
</n-button>
|
||||
</div>
|
||||
|
@ -1,60 +1,65 @@
|
||||
<template>
|
||||
<div class="search-list">
|
||||
<div class="search-result">
|
||||
<div class="search-result-list">
|
||||
<div
|
||||
class="search-result-each-part"
|
||||
v-for="(searchResultValue, searchResultKey, searchResultIndex) in state.searchResult"
|
||||
:key="searchResultKey"
|
||||
>
|
||||
<n-infinite-scroll
|
||||
:style="{ maxHeight: props.searchResultMaxHeight }"
|
||||
@load="doLoadMore"
|
||||
>
|
||||
<div class="search-result">
|
||||
<div class="search-result-list">
|
||||
<div
|
||||
class="search-result-part"
|
||||
v-if="
|
||||
Array.isArray(state?.searchResult[searchResultKey]) &&
|
||||
state?.searchResult[searchResultKey].length > 0 &&
|
||||
searchResultKey !== 'group_infos' &&
|
||||
searchResultKey !== 'group_member_infos'
|
||||
"
|
||||
class="search-result-each-part"
|
||||
v-for="(searchResultValue, searchResultKey, searchResultIndex) in state.searchResult"
|
||||
:key="searchResultKey"
|
||||
>
|
||||
<div class="result-title">
|
||||
<span class="text-[14px] font-regular">
|
||||
{{ getResultKeysValue(searchResultKey) }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="result-list">
|
||||
<div
|
||||
class="result-list-each"
|
||||
v-for="(item, index) in state?.searchResult[searchResultKey]"
|
||||
:key="index"
|
||||
>
|
||||
<searchItem
|
||||
@click="clickSearchItem(searchResultKey, item)"
|
||||
v-if="(props.listLimit && index < 3) || !props.listLimit"
|
||||
:searchResultKey="searchResultKey"
|
||||
:searchItem="item"
|
||||
:searchText="state.searchText"
|
||||
:searchRecordDetail="props.searchRecordDetail"
|
||||
:isClickStay="
|
||||
props.useClickStay &&
|
||||
typeof state.clickStayItem === 'string' &&
|
||||
state.clickStayItem === `${item.talk_type}_${item.receiver_id}`
|
||||
"
|
||||
></searchItem>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="result-has-more"
|
||||
v-if="getHasMoreResult(searchResultKey)"
|
||||
@click="toMoreResultPage(searchResultKey)"
|
||||
class="search-result-part"
|
||||
v-if="
|
||||
Array.isArray(state?.searchResult[searchResultKey]) &&
|
||||
state?.searchResult[searchResultKey].length > 0 &&
|
||||
searchResultKey !== 'group_infos' &&
|
||||
searchResultKey !== 'group_member_infos'
|
||||
"
|
||||
>
|
||||
<span class="text-[14px] font-regular">
|
||||
{{ getHasMoreResult(searchResultKey) }}
|
||||
</span>
|
||||
<div class="result-title">
|
||||
<span class="text-[14px] font-regular">
|
||||
{{ getResultKeysValue(searchResultKey) }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="result-list">
|
||||
<div
|
||||
class="result-list-each"
|
||||
v-for="(item, index) in state?.searchResult[searchResultKey]"
|
||||
:key="index"
|
||||
>
|
||||
<searchItem
|
||||
@click="clickSearchItem(searchResultKey, item)"
|
||||
v-if="(props.listLimit && index < 3) || !props.listLimit"
|
||||
:searchResultKey="searchResultKey"
|
||||
:searchItem="item"
|
||||
:searchText="state.searchText"
|
||||
:searchRecordDetail="props.searchRecordDetail"
|
||||
:isClickStay="
|
||||
props.useClickStay &&
|
||||
typeof state.clickStayItem === 'string' &&
|
||||
state.clickStayItem === `${item.talk_type}_${item.receiver_id}`
|
||||
"
|
||||
></searchItem>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="result-has-more"
|
||||
v-if="getHasMoreResult(searchResultKey)"
|
||||
@click="toMoreResultPage(searchResultKey)"
|
||||
>
|
||||
<span class="text-[14px] font-regular">
|
||||
{{ getHasMoreResult(searchResultKey) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</n-infinite-scroll>
|
||||
<!-- <ZPaging
|
||||
ref="zPaging"
|
||||
:show-scrollbar="false"
|
||||
@ -131,6 +136,7 @@
|
||||
// const zPaging = ref()
|
||||
// useZPaging(zPaging)
|
||||
|
||||
import { NInfiniteScroll } from 'naive-ui'
|
||||
import searchItem from './searchItem.vue'
|
||||
import { ref, reactive, defineEmits, defineProps, onMounted, watch } from 'vue'
|
||||
|
||||
@ -138,8 +144,7 @@ const emits = defineEmits([
|
||||
'toMoreResultPage',
|
||||
'lastIdChange',
|
||||
'clickSearchItem',
|
||||
'clickStayItemChange',
|
||||
'doLoadMore'
|
||||
'clickStayItemChange'
|
||||
])
|
||||
|
||||
const state = reactive({
|
||||
@ -148,7 +153,9 @@ const state = reactive({
|
||||
searchResult: null, //搜索结果
|
||||
pageNum: 1, //当前请求数据页数
|
||||
uid: 12303, //当前用户id
|
||||
clickStayItem: '' //点击停留的item
|
||||
clickStayItem: '', //点击停留的item
|
||||
hasMore: true, //是否还有更多数据
|
||||
loading: false //加载锁
|
||||
})
|
||||
|
||||
const props = defineProps({
|
||||
@ -190,7 +197,11 @@ const props = defineProps({
|
||||
useClickStay: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
} //是否使用点击停留样式
|
||||
}, //是否使用点击停留样式
|
||||
searchResultMaxHeight: {
|
||||
type: String,
|
||||
default: '677px'
|
||||
} //搜索结果最大高度
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
@ -212,9 +223,12 @@ watch(
|
||||
watch(
|
||||
() => props.searchText,
|
||||
(newVal, oldVal) => {
|
||||
queryAllSearch()
|
||||
//重置点击停留列表项
|
||||
state.clickStayItem = ''
|
||||
emits('clickStayItemChange', state.clickStayItem)
|
||||
//重置搜索条件
|
||||
emits('lastIdChange', 0, 0, 0, '', '')
|
||||
queryAllSearch()
|
||||
}
|
||||
)
|
||||
|
||||
@ -223,15 +237,11 @@ const inputSearchText = (e) => {
|
||||
if (e.trim() != state.searchText.trim()) {
|
||||
state.pageNum = 1
|
||||
state.searchResult = null // 清空搜索结果
|
||||
emits('lastIdChange', 0, 0, 0, '', '')
|
||||
}
|
||||
state.searchText = e.trim()
|
||||
if (!e.trim()) {
|
||||
state.searchResult = null // 清空搜索结果
|
||||
emits('lastIdChange', 0, 0, 0, '', '')
|
||||
}
|
||||
// zPaging.value?.reload()
|
||||
queryAllSearch()
|
||||
}
|
||||
|
||||
// ES搜索聊天记录-主页搜索什么都有、指定用户、指定群、群与用户概览
|
||||
@ -354,6 +364,11 @@ const queryAllSearch = (doClearSearchResult) => {
|
||||
total = data.group_record_count
|
||||
}
|
||||
}
|
||||
if (total < props.searchResultPageSize) {
|
||||
state.hasMore = false
|
||||
} else {
|
||||
state.hasMore = true
|
||||
}
|
||||
// zPaging.value?.completeByTotal([data], total)
|
||||
} else {
|
||||
state.searchResult = data
|
||||
@ -383,6 +398,7 @@ const queryAllSearch = (doClearSearchResult) => {
|
||||
// zPaging.value?.complete(state.searchResult ? [state.searchResult] : [])
|
||||
}
|
||||
})
|
||||
return resp
|
||||
}
|
||||
|
||||
//点击取消搜索
|
||||
@ -514,13 +530,15 @@ const clickSearchItem = (searchResultKey, searchItem) => {
|
||||
|
||||
//加载更多数据
|
||||
const doLoadMore = (doClearSearchResult) => {
|
||||
if (!state.hasMore || state.loading) {
|
||||
return
|
||||
}
|
||||
state.loading = true
|
||||
queryAllSearch(doClearSearchResult)
|
||||
.finally(() => {
|
||||
state.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
// 暴露doLoadMore方法给父组件
|
||||
defineExpose({
|
||||
doLoadMore
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.search-list {
|
||||
|
@ -254,7 +254,18 @@ const state = reactive({
|
||||
searchRecordText: '', // 搜索聊天记录文本
|
||||
ServeQueryTalkRecordParams: '', // 搜索聊天记录参数
|
||||
ServeQueryTalkRecordDetailParams: '', // 搜索聊天记录详情参数
|
||||
isShowSearchRecordDetailInfo: false // 是否显示搜索聊天记录详情
|
||||
isShowSearchRecordDetailInfo: false, // 是否显示搜索聊天记录详情
|
||||
// 拆分 searchList 和 searchDetailList 独立状态
|
||||
searchList: {
|
||||
searchText: '',
|
||||
apiParams: '',
|
||||
lastId: undefined as any
|
||||
},
|
||||
searchDetailList: {
|
||||
searchText: '',
|
||||
apiParams: '',
|
||||
lastId: undefined as any
|
||||
}
|
||||
})
|
||||
|
||||
const items = computed((): ISession[] => {
|
||||
@ -303,22 +314,29 @@ watch(
|
||||
}
|
||||
)
|
||||
|
||||
// watch(
|
||||
// () => state.searchRecordText,
|
||||
// (newValue, oldValue) => {
|
||||
// console.log(newValue, 'newValue')
|
||||
// state.ServeQueryTalkRecordParams = encodeURIComponent(
|
||||
// JSON.stringify({
|
||||
// talk_type: 0, //1私聊2群聊
|
||||
// receiver_id: 0, //查详情的时候需传入
|
||||
// last_group_id: 0, //最后一条群id
|
||||
// last_member_id: 0, //最后一条用户id
|
||||
// last_receiver_user_name: '', //最后一条用户名
|
||||
// last_receiver_group_name: '' //最后一条群名
|
||||
// })
|
||||
// )
|
||||
// }
|
||||
// )
|
||||
// 监听搜索关键字变化,重置所有相关状态
|
||||
watch(
|
||||
() => state.searchRecordText,
|
||||
(newVal, oldVal) => {
|
||||
// 重置左侧
|
||||
state.searchList.searchText = newVal
|
||||
state.searchList.apiParams = encodeURIComponent(JSON.stringify({
|
||||
talk_type: 0,
|
||||
receiver_id: 0,
|
||||
last_group_id: 0,
|
||||
last_member_id: 0,
|
||||
last_receiver_user_name: '',
|
||||
last_receiver_group_name: ''
|
||||
}))
|
||||
state.searchList.lastId = undefined
|
||||
// 重置右侧
|
||||
state.searchDetailList.searchText = newVal
|
||||
state.searchDetailList.apiParams = ''
|
||||
state.searchDetailList.lastId = undefined
|
||||
// 关闭右侧详情
|
||||
state.isShowSearchRecordDetailInfo = false
|
||||
}
|
||||
)
|
||||
|
||||
// 列表加载状态
|
||||
const loadStatus = computed(() => talkStore.loadStatus)
|
||||
@ -558,16 +576,19 @@ const handleClickSearchItem = (searchText, searchResultKey, talk_type, receiver_
|
||||
const result = JSON.parse(decodeURIComponent(res))
|
||||
console.log(result)
|
||||
if (searchResultKey === 'general_infos') {
|
||||
state.ServeQueryTalkRecordDetailParams = encodeURIComponent(
|
||||
JSON.stringify({
|
||||
last_group_id: 0, //最后一条群id
|
||||
last_member_id: 0, //最后一条用户id
|
||||
receiver_id: receiver_id, //查详情的时候需传入
|
||||
talk_type: talk_type //1私聊2群聊
|
||||
})
|
||||
)
|
||||
// 先清空右侧
|
||||
state.isShowSearchRecordDetailInfo = false
|
||||
state.searchDetailList.apiParams = encodeURIComponent(JSON.stringify({
|
||||
last_group_id: 0,
|
||||
last_member_id: 0,
|
||||
receiver_id: receiver_id,
|
||||
talk_type: talk_type
|
||||
}))
|
||||
state.searchDetailList.searchText = state.searchRecordText
|
||||
state.searchDetailList.lastId = undefined
|
||||
// 再显示
|
||||
nextTick(() => {
|
||||
searchDetailListRef.value?.doLoadMore(true)
|
||||
state.isShowSearchRecordDetailInfo = true
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -586,52 +607,20 @@ const searchListRef = ref()
|
||||
// 定义搜索详情列表组件的ref
|
||||
const searchDetailListRef = ref()
|
||||
|
||||
//搜索聊天记录列表加载更多
|
||||
const loadMoreRecordList = () => {
|
||||
searchListRef.value?.doLoadMore()
|
||||
// lastIdChange 事件区分来源
|
||||
const handleSearchListLastIdChange = (last_id, last_group_id, last_member_id, last_receiver_user_name, last_receiver_group_name) => {
|
||||
state.searchList.lastId = { last_id, last_group_id, last_member_id, last_receiver_user_name, last_receiver_group_name }
|
||||
state.searchList.apiParams = encodeURIComponent(JSON.stringify({
|
||||
...JSON.parse(decodeURIComponent(state.searchList.apiParams)),
|
||||
last_id, last_group_id, last_member_id, last_receiver_user_name, last_receiver_group_name
|
||||
}))
|
||||
}
|
||||
|
||||
// 搜索聊天记录详情列表加载更多
|
||||
const loadMoreRecordDetail = () => {
|
||||
searchDetailListRef.value?.doLoadMore()
|
||||
}
|
||||
|
||||
const handleMoreRecordLastIdChange = (
|
||||
last_id,
|
||||
last_group_id,
|
||||
last_member_id,
|
||||
last_receiver_user_name,
|
||||
last_receiver_group_name
|
||||
) => {
|
||||
let idChanges = {
|
||||
last_id,
|
||||
last_group_id,
|
||||
last_member_id,
|
||||
last_receiver_user_name,
|
||||
last_receiver_group_name
|
||||
}
|
||||
state.ServeQueryTalkRecordParams = encodeURIComponent(
|
||||
JSON.stringify(
|
||||
Object.assign({}, JSON.parse(decodeURIComponent(state.ServeQueryTalkRecordParams)), idChanges)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
const handleRecordDetailLastIdChange = (last_id, last_group_id, last_member_id) => {
|
||||
let idChanges = {
|
||||
last_id,
|
||||
last_group_id,
|
||||
last_member_id
|
||||
}
|
||||
state.ServeQueryTalkRecordDetailParams = encodeURIComponent(
|
||||
JSON.stringify(
|
||||
Object.assign(
|
||||
{},
|
||||
JSON.parse(decodeURIComponent(state.ServeQueryTalkRecordDetailParams)),
|
||||
idChanges
|
||||
)
|
||||
)
|
||||
)
|
||||
const handleSearchDetailListLastIdChange = (last_id, last_group_id, last_member_id) => {
|
||||
state.searchDetailList.lastId = { last_id, last_group_id, last_member_id }
|
||||
state.searchDetailList.apiParams = encodeURIComponent(JSON.stringify({
|
||||
...JSON.parse(decodeURIComponent(state.searchDetailList.apiParams)),
|
||||
last_id, last_group_id, last_member_id
|
||||
}))
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -653,7 +642,7 @@ const handleRecordDetailLastIdChange = (last_id, last_group_id, last_member_id)
|
||||
<n-dropdown
|
||||
trigger="click"
|
||||
:options="state.chatSearchOptions"
|
||||
style="width: 248px; height: 677px; overflow-y: scroll;"
|
||||
style="width: 248px; height: 677px;"
|
||||
>
|
||||
<n-input
|
||||
placeholder="搜索好友 / 群聊"
|
||||
@ -865,34 +854,36 @@ const handleRecordDetailLastIdChange = (last_id, last_group_id, last_member_id)
|
||||
</n-input>
|
||||
</div>
|
||||
<div class="search-record-card" v-if="state.searchRecordText">
|
||||
<div class="search-record-list" v-loadmore="loadMoreRecordList">
|
||||
<div class="search-record-list">
|
||||
<chatAppSearchList
|
||||
ref="searchListRef"
|
||||
:searchResultPageSize="10"
|
||||
:listLimit="false"
|
||||
:apiRequest="ServeQueryTalkRecord"
|
||||
:apiParams="state.ServeQueryTalkRecordParams"
|
||||
:searchText="state.searchRecordText"
|
||||
:apiParams="state.searchList.apiParams"
|
||||
:searchText="state.searchList.searchText"
|
||||
:isPagination="true"
|
||||
searchResultKey="general_infos"
|
||||
@clickSearchItem="handleClickSearchItem"
|
||||
:useClickStay="true"
|
||||
@clickStayItemChange="handleClickStayItemChange"
|
||||
@lastIdChange="handleMoreRecordLastIdChange"
|
||||
@lastIdChange="handleSearchListLastIdChange"
|
||||
:searchResultMaxHeight="'517px'"
|
||||
></chatAppSearchList>
|
||||
</div>
|
||||
<div class="search-record-detail" v-loadmore="loadMoreRecordDetail">
|
||||
<div class="search-record-detail">
|
||||
<chatAppSearchList
|
||||
ref="searchDetailListRef"
|
||||
v-if="state.isShowSearchRecordDetailInfo"
|
||||
:searchResultPageSize="10"
|
||||
:listLimit="false"
|
||||
:apiRequest="ServeQueryTalkRecord"
|
||||
:apiParams="state.ServeQueryTalkRecordDetailParams"
|
||||
:searchText="state.searchRecordText"
|
||||
:apiParams="state.searchDetailList.apiParams"
|
||||
:searchText="state.searchDetailList.searchText"
|
||||
:isPagination="true"
|
||||
:searchRecordDetail="true"
|
||||
@lastIdChange="handleRecordDetailLastIdChange"
|
||||
@lastIdChange="handleSearchDetailListLastIdChange"
|
||||
:searchResultMaxHeight="'517px'"
|
||||
></chatAppSearchList>
|
||||
</div>
|
||||
</div>
|
||||
@ -1087,13 +1078,11 @@ html[theme-mode='dark'] {
|
||||
width: 260px;
|
||||
height: 517px;
|
||||
border: 1px solid #efeff5;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
.search-record-detail {
|
||||
width: 578px;
|
||||
height: 517px;
|
||||
border: 1px solid #efeff5;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
}
|
||||
.search-record-empty {
|
||||
|
Loading…
Reference in New Issue
Block a user