admin-vue3/src/views/im/home/pages/conversation/components/message/ConversationGroupRequestPen...

122 lines
4.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<!--
群顶部待处理加群申请横幅
- 仅当登录用户是该群 owner / admin 且该群下未处理申请数 > 0 时显示
- count groupRequestStore 派生全局存本端处理 / WS 通知到达后 store 自动更新
- 点击横幅打开 GroupRequestListDialog含历史已处理记录不再就地展开
-->
<div v-if="canManage && pendingCount > 0" class="im-conversation-group-request">
<div class="im-conversation-group-request__row" @click="dialogVisible = true">
<Icon
icon="ant-design:user-add-outlined"
:size="14"
class="im-conversation-group-request__icon"
/>
<span class="im-conversation-group-request__text"> {{ pendingCount }} </span>
<Icon
icon="ant-design:right-outlined"
:size="11"
class="im-conversation-group-request__chevron"
/>
</div>
<!-- 申请列表 dialog复用同一组件避免群管理面板与会话顶部各写一份 -->
<GroupRequestListDialog v-model="dialogVisible" :group-id="groupId" />
</div>
</template>
<script lang="ts" setup>
import { computed, ref } from 'vue'
import Icon from '@/components/Icon/src/Icon.vue'
import { useUserStore } from '@/store/modules/user'
import { ImGroupMemberRole } from '@/views/im/utils/constants'
import { useGroupStore } from '../../../../store/groupStore'
import { useGroupRequestStore } from '../../../../store/groupRequestStore'
import GroupRequestListDialog from '../../../../components/group/GroupRequestListDialog.vue'
defineOptions({ name: 'ImConversationGroupRequestPending' })
const props = defineProps<{
groupId: number
}>()
const userStore = useUserStore()
const groupStore = useGroupStore()
const groupRequestStore = useGroupRequestStore()
const dialogVisible = ref(false)
/** 当前群(含 ownerUserId / members */
const group = computed(() => groupStore.getGroup(props.groupId))
/** 当前用户在群里的角色;优先用 group.members懒加载未到时回退到 ownerUserId 直判 */
const myRole = computed(() => {
const myId = Number(userStore.getUser?.id) || 0
if (group.value?.ownerUserId === myId) {
return ImGroupMemberRole.OWNER
}
return group.value?.members?.find((m) => m.userId === myId)?.role
})
/** 仅群主 / 管理员可见 */
const canManage = computed(
() => myRole.value === ImGroupMemberRole.OWNER || myRole.value === ImGroupMemberRole.ADMIN
)
/** 当前群未处理申请数;从 store 派生 */
const pendingCount = computed(() => groupRequestStore.getUnhandledCountByGroupId(props.groupId))
</script>
<style scoped>
/* 容器align-items flex-start 让胶囊靠左、不占整行;高度由内容撑开,与置顶消息横幅节奏对齐 */
.im-conversation-group-request {
flex-shrink: 0;
display: flex;
flex-direction: column;
align-items: flex-start;
padding: 6px 16px 8px;
background-color: var(--el-fill-color-light);
}
/* 胶囊本体内容自适应宽度padding / 圆角 / 阴影对齐 ConversationGroupPinned 的 __row */
.im-conversation-group-request__row {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 6px 12px;
background-color: var(--el-bg-color);
border-radius: 10px;
font-size: 13px;
color: var(--el-text-color-primary);
cursor: pointer;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
transition: background-color 0.15s;
}
.im-conversation-group-request__row:hover {
background-color: var(--el-fill-color-lighter);
}
/* 绿色「加好友」icon与置顶消息黄色 pushpin 同节奏仅换色调svg 强制 currentColor 应对暗色覆盖 */
.im-conversation-group-request__icon {
flex-shrink: 0;
color: var(--el-color-success);
}
.im-conversation-group-request__icon :deep(svg) {
fill: currentColor !important;
}
.im-conversation-group-request__text {
flex: 1;
min-width: 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.im-conversation-group-request__chevron {
flex-shrink: 0;
color: var(--el-text-color-placeholder);
}
</style>