Bladeren bron

21st的修改

sophieChenyx 6 jaren geleden
bovenliggende
commit
5797f350e2

+ 3 - 0
src/res/tpl/AudioWareFullScreen.tpl

@@ -0,0 +1,3 @@
+<div id="AudioWareFullScreen" fe-role="Switch">
+    <img id="wareImg" src="assets/img/default_bg.jpg" />
+</div>

+ 7 - 0
src/res/tpl/DownloadTipScene.tpl

@@ -0,0 +1,7 @@
+<div id="DownloadTipScene" class="course-download-wrapper" fe-role="Switch">
+    <div class="toast">
+        <img src="./../../stage/index/assets/img/CourseScene/download_btn_list_undownload.png" alt="">
+        <p>当前正在下载中,请等待下载结束</p>
+        <div class="ok-btn" fe-role="Widget" id="ok-btn">确认</div>
+    </div>
+</div>

+ 2 - 1
src/res/values/api.json

@@ -1,4 +1,5 @@
 {
     "api_url_kid": "http://kid-app.lingjiao.cn",
-    "api_url": "https://21st-winapp.lingjiao.cn"
+    "api_url_": "https://21st-winapp.lingjiao.cn",
+    "api_url": "http://tt-web.api.ai160.com"
 }

BIN
src/stage/index/assets/img/Audio/audio_last.png


BIN
src/stage/index/assets/img/Audio/audio_mute.png


BIN
src/stage/index/assets/img/Audio/audio_next.png


BIN
src/stage/index/assets/img/Audio/audio_play.png


BIN
src/stage/index/assets/img/Audio/audio_stop.png


BIN
src/stage/index/assets/img/Audio/audio_voice.png


+ 2 - 0
src/stage/index/index.less

