Compare commits

...

3 Commits

  1. 6
      src/api/brand.ts
  2. 12
      src/api/home.ts
  3. 12
      src/components/image/image.module.scss
  4. 26
      src/components/image/image.tsx
  5. 27
      src/components/videoList/videoList.module.scss
  6. 35
      src/components/videoList/videoList.tsx
  7. 1
      src/pages/business/videoInfo/components/catalogue.tsx
  8. 2
      src/pages/business/videoInfo/videoInfo.tsx
  9. 21
      src/pages/home/components/feature_recommended.tsx
  10. 7
      src/pages/preview/brand/article/article.module.scss
  11. 3
      src/pages/preview/brand/list/list.tsx
  12. 29
      src/pages/preview/health/health.tsx
  13. 9
      src/pages/preview/profession/profession.module.scss
  14. 32
      src/pages/preview/profession/profession.tsx
  15. 17
      src/pages/preview/videoFull/videoFull.module.scss
  16. 102
      src/pages/preview/videoFull/videoFull.tsx
  17. BIN
      src/static/img/brandSecond.png
  18. BIN
      src/static/img/healthShard.png
  19. BIN
      src/static/img/professionShard.png
  20. BIN
      src/static/img/组 498@2x.png
  21. 1
      types/curriculum.d.ts
  22. 17
      types/home.d.ts
  23. 5
      types/user.d.ts

