Commit 55fd03cc by zhengxiao

feat(custom): 新增首页

parent 631af7bf
<template>
<view class="section-block">
<view class="block-header">
<view class="left">
<text class="title">{{ title }}</text>
<text class="desc">{{ subtitle }}</text>
</view>
<view class="study-count">{{ studyCount }}万人已学习</view>
</view>
<view class="course-list">
<view
class="course-item"
v-for="(item, index) in showCourseList"
:key="index"
>
<image
class="course-img"
:src="item.image || '/static/images/course-placeholder.png'"
mode="aspectFill"
/>
<view class="course-info">
<view class="course-title">{{item.title}}</view>
<view class="course-desc">{{item.desc}}</view>
<view class="course-meta">
<text class="enroll-count">{{item.enrollCount}}人已报名</text>
<button class="study-btn">去学习</button>
</view>
</view>
</view>
</view>
<view v-if="courseList.length > 2" class="show-more" @tap="toggleShowMore">
<text>{{isExpanded ? '收起合集' : '展开更多'}}</text>
<text :class="['arrow', isExpanded ? 'up' : '']"></text>
</view>
</view>
</template>
<script>
export default {
name: 'CourseBlock',
props: {
title: {
type: String,
required: true
},
subtitle: {
type: String,
required: true
},
studyCount: {
type: Number,
required: true
},
courseList: {
type: Array,
default: () => []
}
},
data() {
return {
isExpanded: false
}
},
computed: {
showCourseList() {
return this.isExpanded ? this.courseList : this.courseList.slice(0, 2)
}
},
methods: {
toggleShowMore() {
this.isExpanded = !this.isExpanded
}
}
}
</script>
<style lang="scss">
.section-block {
margin: 20rpx;
padding: 30rpx;
background: #fff;
border-radius: 16rpx;
.block-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 24rpx;
.left {
.title {
font-size: 32rpx;
font-weight: 500;
color: #333;
margin-bottom: 8rpx;
display: block;
}
.desc {
font-size: 24rpx;
color: #999;
}
}
.study-count {
font-size: 24rpx;
color: #999;
background: #F5F6F8;
padding: 8rpx 16rpx;
border-radius: 20rpx;
}
}
.course-list {
.course-item {
display: flex;
padding: 24rpx 0;
border-bottom: 1rpx solid #EBEDF0;
&:last-child {
border-bottom: none;
}
.course-img {
width: 160rpx;
height: 160rpx;
border-radius: 12rpx;
margin-right: 20rpx;
background: #F5F6F8;
}
.course-info {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
.course-title {
font-size: 28rpx;
font-weight: 500;
color: #333;
margin-bottom: 8rpx;
}
.course-desc {
font-size: 24rpx;
color: #999;
margin-bottom: 20rpx;
}
.course-meta {
display: flex;
justify-content: space-between;
align-items: center;
.enroll-count {
font-size: 24rpx;
color: #999;
display: flex;
align-items: center;
&::before {
content: '';
display: inline-block;
width: 24rpx;
height: 24rpx;
// background: url('/static/icons/user.png') no-repeat center/cover;
margin-right: 8rpx;
}
}
.study-btn {
font-size: 26rpx;
color: #666;
background: #F5F6F8;
padding: 8rpx 24rpx;
border-radius: 24rpx;
border: none;
}
}
}
}
}
.show-more {
text-align: center;
padding-top: 20rpx;
font-size: 26rpx;
color: #999;
.arrow {
margin-left: 8rpx;
font-size: 20rpx;
display: inline-block;
transition: transform 0.3s ease;
&.up {
transform: rotate(180deg);
}
}
}
}
</style>
\ No newline at end of file
...@@ -4,6 +4,14 @@ ...@@ -4,6 +4,14 @@
}, },
"pages": [ "pages": [
{ {
"path": "pages/home/home",
"style": {
"navigationStyle": "custom",
"navigationBarTextStyle": "black",
"enablePullDownRefresh": false
}
},
{
"path": "pages/my/my", "path": "pages/my/my",
"style": { "style": {
"navigationStyle": "custom", "navigationStyle": "custom",
...@@ -45,6 +53,25 @@ ...@@ -45,6 +53,25 @@
"navigationBarBackgroundColor": "#ffffff", "navigationBarBackgroundColor": "#ffffff",
"backgroundColor": "#ffffff", "backgroundColor": "#ffffff",
"backgroundTextStyle": "dark" "backgroundTextStyle": "dark"
},
"tabBar": {
"color": "#76787C",
"selectedColor": "#55B5F3",
"iconWidth": "24px",
"spacing": "9px",
"list": [
{
"pagePath": "pages/home/home",
"text": "首页",
"iconPath": "/static/tab_home.png",
"selectedIconPath": "/static/tab_home_selected.png"
},
{
"text": "我的",
"pagePath": "pages/my/my",
"iconPath": "/static/tab_my.png",
"selectedIconPath": "/static/tab_my_selected.png"
}
]
} }
} }
<template>
<view class="container">
<!-- 顶部搜索区域 - 添加安全区域 -->
<view class="search-area">
<!-- 使用微信小程序的胶囊高度适配 -->
<view
class="status-bar"
:style="{
height: statusBarHeight + 'px',
}"
></view>
<view class="search-tags">
<text class="tag">体系化专业课程</text>
<text class="tag">·</text>
<text class="tag">顶尖大师亲身教学</text>
<text class="tag">·</text>
<text class="tag">平台服务保障</text>
</view>
</view>
<!-- 导航菜单 -->
<view class="nav-menu">
<view class="nav-item">
<view class="nav-icon dark"></view>
<text>新手入门</text>
</view>
<view class="nav-item">
<view class="nav-icon dark"></view>
<text>实操进阶</text>
</view>
<view class="nav-item">
<view class="nav-icon dark"></view>
<text>咨询流派</text>
</view>
<view class="nav-item">
<view class="nav-icon dark"></view>
<text>公开课</text>
</view>
<view class="nav-item">
<view class="nav-icon dark"></view>
<text>全部课程</text>
</view>
</view>
<!-- 会员提示区 -->
<view class="vip-tips">
<view class="left-content">
<view class="tag-wrapper">
<image class="tag-bg" src="/static/images/tag-bg.png" mode="aspectFit" />
<text class="tag-text">免费资料</text>
</view>
<view class="text-content">
<text class="main-text">100G 资料包已送达...</text>
<text class="sub-text">AI实战进阶超全资料包免费领取</text>
</view>
</view>
<view class="right-action">
<text class="action-text">去领福利</text>
</view>
</view>
<!-- 执业入驻区域 -->
<view class="career-section">
<view class="section-header">
<view class="title-wrapper">
<view class="title-bar"></view>
<text class="title">执业入驻</text>
</view>
<text class="subtitle">心理咨询执业培养计划</text>
</view>
<!-- 切换按钮组 -->
<view class="career-tabs">
<view class="tab-items">
<view
v-for="(tab, index) in tabs"
:key="index"
:class="['tab-item', currentTab === index ? 'active' : '']"
@tap="switchTab(index)"
>{{ tab }}</view>
</view>
<view class="slider" :style="{ transform: `translateX(${currentTab * 100}%)` }"></view>
</view>
<!-- 内容区域 -->
<swiper
class="content-swiper"
:current="currentTab"
@change="handleSwiperChange"
>
<swiper-item v-for="(tab, index) in tabs" :key="index">
<view class="consultant-card">
<view class="card-title">心理咨询师一对一从业规划</view>
<view class="card-subtitle">专业老师1v1教你入行</view>
<view class="card-features">
<view class="feature-item">
<image src="/static/icons/doc.png" mode="aspectFit" />
<text>入行资料</text>
</view>
<view class="feature-item">
<image src="/static/icons/group.png" mode="aspectFit" />
<text>社群加餐</text>
</view>
<view class="feature-item">
<image src="/static/icons/guide.png" mode="aspectFit" />
<text>学习指导</text>
</view>
<view class="feature-item">
<image src="/static/icons/plan.png" mode="aspectFit" />
<text>职业规划</text>
</view>
</view>
<view class="card-footer">
<text class="footer-text">壹点灵成长规划师,1V1教你入行</text>
<button class="consult-btn">立即咨询</button>
</view>
</view>
</swiper-item>
</swiper>
</view>
<!-- 课程列表区域 -->
<view class="course-section">
<!-- 权威证书 -->
<course-block
title="权威证书"
subtitle="收获成功道路的通行证"
:studyCount="2.1"
:courseList="certificateList"
></course-block>
<!-- 咨询伦理系列 -->
<course-block
title="咨询伦理系列"
subtitle="专业伦理规范指导"
:studyCount="1.8"
:courseList="ethicsList"
></course-block>
<!-- 认知行为系列 -->
<course-block
title="认知行为系列"
subtitle="CBT理论与实操"
:studyCount="1.8"
:courseList="cbtList"
></course-block>
</view>
</view>
</template>
<script>
import courseBlock from '@/components/course-block.vue'
export default {
name: 'HomePage',
components: {
courseBlock // 直接使用对象形式注册组件
},
data() {
return {
title: '壹点灵心理学课程',
appid: '__UNI__2A0BB9F',
courseList: [],
bannerList: [],
statusBarHeight: 0,
currentTab: 1, // 默认选中"成为咨询师"
tabs: ['入行分析', '成为咨询师', '咨询师进阶'],
certificateList: [
{
title: '社会心理服务中级·人社部能建中心',
desc: '解开关系中的结,告别恨、消耗...',
enrollCount: 3240,
image: '/static/images/course-placeholder.png'
},
{
title: '社会心理服务中级·人社部能建中心',
desc: '解开关系中的结,告别恨、消耗...',
enrollCount: 3240,
image: '/static/images/course-placeholder.png'
},
{
title: '社会心理服务中级·人社部能建中心',
desc: '解开关系中的结,告别恨、消耗...',
enrollCount: 3240,
image: '/static/images/course-placeholder.png'
},
// ... 其他证书课程
],
ethicsList: [
{
title: '咨询伦理基础课程',
desc: '建立专业伦理意识,提升职业素养...',
enrollCount: 2156,
image: '/static/images/course-placeholder.png'
},
// ... 其他伦理课程
],
cbtList: [
{
title: 'CBT理论基础与应用',
desc: '认知行为疗法的核心理论与技术...',
enrollCount: 1892,
image: '/static/images/course-placeholder.png'
},
// ... 其他CBT课程
]
}
},
onLoad() {
this.getCourseList()
// 获取系统信息设置状态栏高度
const systemInfo = wx.getSystemInfoSync()
this.statusBarHeight = systemInfo.statusBarHeight
},
methods: {
getCourseList() {
console.log('getCourseList')
},
getBannerList() {
console.log('getBannerList')
},
switchTab(index) {
this.currentTab = index
},
handleSwiperChange(e) {
this.currentTab = e.detail.current
}
},
}
</script>
<style lang="scss">
.container {
min-height: 100vh;
background: #f5f5f5;
}
.search-area {
background: #fff;
.status-bar {
width: 100%;
}
.search-tags {
display: flex;
align-items: center;
justify-content: center;
padding: 20rpx;
.tag {
font-size: 24rpx;
color: #666;
&:nth-child(even) {
margin: 0 10rpx;
color: #999;
}
}
}
}
.nav-menu {
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx 40rpx;
background: #fff;
.nav-item {
display: flex;
flex-direction: column;
align-items: center;
gap: 12rpx;
.nav-icon {
width: 88rpx;
height: 88rpx;
border-radius: 50%;
background: #fff;
box-shadow: 0 0 10rpx rgba(0, 0, 0, 0.05);
&.dark {
background: #4A5B67;
}
}
text {
font-size: 26rpx;
color: #666;
}
}
}
.vip-tips {
margin: 20rpx;
padding: 30rpx;
background: #fff;
border-radius: 16rpx;
display: flex;
justify-content: space-between;
align-items: center;
.left-content {
flex: 1;
.tag-wrapper {
position: relative;
display: inline-flex;
align-items: center;
margin-bottom: 16rpx;
.tag-bg {
width: 140rpx;
height: 40rpx;
}
.tag-text {
position: absolute;
left: 16rpx;
color: #fff;
font-size: 22rpx;
font-weight: 500;
}
}
.text-content {
display: flex;
flex-direction: column;
gap: 8rpx;
.main-text {
font-size: 32rpx;
color: #333;
font-weight: 500;
}
.sub-text {
font-size: 24rpx;
color: #999;
}
}
}
.right-action {
.action-text {
font-size: 26rpx;
color: #666;
background: #F5F6F8;
padding: 12rpx 24rpx;
border-radius: 30rpx;
}
}
}
.career-section {
margin: 20rpx;
background: #fff;
border-radius: 16rpx;
padding: 30rpx;
.section-header {
margin-bottom: 24rpx;
.title-wrapper {
display: flex;
align-items: center;
gap: 12rpx;
margin-bottom: 8rpx;
.title-bar {
width: 6rpx;
height: 32rpx;
background: #333;
border-radius: 3rpx;
}
.title {
font-size: 32rpx;
font-weight: 500;
color: #333;
}
}
.subtitle {
font-size: 24rpx;
color: #999;
}
}
.career-tabs {
position: relative;
background: #F7F8FA;
border-radius: 12rpx;
padding: 8rpx;
margin-bottom: 24rpx;
.tab-items {
display: flex;
position: relative;
z-index: 1;
}
.tab-item {
flex: 1;
text-align: center;
padding: 16rpx 0;
font-size: 28rpx;
color: #666;
position: relative;
z-index: 2;
transition: color 0.3s;
&.active {
color: #333;
font-weight: 500;
}
}
.slider {
position: absolute;
left: 8rpx;
top: 8rpx;
width: calc(33.33% - 6rpx);
height: calc(100% - 16rpx);
background: #fff;
border-radius: 8rpx;
transition: transform 0.3s ease;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
}
}
.content-swiper {
height: 500rpx; // 根据实际内容调整高度
.consultant-card {
height: 100%;
background: #F7F8FA;
border-radius: 12rpx;
padding: 30rpx;
.card-title {
font-size: 36rpx;
font-weight: bold;
color: #333;
margin-bottom: 8rpx;
}
.card-subtitle {
font-size: 26rpx;
color: #666;
margin-bottom: 40rpx;
}
.card-features {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20rpx;
margin-bottom: 40rpx;
.feature-item {
display: flex;
flex-direction: column;
align-items: center;
gap: 8rpx;
image {
width: 64rpx;
height: 64rpx;
background: #fff;
border-radius: 16rpx;
padding: 12rpx;
}
text {
font-size: 24rpx;
color: #666;
}
}
}
.card-footer {
display: flex;
justify-content: space-between;
align-items: center;
background: #fff;
padding: 24rpx;
border-radius: 8rpx;
.footer-text {
font-size: 28rpx;
color: #333;
font-weight: 500;
}
.consult-btn {
background: #333;
color: #fff;
font-size: 26rpx;
padding: 12rpx 32rpx;
border-radius: 30rpx;
border: none;
}
}
}
}
}
.course-section {
padding-bottom: 40rpx;
.section-block {
margin: 20rpx;
padding: 30rpx;
background: #fff;
border-radius: 16rpx;
.block-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 24rpx;
.left {
.title {
font-size: 32rpx;
font-weight: 500;
color: #333;
margin-bottom: 8rpx;
display: block;
}
.desc {
font-size: 24rpx;
color: #999;
}
}
.study-count {
font-size: 24rpx;
color: #999;
background: #F5F6F8;
padding: 8rpx 16rpx;
border-radius: 20rpx;
}
}
.course-list {
.course-item {
display: flex;
padding: 24rpx 0;
border-bottom: 1rpx solid #EBEDF0;
&:last-child {
border-bottom: none;
}
.course-img {
width: 160rpx;
height: 160rpx;
border-radius: 12rpx;
margin-right: 20rpx;
background: #F5F6F8;
}
.course-info {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
.course-title {
font-size: 28rpx;
font-weight: 500;
color: #333;
margin-bottom: 8rpx;
}
.course-desc {
font-size: 24rpx;
color: #999;
margin-bottom: 20rpx;
}
.course-meta {
display: flex;
justify-content: space-between;
align-items: center;
.enroll-count {
font-size: 24rpx;
color: #999;
display: flex;
align-items: center;
&::before {
content: '';
display: inline-block;
width: 24rpx;
height: 24rpx;
//background: url('/static/icons/user.png') no-repeat center/cover;
margin-right: 8rpx;
}
}
.study-btn {
font-size: 26rpx;
color: #666;
background: #F5F6F8;
padding: 8rpx 24rpx;
border-radius: 24rpx;
border: none;
}
}
}
}
}
.show-more {
text-align: center;
padding-top: 20rpx;
font-size: 26rpx;
color: #999;
.arrow {
margin-left: 8rpx;
font-size: 20rpx;
}
}
}
}
</style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment