小程序端核销权益券金额输入限制
CI / verify (pull_request) Has been cancelled

现场取货功能
This commit is contained in:
2026-07-23 00:03:21 +08:00
parent cd206d6baa
commit 0418370c31
5 changed files with 213 additions and 19 deletions
+27 -10
View File
@@ -17,17 +17,29 @@ function formatMoney(amount: number) {
return amount.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
}
/** 核销金额输入:最多两位小数禁止非法字符 */
/** 核销金额输入:最多两位小数;去掉前导 0禁止非法字符 */
function sanitizeRedeemAmountInput(raw: string): string {
let next = raw.replace(/[^\d.]/g, '');
let next = String(raw ?? '').replace(/[^\d.]/g, '');
if (!next) return '';
const firstDot = next.indexOf('.');
if (firstDot >= 0) {
next =
next.slice(0, firstDot + 1) + next.slice(firstDot + 1).replace(/\./g, '');
const [intPart, decPart = ''] = next.split('.');
next = `${intPart}.${decPart.slice(0, 2)}`;
const intRaw = next.slice(0, firstDot).replace(/\D/g, '');
const decRaw = next
.slice(firstDot + 1)
.replace(/\D/g, '')
.replace(/\./g, '')
.slice(0, 2);
const intPart = intRaw.replace(/^0+(?=\d)/, '') || '0';
// 正在输入小数点或小数位时保留点
if (decRaw.length > 0 || next.endsWith('.')) {
return `${intPart}.${decRaw}`;
}
return intPart;
}
if (next.startsWith('.')) next = `0${next}`;
// 纯整数:忽略前导 0(保留单个 0)
next = next.replace(/^0+(?=\d)/, '');
return next;
}
@@ -37,7 +49,7 @@ export default function RedeemPage() {
const initialAmount = router.params.amount ?? '';
const [balance, setBalance] = useState(0);
const [couponBalance, setCouponBalance] = useState<number | null>(null);
const [amount, setAmount] = useState(initialAmount);
const [amount, setAmount] = useState(() => sanitizeRedeemAmountInput(initialAmount));
const [loading, setLoading] = useState(false);
const redeemableMax = couponId ? (couponBalance ?? 0) : balance;
@@ -67,7 +79,11 @@ export default function RedeemPage() {
function fillMaxAmount() {
if (redeemableMax < MIN_REDEEM_AMOUNT) return;
setAmount(String(redeemableMax));
setAmount(sanitizeRedeemAmountInput(redeemableMax.toFixed(2)));
}
function onAmountChange(raw: string) {
setAmount(sanitizeRedeemAmountInput(raw));
}
async function submit() {
@@ -119,7 +135,8 @@ export default function RedeemPage() {
placeholder="输入核销金额"
placeholderClass="redeem-input-placeholder"
value={amount}
onInput={(e) => setAmount(sanitizeRedeemAmountInput(e.detail.value))}
onInput={(e) => onAmountChange(e.detail.value)}
onBlur={(e) => onAmountChange(e.detail.value)}
style={{ textAlign: 'center' }}
/>
</View>