653 lines
16 KiB
Vue
653 lines
16 KiB
Vue
<template>
|
||
<view class="main_div max_page">
|
||
<view class="my-nav-bar"></view>
|
||
<view class="body-title">
|
||
<view class="back_div" @click="common.navigateBack()">
|
||
<view class="back-icon"></view>
|
||
</view>
|
||
<view>任务详情</view>
|
||
</view>
|
||
<view class="detail_div">
|
||
<view class="left">
|
||
<image-preview class="img" :src="detailData.ossAddr" mode="scaleToFill"></image-preview>
|
||
</view>
|
||
<view class="right">
|
||
<view class="title_div">
|
||
<view class="title">
|
||
{{ detailData.taskName }}
|
||
</view>
|
||
</view>
|
||
<view class="time">
|
||
<text class="color_3">起止时间:</text>
|
||
<text class="color_class">
|
||
{{ detailData.startTm?.substr(0, 10) }}至{{ detailData.endTm?.substr(0, 10) }}
|
||
</text>
|
||
<view class="fl1"></view>
|
||
<view class="num-item" @click="collect_click(detailData.collectionId)">
|
||
<image
|
||
v-if="detailData.collectionId"
|
||
class="collect-icon"
|
||
src="@/static/images/courseDetail/out_collect.png"
|
||
mode="widthFix"
|
||
></image>
|
||
<image
|
||
v-else
|
||
class="collect-icon"
|
||
src="@/static/images/courseDetail/in_collect.png"
|
||
mode="widthFix"
|
||
></image>
|
||
</view>
|
||
</view>
|
||
<view class="num_div">
|
||
<view class="num_div_item">
|
||
<text class="color_3">完成人数:</text>
|
||
<text class="color_2">{{ detailData.taskFinishSums ?? 0 }}/{{ detailData.taskSums ?? 0 }}</text>
|
||
</view>
|
||
<view class="num_div_item">
|
||
<text class="color_3">进度:</text>
|
||
<text class="color_2">{{ detailData.finishCrs ?? 0 }}/{{ detailData.sumCrs ?? 0 }}门课程</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="scroll-div">
|
||
<view class="paper_title_div">
|
||
<image src="@/static/images/testingHall/testing.png" class="img" mode="aspectFit"></image>
|
||
<view class="title">任务历程</view>
|
||
</view>
|
||
<scroll-view
|
||
ref="scrollRef"
|
||
:scroll-y="true"
|
||
class="scroll-Y"
|
||
:show-scrollbar="false"
|
||
@scrolltolower="scrolltolower"
|
||
>
|
||
<view class="item" v-for="item in data_list" @click="item_click(item)" :class="getStatusClass(item.status)">
|
||
<view class="progress_div">
|
||
<view class="circle_div"></view>
|
||
<view class="line_div"></view>
|
||
<view class="plug"></view>
|
||
</view>
|
||
<view class="content_div">
|
||
<view class="status_div">
|
||
<text v-if="item.status === '01'">进行中</text>
|
||
<text v-if="item.status === '02'">已完成</text>
|
||
<text v-if="item.status === '03'">未解锁</text>
|
||
</view>
|
||
<view class="main_body_div">
|
||
<view class="title">
|
||
{{ item.crsName }}
|
||
</view>
|
||
<view class="button_div">
|
||
<template
|
||
v-if="item.isFinishStudy === '01' && item.isFinishExam === '01' && item.status !== '02'"
|
||
>
|
||
<image class="img" :src="lockIcon('#999999')"></image>
|
||
<view class="button_text error">暂无通过条件,可自动解锁</view>
|
||
</template>
|
||
<template
|
||
v-if="item.isFinishStudy === '01' && item.isFinishExam === '01' && item.status === '02'"
|
||
>
|
||
<image class="img" :src="lockIcon('#0066FF')"></image>
|
||
<view class="button_text success">已自动解锁</view>
|
||
</template>
|
||
<template v-if="item.isFinishStudy !== '01'">
|
||
<image
|
||
class="img"
|
||
:src="passTheExamIcon(item.isFinishStudy === '02' ? '#0066FF' : '#999999')"
|
||
></image>
|
||
<view class="button_text" :class="item.isFinishStudy === '02' ? 'success' : 'error'">
|
||
完成学习
|
||
</view>
|
||
</template>
|
||
<template v-if="item.isFinishExam !== '01'">
|
||
<image
|
||
class="img"
|
||
:src="completeTheExercisesIcon(item.isFinishExam === '02' ? '#0066FF' : '#999999')"
|
||
></image>
|
||
<view class="button_text" :class="item.isFinishExam === '02' ? 'success' : 'error'">
|
||
通过考试
|
||
</view>
|
||
</template>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<list-no-data v-if="total === 0 && status === 'nomore'">暂无数据</list-no-data>
|
||
<uv-load-more
|
||
v-if="status === 'loading'"
|
||
:status="status"
|
||
loadmore-text="轻轻上拉加载"
|
||
:height="30"
|
||
></uv-load-more>
|
||
</scroll-view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { onLoad, onUnload } from '@dcloudio/uni-app';
|
||
import { ref, reactive, computed, nextTick } from 'vue';
|
||
import { queryAllTraTaskCrsInfo, queryTraTaskInfoByTaskId } from '@/api/learningTasks.js';
|
||
import { passTheExamIcon, completeTheExercisesIcon, lockIcon } from '@/common/imgSvg';
|
||
import { insertTraPersonalCollectionTask, deleteTraPersonalCollectionById } from '@/api/favorites.js';
|
||
import common from '@/common/common';
|
||
import { setPageCache, getPageCache } from '@/common/common';
|
||
const collectId = ref(''); // 记录初始的收藏id
|
||
const detailData = reactive({
|
||
taskId: '',
|
||
taskName: '',
|
||
collectionId: '',
|
||
taskFinishSums: '',
|
||
taskSums: '',
|
||
finishCrs: '',
|
||
sumCrs: ''
|
||
});
|
||
|
||
const total = ref(-1);
|
||
const status = ref('loading'); // loadmore - 加载前,loading - 加载中,nomore - 没有数据
|
||
const data_list = reactive([]);
|
||
const getStatusClass = (isFinish) => {
|
||
// 00进行中、01已完成、02已超时
|
||
if (isFinish === '01') return 'unfinished';
|
||
if (isFinish === '02') return 'completed';
|
||
return 'not_unlocked';
|
||
};
|
||
const getData = () => {
|
||
status.value = 'loading';
|
||
queryAllTraTaskCrsInfo({
|
||
taskId: detailData.taskId
|
||
})
|
||
.then((res) => {
|
||
data_list.length = 0;
|
||
data_list.push(...res.body);
|
||
})
|
||
.finally(() => {
|
||
total.value = data_list.length;
|
||
if (total.value === 0) {
|
||
status.value = 'nomore';
|
||
} else {
|
||
status.value = 'loadmore';
|
||
}
|
||
});
|
||
};
|
||
const scrolltolower = () => {};
|
||
|
||
const item_click = (item) => {
|
||
if (item.status === '03') {
|
||
common.msg('任务未解锁');
|
||
return;
|
||
}
|
||
common.navigateTo('/pages/courseDetail/index?crsId=' + item.crsId);
|
||
};
|
||
const collect_click = async (id) => {
|
||
try {
|
||
if (!id) {
|
||
common.loading('收藏中');
|
||
insertTraPersonalCollectionTask({
|
||
collectTyp: '02',
|
||
collectBusId: detailData.taskId
|
||
})
|
||
.then((res) => {
|
||
detailData.collectionId = res.body;
|
||
common.msg('收藏成功');
|
||
})
|
||
.catch(() => {
|
||
common.hideLoading();
|
||
});
|
||
} else {
|
||
common.loading('取消收藏中');
|
||
deleteTraPersonalCollectionById({
|
||
collectId: id
|
||
})
|
||
.then(() => {
|
||
detailData.collectionId = null;
|
||
common.msg('取消成功');
|
||
})
|
||
.catch(() => {
|
||
common.hideLoading();
|
||
});
|
||
}
|
||
} catch (e) {
|
||
common.hideLoading();
|
||
}
|
||
};
|
||
onLoad((e) => {
|
||
const learning_tasks_details = getPageCache('learning_tasks_details');
|
||
Object.assign(detailData, {
|
||
...learning_tasks_details
|
||
});
|
||
collectId.value = learning_tasks_details.collectionId || '';
|
||
getData();
|
||
const updateFun = () => {
|
||
setTimeout(() => {
|
||
console.log('详情监听里面学习完成后更新任务历程');
|
||
queryTraTaskInfoByTaskId({ taskId: detailData.taskId }).then(({ body }) => {
|
||
uni.$emit('refresh_tasks_data', body);
|
||
Object.assign(detailData, {
|
||
...body
|
||
});
|
||
});
|
||
getData();
|
||
}, 4000);
|
||
};
|
||
|
||
// 监听里面学习完成后更新任务历程,执行更新函数
|
||
uni.$on('refresh_course_list', () => updateFun());
|
||
// 监听考试完成事件,执行更新函数
|
||
uni.$on('exam_completed', () => updateFun());
|
||
});
|
||
onUnload(() => {
|
||
uni.$off('refresh_course_list');
|
||
uni.$off('exam_completed');
|
||
// 如果收藏变了,并且上一页是收藏页,更新收藏列表
|
||
if (detailData.collectionId !== collectId.value) {
|
||
const pages = getCurrentPages();
|
||
if (pages.length >= 2) {
|
||
const prevPage = pages[pages.length - 2];
|
||
if (prevPage.route === 'pages/favorites/index') {
|
||
// 收藏页跳入
|
||
uni.$emit('refresh_favorites_list', {
|
||
type: 'task',
|
||
state: !!detailData.collectionId, // 最终是收藏了还是取消了
|
||
old: collectId.value, // 进入时候的收藏id
|
||
new: detailData.collectionId // 新的收藏id
|
||
});
|
||
} else if (prevPage.route === 'pages/learningTasks/index') {
|
||
// 学习任务页跳入,更新外部列表否则下次列表数据还是老的
|
||
console.log('学习任务页跳入,更新外部列表否则下次列表数据还是老的');
|
||
uni.$emit('refresh_tasks_list', detailData);
|
||
}
|
||
}
|
||
}
|
||
});
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
$bg-margin-left: 30rpx;
|
||
|
||
.scroll-Y .item {
|
||
margin: 0 $bg-margin-left 0 $bg-margin-left;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
// 已完成
|
||
&.completed {
|
||
.circle_div {
|
||
border: 4rpx solid #bdc7e6;
|
||
background-color: #bdc7e6;
|
||
}
|
||
.line_div {
|
||
border-left: 4rpx solid #e1e8f0;
|
||
}
|
||
.status_div {
|
||
color: #adb4c3;
|
||
background-color: #f3f5f5;
|
||
}
|
||
.plug {
|
||
border-top: 4rpx solid #e1e8f0;
|
||
}
|
||
}
|
||
//未完成
|
||
&.unfinished {
|
||
.circle_div {
|
||
border: 4rpx solid #0066ff;
|
||
// background-color: #bdc7e6;
|
||
}
|
||
.line_div {
|
||
border-left: 4rpx solid #0066ff;
|
||
}
|
||
.status_div {
|
||
color: #ffffff;
|
||
background-color: #4c93ff;
|
||
}
|
||
.plug {
|
||
border-top: 4rpx solid #0066ff;
|
||
}
|
||
}
|
||
|
||
// 未解锁
|
||
&.not_unlocked {
|
||
.circle_div {
|
||
border: 4rpx solid #adb4c3;
|
||
}
|
||
.line_div {
|
||
border-left: 4rpx dashed #adb4c3;
|
||
}
|
||
.status_div {
|
||
color: #6c9ce4;
|
||
background-color: #eff6ff;
|
||
}
|
||
.plug {
|
||
border-top: 4rpx solid #adb4c3;
|
||
}
|
||
}
|
||
// 最后一项
|
||
&:last-child .plug {
|
||
width: 80%;
|
||
height: 40rpx;
|
||
margin-top: -6rpx;
|
||
}
|
||
.progress_div {
|
||
width: 30rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
flex-direction: column;
|
||
|
||
.circle_div {
|
||
width: 20rpx;
|
||
height: 20rpx;
|
||
border-radius: 50%;
|
||
overflow: hidden;
|
||
box-sizing: border-box;
|
||
}
|
||
.line_div {
|
||
height: calc(100% - 20rpx);
|
||
width: 4rpx;
|
||
margin: 6rpx 0;
|
||
}
|
||
}
|
||
.content_div {
|
||
flex: 1;
|
||
display: flex;
|
||
min-height: 140rpx;
|
||
background-color: #fff;
|
||
margin-bottom: 34rpx;
|
||
padding: 4rpx 4rpx 4rpx 4rpx;
|
||
// background-color: red;
|
||
border-radius: 16rpx;
|
||
overflow: hidden;
|
||
.status_div {
|
||
font-family: PingFangSC, PingFang SC;
|
||
font-weight: 400;
|
||
font-size: 30rpx;
|
||
writing-mode: vertical-rl;
|
||
border-radius: 12rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 4rpx 4rpx;
|
||
}
|
||
.main_body_div {
|
||
margin-left: 34rpx;
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
padding-right: 10rpx;
|
||
.title {
|
||
// background-color: red;
|
||
margin-top: 10rpx;
|
||
min-height: 30rpx;
|
||
flex: 1;
|
||
font-weight: 500;
|
||
font-size: 30rpx;
|
||
color: #333333;
|
||
line-height: 40rpx;
|
||
text-align: left;
|
||
font-style: normal;
|
||
}
|
||
.button_div {
|
||
// background-color: red;
|
||
|
||
height: 60rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
flex-wrap: nowrap;
|
||
.img {
|
||
width: 30rpx;
|
||
height: 30rpx;
|
||
}
|
||
.button_text {
|
||
font-weight: 400;
|
||
font-size: 24rpx;
|
||
|
||
text-align: left;
|
||
margin-right: 50rpx;
|
||
&.success {
|
||
color: #0066ff;
|
||
}
|
||
&.error {
|
||
color: #999999;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
.paper_title_div {
|
||
display: flex;
|
||
align-items: center;
|
||
margin: 20rpx 0 20rpx $bg-margin-left;
|
||
height: 42rpx;
|
||
.img {
|
||
width: 32rpx;
|
||
height: 28rpx;
|
||
}
|
||
|
||
.title {
|
||
font-weight: 600;
|
||
|
||
font-family: PingFangTC;
|
||
font-weight: 600;
|
||
font-size: 30rpx;
|
||
color: #333333;
|
||
font-style: normal;
|
||
margin-left: 12rpx;
|
||
}
|
||
}
|
||
.scroll-div {
|
||
background: linear-gradient(180deg, #ebf2fe 0%, #f3f7fe 6%, #f9fbff 12%, #f4f6f8 100%);
|
||
|
||
// background: linear-gradient(180deg, #ebf2fe 0%, #f3f7fe 6%, #fafbfc 12%, #fafbfc 100%);
|
||
border-radius: 16rpx;
|
||
margin-top: -20rpx;
|
||
z-index: 2;
|
||
box-shadow: 0 0 10rpx #f9fbff;
|
||
|
||
border: 2rpx solid #f9f9fa;
|
||
margin: 0 auto;
|
||
width: calc(100% - 52rpx);
|
||
}
|
||
.scroll-Y {
|
||
position: relative;
|
||
overflow: hidden;
|
||
height: calc(100vh - var(--status-bar-height) - 120rpx - 250rpx + 20rpx + 20rpx - 20rpx - 42rpx - 50rpx);
|
||
}
|
||
|
||
.main_div {
|
||
background-image: url('@/static/images/learningTasks/learningTasksBg.png');
|
||
background-repeat: no-repeat;
|
||
background-size: 100% calc(420rpx + var(--status-bar-height)); /* 宽度充满,高度自适应比例 */
|
||
background-position: top;
|
||
background-color: #fff;
|
||
}
|
||
.my-nav-bar {
|
||
width: 100%;
|
||
height: calc(var(--status-bar-height) - 10rpx);
|
||
}
|
||
.body-title {
|
||
width: 100%;
|
||
position: relative;
|
||
text-align: center;
|
||
height: 120rpx;
|
||
line-height: 60rpx;
|
||
font-family: PingFangSC;
|
||
font-weight: 600;
|
||
font-size: 32rpx;
|
||
color: #000000;
|
||
font-style: normal;
|
||
}
|
||
|
||
.detail_div {
|
||
margin-top: -20rpx;
|
||
height: 250rpx;
|
||
z-index: 2;
|
||
width: 100%;
|
||
padding: 36rpx 26rpx 20rpx 26rpx;
|
||
background-color: #ffffff;
|
||
border-radius: 16rpx 16rpx 0 0;
|
||
position: relative;
|
||
overflow: hidden;
|
||
display: flex;
|
||
|
||
.subscript {
|
||
position: absolute;
|
||
top: 0;
|
||
right: 0;
|
||
width: 102rpx;
|
||
height: 42rpx;
|
||
font-family: PingFangSC;
|
||
font-weight: 400;
|
||
font-size: 24rpx;
|
||
line-height: 42rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
border-radius: 0 0 0 28rpx;
|
||
}
|
||
.left > .img {
|
||
width: 225rpx;
|
||
height: 169rpx;
|
||
border-radius: 16rpx;
|
||
overflow: hidden;
|
||
}
|
||
.right {
|
||
overflow: hidden;
|
||
margin-left: 24rpx;
|
||
width: 100%;
|
||
.title_div {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
flex: 1;
|
||
|
||
.title {
|
||
font-family: PingFangSC;
|
||
font-weight: 600;
|
||
color: #000000;
|
||
text-align: left;
|
||
font-style: normal;
|
||
font-size: 28rpx; /* 字体大小30rpx */
|
||
display: -webkit-box; /* 启用弹性盒模型 */
|
||
-webkit-box-orient: vertical; /* 设置盒子内子元素的排列方向为垂直 */
|
||
-webkit-line-clamp: 2; /* 限制最多显示2行 */
|
||
overflow: hidden; /* 超出部分隐藏 */
|
||
text-overflow: ellipsis; /* 超出部分显示省略号(多行时可能不显示,但建议保留) */
|
||
line-height: 1.5; /* 可选:设置行高,优化多行显示效果 */
|
||
}
|
||
}
|
||
|
||
.time {
|
||
font-size: 22rpx;
|
||
color: #999999;
|
||
line-height: 30rpx;
|
||
font-family: Arial;
|
||
font-weight: 400;
|
||
color: #666666;
|
||
height: 54rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.num-item {
|
||
display: flex;
|
||
align-items: center;
|
||
font-size: 30rpx;
|
||
color: #666666;
|
||
|
||
.collect-icon {
|
||
width: 36rpx;
|
||
height: 36rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
.num_div {
|
||
font-family: PingFangSC;
|
||
font-weight: 400;
|
||
font-size: 22rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
flex-wrap: nowrap;
|
||
overflow: hidden;
|
||
height: 28rpx;
|
||
.num_div_item {
|
||
display: flex;
|
||
flex-wrap: nowrap;
|
||
line-height: 28rpx;
|
||
height: 28rpx;
|
||
}
|
||
}
|
||
|
||
.color_1 {
|
||
color: #d70c18;
|
||
}
|
||
|
||
.color_2 {
|
||
color: #111111;
|
||
}
|
||
|
||
.color_3 {
|
||
color: #666666;
|
||
}
|
||
}
|
||
}
|
||
|
||
.incomplete {
|
||
// 进行中
|
||
.subscript {
|
||
color: #ffffff;
|
||
background-color: #ef5705;
|
||
}
|
||
|
||
.color_class {
|
||
color: #d70c18;
|
||
}
|
||
}
|
||
|
||
.completed {
|
||
// 已完成
|
||
.subscript {
|
||
color: #ffffff;
|
||
background-color: #33c583;
|
||
}
|
||
|
||
.color_class {
|
||
color: #0066ff;
|
||
}
|
||
}
|
||
|
||
.back_div {
|
||
position: absolute;
|
||
left: 26rpx;
|
||
height: 100%;
|
||
top: -30rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.back-icon {
|
||
position: relative;
|
||
width: 50rpx;
|
||
height: 50rpx;
|
||
cursor: pointer;
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.back-icon::before,
|
||
.back-icon::after {
|
||
content: '';
|
||
position: absolute;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.back-icon::after {
|
||
top: 25%;
|
||
left: 25%;
|
||
width: 40%;
|
||
height: 40%;
|
||
border-top: 4rpx solid #000000;
|
||
border-left: 4rpx solid #000000;
|
||
transform: rotate(-45deg);
|
||
}
|
||
}
|
||
</style>
|