vue-chat-kit 0.3.10 → 0.3.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/vue-chat-kit.css +1 -1
- package/dist/vue-chat-kit.es.js +4426 -2819
- package/dist/vue-chat-kit.umd.js +1 -1
- package/package.json +1 -1
- package/src/components/AvatarCrop.vue +16 -127
- package/src/components/ChatPanel.vue +491 -2675
- package/src/components/EmojiPicker.vue +2 -73
- package/src/components/chat/ChatWindow.vue +177 -0
- package/src/components/chat/ContentList.vue +300 -0
- package/src/components/chat/ContextMenu.vue +32 -0
- package/src/components/chat/GroupSidebar.vue +284 -0
- package/src/components/chat/MainArea.vue +87 -0
- package/src/components/chat/Sidebar.vue +52 -0
- package/src/components/chat/dialogs/AddFriendDialog.vue +62 -0
- package/src/components/chat/dialogs/CreateGroupDialog.vue +86 -0
- package/src/components/chat/dialogs/GroupDetailDialog.vue +132 -0
- package/src/components/ui/Button.vue +190 -0
- package/src/components/ui/Dialog.vue +194 -0
- package/src/components/ui/Empty.vue +66 -0
- package/src/components/ui/Input.vue +166 -0
- package/src/components/ui/Message.vue +186 -0
- package/src/components/ui/MessageBox.vue +143 -0
- package/src/components/ui/MessageManager.vue +92 -0
- package/src/components/ui/Switch.vue +65 -0
- package/src/components/ui/Tag.vue +68 -0
- package/src/components/ui/icons/ArrowDown.vue +5 -0
- package/src/components/ui/icons/ArrowRight.vue +5 -0
- package/src/components/ui/icons/Bell.vue +6 -0
- package/src/components/ui/icons/Camera.vue +6 -0
- package/src/components/ui/icons/ChatDotRound.vue +5 -0
- package/src/components/ui/icons/Check.vue +5 -0
- package/src/components/ui/icons/CircleCheck.vue +6 -0
- package/src/components/ui/icons/Clock.vue +6 -0
- package/src/components/ui/icons/Close.vue +5 -0
- package/src/components/ui/icons/Delete.vue +8 -0
- package/src/components/ui/icons/Edit.vue +6 -0
- package/src/components/ui/icons/Folder.vue +5 -0
- package/src/components/ui/icons/Minus.vue +5 -0
- package/src/components/ui/icons/Monitor.vue +7 -0
- package/src/components/ui/icons/Moon.vue +5 -0
- package/src/components/ui/icons/Picture.vue +7 -0
- package/src/components/ui/icons/Plus.vue +5 -0
- package/src/components/ui/icons/Search.vue +6 -0
- package/src/components/ui/icons/Setting.vue +6 -0
- package/src/components/ui/icons/Sunny.vue +6 -0
- package/src/components/ui/icons/User.vue +6 -0
- package/src/components/ui/icons/UserFilled.vue +6 -0
- package/src/components/ui/icons/Warning.vue +5 -0
- package/src/components/ui/icons/index.js +24 -0
- package/src/components/ui/index.js +10 -0
- package/src/composables/useFriendChat.js +10 -14
- package/src/composables/useGroupChat.js +140 -48
- package/src/composables/useMessage.js +21 -0
- package/src/composables/useMessageBox.js +98 -0
- package/src/composables/useTheme.js +140 -0
- package/src/config/index.js +1 -0
- package/src/const/index.js +1 -0
- package/src/const/theme.js +19 -0
- package/src/core/api.js +13 -2
- package/src/index.js +5 -5
- package/src/styles/_base.scss +38 -0
- package/src/styles/_variables.scss +43 -0
- package/src/styles/components/_add-friend-dialog.scss +45 -0
- package/src/styles/components/_avatar-crop.scss +120 -0
- package/src/styles/components/_chat-panel.scss +546 -0
- package/src/styles/components/_chat-window.scss +239 -0
- package/src/styles/components/_content-list.scss +260 -0
- package/src/styles/components/_context-menu.scss +35 -0
- package/src/styles/components/_create-group-dialog.scss +78 -0
- package/src/styles/components/_dialogs.scss +226 -0
- package/src/styles/components/_emoji-picker.scss +74 -0
- package/src/styles/components/_group-detail-dialog.scss +110 -0
- package/src/styles/components/_group-sidebar.scss +278 -0
- package/src/styles/components/_main-area.scss +94 -0
- package/src/styles/components/_sidebar.scss +83 -0
- package/src/styles/index.scss +18 -0
- package/src/styles/themes/_dark.scss +68 -0
- package/src/styles/themes/_index.scss +7 -0
- package/src/styles/themes/_light.scss +69 -0
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
4
|
+
<path d="M13.73 21a2 2 0 0 1-3.46 0" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
5
|
+
</svg>
|
|
6
|
+
</template>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<path d="M23 19V5C23 3.89543 22.1046 3 21 3H17L15 1H9L7 3H3C1.89543 3 1 3.89543 1 5V19C1 20.1046 1.89543 21 3 21H21C22.1046 21 23 20.1046 23 19Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
4
|
+
<path d="M12 17C14.7614 17 17 14.7614 17 12C17 9.23858 14.7614 7 12 7C9.23858 7 7 9.23858 7 12C7 14.7614 9.23858 17 12 17Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
5
|
+
</svg>
|
|
6
|
+
</template>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<path d="M21 15C21 18.866 16.9706 22 12 22C8.141 22 4.8475 19.826 3.5 16.5M21 15C21 6 12 2 12 2C12 2 3 6 3 15C3 16.3958 3.38031 17.6959 4.06703 18.8409M21 15C21 16.3958 20.6197 17.6959 19.933 18.8409M3.5 16.5C3.30485 16.7949 3.15853 17.1078 3.06817 17.4314M4.06703 18.8409L3 22L7 20" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
4
|
+
</svg>
|
|
5
|
+
</template>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2"/>
|
|
4
|
+
<path d="M8 12L11 15L16 9" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
5
|
+
</svg>
|
|
6
|
+
</template>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2"/>
|
|
4
|
+
<path d="M12 6V12L16 14" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
5
|
+
</svg>
|
|
6
|
+
</template>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<path d="M3 6H21" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
|
|
4
|
+
<path d="M19 6V20C19 21.1046 18.1046 22 17 22H7C5.89543 22 5 21.1046 5 20V6M8 6V4C8 2.89543 8.89543 2 10 2H14C15.1046 2 16 2.89543 16 4V6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
5
|
+
<path d="M10 11V17" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
|
|
6
|
+
<path d="M14 11V17" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
|
|
7
|
+
</svg>
|
|
8
|
+
</template>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<path d="M11 4H4C2.89543 4 2 4.89543 2 6V20C2 21.1046 2.89543 22 4 22H18C19.1046 22 20 21.1046 20 20V13" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
4
|
+
<path d="M18.5 2.5C18.8978 2.10218 19.4374 1.87869 20 1.87869C20.5626 1.87869 21.1022 2.10218 21.5 2.5C21.8978 2.89782 22.1213 3.43744 22.1213 4C22.1213 4.56256 21.8978 5.10218 21.5 5.5L12 15L8 16L9 12L18.5 2.5Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
5
|
+
</svg>
|
|
6
|
+
</template>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<path d="M3 7V5C3 3.89543 3.89543 3 5 3H8L10 6H19C20.1046 6 21 6.89543 21 8V19C21 20.1046 20.1046 21 19 21H5C3.89543 21 3 20.1046 3 19V7Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
4
|
+
</svg>
|
|
5
|
+
</template>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<rect x="2" y="3" width="20" height="14" rx="2" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
4
|
+
<path d="M8 21H16" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
5
|
+
<path d="M12 17V21" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
6
|
+
</svg>
|
|
7
|
+
</template>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<path d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
4
|
+
</svg>
|
|
5
|
+
</template>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<path d="M21 19V5C21 3.89543 20.1046 3 19 3H5C3.89543 3 3 3.89543 3 5V19C3 20.1046 3.89543 21 5 21H19C20.1046 21 21 20.1046 21 19Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
4
|
+
<path d="M8.5 10C9.88071 10 11 8.88071 11 7.5C11 6.11929 9.88071 5 8.5 5C7.11929 5 6 6.11929 6 7.5C6 8.88071 7.11929 10 8.5 10Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
5
|
+
<path d="M21 15L16 10L5 21" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
6
|
+
</svg>
|
|
7
|
+
</template>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<path d="M11 19C15.4183 19 19 15.4183 19 11C19 6.58172 15.4183 3 11 3C6.58172 3 3 6.58172 3 11C3 15.4183 6.58172 19 11 19Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
4
|
+
<path d="M21 21L16.65 16.65" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
5
|
+
</svg>
|
|
6
|
+
</template>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<path d="M12 15C13.6569 15 15 13.6569 15 12C15 10.3431 13.6569 9 12 9C10.3431 9 9 10.3431 9 12C9 13.6569 10.3431 15 12 15Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
4
|
+
<path d="M19.4 15C19.1 15.6 18.6 16.1 18 16.4L16.5 13.9C16.2 13.8 15.8 13.8 15.5 13.9L14.5 16.4C13.9 16.8 13 16.9 12.4 16.6L12 14.4C12 14.1 11.8 13.9 11.6 13.9H9.6C9.4 13.9 9.1 14.1 9 14.4L8.6 16.6C8 16.9 7.1 16.8 6.5 16.4L5.5 13.9C5.2 13.8 4.8 13.8 4.5 13.9L3 16.4C2.4 16.1 1.9 15.6 1.6 15L1 13C0.7 12.3 0.9 11.5 1.6 11L4.5 8.5C4.8 8.2 4.8 7.8 4.5 7.5L3 5C3.3 4.4 3.8 3.9 4.4 3.6L7.5 2.5C8.1 2.3 8.8 2.5 9.2 2.9L10.2 5.4C10.5 5.7 10.8 5.8 11.2 5.8H13.2C13.5 5.8 13.8 5.7 14.1 5.4L15.1 2.9C15.5 2.5 16.2 2.3 16.8 2.5L19.9 3.6C20.5 3.9 21 4.4 21.3 5L22.8 7.5C23.1 7.8 23.1 8.2 22.8 8.5L20 11C20.3 11.5 20.4 12.2 20.1 12.8L19.4 15Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
5
|
+
</svg>
|
|
6
|
+
</template>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<path d="M12 17C14.7614 17 17 14.7614 17 12C17 9.23858 14.7614 7 12 7C9.23858 7 7 9.23858 7 12C7 14.7614 9.23858 17 12 17Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
4
|
+
<path d="M12 1V3M12 21V23M4.22 4.22L5.64 5.64M18.36 18.36L19.78 19.78M1 12H3M21 12H23M4.22 19.78L5.64 18.36M18.36 5.64L19.78 4.22" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
5
|
+
</svg>
|
|
6
|
+
</template>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<path d="M20 21V19C20 17.9391 19.5786 16.9217 18.8284 16.1716C18.0783 15.4214 17.0609 15 16 15H8C6.93913 15 5.92172 15.4214 5.17157 16.1716C4.42143 16.9217 4 17.9391 4 19V21" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
4
|
+
<path d="M12 11C14.2091 11 16 9.20914 16 7C16 4.79086 14.2091 3 12 3C9.79086 3 8 4.79086 8 7C8 9.20914 9.79086 11 12 11Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
5
|
+
</svg>
|
|
6
|
+
</template>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<path d="M12 13C14.7614 13 17 10.7614 17 8C17 5.23858 14.7614 3 12 3C9.23858 3 7 5.23858 7 8C7 10.7614 9.23858 13 12 13Z" fill="currentColor"/>
|
|
4
|
+
<path d="M20 21V19C20 17.9391 19.5786 16.9217 18.8284 16.1716C18.0783 15.4214 17.0609 15 16 15H8C6.93913 15 5.92172 15.4214 5.17157 16.1716C4.42143 16.9217 4 17.9391 4 19V21" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
5
|
+
</svg>
|
|
6
|
+
</template>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<path d="M12 9V13M12 17H12.01M21 12C21 16.9706 16.9706 21 12 21 7.02944 21 3 16.9706 3 12 3 7.02944 7.02944 3 12 3 16.9706 3 21 7.02944 21 12 21Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
4
|
+
</svg>
|
|
5
|
+
</template>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// 图标组件导出
|
|
2
|
+
export { default as Search } from './Search.vue'
|
|
3
|
+
export { default as User } from './User.vue'
|
|
4
|
+
export { default as UserFilled } from './UserFilled.vue'
|
|
5
|
+
export { default as ArrowDown } from './ArrowDown.vue'
|
|
6
|
+
export { default as ArrowRight } from './ArrowRight.vue'
|
|
7
|
+
export { default as Folder } from './Folder.vue'
|
|
8
|
+
export { default as ChatDotRound } from './ChatDotRound.vue'
|
|
9
|
+
export { default as Check } from './Check.vue'
|
|
10
|
+
export { default as CircleCheck } from './CircleCheck.vue'
|
|
11
|
+
export { default as Close } from './Close.vue'
|
|
12
|
+
export { default as Delete } from './Delete.vue'
|
|
13
|
+
export { default as Setting } from './Setting.vue'
|
|
14
|
+
export { default as Camera } from './Camera.vue'
|
|
15
|
+
export { default as Edit } from './Edit.vue'
|
|
16
|
+
export { default as Plus } from './Plus.vue'
|
|
17
|
+
export { default as Minus } from './Minus.vue'
|
|
18
|
+
export { default as Sunny } from './Sunny.vue'
|
|
19
|
+
export { default as Moon } from './Moon.vue'
|
|
20
|
+
export { default as Monitor } from './Monitor.vue'
|
|
21
|
+
export { default as Warning } from './Warning.vue'
|
|
22
|
+
export { default as Picture } from './Picture.vue'
|
|
23
|
+
export { default as Bell } from './Bell.vue'
|
|
24
|
+
export { default as Clock } from './Clock.vue'
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// UI 组件导出
|
|
2
|
+
export { default as Button } from './Button.vue'
|
|
3
|
+
export { default as Dialog } from './Dialog.vue'
|
|
4
|
+
export { default as Input } from './Input.vue'
|
|
5
|
+
export { default as Empty } from './Empty.vue'
|
|
6
|
+
export { default as Message } from './Message.vue'
|
|
7
|
+
export { default as MessageManager } from './MessageManager.vue'
|
|
8
|
+
export { default as MessageBox } from './MessageBox.vue'
|
|
9
|
+
export { default as Switch } from './Switch.vue'
|
|
10
|
+
export { default as Tag } from './Tag.vue'
|
|
@@ -36,7 +36,7 @@ export function useFriendChat(core) {
|
|
|
36
36
|
return list.map(item => ({
|
|
37
37
|
id: item.username,
|
|
38
38
|
name: item.username,
|
|
39
|
-
avatar: item.avatar ? `${config.api.baseUrl}${item.avatar}` :
|
|
39
|
+
avatar: item.avatar ? `${config.api.baseUrl}${item.avatar}` : `https://api.dicebear.com/7.x/avataaars/svg?seed=${item.username}`,
|
|
40
40
|
online: item.online,
|
|
41
41
|
lastMsg: item.lastMsg || '暂无消息',
|
|
42
42
|
lastTime: item.lastTime,
|
|
@@ -56,7 +56,7 @@ export function useFriendChat(core) {
|
|
|
56
56
|
return list.map(item => ({
|
|
57
57
|
id: item.username,
|
|
58
58
|
name: item.username,
|
|
59
|
-
avatar: item.avatar ? `${config.api.baseUrl}${item.avatar}` :
|
|
59
|
+
avatar: item.avatar ? `${config.api.baseUrl}${item.avatar}` : `https://api.dicebear.com/7.x/avataaars/svg?seed=${item.username}`,
|
|
60
60
|
online: item.online,
|
|
61
61
|
isChatting: item.isChatting
|
|
62
62
|
}))
|
|
@@ -111,20 +111,16 @@ export function useFriendChat(core) {
|
|
|
111
111
|
const res = await api.getFriends(myUsername)
|
|
112
112
|
const allFriends = res.data || []
|
|
113
113
|
friendList.value = allFriends
|
|
114
|
+
|
|
115
|
+
console.log('[VueChatKit] 获取到的好友列表:', friendList.value)
|
|
116
|
+
console.log('[VueChatKit] 所有好友的 isChatting:', friendList.value.map(f => ({ username: f.username, isChatting: f.isChatting })))
|
|
117
|
+
|
|
114
118
|
chatList.value = allFriends.filter(item => item.isChatting === 1)
|
|
115
119
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
const messages = historyRes.data || []
|
|
121
|
-
friend.unReadNum = messages.filter(msg =>
|
|
122
|
-
msg.isRead === 0 && msg.sendUsername === friend.username
|
|
123
|
-
).length
|
|
124
|
-
} catch {
|
|
125
|
-
friend.unReadNum = 0
|
|
126
|
-
}
|
|
127
|
-
}
|
|
120
|
+
console.log('[VueChatKit] 正在聊天的好友列表:', chatList.value)
|
|
121
|
+
|
|
122
|
+
// 未读数直接从接口返回的数据中获取,不再单独请求历史记录
|
|
123
|
+
// 假设接口返回的 friend 对象中已经包含 unReadNum 字段
|
|
128
124
|
} catch (error) {
|
|
129
125
|
console.error('[VueChatKit] 获取好友列表失败', error)
|
|
130
126
|
}
|
|
@@ -9,6 +9,7 @@ export function useGroupChat(core) {
|
|
|
9
9
|
// ========== 状态 ==========
|
|
10
10
|
const activeTab = ref('friends')
|
|
11
11
|
const groupList = ref([])
|
|
12
|
+
const chatList = ref([]) // 正在聊天的群聊列表
|
|
12
13
|
const currentSelectGroup = ref(null)
|
|
13
14
|
const groupMsgList = ref([])
|
|
14
15
|
const groupMemberList = ref([])
|
|
@@ -22,6 +23,7 @@ export function useGroupChat(core) {
|
|
|
22
23
|
const selectedMembersForInvite = ref([])
|
|
23
24
|
// 新增状态
|
|
24
25
|
const groupInfoVisible = ref(false)
|
|
26
|
+
const isRemoveMemberMode = ref(false) // 是否处于移除成员模式
|
|
25
27
|
const editingGroupInfo = ref({
|
|
26
28
|
groupNickname: '',
|
|
27
29
|
remark: '',
|
|
@@ -53,6 +55,69 @@ export function useGroupChat(core) {
|
|
|
53
55
|
})
|
|
54
56
|
|
|
55
57
|
// ========== 计算属性 ==========
|
|
58
|
+
|
|
59
|
+
// 判断当前用户是否是群主:优先检查群成员列表中当前用户的 memberType === 0
|
|
60
|
+
const isGroupOwner = computed(() => {
|
|
61
|
+
console.log('[VueChatKit] 检查是否群主:', {
|
|
62
|
+
myUsername,
|
|
63
|
+
groupMemberCount: groupMemberList.value?.length
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
if (!currentSelectGroup.value) {
|
|
67
|
+
console.log('[VueChatKit] 没有选择群')
|
|
68
|
+
return false
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// 优先检查群成员列表中当前用户的 memberType === 0
|
|
72
|
+
if (groupMemberList.value && groupMemberList.value.length > 0) {
|
|
73
|
+
const currentUserInGroup = groupMemberList.value.find(
|
|
74
|
+
m => m.username === myUsername
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
console.log('[VueChatKit] 当前用户在群成员:', currentUserInGroup)
|
|
78
|
+
|
|
79
|
+
if (currentUserInGroup) {
|
|
80
|
+
if (currentUserInGroup.memberType === 0) {
|
|
81
|
+
console.log('[VueChatKit] ✅ 当前用户是群主 (memberType=0)')
|
|
82
|
+
return true
|
|
83
|
+
}
|
|
84
|
+
console.log('[VueChatKit] 当前用户 memberType:', currentUserInGroup.memberType)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// 兜底逻辑:检查群的 ownerUsername/owner 字段
|
|
89
|
+
if (currentSelectGroup.value.ownerUsername === myUsername ||
|
|
90
|
+
currentSelectGroup.value.owner === myUsername) {
|
|
91
|
+
console.log('[VueChatKit] ✅ 通过群 owner 字段判断是群主')
|
|
92
|
+
return true
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
console.log('[VueChatKit] ❌ 当前用户不是群主')
|
|
96
|
+
return false
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
// 从群成员列表中获取群主用户名
|
|
100
|
+
const groupOwnerUsername = computed(() => {
|
|
101
|
+
if (!currentSelectGroup.value) return ''
|
|
102
|
+
|
|
103
|
+
// 优先从群信息中获取
|
|
104
|
+
if (currentSelectGroup.value.ownerUsername) {
|
|
105
|
+
return currentSelectGroup.value.ownerUsername
|
|
106
|
+
}
|
|
107
|
+
if (currentSelectGroup.value.owner) {
|
|
108
|
+
return currentSelectGroup.value.owner
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// 从成员列表中查找 memberType === 0 的用户
|
|
112
|
+
if (groupMemberList.value.length > 0) {
|
|
113
|
+
const ownerMember = groupMemberList.value.find(m => m.memberType === 0)
|
|
114
|
+
if (ownerMember) {
|
|
115
|
+
return ownerMember.username
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return ''
|
|
120
|
+
})
|
|
56
121
|
|
|
57
122
|
// 过滤后的群聊列表
|
|
58
123
|
const filteredGroupList = computed(() => {
|
|
@@ -65,41 +130,23 @@ export function useGroupChat(core) {
|
|
|
65
130
|
)
|
|
66
131
|
}
|
|
67
132
|
return list.map(item => {
|
|
68
|
-
|
|
69
|
-
const memberAvatars =
|
|
70
|
-
username: member
|
|
71
|
-
avatar:
|
|
72
|
-
|
|
73
|
-
: `https://api.dicebear.com/7.x/avataaars/svg?seed=${member.username}`
|
|
74
|
-
}))
|
|
133
|
+
// 使用接口返回的 groupAvatarList 来生成 memberAvatars
|
|
134
|
+
const memberAvatars = (item.groupAvatarList || []).map((avatarPath, index) => ({
|
|
135
|
+
username: `member-${index}`,
|
|
136
|
+
avatar: `${config.api.baseUrl}${avatarPath}`
|
|
137
|
+
})).slice(0, 4)
|
|
75
138
|
|
|
76
|
-
//
|
|
77
|
-
|
|
78
|
-
if (item.lastMsg) {
|
|
79
|
-
lastMsg = item.lastMsg
|
|
80
|
-
} else if (item.lastMessage) {
|
|
81
|
-
lastMsg = item.lastMessage
|
|
82
|
-
} else if (item.latestMessage) {
|
|
83
|
-
lastMsg = item.latestMessage
|
|
84
|
-
}
|
|
139
|
+
// 获取最后一条消息
|
|
140
|
+
const lastMsg = item.lastMsgContent || '暂无消息'
|
|
85
141
|
|
|
86
|
-
//
|
|
87
|
-
|
|
88
|
-
if (item.unReadNum !== undefined && item.unReadNum !== null) {
|
|
89
|
-
unread = item.unReadNum
|
|
90
|
-
} else if (item.unreadCount !== undefined && item.unreadCount !== null) {
|
|
91
|
-
unread = item.unreadCount
|
|
92
|
-
} else if (item.unread !== undefined && item.unread !== null) {
|
|
93
|
-
unread = item.unread
|
|
94
|
-
}
|
|
142
|
+
// 获取最后消息发送者
|
|
143
|
+
const lastMsgSender = item.lastMsgSender || ''
|
|
95
144
|
|
|
96
|
-
//
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
lastTime = item.lastMsgTime
|
|
102
|
-
}
|
|
145
|
+
// 获取未读数
|
|
146
|
+
const unread = item.unreadCount || 0
|
|
147
|
+
|
|
148
|
+
// 获取最后时间
|
|
149
|
+
const lastTime = item.lastMsgTime
|
|
103
150
|
|
|
104
151
|
return {
|
|
105
152
|
id: item.groupId,
|
|
@@ -110,9 +157,10 @@ export function useGroupChat(core) {
|
|
|
110
157
|
avatar: `https://api.dicebear.com/7.x/avataaars/svg?seed=${item.groupId}`,
|
|
111
158
|
memberAvatars: memberAvatars,
|
|
112
159
|
lastMsg: lastMsg,
|
|
160
|
+
lastMsgSender: lastMsgSender,
|
|
113
161
|
lastTime: lastTime,
|
|
114
162
|
unread: unread,
|
|
115
|
-
memberCount: item.
|
|
163
|
+
memberCount: item.memberTotal || 0,
|
|
116
164
|
// 保留原始字段用于编辑功能
|
|
117
165
|
notice: item.notice,
|
|
118
166
|
groupNickname: item.groupNickname
|
|
@@ -160,19 +208,43 @@ export function useGroupChat(core) {
|
|
|
160
208
|
const res = await api.getMyGroups(myUsername)
|
|
161
209
|
groupList.value = res.data || []
|
|
162
210
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
}
|
|
211
|
+
console.log('[VueChatKit] 获取到的群聊列表:', groupList.value)
|
|
212
|
+
console.log('[VueChatKit] 所有群聊的 groupChatStatus:', groupList.value.map(g => ({ groupId: g.groupId, groupName: g.groupName, groupChatStatus: g.groupChatStatus })))
|
|
213
|
+
|
|
214
|
+
chatList.value = groupList.value.filter(item => item.groupChatStatus === 1)
|
|
215
|
+
|
|
216
|
+
console.log('[VueChatKit] 正在聊天的群聊列表:', chatList.value)
|
|
217
|
+
|
|
218
|
+
// 不在这里获取所有群成员,改为按需获取
|
|
172
219
|
} catch (error) {
|
|
173
220
|
console.error('[VueChatKit] 获取群聊列表失败', error)
|
|
174
221
|
}
|
|
175
222
|
}
|
|
223
|
+
|
|
224
|
+
// 按需获取单个群的成员
|
|
225
|
+
const ensureGroupMembers = async (groupId) => {
|
|
226
|
+
if (!groupMembersMap.value[groupId]) {
|
|
227
|
+
try {
|
|
228
|
+
const membersRes = await api.getGroupMembers(groupId, myUsername)
|
|
229
|
+
groupMembersMap.value[groupId] = membersRes.data || []
|
|
230
|
+
} catch (err) {
|
|
231
|
+
console.error(`[VueChatKit] 获取群 ${groupId} 成员失败`, err)
|
|
232
|
+
groupMembersMap.value[groupId] = []
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// 设置群聊聊天状态
|
|
238
|
+
const setGroupToChatStatus = async (groupId, status = 1) => {
|
|
239
|
+
try {
|
|
240
|
+
await api.setGroupChatStatus(groupId, myUsername, status)
|
|
241
|
+
await getGroupList()
|
|
242
|
+
return true
|
|
243
|
+
} catch (error) {
|
|
244
|
+
console.error('[VueChatKit] 设置群聊状态失败', error)
|
|
245
|
+
return false
|
|
246
|
+
}
|
|
247
|
+
}
|
|
176
248
|
|
|
177
249
|
// 获取群聊历史消息
|
|
178
250
|
const getGroupHistory = async (groupId) => {
|
|
@@ -206,9 +278,11 @@ export function useGroupChat(core) {
|
|
|
206
278
|
// 3. 设置当前选中的群
|
|
207
279
|
currentSelectGroup.value = group
|
|
208
280
|
|
|
209
|
-
// 4.
|
|
281
|
+
// 4. 按需加载群成员和历史聊天消息
|
|
282
|
+
await ensureGroupMembers(group.groupId)
|
|
210
283
|
await getGroupHistory(group.groupId)
|
|
211
|
-
|
|
284
|
+
// 同时也更新 groupMemberList 供当前选中的群使用
|
|
285
|
+
groupMemberList.value = groupMembersMap.value[group.groupId] || []
|
|
212
286
|
|
|
213
287
|
scrollToBottom()
|
|
214
288
|
}
|
|
@@ -288,10 +362,14 @@ export function useGroupChat(core) {
|
|
|
288
362
|
}
|
|
289
363
|
|
|
290
364
|
// 开始编辑字段
|
|
291
|
-
const startEditField = (field) => {
|
|
365
|
+
const startEditField = async (field) => {
|
|
292
366
|
// 先确保有最新数据
|
|
293
367
|
if (!currentGroupInfo.value && currentSelectGroup.value) {
|
|
294
|
-
fetchGroupDetail(currentSelectGroup.value.groupId)
|
|
368
|
+
await fetchGroupDetail(currentSelectGroup.value.groupId)
|
|
369
|
+
}
|
|
370
|
+
// 初始化临时编辑值
|
|
371
|
+
if (currentGroupInfo.value) {
|
|
372
|
+
tempEditValues.value[field] = currentGroupInfo.value[field] || ''
|
|
295
373
|
}
|
|
296
374
|
editingFields.value[field] = true
|
|
297
375
|
}
|
|
@@ -386,22 +464,30 @@ export function useGroupChat(core) {
|
|
|
386
464
|
const removeGroupMember = async (targetUsername) => {
|
|
387
465
|
if (!currentSelectGroup.value) return false
|
|
388
466
|
try {
|
|
467
|
+
console.log('[VueChatKit] 开始移除成员:', targetUsername)
|
|
389
468
|
const res = await api.removeGroupMember(
|
|
390
469
|
currentSelectGroup.value.groupId,
|
|
391
470
|
myUsername,
|
|
392
471
|
targetUsername
|
|
393
472
|
)
|
|
394
473
|
if (res.code === 200) {
|
|
474
|
+
console.log('[VueChatKit] 移除成员成功,刷新成员列表')
|
|
395
475
|
await getGroupMembers(currentSelectGroup.value.groupId)
|
|
476
|
+
// 如果移除的成员在当前显示列表中,刷新成员列表
|
|
477
|
+
if (isRemoveMemberMode.value) {
|
|
478
|
+
isRemoveMemberMode.value = false
|
|
479
|
+
}
|
|
396
480
|
return true
|
|
397
481
|
}
|
|
482
|
+
console.warn('[VueChatKit] 移除成员失败,返回结果:', res)
|
|
398
483
|
return false
|
|
399
484
|
} catch (error) {
|
|
400
|
-
console.error('[VueChatKit]
|
|
485
|
+
console.error('[VueChatKit] 移除成员异常', error)
|
|
401
486
|
return false
|
|
402
487
|
}
|
|
403
488
|
}
|
|
404
489
|
|
|
490
|
+
|
|
405
491
|
// 转让群主
|
|
406
492
|
const transferGroupOwner = async (newOwnerUsername) => {
|
|
407
493
|
if (!currentSelectGroup.value) return false
|
|
@@ -687,6 +773,7 @@ export function useGroupChat(core) {
|
|
|
687
773
|
// 状态
|
|
688
774
|
activeTab,
|
|
689
775
|
groupList,
|
|
776
|
+
chatList,
|
|
690
777
|
currentSelectGroup,
|
|
691
778
|
groupMsgList,
|
|
692
779
|
groupMemberList,
|
|
@@ -699,6 +786,7 @@ export function useGroupChat(core) {
|
|
|
699
786
|
inviteMemberDialogVisible,
|
|
700
787
|
selectedMembersForInvite,
|
|
701
788
|
groupInfoVisible,
|
|
789
|
+
isRemoveMemberMode,
|
|
702
790
|
editingGroupInfo,
|
|
703
791
|
editingMemberNick,
|
|
704
792
|
memberNickDialogVisible,
|
|
@@ -711,6 +799,8 @@ export function useGroupChat(core) {
|
|
|
711
799
|
// 计算属性
|
|
712
800
|
filteredGroupList,
|
|
713
801
|
currentGroupMessages,
|
|
802
|
+
isGroupOwner,
|
|
803
|
+
groupOwnerUsername,
|
|
714
804
|
|
|
715
805
|
// 方法
|
|
716
806
|
getGroupList,
|
|
@@ -741,7 +831,9 @@ export function useGroupChat(core) {
|
|
|
741
831
|
updateSingleGroupField,
|
|
742
832
|
startEditField,
|
|
743
833
|
cancelEditField,
|
|
744
|
-
saveEditField
|
|
834
|
+
saveEditField,
|
|
835
|
+
setGroupToChatStatus,
|
|
836
|
+
ensureGroupMembers
|
|
745
837
|
}
|
|
746
838
|
}
|
|
747
839
|
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { inject } from 'vue'
|
|
2
|
+
|
|
3
|
+
const MESSAGE_MANAGER_KEY = Symbol('messageManager')
|
|
4
|
+
|
|
5
|
+
export const useMessage = () => {
|
|
6
|
+
const manager = inject(MESSAGE_MANAGER_KEY)
|
|
7
|
+
|
|
8
|
+
if (!manager) {
|
|
9
|
+
console.warn('MessageManager not found. Please wrap your app with MessageManager component.')
|
|
10
|
+
// 提供一个后备实现
|
|
11
|
+
return {
|
|
12
|
+
show: (msg) => console.log('[Message]', msg),
|
|
13
|
+
success: (msg) => console.log('[Success]', msg),
|
|
14
|
+
warning: (msg) => console.warn('[Warning]', msg),
|
|
15
|
+
error: (msg) => console.error('[Error]', msg),
|
|
16
|
+
info: (msg) => console.info('[Info]', msg)
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return manager
|
|
21
|
+
}
|