A-Z排序的人员列表新增#处理首字母不在其中的;新增查看部门页面;处理聊天记录本地缓存时卡死的问题

This commit is contained in:
wangyifeng 2025-03-21 17:01:34 +08:00
parent d13ae03355
commit d781a94a89
11 changed files with 192 additions and 47 deletions

View File

@ -17,7 +17,7 @@ export const ChatMsgSysText = 1000 // 系统文本消息
export const ChatMsgSysGroupCreate = 1101 // 创建群聊消息
export const ChatMsgSysGroupMemberJoin = 1102 // 加入群聊消息
export const ChatMsgSysGroupMemberQuit = 1103 // 群成员退出群消息
export const ChatMsgSysGroupMemberKicked = 1104 // 移出群成员消息
export const ChatMsgSysGroupMemberKicked = 1104 // 移出群成员消息(普通群、项目群被踢)
export const ChatMsgSysGroupMessageRevoke = 1105 // 管理员撤回成员消息
export const ChatMsgSysGroupDismissed = 1106 // 群解散
export const ChatMsgSysGroupMuted = 1107 // 群禁言
@ -27,6 +27,8 @@ export const ChatMsgSysGroupMemberCancelMuted = 1110 // 群成员解除禁言
export const ChatMsgSysGroupNotice = 1111 // 编辑群公告
export const ChatMsgSysGroupTransfer = 1113 // 变更群主
export const ChatMsgSysGroupAdmin = 1114 // 设置管理员
export const ChatMsgSysGroupMemberRemoved = 1115 // 移出群成员消息(部门群、公司群自动移出)
export const ChatMsgSysGroupNameChange = 1116 // 修改群名称
export const ChatMsgTypeMapping = {
[ChatMsgTypeText]: '[文本消息]',
@ -56,7 +58,9 @@ export const ChatMsgTypeMapping = {
[ChatMsgSysGroupMemberCancelMuted]: '[群成员解除禁言消息]',
[ChatMsgSysGroupNotice]: '[群公告]',
[ChatMsgSysGroupTransfer]: '[转让群主]',
[ChatMsgSysGroupAdmin]: '[设置管理员]'
[ChatMsgSysGroupAdmin]: '[设置管理员]',
[ChatMsgSysGroupMemberRemoved]: '[移出群成员消息]',
[ChatMsgSysGroupNameChange]: '[修改群名称]'
}
// 消息类型 - 消息组件 映射关系
@ -87,7 +91,9 @@ export const MessageComponents = {
[ChatMsgSysGroupMemberMuted]: 'sys-group-member-muted-message',
[ChatMsgSysGroupMemberCancelMuted]: 'sys-group-member-cancel-muted-message',
[ChatMsgSysGroupTransfer]: 'sys-group-transfer-message',
[ChatMsgSysGroupAdmin]:'sys-group-admin-message'
[ChatMsgSysGroupAdmin]:'sys-group-admin-message',
[ChatMsgSysGroupMemberRemoved]:'sys-group-member-removed-message',
[ChatMsgSysGroupNameChange]:'sys-group-name-change-message'
}
// 可转发的消息类型

View File

@ -178,7 +178,7 @@ class Talk extends Base {
let newRecord = formatTalkRecord(this.getAccountId(), this.resource);
const {addDialogueRecord,addChatRecord} = useDialogueListStore()
// 群成员变化的消息,需要更新群成员列表
if ([1102, 1103, 1104].includes(record.msg_type)) {
if ([1102, 1103, 1104, 1115].includes(record.msg_type)) {
useDialogueStore().updateGroupMembers()
}
addDialogueRecord([newRecord],'add')

View File

@ -178,6 +178,14 @@
"navigationStyle": "custom",
"enablePullDownRefresh": false
}
},
{
"path": "pages/chatSettings/groupManage/manageGroupDeps",
"type": "page",
"style": {
"navigationStyle": "custom",
"enablePullDownRefresh": false
}
}
],
"globalStyle": {

View File

@ -69,7 +69,7 @@
alphabetItem?.memberList?.length > 0 &&
alphabetItem?.key !== '0'
"
:id="alphabetItem.key"
:id="alphabetItem.key === '#' ? 'special-hash' : alphabetItem.key"
:ref="
(el) => {
if (el) alphabetElementRefs[alphabetIndex] = el
@ -418,16 +418,47 @@ const assembleAlphabetMemberList = async (newMemberList) => {
String.fromCharCode(i + 65),
)
let tempAlphabet = []
//
let groupedData = {
'#': []
}
alphabet.forEach(letter => {
groupedData[letter] = []
})
//
if (newMemberList) {
newMemberList.forEach(item => {
const key = item.key?.toUpperCase()
if (alphabet.includes(key)) {
groupedData[key].push(item)
} else {
groupedData['#'].push(item)
}
})
}
//
alphabet.forEach((letter) => {
const matchedItems = newMemberList.filter((item) => item.key === letter)
if (matchedItems.length > 0) {
if (groupedData[letter].length > 0) {
tempAlphabet.push(letter)
}
resultMemberList.value.push({
key: letter,
memberList: matchedItems.length ? matchedItems : [],
memberList: groupedData[letter],
})
})
// #
if (groupedData['#'].length > 0) {
tempAlphabet.push('#')
resultMemberList.value.push({
key: '#',
memberList: groupedData['#'],
})
}
state.alphabet = tempAlphabet
if (props?.manageType === 'mention' && !props?.isMulSelect) {
resultMemberList.value.unshift({
@ -544,15 +575,17 @@ const getPosiByDep = async (departmentIdsArr) => {
const scrollToView = (alphabet) => {
state.currentAlphabet = alphabet
state.isAssign = true
console.log()
zPaging.value?.scrollIntoViewById(
alphabet,
document.getElementById('topArea')?.clientHeight
//
const offsetHeight = document.getElementById('topArea')?.clientHeight
? document.getElementById('topArea').clientHeight - 1
: props?.manageType === 'mention'
? 140
: 80,
)
: 80
// 使scrollIntoViewById
const targetId = alphabet === '#' ? 'special-hash' : alphabet
zPaging.value?.scrollIntoViewById(targetId, offsetHeight)
}
//
@ -754,3 +787,4 @@ defineExpose({
}
}
</style>

View File

@ -16,7 +16,8 @@
props?.item?.hasPointer &&
(props?.isManager ||
(!props?.isManager &&
props?.item?.label !== $t('chat.settings.groupName')))
(props?.item?.label !== $t('chat.settings.groupName') ||
props?.item?.label !== $t('chat.settings.groupType'))))
"
src="/src/static/image/chatSettings/pointer.png"
/>

View File

@ -0,0 +1,75 @@
<template>
<div class="outer-layer manage-group-deps-page">
<div class="root">
<ZPaging
ref="zPaging"
:show-scrollbar="false"
:use-virtual-list="true"
:virtual-list-col="5"
:auto="false"
:refresher-enabled="false"
:loading-more-enabled="false"
>
<template #top>
<customNavbar :title="$t('pageTitle.view.deps')"></customNavbar>
</template>
<div class="group-deps-list">
<div
class="group-deps-list-each"
v-for="item in groupParams.groupInfo.deptInfos"
:key="item.dept_id"
>
<span>{{ item.dept_name }}</span>
</div>
</div>
</ZPaging>
</div>
</div>
</template>
<script setup>
import settingFormItem from '../components/settingFormItem.vue'
import ZPaging from '@/uni_modules/z-paging/components/z-paging/z-paging.vue'
import { onLoad } from '@dcloudio/uni-app'
import { computed, onMounted, reactive } from 'vue'
import { useGroupStore } from '@/store'
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const groupStore = useGroupStore()
const groupParams = reactive({
groupInfo: computed(() => groupStore.groupInfo),
})
const state = reactive({})
onLoad((options) => {
console.log(options)
})
onMounted(() => {
console.log(groupParams.groupInfo.deptInfos)
})
</script>
<style scoped lang="scss">
.outer-layer {
flex: 1;
background-image: url('@/static/image/clockIn/z3280@3x.png');
background-size: cover;
background-repeat: no-repeat;
}
.group-deps-list {
margin: 20rpx 32rpx;
background-color: #fff;
.group-deps-list-each {
padding: 34rpx 32rpx;
span {
font-size: 28rpx;
font-weight: 500;
color: #333;
line-height: 40rpx;
}
}
}
</style>

View File

@ -397,7 +397,7 @@ const updateGroupInfos = () => {
},
{
label: t('chat.settings.groupType'),
hasPointer: false,
hasPointer: groupParams?.groupInfo?.group_type === 2 ? true : false,
value: groupType.value + '群',
subValue: '',
customInfo: '',
@ -463,6 +463,10 @@ const toManagePage = (label) => {
uni.navigateTo({
url: `/pages/chatSettings/groupManage/manageNotice?is_manager=${groupParams?.groupInfo?.is_manager}`,
})
} else if (label === t('chat.settings.groupType')) {
uni.navigateTo({
url: `/pages/chatSettings/groupManage/manageGroupDeps`,
})
} else if (label === t('chat.settings.groupMember')) {
uni.navigateTo({
url:

View File

@ -94,7 +94,7 @@
v-else
class="message-box record-box"
:class="{
'direction-rt': item.float == 'right',
'direction-rt': item.user_id === talkParams.uid,
'multi-select': dialogueStore.isOpenMultiSelect,
'multi-select-check': item.isCheck,
}"
@ -130,7 +130,7 @@
<div class="talk-title">
<span
class="nickname pointer"
v-show="talkParams.type == 2 && item.float == 'left'"
v-show="talkParams.type == 2 && item.user_id !== talkParams.uid"
>
<span class="at">@</span>
{{ item.nickname }}

View File

@ -7,8 +7,8 @@ import { createGlobalState, useStorage } from '@vueuse/core'
import { uniStorage } from '@/utils/uniStorage.js'
export const useDialogueListStore = createGlobalState(() => {
// const dialogueList = useStorage('dialogueList', [], uniStorage)
const dialogueList = ref([])
const dialogueList = useStorage('dialogueList', [], uniStorage)
// const dialogueList = ref([])
const zpagingRef = ref()
const virtualList = ref([])
@ -19,18 +19,47 @@ export const useDialogueListStore = createGlobalState(() => {
const addDialogueRecord = (newRecords, type = 'add') => {
console.log(newRecords)
const dialogue = lodash.cloneDeep(useDialogueStore())
const dialogue = useDialogueStore()
if (!dialogue || typeof dialogue !== 'object') return
// 检查是否已存在相同 index_name 的对话
const existingIndex = dialogueList.value.findIndex(
(item) => item.index_name === dialogue.index_name,
)
if (existingIndex === -1) {
// 如果不存在,直接添加
dialogueList.value.push(dialogue)
// 如果不存在,创建新对话,只保存需要的属性
const newDialogue = {
index_name: dialogue.index_name,
talk: {
username: dialogue.talk.username,
talk_type: dialogue.talk.talk_type,
receiver_id: dialogue.talk.receiver_id
},
online: dialogue.online,
records: dialogue.records || [],
unreadBubble: dialogue.unreadBubble,
isOpenMultiSelect: dialogue.isOpenMultiSelect,
isShowEditor: dialogue.isShowEditor,
isShowSessionList: dialogue.isShowSessionList,
isDismiss: dialogue.isDismiss,
members: dialogue.members.map(member => ({
id: member.id,
nickname: member.nickname,
avatar: member.avatar,
gender: member.gender,
leader: member.leader,
remark: member.remark,
online: member.online,
value: member.value,
key: member.key,
erp_user_id: member.erp_user_id,
is_mute: member.is_mute,
is_mine: member.is_mine
})),
forwardType: dialogue.forwardType
}
dialogueList.value.push(newDialogue)
} else {
// 如果对话存在,处理 records 数组
const { records = [] } = dialogue
newRecords.forEach((newRecord) => {
const recordIndex = dialogueList.value[existingIndex].records.findIndex(
(record) => record.msg_id === newRecord.msg_id,
@ -45,18 +74,11 @@ export const useDialogueListStore = createGlobalState(() => {
}
}
})
// 更新除 records 和 index_name 外的其他属性
const { index_name, records: _, ...updateProps } = dialogue
dialogueList.value[existingIndex] = {
...dialogueList.value[existingIndex],
...updateProps,
}
}
}
const updateDialogueRecord = (record) => {
const dialogue = lodash.cloneDeep(useDialogueStore())
const dialogue = useDialogueStore()
const item = getDialogueList(dialogue.index_name)
const recordIndex = item.records.findIndex(
(item) => item.msg_id === record.msg_id,
@ -79,7 +101,7 @@ export const useDialogueListStore = createGlobalState(() => {
}
const deleteDialogueRecord = (record) => {
const dialogue = lodash.cloneDeep(useDialogueStore())
const dialogue = useDialogueStore()
const item = getDialogueList(dialogue.index_name)
const recordIndex = item.records.findIndex(
(item) => item.msg_id === record.msg_id,
@ -105,7 +127,7 @@ export const useDialogueListStore = createGlobalState(() => {
}
const addChatRecord = (indexName, item) => {
const dialogue = lodash.cloneDeep(useDialogueStore())
const dialogue = useDialogueStore()
if (dialogue?.index_name === indexName) {
if (item?.file_num) {
const index = virtualList.value.findIndex(
@ -125,7 +147,7 @@ export const useDialogueListStore = createGlobalState(() => {
}
const batchDelDialogueRecord = (msgIds) => {
const dialogue = lodash.cloneDeep(useDialogueStore())
const dialogue = useDialogueStore()
const item = getDialogueList(dialogue.index_name)
item.records = item.records.filter((item) => !msgIds.includes(item.msg_id))
}
@ -143,7 +165,7 @@ export const useDialogueListStore = createGlobalState(() => {
//清空聊天记录时,同时清空本地保存的聊天记录
const clearDialogueRecord = () => {
const dialogue = lodash.cloneDeep(useDialogueStore())
const dialogue = useDialogueStore()
const item = getDialogueList(dialogue.index_name)
item.records = []
virtualList.value = []

View File

@ -153,5 +153,6 @@
"choose.deps.current": "当前",
"chat.mention.select": "选择提醒的人",
"do.phone.call": "拨打",
"popup.title.phone": "电话"
"popup.title.phone": "电话",
"pageTitle.view.deps": "查看部门"
}

View File

@ -3,14 +3,8 @@ import { parseTime } from './datetime'
export const KEY_INDEX_NAME = 'send_message_index_name'
export function formatTalkRecord(uid, data) {
data.float = 'center'
if (data.user_id > 0) {
data.float = data.user_id == uid ? 'right' : 'left'
}
// 不再设置float值,改为在模板中动态判断
data.isCheck = false
return data
}