✨ feat(购物页面): 已完成页面逻辑,等待对接接口
This commit is contained in:
@@ -7,7 +7,8 @@ import styles from './index.module.scss'
|
||||
import { debounce } from '@/common/util'
|
||||
import { formatPriceDiv } from '@/common/format'
|
||||
import { EnumSaleMode } from '@/common/Enumerate'
|
||||
|
||||
import { useNeedMemoCallback } from '@/use/useCommon'
|
||||
import {selectList} from '../../config'
|
||||
type PropsType = {
|
||||
item: Record<string, any> & object
|
||||
orderType: EnumSaleMode
|
||||
@@ -16,12 +17,6 @@ type PropsType = {
|
||||
onUnChecked?: Function
|
||||
}
|
||||
|
||||
const selectList = [
|
||||
{ value: 0, title: '大货', unit: '条', eunit: 'kg', step: 1, digits: 0, minNum: 1, maxNum: 100000, defaultNum: 1 },
|
||||
{ value: 1, title: '剪板', unit: '米', eunit: 'm', step: 1, digits: 2, minNum: 0.5, maxNum: 9.99, defaultNum: 1 },
|
||||
{ value: 2, title: '散剪', unit: '米', eunit: 'kg', step: 1, digits: 2, minNum: 3, maxNum: 100000, defaultNum: 3 },
|
||||
]
|
||||
|
||||
const ColorKindItem: FC<PropsType> = memo(
|
||||
(props) => {
|
||||
const { item, orderType = EnumSaleMode.Bulk, isSelected = false, onChecked, onUnChecked } = props
|
||||
@@ -41,13 +36,6 @@ const ColorKindItem: FC<PropsType> = memo(
|
||||
return item.sale_mode == EnumSaleMode.Bulk ? '条' : '米'
|
||||
}, [])
|
||||
|
||||
// const [checked, setCheck] = useState(false)
|
||||
|
||||
// useEffect(() => {
|
||||
// setCheck(isSelected)
|
||||
// console.log('useEffect', isSelected)
|
||||
// }, [isSelected])
|
||||
|
||||
const handleSelect = () => {
|
||||
console.log('handleSelect')
|
||||
// setCheck(true)
|
||||
@@ -58,7 +46,14 @@ const ColorKindItem: FC<PropsType> = memo(
|
||||
onUnChecked && onUnChecked({ ...item, checked: false })
|
||||
}
|
||||
|
||||
const getInputValue = debounce(async (num, item) => {}, 300)
|
||||
const getInputValue = debounce(async (num, item) => {
|
||||
if (item.sale_mode === EnumSaleMode.Bulk) {
|
||||
item.roll = num
|
||||
}else{
|
||||
item.length = num
|
||||
}
|
||||
onChecked && onChecked({ ...item, checked: true })
|
||||
}, 300)
|
||||
|
||||
return (
|
||||
<MCheckbox
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
margin: 24px;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
border: 1px solid transparent;
|
||||
.checkbox {
|
||||
padding: 0 24px;
|
||||
&--text {
|
||||
@@ -11,6 +12,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
.selected{
|
||||
border-color: $color_main;
|
||||
}
|
||||
|
||||
.line {
|
||||
margin: 16px 0;
|
||||
}
|
||||
@@ -80,6 +85,5 @@
|
||||
height: auto;
|
||||
}
|
||||
.drawerClose {
|
||||
|
||||
height: 0;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Text, View } from '@tarojs/components'
|
||||
import { memo, useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import { memo, useCallback, useContext, useEffect, useMemo, useState } from 'react'
|
||||
import styles from './index.module.scss'
|
||||
import classnames from 'classnames'
|
||||
import { formatPriceDiv } from '@/common/format'
|
||||
import Taro from '@tarojs/taro'
|
||||
import Taro, { useDidShow } from '@tarojs/taro'
|
||||
import LayoutBlock from '@/components/layoutBlock'
|
||||
import MCheckbox from '@/components/checkbox'
|
||||
import Tag from '@/components/tag'
|
||||
@@ -11,9 +11,14 @@ import Divider from '@/components/divider'
|
||||
import NormalButton from '@/components/normalButton'
|
||||
import ColorKindItem from '../colorKindItem'
|
||||
import { EnumSaleMode } from '@/common/Enumerate'
|
||||
import { useNeedMemoCallback } from '@/use/useCommon'
|
||||
import {selectList} from '../../config'
|
||||
import { ShoppingContext } from '../../index'
|
||||
|
||||
type PropsType = {
|
||||
obj?: any
|
||||
itemData?: ShoppingCartData
|
||||
selectedId?: number
|
||||
onSelectedId?: Function
|
||||
}
|
||||
|
||||
const DrawerButton = memo<{ isOpen: boolean }>(({ isOpen }) => {
|
||||
@@ -23,12 +28,15 @@ const DrawerButton = memo<{ isOpen: boolean }>(({ isOpen }) => {
|
||||
})
|
||||
|
||||
export default memo((props: PropsType) => {
|
||||
console.log('重新渲染 shoppingCartItem');
|
||||
|
||||
// const { handleSelectedItem } = useLayoutBlockContext()
|
||||
const { itemData, selectedId } = props
|
||||
|
||||
console.log('重新渲染 shoppingCartItem', selectedId)
|
||||
const [openDetail, setOpenDetail] = useState(false)
|
||||
|
||||
const handleOpenDetail = () => {
|
||||
setOpenDetail((isOpen) => !isOpen)
|
||||
|
||||
}
|
||||
|
||||
const [selected, setSelect] = useState<EnumSaleMode>(0)
|
||||
@@ -37,70 +45,65 @@ export default memo((props: PropsType) => {
|
||||
setSelect(type)
|
||||
}
|
||||
|
||||
const [mockList, setMockList] = useState([
|
||||
const [mockList, setMockList] = useState(
|
||||
{
|
||||
sale_mode: 0,
|
||||
list: [
|
||||
0: [
|
||||
{ id: 0, sale_mode: 0, roll: 5, length: 0, checked: true },
|
||||
{ id: 1, sale_mode: 0, roll: 6, length: 0, checked: false },
|
||||
{ id: 2, sale_mode: 0, roll: 7, length: 0, checked: true },
|
||||
],
|
||||
},
|
||||
{
|
||||
sale_mode: 1,
|
||||
list: [
|
||||
1: [
|
||||
{ id: 5, sale_mode: 1, roll: 0, length: 77700, checked: false },
|
||||
{ id: 6, sale_mode: 1, roll: 0, length: 7600, checked: true },
|
||||
{ id: 7, sale_mode: 1, roll: 0, length: 400, checked: true },
|
||||
],
|
||||
},
|
||||
{
|
||||
sale_mode: 2,
|
||||
list: [
|
||||
2: [
|
||||
{ id: 8, sale_mode: 2, roll: 0, length: 11100, checked: false },
|
||||
{ id: 9, sale_mode: 2, roll: 0, length: 8540, checked: true },
|
||||
],
|
||||
},
|
||||
])
|
||||
}
|
||||
)
|
||||
// const [mockList, setMockList] = useState(itemData?.color_list)
|
||||
|
||||
const handleChecked = (current) => {
|
||||
console.log('handleChecked', current)
|
||||
const index = mockList.findIndex(item=>item.sale_mode === selected)
|
||||
const tempList = mockList[index].list.map((item) => {
|
||||
if (item.id === current.id) {
|
||||
item = current
|
||||
}
|
||||
return item
|
||||
})
|
||||
setMockList((pre=>{
|
||||
return pre.map(item=>{
|
||||
if(item.sale_mode === selected){
|
||||
item.list = tempList
|
||||
const handleChecked = useCallback(
|
||||
(current) => {
|
||||
console.log('handleChecked', current)
|
||||
const tempList = mockList[selected].map((item) => {
|
||||
if (item.id === current.id) {
|
||||
item = current
|
||||
}
|
||||
return item
|
||||
})
|
||||
}))
|
||||
}
|
||||
const handleUnChecked = (current) => {
|
||||
const index = mockList.findIndex((item) => item.sale_mode === selected)
|
||||
const tempList = mockList[index].list.map((item) => {
|
||||
if (item.id === current.id) {
|
||||
item = current
|
||||
}
|
||||
return item
|
||||
})
|
||||
setMockList((pre) => {
|
||||
return pre.map((item) => {
|
||||
if (item.sale_mode === selected) {
|
||||
item.list = tempList
|
||||
setMockList((pre) => {
|
||||
return {
|
||||
...pre,
|
||||
[selected]: tempList,
|
||||
}
|
||||
})
|
||||
},
|
||||
[mockList, selected],
|
||||
)
|
||||
const handleUnChecked = useCallback(
|
||||
(current) => {
|
||||
console.log('handleChecked', current)
|
||||
const tempList = mockList[selected].map((item) => {
|
||||
if (item.id === current.id) {
|
||||
item = current
|
||||
}
|
||||
return item
|
||||
})
|
||||
})
|
||||
}
|
||||
setMockList((pre) => {
|
||||
return {
|
||||
...pre,
|
||||
[selected]: tempList,
|
||||
}
|
||||
})
|
||||
},
|
||||
[mockList, selected],
|
||||
)
|
||||
|
||||
const memoList = useMemo(() => {
|
||||
return mockList[selected].list.map((item, index) => {
|
||||
return mockList[selected].map((item, index) => {
|
||||
return (
|
||||
<ColorKindItem
|
||||
key={item.id}
|
||||
@@ -113,19 +116,27 @@ export default memo((props: PropsType) => {
|
||||
})
|
||||
}, [mockList, selected])
|
||||
|
||||
const handleClickLayout = () => {
|
||||
console.log('itemData===>', itemData)
|
||||
}
|
||||
|
||||
const {isManager} = useContext(ShoppingContext)
|
||||
|
||||
return (
|
||||
<LayoutBlock circle customClassName={styles.layout}>
|
||||
<MCheckbox customClassName={styles['checkbox']} customTextClass={styles['checkbox--text']} triggerLabel={false}>
|
||||
<LayoutBlock circle customClassName={classnames(styles.layout, itemData?.purchaser_id === selectedId ? styles.selected : '')} onClick={handleClickLayout}>
|
||||
<MCheckbox customClassName={styles['checkbox']} customTextClass={styles['checkbox--text']} triggerLabel={false} hidden={isManager}>
|
||||
<View className='flex-row justify-between' onClick={handleOpenDetail}>
|
||||
<View className={styles.topItem}>
|
||||
<View className='flex-row items-center'>
|
||||
<View className={styles.topTitle}>灵玉布行</View>
|
||||
<View className={styles.topTitle}>{itemData?.purchaser_name}</View>
|
||||
<Tag type='info' size='normal' circle plain>
|
||||
刘思伟
|
||||
{itemData?.sale_user_name}
|
||||
</Tag>
|
||||
</View>
|
||||
<View className={styles.summary}>
|
||||
<Text>已选 1 种面料,1 个颜色,共 4 条</Text>
|
||||
<Text>
|
||||
已选 {mockList[selected].filter(item=>item.checked).length} 种面料,1 个颜色,共 {selected === EnumSaleMode.Bulk ? `${4} 条` : `${4} 米`}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
<DrawerButton isOpen={openDetail} />
|
||||
@@ -167,7 +178,7 @@ export default memo((props: PropsType) => {
|
||||
<View className={classnames(styles.orderTitle, 'justify-between')}>
|
||||
<Text>布料颜色</Text>
|
||||
<Tag type='danger' size='normal' circle plain={false}>
|
||||
大货单位:条
|
||||
{selectList[selected].title}单位:{selectList[selected].unit}
|
||||
</Tag>
|
||||
</View>
|
||||
</View>
|
||||
@@ -175,4 +186,4 @@ export default memo((props: PropsType) => {
|
||||
</View>
|
||||
</LayoutBlock>
|
||||
)
|
||||
})
|
||||
}, useNeedMemoCallback())
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
export const selectList = {
|
||||
0: { title: '大货', unit: '条', eunit: 'kg', step: 1, digits: 0, minNum: 1, maxNum: 100000, defaultNum: 1 },
|
||||
1: {
|
||||
title: '剪板',
|
||||
unit: '米',
|
||||
eunit: 'm',
|
||||
step: 1,
|
||||
digits: 2,
|
||||
minNum: 0.5,
|
||||
maxNum: 9.99,
|
||||
defaultNum: 1,
|
||||
},
|
||||
2: {
|
||||
title: '散剪',
|
||||
unit: '米',
|
||||
eunit: 'kg',
|
||||
step: 1,
|
||||
digits: 2,
|
||||
minNum: 3,
|
||||
maxNum: 100000,
|
||||
defaultNum: 3,
|
||||
},
|
||||
}
|
||||
@@ -10,7 +10,8 @@
|
||||
justify-content: space-between;
|
||||
height: 100%;
|
||||
.shopping__list__container{
|
||||
overflow: scroll;
|
||||
flex: 0 1 auto;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import Search from '@/components/search'
|
||||
import { View } from '@tarojs/components'
|
||||
import Taro, { useDidShow } from '@tarojs/taro'
|
||||
import { FC, useCallback, useMemo, useState } from 'react'
|
||||
import React, { FC, useCallback, useContext, useEffect, useMemo, useState } from 'react'
|
||||
import styles from './index.module.scss'
|
||||
import classnames from 'classnames'
|
||||
import IconText from '@/components/iconText'
|
||||
@@ -11,20 +11,29 @@ import BottomBtns from '@/components/BottomBtns'
|
||||
import { formatPriceDiv } from '@/common/format'
|
||||
import BottomSettleBar from './components/bottomSettleBar'
|
||||
import BottomEditBar from './components/bottomEditBar'
|
||||
import { ShoppingCartListApi } from '@/api/index'
|
||||
import { dataLoadingStatus } from '@/common/util'
|
||||
|
||||
const Shopping: FC = () => {
|
||||
const defaultContext = {
|
||||
isManager: false
|
||||
}
|
||||
|
||||
export const ShoppingContext = React.createContext(defaultContext)
|
||||
|
||||
export const Shopping: FC = () => {
|
||||
//输入了搜索关键字
|
||||
const getSearchData = useCallback((e) => {
|
||||
// pageNum.current.page = 1
|
||||
// setOrderData(() => ({ list: [], total: 0 }))
|
||||
// setSearchField((val) => ({ ...val, name: e, size: 10 }))
|
||||
}, [])
|
||||
|
||||
// 是否在 管理 状态
|
||||
const [isManage, setManage] = useState(false)
|
||||
|
||||
// 管理
|
||||
const onStartToManage = () => {
|
||||
setManage((isManage) => !isManage)
|
||||
ShoppingContext.Consumer
|
||||
}
|
||||
|
||||
const [selectedAmount, setSelectedAmount] = useState(0)
|
||||
@@ -38,9 +47,50 @@ const Shopping: FC = () => {
|
||||
console.log('handleSelectAllCheckbox', isSelectAll)
|
||||
}
|
||||
|
||||
const [listHeight, setListHeight] = useState('auto')
|
||||
|
||||
const { fetchData, state } = ShoppingCartListApi()
|
||||
|
||||
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])
|
||||
|
||||
useDidShow(() => {
|
||||
fetchData()
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
setShoppingCartData({ list: state.data, total: state.data.length })
|
||||
}, [state])
|
||||
|
||||
useEffect(() => {
|
||||
let query = Taro.createSelectorQuery()
|
||||
console.log(query)
|
||||
query.select('#shoppingContainer').boundingClientRect()
|
||||
query.select('#topBar').boundingClientRect()
|
||||
query.select('#bottomBar').boundingClientRect()
|
||||
query.exec((res) => {
|
||||
const containerHeight = res[0].height
|
||||
const topBarHeight = res[1].height
|
||||
const bottomBarHeight = res[2].height
|
||||
const listHeight = containerHeight - topBarHeight - bottomBarHeight
|
||||
console.log('res==>', listHeight)
|
||||
setListHeight(listHeight + 'px')
|
||||
})
|
||||
}, [])
|
||||
|
||||
const [selectedId, setSelectedId] = useState<number>()
|
||||
|
||||
const handleSelectedItem = (item: ShoppingCartData) => {
|
||||
setSelectedId(item.purchaser_id)
|
||||
}
|
||||
|
||||
return (
|
||||
<View className={classnames('flex-col', styles.shopping)}>
|
||||
<View className={styles['shopping--topBar']}>
|
||||
<View className={classnames('flex-col', styles.shopping)} id='shoppingContainer'>
|
||||
<View className={styles['shopping--topBar']} id='topBar'>
|
||||
<Search placeholder='请输入客户名称' showBtn={false} changeOnSearch={getSearchData} debounceTime={300}>
|
||||
<View className={styles.flexBox} onClick={onStartToManage}>
|
||||
{isManage ? (
|
||||
@@ -52,29 +102,23 @@ const Shopping: FC = () => {
|
||||
</Search>
|
||||
</View>
|
||||
<View className={classnames('flex-item', 'flex-col', styles['shopping--context'])}>
|
||||
<View className={classnames(styles.shopping__list__container, 'flex-item')}>
|
||||
{/* <InfiniteScroll
|
||||
statusMore={statusMore}
|
||||
selfonScrollToLower={getScrolltolower}
|
||||
refresherEnabled={true}
|
||||
refresherTriggered={refresherTriggeredStatus}
|
||||
selfOnRefresherRefresh={getRefresherRefresh}>
|
||||
{orderData?.list?.map((item, index) => {
|
||||
return (
|
||||
<View key={item.id} className={styles.order_item_con}>
|
||||
<ItemList obj={item} key={index}></ItemList>
|
||||
</View>
|
||||
)
|
||||
})}
|
||||
</InfiniteScroll> */}
|
||||
<ItemList></ItemList>
|
||||
<ItemList></ItemList>
|
||||
<View className={classnames(styles.shopping__list__container, 'flex-item')} style={{ height: listHeight }}>
|
||||
<ShoppingContext.Provider value={{isManager:false}}>
|
||||
<InfiniteScroll statusMore={statusMore}>
|
||||
{!!shoppingCartData.list?.length &&
|
||||
shoppingCartData.list?.map((item, index) => {
|
||||
return <ItemList itemData={item} key={index} selectedId={selectedId}></ItemList>
|
||||
})}
|
||||
</InfiniteScroll>
|
||||
</ShoppingContext.Provider>
|
||||
</View>
|
||||
<View id='bottomBar'>
|
||||
{isManage ? (
|
||||
<BottomEditBar onDelete={handleDelete} onSelectCheckbox={handleSelectAllCheckbox}></BottomEditBar>
|
||||
) : (
|
||||
<BottomSettleBar onSettleAccount={handleSettleAccount} amount={selectedAmount}></BottomSettleBar>
|
||||
)}
|
||||
</View>
|
||||
{isManage ? (
|
||||
<BottomEditBar onDelete={handleDelete} onSelectCheckbox={handleSelectAllCheckbox}></BottomEditBar>
|
||||
) : (
|
||||
<BottomSettleBar onSettleAccount={handleSettleAccount} amount={selectedAmount}></BottomSettleBar>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
type ProductImageUrl = string
|
||||
interface ShoppingCartData {
|
||||
purchaser_code: string
|
||||
purchaser_id: number
|
||||
purchaser_name: string
|
||||
purchaser_short_name: string
|
||||
sale_user_id: number
|
||||
sale_user_name: string
|
||||
color_list: ColorList
|
||||
[Property:string]: any
|
||||
}
|
||||
interface ColorList {
|
||||
estimate_amount: number
|
||||
estimate_weight: number
|
||||
id: number
|
||||
length: number
|
||||
product_code: string
|
||||
product_color_code: string
|
||||
product_color_id: number
|
||||
product_color_name: string
|
||||
product_color_texture_url: ProductImageUrl
|
||||
product_id: number
|
||||
product_name: string
|
||||
roll: number
|
||||
sale_mode: number
|
||||
sale_mode_name: string
|
||||
sale_offset: number
|
||||
sale_price: number
|
||||
standard_price: number
|
||||
[Property: string]: any
|
||||
}
|
||||
Reference in New Issue
Block a user