处理解散群聊、退出群聊按钮的可视权限;使用naiveUI的infiniteScroll组件代替overflowY,并用自带的load事件代替v-loadmore指令,重新整理复用的搜索列表组件,整理传参、数据处理等,解决参数混乱、数据处理混乱问题

This commit is contained in:
wangyifeng 2025-05-20 19:58:16 +08:00
parent 8694921f25
commit 41dbb8c872
4 changed files with 162 additions and 145 deletions

1
components.d.ts vendored
View File

@ -62,6 +62,7 @@ declare module 'vue' {
NotificationApi: typeof import('./src/components/common/NotificationApi.vue')['default'] NotificationApi: typeof import('./src/components/common/NotificationApi.vue')['default']
NPopover: typeof import('naive-ui')['NPopover'] NPopover: typeof import('naive-ui')['NPopover']
NRadio: typeof import('naive-ui')['NRadio'] NRadio: typeof import('naive-ui')['NRadio']
NScrollbar: typeof import('naive-ui')['NScrollbar']
NSpin: typeof import('naive-ui')['NSpin'] NSpin: typeof import('naive-ui')['NSpin']
NTag: typeof import('naive-ui')['NTag'] NTag: typeof import('naive-ui')['NTag']
NVirtualList: typeof import('naive-ui')['NVirtualList'] NVirtualList: typeof import('naive-ui')['NVirtualList']

View File

@ -663,7 +663,10 @@ const handleEditGroupNameConfirm = () => {
清空聊天记录 清空聊天记录
</n-button> </n-button>
<n-button <n-button
v-if="isAdmin || isLeader" v-if="
(isAdmin || isLeader) &&
(state.detail.group_type === 1 || state.detail.group_type === 3)
"
class="btn" class="btn"
type="error" type="error"
ghost ghost
@ -671,7 +674,13 @@ const handleEditGroupNameConfirm = () => {
> >
解散该群 解散该群
</n-button> </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> </n-button>
</div> </div>

View File

@ -1,5 +1,9 @@
<template> <template>
<div class="search-list"> <div class="search-list">
<n-infinite-scroll
:style="{ maxHeight: props.searchResultMaxHeight }"
@load="doLoadMore"
>
<div class="search-result"> <div class="search-result">
<div class="search-result-list"> <div class="search-result-list">
<div <div
@ -55,6 +59,7 @@
</div> </div>
</div> </div>
</div> </div>
</n-infinite-scroll>
<!-- <ZPaging <!-- <ZPaging
ref="zPaging" ref="zPaging"
:show-scrollbar="false" :show-scrollbar="false"
@ -131,6 +136,7 @@
// const zPaging = ref() // const zPaging = ref()
// useZPaging(zPaging) // useZPaging(zPaging)
import { NInfiniteScroll } from 'naive-ui'
import searchItem from './searchItem.vue' import searchItem from './searchItem.vue'
import { ref, reactive, defineEmits, defineProps, onMounted, watch } from 'vue' import { ref, reactive, defineEmits, defineProps, onMounted, watch } from 'vue'
@ -138,8 +144,7 @@ const emits = defineEmits([
'toMoreResultPage', 'toMoreResultPage',
'lastIdChange', 'lastIdChange',
'clickSearchItem', 'clickSearchItem',
'clickStayItemChange', 'clickStayItemChange'
'doLoadMore'
]) ])
const state = reactive({ const state = reactive({
@ -148,7 +153,9 @@ const state = reactive({
searchResult: null, // searchResult: null, //
pageNum: 1, // pageNum: 1, //
uid: 12303, //id uid: 12303, //id
clickStayItem: '' //item clickStayItem: '', //item
hasMore: true, //
loading: false //
}) })
const props = defineProps({ const props = defineProps({
@ -190,7 +197,11 @@ const props = defineProps({
useClickStay: { useClickStay: {
type: Boolean, type: Boolean,
default: false default: false
} //使 }, //使
searchResultMaxHeight: {
type: String,
default: '677px'
} //
}) })
onMounted(() => { onMounted(() => {
@ -212,9 +223,12 @@ watch(
watch( watch(
() => props.searchText, () => props.searchText,
(newVal, oldVal) => { (newVal, oldVal) => {
queryAllSearch() //
state.clickStayItem = '' state.clickStayItem = ''
emits('clickStayItemChange', 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()) { if (e.trim() != state.searchText.trim()) {
state.pageNum = 1 state.pageNum = 1
state.searchResult = null // state.searchResult = null //
emits('lastIdChange', 0, 0, 0, '', '')
} }
state.searchText = e.trim() state.searchText = e.trim()
if (!e.trim()) { if (!e.trim()) {
state.searchResult = null // state.searchResult = null //
emits('lastIdChange', 0, 0, 0, '', '')
} }
// zPaging.value?.reload()
queryAllSearch()
} }
// ES- // ES-
@ -354,6 +364,11 @@ const queryAllSearch = (doClearSearchResult) => {
total = data.group_record_count total = data.group_record_count
} }
} }
if (total < props.searchResultPageSize) {
state.hasMore = false
} else {
state.hasMore = true
}
// zPaging.value?.completeByTotal([data], total) // zPaging.value?.completeByTotal([data], total)
} else { } else {
state.searchResult = data state.searchResult = data
@ -383,6 +398,7 @@ const queryAllSearch = (doClearSearchResult) => {
// zPaging.value?.complete(state.searchResult ? [state.searchResult] : []) // zPaging.value?.complete(state.searchResult ? [state.searchResult] : [])
} }
}) })
return resp
} }
// //
@ -514,13 +530,15 @@ const clickSearchItem = (searchResultKey, searchItem) => {
// //
const doLoadMore = (doClearSearchResult) => { const doLoadMore = (doClearSearchResult) => {
queryAllSearch(doClearSearchResult) if (!state.hasMore || state.loading) {
return
} }
state.loading = true
// doLoadMore queryAllSearch(doClearSearchResult)
defineExpose({ .finally(() => {
doLoadMore state.loading = false
}) })
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.search-list { .search-list {

View File

@ -254,7 +254,18 @@ const state = reactive({
searchRecordText: '', // searchRecordText: '', //
ServeQueryTalkRecordParams: '', // ServeQueryTalkRecordParams: '', //
ServeQueryTalkRecordDetailParams: '', // 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[] => { const items = computed((): ISession[] => {
@ -303,22 +314,29 @@ watch(
} }
) )
// watch( //
// () => state.searchRecordText, watch(
// (newValue, oldValue) => { () => state.searchRecordText,
// console.log(newValue, 'newValue') (newVal, oldVal) => {
// state.ServeQueryTalkRecordParams = encodeURIComponent( //
// JSON.stringify({ state.searchList.searchText = newVal
// talk_type: 0, //12 state.searchList.apiParams = encodeURIComponent(JSON.stringify({
// receiver_id: 0, // talk_type: 0,
// last_group_id: 0, //id receiver_id: 0,
// last_member_id: 0, //id last_group_id: 0,
// last_receiver_user_name: '', // last_member_id: 0,
// last_receiver_group_name: '' // 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) const loadStatus = computed(() => talkStore.loadStatus)
@ -558,16 +576,19 @@ const handleClickSearchItem = (searchText, searchResultKey, talk_type, receiver_
const result = JSON.parse(decodeURIComponent(res)) const result = JSON.parse(decodeURIComponent(res))
console.log(result) console.log(result)
if (searchResultKey === 'general_infos') { if (searchResultKey === 'general_infos') {
state.ServeQueryTalkRecordDetailParams = encodeURIComponent( //
JSON.stringify({ state.isShowSearchRecordDetailInfo = false
last_group_id: 0, //id state.searchDetailList.apiParams = encodeURIComponent(JSON.stringify({
last_member_id: 0, //id last_group_id: 0,
receiver_id: receiver_id, // last_member_id: 0,
talk_type: talk_type //12 receiver_id: receiver_id,
}) talk_type: talk_type
) }))
state.searchDetailList.searchText = state.searchRecordText
state.searchDetailList.lastId = undefined
//
nextTick(() => { nextTick(() => {
searchDetailListRef.value?.doLoadMore(true) state.isShowSearchRecordDetailInfo = true
}) })
} }
} }
@ -586,52 +607,20 @@ const searchListRef = ref()
// ref // ref
const searchDetailListRef = ref() const searchDetailListRef = ref()
// // lastIdChange
const loadMoreRecordList = () => { const handleSearchListLastIdChange = (last_id, last_group_id, last_member_id, last_receiver_user_name, last_receiver_group_name) => {
searchListRef.value?.doLoadMore() 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 handleSearchDetailListLastIdChange = (last_id, last_group_id, last_member_id) => {
// state.searchDetailList.lastId = { last_id, last_group_id, last_member_id }
const loadMoreRecordDetail = () => { state.searchDetailList.apiParams = encodeURIComponent(JSON.stringify({
searchDetailListRef.value?.doLoadMore() ...JSON.parse(decodeURIComponent(state.searchDetailList.apiParams)),
} last_id, last_group_id, last_member_id
}))
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
)
)
)
} }
</script> </script>
@ -653,7 +642,7 @@ const handleRecordDetailLastIdChange = (last_id, last_group_id, last_member_id)
<n-dropdown <n-dropdown
trigger="click" trigger="click"
:options="state.chatSearchOptions" :options="state.chatSearchOptions"
style="width: 248px; height: 677px; overflow-y: scroll;" style="width: 248px; height: 677px;"
> >
<n-input <n-input
placeholder="搜索好友 / 群聊" placeholder="搜索好友 / 群聊"
@ -865,34 +854,36 @@ const handleRecordDetailLastIdChange = (last_id, last_group_id, last_member_id)
</n-input> </n-input>
</div> </div>
<div class="search-record-card" v-if="state.searchRecordText"> <div class="search-record-card" v-if="state.searchRecordText">
<div class="search-record-list" v-loadmore="loadMoreRecordList"> <div class="search-record-list">
<chatAppSearchList <chatAppSearchList
ref="searchListRef" ref="searchListRef"
:searchResultPageSize="10" :searchResultPageSize="10"
:listLimit="false" :listLimit="false"
:apiRequest="ServeQueryTalkRecord" :apiRequest="ServeQueryTalkRecord"
:apiParams="state.ServeQueryTalkRecordParams" :apiParams="state.searchList.apiParams"
:searchText="state.searchRecordText" :searchText="state.searchList.searchText"
:isPagination="true" :isPagination="true"
searchResultKey="general_infos" searchResultKey="general_infos"
@clickSearchItem="handleClickSearchItem" @clickSearchItem="handleClickSearchItem"
:useClickStay="true" :useClickStay="true"
@clickStayItemChange="handleClickStayItemChange" @clickStayItemChange="handleClickStayItemChange"
@lastIdChange="handleMoreRecordLastIdChange" @lastIdChange="handleSearchListLastIdChange"
:searchResultMaxHeight="'517px'"
></chatAppSearchList> ></chatAppSearchList>
</div> </div>
<div class="search-record-detail" v-loadmore="loadMoreRecordDetail"> <div class="search-record-detail">
<chatAppSearchList <chatAppSearchList
ref="searchDetailListRef" ref="searchDetailListRef"
v-if="state.isShowSearchRecordDetailInfo" v-if="state.isShowSearchRecordDetailInfo"
:searchResultPageSize="10" :searchResultPageSize="10"
:listLimit="false" :listLimit="false"
:apiRequest="ServeQueryTalkRecord" :apiRequest="ServeQueryTalkRecord"
:apiParams="state.ServeQueryTalkRecordDetailParams" :apiParams="state.searchDetailList.apiParams"
:searchText="state.searchRecordText" :searchText="state.searchDetailList.searchText"
:isPagination="true" :isPagination="true"
:searchRecordDetail="true" :searchRecordDetail="true"
@lastIdChange="handleRecordDetailLastIdChange" @lastIdChange="handleSearchDetailListLastIdChange"
:searchResultMaxHeight="'517px'"
></chatAppSearchList> ></chatAppSearchList>
</div> </div>
</div> </div>
@ -1087,13 +1078,11 @@ html[theme-mode='dark'] {
width: 260px; width: 260px;
height: 517px; height: 517px;
border: 1px solid #efeff5; border: 1px solid #efeff5;
overflow-y: scroll;
} }
.search-record-detail { .search-record-detail {
width: 578px; width: 578px;
height: 517px; height: 517px;
border: 1px solid #efeff5; border: 1px solid #efeff5;
overflow-y: scroll;
} }
} }
.search-record-empty { .search-record-empty {