✨ feat(优化):
This commit is contained in:
parent
2a8a13cca2
commit
8c7f25e7f9
@ -6,7 +6,7 @@ import Counter from '../counter'
|
||||
import Big from 'big.js'
|
||||
import classnames from 'classnames'
|
||||
import styles from './index.module.scss'
|
||||
import { memo, useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { memo, useCallback, useEffect, useRef, useState, useTransition } from 'react'
|
||||
import { useSelector } from '@/reducers/hooks'
|
||||
import { GetColorList } from '@/api/materialColor'
|
||||
import { AddShoppingCartApi } from '@/api/shopCart'
|
||||
@ -18,6 +18,7 @@ import LabAndImg from '@/components/LabAndImg'
|
||||
import VirtualList from '@tarojs/components/virtual-list'
|
||||
import useCommonData from '@/use/useCommonData'
|
||||
import LabAndImgShow from '@/components/LabAndImgShow'
|
||||
import InfiniteScroll from '@/components/infiniteScroll'
|
||||
|
||||
type param = {
|
||||
show?: true | false
|
||||
@ -26,6 +27,8 @@ type param = {
|
||||
productId?: number
|
||||
}
|
||||
export default memo(({ show = false, onClose, title = '', productId = 0 }: param) => {
|
||||
const [isPending, startTransition] = useTransition()
|
||||
|
||||
const { adminUserInfo } = useSelector((state) => state.userInfo)
|
||||
|
||||
const [selectList, _] = useState([
|
||||
@ -40,12 +43,16 @@ export default memo(({ show = false, onClose, title = '', productId = 0 }: param
|
||||
|
||||
//重置数据
|
||||
useEffect(() => {
|
||||
const newList = initList(list)
|
||||
setList([...newList])
|
||||
// const newList = initList(list)
|
||||
startTransition(() => {
|
||||
// setList([...newList])
|
||||
})
|
||||
condition.current.code_or_name = null
|
||||
setSearchShow(false)
|
||||
}, [selectIndex])
|
||||
|
||||
useEffect(() => console.log('isPending::', isPending), [isPending])
|
||||
|
||||
//获取面料颜色列表
|
||||
const { fetchData: colorFetchData, state: colorState } = GetColorList()
|
||||
const [list, setList] = useState<any[]>([])
|
||||
@ -70,14 +77,16 @@ export default memo(({ show = false, onClose, title = '', productId = 0 }: param
|
||||
}, [show])
|
||||
|
||||
//初始化列表数据
|
||||
const initList = useCallback((list) => {
|
||||
const initList = (list) => {
|
||||
const newList = list.map((item) => {
|
||||
item.count = 0
|
||||
item.show = false
|
||||
item.unit = selectList[selectIndex].unit
|
||||
item.formatePrice = Number(formatPriceDiv(item[selectList[selectIndex].priceField]))
|
||||
return item
|
||||
})
|
||||
return newList
|
||||
}, [])
|
||||
}
|
||||
|
||||
//卸载数据
|
||||
useEffect(() => {
|
||||
@ -191,19 +200,16 @@ export default memo(({ show = false, onClose, title = '', productId = 0 }: param
|
||||
}
|
||||
|
||||
//格式化金额
|
||||
const formatPrice = useCallback(
|
||||
(item) => {
|
||||
const price = Number(formatPriceDiv(item[selectList[selectIndex].priceField]))
|
||||
return (
|
||||
<View className={styles.priceText}>
|
||||
<Text>¥</Text>
|
||||
{price}
|
||||
<Text> /{selectList[selectIndex].eunit}</Text>
|
||||
</View>
|
||||
)
|
||||
},
|
||||
[selectIndex],
|
||||
)
|
||||
const formatPrice = (item) => {
|
||||
return Number(formatPriceDiv(item[selectList[selectIndex].priceField]))
|
||||
// return (
|
||||
// <View className={styles.priceText}>
|
||||
// <Text>¥</Text>
|
||||
// {price}
|
||||
// <Text> /{selectList[selectIndex].eunit}</Text>
|
||||
// </View>
|
||||
// )
|
||||
}
|
||||
|
||||
//显示图片弹窗
|
||||
const [showLabImage, setShowLabImage] = useState(false)
|
||||
@ -217,45 +223,45 @@ export default memo(({ show = false, onClose, title = '', productId = 0 }: param
|
||||
}, [])
|
||||
|
||||
//虚拟滚动
|
||||
const Rows = memo(({ id, index, style, data }: any) => {
|
||||
let item = data[index]
|
||||
return (
|
||||
<>
|
||||
{(item && (
|
||||
<View className={styles.item} key={item.id}>
|
||||
<View className={styles.item_color}>
|
||||
<LabAndImg value={{ lab: item.lab, rgb: item.rgb, texture_url: item.texture_url, title: item.code }} showStatus={false} onClick={getLabAndImg} />
|
||||
</View>
|
||||
<View className={styles.item_con}>
|
||||
<View className={styles.title}>{formatHashTag(item.code, item.name)}</View>
|
||||
<View className={styles.num}>{formatPrice(item)}</View>
|
||||
</View>
|
||||
<View className={styles.btn_con}>
|
||||
{(!item.show && (
|
||||
<View className={styles.btn} onClick={() => onAdd(item)}>
|
||||
添加
|
||||
</View>
|
||||
)) || (
|
||||
<View className={styles.btn_count}>
|
||||
<Counter
|
||||
otherData={item}
|
||||
onBlue={getInputValue}
|
||||
defaultNum={item.count}
|
||||
step={selectList[selectIndex].step}
|
||||
digits={selectList[selectIndex].digits}
|
||||
onClickBtn={getInputValue}
|
||||
unit={selectList[selectIndex].unit}
|
||||
minNum={selectList[selectIndex].minNum}
|
||||
maxNum={selectList[selectIndex].maxNum}
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
)) || <View className={styles.item}></View>}
|
||||
</>
|
||||
)
|
||||
})
|
||||
// const Rows = memo(({ id, index, style, data }: any) => {
|
||||
// let item = data[index]
|
||||
// return (
|
||||
// <>
|
||||
// {(item && (
|
||||
// <View className={styles.item} key={item.id}>
|
||||
// <View className={styles.item_color}>
|
||||
// <LabAndImg value={{ lab: item.lab, rgb: item.rgb, texture_url: item.texture_url, title: item.code }} showStatus={false} onClick={getLabAndImg} />
|
||||
// </View>
|
||||
// <View className={styles.item_con}>
|
||||
// <View className={styles.title}>{formatHashTag(item.code, item.name)}</View>
|
||||
// <View className={styles.num}>{formatPrice(item)}</View>
|
||||
// </View>
|
||||
// <View className={styles.btn_con}>
|
||||
// {(!item.show && (
|
||||
// <View className={styles.btn} onClick={() => onAdd(item)}>
|
||||
// 添加
|
||||
// </View>
|
||||
// )) || (
|
||||
// <View className={styles.btn_count}>
|
||||
// <Counter
|
||||
// otherData={item}
|
||||
// onBlue={getInputValue}
|
||||
// defaultNum={item.count}
|
||||
// step={selectList[selectIndex].step}
|
||||
// digits={selectList[selectIndex].digits}
|
||||
// onClickBtn={getInputValue}
|
||||
// unit={selectList[selectIndex].unit}
|
||||
// minNum={selectList[selectIndex].minNum}
|
||||
// maxNum={selectList[selectIndex].maxNum}
|
||||
// />
|
||||
// </View>
|
||||
// )}
|
||||
// </View>
|
||||
// </View>
|
||||
// )) || <View className={styles.item}></View>}
|
||||
// </>
|
||||
// )
|
||||
// })
|
||||
|
||||
return (
|
||||
<View className={styles.shop_cart_main}>
|
||||
@ -295,19 +301,63 @@ export default memo(({ show = false, onClose, title = '', productId = 0 }: param
|
||||
<View className={styles.product_color_con}>
|
||||
{list.length <= 0 && colorState.loading && <LoadingCard />}
|
||||
{list.length > 0 && !colorState.loading && (
|
||||
<View className={styles.color_con}>
|
||||
<VirtualList
|
||||
className={styles.virtual_list}
|
||||
height={400}
|
||||
width='100%'
|
||||
itemData={list}
|
||||
itemCount={list.length + 1}
|
||||
itemSize={100}
|
||||
overscanCount={1}>
|
||||
{Rows}
|
||||
</VirtualList>
|
||||
<View className='common_safe_area_y'></View>
|
||||
</View>
|
||||
<InfiniteScroll moreStatus={false}>
|
||||
<View className={styles.color_con}>
|
||||
{list.map((item) => {
|
||||
return (
|
||||
<View className={styles.item} key={item.id}>
|
||||
<View className={styles.item_color}>
|
||||
<LabAndImg value={{ lab: item.lab, rgb: item.rgb, texture_url: item.texture_url }} />
|
||||
</View>
|
||||
<View className={styles.item_con}>
|
||||
<View className={styles.title}>{formatHashTag(item.code, item.name)}</View>
|
||||
<View className={styles.num}>
|
||||
<View className={styles.priceText}>
|
||||
<Text>¥</Text>
|
||||
{item.formatePrice}
|
||||
<Text>/{item.unit}</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
<View className={styles.btn_con}>
|
||||
{(!item.show && (
|
||||
<View className={styles.btn} onClick={() => onAdd(item)}>
|
||||
添加
|
||||
</View>
|
||||
)) || (
|
||||
<View className={styles.btn_count}>
|
||||
<Counter
|
||||
onBlue={(e) => getInputValue(e, item)}
|
||||
defaultNum={item.count}
|
||||
step={selectList[selectIndex].step}
|
||||
digits={selectList[selectIndex].digits}
|
||||
onClickBtn={(e) => getInputValue(e, item)}
|
||||
unit={selectList[selectIndex].unit}
|
||||
minNum={selectList[selectIndex].minNum}
|
||||
maxNum={selectList[selectIndex].maxNum}
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
})}
|
||||
</View>
|
||||
</InfiniteScroll>
|
||||
|
||||
// <View className={styles.color_con}>
|
||||
// <VirtualList
|
||||
// className={styles.virtual_list}
|
||||
// height={400}
|
||||
// width='100%'
|
||||
// itemData={list}
|
||||
// itemCount={list.length + 1}
|
||||
// itemSize={100}
|
||||
// overscanCount={1}>
|
||||
// {Rows}
|
||||
// </VirtualList>
|
||||
// <View className='common_safe_area_y'></View>
|
||||
// </View>
|
||||
)}
|
||||
{list.length <= 0 && !colorState.loading && <View className={styles.noData}>暂无此商品</View>}
|
||||
</View>
|
||||
|
176
src/pages/details/components/productItem/index.module.scss
Normal file
176
src/pages/details/components/productItem/index.module.scss
Normal file
@ -0,0 +1,176 @@
|
||||
.shop_cart_main{
|
||||
.popup_con{
|
||||
height: 80vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.header{
|
||||
color: $color_font_one;
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
padding: 20px;
|
||||
}
|
||||
.colorFind{
|
||||
padding: 10px 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.search{
|
||||
flex:1;
|
||||
}
|
||||
.text{
|
||||
font-size: $font_size_medium;
|
||||
color: $color_main;
|
||||
}
|
||||
}
|
||||
.search{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
.search_title{
|
||||
font-size: $font_size;
|
||||
color: #000;
|
||||
width: 160px;
|
||||
}
|
||||
.search_list{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex:1;
|
||||
}
|
||||
.search_item{
|
||||
width: 148px;
|
||||
height: 55px;
|
||||
text-align: center;
|
||||
line-height: 55px;
|
||||
color: $color_font_two;
|
||||
font-size: $font_size_medium;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 50px;
|
||||
}
|
||||
.search_item_select{
|
||||
border: 2px solid $color_main;
|
||||
background-color: #ecf5ff;
|
||||
color: $color_main;
|
||||
width: 144px;
|
||||
height: 51px;
|
||||
}
|
||||
}
|
||||
.colorNum{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 20px;
|
||||
.title{
|
||||
font-size: 26px;
|
||||
}
|
||||
.miconfont{
|
||||
font-size: 36px;
|
||||
color: $color_font_two;
|
||||
}
|
||||
}
|
||||
.product_color_con{
|
||||
flex:1;
|
||||
height: 0;
|
||||
padding-bottom:151px;
|
||||
}
|
||||
.color_con{
|
||||
.virtual_list{
|
||||
padding-bottom: 300px;
|
||||
}
|
||||
.item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 0 20px;
|
||||
margin-bottom: 40px;
|
||||
.item_color{
|
||||
width: 156.5px;
|
||||
height: 156.5px;
|
||||
border-radius: 20px;
|
||||
|
||||
}
|
||||
.item_con{
|
||||
flex:1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
padding: 20px 0 20px 20px;
|
||||
.title{
|
||||
font-size: $font_size_big;
|
||||
font-weight: 700;
|
||||
}
|
||||
.num{
|
||||
font-size: $font_size;
|
||||
color: $color_main;
|
||||
}
|
||||
.priceText{
|
||||
font-size: $font_size_big;
|
||||
Text{
|
||||
font-size: $font_size_min;
|
||||
}
|
||||
}
|
||||
}
|
||||
.btn_con{
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
.btn{
|
||||
width: 116px;
|
||||
height: 64px;
|
||||
background-color: $color_main;
|
||||
border-radius: 40px 0px 16px 0px;
|
||||
font-size: $font_size_medium;
|
||||
text-align: center;
|
||||
line-height: 64px;
|
||||
color: #fff;
|
||||
}
|
||||
.btn_count{
|
||||
width: 235px;
|
||||
height: 64px;
|
||||
background-color: #ECF5FF;
|
||||
border-radius: 40px 0px 16px 0px;
|
||||
padding: 0 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.noData{
|
||||
width:100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: $color_font_three;
|
||||
font-size: $font_size_medium;
|
||||
}
|
||||
.buy_btn{
|
||||
width: 100%;
|
||||
padding: 0 40px;
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
box-sizing: border-box;
|
||||
position: fixed;
|
||||
bottom:0;
|
||||
font-size: $font_size_medium;
|
||||
color: $color_font_two;
|
||||
background-color: #fff;
|
||||
box-shadow: 6px 0px 12px 0px rgba(0,0,0,0.16);
|
||||
.buy_btn_con{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 151px;
|
||||
}
|
||||
.add_cart{
|
||||
width: 260px;
|
||||
height: 90px;
|
||||
font-size: $font_size_big;
|
||||
text-align: center;
|
||||
line-height: 90px;
|
||||
border-radius: 50px;
|
||||
color: #fff;
|
||||
background: linear-gradient(38deg,#5cabff, #7cbcfc 100%, #99ccff 100%);
|
||||
}
|
||||
.select_add_cart{
|
||||
background: linear-gradient(38deg,#007aff, #4fa6ff 100%, #68b4ff 100%);
|
||||
}
|
||||
}
|
||||
}
|
45
src/pages/details/components/productItem/index.tsx
Normal file
45
src/pages/details/components/productItem/index.tsx
Normal file
@ -0,0 +1,45 @@
|
||||
import LabAndImg from '@/components/LabAndImg'
|
||||
import { View } from '@tarojs/components'
|
||||
import { memo } from 'react'
|
||||
import styles from './index.module.scss'
|
||||
export default memo(() => {
|
||||
return (
|
||||
<View>
|
||||
<View className={styles.item} key={item.id}>
|
||||
<View className={styles.item_color}>
|
||||
<LabAndImg value={{ lab: item.lab, rgb: item.rgb, texture_url: item.texture_url }} />
|
||||
</View>
|
||||
<View className={styles.item_con}>
|
||||
<View className={styles.title}>{formatHashTag(item.code, item.name)}</View>
|
||||
<View className={styles.num}>
|
||||
<View className={styles.priceText}>
|
||||
<Text>¥</Text>
|
||||
{formatPrice(item)}
|
||||
<Text> /{selectList[selectIndex].eunit}</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
<View className={styles.btn_con}>
|
||||
{(!item.show && (
|
||||
<View className={styles.btn} onClick={() => onAdd(item)}>
|
||||
添加
|
||||
</View>
|
||||
)) || (
|
||||
<View className={styles.btn_count}>
|
||||
<Counter
|
||||
onBlue={(e) => getInputValue(e, item)}
|
||||
defaultNum={item.count}
|
||||
step={selectList[selectIndex].step}
|
||||
digits={selectList[selectIndex].digits}
|
||||
onClickBtn={(e) => getInputValue(e, item)}
|
||||
unit={selectList[selectIndex].unit}
|
||||
minNum={selectList[selectIndex].minNum}
|
||||
maxNum={selectList[selectIndex].maxNum}
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
})
|
Loading…
x
Reference in New Issue
Block a user