医学道
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
video/src/pages/preview/brand/article/article.tsx

277 lines
9.5 KiB

import {FC, useCallback, useEffect, useMemo, useRef, useState} from "react";
import {Image, PageContainer, ScrollView, Text, View} from "@tarojs/components";
import Taro, {useRouter} from "@tarojs/taro";
import {ArticleRecord, brandApi, HomeApi} from "@/api";
import styles from "./article.module.scss";
import down from "@/static/img/doubleDown.png";
import {Profile} from "@/store";
import {parse} from "@/utils/marked/marked";
import Empty from "@/components/empty/empty";
import Spin from "@/components/spinner";
import {beforeTime} from "@/utils/time";
import Img from "@/components/image/image";
import Collect from "@/components/collect/collect";
import catalogue from "@/static/img/catalogue-inactive.png";
import Icon from "@/components/icon";
import articlesEvent from "@/hooks/articlesEvent";
const article: FC = () => {
const {token} = Profile.useContainer()
const [enable, setEnable] = useState(true)
const {id} = useRouter().params as unknown as { id: number }
const [articleInfo, setArticleInfo] = useState<ArticleRecord>()
const [ultra, setUltra] = useState(true)
const [show, setShow] = useState(false)
const globalData = Taro.getApp().globalData
const {children, headings} = useMemo(() => parse(articleInfo?.content || ''), [articleInfo])
const query = Taro.createSelectorQuery()
const [maoId, setMaoId] = useState('')
const [timing, setTiming] = useState<NodeJS.Timeout | undefined>(undefined)
const headingTop = useRef<{ id: string; top: number }[]>([])
useEffect(() => {
if(headings.length){
if(headingTop.current?.[0]?.top){
return
}
headings.forEach(item => {
query.select(`#${item.id}`).boundingClientRect().exec((res) => {
if(res.length === headings.length && res?.[0]?.top){
headingTop.current = res
}
})
})
}
},[headings])
useEffect(() => {
setTimeout(() => {
const query = Taro.createSelectorQuery()
query.select('#childrenNode').boundingClientRect((res) => {
if (!Array.isArray(res)) {
console.log({childrenNode: res})
setUltra(globalData.pageHeight * .45 <= res.height)
}
}).exec()
}, 300)
}, [children])
useEffect(() => {
if (!maoId && headings.length) {
setMaoId(headings[0].id)
}
}, [headings])
function mao(id: string) {
setMaoId(id)
setShow(false)
Taro.nextTick(() => {
console.log(headingTop.current,'headingTop.cur')
query.select(`#${id}`).boundingClientRect()
query.exec((res) => {
if (res.length) {
Taro.pageScrollTo({
scrollTop: headingTop.current.find(d => d.id === id)?.top ?? 0,
duration: 300
}
)
}
})
})
}
const onCollect = (v: boolean | undefined) => {
setArticleInfo((s) => ({...s, collect: v} as ArticleRecord))
}
Taro.useReady(() => {
getData().then()
})
Taro.useUnload(() => {
clearTimeout(timing)
})
const getData = useCallback(async () => {
try {
const data = await brandApi.articleInfo(id)
setTiming(setTimeout(() => {
HomeApi.articleViews(id).then(() => {
setArticleInfo({
...data,
page_view: data.page_view + 1
})
articlesEvent.recordsAdd({id: Number(id), view: (data?.page_view || 0) + 1})
})
}, 2000))
Taro.setNavigationBarTitle({title: data.title})
if (data.content.length < 200) {
setUltra(false)
}
setArticleInfo(data)
} catch (e) {
}
setEnable(false)
}, [id])
function helloWorld() {
return (
<>
{
headings.length > 0 && <View className={styles.botmBox}>
<View>
<Collect
select={articleInfo?.collect}
styles={{flexDirection: 'column', justifyContent: 'center'}}
stylesImage={{margin: '0 0 8rpx 0'}}
owner_id={Number(id)}
owner_type={1}
onUpdate={onCollect}
/>
</View>
<View className='flex flex-column justify-center align-center text-center px-10'
onClick={() => setShow(true)}>
<Image src={catalogue} mode='widthFix' style={{width: '36rpx', height: '36rpx', marginBottom: '8rpx'}}/>
<View className='font-26'></View>
</View>
</View>
}
<Spin overlay enable={enable}/>
<View
className={styles.articleBox}
style={{
height: !token ? globalData.pageHeight - 60 + 'px' : 'auto',
overflow: !token ? 'hidden' : 'auto',
boxSizing: 'border-box'
}}>
<View id="childrenNode">
<View className={styles.articleTitle}>{articleInfo?.title}</View>
{
articleInfo?.owner_type === 1 && articleInfo?.brands?.map(d => (
<View key={d.id} className='flex align-center mb-4'>
<View className={`${styles.article} flex-1`}>
<Img src={d.logo} width={80} height={80} className={styles.articleImag} errorType='avatar'/>
<View className='ml-2'>
<View>{d?.name}</View>
<View className='flex mt-1 text-muted font-24'>
<View className='mr-2'>{beforeTime(articleInfo?.created_at)} . </View>
<View> {articleInfo.page_view || 0}</View>
</View>
</View>
</View>
<View className='ml-2'>
<Collect
select={articleInfo?.collect}
styles={{flexDirection: 'column', justifyContent: 'center', padding: '20rpx'}}
stylesImage={{margin: '0 0 8rpx 0'}}
owner_id={Number(id)}
owner_type={1}
textHidden
onUpdate={onCollect}
/>
</View>
</View>
))
}
{
articleInfo?.owner_type === 2 && articleInfo?.illness?.map(d => (
<View key={d.name} className='flex align-center mb-4'>
<View className={`${styles.article} flex-1`}>
<Img src={''} width={80} height={80} className={styles.articleImag} errorType='health'/>
<View className='ml-2'>
<View>{d.name}</View>
<View className='flex mt-1 text-muted font-24'>
<View className='mr-2'>{beforeTime(articleInfo?.created_at)} . </View>
<View> {articleInfo.page_view || 0}</View>
</View>
</View>
</View>
<View className='ml-2'>
<Collect
select={articleInfo?.collect}
styles={{flexDirection: 'column', justifyContent: 'center', padding: '20rpx'}}
stylesImage={{margin: '0 0 8rpx 0'}}
owner_id={Number(id)}
owner_type={1}
textHidden
onUpdate={onCollect}
/>
</View>
</View>
))
}
{
children.length > 0
? <View>{children}</View>
: <Empty name='暂无数据'/>
}
</View>
</View>
{
!token && ultra && children.length > 0 &&
<View className={styles.fixedBox}>
<View className={styles['fixedBox-inner']}>
<View className={styles['fixedBox-inner-icon']}>
<Image src={down}/>
</View>
<View className={styles['fixedBox-inner-box']}
onClick={() => Taro.navigateTo({url: '/pages/login/login'})}>
<Text></Text>
</View>
</View>
</View>
}
<PageContainer
onClickOverlay={() => setShow(false)}
onAfterLeave={() => setShow(false)}
show={show}
round
overlay
overlayStyle={'background:rgba(0,0,0,0.3)'}
>
<View>
<View className='text-center text-black relative clip'>
<View className='absolute left top bottom flex flex-column justify-center align-center'
style={{width: '58px'}} onClick={() => setShow(false)}>
<Icon name='close' color="#000" bold/>
</View>
<View className='py-3 bold'></View>
</View>
<View className='hr-solid'/>
<ScrollView scrollY={true} style={{height:'50vh'}}>
<View className="px-3 py-5">
{
headings.length > 0 && headings.map((d) => <View
key={d.id}
className="pb-3"
style={{
fontSize: '28rpx',
fontWeight: '500',
color: maoId === d.id ? '#45D4A8' : '#323635',
marginLeft: 24 * (d.level - 1) + 'px',
}}
onClick={() => mao(d.id)}>
{d.text}
</View>
)
}
</View>
</ScrollView>
</View>
</PageContainer>
</>
)
}
return helloWorld()
}
export default article