feat(代理): 代理配置按登录用户隔离——桌面端 current_uid 登录同步 + brand 页 proxy_users[uid] 读写,各用户各自代理池各自计费复用(未登录回退全局 proxy_url 兼容旧配置)
This commit is contained in:
@@ -163,7 +163,7 @@ import {
|
||||
type ApiSecretModuleKey,
|
||||
type ApiSecretRetention,
|
||||
} from '@/shared/utils/api-secret-store'
|
||||
import { getPywebviewApi, type ProxyMode } from '@/shared/bridges/pywebview'
|
||||
import { getPywebviewApi, type ProxyMode, type DesktopConfigUpdate } from '@/shared/bridges/pywebview'
|
||||
|
||||
type SecretState = {
|
||||
value: string
|
||||
@@ -275,6 +275,39 @@ function clearSecret(moduleKey: ApiSecretModuleKey) {
|
||||
ElMessage.success('已清空密钥')
|
||||
}
|
||||
|
||||
function proxyUserId() {
|
||||
if (typeof window === 'undefined') return '0'
|
||||
return window.localStorage.getItem('uid') || '0'
|
||||
}
|
||||
|
||||
/** 代理地址按登录用户隔离:proxy_users[uid],各自计费各自复用;
|
||||
* 未登录(uid=0)回退全局 proxy_url(兼容旧版本已保存的配置)。 */
|
||||
function readUserProxy(config: Record<string, unknown> | null | undefined) {
|
||||
const uid = proxyUserId()
|
||||
if (uid !== '0') {
|
||||
const users = (config?.proxy_users ?? {}) as Record<string, unknown>
|
||||
const own = (users[uid] ?? {}) as Record<string, unknown>
|
||||
return {
|
||||
url: typeof own.proxy_url === 'string' ? own.proxy_url : '',
|
||||
mode: Number(own.proxy_mode) === 2 ? 2 : 1,
|
||||
}
|
||||
}
|
||||
return {
|
||||
url: typeof config?.proxy_url === 'string' ? config.proxy_url : '',
|
||||
mode: Number(config?.proxy_mode) === 2 ? 2 : 1,
|
||||
}
|
||||
}
|
||||
|
||||
function userProxyPatch(nextProxyUrl: string, nextProxyMode: ProxyMode) {
|
||||
const uid = proxyUserId()
|
||||
if (uid === '0') {
|
||||
return { proxy_url: nextProxyUrl, proxy_mode: nextProxyMode }
|
||||
}
|
||||
const users: Record<string, unknown> = {}
|
||||
users[uid] = { proxy_url: nextProxyUrl, proxy_mode: nextProxyMode }
|
||||
return { proxy_users: users }
|
||||
}
|
||||
|
||||
async function loadProxyConfig() {
|
||||
const requestId = ++proxyLoadRequestId
|
||||
proxyLoading.value = true
|
||||
@@ -294,10 +327,9 @@ async function loadProxyConfig() {
|
||||
try {
|
||||
const config = await api.read_config()
|
||||
if (requestId !== proxyLoadRequestId || !dialogVisible.value) return
|
||||
const nextUrl = typeof config?.proxy_url === 'string' ? config.proxy_url : ''
|
||||
const nextMode: ProxyMode = Number(config?.proxy_mode) === 2 ? 2 : 1
|
||||
proxyUrl.value = nextUrl
|
||||
proxyMode.value = nextMode
|
||||
const own = readUserProxy(config as Record<string, unknown>)
|
||||
proxyUrl.value = own.url
|
||||
proxyMode.value = (own.mode === 2 ? 2 : 1) as ProxyMode
|
||||
proxyReady.value = true
|
||||
} catch (error) {
|
||||
if (requestId !== proxyLoadRequestId || !dialogVisible.value) return
|
||||
@@ -331,10 +363,8 @@ async function saveAll() {
|
||||
if (shouldSaveProxy) {
|
||||
const api = getPywebviewApi()
|
||||
if (!api?.save_config) throw new Error('当前客户端未提供代理配置保存能力')
|
||||
await api.save_config({
|
||||
proxy_url: nextProxyUrl,
|
||||
proxy_mode: nextProxyMode,
|
||||
})
|
||||
// 按登录用户保存:proxy_users[uid](未登录回退全局 proxy_url 字段)
|
||||
await api.save_config(userProxyPatch(nextProxyUrl, nextProxyMode) as DesktopConfigUpdate)
|
||||
proxyUrl.value = nextProxyUrl
|
||||
proxyDirty.value = false
|
||||
}
|
||||
|
||||
@@ -333,6 +333,17 @@ async function submitLogin() {
|
||||
} catch {
|
||||
/* 忽略 */
|
||||
}
|
||||
// 同步登录用户到桌面客户端配置:Python 端按 uid 选用该用户自己的
|
||||
// 代理密钥/代理池(各自计费、各自复用省钱)。网页形态无 pywebview
|
||||
// 桥,静默跳过。
|
||||
try {
|
||||
const bridge = (window as unknown as { pywebview?: { api?: { save_config?: (data: Record<string, unknown>) => Promise<unknown> } } }).pywebview
|
||||
if (bridge?.api && typeof bridge.api.save_config === 'function') {
|
||||
void bridge.api.save_config({ current_uid: String(data.userId) })
|
||||
}
|
||||
} catch {
|
||||
/* 忽略 */
|
||||
}
|
||||
}
|
||||
if (data.username) {
|
||||
try {
|
||||
@@ -365,6 +376,15 @@ onMounted(() => {
|
||||
} catch {
|
||||
/* 忽略 */
|
||||
}
|
||||
// 同步清掉客户端的登录用户标记:Python 端回退到全局/默认代理池
|
||||
try {
|
||||
const bridge = (window as unknown as { pywebview?: { api?: { save_config?: (data: Record<string, unknown>) => Promise<unknown> } } }).pywebview
|
||||
if (bridge?.api && typeof bridge.api.save_config === 'function') {
|
||||
void bridge.api.save_config({ current_uid: '' })
|
||||
}
|
||||
} catch {
|
||||
/* 忽略 */
|
||||
}
|
||||
// 显式登出/切号后不再自动登录(保留记住的账号,仅关闭自动登录)
|
||||
autoLogin.value = false
|
||||
lsSet(AUTO_LOGIN_KEY, '0')
|
||||
|
||||
@@ -56,6 +56,8 @@ export interface DesktopConfig {
|
||||
export interface DesktopConfigUpdate {
|
||||
proxy_url?: string;
|
||||
proxy_mode?: ProxyMode;
|
||||
current_uid?: string;
|
||||
proxy_users?: Record<string, { proxy_url?: string; proxy_mode?: number }>;
|
||||
aliprice_usename?: string;
|
||||
aliprice_pwd?: string;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user