feat(购物界面): 已完成已选汇总

This commit is contained in:
xuan 2022-09-27 15:38:33 +08:00
parent 3b3adcb203
commit 37d9f85c82
5 changed files with 139 additions and 65 deletions

View File

@ -98,20 +98,22 @@ export default ({minNum = 0, maxNum = 10000, step=1, digits = 0, defaultNum = 0,
onBlue?.(defaultNum) onBlue?.(defaultNum)
} }
} }
const noop = (e) => {
e.stopPropagation()
}
return ( return (
<View className={styles.main}> <View className={styles.main}>
<View className={styles.reduce} onClick={minus}>-</View> <View className={styles.reduce} onClick={minus}>
<View className={styles.input}> -
<Input
value={String(value.count)}
onInput={onInputEven}
onBlur={onBluerEven}
type='digit'
disabled={disable}
/>
<View className={styles.unit}>{unit}</View>
</View>
<View className={styles.plus} onClick={onPlus}>+</View>
</View> </View>
<View className={styles.input} onClick={noop}>
<Input value={String(value.count)} onInput={onInputEven} onBlur={onBluerEven} type='digit' disabled={disable} />
<View className={styles.unit}>{unit}</View>
</View>
<View className={styles.plus} onClick={onPlus}>
+
</View>
</View>
) )
} }

View File

