diff --git a/src/user/ticket/use.tsx b/src/user/ticket/use.tsx index 7f698dd..8a98f8f 100644 --- a/src/user/ticket/use.tsx +++ b/src/user/ticket/use.tsx @@ -26,6 +26,7 @@ import {getShopStore, listShopStore} from "@/api/shop/shopStore"; import {getSelectedStoreFromStorage, saveSelectedStoreToStorage} from "@/utils/storeSelection"; import type { GltUserTicket } from '@/api/glt/gltUserTicket/model' import { getGltUserTicket, listGltUserTicket } from '@/api/glt/gltUserTicket' +import { getGltTicketTemplate, getGltTicketTemplateByGoodsId } from '@/api/glt/gltTicketTemplate' import { addGltTicketOrder, getGltTicketOrder, updateGltTicketOrder } from '@/api/glt/gltTicketOrder' import { pageGltTicketOrder } from '@/api/glt/gltTicketOrder' import type { GltTicketOrder } from '@/api/glt/gltTicketOrder/model' @@ -35,13 +36,14 @@ import type { ShopStoreFence } from '@/api/shop/shopStoreFence/model' import { listShopStoreFence } from '@/api/shop/shopStoreFence' import { parseFencePoints, parseLngLatFromText, pointInAnyPolygon, pointInPolygon } from '@/utils/geofence' -const MIN_START_QTY = 10 +const DEFAULT_MIN_START_QTY = 10 const ADDRESS_CHANGE_COOLDOWN_DAYS = 30 const OrderConfirm = () => { const [goods, setGoods] = useState(null); const [address, setAddress] = useState() - const [quantity, setQuantity] = useState(MIN_START_QTY) + const [minStartQty, setMinStartQty] = useState(DEFAULT_MIN_START_QTY) + const [quantity, setQuantity] = useState(DEFAULT_MIN_START_QTY) const [orderRemark, setOrderRemark] = useState('') // Delivery date only (no hour/min selection). const [sendTime, setSendTime] = useState(() => dayjs().startOf('day').toDate()) @@ -325,13 +327,13 @@ const OrderConfirm = () => { }, [availableTicketTotal, editingOrder?.totalNum, editingOrder?.userTicketId, goods?.stock, isEditMode, tickets]) const canStartOrder = useMemo(() => { - return maxQuantity >= MIN_START_QTY - }, [maxQuantity]) + return maxQuantity >= minStartQty + }, [maxQuantity, minStartQty]) const displayQty = useMemo(() => { if (!canStartOrder) return 0 - return Math.max(MIN_START_QTY, Math.min(quantity, maxQuantity)) - }, [quantity, maxQuantity, canStartOrder]) + return Math.max(minStartQty, Math.min(quantity, maxQuantity)) + }, [quantity, maxQuantity, canStartOrder, minStartQty]) const sendTimeText = useMemo(() => { return dayjs(sendTime).format('YYYY-MM-DD') @@ -600,7 +602,7 @@ const OrderConfirm = () => { setQuantity(0) return } - setQuantity(Math.max(MIN_START_QTY, Math.min(newQuantity || MIN_START_QTY, upper))) + setQuantity(Math.max(minStartQty, Math.min(newQuantity || minStartQty, upper))) } const loadUserTickets = async () => { @@ -718,8 +720,8 @@ const OrderConfirm = () => { Taro.showToast({ title: '商品库存不足', icon: 'none' }) return } - if (finalQty < MIN_START_QTY) { - Taro.showToast({ title: `最低起送 ${MIN_START_QTY} 桶`, icon: 'none' }) + if (finalQty < minStartQty) { + Taro.showToast({ title: `最低起送 ${minStartQty} 桶`, icon: 'none' }) return } if (!sendTime) { @@ -863,8 +865,8 @@ const OrderConfirm = () => { return } - const initQty = Number(editingOrderRes.totalNum ?? MIN_START_QTY) - setQuantity(Number.isFinite(initQty) && initQty > 0 ? initQty : MIN_START_QTY) + const initQty = Number(editingOrderRes.totalNum ?? minStartQty) + setQuantity(Number.isFinite(initQty) && initQty > 0 ? initQty : minStartQty) setOrderRemark(String(editingOrderRes.buyerRemarks || '')) const st = parseTime(editingOrderRes.sendTime) if (st) setSendTime(st.startOf('day').toDate()) @@ -1000,11 +1002,54 @@ const OrderConfirm = () => { useEffect(() => { setQuantity(prev => { if (maxQuantity <= 0) return 0 - if (maxQuantity < MIN_START_QTY) return 0 - if (!prev || prev < MIN_START_QTY) return MIN_START_QTY + if (maxQuantity < minStartQty) return 0 + if (!prev || prev < minStartQty) return minStartQty return Math.min(prev, maxQuantity) }) - }, [maxQuantity]) + }, [maxQuantity, minStartQty]) + + const minStartQtyKey = useMemo(() => { + const gid = Number(goods?.goodsId) + if (Number.isFinite(gid) && gid > 0) return `g:${gid}` + + // If there is exactly one ticket template available, infer min start qty from it (covers "稍后再送" without goodsId). + const ids = Array.from( + new Set( + (usableTickets || []) + .map(t => Number(t?.templateId)) + .filter(id => Number.isFinite(id) && id > 0) + ) + ) + if (ids.length === 1) return `t:${ids[0]}` + return '' + }, [goods?.goodsId, usableTickets]) + + // Use configured min start-send qty from ticket template (by goodsId or by user's unique templateId). + useEffect(() => { + let cancelled = false + ;(async () => { + try { + if (!minStartQtyKey) { + setMinStartQty(DEFAULT_MIN_START_QTY) + return + } + const [kind, rawId] = minStartQtyKey.split(':') + const id = Number(rawId) + const tpl = + kind === 'g' + ? await getGltTicketTemplateByGoodsId(id) + : await getGltTicketTemplate(id) + const n = Number(tpl?.startSendQty) + const safe = Number.isFinite(n) && n > 0 ? n : DEFAULT_MIN_START_QTY + if (!cancelled) setMinStartQty(safe) + } catch (_e) { + if (!cancelled) setMinStartQty(DEFAULT_MIN_START_QTY) + } + })() + return () => { + cancelled = true + } + }, [minStartQtyKey]) // If user has no usable tickets, proactively guide them to purchase (only once per page lifecycle). useEffect(() => { @@ -1138,16 +1183,16 @@ const OrderConfirm = () => { title={'送水数量'} description={ canStartOrder - ? `最低起送 ${MIN_START_QTY} 桶` - : `最低起送 ${MIN_START_QTY} 桶(当前最多 ${maxQuantity} 桶)` + ? `最低起送 ${minStartQty} 桶` + : `最低起送 ${minStartQty} 桶(当前最多 ${maxQuantity} 桶)` } extra={( = 10 ? 10 : 1} readOnly disabled={!canStartOrder} onChange={handleQuantityChange}