661 lines
16 KiB
Vue
661 lines
16 KiB
Vue
<template>
|
|
<view class="study-analytics max_page">
|
|
<view class="cont-body">
|
|
<view class="top-box">
|
|
<view class="top-title">
|
|
<view class="back-icon" @click="common.navigateBack()"></view>
|
|
</view>
|
|
</view>
|
|
<!-- <view class="analytics-box loading-box-cont" v-if="loading">
|
|
<CommonLoading color="#06f" class="loading-box" />
|
|
</view> -->
|
|
<view :class="['analytics-box', loading?'loading-box-cont':'']" >
|
|
<CommonLoading color="#06f" class="loading-box" v-if="loading"/>
|
|
<view class="tabs-box">
|
|
<uv-tabs :list="tabList" @click="changeTab" :scrollable="true" active-style="font-weight:bold; color:#000;"
|
|
:current="currentTab" class="font_pf my_tabs"
|
|
:inactive-style="{ color: '#333333', fontSize: '28rpx', fontWeight: '500' }"
|
|
:activeStyle="{ color: '#333333', fontSize: '28rpx', fontWeight: '600' }"></uv-tabs>
|
|
</view>
|
|
<!-- <view class="calendar-box" @click="openCalendar">统计周期</view>
|
|
<uv-calendar ref="calendarRef" mode="range" @confirm="calendarConfirm" minDate="2025-01-01" :maxDate="maxDate" monthNum="100" :allowSameDay="true"></uv-calendar> -->
|
|
<view class="date-input" v-show="activeTabVal === '04'">
|
|
<uni-datetime-picker class="custom-datepicker" ref="dateinputRef" type="daterange" v-model="daterange"
|
|
start="2025-01-01" :end="maxDate" rangeSeparator="至" @change="changeDate"></uni-datetime-picker>
|
|
</view>
|
|
<view class="analytics-items">
|
|
<view class="analytics-item">
|
|
<view class="analytics-item-title">
|
|
课程学习时长
|
|
</view>
|
|
<view class="analytics-item-value">
|
|
<text class="analytics-item-value-v">{{statisticsObj.crsStdyTmLen }}</text>
|
|
<text class="analytics-item-value-unit">h</text>
|
|
</view>
|
|
</view>
|
|
<view class="analytics-item">
|
|
<view class="analytics-item-title">
|
|
完成课程数
|
|
</view>
|
|
<view class="analytics-item-value">
|
|
<text class="analytics-item-value-v">{{statisticsObj.completeCrsCnt }}</text>
|
|
<text class="analytics-item-value-unit"></text>
|
|
</view>
|
|
</view>
|
|
<view class="analytics-item">
|
|
<view class="analytics-item-title">
|
|
课程完成率
|
|
</view>
|
|
<view class="analytics-item-value">
|
|
<text class="analytics-item-value-v">{{statisticsObj.crsCompleteRate }}</text>
|
|
<text class="analytics-item-value-unit">%</text>
|
|
</view>
|
|
</view>
|
|
<view class="analytics-item">
|
|
<view class="analytics-item-title">
|
|
完成任务数
|
|
</view>
|
|
<view class="analytics-item-value">
|
|
<text class="analytics-item-value-v">{{statisticsObj.completeTaskCnt }}</text>
|
|
<text class="analytics-item-value-unit"></text>
|
|
</view>
|
|
</view>
|
|
<view class="analytics-item">
|
|
<view class="analytics-item-title">
|
|
完成考试数
|
|
</view>
|
|
<view class="analytics-item-value">
|
|
<text class="analytics-item-value-v">{{statisticsObj.completedExamCnt }}</text>
|
|
<text class="analytics-item-value-unit"></text>
|
|
</view>
|
|
</view>
|
|
<view class="analytics-item">
|
|
<view class="analytics-item-title">
|
|
考试及格率
|
|
</view>
|
|
<view class="analytics-item-value">
|
|
<text class="analytics-item-value-v">{{statisticsObj.passExamRate }}</text>
|
|
<text class="analytics-item-value-unit">%</text>
|
|
</view>
|
|
</view>
|
|
<view class="analytics-item">
|
|
<view class="analytics-item-title">
|
|
问答次数
|
|
</view>
|
|
<view class="analytics-item-value">
|
|
<text class="analytics-item-value-v">{{statisticsObj.askCnt }}</text>
|
|
<text class="analytics-item-value-unit">次</text>
|
|
</view>
|
|
</view>
|
|
<view class="analytics-item">
|
|
<view class="analytics-item-title">
|
|
陪练次数
|
|
</view>
|
|
<view class="analytics-item-value">
|
|
<text class="analytics-item-value-v">{{statisticsObj.partnerCnt }}</text>
|
|
<text class="analytics-item-value-unit">次</text>
|
|
</view>
|
|
</view>
|
|
<view class="analytics-item">
|
|
<view class="analytics-item-title">
|
|
陪练通过率
|
|
</view>
|
|
<view class="analytics-item-value">
|
|
<text class="analytics-item-value-v">{{statisticsObj.partnerRate }}</text>
|
|
<text class="analytics-item-value-unit">%</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view class="evaluation-box dens" v-if="loading">
|
|
<CommonLoading color="#06f" class="loading-box" />
|
|
</view>
|
|
<view class="evaluation-box dens" v-if="!loading">
|
|
<view class="dens-item" v-for="(item, index) in dimesionList">
|
|
<view :class="['item-title', index%2===0?'study1-tip': 'study2-tip']">{{item.title}}</view>
|
|
<view :class="['item-cont ', index%2===0?'study1-bg': 'study2-bg']">{{item.content}}</view>
|
|
</view>
|
|
</view>
|
|
<view class="evaluation-box study" v-if="loading">
|
|
<CommonLoading color="#06f" class="loading-box" />
|
|
</view>
|
|
<view class="evaluation-box study" v-if="!loading">
|
|
<view class="study-item" v-for="(item, index) in studyList">
|
|
<view :class="['item-title', index%2===0?'study1-tip': 'study2-tip']">{{item.title}}</view>
|
|
<view :class="['item-cont ', index%2===0?'study1-bg': 'study2-bg']">{{item.content}}</view>
|
|
</view>
|
|
</view>
|
|
<view class="evaluation-box study1" v-if="loading">
|
|
<CommonLoading color="#06f" class="loading-box" />
|
|
</view>
|
|
<view class="evaluation-box study1" v-if="!loading">
|
|
<view class="study1-item">
|
|
<view class="item-cont study3-bg">{{suggestObj.content}}</view>
|
|
</view>
|
|
</view>
|
|
<view class="evaluation-box course" v-if="loading">
|
|
<CommonLoading color="#06f" class="loading-box" />
|
|
</view>
|
|
<view class="evaluation-box course" v-if="!loading">
|
|
<CourseItem v-for="item in courseList" :itemInfo="item" @clickItem="toCourseDetail(item)" />
|
|
<view class="empty-box" v-if="courseList.length === 0">暂无数据</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
import common from '@/common/common'
|
|
import {
|
|
queryStudyStatistics,
|
|
queryRecmdCrsInfo,
|
|
queryDimesionInfo,
|
|
queryHabitInfo,
|
|
querySuggestInfo,
|
|
} from '@/api/analytics.js'
|
|
import {
|
|
onMounted,
|
|
ref,
|
|
computed,
|
|
} from 'vue'
|
|
import CourseItem from '@/components/course-item/course-item.vue'
|
|
const tabList = ref([{
|
|
name: '本月',
|
|
value: '01'
|
|
},
|
|
{
|
|
name: '本年',
|
|
value: '02'
|
|
},
|
|
{
|
|
name: '累计',
|
|
value: '03'
|
|
},
|
|
{
|
|
name: '自定义',
|
|
value: '04'
|
|
}
|
|
])
|
|
const courseList = ref([])
|
|
const currentTab = ref(0)
|
|
const activeTabVal = ref('01')
|
|
const daterange = ref(['', ''])
|
|
const dateinputRef = ref()
|
|
const maxDate = computed(() => {
|
|
let _date = new Date()
|
|
let _year = _date.getFullYear()
|
|
let _month = _date.getMonth() + 1
|
|
let _day = new Date(_year, _month, 0).getDate()
|
|
return `${_year}-${_month < 10 ? '0' + _month: _month}-${_day < 10 ? '0' + _day: _day}`
|
|
})
|
|
const calendarRef = ref()
|
|
const statisticsObj = ref({
|
|
crsStdyTmLen: 0,
|
|
completeTaskCnt: 0,
|
|
completedExamCnt: 0,
|
|
passExamRate: 0,
|
|
partnerCnt: 0,
|
|
askCnt: 0,
|
|
completeCrsCnt: 0,
|
|
crsCompleteRate: 0,
|
|
partnerRate: 0
|
|
})
|
|
const dimesionList = ref([])
|
|
const studyList = ref([])
|
|
const suggestObj = ref({
|
|
content: ''
|
|
})
|
|
|
|
// const openCalendar = () => {
|
|
// calendarRef.value.open()
|
|
// }
|
|
// const calendarConfirm = (data) => {
|
|
// console.log('data:', data)
|
|
// currentTab.value = -1
|
|
// }
|
|
const changeDate = (date) => {
|
|
if (date.length > 0) {
|
|
if (!!date[0]) {
|
|
getInfoNow({
|
|
dateType: '04',
|
|
startDate: date[0],
|
|
endDate: date[1],
|
|
})
|
|
}
|
|
}
|
|
}
|
|
const loading = ref(false)
|
|
const getInfoNow = async (params) => {
|
|
loading.value = true
|
|
try {
|
|
let _res1 = await queryStudyStatistics(params)
|
|
statisticsObj.value = {
|
|
..._res1.body
|
|
}
|
|
let _res2 = await queryDimesionInfo(params)
|
|
dimesionList.value = [..._res2.body]
|
|
let _res3 = await queryHabitInfo(params)
|
|
studyList.value = [..._res3.body]
|
|
let _res4 = await querySuggestInfo(params)
|
|
if (_res4.body && _res4.body.length > 0) {
|
|
suggestObj.value = {
|
|
..._res4.body[0]
|
|
}
|
|
}
|
|
} catch {} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
// 跳转 课程详情
|
|
const toCourseDetail = item => {
|
|
common.navigateTo('/pages/courseDetail/index?crsNum=' + item.crsNum + '&crsId=' + item.crsId)
|
|
}
|
|
const changeTab = (info) => {
|
|
activeTabVal.value = info.value
|
|
if (info.value === '04') {
|
|
dateinputRef.value && dateinputRef.value?.clear()
|
|
daterange.value = ['', '']
|
|
} else {
|
|
getInfoNow({
|
|
dateType: activeTabVal.value
|
|
})
|
|
}
|
|
}
|
|
|
|
const getCrsListNow = () => {
|
|
queryRecmdCrsInfo().then(res => {
|
|
console.log(res)
|
|
courseList.value = res.body || []
|
|
})
|
|
}
|
|
onMounted(() => {
|
|
getCrsListNow()
|
|
getInfoNow({
|
|
dateType: activeTabVal.value
|
|
})
|
|
})
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.my_tabs {
|
|
|
|
// 解决这个圆角的图片,开穿透
|
|
:deep(.uv-tabs__wrapper__nav__line) {
|
|
background: linear-gradient(90deg, #06f 0%, rgb(0, 159, 255) 50%, rgb(255, 255, 255) 100%) !important;
|
|
}
|
|
|
|
:deep(.uv-tabs__wrapper__nav__item) {
|
|
padding: 0 30rpx !important;
|
|
}
|
|
}
|
|
|
|
.study-analytics {
|
|
position: relative;
|
|
background-color: #ddeafa;
|
|
|
|
.cont-body {
|
|
position: absolute;
|
|
width: 100vw;
|
|
height: 100vh;
|
|
padding: var(--status-bar-height) 20rpx 24rpx;
|
|
// padding: 280rpx 20rpx 24rpx;
|
|
overflow-x: hidden;
|
|
overflow-y: auto;
|
|
box-sizing: border-box;
|
|
background-image: url(@/static/images/analytics/bg1.png);
|
|
background-repeat: no-repeat;
|
|
background-size: 100% auto;
|
|
background-position: top center;
|
|
background-attachment: local;
|
|
|
|
|
|
.top-box {
|
|
height: 280rpx;
|
|
width: 100%;
|
|
// position: fixed;
|
|
// float: left;
|
|
// margin-top: var(--status-bar-height);
|
|
|
|
.top-title {
|
|
height: 90rpx;
|
|
// background-color: red;
|
|
text-align: center;
|
|
font-size: 33rpx;
|
|
padding: 10rpx 0rpx 0;
|
|
line-height: 46rpx;
|
|
box-sizing: border-box;
|
|
font-weight: 500;
|
|
color: #000;
|
|
position: relative;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
|
|
.back-icon {
|
|
position: absolute;
|
|
width: 40rpx;
|
|
height: 40rpx;
|
|
cursor: pointer;
|
|
left: 30rpx;
|
|
top: 33rpx;
|
|
transform: translateY(-50%);
|
|
}
|
|
|
|
.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 #000;
|
|
border-left: 4rpx solid #000;
|
|
transform: rotate(-45deg);
|
|
}
|
|
}
|
|
}
|
|
|
|
.analytics-box {
|
|
min-height: 490rpx;
|
|
border-radius: 15rpx;
|
|
// overflow: hidden;
|
|
background: url(@/static/images/analytics/bg2.png) no-repeat;
|
|
background-size: cover;
|
|
background-position: center;
|
|
position: relative;
|
|
margin-bottom: 24rpx;
|
|
backdrop-filter: blur(10rpx);
|
|
overflow: hidden;
|
|
z-index: 1;
|
|
&.loading-box-cont::before{
|
|
content: '';
|
|
display: block;
|
|
position: absolute;
|
|
width: 100% ;
|
|
height: 100%;
|
|
z-index: 2;
|
|
background: #ffffffee;
|
|
backdrop-filter: blur(50rpx);
|
|
}
|
|
.loading-box {
|
|
position: absolute;
|
|
z-index: 3;
|
|
top: 120rpx;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
}
|
|
|
|
.calendar-box {
|
|
position: absolute;
|
|
right: 25rpx;
|
|
top: 25rpx;
|
|
color: #06f;
|
|
padding-left: 40rpx;
|
|
background: url(@/static/images/analytics/date-icon.png) no-repeat;
|
|
background-size: 30rpx 30rpx;
|
|
background-position: left center;
|
|
font-size: 29rpx;
|
|
}
|
|
|
|
.tabs-box {
|
|
width: 600rpx;
|
|
}
|
|
|
|
.analytics-items {
|
|
padding-top: 20rpx;
|
|
padding-bottom: 20rpx;
|
|
width: 100%;
|
|
overflow: hidden;
|
|
position: relative;
|
|
|
|
.analytics-item {
|
|
padding-bottom: 12rpx;
|
|
box-sizing: border-box;
|
|
width: 33.3%;
|
|
float: left;
|
|
text-align: center;
|
|
height: 128rpx;
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: space-around;
|
|
|
|
&-title {
|
|
font-size: 25rpx;
|
|
color: #666;
|
|
}
|
|
|
|
&-value {
|
|
font-size: 54rpx;
|
|
font-weight: 600;
|
|
|
|
&-v {
|
|
font-family: DINAlternate, DINAlternate;
|
|
}
|
|
|
|
&-unit {
|
|
font-size: 28rpx;
|
|
margin-left: 8rpx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.evaluation-box {
|
|
background-color: rgba(255, 255, 255, .8);
|
|
background-repeat: no-repeat;
|
|
background-size: auto 78rpx;
|
|
background-position: 26rpx 26rpx;
|
|
padding: 80rpx 26rpx 24rpx;
|
|
border-radius: 15rpx;
|
|
margin-bottom: 24rpx;
|
|
position: relative;
|
|
min-height: 200rpx;
|
|
|
|
.loading-box {
|
|
position: absolute;
|
|
top: 120rpx;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
}
|
|
|
|
&::before {
|
|
content: '';
|
|
display: block;
|
|
position: absolute;
|
|
width: 208rpx;
|
|
height: 76rpx;
|
|
position: absolute;
|
|
left: -7rpx;
|
|
top: -12rpx;
|
|
background-size: cover;
|
|
}
|
|
|
|
&.dens {
|
|
&::before {
|
|
background-image: url(@/static/images/analytics/weidu-1.png);
|
|
}
|
|
}
|
|
|
|
&.study {
|
|
&::before {
|
|
background-image: url(@/static/images/analytics/study1-1.png)
|
|
}
|
|
}
|
|
|
|
&.study1 {
|
|
&::before {
|
|
background-image: url(@/static/images/analytics/study-1.png);
|
|
}
|
|
}
|
|
|
|
&.course {
|
|
&::before {
|
|
background-image: url(@/static/images/analytics/course-1.png);
|
|
}
|
|
}
|
|
|
|
// .dens-item {
|
|
// padding: 23rpx 0;
|
|
// .item-title{
|
|
// line-height: 40rpx;
|
|
// position: relative;
|
|
// padding: 8rpx 46rpx 8rpx 26rpx;
|
|
// line-height: 42rpx;
|
|
// font-size: 29rpx;
|
|
// margin-bottom: 16rpx;
|
|
// &::before{
|
|
// content: '';
|
|
// display: block;
|
|
// background-color: #000;
|
|
// width: 12rpx;
|
|
// height: 12rpx;
|
|
// border-radius: 50%;
|
|
// position: absolute;
|
|
// left: 0rpx;
|
|
// top: 22rpx;
|
|
// }
|
|
// }
|
|
|
|
// .item-cont {
|
|
// font-size: 28rpx;
|
|
// line-height: 50rpx;
|
|
// }
|
|
// }
|
|
|
|
.study-item,
|
|
.study1-item,
|
|
.dens-item {
|
|
padding: 12rpx 0;
|
|
|
|
.item-title {
|
|
line-height: 40rpx;
|
|
position: relative;
|
|
padding: 8rpx 46rpx 8rpx 40rpx;
|
|
line-height: 42rpx;
|
|
font-size: 29rpx;
|
|
margin-bottom: 16rpx;
|
|
|
|
&::before {
|
|
content: '';
|
|
display: block;
|
|
// background-color: #000;
|
|
width: 28rpx;
|
|
height: 28rpx;
|
|
// border-radius: 50%;
|
|
position: absolute;
|
|
left: 0rpx;
|
|
top: 14rpx;
|
|
background-image: url(@/static/images/analytics/den-tips.png);
|
|
background-repeat: no-repeat;
|
|
background-size: 100% 100%;
|
|
}
|
|
|
|
&.study2-tip {
|
|
&::before {
|
|
background-image: url(@/static/images/analytics/den-tips2.png);
|
|
}
|
|
}
|
|
|
|
&.bg-tm {
|
|
padding-left: 54rpx;
|
|
background-image: url(@/static/images/analytics/time-icon.png);
|
|
background-repeat: no-repeat;
|
|
background-size: 38rpx 40rpx;
|
|
background-position: left center;
|
|
|
|
&::before {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
&.bg-know {
|
|
padding-left: 54rpx;
|
|
background-image: url(@/static/images/analytics/knowledge.png);
|
|
background-repeat: no-repeat;
|
|
background-size: 38rpx 40rpx;
|
|
background-position: left center;
|
|
|
|
&::before {
|
|
display: none;
|
|
}
|
|
}
|
|
}
|
|
|
|
.item-cont {
|
|
font-size: 28rpx;
|
|
line-height: 50rpx;
|
|
|
|
&.study1-bg {
|
|
background-color: #e4efff;
|
|
border-radius: 15rpx;
|
|
padding: 12rpx 24rpx;
|
|
// width: calc(100% - 54rpx);
|
|
// margin-left: 54rpx;
|
|
}
|
|
|
|
&.study2-bg {
|
|
background-color: #f6f0df;
|
|
border-radius: 15rpx;
|
|
padding: 12rpx 24rpx;
|
|
// width: calc(100% - 54rpx);
|
|
// margin-left: 54rpx;
|
|
}
|
|
|
|
&.study3-bg {
|
|
background-color: #e4efff;
|
|
border-radius: 15rpx;
|
|
padding: 12rpx 24rpx;
|
|
// width: calc(100% - 54rpx);
|
|
// margin-left: 54rpx;
|
|
}
|
|
}
|
|
}
|
|
|
|
.empty-box {
|
|
text-align: center;
|
|
font-size: 25rpx;
|
|
color: #ccc;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.date-input {
|
|
.custom-datepicker {
|
|
width: 500rpx;
|
|
position: relative;
|
|
|
|
&::after {
|
|
content: '';
|
|
position: absolute;
|
|
top: 50%;
|
|
right: 0;
|
|
width: 10rpx;
|
|
height: 10rpx;
|
|
border-top: 3rpx solid #999;
|
|
border-left: 3rpx solid #999;
|
|
transform: rotate(135deg) translateY(50%);
|
|
}
|
|
|
|
::v-deep .uni-date-x {
|
|
background-color: rgba(255, 255, 255, 0);
|
|
width: 500rpx;
|
|
}
|
|
|
|
::v-deep .uni-date-x--border {
|
|
border: 0;
|
|
width: 500rpx;
|
|
}
|
|
|
|
::v-deep .range-separator {
|
|
font-size: 13px;
|
|
}
|
|
}
|
|
}
|
|
</style> |