feat(购物页面): 新增批量删除商品功能

This commit is contained in:
xuan 2022-10-17 17:59:38 +08:00
parent d5190ba439
commit 4b75ef1493
10 changed files with 119 additions and 139 deletions

View File

@ -15,7 +15,7 @@ export const ShoppingCartUpdateApi = () => {
*/ */
export const ShoppingCartDeleteApi = () => { export const ShoppingCartDeleteApi = () => {
return useRequest({ return useRequest({
url: `/v1/mp/shoppingCart/productColor`, url: `/v2/mp/shoppingCart/productColor`,
method: "delete", method: "delete",
}) })
} }

View File

@ -6,29 +6,25 @@
background-color: white; background-color: white;
padding: 16px 24px; padding: 16px 24px;
.bottomLeft{ .bottomLeft {
margin-left: 12px; margin-left: 12px;
.moneyText{ .moneyText {
font-size: 24px; font-size: 24px;
font-family: $font_family; font-family: $font_family;
font-weight: 400; font-weight: 400;
color: rgba($color: #000000, $alpha: 0.6); color: rgba($color: #000000, $alpha: 0.6);
} }
.moneyNumber{ .moneyNumber {
font-size: 28px; font-size: 28px;
font-family: $font_family; font-family: $font_family;
font-weight: 500; font-weight: 500;
color: $color_money; color: $color_money;
} }
} }
.bottomRight{ .bottomRight {
display: flex;
flex-flow: row nowrap;
align-items: center;
} }
.bottomButton {
}
} }

View File