@ -20,7 +20,7 @@ export type ArticleRecord = {
created_at: string created_at: string
content: string content: string
brands: BrandRecord[] brands: BrandRecord[]
collect:boolean collect: boolean
} }
export const brandApi = { export const brandApi = {
@ -45,4 +45,8 @@ export const brandApi = {
articleInfo(id: number) { articleInfo(id: number) {
return request<ArticleRecord>(`/home/v1/article/${id}`, "GET") return request<ArticleRecord>(`/home/v1/article/${id}`, "GET")
}, },
/** 品牌 & 健康详情 */
videoInfo(id: number | string) {
return request<VideList>(`/home/v1/health/${id}`, "GET")
}
} }

@ -31,8 +31,8 @@ export interface AdwareType {
export interface HomeData { export interface HomeData {
adverts: AdwareType[] adverts: AdwareType[]
skill: Kill[] skill: VideList[]
health: Health[] health: VideList[]
brand: { brand: {
list: Brand[] list: Brand[]
} }
@ -56,10 +56,10 @@ export const HomeApi = {
}, },
/** 健康管理 */ /** 健康管理 */
healthTop(count: number) { healthTop(count: number) {
return request<Health[]>('/home/v1/health/top', "GET", {count}) return request<VideList[]>('/home/v1/health/top', "GET", {count})
}, },
health(page: number, page_size: number) { health(page: number, page_size: number) {
return request<{ data: Health[], total: number }>('/home/v1/health/index', "GET", {page, page_size}) return request<{ data: VideList[], total: number }>('/home/v1/health/index', "GET", {page, page_size})
}, },
/** 增加播放量 */ /** 增加播放量 */
healthSetPlay(id) { healthSetPlay(id) {
@ -71,13 +71,13 @@ export const HomeApi = {
}, },
/** 技能 */ /** 技能 */
skillTop(count: number) { skillTop(count: number) {
return request<Kill[]>('/home/v1/skill/top', "GET", {count}) return request<VideList[]>('/home/v1/skill/top', "GET", {count})
}, },
skillCategory() { skillCategory() {
return request<Category[]>('/home/v1/skill/category', "GET") return request<Category[]>('/home/v1/skill/category', "GET")
}, },
skillList(categoryId: number, page: number, page_size: number) { skillList(categoryId: number, page: number, page_size: number) {
return request<{ data: Kill[], total: number }>('/home/v1/skill/index', "GET", {categoryId, page, page_size}) return request<{ data: VideList[], total: number }>('/home/v1/skill/index', "GET", {categoryId, page, page_size})
}, },
skillSetPlay(id: number) { skillSetPlay(id: number) {
return request(`/home/v1/skill/set_play/${id}`, "PUT") return request(`/home/v1/skill/set_play/${id}`, "PUT")

@ -1,12 +0,0 @@
.imgBox {
position: relative;
}
.imgError {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
margin: auto;
}

@ -1,15 +1,17 @@
import {FC, useEffect, useState} from "react"; import {FC, useEffect, useState} from "react";
import {Image, ImageProps, View} from "@tarojs/components"; import {Image, ImageProps, View} from "@tarojs/components";
import shard from '@/static/img/shard.png' import shard from '@/static/img/shard.png'
import styles from './image.module.scss'
import Taro from "@tarojs/taro"; import Taro from "@tarojs/taro";
import avatar from '@/static/img/avatar.png' import avatar from '@/static/img/avatar.png'
import healthShard from '@/static/img/healthShard.png'
import professionShard from '@/static/img/professionShard.png'
import brandSecond from '@/static/img/brandSecond.png'
interface Props extends ImageProps { interface Props extends ImageProps {
width?: number | string width?: number | string
height?: number | string height?: number | string
fallback?: string fallback?: string
errorType?: "acquiesce" | 'avatar' errorType?: ImgErrType
} }
const Img: FC<Props> = ({src, mode = 'aspectFill', width, height, fallback = shard, ...props}) => { const Img: FC<Props> = ({src, mode = 'aspectFill', width, height, fallback = shard, ...props}) => {
@ -34,6 +36,15 @@ const Img: FC<Props> = ({src, mode = 'aspectFill', width, height, fallback = sha
case "avatar": case "avatar":
setErrorUrl(avatar) setErrorUrl(avatar)
break break
case 'health':
setErrorUrl(healthShard)
break
case 'profession':
setErrorUrl(professionShard)
break
case 'brand':
setErrorUrl(brandSecond)
break
} }
}, [props.errorType]) }, [props.errorType])
@ -53,11 +64,12 @@ const Img: FC<Props> = ({src, mode = 'aspectFill', width, height, fallback = sha
return ( return (
<View <View
style={{ style={{
width: `${width}rpx`, overflow: 'hidden',
height: `${height}rpx`, width: width ? `${width}rpx` : "100%",
height: height ? `${height}rpx` : "100%",
backgroundColor: (isError || !loading) ? 'transparent' : '#F8F8F8' backgroundColor: (isError || !loading) ? 'transparent' : '#F8F8F8'
}} }}
className={`${props?.className} ${styles.imgBox}`}> className={`${props?.className}`}>
{!isError && {!isError &&
<View animation={animationData}> <View animation={animationData}>
<Image <Image
@ -79,14 +91,12 @@ const Img: FC<Props> = ({src, mode = 'aspectFill', width, height, fallback = sha
{ {
isError && !loading && isError && !loading &&
<Image <Image
className={styles.imgError} mode='widthFix'
mode='aspectFill'
src={errorUrl} src={errorUrl}
lazyLoad lazyLoad
fadeIn fadeIn
style={{ style={{
width: "100%", width: "100%",
height: "100%",
}}/> }}/>
} }
</View> </View>

@ -0,0 +1,27 @@
.container {
width: 100%;
padding: 20rpx;
box-sizing: border-box;
columns: 2;
column-gap: 20rpx;
}
.health {
break-inside: avoid;
background: #fff;
border-radius: 10px;
overflow: hidden;
margin-bottom: 20rpx;
position: relative;
}
.play {
position: absolute;
min-height: 70rpx !important;
z-index: 9999;
width: 40rpx !important;
height: 40rpx !important;
top: 20rpx;
right: 20rpx;
background: transparent !important;
}

@ -0,0 +1,35 @@
import {FC} from "react";
import styles from "@/pages/preview/health/health.module.scss";
import {Image, Text, View} from "@tarojs/components";
import Img from "@/components/image/image";
import play from "@/static/img/play-back.png";
import {formatDate} from "@/utils/time";
import Taro from "@tarojs/taro";
interface Props {
data: VideList
errorType?: ImgErrType
}
const VideoList: FC<Props> = ({data, errorType}) => {
function jump() {
Taro.preload(data)
Taro.navigateTo({url: `/pages/preview/videoFull/videoFull?id=${data.id}`})
}
return (
<View key={data.id} className={styles.health} onClick={jump}>
<Img src={data.url_path} mode='widthFix' errorType={errorType}/>
<Image src={play} className={styles.play} mode='aspectFit'/>
<View className='p-1'>
<View className='text-ellipsis-2 text-dark'>{data.title}</View>
<View className='text-ellipsis-2 mt-1 font-26 text-secondary'>{data.introduction}</View>
<View className='font-24 text-muted my-2 flex justify-between'>
<Text>{formatDate(new Date(data.publish_time), "YY-MM-dd")}</Text>
<Text>{data.video_view}</Text>
</View>
</View>
</View>)
}
export default VideoList

@ -195,6 +195,7 @@ const Catalogue: FC<Props> = ({data, setHors, id, playId}) => {
<Collect <Collect
owner_id={id} owner_id={id}
owner_type={3} owner_type={3}
select={data?.course.collect}
styles={{flexDirection: 'column', justifyContent: 'center', padding: '20rpx'}} styles={{flexDirection: 'column', justifyContent: 'center', padding: '20rpx'}}
stylesImage={{margin: '0 0 8rpx 0'}}/> stylesImage={{margin: '0 0 8rpx 0'}}/>
<View className='px-2' onClick={() => setShow(true)}> <View className='px-2' onClick={() => setShow(true)}>

@ -106,7 +106,7 @@ const VideoInfo: FC = () => {
{ {
playId playId
? <Course id={playId} courseId={id} curEnd={curEnd} preview={preview}/> ? <Course id={playId} courseId={id} curEnd={curEnd} preview={preview}/>
: <Img width={750} height={500} src={data?.course.thumb || ''} mode='aspectFill'/> : <Img width={750} height={500} src={data?.course.thumb || ''} errorType='health'/>
} }
</View> </View>

@ -26,12 +26,13 @@ interface Data {
url: string url: string
detailsUrl: string detailsUrl: string
data: DataContent[] data: DataContent[]
errorType: ImgErrType
type?: 'health' | 'kill' type?: 'health' | 'kill'
} }
interface Props { interface Props {
skill: Kill[] // 技能 skill: VideList[] // 技能
health: Health[] // 健康 health: VideList[] // 健康
brand: Brand[] // 品牌 brand: Brand[] // 品牌
illness: Illness[] // 疾病 illness: Illness[] // 疾病
} }
@ -42,27 +43,31 @@ const FeatureRecommended: FC<Props> = (props) => {
titleUrl: brandTop, titleUrl: brandTop,
url: '/pages/preview/brand/list/list', url: '/pages/preview/brand/list/list',
detailsUrl: '/pages/preview/brand/info/info', detailsUrl: '/pages/preview/brand/info/info',
data: [] data: [],
errorType: 'brand',
}, },
{ {
titleUrl: healthTop, titleUrl: healthTop,
url: '/pages/preview/health/health', url: '/pages/preview/health/health',
detailsUrl: '/pages/preview/videoFull/videoFull', detailsUrl: '/pages/preview/videoFull/videoFull',
data: [], data: [],
type: "health" type: "health",
errorType: 'health'
}, },
{ {
titleUrl: professionTop, titleUrl: professionTop,
url: '/pages/preview/profession/profession', url: '/pages/preview/profession/profession',
detailsUrl: '/pages/preview/videoFull/videoFull', detailsUrl: '/pages/preview/videoFull/videoFull',
data: [], data: [],
type: 'kill' type: 'kill',
errorType: 'profession'
}, },
{ {
titleUrl: illnessTop, titleUrl: illnessTop,
url: '/pages/preview/illness/sort/sort', url: '/pages/preview/illness/sort/sort',
detailsUrl: '/pages/preview/illness/list/list', detailsUrl: '/pages/preview/illness/list/list',
data: [] data: [],
errorType: 'health'
}, },
]) ])
@ -153,7 +158,7 @@ const FeatureRecommended: FC<Props> = (props) => {
<View className={styles.feature}> <View className={styles.feature}>
<Swiper nextMargin='30px' style={{height: '390rpx'}} circular autoplay> <Swiper nextMargin='30px' style={{height: '390rpx'}} circular autoplay>
{ {
data.filter(d=>d.data.length === 3).map(d => <SwiperItem key={d.url}> data.filter(d => d.data.length === 3).map(d => <SwiperItem key={d.url}>
<Image <Image
mode='heightFix' mode='heightFix'
className={styles.featureTitle} className={styles.featureTitle}
@ -166,7 +171,7 @@ const FeatureRecommended: FC<Props> = (props) => {
onClick={() => jump(d.detailsUrl + c.path, c.id, d.type)}> onClick={() => jump(d.detailsUrl + c.path, c.id, d.type)}>
<View style={{position: 'relative'}}> <View style={{position: 'relative'}}>
<View className={styles.featureImage}> <View className={styles.featureImage}>
<Img src={c.imageUrl} height={100} width={140}/> <Img src={c.imageUrl} height={100} width={140} errorType={d.errorType}/>
</View> </View>
<Image src={[first, second, third][index]} className={styles.ranking} mode='aspectFill'/> <Image src={[first, second, third][index]} className={styles.ranking} mode='aspectFill'/>
</View> </View>

@ -1,3 +1,7 @@
page{
background: #fff !important;
}
.fixedBox { .fixedBox {
position: fixed; position: fixed;
z-index: 1000; z-index: 1000;
@ -74,8 +78,5 @@
} }
.articleBox { .articleBox {
background: #fff;
min-height: calc(100vh - env(safe-area-inset-bottom) + 180rpx);
box-sizing: border-box;
padding: 30rpx 30rpx calc(env(safe-area-inset-bottom) + 150rpx) 30rpx; padding: 30rpx 30rpx calc(env(safe-area-inset-bottom) + 150rpx) 30rpx;
} }

@ -20,6 +20,7 @@ const BrandItem: FC<{ data: BrandRecord; onClick: VoidFunction }> = ({data, onCl
} else if (data.brand_album) { } else if (data.brand_album) {
media = <Img media = <Img
height={320} height={320}
errorType='profession'
src={data.brand_album.split(",")[0]} src={data.brand_album.split(",")[0]}
mode="aspectFill" mode="aspectFill"
style={{background: '#ededed'}} style={{background: '#ededed'}}
@ -36,7 +37,7 @@ const BrandItem: FC<{ data: BrandRecord; onClick: VoidFunction }> = ({data, onCl
height={76} height={76}
src={data.logo} src={data.logo}
mode='aspectFill' mode='aspectFill'
errorType='avatar' errorType='brand'
className="rounded-10 clip" className="rounded-10 clip"
style={{background: '#ededed'}} style={{background: '#ededed'}}
/> />

@ -1,24 +1,25 @@
import {FC, useEffect, useState} from "react"; import {FC, useEffect, useState} from "react";
import {Image, Text, View} from "@tarojs/components"; import {View} from "@tarojs/components";
import {HomeApi} from "@/api"; import {HomeApi} from "@/api";
import Taro, {useReachBottom} from "@tarojs/taro"; import {useReachBottom} from "@tarojs/taro";
import styles from './health.module.scss' import styles from './health.module.scss'
import play from '@/static/img/play-back.png'
import Empty from "@/components/empty/empty"; import Empty from "@/components/empty/empty";
import Spin from "@/components/spinner"; import Spin from "@/components/spinner";
import Img from "@/components/image/image"; import VideoList from "@/components/videoList/videoList";
import {formatDate} from "@/utils/time";
const Health: FC = () => { const Health: FC = () => {
const [page, setPage] = useState(1) const [page, setPage] = useState(1)
const [data, setData] = useState<Health[]>([]) const [data, setData] = useState<VideList[]>([])
const [total, setTotal] = useState(0) const [total, setTotal] = useState(0)
const [enable, setEnable] = useState(true) const [enable, setEnable] = useState(true)
async function getData(page: number) { async function getData(page: number) {
try { try {
const res = await HomeApi.health(page, 10) const res = await HomeApi.health(page, 10)
setData(res.data) setData([
...data,
...res.data
])
setTotal(res.total) setTotal(res.total)
} catch (e) { } catch (e) {
} }
@ -33,10 +34,6 @@ const Health: FC = () => {
getData(page) getData(page)
}, [page]) }, [page])
function jump(health: Health) {
HomeApi.healthSetPlay(health.id)
Taro.navigateTo({url: `/pages/preview/videoFull/videoFull?url=${health.resource.url}&poster=${health.url_path}&title=${health.title}`})
}
return ( return (
<> <>
@ -45,15 +42,7 @@ const Health: FC = () => {
{ {
data.length > 0 ? <> data.length > 0 ? <>
<View className={styles.container}> <View className={styles.container}>
{data.map(d => <View key={d.id} className={styles.health} onClick={() => jump(d)}> {data.map(d => <VideoList data={d} errorType='health'/>)}
<Img width={370} height={345} src={d.url_path} mode='widthFix'/>
<Image src={play} className={styles.play} mode='aspectFit'/>
<View className='text-ellipsis-2 m-2 text-dark'>{d.title}</View>
<View className='font-26 text-muted mx-2 mb-2 flex justify-between'>
<Text>{formatDate(new Date(d.publish_time), "YY-MM-dd")}</Text>
<Text>{d.video_view}</Text>
</View>
</View>)}
</View> </View>
<View className='text-center font-24 text-dark mt-2'></View> <View className='text-center font-24 text-dark mt-2'></View>
</> </>

@ -1,3 +1,12 @@
.container {
width: 100%;
padding: 20rpx;
box-sizing: border-box;
columns: 2;
column-gap: 20rpx;
position: relative;
}
.height { .height {
height: calc(100vh - 80rpx - env(safe-area-inset-bottom)); height: calc(100vh - 80rpx - env(safe-area-inset-bottom));
overflow: hidden; overflow: hidden;

@ -6,10 +6,10 @@ import Empty from "@/components/empty/empty";
import Taro from "@tarojs/taro"; import Taro from "@tarojs/taro";
import styles from './profession.module.scss' import styles from './profession.module.scss'
import Spin from "@/components/spinner"; import Spin from "@/components/spinner";
import Img from "@/components/image/image"; import VideoList from "@/components/videoList/videoList";
interface KillData { interface KillData {
data: Kill[] data: VideList[]
total: number total: number
page: number page: number
} }
@ -19,6 +19,7 @@ const Profession = () => {
const [categoryId, setCategoryId] = useState<number | null>(null) const [categoryId, setCategoryId] = useState<number | null>(null)
const [data, setData] = useState<Map<number, KillData>>(new Map) const [data, setData] = useState<Map<number, KillData>>(new Map)
const [enable, setEnable] = useState(true) const [enable, setEnable] = useState(true)
const [loading, setLoading] = useState(false)
/** /**
* more * more
@ -35,6 +36,7 @@ const Profession = () => {
} }
try { try {
setLoading(true)
const res = await HomeApi.skillList(categoryId!, page, 10) const res = await HomeApi.skillList(categoryId!, page, 10)
const dataList = res.data.reduce((pre, cur) => { const dataList = res.data.reduce((pre, cur) => {
const index = pre.findIndex(d => d.id === cur.id) const index = pre.findIndex(d => d.id === cur.id)
@ -54,6 +56,7 @@ const Profession = () => {
setData(oldData) setData(oldData)
} catch (e) { } catch (e) {
} }
setLoading(false)
} }
useEffect(() => { useEffect(() => {
@ -75,10 +78,6 @@ const Profession = () => {
setCategoryId(tab.tab?.value as number) setCategoryId(tab.tab?.value as number)
} }
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}`})
}
function swiperChange(e) { function swiperChange(e) {
const categoryId = tabs[e.target.current].value const categoryId = tabs[e.target.current].value
@ -89,21 +88,21 @@ const Profession = () => {
function KillList(data: KillData): JSX.Element { function KillList(data: KillData): JSX.Element {
if (!data?.data?.length) { if (!data?.data?.length) {
return <Empty name='暂无数据'/> return (
<Empty name='暂无数据'/>
)
} }
return ( return (
<ScrollView <ScrollView
scrollY scrollY
onScrollToLower={() => getData(true)} onScrollToLower={() => getData(true)}
className={styles.height}> className={styles.height}>
{ <View className={styles.container}>
data.data.map(d =>
<View className={styles.killBox} onClick={() => jump(d)}> {
<Img width={320} height={180} src={d.url_path} mode='widthFix' className={styles.image}/> data.data.map(d => <VideoList data={d} errorType='profession'/>)
<View className='text-ellipsis flex-1'>{d?.resource?.name}</View> }
</View> </View>
)
}
<View className='text-center font-24 text-dark mt-2'></View> <View className='text-center font-24 text-dark mt-2'></View>
</ScrollView> </ScrollView>
) )
@ -123,7 +122,8 @@ const Profession = () => {
className={styles.height} className={styles.height}
style={{paddingTop: '10px'}}> style={{paddingTop: '10px'}}>
{ {
tabs.map(d => <SwiperItem key={d.title}> tabs.map(d => <SwiperItem key={d.title} className='relative'>
<Spin enable={loading} block/>
{KillList(data.get(Number(d.value))!)} {KillList(data.get(Number(d.value))!)}
</SwiperItem>) </SwiperItem>)
} }

@ -1,3 +1,8 @@
page {
background: #000 !important;
min-height: 100vh;
}
.video { .video {
width: 100%; width: 100%;
height: 100vh; height: 100vh;
@ -5,15 +10,19 @@
top: 0; top: 0;
left: 0; left: 0;
right: 0; right: 0;
bottom: 0; bottom: calc(env(safe-area-inset-bottom) + 250rpx);
margin: auto; margin: auto;
background: #000; background: #000;
} }
.title { .title {
position: fixed; position: fixed;
z-index: 9999; z-index: 10;
top: 20rpx; bottom: env(safe-area-inset-bottom);
left: 20rpx; width: 100%;
color: #fff; color: #fff;
padding: 0 30rpx;
box-sizing: border-box;
background: #000;
width: 100%;
} }

@ -2,28 +2,52 @@ import {Video, View} from "@tarojs/components";
import {FC, useState} from "react"; import {FC, useState} from "react";
import Taro from "@tarojs/taro"; import Taro from "@tarojs/taro";
import styles from './videoFull.module.scss' import styles from './videoFull.module.scss'
import {brandApi} from "@/api";
import Collect from "@/components/collect/collect";
import Spin from "@/components/spinner";
interface Params { interface Params {
url: string id: string
poster?: string
title?: string
} }
const VideoFull: FC = () => { const VideoFull: FC = () => {
const params = Taro.useRouter().params as unknown as Params const {id} = Taro.useRouter().params as unknown as Params
const video = Taro.createVideoContext('myVideo') const video = Taro.createVideoContext('myVideo')
const [palying, setpalying] = useState(false) const [palying, setpalying] = useState(false)
const [data, setData] = useState<VideList | null>(null)
const [enable, setEnable] = useState<boolean>(!Taro.getCurrentInstance().preloadData)
Taro.useLoad(() => { Taro.useLoad(() => {
console.log(params) const preloadData: VideList = Taro.getCurrentInstance().preloadData as VideList
if (!params.url) { if (preloadData) {
Taro.showModal({ setData(preloadData)
title: '播放地址错',
success() {
Taro.navigateBack()
}
})
} }
brandApi.videoInfo(id).then(res => {
if (!res?.resource?.url) {
Taro.showModal({
title: '加载资源失败',
confirmText: '退出',
showCancel: true,
success() {
Taro.navigateBack()
}
})
}
setData(res)
}).catch(() => {
if (!preloadData) {
Taro.showModal({
title: '加载资源失败',
confirmText: '退出',
showCancel: true,
success() {
Taro.navigateBack()
}
})
}
}).finally(() => {
setEnable(false)
})
}) })
function click() { function click() {
@ -46,28 +70,38 @@ const VideoFull: FC = () => {
} }
return ( return (
<> <View>
{params.title && <View className={styles.title}>{params.title}</View>} {
<Video data ? <>
posterSize='100%' <Video
id={'myVideo'} posterSize='100%'
onClick={click} id={'myVideo'}
className={styles.video} onClick={click}
controls className={styles.video}
// poster={params.poster} controls
src={params.url} src={data?.resource?.url}
autoplay autoplay
showCenterPlayBtn showCenterPlayBtn
autoPauseIfOpenNative autoPauseIfOpenNative
autoPauseIfNavigate autoPauseIfNavigate
playBtnPosition='center' playBtnPosition='center'
showFullscreenBtn={false} showFullscreenBtn={false}
enableProgressGesture={false} enableProgressGesture={false}
onPlay={() => setpalying(true)} onPlay={() => setpalying(true)}
onPause={() => setpalying(false)} onPause={() => setpalying(false)}
onError={onError} onError={onError}
/> />
</> <View className={styles.title}>
<View className='flex'>
<View className='font-36 font-weight flex-1 pr-3 text-row1'>{data.title}</View>
<Collect owner_id={Number(id)} owner_type={2} styles={{color: '#fff'}} select={data.collects}/>
</View>
<View className='font-32 mt-1 text-ellipsis-2'>{data.introduction}</View>
</View>
</> : <Spin enable={enable} overlay/>
}
</View>
) )
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

@ -8,6 +8,7 @@ interface Curriculum {
id: number; id: number;
title: string; title: string;
charge: number; charge: number;
collect:boolean
/** 课时 */ /** 课时 */
class_hour: number; class_hour: number;
created_at: string; created_at: string;

17
types/home.d.ts vendored

@ -1,4 +1,4 @@
interface Health { interface VideList {
id: number id: number
title: string title: string
introduction: string introduction: string
@ -7,6 +7,7 @@ interface Health {
/** 播放量 */ /** 播放量 */
video_view: number video_view: number
publish_time:string publish_time:string
collects:boolean
} }
interface Brand { interface Brand {
@ -23,13 +24,13 @@ interface Resource {
url: string url: string
} }
interface Kill { // interface Kill {
id: number // id: number
resource: Resource // resource: Resource
introduction:string // introduction:string
title: string // title: string
url_path: string // url_path: string
} // }
interface Illness { interface Illness {
id: number id: number

5
types/user.d.ts vendored

@ -109,5 +109,10 @@ interface Create {
owner_type: CreateOwnerType owner_type: CreateOwnerType
} }
type ImgErrType = "acquiesce" // 默认
| 'avatar' // 头像
| 'health' // 健康
| 'profession' // 技能
| 'brand' // 品牌

Loading…
Cancel
Save