mirror of
https://github.com/kuaifan/dootask.git
synced 2026-03-10 09:56:00 +00:00
perf: 优化搜索
This commit is contained in:
parent
c30c6114d5
commit
e564be3fb5
@ -5,16 +5,16 @@
|
|||||||
<div class="messenger-select">
|
<div class="messenger-select">
|
||||||
<div class="messenger-search">
|
<div class="messenger-search">
|
||||||
<div class="search-wrapper">
|
<div class="search-wrapper">
|
||||||
<Input v-if="tabActive==='dialog'" v-model="dialogKey" :placeholder="$L(loadDialogs ? '更新中...' : '搜索消息')" clearable >
|
<Input v-if="tabActive==='dialog'" v-model="dialogSearchKey" :placeholder="$L(loadDialogs ? '更新中...' : '搜索消息')" clearable >
|
||||||
<div class="search-pre" slot="prefix">
|
<div class="search-pre" slot="prefix">
|
||||||
<Loading v-if="loadDialogs"/>
|
<Loading v-if="loadDialogs || dialogSearchLoad > 0"/>
|
||||||
<Icon v-else type="ios-search" />
|
<Icon v-else type="ios-search" />
|
||||||
</div>
|
</div>
|
||||||
</Input>
|
</Input>
|
||||||
<Input v-else prefix="ios-search" v-model="contactsKey" :placeholder="$L('搜索联系人')" clearable />
|
<Input v-else prefix="ios-search" v-model="contactsKey" :placeholder="$L('搜索联系人')" clearable />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="tabActive==='dialog' && !dialogKey" class="messenger-nav">
|
<div v-if="tabActive==='dialog' && !dialogSearchKey" class="messenger-nav">
|
||||||
<EDropdown
|
<EDropdown
|
||||||
trigger="click"
|
trigger="click"
|
||||||
placement="bottom-start"
|
placement="bottom-start"
|
||||||
@ -53,14 +53,8 @@
|
|||||||
<ul
|
<ul
|
||||||
v-if="tabActive==='dialog'"
|
v-if="tabActive==='dialog'"
|
||||||
class="dialog">
|
class="dialog">
|
||||||
<template v-if="dialogList.length === 0">
|
|
||||||
<li v-if="dialogLoad > 0" class="loading"><Loading/></li>
|
|
||||||
<li v-else class="nothing">
|
|
||||||
{{$L(dialogKey ? `没有任何与"${dialogKey}"相关的会话` : `没有任何会话`)}}
|
|
||||||
</li>
|
|
||||||
</template>
|
|
||||||
<li
|
<li
|
||||||
v-else
|
v-if="dialogList.length > 0"
|
||||||
v-for="(dialog, key) in dialogList"
|
v-for="(dialog, key) in dialogList"
|
||||||
:ref="`dialog_${dialog.id}`"
|
:ref="`dialog_${dialog.id}`"
|
||||||
:key="key"
|
:key="key"
|
||||||
@ -107,6 +101,9 @@
|
|||||||
<Badge class="dialog-num" :type="dialog.silence ? 'normal' : 'error'" :overflow-count="999" :count="$A.getDialogUnread(dialog, true)"/>
|
<Badge class="dialog-num" :type="dialog.silence ? 'normal' : 'error'" :overflow-count="999" :count="$A.getDialogUnread(dialog, true)"/>
|
||||||
<div class="dialog-line"></div>
|
<div class="dialog-line"></div>
|
||||||
</li>
|
</li>
|
||||||
|
<li v-else-if="dialogSearchLoad === 0" class="nothing">
|
||||||
|
{{$L(dialogSearchKey ? `没有任何与"${dialogSearchKey}"相关的会话` : `没有任何会话`)}}
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul v-else class="contacts">
|
<ul v-else class="contacts">
|
||||||
<template v-if="contactsFilter.length === 0">
|
<template v-if="contactsFilter.length === 0">
|
||||||
@ -193,9 +190,9 @@ export default {
|
|||||||
activeNum: 0,
|
activeNum: 0,
|
||||||
tabActive: 'dialog',
|
tabActive: 'dialog',
|
||||||
|
|
||||||
dialogLoad: 0,
|
dialogSearchLoad: 0,
|
||||||
dialogKey: '',
|
dialogSearchKey: '',
|
||||||
dialogSearch: [],
|
dialogSearchList: [],
|
||||||
|
|
||||||
dialogActive: '',
|
dialogActive: '',
|
||||||
dialogMenus: [
|
dialogMenus: [
|
||||||
@ -296,8 +293,14 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
dialogList() {
|
dialogList() {
|
||||||
const {dialogActive, dialogKey, dialogSearch} = this;
|
const {dialogActive, dialogSearchKey, dialogSearchList} = this
|
||||||
if (dialogActive == '' && dialogKey == '') {
|
if (dialogSearchList.length > 0) {
|
||||||
|
return dialogSearchList.sort((a, b) => {
|
||||||
|
// 搜索结果排在后面
|
||||||
|
return (a.is_search === true ? 1 : 0) - (b.is_search === true ? 1 : 0)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (dialogActive == '' && dialogSearchKey == '') {
|
||||||
return this.cacheDialogs.filter(dialog => this.filterDialog(dialog)).sort((a, b) => {
|
return this.cacheDialogs.filter(dialog => this.filterDialog(dialog)).sort((a, b) => {
|
||||||
if (a.top_at || b.top_at) {
|
if (a.top_at || b.top_at) {
|
||||||
return $A.Date(b.top_at) - $A.Date(a.top_at);
|
return $A.Date(b.top_at) - $A.Date(a.top_at);
|
||||||
@ -312,7 +315,7 @@ export default {
|
|||||||
if (!this.filterDialog(dialog)) {
|
if (!this.filterDialog(dialog)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (dialogKey) {
|
if (dialogSearchKey) {
|
||||||
const {name, pinyin, last_msg} = dialog;
|
const {name, pinyin, last_msg} = dialog;
|
||||||
let searchString = `${name} ${pinyin}`
|
let searchString = `${name} ${pinyin}`
|
||||||
if (last_msg) {
|
if (last_msg) {
|
||||||
@ -326,7 +329,7 @@ export default {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!$A.strExists(searchString, dialogKey)) {
|
if (!$A.strExists(searchString, dialogSearchKey)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (dialogActive) {
|
} else if (dialogActive) {
|
||||||
@ -358,36 +361,7 @@ export default {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
if (dialogSearch.length > 0) {
|
|
||||||
const msgIds = [];
|
|
||||||
const userIds = [];
|
|
||||||
list.forEach(item => {
|
|
||||||
if (item.last_msg && !msgIds.includes(item.last_msg.id)) {
|
|
||||||
msgIds.push(item.last_msg.id)
|
|
||||||
}
|
|
||||||
if (item.dialog_user && !userIds.includes(item.dialog_user.userid)) {
|
|
||||||
userIds.push(item.dialog_user.userid)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
dialogSearch.forEach(item => {
|
|
||||||
if ($A.leftExists(item.id, "u:")) {
|
|
||||||
if (!userIds.includes(item.dialog_user.userid)) {
|
|
||||||
list.push(Object.assign(item, {is_search: true}))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!item.last_msg || !msgIds.includes(item.last_msg.id)) {
|
|
||||||
list.push(Object.assign(item, {is_search: true}))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return list.sort((a, b) => {
|
return list.sort((a, b) => {
|
||||||
// 搜索结果排在后面
|
|
||||||
a._by_search = a.is_search === true ? 1 : 0
|
|
||||||
b._by_search = b.is_search === true ? 1 : 0
|
|
||||||
if (a._by_search || b._by_search) {
|
|
||||||
return a._by_search - b._by_search
|
|
||||||
}
|
|
||||||
// 根据置顶时间排序
|
// 根据置顶时间排序
|
||||||
if (a.top_at || b.top_at) {
|
if (a.top_at || b.top_at) {
|
||||||
return $A.Date(b.top_at) - $A.Date(a.top_at);
|
return $A.Date(b.top_at) - $A.Date(a.top_at);
|
||||||
@ -482,31 +456,24 @@ export default {
|
|||||||
immediate: true
|
immediate: true
|
||||||
},
|
},
|
||||||
|
|
||||||
dialogKey(val) {
|
dialogSearchKey(val) {
|
||||||
switch (val) {
|
switch (val) {
|
||||||
case 'log.open':
|
case 'log.o':
|
||||||
case 'log:open':
|
|
||||||
case 'eruda:open':
|
|
||||||
$A.IDBSet("logOpen", "open").then(_ => $A.reloadUrl());
|
$A.IDBSet("logOpen", "open").then(_ => $A.reloadUrl());
|
||||||
break;
|
break;
|
||||||
case 'log.close':
|
case 'log.c':
|
||||||
case 'log:close':
|
|
||||||
case 'eruda:close':
|
|
||||||
$A.IDBSet("logOpen", "close").then(_ => $A.reloadUrl());
|
$A.IDBSet("logOpen", "close").then(_ => $A.reloadUrl());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
this.dialogSearch = [];
|
this.dialogSearchList = [];
|
||||||
if (val == '') {
|
if (val == '') {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
this.dialogLoad++;
|
this.__searchTimer && clearTimeout(this.__searchTimer)
|
||||||
setTimeout(() => {
|
this.__searchTimer = setTimeout(this.searchDialog, 600)
|
||||||
if (this.dialogKey == val) {
|
this.dialogSearchLoad++
|
||||||
this.searchDialog(val);
|
setTimeout(_ => this.dialogSearchLoad--, 600)
|
||||||
}
|
|
||||||
this.dialogLoad--;
|
|
||||||
}, 600);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
contactsKey(val) {
|
contactsKey(val) {
|
||||||
@ -604,7 +571,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
dialogClass(dialog) {
|
dialogClass(dialog) {
|
||||||
if (this.dialogKey) {
|
if (this.dialogSearchKey) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
@ -619,7 +586,6 @@ export default {
|
|||||||
if (this.operateVisible) {
|
if (this.operateVisible) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.dialogKey = "";
|
|
||||||
//
|
//
|
||||||
if ($A.isJson(dialogId) && $A.leftExists(dialogId.dialog_id, "u:")) {
|
if ($A.isJson(dialogId) && $A.leftExists(dialogId.dialog_id, "u:")) {
|
||||||
this.$store.dispatch("openDialogUserid", $A.leftDelete(dialogId.dialog_id, "u:")).catch(({msg}) => {
|
this.$store.dispatch("openDialogUserid", $A.leftDelete(dialogId.dialog_id, "u:")).catch(({msg}) => {
|
||||||
@ -684,15 +650,45 @@ export default {
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
searchDialog(key) {
|
searchDialog() {
|
||||||
this.dialogLoad++;
|
const key = this.dialogSearchKey
|
||||||
|
if (key == '') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//
|
||||||
|
this.dialogSearchLoad++;
|
||||||
this.$store.dispatch("call", {
|
this.$store.dispatch("call", {
|
||||||
url: 'dialog/search',
|
url: 'dialog/search',
|
||||||
data: {key},
|
data: {key},
|
||||||
}).then(({data}) => {
|
}).then(({data}) => {
|
||||||
this.dialogSearch = data;
|
if (key !== this.dialogSearchKey) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const list = $A.cloneJSON(this.dialogList)
|
||||||
|
const msgIds = [];
|
||||||
|
const userIds = [];
|
||||||
|
list.forEach(item => {
|
||||||
|
if (item.last_msg && !msgIds.includes(item.last_msg.id)) {
|
||||||
|
msgIds.push(item.last_msg.id)
|
||||||
|
}
|
||||||
|
if (item.dialog_user && !userIds.includes(item.dialog_user.userid)) {
|
||||||
|
userIds.push(item.dialog_user.userid)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
data.some(item => {
|
||||||
|
if ($A.leftExists(item.id, "u:")) {
|
||||||
|
if (!userIds.includes(item.dialog_user.userid)) {
|
||||||
|
list.push(Object.assign(item, {is_search: true}))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!item.last_msg || !msgIds.includes(item.last_msg.id)) {
|
||||||
|
list.push(Object.assign(item, {is_search: true}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.dialogSearchList = list;
|
||||||
}).finally(_ => {
|
}).finally(_ => {
|
||||||
this.dialogLoad--;
|
this.dialogSearchLoad--;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -801,7 +797,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
handleLongpress(event, el) {
|
handleLongpress(event, el) {
|
||||||
if (this.dialogKey) {
|
if (this.dialogSearchKey) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const dialogId = $A.getAttr(el, 'data-id')
|
const dialogId = $A.getAttr(el, 'data-id')
|
||||||
|
|||||||
13
resources/assets/sass/pages/page-messenger.scss
vendored
13
resources/assets/sass/pages/page-messenger.scss
vendored
@ -350,8 +350,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&.nothing,
|
&.nothing {
|
||||||
&.loading {
|
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding: 24px;
|
padding: 24px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@ -360,16 +359,6 @@
|
|||||||
cursor: default;
|
cursor: default;
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
}
|
}
|
||||||
&.loading {
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-start;
|
|
||||||
justify-content: center;
|
|
||||||
.common-loading {
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
margin: 1px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&.contacts {
|
&.contacts {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user