import Search from '@/components/search' import { View } from '@tarojs/components' import Taro, { useDidShow } from '@tarojs/taro' import { FC, memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, useTransition } from 'react' import styles from './index.module.scss' import classnames from 'classnames' import IconText from '@/components/iconText' import InfiniteScroll from '@/components/infiniteScroll' import ItemList from './components/shoppingCartItem/index' import { formatPriceDiv } from '@/common/format' import BottomSettleBar from './components/bottomSettleBar' import BottomEditBar from './components/bottomEditBar' import { ShoppingCartDeleteApi, ShoppingCartListApi } from '@/api/index' import { dataLoadingStatus, debounce, getFilterData } from '@/common/util' import { ShoppingProvider } from './components/shoppingCart/index' import { Goods, ShoppingDispatchType, useShoppingDispatch, useShoppingState } from './context' import { alert, goLink, isEmptyObject } from '@/common/common' import LoadingCard from '@/components/loadingCard' export const Shopping: FC = memo(() => { // 计算总的预估金额 const handleTriggerCheckbox = ({ colorStore, currentCheckedPurchaserId, setSelectedAmount }) => { const targetGoodsKind = colorStore?.[currentCheckedPurchaserId]?.['goodsKind'] console.log('handleTriggerCheckbox==>', colorStore) if (targetGoodsKind) { const result = Object.values(targetGoodsKind).reduce((prev: number, value: Goods) => { if (value.checked) { return prev + Number(formatPriceDiv(value.estimate_amount)) } return prev }, 0) as number console.log('result==>', result) // 同步修改上下文的 预估金额 setSelectedAmount(result) } else { setSelectedAmount(0) } } return ( ) }) interface InternalContainer {} const ShoppingCartContainer: FC = () => { let isFirst = useRef(true) const { isManageStatus, selectedAmount, currentCheckedPurchaserId, currentCheckedSaleMode, colorStore } = useShoppingState() const dispatch = useShoppingDispatch() // 管理 const onStartToManage = () => { dispatch({ type: ShoppingDispatchType.UPDATE_MANAGE_STATUS, data: !isManageStatus }) } const listHeightRef = useRef('auto') const { fetchData, state } = ShoppingCartListApi() const [searchOptions, setSearchOptions] = useState({ short_name_or_phone: '', }) useDidShow(() => { if (!isFirst.current) { fetchData(searchOptions) } }) console.log('Rerender component: ShoppingCartContainer') useEffect(() => { console.log('useEffect fetchData') if (!isEmptyObject(getFilterData(searchOptions))) { fetchData(searchOptions) } }, [searchOptions]) // 输入了搜索关键字 const getSearchData = useCallback(e => { setSearchOptions(prev => ({ ...prev, short_name_or_phone: e })) }, []) const [shoppingCartData, setShoppingCartData] = useState<{ list: ShoppingCartData[]; total: number }>({ list: [], total: 0 }) //数据加载状态 const statusMore = useMemo(() => { const status = dataLoadingStatus({ list: shoppingCartData.list, total: shoppingCartData.total, status: state.loading }) console.log('status==>', status) return status }, [shoppingCartData, state]) // useLayoutEffect 执行在DOM更新之后,浏览器绘制之前 如果放在 useEffect 里面会产生多一次不必要的回流和重绘,可能会引起视图闪现 useLayoutEffect(() => { ;(async () => { console.log('useLayoutEffect') await fetchData() isFirst.current = false let query = Taro.createSelectorQuery() console.log('query', query) query.select('#shoppingContainer').boundingClientRect() query.select('#topBar').boundingClientRect() query.select('#bottomBar').boundingClientRect() query.exec(res => { console.log('res==>', res) const containerHeight = res[0].height const topBarHeight = res[1].height const bottomBarHeight = res[2].height const listHeight = containerHeight - topBarHeight - bottomBarHeight listHeightRef.current = listHeight + 'px' }) })() }, []) const [isPending, startTransition] = useTransition() useEffect(() => { startTransition(() => { setShoppingCartData({ list: state.data, total: state.data.length }) }) }, [state]) // 结算 const handleSettleAccount = debounce(() => { const targetGoodsKind = colorStore?.[currentCheckedPurchaserId]?.['goodsKind'] if (!targetGoodsKind) return Taro.showToast({ title: '请先选择客户', icon: 'error' }) const checkedGoodsKind = Object.values(targetGoodsKind).reduce((prev, item: Goods) => { if (item.checked) { return [...prev, item.id] } return prev }, []) if (checkedGoodsKind.length === 0) return Taro.showToast({ title: '请先选择商品', icon: 'error' }) goLink('/pages/submitOrder/index', { purchaser_id: currentCheckedPurchaserId, sale_mode: currentCheckedSaleMode, shopping_cart_product_color_list: JSON.stringify(checkedGoodsKind), purchaser_name: shoppingCartData?.list.find(item => item.purchaser_id === currentCheckedPurchaserId)?.purchaser_name, }) }, 400) const { fetchData: deleteApi } = ShoppingCartDeleteApi() // 批量某个客户的删除商品 const handleDelete = async () => { const targetGoodsKind = colorStore?.[currentCheckedPurchaserId]?.['goodsKind'] let checked: Goods[] = [] if (targetGoodsKind) { checked = Object.values(targetGoodsKind).filter((item: Goods) => item.checked) if (checked.length === 0) { return Taro.showToast({ title: '请选择商品', icon: 'error' }) } } console.log('checked==>', checked) Taro.showModal({ title: '要删除这些商品吗?', success: async function(res) { if (res.confirm) { const res = await deleteApi({ ids: checked.map(item => item.id).join(','), }) if (res.success) { alert.success('删除成功') fetchData(searchOptions) } else { alert.none(res.msg) } } }, }) } // 全选 const handleSelectAllCheckbox = (isSelectAll: boolean) => { console.log('handleSelectAllCheckbox', isSelectAll) const targetGoodsKind = colorStore?.[currentCheckedPurchaserId]?.['goodsKind'] if (!targetGoodsKind) return Taro.showToast({ title: '请先选择客户', icon: 'error' }) console.log('targetGoodsKind==>', targetGoodsKind) const tempObject = {} Object.entries(targetGoodsKind).forEach(([key, value]) => { tempObject[key] = { ...value, checked: isSelectAll, } }) console.log('tempObject==>', tempObject) dispatch({ type: ShoppingDispatchType.UPDATE_CHANGED_CHECKBOX, data: { purchaserId: currentCheckedPurchaserId, goodsKind: tempObject, }, }) // setChangedCheckbox({ // purchaserId: currentCheckedPurchaserId, // goodsKind: tempObject, // }) } // 加载刷新数据 const [refreshStatus, setRefreshStatus] = useState(false) // 下拉刷新 const handleRefresh = async () => { setRefreshStatus(true) const res = await fetchData(searchOptions) if (res.success) { console.log('请求 成功') setRefreshStatus(false) Taro.showToast({ title: '刷新成功', icon: 'success' }) } else { console.log('请求 失败') Taro.showToast({ title: '刷新失败', icon: 'error' }) setRefreshStatus(false) } } return ( {isManageStatus ? ( ) : ( )} {isPending ? ( ) : ( !!shoppingCartData?.list?.length && shoppingCartData?.list?.map((item, index) => { return }) )} {isManageStatus ? ( handleSelectAllCheckbox(isAll)}> ) : ( )} ) } // interface ScrollListPropType { // height: string // } // const ScrollList = memo((props) => { // const { height } = props // const [shoppingCartData, setShoppingCartData] = useState<{ list: ShoppingCartData[]; total: number }>({ list: [], total: 0 }) // //数据加载状态 // const statusMore = useMemo(() => { // return dataLoadingStatus({ list: shoppingCartData.list, total: shoppingCartData.total, status: state.loading }) // }, [shoppingCartData, state]) // return ( // // // // {!!shoppingCartData?.list?.length && // shoppingCartData?.list?.map((item, index) => { // return // })} // // // // ) // }) export default Shopping