1.右上角样式修改

2.发起群聊样式修改
3.首页-视讯样式修改
main
ysn 5 days ago
parent 6d3ebd0bb7
commit c80902dab3
  1. 5
      src/layout/components/Navbar.vue
  2. 303
      src/views/message/components/CreateGroupDialog.vue
  3. 19
      src/views/videoCommunication/index.vue

@ -117,10 +117,7 @@
<div class="avatar-container right-menu-item hover-effect">
<div class="avatar-wrapper">
<span class="user-nickname" v-if="userInfo.group">
所属单位
<el-link type="primary" :underline="false">
{{ userInfo.group }}
</el-link>
所属单位:{{ userInfo.group }}
</span>
</div>
</div>

@ -21,11 +21,15 @@
style="margin-bottom: 10px"
/>
<!-- 标签页 -->
<el-tabs v-model="activeName" @tab-click="handleClick">
<!-- 无搜索时展示标签页 -->
<el-tabs v-if="!isSearching" v-model="activeName" @tab-click="handleClick">
<!-- 最近联系人 -->
<el-tab-pane label="最近联系人" name="recentContacts">
<div v-loading="loading" class="contact-list">
<div
v-loading="loading"
class="contact-list"
@scroll="handleScroll"
>
<div
v-for="member in displayMembers"
:key="member.id"
@ -60,12 +64,25 @@
v-if="!loading && displayMembers.length === 0"
description="暂无联系人"
/>
<div v-if="loadMoreLoading" class="load-more-tip">
加载更多...
</div>
<div
v-if="contactNoMore && displayMembers.length > 0"
class="load-more-tip"
>
没有更多数据了
</div>
</div>
</el-tab-pane>
<!-- 最近群组 -->
<el-tab-pane label="最近群组" name="recentGroups">
<div v-loading="loading" class="contact-list">
<div
v-loading="loading"
class="contact-list"
@scroll="handleScroll"
>
<div v-for="group in recentGroups" :key="group.id">
<!-- 群组标题 -->
<div
@ -133,6 +150,15 @@
v-if="!loading && recentGroups.length === 0"
description="暂无群组"
/>
<div v-if="loadMoreLoading" class="load-more-tip">
加载更多...
</div>
<div
v-if="groupNoMore && recentGroups.length > 0"
class="load-more-tip"
>
没有更多数据了
</div>
</div>
</el-tab-pane>
@ -196,6 +222,47 @@
</div>
</el-tab-pane>
</el-tabs>
<!-- 有搜索内容隐藏tab展示搜索结果同事列表 -->
<div v-else class="search-result-wrap">
<div class="search-title">同事</div>
<div v-loading="loading" class="contact-list">
<div
v-for="member in displayMembers"
:key="member.id"
:class="[
'member-item',
{
active: isSelected(member.id),
offline: !member.online,
},
]"
@click="toggleSelect(member)"
>
<el-checkbox
v-model="member.selected"
:disabled="isSelectDisabled && !member.selected"
@change="toggleSelect(member)"
>
<div class="member-item-label">
<el-avatar
:src="
$store.state.user.netConfig.MINIO_ENDPOINT_HTTPS +
member.avatar
"
icon="el-icon-user-solid"
/>
<span class="member-name">{{ member.name }}</span>
<span v-if="member.online" class="online-dot" />
</div>
</el-checkbox>
</div>
<el-empty
v-if="!loading && displayMembers.length === 0"
description="未匹配到同事"
/>
</div>
</div>
</el-col>
<!-- 右侧已选人员 -->
@ -299,11 +366,18 @@ export default {
activeName: "recentContacts",
searchText: "",
loading: false,
loadMoreLoading: false,
confirmLoading: false,
selectedMembers: [],
contactPage: 1,
groupPage: 1,
pageSize: 10,
memberList: [],
recentGroups: [],
treeData: [],
contactNoMore: false, //
groupNoMore: false, //
isSearching: false,
};
},
computed: {
@ -320,27 +394,45 @@ export default {
methods: {
show() {
this.visible = true;
this.resetPage();
this.loadData();
},
//
resetPage() {
this.contactPage = 1;
this.groupPage = 1;
this.contactNoMore = false;
this.groupNoMore = false;
this.memberList = [];
this.recentGroups = [];
},
async loadData() {
await Promise.all([
this.fetchRecentContacts(),
this.fetchRecentGroups(),
this.fetchRecentContacts(true),
this.fetchRecentGroups(true),
this.fetchOrgTree(),
]);
},
//
async fetchRecentContacts() {
this.loading = true;
/**
* 获取联系人列表
* @param {Boolean} isReset true=首页刷新false=滚动追加
*/
async fetchRecentContacts(isReset = false) {
// return
if (this.contactNoMore && !isReset) return;
if (isReset) this.loading = true;
else this.loadMoreLoading = true;
try {
const res = await getMessagesLatestContacts({
scene: 1,
page: 1,
size: 65535,
page: this.contactPage,
size: this.pageSize,
});
const list = res.data?.list || [];
this.memberList = list.map((item) => ({
const formatList = list.map((item) => ({
id: item.id,
name: item.name,
role: item.role,
@ -353,24 +445,47 @@ export default {
online: item.online === 1 || item.online === true,
selected: this.isSelected(item.id),
}));
if (isReset) {
this.memberList = formatList;
} else {
this.memberList.push(...formatList);
}
// <
if (list.length < this.pageSize) {
this.contactNoMore = true;
} else {
this.contactNoMore = false;
}
} catch (e) {
console.error("获取最近联系人失败", e);
this.memberList = [];
if (isReset) this.memberList = [];
} finally {
this.loading = false;
this.loadMoreLoading = false;
}
},
//
async fetchRecentGroups() {
//
loadMoreContacts() {
// /
if (this.loadMoreLoading || this.contactNoMore) return;
this.contactPage++;
this.fetchRecentContacts(false);
},
async fetchRecentGroups(isReset = false) {
if (this.groupNoMore && !isReset) return;
try {
const res = await getMessagesLatestContacts({
scene: 4,
page: 1,
size: 65535,
page: this.groupPage,
size: this.pageSize,
});
const list = res.data?.list || [];
this.recentGroups = list.map((item) => ({
const formatGroups = list.map((item) => ({
id: item.id,
name: item.name,
avatar: item.avatar,
@ -378,13 +493,32 @@ export default {
allSelected: false,
members: [],
}));
if (isReset) {
this.recentGroups = formatGroups;
} else {
this.recentGroups.push(...formatGroups);
}
//
if (list.length < this.pageSize) {
this.groupNoMore = true;
} else {
this.groupNoMore = false;
}
} catch (e) {
console.error("获取最近群组失败", e);
this.recentGroups = [];
if (isReset) this.recentGroups = [];
}
},
//
//
loadMoreGroups() {
if (this.loadMoreLoading || this.groupNoMore) return;
this.groupPage++;
this.fetchRecentGroups(false);
},
async fetchOrgTree() {
try {
const res = await getGroupsList();
@ -396,7 +530,22 @@ export default {
}
},
//
//
handleScroll(e) {
const target = e.target;
const scrollTop = target.scrollTop;
const scrollHeight = target.scrollHeight;
const clientHeight = target.clientHeight;
// 50px
if (scrollTop + clientHeight >= scrollHeight - 50) {
if (this.activeName === "recentContacts") {
this.loadMoreContacts();
} else if (this.activeName === "recentGroups") {
this.loadMoreGroups();
}
}
},
buildOrgTree(list) {
if (!list || list.length === 0) return [];
return list.map((item) => ({
@ -412,7 +561,6 @@ export default {
}));
},
//
async loadOrgUsers(node) {
if (node.isLoaded || node.type === "user" || node.type === "all") return;
if (node.hasChildren && node.children && node.children.length > 0) {
@ -450,13 +598,15 @@ export default {
}
},
//
async handleSearch() {
const text = this.searchText.trim();
if (!text) {
await this.fetchRecentContacts();
this.isSearching = false;
this.resetPage();
await this.fetchRecentContacts(true);
return;
}
this.isSearching = true;
this.loading = true;
try {
const res = await searchUsers({
@ -479,6 +629,8 @@ export default {
online: item.online === 1 || item.online === true,
selected: this.isSelected(item.id),
}));
//
this.contactNoMore = true;
} catch (e) {
console.error("搜索联系人失败", e);
} finally {
@ -486,21 +638,16 @@ export default {
}
},
//
handleClearSearch() {
this.searchText = "";
this.fetchRecentContacts();
this.resetPage();
this.fetchRecentContacts(true);
},
//
handleClick(tab) {
this.activeName = tab.name;
if (tab.name === "recentGroups") {
this.loadGroupMembers();
}
},
//
async loadGroupMembers() {
for (const group of this.recentGroups) {
if (!group.members || group.members.length === 0) {
@ -522,17 +669,13 @@ export default {
}
},
//
async toggleGroupExpand(group) {
group.expanded = !group.expanded;
if (group.expanded) {
// getMultiChatInfo
try {
const res = await getMultiChatInfo({ multi_chat_id: group.id });
const data = res.data || {};
// 使 user_id
const userList = data.user_list || [];
// ID
group.members = userList
.filter((item) => item.id !== data.user_id)
.map((item) => {
@ -545,23 +688,19 @@ export default {
}
},
//
async handleOrgNodeClick(data) {
if (data.type === "org") {
this.$refs.orgTree.setCurrentKey(data.id);
//
if (!data.isLoaded) {
await this.loadOrgUsers(data);
}
}
},
//
isSelected(userId) {
return this.selectedMembers.some((m) => m.id === userId);
},
//
toggleSelect(member) {
if (this.isSelectDisabled && !member.selected) {
this.$message.warning(`最多只能选择${this.maxSelectCount}个成员`);
@ -582,13 +721,10 @@ export default {
this.syncSelection(member);
},
//
syncSelection(member) {
//
this.memberList.forEach((m) => {
if (m.id === member.id) m.selected = member.selected;
});
//
this.recentGroups.forEach((group) => {
if (group.members) {
const groupMember = group.members.find((m) => m.id === member.id);
@ -598,11 +734,9 @@ export default {
}
}
});
//
this.syncOrgTreeSelection(this.treeData, member);
},
//
syncOrgTreeSelection(nodes, member) {
nodes.forEach((node) => {
if (node.id === member.id && node.type === "user") {
@ -615,7 +749,6 @@ export default {
});
},
//
toggleGroupAllSelect(group) {
if (!group.members || group.members.length === 0) return;
if (group.allSelected) {
@ -624,16 +757,14 @@ export default {
const index = this.selectedMembers.findIndex(
(m) => m.id === member.id
);
if (index >= 0) {
this.selectedMembers.splice(index, 1);
}
if (index >= 0) this.selectedMembers.splice(index, 1);
});
group.allSelected = false;
} else {
const selectedCount = group.members.filter((m) => !m.selected).length;
const unselectedCount = group.members.filter((m) => !m.selected).length;
if (
this.maxSelectCount > 0 &&
this.selectedMembers.length + selectedCount > this.maxSelectCount
this.selectedMembers.length + unselectedCount > this.maxSelectCount
) {
this.$message.warning(`最多只能选择${this.maxSelectCount}个成员`);
return;
@ -653,14 +784,10 @@ export default {
this.syncGroupSelection(group);
},
//
syncGroupSelection(group) {
group.members.forEach((member) => {
this.syncSelection(member);
});
group.members.forEach((member) => this.syncSelection(member));
},
//
handleOrgCheckAllChange(allNode) {
const parentNode = this.findParentNode(this.treeData, allNode.id);
if (!parentNode || !parentNode.children) return;
@ -693,16 +820,13 @@ export default {
users.forEach((user) => {
user.selected = false;
const index = this.selectedMembers.findIndex((m) => m.id === user.id);
if (index >= 0) {
this.selectedMembers.splice(index, 1);
}
if (index >= 0) this.selectedMembers.splice(index, 1);
});
allNode.indeterminate = false;
}
users.forEach((user) => this.syncSelection(user));
},
//
findParentNode(nodes, childId, parent = null) {
for (const node of nodes) {
if (node.id === childId) return parent;
@ -714,7 +838,6 @@ export default {
return null;
},
//
updateParentAllSelectStatus(userNode) {
const parentNode = this.findParentNode(this.treeData, userNode.id);
if (!parentNode || !parentNode.children) return;
@ -728,17 +851,14 @@ export default {
}
},
//
removeSelected(member) {
const index = this.selectedMembers.findIndex((m) => m.id === member.id);
if (index >= 0) {
this.selectedMembers.splice(index, 1);
member.selected = false;
this.syncSelection({ id: member.id, selected: false });
}
},
//
clearAllSelected() {
this.selectedMembers = [];
this.memberList.forEach((m) => (m.selected = false));
@ -749,7 +869,6 @@ export default {
this.clearOrgTreeSelected(this.treeData);
},
//
clearOrgTreeSelected(nodes) {
nodes.forEach((node) => {
node.selected = false;
@ -757,14 +876,13 @@ export default {
});
},
//
handleClose(done) {
this.clearAllSelected();
this.searchText = "";
this.resetPage();
this.visible = false;
},
//
async confirmCreateGroup() {
if (this.selectedMembers.length < this.minSelectCount) {
this.$message.warning(`至少选择${this.minSelectCount}个成员`);
@ -772,13 +890,10 @@ export default {
}
this.confirmLoading = true;
try {
// 1. props
if (typeof this.confirmCallback === "function") {
await this.confirmCallback(this.selectedMembers);
}
// 2. confirm
this.$emit("confirm", this.selectedMembers);
// 3.
this.clearAllSelected();
this.searchText = "";
this.visible = false;
@ -796,10 +911,28 @@ export default {
.body {
height: 450px;
.search-result-wrap {
.search-title {
font-size: 14px;
font-weight: 500;
color: #606266;
padding: 6px 0 8px;
border-bottom: 1px solid #ebeef5;
margin-bottom: 8px;
}
}
.contact-list {
height: 400px;
overflow-y: auto;
.load-more-tip {
text-align: center;
padding: 8px 0;
color: #909399;
font-size: 13px;
}
.member-item {
display: flex;
align-items: center;
@ -809,6 +942,15 @@ export default {
border-radius: 4px;
transition: background 0.2s;
// el-checkbox
::v-deep .el-checkbox {
display: flex;
align-items: center;
}
::v-deep .el-checkbox__inner {
margin-top: 0 !important;
}
&:hover {
background: #f5f7fa;
}
@ -887,6 +1029,21 @@ export default {
padding: 5px;
}
//
.userline {
display: flex;
align-items: center;
gap: 10px;
padding: 8px 16px;
::v-deep .el-checkbox {
display: flex;
align-items: center;
}
::v-deep .el-checkbox__inner {
margin-top: 0 !important;
}
}
.org-icon {
font-size: 16px;
color: #409eff;
@ -983,14 +1140,6 @@ export default {
justify-content: center;
}
.userline {
display: flex;
align-items: center;
gap: 10px;
padding: 8px 16px;
}
//
.group-detail-info {
padding: 12px 16px;
margin: 8px 0;

@ -59,28 +59,22 @@
/>
</template>
</el-table-column>
<el-table-column
label="会诊名称"
prop="name"
align="left"
width="490"
>
<el-table-column label="会诊名称" prop="name" align="left">
<template slot-scope="scope">
<el-button type="text">
<span class="table-column">
{{ scope.row.name }}
</el-button>
</span>
</template>
</el-table-column>
<el-table-column
label="会议类型名称"
prop="meet_type_name"
align="left"
width="420"
>
<template slot-scope="scope">
<el-button type="text">
<span class="table-column" style="font-weight: bold">
{{ scope.row.meet_type_name }}
</el-button>
</span>
</template>
</el-table-column>
<el-table-column label="创建时间" prop="create_time" align="left" />
@ -342,6 +336,9 @@ export default {
margin-right: 8px;
}
}
.table-column {
color: #009696;
}
//
.join-area {

Loading…
Cancel
Save