✨ feat(优化):
This commit is contained in:
parent
2a8a13cca2
commit
8c7f25e7f9
@ -6,7 +6,7 @@ import Counter from '../counter'
|
|||||||
import Big from 'big.js'
|
import Big from 'big.js'
|
||||||
import classnames from 'classnames'
|
import classnames from 'classnames'
|
||||||
import styles from './index.module.scss'
|
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 { useSelector } from '@/reducers/hooks'
|
||||||
import { GetColorList } from '@/api/materialColor'
|
import { GetColorList } from '@/api/materialColor'
|
||||||
import { AddShoppingCartApi } from '@/api/shopCart'
|
import { AddShoppingCartApi } from '@/api/shopCart'
|
||||||
@ -18,6 +18,7 @@ import LabAndImg from '@/components/LabAndImg'
|
|||||||
import VirtualList from '@tarojs/components/virtual-list'
|
import VirtualList from '@tarojs/components/virtual-list'
|
||||||
import useCommonData from '@/use/useCommonData'
|
import useCommonData from '@/use/useCommonData'
|
||||||
import LabAndImgShow from '@/components/LabAndImgShow'
|
import LabAndImgShow from '@/components/LabAndImgShow'
|
||||||
|
import InfiniteScroll from '@/components/infiniteScroll'
|
||||||
|
|
||||||
type param = {
|
type param = {
|
||||||
show?: true | false
|
show?: true | false
|
||||||
@ -26,6 +27,8 @@ type param = {
|
|||||||
productId?: number
|
productId?: number
|
||||||
}
|
}
|
||||||
export default memo(({ show = false, onClose, title = '', productId = 0 }: param) => {
|
export default memo(({ show = false, onClose, title = '', productId = 0 }: param) => {
|
||||||
|
const [isPending, startTransition] = useTransition()
|
||||||
|
|
||||||
const { adminUserInfo } = useSelector((state) => state.userInfo)
|
const { adminUserInfo } = useSelector((state) => state.userInfo)
|
||||||
|
|
||||||
const [selectList, _] = useState([
|
const [selectList, _] = useState([
|
||||||
@ -40,12 +43,16 @@ export default memo(({ show = false, onClose, title = '', productId = 0 }: param
|
|||||||
|
|
||||||
//重置数据
|
//重置数据
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const newList = initList(list)
|
// const newList = initList(list)
|
||||||
setList([...newList])
|
startTransition(() => {
|
||||||
|
// setList([...newList])
|
||||||
|
})
|
||||||
condition.current.code_or_name = null
|
condition.current.code_or_name = null
|
||||||
setSearchShow(false)
|
setSearchShow(false)
|
||||||
}, [selectIndex])
|
}, [selectIndex])
|
||||||
|
|
||||||
|
useEffect(() => console.log('isPending::', isPending), [isPending])
|
||||||
|
|
||||||
//获取面料颜色列表
|
//获取面料颜色列表
|
||||||
const { fetchData: colorFetchData, state: colorState } = GetColorList()
|
const { fetchData: colorFetchData, state: colorState } = GetColorList()
|
||||||
const [list, setList] = useState<any[]>([])
|
const [list, setList] = useState<any[]>([])
|
||||||
@ -70,14 +77,16 @@ export default memo(({ show = false, onClose, title = '', productId = 0 }: param
|
|||||||
}, [show])
|
}, [show])
|
||||||
|
|
||||||
//初始化列表数据
|
//初始化列表数据
|
||||||
const initList = useCallback((list) => {
|
const initList = (list) => {
|
||||||
const newList = list.map((item) => {
|
const newList = list.map((item) => {
|
||||||
item.count = 0
|
item.count = 0
|
||||||
item.show = false
|
item.show = false
|
||||||
|
item.unit = selectList[selectIndex].unit
|
||||||
|
item.formatePrice = Number(formatPriceDiv(item[selectList[selectIndex].priceField]))
|
||||||
return item
|
return item
|
||||||
})
|
})
|
||||||
return newList
|
return newList
|
||||||
}, [])
|
}
|
||||||
|
|
||||||
//卸载数据
|
//卸载数据
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -191,19 +200,16 @@ export default memo(({ show = false, onClose, title = '', productId = 0 }: param
|
|||||||
}
|
}
|
||||||
|
|
||||||
//格式化金额
|
//格式化金额
|
||||||
const formatPrice = useCallback(
|
const formatPrice = (item) => {
|
||||||
(item) => {
|
return Number(formatPriceDiv(item[selectList[selectIndex].priceField]))
|
||||||
const price = Number(formatPriceDiv(item[selectList[selectIndex].priceField]))
|
// return (
|
||||||
return (
|
// <View className={styles.priceText}>
|
||||||
<View className={styles.priceText}>
|
// <Text>¥</Text>
|
||||||
<Text>¥</Text>
|
// {price}
|
||||||
{price}
|
// <Text> /{selectList[selectIndex].eunit}</Text>
|
||||||
<Text> /{selectList[selectIndex].eunit}</Text>
|
// </View>
|
||||||
</View>
|
// )
|
||||||
)
|
}
|
||||||
},
|
|
||||||
[selectIndex],
|
|
||||||
)
|
|
||||||
|
|
||||||
//显示图片弹窗
|
//显示图片弹窗
|
||||||
const [showLabImage, setShowLabImage] = useState(false)
|
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) => {
|
// const Rows = memo(({ id, index, style, data }: any) => {
|
||||||
let item = data[index]
|
// let item = data[index]
|
||||||
return (
|
// return (
|
||||||
<>
|
// <>
|
||||||
{(item && (
|
// {(item && (
|
||||||
<View className={styles.item} key={item.id}>
|
// <View className={styles.item} key={item.id}>
|
||||||
<View className={styles.item_color}>
|
// <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} />
|
// <LabAndImg value={{ lab: item.lab, rgb: item.rgb, texture_url: item.texture_url, title: item.code }} showStatus={false} onClick={getLabAndImg} />
|
||||||
</View>
|
// </View>
|
||||||
<View className={styles.item_con}>
|
// <View className={styles.item_con}>
|
||||||
<View className={styles.title}>{formatHashTag(item.code, item.name)}</View>
|
// <View className={styles.title}>{formatHashTag(item.code, item.name)}</View>
|
||||||
<View className={styles.num}>{formatPrice(item)}</View>
|
// <View className={styles.num}>{formatPrice(item)}</View>
|
||||||
</View>
|
// </View>
|
||||||
<View className={styles.btn_con}>
|
// <View className={styles.btn_con}>
|
||||||
{(!item.show && (
|
// {(!item.show && (
|
||||||
<View className={styles.btn} onClick={() => onAdd(item)}>
|
// <View className={styles.btn} onClick={() => onAdd(item)}>
|
||||||
添加
|
// 添加
|
||||||
</View>
|
// </View>
|
||||||
)) || (
|
// )) || (
|
||||||
<View className={styles.btn_count}>
|
// <View className={styles.btn_count}>
|
||||||
<Counter
|
// <Counter
|
||||||
otherData={item}
|
// otherData={item}
|
||||||
onBlue={getInputValue}
|
// onBlue={getInputValue}
|
||||||
defaultNum={item.count}
|
// defaultNum={item.count}
|
||||||
step={selectList[selectIndex].step}
|
// step={selectList[selectIndex].step}
|
||||||
digits={selectList[selectIndex].digits}
|
// digits={selectList[selectIndex].digits}
|
||||||
onClickBtn={getInputValue}
|
// onClickBtn={getInputValue}
|
||||||
unit={selectList[selectIndex].unit}
|
// unit={selectList[selectIndex].unit}
|
||||||
minNum={selectList[selectIndex].minNum}
|
// minNum={selectList[selectIndex].minNum}
|
||||||
maxNum={selectList[selectIndex].maxNum}
|
// maxNum={selectList[selectIndex].maxNum}
|
||||||
/>
|
// />
|
||||||
</View>
|
// </View>
|
||||||
)}
|
// )}
|
||||||
</View>
|
// </View>
|
||||||
</View>
|
// </View>
|
||||||
)) || <View className={styles.item}></View>}
|
// )) || <View className={styles.item}></View>}
|
||||||
</>
|
// </>
|
||||||
)
|
// )
|
||||||
})
|
// })
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View className={styles.shop_cart_main}>
|
<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}>
|
<View className={styles.product_color_con}>
|
||||||
{list.length <= 0 && colorState.loading && <LoadingCard />}
|
{list.length <= 0 && colorState.loading && <LoadingCard />}
|
||||||
{list.length > 0 && !colorState.loading && (
|
{list.length > 0 && !colorState.loading && (
|
||||||
<View className={styles.color_con}>
|
<InfiniteScroll moreStatus={false}>
|
||||||
<VirtualList
|
<View className={styles.color_con}>
|
||||||
className={styles.virtual_list}
|
{list.map((item) => {
|
||||||
height={400}
|
return (
|
||||||
width='100%'
|
<View className={styles.item} key={item.id}>
|
||||||
itemData={list}
|
<View className={styles.item_color}>
|
||||||
itemCount={list.length + 1}
|
<LabAndImg value={{ lab: item.lab, rgb: item.rgb, texture_url: item.texture_url }} />
|
||||||
itemSize={100}
|
</View>
|
||||||
overscanCount={1}>
|
<View className={styles.item_con}>
|
||||||
{Rows}
|
<View className={styles.title}>{formatHashTag(item.code, item.name)}</View>
|
||||||
</VirtualList>
|
<View className={styles.num}>
|
||||||
<View className='common_safe_area_y'></View>
|
<View className={styles.priceText}>
|
||||||
</View>
|
<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>}
|
{list.length <= 0 && !colorState.loading && <View className={styles.noData}>暂无此商品</View>}
|
||||||
</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