2022-08-01 00:32:59 +08:00

334 lines
11 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { View, Text } from '@tarojs/components'
import Popup from '@/components/popup'
import LoadingCard from '@/components/loadingCard'
import Search from '@/components/search'
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 { useSelector } from '@/reducers/hooks'
import { GetColorList } from '@/api/materialColor'
import { AddShoppingCartApi } from '@/api/shopCart'
import Taro, { useRouter } from '@tarojs/taro'
import UseLogin from '@/use/useLogin'
import { formatHashTag, formatPriceDiv } from '@/common/fotmat'
import { getFilterData } from '@/common/util'
import LabAndImg from '@/components/LabAndImg'
import VirtualList from '@tarojs/components/virtual-list'
import useCommonData from '@/use/useCommonData'
import LabAndImgShow from '@/components/LabAndImgShow'
type param = {
show?: true | false
onClose?: () => void
title?: string
productId?: number
}
export default memo(({ show = false, onClose, title = '', productId = 0 }: param) => {
const { adminUserInfo } = useSelector((state) => state.userInfo)
const [selectList, _] = useState([
{ id: 0, step: 1, digits: 0, maxNum: 100000, defaultNum: 1, title: '大货', unit: '条', eunit: 'kg', priceField: 'bulk_price' },
{ id: 1, step: 1, digits: 2, maxNum: 9.99, defaultNum: 1, title: '剪板', unit: '米', eunit: 'm', priceField: 'length_cut_price' },
{ id: 2, step: 1, digits: 2, minNum: 10, maxNum: 100000, defaultNum: 10, title: '散剪', unit: '米', eunit: 'kg', priceField: 'weight_cut_price' },
])
const [selectIndex, setSelectIndex] = useState(0)
const selectProduct = (index: number) => {
setSelectIndex(() => index)
}
//重置数据
useEffect(() => {
const newList = initList(list)
setList([...newList])
condition.current.code_or_name = null
setSearchShow(false)
}, [selectIndex])
//获取面料颜色列表
const { fetchData: colorFetchData, state: colorState } = GetColorList()
const [list, setList] = useState<any[]>([])
const condition = useRef({ physical_warehouse: adminUserInfo?.physical_warehouse, sale_mode: selectIndex, product_id: 0, code_or_name: null })
const getColorList = async () => {
let { data } = await colorFetchData(getFilterData(condition.current))
let lists = initList(data.list)
setList(() => [...lists])
}
const [showPopup, setShowPopup] = useState(false)
//显示获取
useEffect(() => {
if (show) {
setSelectIndex(0)
condition.current.code_or_name = null
setSearchShow(false)
condition.current.product_id = productId
getColorList()
}
setShowPopup(show)
}, [show])
//初始化列表数据
const initList = useCallback((list) => {
const newList = list.map((item) => {
item.count = 0
item.show = false
return item
})
return newList
}, [])
//卸载数据
useEffect(() => {
return () => {
setList([])
}
}, [])
//popup关闭
const closePopup = () => {
onClose?.()
setShowPopup(false)
setList([])
}
//计算总数量和总米/件数
const [selectCount, setSelectCount] = useState<{ sumCount: number; kindCount: number; color_list: any[] }>({
sumCount: 0,
kindCount: 0,
color_list: [],
})
useEffect(() => {
let sumCount = 0,
kindCount = 0,
color_list: any[] = []
let color_list_info = {}
list.map((item) => {
if (item.count > 0) {
sumCount = Big(sumCount).add(item.count).toNumber()
kindCount++
color_list_info = selectIndex == 0 ? { product_color_id: item.id, roll: item.count } : { product_color_id: item.id, length: item.count * 100 }
color_list.push(color_list_info)
}
})
setSelectCount({ ...selectCount, sumCount, kindCount, color_list })
}, [list])
//计数组件
const getInputValue = useCallback(
(num, item) => {
item.count = parseFloat(num)
if (num == 0) item.show = false
setList(() => [...list])
},
[list],
)
const onAdd = (item) => {
item.show = true
item.count = selectList[selectIndex].defaultNum
setList((list) => [...list])
}
//搜索显示与隐藏
const [searchShow, setSearchShow] = useState(false)
const changeSearchShow = () => {
setSearchShow(true)
}
//添加购物车
const { getShopCount } = useCommonData()
const { getSelfUserInfo } = UseLogin()
const { fetchData: addFetchData } = AddShoppingCartApi()
const addShopCart = async () => {
try {
await getSelfUserInfo()
} catch (msg) {
Taro.showToast({
icon: 'none',
title: '授权失败,请求完善授权',
})
return false
}
if (selectCount.sumCount == 0) {
Taro.showToast({
icon: 'none',
title: '请选择面料颜色!',
})
return false
}
const state = await addFetchData({
sale_mode: selectIndex,
color_list: selectCount.color_list,
})
if (state.success) {
Taro.showToast({
title: '添加成功',
})
getShopCount()
onClose?.()
} else {
Taro.showToast({
icon: 'none',
title: state.msg,
})
}
}
//筛选数据
const searchInput = useCallback((e) => {
condition.current.code_or_name = e
getColorList()
}, [])
//清空搜索内容
const searchRef = useRef<any>(null)
const clearSearch = () => {
searchRef.current.clearInput()
setSearchShow(false)
}
//格式化金额
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 [showLabImage, setShowLabImage] = useState(false)
const [labImageValue, setLabImageValue] = useState()
const getLabAndImg = useCallback((val) => {
setShowLabImage(() => true)
setLabImageValue(val)
}, [])
const closeLabImgShow = useCallback(() => {
setShowLabImage(() => false)
}, [])
//虚拟滚动
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}>
<Popup showTitle={false} show={showPopup} onClose={() => closePopup()}>
<View className={styles.popup_con}>
<View className={styles.header}>{title}</View>
<View className={styles.search}>
<View className={styles.search_title}>:</View>
<View className={styles.search_list}>
{selectList.map((item, index) => {
return (
<View
key={index}
onClick={() => selectProduct(index)}
className={classnames(styles.search_item, selectIndex == index && styles.search_item_select)}>
{item.title}
</View>
)
})}
</View>
</View>
{searchShow && (
<View className={styles.colorFind}>
<View className={styles.search}>
<Search placeIcon='out' ref={searchRef} changeOnSearch={searchInput} debounceTime={400} />
</View>
<View className={styles.text} onClick={() => clearSearch()}>
</View>
</View>
)}
<View className={styles.colorNum}>
<View className={styles.title}> ({list.length})</View>
{!searchShow && <View className={classnames('iconfont icon-sousuo', styles.miconfont)} onClick={() => changeSearchShow()}></View>}
</View>
<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>
)}
{list.length <= 0 && !colorState.loading && <View className={styles.noData}></View>}
</View>
<View className={styles.buy_btn}>
<View className={styles.buy_btn_con}>
<View className={styles.count}>
{selectCount.kindCount}{selectCount.sumCount}
{selectList[selectIndex].unit}
</View>
<View className={classnames(styles.add_cart, selectCount.kindCount && styles.select_add_cart)} onClick={() => addShopCart()}>
</View>
</View>
</View>
</View>
<View className='common_safe_area_y'></View>
</Popup>
<View>
<LabAndImgShow value={labImageValue} show={showLabImage} onClose={closeLabImgShow} />
</View>
</View>
)
})