diff --git a/pages/parent/report/report.js b/pages/parent/report/report.js
index c10fca8..00077af 100644
--- a/pages/parent/report/report.js
+++ b/pages/parent/report/report.js
@@ -61,6 +61,7 @@ Page({
],
mockMonthData: {},
mockQuarterData: {},
+ studentReportLoading: false,
},
/**
@@ -71,62 +72,95 @@ Page({
const nowYear = now.getFullYear()
const nowMonth = now.getMonth() + 1
const nowQuarter = Math.ceil(nowMonth / 3)
+ const isTrainee = wx.getStorageSync('roleId') && wx.getStorageSync('roleId') == 5
this.setData({
nowYear, nowMonth, nowQuarter,
selectedYear: nowYear,
selectedMonth: nowMonth,
selectedQuarter: nowQuarter,
pickerYear: nowYear,
+ isTrainee,
+ activeTab: isTrainee ? 0 : 1,
})
-
- if(wx.getStorageSync('roleId') && wx.getStorageSync('roleId') == 5 ){
- this.setData({
- isTrainee: true
- }, () => {
- this.getTrainClass(true)
- this.fetchFitnessReport()
- })
+ await this.getTrainClass(true)
+ if (isTrainee) {
+ await this.fetchFitnessReport()
} else {
await this.getStudentReport()
}
},
- async getStudentReport() {
- const res = await getReport()
- let list = []
- res.data.categoryScoreList.forEach(e => {
- list.push({
- ...e,
- width: e.score >= 60 && e.score <= 80 ? (((e.score - 60) / 4)*5 + 25) + '%' : ((e.score - 60) / 0.4 + 2) + '%',
- grade: e.score >= 90 ? 'grate' : e.score >= 80 ? 'good' : e.score >= 60 ? 'normal' : ''
- })
- })
-
- res.data.width = res.data.totalScore >= 60 && res.data.totalScore <= 80 ? (((res.data.totalScore - 60) / 4)*5 + 25) + '%' : ((res.data.totalScore - 60) / 0.4 + 2) + '%',
- res.data.grade = res.data.totalScore >= 90 ? 'grate' : res.data.totalScore >= 80 ? 'good' : res.data.totalScore >= 60 ? 'normal' : ''
- res.data.totalScore = res.data.totalScore.toFixed(0)
- res.data.bodyFunction = res.data.bodyFunction.toFixed(0)
- res.data.bodyQuality = res.data.bodyQuality.toFixed(0)
- res.data.bodyShape = res.data.bodyShape.toFixed(0)
- this.setData({
- report: res.data,
- list
- })
+ _toScoreValue(value) {
+ const score = Number(value || 0)
+ return Number.isFinite(score) ? score : 0
+ },
+
+ _formatScore(value) {
+ return this._toScoreValue(value).toFixed(0)
+ },
+
+ _getScoreGrade(score) {
+ const value = this._toScoreValue(score)
+ return value >= 90 ? 'grate' : value >= 80 ? 'good' : value >= 60 ? 'normal' : ''
+ },
+
+ _getScoreWidth(score) {
+ const value = Math.max(0, Math.min(100, this._toScoreValue(score)))
+ if (value >= 60 && value <= 80) return (((value - 60) / 4) * 5 + 25) + '%'
+ return Math.max(2, (value - 60) / 0.4 + 2) + '%'
+ },
+
+ _hasReportRecord(item) {
+ const scoreTrendChart = (item && item.scoreTrendChart) || {}
+ const axisY = Array.isArray(scoreTrendChart.axisY) ? scoreTrendChart.axisY : []
+ return axisY.length > 0
+ },
+
+ _getAverageScore(items) {
+ const valid = (items || []).filter(item => item && item.hasRecord)
+ if (!valid.length) return 0
+ return valid.reduce((sum, item) => sum + this._toScoreValue(item.lastScore), 0) / valid.length
+ },
+
+ _buildStudentReport(rawData) {
+ const sourceList = (rawData && rawData.categoryScoreList) || []
+ const list = sourceList.map(item => {
+ const score = this._toScoreValue(item.lastScore)
+ const scoreTrendChart = item.scoreTrendChart || { axisX: [], axisY: [] }
+ const reportItem = { ...item, scoreTrendChart }
+ const hasRecord = this._hasReportRecord(reportItem)
+ return { ...reportItem, hasRecord, score: this._formatScore(score), width: this._getScoreWidth(score), grade: this._getScoreGrade(score) }
+ }).filter(item => item.hasRecord)
+ const shapeList = list.filter(item => item.categoryValue === 1)
+ const functionList = list.filter(item => item.categoryValue === 2)
+ const qualityList = list.filter(item => item.categoryValue !== 1 && item.categoryValue !== 2)
+ const totalScore = this._getAverageScore(list)
+ return {
+ report: { totalScore: this._formatScore(totalScore), bodyShape: this._formatScore(this._getAverageScore(shapeList)), bodyFunction: this._formatScore(this._getAverageScore(functionList)), bodyQuality: this._formatScore(this._getAverageScore(qualityList)), width: this._getScoreWidth(totalScore), grade: this._getScoreGrade(totalScore) },
+ list,
+ }
+ },
+
+ async getStudentReport() {
+ this.setData({ studentReportLoading: true })
+ try {
+ const res = await getReport()
+ const viewData = this._buildStudentReport(res.data || {})
+ this.setData({ ...viewData, fitnessItems: viewData.list.map(item => ({ ...item, unit: UNIT_MAP[item.name] || '' })), studentReportLoading: false })
+ } catch (e) {
+ this.setData({ report: {}, list: [], fitnessItems: [], studentReportLoading: false })
+ }
},
- // 切换体测/课堂 Tab
switchTab(e) {
const tab = Number(e.currentTarget.dataset.tab)
if (tab === this.data.activeTab) return
this.setData({ activeTab: tab }, () => {
- if (tab === 1) {
- // 切到体测报告时绘制雷达图
- this.drawRadarChart(this)
- }
+ if (tab === 0 && this.data.roomList.length === 0) this.getTrainClass(true)
+ if (this.data.isTrainee && tab === 1) this.drawRadarChart(this)
})
},
- // 切换课堂报告子Tab (课堂/月/季度)
switchClassroomSubTab(e) {
const tab = Number(e.currentTarget.dataset.tab)
if (tab === this.data.classroomSubTab) return
@@ -409,7 +443,7 @@ Page({
})
this.setData({
roomList: refresh ? newList : [...this.data.roomList, ...newList],
- page: this.data.page + 1,
+ pageIndex: this.data.pageIndex + 1,
hasMore: res.data.total > (this.data.pageIndex) * 20,
})
@@ -447,16 +481,10 @@ Page({
*/
onShow() {
tabService.updateIndex(this, 2)
- if(wx.getStorageSync('roleId') && wx.getStorageSync('roleId') == 5){ //学员
- this.setData({
- isTrainee:true
- })
- }
+ const isTrainee = wx.getStorageSync('roleId') && wx.getStorageSync('roleId') == 5
+ this.setData({ isTrainee })
},
- /**
- * 生命周期函数--监听页面隐藏
- */
onHide() {
},
@@ -472,53 +500,40 @@ Page({
* 页面相关事件处理函数--监听用户下拉动作
*/
async onPullDownRefresh() {
- if (this.data.isTrainee) {
- const { activeTab, classroomSubTab } = this.data
- if (activeTab === 0) {
- // 课堂报告 Tab
- if (classroomSubTab === 0) {
- // 课堂列表
- this.setData({ pageIndex: 1, hasMore: true }, async () => {
- await this.getTrainClass(true)
- wx.stopPullDownRefresh()
- wx.showToast({ title: '刷新成功', icon: 'none' })
- })
- } else if (classroomSubTab === 1) {
- // 月报告
- await this.fetchMonthReport()
+ const { activeTab, classroomSubTab, isTrainee } = this.data
+ if (activeTab === 0) {
+ if (classroomSubTab === 0) {
+ this.setData({ pageIndex: 1, hasMore: true }, async () => {
+ await this.getTrainClass(true)
wx.stopPullDownRefresh()
wx.showToast({ title: '刷新成功', icon: 'none' })
- } else if (classroomSubTab === 2) {
- // 季度报告
- await this.fetchQuarterReport()
- wx.stopPullDownRefresh()
- wx.showToast({ title: '刷新成功', icon: 'none' })
- }
- } else if (activeTab === 1) {
- // 体测报告 Tab
- await this.fetchFitnessReport()
- this.drawRadarChart(this)
+ })
+ } else if (classroomSubTab === 1) {
+ await this.fetchMonthReport()
+ wx.stopPullDownRefresh()
+ wx.showToast({ title: '刷新成功', icon: 'none' })
+ } else if (classroomSubTab === 2) {
+ await this.fetchQuarterReport()
wx.stopPullDownRefresh()
wx.showToast({ title: '刷新成功', icon: 'none' })
}
+ } else if (isTrainee && activeTab === 1) {
+ await this.fetchFitnessReport()
+ this.drawRadarChart(this)
+ wx.stopPullDownRefresh()
+ wx.showToast({ title: '刷新成功', icon: 'none' })
} else {
await this.getStudentReport()
wx.stopPullDownRefresh()
- wx.showToast({ title: '刷新成功!', icon: 'none' })
+ wx.showToast({ title: '刷新成功', icon: 'none' })
}
},
- /**
- * 页面上拉触底事件的处理函数
- */
onReachBottom() {
- this.getTrainClass()
+ if (this.data.activeTab === 0 && this.data.classroomSubTab === 0) this.getTrainClass()
},
- /**
- * 用户点击右上角分享
- */
onShareAppMessage() {
}
-})
\ No newline at end of file
+})
diff --git a/pages/parent/report/report.wxml b/pages/parent/report/report.wxml
index bedcf79..79ffc29 100644
--- a/pages/parent/report/report.wxml
+++ b/pages/parent/report/report.wxml
@@ -1,8 +1,17 @@
+
+
+ 课堂报告
+
+
+ {{isTrainee ? '体测报告' : '学生报告'}}
+
+
+
-
+
健康身体 坚持运动
@@ -102,17 +111,12 @@
-
-
-
-
-
- 课堂报告
-
-
- 体测报告
-
+
+ 暂无
+ 暂无学生报告数据
+
+
@@ -136,8 +140,12 @@
- 加载中...
- 没有更多了哦~
+ 加载中...
+ 没有更多了哦~
+
+ 暂无
+ 暂无课堂报告数据
+
@@ -278,7 +286,7 @@
-
+
体测成绩对比
@@ -381,4 +389,4 @@
-
\ No newline at end of file
+
diff --git a/pages/parent/report/report.wxss b/pages/parent/report/report.wxss
index 1f52edf..a3bed35 100644
--- a/pages/parent/report/report.wxss
+++ b/pages/parent/report/report.wxss
@@ -882,4 +882,32 @@
.picker-year-arrow-disabled {
opacity: 0.3;
color: #ccc;
-}
\ No newline at end of file
+}
+
+.report-empty {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ min-height: 260rpx;
+ margin: 30rpx 0;
+ background: #fff;
+ border-radius: 20rpx;
+ box-shadow: 0 4rpx 16rpx rgba(73,165,252,0.1);
+ color: #9aa7b2;
+ font-size: 26rpx;
+}
+
+.report-empty-icon {
+ width: 96rpx;
+ height: 96rpx;
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin-bottom: 18rpx;
+ background: #eef8ff;
+ color: #26A5F6;
+ font-size: 24rpx;
+ font-weight: 600;
+}
diff --git a/subpackage/teacher/resource-detail/resource-detail.js b/subpackage/teacher/resource-detail/resource-detail.js
index 385f38a..f380e0f 100644
--- a/subpackage/teacher/resource-detail/resource-detail.js
+++ b/subpackage/teacher/resource-detail/resource-detail.js
@@ -1,147 +1,164 @@
const utils = require("../../../utils/utils");
-// subpackage/teacher/resource-detail/resource-detail.js
Page({
-
- /**
- * 页面的初始数据
- */
data: {
- title: '口令',
- value: '00:00',
- duration: '00:00',
- aduio:null,
- data:{},
- isPlay:false,
- percent:0,
- isReload:false,//是否重复播放
- isShow:false,//是否展示弹窗
+ title: "音乐",
+ data: {},
+ playlist: [],
+ currentIndex: 0,
+ value: "00:00",
+ duration: "00:00",
+ percent: 0,
+ isPlay: false,
+ isSingleLoop: false,
+ isShow: false,
+ isClosing: false
},
- /**
- * 生命周期函数--监听页面加载
- */
onLoad(options) {
- console.log(JSON.parse(options.data))
+ let current = {};
+ try {
+ current = JSON.parse(decodeURIComponent(options.data || "{}"));
+ } catch (error) {
+ console.error("资源参数解析失败", error);
+ }
+
this.setData({
- data: JSON.parse(options.data),
- title: JSON.parse(options.data).id == 1 ? '口令' : JSON.parse(options.data).id == 2 ? '音乐' : '视频'
- })
- this.loadAudio(JSON.parse(options.data).resourceUrl)
+ data: current,
+ playlist: current.resourceUrl ? [current] : [],
+ title: current.id == 1 ? "口令" : "音乐"
+ });
+
+ this.createAudioContext();
+ if (current.resourceUrl) {
+ this.loadTrack(current, false);
+ }
+
+ const eventChannel = this.getOpenerEventChannel && this.getOpenerEventChannel();
+ if (eventChannel && eventChannel.on) {
+ eventChannel.on("setPlaylist", ({ playlist = [], currentIndex = 0 }) => {
+ if (!playlist.length) return;
+ const safeIndex = Math.min(Math.max(Number(currentIndex) || 0, 0), playlist.length - 1);
+ this.setData({ playlist, currentIndex: safeIndex, data: playlist[safeIndex] });
+ });
+ }
},
- loadAudio(url) {
+ createAudioContext() {
this.audioCtx = wx.createInnerAudioContext();
- this.audioCtx.src = url
- this.audioCtx.onCanplay(() => {
- this.audioCtx.duration
- this.audioCtx.currentTime
- console.log(this.audioCtx.currentTime)
- console.log(this.audioCtx.duration)
- console.log(this.audioCtx.currentTime)
- this.setData({
- value: utils.formatTimeStr(this.audioCtx.currentTime),
- duration: utils.formatTimeStr(this.audioCtx.duration),
- })
- })
+ this.audioCtx.obeyMuteSwitch = false;
- this.audioCtx.onTimeUpdate(() => {
- console.log('在播放咯')
- console.log(this.data.percent)
- console.log('在播放咯')
- this.audioCtx.duration
- this.audioCtx.currentTime
- this.setData({
- value: utils.formatTimeStr(this.audioCtx.currentTime),
- duration: utils.formatTimeStr(this.audioCtx.duration),
- percent:((this.audioCtx.currentTime/this.audioCtx.duration)*100).toFixed(0)
- })
- })
+ this.audioCtx.onCanplay(() => this.updateProgress());
+ this.audioCtx.onTimeUpdate(() => this.updateProgress());
+ this.audioCtx.onPlay(() => this.setData({ isPlay: true }));
+ this.audioCtx.onPause(() => this.setData({ isPlay: false }));
+ this.audioCtx.onStop(() => this.setData({ isPlay: false }));
+ this.audioCtx.onEnded(() => {
+ if (!this.data.isSingleLoop) this.changeTrack(1, true);
+ });
+ this.audioCtx.onError((error) => {
+ console.error("音频播放失败", error);
+ this.setData({ isPlay: false });
+ wx.showToast({ title: "音频加载失败,请稍后重试", icon: "none" });
+ });
},
- btnCilck(){
- console.log(this.audioCtx.src)
- if(this.data.isPlay){
- this.audioCtx.pause()
- this.setData({
- isPlay:false
- })
- }else{
- this.audioCtx.play()
- this.setData({
- isPlay:true
- })
+ loadTrack(track, autoplay = true) {
+ if (!track || !track.resourceUrl || !this.audioCtx) return;
+ this.audioCtx.stop();
+ this.audioCtx.loop = this.data.isSingleLoop;
+ this.audioCtx.src = track.resourceUrl;
+ this.setData({
+ data: track,
+ value: "00:00",
+ duration: "00:00",
+ percent: 0,
+ isPlay: autoplay
+ });
+ if (autoplay) this.audioCtx.play();
+ },
+
+ updateProgress() {
+ if (!this.audioCtx) return;
+ const currentTime = Number(this.audioCtx.currentTime) || 0;
+ const duration = Number(this.audioCtx.duration) || 0;
+ this.setData({
+ value: utils.formatTimeStr(currentTime),
+ duration: utils.formatTimeStr(duration),
+ percent: duration ? Math.min((currentTime / duration) * 100, 100) : 0
+ });
+ },
+
+ btnCilck() {
+ if (!this.audioCtx || !this.data.data.resourceUrl) return;
+ this.data.isPlay ? this.audioCtx.pause() : this.audioCtx.play();
+ },
+
+ playPrevious() {
+ this.changeTrack(-1, true);
+ },
+
+ playNext() {
+ this.changeTrack(1, true);
+ },
+
+ changeTrack(step, autoplay) {
+ const { playlist, currentIndex } = this.data;
+ if (!playlist.length) return;
+ const nextIndex = (currentIndex + step + playlist.length) % playlist.length;
+ this.setData({ currentIndex: nextIndex }, () => this.loadTrack(playlist[nextIndex], autoplay));
+ },
+
+ selectTrack(e) {
+ const index = Number(e.currentTarget.dataset.index);
+ if (!Number.isInteger(index) || !this.data.playlist[index]) return;
+ this.setData({ currentIndex: index }, () => {
+ this.loadTrack(this.data.playlist[index], true);
+ this.hideList();
+ });
+ },
+
+ toggleLoop() {
+ const isSingleLoop = !this.data.isSingleLoop;
+ if (this.audioCtx) this.audioCtx.loop = isSingleLoop;
+ this.setData({ isSingleLoop });
+ wx.showToast({ title: isSingleLoop ? "单曲循环" : "列表循环", icon: "none" });
+ },
+
+ seekAudio(e) {
+ if (!this.audioCtx || !this.audioCtx.duration) return;
+ wx.createSelectorQuery().in(this).select("#audio-progress").boundingClientRect((rect) => {
+ if (!rect || !rect.width) return;
+ const ratio = Math.min(Math.max((e.detail.x - rect.left) / rect.width, 0), 1);
+ this.audioCtx.seek(this.audioCtx.duration * ratio);
+ }).exec();
+ },
+
+ showList() {
+ if (this.closeTimer) {
+ clearTimeout(this.closeTimer);
+ this.closeTimer = null;
}
+ this.setData({ isShow: true, isClosing: false });
},
- showList(){
- this.setData({
- isShow:true
- })
+ hideList() {
+ if (!this.data.isShow || this.data.isClosing) return;
+ this.setData({ isClosing: true });
+ this.closeTimer = setTimeout(() => {
+ this.setData({ isShow: false, isClosing: false });
+ this.closeTimer = null;
+ }, 240);
},
- reload(){
- wx.showToast({
- title: this.data.isReload ?'列表循环':'单曲循环',
- icon:'none'
- })
- this.audioCtx.loop = true
- this.setData({
- isReload:!this.data.isReload
- })
- },
-
- /**
- * 生命周期函数--监听页面初次渲染完成
- */
- onReady() {
+ preventClose() {},
- },
-
- /**
- * 生命周期函数--监听页面显示
- */
- onShow() {
-
- },
-
- /**
- * 生命周期函数--监听页面隐藏
- */
- onHide() {
-
- },
-
- /**
- * 生命周期函数--监听页面卸载
- */
onUnload() {
- if(this.audioCtx){
+ if (this.closeTimer) clearTimeout(this.closeTimer);
+ if (this.audioCtx) {
this.audioCtx.stop();
- if(this.audioCtx.destory){
- this.audioCtx.destory();
- }
+ if (this.audioCtx.destroy) this.audioCtx.destroy();
+ this.audioCtx = null;
}
- },
-
- /**
- * 页面相关事件处理函数--监听用户下拉动作
- */
- onPullDownRefresh() {
-
- },
-
- /**
- * 页面上拉触底事件的处理函数
- */
- onReachBottom() {
-
- },
-
- /**
- * 用户点击右上角分享
- */
- onShareAppMessage() {
-
}
-})
\ No newline at end of file
+});
diff --git a/subpackage/teacher/resource-detail/resource-detail.json b/subpackage/teacher/resource-detail/resource-detail.json
index d28dfb6..6cab79c 100644
--- a/subpackage/teacher/resource-detail/resource-detail.json
+++ b/subpackage/teacher/resource-detail/resource-detail.json
@@ -1,10 +1,9 @@
{
"usingComponents": {
"mp-bar": "weui-miniprogram/navigation-bar/navigation-bar",
- "mp-icon": "weui-miniprogram/icon/icon",
- "mp-half-screen-dialog": "weui-miniprogram/half-screen-dialog/half-screen-dialog"
+ "mp-icon": "weui-miniprogram/icon/icon"
},
"backgroundColorContent": "#f7f7f7",
"backgroundColor": "#f7f7f7",
"navigationStyle": "custom"
-}
\ No newline at end of file
+}
diff --git a/subpackage/teacher/resource-detail/resource-detail.wxml b/subpackage/teacher/resource-detail/resource-detail.wxml
index 81ee3a0..ee9e26c 100644
--- a/subpackage/teacher/resource-detail/resource-detail.wxml
+++ b/subpackage/teacher/resource-detail/resource-detail.wxml
@@ -1,32 +1,73 @@
-
-
-
+
+
-
-
- {{data.resourceName}}
-
- {{value}}
- {{duration}}
+
+
+
+
+
+
+ ♫
+
+
-
-
+ {{data.resourceName || '暂无音频'}}
+ {{currentIndex + 1}} / {{playlist.length}}
+
+
+
+
+
+
+
+
+ {{value}}
+ {{duration}}
+
-
-
-
-
+
+
+ {{isSingleLoop ? '单曲' : '列表'}}
+
+
+
+
+
+
+
+
+ 列表
-
-
-
- 1
-
-
-
\ No newline at end of file
+
+
+
+
+ 暂无可播放歌曲
+
+ {{index === currentIndex && isPlay ? '♪' : index + 1}}
+ {{item.resourceName}}
+ {{isPlay ? '播放中' : '当前'}}
+
+
+
+
+
diff --git a/subpackage/teacher/resource-detail/resource-detail.wxss b/subpackage/teacher/resource-detail/resource-detail.wxss
index 1af1423..e33ffb5 100644
--- a/subpackage/teacher/resource-detail/resource-detail.wxss
+++ b/subpackage/teacher/resource-detail/resource-detail.wxss
@@ -1,78 +1,161 @@
-/* subpackage/teacher/resource-detail/resource-detail.wxss */
-.pad{
- padding: 0 30rpx;
+.player-page {
+ min-height: 100vh;
box-sizing: border-box;
+ padding: 0 30rpx 60rpx;
+ overflow: hidden;
+ background: linear-gradient(160deg, #42a4fc 0%, #7fc8ff 28%, #f4f8fc 64%, #f7f7f7 100%);
}
-.card{
- padding: 60rpx 30rpx;
- box-sizing: border-box;
- box-shadow: 0 10rpx 10rpx rgba(226, 222, 222,.4);
- background-color: #fff;
- border-radius: 20rpx;
- margin-top: 30rpx;
+.player-card {
+ margin-top: 38rpx;
+ padding: 66rpx 34rpx 54rpx;
+ border: 1rpx solid rgba(255, 255, 255, .75);
+ border-radius: 36rpx;
+ background: rgba(255, 255, 255, .94);
+ box-shadow: 0 24rpx 60rpx rgba(35, 116, 180, .18);
text-align: center;
}
-.title{
- font-weight: bold;
- font-size: 48rpx;
-}
-
-.time{
- display: flex;
- align-items: center;
- justify-content: space-between;
- color: #636363;
- font-size: 32rpx;
- margin-top: 100rpx;
- margin-bottom: 20rpx;
-}
-
-.progress{
- width: 100%;
- height: 24rpx;
- border-radius: 24rpx;
- background-color: #e4e4e4;
-}
-.active{
- background-color: #FBB716;
- border-radius: 24rpx;
- height: 24rpx;
- width: 10%;
- transition: all 0.2s ease;
-}
-
-.btn{
- background-color: #FBB716;
+.record-wrap {
+ width: 330rpx;
+ height: 330rpx;
+ margin: 0 auto 52rpx;
+ padding: 18rpx;
+ box-sizing: border-box;
border-radius: 50%;
- width: 140rpx;
- height: 140rpx;
- margin: auto;
+ background: rgba(251, 183, 22, .16);
+ box-shadow: 0 18rpx 38rpx rgba(48, 66, 84, .2);
+}
+
+.record {
+ position: relative;
display: flex;
align-items: center;
justify-content: center;
+ width: 100%;
+ height: 100%;
+ border-radius: 50%;
+ background: repeating-radial-gradient(circle, #2d3741 0, #2d3741 10rpx, #202832 11rpx, #202832 17rpx);
}
-.btnlist{
+.record-playing .record { animation: recordRotate 7s linear infinite; }
+.record-line { position: absolute; border: 2rpx solid rgba(255, 255, 255, .2); border-radius: 50%; }
+.line-one { width: 210rpx; height: 210rpx; }
+.line-two { width: 150rpx; height: 150rpx; }
+.record-core {
display: flex;
- justify-content: space-between;
align-items: center;
- margin-top: 80rpx;
+ justify-content: center;
+ width: 108rpx;
+ height: 108rpx;
+ border: 12rpx solid #f7c143;
+ border-radius: 50%;
+ background: #fbb716;
+}
+.record-note { color: #fff; font-size: 52rpx; line-height: 1; }
+
+@keyframes recordRotate { from { transform: rotate(0); } to { transform: rotate(360deg); } }
+
+.song-name {
+ min-height: 58rpx;
+ overflow: hidden;
+ color: #1d2a36;
+ font-size: 42rpx;
+ font-weight: 600;
+ line-height: 58rpx;
+ text-overflow: ellipsis;
+ white-space: nowrap;
}
-.img{
- width: 64rpx;
- height: 64rpx;
- margin: 20rpx;
+.song-count { margin-top: 10rpx; color: #96a0aa; font-size: 24rpx; }
+.progress-area { margin-top: 70rpx; }
+.progress {
+ width: 100%;
+ height: 10rpx;
+ border-radius: 10rpx;
+ background: #e5eaf0;
+}
+.active { position: relative; height: 10rpx; border-radius: 10rpx; background: linear-gradient(90deg, #ffd465, #fbb716); }
+.progress-dot {
+ position: absolute;
+ top: -8rpx;
+ right: -13rpx;
+ width: 26rpx;
+ height: 26rpx;
+ border: 5rpx solid #fff;
+ border-radius: 50%;
+ background: #fbb716;
+ box-shadow: 0 3rpx 10rpx rgba(251, 183, 22, .55);
+}
+.time { display: flex; justify-content: space-between; margin-top: 18rpx; color: #87929d; font-size: 25rpx; }
+
+.btnlist { display: flex; align-items: center; justify-content: space-between; margin-top: 58rpx; }
+.play-button {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 142rpx;
+ height: 142rpx;
+ border-radius: 50%;
+ background: linear-gradient(145deg, #ffd052, #f5a900);
+ box-shadow: 0 16rpx 30rpx rgba(251, 183, 22, .35);
+}
+.switch-icon { width: 62rpx; height: 62rpx; padding: 12rpx; }
+.tool-button { display: flex; flex-direction: column; align-items: center; min-width: 72rpx; color: #7e8994; font-size: 21rpx; }
+.tool-icon { width: 50rpx; height: 50rpx; margin-bottom: 5rpx; }
+
+.playlist-mask {
+ position: fixed;
+ z-index: 99;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ background: rgba(13, 26, 39, .48);
+}
+.playlist-mask-enter { animation: maskFadeIn 240ms ease-out both; }
+.playlist-mask-leave { animation: maskFadeOut 240ms ease-in both; }
+.playlist-panel {
+ position: absolute;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ padding: 38rpx 30rpx calc(24rpx + env(safe-area-inset-bottom));
+ border-radius: 34rpx 34rpx 0 0;
+ background: #fff;
+ box-shadow: 0 -16rpx 50rpx rgba(18, 43, 65, .15);
+}
+.playlist-panel-enter { animation: playlistSlideUp 300ms cubic-bezier(.22, .8, .3, 1) both; }
+.playlist-panel-leave { animation: playlistSlideDown 240ms ease-in both; }
+
+@keyframes maskFadeIn {
+ from { opacity: 0; }
+ to { opacity: 1; }
}
-.none{
- padding: 0;
- margin: 0;
- height: 0;
+@keyframes maskFadeOut {
+ from { opacity: 1; }
+ to { opacity: 0; }
}
-.weui-half-screen-dialog__ft{
- padding: 0;
-}
\ No newline at end of file
+@keyframes playlistSlideUp {
+ from { transform: translate3d(0, 100%, 0); }
+ to { transform: translate3d(0, 0, 0); }
+}
+
+@keyframes playlistSlideDown {
+ from { transform: translate3d(0, 0, 0); }
+ to { transform: translate3d(0, 100%, 0); }
+}
+.playlist-header { display: flex; align-items: center; justify-content: space-between; padding: 0 10rpx 28rpx; }
+.playlist-title { color: #172532; font-size: 36rpx; font-weight: 600; }
+.playlist-subtitle { margin-top: 6rpx; color: #9aa4ad; font-size: 24rpx; }
+.close-button { width: 64rpx; color: #8c969f; font-size: 48rpx; font-weight: 300; line-height: 64rpx; text-align: center; }
+.playlist-scroll { max-height: 650rpx; }
+.playlist-item { display: flex; align-items: center; min-height: 96rpx; padding: 0 22rpx; border-radius: 18rpx; color: #34424e; }
+.playlist-active { color: #eaa400; background: #fff8e8; }
+.song-index { width: 52rpx; flex-shrink: 0; color: #a0a9b2; font-size: 26rpx; text-align: left; }
+.playlist-active .song-index { color: #f1ac00; }
+.playlist-name { overflow: hidden; flex: 1; font-size: 29rpx; text-align: left; text-overflow: ellipsis; white-space: nowrap; }
+.playing-label { margin-left: 20rpx; color: #f1ac00; font-size: 22rpx; }
+.empty-list { padding: 100rpx 0; color: #a0a9b2; font-size: 28rpx; text-align: center; }
diff --git a/subpackage/teacher/resource/resource.js b/subpackage/teacher/resource/resource.js
index 79979c5..976d74d 100644
--- a/subpackage/teacher/resource/resource.js
+++ b/subpackage/teacher/resource/resource.js
@@ -59,10 +59,21 @@ Page({
}else if(this.data.id == 4){
return
}else {
- const data = e.currentTarget.dataset.item
- data.id = this.data.id
+ const data = Object.assign({}, e.currentTarget.dataset.item, { id: this.data.id })
+ const playlist = []
+ const collectResources = (nodes) => {
+ (nodes || []).forEach((node) => {
+ (node.resourceDetails || []).forEach((item) => playlist.push(Object.assign({}, item, { id: this.data.id })))
+ collectResources(node.children)
+ })
+ }
+ collectResources(this.data.list)
+ const currentIndex = Math.max(playlist.findIndex((item) => item.resourceUrl === data.resourceUrl), 0)
wx.navigateTo({
- url: '/subpackage/teacher/resource-detail/resource-detail?data='+JSON.stringify(data),
+ url: '/subpackage/teacher/resource-detail/resource-detail?data='+encodeURIComponent(JSON.stringify(data)),
+ success(res) {
+ res.eventChannel.emit('setPlaylist', { playlist, currentIndex })
+ }
})
}
},
@@ -115,4 +126,4 @@ Page({
onShareAppMessage() {
}
-})
\ No newline at end of file
+})