@@ -18,6 +18,7 @@ body {
 @import './style/IndexScene.less';
 @import './style/TerminalScene.less';
 @import './style/DownloadScene.less';
+@import './style/DownloadTipScene.less';
 @import './style/RepeatLoginScene.less';
 @import './style/BuyConfirmScene.less';
 @import './style/DelConfirmScene.less';
@@ -31,3 +32,4 @@ body {
 @import './style/GlobalGoodDetail.less';
 @import './style/ImageWareFullScreen.less';
 @import './style/VideoWareFullScreen.less';
+@import './style/AudioWareFullScreen.less';

+ 296 - 0
src/stage/index/scene/AudioWareFullScreenScene.js

@@ -0,0 +1,296 @@
+import Consts from '../../../util/Consts';
+
+function getLocalResourceUrl(absoluteUrl) {
+  if (!absoluteUrl) return;
+  const segments = absoluteUrl.split('/') || [];
+  return `${Consts.NODE_SERVER}/lesson/readFile?n=${segments.slice(3).join('*')}`;
+}
+
+class AudioWareFullScreenScene extends scene {
+	constructor(scope) {
+		super(scope);
+		this.isDownload = false;
+		this.wareList = [];
+		this.curWareIndex = 0;
+		this.curWareType = null;
+		this.curAudioList = [];
+		this.curAudioIndex = 0;
+	}
+
+  /**
+   * 音频播放控制
+   */
+  audioPlayControl(eventId) {
+    let targetAudio = document.getElementById('courseware-audio');
+    if (!targetAudio) { return; }
+    switch (eventId) {
+        case 'audio-play':
+            let playBtn = document.querySelector('#audio-play');
+            if (targetAudio.paused) {
+                targetAudio.play();
+                playBtn.classList.remove('paused');
+            } else {
+                targetAudio.pause();
+                playBtn.classList.add('paused');
+            }
+            break;
+        case 'audio-mute':
+            let muteBtn = document.querySelector('#audio-mute');
+            if (targetAudio.muted) {
+                targetAudio.muted = false;
+                muteBtn.classList.remove('muted');
+            } else {
+                targetAudio.muted = true;
+                muteBtn.classList.add('muted');
+            }
+            break;
+        case 'audio-next':
+            if (this.curAudioIndex < this.curAudioList.length -1) {
+                this.curAudioIndex += 1;
+                this.renderAudioView('audio-next');
+            } else {
+                this.keyRightHandler();
+            }
+            break;
+        case 'audio-last':
+            if (this.curAudioIndex > 0) {
+                this.curAudioIndex -= 1;
+                this.renderAudioView('audio-last');
+            } else {
+                this.keyLeftHandler();
+            }
+            break;
+        default:
+            break;
+      }
+  }
+
+  /**
+   * 音频渲染
+   */
+	renderAudioView(focusTarget) {
+    const curAudio = this.curAudioList[this.curAudioIndex];
+    const { type, img, audio } = curAudio;
+    let imgPath = (img || {}).path || '';
+    let audioUrl = (audio || {}).url || '';
+    let content = document.getElementById('AudioWareFullScreen');
+    // 1.更换背景图片
+    let imgUrl = `${Consts.IMG_PATH}/${imgPath}`;
+		let imgHTML = `<img src="${imgUrl}" />`;
+		if (this.isDownload) {
+    	imgHTML = `<img src="${getLocalResourceUrl(imgUrl)}" />`;
+		}
+    content.innerHTML = imgHTML;
+    // 2.根据是否有无audioURL来控制面板及audio的展现
+    if (type === Consts.TYPE_AUDIOBOOK && audioUrl) {
+      if (this.isDownload) {
+        audioUrl = getLocalResourceUrl(audioUrl)
+      }
+      let audioElement = document.createElement('audio');
+      audioElement.setAttribute('id', 'courseware-audio');
+      audioElement.setAttribute('src', audioUrl);
+      audioElement.setAttribute('autoplay', 'autoplay');
+      let controlsElement = document.createElement('div');
+      controlsElement.setAttribute('autoplay', 'autoplay');
+      controlsElement.setAttribute('class', 'audio-controls');
+      let controlsBtns = `
+          <!-- 播放/暂停 -->
+          <div id="audio-play" class="audio-controls-item btn-play" fe-role="Widget"></div>
+          <!-- 有声/静音 -->
+          <div id="audio-mute" class="audio-controls-item btn-mute" fe-role="Widget"></div>
+          <!-- 下一个音频 -->
+          <div id="audio-next" class="audio-controls-item btn-next" fe-role="Widget"></div>
+          <!-- 上一个音频 -->
+          <div id="audio-last" class="audio-controls-item btn-last" fe-role="Widget"></div>
+      `;
+      controlsElement.innerHTML = controlsBtns;
+      content.appendChild(audioElement);
+      content.appendChild(controlsElement);
+      this.moye.root.reRender();
+      // 监听onended事件
+      let audioDom = document.getElementById('courseware-audio');
+      if (audioDom) {
+        audioDom.addEventListener('ended', function () {
+        TVUtil.Toast.show('播放结束', 1500);
+        document.getElementById('audio-play').classList.add('paused');
+        audioDom.currentTime = 0;
+        }, false);
+      }
+      // 指定光标位置
+      if (focusTarget && this.moye.root.getWidgetById(focusTarget)) {
+        this.moye.root.getWidgetById(focusTarget).focus();
+      }
+    }
+	}
+
+	dynamicChangeWare(wareIndex, type) {
+		if (type === 'BACK') {
+			TVUtil.Toast.show('即将播放上个课件...', 1500);
+		} else if (type === 'NEXT') {
+			TVUtil.Toast.show('即将播放下个课件...', 1500);
+		}
+		setTimeout(() => {
+			this.curWareIndex = wareIndex;
+			this.curWareType = this.wareList[wareIndex].type;
+			//下一个或前一个课件是视频课件
+			if (this.curWareType === Consts.TYPE_VIDEO) {
+				this.hideScene();
+				this.showScene(require('./VideoWareFullScreenScene.js'), {
+					wareList: this.wareList,
+					curWareIndex: this.curWareIndex,
+				});
+            //下一个或前一个课件是图片课件
+            } else if (this.curWareType === Consts.TYPE_IMAGE) {
+                let imgList = this.wareList[this.curWareIndex].list;
+                let imgIndex = 0;
+                if (type === 'BACK' && imgList.length) {
+                    imgIndex = imgList.length - 1;
+                }
+                this.hideScene();
+        		this.showScene(require('./ImageWareFullScreenScene.js'), {
+        			wareList: this.wareList,
+        			curWareIndex: this.curWareIndex,
+        			curImageList: imgList,
+        			curImageIndex: imgIndex,
+        		});
+			//下一个或前一个课件是音频课件
+			} else {
+				this.curAudioList = this.wareList[wareIndex].list;
+				if (type === 'BACK') {
+					this.curAudioIndex = this.wareList[wareIndex].list.length - 1;
+				}
+				if (type === 'NEXT') {
+					this.curAudioIndex = 0;
+				}
+				this.renderAudioView();
+			}
+		}, 1500);
+	}
+
+	keyRightHandler() {
+		const hasNextWare = this.curWareIndex < this.wareList.length - 1 ? true : false;
+		//当前图片是该图片课件最后一张图片,且后边还有课件则切换课件
+		if (this.curAudioIndex === this.curAudioList.length - 1 && hasNextWare) {
+			return;
+			// const nextWareIndex = this.curWareIndex + 1;
+			// this.dynamicChangeWare(nextWareIndex, 'NEXT')
+		//当前图片是该图片课件最后一张图片,且后边没有课件,给出提示
+		} else if (this.curAudioIndex === this.curAudioList.length - 1 && !hasNextWare) {
+			return;
+			// TVUtil.Toast.show('已经是最后一个课件了', 2000);
+		//当前图片不是该图片课件的最后一张图片
+    } else {
+			this.curAudioIndex += 1;
+			this.renderAudioView();
+    }
+	}
+
+	keyLeftHandler() {
+		const hasPreviousWare = this.curWareIndex === 0 ? false : true;
+		//当前图片是该图片课件的第一张图片,且前边还有课件
+	  if (this.curAudioIndex == 0 && hasPreviousWare) {
+			return;
+			// const previousWareIndex = this.curWareIndex - 1;
+			// this.dynamicChangeWare(previousWareIndex, 'BACK');
+		//当前图片是该图片课件的第一张图片,且前边没有课件,则给出提示
+		} else if (this.curAudioIndex === 0 && !hasPreviousWare) {
+			return;
+			// TVUtil.Toast.show('已经是第一个课件了', 2000);
+		//当前图片不是该图片课件的第一张图片
+		} else {
+			this.curAudioIndex -= 1;
+			this.renderAudioView();
+		}
+	}
+
+	onCreate(data) {
+	    this.wareList = data.wareList;
+	    this.curWareIndex = data.curWareIndex;
+			this.isDownload = data.isDownload;
+	    if (data.curAudioList) {
+				this.curAudioList = data.curAudioList;
+	    }
+	    if (data.curAudioIndex) {
+				this.curAudioIndex = data.curAudioIndex;
+	    }
+	    this.curWareType = this.wareList[this.curWareIndex].type;
+		this.setContentView(require('../../../res/tpl/AudioWareFullScreen.tpl'), {}, 'AudioWareFullScreen', {}, () => {
+			this.renderAudioView();
+		});
+	}
+
+	onResume() {
+
+	}
+
+	onPause() {
+
+	}
+
+	onDestroy() {
+
+	}
+
+	onActive() {
+
+	}
+
+	onInactive() {
+
+	}
+
+	onOK() {
+    	const leaf = FocusEngine.getFocusedLeaf();
+        // 拦截音频控制相关事件单独处理
+        if (leaf.id && leaf.id.startsWith('audio')) {
+            this.audioPlayControl(leaf.id);
+            return;
+        }
+	}
+
+	onBack() {
+
+	}
+
+	onKeyup() {
+
+	}
+
+	onKeydown(e) {
+    let curFocusedLeaf = FocusEngine.getFocusedLeaf();
+		switch (e.keyCode) {
+			//左键
+			case 37:
+        if (!curFocusedLeaf || !curFocusedLeaf.id.startsWith('audio')) {
+          this.keyLeftHandler();
+        }
+				break;
+			//右键
+			case 39:
+        if (!curFocusedLeaf || !curFocusedLeaf.id.startsWith('audio')) {
+          this.keyRightHandler();
+        }
+				break;
+			//触屏设备向左滑动
+			case Consts.KEYCODE_CLICK_LEFT_SCREEN:
+				this.keyLeftHandler();
+				break;
+			//触屏设备向右滑动
+			case Consts.KEYCODE_CLICK_RIGHT_SCREEN:
+				this.keyRightHandler();
+				break;
+			//ESC键退出图片全屏
+			case 27:
+				this.hideScene({
+					curWareIndex: this.curWareIndex,
+					curAudioList: this.curAudioList,
+					curAudioIndex: this.curAudioIndex,
+				}, 'LessonScene');
+				break;
+			default:
+				break;
+		}
+	}
+}
+
+module.exports = AudioWareFullScreenScene;

+ 0 - 0
src/stage/index/scene/CourseList.js


+ 49 - 66
src/stage/index/scene/CourseScene.js

@@ -5,6 +5,7 @@ import efMarquee from '../../../component/EFMarquee';
 import ShopCartState from '../../../util/ShopCartState';
 import NotificationCenter from '../../../util/NotificationCenter';
 import {CommandBus, CMD_TYPE} from '../../../util/CommandBus';
+import WinBoxAPI from '../../../util/WinBoxAPI';
 import Consts from '../../../util/Consts';
 
 class CourseScene extends scene {
@@ -19,9 +20,9 @@ class CourseScene extends scene {
 		this.id = 1;
 		this.isFirst = true;
 		this.marquee = null;
-	    //course name
-	    this.title = '';
-	    this.isBought = false;
+    //course name
+    this.title = '';
+    this.isBought = false;
 	}
 
 	generateCourseDetailTitle(itemTitle, secondTitle){
@@ -243,31 +244,20 @@ class CourseScene extends scene {
 	/**
 	 * 添加课程下载任务
 	 */
-	addLessonDownloadTask({resData, courseID, courseName, lessonID, lessonName}){
-		let { images, videos } = this.getDownloadTargetFromLessonData(resData);
-		let lessonDownloadData = {
-			courseID,
-			courseName,
-			lessonID,
-			lessonName,
-			images,
-			videos,
-		}
-		console.log('下载数据...', lessonDownloadData);
-	    //send to download
-	    let {status} = CommandBus.execute({type:CMD_TYPE.DOWNLOAD_LESSON_POST, payload:lessonDownloadData});
-	    //统计下载行为
-	    CommandBus.execute({type:CMD_TYPE.APP_BHV_POST, payload:{
-			eventName: "downloadLesson",
-			eventPage: "courseScene",
-			eventAttr: {
-				courseId:courseID,
-				courseName:courseName,
-				lessonId:lessonID,
-				lessonName:lessonName
+	addLessonDownloadTask({lessonID, courseID, event}){
+		WinBoxAPI.postDownloadRequest(lessonID, courseID, (isTrue, res) => {
+			if (!isTrue) {
+				TVUtil.Toast.show('本地服务请求失败...', 3000);
+				return;
 			}
-		}});
-		return true;
+			if (event.target.con.classList.contains('download-btn-lesson-list-ready')) {
+  			event.target.con.classList.add('download-btn-lesson-list-ongoing');
+  			event.target.con.classList.remove('download-btn-lesson-list-ready');
+			} else {
+  			event.target.con.classList.add('download-btn-lesson-icon-ongoing');
+  			event.target.con.classList.remove('download-btn-lesson-icon-ready');
+			}
+		});
 	}
 
 	onCreate(data) {
@@ -278,16 +268,12 @@ class CourseScene extends scene {
 			// check course is blank
 			this.renderCourse(this.id);
 		});
-	    CommandBus.execute({type:CMD_TYPE.APP_BHV_POST, payload:{
-			eventName: "enter_courseScene",
-			eventPage: "courseScene",
-			eventAttr: { courseID: data.id },
-	    }});
 	}
 
 	onResume(data) {
 		if (!data) { return }
 		if ('BuyConfirmScene' === data.backScene) {
+
 			if ('goBuy' === data.mode) {
 				//TODO:需降低耦合,统一管理路由,暂时先造个对象
 				this.navSwitch({ target: { id: 'course-tab-detail' } });
@@ -297,6 +283,9 @@ class CourseScene extends scene {
 			} else {
 				return;
 			}
+
+		} else if ('DownloadTipScene' === data.backScene) {
+				return;
 		} else {
 			this.renderCourse(this.id);
 		}
@@ -351,25 +340,40 @@ class CourseScene extends scene {
             this.hideScene({});
             return;
         }
-		
-		// 点击某一课
+
+		// 点击正在下载的某一课
+		if (e.target.con.classList.contains('download-btn-lesson-list-ongoing') || e.target.con.classList.contains('download-btn-lesson-icon-ready')) {
+      this.showScene(require('./DownloadTipScene.js'), {});
+      return;
+		}
+
 		if (e.target.con.classList.contains('img-wrapper') || e.target.con.classList.contains('text-wrapper')) {
 			// 课件模版 COURSE_WARE_VIDEO(课视频模版)  COURSE_WARE_LIST(课列表)
+      if (e.target.con.classList.contains('text-wrapper')) {
+        let i = 0;
+        for (i < e.target.parentWidget.childWidgets; i++;) {
+          if(e.target.parentWidget.childWidgets[i].con.classList.contains('download-btn-lesson-list-ongoing') || e.target.parentWidget.childWidgets[i].con.classList.contains('download-btn-lesson-icon-ready')) {
+            this.showScene(require('./DownloadTipScene.js'), {});
+            return;
+          }
+        }
+      }
 			let id = e.target.con.dataset.id;
-
-			//检查课的权限
+      //检查课的权限
 			//首先获取课的序号
 			let lessonSeq = parseInt(e.target.con.dataset.seq);
 			if (!this.isAuthorized(lessonSeq)) {
-				//新添需求,如果该课程未购买,出现确认购买弹框
 				this.showScene(require('./BuyConfirmScene.js'), {});
 				return;
 			}
 			let title = e.target.con.dataset.name;
-			this.showScene(require('./LessonScene.js'), { id, title, courseId: this.id });
+			let downloadStatus = parseInt(e.target.con.dataset.dload);
+			this.showScene(require('./LessonScene.js'), { id, title, downloadStatus, courseId: this.id });
+
 			return;
 		}
 
+
     	//点击课程配套列表中的某个配套
 		if (e.target.con.classList.contains('periphery-wrapper')) {
 			document.querySelector('.periphery-container').style.opacity = '0';
@@ -414,49 +418,28 @@ class CourseScene extends scene {
     //点击课的下载按钮
     if (e.target.con.classList.contains('download-btn-lesson-list-ready')
 		|| e.target.con.classList.contains('download-btn-lesson-icon-ready')) {
-			let courseID = this.id;
+      let courseID = this.id;
 			let courseName = this.title;
-
+      TVUtil.Toast.show('点击下载', 1500);
 			let lessonID = e.target.con.dataset.id;
 			let lessonName = e.target.con.dataset.name;
 
+			/*调试不启用
 			let lessonSeq = parseInt(e.target.con.dataset.seq);
 			if (!this.isAuthorized(lessonSeq)) {
 				TVUtil.Toast.show('购买后方可下载!', 3000);
 				return;
-			}
+			}*/
 
+			/* windows不提供此方法
 			if (this.getAvailableBlocks() < 200*1024){
 				//剩余空间小于200M
 				TVUtil.Toast.show('存储空间不足! 请到下载管理界面删除不需要的课以释放存储空间!', 3000);
 				return;
 			}
+			*/
 
-			//get courseware via Lesson
-			console.error('DEBUG, download cmd begin');
-			APIClient.getWareList(lessonID, courseID, (isTrue, res) => {
-				if (!isTrue) { return; }
-				if (!res.success) {
-					TVUtil.Toast.show('获取课件列表失败!', 1500);
-					return;
-				}
-				let resData = res.data.list;
-				if (!resData){
-					console.log('Cannot Get coursewares, lessonID=%s', lessonID);
-					return;
-				}
-
-	      if (this.addLessonDownloadTask({resData, courseID, courseName, lessonID, lessonName})){
-					//set download-btn to ongoing
-					if (e.target.con.classList.contains('download-btn-lesson-list-ready')) {
-	    			e.target.con.classList.add('download-btn-lesson-list-ongoing')
-	    			e.target.con.classList.remove('download-btn-lesson-list-ready')
-					} else {
-	    			e.target.con.classList.add('download-btn-lesson-icon-ongoing')
-	    			e.target.con.classList.remove('download-btn-lesson-icon-ready')
-					}
-	      }
-			});//APIClient Over
+			this.addLessonDownloadTask({ lessonID, courseID, event: e });
 		}
 	}
 

+ 1 - 1
src/stage/index/scene/DelConfirmScene.js

@@ -27,7 +27,7 @@ class DelConfirmScene extends scene {
 			this.moye.root.getWidgetById('cancle-btn').focus();
 			// 记录下课id
 			this.store = {
-				lessonID: data.lessonID,
+				lessonId: data.lessonId,
 				parentScene: data.parentScene,
 			};
 		});

+ 82 - 70
src/stage/index/scene/DownloadManagerScene.js

@@ -1,6 +1,7 @@
 import Consts from '../../../util/Consts';
+import APIClient from '../../../util/API/APIClient';
+import WinBoxAPI from '../../../util/WinBoxAPI';
 import Utils from '../../../util/Utils';
-import {CommandBus, CMD_TYPE} from '../../../util/CommandBus';
 
 class DownloadManagerScene extends scene {
     constructor(scope) {
@@ -9,6 +10,65 @@ class DownloadManagerScene extends scene {
         this.lessonItems = {};
     }
 
+    fetchDownloadList() {
+      APIClient.getUserDownloadList((isTrue, res) => {
+        // 判断响应内容
+        if (!isTrue || !res || !res.success) {
+          TVUtil.Toast.show('获取下载内容失败', 2000);
+          return;
+        };
+        // 遍历下载列表数据
+        const downloadedList = res.data || [];
+        let recs = [];
+        for (let i in downloadedList) {
+          recs.push(downloadedList[i]);
+          let item = downloadedList[i];
+          // 记录lessonId
+          this.lessonIds = [];
+          this.lessonIds.push(item['lessonId']);
+          // make a map of lessonId to courseId
+          this.lessonItems[item['lessonId']] = {
+              'lessonName':item['lessonName'],
+              'courseId':item['courseId'],
+              'downloadStatus':item['downloadStatus'],
+          }
+        }
+        let downloadStatusTableHtml = this.generateDownloadStatusTable({recs});
+        let downloadStatusTableWrapper = document.getElementById('download-status-table-wrapper');
+        downloadStatusTableWrapper.innerHTML = downloadStatusTableHtml;
+        this.moye.root.reRender();
+      })
+    }
+
+    deleteDownloadFile(lessonId, courseId) {
+      WinBoxAPI.deleteDownloadFile(lessonId, courseId, (isTrue, res) => {
+        if (!isTrue || !res || !res.success) {
+          TVUtil.Toast.show('本地文件删除失败', 2000);
+          return;
+        }
+        //删除dom节点
+        let curNode = document.getElementById('lesson-download-record-'+lessonId);
+        curNode.parentNode.removeChild(curNode);
+        this.moye.root.reRender();
+        //找兄弟结点
+        let findIdx = this.lessonIds.indexOf(lessonId);
+        if(-1 == findIdx){
+            return;
+        }
+        this.lessonIds.splice(findIdx, 1);
+        if(findIdx >= this.lessonIds.length){
+            findIdx = this.lessonIds.length - 1;
+        }
+        let nextFocusLessonId = null;
+        if(findIdx >= 0){
+            nextFocusLessonId = this.lessonIds[findIdx];
+        }
+        if(nextFocusLessonId){
+          this.moye.root.getWidgetById('del-btn-lesson-'+nextFocusLessonId).focus();
+        }
+      });
+    }
+
     generateDownloadStatusTable({recs}) {
         let trAcc = '';
         let count = 0;
@@ -19,13 +79,12 @@ class DownloadManagerScene extends scene {
                 feCfg = "default_focus:yes";
             }
             count += 1;
-            //for tmp
 
             //downloadDate
             let downloadDateStr = '2017-09-10';
-            if (rec.createTime) {
+            if (rec.gmtCreated) {
                 let createDate = new Date();
-                createDate.setTime(rec.createTime);
+                createDate.setTime(rec.gmtCreated);
                 downloadDateStr = Utils.dateFormat(createDate, 'yyyy-MM-dd');
             }
             let downloadStatus = rec['downloadStatus'];
@@ -33,8 +92,8 @@ class DownloadManagerScene extends scene {
 
             //storageUsage
             let storageUsageStr = '';
-            if (rec.storageUsage){
-                storageUsageStr = '' + parseInt(rec.storageUsage/1000) + 'M';
+            if (rec.storageUsage || 0){
+                storageUsageStr = '' + parseInt((rec.storageUsage || 0)/1000) + 'M';
             }
 
             //downloadStatus
@@ -43,7 +102,6 @@ class DownloadManagerScene extends scene {
                 downloadDesc = '未下载';
                 break;
             case Consts.DOWNLOAD_STATUS_ONGOING:
-                //downloadDesc = '已下载'+rec['progress']*100 + '%';
                 downloadDesc = '正在下载';
                 break;
             case Consts.DOWNLOAD_STATUS_SUCCESS:
@@ -59,7 +117,7 @@ class DownloadManagerScene extends scene {
                 rec['lessonName'] = rec['courseName'];
             }
 
-            trAcc += `<div id='lesson-download-record-${rec['lessonID']}' class="row" lesson_id="${rec['lessonID']}">
+            trAcc += `<div id='lesson-download-record-${rec['lessonId']}' class="row" lesson_id="${rec['lessonId']}">
             <div class="one">${downloadDateStr}</div>
             <div class="two">${rec['courseName']}</div>
             <div class="three">${rec['lessonName']}</div>
@@ -67,17 +125,15 @@ class DownloadManagerScene extends scene {
             <div class="five">${downloadDesc}</div>
             <div class="six" >
               <div id="download-btn-wrapper" fe-fole="Switch">
-                <div id="enter-btn-lesson-${rec['lessonID']}" class="download-enter-btn" fe-role="Widget" data-id="${rec['lessonID']}">
+                <div id="enter-btn-lesson-${rec['lessonId']}" class="download-enter-btn" fe-role="Widget" data-id="${rec['lessonId']}">
                   <img src="./assets/img/DownloadScene/download_enter_btn.png" class="img-btn"/>
                 </div>
-                <div id="del-btn-lesson-${rec['lessonID']}" class="download-del-btn" fe-role="Widget" data-id="${rec['lessonID']}" >
+                <div id="del-btn-lesson-${rec['lessonId']}" class="download-del-btn" fe-role="Widget" data-id="${rec['lessonId']}" >
                   <img src="./assets/img/DownloadScene/download_del_btn.png" class="img-btn"/>
                 </div>
               </div>
             </div>
             </div>`
-            //<div class="delete-btn"  fe-role="Widget" fe-cfg="${feCfg}"/>
-            //<img src="./assets/img/download_del_btn.png" />
         }
         let header = `<div class="row header">
           <div class="one">下载日期</div>
@@ -97,71 +153,26 @@ class DownloadManagerScene extends scene {
             recs.push({
               'date':'2017-09-01',
               'courseName':'同步辅导语文一年级上'+i,
-              'courseID':'course-'+i,
+              'courseId':'course-'+i,
               'lessonName':'悯农',
-              'lessonID':'lesson-'+i,
+              'lessonId':'lesson-'+i,
               'downloadStatus':'下载完成',
               'createTime':1505187194,
               'storageUsage':150211,
             });
           }
           */
-        let {status, data, error} = CommandBus.execute({type:CMD_TYPE.DOWNLOAD_ALL_LESSON_STATUS_GET, payload:{}});
-        let recs = [];
-        if (!status && data && data.recs){
-            recs = data.recs;
-        }
-
-        this.lessonIds = [];
-        for(let idx in recs){
-            let item = recs[idx];
-            this.lessonIds.push(item['lessonID']);
-
-            // make a map of lessonID to courseID
-            this.lessonItems[item['lessonID']] = {
-                'lessonName':item['lessonName'],
-                'courseID':item['courseID'],
-            }
-        }
-
-        //TVUtil.Toast.show(JSON.stringify({status,data, error, recs}), 5000);
         this.setContentView(require('../../../res/tpl/DownloadScene.tpl'), {}, 'DownloadManagerScene', {}, () => {
-            let downloadStatusTableHtml = this.generateDownloadStatusTable({recs});
-            let downloadStatusTableWrapper = document.getElementById('download-status-table-wrapper');
-            downloadStatusTableWrapper.innerHTML = downloadStatusTableHtml;
-            this.moye.root.reRender();
+          this.fetchDownloadList();
         });
     }
 
     onResume(retData) {
       if (!retData) return;
       //send delete cmd
-      let lessonID = retData.lessonID;
-      let {status, data} = CommandBus.execute({type:CMD_TYPE.DOWNLOAD_LESSON_DELETE, payload:{lessonID}});
-      //delete dom node
-
-      //if(0 == status){
-      let curNode = document.getElementById('lesson-download-record-'+lessonID);
-      curNode.parentNode.removeChild(curNode);
-      //}
-
-      this.moye.root.reRender();
-      //找兄弟结点
-      let findIdx = this.lessonIds.indexOf(lessonID);
-      if(-1 == findIdx){
-          return;
-      }
-      this.lessonIds.splice(findIdx, 1);
-      if(findIdx >= this.lessonIds.length){
-          findIdx = this.lessonIds.length - 1;
-      }
-      let nextFocusLessonId = null;
-      if(findIdx >= 0){
-          nextFocusLessonId = this.lessonIds[findIdx];
-      }
-      if(nextFocusLessonId){
-        this.moye.root.getWidgetById('del-btn-lesson-'+nextFocusLessonId).focus();
-      }
+      let lessonId = retData.lessonId;
+      let courseId = this.lessonItems[lessonId]['courseId']
+      this.deleteDownloadFile(lessonId, courseId)
     }
 
     onPause() {
@@ -187,16 +198,17 @@ class DownloadManagerScene extends scene {
             return;
         }
         if(e.target.con.classList.contains('download-del-btn')){
-            let lessonID = e.target.con.dataset.id;
-            let title = this.lessonItems[lessonID].lessonName;
+            let lessonId = e.target.con.dataset.id;
+            let title = this.lessonItems[lessonId].lessonName;
             let parentScene = 'DownloadManagerScene';
-            this.showScene(require('./DelConfirmScene.js'), { parentScene, lessonID, title });
+            this.showScene(require('./DelConfirmScene.js'), { parentScene, lessonId, title });
         } else if (e.target.con.classList.contains('download-enter-btn')) {
-            let lessonID = e.target.con.dataset.id;
-            let courseID = this.lessonItems[lessonID].courseID;
-            let lessonName = this.lessonItems[lessonID].lessonName;
+            let lessonId = e.target.con.dataset.id;
+            let courseId = this.lessonItems[lessonId].courseId;
+            let lessonName = this.lessonItems[lessonId].lessonName;
+            let downloadStatus = this.lessonItems[lessonId].downloadStatus;
             // enter relative lesson scene
-            this.showScene(require('./LessonScene.js'), {id:lessonID, courseId:courseID, title:lessonName});
+            this.showScene(require('./LessonScene.js'), {courseId, downloadStatus, id:lessonId, title:lessonName});
         }
     }
 

+ 59 - 0
src/stage/index/scene/DownloadTipScene.js

@@ -0,0 +1,59 @@
+class DownloadTipScene extends scene {
+  constructor(scope) {
+    super(scope);
+  }
+
+  onCreate() {
+    this.setContentView(require('../../../res/tpl/DownloadTipScene.tpl'), {}, 'DownloadTipScene', {
+      'isParentShow': true
+    }, () => {
+      this.moye.root.getWidgetById('ok-btn').focus();
+    });
+  }
+
+  onResume() {
+
+  }
+
+  onPause() {
+
+  }
+
+  onDestroy() {
+
+  }
+
+  onActive() {
+
+  }
+
+  onInactive() {
+
+  }
+
+  // 所有事件类函数默认触发时会传递过来一个Event,其中包含着事件响应节点以及其他相关信息
+  // 查看信息:console.log(e)
+  // 获取Event节点Id的方法(前提是触发事件的节点存在Id)
+  // 在使用Atv时Id对应:e.target.id
+  // 非使用Atv是Id对应:e.target.id
+  onOK(e) {
+    let backScene = 'DownloadTipScene';
+    if (e.target.con.id == 'ok-btn') {
+      this.hideScene( { backScene } , 'CourseScene');
+    }
+  }
+
+  onBack() {
+
+  }
+
+  onKeydown() {
+
+  }
+
+  onKeyup() {
+
+  }
+}
+
+module.exports = DownloadTipScene;

+ 27 - 1
src/stage/index/scene/ImageWareFullScreenScene.js

@@ -1,8 +1,15 @@
 import Consts from '../../../util/Consts';
 
+function getLocalResourceUrl(absoluteUrl) {
+  if (!absoluteUrl) return;
+  const segments = absoluteUrl.split('/') || [];
+  return `${Consts.NODE_SERVER}/lesson/readFile?n=${segments.slice(3).join('*')}`;
+}
+
 class ImageWareFullScreenScene extends scene {
 	constructor(scope) {
 		super(scope);
+		this.isDownload = false;
 		this.wareList = [];
 		this.curWareIndex = 0;
 		this.curWareType = null;
@@ -12,7 +19,11 @@ class ImageWareFullScreenScene extends scene {
 
 	renderImageView() {
 		const curImage = this.curImageList[this.curImageIndex];
-		document.getElementById('wareImg').setAttribute('src', curImage.url);
+		if (this.isDownload) {
+			document.getElementById('wareImg').setAttribute('src', getLocalResourceUrl(curImage.url));
+		} else {
+			document.getElementById('wareImg').setAttribute('src', curImage.url);
+		}
 	}
 
 	dynamicChangeWare(wareIndex, type) {
@@ -31,6 +42,20 @@ class ImageWareFullScreenScene extends scene {
 					wareList: this.wareList,
 					curWareIndex: this.curWareIndex,
 				});
+            //下一个或前一个课件是音频课件
+			} else if (this.curWareType === Consts.TYPE_AUDIOBOOK) {
+        let imgList = this.wareList[this.curWareIndex].list;
+        let imgIndex = 0;
+        if (type === 'BACK' && imgList.length) {
+            imgIndex = imgList.length - 1;
+        }
+        this.hideScene();
+        this.showScene(require('./AudioWareFullScreenScene.js'), {
+            wareList: this.wareList,
+            curWareIndex: this.curWareIndex,
+            curAudioList: imgList,
+            curAudioIndex: imgIndex,
+        });
 			//下一个或前一个课件是图片课件
 			} else {
 				this.curImageList = this.wareList[wareIndex].list;
@@ -94,6 +119,7 @@ class ImageWareFullScreenScene extends scene {
 	}
 
 	onCreate(data) {
+		this.isDownload = data.isDownload;
     this.wareList = data.wareList;
     this.curWareIndex = data.curWareIndex;
     if (data.curImageList) {

+ 511 - 358
src/stage/index/scene/LessonScene.js

@@ -1,8 +1,8 @@
 import APIClient from '../../../util/API/APIClient';
+import WinBoxAPI from '../../../util/WinBoxAPI';
 import Consts from '../../../util/Consts';
 import Utils from '../../../util/Utils';
 import EfunVideoPlayer from '../../../util/EfunVideoPlayer';
-import {CommandBus, CMD_TYPE} from '../../../util/CommandBus';
 
 function matchWare(wareList, wareId) {
     const matchedWareList = wareList.filter((ware) => {
@@ -16,12 +16,27 @@ function matchWare(wareList, wareId) {
     return false;
 }
 
+function checkDownloadStatus(status) {
+  if (status === Consts.DOWNLOAD_STATUS_SUCCESS) {
+    return true;
+  } else {
+    return false;
+  }
+}
+
+function getLocalResourceUrl(absoluteUrl) {
+  if (!absoluteUrl) return;
+  const segments = absoluteUrl.split('/') || [];
+  return `${Consts.NODE_SERVER}/lesson/readFile?n=${segments.slice(3).join('*')}`;
+}
+
 class LessonScene extends scene {
-    constructor(scope) {
+  constructor(scope) {
     super(scope);
     this.timer = null;        //记录定时器
     this.isBack = false;      //是否返回上个场景
     this.videoPlayer = null;  //视频播放器
+    this.isDownload = false;  //是否已下载
     this.courseId = null;     //记录课程ID
     this.lessonId = null;     //记录课ID
     this.wareList = null;     //记录课件列表
@@ -30,137 +45,153 @@ class LessonScene extends scene {
     this.curWareIndex = 0;    //当前课件在课件列表中的索引
     this.curImageList = null; //当前图片课件的图片列表
     this.curImageIndex = null;//当前图片在列表中的索引
+    this.curAudioList = null; //当前音频课件的音频列表
+    this.curAudioIndex = 0;   //当前音频在列表中的索引
     this.videoPosition = {
     	top: 270,
     	left: 790,
     	width: 1072,
     	height: 603,
     };
-    }
+  }
 
-    /**
-    * 根据课程id及课id请求课件列表
-    */
-    loadWareList() {
-        APIClient.getWareList(this.lessonId, this.courseId, (isTrue, response) => {
-        	if (!isTrue) { return; }
-        	if (!response.success) {
-        		TVUtil.Toast.show('获取课件列表失败!', 1500);
-                return;
-        	}
-        	if (response.data && response.data.list && response.data.list.length > 0) {
-        		this.renderWareList(response.data.list);
-        		this.wareList = response.data.list;
-        	} else {
-        		this.hideScene();
-        		this.showScene(require('./DataBuildingScene'), {});
-        	}
-        });
-    }
+  /**
+  * 根据课程id及课id请求课件列表
+  */
+  loadWareList() {
+    APIClient.getWareList(this.lessonId, this.courseId, (isTrue, response) => {
+    	if (!isTrue) { return; }
+    	if (!response.success) {
+    		TVUtil.Toast.show('获取课件列表失败!', 1500);
+            return;
+    	}
+    	if (response.data && response.data.list && response.data.list.length > 0) {
+    		this.renderWareList(response.data.list);
+    		this.wareList = response.data.list;
+    	} else {
+    		this.hideScene();
+    		this.showScene(require('./DataBuildingScene'), {});
+    	}
+    });
+  }
 
-    /**
-    * 把课件列表进行渲染
-    */
-    renderWareList(dataset) {
-    	let listDom = document.getElementById('list-content');
-    	dataset.forEach(function(item, index) {
-    		const { id, type } = item;
+  /**
+  * 把课件列表进行渲染
+  */
+  renderWareList(dataset) {
+  	let listDom = document.getElementById('list-content');
+  	dataset.forEach(function(item, index) {
+  		const { id, type } = item;
 
-    		let itemDom = document.createElement('div');
-    		itemDom.setAttribute('id', `item-${type}-${id}-${index}`);
-    		itemDom.setAttribute('class', 'ware-item');
-    		itemDom.setAttribute('fe-role', 'Widget');
-    		itemDom.innerHTML = this.createHTMLString(item);
-    		listDom.appendChild(itemDom);
-    		if (index === 0) {
-    			this.curWareType = parseInt(type);
-    			this.curWareId = id;
-    			this.createRightView(item);
-    		}
-    	}.bind(this));
+  		let itemDom = document.createElement('div');
+  		itemDom.setAttribute('id', `item-${type}-${id}-${index}`);
+  		itemDom.setAttribute('class', 'ware-item');
+  		itemDom.setAttribute('fe-role', 'Widget');
+  		itemDom.innerHTML = this.createHTMLString(item);
+  		listDom.appendChild(itemDom);
+  		if (index === 0) {
+  			this.curWareType = parseInt(type);
+  			this.curWareId = id;
+  			this.createRightView(item);
+  		}
+  	}.bind(this));
 
-    	let listScroll = this.moye.root.getWidgetById('list');
-    	listScroll.on('focus', e => {
-    		if (this.curWareId === e.target.id.split('-')[2]) {
-    			return;
-    		}
-    		this.curWareId = e.target.id.split('-')[2]
-    		this.curWareType = parseInt(e.target.id.split('-')[1]);
-    		this.curWareIndex = parseInt(e.target.id.split('-')[3]);
-            let curWare = matchWare(this.wareList, this.curWareId);
-            if (curWare) {
-                this.createRightView(curWare);
-            }
-    	});
-    	this.moye.root.reRender();
-    }
+  	let listScroll = this.moye.root.getWidgetById('list');
+  	listScroll.on('focus', e => {
+  		if (this.curWareId === e.target.id.split('-')[2]) {
+  			return;
+  		}
+  		this.curWareId = e.target.id.split('-')[2]
+  		this.curWareType = parseInt(e.target.id.split('-')[1]);
+  		this.curWareIndex = parseInt(e.target.id.split('-')[3]);
+      let curWare = matchWare(this.wareList, this.curWareId);
+      if (curWare) {
+        this.createRightView(curWare);
+      }
+  	});
+  	this.moye.root.reRender();
+  }
 
-    /**
-    * 创建左侧列表项内容
-    */
-    createHTMLString(data) {
-    	let item = {
-    		text: data.category || '',
-    		icon: '',
-    	}
-    	switch (data.type) {
-    		case Consts.TYPE_IMAGE:
-    			item.icon = 'assets/img/LessonScene/img.png';
-    			break;
-    		case Consts.TYPE_VIDEO:
-    			item.icon = 'assets/img/LessonScene/video.png';
-    			break;
-    	}
-    	return `<div class="ware-item-frame">
-              <div class="ware-type">${item.text}</div>
-              <div class="ware-desc">
-                <div class="ware-names">${data.title}</div>
-                <div class="ware-icon">
-                	<img class="ware-icon-content" src="${item.icon}">
-                </div>
-              </div>
-            </div>
-          `;
-    }
+  /**
+  * 创建左侧列表项内容
+  */
+  createHTMLString(data) {
+  	let item = {
+  		text: data.category || '',
+  		icon: '',
+  	}
+  	switch (data.type) {
+  		case Consts.TYPE_IMAGE:
+  			item.icon = 'assets/img/LessonScene/img.png';
+  			break;
+  		case Consts.TYPE_VIDEO:
+  			item.icon = 'assets/img/LessonScene/video.png';
+  			break;
+      case Consts.TYPE_AUDIOBOOK:
+        item.icon = 'assets/img/LessonScene/audio.png';
+        break;
+  	}
+  	return `
+      <div class="ware-item-frame">
+        <div class="ware-type">${item.text}</div>
+        <div class="ware-desc">
+          <div class="ware-names">${data.title}</div>
+          <div class="ware-icon">
+          	<img class="ware-icon-content" src="${item.icon}">
+          </div>
+        </div>
+      </div>
+    `;
+  }
 
-    /**
-    * 创建右侧视窗
-    */
-    createRightView(item) {
-        // 清一下定时器
-        window.clearInterval(this.timer);
-        this.timer = null;
+  /**
+  * 创建右侧视窗
+  */
+  createRightView(item) {
+    // 清一下定时器
+    window.clearInterval(this.timer);
+    this.timer = null;
 
-        const { title, type, list } = item;
-        //设定视窗的标题
-        document.getElementById('view-top').innerHTML = title;
-        //关闭安卓播放器
-    	if (window.efunbox) {
-    		window.efunbox.closePlayer();
-    	}
-    	switch (type) {
-    		case Consts.TYPE_VIDEO:
-    			let playUrl = '';
-    			if (list && list.length >= 1) {
-    				playUrl = Utils.videoUrlFormat(list[0].url);
-    			}
-          /*
-    			let videoViewDom =
-            `
-              <div id="view-full-screen" fe-role="Widget" class="view-full-screen-video">
-              </div>
-              <div id="view-video-start" fe-role="Widget">
-                <div class="transparent-btn">播放</div>
-              </div>
-            `;
-          */
-          let videoViewDom = '';
-    			document.getElementById('view-bottom').innerHTML = videoViewDom;
-    			this.moye.root.reRender();
-    			this.renderVideoView(title, playUrl, type);
-    			break;
-    		case Consts.TYPE_IMAGE:
-    			let imageViewDom =
+    const { title, type, list } = item;
+    //设定视窗的标题
+    document.getElementById('view-top').innerHTML = title;
+    //关闭安卓播放器
+  	if (window.efunbox) {
+  		window.efunbox.closePlayer();
+  	}
+  	switch (type) {
+  		case Consts.TYPE_VIDEO:
+  			let playUrl = '';
+  			if (list && list.length >= 1) {
+  				playUrl = Utils.videoUrlFormat(list[0].url);
+  			}
+        let videoViewDom = '';
+  			document.getElementById('view-bottom').innerHTML = videoViewDom;
+  			this.moye.root.reRender();
+  			this.renderVideoView(title, playUrl, type);
+  			break;
+  		case Consts.TYPE_IMAGE:
+  			let imageViewDom =
+  			`
+  				<div id="view-full-screen" fe-role="Widget" class="view-full-screen-img"></div>
+  				<div id="view-previous" fe-role="Widget">
+            <div class="transparent-btn">上一页</div>
+          </div>
+  				<div id="view-page">1/1</div>
+            <div id="view-next" fe-role="Widget">
+            <div class="transparent-btn">下一页</div>
+          </div>
+  			`;
+  			document.getElementById('view-bottom').innerHTML = imageViewDom;
+  			this.moye.root.reRender();
+  			this.curImageList = list;
+  			if (this.curImageList.length > 0) {
+  				this.curImageIndex = 0;
+  				this.renderImageView();
+  			}
+        break;
+      case Consts.TYPE_AUDIOBOOK:
+    		let audioViewDom =
     			`
     				<div id="view-full-screen" fe-role="Widget" class="view-full-screen-img"></div>
     				<div id="view-previous" fe-role="Widget">
@@ -171,269 +202,391 @@ class LessonScene extends scene {
               <div class="transparent-btn">下一页</div>
             </div>
     			`;
-    			document.getElementById('view-bottom').innerHTML = imageViewDom;
-    			this.moye.root.reRender();
-    			this.curImageList = list;
-    			if (this.curImageList.length > 0) {
-    				this.curImageIndex = 0;
-    				this.renderImageView();
-    			}
-    			break;
-            default:
-                break;
-    	}
+  			document.getElementById('view-bottom').innerHTML = audioViewDom;
+  			this.moye.root.reRender();
+  			this.curAudioList = list;
+  			if (this.curAudioList.length > 0) {
+  				this.curAudioIndex = 0;
+  				this.renderAudioView();
+  			}
+  			break;
+      default:
+        break;
+  	}
+  }
+
+  /**
+  * 渲染图片视图
+  */
+  renderImageView() {
+  	const curImage = this.curImageList[this.curImageIndex];
+  	document.getElementById('view-page').innerHTML = (this.curImageIndex + 1) + '/' + this.curImageList.length;
+    let imageDom = `<img src="${curImage.url}" />`
+    if (this.isDownload) {
+      imageDom = `<img src="${getLocalResourceUrl(curImage.url)}" onerror="this.src='${curImage.url}'" />`
+    }
+  	document.getElementById('view-content').innerHTML = imageDom;
+  }
+
+  /**
+  * 渲染视频视图
+  */
+  renderVideoView(name, url, type) {
+    let localUrl = url;
+    if (this.isDownload) {
+      localUrl = getLocalResourceUrl(url)
+    }
+    if (window.efunbox) {
+        window.efunbox.initAndroidPlayer(
+        	name,
+        	localUrl,
+        	1, //与android里的音视频类型定义有关,这里写死为type=1
+        	this.videoPosition.top,
+        	this.videoPosition.left,
+        	this.videoPosition.width,
+        	this.videoPosition.height,
+        	false
+        );
+        window.efunbox.start();
+        this.videoPlayer = window.efunbox;
+    } else {
+        const videoDom = `<div id="hls-video"></div>`;
+        document.getElementById('view-content').innerHTML = videoDom;
+        this.videoPlayer = new EfunVideoPlayer();
+        this.videoPlayer.initPlayer(localUrl, 'hls-video', url);
     }
+  	// 监控到初始化视频成功后暂停画面
+  	this.timer = window.setInterval(() => {
+  		if (this.videoPlayer.playStatus()) {
+  			if(this.videoPlayer.getCurtime() > 1000){
+  				this.videoPlayer.pause();
+  				document.getElementById('view-video-start').innerHTML = '播放';
+  				window.clearInterval(this.timer);
+  				this.timer = null;
+  			}
+  		}
+  	}, 500);
+  }
 
-    /**
-    * 渲染图片视图
-    */
-    renderImageView() {
-    	const curImage = this.curImageList[this.curImageIndex];
-    	document.getElementById('view-page').innerHTML = (this.curImageIndex + 1) + '/' + this.curImageList.length; const imageDom = `<img src=${curImage.url} />`
-    	document.getElementById('view-content').innerHTML = imageDom;
+  /**
+   * 渲染音频视图
+   */
+  renderAudioView(focusTarget) {
+    const curAudio = this.curAudioList[this.curAudioIndex];
+    const { img, audio, type } = curAudio;
+    let imgPath = (img || {}).path || '';
+    let audioUrl = (audio || {}).url;
+	  let footer = document.getElementById('view-page');
+    if (footer) {
+      footer.innerHTML = (this.curAudioIndex + 1) + '/' + this.curAudioList.length;
+    }
+    let content = document.getElementById('view-content');
+    // 1.更换背景图片
+    const imgUrl = `${Consts.IMG_PATH}/${imgPath}`;
+    let imgHTML = `<img src="${imgUrl}" />`;
+    if (this.isDownload) {
+      imgHTML = `<img src="${getLocalResourceUrl(imgUrl)}" />`
+    }
+    content.innerHTML = imgHTML;
+    // 2.根据是否有无audioURL来控制面板及audio的展现
+    if (type === Consts.TYPE_AUDIOBOOK && audioUrl) {
+      if (this.isDownload) {
+        audioUrl = getLocalResourceUrl(audioUrl)
+      }
+      let audioElement = document.createElement('audio');
+      audioElement.setAttribute('id', 'courseware-audio');
+      audioElement.setAttribute('src', audioUrl);
+      audioElement.setAttribute('autoplay', 'autoplay');
+      let controlsElement = document.createElement('div');
+      controlsElement.setAttribute('class', 'audio-controls');
+      let controlsBtns = `
+        <!-- 播放/暂停 -->
+        <div id="audio-play" class="audio-controls-item btn-play" fe-role="Widget"></div>
+        <!-- 有声/静音 -->
+        <div id="audio-mute" class="audio-controls-item btn-mute" fe-role="Widget"></div>
+        <!-- 下一个音频 -->
+        <div id="audio-next" class="audio-controls-item btn-next" fe-role="Widget"></div>
+        <!-- 上一个音频 -->
+        <div id="audio-last" class="audio-controls-item btn-last" fe-role="Widget"></div>
+      `;
+      controlsElement.innerHTML = controlsBtns;
+      content.appendChild(audioElement);
+      content.appendChild(controlsElement);
+      this.moye.root.reRender();
+      // 监听onended事件
+      let audioDom = document.getElementById('courseware-audio');
+      if (audioDom) {
+        audioDom.addEventListener('ended', function () {
+        document.getElementById('audio-play').classList.add('paused');
+        audioDom.currentTime = 0;
+        }, false);
+      }
+      // 指定光标位置
+      if (focusTarget && this.moye.root.getWidgetById(focusTarget)) {
+        this.moye.root.getWidgetById(focusTarget).focus();
+      }
     }
+  }
+
+  /* 音频播放控制 */
+  audioPlayControl(eventId) {
+      let targetAudio = document.getElementById('courseware-audio');
+      if (!targetAudio) { return; }
+      switch (eventId) {
+          case 'audio-play':
+              let playBtn = document.querySelector('#audio-play');
+              if (targetAudio.paused) {
+                  targetAudio.play();
+                  playBtn.classList.remove('paused');
+              } else {
+                  targetAudio.pause();
+                  playBtn.classList.add('paused');
+              }
+              break;
+          case 'audio-mute':
+              let muteBtn = document.querySelector('#audio-mute');
+              if (targetAudio.muted) {
+                  targetAudio.muted = false;
+                  muteBtn.classList.remove('muted');
+              } else {
+                  targetAudio.muted = true;
+                  muteBtn.classList.add('muted');
+              }
+              break;
+          case 'audio-next':
+              if (this.curAudioIndex < this.curAudioList.length -1) {
+                  this.curAudioIndex += 1;
+                  this.renderAudioView('audio-next');
+              }
+              break;
+          case 'audio-last':
+              if (this.curAudioIndex > 0) {
+                  this.curAudioIndex -= 1;
+                  this.renderAudioView('audio-last');
+              }
+              break;
+          default:
+              break;
+      }
+  }
 
-    /**
-    * 渲染视频视图
-    */
-    renderVideoView(name, url, type) {
-      if (window.efunbox) {
-          window.efunbox.initAndroidPlayer(
-          	name,
-          	url,
-          	1, //与android里的音视频类型定义有关,这里写死为type=1
-          	this.videoPosition.top,
-          	this.videoPosition.left,
-          	this.videoPosition.width,
-          	this.videoPosition.height,
-          	false
-          );
-          window.efunbox.start();
-          this.videoPlayer = window.efunbox;
-      } else {
+  updateRightView(item) {
+  	const { title, type, list } = item;
+  	document.getElementById('view-top').innerHTML = title;
+  	switch (type) {
+  		case Consts.TYPE_VIDEO:
+  			let playUrl = '';
+  			if (list && list.length >= 1) {
+  				playUrl = Utils.videoUrlFormat(list[0].url);
+  			}
+  			document.getElementById('view-bottom').innerHTML = '';
+  			this.moye.root.reRender();
+        //如果是H5播放器,则重新创建video标签
+        if (window.efunbox) {
+            window.efunbox.customScreen(270, 790, 1072, 603);
+        } else {
           const videoDom = `<div id="hls-video"></div>`;
           document.getElementById('view-content').innerHTML = videoDom;
           this.videoPlayer = new EfunVideoPlayer();
-          this.videoPlayer.initPlayer(url, 'hls-video');
-      }
-    	// 监控到初始化视频成功后暂停画面
-    	this.timer = window.setInterval(() => {
-    		if (this.videoPlayer.playStatus()) {
-    			if(this.videoPlayer.getCurtime() > 1000){
-    				this.videoPlayer.pause();
-    				document.getElementById('view-video-start').innerHTML = '播放';
-    				window.clearInterval(this.timer);
-    				this.timer = null;
-    			}
-    		}
-    	}, 500);
-    }
+          this.videoPlayer.initPlayer(playUrl, 'hls-video', url);
+        }
+  			break;
+  		case Consts.TYPE_IMAGE:
+  			let imageViewDom =
+  			`
+  				<div id="view-full-screen" fe-role="Widget" class="view-full-screen-img"></div>
+  				<div id="view-previous" fe-role="Widget">
+            <div class="transparent-btn">上一页</div>
+          </div>
+  				<div id="view-page">1/1</div>
+  				<div id="view-next" fe-role="Widget">
+            <div class="transparent-btn">下一页</div>
+          </div>
+  			`;
+  			document.getElementById('view-bottom').innerHTML = imageViewDom;
+  			this.moye.root.reRender();
+  			this.renderImageView();
+  			break;
+      default:
+        break;
+  	}
+  }
 
-    updateRightView(item) {
-    	const { title, type, list } = item;
-    	document.getElementById('view-top').innerHTML = title;
-    	switch (type) {
-    		case Consts.TYPE_VIDEO:
-    			let playUrl = '';
-    			if (list && list.length >= 1) {
-    				playUrl = Utils.videoUrlFormat(list[0].url);
-    			}
-          /*
-          let playText = '播放';
-          if (this.videoPlayer && this.videoPlayer.playStatus()) {
-              playText = '暂停';
-          }
-    			let videoViewDom =
-            `
-              <div id="view-full-screen" fe-role="Widget" class="view-full-screen-video">
-              </div>
-              <div id="view-video-start" fe-role="Widget">
-                <div class="transparent-btn">${playText}</div>
-              </div>
-            `;
-          */
-    			document.getElementById('view-bottom').innerHTML = '';
-    			this.moye.root.reRender();
-          //如果是H5播放器,则重新创建video标签
-          if (window.efunbox) {
-              window.efunbox.customScreen(270, 790, 1072, 603);
-          } else {
-            const videoDom = `<div id="hls-video"></div>`;
-            document.getElementById('view-content').innerHTML = videoDom;
-            this.videoPlayer = new EfunVideoPlayer();
-            this.videoPlayer.initPlayer(playUrl, 'hls-video');
-          }
-    			break;
-    		case Consts.TYPE_IMAGE:
-    			let imageViewDom =
-    			`
-    				<div id="view-full-screen" fe-role="Widget" class="view-full-screen-img"></div>
-    				<div id="view-previous" fe-role="Widget">
-                        <div class="transparent-btn">上一页</div>
-                    </div>
-    				<div id="view-page">1/1</div>
-    				<div id="view-next" fe-role="Widget">
-                        <div class="transparent-btn">下一页</div>
-                    </div>
-    			`;
-    			document.getElementById('view-bottom').innerHTML = imageViewDom;
-    			this.moye.root.reRender();
-    			this.renderImageView();
-    			break;
-        default:
-          break;
-    	}
-    }
+  /**
+  * 记录播放行为事件
+  */
+  postPlayRecord(lessonId, courseId, playStopTime=1){
+  	APIClient.putUserAction(
+  		Consts.USER_ACTION_WATCH,
+  		Consts.USER_ACTION_WATCH_NAME,
+  		`${courseId}_${lessonId}`,
+  		playStopTime,
+  		(isTrue, res) => {},
+  	);
+  }
 
-    /**
-    * 记录播放行为事件
-    */
-    postPlayRecord(lessonId, courseId, playStopTime=1){
-    	APIClient.putUserAction(
-    		Consts.USER_ACTION_WATCH,
-    		Consts.USER_ACTION_WATCH_NAME,
-    		`${courseId}_${lessonId}`,
-    		playStopTime,
-    		(isTrue, res) => {},
-    	);
-    }
+  onCreate(data) {
+    //是否已下载
+    // this.isDownload = checkDownloadStatus(data.downloadStatus);
+    this.isDownload = true;
+    this.lessonId = data.id;
+    this.courseId = data.courseId;
+    this.setContentView(require('../../../res/tpl/LessonScene.tpl'), {}, 'LessonScene', {}, () => {
+      document.getElementById('title').appendChild(document.createTextNode(data.title));
+      this.loadWareList();
+    });
+  }
 
-    onCreate(data) {
-        this.lessonId = data.id;
-        this.courseId = data.courseId;
-        this.setContentView(require('../../../res/tpl/LessonScene.tpl'), {}, 'LessonScene', {}, () => {
-            document.getElementById('title').appendChild(document.createTextNode(data.title));
-            this.loadWareList();
-    		CommandBus.execute({
-    			type: CMD_TYPE.APP_BHV_POST,
-    			payload: {
-    				eventName: "enter_wareScene",
-    				eventPage: "wareScene",
-    				eventAttr: {
-    					courseId: data.courseId,
-    					lessonId: data.id,
-    				}
-                },
-    		});
-          }
-        );
+  onResume(data) {
+    if (!data) { return; }
+    //更新下当前的课件信息
+    const { curWareIndex, curImageList, curImageIndex, curAudioList, curAudioIndex } = data;
+    this.curWareIndex = curWareIndex;
+    this.curWareId = this.wareList[curWareIndex].id;
+    this.curWareType = this.wareList[curWareIndex].type;
+    if (curImageList) {
+      this.curImageList = curImageList;
+    }
+    if (curImageIndex) {
+      this.curImageIndex = curImageIndex;
+    }
+    if (curAudioList) {
+      this.curAudioList = curAudioList;
     }
+    if (curAudioIndex) {
+      this.curAudioIndex = curAudioIndex;
+    }
+    //更新左侧焦点位置
+    this.moye.root.getWidgetById(`item-${this.curWareType}-${this.curWareId}-${this.curWareIndex}`).focus();
+    //更新右侧视图
+    this.updateRightView(this.wareList[curWareIndex]);
+    this.isBack = true;
+  }
 
-    onResume(data) {
-        if (!data) { return; }
-        //更新下当前的课件信息
-        const { curWareIndex, curImageList, curImageIndex } = data;
-        this.curWareIndex = curWareIndex;
-        this.curWareId = this.wareList[curWareIndex].id;
-        this.curWareType = this.wareList[curWareIndex].type;
-        if (curImageList) {
-            this.curImageList = curImageList;
+  onOK(e) {
+    // 点击后退按钮
+    if (e.target.con.classList.contains('goback')) {
+      this.hideScene({id: this.courseId}, 'CourseScene');
+      return;
+    }
+    // 拦截音频控制相关事件单独处理
+  	const leaf = FocusEngine.getFocusedLeaf();
+    if (leaf.id && leaf.id.startsWith('audio')) {
+      this.audioPlayControl(leaf.id);
+      return;
+    }
+    switch (leaf.id) {
+      case 'view-video-start':
+        if (this.curWareType == Consts.TYPE_VIDEO) {
+          if (this.videoPlayer.playStatus()) {
+            this.videoPlayer.pause();
+            document.getElementById('view-video-start').innerHTML = '播放';
+          } else {
+            this.videoPlayer.start();
+            document.getElementById('view-video-start').innerHTML = '暂停';
+          }
         }
-        if (curImageIndex) {
-            this.curImageIndex = curImageIndex;
+        //添加播放记录
+        this.postPlayRecord(this.curWareId, this.courseId);
+        break;
+      case 'view-full-screen':
+        if (this.curWareType === Consts.TYPE_IMAGE) {
+          this.showScene(require('./ImageWareFullScreenScene.js'), {
+            wareList: this.wareList,
+            curWareIndex: this.curWareIndex,
+            curImageList: this.curImageList,
+            curImageIndex: this.curImageIndex,
+          });
+        } else if (this.curWareType === Consts.TYPE_VIDEO) {
+          let video = document.getElementById('hls-video');
+          if (video) {
+            document.getElementById('view-content').removeChild(video);
+          }
+          this.showScene(require('./VideoWareFullScreenScene.js'), {
+            isFull: true,
+            wareList: this.wareList,
+            curWareIndex: this.curWareIndex,
+          });
+        } else if (this.curWareType === Consts.TYPE_AUDIOBOOK) {
+          // 全屏前移除audio标签
+          let audio = document.getElementById('courseware-audio');
+          let controls = document.querySelector('.audio-controls');
+          if (audio) {
+            document.getElementById('view-content').removeChild(audio);
+          }
+          if (controls) {
+            document.getElementById('view-content').removeChild(controls);
+          }
+          this.showScene(require('./AudioWareFullScreenScene.js'), {
+            wareList: this.wareList,
+            curWareIndex: this.curWareIndex,
+            curAudioList: this.curAudioList,
+            curAudioIndex: this.curAudioIndex,
+            isDownload: this.isDownload,
+          });
         }
-        //更新左侧焦点位置
-        this.moye.root.getWidgetById(`item-${this.curWareType}-${this.curWareId}-${this.curWareIndex}`).focus();
-        //更新右侧视图
-        this.updateRightView(this.wareList[curWareIndex]);
-        this.isBack = true;
-    }
-
-    onOK(e) {
-        // 后退
-        if (e.target.con.classList.contains('goback')) {
-            this.hideScene({id: this.courseId}, 'CourseScene');
-            return;
+        this.postPlayRecord(this.cur_item_id, this.courseId);
+        break;
+      case 'view-previous':
+        if (this.curWareType === Consts.TYPE_IMAGE && this.curImageIndex - 1 >= 0) {
+          this.curImageIndex -= 1;
+          this.renderImageView();
         }
-    	const leaf = FocusEngine.getFocusedLeaf();
-    	switch (leaf.id) {
-    		case 'view-video-start':
-    			if (this.curWareType == Consts.TYPE_VIDEO) {
-    				if (this.videoPlayer.playStatus()) {
-    					this.videoPlayer.pause();
-    					document.getElementById('view-video-start').innerHTML = '播放';
-    				} else {
-    					this.videoPlayer.start();
-    					document.getElementById('view-video-start').innerHTML = '暂停';
-    				}
-    			}
-    			//添加播放记录
-    			this.postPlayRecord(this.curWareId, this.courseId);
-    			break;
-    		case 'view-full-screen':
-                if (this.curWareType === Consts.TYPE_IMAGE) {
-            		this.showScene(require('./ImageWareFullScreenScene.js'), {
-            			wareList: this.wareList,
-            			curWareIndex: this.curWareIndex,
-            			curImageList: this.curImageList,
-            			curImageIndex: this.curImageIndex,
-            		});
-                } else if (this.curWareType === Consts.TYPE_VIDEO) {
-                    let video = document.getElementById('hls-video');
-                    if (video) {
-                        video.webkitEnterFullScreen();
-                        // document.getElementById('view-content').removeChild(video);
-                    }
-                    // this.showScene(require('./VideoWareFullScreenScene.js'), {
-                    //     isFull: true,
-                    //     wareList: this.wareList,
-                    //     curWareIndex: this.curWareIndex,
-                    // });
-                }
-    			this.postPlayRecord(this.cur_item_id, this.courseId);
-    			break;
-    		case 'view-previous':
-    			if (this.curWareType === Consts.TYPE_IMAGE && this.curImageIndex - 1 >= 0) {
-    				this.curImageIndex -= 1;
-    				this.renderImageView();
-    			}
-    			this.postPlayRecord(this.curWareId, this.courseId);
-    			break;
-    		case 'view-next':
-    			if (this.curWareType === Consts.TYPE_IMAGE && this.curImageIndex + 1 < this.curImageList.length) {
-    				this.curImageIndex += 1;
-    				this.renderImageView();
-    			}
-    			this.postPlayRecord(this.curWareId, this.courseId);
-    			break;
-            default:
-                break;
-    	}
-    }
+        if (this.curWareType === Consts.TYPE_AUDIOBOOK && this.curAudioIndex - 1 >= 0) {
+          this.curAudioIndex -= 1;
+          this.renderAudioView();
+        }
+        this.postPlayRecord(this.curWareId, this.courseId);
+        break;
+      case 'view-next':
+        if (this.curWareType === Consts.TYPE_IMAGE && this.curImageIndex + 1 < this.curImageList.length) {
+          this.curImageIndex += 1;
+          this.renderImageView();
+        }
+        if (this.curWareType === Consts.TYPE_AUDIOBOOK && this.curAudioIndex + 1 < this.curAudioList.length) {
+          this.curAudioIndex += 1;
+          this.renderAudioView();
+        }
+        this.postPlayRecord(this.curWareId, this.courseId);
+        break;
+      default:
+        break;
+  	}
+  }
 
-    onPause() {
+  onPause() {
 
-    }
+  }
 
-    onDestroy() {
+  onDestroy() {
 
-    }
+  }
 
-    onActive() {
+  onActive() {
 
-    }
+  }
 
-    onInactive() {
+  onInactive() {
 
-    }
+  }
 
-    onBack() {
-    	if (this.isBack) {
-    		return true;
-    	} else if (window.efunbox) {
-    		window.efunbox.closePlayer();
-    	}
-    }
+  onBack() {
+  	if (this.isBack) {
+  		return true;
+  	} else if (window.efunbox) {
+  		window.efunbox.closePlayer();
+  	}
+  }
 
-    onKeydown(e) {
-    	switch (e.keyCode) {
-    		case Consts.KEYCODE_EXIT:
-    			this.isBack = false;
-    			break;
-            default:
-                break;
-    	}
-    }
+  onKeydown(e) {
+  	switch (e.keyCode) {
+  		case Consts.KEYCODE_EXIT:
+  			this.isBack = false;
+  			break;
+      default:
+        break;
+  	}
+  }
 }
 
 module.exports = LessonScene;

+ 21 - 2
src/stage/index/scene/VideoWareFullScreenScene.js

@@ -36,12 +36,31 @@ class VideoWareFullScreenScene extends scene {
                 this.initVideoPlayer(curWareItem);
             } else if (this.curWareType === Consts.TYPE_IMAGE) {
                 //进入到图片全屏场景
+                let imgList = curWareItem.list;
+                let imgIndex = 0;
+                if (type === 'BACK' && imgList.length) {
+                    imgIndex = imgList.length - 1;
+                }
                 this.hideScene();
                 this.showScene(require('./ImageWareFullScreenScene.js'), {
                     wareList: this.wareList,
                     curWareIndex: this.curWareIndex,
-                    curImageList: curWareItem.list,
-                    curImageIndex: 0,
+                    curImageList: imgList,
+                    curImageIndex: imgIndex,
+                });
+            } else if (this.curWareType === Consts.TYPE_AUDIOBOOK) {
+                //进入到音频全屏场景
+                let imgList = curWareItem.list;
+                let imgIndex = 0;
+                if (type === 'BACK' && imgList.length) {
+                    imgIndex = imgList.length - 1;
+                }
+                this.hideScene();
+                this.showScene(require('./AudioWareFullScreenScene.js'), {
+                    wareList: this.wareList,
+                    curWareIndex: this.curWareIndex,
+                    curAudioList: imgList,
+                    curAudioIndex: imgIndex,
                 });
             }
         }, 1500);

+ 65 - 0
src/stage/index/style/AudioWareFullScreen.less

@@ -0,0 +1,65 @@
+#AudioWareFullScreen {
+	position: absolute;
+	left: 0;
+	top: 0;
+	width: 100%;
+	height: 100%;
+	overflow: hidden;
+	background-image: url(assets/img/icon.png);
+	background-size: 100% 100%;
+	background-repeat: no-repeat;
+
+	img {
+		width: 100%;
+		height: 100%;
+	}
+
+	audio {
+		width: 100%;
+		height: 100%;
+	}
+
+	.audio-controls {
+		z-index: 10;
+		position: absolute;
+		left: 0;
+		bottom: .4rem;
+		width: 100%;
+		height: .7rem;
+		.audio-controls-item {
+			width: .6rem;
+			height: .6rem;
+			border: solid unit(@borderSize, rem) transparent;
+			border-radius: 50%;
+			background-size: 100% 100%;
+			background-repeat: no-repeat;
+			&.btn-play {
+				float: left;
+				margin-left: .2rem;
+				background-image: url(assets/img/Audio/audio_stop.png);
+				&.paused {
+					background-image: url(assets/img/Audio/audio_play.png);
+				}
+			}
+			&.btn-mute {
+				float: left;
+				background-image: url(assets/img/Audio/audio_voice.png);
+				&.muted {
+					background-image: url(assets/img/Audio/audio_mute.png);
+				}
+			}
+			&.btn-last {
+				float: right;
+				background-image: url(assets/img/Audio/audio_last.png);
+			}
+			&.btn-next {
+				float: right;
+				margin-right: .2rem;
+				background-image: url(assets/img/Audio/audio_next.png);
+			}
+			&.fe-focus {
+				// .after-focus(@borderSize; #ffe100; .1rem; rgba(0,0,0,0.5));
+			}
+		}
+	}
+}

+ 74 - 0
src/stage/index/style/DownloadTipScene.less

@@ -0,0 +1,74 @@
+.course-download-wrapper {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background-color: rgba(0, 0, 0, .5);
+  z-index: 2;
+
+  .toast {
+    position: absolute;
+    width: 8.52rem;
+    height: 5.04rem;
+    top: 50%;
+    left: 50%;
+    transform: translate3d(-50%, -50%, 0);
+    -webkit-transform: translate3d(-50%, -50%, 0);
+    overflow: hidden;
+    padding: 0.33rem;
+    line-height: 1;
+    background-color: #ffffff;
+    text-align: center;
+    border-radius: 0.6rem;
+    font-size: 0.48rem;
+
+    img {
+      width: 1.3rem;
+      height: 1.3rem;
+      border-radius: 0.65rem;
+    }
+
+    p {
+      color: #515151;
+      font-size: 0.48rem;
+      margin: 0.4rem;
+    }
+
+    .ok-btn {
+      position: absolute;
+      bottom: .34rem;
+      left: 2.5rem;
+      width: 3.6rem;
+      height: 1.2rem;
+      padding: 0.3rem 0;
+      border-radius: .5rem;
+      color: #fff;
+      background-color: #fe84b2;
+      font-size: 0.48rem;
+
+      &.fe-focus {
+        //.after-focus(@borderSize; #ff5050);
+      }
+    }
+
+    /*
+    .cancle {
+        position: absolute;
+        bottom: .34rem;
+        right: .34rem;
+        width: 3.6rem;
+        height: 1.2rem;
+        line-height: 1.2rem;
+        border-radius: .5rem;
+        color: #fff;
+        background-color: #fe84b2;
+        font-size: 0.48rem;
+
+        &.fe-focus {
+            .after-focus(@borderSize; #ff5050);
+        }
+    }
+    */
+  }
+}

+ 47 - 0
src/stage/index/style/LessonScene.less

@@ -124,6 +124,53 @@
 				width: 100%;
 				height: 100%;
 			}
+			audio {
+				width: 100%;
+				height: 100%;
+			}
+			.audio-controls {
+				z-index: 10;
+				position: absolute;
+				left: 0;
+				bottom: 1.22rem;
+				width: 10.72rem;
+				height: .6rem;
+				.audio-controls-item {
+					width: .6rem;
+					height: .6rem;
+					border: solid unit(@borderSize, rem) transparent;
+					border-radius: 50%;
+					background-size: 100% 100%;
+					background-repeat: no-repeat;
+					&.btn-play {
+						float: left;
+						margin-left: .2rem;
+						background-image: url(assets/img/Audio/audio_stop.png);
+						&.paused {
+							background-image: url(assets/img/Audio/audio_play.png);
+						}
+					}
+					&.btn-mute {
+						float: left;
+						background-image: url(assets/img/Audio/audio_voice.png);
+						&.muted {
+							background-image: url(assets/img/Audio/audio_mute.png);
+						}
+					}
+					&.btn-last {
+						float: right;
+						background-image: url(assets/img/Audio/audio_last.png);
+					}
+					&.btn-next {
+						float: right;
+						margin-right: .2rem;
+						background-image: url(assets/img/Audio/audio_next.png);
+					}
+					&.fe-focus {
+						// .after-focus(@borderSize; #ffe100; .1rem; rgba(0,0,0,0.5));
+					}
+				}
+			}
 		}
 
 		#view-bottom {

+ 18 - 7
src/util/API/APIClient.js

@@ -4,7 +4,7 @@ import userDataStorage from '../userDataStorage';
 import Utils from '../Utils';
 
 class APIClient {
-	constructor() { }
+	constructor() {}
 
 	// 添加缓存参数,安卓截获带有此参数的请求
 	static addCacheParam(params, cacheKeySrc=null, cacheKey=null){
@@ -24,22 +24,28 @@ class APIClient {
 
 	// 账户登录,获取token,绑定设备
 	static userLoginAndBindDevice(data, callback) {
+		let deviceModel,deviceMfrs,deviceBrand = '';
 		let deviceCode = localStorage.getItem('deviceCode');
-		let deviceType = "";
+    if(window.efunbox) {
+      deviceModel = window.efunbox.getModelForDevice();
+      deviceMfrs = window.efunbox.getMfrsForDevice();
+      deviceBrand = window.efunbox.getBrandForDevice();
+		}
 		if (!deviceCode) {
 			if (window.efunbox) {
-				deviceCode = window.efunbox.getUuidForDevice();
-				deviceType = window.efunbox.getTypeForDevice();
+        deviceCode = window.efunbox.getUuidForDevice();
 			} else {
-				deviceCode = Utils.getUuidForWeb();
+        deviceCode = Utils.getUuidForWeb();
 			}
 			localStorage.setItem('deviceCode', deviceCode);
 		}
 		let params = {
-			deviceCode,
+      deviceCode,
 			eid: data.usercode,
 			password: data.password,
-      deviceType:deviceType
+      deviceModel: deviceModel,
+      deviceMfrs: deviceMfrs,
+      deviceBrand: deviceBrand
 		};
 		AJAXHelper.post('/token', params, callback);
 	}
@@ -169,6 +175,11 @@ class APIClient {
 	  let params = { eventType, tarName, tarId, value };
 	  AJAXHelper.post('/callback/event', params, callback);
 	}
+
+	// 获取用户的下载记录
+	static getUserDownloadList(callback) {
+		AJAXHelper.get('/callback/download/list', {}, callback);
+	}
 }
 
 module.exports = APIClient;

+ 7 - 2
src/util/Consts.js

@@ -10,6 +10,9 @@ class Consts {
     }
 }
 
+//node服务接口地址
+Consts.NODE_SERVER = 'http://127.0.0.1:8089';
+
 //图片/视频资源域名
 Consts.IMG_PATH = 'https://efunimgs.ai160.com';
 Consts.VIDEO_PATH = 'https://efunvideo.ai160.com';
@@ -19,7 +22,9 @@ Consts.DATA_BUILDING = 'http://ljimgs.ai160.com/2b/app_resource/data_building.jp
 
 //图片/视频资源类型代号
 Consts.TYPE_VIDEO = 0;
+Consts.TYPE_AUDIO = 1;
 Consts.TYPE_IMAGE = 3;
+Consts.TYPE_AUDIOBOOK = 4;
 
 //产品类型
 Consts.TYPE_COURSE = 'COURSE';
@@ -40,8 +45,8 @@ Consts.DOM_ID_LOCAL_DOWNLOAD_BUTTON = 'local-download-btn'
 Consts.EVENT_TYPE_OK = 'ok';
 
 Consts.DOWNLOAD_STATUS_UNDOWNLOAD = 0;
-Consts.DOWNLOAD_STATUS_ONGOING = 1;
-Consts.DOWNLOAD_STATUS_SUCCESS = 2;
+Consts.DOWNLOAD_STATUS_SUCCESS = 1;
+Consts.DOWNLOAD_STATUS_ONGOING = 2;
 Consts.DOWNLOAD_STATUS_FAILED = 3;
 
 Consts.ANDROID_FORCE_VERSION = '2.2.2';

+ 0 - 7
src/util/EfunVideoPlayer.js

@@ -4,12 +4,6 @@ class EfunVideoPlayer {
     this.metadata = null;
   }
 
-  loadedHandler() {
-    this.efunplayer.addListener('loadedmetadata', () => {
-      this.metadata = this.efunplayer.getMetaDate();
-    });
-  }
-
   initPlayer(url, domId) {
     let videoObject = {
       autoplay: true,
@@ -30,7 +24,6 @@ class EfunVideoPlayer {
   }
 
   pause() {
-    console.log('click pause btn...');
     this.efunplayer.videoPause();
   }
 

+ 64 - 0
src/util/WinBoxAPI.js

@@ -0,0 +1,64 @@
+import userDataStorage from './userDataStorage';
+import Consts from './Consts';
+
+class WinBoxAPI {
+  constructor() {}
+
+  static whenAjaxResponse(httpRequest, callback) {
+		if (httpRequest.readyState != 4) {
+			return;
+		}
+		let res = JSON.parse(httpRequest.responseText);
+		callback(httpRequest.status == 200, res);
+  }
+
+  static baseRequest(method, path, params, callback) {
+		let xmlHttpReq = new XMLHttpRequest();
+
+		let sendBody = null;
+    let url = `${Consts.NODE_SERVER}${path}?`;
+    if (method === 'GET') {
+      for (let key in params) {
+        url += `${key}=${params[key]}&`;
+      }
+    }
+		if (params && (method == 'POST' || method == 'PUT')) {
+			sendBody = JSON.stringify({...params});
+		}
+		xmlHttpReq.open(method, url, true);
+		xmlHttpReq.onreadystatechange = function () {
+			WinBoxAPI.whenAjaxResponse(xmlHttpReq, callback);
+		};
+		xmlHttpReq.send(sendBody);
+  }
+
+  static get(path, params, callback) {
+    WinBoxAPI.baseRequest('GET', path, params, callback);
+  }
+
+  static post(path, params) {
+    WinBoxAPI.baseRequest('POST', path, params, callback);
+  }
+
+  static postDownloadRequest(lessonId, courseId, callback) {
+		const { token = '', uid = '', eid = '' } = userDataStorage.getData() || {};
+    let path = '/lesson/downloadFile';
+    let params = { lessonId, courseId, uid, eid, token };
+    WinBoxAPI.get(path, params, callback);
+  }
+
+  static deleteDownloadFile(lessonId, courseId, callback) {
+		const { token = '', uid = '', eid = '' } = userDataStorage.getData() || {};
+    let path = '/lesson/delFile';
+    let params = { lessonId, courseId, uid, eid, token };
+    WinBoxAPI.get(path, params, callback);
+  }
+
+  static readDownloadedFile(lessonId, courseId, callback) {
+		const { token = '', uid = '', eid = '' } = userDataStorage.getData() || {};
+    let path = '/lesson/readFile';
+    let params = { lessonId, courseId, uid, eid, token };
+  }
+}
+
+module.exports = WinBoxAPI;

+ 8 - 60
src/util/course.js

@@ -16,70 +16,23 @@ class Course {
 			recs.push(item.id);
 		}
 
-    	let cmdResult = CommandBus.execute({type:CMD_TYPE.DOWNLOAD_LESSON_STATUS_GET, payload:{recs}});
-		let lessonDownloadStatus = {};
-		if (!cmdResult.status){
-			for(let idx in cmdResult.data.recs){
-        		let rec = cmdResult.data.recs[idx];
-				lessonDownloadStatus[rec.lessonID.toString()] = parseInt(rec.downloadStatus);
-			}
-		}
-
 		// 现在只按文字模板进行渲染
-		main.innerHTML = this.textList(data, lessonDownloadStatus, auth);
+		main.innerHTML = this.textList(data, auth);
 	}
 
-	//废弃
-	static imgList(data, lessonDownloadStatus) {
+	static textList(data, auth) {
 		let content = '';
-		function listItem(data, seq, downloadStatus) {
-
-      	//根据不同的下载状态,设置不同的Button状态
-		let btnClass = 'download-btn-lesson-icon-ready';
-		if (downloadStatus == Consts.DOWNLOAD_STATUS_ONGOING){
-			btnClass = 'download-btn-lesson-icon-ongoing';
-		}
-		else if (downloadStatus == Consts.DOWNLOAD_STATUS_SUCCESS) {
-			btnClass = 'download-btn-lesson-icon-success';
-		}
-
-		let url = data.picUrl ? `${Consts.IMG_PATH}/${data.picUrl}` : `http://via.placeholder.com/350x150?text=NO PIC ${data.id}`
-		return `<div data-seq="${seq}" class="lesson-icon-wrapper">
-		        <div id="lesson-btn-${seq}" data-id="${data.id}" data-template="${data.templateCode}" data-name="${data.itemTitle}" fe-role="Widget" class="img-wrapper" data-seq="${seq}">
-		  				<img src="${url}" alt="${data.itemTitle}">
-		  			</div>
-		        <div id="download-btn-${data.id}" fe-role="Widget" class="${btnClass}" data-id="${data.id}" data-name="${data.itemTitle}" data-seq="${seq}" ></div>
-			</div>`;
-		}
-
-		for (let i in data) {
-			let downloadStatus = Consts.DOWNLOAD_STATUS_UNDOWNLOAD;
-			let lessonId = data[i].id.toString();
-			if (lessonDownloadStatus[lessonId]){
-				downloadStatus = lessonDownloadStatus[lessonId];
-			}
-
-			content += listItem(data[i], i, downloadStatus);
-		}
-
-		return `<div class="list-pic-container" fe-role="Scroll" fe-cfg="scroll_dir:v,scroll_center:con,scroll_duration:0.2,scroll_easing:linear">
-		<div class="scroll-list clearfix" id="course-main-list">${content}</div>
-		</div>`;
-	}
-
-	static textList(data, lessonDownloadStatus, auth) {
-		let content = '';
-		function listItem(data, seq, downloadStatus, isFree) {
+		function listItem(data, seq, isFree) {
 			let btnClass = 'download-btn-lesson-list-ready';
-			if (downloadStatus == Consts.DOWNLOAD_STATUS_ONGOING){
+			if (data.downloadStatus == Consts.DOWNLOAD_STATUS_ONGOING){
 				btnClass = 'download-btn-lesson-list-ongoing';
 			}
-			else if (downloadStatus == Consts.DOWNLOAD_STATUS_SUCCESS) {
+			else if (data.downloadStatus == Consts.DOWNLOAD_STATUS_SUCCESS) {
 				btnClass = 'download-btn-lesson-list-success';
 			}
 			return `
 				<div data-seq="${seq}">
-		        	<div id="lesson-btn-${seq}" data-id="${data.id}" data-name="${data.title}" data-seq="${seq}" fe-role="Widget" class="text-wrapper">
+		        	<div id="lesson-btn-${seq}" data-id="${data.id}" data-name="${data.title}" data-dload="${data.downloadStatus}" data-seq="${seq}" fe-role="Widget" class="text-wrapper">
 						${Utils.fixOverflowStr(data.title, 32, '...')}
 						<div class="free-flag" style="display: ${isFree ? "block" : "none"}"></div>
 					</div>
@@ -89,16 +42,11 @@ class Course {
 			`;
 		}
 		for (let i in data) {
-			let downloadStatus = Consts.DOWNLOAD_STATUS_UNDOWNLOAD;
-			let lessonId = data[i].id.toString();
-			if (lessonDownloadStatus[lessonId]){
-				downloadStatus = lessonDownloadStatus[lessonId];
-			}
 			// 课程未购买的第一课加入free标记
 			if (i == 0 && !auth) {
-				content += listItem(data[i], i, downloadStatus, true);
+				content += listItem(data[i], i, true);
 			} else {
-				content += listItem(data[i], i, downloadStatus, false);
+				content += listItem(data[i], i, false);
 			}
 		}
 		return `<div id="list-text-container" class="list-text-container" fe-role="Scroll" fe-cfg="scroll_dir:v,scroll_center:con,scroll_duration:0.2,scroll_easing:linear"><div class="scroll-list clearfix" id="course-main-list">${content}</div></div> `;