useStudyRecordTracker.js 3.03 KB
import { ref, onUnmounted } from 'vue';
import { v4 as uuidv4 } from 'uuid';
import { addStudyRecordAPI } from '@/api/record';

/**
 * 学习记录跟踪器
 * @param {*} course 课程对象
 * @param {*} courseId 课程ID
 * @param {*} videoPlayerRef 视频播放器引用
 * @param {*} audioPlayerRef 音频播放器引用
 * @returns 学习记录跟踪器对象,包含 startAction、addRecord 等方法
 */
export const useStudyRecordTracker = ({ course, courseId, videoPlayerRef, audioPlayerRef }) => {
    const action_timer = ref(null);
    const playback_id = ref('');

    const clear_timer = () => {
        if (action_timer.value) {
            clearInterval(action_timer.value);
            action_timer.value = null;
        }
    };

    const addRecord = async (paramsObj) => {
        if (!paramsObj || !paramsObj.schedule_id) return;
        return await addStudyRecordAPI(paramsObj);
    };

    const get_schedule_id = () => {
        if (typeof courseId === 'object' && courseId && 'value' in courseId) return courseId.value;
        return courseId || '';
    };

    const get_video_payload = () => {
        const player = videoPlayerRef?.value?.getPlayer?.();
        if (!player) return null;

        const duration = typeof player.duration === 'function' ? player.duration() : (player.duration || 0);
        const position = typeof player.currentTime === 'function' ? player.currentTime() : (player.currentTime || 0);
        const meta_id = videoPlayerRef?.value?.getId?.();
        if (!meta_id) return null;

        return {
            meta_id,
            media_duration: duration,
            playback_position: position,
            playback_id: playback_id.value,
        };
    };

    const get_audio_payload = (item) => {
        const player = audioPlayerRef?.value?.getPlayer?.();
        if (!player) return null;

        const meta_id = item?.meta_id;
        if (!meta_id) return null;

        return {
            meta_id,
            media_duration: player.duration || 0,
            playback_position: player.currentTime || 0,
            playback_id: playback_id.value,
        };
    };

    const startAction = (item) => {
        clear_timer();

        const schedule_id = get_schedule_id();
        if (!schedule_id) return;

        playback_id.value = uuidv4();

        action_timer.value = setInterval(() => {
            const is_video = course?.value?.course_type === 'video';
            const is_audio = course?.value?.course_type === 'audio';

            let payload = null;
            if (is_video) payload = get_video_payload();
            if (is_audio) payload = get_audio_payload(item);
            if (!payload) payload = get_video_payload() || get_audio_payload(item);
            if (!payload) return;

            addRecord({
                schedule_id,
                ...payload,
            });
        }, 3000);
    };

    const endAction = () => {
        clear_timer();
    };

    onUnmounted(() => {
        clear_timer();
    });

    return {
        startAction,
        endAction,
        addRecord,
    };
};