mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-09-24 16:05:44 +08:00
Polish EasyPay custom method UI
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" role="img" aria-label="Payment">
|
||||
<path d="M512 64c247.424 0 448 200.576 448 448S759.424 960 512 960 64 759.424 64 512 264.576 64 512 64Z" fill="#4F46E5"/>
|
||||
<path d="M307 329c0-39.765 32.235-72 72-72h274c39.765 0 72 32.235 72 72v36H371c-35.346 0-64 28.654-64 64V329Z" fill="#C7D2FE"/>
|
||||
<path d="M260 413c0-35.346 28.654-64 64-64h392c35.346 0 64 28.654 64 64v258c0 35.346-28.654 64-64 64H324c-35.346 0-64-28.654-64-64V413Z" fill="#FFFFFF"/>
|
||||
<path d="M636 481c0-30.928 25.072-56 56-56h88v214h-88c-30.928 0-56-25.072-56-56V481Z" fill="#EEF2FF"/>
|
||||
<path d="M708 494c30.928 0 56 25.072 56 56s-25.072 56-56 56-56-25.072-56-56 25.072-56 56-56Z" fill="#FBBF24"/>
|
||||
<path d="M348 457c0-17.673 14.327-32 32-32h172c17.673 0 32 14.327 32 32s-14.327 32-32 32H380c-17.673 0-32-14.327-32-32Z" fill="#4F46E5"/>
|
||||
<path d="M348 557c0-15.464 12.536-28 28-28h152c15.464 0 28 12.536 28 28s-12.536 28-28 28H376c-15.464 0-28-12.536-28-28Z" fill="#A5B4FC"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1012 B |
@@ -44,6 +44,7 @@ import alipayIcon from '@/assets/icons/alipay.svg'
|
||||
import wxpayIcon from '@/assets/icons/wxpay.svg'
|
||||
import stripeIcon from '@/assets/icons/stripe.svg'
|
||||
import airwallexIcon from '@/assets/icons/airwallex.svg'
|
||||
import paymentIcon from '@/assets/icons/payment.svg'
|
||||
|
||||
export interface PaymentMethodOption {
|
||||
type: string
|
||||
@@ -68,6 +69,7 @@ const METHOD_ICONS: Record<string, string> = {
|
||||
wxpay: wxpayIcon,
|
||||
stripe: stripeIcon,
|
||||
airwallex: airwallexIcon,
|
||||
credit_card: paymentIcon,
|
||||
}
|
||||
|
||||
const sortedMethods = computed(() => {
|
||||
@@ -83,7 +85,7 @@ function methodIcon(type: string): string {
|
||||
if (type.includes('alipay')) return METHOD_ICONS.alipay
|
||||
if (type.includes('wxpay')) return METHOD_ICONS.wxpay
|
||||
if (type === 'airwallex') return METHOD_ICONS.airwallex
|
||||
return METHOD_ICONS[type] || stripeIcon
|
||||
return METHOD_ICONS[type] || paymentIcon
|
||||
}
|
||||
|
||||
function methodLabel(method: PaymentMethodOption): string {
|
||||
|
||||
@@ -70,6 +70,49 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="form.provider_key === 'easypay'" class="space-y-3 rounded-lg border border-gray-100 p-3 dark:border-dark-700">
|
||||
<div class="flex items-center justify-between gap-3">
|
||||
<div>
|
||||
<h5 class="text-sm font-medium text-gray-900 dark:text-white">
|
||||
{{ t('admin.settings.payment.easypayCustomMethods') }}
|
||||
</h5>
|
||||
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">
|
||||
{{ t('admin.settings.payment.easypayCustomMethodsHint') }}
|
||||
</p>
|
||||
</div>
|
||||
<button type="button" class="btn btn-secondary btn-sm" @click="addEasyPayCustomMethod">
|
||||
{{ t('admin.settings.payment.addCustomMethod') }}
|
||||
</button>
|
||||
</div>
|
||||
<div v-if="easyPayCustomMethods.length" class="space-y-2">
|
||||
<div
|
||||
v-for="(method, index) in easyPayCustomMethods"
|
||||
:key="index"
|
||||
class="grid grid-cols-[1fr_1fr_1fr_auto] items-end gap-2"
|
||||
>
|
||||
<div>
|
||||
<label class="text-xs text-gray-500 dark:text-gray-400">{{ t('admin.settings.payment.customMethodType') }}</label>
|
||||
<input v-model="method.type" type="text" class="input mt-0.5" placeholder="credit_card" />
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-xs text-gray-500 dark:text-gray-400">{{ t('admin.settings.payment.customMethodUpstreamType') }}</label>
|
||||
<input v-model="method.upstreamType" type="text" class="input mt-0.5" placeholder="credit_card" />
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-xs text-gray-500 dark:text-gray-400">{{ t('admin.settings.payment.customMethodDisplayName') }}</label>
|
||||
<input v-model="method.displayName" type="text" class="input mt-0.5" placeholder="信用卡" />
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
class="rounded-lg border border-red-200 px-2.5 py-2 text-xs font-medium text-red-600 transition-colors hover:bg-red-50 dark:border-red-800/60 dark:text-red-300 dark:hover:bg-red-900/20"
|
||||
@click="removeEasyPayCustomMethod(index)"
|
||||
>
|
||||
{{ t('common.delete') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Config fields -->
|
||||
<div class="border-t border-gray-200 pt-4 dark:border-dark-700">
|
||||
@@ -168,49 +211,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="form.provider_key === 'easypay'" class="mt-4 space-y-3 rounded-lg border border-gray-100 p-3 dark:border-dark-700">
|
||||
<div class="flex items-center justify-between gap-3">
|
||||
<div>
|
||||
<h5 class="text-sm font-medium text-gray-900 dark:text-white">
|
||||
{{ t('admin.settings.payment.easypayCustomMethods') }}
|
||||
</h5>
|
||||
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">
|
||||
{{ t('admin.settings.payment.easypayCustomMethodsHint') }}
|
||||
</p>
|
||||
</div>
|
||||
<button type="button" class="btn btn-secondary btn-sm" @click="addEasyPayCustomMethod">
|
||||
{{ t('admin.settings.payment.addCustomMethod') }}
|
||||
</button>
|
||||
</div>
|
||||
<div v-if="easyPayCustomMethods.length" class="space-y-2">
|
||||
<div
|
||||
v-for="(method, index) in easyPayCustomMethods"
|
||||
:key="index"
|
||||
class="grid grid-cols-[1fr_1fr_1fr_auto] items-end gap-2"
|
||||
>
|
||||
<div>
|
||||
<label class="text-xs text-gray-500 dark:text-gray-400">{{ t('admin.settings.payment.customMethodType') }}</label>
|
||||
<input v-model="method.type" type="text" class="input mt-0.5" placeholder="ldc" />
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-xs text-gray-500 dark:text-gray-400">{{ t('admin.settings.payment.customMethodUpstreamType') }}</label>
|
||||
<input v-model="method.upstreamType" type="text" class="input mt-0.5" placeholder="epay" />
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-xs text-gray-500 dark:text-gray-400">{{ t('admin.settings.payment.customMethodDisplayName') }}</label>
|
||||
<input v-model="method.displayName" type="text" class="input mt-0.5" placeholder="LDC" />
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
class="rounded-lg border border-red-200 px-2.5 py-2 text-xs font-medium text-red-600 transition-colors hover:bg-red-50 dark:border-red-800/60 dark:text-red-300 dark:hover:bg-red-900/20"
|
||||
@click="removeEasyPayCustomMethod(index)"
|
||||
>
|
||||
{{ t('common.delete') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Callback URLs (each = editable URL + fixed path) -->
|
||||
<div v-if="callbackPaths" class="mt-4 space-y-3">
|
||||
<div v-if="callbackPaths.notifyUrl">
|
||||
|
||||
@@ -187,9 +187,10 @@ describe('PaymentProviderDialog payment guide', () => {
|
||||
await nextTick()
|
||||
|
||||
const inputs = wrapper.findAll('input[type="text"]')
|
||||
const ldcTypeInput = inputs.find(input => (input.element as HTMLInputElement).placeholder === 'ldc')
|
||||
const upstreamTypeInput = inputs.find(input => (input.element as HTMLInputElement).placeholder === 'epay')
|
||||
const displayNameInput = inputs.find(input => (input.element as HTMLInputElement).placeholder === 'LDC')
|
||||
const customTypeInputs = inputs.filter(input => (input.element as HTMLInputElement).placeholder === 'credit_card')
|
||||
const ldcTypeInput = customTypeInputs[0]
|
||||
const upstreamTypeInput = customTypeInputs[1]
|
||||
const displayNameInput = inputs.find(input => (input.element as HTMLInputElement).placeholder === '信用卡')
|
||||
if (!ldcTypeInput || !upstreamTypeInput || !displayNameInput) {
|
||||
throw new Error('custom method inputs not found')
|
||||
}
|
||||
@@ -229,9 +230,10 @@ describe('PaymentProviderDialog payment guide', () => {
|
||||
await nextTick()
|
||||
|
||||
const inputs = wrapper.findAll('input[type="text"]')
|
||||
const typeInput = inputs.find(input => (input.element as HTMLInputElement).placeholder === 'ldc')
|
||||
const upstreamTypeInput = inputs.find(input => (input.element as HTMLInputElement).placeholder === 'epay')
|
||||
const displayNameInput = inputs.find(input => (input.element as HTMLInputElement).placeholder === 'LDC')
|
||||
const customTypeInputs = inputs.filter(input => (input.element as HTMLInputElement).placeholder === 'credit_card')
|
||||
const typeInput = customTypeInputs[0]
|
||||
const upstreamTypeInput = customTypeInputs[1]
|
||||
const displayNameInput = inputs.find(input => (input.element as HTMLInputElement).placeholder === '信用卡')
|
||||
if (!typeInput || !upstreamTypeInput || !displayNameInput) {
|
||||
throw new Error('custom method inputs not found')
|
||||
}
|
||||
|
||||
@@ -6422,8 +6422,8 @@ export default {
|
||||
field_cid: '支付渠道 ID',
|
||||
field_cidAlipay: '支付宝渠道 ID',
|
||||
field_cidWxpay: '微信渠道 ID',
|
||||
easypayCustomMethods: '易支付自定义方式',
|
||||
easypayCustomMethodsHint: '添加当前易支付接口额外支持的方式。支付方式会记录到 Sub2API 订单中,上游 type 会作为易支付 type 参数提交。',
|
||||
easypayCustomMethods: '易支付自定义支付方式',
|
||||
easypayCustomMethodsHint: '添加当前易支付服务商额外支持的支付方式。支付方式会记录到 Sub2API 订单中,上游 type 会作为易支付 type 参数提交。',
|
||||
addCustomMethod: '添加方式',
|
||||
customMethodType: '支付方式',
|
||||
customMethodUpstreamType: '上游 type',
|
||||
|
||||
Reference in New Issue
Block a user