diff --git a/package.json b/package.json
index d5e3680..5e0ba18 100644
--- a/package.json
+++ b/package.json
@@ -26,6 +26,7 @@
"protobufjs": "^7.4.0",
"uuid": "^10.0.0",
"vue": "^3.4.29",
+ "vue-audio-visual": "^3.0.10",
"vue-cropper": "^1.1.1",
"vue-router": "^4.3.3"
},
diff --git a/src/api/mts.js b/src/api/mts.js
index 29c832d..8a63f3e 100644
--- a/src/api/mts.js
+++ b/src/api/mts.js
@@ -7,3 +7,7 @@ export const mtsUploadService = (obj) => {
export const mtsImageService = (obj) => {
return request.get('/mts/image', { params: obj })
}
+
+export const mtsAudioService = (obj) => {
+ return request.get('/mts/audio', { params: obj })
+}
diff --git a/src/assets/svg/pause.svg b/src/assets/svg/pause.svg
new file mode 100644
index 0000000..b7359c7
--- /dev/null
+++ b/src/assets/svg/pause.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/svg/play.svg b/src/assets/svg/play.svg
new file mode 100644
index 0000000..f290141
--- /dev/null
+++ b/src/assets/svg/play.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/stores/audio.js b/src/stores/audio.js
new file mode 100644
index 0000000..dc2d563
--- /dev/null
+++ b/src/stores/audio.js
@@ -0,0 +1,41 @@
+import { mtsAudioService } from '@/api/mts'
+import { defineStore } from 'pinia'
+import { ref } from 'vue'
+
+// audio的缓存数据,不持久化存储
+export const audioStore = defineStore('anylink-audio', () => {
+ /**
+ * {
+ * objectId_01: {objectId: objectId_01, url: xxx},
+ * objectId_02: {objectId: objectId_02, url: xxx},
+ * }
+ */
+ const audio = ref({})
+
+ /**
+ * 在同一个session中的audio(id)集合
+ */
+ const audioInSession = ref({})
+
+ const setAudio = (sessionId, obj) => {
+ audio.value[obj.objectId] = obj
+ if (!audioInSession.value[sessionId]) {
+ audioInSession.value[sessionId] = []
+ }
+ audioInSession.value[sessionId].push(obj.objectId)
+ }
+
+ const loadAudio = async (sessionId, objectId) => {
+ if (!(objectId in audio.value)) {
+ const res = await mtsAudioService({ objectId: objectId })
+ setAudio(sessionId, res.data.data) // 缓存image数据
+ }
+ }
+
+ return {
+ audio,
+ audioInSession,
+ setAudio,
+ loadAudio
+ }
+})
diff --git a/src/stores/index.js b/src/stores/index.js
index e905ddc..f1870ef 100644
--- a/src/stores/index.js
+++ b/src/stores/index.js
@@ -13,3 +13,4 @@ export * from './search'
export * from './userCard'
export * from './groupCard'
export * from './image'
+export * from './audio'
diff --git a/src/views/message/MessageLayout.vue b/src/views/message/MessageLayout.vue
index d1ac626..52a8ae1 100644
--- a/src/views/message/MessageLayout.vue
+++ b/src/views/message/MessageLayout.vue
@@ -964,7 +964,7 @@ const onSendImage = ({ objectId }) => {
}
const onSendAudio = ({ objectId }) => {
- console.log('onSendAudio: ', objectId)
+ handleSendMessage(JSON.stringify({ type: msgContentType.AUDIO, value: `(${objectId})` }))
}
diff --git a/src/views/message/components/AudioMessage.vue b/src/views/message/components/AudioMessage.vue
deleted file mode 100644
index 0405a48..0000000
--- a/src/views/message/components/AudioMessage.vue
+++ /dev/null
@@ -1,180 +0,0 @@
-
-
-
-
-
-
-
-
-
-
{{ formatTime(currentTime) }} / {{ formatTime(duration) }}
-
-
-
-
diff --git a/src/views/message/components/AudioMsgBox.vue b/src/views/message/components/AudioMsgBox.vue
new file mode 100644
index 0000000..723fe5a
--- /dev/null
+++ b/src/views/message/components/AudioMsgBox.vue
@@ -0,0 +1,124 @@
+
+
+
+
+
+
+
+
+
{{ formatDuration }}
+
+
+
+
diff --git a/src/views/message/components/MessageItem.vue b/src/views/message/components/MessageItem.vue
index fe52398..020f3cd 100644
--- a/src/views/message/components/MessageItem.vue
+++ b/src/views/message/components/MessageItem.vue
@@ -3,12 +3,19 @@ import { computed, onMounted, h, createApp, watch, nextTick, reactive } from 'vu
import { ElImage } from 'element-plus'
import { WarningFilled } from '@element-plus/icons-vue'
import { MsgType } from '@/proto/msg'
-import { userStore, messageStore, groupStore, groupCardStore, imageStore } from '@/stores'
+import {
+ userStore,
+ messageStore,
+ groupStore,
+ groupCardStore,
+ imageStore,
+ audioStore
+} from '@/stores'
import { messageSysShowTime, showTimeFormat, jsonParseSafe } from '@/js/utils/common'
import UserAvatarIcon from '@/components/common/UserAvatarIcon.vue'
import { emojis } from '@/js/utils/emojis'
import { msgContentType, msgSendStatus } from '@/const/msgConst'
-import AudioMessage from '@/views/message/components/AudioMessage.vue'
+import AudioMsgBox from '@/views/message/components/AudioMsgBox.vue'
const props = defineProps([
'sessionId',
@@ -29,6 +36,7 @@ const messageData = messageStore()
const groupData = groupStore()
const groupCardData = groupCardStore()
const imageData = imageStore()
+const audioData = audioStore()
onMounted(() => {
rendering()
@@ -71,7 +79,12 @@ const renderComponent = async (content) => {
case msgContentType.TEXT:
return renderText(value)
case msgContentType.AUDIO:
- return renderAudio(value)
+ if (value.startsWith('(') && value.endsWith(')')) {
+ await audioData.loadAudio(props.sessionId, value.slice(1, -1))
+ return renderAudio(value)
+ } else {
+ return h('span', value)
+ }
case msgContentType.IMAGE:
if (value.startsWith('{') && value.endsWith('}')) {
await imageData.loadImageInfoFromContent(props.sessionId, value)
@@ -91,12 +104,6 @@ const renderComponent = async (content) => {
}
}
-const renderAudio = (url) => {
- return h(AudioMessage, {
- audioUrl: url
- })
-}
-
const renderText = (content) => {
return h('span', content)
}
@@ -196,6 +203,21 @@ const renderImage = (content) => {
}
}
+const renderAudio = (content) => {
+ const audioId = content.slice(1, -1)
+ const url = audioData.audio[audioId]?.url
+ if (url) {
+ return h(AudioMsgBox, {
+ audioUrl: import.meta.env.VITE_OSS_CORS_FLAG + url,
+ onLoad: () => {
+ emit('loadFinished')
+ }
+ })
+ } else {
+ return h('span', content)
+ }
+}
+
const msg = computed(() => {
return reactive({ ...messageData.getMsg(props.sessionId, props.msgId) })
})