63fcf33416
要求门店支持多个分类; 小程序C端“瓶”位置调整; 商品单元“立即购买”直接跳转到“确认订单”页;
64 lines
1.7 KiB
TypeScript
64 lines
1.7 KiB
TypeScript
import { useEffect, useState } from 'react';
|
||
import { View, Text, Input } from '@tarojs/components';
|
||
|
||
type OrderQtyControlsProps = {
|
||
value: number;
|
||
unitLabel: string;
|
||
onChange: (next: number) => void;
|
||
};
|
||
|
||
const MAX_QTY = 999;
|
||
|
||
function parseQty(raw: string): number | null {
|
||
const n = parseInt(String(raw).replace(/\D/g, ''), 10);
|
||
if (!Number.isFinite(n)) return null;
|
||
return Math.min(MAX_QTY, Math.max(1, n));
|
||
}
|
||
|
||
/** 下单数量:加减 + 手动输入,旁注单位(瓶/箱) */
|
||
export default function OrderQtyControls({ value, unitLabel, onChange }: OrderQtyControlsProps) {
|
||
const [draft, setDraft] = useState(String(value));
|
||
|
||
useEffect(() => {
|
||
setDraft(String(value));
|
||
}, [value]);
|
||
|
||
function current(): number {
|
||
return parseQty(draft) ?? value;
|
||
}
|
||
|
||
function commit() {
|
||
const next = parseQty(draft);
|
||
if (next == null) {
|
||
setDraft(String(value));
|
||
return;
|
||
}
|
||
setDraft(String(next));
|
||
if (next !== value) onChange(next);
|
||
}
|
||
|
||
return (
|
||
<View className="order-qty-row">
|
||
<Text>购买数量</Text>
|
||
<View className="order-qty-controls">
|
||
<View className="order-qty-btn" onClick={() => onChange(Math.max(1, current() - 1))}>
|
||
<Text>−</Text>
|
||
</View>
|
||
<Input
|
||
className="order-qty-input"
|
||
type="number"
|
||
maxlength={3}
|
||
value={draft}
|
||
onInput={(e) => setDraft(String(e.detail.value ?? ''))}
|
||
onBlur={commit}
|
||
onConfirm={commit}
|
||
/>
|
||
<View className="order-qty-btn" onClick={() => onChange(Math.min(MAX_QTY, current() + 1))}>
|
||
<Text>+</Text>
|
||
</View>
|
||
<Text className="order-qty-unit">{unitLabel}</Text>
|
||
</View>
|
||
</View>
|
||
);
|
||
}
|