perf: 群聊总人数排除机器人

This commit is contained in:
kuaifan 2025-01-02 14:23:23 +08:00
parent be9a968ad9
commit ab2b29f267
5 changed files with 83 additions and 20 deletions

View File

@ -265,7 +265,9 @@ class WebSocketDialog extends AbstractModel
// 未读消息
$data = array_merge($data, self::generateUnread($data['id'], $userid));
// 对话人数
$data['people'] = $data['people'] ?? WebSocketDialogUser::whereDialogId($data['id'])->count();
if (!isset($data['people'])) {
$data = array_merge($data, self::generatePeople($data['id']));
}
// 有待办
$data['todo_num'] = $data['todo_num'] ?? WebSocketDialogMsgTodo::whereDialogId($data['id'])->whereUserid($userid)->whereDoneAt(null)->count();
// 最后消息
@ -401,6 +403,26 @@ class WebSocketDialog extends AbstractModel
return $data;
}
/**
* 获取对话人数
* @param $dialogId
* @return array
*/
public static function generatePeople($dialogId)
{
$counts = WebSocketDialogUser::whereDialogId($dialogId)
->groupBy('bot')
->selectRaw('bot, COUNT(*) as count')
->pluck('count', 'bot');
$userCount = $counts->get(0, 0); // 非机器人数量
$botCount = $counts->get(1, 0); // 机器人数量
return [
'people' => $userCount + $botCount,
'people_user' => $userCount,
'people_bot' => $botCount,
];
}
/**
* 加入聊天室
* @param int|array $userid 加入的会员ID或会员ID组
@ -436,10 +458,9 @@ class WebSocketDialog extends AbstractModel
}
}
});
$this->pushMsg("groupUpdate", [
'id' => $this->id,
'people' => WebSocketDialogUser::whereDialogId($this->id)->count()
]);
$data = WebSocketDialog::generatePeople($this->id);
$data['id'] = $this->id;
$this->pushMsg("groupUpdate", $data);
return true;
}
@ -496,10 +517,9 @@ class WebSocketDialog extends AbstractModel
});
});
//
$this->pushMsg("groupUpdate", [
'id' => $this->id,
'people' => WebSocketDialogUser::whereDialogId($this->id)->count()
]);
$data = WebSocketDialog::generatePeople($this->id);
$data['id'] = $this->id;
$this->pushMsg("groupUpdate", $data);
}
/**

View File

@ -1623,7 +1623,9 @@ export default {
if (this.cacheDialogs.find(({id}) => id == this.dialogId)) {
this.$store.dispatch("saveDialog", {
id: this.dialogId,
people: data.length
people: data.length,
people_user: data.filter(item => !item.bot).length,
people_bot: data.filter(item => item.bot).length,
})
}
if (data.length > 0) {

View File

@ -18,15 +18,35 @@
<div class="group-info-user">
<ul>
<li v-for="(item, index) in userList" :key="index" @click="openUser(item.userid)">
<UserAvatar :userid="item.userid" :size="32" showName/>
<div v-if="item.userid === dialogData.owner_id" class="user-tag">{{ $L("群主") }}</div>
<div v-else-if="operableExit(item)" class="user-exit" @click.stop="onExit(item)"><Icon type="md-exit"/></div>
</li>
<li v-if="userList.length === 0" class="no">
<li v-if="allList.length === 0" class="no">
<Loading v-if="loadIng > 0"/>
<span v-else>{{$L('没有符合条件的数据')}}</span>
</li>
<template v-else-if="botList.length > 0">
<li class="label">
<span>{{$L('群机器人')}}</span>
</li>
<li v-for="item in botList" @click="openUser(item.userid)">
<UserAvatar :userid="item.userid" :size="32" showName/>
<div v-if="item.userid === dialogData.owner_id" class="user-tag">{{ $L("群主") }}</div>
<div v-else-if="operableExit(item)" class="user-exit" @click.stop="onExit(item)"><Icon type="md-exit"/></div>
</li>
<li class="label">
<span>{{$L(`群成员 (${userList.length}人)`)}}</span>
</li>
<li v-for="item in userList" @click="openUser(item.userid)">
<UserAvatar :userid="item.userid" :size="32" showName/>
<div v-if="item.userid === dialogData.owner_id" class="user-tag">{{ $L("群主") }}</div>
<div v-else-if="operableExit(item)" class="user-exit" @click.stop="onExit(item)"><Icon type="md-exit"/></div>
</li>
</template>
<template v-else>
<li v-for="item in userList" @click="openUser(item.userid)">
<UserAvatar :userid="item.userid" :size="32" showName/>
<div v-if="item.userid === dialogData.owner_id" class="user-tag">{{ $L("群主") }}</div>
<div v-else-if="operableExit(item)" class="user-exit" @click.stop="onExit(item)"><Icon type="md-exit"/></div>
</li>
</template>
</ul>
</div>
@ -103,7 +123,7 @@ export default {
return '未知'
},
userList() {
allList() {
const {dialogUser, searchKey, cacheUserBasic, dialogData} = this;
const list = dialogUser.map(item => {
const userBasic = cacheUserBasic.find(basic => basic.userid == item.userid)
@ -126,7 +146,16 @@ export default {
}
return $A.dayjs(a.created_at) - $A.dayjs(b.created_at);
})
}
},
botList({allList}) {
return allList.filter(item => item.bot)
},
userList({allList}) {
return allList.filter(item => !item.bot)
},
},
watch: {
@ -173,7 +202,9 @@ export default {
this.dialogUser = data;
this.$store.dispatch("saveDialog", {
id: this.dialogId,
people: data.length
people: data.length,
people_user: data.filter(item => !item.bot).length,
people_bot: data.filter(item => item.bot).length,
});
}).catch(({msg}) => {
$A.modalError(msg);

View File

@ -999,7 +999,7 @@ export default {
},
peopleNum() {
return this.dialogData.type === 'group' ? $A.runNum(this.dialogData.people) : 0;
return this.dialogData.type === 'group' ? $A.runNum(this.dialogData.people_user) : 0;
},
pasteTitle() {

View File

@ -85,6 +85,16 @@
}
}
&.label {
&:hover {
background-color: transparent;
}
color: #999;
font-size: 13px;
height: auto;
}
.common-avatar {
width: 0;
flex: 1;