mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-09-24 16:05:44 +08:00
fix(payment): collapsible limits, reject <=0, hint uses global config
- Limits section collapsible (default collapsed, auto-expand if has values) - Empty input = use global config; reject values <= 0 - Input min changed from 0 to 1, placeholder changed to empty - Hint: "留空表示使用全局配置"
This commit is contained in:
@@ -118,12 +118,15 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Per-type limits -->
|
||||
<!-- Per-type limits (collapsible) -->
|
||||
<div v-if="limitableTypes.length" class="border-t border-gray-200 pt-4 dark:border-dark-700">
|
||||
<h4 class="mb-3 text-sm font-semibold text-gray-900 dark:text-white">
|
||||
{{ t('admin.settings.payment.limitsTitle') }}
|
||||
</h4>
|
||||
<div class="space-y-3">
|
||||
<button type="button" @click="limitsExpanded = !limitsExpanded" class="flex w-full items-center justify-between">
|
||||
<h4 class="text-sm font-semibold text-gray-900 dark:text-white">
|
||||
{{ t('admin.settings.payment.limitsTitle') }}
|
||||
</h4>
|
||||
<svg :class="['h-4 w-4 text-gray-400 transition-transform', limitsExpanded && 'rotate-180']" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" /></svg>
|
||||
</button>
|
||||
<div v-show="limitsExpanded" class="mt-3 space-y-3">
|
||||
<div
|
||||
v-for="lt in limitableTypes"
|
||||
:key="lt.value"
|
||||
@@ -137,7 +140,7 @@
|
||||
type="number"
|
||||
:value="getLimitVal(lt.value, 'singleMin')"
|
||||
@input="setLimitVal(lt.value, 'singleMin', ($event.target as HTMLInputElement).value)"
|
||||
class="input mt-0.5" min="0" step="0.01" placeholder="0"
|
||||
class="input mt-0.5" min="1" step="0.01" placeholder=""
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
@@ -146,7 +149,7 @@
|
||||
type="number"
|
||||
:value="getLimitVal(lt.value, 'singleMax')"
|
||||
@input="setLimitVal(lt.value, 'singleMax', ($event.target as HTMLInputElement).value)"
|
||||
class="input mt-0.5" min="0" step="0.01" placeholder="0"
|
||||
class="input mt-0.5" min="1" step="0.01" placeholder=""
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
@@ -155,13 +158,13 @@
|
||||
type="number"
|
||||
:value="getLimitVal(lt.value, 'dailyLimit')"
|
||||
@input="setLimitVal(lt.value, 'dailyLimit', ($event.target as HTMLInputElement).value)"
|
||||
class="input mt-0.5" min="0" step="0.01" placeholder="0"
|
||||
class="input mt-0.5" min="1" step="0.01" placeholder=""
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-xs text-gray-400 dark:text-gray-500">{{ t('admin.settings.payment.limitsHint') }}</p>
|
||||
</div>
|
||||
<p class="mt-2 text-xs text-gray-400 dark:text-gray-500">{{ t('admin.settings.payment.limitsHint') }}</p>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -229,6 +232,7 @@ const form = reactive({
|
||||
const config = reactive<Record<string, string>>({})
|
||||
const limits = reactive<Record<string, Record<string, number>>>({})
|
||||
const callbackBaseUrl = ref('')
|
||||
const limitsExpanded = ref(false)
|
||||
|
||||
// --- Computed ---
|
||||
const defaultBaseUrl = typeof window !== 'undefined' ? window.location.origin : ''
|
||||
@@ -281,6 +285,7 @@ function clearConfig() {
|
||||
Object.keys(config).forEach(k => delete config[k])
|
||||
Object.keys(limits).forEach(k => delete limits[k])
|
||||
callbackBaseUrl.value = ''
|
||||
limitsExpanded.value = false
|
||||
}
|
||||
|
||||
function applyDefaults() {
|
||||
@@ -296,7 +301,14 @@ function getLimitVal(paymentType: string, field: string): string {
|
||||
|
||||
function setLimitVal(paymentType: string, field: string, val: string) {
|
||||
if (!limits[paymentType]) limits[paymentType] = {}
|
||||
limits[paymentType][field] = Number(val) || 0
|
||||
const num = Number(val)
|
||||
// Empty → clear the field (use global); reject ≤0
|
||||
if (val === '' || isNaN(num)) {
|
||||
delete limits[paymentType][field]
|
||||
return
|
||||
}
|
||||
if (num <= 0) return
|
||||
limits[paymentType][field] = num
|
||||
}
|
||||
|
||||
function serializeLimits(): string {
|
||||
@@ -404,6 +416,7 @@ function loadProvider(provider: ProviderInstance) {
|
||||
for (const [pt, fields] of Object.entries(parsed as Record<string, Record<string, number>>)) {
|
||||
limits[pt] = { ...fields }
|
||||
}
|
||||
limitsExpanded.value = Object.keys(limits).length > 0
|
||||
} catch { /* ignore */ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4381,7 +4381,7 @@ export default {
|
||||
limitSingleMin: 'Min per order',
|
||||
limitSingleMax: 'Max per order',
|
||||
limitDaily: 'Daily limit',
|
||||
limitsHint: 'Leave empty or 0 for no limit',
|
||||
limitsHint: 'Leave empty to use global settings',
|
||||
productNamePrefix: 'Product Name Prefix',
|
||||
productNameSuffix: 'Product Name Suffix',
|
||||
preview: 'Preview',
|
||||
|
||||
@@ -4554,7 +4554,7 @@ export default {
|
||||
limitSingleMin: '单笔最低',
|
||||
limitSingleMax: '单笔最高',
|
||||
limitDaily: '每日限额',
|
||||
limitsHint: '留空或填 0 表示不限制',
|
||||
limitsHint: '留空表示使用全局配置',
|
||||
productNamePrefix: '商品名前缀',
|
||||
productNameSuffix: '商品名后缀',
|
||||
preview: '预览',
|
||||
|
||||
Reference in New Issue
Block a user