首页公共接口

main
king 1 year ago
parent 25c4f85381
commit 9973c5b6fd
  1. 16
      src/api/home.ts
  2. 15
      src/components/tabs/tabs.scss
  3. 42
      src/pages/home/components/adware.tsx
  4. 4
      src/pages/home/components/curRecommended.tsx
  5. 7
      src/pages/home/components/feature.tsx
  6. 53
      src/pages/home/components/feature_recommended.tsx
  7. 51
      src/pages/home/home.module.scss
  8. 31
      src/pages/home/home.tsx
  9. 1
      src/pages/preview/brand/info/info.module.scss
  10. 25
      src/pages/preview/illness/sort/sort.module.scss
  11. 17
      src/pages/preview/illness/sort/sort.tsx
  12. 1
      src/pages/preview/profession/profession.tsx
  13. 4
      types/home.d.ts

@ -16,7 +16,7 @@ export interface AdwareLinkType {
}
export interface AdwareType {
image_path:string
image_path: string
advert_link: AdwareLinkType
scope_id: number | string
id: number
@ -29,6 +29,14 @@ export interface AdwareType {
end_time?: number
}
export interface HomeData {
adverts: AdwareType[]
skill: Kill[]
health: Health[]
brand: Brand[]
illness: Illness[]
}
export const HomeApi = {
advert(only_flag: string) {
return request<AdwareType[]>("/home/v1/advert/unique?only_flag=" + only_flag, "GET")
@ -61,11 +69,17 @@ export const HomeApi = {
skillList(categoryId: number, page: number, page_size: number) {
return request<{ data: Kill[], total: number }>('/home/v1/skill/index', "GET", {categoryId, page, page_size})
},
skillSetPlay(id: number) {
return request(`/home/v1/skill/set_play/${id}`, "PUT")
},
/** 疾病知识 */
illness(page: number, page_size: number) {
return request<{ list: Illness[], total: number }>('/home/v1/article/illness_list', "GET", {page, page_size})
},
category(type: number) {
return request<Category[]>('/home/v1/category/index/info?type=' + type, "GET")
},
home() {
return request<HomeData>('/home/v1/home/home_page', "GET", {count: 3})
}
}

@ -17,9 +17,20 @@ View::-webkit-scrollbar {
text-align: center;
}
.tabs-item {
padding: 20rpx;
font-size: 36rpx;
font-family: PingFang SC-Medium, PingFang SC;
font-weight: 500;
color: #606563;
}
.current {
position: relative;
font-size: 36rpx;
font-family: PingFang SC-Bold, PingFang SC;
font-weight: bold;
color: #323635;
&:after {
position: absolute;
@ -37,10 +48,6 @@ View::-webkit-scrollbar {
transition: all 200ms;
}
}
.tabs-item {
padding: 20rpx;
}
}
@keyframes spread {

@ -1,16 +1,25 @@
import {Image, Swiper, SwiperItem, View} from "@tarojs/components";
import {FC, useState} from "react";
import {AdwareType, HomeApi} from "@/api";
import {FC, useEffect, useState} from "react";
import {AdwareType} from "@/api";
import Taro from "@tarojs/taro";
import styles from '../home.module.scss'
const Adware: FC = () => {
const [data, setData] = useState<AdwareType[]>([])
interface Props {
data: any[]
only_flag: string
width: number
}
const Adware: FC<Props> = ({data, only_flag, width}) => {
const [adverts, setAdverts] = useState<AdwareType[]>([])
const [space, setSpace] = useState<any | null>(null)
async function getAdware() {
const res = await HomeApi.advert('home_space')
setData(res)
}
useEffect(() => {
const res = data.find(d => d.only_flag === only_flag)
setSpace(res)
setAdverts(res?.adverts || [])
}, [data])
function jumpAdware(url: string) {
if (url.substring(0, 3) === 'wx:') {
@ -20,34 +29,33 @@ const Adware: FC = () => {
}
}
Taro.useLoad(getAdware)
return (
<View>
{
data.length === 1 && <Image
src={data[0].image_url}
adverts.length === 1 && <Image
src={adverts[0].image_url}
mode='scaleToFill'
lazyLoad
fadeIn
onClick={() => jumpAdware(data[0].image_path)}
style={{width: width + "rpx", height: (space.height / space.width) * width + "rpx"}}
onClick={() => jumpAdware(adverts[0].image_path)}
className={styles.adware}/>
}
{
data.length > 1 && <Swiper
adverts.length > 1 && <Swiper
indicatorDots
autoplay
circular
style={{width: width + "rpx", height: (space.height / space.width) * width + "rpx", overflow: 'hidden'}}
indicatorActiveColor='rgba(255,255,255,0.5)'
className={styles.adware}>
{data.map(d => <SwiperItem key={d.id}>
{adverts.map(d => <SwiperItem key={d.id}>
<Image
src={d.image_url}
mode='widthFix'
lazyLoad
fadeIn
onClick={() => jumpAdware(d.image_path)}
style={{width: "100%"}}/>
style={{width: width + "rpx", height: '100%'}}/>
</SwiperItem>)}
</Swiper>
}

@ -37,7 +37,7 @@ const CurRecommended: FC = () => {
return (
<>
{
data.length > 0 && <View className='mt-6'>
data.length > 0 && <View className='mt-8'>
<Image src={courseTag} mode='widthFix' className={styles.courseTag}/>
<View className={'py-2 flex justify-between flex-wrap ' + styles.videoListBox}>
{
@ -52,7 +52,7 @@ const CurRecommended: FC = () => {
</View>
</View>
}
<View className='text-center'>- -</View>
<View className='text-center text-muted pb-3 font-28'>- -</View>
</>
)
}

@ -4,6 +4,7 @@ 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 styles from '../home.module.scss'
import Taro from "@tarojs/taro";
const Feature: FC = () => {
@ -19,11 +20,11 @@ const Feature: FC = () => {
}
return (
<View className='flex justify-around mt-4'>
<View className='flex justify-around' style={{marginBottom: '20px'}}>
{
list.map(d => <View className='text-center' onClick={() => jump(d.url)}>
<Image src={d.image} style={{width: '48px',height: '48px'}} />
<View className='mt-1 text-dark font-26 mt-1'>{d.text}</View>
<Image src={d.image} style={{width: '48px', height: '48px'}}/>
<View className={styles.featureList}>{d.text}</View>
</View>)
}
</View>

@ -25,9 +25,17 @@ interface Data {
url: string
detailsUrl: string
data: DataContent[]
type?: 'health' | 'kill'
}
const FeatureRecommended: FC = () => {
interface Props {
skill: Kill[] // 技能
health: Health[] // 健康
brand: Brand[] // 品牌
illness: Illness[] // 疾病
}
const FeatureRecommended: FC<Props> = (props) => {
const [data, setData] = useState<Data[]>([
{
titleUrl: brandTop,
@ -39,13 +47,15 @@ const FeatureRecommended: FC = () => {
titleUrl: healthTop,
url: '/pages/preview/health/health',
detailsUrl: '/pages/preview/videoFull/videoFull',
data: []
data: [],
type: "health"
},
{
titleUrl: professionTop,
url: '/pages/preview/profession/profession',
detailsUrl: '/pages/preview/videoFull/videoFull',
data: []
data: [],
type: 'kill'
},
{
titleUrl: illnessTop,
@ -58,8 +68,7 @@ const FeatureRecommended: FC = () => {
/** 品牌 */
async function getBrand(): Promise<DataContent[]> {
try {
const res = await HomeApi.brand(1, 3)
return res.list.map<DataContent>(d => ({
return props.brand.map<DataContent>(d => ({
id: d.id,
title: d.name,
imageUrl: d.brand_album,
@ -67,6 +76,7 @@ const FeatureRecommended: FC = () => {
path: `?id=${d.id}`,
}))
} catch (e) {
console.log(e)
}
return []
}
@ -74,8 +84,7 @@ const FeatureRecommended: FC = () => {
/** 健康知识 */
async function getHealth(): Promise<DataContent[]> {
try {
const res = await HomeApi.healthTop(3)
return res.map<DataContent>(d => ({
return props.health?.map<DataContent>(d => ({
id: d.id,
title: d.title,
imageUrl: d.url_path,
@ -90,8 +99,7 @@ const FeatureRecommended: FC = () => {
/** 技能 */
async function getKill(): Promise<DataContent[]> {
try {
const res = await HomeApi.skillTop(3)
return res.map<DataContent>(d => ({
return props.skill.map<DataContent>(d => ({
id: d.id,
imageUrl: d.url_path,
description: d.introduction,
@ -106,12 +114,11 @@ const FeatureRecommended: FC = () => {
/** 疾病 */
async function getIllness(): Promise<DataContent[]> {
try {
const res = await HomeApi.illness(1, 3)
return res.list.map<DataContent>(d => ({
return props.illness.map<DataContent>(d => ({
id: d.id,
imageUrl: '',
description: d.content,
title: d.title,
description: d.description,
title: d.name,
path: `?id=${d.id}`
}))
} catch (e) {
@ -128,15 +135,23 @@ const FeatureRecommended: FC = () => {
oldData[3].data = illness
setData(oldData)
})
}, [])
}, [props])
function jump(url: string) {
// TODO 后续增加播放量使用公共接口
function jump(url: string, playId?: number, type?: 'health' | 'kill') {
if (playId && type) {
if (type === 'health') {
HomeApi.healthSetPlay(playId)
} else if (type === 'kill') {
HomeApi.skillSetPlay(playId)
}
}
Taro.navigateTo({url})
}
return (
<View className={styles.feature}>
<Swiper nextMargin='30px' style={{height: '250px'}}>
<Swiper nextMargin='30px' style={{height: '263px'}}>
{
data.map(d => <SwiperItem key={d.url}>
<Image
@ -147,14 +162,14 @@ const FeatureRecommended: FC = () => {
d.data.map((c, index) => <View
className='flex mb-3'
key={c.id}
onClick={() => jump(d.detailsUrl + c.path)}>
onClick={() => jump(d.detailsUrl + c.path, c.id, d.type)}>
<View>
<Image src={c.imageUrl} className={styles.featureImage} mode='aspectFill'/>
<Image src={[first, second, third][index]} className={styles.ranking} mode='aspectFill'/>
</View>
<View className={styles.featureText}>
<View className='text-ellipsis text-secondary'>{c.title}</View>
<View className='font-26 mt-1 text-muted text-ellipsis'>{c.description}</View>
<View className={styles.featureTextTitle}>{c.title}</View>
<View className={styles.featureTextDescription}>{c.description}</View>
</View>
</View>)
}

@ -1,5 +1,5 @@
.tipsLogin {
padding: 24rpx;
padding: 20px;
color: #fff;
align-items: center;
position: fixed;
@ -9,7 +9,10 @@
justify-content: space-between;
width: 100%;
box-sizing: border-box;
background: rgba(#000, .7);
background: rgba(#000, .6);
font-size: 28rpx;
font-family: PingFang SC-Medium, PingFang SC;
font-weight: 500;
}
@ -48,18 +51,25 @@
}
.adware {
//margin-top: 40rpx;
width: 100%;
height: 260rpx;
border-radius: 16rpx;
overflow: hidden;
background: #eee;
margin-bottom: 40rpx;
}
.videoListBox {
border-radius: 20px;
}
.featureList {
font-size: 28rpx;
font-family: PingFang SC-Medium, PingFang SC;
font-weight: 500;
color: #323635;
margin-top: 10px;
}
.courseTag {
width: 200px;
margin: auto;
@ -70,7 +80,7 @@
color: #323635;
background: #fff;
padding: 30rpx 0 30rpx 30rpx;
margin-top: 40rpx;
margin-bottom: 40rpx;
border-radius: 30rpx;
}
@ -83,16 +93,39 @@
width: calc(100% - 140px - 50px);
}
.featureTextTitle {
font-size: 30rpx;
font-family: PingFang SC-Medium, PingFang SC;
font-weight: 500;
color: #323635;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
-o-text-overflow: ellipsis;
line-height: 2;
}
.featureTextDescription {
font-size: 24rpx;
font-family: PingFang SC-Medium, PingFang SC;
font-weight: 500;
color: #909795;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
-o-text-overflow: ellipsis;
}
.ranking {
position: absolute;
left: 24rpx;
width: 24px;
height: 24px;
width: 40px;
height: 40px;
}
.featureImage {
width: 140px;
height: 90px;
height: 100px;
background: #eee;
border-radius: 12rpx;
overflow: hidden;

@ -1,4 +1,4 @@
import {FC} from "react";
import {FC, useEffect, useState} from "react";
import {View} from "@tarojs/components";
import styles from "./home.module.scss";
// import {Search} from "@/pages/home/components/search";
@ -8,19 +8,40 @@ import FeatureRecommended from "@/pages/home/components/feature_recommended";
import CurRecommended from "@/pages/home/components/curRecommended";
import MyButton from "@/components/button/MyButton";
import {Profile} from "@/store";
import Taro from "@tarojs/taro";
import {HomeApi, HomeData} from "@/api";
const Home: FC = () => {
const {token, empty} = Profile.useContainer()
const {token} = Profile.useContainer()
const [data, setData] = useState<null | HomeData>(null)
function unLogin() {
Taro.removeStorageSync('profile')
Taro.navigateTo({url: '/pages/login/login'})
}
useEffect(() => {
HomeApi.home().then(res => {
setData(res)
})
}, [])
return (
<View className={styles.content} style={{paddingTop: '20px'}}>
{/*<Search/>*/}
<Adware/>
<Adware data={data?.adverts || []} only_flag='routine_home_top_banner' width={710}/>
<Feature/>
<FeatureRecommended/>
<FeatureRecommended
illness={(data?.illness as any)?.list || []}
health={data?.health || []}
brand={((data?.brand as any)?.list) || []}
skill={data?.skill || []}
/>
<Adware data={data?.adverts || []} only_flag='routine_home_recommend_banner' width={710}/>
<CurRecommended/>
{
!token && <View className={styles.tipsLogin} onClick={empty}>
!token && <View className={styles.tipsLogin} onClick={unLogin}>
<View>~</View>
<MyButton fillet size='mini'></MyButton>
</View>

@ -26,7 +26,6 @@ page{
position: -webkit-sticky;
top: 0;
padding:40rpx 30rpx 30rpx 30rpx;
border-radius: 32rpx;
background-color: #fff;
.title{
font-size: 32rpx;

@ -1,4 +1,4 @@
.scrollView{
.scrollView {
position: fixed;
top: 0;
bottom: 0;
@ -9,19 +9,18 @@
}
.firstOrder {
width: 300rpx;
width: 400rpx;
height: 100%;
View {
width: 100%;
text-align: center;
min-height: 100rpx;
color: #323635;
color: #606563;
display: flex;
align-items: center;
padding: 10rpx;
padding: 20rpx 20rpx 20rpx 30rpx;
box-sizing: border-box;
justify-content: center;
font-size: 28rpx;
}
}
@ -36,8 +35,8 @@
&:after {
content: '';
display: block;
width: 8rpx;
height: 60rpx;
width: 6rpx;
height: 40rpx;
background: #45D4A8;
position: absolute;
left: 0;
@ -65,6 +64,10 @@
background: #fff;
box-sizing: border-box;
height: 100%;
font-size: 28rpx;
font-family: PingFang SC-Bold, PingFang SC;
font-weight: bold;
color: #323635;
}
.list {
@ -77,3 +80,9 @@
display: flex;
align-items: center;
}
.back {
padding: 25rpx 10rpx 20rpx 30rpx;
width: 30rpx;
height: 30rpx;
}

@ -14,11 +14,9 @@ const Sort: FC = () => {
const [firstId, setFirstId] = useState<number | undefined>(undefined)
const [secondId, setSecondId] = useState<number | undefined>(undefined)
const [list, setList] = useState<any[]>([])
const globalData = Taro.getApp().globalData
const menu = Taro.getMenuButtonBoundingClientRect()
async function getData() {
const res = await HomeApi.category(3)
setData(res)
@ -44,7 +42,6 @@ const Sort: FC = () => {
display: 'flex',
alignItems: "center",
width: menu.left - 10 + 'px',
paddingLeft: '10px'
}
function firstIdChange(id: number) {
@ -75,15 +72,21 @@ const Sort: FC = () => {
<View style={headerStyles}>
<Image src={leftArrow}
mode='widthFix'
style={{width: '15px', height: '15px'}}
className={styles.back}
onClick={() => Taro.navigateBack()}/>
<Tabs tabList={getTabList} onChange={(data) => firstIdChange(data.tab?.value as number)}/>
<View style={{width: '100%'}}>
<View style={{width: '200px', margin: 'auto'}}>
<Tabs
tabList={getTabList}
onChange={(data) => firstIdChange(data.tab?.value as number)}/>
</View>
</View>
</View>
{/*<Search onConfirm={onConfirm}/>*/}
<View className={styles.scrollView} style={{top: `${globalData.statusBarHeight + 59}px`}}>
<ScrollView scrollY className={styles.firstOrder}>
<ScrollView scrollY className={styles.firstOrder} enhanced showScrollbar={false}>
{
data.find(d => d.id === firstId)?.resource_category?.map(d => <View
id={`${prefix}-${d.id}`}
@ -96,6 +99,8 @@ const Sort: FC = () => {
</ScrollView>
<ScrollView
enhanced
showScrollbar={false}
scrollY
className={styles.tree}
scrollWithAnimation>

@ -68,6 +68,7 @@ const Profession = () => {
}
function jump(kill: Kill) {
HomeApi.skillSetPlay(kill.id)
Taro.navigateTo({url: `/pages/preview/videoFull/videoFull?url=${kill.resource.url}&poster=${kill.url_path}&title=${kill.resource.name}`})
}

4
types/home.d.ts vendored

@ -32,7 +32,7 @@ interface Kill {
interface Illness {
id: number
content: string
title: string
description: string
name: string
thumb:string
}

Loading…
Cancel
Save