@ -8,23 +8,23 @@ import MCheckbox from '@/components/checkbox'
type PropsType = { type PropsType = {
onDelete?: Function onDelete?: Function
onSelectCheckbox?: (bool: boolean) => void onSelectCheckbox?: (bool: boolean) => void
disabled?: boolean
} }
export default memo<PropsType>((props) => { export default memo<PropsType>(props => {
const { onDelete, onSelectCheckbox } = props const { onDelete, onSelectCheckbox, disabled = false } = props
const handleSettle = () => { const handleDelete = () => {
onDelete && onDelete() onDelete && onDelete()
} }
const selectCallBack = () => { const selectCallBack = () => {
setSelectAll(true)
onSelectCheckbox && onSelectCheckbox(true) onSelectCheckbox && onSelectCheckbox(true)
setSelectAll(true)
} }
const closeCallBack = () => { const closeCallBack = () => {
setSelectAll(false) setSelectAll(false)
onSelectCheckbox && onSelectCheckbox(false) onSelectCheckbox && onSelectCheckbox(false)
} }
const [isSelectAll, setSelectAll] = useState(false) const [isSelectAll, setSelectAll] = useState(false)
@ -34,6 +34,7 @@ export default memo<PropsType>((props) => {
<View className={styles.bottomLeft}> <View className={styles.bottomLeft}>
<MCheckbox <MCheckbox
status={isSelectAll} status={isSelectAll}
disabled={disabled}
round round
size='small' size='small'
onSelect={selectCallBack} onSelect={selectCallBack}
@ -43,7 +44,7 @@ export default memo<PropsType>((props) => {
</MCheckbox> </MCheckbox>
</View> </View>
<View className={styles.bottomRight}> <View className={styles.bottomRight}>
<NormalButton round type='danger' size='normal' onClick={handleSettle} customStyles={{ backgroundColor: '#F44761' }}> <NormalButton round type='danger' size='normal' onClick={handleDelete} customStyles={{ backgroundColor: '#F44761', padding: '0 80rpx' }}>
<Text style={{ fontSize: '32rpx' }}></Text> <Text style={{ fontSize: '32rpx' }}></Text>
</NormalButton> </NormalButton>
</View> </View>

View File

@ -1,4 +1,3 @@
import { formatPriceDiv } from '@/common/format'
import NormalButton from '@/components/normalButton' import NormalButton from '@/components/normalButton'
import { View, Text } from '@tarojs/components' import { View, Text } from '@tarojs/components'
import { memo } from 'react' import { memo } from 'react'
@ -9,7 +8,7 @@ type PropsType = {
onSettleAccount?: Function onSettleAccount?: Function
} }
export default memo<PropsType>((props) => { export default memo<PropsType>(props => {
const { onSettleAccount, amount = 0 } = props const { onSettleAccount, amount = 0 } = props
const handleSettle = () => { const handleSettle = () => {
@ -26,8 +25,8 @@ export default memo<PropsType>((props) => {
</Text> </Text>
</View> </View>
<View className={styles.bottomRight}> <View className={styles.bottomRight}>
<NormalButton type='primary' round size='normal' onClick={handleSettle}> <NormalButton type='primary' round size='normal' onClick={handleSettle} customStyles={{ padding: '0 80rpx' }}>
<Text style={{fontSize: '32rpx'}}></Text> <Text style={{ fontSize: '32rpx' }}></Text>
</NormalButton> </NormalButton>
</View> </View>
</View> </View>

View File

@ -45,14 +45,12 @@ const ColorKindItem: FC<PropsType> = memo(
setChangedCheckbox({ setChangedCheckbox({
purchaserId: purchaserId, purchaserId: purchaserId,
goodsKind: { [itemData.id]: { ...colorStore[purchaserId].goodsKind?.[itemData.id]!, checked: true } }, goodsKind: { [itemData.id]: { ...colorStore[purchaserId].goodsKind?.[itemData.id]!, checked: true } },
checked: colorStore[purchaserId].checked,
}) })
} }
const handleClose = () => { const handleClose = () => {
setChangedCheckbox({ setChangedCheckbox({
purchaserId: purchaserId, purchaserId: purchaserId,
goodsKind: { [itemData.id]: { ...colorStore[purchaserId].goodsKind?.[itemData.id]!, checked: false } }, goodsKind: { [itemData.id]: { ...colorStore[purchaserId].goodsKind?.[itemData.id]!, checked: false } },
checked: colorStore[purchaserId].checked,
}) })
} }

View File

@ -27,6 +27,7 @@ export const ShoppingCart: FC<ShoppingCartPropsType> = (props) => {
onTriggerCheckboxRef.current = onTriggerCheckbox onTriggerCheckboxRef.current = onTriggerCheckbox
const [colorStore, setColorStore] = useState<ColorStore>(() => initialValues || {}) const [colorStore, setColorStore] = useState<ColorStore>(() => initialValues || {})
// 客户的选中状态
const [changedCheckbox, setChangedCheckbox] = useState<GoodsMeta>({} as GoodsMeta) const [changedCheckbox, setChangedCheckbox] = useState<GoodsMeta>({} as GoodsMeta)
// 当前高亮的客户 // 当前高亮的客户
const [currentCheckedPurchaserId, setCurrentCheckedPurchaserId] = useState<number>(-1) const [currentCheckedPurchaserId, setCurrentCheckedPurchaserId] = useState<number>(-1)
@ -55,7 +56,6 @@ export const ShoppingCart: FC<ShoppingCartPropsType> = (props) => {
[changedGoods.purchaserId as number]: { [changedGoods.purchaserId as number]: {
purchaserId: changedGoods.purchaserId, purchaserId: changedGoods.purchaserId,
goodsKind: currentGoodsKind, goodsKind: currentGoodsKind,
checked: changedGoods.checked,
}, },
} }
}) })

View File

@ -1,7 +1,7 @@
.layout { .layout {
margin: 24px; margin: 24px;
padding-left: 0; // padding-left: 0;
padding-right: 0; // padding-right: 0;
border: 1px solid transparent; border: 1px solid transparent;
.checkbox { .checkbox {
padding: 0 24px; padding: 0 24px;

View File

@ -66,18 +66,9 @@ 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, currentCheckedSaleMode } = useShoppingContext() const { setChangedCheckbox, currentCheckedPurchaserId, setCurrentCheckedPurchaserId, setSelectedAmount, colorStore } = useShoppingContext()
const memoList = useMemo(() => { const memoList = useMemo(() => {
const selectedList = itemData?.[BackEndSaleModeListFieldMap[selected]].length !== 0 ? itemData?.[BackEndSaleModeListFieldMap[selected]] : [{}]
// 给每一个客户都初始化一个 checked 状态
selectedList.forEach(() => {
// 初始化选中状态
setChangedCheckbox({
purchaserId: itemData?.purchaser_id!,
checked: false,
})
})
// 向 context 中初始化数据 // 向 context 中初始化数据
return itemData?.[BackEndSaleModeListFieldMap[selected]].length !== 0 ? ( return itemData?.[BackEndSaleModeListFieldMap[selected]].length !== 0 ? (
itemData?.[BackEndSaleModeListFieldMap[selected]].map(item => { itemData?.[BackEndSaleModeListFieldMap[selected]].map(item => {
@ -94,7 +85,6 @@ export default memo<PropsType>(props => {
count: selected === EnumSaleMode.Bulk ? item.roll : Number(formatMeterDiv(item.length)), 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> return <ColorKindItem purchaserId={itemData.purchaser_id} key={item.id} itemData={item} orderType={selected}></ColorKindItem>
}) })
@ -112,20 +102,6 @@ export default memo<PropsType>(props => {
setCurrentCheckedPurchaserId(itemData?.purchaser_id as number) setCurrentCheckedPurchaserId(itemData?.purchaser_id as number)
} }
const handleChecked = () => {
// 初始化选中状态
setChangedCheckbox({
purchaserId: itemData?.purchaser_id!,
checked: true,
})
}
const handleUnchecked = () => {
// 初始化选中状态
setChangedCheckbox({
purchaserId: itemData?.purchaser_id!,
checked: false,
})
}
// 统计已选面料 // 统计已选面料
const materialChecked = useMemo(() => { const materialChecked = useMemo(() => {
const targetGoodsKind = colorStore?.[itemData?.purchaser_id!]?.['goodsKind'] const targetGoodsKind = colorStore?.[itemData?.purchaser_id!]?.['goodsKind']
@ -173,19 +149,11 @@ export default memo<PropsType>(props => {
circle circle
customClassName={classnames(styles.layout, itemData?.purchaser_id === currentCheckedPurchaserId ? styles.selected : '')} customClassName={classnames(styles.layout, itemData?.purchaser_id === currentCheckedPurchaserId ? styles.selected : '')}
onClick={handleClickLayout}> onClick={handleClickLayout}>
<MCheckbox
hiddenCheckboxIcon={!isManageStatus}
onSelect={handleChecked}
onClose={handleUnchecked}
status={colorStore[itemData?.purchaser_id!]?.checked}
customClassName={styles['checkbox']}
customTextClass={styles['checkbox--text']}
triggerLabel={false}>
<View className='flex-row justify-between' onClick={handleOpenDetail}> <View className='flex-row justify-between' onClick={handleOpenDetail}>
<View className={styles.topItem}> <View className={styles.topItem}>
<View className='flex-row items-center'> <View className='flex-row items-center'>
<View className={styles.topTitle}>{itemData?.purchaser_name}</View> <View className={styles.topTitle}>{itemData?.purchaser_name}</View>
<Tag type='info' size='normal' circle customStyle={{ backgroundColor: '#f0f0f0',borderColor: 'transparent' }} plain> <Tag type='info' size='normal' circle customStyle={{ backgroundColor: '#f0f0f0', borderColor: 'transparent' }} plain>
{itemData?.sale_user_name} {itemData?.sale_user_name}
</Tag> </Tag>
</View> </View>
@ -198,12 +166,12 @@ export default memo<PropsType>(props => {
</View> </View>
<DrawerButton isOpen={openDetail} /> <DrawerButton isOpen={openDetail} />
</View> </View>
</MCheckbox>
{/* 减少节点渲染 */} {/* 减少节点渲染 */}
{openDetail && ( {openDetail && (
<>
<Divider customClassName={styles.line}></Divider>
<View className={classnames(styles.detailBox, openDetail ? styles.drawerOpen : styles.drawerClose)}> <View className={classnames(styles.detailBox, openDetail ? styles.drawerOpen : styles.drawerClose)}>
<View className={styles.orderType}> <View className={styles.orderType}>
<Divider customClassName={styles.line}></Divider>
<View className={styles.orderTitle}></View> <View className={styles.orderTitle}></View>
<View className={styles.orderTypeDetail}> <View className={styles.orderTypeDetail}>
<SaleModeButton <SaleModeButton
@ -237,6 +205,7 @@ export default memo<PropsType>(props => {
</View> </View>
<View className={styles.orderContainer}>{memoList}</View> <View className={styles.orderContainer}>{memoList}</View>
</View> </View>
</>
)} )}
</LayoutBlock> </LayoutBlock>
) )

View File

@ -43,7 +43,6 @@ export interface GoodsMeta {
goodsKind?: { goodsKind?: {
[id: number]: Goods [id: number]: Goods
} }
checked: boolean
} }
export interface ShoppingContextValue { export interface ShoppingContextValue {

View File

@ -1,7 +1,7 @@
import Search from '@/components/search' import Search from '@/components/search'
import { View } from '@tarojs/components' import { View } from '@tarojs/components'
import Taro, { useDidHide, useDidShow, useRouter } from '@tarojs/taro' import Taro, { useDidHide, useDidShow } from '@tarojs/taro'
import React, { FC, memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react' import { FC, memo, useCallback, useEffect, useLayoutEffect, 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 IconText from '@/components/iconText' import IconText from '@/components/iconText'
@ -24,7 +24,6 @@ export const Shopping: FC = memo(() => {
if (targetGoodsKind) { if (targetGoodsKind) {
const result = Object.values(targetGoodsKind).reduce((prev: number, value: Goods) => { const result = Object.values(targetGoodsKind).reduce((prev: number, value: Goods) => {
console.log('value==>', value)
if (value.checked) { if (value.checked) {
return prev + Number(formatPriceDiv(value.estimate_amount)) return prev + Number(formatPriceDiv(value.estimate_amount))
} }
@ -47,10 +46,17 @@ export const Shopping: FC = memo(() => {
interface InternalContainer {} interface InternalContainer {}
const ShoppingCartContainer: FC<InternalContainer> = () => { const ShoppingCartContainer: FC<InternalContainer> = () => {
let isFirst = useRef(true) let isFirst = useRef(true)
const { isManageStatus, setManageStatus, selectedAmount, currentCheckedPurchaserId, currentCheckedSaleMode, colorStore, setColorStore } = useShoppingContext() const {
setChangedCheckbox,
isManageStatus,
setManageStatus,
selectedAmount,
currentCheckedPurchaserId,
currentCheckedSaleMode,
colorStore,
} = useShoppingContext()
// 管理 // 管理
const onStartToManage = () => { const onStartToManage = () => {
@ -64,21 +70,16 @@ const ShoppingCartContainer: FC<InternalContainer> = () => {
const [searchOptions, setSearchOptions] = useState({ const [searchOptions, setSearchOptions] = useState({
short_name_or_phone: '', short_name_or_phone: '',
}) })
useDidShow(()=>{ useDidShow(() => {
console.log('onShow'); if (!isFirst.current) {
if (!isFirst.current){
fetchData(searchOptions) fetchData(searchOptions)
} }
}) })
useDidHide(() => { console.log('rerender')
console.log('onHide');
})
console.log('rerender');
useEffect(() => { useEffect(() => {
console.log('useEffect fetchData') console.log('useEffect fetchData')
if (!isEmptyObject(getFilterData(searchOptions))){ if (!isEmptyObject(getFilterData(searchOptions))) {
fetchData(searchOptions) fetchData(searchOptions)
} }
}, [searchOptions]) }, [searchOptions])
@ -142,20 +143,27 @@ const ShoppingCartContainer: FC<InternalContainer> = () => {
const { fetchData: deleteApi } = ShoppingCartDeleteApi() const { fetchData: deleteApi } = ShoppingCartDeleteApi()
// TODO: 批量删除商品 // 批量某个客户的删除商品
const handleDelete = async () => { const handleDelete = async () => {
const targetGoodsKind = colorStore?.[currentCheckedPurchaserId]?.['goodsKind'] const targetGoodsKind = colorStore?.[currentCheckedPurchaserId]?.['goodsKind']
if (targetGoodsKind && Object.values(targetGoodsKind).every((item: Goods) => !item.checked)) { let checked: Goods[] = []
if (targetGoodsKind) {
checked = Object.values(targetGoodsKind).filter((item: Goods) => item.checked)
if (checked.length === 0) {
return Taro.showToast({ title: '请选择商品', icon: 'error' }) return Taro.showToast({ title: '请选择商品', icon: 'error' })
} }
}
console.log('checked==>', checked)
Taro.showModal({ Taro.showModal({
title: '要取消这些商品吗?', title: '要删除这些商品吗?',
success: async function(res) { success: async function(res) {
if (res.confirm) { if (res.confirm) {
const res = await deleteApi() const res = await deleteApi({
ids: checked.map(item => item.id).join(','),
})
if (res.success) { if (res.success) {
alert.success('取消成功') alert.success('删除成功')
fetchData() fetchData(searchOptions)
} else { } else {
alert.none(res.msg) alert.none(res.msg)
} }
@ -166,15 +174,22 @@ const ShoppingCartContainer: FC<InternalContainer> = () => {
// 全选 // 全选
const handleSelectAllCheckbox = (isSelectAll: boolean) => { const handleSelectAllCheckbox = (isSelectAll: boolean) => {
console.log('handleSelectAllCheckbox', isSelectAll) console.log('handleSelectAllCheckbox', isSelectAll)
const targetGoodsKind = colorStore?.[currentCheckedPurchaserId]?.['goodsKind']
if (!targetGoodsKind) return Taro.showToast({ title: '请先选择客户', icon: 'error' })
console.log('targetGoodsKind==>', targetGoodsKind)
const tempObject = {} const tempObject = {}
Object.entries(colorStore).forEach(([key, value]) => { Object.entries(targetGoodsKind).forEach(([key, value]) => {
tempObject[key] = { tempObject[key] = {
...value, ...value,
checked: isSelectAll, checked: isSelectAll,
} }
}) })
console.log(tempObject) console.log('tempObject==>', tempObject)
setColorStore(() => tempObject) setChangedCheckbox({
purchaserId: currentCheckedPurchaserId,
goodsKind: tempObject,
})
} }
// 加载刷新数据 // 加载刷新数据
@ -220,7 +235,10 @@ const ShoppingCartContainer: FC<InternalContainer> = () => {
</View> </View>
<View id='bottomBar'> <View id='bottomBar'>
{isManageStatus ? ( {isManageStatus ? (
<BottomEditBar onDelete={handleDelete} onSelectCheckbox={isAll => handleSelectAllCheckbox(isAll)}></BottomEditBar> <BottomEditBar
disabled={currentCheckedPurchaserId < 0}
onDelete={handleDelete}
onSelectCheckbox={isAll => handleSelectAllCheckbox(isAll)}></BottomEditBar>
) : ( ) : (
<BottomSettleBar onSettleAccount={handleSettleAccount} amount={selectedAmount}></BottomSettleBar> <BottomSettleBar onSettleAccount={handleSettleAccount} amount={selectedAmount}></BottomSettleBar>
)} )}