【【电子商城】-功能{筛选}:点击重置只需清除筛选条件,不需关闭筛选页面】 https://www.tapd.cn/53459131/bugtrace/bugs/view/1153459131001001433
277 lines
10 KiB
TypeScript
277 lines
10 KiB
TypeScript
import { Text, View } from '@tarojs/components'
|
||
import Taro, { usePullDownRefresh, useReady, useRouter } from '@tarojs/taro'
|
||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||
import SelectData from './components/selectData'
|
||
import styles from './searchList.module.scss'
|
||
import Search from '@/components/search'
|
||
import Filter from '@/components/filter'
|
||
import InfiniteScroll from '@/components/infiniteScroll'
|
||
import type { SortBtnRef, SortParam } from '@/components/sortBtn'
|
||
import SortBtn from '@/components/sortBtn'
|
||
import { goLink } from '@/common/common'
|
||
import { formatHashTag, formatPriceDiv } from '@/common/fotmat'
|
||
import { dataLoadingStatus, getFilterData } from '@/common/util'
|
||
import useLogin from '@/use/useLogin'
|
||
import LabAndImg from '@/components/LabAndImg'
|
||
import IconFont from '@/components/iconfont/iconfont'
|
||
import Tag from '@/components/tag'
|
||
import { EnumAllLabelApi, GetLabelProductsApi, HomePageJumpApi } from '@/api/search'
|
||
|
||
enum FilterOptions {
|
||
RECOMMEND = 1,
|
||
SALES = 2,
|
||
PRICE = 3,
|
||
}
|
||
|
||
export default () => {
|
||
const isFirst = useRef(true)
|
||
|
||
useLogin()
|
||
|
||
const router = useRouter()
|
||
|
||
const { fetchData } = HomePageJumpApi()
|
||
// 获取指定的标签组的标签列表
|
||
const getLabelsWithHomeJump = async() => {
|
||
await getAllLabel()
|
||
if (router.params.pageJump) {
|
||
const res = await fetchData({ page_jump: router.params.pageJump || 1 })
|
||
const labelIds = res.data.list.map(item => item.product_label_id)
|
||
setLabelIds(labelIds)
|
||
setSearchField(prev => ({ ...prev, label_ids: labelIds.join(',') }))
|
||
}
|
||
else {
|
||
setLabelIds([])
|
||
setSearchField(prev => ({ ...prev, label_ids: '' }))
|
||
}
|
||
isFirst.current = false
|
||
}
|
||
// 获取所有标签列表
|
||
const { fetchData: getAllLabelApi } = EnumAllLabelApi()
|
||
const getAllLabel = async() => {
|
||
const res = await getAllLabelApi()
|
||
const labelList = res.data.list.map(item => ({ id: item.id, name: item.name }))
|
||
setLabelList(labelList)
|
||
}
|
||
|
||
// 搜索参数
|
||
const [searchField, setSearchField] = useState({
|
||
code_or_name: router.params.key,
|
||
page: 1,
|
||
size: 10,
|
||
filter_type: 1, // 综合推荐
|
||
width: '',
|
||
weight_density: '',
|
||
label_ids: router.params?.label_ids || '',
|
||
component: '', // 成分
|
||
abstract_sort_key: '',
|
||
})
|
||
|
||
// 获取面料列表
|
||
const [materialList, setMaterialList] = useState<{ list: any[]; total: number }>({ list: [], total: 0 })
|
||
const { fetchData: materialFetchData, state: materialState } = GetLabelProductsApi()
|
||
const getProductList = async() => {
|
||
const { data } = await materialFetchData(getFilterData(searchField))
|
||
setMaterialList({ list: data.list, total: data.total })
|
||
setRefresherTriggeredStatus(false)
|
||
}
|
||
|
||
useEffect(() => {
|
||
getLabelsWithHomeJump()
|
||
}, [])
|
||
|
||
// 监听筛选条件变化
|
||
useEffect(() => {
|
||
// 首次进入页面不执行
|
||
if (!isFirst.current) {
|
||
getProductList()
|
||
}
|
||
}, [searchField, isFirst.current])
|
||
|
||
// 上拉加载数据
|
||
const pageNum = useRef({ size: searchField.size, page: searchField.page })
|
||
const getScrolltolower = () => {
|
||
if (materialList.list.length < materialList.total) {
|
||
pageNum.current.page++
|
||
const size = pageNum.current.size * pageNum.current.page
|
||
setSearchField(prev => ({ ...prev, size }))
|
||
}
|
||
}
|
||
|
||
// 数据加载状态
|
||
const statusMore = useMemo(() => {
|
||
return dataLoadingStatus({ list: materialList.list, total: materialList.total, status: materialState.loading })
|
||
}, [materialList, materialState])
|
||
|
||
// 输入了搜索关键字
|
||
const getSearchData = useCallback((e) => {
|
||
console.log('e', e)
|
||
pageNum.current.page = 1
|
||
setSearchField(val => ({ ...val, code_or_name: e, size: 10 }))
|
||
pageNum.current = { size: 10, page: 1 }
|
||
}, [])
|
||
|
||
const handleInput = (e) => {
|
||
if (e === '') {
|
||
getSearchData(e)
|
||
}
|
||
}
|
||
|
||
const goLinkPage = (item) => {
|
||
goLink('/pages/details/index', { id: item.id })
|
||
}
|
||
|
||
const [labelIds, setLabelIds] = useState<number[]>([])
|
||
|
||
// 获取筛选条件
|
||
const getFilter = (e) => {
|
||
console.log('e', e)
|
||
pageNum.current.page = 1
|
||
setSearchField(prev => ({
|
||
...prev,
|
||
width: e?.width,
|
||
weight_density: e?.weight_density,
|
||
size: 10,
|
||
component: e?.component,
|
||
label_ids: e?.label_ids.join(','),
|
||
}))
|
||
setLabelIds([...e?.label_ids])
|
||
}
|
||
|
||
// 排序
|
||
const sortCollectionRef = useRef<SortBtnRef>(null)
|
||
|
||
const [sortStatus, setSortStatus] = useState<SortParam>('none')
|
||
|
||
const changeSort = () => {
|
||
setCurrentOption(FilterOptions.PRICE)
|
||
if (sortCollectionRef.current) {
|
||
const { status, value } = sortCollectionRef.current.changeSort()
|
||
setSortStatus(status)
|
||
// 如果状态为none,就是综合推荐
|
||
if (status === 'none') {
|
||
setSearchField(e => ({ ...e, filter_type: FilterOptions.RECOMMEND, size: 10, page: 1 }))
|
||
setCurrentOption(FilterOptions.RECOMMEND)
|
||
}
|
||
else {
|
||
setSearchField(e => ({ ...e, filter_type: value as number, size: 10, page: 1 }))
|
||
}
|
||
}
|
||
pageNum.current = { size: 10, page: 1 }
|
||
}
|
||
|
||
const labAndImgObj = useCallback(
|
||
(item) => {
|
||
const img = item ? item.texture_url.split(',')[0] : ''
|
||
return { lab: item.lab, rgb: item.rgb, texture_url: img }
|
||
},
|
||
[materialList],
|
||
)
|
||
|
||
const [currentOption, setCurrentOption] = useState(FilterOptions.RECOMMEND)
|
||
|
||
const handleSelectFilterOptions = (key: FilterOptions) => {
|
||
if (key === currentOption) { return }
|
||
setSearchField(e => ({ ...e, filter_type: key, size: 10, page: 1 }))
|
||
setSortStatus('none')
|
||
setCurrentOption(key)
|
||
}
|
||
|
||
const [labelList, setLabelList] = useState<any[]>([])
|
||
|
||
const [selected, setSelected] = useState<number[]>([])
|
||
|
||
const handleClickTag = (ids: number[]) => {
|
||
console.log('ids', ids)
|
||
setSelected([...ids])
|
||
setSearchField(prev => ({
|
||
...prev,
|
||
label_ids: ids.join(','),
|
||
}))
|
||
}
|
||
|
||
// 列表下拉刷新
|
||
const [refresherTriggeredStatus, setRefresherTriggeredStatus] = useState(false)
|
||
const getRefresherRefresh = async() => {
|
||
pageNum.current.page = 1
|
||
pageNum.current.size = 10
|
||
setRefresherTriggeredStatus(true)
|
||
setSearchField(val => ({ ...val, size: 10 }))
|
||
}
|
||
|
||
return (
|
||
<View className={styles.main}>
|
||
<View className={styles.search}>
|
||
<Search placeholder="请输入搜索面料" showBtn btnTitle="搜索" clickOnSearch={getSearchData} defaultValue={router.params.key} changeOnSearch={handleInput} debounceTime={300} />
|
||
</View>
|
||
<View className={styles.filter}>
|
||
<View className={styles.filter_all}>
|
||
<View className={styles.text_zh} onClick={() => handleSelectFilterOptions(FilterOptions.RECOMMEND)}>
|
||
<Text className={currentOption === FilterOptions.RECOMMEND ? styles.filter_active : ''}>综合推荐</Text>
|
||
</View>
|
||
<View className={styles.text_sc} onClick={() => handleSelectFilterOptions(FilterOptions.SALES)}>
|
||
<Text className={currentOption === FilterOptions.SALES ? styles.filter_active : ''}>销量</Text>
|
||
</View>
|
||
<View className={styles.text_sc} onClick={changeSort}>
|
||
<Text className={currentOption === FilterOptions.PRICE ? styles.filter_active : ''} style={{ marginRight: '8rpx' }}>价格</Text>
|
||
<SortBtn status={sortStatus} ref={sortCollectionRef} sortValue={{ desc: 3, asc: 4 }} />
|
||
</View>
|
||
<View className={styles.text_sc}>
|
||
<Filter defaultValue={selected} onFilter={e => getFilter(e)} />
|
||
</View>
|
||
</View>
|
||
{
|
||
!!labelList.length && <View className={styles.filter_btn_con}>
|
||
<View className={styles.filter_scroll}>
|
||
<SelectData defaultValue={labelIds} list={labelList} onClickTag={handleClickTag} />
|
||
</View>
|
||
</View>
|
||
}
|
||
</View>
|
||
<View className={styles.list}>
|
||
<View className={styles.scroll}>
|
||
<InfiniteScroll refresherEnabled selfOnRefresherRefresh={getRefresherRefresh} refresherTriggered={refresherTriggeredStatus} safeAreaInsetBottom={false} selfonScrollToLower={getScrolltolower} statusMore={statusMore}>
|
||
<View className={styles.product_list}>
|
||
{materialList.list?.map((item) => {
|
||
return (
|
||
<View key={item.id} className={styles.product_item} onClick={() => goLinkPage(item)}>
|
||
<View className={styles.product_img}>
|
||
<LabAndImg value={labAndImgObj(item)} />
|
||
<View className={styles.color_num}>{item.product_color_count}色</View>
|
||
</View>
|
||
<View className={styles.product_info}>
|
||
<View className={styles.title}>
|
||
<Text className={styles.title_text}>
|
||
{formatHashTag(item.code, item.name)}
|
||
</Text>
|
||
<View className={styles.favorite}>
|
||
{item.is_favorite && <IconFont customClassName={styles.collection_icon} name="icon-shoucang1" size={40} />}
|
||
</View>
|
||
</View>
|
||
<View className={styles.tag_list}>
|
||
<Tag customClassName={styles.tag} type="primary" size="small" circle>{item.width}</Tag>
|
||
<Tag customClassName={styles.tag} type="primary" size="small" circle>{item.weight_density}</Tag>
|
||
{
|
||
!!item.product_screw_id
|
||
&& <Tag customClassName={styles.tag_g} circle type="primary" size="small">配套螺纹</Tag>
|
||
}
|
||
</View>
|
||
<View className={styles.bottom}>
|
||
<View className={styles.introduce}>{item.component}</View>
|
||
<View className={styles.price}>
|
||
<View className={styles.price_unit}>¥</View>
|
||
<View className={styles.price_num}>{formatPriceDiv(item.lowest_price).toLocaleString()}起</View>
|
||
</View>
|
||
</View>
|
||
</View>
|
||
</View>
|
||
)
|
||
})}
|
||
</View>
|
||
</InfiniteScroll>
|
||
</View>
|
||
</View>
|
||
</View>
|
||
)
|
||
}
|