✨ feat(购物页面): 购物页面UI完成度80%
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
justify-content: space-between;
|
||||
background-color: white;
|
||||
padding: 16px 24px;
|
||||
|
||||
|
||||
.bottomLeft{
|
||||
margin-left: 12px;
|
||||
.moneyText{
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
.colorKindItem {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin-left: 20px;
|
||||
padding: 16px 0;
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
&__left {
|
||||
flex: none;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
border-radius: 8px;
|
||||
margin-right: 24px;
|
||||
&--image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
&__center {
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
justify-content: space-between;
|
||||
flex: 1 1 auto;
|
||||
&--title {
|
||||
color: $color_font_one;
|
||||
font-size: 28px;
|
||||
@include common_ellipsis(2);
|
||||
}
|
||||
&--detail {
|
||||
}
|
||||
&--ID {
|
||||
color: rgba($color: #000000, $alpha: 0.4);
|
||||
font-size: 24px;
|
||||
@include common_ellipsis();
|
||||
}
|
||||
&--description {
|
||||
color: rgba($color: #000000, $alpha: 0.4);
|
||||
font-size: 24px;
|
||||
@include common_ellipsis();
|
||||
}
|
||||
}
|
||||
&__right {
|
||||
flex: none;
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
align-items: flex-end;
|
||||
justify-content: space-around;
|
||||
align-self: stretch;
|
||||
&--price {
|
||||
color: $color_money;
|
||||
font-weight: 550;
|
||||
font-size: 28px;
|
||||
}
|
||||
&--counter {
|
||||
}
|
||||
}
|
||||
}
|
||||
.checkbox{
|
||||
padding: 0 24px;
|
||||
}
|
||||
.selected {
|
||||
background-color: #F8FAFF;
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
import { View, Text, Image } from '@tarojs/components'
|
||||
import MCheckbox from '@/components/checkbox'
|
||||
import Counter from '@/components/counter'
|
||||
import { FC, memo, ReactNode, useCallback, useEffect, useState } from 'react'
|
||||
import classnames from 'classnames'
|
||||
import styles from './index.module.scss'
|
||||
import { debounce } from '@/common/util'
|
||||
import { formatPriceDiv } from '@/common/format'
|
||||
import { EnumSaleMode } from '@/common/Enumerate'
|
||||
|
||||
type PropsType = {
|
||||
item: Record<string, any> & object
|
||||
orderType: EnumSaleMode
|
||||
isSelected: boolean
|
||||
onChecked?: Function
|
||||
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
|
||||
console.log('重新渲染', item.id, orderType)
|
||||
//格式化金额
|
||||
const formatPirce = useCallback((price) => {
|
||||
return Number(formatPriceDiv(price))
|
||||
}, [])
|
||||
|
||||
//格式化数量
|
||||
const formatCount = useCallback((item) => {
|
||||
return item.sale_mode == EnumSaleMode.Bulk ? item.roll : item.length / 100
|
||||
}, [])
|
||||
|
||||
//格式化单位
|
||||
const formatUnit = useCallback((item) => {
|
||||
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)
|
||||
onChecked && onChecked({ ...item, checked: true })
|
||||
}
|
||||
const handleClose = () => {
|
||||
// setCheck(false)
|
||||
onUnChecked && onUnChecked({ ...item, checked: false })
|
||||
}
|
||||
|
||||
const getInputValue = debounce(async (num, item) => {}, 300)
|
||||
|
||||
return (
|
||||
<MCheckbox
|
||||
triggerLabel={false}
|
||||
status={isSelected}
|
||||
onSelect={handleSelect}
|
||||
onClose={handleClose}
|
||||
customClassName={classnames(styles.checkbox, isSelected ? styles.selected : '')}
|
||||
customTextClass={styles.colorKindItem}>
|
||||
<View className={styles['colorKindItem__left']}>
|
||||
<Image className={styles['colorKindItem__left--image']} mode='aspectFill' src='https://test.cdn.zzfzyc.com/mall/no_img.png'></Image>
|
||||
</View>
|
||||
<View className={styles['colorKindItem__center']}>
|
||||
<Text className={styles['colorKindItem__center--title']}>001# 环保黑 环保黑 环保黑 环保黑 环保黑 环保黑</Text>
|
||||
<View className={styles['colorKindItem__center--detail']}>
|
||||
<Text className={styles['colorKindItem__center--ID']}>6002#220G</Text>
|
||||
<Text className={styles['colorKindItem__center--description']}>流线棉拉架卫衣</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View className={styles['colorKindItem__right']}>
|
||||
<View className={styles['colorKindItem__right--price']}>¥ 37.50/kg</View>
|
||||
<View className={styles['colorKindItem__right--counter']}>
|
||||
<Counter
|
||||
onBlue={(e) => getInputValue(e, item)}
|
||||
defaultNum={formatCount(item)}
|
||||
step={selectList[orderType].step}
|
||||
digits={selectList[orderType].digits}
|
||||
onClickBtn={(e) => getInputValue(e, item)}
|
||||
unit={formatUnit(item)}
|
||||
minNum={selectList[orderType].minNum}
|
||||
maxNum={selectList[orderType].maxNum}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</MCheckbox>
|
||||
)
|
||||
},
|
||||
(preProp, nextProp) => {
|
||||
const stringifyPreProp = JSON.stringify(preProp.item)
|
||||
const stringifyNextProp = JSON.stringify(nextProp.item)
|
||||
console.log('memo==>', preProp, nextProp);
|
||||
let needMemoized = true
|
||||
if (preProp.isSelected !== nextProp.isSelected) {
|
||||
needMemoized = false
|
||||
}
|
||||
if (preProp.orderType !== nextProp.orderType) {
|
||||
needMemoized = false
|
||||
}
|
||||
if (stringifyPreProp !== stringifyNextProp) {
|
||||
needMemoized = false
|
||||
}
|
||||
return needMemoized
|
||||
},
|
||||
)
|
||||
export default ColorKindItem
|
||||
@@ -1,8 +1,17 @@
|
||||
.layout{
|
||||
.layout {
|
||||
margin: 24px;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
.checkbox {
|
||||
padding: 0 24px;
|
||||
&--text {
|
||||
width: 100%;
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.line{
|
||||
.line {
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
@@ -16,37 +25,40 @@
|
||||
font-size: 32px;
|
||||
font-family: $font_family;
|
||||
font-weight: 550;
|
||||
line-height: 2;
|
||||
color: rgba($color: #000000, $alpha: 0.8);
|
||||
margin-right: 16px;
|
||||
}
|
||||
// 汇总
|
||||
.summary{
|
||||
.summary {
|
||||
color: rgba($color: #000000, $alpha: 0.4);
|
||||
font-size: 24px;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.detailBox {
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
.orderType{
|
||||
width: 100%;
|
||||
.orderTitle {
|
||||
padding: 0 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: $color_font_one;
|
||||
font-weight: 550;
|
||||
font-size: 28px;
|
||||
line-height: 2.5;
|
||||
}
|
||||
.orderType {
|
||||
padding: 0 24px;
|
||||
margin-left: 56px;
|
||||
.orderTypeTitle{
|
||||
color: $color_font_one;
|
||||
font-weight: 550;
|
||||
font-size: 28px;
|
||||
line-height: 2.5;
|
||||
}
|
||||
.orderTypeDetail{
|
||||
|
||||
.orderTypeDetail {
|
||||
display: flex;
|
||||
gap: 0 16px;
|
||||
}
|
||||
}
|
||||
.orderColor{
|
||||
|
||||
width: 100%;
|
||||
.orderColor {
|
||||
padding: 0 24px;
|
||||
margin-left: 56px;
|
||||
}
|
||||
}
|
||||
@@ -54,3 +66,20 @@
|
||||
.bottomBox {
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.drawerButton {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
Text {
|
||||
font-size: 52px;
|
||||
}
|
||||
}
|
||||
|
||||
.drawerOpen{
|
||||
height: auto;
|
||||
}
|
||||
.drawerClose {
|
||||
|
||||
height: 0;
|
||||
}
|
||||
|
||||
@@ -9,36 +9,118 @@ import MCheckbox from '@/components/checkbox'
|
||||
import Tag from '@/components/tag'
|
||||
import Divider from '@/components/divider'
|
||||
import NormalButton from '@/components/normalButton'
|
||||
import ColorKindItem from '../colorKindItem'
|
||||
import { EnumSaleMode } from '@/common/Enumerate'
|
||||
|
||||
type PropsType = {
|
||||
obj?: any
|
||||
}
|
||||
|
||||
const DrawerButton = memo<{ isOpen: boolean }>(({ isOpen }) => {
|
||||
return isOpen ? <Text className='iconfont '></Text> : <Text className='iconfont '></Text>
|
||||
return (
|
||||
<View className={styles.drawerButton}>{isOpen ? <Text className='iconfont icon-shouqi'></Text> : <Text className='iconfont icon-zhankai'></Text>}</View>
|
||||
)
|
||||
})
|
||||
|
||||
export default memo((props: PropsType) => {
|
||||
console.log('重新渲染 shoppingCartItem');
|
||||
const [openDetail, setOpenDetail] = useState(false)
|
||||
|
||||
const handleOpenDetail = () => {
|
||||
setOpenDetail((isOpen) => !isOpen)
|
||||
|
||||
}
|
||||
|
||||
const [selected, setSelect] = useState(0)
|
||||
const [selected, setSelect] = useState<EnumSaleMode>(0)
|
||||
|
||||
const onSelectOrderType = (type) => {
|
||||
const onSelectOrderType = (type: EnumSaleMode) => {
|
||||
setSelect(type)
|
||||
}
|
||||
|
||||
const [mockList, setMockList] = useState([
|
||||
{
|
||||
sale_mode: 0,
|
||||
list: [
|
||||
{ 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: [
|
||||
{ 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: [
|
||||
{ id: 8, sale_mode: 2, roll: 0, length: 11100, checked: false },
|
||||
{ id: 9, sale_mode: 2, roll: 0, length: 8540, checked: true },
|
||||
],
|
||||
},
|
||||
])
|
||||
|
||||
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
|
||||
}
|
||||
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
|
||||
}
|
||||
return item
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const memoList = useMemo(() => {
|
||||
return mockList[selected].list.map((item, index) => {
|
||||
return (
|
||||
<ColorKindItem
|
||||
key={item.id}
|
||||
isSelected={item.checked}
|
||||
item={item}
|
||||
orderType={selected}
|
||||
onChecked={handleChecked}
|
||||
onUnChecked={handleUnChecked}></ColorKindItem>
|
||||
)
|
||||
})
|
||||
}, [mockList, selected])
|
||||
|
||||
return (
|
||||
<LayoutBlock circle customClassName={styles.layout}>
|
||||
<MCheckbox>
|
||||
<MCheckbox customClassName={styles['checkbox']} customTextClass={styles['checkbox--text']} triggerLabel={false}>
|
||||
<View className='flex-row justify-between' onClick={handleOpenDetail}>
|
||||
<View className={styles.topItem}>
|
||||
<View className='flex-row'>
|
||||
<View className='flex-row items-center'>
|
||||
<View className={styles.topTitle}>灵玉布行</View>
|
||||
<Tag type='info' size='normal'>
|
||||
<Tag type='info' size='normal' circle plain>
|
||||
刘思伟
|
||||
</Tag>
|
||||
</View>
|
||||
@@ -49,46 +131,47 @@ export default memo((props: PropsType) => {
|
||||
<DrawerButton isOpen={openDetail} />
|
||||
</View>
|
||||
</MCheckbox>
|
||||
<View className={styles.detailBox}>
|
||||
<View className={classnames(styles.detailBox, openDetail ? styles.drawerOpen : styles.drawerClose)}>
|
||||
<View className={styles.orderType}>
|
||||
<Divider customClassName={styles.line}></Divider>
|
||||
<View className={styles.orderTypeTitle}>订单类型</View>
|
||||
<View className={styles.orderTitle}>订单类型</View>
|
||||
<View className={styles.orderTypeDetail}>
|
||||
<NormalButton
|
||||
type={selected === 0 ? 'primary' : 'info'}
|
||||
plain={selected !== 0}
|
||||
type={selected === EnumSaleMode.Bulk ? 'primary' : 'info'}
|
||||
plain={selected !== EnumSaleMode.Bulk}
|
||||
customStyles={{ padding: '0 50rpx' }}
|
||||
circle
|
||||
onClick={() => onSelectOrderType(0)}>
|
||||
onClick={() => onSelectOrderType(EnumSaleMode.Bulk)}>
|
||||
大货
|
||||
</NormalButton>
|
||||
<NormalButton
|
||||
type={selected === 1 ? 'primary' : 'info'}
|
||||
plain={selected !== 1}
|
||||
type={selected === EnumSaleMode.Plate ? 'primary' : 'info'}
|
||||
plain={selected !== EnumSaleMode.Plate}
|
||||
customStyles={{ padding: '0 50rpx' }}
|
||||
circle
|
||||
onClick={() => onSelectOrderType(1)}>
|
||||
散剪
|
||||
onClick={() => onSelectOrderType(EnumSaleMode.Plate)}>
|
||||
剪板
|
||||
</NormalButton>
|
||||
<NormalButton
|
||||
type={selected === 2 ? 'primary' : 'info'}
|
||||
plain={selected !== 2}
|
||||
type={selected === EnumSaleMode.BulkCut ? 'primary' : 'info'}
|
||||
plain={selected !== EnumSaleMode.BulkCut}
|
||||
customStyles={{ padding: '0 50rpx' }}
|
||||
circle
|
||||
onClick={() => onSelectOrderType(2)}>
|
||||
剪板
|
||||
onClick={() => onSelectOrderType(EnumSaleMode.BulkCut)}>
|
||||
散剪
|
||||
</NormalButton>
|
||||
</View>
|
||||
</View>
|
||||
<View className={styles.orderColor}>
|
||||
<Divider customClassName={styles.line}></Divider>
|
||||
<View className={classnames(styles.orderTypeTitle, 'justify-between')}>
|
||||
<View className={classnames(styles.orderTitle, 'justify-between')}>
|
||||
<Text>布料颜色</Text>
|
||||
<Tag type='danger' size='normal' circle>
|
||||
<Tag type='danger' size='normal' circle plain={false}>
|
||||
大货单位:条
|
||||
</Tag>
|
||||
</View>
|
||||
</View>
|
||||
<View className={styles.orderContainer}>{memoList}</View>
|
||||
</View>
|
||||
</LayoutBlock>
|
||||
)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
export default {
|
||||
navigationBarTitleText: '购物页面',
|
||||
|
||||
}
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
&--context {
|
||||
justify-content: space-between;
|
||||
height: 100%;
|
||||
|
||||
.shopping__list__container{
|
||||
overflow: scroll;
|
||||
}
|
||||
}
|
||||
}
|
||||
.flexBox {
|
||||
|
||||
@@ -52,7 +52,7 @@ const Shopping: FC = () => {
|
||||
</Search>
|
||||
</View>
|
||||
<View className={classnames('flex-item', 'flex-col', styles['shopping--context'])}>
|
||||
<View className={classnames('flex-item')}>
|
||||
<View className={classnames(styles.shopping__list__container, 'flex-item')}>
|
||||
{/* <InfiniteScroll
|
||||
statusMore={statusMore}
|
||||
selfonScrollToLower={getScrolltolower}
|
||||
@@ -68,6 +68,7 @@ const Shopping: FC = () => {
|
||||
})}
|
||||
</InfiniteScroll> */}
|
||||
<ItemList></ItemList>
|
||||
<ItemList></ItemList>
|
||||
</View>
|
||||
{isManage ? (
|
||||
<BottomEditBar onDelete={handleDelete} onSelectCheckbox={handleSelectAllCheckbox}></BottomEditBar>
|
||||
|
||||
Reference in New Issue
Block a user