YNUtdPlatform/pages/YNEduApp/learnProj/learnProjDetail.vue

652 lines
21 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="page">
<u-navbar title="学习项目" @leftClick="leftClick" placeholder />
<view class="proj-cont">
<h2 style="margin-bottom: 15rpx">{{ name }}</h2>
<span style="font-size: 12px; color: #b0b0b0">合格标准学习进度达到{{ eligibility }}%</span>
<view class="user-info">
<div style="font-size: 18px">{{ createUserName }}</div>
<div class="training-content">
<div>培训内容{{ listStageContentNum || '暂无' }}</div>
</div>
<!-- <view class="info-lef">
<view class="avatar">
<image src="/static/eduImg/avatar.jpg"></image>
<div style="font-size: 18px">{{ createUserName }}</div>
</view>
<view style="display: flex; align-items: center">
<l-starRate v-model="starRate" :disabled="true" style="margin-right: 1vw"></l-starRate>
<span style="color: #ffca3e">{{ starRate }}.0</span>
</view>
</view>
<view class="info-rig">
<view class="rig-up">
<view>
培训内容
<span>{{ 'listStageContentNum' }}</span>
</view>
<view style="margin-left: 2vw">
观看记录
<span>28</span>
<uni-icons style="color: #b0b0b0" type="right" size="12"></uni-icons>
</view>
</view>
<view class="rig-dn">
去评分
<uni-icons style="color: #b0b0b0" type="right" size="12"></uni-icons>
</view>
</view> -->
</view>
<!-- <view class="tip">已开启进度同步,其他途径的学习进度已自动同步</view> -->
<div v-for="(stageItem, stageIndex) in listStage" :key="stageIndex" :title="stageItem.stageName">
<div class="item-stage" @click="handleShow(stageItem)">
<span>{{ stageItem.stageName }}</span>
<u-icon :name="stageItem.isShow ? 'arrow-down' : 'arrow-up'" size="17" />
</div>
<div v-if="stageItem.isShow">
<div v-for="(content, conIndex) in stageItem.listStageContent" :key="conIndex">
<u-collapse :border="false">
<u-collapse-item title="素材" v-if="content.stageType == 1" :border="false">
<div
class="list-wrapper"
v-for="(item, index) in content.studyList"
:key="index"
@click="toggleTheoryLearn(item, content)"
>
<div class="left-content">
<div class="title">
<u-icon name="/static/images/curriculum.png" size="15" />
<div style="margin: 0 15px 0 3px">素材</div>
<div>{{ item.totalTime }}</div>
</div>
<div class="note">{{ item.studyName }}</div>
</div>
<div class="right-content">
<div class="progress">
<u-line-progress
:percentage="item.studyPercentage"
:showText="false"
activeColor="#579AF8"
height="8"
/>
</div>
<div>{{ item.studyPercentage || 0 }}%</div>
</div>
</div>
</u-collapse-item>
<u-collapse-item title="课程" v-if="content.stageType == 2" :border="false">
<div
class="list-wrapper"
v-for="(item, index) in content.studyList"
:key="index"
@click="toggleTheoryLearn(item, content)"
>
<div class="left-content">
<div class="title">
<u-icon name="/static/images/curriculum.png" size="15" />
<div style="margin: 0 15px 0 3px">课程</div>
<div>{{ item.totalTime }}</div>
</div>
<div class="note">{{ item.studyName }}</div>
</div>
<div class="right-content">
<div class="progress">
<u-line-progress
:percentage="item.studyPercentage"
:showText="false"
activeColor="#579AF8"
height="8"
/>
</div>
<div>{{ item.studyPercentage || 0 }}%</div>
</div>
</div>
</u-collapse-item>
<u-collapse-item title="练习" v-if="content.stageType == 3" :border="false">
<div class="list-wrapper" @click="toggleTheoryPrac(content)">
<div class="left-content">
<div class="title">
<u-icon name="/static/images/exercises.png" size="15" />
<div style="margin: 0 15px 0 3px">练习</div>
</div>
<div class="note">{{ content.studyName }}</div>
<div v-show="content.practiceMsg && content.practiceMsg.allQuestionNum > 0">
{{
content.practiceMsg.trueRate.replace('%', '') >= content.practiceMsg.qualified
? `合格(${content.practiceMsg.trueRate})`
: `不合格(${content.practiceMsg.trueRate})`
}}
</div>
</div>
<div class="right-content">
{{ content.practiceMsg && content.practiceMsg.allQuestionNum == 0 ? '未开始' : '已练习' }}
</div>
</div>
</u-collapse-item>
<u-collapse-item title="考试" v-if="content.stageType == 4" :border="false">
<div class="list-wrapper" @click="toggleTheoryExam(content)">
<div class="left-content">
<div class="title">
<u-icon name="/static/images/examine.png" size="15" />
<div style="margin: 0 15px 0 3px">考试</div>
<div>{{ content.responseTime }}分钟</div>
</div>
<div class="note">{{ content.name }}</div>
<div
v-show="content.examMsg && content.examMsg.examNum > 0 && content.examMsg.results == 1"
style="color: #5ac725"
>
及格
</div>
<div
v-show="content.examMsg && content.examMsg.examNum > 0 && content.examMsg.results == 0"
style="color: #f56c6c"
>
不及格
</div>
</div>
<div class="right-content">
{{ !content.examMsg || content.examMsg.examNum == 0 ? '开始考试' : '重考' }}
</div>
</div>
</u-collapse-item>
</u-collapse>
</div>
</div>
</div>
</view>
<!-- <view class="comment-area">
<h2 style="margin-bottom: 15rpx">最新评论 ({{ commentList.length }})</h2>
<view class="write-cmt">
<u--input
ref="uInput"
placeholder="写评论"
prefixIcon="edit-pen"
prefixIconStyle="font-size: 18px;color: #c0c4cc"
placeholderStyle="font-size: 13px;color: #c0c4cc"
border="none"
maxlength="999"
clearable
/>
</view>
<view class="cmts" v-for="(item, index) in commentList" :key="index">
<view class="cmt-up">
<image :src="item.avatar"></image>
<span>{{ item.username }}</span>
</view>
<view class="cmt-dn">
{{ item.cont }}
</view>
</view>
</view> -->
<!-- <view class="btm-sticky">
<view class="icons">
<view>
<uni-icons style="color: #1989fa; margin-right: 1vw" type="chat-filled" size="24"></uni-icons>
<span>23</span>
</view>
<view>
<uni-icons style="color: #1989fa; margin-right: 1vw" type="hand-up-filled" size="24"></uni-icons>
<span>12</span>
</view>
</view>
<view class="learn-btn">继续学习</view>
</view> -->
</view>
</template>
<script>
import { getToken, getUserId } from '@/utils/auth'
import config from 'config'
export default {
data() {
return {
projId: '',
studyId: '', // 学习id
starRate: 4,
name: '',
createUserName: '',
listStageContentNum: 0,
eligibility: '',
learnIconObj: { color: '#1A63AC', size: '18', type: 'calendar' },
pracIconObj: { color: '#38B022', size: '18', type: 'compose' },
listStage: []
// theoryLearnList: [
// { title: '高压电', id: 121, percent: 86 },
// { title: '氨基酸', id: 122, percent: 42 },
// { title: '维他命', id: 123, percent: 66 },
// { title: '电功率', id: 124, percent: 13 }
// ],
// theoryPracList: [
// { title: '物理练习', id: 141, ifPrac: false },
// { title: '魔法练习', id: 142, ifPrac: true },
// { title: '近战练习', id: 143, ifPrac: true },
// { title: '远程练习', id: 144, ifPrac: false }
// ],
// theoryExamList: [
// { title: '物理考试', id: 161, ifExam: false, time: '00:34:21' },
// { title: '魔法考试', id: 162, ifExam: true, time: '00:34:21' },
// { title: '近战考试', id: 163, ifExam: true, time: '00:34:21' },
// { title: '远程考试', id: 164, ifExam: false, time: '00:34:21' }
// ],
// commentList: [
// { username: '王二', avatar: '/static/eduImg/avatar.jpg', cont: '写的什么东西' },
// { username: '张三', avatar: '/static/eduImg/avatar.jpg', cont: '我感觉写得挺好' },
// { username: '李四', avatar: '/static/eduImg/avatar.jpg', cont: '+3' },
// {
// username: '孙笑川',
// avatar: '/static/eduImg/avatar.jpg',
// cont: '我着火了我着火了我着火了我着火了我着火了我着火了我着火了我着火了我着火了我着火了我着火了我着火了我着火了我着火了我着火了我着火了我着火了我着火了我着火了我着火了我着火了我着火了'
// }
// ]
}
},
onLoad(params) {
this.projId = params.id
console.log('🚀 ~ onLoad ~ this.projId:', this.projId)
// console.log('Userid', getUserId())
this.getStudyWorkAll()
},
methods: {
handleShow(item) {
console.log('🚀 ~ handleShow ~ item:', item.isShow)
item.isShow = this.$set(item, 'isShow', !item.isShow)
},
// 获取学习项目详情
async getStudyWorkAll() {
let params = { userId: uni.getStorageSync('userId'), id: this.projId, type: '1' }
this.$verificationToken()
uni.request({
method: 'post',
url: config.bmwUrl + '/studyWork/StudyWorkAll',
data: params,
header: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization: uni.getStorageSync('access_token')
},
dataType: 'json',
success: res => {
console.log('🚀 ~ getStudyWorkAll ~ res:', res)
this.studyId = res.data.id
this.name = res.data.name
this.createUserName = res.data.createUserName
this.listStageContentNum = res.data.listStageContentNum
this.eligibility = res.data.eligibility
this.listStage = res.data.listStage
if (this.listStage.length > 0) {
this.listStage.forEach((item, index) => {
this.$set(item, 'isShow', true)
})
}
}
})
},
// 跳转素材
toggleTheoryLearn(item, content) {
console.log('🚀 ~ toggleTheoryLearn ~ content:', item, content)
const params = {
userId: uni.getStorageSync('userId'), // 用户id
studyId: this.studyId, // 学习id
stageId: content.stageId, // 阶段id
stageContentId: content.id, // 阶段内容id
stageType: content.stageType, // 阶段类型
studyCourseId: content.forgeId || '',
sourceId: item.id, // 素材id
path: item.path, // 视频路径
studyDuration: item.studyDuration || 0, // 学习时长
allStudyDuration: item.allStudyDuration, // 总时长
isEnd: item.studyPercentage >= 100 ? true : false
}
console.log('🚀 ~ toggleTheoryLearn ~ params:', params)
console.log('🚀 ~ toggleTheoryLearn ~ item:', item.path)
let url = ''
// 如果item.path 包含 .mp4 则跳转到视频播放页面 否则跳转到文档页面
if (item.path.includes('.mp4')) {
url = '/pages/YNEduApp/learn/learn'
} else if (item.path.includes('.pdf')) {
url = '/pages/YNEduApp/learnProj/pdfStudy'
} else {
url = '/pages/YNEduApp/learnProj/imageStudy'
}
uni.navigateTo({
url: url + '?params=' + JSON.stringify(params)
})
},
// 跳转-课程
toggleTheoryCourse(item) {
console.log('🚀 ~ toggleTheoryCourse ~ item:', item)
},
// 跳转练习
toggleTheoryPrac(item) {
const params = {
practiceId: item.practiceMsg.id, // 练习id
title: item.practiceMsg.name,
studyId: this.studyId, // 学习id
isNew: item.practiceMsg.alreadyNum == 0 ? true : false
}
uni.navigateTo({
url: '/pages/YNEduApp/prac/pracDetail?params=' + JSON.stringify(params)
})
uni.removeStorageSync('from')
uni.setStorageSync('from', '/pages/YNEduApp/learnProj/learnProjDetail')
},
// 跳转考试
toggleTheoryExam(item) {
console.log('🚀 ~ toggleTheoryExam ~ item:', item, item.examMsg.examEquipment)
const date = new Date()
const validityDate = item.examMsg.validityDate.split('~')
const startDate = new Date(validityDate[0].trim())
const endDate = new Date(validityDate[1].trim())
if (date < startDate || date > endDate) {
uni.showToast({
title: '当前时间不在考试时间范围内',
icon: 'none'
})
return
}
if (item.examMsg.examEquipment == 2) {
uni.showToast({
title: '请在电脑端进行考试',
icon: 'none'
})
return
}
// examCount 1: 不限次 2: 及格终止 3: 自定义
if (item.examMsg.examCount == 2 && item.examMsg.results == 1) {
uni.showToast({
title: '此考试及格终止, 考试以及格, 无需再次考试',
icon: 'none'
})
return
} else if (item.examMsg.examCount == 3 && item.examMsg.examNum >= item.examMsg.examCustom) {
uni.showToast({
title: '此考试有次数限制, 考试次数已达上限, 无法再考试了',
icon: 'none'
})
return
}
const params = {
id: item.examMsg.id, // 考试id
cutNum: item.examMsg.isCut, // 切屏次数
examNum: item.examMsg.examNum, // 考试次数
examCount: item.examMsg.examCount, // 1: 不限次 2: 及格终止 3: 自定义
examCustom: item.examMsg.examCustom, // 自定义次数
studyId: this.studyId, // 学习id
responseTime: item.examMsg.responseTime, // 考试时长
score: item.examMsg.score, // 总分
passScore: item.examMsg.passScore // 及格分数
}
console.log('🚀 ~ toggleTheoryExam ~ params:', params)
uni.navigateTo({
url: '/pages/YNEduApp/exam/beforeExam?params=' + JSON.stringify(params)
})
uni.removeStorageSync('from')
uni.setStorageSync('from', '/pages/YNEduApp/learnProj/learnProjDetail')
},
leftClick() {
uni.navigateTo({
url: '/pages/YNEduApp/learnProj/learnProj'
})
}
},
onBackPress(options) {
console.log(options)
if (options.from == 'backbutton') {
// 来自手势返回
console.log('手势返回')
// 返回为 true 时,不会执行返回操作,可以自定义返回逻辑
// 返回为 false 或者不返回时,则执行默认返回操作
return true
}
// 返回为 false 或者不返回时,则执行默认返回操作
return false
}
}
</script>
<style lang="scss">
::v-deep .u-cell__body {
padding: 5px !important;
}
::v-deep .u-collapse-item__content__text{
padding: 0 5px !important;
}
.page {
width: 100vw;
height: 100vh;
background-color: #f8f8f8;
box-sizing: border-box;
padding: 5vw 5px;
position: relative;
.item-stage {
margin: 8px 0;
font-size: 16px;
display: flex;
justify-content: space-between;
align-items: center;
}
.proj-cont {
width: 100%;
box-sizing: border-box;
padding: 30rpx 20rpx;
background-color: #fff;
border-radius: 20rpx;
display: flex;
flex-direction: column;
box-shadow: #f4f4f4 2px 2px;
.user-info {
width: 100%;
/* height: 8vh; */
display: flex;
flex-direction: column;
margin-top: 2vh;
margin-bottom: 2vh;
.training-content {
display: flex;
margin-top: 10px;
white-space: normal;
word-wrap: break-word;
word-break: break-all;
}
.info-lef {
width: 35%;
height: 100%;
display: flex;
flex-direction: column;
.avatar {
width: 100%;
display: flex;
align-items: center;
image {
width: 60rpx;
height: 60rpx;
border-radius: 50%;
margin-right: 1.5vw;
}
}
}
.info-rig {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-around;
box-sizing: border-box;
color: #b0b0b0;
.rig-up {
display: flex;
align-items: center;
view {
span {
padding: 0 1vw;
}
}
}
}
}
.tip {
width: 100%;
margin: 2vh auto;
background-color: #f7f7f7;
font-size: 12px;
color: #9b9b9b;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
padding: 25rpx 15rpx;
}
.collapse-item {
/* height: 400px; */
overflow: auto;
}
.list-wrapper {
display: flex;
justify-content: space-between;
align-items: center;
/* padding: 20px 0; */
margin-bottom: 10px;
padding-bottom: 5px;
border-bottom: 1px solid #f0f0f0;
font-size: 12px;
color: #b0b0b0;
/* height: 400px; */
overflow: auto;
.left-content {
width: 50vw;
.title {
display: flex;
align-items: center;
}
.note {
/* width: 130px; */
margin-top: 10px;
font-size: 14px;
color: #333;
word-wrap: break-word;
}
}
.right-content {
width: 35vw;
display: flex;
align-items: center;
.progress {
width: 100px;
margin-right: 5px;
}
}
}
}
.comment-area {
width: 100%;
box-sizing: border-box;
margin: 1vh auto;
padding: 30rpx 20rpx 5vh 20rpx;
background-color: #fff;
border-radius: 20rpx;
display: flex;
flex-direction: column;
box-shadow: #f4f4f4 2px 2px;
.write-cmt {
width: 100%;
margin: 2vh auto;
background-color: #f7f7f7;
font-size: 12px;
color: #9b9b9b;
display: flex;
align-items: center;
box-sizing: border-box;
padding: 15rpx;
}
.cmts {
width: 100%;
display: flex;
flex-direction: column;
margin-bottom: 2vh;
.cmt-up {
display: flex;
align-items: center;
font-weight: bold;
image {
width: 60rpx;
height: 60rpx;
border-radius: 50%;
margin-right: 2vw;
}
}
.cmt-dn {
box-sizing: border-box;
padding-left: calc(60rpx + 2vw);
}
}
}
.btm-sticky {
position: fixed;
left: 0;
bottom: 0;
width: 100%;
height: 8vh;
background-color: #fff;
border-top: 1px solid #d8d8d8;
display: flex;
justify-content: space-between;
align-items: center;
box-sizing: border-box;
padding: 0 5vw;
.icons {
width: 40%;
display: flex;
justify-content: space-between;
view {
display: flex;
align-items: center;
span {
font-size: 16px;
color: #1a89fa;
font-weight: bold;
}
}
}
.learn-btn {
width: 30%;
height: 60%;
background-color: #1a89fa;
color: #fff;
display: flex;
justify-content: center;
align-items: center;
font-size: 14px;
border-radius: 50rpx;
}
}
}
</style>