guoyu/frontend-uniapp/dist/build/h5/assets/pages-course-detail.Cxv9sB-l.js

2 lines
12 KiB
JavaScript

import{E as e,l as t,s,G as o,H as i,I as r,J as a,_ as n,c as l,w as d,C as u,K as c,L as h,M as p,i as g,r as f,y as w,d as m,o as y,z as v,h as T,N as I,O as P,j as U,k as C,P as D,Q as R,u as _,D as S}from"./index-LOi95lww.js";const k=new class{constructor(){this.screenshotTimer=null,this.uploadQueue=[],this.isUploading=!1,this.interval=3e4,this.currentCourseId=null,this.isEnabled=!1}start(e=null,t=3e4){this.isEnabled?console.log("监控已启动"):(this.currentCourseId=e,this.interval=t,this.isEnabled=!0,console.log("启动学习监控,间隔:",t/1e3,"秒"),this.captureAndUpload(),this.screenshotTimer=setInterval(()=>{this.isEnabled&&this.captureAndUpload()},this.interval))}stop(){this.isEnabled=!1,this.screenshotTimer&&(clearInterval(this.screenshotTimer),this.screenshotTimer=null),console.log("学习监控已停止")}setCourseId(e){this.currentCourseId=e}async captureAndUpload(){try{if("none"===await this.getNetworkType())return void console.log("网络未连接,跳过截图上传");const e=await this.captureScreenshot();if(!e)return void console.log("截图失败");this.uploadQueue.push({filePath:e,courseId:this.currentCourseId,timestamp:Date.now()}),this.processUploadQueue()}catch(e){console.error("截图上传失败:",e)}}captureScreenshot(){return new Promise((e,t)=>{this.captureScreenshotH5(e,t)})}captureScreenshotApp(e,t){t(new Error("App环境不可用"))}captureScreenshotH5(e,t){try{const t=document.createElement("canvas"),s=t.getContext("2d");t.width=window.innerWidth,t.height=window.innerHeight,s.fillStyle="#fff",s.fillRect(0,0,t.width,t.height),s.fillStyle="#000",s.font="16px Arial",s.fillText("学习监控截图",20,40),s.fillText((new Date).toLocaleString(),20,60),s.fillText("H5环境截图功能有限",20,80),t.toBlob(t=>{const s=URL.createObjectURL(t);e(s)},"image/png",.8)}catch(s){console.error("H5截图失败:",s),t(s)}}getNetworkType(){return new Promise(t=>{e({success:e=>{t(e.networkType)},fail:()=>{t("unknown")}})})}async processUploadQueue(){if(!this.isUploading&&0!==this.uploadQueue.length){for(this.isUploading=!0;this.uploadQueue.length>0;){const t=this.uploadQueue.shift();try{await this.uploadScreenshot(t.filePath,t.courseId),console.log("截图上传成功")}catch(e){console.error("截图上传失败:",e),void 0===t.retryCount&&(t.retryCount=0),t.retryCount<3&&(t.retryCount++,this.uploadQueue.push(t))}}this.isUploading=!1}}async uploadScreenshot(e,s=null){const o={};return s&&(o.courseId=s),await t.upload("/study/monitor/screenshot",e,o,{name:"file"})}async manualCapture(){try{const e=await this.captureScreenshot();e&&(await this.uploadScreenshot(e,this.currentCourseId),s({title:"截图上传成功",icon:"success"}))}catch(e){s({title:"截图失败",icon:"none"}),console.error("手动截图失败:",e)}}};const L=new class{constructor(){this.queue=[],this.isUploading=!1,this.retryCount=0,this.maxRetryCount=3,this.uploadInterval=5e3,this.uploadTimer=null,this.storageKey="learning_progress_queue",this.isOnline=!0,this.initNetworkListener(),this.loadFromStorage()}initNetworkListener(){o(e=>{const t=!this.isOnline;this.isOnline=e.isConnected,t&&this.isOnline?(console.log("网络已恢复,开始上传队列"),this.processQueue()):this.isOnline||console.log("网络已断开,暂停上传")}),e({success:e=>{this.isOnline="none"!==e.networkType}})}addProgress(e){const t={id:Date.now()+Math.random(),courseId:e.courseId,duration:e.duration||0,videoPosition:e.videoPosition||0,videoTotalDuration:e.videoTotalDuration||0,timestamp:Date.now()},s=this.queue.findIndex(e=>e.courseId===t.courseId&&!e.uploaded);if(s>=0){const e=this.queue[s];e.duration=(e.duration||0)+(t.duration||0),e.videoPosition=t.videoPosition,e.videoTotalDuration=t.videoTotalDuration,e.timestamp=t.timestamp}else this.queue.push(t);this.saveToStorage(),this.isOnline&&this.processQueue()}async processQueue(){if(this.isUploading||!this.isOnline||0===this.queue.length)return;this.isUploading=!0;const e=this.queue.filter(e=>!e.uploaded);if(0===e.length)return void(this.isUploading=!1);const t=[];for(let o=0;o<e.length;o+=5)t.push(e.slice(o,o+5));for(const o of t)try{await this.uploadBatch(o),o.forEach(e=>{e.uploaded=!0,e.uploadTime=Date.now()}),this.queue=this.queue.filter(e=>!e.uploaded||Date.now()-e.uploadTime<6e4),this.saveToStorage(),this.retryCount=0}catch(s){if(console.error("批量上传失败:",s),this.retryCount++,this.retryCount>=this.maxRetryCount)return console.error("达到最大重试次数,停止上传"),void(this.isUploading=!1);await this.delay(2e3*this.retryCount)}this.isUploading=!1,this.queue.some(e=>!e.uploaded)&&setTimeout(()=>{this.processQueue()},this.uploadInterval)}async uploadBatch(e){if(1===e.length){const s=e[0];return void(await t.post("/study/learningRecord/progress",{courseId:s.courseId,duration:s.duration,videoPosition:s.videoPosition,videoTotalDuration:s.videoTotalDuration}))}const s={};e.forEach(e=>{s[e.courseId]||(s[e.courseId]={courseId:e.courseId,duration:0,videoPosition:0,videoTotalDuration:0});const t=s[e.courseId];t.duration+=e.duration||0,t.videoPosition=e.videoPosition,t.videoTotalDuration=e.videoTotalDuration});for(const o in s){const e=s[o];await t.post("/study/learningRecord/progress",e)}}delay(e){return new Promise(t=>setTimeout(t,e))}saveToStorage(){try{const e=this.queue.filter(e=>!e.uploaded||Date.now()-e.uploadTime<6e4);i(this.storageKey,JSON.stringify(e))}catch(e){console.error("保存队列到本地存储失败:",e)}}loadFromStorage(){try{const e=r(this.storageKey);if(e){const t=JSON.parse(e);this.queue=t.filter(e=>!e.uploaded)||[],this.queue.length>0&&this.isOnline&&setTimeout(()=>{this.processQueue()},1e3)}}catch(e){console.error("从本地存储加载队列失败:",e)}}clear(){this.queue=[];try{a(this.storageKey)}catch(e){console.error("清空队列失败:",e)}}getStatus(){const e=this.queue.filter(e=>!e.uploaded).length;return{total:this.queue.length,pending:e,uploaded:this.queue.length-e,isOnline:this.isOnline,isUploading:this.isUploading}}};const E=n({data:()=>({courseId:null,course:{},courseware:null,learningRecord:null,loading:!1,isLandscape:!1,videoId:"course-video-"+Date.now(),videoUrl:"",videoPoster:"",pdfUrl:"",imageUrl:"",progressTimer:null,lastReportTime:0,reportInterval:1e4,videoStartTime:0,videoCurrentTime:0,videoTotalDuration:0,isPlaying:!1}),onLoad(e){this.courseId=e.id,this.loadCourseDetail()},onShow(){this.checkOrientation(),this.orientationListener=setInterval(()=>{this.checkOrientation()},500),this.courseId&&(k.setCourseId(this.courseId),k.start(this.courseId,3e4))},onHide(){this.clearProgressTimer(),this.orientationListener&&clearInterval(this.orientationListener),k.stop()},onUnload(){this.clearProgressTimer(),this.orientationListener&&clearInterval(this.orientationListener),k.stop()},computed:{isPdf(){return this.courseware&&this.courseware.fileName&&this.courseware.fileName.toLowerCase().endsWith(".pdf")}},methods:{checkOrientation(){if("undefined"!=typeof window&&void 0!==window.orientation){const e=window.orientation||0;this.isLandscape=90===Math.abs(e)}},async loadCourseDetail(){if(this.courseId){this.loading=!0;try{const e=await t.get(`/study/course/${this.courseId}`);200===e.code&&(this.course=e.data||{},this.course.coursewareId&&await this.loadCourseware(this.course.coursewareId),await this.loadLearningRecord())}catch(e){s({title:e.message||"加载失败",icon:"none"})}finally{this.loading=!1}}},async loadCourseware(e){try{const s=await t.get(`/study/courseware/${e}`);if(200===s.code&&(this.courseware=s.data||{},this.courseware.filePath)){const e=h.FILE_BASE_URL+this.courseware.filePath;"video"===this.courseware.type?(this.videoUrl=e,this.learningRecord&&this.learningRecord.lastVideoPosition&&this.$nextTick(()=>{const e=p(this.videoId);e&&e.seek(this.learningRecord.lastVideoPosition)})):"image"===this.courseware.type?this.imageUrl=e:"document"===this.courseware.type&&this.isPdf&&(this.pdfUrl=e)}}catch(s){console.error("加载课件失败:",s)}},async loadLearningRecord(){try{const e=await t.get("/study/learningRecord/my-records");if(200===e.code){const t=e.data||[];this.learningRecord=t.find(e=>e.courseId===this.courseId)||null,this.learningRecord&&(this.videoTotalDuration=this.learningRecord.videoTotalDuration||0)}}catch(e){console.error("加载学习记录失败:",e)}},onVideoPlay(e){this.isPlaying=!0,this.videoStartTime=Date.now(),this.startProgressTimer()},onVideoPause(e){this.isPlaying=!1,this.reportProgress(!0)},onVideoEnded(e){this.isPlaying=!1,this.reportProgress(!0)},onVideoTimeUpdate(e){this.videoCurrentTime=e.detail.currentTime,this.videoTotalDuration=e.detail.duration||this.videoTotalDuration},onVideoWaiting(e){},onVideoError(e){s({title:"视频播放失败",icon:"none"})},startProgressTimer(){this.clearProgressTimer(),this.progressTimer=setInterval(()=>{this.isPlaying&&this.reportProgress()},this.reportInterval)},clearProgressTimer(){this.progressTimer&&(clearInterval(this.progressTimer),this.progressTimer=null)},async reportProgress(e=!1){const t=Date.now();if(!e&&t-this.lastReportTime<this.reportInterval)return;const s=Math.floor((t-this.videoStartTime)/1e3),o=Math.floor(this.videoCurrentTime),i=Math.floor(this.videoTotalDuration);let r=0;i>0&&(r=Math.min(100,Math.floor(o/i*100))),L.addProgress({courseId:this.courseId,duration:s,videoPosition:o,videoTotalDuration:i}),this.lastReportTime=t,this.learningRecord&&(this.learningRecord.progress=r,this.learningRecord.totalDuration=(this.learningRecord.totalDuration||0)+s,this.learningRecord.learnCount=(this.learningRecord.learnCount||0)+1,this.learningRecord.lastVideoPosition=o)},previewImage(){this.imageUrl&&c({urls:[this.imageUrl],current:this.imageUrl})},formatDuration(e){if(!e)return"0分钟";const t=Math.floor(e/3600),s=Math.floor(e%3600/60);return t>0?`${t}小时${s}分钟`:`${s}分钟`}}},[["render",function(e,t,s,o,i,r){const a=I,n=g,c=P,h=U,p=D,k=R,L=f(m("u-loading-page"),w);return y(),l(n,{class:u(["course-detail-container",{landscape:i.isLandscape}])},{default:d(()=>[i.courseware&&"video"===i.courseware.type?(y(),l(n,{key:0,class:"video-container"},{default:d(()=>[T(a,{id:i.videoId,src:i.videoUrl,poster:i.videoPoster,controls:!0,"show-center-play-btn":!0,"enable-play-gesture":!0,"enable-progress-gesture":!0,"show-fullscreen-btn":!0,"show-play-btn":!0,"show-loading":!0,"object-fit":(i.isLandscape,"contain"),class:"course-video",onPlay:r.onVideoPlay,onPause:r.onVideoPause,onEnded:r.onVideoEnded,onTimeupdate:r.onVideoTimeUpdate,onWaiting:r.onVideoWaiting,onError:r.onVideoError},null,8,["id","src","poster","object-fit","onPlay","onPause","onEnded","onTimeupdate","onWaiting","onError"])]),_:1})):v("",!0),i.courseware&&"video"!==i.courseware.type?(y(),l(n,{key:1,class:"courseware-container"},{default:d(()=>[T(n,{class:"courseware-viewer"},{default:d(()=>["document"===i.courseware.type&&r.isPdf?(y(),l(n,{key:0,class:"pdf-viewer"},{default:d(()=>[i.pdfUrl?(y(),l(c,{key:0,src:i.pdfUrl},null,8,["src"])):(y(),l(n,{key:1,class:"placeholder"},{default:d(()=>[T(h,null,{default:d(()=>[C("PDF文件加载中...")]),_:1})]),_:1}))]),_:1})):"image"===i.courseware.type?(y(),l(n,{key:1,class:"image-viewer"},{default:d(()=>[T(p,{src:i.imageUrl,mode:"aspectFit",class:"courseware-image",onClick:r.previewImage},null,8,["src","onClick"])]),_:1})):"text"===i.courseware.type?(y(),l(n,{key:2,class:"text-viewer"},{default:d(()=>[T(k,{nodes:i.courseware.description||"暂无内容"},null,8,["nodes"])]),_:1})):v("",!0)]),_:1})]),_:1})):v("",!0),i.isLandscape?v("",!0):(y(),l(n,{key:2,class:"course-info"},{default:d(()=>[T(n,{class:"info-header"},{default:d(()=>[T(h,{class:"course-name"},{default:d(()=>[C(_(i.course.courseName||"加载中..."),1)]),_:1})]),_:1}),T(h,{class:"course-desc"},{default:d(()=>[C(_(i.course.description||"暂无描述"),1)]),_:1}),i.learningRecord?(y(),l(n,{key:0,class:"learning-progress"},{default:d(()=>[T(n,{class:"progress-header"},{default:d(()=>[T(h,{class:"progress-title"},{default:d(()=>[C("学习进度")]),_:1}),T(h,{class:"progress-percent"},{default:d(()=>[C(_(i.learningRecord.progress||0)+"%",1)]),_:1})]),_:1}),T(n,{class:"progress-bar"},{default:d(()=>[T(n,{class:"progress-fill",style:S({width:(i.learningRecord.progress||0)+"%"})},null,8,["style"])]),_:1}),T(n,{class:"progress-stats"},{default:d(()=>[T(h,null,{default:d(()=>[C("学习时长:"+_(r.formatDuration(i.learningRecord.totalDuration)),1)]),_:1}),T(h,null,{default:d(()=>[C("学习次数:"+_(i.learningRecord.learnCount||0)+"次",1)]),_:1})]),_:1})]),_:1})):v("",!0)]),_:1})),T(L,{loading:i.loading},null,8,["loading"])]),_:1},8,["class"])}],["__scopeId","data-v-6cd6045d"]]);export{E as default};