diff --git a/backend/cmd/server/VERSION b/backend/cmd/server/VERSION index d2ddc9d46a..d8250c3818 100644 --- a/backend/cmd/server/VERSION +++ b/backend/cmd/server/VERSION @@ -1 +1 @@ -0.1.108.44 +0.1.108.45 diff --git a/frontend/src/components/payment/AmountInput.vue b/frontend/src/components/payment/AmountInput.vue index 0b0f0e8886..dbbc6935eb 100644 --- a/frontend/src/components/payment/AmountInput.vue +++ b/frontend/src/components/payment/AmountInput.vue @@ -36,7 +36,7 @@ type="text" inputmode="decimal" :value="customText" - :placeholder="`${min} - ${max}`" + :placeholder="placeholderText" class="input w-full py-3 pl-8 pr-4" @input="handleInput" /> @@ -56,8 +56,8 @@ const props = withDefaults(defineProps<{ max?: number }>(), { amounts: () => [10, 50, 100, 200, 500, 1000], - min: 1, - max: 10000, + min: 0, + max: 0, }) const emit = defineEmits<{ @@ -68,10 +68,18 @@ const { t } = useI18n() const customText = ref('') +// 0 = no limit const filteredAmounts = computed(() => - props.amounts.filter((a) => a >= props.min && a <= props.max) + props.amounts.filter((a) => (props.min <= 0 || a >= props.min) && (props.max <= 0 || a <= props.max)) ) +const placeholderText = computed(() => { + if (props.min > 0 && props.max > 0) return `${props.min} - ${props.max}` + if (props.min > 0) return `≥ ${props.min}` + if (props.max > 0) return `≤ ${props.max}` + return t('payment.enterAmount', '输入金额') +}) + const AMOUNT_PATTERN = /^\d*(\.\d{0,2})?$/ function selectAmount(amt: number) { diff --git a/frontend/src/i18n/locales/en.ts b/frontend/src/i18n/locales/en.ts index 3d04c8f695..ae02561941 100644 --- a/frontend/src/i18n/locales/en.ts +++ b/frontend/src/i18n/locales/en.ts @@ -5050,6 +5050,7 @@ export default { amountLabel: 'Amount', quickAmounts: 'Quick Amounts', customAmount: 'Custom Amount', + enterAmount: 'Enter amount', paymentMethod: 'Payment Method', fee: 'Fee', actualPay: 'Actual Payment', diff --git a/frontend/src/i18n/locales/zh.ts b/frontend/src/i18n/locales/zh.ts index 2a84cec10b..d186a5228b 100644 --- a/frontend/src/i18n/locales/zh.ts +++ b/frontend/src/i18n/locales/zh.ts @@ -5247,6 +5247,7 @@ export default { amountLabel: '充值金额', quickAmounts: '快捷金额', customAmount: '自定义金额', + enterAmount: '输入金额', paymentMethod: '支付方式', fee: '手续费', actualPay: '实付金额', diff --git a/frontend/src/views/user/PaymentView.vue b/frontend/src/views/user/PaymentView.vue index 35d502b8a5..8b04a2d0eb 100644 --- a/frontend/src/views/user/PaymentView.vue +++ b/frontend/src/views/user/PaymentView.vue @@ -151,15 +151,16 @@ const tabs = computed(() => { }) const enabledMethods = computed(() => config.value?.enabled_payment_types ?? []) +// 0 = no limit; provider-level overrides global const minAmount = computed(() => { const limit = methodLimits.value[selectedMethod.value] if (limit?.single_min && limit.single_min > 0) return limit.single_min - return config.value?.min_amount && config.value.min_amount > 0 ? config.value.min_amount : 1 + return config.value?.min_amount && config.value.min_amount > 0 ? config.value.min_amount : 0 }) const maxAmount = computed(() => { const limit = methodLimits.value[selectedMethod.value] if (limit?.single_max && limit.single_max > 0) return limit.single_max - return config.value?.max_amount && config.value.max_amount > 0 ? config.value.max_amount : 99999999 + return config.value?.max_amount && config.value.max_amount > 0 ? config.value.max_amount : 0 }) const methodOptions = computed(() => @@ -184,14 +185,17 @@ const totalAmount = computed(() => const amountError = computed(() => { if (validAmount.value <= 0) return '' - if (validAmount.value < minAmount.value) return t('payment.amountTooLow', { min: minAmount.value }) - if (validAmount.value > maxAmount.value) return t('payment.amountTooHigh', { max: maxAmount.value }) + if (minAmount.value > 0 && validAmount.value < minAmount.value) return t('payment.amountTooLow', { min: minAmount.value }) + if (maxAmount.value > 0 && validAmount.value > maxAmount.value) return t('payment.amountTooHigh', { max: maxAmount.value }) return '' }) const canSubmit = computed(() => { const limitInfo = methodLimits.value[selectedMethod.value] - return validAmount.value >= minAmount.value && validAmount.value <= maxAmount.value && limitInfo?.available !== false + if (validAmount.value <= 0) return false + if (minAmount.value > 0 && validAmount.value < minAmount.value) return false + if (maxAmount.value > 0 && validAmount.value > maxAmount.value) return false + return limitInfo?.available !== false }) function openSubscribeDialog(plan: SubscriptionPlan) {