🐞 fix(购物页面): 修复选中条数不正确的偶现问题

This commit is contained in:
xuan 2023-01-03 19:30:16 +08:00
parent b37006724b
commit 9cd2f5579d
4 changed files with 99 additions and 75 deletions

View File

@ -15,7 +15,7 @@ export const BASE_URL = CURRENT_BASE_URL
// export const BASE_URL = 'http://192.168.1.7:50002/lymarket' // 添
// export const BASE_URL = 'http://192.168.1.42:50002/lymarket' // 杰
// export const BASE_URL = `http://192.168.1.95:40001/lymarket` // 华
// export const BASE_URL = 'http://192.168.1.28:50002/lymarket' // 婷
// export const BASE_URL = 'http://192.168.1.28:50001/lymarket' // 婷
// CDN
// 生成密钥

View File

@ -1,6 +1,6 @@
import { Image, Text, View } from '@tarojs/components'
import type { FC } from 'react'
import { forwardRef, memo, useCallback, useEffect, useState } from 'react'
import { forwardRef, memo, useCallback, useEffect, useRef, useState } from 'react'
import classnames from 'classnames'
import { selectList } from '../../config'
import type { ShoppingStateContextValue } from '../../context'
@ -37,7 +37,10 @@ const ColorKindItem: FC<PropsType> = (props) => {
props.onChange?.(value, itemData.id)
},
})
const currentCount = useRef({
roll: itemData.roll,
length: itemData.length,
})
// 格式化数量
const formatCount = (itemData) => {
return itemData.sale_mode == EnumSaleMode.Bulk ? itemData.roll : formatMeterDiv(itemData.length)
@ -60,13 +63,14 @@ const ColorKindItem: FC<PropsType> = (props) => {
}
// 选中
const handleSelect = () => {
console.log('currentCount==>', currentCount.current, itemData)
const payload = {
id: itemData?.id,
estimate_amount: itemData.estimate_amount,
product_code: itemData.product_code,
product_color_code: itemData.product_color_code,
sale_mode: itemData.sale_mode,
count: itemData.sale_mode === EnumSaleMode.Bulk ? itemData.roll : Number(formatMeterDiv(itemData.length)),
count: itemData.sale_mode === EnumSaleMode.Bulk ? currentCount.current.roll : Number(formatMeterDiv(currentCount.current.length)),
}
events.trigger('updatePurchaserMultipleSelection', purchaserId, payload, 'add', itemData?.id)
setCheck(true)
@ -81,16 +85,16 @@ const ColorKindItem: FC<PropsType> = (props) => {
// 调整条数/米数的接口 并在调整完成后重新请求整个购物车页面
const getInputValue = useCallback(debounce(async(num) => {
console.log('num===>', num)
const targetColor: Record<string, any> = {
const targetColor = {
roll: 0,
length: 0,
}
if (itemData.sale_mode === EnumSaleMode.Bulk) {
itemData.roll = num
// itemData.roll = num
targetColor.roll = num
}
else {
itemData.length = formatMeterMul(num)
// itemData.length = formatMeterMul(num)
targetColor.length = formatMeterMul(num)
}
const res = await fetchData({
@ -99,17 +103,24 @@ const ColorKindItem: FC<PropsType> = (props) => {
length: targetColor.length,
})
if (res.success) {
currentCount.current = targetColor
state?.Observer?.notify(purchaserId)
}
else {
// 请求失败,赋值回初始数量
setCount(formatCount(itemData))
}
}, 460), [itemData])
const labAndImgObj = useCallback((item) => {
return { lab: item.lab, rgb: item.rgb, texture_url: item.product_color_texture_url }
}, [])
useEffect(() => {
console.log('itemData==>', itemData)
setCount(formatCount(itemData))
}, [itemData.roll, itemData.length])
return (
<MCheckbox
status={isChecked}

View File

@ -7,7 +7,7 @@ import classNames from 'classnames'
import produce, { setAutoFreeze } from 'immer'
import ColorKindItem from '../colorKindItem'
import { selectList } from '../../config'
import type { Goods, GoodsMeta, ShoppingStateContextValue } from '../../context'
import type { ColorStore, Goods, GoodsMeta, ShoppingStateContextValue } from '../../context'
import { ShoppingDispatchType, useShoppingDispatch, useShoppingState } from '../../context'
import type { ShoppingStore } from '../../context/shoppingStore'
import { events } from '../../context/shoppingStore'
@ -66,47 +66,48 @@ interface GoodsListPropType {
}
const GoodsList = (props: GoodsListPropType) => {
const { itemData, selected, isPending, startTransition, multipleSelection } = props
const prevMultipleSelection = useRef(multipleSelection)
console.log('rerender component GoodsList', props)
// const prevMultipleSelection = useRef(multipleSelection)
const currentSelected = useRef<EnumSaleMode | null>(null)
const dispatch = useShoppingDispatch()
const [component, setComponent] = useState<JSX.Element | null>(null)
// 使用 produce 更新特定的 ColorKindItem
const updateSpecifiedComponent = () => {
let newId
if (multipleSelection && prevMultipleSelection.current !== multipleSelection) {
for (const key in multipleSelection) {
if (!prevMultipleSelection.current?.hasOwnProperty(key)) {
newId = key
break
}
}
}
console.log('multipleSelection==+>', multipleSelection)
console.log('currentSelected', currentSelected.current, selected)
console.log('component', component)
if (component) {
if (itemData?.[BackEndSaleModeListFieldMap[selected]].length !== 0) {
setComponent(produce(component, (draft) => {
console.log('prev', component)
const index = (draft as unknown as any[]).findIndex(item => item.key === newId)
console.log('index', index)
if (index !== -1) {
const item = itemData?.[BackEndSaleModeListFieldMap[selected]].find((item) => {
return item.id === Number(newId)
})
console.log('item', item, newId)
draft![index] = <ColorKindItem checked={multipleSelection?.hasOwnProperty(newId)} purchaserId={itemData?.purchaser_id} key={newId} itemData={item}></ColorKindItem>
}
}))
}
else {
setComponent(<View className={styles.noList}></View>)
}
}
prevMultipleSelection.current = multipleSelection
}
// const updateSpecifiedComponent = () => {
// let newId
// if (multipleSelection && prevMultipleSelection.current !== multipleSelection) {
// for (const key in multipleSelection) {
// if (!prevMultipleSelection.current?.hasOwnProperty(key)) {
// newId = key
// break
// }
// }
// }
// console.log('multipleSelection==+>', multipleSelection)
// console.log('currentSelected', currentSelected.current, selected)
// console.log('component', component)
// if (component) {
// if (itemData?.[BackEndSaleModeListFieldMap[selected]].length !== 0) {
// setComponent(produce(component, (draft) => {
// console.log('prev', component)
// const index = (draft as unknown as any[]).findIndex(item => item.key === newId)
// console.log('index', index)
// if (index !== -1) {
// const item = itemData?.[BackEndSaleModeListFieldMap[selected]].find((item) => {
// return item.id === Number(newId)
// })
// console.log('item', item, newId)
// draft![index] = <ColorKindItem checked={multipleSelection?.hasOwnProperty(newId)} purchaserId={itemData?.purchaser_id} key={newId} itemData={item}></ColorKindItem>
// }
// }))
// }
// else {
// setComponent(<View className={styles.noList}>暂无数据</View>)
// }
// }
// prevMultipleSelection.current = multipleSelection
// }
// 更新 GoodsList 组件
const updateComponent = () => {
setComponent(
@ -121,7 +122,7 @@ const GoodsList = (props: GoodsListPropType) => {
<View className={styles.noList}></View>
),
)
prevMultipleSelection.current = multipleSelection
// prevMultipleSelection.current = multipleSelection
}
useEffect(() => {
@ -184,6 +185,7 @@ const GoodsListWithMemo = memo<GoodsListPropType>(GoodsList)
interface PropsType {
itemData?: ShoppingCartData
state?: {
colorStore?: ColorStore
multipleSelection?: GoodsMeta['multipleSelection']
currentCheckedPurchaserId?: number
Observer?: ShoppingStore
@ -194,11 +196,13 @@ const ShoppingCartItem: FC<PropsType> = (props) => {
const { state } = props
console.log('rerender component ShoppingCartItem', props)
const currentItemData = useRef<ShoppingCartData | undefined>(props.itemData)
const [itemData, setItemData] = usePropsValue({
value: props.itemData,
value: currentItemData.current,
defaultValue: props.itemData,
})
const { multipleSelection, currentCheckedPurchaserId } = state!
const { multipleSelection, currentCheckedPurchaserId, colorStore } = state!
const dispatch = useShoppingDispatch()
const [openDetail, setOpenDetail] = useState(false)
@ -216,14 +220,16 @@ const ShoppingCartItem: FC<PropsType> = (props) => {
}
const handleClickLayout = () => {
if (currentCheckedPurchaserId === itemData?.purchaser_id) {
if (currentCheckedPurchaserId === props.itemData?.purchaser_id) {
return
}
currentItemData.current = props.itemData
setItemData(props.itemData)
dispatch({ type: ShoppingDispatchType.UPDATE_SELECTED_AMOUNT, data: 0 })
dispatch({ type: ShoppingDispatchType.UPDATE_CURRENT_CHECKED_SALEMODE, data: selected })
dispatch({
type: ShoppingDispatchType.UPDATE_CURRENT_CHECKED_PURCHASERID,
data: itemData?.purchaser_id as number,
data: props.itemData?.purchaser_id as number,
})
dispatch({ type: ShoppingDispatchType.UPDATE_MULTIPLE_SELECTION_STATUS, data: false })
}
@ -233,6 +239,7 @@ const ShoppingCartItem: FC<PropsType> = (props) => {
}
// 统计已选面料
const materialChecked = useMemo(() => {
const multipleSelection = colorStore?.[itemData!.purchaser_id]?.multipleSelection
if (!multipleSelection || isEmptyObject(multipleSelection)) { return 0 }
return new Set(
Object.values(multipleSelection)?.reduce((prev, item: Goods) => {
@ -242,10 +249,11 @@ const ShoppingCartItem: FC<PropsType> = (props) => {
return prev
}, []),
).size
}, [multipleSelection, currentCheckedPurchaserId, selected, itemData])
}, [colorStore, currentCheckedPurchaserId, selected, itemData])
// 统计已选颜色
const colorChecked = useMemo(() => {
const multipleSelection = colorStore?.[itemData!.purchaser_id]?.multipleSelection
console.log('colorChecked item', multipleSelection)
if (!multipleSelection || isEmptyObject(multipleSelection)) { return 0 }
return new Set(
@ -256,20 +264,26 @@ const ShoppingCartItem: FC<PropsType> = (props) => {
return prev
}, []),
).size
}, [multipleSelection, currentCheckedPurchaserId, selected, itemData])
}, [colorStore, currentCheckedPurchaserId, selected, itemData])
// 统计已选条数 / 米数
const lengthOrRollChecked = useMemo(() => {
console.log('lengthOrRollChecked item', multipleSelection)
const multipleSelection = colorStore?.[itemData!.purchaser_id]?.multipleSelection
console.log('lengthOrRollChecked item', multipleSelection, currentCheckedPurchaserId, itemData)
if (!multipleSelection || isEmptyObject(multipleSelection)) { return 0 }
return (
Object.values(multipleSelection).reduce((prev, item: Goods) => {
return prev + item.count
}, 0) || 0
)
}, [multipleSelection, currentCheckedPurchaserId, selected, itemData])
}, [colorStore, currentCheckedPurchaserId, selected, itemData])
const { fetchData } = ShoppingCartListApi()
useEffect(() => {
if (itemData?.purchaser_id === 1708 || itemData?.purchaser_id === 642) {
console.log('useEffect multipleSelection', multipleSelection, colorStore)
}
}, [itemData, multipleSelection, colorStore])
// 更新当前客户的多选项
const updatePurchaserMultipleSelection = (purchaserId, payload, operationType: OperationType, goodsId: number) => {
if (operationType === 'add') {
@ -277,21 +291,15 @@ const ShoppingCartItem: FC<PropsType> = (props) => {
type: ShoppingDispatchType.UPDATE_CHANGED_CHECKBOX,
data: {
purchaserId,
multipleSelection: produce(multipleSelection, (multipleSelectionDraft) => {
if (!multipleSelectionDraft) {
return {
[goodsId]: payload,
}
}
else {
multipleSelectionDraft[goodsId] = payload
}
}),
multipleSelection: {
...colorStore?.[purchaserId].multipleSelection,
[goodsId]: payload,
},
},
})
}
else if (operationType === 'delete') {
const temp = { ...multipleSelection }
const temp = { ...colorStore?.[purchaserId].multipleSelection }
delete temp?.[goodsId]
dispatch({
type: ShoppingDispatchType.UPDATE_CHANGED_CHECKBOX,
@ -326,6 +334,7 @@ const ShoppingCartItem: FC<PropsType> = (props) => {
// ...
// }
if (!res.data.list.length) { return alert.error('修改数量失败') }
const newGoodsKind = Object.fromEntries(
res.data.list[0]?.[BackEndSaleModeListFieldMap[selected]].map(item => [
item?.id,
@ -360,6 +369,7 @@ const ShoppingCartItem: FC<PropsType> = (props) => {
),
},
})
currentItemData.current = res.data.list[0]
setItemData(() => res.data.list[0])
}
else {
@ -459,17 +469,17 @@ const withStateSlice = (comp, slice) => {
if (JSON.stringify(prevProps.itemData) !== JSON.stringify(nextProps.itemData)) {
needMemo = false
}
if (prevProps.itemData.purchaser_name === 'JENNIE') {
console.log('------withStateSlice props-------')
console.log('withStateSlice props prevProps', prevProps)
console.log('withStateSlice props prevProps comparison itemData', prevProps.itemData === nextProps.itemData)
console.log('withStateSlice props nextProps', nextProps)
console.log('withStateSlice props prevProps comparison multipleSelection', prevProps.state.multipleSelection === nextProps.state.multipleSelection)
console.log('withStateSlice props prevProps comparison currentCheckedPurchaserId', prevProps.state.currentCheckedPurchaserId === nextProps.state.currentCheckedPurchaserId)
console.log('withStateSlice props prevProps comparison Observer', prevProps.state.Observer === nextProps.state.Observer)
console.log('withStateSlice props prevProps comparison state', prevProps.state === nextProps.state)
console.log('------withStateSlice props-------')
}
// if (prevProps.itemData.purchaser_name === 'JENNIE') {
// console.log('------withStateSlice props-------')
// console.log('withStateSlice props prevProps', prevProps)
// console.log('withStateSlice props prevProps comparison itemData', prevProps.itemData === nextProps.itemData)
// console.log('withStateSlice props nextProps', nextProps)
// console.log('withStateSlice props prevProps comparison multipleSelection', prevProps.state.multipleSelection === nextProps.state.multipleSelection)
// console.log('withStateSlice props prevProps comparison currentCheckedPurchaserId', prevProps.state.currentCheckedPurchaserId === nextProps.state.currentCheckedPurchaserId)
// console.log('withStateSlice props prevProps comparison Observer', prevProps.state.Observer === nextProps.state.Observer)
// console.log('withStateSlice props prevProps comparison state', prevProps.state === nextProps.state)
// console.log('------withStateSlice props-------')
// }
if (prevProps.state.Observer !== nextProps.state.Observer) {
console.log('Observer 有变化')
needMemo = false
@ -486,13 +496,15 @@ const withStateSlice = (comp, slice) => {
})
const Wrapper = (props, ref) => {
const state = useShoppingState()
// console.log('Wrapper colorStore', state.colorStore)
return <MemoComp ref={ref} state={slice(state, props)} {...props} />
}
return memo(forwardRef(Wrapper))
}
const ShoppingCartItemWithStateSlice = withStateSlice(ShoppingCartItem, (state: ShoppingStateContextValue, props) => ({
multipleSelection: state.colorStore?.[props.itemData?.purchaser_id]?.multipleSelection,
colorStore: state.colorStore,
multipleSelection: state.colorStore?.[props.itemData.purchaser_id]?.multipleSelection,
currentCheckedPurchaserId: state.currentCheckedPurchaserId,
Observer: state.Observer,
}))

View File

@ -5,6 +5,7 @@ import type { ShoppingStore } from './shoppingStore'
import type { EnumSaleMode } from '@/common/Enumerate'
/**
* 使weakmap来作为第一层的数据结构
* 456: {
* purchaserId: 456,
* colorKind: {