mirror of https://gitee.com/godoos/godoos.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
279 lines
5.6 KiB
279 lines
5.6 KiB
<script setup>
|
|
import { useChatStore } from "@/stores/chat";
|
|
import {
|
|
ElAvatar,
|
|
ElCol,
|
|
ElCollapse,
|
|
ElCollapseItem,
|
|
ElRow,
|
|
} from "element-plus";
|
|
const store = useChatStore();
|
|
const handleNodeClick = (data) => {
|
|
if (data.isUser) {
|
|
store.getSessionInfo(data.id, "user");
|
|
}
|
|
};
|
|
|
|
const defaultProps = {
|
|
children: "children",
|
|
label: "label",
|
|
};
|
|
|
|
// 将数据转换成树形结构
|
|
function transformData(data) {
|
|
return data.map((dept) => ({
|
|
label: dept.dept_name,
|
|
children: transformUsers(dept.users).concat(
|
|
transformSubDepts(dept.sub_depts)
|
|
),
|
|
}));
|
|
}
|
|
|
|
function transformUsers(users) {
|
|
if (!users) return [];
|
|
console.log(users);
|
|
return users.map((user) => ({
|
|
label: `${user.nick_name}`,
|
|
id: user.user_id, // 添加用户ID
|
|
isUser: true,
|
|
children: [],
|
|
}));
|
|
}
|
|
|
|
function transformSubDepts(sub_depts) {
|
|
if (!sub_depts) return [];
|
|
return transformData(sub_depts);
|
|
}
|
|
|
|
const data = transformData(store.departmentList);
|
|
console.log(data);
|
|
</script>
|
|
|
|
<template>
|
|
<el-collapse v-model="store.activeNames">
|
|
<el-collapse-item name="1">
|
|
<template #title>
|
|
<span
|
|
v-if="store.onlineUserList.length > 0"
|
|
class="title"
|
|
>在线({{ store.onlineUserList.length }})</span
|
|
>
|
|
<span
|
|
v-else
|
|
class="title"
|
|
>在线</span
|
|
>
|
|
</template>
|
|
<div v-if="store.onlineUserList.length > 0">
|
|
<div
|
|
v-for="item in store.onlineUserList"
|
|
:key="item.id"
|
|
>
|
|
<div
|
|
class="list-item"
|
|
@click="store.getSessionInfo(item.chatId, 'user')"
|
|
:style="{
|
|
backgroundColor:
|
|
item.id === store.targetChatId ? '#F5F5F5' : '',
|
|
}"
|
|
>
|
|
<el-row>
|
|
<el-col :span="6">
|
|
<el-avatar
|
|
shape="square"
|
|
:size="40"
|
|
class="avatar"
|
|
:src="item.avatar"
|
|
/>
|
|
</el-col>
|
|
<el-col :span="18">
|
|
<el-row
|
|
style="display: flex; align-items: center"
|
|
>
|
|
<el-col>
|
|
<div class="previewName">
|
|
{{ item.nickname }}
|
|
</div>
|
|
</el-col>
|
|
<el-col :span="6">
|
|
<!-- 空白占位 -->
|
|
</el-col>
|
|
</el-row>
|
|
<el-row>
|
|
<div class="previewIP">
|
|
{{ item.login_ip }}
|
|
</div>
|
|
</el-row>
|
|
</el-col>
|
|
</el-row>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div v-else>
|
|
<p class="no-data">暂无数据</p>
|
|
</div>
|
|
</el-collapse-item>
|
|
<el-collapse-item name="2">
|
|
<template #title>
|
|
<span
|
|
v-if="store.departmentList.length > 0"
|
|
class="title"
|
|
>
|
|
部门({{ store.departmentList.length }})
|
|
</span>
|
|
<span
|
|
v-else
|
|
class="title"
|
|
>部门</span
|
|
>
|
|
</template>
|
|
<div
|
|
class="tree-container"
|
|
v-if="data.length > 0"
|
|
>
|
|
<el-tree
|
|
:data="data"
|
|
node-key="dept_id"
|
|
:props="{ label: 'label', children: 'children' }"
|
|
@node-click="handleNodeClick"
|
|
:default-expand-all="false"
|
|
>
|
|
</el-tree>
|
|
</div>
|
|
|
|
<div v-else>
|
|
<p class="no-data">暂无数据</p>
|
|
</div>
|
|
</el-collapse-item>
|
|
<el-collapse-item name="3">
|
|
<template #title>
|
|
<span
|
|
v-if="store.groupList.length > 0"
|
|
class="title"
|
|
>群组({{ store.groups.length }})</span
|
|
>
|
|
<span
|
|
v-else
|
|
class="title"
|
|
>群组</span
|
|
>
|
|
</template>
|
|
<div v-if="store.groupList.length > 0">
|
|
<div
|
|
v-for="group in store.groups"
|
|
:key="group.id"
|
|
>
|
|
<div
|
|
class="list-item"
|
|
@click="store.getSessionInfo(group.id, 'group')"
|
|
:style="{
|
|
backgroundColor:
|
|
group.id === store.targetChatId
|
|
? '#F5F5F5'
|
|
: '',
|
|
}"
|
|
>
|
|
<el-row>
|
|
<el-col :span="6">
|
|
<el-avatar
|
|
shape="square"
|
|
:size="40"
|
|
class="avatar"
|
|
>群</el-avatar
|
|
>
|
|
</el-col>
|
|
<el-col :span="18">
|
|
<div class="previewName">{{ group.name }}</div>
|
|
</el-col>
|
|
</el-row>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div v-else>
|
|
<p class="no-data">暂无数据</p>
|
|
</div>
|
|
</el-collapse-item>
|
|
</el-collapse>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.title {
|
|
padding-left: 10px;
|
|
}
|
|
.list-item {
|
|
width: 95%;
|
|
height: 60px;
|
|
margin: 0 auto;
|
|
border-radius: 4px;
|
|
transition: all 0.5s;
|
|
margin-bottom: 5px;
|
|
}
|
|
|
|
.list-item:hover {
|
|
background-color: #f5f5f5;
|
|
}
|
|
|
|
.avatar {
|
|
margin: 10px;
|
|
}
|
|
|
|
.previewName {
|
|
margin-left: 10px;
|
|
font-size: 14px;
|
|
font-family: Arial, sans-serif;
|
|
line-height: 1.5;
|
|
overflow: hidden; /* 隐藏超出部分 */
|
|
text-overflow: ellipsis; /* 显示为省略号 */
|
|
white-space: nowrap; /* 不换行 */
|
|
max-width: 100%; /* 最大宽度 */
|
|
display: flex; /* 使用 Flexbox */
|
|
align-items: center; /* 垂直居中 */
|
|
}
|
|
|
|
/* 为了使内部的 el-row 垂直居中,我们也需要设置其父级元素 */
|
|
.el-row {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.previewIP {
|
|
margin-left: 10px;
|
|
font-size: 12px;
|
|
font-family: Arial, sans-serif;
|
|
color: #999999;
|
|
display: flex; /* 使用 Flexbox */
|
|
align-items: center; /* 垂直居中 */
|
|
}
|
|
|
|
.online-icon {
|
|
font-size: 16px; /* 调整图标大小 */
|
|
color: green; /* 在线状态颜色 */
|
|
margin-left: 5px; /* 与用户名之间的间距 */
|
|
}
|
|
|
|
.previewChat {
|
|
margin-left: 10px;
|
|
font-size: 12px; /* 调整字体大小 */
|
|
font-family: Arial, sans-serif;
|
|
color: #999999;
|
|
overflow: hidden; /* 隐藏超出部分 */
|
|
text-overflow: ellipsis; /* 显示为省略号 */
|
|
white-space: nowrap; /* 不换行 */
|
|
max-width: 100%; /* 最大宽度 */
|
|
}
|
|
|
|
.previewTime {
|
|
float: right;
|
|
margin-top: 10px;
|
|
margin-right: 10px;
|
|
font-size: 12px;
|
|
font-family: Arial, sans-serif;
|
|
color: #999999;
|
|
}
|
|
|
|
.no-data {
|
|
text-align: center;
|
|
color: #999999;
|
|
}
|
|
</style>
|
|
|