fix(proxy): separate upstream target resolution from proxy dispatch and add site-level proxy URLs

This commit is contained in:
Brucents
2026-03-20 17:40:02 +08:00
parent 112191c5bc
commit a66cbafeb8
11 changed files with 111 additions and 40 deletions
+11
View File
@@ -40,6 +40,7 @@ type SiteRow = {
externalCheckinUrl?: string | null;
platform?: string;
status?: string;
proxyUrl?: string | null;
useSystemProxy?: boolean;
customHeaders?: string | null;
globalWeight?: number;
@@ -382,6 +383,7 @@ export default function Sites() {
url: form.url.trim(),
externalCheckinUrl: form.externalCheckinUrl.trim(),
platform: form.platform.trim(),
proxyUrl: form.proxyUrl.trim(),
useSystemProxy: !!form.useSystemProxy,
customHeaders: serializedCustomHeaders.customHeaders,
globalWeight: Number(parsedGlobalWeight.toFixed(3)),
@@ -918,6 +920,15 @@ export default function Sites() {
</div>
)}
</div>
<input
placeholder="站点代理 URL(可选,如 http://127.0.0.1:7890 或 socks5://127.0.0.1:1080)"
value={form.proxyUrl}
onChange={(e) => setForm((prev) => ({ ...prev, proxyUrl: e.target.value }))}
style={formInputStyle}
/>
<div style={{ fontSize: 12, color: 'var(--color-text-muted)' }}>
留空则直连;填写后优先于系统代理。
</div>
<label style={{
display: 'flex',
alignItems: 'center',
+10 -1
View File
@@ -16,6 +16,7 @@ describe('buildSiteSaveAction', () => {
url: 'https://a.example.com/',
externalCheckinUrl: 'https://checkin.a.example.com',
platform: 'new-api',
proxyUrl: 'socks5://127.0.0.1:1080',
customHeaders: '{"x-site-token":"alpha"}',
useSystemProxy: false,
globalWeight: 1.2,
@@ -29,6 +30,7 @@ describe('buildSiteSaveAction', () => {
url: 'https://a.example.com/',
externalCheckinUrl: 'https://checkin.a.example.com',
platform: 'new-api',
proxyUrl: 'socks5://127.0.0.1:1080',
customHeaders: '{"x-site-token":"alpha"}',
useSystemProxy: false,
globalWeight: 1.2,
@@ -44,6 +46,7 @@ describe('buildSiteSaveAction', () => {
url: 'https://b.example.com',
externalCheckinUrl: '',
platform: 'one-api',
proxyUrl: '',
useSystemProxy: true,
customHeaders: '',
globalWeight: 0.8,
@@ -58,6 +61,7 @@ describe('buildSiteSaveAction', () => {
url: 'https://b.example.com',
externalCheckinUrl: '',
platform: 'one-api',
proxyUrl: '',
useSystemProxy: true,
customHeaders: '',
globalWeight: 0.8,
@@ -74,6 +78,7 @@ describe('buildSiteSaveAction', () => {
url: 'https://c.example.com',
externalCheckinUrl: '',
platform: '',
proxyUrl: '',
useSystemProxy: false,
customHeaders: '',
globalWeight: 1,
@@ -85,16 +90,20 @@ describe('buildSiteSaveAction', () => {
it('does not expose deprecated apiKey in site editor state', () => {
expect(emptySiteForm()).not.toHaveProperty('apiKey');
expect(emptySiteForm().customHeaders).toEqual([emptySiteCustomHeader()]);
expect(emptySiteForm().proxyUrl).toBe('');
expect(siteFormFromSite({
name: 'site-d',
url: 'https://d.example.com',
externalCheckinUrl: null,
platform: 'new-api',
proxyUrl: null,
proxyUrl: 'http://127.0.0.1:8080',
customHeaders: '{"x-site-token":"alpha"}',
globalWeight: 1,
apiKey: 'sk-legacy-site-key',
})).not.toHaveProperty('apiKey');
expect(siteFormFromSite({
proxyUrl: 'http://127.0.0.1:8080',
}).proxyUrl).toBe('http://127.0.0.1:8080');
});
it('parses custom headers json into key value rows', () => {
+6 -1
View File
@@ -8,6 +8,7 @@ export type SiteForm = {
url: string;
externalCheckinUrl: string;
platform: string;
proxyUrl: string;
useSystemProxy: boolean;
customHeaders: SiteCustomHeaderField[];
globalWeight: string;
@@ -22,6 +23,7 @@ export type SiteSavePayload = {
url: string;
externalCheckinUrl: string;
platform: string;
proxyUrl: string;
useSystemProxy: boolean;
customHeaders: string;
globalWeight: number;
@@ -45,6 +47,7 @@ export function emptySiteForm(): SiteForm {
url: '',
externalCheckinUrl: '',
platform: '',
proxyUrl: '',
useSystemProxy: false,
customHeaders: [emptySiteCustomHeader()],
globalWeight: '1',
@@ -76,8 +79,9 @@ function parseCustomHeadersForEditor(raw: unknown): SiteCustomHeaderField[] {
}
}
export function siteFormFromSite(site: Partial<Omit<SiteForm, 'customHeaders' | 'globalWeight' | 'externalCheckinUrl' | 'useSystemProxy'>> & {
export function siteFormFromSite(site: Partial<Omit<SiteForm, 'customHeaders' | 'globalWeight' | 'externalCheckinUrl' | 'proxyUrl' | 'useSystemProxy'>> & {
externalCheckinUrl?: string | null;
proxyUrl?: string | null;
useSystemProxy?: boolean | null;
customHeaders?: string | null;
globalWeight?: number | string | null;
@@ -89,6 +93,7 @@ export function siteFormFromSite(site: Partial<Omit<SiteForm, 'customHeaders' |
url: site.url ?? '',
externalCheckinUrl: site.externalCheckinUrl ?? '',
platform: site.platform ?? '',
proxyUrl: site.proxyUrl ?? '',
useSystemProxy: !!site.useSystemProxy,
customHeaders: parseCustomHeadersForEditor(site.customHeaders),
globalWeight,