@ -12,7 +12,7 @@ import { selectList } from '../../config'
import { useShoppingContext, useWatch } from '../../context' import { useShoppingContext, useWatch } from '../../context'
type PropsType = { type PropsType = {
purchaserId: number purchaserId: number
item: Record<string, any> & object itemData: Record<string, any> & object
orderType: EnumSaleMode orderType: EnumSaleMode
} }
@ -20,11 +20,11 @@ type PropsType = {
const ColorKindItem: FC<PropsType> = memo( const ColorKindItem: FC<PropsType> = memo(
(props) => { (props) => {
const { purchaserId, item, orderType = EnumSaleMode.Bulk } = props const { purchaserId, itemData, orderType = EnumSaleMode.Bulk } = props
console.log('重新渲染 ColorKindItem', item.id, orderType, purchaserId) console.log('重新渲染 ColorKindItem', itemData.id, orderType, purchaserId)
const { setChangedCheckbox, colorStore } = useShoppingContext() const { setChangedCheckbox, colorStore } = useShoppingContext()
// @ts-ignore // @ts-ignore
const { checked } = useWatch(purchaserId, item?.id) const { checked } = useWatch(purchaserId, itemData?.id)
//格式化金额 //格式化金额
const formatPrice = useCallback((price) => { const formatPrice = useCallback((price) => {
@ -32,36 +32,36 @@ const ColorKindItem: FC<PropsType> = memo(
}, []) }, [])
//格式化数量 //格式化数量
const formatCount = useCallback((item) => { const formatCount = useCallback((itemData) => {
return item.sale_mode == EnumSaleMode.Bulk ? item.roll : item.length / 100 return itemData.sale_mode == EnumSaleMode.Bulk ? itemData.roll : itemData.length / 100
}, []) }, [])
//格式化单位 //格式化单位
const formatUnit = useCallback((item) => { const formatUnit = useCallback((itemData) => {
return item.sale_mode == EnumSaleMode.Bulk ? '条' : '米' return itemData.sale_mode == EnumSaleMode.Bulk ? '条' : '米'
}, []) }, [])
const handleSelect = () => { const handleSelect = () => {
console.log('handleSelect') console.log('handleSelect')
setChangedCheckbox({ setChangedCheckbox({
purchaserId: purchaserId, purchaserId: purchaserId,
goodsKind: { [item.id]: { id: item.id, estimate_amount: item.estimate_amount, checked: true } }, goodsKind: { [itemData.id]: { ...colorStore[purchaserId].goodsKind?.[itemData.id]!, checked: true } },
checked: colorStore[purchaserId].checked, checked: colorStore[purchaserId].checked,
}) })
} }
const handleClose = () => { const handleClose = () => {
setChangedCheckbox({ setChangedCheckbox({
purchaserId: purchaserId, purchaserId: purchaserId,
goodsKind: { [item.id]: { id: item.id, estimate_amount: item.estimate_amount, checked: false } }, goodsKind: { [itemData.id]: { ...colorStore[purchaserId].goodsKind?.[itemData.id]!, checked: false } },
checked: colorStore[purchaserId].checked, checked: colorStore[purchaserId].checked,
}) })
} }
const getInputValue = debounce(async (num, item) => { const getInputValue = debounce(async (num, itemData) => {
if (item.sale_mode === EnumSaleMode.Bulk) { if (itemData.sale_mode === EnumSaleMode.Bulk) {
item.roll = num itemData.roll = num
} else { } else {
item.length = num itemData.length = num
} }
}, 300) }, 300)
@ -73,27 +73,27 @@ const ColorKindItem: FC<PropsType> = memo(
customClassName={classnames(styles.checkbox, checked ? styles.selected : '')} customClassName={classnames(styles.checkbox, checked ? styles.selected : '')}
customTextClass={styles.colorKindItem}> customTextClass={styles.colorKindItem}>
<View className={styles['colorKindItem__left']}> <View className={styles['colorKindItem__left']}>
<Image className={styles['colorKindItem__left--image']} mode='aspectFill' src={formatImgUrl(item.product_color_texture_url)}></Image> <Image className={styles['colorKindItem__left--image']} mode='aspectFill' src={formatImgUrl(itemData.product_color_texture_url)}></Image>
</View> </View>
<View className={styles['colorKindItem__center']}> <View className={styles['colorKindItem__center']}>
<Text className={styles['colorKindItem__center--title']}> <Text className={styles['colorKindItem__center--title']}>
{item.product_code}# {item.product_name} {itemData.product_code}# {itemData.product_name}
</Text> </Text>
<View className={styles['colorKindItem__center--detail']}> <View className={styles['colorKindItem__center--detail']}>
<Text className={styles['colorKindItem__center--ID']}>{item.product_color_code}</Text> <Text className={styles['colorKindItem__center--ID']}>{itemData.product_color_code}</Text>
<Text className={styles['colorKindItem__center--description']}>{item.product_color_name}</Text> <Text className={styles['colorKindItem__center--description']}>{itemData.product_color_name}</Text>
</View> </View>
</View> </View>
<View className={styles['colorKindItem__right']}> <View className={styles['colorKindItem__right']}>
<View className={styles['colorKindItem__right--price']}> {formatPrice(item.sale_price)}/kg</View> <View className={styles['colorKindItem__right--price']}> {formatPrice(itemData.sale_price)}/kg</View>
<View className={styles['colorKindItem__right--counter']}> <View className={styles['colorKindItem__right--counter']}>
<Counter <Counter
onBlue={(e) => getInputValue(e, item)} onBlue={(e) => getInputValue(e, itemData)}
defaultNum={formatCount(item)} defaultNum={formatCount(itemData)}
step={selectList[orderType].step} step={selectList[orderType].step}
digits={selectList[orderType].digits} digits={selectList[orderType].digits}
onClickBtn={(e) => getInputValue(e, item)} onClickBtn={(e) => getInputValue(e, itemData)}
unit={formatUnit(item)} unit={formatUnit(itemData)}
minNum={selectList[orderType].minNum} minNum={selectList[orderType].minNum}
maxNum={selectList[orderType].maxNum} maxNum={selectList[orderType].maxNum}
/> />
@ -103,8 +103,8 @@ const ColorKindItem: FC<PropsType> = memo(
) )
}, },
(preProp, nextProp) => { (preProp, nextProp) => {
const stringifyPreProp = JSON.stringify(preProp.item) const stringifyPreProp = JSON.stringify(preProp.itemData)
const stringifyNextProp = JSON.stringify(nextProp.item) const stringifyNextProp = JSON.stringify(nextProp.itemData)
console.log('memo==>', preProp, nextProp) console.log('memo==>', preProp, nextProp)
let needMemoized = true let needMemoized = true
if (preProp.purchaserId !== nextProp.purchaserId) { if (preProp.purchaserId !== nextProp.purchaserId) {

View File

@ -49,14 +49,17 @@ export const ShoppingCart: FC<ShoppingCartPropsType> = (props) => {
colorStore, colorStore,
setChangedCheckbox(changedGoods) { setChangedCheckbox(changedGoods) {
console.log('changedGoods==>', colorStore, changedGoods) console.log('changedGoods==>', colorStore, changedGoods)
setColorStore((prev) => ({ setColorStore((prev) => {
...prev, const currentGoodsKind = { ...prev[changedGoods.purchaserId]?.goodsKind, ...changedGoods.goodsKind }
[changedGoods.purchaserId as number]: { return {
purchaserId: changedGoods.purchaserId, ...prev,
goodsKind: { ...prev[changedGoods.purchaserId]?.goodsKind, ...changedGoods.goodsKind }, [changedGoods.purchaserId as number]: {
checked: changedGoods.checked, purchaserId: changedGoods.purchaserId,
}, goodsKind: currentGoodsKind,
})) checked: changedGoods.checked,
},
}
})
setChangedCheckbox(changedGoods) setChangedCheckbox(changedGoods)
}, },
setColorStore, setColorStore,

View File

@ -2,26 +2,30 @@ import { Text, View } from '@tarojs/components'
import { FC, memo, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react' import { FC, memo, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react'
import styles from './index.module.scss' import styles from './index.module.scss'
import classnames from 'classnames' import classnames from 'classnames'
import { formatPriceDiv } from '@/common/format' import { formatMeterDiv, formatPriceDiv } from '@/common/format'
import Taro, { useDidShow } from '@tarojs/taro' import Taro, { useDidShow } from '@tarojs/taro'
import LayoutBlock from '@/components/layoutBlock' import LayoutBlock from '@/components/layoutBlock'
import MCheckbox from '@/components/checkbox' import MCheckbox from '@/components/checkbox'
import Tag from '@/components/tag' import Tag from '@/components/tag'
import Divider from '@/components/divider' import Divider from '@/components/divider'
import NormalButton from '@/components/normalButton'
import ColorKindItem from '../colorKindItem' import ColorKindItem from '../colorKindItem'
import { EnumSaleMode } from '@/common/Enumerate' import { EnumSaleMode } from '@/common/Enumerate'
import { useNeedMemoCallback } from '@/use/useCommon' import { useNeedMemoCallback } from '@/use/useCommon'
import { selectList } from '../../config' import { selectList } from '../../config'
import { useShoppingContext } from '../../context' import { Goods, useShoppingContext } from '../../context'
import IconFont from '@/components/iconfont/iconfont' import IconFont from '@/components/iconfont/iconfont'
import { isEmptyObject } from '@/common/common'
type PropsType = { type PropsType = {
itemData?: ShoppingCartData itemData?: ShoppingCartData
} }
const DrawerButton = memo<{ isOpen: boolean }>(({ isOpen }) => { const DrawerButton = memo<{ isOpen: boolean }>(({ isOpen }) => {
return <View className={styles.drawerButton}>{isOpen ? <IconFont name='icon-shouqi' size={52}></IconFont> : <IconFont name='icon-zhankai' size={52}></IconFont>}</View> return (
<View className={styles.drawerButton}>
{isOpen ? <IconFont name='icon-shouqi' size={52}></IconFont> : <IconFont name='icon-zhankai' size={52}></IconFont>}
</View>
)
}) })
enum BackEndSaleModeListFieldMap { enum BackEndSaleModeListFieldMap {
@ -30,7 +34,7 @@ enum BackEndSaleModeListFieldMap {
weight_cut_color_list = 2, weight_cut_color_list = 2,
} }
export default memo<PropsType>((props) => { export default memo<PropsType>(props => {
console.log('props==>', props) console.log('props==>', props)
const { itemData } = props const { itemData } = props
@ -40,7 +44,7 @@ export default memo<PropsType>((props) => {
const [openDetail, setOpenDetail] = useState(false) const [openDetail, setOpenDetail] = useState(false)
const handleOpenDetail = () => { const handleOpenDetail = () => {
setOpenDetail((isOpen) => !isOpen) setOpenDetail(isOpen => !isOpen)
handleClickLayout() handleClickLayout()
} }
@ -64,25 +68,37 @@ export default memo<PropsType>((props) => {
weight_cut_color_list: itemData?.weight_cut_color_list, weight_cut_color_list: itemData?.weight_cut_color_list,
} }
const { setChangedCheckbox, currentCheckedPurchaserId, setCurrentCheckedPurchaserId, isManageStatus, setSelectedAmount, colorStore } = useShoppingContext() const { setChangedCheckbox, currentCheckedPurchaserId, setCurrentCheckedPurchaserId, isManageStatus, setSelectedAmount, colorStore, currentCheckedSaleMode } = useShoppingContext()
const memoList = useMemo(() => { const memoList = useMemo(() => {
const selectedList = itemData?.[BackEndSaleModeListFieldMap[selected]].length !== 0 ? itemData?.[BackEndSaleModeListFieldMap[selected]] : [{}]
const selectedList = itemData?.[BackEndSaleModeListFieldMap[selected]].length !==0 ? itemData?.[BackEndSaleModeListFieldMap[selected]] : [{}] // 给每一个客户都初始化一个 checked 状态
selectedList.forEach(() => {
selectedList.forEach((item) => {
console.log('memoList itemData', item)
// 初始化选中状态 // 初始化选中状态
setChangedCheckbox({ setChangedCheckbox({
purchaserId: itemData?.purchaser_id!, purchaserId: itemData?.purchaser_id!,
goodsKind: { [item?.id]: { id: item?.id, estimate_amount: item.estimate_amount, checked: false } },
checked: false, checked: false,
}) })
}) })
// 向 context 中初始化数据
return itemData?.[BackEndSaleModeListFieldMap[selected]].length !== 0 ? ( return itemData?.[BackEndSaleModeListFieldMap[selected]].length !== 0 ? (
itemData?.[BackEndSaleModeListFieldMap[selected]].map((item) => { itemData?.[BackEndSaleModeListFieldMap[selected]].map(item => {
return <ColorKindItem purchaserId={itemData.purchaser_id} key={item.id} item={item} orderType={selected}></ColorKindItem> setChangedCheckbox({
purchaserId: itemData?.purchaser_id!,
goodsKind: {
[item?.id]: {
id: item?.id,
estimate_amount: item.estimate_amount,
checked: false,
product_code: item.product_code,
product_color_code: item.product_color_code,
sale_mode: item.sale_mode,
count: selected === EnumSaleMode.Bulk ? item.roll : Number(formatMeterDiv(item.length)),
},
},
checked: false,
})
return <ColorKindItem purchaserId={itemData.purchaser_id} key={item.id} itemData={item} orderType={selected}></ColorKindItem>
}) })
) : ( ) : (
<View className={styles.noList}></View> <View className={styles.noList}></View>
@ -115,6 +131,48 @@ export default memo<PropsType>((props) => {
checked: false, checked: false,
}) })
} }
// 统计已选面料
const materialChecked = useMemo(() => {
const targetGoodsKind = colorStore?.[itemData?.purchaser_id!]?.['goodsKind']
console.log('targetGoodsKind==>', targetGoodsKind)
if (!targetGoodsKind || isEmptyObject(targetGoodsKind)) return 0
return new Set(
Object.values(targetGoodsKind)?.reduce((prev, item: Goods) => {
if (item.checked && item.sale_mode === selected) {
return [...prev, item.product_code]
}
return prev
}, []),
).size
}, [colorStore, currentCheckedPurchaserId, selected, itemData])
// 统计已选颜色
const colorChecked = useMemo(() => {
const targetGoodsKind = colorStore?.[itemData?.purchaser_id!]?.['goodsKind']
if (!targetGoodsKind || isEmptyObject(targetGoodsKind)) return 0
return new Set(
Object.values(targetGoodsKind).reduce((prev, item: Goods) => {
if (item.checked && item.sale_mode === selected) {
return [...prev, item.product_color_code]
}
return prev
}, []),
).size
}, [colorStore, currentCheckedPurchaserId, selected, itemData])
// 统计已选条数 / 米数
const lengthOrRollChecked = useMemo(() => {
const targetGoodsKind = colorStore?.[itemData?.purchaser_id!]?.['goodsKind']
if (!targetGoodsKind || isEmptyObject(targetGoodsKind)) return 0
return (
Object.values(targetGoodsKind).reduce((prev, item: Goods) => {
if (item.checked && item.sale_mode === selected) {
return prev + item.count
}
return prev
}, 0) || 0
)
}, [colorStore, currentCheckedPurchaserId, selected, itemData])
return ( return (
<LayoutBlock <LayoutBlock
@ -139,9 +197,13 @@ export default memo<PropsType>((props) => {
</View> </View>
<View className={styles.summary}> <View className={styles.summary}>
<Text> <Text>
{itemData?.[BackEndSaleModeListFieldMap[selected]].filter((item) => item.checked).length} 1 {' '} {materialChecked} {colorChecked} {' '}
{selected === EnumSaleMode.Bulk ? `${4}` : `${4}`} {selected === EnumSaleMode.Bulk ? `${lengthOrRollChecked}` : `${lengthOrRollChecked}`}
</Text> </Text>
{/* <Text>
{0} {0} {' '}
{selected === EnumSaleMode.Bulk ? `${0}` : `${0}`}
</Text> */}
</View> </View>
</View> </View>
<DrawerButton isOpen={openDetail} /> <DrawerButton isOpen={openDetail} />
@ -197,7 +259,7 @@ interface ButtonPropsType {
customStyle?: React.CSSProperties customStyle?: React.CSSProperties
} }
// 订单类型 // 订单类型
const SaleModeButton: FC<ButtonPropsType> = (props) => { const SaleModeButton: FC<ButtonPropsType> = props => {
const { onClick, children, isActive = false, customStyle } = props const { onClick, children, isActive = false, customStyle } = props
const handleClick = () => { const handleClick = () => {
onClick?.() onClick?.()

View File

@ -27,12 +27,19 @@ export type ColorStore = {
export type Goods = { export type Goods = {
id: number id: number
product_code: number // 面料编号
product_color_code: number // 颜色编号
estimate_amount: number // 预估金额 estimate_amount: number // 预估金额
count: number // 已选的条数或米数
sale_mode: number
checked: boolean checked: boolean
} }
// 分组 // 分组
export interface GoodsMeta { export interface GoodsMeta {
purchaserId: number purchaserId: number
// materialChecked: number // 已选 x 种面料
// colorChecked: number // 已选 x 颜色
// lengthOrRollChecked: number // 共 x 条 共 x 米
goodsKind?: { goodsKind?: {
[id: number]: Goods [id: number]: Goods
} }