From 23b3711e648d9c9f091475978a3948cc88d16ebf Mon Sep 17 00:00:00 2001 From: yml2213 Date: Sat, 8 Aug 2026 14:30:43 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B9=B3=E5=8F=B0=E9=85=8D=E7=BD=AE=20kuaishou?= =?UTF-8?q?-lewan=20=E8=B0=83=E8=AF=95=E5=8C=BA=E6=96=B0=E5=A2=9E=E8=99=9A?= =?UTF-8?q?=E6=8B=9F=E5=8F=B7=E5=88=97=E8=A1=A8=E6=9F=A5=E7=9C=8B=E4=B8=8E?= =?UTF-8?q?=E6=89=8B=E5=8A=A8=E9=80=80=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/platform/AdminPlatformShopsPage.tsx | 154 ++++++++++++++++++ .../admin/platform-config/cloudtentacles.ts | 3 +- apps/frontend/src/types/admin/index.ts | 2 + .../admin/platform-config/cloudtentacles.ts | 17 ++ .../src/types/admin/platform-config/index.ts | 2 + 5 files changed, 177 insertions(+), 1 deletion(-) diff --git a/apps/frontend/src/pages/admin/platform/AdminPlatformShopsPage.tsx b/apps/frontend/src/pages/admin/platform/AdminPlatformShopsPage.tsx index b792e5a1..1d22067a 100644 --- a/apps/frontend/src/pages/admin/platform/AdminPlatformShopsPage.tsx +++ b/apps/frontend/src/pages/admin/platform/AdminPlatformShopsPage.tsx @@ -16,6 +16,7 @@ import { Empty, Input, InputNumber, + Popconfirm, Select, Space, Spin, @@ -32,11 +33,13 @@ import { useSearchParams } from 'react-router' import PageHeader from '@/components/admin/PageHeader' import { showError, showSuccess } from '@/lib/feedback' import { + backAdminCloudtentaclesVn, deleteAdminCloudtentaclesSource, exchangeAdminKuaishouIndustryAuthorizationCode, fetchAdminCloudtentaclesAsset, fetchAdminCloudtentaclesSkuList, fetchAdminCloudtentaclesSourceConfig, + fetchAdminCloudtentaclesVnList, fetchAdminAffiliateDashConfig, fetchAdminAffiliateDashProducts, fetchAdminAffiliateDashWallet, @@ -64,6 +67,7 @@ import type { AdminCloudtentaclesMonitorAccount, AdminCloudtentaclesSourceConfigResponse, AdminCloudtentaclesSourceItem, + AdminCloudtentaclesVnListItem, AdminAffiliateDashConfig, AdminAffiliateDashConfigResponse, AdminAffiliateDashMatchResult, @@ -1748,6 +1752,9 @@ function CloudtentaclesPlatformPanel({ const [selectedSourceKey, setSelectedSourceKey] = useState(config.sources[0]?.key || '') const [smsCode, setSmsCode] = useState('') const [debugResult, setDebugResult] = useState(null) + const [vnItems, setVnItems] = useState(null) + const [vnLoading, setVnLoading] = useState(false) + const [vnBackingId, setVnBackingId] = useState(null) useEffect(() => { if (!config.sources.some((source) => source.key === selectedSourceKey)) { @@ -1822,6 +1829,45 @@ function CloudtentaclesPlatformPanel({ onChange({ ...config, ...next }) } + async function loadVnList() { + if (!selectedSource) { + showError('请先选择一个账号') + return + } + setVnLoading(true) + try { + const response = await fetchAdminCloudtentaclesVnList({ + sourceKey: selectedSource.key, + key: '1', + }) + setVnItems(response.data.items || []) + } catch (error) { + showError(error instanceof Error ? error.message : '查询虚拟号列表失败') + } finally { + setVnLoading(false) + } + } + + async function backVn(item: AdminCloudtentaclesVnListItem) { + if (!selectedSource) { + return + } + setVnBackingId(item.id) + try { + await backAdminCloudtentaclesVn({ + sourceKey: selectedSource.key, + key: '1', + id: item.id, + }) + showSuccess(`号码 ${item.phone} 已退回`) + await loadVnList() + } catch (error) { + showError(error instanceof Error ? error.message : '退回号码失败') + } finally { + setVnBackingId(null) + } + } + function updateSource(sourceKey: string, patch: Partial) { updateConfig({ sources: config.sources.map((source) => @@ -2104,8 +2150,86 @@ function CloudtentaclesPlatformPanel({ > 查商品 + {debugResult ?
{JSON.stringify(debugResult, null, 2)}
: null} + {vnItems !== null ? ( + + className="platform-section-gap" + size="small" + rowKey="id" + loading={vnLoading} + dataSource={vnItems} + pagination={{ pageSize: 10, showSizeChanger: false }} + columns={[ + { + title: '手机号', + dataIndex: 'phone', + render: (phone: string) => phone || '-', + }, + { + title: '绑定角色', + dataIndex: 'bindInfo', + render: (bindInfo: AdminCloudtentaclesVnListItem['bindInfo']) => { + const role = resolveVnBindRole(bindInfo) + return role ? ( + + {role.name || '-'} + + {role.rid || ''} + + + ) : ( + 未绑定 + ) + }, + }, + { + title: '回收倒计时', + dataIndex: 'countTime', + render: (countTime: number) => ( + + {formatCountdownSeconds(Number(countTime))} + + ), + }, + { + title: '状态', + dataIndex: 'status', + render: (status: number) => + Number(status) === 0 ? 空闲 : 占用中, + }, + { + title: '操作', + width: 120, + render: (_, item) => ( + void backVn(item)} + > + + + ), + }, + ]} + /> + ) : null} )} @@ -2117,6 +2241,36 @@ function formatCloudtentaclesSourceLabel(source: Pick).name || '').trim(), + rid: String((bindInfo as Record).rid || '').trim(), + } + } + if (typeof bindInfo === 'string' && bindInfo.trim()) { + try { + const parsed = JSON.parse(bindInfo) as Record + if (parsed && typeof parsed === 'object') { + return { + name: String(parsed.name || '').trim(), + rid: String(parsed.rid || '').trim(), + } + } + } catch { + return null + } + } + return null +} + +function formatCountdownSeconds(totalSeconds: number) { + const seconds = Math.max(0, Number(totalSeconds) || 0) + const minutes = Math.floor(seconds / 60) + const restSeconds = seconds % 60 + return `${String(minutes).padStart(2, '0')}:${String(restSeconds).padStart(2, '0')}` +} + function resolveIndustryAccessTokenStatus( source: Pick, ) { diff --git a/apps/frontend/src/services/admin/platform-config/cloudtentacles.ts b/apps/frontend/src/services/admin/platform-config/cloudtentacles.ts index 30e5890a..0cc6ef8f 100644 --- a/apps/frontend/src/services/admin/platform-config/cloudtentacles.ts +++ b/apps/frontend/src/services/admin/platform-config/cloudtentacles.ts @@ -9,6 +9,7 @@ import type { AdminCloudtentaclesSourceItem, AdminCloudtentaclesSourcesConfig, AdminCloudtentaclesValidateSessionResult, + AdminCloudtentaclesVnListResult, } from '@/types/admin' export function fetchAdminCloudtentaclesSourceConfig() { @@ -223,7 +224,7 @@ export function fetchAdminCloudtentaclesVnList(payload: { key?: string sourceKey?: string }) { - return apiPost>( + return apiPost( '/api/v1/admin/platform-config/cloudtentacles/vn/list', payload, ) diff --git a/apps/frontend/src/types/admin/index.ts b/apps/frontend/src/types/admin/index.ts index 5e2fca5c..40662b6e 100644 --- a/apps/frontend/src/types/admin/index.ts +++ b/apps/frontend/src/types/admin/index.ts @@ -93,6 +93,8 @@ export type { AdminCloudtentaclesValidateSessionResult, AdminCloudtentaclesSkuItem, AdminCloudtentaclesSkuListResult, + AdminCloudtentaclesVnListItem, + AdminCloudtentaclesVnListResult, AdminCloudtentaclesDeliveryRecordItem, AdminCloudtentaclesDeliveryRecordListResult, AdminFulfillmentRoutingConfig, diff --git a/apps/frontend/src/types/admin/platform-config/cloudtentacles.ts b/apps/frontend/src/types/admin/platform-config/cloudtentacles.ts index 6442d35f..f4752132 100644 --- a/apps/frontend/src/types/admin/platform-config/cloudtentacles.ts +++ b/apps/frontend/src/types/admin/platform-config/cloudtentacles.ts @@ -179,3 +179,20 @@ export interface AdminCloudtentaclesSourceConfig { deviceId: string deviceType: number } + +export interface AdminCloudtentaclesVnListItem { + id: number + phone: string + status: number + countTime: number + bindInfo: string | Record | null + raw: Record +} + +export interface AdminCloudtentaclesVnListResult { + baseUrl: string + key: string + itemCount: number + items: AdminCloudtentaclesVnListItem[] + rawItems: Array> +} diff --git a/apps/frontend/src/types/admin/platform-config/index.ts b/apps/frontend/src/types/admin/platform-config/index.ts index ed6fe284..9b138742 100644 --- a/apps/frontend/src/types/admin/platform-config/index.ts +++ b/apps/frontend/src/types/admin/platform-config/index.ts @@ -66,6 +66,8 @@ export type { AdminCloudtentaclesValidateSessionResult, AdminCloudtentaclesSkuItem, AdminCloudtentaclesSkuListResult, + AdminCloudtentaclesVnListItem, + AdminCloudtentaclesVnListResult, AdminCloudtentaclesDeliveryRecordItem, AdminCloudtentaclesDeliveryRecordListResult, } from './cloudtentacles'