Files
tra-app/src/pages/index/components/class_scroll.vue
T

328 lines
7.6 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="module_title_div">
<view class="icon icon_1">
<image class="img" :src="icon"></image>
</view>
<view class="text font_pf">{{ title }}</view>
</view>
<!-- 热门课程 -->
<view class="hot_class_div">
<view class="no-data-style" v-if="class_list.length === 0">暂无数据...</view>
<scroll-view class="scroll-view" :scroll-x="true" :show-scrollbar="false">
<view class="scroll-view-item" v-for="(item, index) in class_list" :key="index">
<!-- 角标 -->
<view class="icon" v-if="item.type">
<image class="img_100" :src="item.type === '00' ? kcIcon : plIcon" mode="widthFix" />
</view>
<view class="item_div">
<uv-skeletons :loading="!item.id" avatar avatar-shape="square" :title="false" :skeleton="skeleton">
<view class="item" @click="goto_course_detail(item)">
<view class="title ellipsis-text">
{{ item.name || '' }}
</view>
<view class="content">
<view class="left">
<view class="img-div">
<image-preview
class="img-box img"
:imgId="item.ossKey"
:isCache="true"
:width="240"
:height="160"
></image-preview>
</view>
<view class="subscript" v-if="item.evalGrade && item.type === '00'">{{item.evalGrade}}</view>
</view>
<view class="right">
<view class="note ellipsis-text">更新{{ (item.mtTime || '').substr(0, 10) }}</view>
<view class="note ellipsis-text">{{ item.type === '00' ? '已学' : '已练' }}{{ item.accmCnt }}</view>
<view class="button_div">
<view class="button">{{ item.type === '00' ? '去学习' : '去陪练' }}</view>
</view>
</view>
</view>
</view>
</uv-skeletons>
</view>
</view>
</scroll-view>
</view>
</template>
<script setup>
import { ref } from 'vue';
import { queryCrsInfoByRecmd, queryNewPolicyNewProducts } from '@/api/index.js';
import common from '@/common/common';
import hostIcon from '@/static/images/index/hot.png';
import recommendIcon from '@/static/images/index/recommend.png';
import newIcon from '@/static/images/index/new.png';
import kcIcon from '@/static/images/index/kc_icon.png';
import plIcon from '@/static/images/index/pl_icon.png';
const props = defineProps({
name: {
type: String
}
});
const getConfigByProps = () => {
if (props.name === 'recommend_class') {
return {
fetchFunction: queryCrsInfoByRecmd,
title: '精选推荐',
icon: recommendIcon
};
} else if (props.name === 'new_class') {
return {
fetchFunction: queryNewPolicyNewProducts,
title: '新政新品',
icon: newIcon
};
}
};
const { fetchFunction, title, icon } = getConfigByProps(); // 调用函数,获取返回对象后解构
const init_class_data = [
{
id: '',
ossKey: '',
nama: '',
mtTime: '',
accmCnt: ''
},
{
id: '',
img: '',
nama: '',
mtTime: '',
accmCnt: ''
}
];
const class_list = ref([]);
const skeleton = [
{
type: 'line',
num: 1,
style: 'marginBottom:20rpx;'
},
{
type: 'flex',
num: 1,
children: [
{
type: 'avatar',
num: 1,
style: 'marginRight: 22rpx;width: 256rpx;height:144rpx;border-radius:16rpx;'
},
{
type: 'line',
num: 3,
style: ['width: 240rpx;']
}
]
}
];
const get_data = () => {
class_list.value = [...init_class_data];
fetchFunction().then((res) => {
class_list.value = res.body;
});
};
// 进入课程详情页
const goto_course_detail = ({ id, type }) => {
// 00课程 01陪练
if (type === '00') {
common.navigateTo('/pages/courseDetail/index?crsId=' + id);
} else if (type === '01') {
common.navigateTo('/pages/sparring/detail?traId=' + id);
}
};
defineExpose({ get_data });
</script>
<style lang="scss" scoped>
$bg-margin-left: 30rpx;
// 设置骨架屏左侧图片框的大小,设置成和图片大小一致,否则横向滑动会串行(对不齐)
// 热门课程等三个横向滑动模块的样式
.hot_class_div {
margin-left: $bg-margin-left;
.no-data-style {
text-align: center;
line-height: 80rpx;
min-height: 80rpx;
color: #666666;
font-size: 30rpx;
}
.scroll-view {
white-space: nowrap;
width: 100%;
}
.scroll-view-item {
display: inline-block;
margin-right: 30rpx;
background-color: #ffffff;
border-radius: 22rpx;
box-shadow: #eaeaea 0 0 6rpx;
padding: 20rpx 20rpx 26rpx 34rpx;
position: relative;
overflow: hidden;
.icon {
position: absolute;
right: 0;
top: 0;
width: 76rpx;
height: 76rpx;
}
}
.item_div {
// width: calc(562rpx + 56rpx);
width: 562rpx;
}
.item {
display: flex;
width: 562rpx;
flex-direction: column;
.title {
font-weight: 500;
font-size: 30rpx;
color: #333333;
margin-bottom: 10rpx;
padding-right: 30rpx;
width: 100%;
}
.content {
display: flex;
.left {
position: relative;
.img-div {
border-radius: 16rpx;
overflow: hidden;
width: 256rpx;
height: 144rpx;
.img {
width: 256rpx;
height: 144rpx;
}
}
.subscript {
width: 70rpx;
height: 30rpx;
position: absolute;
right: -6rpx;
top: 20rpx;
text-align: center;
line-height: 30rpx;
font-size: 22rpx;
background-color: #ff7227;
font-family: Arial, Arial;
font-weight: 700;
color: #ffffff;
font-style: normal;
border-radius: 4rpx 0px 0px 4rpx;
z-index: 2;
}
/* 伪元素实现右下角黑色三角形 */
.subscript::after {
z-index: 1;
content: ''; /* 伪元素必须有content,空值即可 */
position: absolute; /* 绝对定位 */
right: 0; /* 靠右 */
bottom: -6rpx; /* 靠下 */
/* 核心:用边框实现三角形(宽高为0,只显示边框) */
width: 0;
height: 0;
border-top: 4rpx solid #000; /* 上边框透明 */
border-left: 4rpx solid #000; /* 左边框透明 */
border-bottom: 4rpx solid transparent; /* 下边框黑色(三角形的垂直边) */
border-right: 4rpx solid transparent; /* 右边框黑色(三角形的水平边) */
/* 可选:消除伪元素的点击事件 */
pointer-events: none;
}
}
.right {
overflow: hidden;
flex: 1;
padding-left: 16rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
.note {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 23rpx;
color: #666666;
line-height: 33rpx;
text-align: left;
font-style: normal;
}
.button_div {
display: flex;
justify-content: flex-end;
.button {
text-align: center;
line-height: 62rpx;
width: 138rpx;
height: 62rpx;
background: #ebf1ff;
border-radius: 30rpx;
font-weight: 500;
font-size: 30rpx;
color: #0066ff;
font-style: normal;
margin-right: 10rpx;
}
}
}
}
}
}
.module_title_div {
display: flex;
margin: 20rpx $bg-margin-left;
align-items: center;
.icon {
margin-right: 8rpx;
margin-top: 12rpx;
}
.icon_1 {
.img {
width: 31rpx;
height: 36rpx;
}
}
.icon_2 {
margin-top: 10rpx;
.img {
width: 38rpx;
height: 38rpx;
}
}
.icon_3 {
// margin-top: 10rpx;
.img {
width: 38rpx;
height: 31rpx;
}
}
.title {
font-size: 34rpx;
color: #323e57;
font-weight: 700;
line-height: 46rpx;
text-align: left;
}
}
</style>