infoOld.vue 69 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425
  1. <template>
  2. <!-- <page-meta :page-font-size="`${this.$store.getters.scaleFontSize}px`" :root-font-size="`${this.$store.getters.scaleFontSize}px`"></page-meta>
  3. -->
  4. <view class="content">
  5. <view class="video-box">
  6. <!-- #ifndef APP-PLUS -->
  7. <video @tap="toggleBarChange" ref="myVideo" id="myVideo" :src="pickCatalog.videoUrl"
  8. @error="videoErrorCallback" :enable-progress-gesture="data.isFast==1" :enable-danmu="false" :danmu-btn="false" :danmu-list="danmuList" :initial-time="studyTimes"
  9. @play="onPlayVideo" @pause="onPauseVideo" :poster="poster" objectFit="contain" :show-progress="data.isFast==1" :title="pickCatalog.courseName" :controls="true" :show-fullscreen-btn="true" @controlstoggle="toggleBarChange"
  10. @timeupdate="onTimeUpdate" @fullscreenchange="onFullscreenChange" @waiting="onWaiting()" @progress="onProgress" @ended="endedPlayNext()" @canplay="onVideoCanPlay" @canplaythrough="onVideoCanPlayThrough"
  11. @loadeddata="onLoadeddata" @loadedmetadata="onLoadedMetadata" >
  12. <!-- 疗法 -->
  13. <cover-view v-if="showTherapy&&fullScreen" class="horizontal" @tap.stop>
  14. <cover-view class="goods" @tap.stop="goToPro(showTherapyItem.packageId)">
  15. <cover-image :src="showTherapyItem.imgUrl" mode="aspectFill" class="goodsimg"></cover-image>
  16. <cover-view class="goodsname"><cover-view class="goodsname-txt">{{showTherapyItem.packageName}}</cover-view></cover-view>
  17. </cover-view>
  18. <cover-view class="es-w-40 es-h-40" style="position: absolute;right:0rpx;top:0rpx;z-index:999">
  19. <cover-image class="es-w-40 es-h-40" src="@/static/images/close40.png" @tap.stop="closeTherapy"></cover-image>
  20. </cover-view>
  21. </cover-view>
  22. </video>
  23. <cover-view v-if="showAudio" class="audiobox es es-ver es-ac es-pc" @click.stop>
  24. <cover-view class="audiobox-title textOne" :style="{paddingTop: paddingTop + 'px'}">{{catalogueList[pickCatalogIdx]&&catalogueList[pickCatalogIdx].title}}</cover-view>
  25. <cover-view class="es es-ver es-ac es-pc">
  26. <cover-view class="es es-ac es-pc">
  27. <cover-image class="es-icon-52 es-icon-play-last"
  28. src="/static/images/other/video/play-last.png" @tap="endedPlayPrev()"></cover-image>
  29. <cover-image class="es-icon-88 es-ml-50 es-mr-50"
  30. :src="audioPlayIng?'/static/images/other/video/play-stop.png':'/static/image/hall/video_icon.png'" @tap="playAudioAction()"></cover-image>
  31. <cover-image class="es-icon-52 es-icon-play-next"
  32. src="/static/images/other/video/play-next.png" @tap="endedPlayNext('click')"></cover-image>
  33. </cover-view>
  34. <cover-view class="audiobox-time">{{playTime}} / {{$formatSeconds(pickCatalog.seconds)}}</cover-view>
  35. </cover-view>
  36. <cover-view class="audiobox-video es es-pc" @tap="backPlayVideo">返回视频</cover-view>
  37. </cover-view>
  38. <!-- #endif -->
  39. </view>
  40. <scroll-view class="scroll-Y" :scroll-y="true" :style="'height:' + clientHeight + 'px;'" v-show="!isShowList">
  41. <view class="video-info">
  42. <view class="video-info-header">
  43. <view class="video-info-headerl">
  44. <image mode="aspectFill" :src="data.talentAvatar"></image>
  45. <text class="textOne">{{data.courseName}}</text>
  46. </view>
  47. <button class="follow-btn" @tap="doFollow()" >
  48. <image v-show="!isFollow" src="@/static/image/hall/guanzhu_icon.png" mode="aspectFill"></image>
  49. <text>{{isFollow?"已关注":"关注"}}</text>
  50. </button>
  51. </view>
  52. <view class="video-info-voice" v-if="false">
  53. <view class="video-info-voicebox1">
  54. <view class="video-info-voice-l">
  55. <image src="@/static/image/hall/hear_icon.png" mode="aspectFill"></image>
  56. <text>听声音</text>
  57. </view>
  58. <image class="video-info-voice-r" src="@/static/image/hall/left_show_icon.png" mode="aspectFill"></image>
  59. </view>
  60. <view style="margin-top: 36rpx;">
  61. <!-- <myAudio audioId="audio1" :url="audioPath" /> -->
  62. <view class="audio">
  63. <view class="audio-play" @tap='playAudioAction()'>
  64. <image class='audio-icon' :src="audioPlayIng?'/static/image/hall/hear_play_icon.png':'/static/image/hall/hear_suspend_icon.png'"></image>
  65. </view>
  66. <view class='audio-time es-ml-18 es-mr-18'>{{playTime}}</view>
  67. <view class='audio-slider'>
  68. <slider :disabled="data.isFast==0" @change="audioChange" @changing="audioChanging" activeColor='#FF5C03' :block-size="25" :min="0" :max="pickCatalog.seconds==0?1:pickCatalog.seconds.toFixed(0)" :value="courseDuration" :step='0.1'></slider>
  69. </view>
  70. <view class='audio-time'>{{ $formatSeconds(pickCatalog.seconds) }}</view>
  71. </view>
  72. </view>
  73. </view>
  74. <view>
  75. <view class="video-info-voicebox2">
  76. <text>{{data.views}}次播放 · 总时长:{{data.totalDuration}}</text>
  77. <view class="x-c" @click="isExpand = !isExpand" v-if="showExpandText">
  78. <text>{{isExpand ? '收起简介' : '展开简介'}}</text>
  79. <view :class="isExpand ? 'rotate':''"><uni-icons type="down" size="14" color="#bbbbbb"></uni-icons></view>
  80. </view>
  81. </view>
  82. <view :class="showDes|| !showExpandText? 'opacity video-info-desc':'video-info-desc' " id="descbox-desc" :style="{height: isExpand ? 'auto': '84rpx'}">
  83. {{data.description}}
  84. <image v-show="!isExpand&&showExpandText" class="desc-image x-c" src="/static/images/other/bg_bar.png"></image>
  85. </view>
  86. </view>
  87. <view class="video-info-footer">
  88. <view @tap="playAudioAction('backvideo')">
  89. <image src="@/static/image/hall/sound_icon24.png" mode="aspectFill"></image>
  90. <text :style="{color: showAudio ? '#FF5C03':'#757575'}">听声</text>
  91. </view>
  92. <view @tap="$navTo('./note?courseId='+courseId)" v-if="!$qconfig.isAppStore">
  93. <image src="@/static/image/hall/note_icon24.png" mode="aspectFill"></image>
  94. <text>笔记</text>
  95. </view>
  96. <view @tap="doFavorite()">
  97. <image :src="isFavorite?'/static/image/hall/collect_on_icon24.png':'/static/image/hall/collect_icon24.png'" mode="aspectFill"></image>
  98. <text>{{isFavorite?"已收藏":"收藏"}}</text>
  99. </view>
  100. <view @tap="doLike()">
  101. <image :src="isLike?'/static/image/hall/like_on_icon.png':'/static/image/hall/like_icon.png'" mode="aspectFill"></image>
  102. <text>{{isLike?"喜欢":"喜欢"}}</text>
  103. </view>
  104. <view @tap="openShare()">
  105. <image src="@/static/image/hall/weixin_icon.png" mode="aspectFill"></image>
  106. <text>分享</text>
  107. </view>
  108. </view>
  109. </view>
  110. <!-- 讲堂目录 -->
  111. <view class="video-directory">
  112. <view class="box-header">
  113. <view class="box-header-title">讲堂目录</view>
  114. <view class="box-header-r" @tap="goToCatalogue()">
  115. <text>共{{catalogueList.length}}节</text>
  116. <image src="@/static/image/hall/my_right_arrow_right_icon.png" mode="aspectFill"></image>
  117. </view>
  118. </view>
  119. <scroll-view class="video-directory-scrollx" scroll-x="true" :scroll-into-view="scrollIntoViewId"
  120. scroll-with-animation="true" overflow-anchor="none">
  121. <view :id="'cataLogue' + index"
  122. :class="pickCatalogIdx == index ? 'active-scrollitem video-directory-scrollitem':'video-directory-scrollitem'"
  123. v-for="(item,index) in catalogueList" :key="index" @click="pickCatalogAction(index)">
  124. <view :class="index>1 && canShowVip(item) ? 'freeflag freeflag-member':'freeflag freeflag-free'">
  125. {{ index>1 && canShowVip(item) ? '会员' : '免费'}}
  126. </view>
  127. <view class="video-directory-num">
  128. <text>第{{item.courseSort}}讲</text>
  129. <image v-if='pickCatalogIdx == index' src="@/static/image/hall/hear_icon.png"></image>
  130. <view class="empty" v-else></view>
  131. </view>
  132. <view class="video-directory-title">
  133. <view class="textTwo">{{item.title}}</view>
  134. <!-- <view class="imagebox">
  135. <view class="mask" v-if='pickCatalogIdx != index'>
  136. <image src="@/static/image/hall/video_icon.png" mode="aspectFill"></image>
  137. </view>
  138. <image class="video-directory-img" src="@/static/image/home1/logo.png" mode="aspectFill"></image>
  139. </view> -->
  140. </view>
  141. </view>
  142. </scroll-view>
  143. </view>
  144. <!-- 课程疗法 -->
  145. <view class="therapy" v-show="packageJsonList&&packageJsonList.length > 0">
  146. <view class="box-header-title" style="margin-bottom: 20rpx;">课程疗法</view>
  147. <scroll-view class="therapy-scrollx" scroll-x="true" :scroll-into-view="scrollIntoTherapy"
  148. scroll-with-animation="true" overflow-anchor="none">
  149. <view
  150. :class="therapyIndex == idx ? 'therapy-active therapy-scrollitem':'therapy-scrollitem'"
  151. :id="'therapy' + idx"
  152. v-for="(item,idx) in packageJsonList"
  153. :key="idx"
  154. @click="handleTherapy(item,idx)">
  155. <image mode="aspectFill" class="therapy-goodsimg" :src="item.imgUrl"></image>
  156. <view class="therapy-goodsname textTwo">{{item.packageName}}</view>
  157. </view>
  158. </scroll-view>
  159. </view>
  160. <!-- 评论 -->
  161. <view class="video-comment" v-if="!$qconfig.isAppStore">
  162. <view class="box-header">
  163. <view class="box-header-title">评论</view>
  164. <view class="box-header-r" @tap="goToComment()">
  165. <text>共{{data.commentNum}}条</text>
  166. <image src="@/static/image/hall/my_right_arrow_right_icon.png" mode="aspectFill"></image>
  167. </view>
  168. </view>
  169. <view style="padding: 20rpx 24rpx;">
  170. <commentList :commentList="data.commentList" />
  171. </view>
  172. </view>
  173. <!-- 猜你喜欢 -->
  174. <view class="video-comment">
  175. <view class="box-header">
  176. <view class="box-header-title">猜你喜欢</view>
  177. <view class="box-header-r" v-if="false">
  178. <text>更多</text>
  179. <image src="@/static/image/hall/my_right_arrow_right_icon.png" mode="aspectFill"></image>
  180. </view>
  181. </view>
  182. <view class="hall-box">
  183. <hallItem class="gapitem" v-for="(item, index) in dataList " :key="index" :item="item" @click="navTo('/pages/course/info?courseId='+item.courseId)" />
  184. </view>
  185. </view>
  186. </scroll-view>
  187. <!-- h5下载 -->
  188. <h5-down-app-tip :pageUrl="pageUrl" :type="'course'" :courseId="courseId" />
  189. <!-- 分享弹窗 -->
  190. <u-popup :show="showShare" @close="closeShareAct()" >
  191. <share-box :shareItem="shareItem" @closeShare='closeShareAct()' ></share-box>
  192. </u-popup>
  193. <!-- VIP特权弹窗 -->
  194. <uni-popup ref="popPrivilege" type="bottom" borderRadius="10rpx 10rpx 0px 0px">
  195. <view class="privilegeBox es es-ver es-br-38 es-pt-30 es-pb-30 ">
  196. <view class="es es-fx es-pc es-h-56 es-ml-48 es-mr-48">
  197. <image class="es-w-74 es-h-40" style="position: absolute;left:60rpx;top:0" src="../../static/image/course/xiangyun.png"></image>
  198. <view class="es-fs-40 es-h-56 es-fw-500" style="color: #FFDAA3;">开通VIP专享以下特权</view>
  199. <image class="es-w-74 es-h-40" style="position: absolute;right:60rpx;top:0" src="../../static/image/course/xiangyun2.png"></image>
  200. <image class="es-w-40 es-h-40" style="position: absolute;right:-20rpx;top:-10rpx" @tap="closePrivilege" src="/static/images/close40.png"></image>
  201. </view>
  202. <view class="sec1 es-mt-20 es-ml-48 es-mr-48">
  203. <view class="es x-bc es-pl-28 es-pt-12">
  204. <view class="l1">
  205. <view class="x-f">
  206. <image class="es-w-44 es-h-44" src="../../static/image/course/privilege/fozhu.png"></image>
  207. <view class="es-ml-8 es-c-white es-fs-32 es-fw-600">名家讲堂</view>
  208. </view>
  209. <view class="es-fs-30 es-mt-10 es-c-99">畅享10000+VIP视频</view>
  210. </view>
  211. <view class="es">
  212. <image src="../../static/image/course/zyx.png" class="es-w-183 es-h-98 es-br-15"></image>
  213. <!-- <view class="es-fs-20 es-br-8 es-w-80 es-h-30 es-fw-bold x-c" style="position:absolute; right: 0;top:10rpx;background: #000;opacity: 0.7;color: #FFDAA3;">10000+</view> -->
  214. </view>
  215. </view>
  216. </view>
  217. <view class="sec2 es es-fx es-pc es-h-56 es-mt-40 es-ml-48 es-mr-48">
  218. <!-- <image class="es-w-148 es-h-3" style="position: absolute;left:0;top:16rpx" src="../../static/image/course/privilege/line1.png"></image> -->
  219. <view class="es-fs-30 es-h-56 es-fw-bold" style="color: #FFDAA3;">超多权益待你开启</view>
  220. <!-- <image class="es-w-148 es-h-3" style="position: absolute;right:0;top:16rpx" src="../../static/image/course/privilege/line2.png"></image> -->
  221. </view>
  222. <view class="primenu-box es es-fx es-pc es-mt-20 es-ml-48 es-mr-48">
  223. <view class="content-inner">
  224. <view class="item">
  225. <image class="img" src="/static/image/course/privilege/she.png" mode="heightFix"></image>
  226. <text class="label">AI舌诊</text>
  227. </view>
  228. <view class="item">
  229. <image class="img jlxw" src="/static/image/course/privilege/tizhi.png" mode="heightFix"></image>
  230. <text class="label">体质检测</text>
  231. </view>
  232. <view class="item" >
  233. <image class="img" src="/static/image/course/privilege/baike.png" mode="heightFix"></image>
  234. <text class="label">养生百科</text>
  235. </view>
  236. <view class="item">
  237. <image class="img" src="/static/image/course/privilege/yishu.png" mode="heightFix"></image>
  238. <text class="label">经典医书</text>
  239. </view>
  240. <view class="item">
  241. <image class="img" src="/static/image/course/privilege/more.png" mode="heightFix"></image>
  242. <text class="label">多设备登陆</text>
  243. </view>
  244. <view class="item">
  245. <image class="img" src="/static/image/course/privilege/ad.png" mode="heightFix"></image>
  246. <text class="label">去除广告</text>
  247. </view>
  248. </view>
  249. </view>
  250. <view class="es-ml-48 es-mr-48 es-mt-10 es-pt-10 es-pb-10 es-br-5" style="background:#2a2f32">
  251. <view v-for="(item, index) in vipMethods" :key="index" @tap="changeVipMethod(index)" class="vipMethodItem es x-bc">
  252. <view class="x-bc es-ml-14">
  253. <view class="es-fs-32 es-fw-500 es-ml-14">{{item}}</view>
  254. </view>
  255. <image v-if="vipMethodIdx==index" class="es-w-40 es-h-40 es-br-ban es-mr-14 es-mr-26" src="../../static/image/course/vipBuy/check.png"></image>
  256. <view v-else class="es-w-40 es-h-40 es-br-ban es-mr-14 es-mr-26 circle"></view>
  257. </view>
  258. </view>
  259. <view v-if="isShowPayType" class="es-ml-48 es-mr-48 es-mt-40 x-bc" style="background:#2a2f32">
  260. <view v-for="(item, index) in payTypes" :key="index" @tap="changePayType(index)" class="payTypeItem es x-bc " :class="payType==index+1?'pt_ac':''">
  261. <view class="x-bc es-ml-14">
  262. <image class="es-w-59 es-h-52" :src="index==0?'../../static/image/course/vipBuy/wx.png':'../../static/image/course/vipBuy/zfb.png'"></image>
  263. <view class="es-fs-33 es-c-white es-fw-500 es-ml-14">{{item}}</view>
  264. </view>
  265. <image v-if="payType==index+1" src="../../static/image/course/vipBuy/check.png" class="es-w-40 es-h-40 es-br-ban es-mr-14"></image>
  266. <view v-else class="es-w-40 es-h-40 es-br-ban es-mr-14 circle"></view>
  267. </view>
  268. </view>
  269. <view class="es es-mt-40 es-ml-48 es-mr-48 x-c">
  270. <view @tap="doBuy()" class="es-h-94 x-c es-fw-700 es-fs-34 vipCourseBtn vipAc es-br-46" style="width: 310rpx;">
  271. 立即购买
  272. </view>
  273. </view>
  274. </view>
  275. </uni-popup>
  276. <uni-popup ref="popTip" type="dialog">
  277. <uni-popup-dialog cancelText="支付失败" confirmText="支付成功" mode="base" content="是否已支付成功?" title="提示" :duration="2000" :before-close="true" @close="confirmTip" @confirm="confirmTip"></uni-popup-dialog>
  278. </uni-popup>
  279. <!-- 评论弹窗 -->
  280. <popupBottom ref="mescrollItem" :visible.sync="specVisible" @close="closePop" :cmdId="courseId" :smsNum="data.commentNum" :title="data.commentNum+'条评论'" :type="1" radius="32" maxHeight="1200"></popupBottom>
  281. <!-- 线路 -->
  282. <!-- #ifdef APP-PLUS -->
  283. <view class="video-line" @click="openPop">
  284. <text>线路{{lineIndex + 1 | numberToChinese}}</text>
  285. </view>
  286. <!-- #endif -->
  287. <!-- 线路弹窗 -->
  288. <uni-popup ref="popup" type="bottom">
  289. <view class="popupbox">
  290. <view class="popupbox-head">
  291. <text>线路选择</text>
  292. <image class="close-icon" src="@/static/images/close40.png" mode="aspectFill" @click="close"></image>
  293. </view>
  294. <view class="popupbox-content">
  295. <view
  296. :class="lineIndex == index ? 'line-item line-active': 'line-item'"
  297. v-for="(it,index) in lineList"
  298. :key="index"
  299. @click="handleLine(index)"
  300. >线路{{index + 1 | numberToChinese}}</view>
  301. </view>
  302. </view>
  303. </uni-popup>
  304. </view>
  305. </template>
  306. <script>
  307. import {getUserInfo} from '@/api/user'
  308. import { getCourseById,getCourseList,getCourseVideoList,checkFavorite,checkFollow,checkLike,doFavorite,doFollow,doLike,addDuration,
  309. createCourseOrder,createIntegralOrder,getIntegral,createVipOrder,aliPayment,wxPayment,getCourseOrderById } from '@/api/course'
  310. import commentList from "./components/commentList.vue";
  311. import hallItem from "./components/hallItem.vue";
  312. import popupBottom from '@/components/popupBottom/popupBottom.vue'
  313. import MescrollCompMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-comp.js";
  314. import adMask from "@/components/adMask/adMask.vue"
  315. export default {
  316. mixins: [MescrollCompMixin],
  317. components: {
  318. popupBottom,
  319. commentList,
  320. hallItem,
  321. adMask
  322. },
  323. data() {
  324. return {
  325. lineIndex: 0,
  326. showDes: false,
  327. showExpandText: false,
  328. isExpand: true,
  329. textHeight: 0, //文本高度
  330. videoContext: null,
  331. video: {
  332. percent: 10, //进度百分比
  333. },
  334. courseId:null,
  335. talentId:null,
  336. videoId:null,
  337. curVideoId:null,
  338. showShare:false,
  339. shareItem:{ imageUrl:"",title:"",path:""},
  340. scrollIdx: 1,
  341. scrollIntoViewId: 'cataLogue0',
  342. isShowList: false, // 是否展示讲堂目录列表
  343. isShare:false,
  344. user:null,
  345. data:{
  346. courseId:null,
  347. imgUrl:"",
  348. talentAvatar:"",
  349. price:"",
  350. remark:"",
  351. noteNum:0,
  352. courseName:"",
  353. description:"",
  354. cataIndex:0,
  355. isFast:false,
  356. isAutoPlay:false,
  357. commentList:[
  358. {avatar:"",content:"",createTime:"",nickName:""}
  359. ]
  360. },
  361. dataList:[],
  362. notes:[],
  363. catalogueList:[],
  364. pickCatalog:{ videoUrl:"https://tcpv.ylrzcloud.com/course/20241014/1728890026184.mp4",thumbnail:"",duration:0,videoId:0,seconds:0,studyTime:null},
  365. pickCatalogIdx:0,
  366. danmuList:[],
  367. isFavorite:0,
  368. isFollow:0,
  369. isLike:0,
  370. courseDuration:0,
  371. lookDuration:0, //记录当前观看小节的时长
  372. allLookDuration:0,//H5未登录状态播放五分钟就跳出登录页面
  373. audioDuration:0,
  374. totalDuration:0,
  375. tempAudioDuration:0, //用于记录视频/音频播放切换时 播放的时间,达到无缝续播
  376. countdowning: false, // 观看时长计时开关
  377. isAudioChanging:false,//音频滑块是否在拖动,audioTimer倒计时是否暂停
  378. timer: null, // 定时器
  379. audioTimer:null,
  380. playTime:"00:00",
  381. scaleFontSize:18,
  382. studyTimes:0,
  383. audioContext: null,
  384. audioPlayIng:false,
  385. showFullScreenBtn:true,
  386. isLearning:false,
  387. myVideo:null,
  388. showProgress:true,
  389. videoUrl:"https://1319721001.vod-qcloud.com/3525603bvodcq1319721001/2b3e76ac1253642698811158287/Hmod7JMfAowA.mp4",
  390. poster: "",
  391. studyLog:null,
  392. isPostBack:true,//页面是否已初次加载
  393. isWaiting:false, //视频出现缓冲
  394. specVisible: false,
  395. esComment:null,
  396. isH5:false,
  397. vipSelIndex:0,
  398. vipMethods:["开通会员"],
  399. vipMethodIdx:0,
  400. isShowPayType:false,
  401. payTypes:["微信支付","支付宝支付"],
  402. payType:1,//微信支付1 支付宝支付2
  403. createType:3,//1直接购买,2芳华币兑换 3开通会员
  404. orderId:null,
  405. order:null,
  406. showPayTips:false,
  407. clientHeight: 0,
  408. courseOrderId:0,
  409. accordionVal:'0',
  410. dataUsage:0,
  411. lastBuffered: 0,
  412. isPlayIng:false,//是否正在播放
  413. statusBarHeight: uni.getSystemInfoSync().statusBarHeight,
  414. fullScreen: false,
  415. direction: "",
  416. scrollIntoTherapy: 'therapy0',
  417. therapyIndex: null,
  418. packageJsonList: [],
  419. showTherapy: false,
  420. showTherapyItem: {},
  421. currentTime: 0,
  422. nodeTime: 0,
  423. paddingTop: 0,
  424. showAudio: false,
  425. isNext: 0,
  426. pageUrl: ''
  427. }
  428. },
  429. watch: {
  430. studyTimes: {
  431. handler(val){
  432. uni.$emit("studyTimes",val);
  433. },
  434. immediate: true
  435. }
  436. },
  437. filters: {
  438. numberToChinese(number) {
  439. if(number) {
  440. const chineseNumber = ['一', '二', '三', '四', '五', '六', '七', '八', '九'];
  441. return chineseNumber[number - 1];
  442. } else {
  443. return ''
  444. }
  445. },
  446. },
  447. onLoad(options) {
  448. this.paddingTop = this.statusBarHeight > 0 ? this.statusBarHeight : this.statusBarHeight + uni.upx2px(30)
  449. // #ifdef APP-PLUS
  450. uni.getSubNVueById('videoPopup').hide();
  451. const height = uni.upx2px(425)+ this.statusBarHeight
  452. const subNVue = uni.getSubNVueById('courseVideo')
  453. subNVue.setStyle({
  454. position: "absolute",
  455. width: "100%",
  456. height: height + 'px',
  457. left:"0",
  458. top:"0"
  459. })
  460. uni.$on('getEventType', (data) => {
  461. uni.getSubNVueById('videoPopup').hide();
  462. if(data.type == 'confirm') {
  463. // 确认
  464. this.tipConfirm(data.extraData)
  465. } else {
  466. // 取消
  467. this.tipCancel(data.extraData)
  468. }
  469. })
  470. // #endif
  471. this.courseId=options.courseId;
  472. if(options.isShare!=undefined){
  473. this.isShare=options.isShare;
  474. }
  475. if(options.videoId!=undefined){
  476. this.videoId=options.videoId;
  477. }
  478. if(options.isLearning!=undefined){
  479. this.isLearning=options.isLearning;
  480. }
  481. this.esComment=this.$refs["esComment"];
  482. let that=this;
  483. uni.$on('refreshTitle', (pingCount) => {
  484. that.data.commentNum=pingCount;
  485. });
  486. setTimeout(()=>{
  487. this.getCourseInfo();
  488. this.onNvueEvent()
  489. },200);
  490. if(this.$isLogin()){
  491. this.getUserInfo();
  492. this.checkFavorite();
  493. this.checkLike();
  494. }
  495. },
  496. onShow(){
  497. if(!this.$isLogin()) {
  498. uni.navigateTo({
  499. url: '/pages/auth/loginIndex'
  500. })
  501. return
  502. }
  503. //#ifdef H5
  504. this.isH5=true;
  505. //#endif
  506. //#ifdef APP-PLUS
  507. //plus.navigator.setFullscreen(false)
  508. //plus.screen.lockOrientation('portrait-primary');
  509. if(this.$isLogin()){
  510. if(!this.timer){
  511. this.timer=setInterval(() => {
  512. if(this.countdowning){ //观看时长计时开关开启
  513. this.lookDuration+=5;
  514. this.allLookDuration+=5;
  515. this.addIntegral();
  516. }
  517. }, 5000);
  518. }
  519. }
  520. if(this.isPlayIng){
  521. this.playVideo();
  522. }
  523. //#endif
  524. if(this.showPayTips){
  525. this.$refs.popTip.open();
  526. this.showPayTips=false;
  527. }
  528. },
  529. onHide() {
  530. this.pauseVideo();
  531. //this.$store.commit('setScaleFontSize',16);
  532. },
  533. onReady() {
  534. // #ifndef APP-PLUS
  535. this.videoContext = uni.createVideoContext("myVideo", this);
  536. // #endif
  537. this.audioContext = uni.createInnerAudioContext();
  538. uni.getSystemInfo({success: (res) => {
  539. this.clientHeight = res.windowHeight - uni.upx2px(422) - res.statusBarHeight;
  540. }
  541. });
  542. },
  543. methods: {
  544. onNvueEvent() {
  545. uni.$on("navBack",()=>{this.$navBack()});
  546. uni.$on("onPlayVideo",()=>{
  547. this.onPlayVideo()
  548. });
  549. uni.$on("onWaiting",()=>{this.onWaiting()});
  550. uni.$on("onTimeUpdate",(res)=>{this.onTimeUpdate(res)});
  551. uni.$on("endedPlayNext",(type)=>{this.endedPlayNext(type)});
  552. uni.$on("onLoadedMetadata",(event)=>{this.onLoadedMetadata(event)});
  553. uni.$on("audioBtnEvent",(event)=>{
  554. if(event == 'backPlayVideo') {
  555. this.backPlayVideo()
  556. } else if(event == 'endedPlayPrev'){
  557. this.endedPlayPrev()
  558. } else if(event == 'playAudioAction'){
  559. this.playAudioAction()
  560. }
  561. });
  562. },
  563. getDescHeight() {
  564. this.$nextTick(()=>{
  565. const query = uni.createSelectorQuery().in(this);
  566. query
  567. .select("#descbox-desc")
  568. .boundingClientRect((data) => {
  569. this.textHeight = data.height
  570. this.isExpand = this.textHeight > uni.upx2px(84) ? false : true
  571. this.showExpandText = this.textHeight > uni.upx2px(84) ? true : false
  572. this.showDes = true
  573. })
  574. .exec();
  575. })
  576. },
  577. handleTherapy(item,idx) {
  578. this.scrollIntoTherapy = 'therapy' + idx,
  579. this.therapyIndex = idx
  580. setTimeout(()=> {
  581. uni.navigateTo({
  582. url: "/pages/store/packageDetails?packageId="+item.packageId
  583. });
  584. }, 500);
  585. },
  586. getCourseInfo(){
  587. this.showDes = false
  588. getCourseById(this.courseId).then(res => {
  589. if(res.code==200){
  590. this.data=res.data;
  591. uni.$emit("getDataInfo",this.data);
  592. this.dataList=res.data.courseList;
  593. this.talentId=res.data.talentId;
  594. this.studyLog=res.data.studyLog;
  595. this.isNext = res.data.isNext;
  596. if(this.studyLog!=null){
  597. this.videoId=this.studyLog.videoId;
  598. }
  599. this.vipMethods=["开通会员"];
  600. if(this.data.isIntegral==1){
  601. this.vipMethods.push("芳华币兑换")
  602. }
  603. if(this.data.sellPrice>0){
  604. this.vipMethods.push(this.data.sellPrice+"元购买");
  605. }
  606. this.getDescHeight()
  607. this.getCourseVideoList();
  608. if(this.$isLogin()){
  609. this.checkFollow();
  610. }
  611. }
  612. },
  613. rej => {}
  614. );
  615. },
  616. getCourseList(){
  617. let that=this;
  618. const params={"cateId":this.data.cateId,"isTui":1};
  619. getCourseList(params).then(res => {
  620. if(res.code==200){
  621. this.dataList=res.data.list;
  622. }
  623. },
  624. rej => {}
  625. );
  626. },
  627. //课程目录
  628. getCourseVideoList(){
  629. let that=this;
  630. const params={"courseId":this.courseId};
  631. getCourseVideoList(params,1,50).then(res => {
  632. if(res.code==200){
  633. this.catalogueList=res.data.list;
  634. if(this.catalogueList.length>0){
  635. if(this.videoId!=null&&this.videoId!=0){
  636. this.pickCatalogIdx=this.getCatalogIdx();
  637. this.scrollIntoViewId="cataLogue"+this.pickCatalogIdx;
  638. this.pickCatalog=this.catalogueList[this.pickCatalogIdx];
  639. }else{
  640. this.pickCatalog=this.catalogueList[0];
  641. }
  642. this.packageJsonList = this.pickCatalog && this.pickCatalog.packageJson ? JSON.parse(this.pickCatalog.packageJson) : []
  643. uni.$emit("getPickCatalog",this.pickCatalog);
  644. if(this.pickCatalog.studyTime!=null&&this.pickCatalog.studyTime!=0){
  645. this.initStudyTime(this.pickCatalog.studyTime);
  646. }
  647. //开始播放计时
  648. if(this.data.isAutoPlay==1){
  649. this.pickCatalogMethod(this.pickCatalogIdx);
  650. this.startCountsTime();
  651. }
  652. this.poster=this.pickCatalog.thumbnail;
  653. uni.$emit('poster',this.poster)
  654. this.audioContext.src = this.pickCatalog.videoUrl;
  655. this.video.percent=(this.audioDuration/this.pickCatalog.seconds*1.0).toFixed(2)*100;
  656. }
  657. }
  658. },
  659. rej => {}
  660. );
  661. },
  662. getUserInfo(){
  663. let that=this;
  664. getUserInfo().then(res => {
  665. if(res.code==200){
  666. if(res.user!=null){
  667. uni.setStorageSync('userInfo',JSON.stringify(res.user));
  668. this.user=res.user;
  669. }
  670. else{
  671. uni.showToast({
  672. icon:'none',
  673. title: res.msg,
  674. });
  675. }
  676. }
  677. },
  678. rej => {}
  679. );
  680. },
  681. checkFavorite(){
  682. checkFavorite(this.courseId).then(res => {
  683. if(res.code==200){
  684. this.isFavorite=res.isFavorite;
  685. }
  686. },
  687. rej => {}
  688. );
  689. },
  690. checkFollow(){
  691. checkFollow(this.talentId).then(res => {
  692. if(res.code==200){
  693. this.isFollow=res.isFollow;
  694. }
  695. },
  696. rej => {}
  697. );
  698. },
  699. checkLike(){
  700. checkLike(this.courseId).then(res => {
  701. if(res.code==200){
  702. this.isLike=res.isLike;
  703. }
  704. },
  705. rej => {}
  706. );
  707. },
  708. doFavorite(){
  709. if(!this.$isLogin()){
  710. this.$showLoginPage();
  711. return;
  712. }
  713. uni.showLoading({title:""});
  714. doFavorite(this.courseId).then(res => {
  715. uni.hideLoading();
  716. if(res.code==200){
  717. uni.showToast({title: '操作成功',icon: 'none'});
  718. }else{
  719. uni.showToast({title: res.msg,icon: 'none'});
  720. }
  721. this.isFavorite=!this.isFavorite;
  722. },
  723. rej => {}
  724. );
  725. },
  726. doLike(){
  727. if(!this.$isLogin()){
  728. this.$showLoginPage();
  729. return;
  730. }
  731. uni.showLoading({title:""});
  732. doLike(this.courseId).then(res => {
  733. uni.hideLoading();
  734. if(res.code==200){
  735. uni.showToast({title: '操作成功',icon: 'none'});
  736. }else{
  737. uni.showToast({title: res.msg,icon: 'none'});
  738. }
  739. this.isLike=!this.isLike;
  740. },
  741. rej => {}
  742. );
  743. },
  744. doFollow(){
  745. if(!this.$isLogin()){
  746. this.$showLoginPage();
  747. return;
  748. }
  749. uni.showLoading({title:""});
  750. doFollow(this.talentId).then(res => {
  751. uni.hideLoading();
  752. if(res.code==200){
  753. uni.showToast({title: '操作成功',icon: 'none'});
  754. }else{
  755. uni.showToast({title: res.msg,icon: 'none'});
  756. }
  757. this.isFollow=!this.isFollow;
  758. },
  759. rej => {}
  760. );
  761. },
  762. pickCatalogAction(index,type){
  763. if (this.pickCatalogIdx === index) return;
  764. if(type == 'catalogueN'&&this.isNext == 1 && this.pickCatalogIdx != index - 1) {
  765. if(this.showAudio && this.audioPlayIng) {
  766. this.playAudioAction()
  767. }
  768. if(!this.showAudio) {
  769. this.pauseVideo()
  770. }
  771. this.openTips(index)
  772. return
  773. }
  774. this.pickCatalogActionFun(index,type)
  775. },
  776. pickCatalogActionFun(index,type) {
  777. if(!this.$isLogin()){ //切换小节需要登录
  778. this.$showLoginPage();
  779. return;
  780. }
  781. if(this.isH5 && index>1){
  782. uni.showToast({title: "请下载App观看",icon: 'none'});
  783. return;
  784. }
  785. //切换之前添加课程目录学习记录
  786. this.addStudyCourse();
  787. this.addIntegral(); //加芳华币
  788. this.pickCatalogMethod(index,type);
  789. this.scrollIntoViewId = 'cataLogue' + index;
  790. },
  791. pickCatalogMethod(index,type){
  792. let tempCatalogue=this.catalogueList[index];
  793. this.curVideoId=tempCatalogue.videoId;
  794. this.lookDuration=0;//重置观看当前小节的课程时长
  795. if(tempCatalogue.isVip==1){ //需要Vip才能观看
  796. if(!this.$isLogin()){
  797. this.$showLoginPage();
  798. return;
  799. }
  800. if(this.user==null){
  801. this.user=this.$getUserInfo();
  802. }
  803. if(this.user.isVip!=1 && tempCatalogue.isBuy!=1){
  804. this.openVipCourse(index);
  805. return;
  806. }
  807. }
  808. this.pickCatalogIdx=index;
  809. //传递消息给小节弹窗
  810. uni.$emit('pickCatalogIdx', {pickCatalogIdx:index,type:type});
  811. this.pickCatalog=this.catalogueList[index];
  812. this.packageJsonList = this.pickCatalog && this.pickCatalog.packageJson ? JSON.parse(this.pickCatalog.packageJson) : []
  813. uni.$emit("getPickCatalog",this.pickCatalog);
  814. this.studyTimes=0;//当pickCatalog.studyTime=null 或者等于视频总时长时默认切为零
  815. if(this.pickCatalog.studyTime!=this.pickCatalog.seconds){
  816. this.studyTimes=this.pickCatalog.studyTime;
  817. }
  818. this.initStudyTime(this.studyTimes);
  819. this.poster=this.pickCatalog.thumbnail;
  820. uni.$emit('poster',this.poster)
  821. if (this.audioContext==null) {
  822. this.audioContext = uni.createInnerAudioContext();
  823. }
  824. this.audioContext.src = this.pickCatalog.videoUrl;
  825. if(this.audioTimer) {
  826. clearInterval(this.audioTimer);
  827. this.audioTimer=null;
  828. }
  829. this.audioPlayIng = false
  830. uni.$emit('changeData',{
  831. audioPlayIng: this.audioPlayIng,
  832. showAudio: this.showAudio,
  833. })
  834. let that=this;
  835. setTimeout(function(){
  836. if(that.showAudio) {
  837. that.playAudioAction()
  838. } else {
  839. that.playVideo();
  840. }
  841. },300);
  842. },
  843. playVideo() {
  844. if(this.audioPlayIng) {
  845. this.playAudio()
  846. return
  847. }
  848. // #ifdef APP-PLUS
  849. uni.$emit("playVideo");
  850. // #endif
  851. // #ifndef APP-PLUS
  852. this.videoContext.play();
  853. // #endif
  854. },
  855. pauseVideo() {
  856. // #ifdef APP-PLUS
  857. uni.$emit("pauseVideo");
  858. // #endif
  859. // #ifndef APP-PLUS
  860. this.videoContext.pause();
  861. // #endif
  862. },
  863. onPlayVideo(){ //视频播放器事件
  864. if(this.showAudio) {
  865. setTimeout(()=>{
  866. this.videoContext.pause();
  867. },200)
  868. return
  869. }
  870. console.log("qxj onPlayVideo tempAudioDuration:"+this.tempAudioDuration);
  871. this.countdowning=true;
  872. // this.isPlayIng = true
  873. if(this.tempAudioDuration==0){
  874. return;
  875. }
  876. this.playVideoAction('onPlayVideo');
  877. },
  878. playVideoAction(type){
  879. this.courseDuration=(this.tempAudioDuration*1.0).toFixed(0);
  880. this.studyTimes=this.tempAudioDuration;
  881. if(this.audioPlayIng){
  882. this.pauseAudio();
  883. this.audioPlayIng=false;
  884. uni.$emit('changeData',{
  885. audioPlayIng: this.audioPlayIng,
  886. showAudio: this.showAudio,
  887. })
  888. }
  889. // #ifdef APP-PLUS
  890. uni.$emit("seekVideo",this.courseDuration);
  891. // #endif
  892. // #ifndef APP-PLUS
  893. this.videoContext.seek(this.courseDuration);
  894. // #endif
  895. },
  896. onPauseVideo(){
  897. console.log("qxj onPauseVideo");
  898. this.isPlayIng=false;
  899. },
  900. playAudioAction(type){
  901. if(type == 'backvideo' && this.showAudio) {
  902. this.backPlayVideo()
  903. } else {
  904. const ended = this.playTime == this.$formatSeconds(this.pickCatalog.seconds)
  905. this.showAudio = true
  906. uni.$emit('changeData',{
  907. audioPlayIng: this.audioPlayIng,
  908. showAudio: this.showAudio,
  909. })
  910. if(!this.audioPlayIng){
  911. //if(this.isLearning){ //若从在学课程跳转过来则续播
  912. this.playTime= ended ? '00:00' : this.$formatSeconds(this.courseDuration);
  913. uni.$emit('playTime',this.playTime)
  914. this.audioDuration = ended ? 0: this.audioDuration
  915. this.audioContext.seek(ended ? 0: this.audioDuration+0.8);
  916. this.isLearning=false;
  917. //}
  918. setTimeout(()=>{
  919. this.pauseVideo();
  920. this.playAudio();
  921. },200)
  922. }
  923. else{
  924. this.courseDuration = (this.tempAudioDuration*1.0).toFixed(0)
  925. //if(this.isLearning){
  926. this.isLearning=false;
  927. // }
  928. setTimeout(()=>{
  929. this.pauseAudio();
  930. },200)
  931. }
  932. this.audioPlayIng=!this.audioPlayIng;
  933. uni.$emit('changeData',{
  934. audioPlayIng: this.audioPlayIng,
  935. showAudio: this.showAudio,
  936. })
  937. }
  938. },
  939. playAudio() {
  940. let that=this;
  941. this.audioTimer = setInterval(() => {
  942. if(that.isAudioChanging){
  943. return;
  944. }
  945. if((that.audioDuration*1.0).toFixed(0)>=that.pickCatalog.seconds){
  946. this.audioPlayIng = false
  947. this.courseDuration = (this.tempAudioDuration*1.0).toFixed(0)
  948. uni.$emit('changeData',{
  949. audioPlayIng: this.audioPlayIng,
  950. showAudio: this.showAudio,
  951. })
  952. clearInterval(that.audioTimer);
  953. that.countdowning=false; //观看时长开关关闭
  954. this.endedPlayNext()
  955. return;
  956. }
  957. that.audioDuration++;
  958. that.tempAudioDuration=that.audioDuration;
  959. let tempAudioDuration=(that.audioDuration*1.0).toFixed(0);
  960. that.video.percent=(tempAudioDuration/that.pickCatalog.seconds*1.0).toFixed(2)*100;
  961. that.playTime=this.$formatSeconds(tempAudioDuration);
  962. that.countdowning=true; //观看时长开关开启
  963. uni.$emit('playTime',this.playTime)
  964. }, 1000);
  965. this.audioContext.play();
  966. this.pauseCountsTime();
  967. },
  968. pauseAudio() {
  969. if(this.audioContext) {
  970. this.audioContext.pause();
  971. clearInterval(this.audioTimer);
  972. this.audioTimer=null;
  973. }
  974. },
  975. destoryAudio() {
  976. console.log("qxj destoryAudio");
  977. if (this.audioContext) {
  978. this.audioContext.destroy();
  979. clearInterval(this.audioTimer);
  980. this.audioTimer=null;
  981. }
  982. },
  983. input(){
  984. this.isAudioChanging=true;
  985. },
  986. audioChanging(){
  987. this.isAudioChanging=true; //正在拖动时屏蔽掉audio倒计时
  988. },
  989. audioChange(e){
  990. let value=e.detail.value;
  991. console.log("audioChange value:"+JSON.stringify(e)+" audioPlayIng:"+this.audioPlayIng);
  992. this.isAudioChanging=false;
  993. this.tempAudioDuration=parseInt(value/100.0*this.pickCatalog.seconds);
  994. this.playTime=this.$formatSeconds(this.tempAudioDuration);
  995. uni.$emit('playTime',this.playTime)
  996. if(this.audioPlayIng){
  997. console.log("qxj audioDuration:"+this.tempAudioDuration);
  998. this.audioDuration=this.tempAudioDuration;
  999. this.audioContext.seek(this.tempAudioDuration);
  1000. }else{
  1001. this.playVideoAction();
  1002. }
  1003. },
  1004. startCountsTime(){
  1005. },
  1006. pauseCountsTime(){ //暂停
  1007. },
  1008. resumeCountsTime(){ //恢复
  1009. },
  1010. endCountsTime(){
  1011. if (this.timer) {
  1012. clearInterval(this.timer);
  1013. this.timer = null;
  1014. }
  1015. },
  1016. onFullscreenChange(event){
  1017. // #ifndef APP-PLUS
  1018. this.fullScreen = event.detail.fullScreen
  1019. // direction取为 vertical 或 horizontal
  1020. this.direction = event.detail.direction
  1021. // 检查是否全屏
  1022. if (!event.detail.fullScreen) {
  1023. // this.showTherapy = false
  1024. }
  1025. // #endif
  1026. },
  1027. toggleBarChange(event){
  1028. console.log("qxj toggleBarChange");
  1029. this.showFullScreenBtn=!this.showFullScreenBtn;
  1030. },
  1031. onWaiting(res){
  1032. this.isWaiting=true;
  1033. //this.showToast("qxj onWaiting:"+JSON.stringify(res));
  1034. },
  1035. onProgress(event) {
  1036. //console.log("qxj onProgress:"+JSON.stringify(event));
  1037. //uni.showToast({title:event.detail.buffered,icon: 'none'});
  1038. },
  1039. onVideoCanPlay(res) {
  1040. console.log('视频可以开始播放,但可能需要缓冲');
  1041. //this.showToast("qxj onVideoCanPlay:"+JSON.stringify(res));
  1042. },
  1043. onVideoCanPlayThrough(res) {
  1044. console.log('视频可以无暂停地播放');
  1045. //this.showToast("qxj onVideoCanPlay:"+JSON.stringify(res));
  1046. },
  1047. endedPlayNext(type){
  1048. let nextCatalog=this.catalogueList[this.pickCatalogIdx+1];
  1049. if(!nextCatalog){
  1050. return;
  1051. }
  1052. if(nextCatalog && this.pickCatalogIdx<this.catalogueList.length-1){ //未播放到最后一节自动续播
  1053. this.pickCatalogAction(this.pickCatalogIdx+1)
  1054. }
  1055. },
  1056. endedPlayPrev(){
  1057. if(this.pickCatalogIdx == 0) {
  1058. uni.showToast({
  1059. title: '已经是第一节视频了',
  1060. icon: 'none',
  1061. position: 'top',
  1062. duration: 2000
  1063. })
  1064. return
  1065. }
  1066. let nextCatalog=this.catalogueList[this.pickCatalogIdx-1];
  1067. if(!nextCatalog || nextCatalog.isBuy==0){
  1068. return;
  1069. }
  1070. this.pickCatalogAction(this.pickCatalogIdx-1)
  1071. },
  1072. onLoadeddata(res) {
  1073. //this.showToast("qxj onLoadeddata res:"+JSON.stringify(res));
  1074. console.log('视频缓冲完成');
  1075. },
  1076. onLoadedMetadata(event) { //在视频元数据加载完成时初始化。
  1077. this.lastBuffered+=event.detail.duration;
  1078. //this.showToast("qxj onLoadedMetadata 已缓冲(秒):"+event.detail.duration);
  1079. // const video = event.target;
  1080. // if (video.buffered.length > 0) {
  1081. // this.lastBuffered = video.buffered.end(0);
  1082. // }
  1083. },
  1084. onTimeUpdate(res){ //在视频播放时,检查缓存的变化,估算新增的已加载字节数并累加到 dataUsage 中。
  1085. this.audioDuration=res.detail.currentTime;
  1086. this.courseDuration = (res.detail.currentTime*1.0).toFixed(0);
  1087. this.totalDuration=res.detail.currentTime;
  1088. if(this.isH5){
  1089. if(this.allLookDuration>=300){ //H5未登录状态播放五分钟就跳出登录页面
  1090. if(!this.$isLogin()){
  1091. this.$showLoginPage();
  1092. this.pauseVideo();
  1093. }
  1094. }
  1095. }
  1096. else{
  1097. if(this.allLookDuration>=120){ //未登录状态播放两分钟就跳出登录页面
  1098. if(!this.$isLogin()){
  1099. this.$showLoginPage();
  1100. this.pauseVideo();
  1101. }
  1102. }
  1103. }
  1104. let detail=res.detail;
  1105. let currentDuration=parseInt(detail.duration);
  1106. if(this.pickCatalog.duration==null&&this.pickCatalog.duration==0 && !!currentDuration){
  1107. this.pickCatalog.duration=currentDuration;
  1108. this.pickCatalog.seconds=currentDuration;
  1109. this.catalogueList[this.pickCatalogIdx]=this.pickCatalog;
  1110. this.$forceUpdate();
  1111. }
  1112. if(res.detail.currentTime>=this.pickCatalog.seconds){
  1113. this.countdowning=false; //观看时长开关关闭
  1114. }
  1115. if(!this.isWaiting){
  1116. this.video.percent=(this.courseDuration/this.pickCatalog.seconds*1.0).toFixed(2)*100;
  1117. this.playTime=this.$formatSeconds(this.courseDuration);
  1118. uni.$emit('playTime',this.playTime)
  1119. }else{
  1120. setTimeout(()=>{
  1121. this.isWaiting=false;
  1122. },2000);
  1123. }
  1124. this.isPlayIng=true;
  1125. // #ifndef APP-PLUS
  1126. uni.$u.throttle(this.checkTherapy, 1000,false);
  1127. // #endif
  1128. },
  1129. checkTherapy() {
  1130. let currentTime = Math.round(this.audioDuration || 0)
  1131. let node = this.packageJsonList.filter(item => item.duration == currentTime)
  1132. if(node&&node.length > 0) {
  1133. this.nodeTime = node[0].duration
  1134. this.showTherapyItem = node[0]
  1135. if(!this.showTherapy) {
  1136. this.showTherapy = true
  1137. }
  1138. } else {
  1139. if(this.showTherapy && this.nodeTime && this.nodeTime > currentTime) {
  1140. this.showTherapy = false
  1141. }
  1142. }
  1143. },
  1144. initStudyTime(times){
  1145. this.studyTimes=times;
  1146. this.courseDuration=times;
  1147. this.audioDuration=times;
  1148. // this.tempAudioDuration=times;
  1149. this.playTime=this.$formatSeconds(this.studyTimes);
  1150. uni.$emit('playTime',this.playTime)
  1151. },
  1152. getCatalogIdx(){
  1153. let index=this.catalogueList.findIndex(item=>item.videoId==this.videoId);
  1154. if(index<0){
  1155. index=0;
  1156. }
  1157. return index;
  1158. },
  1159. goToPlay(){
  1160. this.navTo("./videoUni");
  1161. //this.navTo("/pages/course/video/play?videoUrl="+this.pickCatalog.videoUrl+"&currentTime="+this.currentTime+"&catalogIdx="+this.pickCatalogIdx);
  1162. },
  1163. goToInfo(item){
  1164. this.$navTo('./info?courseId='+item.courseId);
  1165. },
  1166. goToIntroduce(){
  1167. let url='./introduce?courseId='+this.courseId+'&videoId='+this.pickCatalog.videoId+'&studyTimes='+this.courseDuration;
  1168. this.$navTo(url);
  1169. },
  1170. goToCatalogue(){
  1171. if(this.isH5){
  1172. let url='./catalogue?courseId='+this.courseId+'&videoId='+this.pickCatalog.videoId+'&isAutoPlay='+this.data.isAutoPlay+'&studyTimes='+this.courseDuration;
  1173. this.$navTo(url);
  1174. }
  1175. else{
  1176. const subNVue = uni.getSubNVueById('catalogueN');
  1177. subNVue.show('slide-in-bottom', 250);
  1178. uni.$emit('catalogue', {
  1179. videoId: this.pickCatalog.videoId,
  1180. courseId: this.courseId,
  1181. pickCatalogIdx:this.pickCatalogIdx
  1182. });
  1183. }
  1184. },
  1185. goToComment(){
  1186. if(this.isH5){
  1187. this.specVisible=true;
  1188. }
  1189. else{
  1190. // this.$navTo('./comment?courseId='+this.courseId);
  1191. // return;
  1192. const subNVue = uni.getSubNVueById('commentN');
  1193. subNVue.show('slide-in-bottom', 250);
  1194. uni.$emit('comment', {
  1195. videoId: this.pickCatalog.videoId,
  1196. courseId: this.courseId
  1197. });
  1198. }
  1199. },
  1200. closePop(){
  1201. this.specVisible=false;
  1202. },
  1203. navTo(url) {
  1204. uni.navigateTo({
  1205. url: url
  1206. });
  1207. },
  1208. openShare(){
  1209. if(this.isH5){
  1210. return;
  1211. }
  1212. console.log("qxj title:"+this.pickCatalog.title);
  1213. if(this.$isEmpty(this.pickCatalog.title)){
  1214. this.shareItem.title=this.data.courseName;
  1215. }else{
  1216. this.shareItem.title=this.data.courseName+"-"+this.pickCatalog.title;
  1217. }
  1218. this.shareItem.imageUrl=this.data.imgUrl;
  1219. this.shareItem.compressImage = 1
  1220. this.shareItem.courseId=this.courseId;
  1221. this.shareItem.summary=!this.$isEmpty(this.data.description)?this.data.description:"";
  1222. let cdn=uni.getStorageSync('h5Path');
  1223. this.shareItem.url=cdn+"/pages/course/info?courseId="+this.courseId;
  1224. this.showShare=true;
  1225. },
  1226. openVipCourse(index) {
  1227. if(!this.isPostBack){
  1228. this.isPostBack=true;
  1229. return;
  1230. }
  1231. this.showPopPrivilege(index);
  1232. },
  1233. showPopPrivilege(index){
  1234. if(this.isH5){
  1235. this.$refs.popPrivilege.open("bottom");
  1236. }
  1237. else{
  1238. const subNVue = uni.getSubNVueById('privilege');
  1239. subNVue.show('slide-in-bottom', 250);
  1240. let pickCatalog=this.catalogueList[index];
  1241. uni.$emit('privilege', {
  1242. videoId: pickCatalog.videoId,
  1243. courseId: this.courseId,
  1244. sellPrice:this.data.sellPrice,
  1245. catalogIndex:index,
  1246. integral: this.data.integral,
  1247. });
  1248. }
  1249. },
  1250. changeVip(index){
  1251. this.vipSelIndex=index;
  1252. if(index==2){
  1253. this.showPopPrivilege();
  1254. }
  1255. },
  1256. changeVipMethod(index){
  1257. this.vipMethodIdx=index;
  1258. const vipMethod=this.vipMethods[index];
  1259. this.isShowPayType=false;
  1260. if(vipMethod.indexOf('元购买')!=-1){ //直接购买
  1261. this.isShowPayType=true;
  1262. this.createType=1;
  1263. }
  1264. if(vipMethod.indexOf('芳华币兑换')!=-1){ //芳华币兑换
  1265. this.createType=2;
  1266. }
  1267. if(vipMethod.indexOf('开通会员')!=-1){ //开通会员
  1268. this.createType=3;
  1269. }
  1270. },
  1271. changePayType(index){
  1272. this.payType=index+1;
  1273. },
  1274. doBuy(){
  1275. if(this.createType==1){ //直接购买
  1276. this.createCourseOrder();
  1277. }
  1278. else if(this.createType==2){ //芳华币兑换
  1279. this.createIntegralOrder();
  1280. }
  1281. else{ //开通会员
  1282. this.$navTo('./vipBuy');
  1283. }
  1284. },
  1285. createCourseOrder(){
  1286. if(!this.$isLogin()){
  1287. this.$showLoginPage();
  1288. return;
  1289. }
  1290. uni.showLoading({title:""});
  1291. let params={"courseId":this.courseId,"createType":this.createType,"videoId":this.pickCatalog.videoId,"payType":this.payType};
  1292. createCourseOrder(params).then(res => {
  1293. uni.hideLoading();
  1294. if(res.code==200){
  1295. this.order=res.order;
  1296. if(this.payType==1){ //微信支付
  1297. this.doWxPay();
  1298. }else{ //支付宝
  1299. this.doAlipay();
  1300. }
  1301. }else{
  1302. uni.showToast({title: res.msg,icon: 'none'});
  1303. }
  1304. },
  1305. rej => {}
  1306. );
  1307. },
  1308. createIntegralOrder(){
  1309. if(!this.$isLogin()){
  1310. this.$showLoginPage();
  1311. return;
  1312. }
  1313. uni.showLoading({title:""});
  1314. let params={"courseId":this.courseId,"videoId":this.pickCatalog.videoId};
  1315. createIntegralOrder(params).then(res => {
  1316. uni.hideLoading();
  1317. if(res.code==200){
  1318. uni.showToast({title: res.msg,icon: 'success'});
  1319. }else{
  1320. uni.showToast({title: res.msg,icon: 'none'});
  1321. }
  1322. },
  1323. rej => {}
  1324. );
  1325. },
  1326. doAlipay(){
  1327. var data = {orderId:this.order.orderId};
  1328. uni.showLoading();
  1329. aliPayment(data).then(res => {
  1330. uni.hideLoading()
  1331. this.$refs.popPrivilege.close();
  1332. if(res.code==200){
  1333. this.$refs.popTip.open();
  1334. if (uni.getSystemInfoSync().platform == 'android') {
  1335. var alipayScheme ='alipays://platformapi/startApp?&saId=10000007&qrcode=' + res.data.qr_code;
  1336. }else{
  1337. var alipayScheme ='alipay://platformapi/startApp?&saId=10000007&qrcode=' + res.data.qr_code;
  1338. }
  1339. console.log(alipayScheme)
  1340. // 在uni-app中使用plus.runtime.openURL打开URL
  1341. plus.runtime.openURL(alipayScheme, function(error) {
  1342. // console.error('打开支付宝失败: ' + error.message);
  1343. // 处理打开支付宝失败的情况,比如提示用户或者跳转到其他支付方式
  1344. });
  1345. }
  1346. else{
  1347. uni.showToast({
  1348. title:res.msg,
  1349. icon:'none'
  1350. })
  1351. }
  1352. },
  1353. rej => {}
  1354. );
  1355. },
  1356. doWxPay(){
  1357. var that=this;
  1358. plus.share.getServices(function(res){
  1359. var sweixin = null;
  1360. for(var i=0;i<res.length;i++){
  1361. var t = res[i];
  1362. if(t.id == 'weixin'){
  1363. sweixin = t;
  1364. }
  1365. }
  1366. if(sweixin){
  1367. console.log('调起小程序')
  1368. that.$refs.popPrivilege.close();
  1369. that.$refs.popTip.open()
  1370. //唤起微信跳转小程序
  1371. sweixin.launchMiniProgram({
  1372. id:"gh_7a6a32e5ef61",
  1373. path:'pages_order/coursePayment?orderId='+that.orderId+"&payMethod=app",
  1374. type:0
  1375. },function(){
  1376. console.log("微信唤起成功");
  1377. return true;
  1378. },function(e){
  1379. console.log("微信唤起失败",e);
  1380. uni.showToast({
  1381. title:'微信唤起失败,请检查是否有微信应用',
  1382. icon:'none'
  1383. })
  1384. return false;
  1385. })
  1386. }else{
  1387. uni.showToast({
  1388. title:'微信唤起失败,请检查是否有微信应用',
  1389. icon:'none',
  1390. duration:3000
  1391. })
  1392. return false;
  1393. }
  1394. },function(res){
  1395. console.log(JSON.stringify(res));
  1396. });
  1397. },
  1398. addStudyCourse(){
  1399. if(this.catalogueList.length==0 || this.courseDuration==0){
  1400. return;
  1401. }
  1402. this.pickCatalog=this.catalogueList[this.pickCatalogIdx];
  1403. this.packageJsonList = this.pickCatalog && this.pickCatalog.packageJson ? JSON.parse(this.pickCatalog.packageJson) : []
  1404. uni.$emit("getPickCatalog",this.pickCatalog);
  1405. if(this.pickCatalog.isBuy==0){
  1406. return;
  1407. }
  1408. const parmas={"courseId":parseInt(this.courseId),"duration":this.courseDuration,"videoId":this.pickCatalog.videoId};
  1409. addDuration(parmas).then(res => {
  1410. if(res.code==200){
  1411. this.courseDuration=0;
  1412. }
  1413. },
  1414. rej => {}
  1415. );
  1416. },
  1417. addIntegral(){
  1418. if(this.lookDuration==0 || this.courseDuration==0){
  1419. return;
  1420. }
  1421. this.pickCatalog=this.catalogueList[this.pickCatalogIdx];
  1422. this.packageJsonList = this.pickCatalog && this.pickCatalog.packageJson ? JSON.parse(this.pickCatalog.packageJson) : []
  1423. uni.$emit("getPickCatalog",this.pickCatalog);
  1424. if(this.lookDuration<this.pickCatalog.seconds*0.5){
  1425. return;
  1426. }
  1427. let data={videoId:this.pickCatalog.videoId,duration:this.lookDuration};
  1428. getIntegral(data).then(res => {
  1429. if(res.code==200){
  1430. uni.showToast({icon:'none',title:res.msg,duration:3000,position:'bottom'});
  1431. this.countdowning=false;
  1432. }
  1433. },
  1434. rej => {}
  1435. );
  1436. },
  1437. closePrivilege(){
  1438. this.$refs.popPrivilege.close();
  1439. },
  1440. closeTip(){
  1441. this.$refs.popTip.close();
  1442. },
  1443. canShowVip(item){
  1444. return true;
  1445. if(this.user.isVip){
  1446. return false;
  1447. }
  1448. return item.isVip==1 && item.isBuy==0;
  1449. },
  1450. confirmTip() {
  1451. this.getUserInfo();
  1452. this.getCourseInfo();
  1453. this.$refs.popTip.close();
  1454. uni.showLoading({title:"请稍侯...",mask:true,duration:3000});
  1455. setTimeout(()=>{
  1456. this.getCourseOrderById();
  1457. },2000);
  1458. },
  1459. getCourseOrderById(){
  1460. getCourseOrderById(this.courseOrderId).then(res => {
  1461. uni.hideLoading();
  1462. if(res.code==200){
  1463. if(res.order.status==2 || res.order.payTime!=null){
  1464. // #ifdef APP-PLUS
  1465. if(plus.runtime.channel=="baidu"){ //获取渠道标识
  1466. let bdCmdType=uni.getStorageSync("bdCmdType");
  1467. if(bdCmdType!=null && parseInt(bdCmdType)<=2){
  1468. //this.$registerIdCode("orders",2,res.order.payMoney.toString()); //已下单
  1469. }
  1470. }
  1471. // #endif
  1472. uni.showToast({title:"支付成功",icon:'success'});
  1473. }
  1474. else if(res.order.status==1){
  1475. uni.showToast({title:"课程待支付请稍侯",icon:'none'});
  1476. }
  1477. else{
  1478. uni.showToast({title:"支付失败",icon:'error'});
  1479. }
  1480. }
  1481. },
  1482. rej => {}
  1483. );
  1484. },
  1485. openApp(){
  1486. window.location.href="rtlive://course?courseId="+this.courseId;
  1487. },
  1488. videoErrorCallback(){
  1489. },
  1490. showToast(title){
  1491. uni.showToast({
  1492. title:title,
  1493. icon:'none',
  1494. duration:3000
  1495. })
  1496. },
  1497. closeShareAct(){
  1498. this.showShare=false;
  1499. },
  1500. closeTherapy() {
  1501. this.showTherapy = false
  1502. },
  1503. goToPro(productId) {
  1504. this.videoContext.exitFullScreen()
  1505. this.showTherapy = false
  1506. setTimeout(()=> {
  1507. uni.navigateTo({
  1508. url: "/pages/store/packageDetails?packageId="+productId
  1509. });
  1510. }, 500);
  1511. },
  1512. // 返回视频
  1513. backPlayVideo() {
  1514. this.showAudio = false;
  1515. this.audioPlayIng = false;
  1516. uni.$emit('changeData',{
  1517. audioPlayIng: this.audioPlayIng,
  1518. showAudio: this.showAudio,
  1519. })
  1520. this.isLearning=false;
  1521. setTimeout(()=>{
  1522. this.pauseAudio();
  1523. this.playVideo();
  1524. },200)
  1525. },
  1526. // 打开集观看提示弹窗
  1527. openTips(index){
  1528. // #ifdef APP-PLUS
  1529. uni.$emit('getTipShowType', {index:index})
  1530. uni.getSubNVueById('videoPopup').show();
  1531. // #endif
  1532. },
  1533. tipConfirm() { // 提示确认
  1534. // 继续播放
  1535. //传递消息给小节弹窗
  1536. uni.$emit('pickCatalogIdx', {pickCatalogIdx:this.pickCatalogIdx,type: 'catalogueN'});
  1537. if(this.showAudio) {
  1538. this.playAudioAction()
  1539. } else {
  1540. this.playVideo();
  1541. }
  1542. },
  1543. tipCancel(index) { // 提示取消
  1544. // 播放选择的一节
  1545. this.pickCatalogActionFun(index,'catalogueN')
  1546. },
  1547. // 线路
  1548. openPop() {
  1549. console.log("线路===",this.pickCatalog)
  1550. let lineList = []
  1551. if(this.pickCatalog&&this.pickCatalog.lineOne) {
  1552. lineList.push(this.pickCatalog.lineOne)
  1553. }
  1554. if(this.pickCatalog&&this.pickCatalog.lineTwo) {
  1555. lineList.push(this.pickCatalog.lineTwo)
  1556. }
  1557. if(this.pickCatalog&&this.pickCatalog.lineThree) {
  1558. lineList.push(this.pickCatalog.lineThree)
  1559. }
  1560. this.lineList = lineList
  1561. this.lineList.push("https://tcpv.ylrzcloud.com/transferCode/1732246123922_transcode_100323.mp4")
  1562. this.lineIndex = lineList.indexOf(this.pickCatalog.videoUrl)
  1563. this.$refs.popup.open('bottom')
  1564. },
  1565. close() {
  1566. this.$refs.popup.close()
  1567. },
  1568. handleLine(index) {
  1569. this.lineIndex = index
  1570. this.pickCatalog.videoUrl=this.lineList[index]
  1571. uni.$emit("getPickCatalog",this.pickCatalog);
  1572. // this.$nextTick(()=>{
  1573. // this.tipsOpen = false
  1574. // // this.player = null
  1575. // this.videoConfig.url = this.lineList[index]
  1576. // this.videoConfig.startTime = this.playTime
  1577. // this.videoConfig.plugins = this.checkMSE()&&this.lineIndex!=0 ? [Mp4Plugin] : []
  1578. // // this.initVideo('play')
  1579. // this.playDuration = this.playTime
  1580. // this.player.playNext({
  1581. // url: this.lineList[index],
  1582. // startTime: this.playTime,
  1583. // plugins: this.videoConfig.plugins,
  1584. // mp4plugin: this.videoConfig.mp4plugin
  1585. // })
  1586. // if(this.checkMSE()&&this.lineIndex!=0) {
  1587. // this.player.registerPlugin(Mp4Plugin)
  1588. // } else {
  1589. // this.player.unRegisterPlugin('Mp4Plugin')
  1590. // }
  1591. // this.isPlayNext = true
  1592. // })
  1593. this.close()
  1594. },
  1595. },
  1596. onUnload() {
  1597. // 页面卸载时清除计时器
  1598. this.endCountsTime();
  1599. this.addStudyCourse();
  1600. this.destoryAudio();
  1601. uni.$emit('refreshStudyTime', {});
  1602. uni.$off("navBack");
  1603. uni.$off("onPlayVideo");
  1604. uni.$off("onWaiting");
  1605. uni.$off("onTimeUpdate");
  1606. uni.$off("endedPlayNext");
  1607. uni.$off("onLoadedMetadata");
  1608. uni.$off("audioBtnEvent");
  1609. // #ifdef APP-PLUS
  1610. uni.$off('getEventType');
  1611. // #endif
  1612. },
  1613. created(){
  1614. let that = this;
  1615. uni.$on('backStudyTime', function(data) {
  1616. //console.log("qxj backStudyTime:"+JSON.stringify(data));
  1617. that.videoId=data.videoId;
  1618. that.pickCatalogIdx=that.getCatalogIdx();
  1619. that.pickCatalog=that.catalogueList[that.pickCatalogIdx];
  1620. that.pickCatalog.studyTime=data.studyTimes;
  1621. that.catalogueList[that.pickCatalogIdx]=that.pickCatalog;
  1622. that.tempAudioDuration=data.studyTimes;
  1623. that.packageJsonList = that.pickCatalog && that.pickCatalog.packageJson ? JSON.parse(that.pickCatalog.packageJson) : []
  1624. uni.$emit("getPickCatalog",that.pickCatalog);
  1625. that.pickCatalogMethod(that.pickCatalogIdx);
  1626. });
  1627. uni.$on('showPayTips', function(data) {
  1628. console.log("qxj showPayTips")
  1629. that.courseOrderId=data.courseOrderId;
  1630. //that.showPayTips=true;
  1631. that.$refs.popTip.open();
  1632. });
  1633. uni.$on('refreshUser', function(data) {
  1634. that.getUserInfo();
  1635. that.getCourseInfo();
  1636. });
  1637. uni.$on('pickCatalogAction', function(data) {
  1638. that.pickCatalogAction(data.index,data.type);
  1639. });
  1640. uni.$on('refreshCatalog', function(index) {
  1641. let catalog=that.catalogueList[index];
  1642. catalog.isBuy=true;
  1643. that.catalogueList[index]=catalog;
  1644. });
  1645. },
  1646. destroyed() {
  1647. // 注销全局配置监听
  1648. uni.$off("backStudyTime");
  1649. uni.$off("refreshUser");
  1650. uni.$off("showPayTips");
  1651. uni.$off("pickCatalogAction");
  1652. uni.$off("refreshTitle");
  1653. uni.$off("refreshCatalog");
  1654. uni.$off("navBack");
  1655. uni.$off("onPlayVideo");
  1656. uni.$off("onWaiting");
  1657. uni.$off("onTimeUpdate");
  1658. uni.$off("endedPlayNext");
  1659. uni.$off("onLoadedMetadata");
  1660. uni.$off("audioBtnEvent");
  1661. }
  1662. }
  1663. </script>
  1664. <style lang="scss" scoped>
  1665. .content{
  1666. background: #f7f7f7;
  1667. }
  1668. .popupbox {
  1669. background-color: #fff;
  1670. border-radius: 16rpx 16rpx 0 0;
  1671. padding: 24rpx 32rpx;
  1672. position: relative;
  1673. &-head {
  1674. height: 60rpx;
  1675. margin-bottom: 30rpx;
  1676. text-align: center;
  1677. overflow-y: auto;
  1678. color: #414858;
  1679. font-size: 32rpx;
  1680. font-weight: bold;
  1681. position: relative;
  1682. .close-icon {
  1683. position: absolute;
  1684. right: 0;
  1685. top: 0;
  1686. height: 40rpx;
  1687. width: 40rpx;
  1688. }
  1689. }
  1690. &-content {
  1691. height: 20vh;
  1692. overflow-y: auto;
  1693. display: flex;
  1694. align-items: flex-start;
  1695. flex-wrap: wrap;
  1696. gap: 32rpx;
  1697. .line-item {
  1698. display: inline-block;
  1699. min-width: 200rpx;
  1700. height: 60rpx;
  1701. padding: 0 20rpx;
  1702. box-sizing: border-box;
  1703. border-radius: 50rpx;
  1704. overflow: hidden;
  1705. background-color: #f7f7f7;
  1706. text-align: center;
  1707. color: #414858;
  1708. font-size: 28rpx;
  1709. line-height: 60rpx;
  1710. }
  1711. .line-active {
  1712. color: #f56c6c !important;
  1713. background-color: #fef0f0 !important;
  1714. }
  1715. }
  1716. }
  1717. .video-line {
  1718. min-width: 140rpx;
  1719. max-width: 200rpx;
  1720. height: 60rpx;
  1721. padding: 0 20rpx;
  1722. box-sizing: border-box;
  1723. border-radius: 50rpx 0 0 50rpx;
  1724. overflow: hidden;
  1725. background-color: #fff;
  1726. text-align: center;
  1727. color: #888;
  1728. font-size: 28rpx;
  1729. line-height: 60rpx;
  1730. display: inline-flex;
  1731. align-items: center;
  1732. justify-content: center;
  1733. position: fixed;
  1734. right: 0;
  1735. z-index: 9;
  1736. bottom: calc(var(--window-bottom) + 280rpx);
  1737. box-shadow: 0 4rpx 10rpx rgba(0, 0, 0, .12);
  1738. image {
  1739. flex-shrink: 0;
  1740. height: 30rpx;
  1741. width: 30rpx;
  1742. margin-right: 6rpx;
  1743. }
  1744. }
  1745. @mixin u-flex($flexD, $alignI, $justifyC) {
  1746. display: flex;
  1747. flex-direction: $flexD;
  1748. align-items: $alignI;
  1749. justify-content: $justifyC;
  1750. }
  1751. .rotate {
  1752. transform: rotate(-180deg);
  1753. }
  1754. .status_bar {
  1755. background-color: #000;
  1756. }
  1757. .back-img {
  1758. width: 50rpx;
  1759. height: 50rpx;
  1760. position: absolute;
  1761. top: 20rpx;
  1762. left: 34rpx;
  1763. z-index: 99;
  1764. }
  1765. .audiobox {
  1766. width: 100%;
  1767. height: calc(422rpx + var(--status-bar-height));
  1768. position: absolute;
  1769. top: 0;
  1770. left: 0;
  1771. background-color: #333;
  1772. z-index: 9990;
  1773. font-family: PingFang SC, PingFang SC;
  1774. font-weight: 400;
  1775. font-size: 26rpx;
  1776. color: #fff;
  1777. &-video {
  1778. background-color: rgba(255, 255, 255, 0.3);
  1779. padding: 8rpx 20rpx;
  1780. border-radius: 50rpx;
  1781. position: absolute;
  1782. bottom: 40rpx;
  1783. left: 50%;
  1784. transform: translateX(-50%);
  1785. z-index: 9991;
  1786. }
  1787. &-title {
  1788. position: absolute;
  1789. top: 0;
  1790. left: 0;
  1791. z-index: 9991;
  1792. padding: 30rpx 40rpx;
  1793. width: 100%;
  1794. box-sizing: border-box;
  1795. background: linear-gradient(to top,rgba(0,0,0,0) 0%, rgba(0,0,0,0.8) 100%);
  1796. }
  1797. &-time {
  1798. margin-top: 18rpx;
  1799. font-size: 24rpx;
  1800. }
  1801. }
  1802. .video-box {
  1803. width: 100%;
  1804. height: 422rpx;
  1805. overflow: hidden;
  1806. position: relative;
  1807. margin-top: var(--status-bar-height);
  1808. #myVideo {
  1809. width: 100%;
  1810. height: 100%;
  1811. }
  1812. }
  1813. .scroll-Y {
  1814. font-family: PingFang SC, PingFang SC;
  1815. font-weight: 400;
  1816. font-size: 28rpx;
  1817. color: #222222;
  1818. }
  1819. .video-info {
  1820. padding: 24rpx;
  1821. background-color: #fff;
  1822. &-header {
  1823. width: 100%;
  1824. @include u-flex(row, center, space-between);
  1825. }
  1826. &-headerl {
  1827. flex: 1;
  1828. @include u-flex(row, center, flex-start);
  1829. font-weight: 500;
  1830. font-size: 32rpx;
  1831. overflow: hidden;
  1832. image {
  1833. flex-shrink: 0;
  1834. width: 88rpx;
  1835. height: 88rpx;
  1836. margin-right: 28rpx;
  1837. background: #F5F7FA;
  1838. border-radius: 50%;
  1839. overflow: hidden;
  1840. }
  1841. }
  1842. .follow-btn {
  1843. @include u-flex(row, center, center);
  1844. height: 56rpx;
  1845. min-width: 154rpx;
  1846. padding: 0 23rpx;
  1847. background: #FF5C03;
  1848. border-radius: 28rpx 28rpx 28rpx 28rpx;
  1849. color: #FFFFFF;
  1850. font-size: 28rpx;
  1851. image {
  1852. height: 32rpx;
  1853. width: 32rpx;
  1854. margin-right: 6rpx;
  1855. }
  1856. }
  1857. &-voice {
  1858. width: 100%;
  1859. padding: 24rpx 20rpx 38rpx 28rpx;
  1860. margin-top: 26rpx;
  1861. background: #F5F7FA;
  1862. border-radius: 16rpx 16rpx 16rpx 16rpx;
  1863. box-sizing: border-box;
  1864. image {
  1865. width: 48rpx;
  1866. height: 48rpx;
  1867. }
  1868. &-l {
  1869. @include u-flex(row, center, flex-start);
  1870. image {
  1871. margin-right: 20rpx;
  1872. }
  1873. }
  1874. }
  1875. &-voicebox1 {
  1876. @include u-flex(row, center, space-between);
  1877. }
  1878. &-voicebox2 {
  1879. padding: 24rpx 0;
  1880. @include u-flex(row, center, space-between);
  1881. font-weight: 400;
  1882. font-size: 26rpx;
  1883. color: #757575;
  1884. }
  1885. ::v-deep .uni-collapse-item__title-arrow {
  1886. margin-right: -8rpx;
  1887. }
  1888. .opacity {
  1889. position: relative !important;
  1890. opacity: 1 !important;
  1891. z-index: 1 !important;
  1892. }
  1893. &-desc {
  1894. margin-bottom: 52rpx;
  1895. font-weight: 400;
  1896. font-size: 28rpx;
  1897. color: #222222;
  1898. word-break: break-all;
  1899. overflow: hidden;
  1900. line-height: 42rpx;
  1901. position: absolute;
  1902. opacity: 0;
  1903. z-index: -1;
  1904. .desc-image {
  1905. height: 60rpx;
  1906. width: 100%;
  1907. // background-color: red;
  1908. position: absolute;
  1909. bottom: 0;
  1910. left: 0;
  1911. }
  1912. }
  1913. .text-clamp{
  1914. display: -webkit-box;
  1915. -webkit-line-clamp: 2; /* 显示的行数 */
  1916. -webkit-box-orient: vertical; /* 内容会垂直堆叠 */
  1917. overflow: hidden; /* 隐藏溢出的内容 */
  1918. text-overflow: ellipsis; /* 当内容被裁剪时显示省略号 */
  1919. }
  1920. &-footer {
  1921. @include u-flex(row, center, space-between);
  1922. color: #757575;
  1923. font-weight: 400;
  1924. font-size: 24rpx;
  1925. view {
  1926. width: 128rpx;
  1927. height: 104rpx;
  1928. @include u-flex(column, center, center);
  1929. }
  1930. image {
  1931. width: 48rpx;
  1932. height: 48rpx;
  1933. margin-bottom: 8rpx;
  1934. }
  1935. }
  1936. }
  1937. .box-header {
  1938. height: 80rpx;
  1939. padding: 0 24rpx;
  1940. @include u-flex(row, center, space-between);
  1941. font-weight: 500;
  1942. font-size: 24rpx;
  1943. color: #999999;
  1944. &-title {
  1945. color: #222222;
  1946. font-size: 34rpx;
  1947. }
  1948. &-r {
  1949. @include u-flex(row, center, flex-start);
  1950. image {
  1951. width: 48rpx;
  1952. height: 48rpx;
  1953. }
  1954. }
  1955. }
  1956. .therapy {
  1957. background-color: #fff;
  1958. padding-left: 24rpx;
  1959. padding-bottom: 20rpx;
  1960. &-scrollx {
  1961. white-space: nowrap;
  1962. width: 100%;
  1963. // margin-left: 24rpx;
  1964. }
  1965. &-scrollitem {
  1966. display: inline-block;
  1967. overflow: hidden;
  1968. background: #F5F7FA;
  1969. padding: 10rpx;
  1970. margin-right: 20rpx;
  1971. border-radius: 10rpx;
  1972. overflow: hidden;
  1973. border: 1rpx solid #F5F7FA;
  1974. box-sizing: border-box;
  1975. position: relative;
  1976. image {
  1977. width: 200rpx;
  1978. height: 200rpx;
  1979. border-radius: 10rpx;
  1980. background-color: #F5F7FA;
  1981. }
  1982. &::after {
  1983. content: '查看详情';
  1984. background-color: #F5F7FA;
  1985. position: absolute;
  1986. top: 0;
  1987. left: 0;
  1988. font-weight: 400;
  1989. font-size: 20rpx;
  1990. padding: 4rpx 14rpx;
  1991. border-radius: 10rpx 0 10rpx 0;
  1992. color: #757575;
  1993. }
  1994. }
  1995. &-active {
  1996. background: #fff;
  1997. border: 1rpx solid #FF5C03;
  1998. .therapy-goodsname {
  1999. color: #FF5C03 !important;
  2000. }
  2001. &::after {
  2002. background: #fff;
  2003. color: #FF5C03 !important;
  2004. }
  2005. }
  2006. &-goodsname {
  2007. margin-top: 6rpx;
  2008. width: 200rpx;
  2009. min-height: 64rpx;
  2010. font-size: 24rpx;
  2011. color: #757575;
  2012. word-break: break-all;
  2013. white-space: normal;
  2014. }
  2015. }
  2016. .video-directory {
  2017. background-color: #fff;
  2018. padding-top: 12rpx;
  2019. margin-top: 20rpx;
  2020. &-scrollx {
  2021. white-space: nowrap;
  2022. width: calc(100% - 24rpx);
  2023. margin-left: 24rpx;
  2024. }
  2025. &-scrollitem {
  2026. display: inline-block;
  2027. width: 276rpx;
  2028. height: 160rpx;
  2029. background: #F5F7FA;
  2030. border-radius: 8rpx 8rpx 8rpx 8rpx;
  2031. margin-right: 18rpx;
  2032. padding: 20rpx 12rpx 20rpx 20rpx;
  2033. box-sizing: border-box;
  2034. position: relative;
  2035. margin-bottom: 20rpx;
  2036. }
  2037. .freeflag {
  2038. width: 68rpx;
  2039. height: 32rpx;
  2040. text-align: center;
  2041. line-height: 32rpx;
  2042. position: absolute;
  2043. right: 0;
  2044. top: 0;
  2045. font-weight: 500;
  2046. font-size: 20rpx;
  2047. color: #FFFFFF;
  2048. &-free {
  2049. background: url('@/static/image/hall/free_lable_bg.png') no-repeat right / 68rpx 32rpx;
  2050. }
  2051. &-member {
  2052. background: url('@/static/image/hall/member_label_bg.png') no-repeat right / 68rpx 32rpx;
  2053. }
  2054. }
  2055. &-num {
  2056. font-weight: 500;
  2057. font-size: 28rpx;
  2058. @include u-flex(row, center, flex-start);
  2059. image,.empty{
  2060. width: 48rpx;
  2061. height: 48rpx;
  2062. margin-left: 10rpx;
  2063. }
  2064. }
  2065. &-title {
  2066. @include u-flex(row, center, space-between);
  2067. font-size: 24rpx;
  2068. color: #757575;
  2069. word-break: break-all;
  2070. white-space: normal;
  2071. .imagebox {
  2072. flex-shrink: 0;
  2073. margin: 0 8rpx;
  2074. position: relative;
  2075. image {
  2076. width: 92rpx;
  2077. height: 72rpx;
  2078. border-radius: 8rpx 8rpx 8rpx 8rpx;
  2079. overflow: hidden;
  2080. }
  2081. }
  2082. }
  2083. .mask {
  2084. width: 92rpx;
  2085. height: 72rpx;
  2086. border-radius: 8rpx 8rpx 8rpx 8rpx;
  2087. background: rgba(0, 0, 0, 0.2);
  2088. overflow: hidden;
  2089. position: absolute;
  2090. top: 0;
  2091. left: 0;
  2092. z-index: 1;
  2093. @include u-flex(row, center, center);
  2094. image {
  2095. width: 24rpx;
  2096. height: 24rpx;
  2097. }
  2098. }
  2099. .active-scrollitem {
  2100. background: #FCF0E7;
  2101. color: #FF5C03;
  2102. .video-directory-title {
  2103. color: #FF5C03;
  2104. }
  2105. }
  2106. }
  2107. .video-comment {
  2108. background-color: #fff;
  2109. padding-top: 12rpx;
  2110. margin-top: 20rpx;
  2111. }
  2112. .hall-box {
  2113. @include u-flex(row, center, flex-start);
  2114. flex-wrap: wrap;
  2115. margin: 0 -18rpx -18rpx 0;
  2116. padding: 12rpx 24rpx 24rpx 24rpx;
  2117. .gapitem {
  2118. margin: 0 18rpx 18rpx 0;
  2119. }
  2120. }
  2121. .popbox {
  2122. background-color: #fff;
  2123. position: relative;
  2124. .box-header {
  2125. padding-top: 12rpx;
  2126. padding-bottom: 12rpx;
  2127. box-sizing: border-box;
  2128. background-color: #fff;
  2129. }
  2130. .popbox-body {
  2131. .comment,
  2132. .directoryinfo {
  2133. padding: 24rpx;
  2134. }
  2135. }
  2136. .search-box {
  2137. @include u-flex(row, center, space-between);
  2138. padding: 10px 24rpx;
  2139. .search {
  2140. padding: 0;
  2141. flex: 1;
  2142. image {
  2143. width: 24rpx;
  2144. height: 24rpx;
  2145. padding-left: 16rpx;
  2146. }
  2147. }
  2148. }
  2149. }
  2150. .search-btn {
  2151. flex-shrink: 0;
  2152. height: 68rpx;
  2153. padding: 0 42rpx;
  2154. margin-left: 20rpx;
  2155. background: #FCF0E7;
  2156. border-radius: 34rpx 34rpx 34rpx 34rpx;
  2157. font-family: PingFang SC, PingFang SC;
  2158. font-weight: 600;
  2159. font-size: 26rpx;
  2160. color: #FF5C03;
  2161. text-align: center;
  2162. line-height: 68rpx;
  2163. }
  2164. .comment-inputbox {
  2165. @include u-flex(row, center, space-between);
  2166. padding: 28rpx 24rpx;
  2167. box-sizing: border-box;
  2168. background: #FFFFFF;
  2169. .inputbox {
  2170. flex: 1;
  2171. height: 72rpx;
  2172. padding-left: 24rpx;
  2173. background: #F5F7FA;
  2174. border-radius: 36rpx 36rpx 36rpx 36rpx;
  2175. font-family: PingFang SC, PingFang SC;
  2176. font-weight: 400;
  2177. font-size: 26rpx;
  2178. color: #999999;
  2179. line-height: 72rpx;
  2180. }
  2181. .release-btn {
  2182. @extend .search-btn;
  2183. }
  2184. }
  2185. .audio {
  2186. display: flex;
  2187. flex-direction: row;
  2188. align-items: center;
  2189. font-family: PingFang SC, PingFang SC;
  2190. font-weight: 500;
  2191. font-size: 24rpx;
  2192. color: #757575;
  2193. &-play {
  2194. display: flex;
  2195. flex-direction: row;
  2196. align-items: center;
  2197. }
  2198. &-icon {
  2199. width: 48rpx;
  2200. height: 48rpx;
  2201. }
  2202. &-slider {
  2203. flex: 1;
  2204. }
  2205. &-time {
  2206. flex-shrink: 0;
  2207. }
  2208. }
  2209. .vipCourseBtn{
  2210. background: #1B1F22;
  2211. border-radius: 46rpx;
  2212. border: 1px solid #FFDAA3;
  2213. color: #FFDAA3;
  2214. width: calc(33.33333% - 46.6666rpx);
  2215. }
  2216. .vipAc{
  2217. background: linear-gradient(90deg, #FFE0B2, #F8BA8B);
  2218. border-radius: 46rpx;
  2219. border: 1px solid #FFDAA3;
  2220. color: #1B1F22;
  2221. }
  2222. .privilegeBox{
  2223. background-color:#171a1d;
  2224. box-sizing: border-box;
  2225. }
  2226. .primenu-box{
  2227. border-radius: 16rpx;
  2228. margin-top: 0rpx;
  2229. padding: 10rpx 20rpx;
  2230. }
  2231. .content-inner {
  2232. display: flex;
  2233. flex-wrap: wrap;
  2234. min-height:310rpx ;
  2235. }
  2236. .content-inner .item{
  2237. width: calc(33.3333333%);
  2238. height: 150rpx;
  2239. display: flex;
  2240. flex-direction: column;
  2241. align-items: center;
  2242. justify-content: center;
  2243. margin-top: 0rpx;
  2244. }
  2245. .content-inner .item .img{
  2246. width: 84rpx;
  2247. height: 84rpx;
  2248. margin-bottom: 8rpx;
  2249. }
  2250. .content-inner .item .label{
  2251. font-size: 32rpx;
  2252. color: #83878A;
  2253. }
  2254. .vipMethodItem{
  2255. border-radius: 10rpx;
  2256. width: calc(100%);
  2257. height: 70rpx;
  2258. color: #FDD8A1;
  2259. }
  2260. .payTypeItem{
  2261. background-color:#1B1F22;
  2262. border:1px solid #fff;
  2263. border-radius: 10rpx;
  2264. width: calc(50% - 15rpx);
  2265. height: 94rpx;
  2266. }
  2267. .circle{
  2268. border:1px solid #FDD8A1;
  2269. }
  2270. .pt_ac{
  2271. border:1px solid #FDD8A1;
  2272. }
  2273. .slider-box{
  2274. flex:1
  2275. }
  2276. .horizontal {
  2277. width: 130px;
  2278. height: 150px;
  2279. position: absolute;
  2280. bottom: 50px;
  2281. left: 20px;
  2282. z-index: 999;
  2283. display: flex;
  2284. flex-direction: column;
  2285. align-items: center;
  2286. justify-content: flex-end;
  2287. background-color: transparent;
  2288. .es-w-40{
  2289. width: 20px;
  2290. }
  2291. .es-h-40 {
  2292. height: 20px;
  2293. }
  2294. .goods {
  2295. width: 120px;
  2296. height: 140px;
  2297. border-radius: 10px;
  2298. background-color: rgba(255, 255, 255, 0.4);
  2299. overflow: hidden;
  2300. display: flex;
  2301. flex-direction: column;
  2302. align-items: center;
  2303. justify-content: center;
  2304. }
  2305. .goodsimg {
  2306. width: 100px;
  2307. height: 100px;
  2308. border-radius: 10px;
  2309. }
  2310. .goodsname {
  2311. width: 100px;
  2312. box-sizing: border-box;
  2313. padding-top: 7px;
  2314. verflow: hidden;
  2315. word-break: break-all; /* break-all(允许在单词内换行 */
  2316. text-overflow: ellipsis; /* 超出部分省略号 */
  2317. -webkit-box-orient: vertical; /* 设置或检索伸缩盒对象的子元素的排列方式 */
  2318. -webkit-line-clamp: 1; /* 显示的行数 */
  2319. lines:1;
  2320. }
  2321. .goodsname-txt {
  2322. font-size: 12px;
  2323. text-overflow: ellipsis; /* 超出部分省略号 */
  2324. lines:1;
  2325. }
  2326. }
  2327. </style>