@ -0,0 +1,37 @@ |
||||
import {request} from "@/api/request"; |
||||
|
||||
export interface AdwareParams { |
||||
key: string |
||||
value: string |
||||
|
||||
[key: string]: string |
||||
} |
||||
|
||||
export interface AdwareLinkType { |
||||
id: number |
||||
api_name: string |
||||
path: string |
||||
param: string |
||||
} |
||||
|
||||
export interface AdwareType { |
||||
advert_link: AdwareLinkType |
||||
scope_id: number | string |
||||
id: number |
||||
name: string |
||||
status: 0 | 1 // 禁用
|
||||
sort: number |
||||
image_url: string |
||||
image_link: string |
||||
start_time: number |
||||
end_time?: number |
||||
} |
||||
|
||||
export const HomeApi = { |
||||
advert(only_flag: string) { |
||||
return request<AdwareType[]>("/home/v1/advert/unique?only_flag=" + only_flag, "GET") |
||||
}, |
||||
course(page: number, page_size: number) { |
||||
return request<{ data: Curriculum[], total: number }>('/home/v1/course/course', "GET", {page, page_size}) |
||||
} |
||||
} |
@ -0,0 +1,51 @@ |
||||
import {Image, Swiper, SwiperItem, View} from "@tarojs/components"; |
||||
import {FC, useState} from "react"; |
||||
import {AdwareType, HomeApi} from "@/api"; |
||||
import Taro from "@tarojs/taro"; |
||||
import styles from '../home.module.scss' |
||||
import {jumpAdware} from "@/utils/pathFormt"; |
||||
|
||||
const Adware: FC = () => { |
||||
const [data, setData] = useState<AdwareType[]>([]) |
||||
|
||||
async function getAdware() { |
||||
const res = await HomeApi.advert('home_swiper') |
||||
setData(res) |
||||
} |
||||
|
||||
Taro.useLoad(getAdware) |
||||
|
||||
return ( |
||||
<View> |
||||
{ |
||||
data.length === 1 && <Image |
||||
src={data[0].image_url} |
||||
mode='widthFix' |
||||
lazyLoad |
||||
fadeIn |
||||
onClick={() => jumpAdware(data[0].advert_link)} |
||||
className={styles.adware}/> |
||||
} |
||||
{ |
||||
data.length > 1 && <Swiper |
||||
indicatorDots |
||||
autoplay |
||||
circular |
||||
indicatorActiveColor='rgba(255,255,255,0.5)' |
||||
className={styles.adware}> |
||||
{data.map(d => <SwiperItem key={d.id}> |
||||
<Image |
||||
src={d.image_url} |
||||
mode='widthFix' |
||||
lazyLoad |
||||
fadeIn |
||||
onClick={() => jumpAdware(d.advert_link)} |
||||
style={{width: "100%"}}/> |
||||
</SwiperItem>)} |
||||
</Swiper> |
||||
} |
||||
</View> |
||||
) |
||||
} |
||||
|
||||
export default Adware |
@ -0,0 +1,59 @@ |
||||
import {FC, useEffect, useState} from "react"; |
||||
import {Image, View} from "@tarojs/components"; |
||||
import {HomeApi} from "@/api"; |
||||
import {useReachBottom} from "@tarojs/taro"; |
||||
import styles from "../home.module.scss"; |
||||
import VideoCover from "@/components/videoCover/videoCover"; |
||||
import courseTag from '@/static/img/courseTag.png' |
||||
|
||||
const CurRecommended: FC = () => { |
||||
const [page, setPage] = useState(1) |
||||
const [data, setData] = useState<Curriculum[]>([]) |
||||
const [total, setTotal] = useState(0) |
||||
|
||||
async function getData() { |
||||
const res = await HomeApi.course(page, 4) |
||||
setTotal(res.total) |
||||
const newData = res.data.reduce((pre, cut) => { |
||||
const index = pre.findIndex(d => d.id === cut.id) |
||||
if (index === 1) { |
||||
pre.push(cut) |
||||
} else { |
||||
pre.splice(index, 1, cut) |
||||
} |
||||
return pre |
||||
}, data) |
||||
setData(newData) |
||||
} |
||||
|
||||
useEffect(() => { |
||||
getData() |
||||
}, [page]) |
||||
|
||||
useReachBottom(() => { |
||||
data.length < total && setPage(page + 1) |
||||
}) |
||||
|
||||
return ( |
||||
<> |
||||
{ |
||||
data.length > 0 && <View className='mt-4'> |
||||
<Image src={courseTag} mode='widthFix' className={styles.courseTag}/> |
||||
<View className={'py-2 flex justify-between flex-wrap ' + styles.videoListBox}> |
||||
{ |
||||
data.map(c => <VideoCover |
||||
thumb={c.thumb} |
||||
title={c.title} |
||||
id={c.id} |
||||
depId={c.id} |
||||
key={c.id} |
||||
/>) |
||||
} |
||||
</View> |
||||
</View> |
||||
} |
||||
</> |
||||
) |
||||
} |
||||
|
||||
export default CurRecommended |
@ -0,0 +1,33 @@ |
||||
import {FC} from "react"; |
||||
import {Image, View} from "@tarojs/components"; |
||||
import illness from '@/static/img/illness.png' |
||||
import profession from '@/static/img/profession.png' |
||||
import health from '@/static/img/health.png' |
||||
import article from '@/static/img/article.png' |
||||
import Taro from "@tarojs/taro"; |
||||
|
||||
const Feature: FC = () => { |
||||
const list = [ |
||||
{url: '', image: article, text: '品牌'}, |
||||
{url: '', image: health, text: '健康管理'}, |
||||
{url: '', image: profession, text: '专业技能'}, |
||||
{url: '', image: illness, text: '疾病知识'}, |
||||
] |
||||
|
||||
function jump(url) { |
||||
Taro.navigateTo({url}) |
||||
} |
||||
|
||||
return ( |
||||
<View className='flex justify-between mt-4'> |
||||
{ |
||||
list.map(d => <View className='text-center' onClick={() => jump(d.url)}> |
||||
<Image src={d.image} style={{width: '50px'}} mode='widthFix'/> |
||||
<View className='mt-1'>{d.text}</View> |
||||
</View>) |
||||
} |
||||
</View> |
||||
) |
||||
} |
||||
|
||||
export default Feature |
@ -0,0 +1,43 @@ |
||||
import {FC, useState} from "react"; |
||||
import {Swiper, SwiperItem, View} from "@tarojs/components"; |
||||
import styles from '../home.module.scss' |
||||
import Taro from "@tarojs/taro"; |
||||
|
||||
interface DataContent { |
||||
id: number, |
||||
title: string, |
||||
Description: string |
||||
} |
||||
|
||||
interface Data { |
||||
title: string, |
||||
url: string, |
||||
data: DataContent[] |
||||
} |
||||
|
||||
const FeatureRecommended: FC = () => { |
||||
const [data] = useState<Data[]>([ |
||||
{title: "品牌TOP3", url: '', data: []}, |
||||
{title: "健康", url: '', data: []}, |
||||
{title: "专业技能", url: '', data: []}, |
||||
{title: "疾病知识", url: '', data: []}, |
||||
]) |
||||
|
||||
function jump(url: string) { |
||||
Taro.navigateTo({url}) |
||||
} |
||||
|
||||
|
||||
return ( |
||||
<View className={styles.featureRecommended}> |
||||
<Swiper nextMargin='30px'> |
||||
{ |
||||
data.map(d => <SwiperItem> |
||||
<View onClick={() => jump(d.url)}>{d.title}</View> |
||||
</SwiperItem>) |
||||
} |
||||
</Swiper> |
||||
</View> |
||||
) |
||||
} |
||||
export default FeatureRecommended |
@ -0,0 +1,13 @@ |
||||
import {FC} from "react"; |
||||
import {Text, View} from "@tarojs/components"; |
||||
import styles from "../home.module.scss"; |
||||
import Icon from "@/components/icon"; |
||||
|
||||
export const Search: FC = () => { |
||||
return ( |
||||
<View className={styles.search}> |
||||
<Icon name='search' size={18}/> |
||||
<Text className='ml-1'>搜索课程</Text> |
||||
</View> |
||||
) |
||||
} |
@ -1,4 +1,5 @@ |
||||
export default definePageConfig({ |
||||
navigationBarTitleText: '首页', |
||||
navigationStyle: 'custom', |
||||
onReachBottomDistance: 30 |
||||
}) |
||||
|
@ -0,0 +1,62 @@ |
||||
.content { |
||||
position: relative; |
||||
padding: 0 20px; |
||||
min-height: 90vh; |
||||
box-sizing: border-box; |
||||
width: 750rpx; |
||||
overflow: hidden; |
||||
|
||||
&:after { |
||||
min-height: 100vh; |
||||
position: absolute; |
||||
top: 0; |
||||
left: -10%; |
||||
width: 120%; |
||||
content: ''; |
||||
display: block; |
||||
background: linear-gradient(40deg, #fff 50rpx, #caf0e2, #92ecc5) no-repeat; |
||||
min-height: 100vh; |
||||
background-size: 100% 600rpx; |
||||
filter: blur(50px); |
||||
z-index: -1; |
||||
} |
||||
} |
||||
|
||||
.search { |
||||
width: 710rpx; |
||||
margin: 34rpx 0 0; |
||||
background: #fff; |
||||
border-radius: 100px; |
||||
line-height: 68rpx; |
||||
color: #bbb; |
||||
font-size: 28rpx; |
||||
display: flex; |
||||
align-items: center; |
||||
justify-content: center; |
||||
} |
||||
|
||||
.adware { |
||||
margin-top: 40rpx; |
||||
width: 100%; |
||||
height: 260rpx; |
||||
border-radius: 16rpx; |
||||
overflow: hidden; |
||||
} |
||||
|
||||
.videoListBox { |
||||
border-radius: 20px; |
||||
} |
||||
|
||||
.courseTag { |
||||
width: 200px; |
||||
margin: auto; |
||||
display: block; |
||||
} |
||||
|
||||
.featureRecommended { |
||||
background: #fff; |
||||
padding: 30rpx; |
||||
margin-top: 20rpx; |
||||
border-radius: 16rpx; |
||||
box-shadow: inset -30px -30px 30px rgba(#fff, .9); |
||||
} |
@ -1,13 +0,0 @@ |
||||
import {FC} from "react"; |
||||
import {Text, View} from "@tarojs/components"; |
||||
import styles from "@/pages/index/index.module.scss"; |
||||
import Icon from "@/components/icon"; |
||||
|
||||
export const Search: FC = () => { |
||||
return ( |
||||
<View className={styles.search}> |
||||
<Icon name='search' size={18}/> |
||||
<Text className='ml-1'>搜索课程</Text> |
||||
</View> |
||||
) |
||||
} |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 5.2 KiB |
After Width: | Height: | Size: 453 B |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 457 B |
After Width: | Height: | Size: 466 B |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 1.0 KiB |
@ -0,0 +1,17 @@ |
||||
import {AdwareLinkType, AdwareParams} from "@/api"; |
||||
import Taro from "@tarojs/taro"; |
||||
|
||||
/** 拼接完整路径 */ |
||||
export function jumpAdware(advert_link: AdwareLinkType) { |
||||
if (advert_link.path && advert_link.param) { |
||||
let url = advert_link.path + "?" |
||||
const params: AdwareParams[] = JSON.parse(advert_link.param) |
||||
params.forEach((d, index) => { |
||||
url += d.key + "=" + d.value |
||||
if (index !== params.length - 1) { |
||||
url += "&" |
||||
} |
||||
}) |
||||
Taro.navigateTo({url}) |
||||
} |
||||
} |