You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
487 lines
13 KiB
487 lines
13 KiB
10 months ago
|
<template>
|
||
|
<BaseContainer class="goodsClass" :fixedNav="false" flex>
|
||
|
<view class="header" >
|
||
|
<view class="search acea-row row-middle"
|
||
|
:style="'margin-top:' + menutop+ 'px;'"
|
||
|
>
|
||
|
|
||
|
<view class="form">
|
||
|
<view class="label">
|
||
|
<image class="img" :src="getImgPath('/wap/first/zsff/images/search.png')" />
|
||
|
<input class="input" @confirm="goSearch" v-model="search" placeholder="搜索课程" />
|
||
|
</view>
|
||
|
<view class="submit" @click="goSearch">搜索</view>
|
||
|
</view>
|
||
|
</view>
|
||
|
<scroll-view scroll-x v-if="gradeCate.length" :scroll-into-view="gradeScrollIdx">
|
||
|
<view class="grade-cate-list flex" @click="handleGradeClick">
|
||
|
<view class="grade-item" :id="`grade${idx}`" v-for="(item, idx) of gradeCate" :key="item.id"
|
||
|
:data-id="item.id" :class="{ cur: item.id == gradeId }">
|
||
|
{{ item.name }}
|
||
|
</view>
|
||
|
</view>
|
||
|
</scroll-view>
|
||
|
<scroll-view scroll-x v-if="subjectCate.length" class="nav" :scroll-into-view="subjectScrollIdx">
|
||
|
<view class="flex">
|
||
|
<view :id="`subject${idx}`" v-for="(item, idx) in subjectCate" :key="item.id" :data-id="item.id"
|
||
|
:class="{ cur: item.id == subjectId }" @click="handleSubjectClick" class="item">
|
||
|
<view class="box" :data-id="item.id">
|
||
|
<view class="name" :data-id="item.id" :class="item.id == subjectId ? '' : 'on'">{{ item.name }}</view>
|
||
|
</view>
|
||
|
</view>
|
||
|
</view>
|
||
|
</scroll-view>
|
||
|
</view>
|
||
|
|
||
|
|
||
|
|
||
|
<view class="flex-auto pos">
|
||
|
<scroll-view scroll-y class="abs full" @scrolltolower="getSpecialList">
|
||
|
<view class="public_list goodList" v-if="updateSpecialList.length">
|
||
|
<view @click="handleSpecialClick(item)" v-for="item in updateSpecialList" :key="item.id"
|
||
|
class="item acea-row">
|
||
|
<view class="pictrue">
|
||
|
<image :src="item.image" mode="aspectFill" :alt="item.title" />
|
||
|
<view class="label">{{ item.special_type }}</view>
|
||
|
</view>
|
||
|
<view class="text">
|
||
|
<view class="title acea-row row-middle">
|
||
|
<view class="name line1">{{ item.title }}</view>
|
||
|
</view>
|
||
|
<view class="labelList">
|
||
|
<text class="labelItem" :key="index" v-for="(label, index) in item.label">{{ label }}</text>
|
||
|
</view>
|
||
|
<view class="acea-row row-middle row-between">
|
||
|
<view>
|
||
|
<view class="money" v-if="item.money > 0">
|
||
|
¥<text>{{ item.money }}</text>
|
||
|
</view>
|
||
|
<view class="free" v-else>免费</view>
|
||
|
<text v-if="!item.is_light && item.type != 4" class="total">共{{ item.count }}节</text>
|
||
|
</view>
|
||
|
<view class="num">{{ item.browse_count }}人已学习</view>
|
||
|
</view>
|
||
|
</view>
|
||
|
</view>
|
||
|
<view class="col-12"></view>
|
||
|
</view>
|
||
|
<view v-if="loadend && !specialList.length">
|
||
|
<image class="nothing" :src="getImgPath('/wap/first/zsff/images/no_data_available.png')" />
|
||
|
</view>
|
||
|
<view v-else class="loading-line" >
|
||
|
<text v-if="loading" class="fa fa-spinner loadingpic" style="font-size: 40rpx"></text>
|
||
|
<text>{{ loadTitle || "加载更多" }}</text>
|
||
|
</view>
|
||
|
<view style="height: var(--tab-bar-height)"></view>
|
||
|
</scroll-view>
|
||
|
</view>
|
||
|
</BaseContainer>
|
||
|
</template>
|
||
|
|
||
|
<script>
|
||
|
import { getCateList, getLogoConfig, getSpecialList } from "@/api/special";
|
||
|
const app = getApp();
|
||
|
export default {
|
||
|
data() {
|
||
|
return {
|
||
|
homeLogo: null,
|
||
|
gradeScrollIdx: "",
|
||
|
subjectScrollIdx: "",
|
||
|
specialType: {
|
||
|
1: "图文",
|
||
|
2: "音频",
|
||
|
3: "视频",
|
||
|
4: "直播",
|
||
|
5: "专栏",
|
||
|
6: "其他",
|
||
|
},
|
||
|
|
||
|
cate_id: 0,
|
||
|
subject_id: 0,
|
||
|
|
||
|
gradeCate: [],
|
||
|
subjectCate: [],
|
||
|
specialList: [],
|
||
|
gradeId: -1,
|
||
|
subjectId: -1,
|
||
|
search: "",
|
||
|
loadTitle: "",
|
||
|
page: 1,
|
||
|
limit: 10,
|
||
|
loading: false,
|
||
|
loadend: false,
|
||
|
count: 0,
|
||
|
menutop:20
|
||
|
};
|
||
|
},
|
||
|
onLoad({ cate_id = 0, subject_id = 0 }) {
|
||
|
this.cate_id = cate_id;
|
||
|
this.subject_id = subject_id;
|
||
|
this.getLogoConfig();
|
||
|
this.getCateList();
|
||
|
let menuButtonInfo = uni.getMenuButtonBoundingClientRect()
|
||
|
/* #ifdef MP-WEIXIN || MP-KUAISHOU */
|
||
|
this.menutop = menuButtonInfo.top;
|
||
|
/* #endif */
|
||
|
/* #ifdef APP-PLUS */
|
||
|
let platform = uni.getSystemInfoSync().platform
|
||
|
if(platform === 'ios'){
|
||
|
this.menutop = 60;
|
||
|
}else{
|
||
|
this.menutop = 40;
|
||
|
}
|
||
|
/* #endif */
|
||
|
/* #ifdef MP-TOUTIAO */
|
||
|
this.menutop = 10;
|
||
|
/* #endif */
|
||
|
|
||
|
},
|
||
|
onShow() {
|
||
|
if (app.globalData.grade_id == 0) return;
|
||
|
this.cate_id = app.globalData.grade_id
|
||
|
app.globalData.grade_id = 0;
|
||
|
this.getLogoConfig();
|
||
|
this.getCateList();
|
||
|
|
||
|
},
|
||
|
computed: {
|
||
|
updateSpecialList() {
|
||
|
return this.specialList.map((value) => {
|
||
|
value.special_type = this.specialType[value.type];
|
||
|
return value;
|
||
|
});
|
||
|
},
|
||
|
},
|
||
|
onShareAppMessage() {
|
||
|
return {};
|
||
|
},
|
||
|
onShareTimeline() {
|
||
|
return {};
|
||
|
},
|
||
|
methods: {
|
||
|
showLoginPage() {
|
||
|
this.$util.jumpLogin(this)
|
||
|
},
|
||
|
handleSpecialClick(item) {
|
||
|
const url = item.is_light
|
||
|
? '/pages/special/single_details?id=' + item.id
|
||
|
: '/pages/special/details?id=' + item.id;
|
||
|
|
||
|
// this.$util.checkLogin(() => {
|
||
|
uni.navigateTo({
|
||
|
url,
|
||
|
});
|
||
|
// }, this.showLoginPage);
|
||
|
},
|
||
|
handleSubjectClick(e) {
|
||
|
if (this.loading) return;
|
||
|
if (e.target.dataset.id !== undefined) {
|
||
|
this.subjectId = e.target.dataset.id;
|
||
|
this.specialList = [];
|
||
|
this.loadend = false;
|
||
|
this.page = 1;
|
||
|
this.getSpecialList();
|
||
|
}
|
||
|
},
|
||
|
handleGradeClick(e) {
|
||
|
if (e.target.dataset.id !== undefined) {
|
||
|
this.gradeId = e.target.dataset.id;
|
||
|
this.getSubject();
|
||
|
}
|
||
|
},
|
||
|
async getLogoConfig() {
|
||
|
try {
|
||
|
const { data } = await getLogoConfig();
|
||
|
this.homeLogo = data.homeLogo;
|
||
|
} catch (err) {
|
||
|
console.log(err);
|
||
|
}
|
||
|
},
|
||
|
goSearch() {
|
||
|
this.loadend = false;
|
||
|
this.page = 1;
|
||
|
this.gradeId = 0;
|
||
|
this.$set(this, "specialList", []);
|
||
|
this.getSpecialList();
|
||
|
},
|
||
|
// 获取导航数据
|
||
|
async getCateList() {
|
||
|
this.loading = true;
|
||
|
try {
|
||
|
const { data, code, msg } = await getCateList();
|
||
|
|
||
|
this.loading = false;
|
||
|
if (code != 200) {
|
||
|
uni.showToast({
|
||
|
title: msg,
|
||
|
});
|
||
|
} else {
|
||
|
this.gradeCate = [
|
||
|
{
|
||
|
id: 0,
|
||
|
name: "全部",
|
||
|
},
|
||
|
...data,
|
||
|
];
|
||
|
let defaultSelect = 0;
|
||
|
for (let i = 0; i < this.gradeCate.length; i++) {
|
||
|
if (this.gradeCate[i].id == this.cate_id) {
|
||
|
defaultSelect = i;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
this.gradeId = this.gradeCate[defaultSelect].id;
|
||
|
this.$nextTick(() => {
|
||
|
this.gradeScrollIdx = "grade" + defaultSelect;
|
||
|
|
||
|
this.count++;
|
||
|
|
||
|
if (this.gradeId) {
|
||
|
this.getSubject();
|
||
|
} else {
|
||
|
this.subjectCate = [];
|
||
|
this.specialList = [];
|
||
|
this.subjectId = 0;
|
||
|
this.loading = false;
|
||
|
this.loadend = false;
|
||
|
this.page = 1;
|
||
|
this.getSpecialList();
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
} catch (err) {
|
||
|
this.loading = false;
|
||
|
console.log(err);
|
||
|
}
|
||
|
},
|
||
|
// 二级导航
|
||
|
getSubject() {
|
||
|
if (!this.gradeId) {
|
||
|
this.subjectCate = [];
|
||
|
this.specialList = [];
|
||
|
this.subjectId = 0;
|
||
|
this.loading = false;
|
||
|
this.loadend = false;
|
||
|
this.page = 1;
|
||
|
this.getSpecialList();
|
||
|
return;
|
||
|
}
|
||
|
let subjectCate = [
|
||
|
{
|
||
|
id: 0,
|
||
|
name: "全部",
|
||
|
pic: this.getImgPath("/wap/first/zsff/images/all.png"),
|
||
|
grade_id: this.gradeId,
|
||
|
},
|
||
|
];
|
||
|
|
||
|
const grade = this.gradeCate.find((i) => i.id == this.gradeId);
|
||
|
if (grade) {
|
||
|
subjectCate = subjectCate.concat(grade.children);
|
||
|
}
|
||
|
|
||
|
this.subjectCate = subjectCate;
|
||
|
|
||
|
let defaultSelect = 0;
|
||
|
if (this.count === 1) {
|
||
|
for (let j = 0; j < this.subjectCate.length; j++) {
|
||
|
if (this.subjectCate[j].id == this.subject_id) {
|
||
|
defaultSelect = j;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
this.$nextTick(() => {
|
||
|
this.subjectScrollIdx = "subject" + defaultSelect;
|
||
|
const id = this.subjectCate[defaultSelect].id;
|
||
|
this.subjectId = id;
|
||
|
this.specialList = [];
|
||
|
this.loadend = false;
|
||
|
this.page = 1;
|
||
|
this.getSpecialList();
|
||
|
});
|
||
|
},
|
||
|
// 课程列表
|
||
|
async getSpecialList() {
|
||
|
if (this.loading || this.loadend) {
|
||
|
return;
|
||
|
}
|
||
|
this.loading = true;
|
||
|
this.loadTitle = "";
|
||
|
uni.showLoading({
|
||
|
mask: true,
|
||
|
});
|
||
|
try {
|
||
|
const { data, code, msg } = await getSpecialList({
|
||
|
grade_id: this.gradeId,
|
||
|
subject_id: this.subjectId,
|
||
|
search: this.search,
|
||
|
page: this.page++,
|
||
|
limit: this.limit,
|
||
|
});
|
||
|
this.loading = false;
|
||
|
if (code != 200) {
|
||
|
uni.showModal({
|
||
|
title: msg,
|
||
|
});
|
||
|
} else {
|
||
|
this.specialList = this.specialList.concat(data);
|
||
|
this.loadend = this.limit > data.length;
|
||
|
this.loadTitle = this.loadend ? "已全部加载完" : "上拉加载更多";
|
||
|
}
|
||
|
} catch (err) {
|
||
|
this.loading = false;
|
||
|
console.log(err);
|
||
|
}
|
||
|
uni.hideLoading();
|
||
|
},
|
||
|
},
|
||
|
};
|
||
|
</script>
|
||
|
<style>
|
||
|
page{
|
||
|
background: #F7F8F9;
|
||
|
}
|
||
|
|
||
|
|
||
|
</style>
|
||
|
<style lang="scss">
|
||
|
@import "@/static/style/good.scss";
|
||
|
</style>
|
||
|
|
||
|
<style lang="scss" scoped>
|
||
|
.grade-item{
|
||
|
font-size: 32rpx;
|
||
|
font-weight: 400;
|
||
|
color: #7A808A;
|
||
|
white-space: inherit;
|
||
|
}
|
||
|
.grade-item.cur{
|
||
|
font-size: 32rpx;
|
||
|
font-weight: 600;
|
||
|
color: #23272E;
|
||
|
&.cur {
|
||
|
&::before {
|
||
|
width: 32rpx;
|
||
|
height: 8rpx;
|
||
|
background: #1D8DFF;
|
||
|
border-radius: 4rpx;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/deep/ ::-webkit-scrollbar {
|
||
|
display: none;
|
||
|
width: 0 !important;
|
||
|
height: 0 !important;
|
||
|
-webkit-appearance: none;
|
||
|
background: transparent;
|
||
|
}
|
||
|
|
||
|
.free {
|
||
|
margin-top: 10rpx;
|
||
|
font-weight: 400;
|
||
|
font-size: 22rpx;
|
||
|
line-height: 38rpx;
|
||
|
color: #ff6b00;
|
||
|
}
|
||
|
|
||
|
.nothing {
|
||
|
position: absolute;
|
||
|
top: 50%;
|
||
|
left: 50%;
|
||
|
width: 414rpx;
|
||
|
height: 336rpx;
|
||
|
|
||
|
transform: translate(-50%, -50%);
|
||
|
}
|
||
|
.goodsClass .header {
|
||
|
background: linear-gradient(180deg, #B1E5FF 0%, #F7F8F9 100%);
|
||
|
}
|
||
|
.goodsClass .header .search .label {
|
||
|
padding-left:0;
|
||
|
margin-left:auto;
|
||
|
background: none;
|
||
|
}
|
||
|
|
||
|
.goodsClass .header .search{
|
||
|
background: #FFFFFF;
|
||
|
border-radius: 40rpx;
|
||
|
height: 70rpx;
|
||
|
line-height: 80rpx;
|
||
|
/* #ifdef MP-WEIXIN */
|
||
|
width: 73%;
|
||
|
margin-left: 10rpx;
|
||
|
/* #endif */
|
||
|
/* #ifdef MP-KUAISHOU */
|
||
|
width: 60%;
|
||
|
margin-left: 10rpx;
|
||
|
/* #endif */
|
||
|
/* #ifdef H5 || APP-PLUS */
|
||
|
width: 686rpx;
|
||
|
margin: auto;
|
||
|
margin-top: 30rpx;
|
||
|
/* #endif */
|
||
|
|
||
|
/* #ifdef MP-TOUTIAO*/
|
||
|
width: 96%;
|
||
|
margin: auto;
|
||
|
padding: 0 10rpx;
|
||
|
/* #endif */
|
||
|
}
|
||
|
.submit {
|
||
|
width: 126rpx;
|
||
|
height: 55rpx;
|
||
|
background: #1D8DFF;
|
||
|
border-radius: 34rpx;
|
||
|
text-align: center;
|
||
|
line-height: 55rpx;
|
||
|
}
|
||
|
.goodsClass .header .search .form{
|
||
|
/* #ifdef APP-PLUS */
|
||
|
padding: 0 10rpx 0 10rpx;
|
||
|
/* #endif */
|
||
|
/* #ifdef MP-WEIXIN || H5 || MP-KUAISHOU*/
|
||
|
margin-top: -16rpx;
|
||
|
/* #endif */
|
||
|
justify-content: center;
|
||
|
padding-right: 6rpx;
|
||
|
}
|
||
|
.goodsClass .header .search .input{
|
||
|
background-color:rgba(0,0,0,0);
|
||
|
}
|
||
|
.goodsClass .header .search .img{
|
||
|
width: 40rpx;
|
||
|
height: 40rpx;
|
||
|
}
|
||
|
.public_list{
|
||
|
width: 686rpx;
|
||
|
background: #FFFFFF;
|
||
|
border-radius: 24rpx;
|
||
|
margin: auto;
|
||
|
margin-top: 30rpx;
|
||
|
}
|
||
|
.goodsClass .goodList{
|
||
|
padding: 32rpx 0 0 10rpx;
|
||
|
}
|
||
|
.goodsClass .nav .item .name {
|
||
|
width: 136rpx;
|
||
|
height: 64rpx;
|
||
|
background: rgba(29,141,255,0.1);
|
||
|
border-radius: 34rpx;
|
||
|
border: 2rpx solid rgba(29,141,255,0.4);
|
||
|
line-height: 64rpx;
|
||
|
}
|
||
|
.goodsClass .nav .item .name.on{
|
||
|
width: 136rpx;
|
||
|
height: 64rpx;
|
||
|
border-radius: 34rpx;
|
||
|
border: 2rpx solid #D8DCE3;
|
||
|
background:none;
|
||
|
}
|
||
|
.col-12{
|
||
|
height:30rpx;
|
||
|
}
|
||
|
</style>
|