Compare commits

...

2 Commits

Author SHA1 Message Date
一杯沧海 29006f34f3 Merge branch 'master' of https://git.yaojiankang.top/xing/video 1 year ago
一杯沧海 c332fdca11 搜索页面bug&个人中心学习记录bug&防抖 1 year ago
  1. 9
      src/components/learningRecord/learningRecord.tsx
  2. 2
      src/pages/my/my.tsx
  3. 162
      src/pages/preview/search/search/components/list.tsx
  4. 5
      src/pages/preview/search/search/index.config.ts
  5. 48
      src/pages/preview/search/search/index.module.scss
  6. 185
      src/pages/preview/search/search/index.tsx
  7. 12
      src/utils/debounce.ts

@ -8,6 +8,7 @@ import styles from './learningRecord.module.scss'
// import Spin from "@/components/spinner"; // import Spin from "@/components/spinner";
import {Profile} from "@/store"; import {Profile} from "@/store";
import Taro from "@tarojs/taro"; import Taro from "@tarojs/taro";
import debounce from "@/utils/debounce";
const tabList: TabList<any>[] = [ const tabList: TabList<any>[] = [
{ {
@ -63,11 +64,15 @@ const LearningRecord: FC<Props> = ({userId, style, className}) => {
Taro.navigateTo({url: '/pages/login/login'}) Taro.navigateTo({url: '/pages/login/login'})
return return
} }
getStatistics(tab?.value! as StatisticsParam) // getStatistics(tab?.value! as StatisticsParam)
debounce(()=>{
// console.log(this,'this')
getStatistics(tab?.value! as StatisticsParam)
})
} }
useEffect(() => { useEffect(() => {
userId && getStatistics(tabList[0].value) userId && setTimeout(() => {getStatistics(tabList[0].value)},500)
}, [userId]) }, [userId])
return (<View className={[styles.box, className].filter(Boolean).join(' ')} style={{display: 'block', ...style}}> return (<View className={[styles.box, className].filter(Boolean).join(' ')} style={{display: 'block', ...style}}>

@ -21,7 +21,6 @@ interface List {
src: string, src: string,
type?: number type?: number
} }
function jump(token: string | null, type?: number) { function jump(token: string | null, type?: number) {
if (!token) { if (!token) {
Taro.navigateTo({url: '/pages/login/login'}) Taro.navigateTo({url: '/pages/login/login'})
@ -169,6 +168,7 @@ const My: FC = () => {
</PageContainer> </PageContainer>
</View> </View>
</View> </View>
) )
} }

@ -4,16 +4,17 @@ import styles from './list.module.scss'
import Taro from "@tarojs/taro"; import Taro from "@tarojs/taro";
import Empty from "@/components/empty/empty"; import Empty from "@/components/empty/empty";
import Img from "@/components/image/image"; import Img from "@/components/image/image";
import {SearchApi} from "@/api/search"; import { SearchApi } from "@/api/search";
import {AtLoadMore} from 'taro-ui' import { AtLoadMore } from 'taro-ui'
import {rfc33392time} from "@/utils/day"; import {rfc33392time} from "@/utils/day";
import play from "@/static/img/play.png"; import play from "@/static/img/play.png";
type Props = { type Props = {
name: string name:string
clear: boolean clear:boolean
} }
const SearchList: FC<Props> = ({name, clear}) => { const SearchList: FC<Props> = ({name,clear}) => {
console.log(name,'name')
const globalData = Taro.getApp().globalData const globalData = Taro.getApp().globalData
const [page, setPage] = useState(1) const [page, setPage] = useState(1)
const [brands, setBrands] = useState<any[]>([]) const [brands, setBrands] = useState<any[]>([])
@ -21,21 +22,21 @@ const SearchList: FC<Props> = ({name, clear}) => {
const [text, setText] = useState('') const [text, setText] = useState('')
const [loading, setLoading] = useState(true) const [loading, setLoading] = useState(true)
useEffect(() => { useEffect(()=>{
if (!clear) { if(!clear){
setBrands([]) setBrands([])
setLoading(true) setLoading(true)
} }
}, [clear]) },[clear])
useEffect(() => { useEffect(() => {
if (name && clear) { if(name && clear){
getData() getData()
} }
}, [page, name, clear]) }, [page,name,clear])
const getData = useCallback(async () => { const getData = useCallback(async () => {
try { try {
const data = await SearchApi.list(page, 10, name) const data = await SearchApi.list(page, 10,name)
if (page === 1) { if (page === 1) {
if (data.data.length < 10) { if (data.data.length < 10) {
setText('没有更多了~') setText('没有更多了~')
@ -45,7 +46,7 @@ const SearchList: FC<Props> = ({name, clear}) => {
setBrands([ setBrands([
...data.data ...data.data
]) ])
} else { }else{
setBrands([ setBrands([
...brands, ...brands,
...data.data ...data.data
@ -56,13 +57,13 @@ const SearchList: FC<Props> = ({name, clear}) => {
} catch (e) { } catch (e) {
} }
setLoading(false) setLoading(false)
}, [page, name]) }, [page,name])
function jumpInfo(id: number, type: string, health: any) { function jumpInfo(id: number,type:string,health:any) {
console.log(type, 'type') console.log(type,'type')
let url = '' let url = ''
switch (type) { switch (type){
case 'brand': case 'brand':
url = '/pages/preview/brand/info/info'; url = '/pages/preview/brand/info/info';
break; break;
@ -73,7 +74,7 @@ const SearchList: FC<Props> = ({name, clear}) => {
url = '/pages/preview/illness/article/article' url = '/pages/preview/illness/article/article'
break break
case 'video_records': case 'video_records':
return Taro.navigateTo({url: `/pages/preview/videoFull/videoFull?url=${health.resources.url}&poster=${health.url_path}&title=${health.title}`}) return Taro.navigateTo({url: `/pages/preview/videoFull/videoFull?url=${health.resources.url}&poster=${health.url_path}&title=${health.title}`})
case 'courses': case 'courses':
url = '/pages/business/videoInfo/videoInfo' url = '/pages/business/videoInfo/videoInfo'
break break
@ -82,13 +83,13 @@ const SearchList: FC<Props> = ({name, clear}) => {
} }
function onScrollToLower() { function onScrollToLower(){
if (brands?.length < total) { if (brands?.length < total) {
setPage(page + 1) setPage(page + 1)
getData().then() getData().then()
} else { } else {
setText('没有更多了~') setText('没有更多了~')
} }
} }
return ( return (
@ -96,71 +97,68 @@ const SearchList: FC<Props> = ({name, clear}) => {
className='scrollview' className='scrollview'
scrollY scrollY
scrollWithAnimation scrollWithAnimation
style={{height: `${globalData.pageHeight - 20}px`, backgroundColor: `#f5f5f5`}} style={{height:`${globalData.windowHeight-140}px`,backgroundColor:`#f5f5f5`}}
onScrollToLower={onScrollToLower} onScrollToLower={onScrollToLower}
> >
{loading && <AtLoadMore status={'loading'}/>} { loading && <AtLoadMore status={'loading'}/>}
{ {
brands.length >= 1 && !loading && brands.length >= 1 && !loading &&
<> <>
{brands.map((d) => {brands.map((d) =>
<View onClick={() => jumpInfo(d.data.id, d.data.table, d.data['@data'])} className={styles.box} <View onClick={() => jumpInfo(d.data.id,d.data.table,d.data['@data'])} className={styles.box} key={d.data.id}>
key={d.data.id}> {
{ d.data.table === 'brand' &&
d.data.table === 'brand' && <>
<> <Img width={128} height={128} src={d.data['@data'].logo} mode='aspectFill' className={styles.image}/>
<Img width={128} height={128} src={d.data['@data'].logo} mode='aspectFill' className={styles.image}/> <View className={styles.rightBox}>
<View className={styles.rightBox}> <View className='font-weight mb-2 font-28'>{d.data.title}</View>
<View className='font-weight mb-2 font-28'>{d.data.title}</View> <View className={styles.desc}>{d.data.content || '暂无品牌简介'}</View>
<View className={styles.desc}>{d.data.content || '暂无品牌简介'}</View> </View>
</View> </>
</> }
} {
{ d.data.table === 'article' &&
d.data.table === 'article' && <>
<> <View className={styles.articleLeftBox}>
<View className={styles.articleLeftBox}> <View className='font-weight mb-2 font-28 lh-40'>{d.data['@data'].title}</View>
<View className='font-weight mb-2 font-28 lh-40'>{d.data['@data'].title}</View> <View className={styles.desc}>{rfc33392time(d.data['@data'].created_at)} {d.data['@data'].page_view}</View>
<View </View>
className={styles.desc}>{rfc33392time(d.data['@data'].created_at)} {d.data['@data'].page_view}</View> <Img width={172} height={128} src={d.data['@data'].logo} mode='aspectFill' className={styles.image}/>
</View> </>
<Img width={172} height={128} src={d.data['@data'].logo} mode='aspectFill' className={styles.image}/> }
</> {
} d.data.table === 'video_records' &&
{ <>
d.data.table === 'video_records' && <Img width={192} height={192} src={d.data['@data'].url_path} mode='aspectFill' className={styles.image}/>
<> <Image src={play} className={styles.play} mode='aspectFit'/>
<Img width={192} height={192} src={d.data['@data'].url_path} mode='aspectFill' <View className={styles.videoRightBox}>
className={styles.image}/> <View className='font-weight mb-2 font-28 lh-40'>{d.data['@data'].title}</View>
<Image src={play} className={styles.play} mode='aspectFit'/> <View className={styles.desc}>{d.data['@data'].introduction}</View>
<View className={styles.videoRightBox}> <View className={`${styles.desc} mt-2`}>: {d.data['@data'].video_view}</View>
<View className='font-weight mb-2 font-28 lh-40'>{d.data['@data'].title}</View> </View>
<View className={styles.desc}>{d.data['@data'].introduction}</View> </>
<View className={`${styles.desc} mt-2`}>: {d.data['@data'].video_view}</View> }
</View> {
</> d.data.table === 'courses' &&
} <>
{ <Img width={192} height={138} src={d.data['@data'].thumb} mode='aspectFill' className={styles.image}/>
d.data.table === 'courses' && <View className={styles.articleLeftBox}>
<> <View className='font-weight mb-2 font-28 lh-40'>{d.data['@data'].title}</View>
<Img width={192} height={138} src={d.data['@data'].thumb} mode='aspectFill' className={styles.image}/> <View className={styles.desc}>:{d.data['@data'].class_hour} {d.data['@data'].charge}</View>
<View className={styles.articleLeftBox}> </View>
<View className='font-weight mb-2 font-28 lh-40'>{d.data['@data'].title}</View> </>
<View className={styles.desc}>:{d.data['@data'].class_hour} }
{d.data['@data'].charge}</View>
</View>
</>
}
</View> </View>
) )
} }
<View style={{width: '750rpx', textAlign: 'center', color: '#999'}} <View style={{width: '750rpx', textAlign: 'center', color: '#999'}} className="font-28 mt-3 mb-3">{text}</View>
className="font-28 mt-3 mb-3">{text}</View> </>
</>
} }
{!loading && brands.length === 0 && <Empty name='空空如也'/>} { !loading && brands.length === 0 && <Empty name='空空如也'/>}
</ScrollView> </ScrollView>
) )
} }

@ -1,6 +1,3 @@
export default definePageConfig({ export default definePageConfig({
navigationBarTitleText: '搜索', navigationStyle: 'custom'
navigationBarBackgroundColor: '#F2F8F6',
onReachBottomDistance: 50,
navigationStyle: 'custom',
}) })

@ -1,58 +1,46 @@
page { page{
background-color: #F2F8F6; background-color:#F2F8F6;
.searchHeader { .navBox{
margin-top: 10px; position: fixed;
padding: 0 20rpx; width:750rpx;
display: flex;
align-items: center;
justify-content: space-between;
transition: all 200ms;
position: sticky;
z-index: 200 ;
overflow: hidden;
} }
.searchBox{
.searchBox { width: 690rpx;
flex: 1;
height: 68rpx; height: 68rpx;
background: #FFFFFF; background: #FFFFFF;
border-radius: 32rpx; border-radius: 32rpx 32rpx 32rpx 32rpx;
box-sizing: border-box; box-sizing: border-box;
display: flex; display: flex;
align-items: center; align-items: center;
padding: 0 24rpx; padding:0 24rpx;
.input{
.input {
font-size: 28rpx; font-size: 28rpx;
margin-left: 20rpx; font-weight: 500;
flex: 1; margin-left: 24rpx;
flex:1;
} }
} }
.titleBox{
.titleBox {
margin-top: 60rpx; margin-top: 60rpx;
width: 100%; width: 100%;
display: flex; display: flex;
box-sizing: border-box; box-sizing: border-box;
padding-right: 30rpx; padding-right: 30rpx;
justify-content: space-between; justify-content: space-between;
.title{
.title {
font-size: 28rpx; font-size: 28rpx;
font-weight: bold; font-weight: bold;
color: #323635; color: #323635;
} }
} }
.contentBox{
.contentBox {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
.items{
.items {
display: inline-block; display: inline-block;
background: #FFFFFF; background: #FFFFFF;
border-radius: 32rpx; border-radius:32rpx;
padding: 10rpx 24rpx; padding: 10rpx 24rpx;
font-size: 24rpx; font-size: 24rpx;
font-weight: 500; font-weight: 500;

@ -1,136 +1,133 @@
import {Input, View, Text, PageContainer, Image} from "@tarojs/components"; import {Input, View, Text, PageContainer} from "@tarojs/components";
import React, {FC, useEffect, useMemo, useState} from "react"; import {FC, useEffect, useState} from "react";
import { AtIcon } from 'taro-ui'
import styles from './index.module.scss' import styles from './index.module.scss'
import Taro from "@tarojs/taro"; import Taro from "@tarojs/taro";
import {useDidShow} from '@tarojs/taro' import { useReady, useDidShow } from '@tarojs/taro'
import SearchList from './components/list' import SearchList from './components/list'
import search from '@/static/img/search.png'
import NavigationBar from "@/components/navigationBar/navigationBar";
import del from '@/static/img/del.png'
const Search: FC = () => { const Search:FC = () => {
const globalData = Taro.getApp().globalData
const [value, setValue] = useState('') const [value, setValue] = useState('')
const [recentSearch, setRecentSearch] = useState<string[]>([]) const [recentSearch, setRecentSearch] = useState<string[]>([])
const [hotSearch] = useState<any[]>([]) const [hotSearch,setHotSearch] = useState<any[]>([])
const [show, setShow] = useState(false) const [show, setShow] = useState(false)
const [focus, setFocus] = useState(false)
useDidShow(getRecentSearch) useReady(()=>{
console.log('onReady')
})
useDidShow(()=>{
getRecentSearch()
})
useEffect(() => { useEffect(()=>{
if (!show) { if(!show){
getRecentSearch() getRecentSearch()
} }
}, [show]) },[show])
function inpFn(e) { function inpFn(e){
setValue(e.detail.value) setValue(e.detail.value)
} }
function clearSearch() { function clearSearch(){
Taro.removeStorageSync('recentSearch') Taro.removeStorageSync('recentSearch')
getRecentSearch() getRecentSearch()
} }
function getRecentSearch() { function getRecentSearch () {
setRecentSearch(Taro.getStorageSync('recentSearch')) setRecentSearch(Taro.getStorageSync('recentSearch'))
} }
function getSearchItem(value) { function getSearchItem(value) {
setValue(value) setValue(value)
// Taro.navigateTo({
// url:`/pages/preview/search/list/index?name=${value}`
// })
setShow(true) setShow(true)
} }
function searchInput() { function searchInput(){
if (value === "") return; if (value === "") return;
getSearchItem(value) getSearchItem(value)
//记录最近搜索 //记录最近搜索
let recentSearch = Taro.getStorageSync('recentSearch') || []; let recentSearch = Taro.getStorageSync('recentSearch') || [];
recentSearch.unshift(value); recentSearch.unshift(value);
Taro.setStorageSync('recentSearch', [...new Set(recentSearch)]) Taro.setStorageSync('recentSearch', [...new Set(recentSearch)])
} }
function navBack(){
Taro.navigateBack()
}
const searchStyles = useMemo((): React.CSSProperties | undefined => {
if (focus || show) {
return {
transform: "translateY(-43px)",
width: "70%",
}
}
}, [focus, show])
return ( return (
<> <View className="flex flex-column">
<NavigationBar text='搜索'/> <View className={styles.navBox} style={{height:`${globalData.statusBarHeight+globalData.textBarHeight}px`}}>
<View className={styles.searchHeader} style={searchStyles}> <View style={{height:`${globalData.statusBarHeight}px`}}></View>
<View className={styles.searchBox}> <View style={{height:`${globalData.textBarHeight}px`,display:'flex',alignItems:'center'}}>
<Image src={search} style={{width: '32rpx', height: '32rpx'}} mode='widthFix'/> <View className="flex justify-end" style={{width:'40px'}}>
<Input <AtIcon value='chevron-left' size='25' color='#333' onClick={navBack}></AtIcon>
onFocus={() => setFocus(true)} </View>
onBlur={() => setFocus(false)} <View className="font-28 font-weight flex-1" style={{display:'flex',justifyContent:'center',paddingRight:'40px',boxSizing:'border-box'}}></View>
className={styles.input} </View>
placeholder={(focus || show) ? '' : "输入关键字搜索"} </View>
type='text'
confirmType='search'
onInput={inpFn}
onConfirm={searchInput}/>
<View style={{paddingLeft: '30rpx'}}>
<View style={{height:`${globalData.statusBarHeight+globalData.textBarHeight}px`}}></View>
<View className={styles.searchBox}>
<AtIcon value='search' size='20' color='#ccc'></AtIcon>
{ show ?
<Text className={styles.input} >{value}</Text>:
<Input className={styles.input} placeholder="输入关键字搜索" type={'text'} confirmType={'search'} onInput={inpFn} onConfirm={searchInput} />
}
</View> </View>
{focus || show ? <View className='px-2 text-dark' onClick={() => setShow(false)}></View> : null}
</View> {
recentSearch.length >= 1 && !show &&
<View className="flex flex-column px-2"> <>
{ <View className={styles.titleBox} >
recentSearch.length >= 1 && !show && <Text className={styles.title}></Text>
<> <AtIcon onClick={clearSearch} value='trash' size='16' color='#909795'></AtIcon>
<View className={styles.titleBox}> </View>
<Text className={styles.title}></Text>
<Image src={del} mode='widthFix' style={{width: '16px'}} onClick={clearSearch}/>
</View>
<View className={styles.contentBox}> <View className={styles.contentBox}>
{ {
recentSearch.length && recentSearch.length &&
recentSearch?.map(d => <View className={styles.items}> recentSearch?.map(d =>
<View onClick={() => getSearchItem(d)} className="font-28">{d}</View> <View className={styles.items}>
</View>) <View onClick={()=>{getSearchItem(d)}} className="font-28" >{d}</View>
</View>)
} }
</View> </View>
</> </>
} }
{ {
hotSearch.length >= 1 && !show && hotSearch.length >= 1 && !show &&
<> <>
<View className={`flex justify-between ${styles.titleBox}`}> <View className={`flex justify-between ${styles.titleBox}`} >
<Text className="font-32 fwb"></Text> <Text className="font-32 fwb"></Text>
</View> </View>
<View className="wid100 pt-3 pl-3 box-b"> <View className="wid100 pt-3 pl-3 box-b">
<View className="wid100 flex flex-wrap"> <View className="wid100 flex flex-wrap">
{ {
hotSearch.length && hotSearch.length &&
hotSearch.map(d => hotSearch.map(d =>
<View className="py-1 px-2 rounded-40 mr-2 mb-2 bg-warning text-white"> <View className="py-1 px-2 rounded-40 mr-2 mb-2 bg-warning text-white">
<View onClick={() => { <View onClick={()=>{getSearchItem(d)}} className="font-28" >{d}</View>
getSearchItem(d) </View>)
}} className="font-28">{d}</View> }
</View>)
}
</View>
</View> </View>
</> </View>
} </>
}
<PageContainer
onClickOverlay={() => setShow(false)} <PageContainer onBeforeLeave={() => {setShow(false)}} onClickOverlay={()=>{ setShow(false)}} show={show} round={true} overlay={true} overlayStyle={'background:rgba(0,0,0,0)'} >
show={show} <SearchList name={value} clear={show} />
overlay </PageContainer>
overlayStyle={'background:rgba(0,0,0,0)'}> </View>
<SearchList name={value} clear={show}/>
</PageContainer>
</View>
</>
</View>
) )
} }
export default Search export default Search

@ -0,0 +1,12 @@
let timeout:any = null
function debounce(func, wait = 500) {
console.log(arguments[0],'arguments')
timeout && clearTimeout(timeout)
timeout = setTimeout(() => {
console.log('执行')
typeof func === 'function' && func()
}, wait)
}
export default debounce
Loading…
Cancel
Save