673 lines
20 KiB
Vue
673 lines
20 KiB
Vue
<template>
|
||
<view class="collection-page">
|
||
|
||
<custom-navbar title="我的收藏" :showBack="true" backgroundColor="#FFFFFF" :show-headle="true" borderBottom="none"
|
||
headleSrc="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/51ebca5d-95c5-4fb8-8aa3-560a79100d25.png" @onHeadleClick="goToSearch">
|
||
</custom-navbar>
|
||
|
||
<view class="nav-placeholder" :style="{ height: navHeight + 'px' }"></view>
|
||
|
||
<view class="tab-bar-wrap" :style="{ top: navHeight + 'px' }">
|
||
<view class="tab-bar">
|
||
<view class="tab-items">
|
||
<view
|
||
class="tab-item"
|
||
:class="{ active: currentTab === 'brand' }"
|
||
@tap="switchTab('brand')"
|
||
>
|
||
收藏的品牌
|
||
</view>
|
||
<view
|
||
class="tab-item"
|
||
:class="{ active: currentTab === 'course' }"
|
||
@tap="switchTab('course')"
|
||
>
|
||
收藏的课程
|
||
</view>
|
||
</view>
|
||
<view class="filter-area" @tap="toggleFilterPanel">
|
||
<text class="filter-text">筛选</text>
|
||
<image class="filter-icon" :src="filterIcon" mode="aspectFit" :class="{ 'rotate': filterVisible }"></image>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="filter-panel" :class="{ 'show': filterVisible }" :style="{ top: filterTop + 'px' }" catchtouchmove="true">
|
||
<view class="filter-mask" @tap="closeFilterPanel"></view>
|
||
<view class="filter-container">
|
||
|
||
<scroll-view scroll-y class="filter-scroll" v-if="currentTab === 'brand'">
|
||
<view class="filter-group" v-for="group in brandFilterData" :key="group.id">
|
||
<view class="group-title">{{ group.title }}</view>
|
||
<view class="pill-list">
|
||
<view
|
||
class="pill-item"
|
||
v-for="sub in group.children"
|
||
:key="sub.id"
|
||
:class="{ active: selectedSecondIds.includes(sub.id) }"
|
||
@tap="toggleSecondSelect(sub.id)"
|
||
>
|
||
{{ sub.title }}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</scroll-view>
|
||
|
||
<view v-else class="course-filter">
|
||
<view
|
||
class="course-type-item"
|
||
:class="{ active: selectedCourseType === 'platform' }"
|
||
@tap="selectCourseType('platform')"
|
||
>
|
||
平台课程
|
||
</view>
|
||
<view
|
||
class="course-type-item"
|
||
:class="{ active: selectedCourseType === 'brand' }"
|
||
@tap="selectCourseType('brand')"
|
||
>
|
||
品牌课程
|
||
</view>
|
||
</view>
|
||
|
||
<view class="filter-footer">
|
||
<view class="reset-btn" @tap="resetFilter">重置</view>
|
||
<view class="confirm-btn" @tap="applyFilterAndClose">确定</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="collection-content" v-if="currentTab === 'brand'">
|
||
<view class="brand-grid" v-if="filteredBrandList.length > 0">
|
||
<brand-card
|
||
class="brand-card-wrap"
|
||
v-for="(item, index) in filteredBrandList"
|
||
:key="index"
|
||
:item="item"
|
||
:tagKeys="item.tagKeys"
|
||
@click="goToBrandDetail(item)"
|
||
></brand-card>
|
||
</view>
|
||
<view class="empty-state" v-else>
|
||
<image class="empty-icon" src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/da814ede-1adc-4f90-8cdf-5357a12fab27.png"></image>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="collection-content" v-else>
|
||
<view class="course-list" v-if="filteredCourseList.length > 0">
|
||
<skill-card
|
||
v-for="(item, index) in filteredCourseList"
|
||
:key="index"
|
||
:item="item"
|
||
></skill-card>
|
||
</view>
|
||
<view class="empty-state" v-else>
|
||
<image class="empty-icon" src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/da814ede-1adc-4f90-8cdf-5357a12fab27.png"></image>
|
||
</view>
|
||
</view>
|
||
|
||
<view style="height: 120rpx;"></view>
|
||
<TabBar :selected="3"></TabBar>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import TabBar from "@/components/tabbar/tabbar.vue"
|
||
import BrandCard from "@/pages/home/components/brand-card.vue"
|
||
import SkillCard from "@/pages/home/components/skill-card.vue"
|
||
import request from "@/utils/request"
|
||
|
||
// 数据模式开关:true=调用真实接口,false=使用模拟数据
|
||
const USE_REAL_API = true
|
||
|
||
export default {
|
||
components: {
|
||
TabBar,
|
||
BrandCard,
|
||
SkillCard
|
||
},
|
||
data() {
|
||
return {
|
||
navHeight: 0, // 动态计算的导航栏高度
|
||
filterTop: 0, // 动态计算的筛选框顶部起点
|
||
|
||
currentTab: 'brand',
|
||
// 筛选相关
|
||
filterVisible: false,
|
||
|
||
// 品牌筛选下拉数据 (合并一级和二级)
|
||
brandFilterData: [],
|
||
selectedSecondIds: [], // 选中的二级ID数组
|
||
|
||
// 课程筛选
|
||
selectedCourseType: '', // 'platform' 或 'brand'
|
||
// 原始数据(收藏的数据)
|
||
rawBrandList: [],
|
||
rawCourseList: [],
|
||
// 展示数据(过滤后)
|
||
filteredBrandList: [],
|
||
filteredCourseList: []
|
||
}
|
||
},
|
||
computed: {
|
||
filterIcon() {
|
||
// 这里的图标链接可以统一成一个,配合CSS的旋转动画更好看
|
||
return 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/e00ab2ac-bccf-42d8-820c-65727327e279.png'
|
||
}
|
||
},
|
||
onLoad() {
|
||
// 精准计算吸顶高度与下拉框起点,防止蒙版遮挡白色的Tab区
|
||
const sysInfo = uni.getSystemInfoSync()
|
||
const sbh = sysInfo.statusBarHeight || 0
|
||
this.navHeight = sbh
|
||
// Tab栏自身的高度大约为 106rpx,转化为 px 叠加上去
|
||
this.filterTop = this.navHeight + uni.upx2px(106)
|
||
|
||
this.loadFilterCategories()
|
||
this.loadData()
|
||
},
|
||
methods: {
|
||
// 跳转搜索页
|
||
goToSearch() {
|
||
// this.currentTab 的值刚好是 'brand' 或 'course'
|
||
uni.navigateTo({
|
||
url: `/pages/search_common/search?type=collection_${this.currentTab}`
|
||
});
|
||
},
|
||
goBack() {
|
||
uni.navigateBack()
|
||
},
|
||
addAddress() {
|
||
// 外部方法占位
|
||
},
|
||
switchTab(tab) {
|
||
if (this.currentTab === tab) return
|
||
this.currentTab = tab
|
||
// 重置筛选(不同tab筛选条件独立)
|
||
if (tab === 'brand') {
|
||
this.resetBrandFilter()
|
||
} else {
|
||
this.resetCourseFilter()
|
||
}
|
||
this.loadData()
|
||
this.closeFilterPanel()
|
||
},
|
||
// 筛选面板控制
|
||
toggleFilterPanel() {
|
||
this.filterVisible = !this.filterVisible
|
||
},
|
||
closeFilterPanel() {
|
||
this.filterVisible = false
|
||
},
|
||
|
||
// 加载一级分类并自动组装其对应的二级分类,兼容 state === 1
|
||
async loadFilterCategories() {
|
||
try {
|
||
const syrId = uni.getStorageSync('syrId') || 1;
|
||
const res = await request.post('/sj/firstclass', { id: syrId })
|
||
if ((res.code === 200 || res.state === 1) && res.data) {
|
||
const firstClasses = res.data;
|
||
|
||
// 并发请求所有的二级分类
|
||
const promises = firstClasses.map(async (first) => {
|
||
try {
|
||
const subRes = await request.post('/sj/secondclass', { id: first.id })
|
||
return {
|
||
id: first.id,
|
||
title: first.title,
|
||
children: ((subRes.code === 200 || subRes.state === 1) && subRes.data) ? subRes.data : []
|
||
}
|
||
} catch(e) {
|
||
return { id: first.id, title: first.title, children: [] }
|
||
}
|
||
});
|
||
|
||
const filterData = await Promise.all(promises);
|
||
// 过滤掉没有子分类的项,避免面板出现光秃秃的标题
|
||
this.brandFilterData = filterData.filter(group => group.children.length > 0);
|
||
} else {
|
||
this.brandFilterData = []
|
||
}
|
||
} catch (error) {
|
||
console.error('获取分类字典失败', error)
|
||
}
|
||
},
|
||
|
||
toggleSecondSelect(secId) {
|
||
const index = this.selectedSecondIds.indexOf(secId)
|
||
if (index === -1) {
|
||
this.selectedSecondIds.push(secId)
|
||
} else {
|
||
this.selectedSecondIds.splice(index, 1)
|
||
}
|
||
},
|
||
// 课程筛选
|
||
selectCourseType(type) {
|
||
// 点击已选中的则取消选中
|
||
if(this.selectedCourseType === type){
|
||
this.selectedCourseType = ''
|
||
}else{
|
||
this.selectedCourseType = type
|
||
}
|
||
},
|
||
// 重置品牌筛选
|
||
resetBrandFilter() {
|
||
this.selectedSecondIds = []
|
||
this.applyBrandFilter()
|
||
},
|
||
resetCourseFilter() {
|
||
this.selectedCourseType = ''
|
||
this.applyCourseFilter()
|
||
},
|
||
resetFilter() {
|
||
if (this.currentTab === 'brand') {
|
||
this.resetBrandFilter()
|
||
} else {
|
||
this.resetCourseFilter()
|
||
}
|
||
},
|
||
applyFilterAndClose() {
|
||
if (this.currentTab === 'brand') {
|
||
this.applyBrandFilter()
|
||
} else {
|
||
this.applyCourseFilter()
|
||
}
|
||
this.closeFilterPanel()
|
||
},
|
||
// 品牌过滤逻辑(根据二级分类ID相交判断)
|
||
applyBrandFilter() {
|
||
if (!this.rawBrandList.length) {
|
||
this.filteredBrandList = []
|
||
return
|
||
}
|
||
if (this.selectedSecondIds.length === 0) {
|
||
this.filteredBrandList = [...this.rawBrandList]
|
||
} else {
|
||
this.filteredBrandList = this.rawBrandList.filter(brand => {
|
||
return brand.secondClassIds && brand.secondClassIds.some(id => this.selectedSecondIds.includes(id))
|
||
})
|
||
}
|
||
},
|
||
// 课程过滤逻辑(根据课程类型)
|
||
applyCourseFilter() {
|
||
if (!this.rawCourseList.length) {
|
||
this.filteredCourseList = []
|
||
return
|
||
}
|
||
if (!this.selectedCourseType) {
|
||
this.filteredCourseList = [...this.rawCourseList]
|
||
} else {
|
||
this.filteredCourseList = this.rawCourseList.filter(course => {
|
||
if (this.selectedCourseType === 'platform') return course.type === '平台课程'
|
||
if (this.selectedCourseType === 'brand') return course.type === '品牌课程'
|
||
return true
|
||
})
|
||
}
|
||
},
|
||
// 加载原始数据(根据当前Tab)
|
||
loadData() {
|
||
if (this.currentTab === 'brand') {
|
||
this.loadBrandList()
|
||
} else {
|
||
this.loadCourseList()
|
||
}
|
||
},
|
||
async loadBrandList() {
|
||
if (USE_REAL_API) {
|
||
await this.fetchRealBrandList()
|
||
} else {
|
||
this.mockBrandList()
|
||
}
|
||
this.applyBrandFilter()
|
||
},
|
||
async loadCourseList() {
|
||
if (USE_REAL_API) {
|
||
await this.fetchRealCourseList()
|
||
} else {
|
||
this.mockCourseList()
|
||
}
|
||
this.applyCourseFilter()
|
||
},
|
||
|
||
// ============ 真实接口调用 ============
|
||
async fetchRealBrandList() {
|
||
try {
|
||
const res = await request.post('/sj/brand/list', { page: 1, limit: 100 })
|
||
if ((res.code === 200 || res.state === 1) && res.data && res.data.list) {
|
||
const collectedBrands = res.data.list.filter(item => item.collect_state === 1)
|
||
this.rawBrandList = collectedBrands.map(item => {
|
||
let tags = []
|
||
if (item.franchise_state === 1) tags.push('franchise')
|
||
if (item.student_state === 1) tags.push('recruit')
|
||
if (tags.length === 0) tags.push('more')
|
||
|
||
return {
|
||
id: item.id,
|
||
name: item.name,
|
||
bgSrc: item.cover_img || 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/default.jpg',
|
||
avatar: item.logo_img || 'https://dummyimage.com/100x100/ccc/fff.png&text=Avatar',
|
||
tagKeys: tags,
|
||
secondClassIds: item.second_class_ids ? item.second_class_ids.split(',').map(Number) : []
|
||
}
|
||
})
|
||
} else {
|
||
this.rawBrandList = []
|
||
}
|
||
} catch (error) {
|
||
console.error('获取品牌收藏失败', error)
|
||
}
|
||
},
|
||
async fetchRealCourseList() {
|
||
try {
|
||
const res = await request.post('/sj/skill/list', { page: 1, limit: 100 })
|
||
if ((res.code === 200 || res.state === 1) && res.data && res.data.list) {
|
||
const collectedCourses = res.data.list.filter(item => item.collect_state === 1)
|
||
this.rawCourseList = collectedCourses.map(item => {
|
||
return {
|
||
id: item.id,
|
||
title: item.name,
|
||
coverSrc: item.cover_img,
|
||
type: item.link_name || (item.link_type === 1 ? '平台课程' : '品牌课程'),
|
||
link_type: item.link_type,
|
||
views: item.browse_num || 0,
|
||
time: item.create_time ? this.formatTimeAgo(item.create_time) : '',
|
||
typeIcon: item.link_logo || ''
|
||
}
|
||
})
|
||
} else {
|
||
this.rawCourseList = []
|
||
}
|
||
} catch (error) {
|
||
console.error('获取课程收藏失败', error)
|
||
}
|
||
},
|
||
|
||
formatTimeAgo(timeStr) {
|
||
const now = new Date()
|
||
const time = new Date(timeStr.replace(/-/g, '/'))
|
||
const diff = Math.floor((now - time) / 1000)
|
||
if (diff < 3600) return Math.floor(diff / 60) + '分钟前'
|
||
if (diff < 86400) return Math.floor(diff / 3600) + '小时前'
|
||
if (diff < 604800) return Math.floor(diff / 86400) + '天前'
|
||
return timeStr.split(' ')[0]
|
||
},
|
||
goToBrandDetail(item) {
|
||
if (item.id) {
|
||
uni.navigateTo({ url: `/pages/brand/detail?id=${item.id}` })
|
||
}
|
||
},
|
||
|
||
// ============ 模拟数据兜底 ============
|
||
mockBrandList() {
|
||
this.rawBrandList = [
|
||
{
|
||
id: 1, name: '脸缘品牌', bgSrc: 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/e2220528-fdf6-4cad-a25d-ec6cbee1501e.jpg',
|
||
avatar: 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/e2220528-fdf6-4cad-a25d-ec6cbee1501e.jpg',
|
||
tagKeys: ['franchise', 'recruit'], secondClassIds: [76, 77]
|
||
},
|
||
{
|
||
id: 2, name: '美肌工坊', bgSrc: 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/e2220528-fdf6-4cad-a25d-ec6cbee1501e.jpg',
|
||
avatar: 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/e2220528-fdf6-4cad-a25d-ec6cbee1501e.jpg',
|
||
tagKeys: ['franchise'], secondClassIds: [78]
|
||
},
|
||
{
|
||
id: 3, name: '悦容堂', bgSrc: 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/e2220528-fdf6-4cad-a25d-ec6cbee1501e.jpg',
|
||
avatar: 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/e2220528-fdf6-4cad-a25d-ec6cbee1501e.jpg',
|
||
tagKeys: ['recruit'], secondClassIds: [201, 202]
|
||
}
|
||
]
|
||
},
|
||
mockCourseList() {
|
||
this.rawCourseList = [
|
||
{ id: 1, title: '穿戴甲的操作视频扫码验券操作教程', coverSrc: 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/e2220528-fdf6-4cad-a25d-ec6cbee1501e.jpg', type: '平台课程', views: 836000, time: '7小时前' },
|
||
{ id: 2, title: '全身SPA的操作视频操作教程', coverSrc: 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/e2220528-fdf6-4cad-a25d-ec6cbee1501e.jpg', type: '平台课程', views: 2344, time: '3天前' },
|
||
{ id: 3, title: '高级面部护理手法详解', coverSrc: 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/e2220528-fdf6-4cad-a25d-ec6cbee1501e.jpg', type: '品牌课程', views: 56700, time: '1周前' }
|
||
]
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.collection-page {
|
||
min-height: 100vh;
|
||
background: #fff;
|
||
}
|
||
|
||
/* 将页面左右 padding 转移到内容区,保证 Tab 背景贯穿全屏 */
|
||
.tab-bar-wrap {
|
||
position: sticky; /* 吸顶,保证滑动页面时一直显示在最前面 */
|
||
background: #fff;
|
||
padding: 10rpx 24rpx;
|
||
z-index: 101;
|
||
}
|
||
|
||
.tab-bar {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
background: transparent;
|
||
padding: 10rpx 0;
|
||
|
||
.tab-items {
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.tab-item {
|
||
font-weight: 400;
|
||
font-size: 26rpx;
|
||
color: #777777;
|
||
background: #f5f5f5;
|
||
border-radius: 27rpx;
|
||
margin-right: 40rpx;
|
||
padding: 9rpx 24rpx;
|
||
transition: all 0.3s ease;
|
||
|
||
&.active {
|
||
color: #FF4767;
|
||
background: #FFECEF;
|
||
border: 1rpx solid #FFB0BD;
|
||
border-radius: 29rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
.filter-area {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 10rpx 0;
|
||
|
||
.filter-text {
|
||
font-size: 24rpx;
|
||
color: #666666;
|
||
margin-right: 6rpx;
|
||
}
|
||
|
||
.filter-icon {
|
||
width: 16rpx;
|
||
height: 10rpx;
|
||
transition: transform 0.3s ease;
|
||
/* 展开时图标倒转 */
|
||
&.rotate {
|
||
transform: rotate(180deg);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 核心抽屉动画布局 */
|
||
.filter-panel {
|
||
position: fixed;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
z-index: 100; /* 低于 Tab区的101,保证隐藏时躲在其后 */
|
||
pointer-events: none; /* 面板关闭时,穿透点击到底部列表 */
|
||
overflow: hidden; /* 防止抽屉向上滑出时外溢 */
|
||
|
||
&.show {
|
||
pointer-events: auto; /* 打开时恢复点击拦截 */
|
||
.filter-mask {
|
||
opacity: 1;
|
||
}
|
||
.filter-container {
|
||
transform: translateY(50rpx); /* 滑出 */
|
||
}
|
||
}
|
||
|
||
.filter-mask {
|
||
position: absolute;
|
||
top: 0; left: 0; right: 0; bottom: 0;
|
||
background: rgba(0,0,0,0.4);
|
||
opacity: 0;
|
||
transition: opacity 0.3s ease-in-out;
|
||
}
|
||
|
||
.filter-container {
|
||
position: absolute;
|
||
top: 0; left: 0; right: 0;
|
||
background: #fff;
|
||
border-radius: 0 0 30rpx 30rpx;
|
||
padding: 40rpx 30rpx;
|
||
max-height: 80vh;
|
||
display: flex;
|
||
flex-direction: column;
|
||
box-shadow: 0 10rpx 20rpx rgba(0,0,0,0.05);
|
||
transform: translateY(-100%); /* 默认隐藏在上方(即Tab背后) */
|
||
transition: transform 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
|
||
}
|
||
}
|
||
|
||
/* 垂直分组设计的样式(图3) */
|
||
.filter-scroll {
|
||
max-height: 50vh;
|
||
}
|
||
.filter-group {
|
||
margin-bottom: 30rpx;
|
||
|
||
.group-title {
|
||
font-weight: 500;
|
||
font-size: 28rpx;
|
||
color: #333333;
|
||
line-height: 40rpx;
|
||
margin-bottom: 20rpx;
|
||
}
|
||
|
||
.pill-list {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 20rpx;
|
||
}
|
||
}
|
||
|
||
/* 通用胶囊按钮 */
|
||
.pill-item {
|
||
width: calc(25% - 16rpx); /* 25%是一行四个,减去间距 */
|
||
height: 58rpx;
|
||
background: #F5F5F5;
|
||
font-weight: 400;
|
||
font-size: 26rpx;
|
||
color: #333333;
|
||
line-height: 37rpx;
|
||
|
||
/* 使用 flex 居中 */
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
|
||
border-radius: 12rpx;
|
||
transition: all 0.3s;
|
||
box-sizing: border-box; /* 防止 padding 会撑大盒子 */
|
||
|
||
&.active {
|
||
background: #FFF0F2;
|
||
color: #FF4767;
|
||
border: 1rpx solid #FFB0BD;
|
||
}
|
||
}
|
||
|
||
.course-filter {
|
||
display: flex;
|
||
gap: 20rpx;
|
||
/* padding: 20rpx 0 40rpx; */
|
||
|
||
.course-type-item {
|
||
background: #F5F5F5;
|
||
color: #666666;
|
||
font-size: 26rpx;
|
||
padding: 12rpx 40rpx;
|
||
border-radius: 12rpx;
|
||
|
||
&.active {
|
||
background: #FFF0F2;
|
||
color: #FF4767;
|
||
}
|
||
}
|
||
}
|
||
|
||
.filter-footer {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
margin-top: 20rpx;
|
||
padding-top: 20rpx;
|
||
/* border-top: 1rpx solid #F5F5F5; */
|
||
|
||
.reset-btn, .confirm-btn {
|
||
width: 47%;
|
||
text-align: center;
|
||
padding: 20rpx 0;
|
||
border-radius: 40rpx;
|
||
font-size: 28rpx;
|
||
}
|
||
|
||
.reset-btn {
|
||
background: #F5F5F5;
|
||
color: #666;
|
||
}
|
||
|
||
.confirm-btn {
|
||
background: #FF4767;
|
||
color: #fff;
|
||
}
|
||
}
|
||
|
||
/* 内容区缩进补充 */
|
||
.collection-content {
|
||
padding: 0 24rpx;
|
||
margin-top: 20rpx;
|
||
}
|
||
|
||
.brand-grid {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
justify-content: space-between;
|
||
|
||
.brand-card-wrap {
|
||
width: 49.2%;
|
||
margin-bottom: 20rpx;
|
||
}
|
||
}
|
||
|
||
.course-list {
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.empty-state {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 120rpx 0;
|
||
|
||
.empty-icon {
|
||
width: 346rpx;
|
||
height: 373rpx;
|
||
}
|
||
}
|
||
|
||
::v-deep .icon-headle {
|
||
width: 32rpx !important;
|
||
height: 32rpx !important;
|
||
}
|
||
</style> |