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.
451 lines
11 KiB
451 lines
11 KiB
<template>
|
|
|
|
<BaseContainer class="favorite" :fixedNav="false">
|
|
<NavBarTitle title="我的收藏" :height="88"/>
|
|
<view v-if="type" ref="tabbar" class="tabbar">
|
|
<view :class="{ on: active === 1 }" @click="tab(1)">资料</view>
|
|
<view :class="{ on: active === 2 }" @click="tab(2)">老师</view>
|
|
<view :class="{ on: active === 0 }" @click="tab(0)">课程</view>
|
|
</view>
|
|
<view v-if="makeGradeList.length" :class="{ material: active }" class="list">
|
|
<template v-if="active < 2">
|
|
<navigator
|
|
v-for="(item, index) in makeGradeList"
|
|
:key="item.id"
|
|
:url="item.path"
|
|
ref="box_center"
|
|
class="list-item"
|
|
@touchstart="drawStart"
|
|
@touchmove="drawMove(index,$event)"
|
|
@touchend="drawEnd(index,$event)"
|
|
:style="{ left: activeHeaderMask === index ? '-120rpx' : '' }"
|
|
>
|
|
<view>
|
|
<image mode="aspectFill" :src="item.image" alt="" />
|
|
<!-- <view v-if="!active">{{ type == 1 ? item.types : item.type }}</view> -->
|
|
</view>
|
|
<view class="function-mask" :style="{visibility: activeHeaderMask === index ? 'visible' : 'hidden' }" @click.stop="activeHeaderMask = -1"></view>
|
|
<view class="function">
|
|
<view class="btn" @click.stop="cancelCollect(item)">取消收藏</view>
|
|
</view>
|
|
<view>
|
|
<view>{{ item.title }}</view>
|
|
<template v-if="active">
|
|
<view :class="{ money: item.pay_type }" style="color:#23272E;">
|
|
<template v-if="item.pay_type"> ¥<text >{{item.money}}</text> </template>
|
|
<template v-else> 免费 </template>
|
|
</view>
|
|
<view>
|
|
<view>{{ item.ficti + item.sales }}人已下载</view>
|
|
<view class="button">去下载</view>
|
|
</view>
|
|
</template>
|
|
<template v-else>
|
|
<view v-if="item.label.length">
|
|
<template v-for="(label, index) in item.label">
|
|
<view v-if="index < 2" :key="index">{{ label }}</view>
|
|
</template>
|
|
</view>
|
|
<view>
|
|
<view :class="{ money: item.pay_type }">
|
|
<template v-if="item.pay_type">
|
|
¥<text>{{ item.is_pink ? item.pink_money : item.money }}</text>
|
|
</template>
|
|
<template v-else> 免费 </template>
|
|
</view>
|
|
<view v-if="!item.is_light && item.types !== 4">共{{ item.count }}节</view>
|
|
</view>
|
|
</template>
|
|
</view>
|
|
|
|
</navigator>
|
|
</template>
|
|
<template v-else>
|
|
<navigator
|
|
v-for="(item, index) in makeGradeList"
|
|
:key="item.id"
|
|
:url="item.path"
|
|
ref="box_center"
|
|
class="list-item lecturer-item"
|
|
@touchstart="drawStart"
|
|
@touchmove="drawMove(index,$event)"
|
|
@touchend="drawEnd(index,$event)"
|
|
:style="{ left: activeHeaderMask === index ? '-120rpx' : '' }"
|
|
>
|
|
<view>
|
|
<image mode="aspectFill" :src="item.lecturer_head" alt="" />
|
|
<!-- <view v-if="!active">{{ type == 1 ? item.types : item.type }}</view> -->
|
|
</view>
|
|
<view class="function-mask" :style="{visibility: activeHeaderMask === index ? 'visible' : 'hidden' }" @click.stop="activeHeaderMask = -1"></view>
|
|
<view class="function">
|
|
<view class="btn" @click.stop="cancelCollect(item)">取消收藏</view>
|
|
</view>
|
|
<view>
|
|
<view class="lecturer-name">{{ item.lecturer_name }} <text v-for="(label, k) in item.label" class="label">{{ label }}</text></view>
|
|
<template>
|
|
<view class="lecturer-intro">{{ item.explain }}</view>
|
|
</template>
|
|
</view>
|
|
|
|
</navigator>
|
|
</template>
|
|
</view>
|
|
<view v-show="loading" class="loading">
|
|
<text class="fa fa-spinner"></text>
|
|
</view>
|
|
<view v-if="loadend && gradeList.length" class="loaded">已全部加载</view>
|
|
<view v-if="loadend && !gradeList.length">
|
|
<image
|
|
class="nothing"
|
|
:src="getImgPath('/wap/first/zsff/images/no_collection.png')"
|
|
v-if="type"
|
|
/>
|
|
<image
|
|
v-else
|
|
class="nothing"
|
|
:src="getImgPath('/wap/first/zsff/images/no_data_available.png')"
|
|
/>
|
|
</view>
|
|
</BaseContainer>
|
|
</template>
|
|
|
|
<script>
|
|
import { toggleCollectMaterial } from "@/api/material";
|
|
import { collectSpecial, getGradeList } from "@/api/special";
|
|
import {
|
|
getFollowList,
|
|
follow
|
|
} from "@/api/merchant";
|
|
import specialType from "@/constants/special-type";
|
|
|
|
export default {
|
|
data() {
|
|
return {
|
|
loadend: false,
|
|
loading: false,
|
|
active: 0,
|
|
type: 1,
|
|
gradeList: [],
|
|
min: 2,
|
|
page: 1,
|
|
limit: 10,
|
|
count: 0,
|
|
activeHeaderMask: -1,
|
|
};
|
|
},
|
|
computed: {
|
|
makeGradeList() {
|
|
return this.gradeList.map((value) => {
|
|
if (this.type) {
|
|
value.types = specialType[value.type];
|
|
}
|
|
if (this.active < 2) {
|
|
if ("is_light" in value) {
|
|
if (value.is_light) {
|
|
value.path = `/pages/special/single_details?id=${value.s_id}`;
|
|
} else {
|
|
value.path = `/pages/special/details?id=${value.s_id}`;
|
|
}
|
|
} else {
|
|
value.path = `/pages/special/data_details?id=${value.id}`;
|
|
}
|
|
} else {
|
|
value.path = `/pages/merchant/teacher_detail?id=${value.id}`;
|
|
}
|
|
return value;
|
|
});
|
|
},
|
|
},
|
|
watch: {
|
|
active() {
|
|
this.$set(this, "gradeList", []);
|
|
this.page = 1;
|
|
this.loadend = false;
|
|
this.getGradeList();
|
|
},
|
|
},
|
|
onLoad({ type = 1 }) {
|
|
this.type = type;
|
|
if (type == 1) {
|
|
this.active = 1;
|
|
}
|
|
this.getGradeList();
|
|
},
|
|
onReachBottom() {
|
|
this.getGradeList();
|
|
},
|
|
methods: {
|
|
// 获取课程
|
|
async getGradeList() {
|
|
if (this.loading || this.loadend) return;
|
|
this.loading = true;
|
|
|
|
uni.showLoading({ mask: true });
|
|
try {
|
|
if (this.active < 2) {
|
|
const { data } = await getGradeList(this.active, this.page, this.limit);
|
|
const { list, page } = data;
|
|
this.gradeList.push.apply(this.gradeList, list);
|
|
this.loadend = list.length < this.limit;
|
|
this.page = page;
|
|
this.$set(this, "gradeList", this.gradeList);
|
|
} else {
|
|
const { data } = await getFollowList({
|
|
page: this.page++,
|
|
limit: this.limit
|
|
});
|
|
data.forEach(function (item) {
|
|
item.label = JSON.parse(item.label);
|
|
});
|
|
this.gradeList.push.apply(this.gradeList, data);
|
|
this.loadend = data.length < this.limit;
|
|
this.$set(this, "gradeList", this.gradeList);
|
|
console.log(data);
|
|
}
|
|
uni.hideLoading();
|
|
} catch (err) {}
|
|
this.loading = false;
|
|
},
|
|
tab(active) {
|
|
if (this.loading) return;
|
|
this.active = active;
|
|
this.gradeList = [];
|
|
this.page = 1;
|
|
this.loadend = false;
|
|
this.getGradeList();
|
|
},
|
|
// 开始触摸
|
|
drawStart(e) {
|
|
console.log('触摸',e);
|
|
this.clientX = e.changedTouches[0].clientX
|
|
},
|
|
// 触摸过程
|
|
drawMove(id, e) {
|
|
console.log('过程',e.changedTouches);
|
|
var endX = e.changedTouches[0].clientX;
|
|
let diff = endX - this.clientX;
|
|
console.log(diff);
|
|
|
|
if (Math.abs(diff) <= 60 && diff < 0) {
|
|
console.log(this.$refs.box_center);
|
|
let box_center = this.$refs.box_center[id]
|
|
// console.log(diff);
|
|
box_center.$el.style.left = diff + 'px'
|
|
}
|
|
|
|
},
|
|
// 结束触摸
|
|
drawEnd(id, e) {
|
|
console.log('结束',e.changedTouches[0]);
|
|
var endX = e.changedTouches[0].clientX;
|
|
let diff = endX - this.clientX;
|
|
if (Math.abs(diff) > 20) {
|
|
// console.log('移动',diff,id,e);
|
|
if (diff < 0) {
|
|
this.activeHeaderMask = id;
|
|
} else {
|
|
this.activeHeaderMask = -1;
|
|
}
|
|
}
|
|
},
|
|
cancelCollect(item) {
|
|
if (this.active === 1) {
|
|
toggleCollectMaterial(item.id).then(() => {
|
|
this.$util.showMsg("取消收藏成功");
|
|
this.$set(this, "gradeList", []);
|
|
this.page = 1;
|
|
this.loadend = false;
|
|
this.activeHeaderMask = -1;
|
|
this.getGradeList();
|
|
});
|
|
} else if (this.active === 2) {
|
|
follow({
|
|
mer_id: item.mer_id,
|
|
is_follow: 0
|
|
}).then(() => {
|
|
this.$util.showMsg("取消收藏成功");
|
|
this.$set(this, "gradeList", []);
|
|
this.page = 1;
|
|
this.loadend = false;
|
|
this.activeHeaderMask = -1;
|
|
this.getGradeList();
|
|
})
|
|
} else {
|
|
collectSpecial(item.id)
|
|
.then(() => {
|
|
this.$util.showMsg("取消收藏成功");
|
|
this.$set(this, "gradeList", []);
|
|
this.page = 1;
|
|
this.loadend = false;
|
|
this.activeHeaderMask = -1;
|
|
this.getGradeList();
|
|
})
|
|
.catch((err) => {
|
|
console.log(err);
|
|
});
|
|
}
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
@import "@/static/style/favorite.scss";
|
|
page{
|
|
background: #F7F8F9;
|
|
|
|
}
|
|
|
|
</style>
|
|
|
|
<style scoped lang="scss">
|
|
.favorite {
|
|
::v-deep .nav-box {
|
|
background: #fff;
|
|
}
|
|
.tabbar {
|
|
position: relative;
|
|
width: 100%;
|
|
margin-top: calc(88rpx + var(--safe-top));
|
|
border-radius: 24rpx;
|
|
z-index: 999;
|
|
background: #fff;
|
|
border-bottom:none;
|
|
}
|
|
}
|
|
|
|
.list {
|
|
// padding-top: calc(88rpx + var(--safe-top) + 90rpx) !important;
|
|
width: 690rpx;
|
|
margin: 0 auto;
|
|
margin-top: 20rpx;
|
|
border-radius: 24rpx;
|
|
z-index: 999;
|
|
overflow-x: hidden;
|
|
.list-item {
|
|
position: relative;
|
|
background: #ffffff;
|
|
&.lecturer-item {
|
|
image {
|
|
width: 100rpx;
|
|
height: 100rpx;
|
|
border-radius: 50%;
|
|
}
|
|
.lecturer-name {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
margin-bottom: 14rpx;
|
|
.label {
|
|
height: 39rpx;
|
|
background: #FFEDE9;
|
|
border-radius: 6rpx;
|
|
padding: 0 14rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
color: #FF4B33;
|
|
font-size: 22rpx;
|
|
margin-left: 12rpx;
|
|
}
|
|
}
|
|
.lecturer-intro {
|
|
color: #999999!important;
|
|
font-size: 24rpx!important;
|
|
font-weight: normal!important;
|
|
max-height: 60rpx;
|
|
line-height: 30rpx;
|
|
-webkit-line-clamp: 2;
|
|
text-overflow: ellipsis;
|
|
display: -webkit-box;
|
|
-webkit-box-orient: vertical;
|
|
}
|
|
}
|
|
.function-mask {
|
|
position: absolute;
|
|
left: 0;
|
|
top: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
z-index: 10;
|
|
visibility: hidden;
|
|
}
|
|
.function {
|
|
width: 120rpx;
|
|
height: 100%;
|
|
background: #F8473E;
|
|
border-radius: 0rpx 10rpx 10rpx 0rpx;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
position: absolute;
|
|
top: 0;
|
|
right: -120rpx;
|
|
.btn {
|
|
width: 30rpx;
|
|
white-space: pre-wrap;
|
|
overflow: auto;
|
|
font-size: 28rpx;
|
|
color: #fff;
|
|
line-height: 36rpx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.money{
|
|
width: 134rpx;
|
|
height: 48rpx;
|
|
font-size: 36rpx;
|
|
font-family: PingFangSC-Semibold, PingFang SC;
|
|
font-weight: 600;
|
|
color: #23272E;
|
|
line-height: 48rpx;
|
|
}
|
|
|
|
.mask .box {
|
|
position: relative;
|
|
}
|
|
|
|
.mask .box .iconfont {
|
|
color: #ffffff;
|
|
font-size: 40rpx;
|
|
left: 50%;
|
|
margin-left: -20rpx;
|
|
bottom: 30rpx;
|
|
}
|
|
|
|
.public_list .item .text {
|
|
-webkit-align-self: flex-start;
|
|
align-self: flex-start;
|
|
}
|
|
|
|
.loading {
|
|
font-size: 40rpx;
|
|
text-align: center;
|
|
color: #999999;
|
|
}
|
|
|
|
.loaded {
|
|
font-size: 28rpx;
|
|
line-height: 72rpx;
|
|
text-align: center;
|
|
color: #999999;
|
|
}
|
|
|
|
.nothing {
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
width: 414rpx;
|
|
height: 336rpx;
|
|
-webkit-transform: translate(-50%, -50%);
|
|
transform: translate(-50%, -50%);
|
|
}
|
|
.button{
|
|
width: 120rpx;
|
|
height: 56rpx;
|
|
background: #1D8DFF;
|
|
border-radius: 28rpx;
|
|
text-align: center;
|
|
line-height: 56rpx;
|
|
color: #ffffff;
|
|
}
|
|
</style>
|
|
|