feat(admin): add compact proxy IP resource link

Add a low-visibility proxy IP resource link near proxy-related controls.

- Show the link beside account proxy selectors

- Show the link in the create proxy dialog tab row

- Keep the entry inline to avoid interrupting form workflows
This commit is contained in:
shaw 2026-05-23 14:17:08 +08:00
parent 3c5a444802
commit 0430899748
6 changed files with 78 additions and 40 deletions

View File

@ -2439,7 +2439,10 @@
</div>
<div>
<label class="input-label">{{ t('admin.accounts.proxy') }}</label>
<div class="mb-1 flex items-center gap-2">
<label class="input-label mb-0">{{ t('admin.accounts.proxy') }}</label>
<ProxyAdBanner />
</div>
<ProxySelector v-model="form.proxy_id" :proxies="proxies" />
</div>
@ -3152,6 +3155,7 @@ import ConfirmDialog from '@/components/common/ConfirmDialog.vue'
import Select from '@/components/common/Select.vue'
import Icon from '@/components/icons/Icon.vue'
import ProxySelector from '@/components/common/ProxySelector.vue'
import ProxyAdBanner from '@/components/common/ProxyAdBanner.vue'
import GroupSelector from '@/components/common/GroupSelector.vue'
import ModelWhitelistSelector from '@/components/account/ModelWhitelistSelector.vue'
import QuotaLimitCard from '@/components/account/QuotaLimitCard.vue'

View File

@ -1258,7 +1258,10 @@
</div>
<div>
<label class="input-label">{{ t('admin.accounts.proxy') }}</label>
<div class="mb-1 flex items-center gap-2">
<label class="input-label mb-0">{{ t('admin.accounts.proxy') }}</label>
<ProxyAdBanner />
</div>
<ProxySelector v-model="form.proxy_id" :proxies="proxies" />
</div>
@ -2224,6 +2227,7 @@ import ConfirmDialog from '@/components/common/ConfirmDialog.vue'
import Select from '@/components/common/Select.vue'
import Icon from '@/components/icons/Icon.vue'
import ProxySelector from '@/components/common/ProxySelector.vue'
import ProxyAdBanner from '@/components/common/ProxyAdBanner.vue'
import GroupSelector from '@/components/common/GroupSelector.vue'
import ModelWhitelistSelector from '@/components/account/ModelWhitelistSelector.vue'
import QuotaLimitCard from '@/components/account/QuotaLimitCard.vue'

View File

@ -0,0 +1,18 @@
<template>
<a
class="inline-flex max-w-full shrink-0 items-center gap-1 truncate text-xs font-normal text-primary-600 transition-colors hover:underline focus:outline-none focus:ring-2 focus:ring-primary-400 focus:ring-offset-2 dark:text-primary-400 dark:focus:ring-offset-dark-800"
href="https://bestproxy.com/?keyword=a2e8iuol"
target="_blank"
rel="noopener noreferrer"
>
<span class="truncate">{{ t('admin.proxies.ad.inline') }}</span>
<Icon name="externalLink" size="xs" />
</a>
</template>
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import Icon from '@/components/icons/Icon.vue'
const { t } = useI18n()
</script>

View File

@ -4002,6 +4002,9 @@ export default {
createProxy: 'Create Proxy',
editProxy: 'Edit Proxy',
deleteProxy: 'Delete Proxy',
ad: {
inline: 'Need proxy IP?'
},
dataImport: 'Import',
dataExportSelected: 'Export Selected',
dataImportTitle: 'Import Proxies',

View File

@ -4097,6 +4097,9 @@ export default {
createProxy: '添加代理',
editProxy: '编辑代理',
deleteProxy: '删除代理',
ad: {
inline: '正在寻找合适的代理 IP'
},
deleteConfirmMessage: "确定要删除代理 '{name}' 吗?",
testProxy: '测试代理',
dataImport: '导入',

View File

@ -357,45 +357,50 @@
@close="closeCreateModal"
>
<!-- Tab Switch -->
<div class="mb-6 flex border-b border-gray-200 dark:border-dark-600">
<button
type="button"
@click="createMode = 'standard'"
:class="[
'-mb-px border-b-2 px-4 py-2 text-sm font-medium transition-colors',
createMode === 'standard'
? 'border-primary-500 text-primary-600 dark:text-primary-400'
: 'border-transparent text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300'
]"
>
<Icon name="plus" size="sm" class="mr-1.5 inline" />
{{ t('admin.proxies.standardAdd') }}
</button>
<button
type="button"
@click="createMode = 'batch'"
:class="[
'-mb-px border-b-2 px-4 py-2 text-sm font-medium transition-colors',
createMode === 'batch'
? 'border-primary-500 text-primary-600 dark:text-primary-400'
: 'border-transparent text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300'
]"
>
<svg
class="mr-1.5 inline h-4 w-4"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
stroke-width="1.5"
<div
class="mb-6 flex items-center justify-between gap-3 border-b border-gray-200 dark:border-dark-600"
>
<div class="flex min-w-0 shrink-0">
<button
type="button"
@click="createMode = 'standard'"
:class="[
'-mb-px border-b-2 px-4 py-2 text-sm font-medium transition-colors',
createMode === 'standard'
? 'border-primary-500 text-primary-600 dark:text-primary-400'
: 'border-transparent text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300'
]"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M3.75 12h16.5m-16.5 3.75h16.5M3.75 19.5h16.5M5.625 4.5h12.75a1.875 1.875 0 010 3.75H5.625a1.875 1.875 0 010-3.75z"
/>
</svg>
{{ t('admin.proxies.batchAdd') }}
</button>
<Icon name="plus" size="sm" class="mr-1.5 inline" />
{{ t('admin.proxies.standardAdd') }}
</button>
<button
type="button"
@click="createMode = 'batch'"
:class="[
'-mb-px border-b-2 px-4 py-2 text-sm font-medium transition-colors',
createMode === 'batch'
? 'border-primary-500 text-primary-600 dark:text-primary-400'
: 'border-transparent text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300'
]"
>
<svg
class="mr-1.5 inline h-4 w-4"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
stroke-width="1.5"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M3.75 12h16.5m-16.5 3.75h16.5M3.75 19.5h16.5M5.625 4.5h12.75a1.875 1.875 0 010 3.75H5.625a1.875 1.875 0 010-3.75z"
/>
</svg>
{{ t('admin.proxies.batchAdd') }}
</button>
</div>
<ProxyAdBanner />
</div>
<!-- Standard Add Form -->
@ -887,6 +892,7 @@ import ConfirmDialog from '@/components/common/ConfirmDialog.vue'
import EmptyState from '@/components/common/EmptyState.vue'
import ImportDataModal from '@/components/admin/proxy/ImportDataModal.vue'
import Select from '@/components/common/Select.vue'
import ProxyAdBanner from '@/components/common/ProxyAdBanner.vue'
import Icon from '@/components/icons/Icon.vue'
import PlatformTypeBadge from '@/components/common/PlatformTypeBadge.vue'
import { useClipboard } from '@/composables/useClipboard'