用户端调整

2.首页商品详情增加点击区域
3.浓香型 酱香型 点击增加提示:暂未开放
5.首页餐券2字更换为“好客权益”
6.门店页面地址筛选功能 (三级菜单,省市区)
7.好客权益:去使用点击交互调整为核销页面,单张好客权益点击核销页面带参数和金额
7.核销金额限制为可用余额最大数,不是500
9.收货地址电话号码增加校验,长度限制,地址或者未填提示,地区调整为省市区三级菜单
10.微信授权位置调整在手机验证码下侧
This commit is contained in:
2026-07-01 00:19:08 +08:00
parent 6e047dc0a5
commit c43defca3f
18 changed files with 772 additions and 190 deletions
+4 -4
View File
@@ -31,9 +31,9 @@ describe('validateMinPurchase', () => {
});
describe('validateRedeemAmount', () => {
it('rejects over balance or 500', () => {
it('rejects over balance or non-positive', () => {
expect(validateRedeemAmount(100, 50).ok).toBe(true);
expect(validateRedeemAmount(100, 501).ok).toBe(false);
expect(validateRedeemAmount(100, 100).ok).toBe(true);
expect(validateRedeemAmount(50, 60).ok).toBe(false);
expect(validateRedeemAmount(100, 0).ok).toBe(false);
});
@@ -68,10 +68,10 @@ describe('allocateBenefitCoupons', () => {
});
describe('calcBenefitSummary', () => {
it('caps max redeem by total and limit', () => {
it('max redeem equals total balance', () => {
expect(calcBenefitSummary([300, 400])).toEqual({
totalBalance: 700,
maxRedeemAmount: 500,
maxRedeemAmount: 700,
activeCouponCount: 2,
});
expect(calcBenefitSummary([100])).toEqual({
+2 -6
View File
@@ -29,11 +29,9 @@ export function validateMinPurchase(
export function validateRedeemAmount(
balance: number,
amount: number,
maxAmount = 500,
): { ok: boolean; message?: string } {
if (amount <= 0) return { ok: false, message: '核销金额必须大于 0' };
if (amount > balance) return { ok: false, message: '核销金额不能超过可用余额' };
if (amount > maxAmount) return { ok: false, message: `单次核销不能超过 ¥${maxAmount}` };
return { ok: true };
}
@@ -47,13 +45,12 @@ export interface BenefitCouponBalance {
export function allocateBenefitCoupons(
coupons: BenefitCouponBalance[],
amount: number,
maxAmount = 500,
): { ok: true; allocations: Array<{ couponId: string; amount: number }> } | { ok: false; message: string } {
const active = coupons
.filter((c) => c.balance > 0)
.sort((a, b) => a.createdAt - b.createdAt);
const totalBalance = active.reduce((sum, c) => sum + c.balance, 0);
const check = validateRedeemAmount(totalBalance, amount, maxAmount);
const check = validateRedeemAmount(totalBalance, amount);
if (!check.ok) return { ok: false, message: check.message! };
let remaining = amount;
@@ -74,12 +71,11 @@ export function allocateBenefitCoupons(
export function calcBenefitSummary(
balances: number[],
maxAmount = 500,
): { totalBalance: number; maxRedeemAmount: number; activeCouponCount: number } {
const totalBalance = Math.round(balances.reduce((sum, b) => sum + b, 0) * 100) / 100;
return {
totalBalance,
maxRedeemAmount: Math.min(maxAmount, totalBalance),
maxRedeemAmount: totalBalance,
activeCouponCount: balances.length,
};
}
+4 -2
View File
@@ -1,12 +1,14 @@
type CouponBadgeProps = {
amount: number | string;
className?: string;
/** 权益标签文案,默认「餐券」;首页使用「好客权益」 */
label?: string;
};
export default function CouponBadge({ amount, className = '' }: CouponBadgeProps) {
export default function CouponBadge({ amount, className = '', label = '餐券' }: CouponBadgeProps) {
return (
<span className={`coupon-badge ${className}`.trim()}>
¥{amount}
¥{amount}{label}
</span>
);
}