feat: 添加音频播放埋点功能并引入uuid库
添加音频播放器的播放和暂停事件监听,用于学习时长埋点统计 引入uuid库生成唯一标识符,用于跟踪用户操作
Showing
3 changed files
with
68 additions
and
1 deletions
| ... | @@ -30,6 +30,7 @@ | ... | @@ -30,6 +30,7 @@ |
| 30 | "dayjs": "^1.11.13", | 30 | "dayjs": "^1.11.13", |
| 31 | "lodash": "^4.17.21", | 31 | "lodash": "^4.17.21", |
| 32 | "swiper": "^11.2.6", | 32 | "swiper": "^11.2.6", |
| 33 | + "uuid": "^11.1.0", | ||
| 33 | "vant": "^4.9.18", | 34 | "vant": "^4.9.18", |
| 34 | "vconsole": "^3.15.1", | 35 | "vconsole": "^3.15.1", |
| 35 | "video.js": "^7.21.7", | 36 | "video.js": "^7.21.7", | ... | ... |
| ... | @@ -29,7 +29,7 @@ | ... | @@ -29,7 +29,7 @@ |
| 29 | <div v-if="course.course_type === 'audio'" class="w-full relative" | 29 | <div v-if="course.course_type === 'audio'" class="w-full relative" |
| 30 | style="border-bottom: 1px solid #F3F4F6;"> | 30 | style="border-bottom: 1px solid #F3F4F6;"> |
| 31 | <!-- 音频播放器 --> | 31 | <!-- 音频播放器 --> |
| 32 | - <AudioPlayer v-if="audioList.length" :songs="audioList" /> | 32 | + <AudioPlayer v-if="audioList.length" :songs="audioList" @play="onAudioPlay" @pause="onAudioPause" /> |
| 33 | </div> | 33 | </div> |
| 34 | <!-- 图片列表展示区域 --> | 34 | <!-- 图片列表展示区域 --> |
| 35 | <div v-if="course.course_type === 'image'" class="w-full relative"> | 35 | <div v-if="course.course_type === 'image'" class="w-full relative"> |
| ... | @@ -250,6 +250,7 @@ import AudioPlayer from '@/components/ui/AudioPlayer.vue'; | ... | @@ -250,6 +250,7 @@ import AudioPlayer from '@/components/ui/AudioPlayer.vue'; |
| 250 | import dayjs from 'dayjs'; | 250 | import dayjs from 'dayjs'; |
| 251 | import { formatDate } from '@/utils/tools' | 251 | import { formatDate } from '@/utils/tools' |
| 252 | import axios from 'axios'; | 252 | import axios from 'axios'; |
| 253 | +import { v4 as uuidv4 } from "uuid"; | ||
| 253 | 254 | ||
| 254 | import PdfPreview from '@/components/ui/PdfPreview.vue'; | 255 | import PdfPreview from '@/components/ui/PdfPreview.vue'; |
| 255 | 256 | ||
| ... | @@ -289,10 +290,14 @@ const startPlay = async () => { | ... | @@ -289,10 +290,14 @@ const startPlay = async () => { |
| 289 | // 处理视频播放状态 | 290 | // 处理视频播放状态 |
| 290 | const handleVideoPlay = () => { | 291 | const handleVideoPlay = () => { |
| 291 | isPlaying.value = true; | 292 | isPlaying.value = true; |
| 293 | + // 学习时长埋点开始 | ||
| 294 | + startAction(); | ||
| 292 | }; | 295 | }; |
| 293 | 296 | ||
| 294 | const handleVideoPause = () => { | 297 | const handleVideoPause = () => { |
| 295 | // 保持视频播放器可见,只在初始状态显示封面 | 298 | // 保持视频播放器可见,只在初始状态显示封面 |
| 299 | + // 学习时长埋点结束 | ||
| 300 | + endAction(); | ||
| 296 | }; | 301 | }; |
| 297 | 302 | ||
| 298 | // 图片预览相关 | 303 | // 图片预览相关 |
| ... | @@ -678,6 +683,62 @@ const downloadFile = ({ title, url }) => { | ... | @@ -678,6 +683,62 @@ const downloadFile = ({ title, url }) => { |
| 678 | console.error('下载文件出错:', error); | 683 | console.error('下载文件出错:', error); |
| 679 | }); | 684 | }); |
| 680 | } | 685 | } |
| 686 | + | ||
| 687 | +/** | ||
| 688 | + * 音频播放事件 | ||
| 689 | + * @param audio 音频对象 | ||
| 690 | + */ | ||
| 691 | +const onAudioPlay = (audio) => { | ||
| 692 | + console.log('开始播放音频', audio); | ||
| 693 | + // 学习时长埋点开始 | ||
| 694 | + startAction(); | ||
| 695 | +} | ||
| 696 | + | ||
| 697 | +/** | ||
| 698 | + * 音频暂停事件 | ||
| 699 | + * @param audio 音频对象 | ||
| 700 | + */ | ||
| 701 | +const onAudioPause = (audio) => { | ||
| 702 | + console.log('暂停播放音频', audio); | ||
| 703 | + // 学习时长埋点结束 | ||
| 704 | + endAction(); | ||
| 705 | +} | ||
| 706 | + | ||
| 707 | +/** | ||
| 708 | + * 开始操作 | ||
| 709 | + * @param action | ||
| 710 | + * @param item | ||
| 711 | + */ | ||
| 712 | +const startAction = (action, item) => { | ||
| 713 | + // 先清除可能存在的定时器 | ||
| 714 | + if (window.actionTimer) { | ||
| 715 | + clearInterval(window.actionTimer); | ||
| 716 | + } | ||
| 717 | + | ||
| 718 | + // 生成唯一标识符 | ||
| 719 | + let uuid = uuidv4(); | ||
| 720 | + console.warn('开始操作', uuid); | ||
| 721 | + | ||
| 722 | + // 设置定时器,持续执行操作 | ||
| 723 | + window.actionTimer = setInterval(() => { | ||
| 724 | + console.warn('持续操作中', uuid); | ||
| 725 | + // 这里可以添加需要持续执行的具体操作 | ||
| 726 | + }, 1000); // 每秒执行一次,可以根据需求调整时间间隔 | ||
| 727 | +} | ||
| 728 | + | ||
| 729 | +/** | ||
| 730 | + * 结束操作 | ||
| 731 | + * @param action | ||
| 732 | + * @param item | ||
| 733 | + */ | ||
| 734 | +const endAction = (action, item) => { | ||
| 735 | + // 清除定时器,停止执行startAction | ||
| 736 | + if (window.actionTimer) { | ||
| 737 | + clearInterval(window.actionTimer); | ||
| 738 | + window.actionTimer = null; | ||
| 739 | + console.warn('操作已停止'); | ||
| 740 | + } | ||
| 741 | +} | ||
| 681 | </script> | 742 | </script> |
| 682 | 743 | ||
| 683 | <style lang="less" scoped> | 744 | <style lang="less" scoped> | ... | ... |
| ... | @@ -2776,6 +2776,11 @@ util-deprecate@^1.0.1, util-deprecate@^1.0.2: | ... | @@ -2776,6 +2776,11 @@ util-deprecate@^1.0.1, util-deprecate@^1.0.2: |
| 2776 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" | 2776 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" |
| 2777 | integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== | 2777 | integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== |
| 2778 | 2778 | ||
| 2779 | +uuid@^11.1.0: | ||
| 2780 | + version "11.1.0" | ||
| 2781 | + resolved "https://registry.yarnpkg.com/uuid/-/uuid-11.1.0.tgz#9549028be1753bb934fc96e2bca09bb4105ae912" | ||
| 2782 | + integrity sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A== | ||
| 2783 | + | ||
| 2779 | vant@^4.9.18: | 2784 | vant@^4.9.18: |
| 2780 | version "4.9.19" | 2785 | version "4.9.19" |
| 2781 | resolved "https://registry.yarnpkg.com/vant/-/vant-4.9.19.tgz#315bebe0e8a58237c8fffaec2d1c162b9f112a23" | 2786 | resolved "https://registry.yarnpkg.com/vant/-/vant-4.9.19.tgz#315bebe0e8a58237c8fffaec2d1c162b9f112a23" | ... | ... |
-
Please register or login to post a comment