feat(购物页面): 购物页面UI完成度80%

This commit is contained in:
xuan 2022-09-15 19:52:45 +08:00
parent fee33aec38
commit b4663f8507
29 changed files with 501 additions and 206 deletions

1
global.d.ts vendored
View File

@ -20,3 +20,4 @@ declare namespace NodeJS {
declare const CURRENT_VERSION: string
declare const CURRENT_GITHASH: string
declare const CURRENT_ENV: string

View File

@ -1,5 +1,5 @@
{
"symbol_url": "//at.alicdn.com/t/c/font_3619513_pecprurprt.js",
"symbol_url": "//at.alicdn.com/t/c/font_3619513_1msan9t0ewxk.js",
"save_dir": "./src/components/iconfont",
"use_typescript": true,
"platforms": ["weapp","h5"],

View File

@ -0,0 +1,8 @@
// 订单类型
// 0 大货 1 剪板 2 散剪
export const enum EnumSaleMode {
Bulk = 0,
Plate = 1,
BulkCut = 2
}

View File

@ -0,0 +1 @@
export { EnumSaleMode } from './BaseEnum/index'

View File

@ -7,6 +7,7 @@
}
}
.checkbox_main {
flex: 0 0 auto;
display: flex;
justify-content: center;
align-items: center;
@ -14,6 +15,7 @@
background-color: #fff;
border: 1px solid #c2c2c2;
text-align: center;
overflow: hidden;
line-height: 40px;
&--normal {
width: 40px;

View File

@ -11,15 +11,30 @@ type params = {
onClose?: () => void //取消触发
status?: boolean //是否选中
disabled?: boolean //是否禁用
triggerLabel?: boolean // 点击label是否触发选中
circle?: boolean
round?: boolean
size?: CheckboxSize
children?: React.ReactNode
customStyles?: React.CSSProperties
customClassName?: string
customTextClass?: string
}
export default forwardRef((props: params, ref) => {
const { onSelect, onClose, status = false, disabled = false, circle = false, round = true, size = 'normal', children, customStyles, customClassName } = props
const {
onSelect,
onClose,
status = false,
disabled = false,
circle = false,
round = true,
triggerLabel = true,
size = 'normal',
children,
customStyles = {},
customClassName = '',
customTextClass = '',
} = props
const [selected, SetSelected] = useState(false)
const onSelectEven = () => {
if (disabled) return false
@ -32,6 +47,12 @@ export default forwardRef((props: params, ref) => {
SetSelected(res)
}
const handleClickChildren = (event) => {
if (!triggerLabel){
return event.stopPropagation()
}
}
const getMainClassName = () => {
const classObject = {
[styles['checkbox_main--selected']]: selected,
@ -57,13 +78,17 @@ export default forwardRef((props: params, ref) => {
SetSelected(status)
}, [status])
return (
<View className={classnames(customClassName, styles.checkbox)} onClick={() => onSelectEven()} style={customStyles}>
<View className={classnames(customClassName, styles.checkbox)} style={customStyles} onClick={onSelectEven}>
<View className={classnames(styles.checkbox_main, getMainClassName())}>
<View className={classnames(styles.checkbox_item, getClassName())}>
{selected && <IconFont name='icon-a-jizhumima' size={22} color='#fff'></IconFont>}
</View>
</View>
{children && <View className={styles['checkbox--text']}>{children}</View>}
{children && (
<View className={classnames(styles['checkbox--text'], customTextClass)} onClick={handleClickChildren}>
{children}
</View>
)}
</View>
)
})

View File

@ -1,37 +0,0 @@
.main{
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
.reduce, .plus{
font-size: $font_size_big;
color: $color_main;
width: 46px;
height: 46px;
display: flex;
align-items: center;
justify-content:center;
font-size: 50px;
background-color: $color_main;
color: #fff;
border-radius: 8px;
}
.input{
display: flex;
align-items: flex-end;
background-color: #fff;
padding: 5px 10px;
box-sizing: border-box;
width: 106px;
border-radius: 10px;
}
input{
font-size: $font_size_medium;
}
.unit{
font-size: $font_size_min;
color: $color_font_two;
}
}

View File

@ -1,111 +0,0 @@
import { Input, View } from "@tarojs/components"
import { useEffect, useMemo, useRef, useState } from "react"
import Big from 'big.js'
import styles from "./index.module.scss"
type params = {
minNum?: number, //最小值
maxNum?: number, //最大值
step?: number, //步长
defaultNum?: number, //默认值
digits?: number //多少位小数
onChange?:(val:number) => void,
onBlue?:(val:number) => void, //失去焦点触发
onClickBtn?:(val:number) => void,
unit?: string
}
export default ({minNum = 0, maxNum = 100, step=1, digits = 0, defaultNum = 0, onChange, onBlue, onClickBtn, unit = ''}: params) => {
const [value, setValue] = useState<any>({count:defaultNum})
const onPlus = () => {
let {count} = value
let num_res = Big(count).add(step).toNumber()
num_res = num_res >= maxNum?maxNum:num_res
num_res = formatDigits(num_res)
setValue({...value, count:num_res})
onChange?.(parseFloat(num_res))
onClickBtn?.(parseFloat(num_res))
}
const minus = () => {
let {count} = value
let num_res = Big(count).minus(step).toNumber()
num_res = num_res < minNum?0:num_res
setValue({...value, count:num_res})
onChange?.(parseFloat(num_res))
onClickBtn?.(parseFloat(num_res))
}
//保留小数
const formatDigits = (num) => {
num = num + ''
if(num.includes('.')&&digits > 0) {
console.log('num::',num.includes('.'))
let res = num.split('.')
let last_num = res[1].substr(0, digits)
return res[0] + '.' + last_num
}
return parseFloat(num)
}
//检查数据
const checkData = (val) => {
let num = parseFloat(val)
if(num > maxNum) return maxNum
if(num < minNum) return minNum
return val
}
const onInputEven = (e) => {
let res = e.detail.value
if(res === '') {
setValue({...value, count:minNum})
onChange?.(minNum)
}
else if(!isNaN(Number(res))) {
let count = formatDigits(res)
count = checkData(count)
setValue({...value, count})
onChange?.(parseFloat(count as string))
} else {
let num = parseFloat(res)
if(!isNaN(num)) {
let count = formatDigits(num)
count = checkData(count)
setValue({...value, count})
onChange?.(count as number)
} else {
setValue({...value, count:defaultNum})
onChange?.(defaultNum)
}
}
}
const onBluerEven = () => {
let num = parseFloat(value.count)
if(!isNaN(num)) {
let count = formatDigits(num)
count = checkData(count)
setValue({...value, count})
onBlue?.(count as number)
} else {
setValue({...value, count:defaultNum})
onBlue?.(defaultNum)
}
}
return (
<View className={styles.main}>
<View className={styles.reduce} onClick={() => minus()}>-</View>
<View className={styles.input}>
<Input
value={String(value.count)}
onInput={onInputEven}
onBlur={onBluerEven}
type='digit'
/>
<View className={styles.unit}>{unit}</View>
</View>
<View className={styles.plus} onClick={() => onPlus()}>+</View>
</View>
)
}

View File

@ -0,0 +1,34 @@
/* tslint:disable */
/* eslint-disable */
import React, { CSSProperties, SVGAttributes, FunctionComponent } from 'react';
import { getIconColor } from './helper';
interface Props extends Omit<SVGAttributes<SVGElement>, 'color'> {
size?: number;
color?: string | string[];
}
const DEFAULT_STYLE: CSSProperties = {
display: 'block',
};
const IconShouqi: FunctionComponent<Props> = ({ size, color, style: _style, ...rest }) => {
const style = _style ? { ...DEFAULT_STYLE, ..._style } : DEFAULT_STYLE;
return (
<svg viewBox="0 0 1024 1024" width={size + 'rem'} height={size + 'rem'} style={style} {...rest}>
<path
d="M492.586667 355.861333a27.434667 27.434667 0 0 1 36.416-2.133333l2.389333 2.133333 232.746667 232.746667a27.434667 27.434667 0 0 1-36.394667 40.917333l-2.389333-2.133333-213.397334-213.333333-213.312 213.333333c-9.941333 9.941333-25.621333 10.666667-36.394666 2.133333l-2.389334-2.133333a27.434667 27.434667 0 0 1-2.133333-36.394667l2.133333-2.389333 232.746667-232.746667z"
fill={getIconColor(color, 0, '#000000')}
opacity=".8"
/>
</svg>
);
};
IconShouqi.defaultProps = {
size: 18,
};
export default IconShouqi;

View File

@ -0,0 +1,34 @@
/* tslint:disable */
/* eslint-disable */
import React, { CSSProperties, SVGAttributes, FunctionComponent } from 'react';
import { getIconColor } from './helper';
interface Props extends Omit<SVGAttributes<SVGElement>, 'color'> {
size?: number;
color?: string | string[];
}
const DEFAULT_STYLE: CSSProperties = {
display: 'block',
};
const IconZhankai: FunctionComponent<Props> = ({ size, color, style: _style, ...rest }) => {
const style = _style ? { ...DEFAULT_STYLE, ..._style } : DEFAULT_STYLE;
return (
<svg viewBox="0 0 1024 1024" width={size + 'rem'} height={size + 'rem'} style={style} {...rest}>
<path
d="M492.586667 668.138667c9.962667 9.941333 25.642667 10.666667 36.416 2.133333l2.389333-2.133333 232.746667-232.746667a27.434667 27.434667 0 0 0-36.394667-40.917333l-2.389333 2.133333-213.397334 213.333333-213.312-213.333333a27.434667 27.434667 0 0 0-36.394666-2.133333l-2.389334 2.133333a27.434667 27.434667 0 0 0-2.133333 36.394667l2.133333 2.389333 232.746667 232.746667z"
fill={getIconColor(color, 0, '#000000')}
opacity=".8"
/>
</svg>
);
};
IconZhankai.defaultProps = {
size: 18,
};
export default IconZhankai;

View File

@ -2,6 +2,8 @@
/* eslint-disable */
import React, { SVGAttributes, FunctionComponent } from 'react';
import IconZhankai from './IconZhankai';
import IconShouqi from './IconShouqi';
import IconLujing from './IconLujing';
import IconJizhumima from './IconJizhumima';
import IconAJizhumima from './IconAJizhumima';
@ -61,6 +63,8 @@ import IconGerenzhongxin from './IconGerenzhongxin';
import IconDingdan from './IconDingdan';
import IconShouye from './IconShouye';
import IconGouwu from './IconGouwu';
export { default as IconZhankai } from './IconZhankai';
export { default as IconShouqi } from './IconShouqi';
export { default as IconLujing } from './IconLujing';
export { default as IconJizhumima } from './IconJizhumima';
export { default as IconAJizhumima } from './IconAJizhumima';
@ -121,7 +125,7 @@ export { default as IconDingdan } from './IconDingdan';
export { default as IconShouye } from './IconShouye';
export { default as IconGouwu } from './IconGouwu';
export type IconNames = 'icon-lujing' | 'icon-jizhumima' | 'icon-a-jizhumima' | 'icon-weixindenglu' | 'icon-kehuxinxi' | 'icon-yewuyuanqizi' | 'icon-chakanquanbukehu' | 'icon-biyan' | 'icon-bianji' | 'icon-daikuan' | 'icon-cangku' | 'icon-guanlidingdan' | 'icon-mima' | 'icon-guanbi' | 'icon-jianshao' | 'icon-dingwei' | 'icon-saomiao' | 'icon-peihuo' | 'icon-shaixuan' | 'icon-paiming' | 'icon-shanchusousuoxinxi' | 'icon-shijian' | 'icon-sousuo' | 'icon-shouhou' | 'icon-sousuofanhui' | 'icon-sousuoshanchu' | 'icon-tuikuan' | 'icon-tishi' | 'icon-xianxiahuizong' | 'icon-xinzeng' | 'icon-yonghuming' | 'icon-yanjing' | 'icon-yufukuan' | 'icon-wodekefu' | 'icon-dizhi' | 'icon-shouhouzhongxin' | 'icon-wodeshoucang' | 'icon-shoukuanliebiao' | 'icon-madanguanli' | 'icon-qusechazhao' | 'icon-pandiansaoma' | 'icon-yaoqingma' | 'icon-duizhang' | 'icon-tihuoliebiao' | 'icon-yangpinduibi' | 'icon-yansequyang' | 'icon-fahuoliebiao' | 'icon-yuncangkucun' | 'icon-xiaoshou' | 'icon-qianzhicangkucun' | 'icon-lingquseka' | 'icon-gouwu1' | 'icon-dingdan1' | 'icon-gerenzhongxin1' | 'icon-shouye1' | 'icon-gerenzhongxin' | 'icon-dingdan' | 'icon-shouye' | 'icon-gouwu';
export type IconNames = 'icon-zhankai' | 'icon-shouqi' | 'icon-lujing' | 'icon-jizhumima' | 'icon-a-jizhumima' | 'icon-weixindenglu' | 'icon-kehuxinxi' | 'icon-yewuyuanqizi' | 'icon-chakanquanbukehu' | 'icon-biyan' | 'icon-bianji' | 'icon-daikuan' | 'icon-cangku' | 'icon-guanlidingdan' | 'icon-mima' | 'icon-guanbi' | 'icon-jianshao' | 'icon-dingwei' | 'icon-saomiao' | 'icon-peihuo' | 'icon-shaixuan' | 'icon-paiming' | 'icon-shanchusousuoxinxi' | 'icon-shijian' | 'icon-sousuo' | 'icon-shouhou' | 'icon-sousuofanhui' | 'icon-sousuoshanchu' | 'icon-tuikuan' | 'icon-tishi' | 'icon-xianxiahuizong' | 'icon-xinzeng' | 'icon-yonghuming' | 'icon-yanjing' | 'icon-yufukuan' | 'icon-wodekefu' | 'icon-dizhi' | 'icon-shouhouzhongxin' | 'icon-wodeshoucang' | 'icon-shoukuanliebiao' | 'icon-madanguanli' | 'icon-qusechazhao' | 'icon-pandiansaoma' | 'icon-yaoqingma' | 'icon-duizhang' | 'icon-tihuoliebiao' | 'icon-yangpinduibi' | 'icon-yansequyang' | 'icon-fahuoliebiao' | 'icon-yuncangkucun' | 'icon-xiaoshou' | 'icon-qianzhicangkucun' | 'icon-lingquseka' | 'icon-gouwu1' | 'icon-dingdan1' | 'icon-gerenzhongxin1' | 'icon-shouye1' | 'icon-gerenzhongxin' | 'icon-dingdan' | 'icon-shouye' | 'icon-gouwu';
interface Props extends Omit<SVGAttributes<SVGElement>, 'color'> {
name: IconNames;
@ -131,6 +135,10 @@ interface Props extends Omit<SVGAttributes<SVGElement>, 'color'> {
const IconFont: FunctionComponent<Props> = ({ name, ...rest }) => {
switch (name) {
case 'icon-zhankai':
return <IconZhankai {...rest} />;
case 'icon-shouqi':
return <IconShouqi {...rest} />;
case 'icon-lujing':
return <IconLujing {...rest} />;
case 'icon-jizhumima':

View File

@ -5,7 +5,7 @@ import React, { FunctionComponent } from 'react';
import Taro from '@tarojs/taro';
import Icon from './h5';
export type IconNames = 'icon-lujing' | 'icon-jizhumima' | 'icon-a-jizhumima' | 'icon-weixindenglu' | 'icon-kehuxinxi' | 'icon-yewuyuanqizi' | 'icon-chakanquanbukehu' | 'icon-biyan' | 'icon-bianji' | 'icon-daikuan' | 'icon-cangku' | 'icon-guanlidingdan' | 'icon-mima' | 'icon-guanbi' | 'icon-jianshao' | 'icon-dingwei' | 'icon-saomiao' | 'icon-peihuo' | 'icon-shaixuan' | 'icon-paiming' | 'icon-shanchusousuoxinxi' | 'icon-shijian' | 'icon-sousuo' | 'icon-shouhou' | 'icon-sousuofanhui' | 'icon-sousuoshanchu' | 'icon-tuikuan' | 'icon-tishi' | 'icon-xianxiahuizong' | 'icon-xinzeng' | 'icon-yonghuming' | 'icon-yanjing' | 'icon-yufukuan' | 'icon-wodekefu' | 'icon-dizhi' | 'icon-shouhouzhongxin' | 'icon-wodeshoucang' | 'icon-shoukuanliebiao' | 'icon-madanguanli' | 'icon-qusechazhao' | 'icon-pandiansaoma' | 'icon-yaoqingma' | 'icon-duizhang' | 'icon-tihuoliebiao' | 'icon-yangpinduibi' | 'icon-yansequyang' | 'icon-fahuoliebiao' | 'icon-yuncangkucun' | 'icon-xiaoshou' | 'icon-qianzhicangkucun' | 'icon-lingquseka' | 'icon-gouwu1' | 'icon-dingdan1' | 'icon-gerenzhongxin1' | 'icon-shouye1' | 'icon-gerenzhongxin' | 'icon-dingdan' | 'icon-shouye' | 'icon-gouwu';
export type IconNames = 'icon-zhankai' | 'icon-shouqi' | 'icon-lujing' | 'icon-jizhumima' | 'icon-a-jizhumima' | 'icon-weixindenglu' | 'icon-kehuxinxi' | 'icon-yewuyuanqizi' | 'icon-chakanquanbukehu' | 'icon-biyan' | 'icon-bianji' | 'icon-daikuan' | 'icon-cangku' | 'icon-guanlidingdan' | 'icon-mima' | 'icon-guanbi' | 'icon-jianshao' | 'icon-dingwei' | 'icon-saomiao' | 'icon-peihuo' | 'icon-shaixuan' | 'icon-paiming' | 'icon-shanchusousuoxinxi' | 'icon-shijian' | 'icon-sousuo' | 'icon-shouhou' | 'icon-sousuofanhui' | 'icon-sousuoshanchu' | 'icon-tuikuan' | 'icon-tishi' | 'icon-xianxiahuizong' | 'icon-xinzeng' | 'icon-yonghuming' | 'icon-yanjing' | 'icon-yufukuan' | 'icon-wodekefu' | 'icon-dizhi' | 'icon-shouhouzhongxin' | 'icon-wodeshoucang' | 'icon-shoukuanliebiao' | 'icon-madanguanli' | 'icon-qusechazhao' | 'icon-pandiansaoma' | 'icon-yaoqingma' | 'icon-duizhang' | 'icon-tihuoliebiao' | 'icon-yangpinduibi' | 'icon-yansequyang' | 'icon-fahuoliebiao' | 'icon-yuncangkucun' | 'icon-xiaoshou' | 'icon-qianzhicangkucun' | 'icon-lingquseka' | 'icon-gouwu1' | 'icon-dingdan1' | 'icon-gerenzhongxin1' | 'icon-shouye1' | 'icon-gerenzhongxin' | 'icon-dingdan' | 'icon-shouye' | 'icon-gouwu';
interface Props {
name: IconNames;

View File

@ -3,7 +3,7 @@
import React, { FunctionComponent } from 'react';
export type IconNames = 'icon-lujing' | 'icon-jizhumima' | 'icon-a-jizhumima' | 'icon-weixindenglu' | 'icon-kehuxinxi' | 'icon-yewuyuanqizi' | 'icon-chakanquanbukehu' | 'icon-biyan' | 'icon-bianji' | 'icon-daikuan' | 'icon-cangku' | 'icon-guanlidingdan' | 'icon-mima' | 'icon-guanbi' | 'icon-jianshao' | 'icon-dingwei' | 'icon-saomiao' | 'icon-peihuo' | 'icon-shaixuan' | 'icon-paiming' | 'icon-shanchusousuoxinxi' | 'icon-shijian' | 'icon-sousuo' | 'icon-shouhou' | 'icon-sousuofanhui' | 'icon-sousuoshanchu' | 'icon-tuikuan' | 'icon-tishi' | 'icon-xianxiahuizong' | 'icon-xinzeng' | 'icon-yonghuming' | 'icon-yanjing' | 'icon-yufukuan' | 'icon-wodekefu' | 'icon-dizhi' | 'icon-shouhouzhongxin' | 'icon-wodeshoucang' | 'icon-shoukuanliebiao' | 'icon-madanguanli' | 'icon-qusechazhao' | 'icon-pandiansaoma' | 'icon-yaoqingma' | 'icon-duizhang' | 'icon-tihuoliebiao' | 'icon-yangpinduibi' | 'icon-yansequyang' | 'icon-fahuoliebiao' | 'icon-yuncangkucun' | 'icon-xiaoshou' | 'icon-qianzhicangkucun' | 'icon-lingquseka' | 'icon-gouwu1' | 'icon-dingdan1' | 'icon-gerenzhongxin1' | 'icon-shouye1' | 'icon-gerenzhongxin' | 'icon-dingdan' | 'icon-shouye' | 'icon-gouwu';
export type IconNames = 'icon-zhankai' | 'icon-shouqi' | 'icon-lujing' | 'icon-jizhumima' | 'icon-a-jizhumima' | 'icon-weixindenglu' | 'icon-kehuxinxi' | 'icon-yewuyuanqizi' | 'icon-chakanquanbukehu' | 'icon-biyan' | 'icon-bianji' | 'icon-daikuan' | 'icon-cangku' | 'icon-guanlidingdan' | 'icon-mima' | 'icon-guanbi' | 'icon-jianshao' | 'icon-dingwei' | 'icon-saomiao' | 'icon-peihuo' | 'icon-shaixuan' | 'icon-paiming' | 'icon-shanchusousuoxinxi' | 'icon-shijian' | 'icon-sousuo' | 'icon-shouhou' | 'icon-sousuofanhui' | 'icon-sousuoshanchu' | 'icon-tuikuan' | 'icon-tishi' | 'icon-xianxiahuizong' | 'icon-xinzeng' | 'icon-yonghuming' | 'icon-yanjing' | 'icon-yufukuan' | 'icon-wodekefu' | 'icon-dizhi' | 'icon-shouhouzhongxin' | 'icon-wodeshoucang' | 'icon-shoukuanliebiao' | 'icon-madanguanli' | 'icon-qusechazhao' | 'icon-pandiansaoma' | 'icon-yaoqingma' | 'icon-duizhang' | 'icon-tihuoliebiao' | 'icon-yangpinduibi' | 'icon-yansequyang' | 'icon-fahuoliebiao' | 'icon-yuncangkucun' | 'icon-xiaoshou' | 'icon-qianzhicangkucun' | 'icon-lingquseka' | 'icon-gouwu1' | 'icon-dingdan1' | 'icon-gerenzhongxin1' | 'icon-shouye1' | 'icon-gerenzhongxin' | 'icon-dingdan' | 'icon-shouye' | 'icon-gouwu';
export interface IconProps {
name: IconNames;

View File

@ -4,7 +4,7 @@
import React, { FunctionComponent } from 'react';
import Taro from '@tarojs/taro';
export type IconNames = 'icon-lujing' | 'icon-jizhumima' | 'icon-a-jizhumima' | 'icon-weixindenglu' | 'icon-kehuxinxi' | 'icon-yewuyuanqizi' | 'icon-chakanquanbukehu' | 'icon-biyan' | 'icon-bianji' | 'icon-daikuan' | 'icon-cangku' | 'icon-guanlidingdan' | 'icon-mima' | 'icon-guanbi' | 'icon-jianshao' | 'icon-dingwei' | 'icon-saomiao' | 'icon-peihuo' | 'icon-shaixuan' | 'icon-paiming' | 'icon-shanchusousuoxinxi' | 'icon-shijian' | 'icon-sousuo' | 'icon-shouhou' | 'icon-sousuofanhui' | 'icon-sousuoshanchu' | 'icon-tuikuan' | 'icon-tishi' | 'icon-xianxiahuizong' | 'icon-xinzeng' | 'icon-yonghuming' | 'icon-yanjing' | 'icon-yufukuan' | 'icon-wodekefu' | 'icon-dizhi' | 'icon-shouhouzhongxin' | 'icon-wodeshoucang' | 'icon-shoukuanliebiao' | 'icon-madanguanli' | 'icon-qusechazhao' | 'icon-pandiansaoma' | 'icon-yaoqingma' | 'icon-duizhang' | 'icon-tihuoliebiao' | 'icon-yangpinduibi' | 'icon-yansequyang' | 'icon-fahuoliebiao' | 'icon-yuncangkucun' | 'icon-xiaoshou' | 'icon-qianzhicangkucun' | 'icon-lingquseka' | 'icon-gouwu1' | 'icon-dingdan1' | 'icon-gerenzhongxin1' | 'icon-shouye1' | 'icon-gerenzhongxin' | 'icon-dingdan' | 'icon-shouye' | 'icon-gouwu';
export type IconNames = 'icon-zhankai' | 'icon-shouqi' | 'icon-lujing' | 'icon-jizhumima' | 'icon-a-jizhumima' | 'icon-weixindenglu' | 'icon-kehuxinxi' | 'icon-yewuyuanqizi' | 'icon-chakanquanbukehu' | 'icon-biyan' | 'icon-bianji' | 'icon-daikuan' | 'icon-cangku' | 'icon-guanlidingdan' | 'icon-mima' | 'icon-guanbi' | 'icon-jianshao' | 'icon-dingwei' | 'icon-saomiao' | 'icon-peihuo' | 'icon-shaixuan' | 'icon-paiming' | 'icon-shanchusousuoxinxi' | 'icon-shijian' | 'icon-sousuo' | 'icon-shouhou' | 'icon-sousuofanhui' | 'icon-sousuoshanchu' | 'icon-tuikuan' | 'icon-tishi' | 'icon-xianxiahuizong' | 'icon-xinzeng' | 'icon-yonghuming' | 'icon-yanjing' | 'icon-yufukuan' | 'icon-wodekefu' | 'icon-dizhi' | 'icon-shouhouzhongxin' | 'icon-wodeshoucang' | 'icon-shoukuanliebiao' | 'icon-madanguanli' | 'icon-qusechazhao' | 'icon-pandiansaoma' | 'icon-yaoqingma' | 'icon-duizhang' | 'icon-tihuoliebiao' | 'icon-yangpinduibi' | 'icon-yansequyang' | 'icon-fahuoliebiao' | 'icon-yuncangkucun' | 'icon-xiaoshou' | 'icon-qianzhicangkucun' | 'icon-lingquseka' | 'icon-gouwu1' | 'icon-dingdan1' | 'icon-gerenzhongxin1' | 'icon-shouye1' | 'icon-gerenzhongxin' | 'icon-dingdan' | 'icon-shouye' | 'icon-gouwu';
interface Props {
name: IconNames;

View File

@ -1,6 +1,6 @@
Component({
properties: {
// icon-lujing | icon-jizhumima | icon-a-jizhumima | icon-weixindenglu | icon-kehuxinxi | icon-yewuyuanqizi | icon-chakanquanbukehu | icon-biyan | icon-bianji | icon-daikuan | icon-cangku | icon-guanlidingdan | icon-mima | icon-guanbi | icon-jianshao | icon-dingwei | icon-saomiao | icon-peihuo | icon-shaixuan | icon-paiming | icon-shanchusousuoxinxi | icon-shijian | icon-sousuo | icon-shouhou | icon-sousuofanhui | icon-sousuoshanchu | icon-tuikuan | icon-tishi | icon-xianxiahuizong | icon-xinzeng | icon-yonghuming | icon-yanjing | icon-yufukuan | icon-wodekefu | icon-dizhi | icon-shouhouzhongxin | icon-wodeshoucang | icon-shoukuanliebiao | icon-madanguanli | icon-qusechazhao | icon-pandiansaoma | icon-yaoqingma | icon-duizhang | icon-tihuoliebiao | icon-yangpinduibi | icon-yansequyang | icon-fahuoliebiao | icon-yuncangkucun | icon-xiaoshou | icon-qianzhicangkucun | icon-lingquseka | icon-gouwu1 | icon-dingdan1 | icon-gerenzhongxin1 | icon-shouye1 | icon-gerenzhongxin | icon-dingdan | icon-shouye | icon-gouwu
// icon-zhankai | icon-shouqi | icon-lujing | icon-jizhumima | icon-a-jizhumima | icon-weixindenglu | icon-kehuxinxi | icon-yewuyuanqizi | icon-chakanquanbukehu | icon-biyan | icon-bianji | icon-daikuan | icon-cangku | icon-guanlidingdan | icon-mima | icon-guanbi | icon-jianshao | icon-dingwei | icon-saomiao | icon-peihuo | icon-shaixuan | icon-paiming | icon-shanchusousuoxinxi | icon-shijian | icon-sousuo | icon-shouhou | icon-sousuofanhui | icon-sousuoshanchu | icon-tuikuan | icon-tishi | icon-xianxiahuizong | icon-xinzeng | icon-yonghuming | icon-yanjing | icon-yufukuan | icon-wodekefu | icon-dizhi | icon-shouhouzhongxin | icon-wodeshoucang | icon-shoukuanliebiao | icon-madanguanli | icon-qusechazhao | icon-pandiansaoma | icon-yaoqingma | icon-duizhang | icon-tihuoliebiao | icon-yangpinduibi | icon-yansequyang | icon-fahuoliebiao | icon-yuncangkucun | icon-xiaoshou | icon-qianzhicangkucun | icon-lingquseka | icon-gouwu1 | icon-dingdan1 | icon-gerenzhongxin1 | icon-shouye1 | icon-gerenzhongxin | icon-dingdan | icon-shouye | icon-gouwu
name: {
type: String,
},

View File

@ -1,3 +1,9 @@
<!--icon-zhankai-->
<view wx:if="{{name === 'icon-zhankai'}}" style="background-image: url({{quot}}data:image/svg+xml, %3Csvg viewBox='0 0 1024 1024' xmlns='http://www.w3.org/2000/svg' width='{{svgSize}}px' height='{{svgSize}}px'%3E%3Cpath d='M492.586667 668.138667c9.962667 9.941333 25.642667 10.666667 36.416 2.133333l2.389333-2.133333 232.746667-232.746667a27.434667 27.434667 0 0 0-36.394667-40.917333l-2.389333 2.133333-213.397334 213.333333-213.312-213.333333a27.434667 27.434667 0 0 0-36.394666-2.133333l-2.389334 2.133333a27.434667 27.434667 0 0 0-2.133333 36.394667l2.133333 2.389333 232.746667 232.746667z' fill='{{(isStr ? colors : colors[0]) || 'rgb(0,0,0)'}}' opacity='.8' /%3E%3C/svg%3E{{quot}}); width: {{svgSize}}px; height: {{svgSize}}px; " class="icon" />
<!--icon-shouqi-->
<view wx:if="{{name === 'icon-shouqi'}}" style="background-image: url({{quot}}data:image/svg+xml, %3Csvg viewBox='0 0 1024 1024' xmlns='http://www.w3.org/2000/svg' width='{{svgSize}}px' height='{{svgSize}}px'%3E%3Cpath d='M492.586667 355.861333a27.434667 27.434667 0 0 1 36.416-2.133333l2.389333 2.133333 232.746667 232.746667a27.434667 27.434667 0 0 1-36.394667 40.917333l-2.389333-2.133333-213.397334-213.333333-213.312 213.333333c-9.941333 9.941333-25.621333 10.666667-36.394666 2.133333l-2.389334-2.133333a27.434667 27.434667 0 0 1-2.133333-36.394667l2.133333-2.389333 232.746667-232.746667z' fill='{{(isStr ? colors : colors[0]) || 'rgb(0,0,0)'}}' opacity='.8' /%3E%3C/svg%3E{{quot}}); width: {{svgSize}}px; height: {{svgSize}}px; " class="icon" />
<!--icon-lujing-->
<view wx:if="{{name === 'icon-lujing'}}" style="background-image: url({{quot}}data:image/svg+xml, %3Csvg viewBox='0 0 1450 1024' xmlns='http://www.w3.org/2000/svg' width='{{svgSize}}px' height='{{svgSize}}px'%3E%3Cpath d='M495.06688 1024a44.672 44.672 0 0 1-31.786667-13.653333L12.080213 549.461333a48.298667 48.298667 0 0 1 0.938667-64.938666 44.373333 44.373333 0 0 1 62.72-2.133334l419.328 428.373334L1375.877547 11.093333a44.330667 44.330667 0 0 1 61.696 2.944c16.682667 17.493333 17.493333 45.354667 1.962666 63.914667l-912.64 931.669333c-8.362667 8.96-19.797333 14.122667-31.829333 14.378667z' fill='{{(isStr ? colors : colors[0]) || 'rgb(64,92,135)'}}' /%3E%3C/svg%3E{{quot}}); width: {{svgSize}}px; height: {{svgSize}}px; " class="icon" />

View File

@ -7,6 +7,7 @@
text-align: center;
justify-content: center;
align-items: center;
box-sizing: border-box;
&--normal {
font-size: $font_size_medium;
height: 40px;
@ -18,18 +19,33 @@
&--circle{
border-radius: 10px;
}
&--danger {
background-color: $color_danger;
border: 1px solid $color_danger;
color: $color_danger;
}
&--primary{
background-color: $color_main;
border: 1px solid $color_main;
color: $color_main;
}
&--warning{
background-color: $color_warning;
border: 1px solid $color_warning;
color: $color_warning;
}
&--info{
background-color: $color_info;
color: rgba($color: #333333, $alpha: 0.8);
border: 1px solid $color_info;
color: $color_info;
.tag--text {
color: rgba($color: #333333, $alpha: 0.8) !important;
}
}
&--plain {
background-color: currentColor;
border-color: currentColor;
border: unset;
.tag--text {
color: #ffffff;
}
}
&--disabled {
opacity: $opacity-disabled;

View File

@ -1,4 +1,4 @@
import { View } from '@tarojs/components'
import { View, Text } from '@tarojs/components'
import { FC, ReactNode } from 'react'
import classnames from 'classnames'
import styles from './index.module.scss'
@ -34,12 +34,11 @@ const Tag: FC<PropsType> = (props) => {
[styles['tag--plain']]: plain,
[styles['tag--circle']]: circle,
}
console.log('classObj==>', classObject)
return classObject
}
return (
<View className={classnames(styles.tag, getClassName())} style={customStyle} onClick={handleClick}>
{children}
<Text className={styles['tag--text']}>{children}</Text>
</View>
)
}

View File

@ -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;
}

View File

@ -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

View File

@ -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%;
margin-left: 56px;
.orderTypeTitle{
.orderTitle {
padding: 0 24px;
display: flex;
align-items: center;
color: $color_font_one;
font-weight: 550;
font-size: 28px;
line-height: 2.5;
}
.orderTypeDetail{
.orderType {
padding: 0 24px;
margin-left: 56px;
.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;
}

View File

@ -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>
)

View File

@ -1,3 +1,4 @@
export default {
navigationBarTitleText: '购物页面',
}

View File

@ -9,7 +9,9 @@
&--context {
justify-content: space-between;
height: 100%;
.shopping__list__container{
overflow: scroll;
}
}
}
.flexBox {

View File

@ -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>

View File

@ -52,6 +52,10 @@ $customTabBarHeight: 100px;
.justify-between {
justify-content: space-between
}
.items-center{
align-items: center;
}
.flex-item {
flex: 1 1 auto;
}

View File

@ -1,6 +1,6 @@
@font-face {
font-family: "iconfont"; /* Project id 3619513 */
src: url('/src/styles/iconfont.ttf?t=1663134774880') format('truetype');
src: url('/src/styles/iconfont.ttf?t=1663207764776') format('truetype');
}
.iconfont {
@ -11,6 +11,14 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-zhankai:before {
content: "\e63f";
}
.icon-shouqi:before {
content: "\e640";
}
.icon-lujing:before {
content: "\e63e";
}

Binary file not shown.