feat(cloudtentacles): 合并前端多账号支持改动
This commit is contained in:
@@ -1,29 +1,37 @@
|
||||
import { apiGet, apiPost } from '@/lib/http'
|
||||
import { apiDelete, apiGet, apiPost } from '@/lib/http'
|
||||
import type {
|
||||
AdminCloudtentaclesLoginTestResult,
|
||||
AdminCloudtentaclesPersistedSession,
|
||||
AdminCloudtentaclesSessionsMap,
|
||||
AdminCloudtentaclesSkuListResult,
|
||||
AdminCloudtentaclesSendSmsResult,
|
||||
AdminCloudtentaclesSourceConfig,
|
||||
AdminCloudtentaclesSourceConfigResponse,
|
||||
AdminCloudtentaclesSourceItem,
|
||||
AdminCloudtentaclesSourcesConfig,
|
||||
AdminCloudtentaclesValidateSessionResult,
|
||||
} from '@/types/admin'
|
||||
|
||||
export function fetchAdminCloudtentaclesSourceConfig() {
|
||||
return apiGet<{
|
||||
filePath: string
|
||||
sessionFilePath: string
|
||||
source: AdminCloudtentaclesSourceConfig
|
||||
session: AdminCloudtentaclesPersistedSession
|
||||
}>('/api/v1/admin/platform-config/cloudtentacles-source')
|
||||
return apiGet<AdminCloudtentaclesSourceConfigResponse>(
|
||||
'/api/v1/admin/platform-config/cloudtentacles-source',
|
||||
)
|
||||
}
|
||||
|
||||
export function saveAdminCloudtentaclesSourceConfig(payload: AdminCloudtentaclesSourceConfig) {
|
||||
return apiPost<{
|
||||
filePath: string
|
||||
sessionFilePath: string
|
||||
source: AdminCloudtentaclesSourceConfig
|
||||
session: AdminCloudtentaclesPersistedSession
|
||||
}>('/api/v1/admin/platform-config/cloudtentacles-source', payload)
|
||||
export function saveAdminCloudtentaclesSourceConfig(
|
||||
payload:
|
||||
| AdminCloudtentaclesSourcesConfig
|
||||
| ({ sourceKey: string } & Partial<AdminCloudtentaclesSourceItem>),
|
||||
) {
|
||||
return apiPost<AdminCloudtentaclesSourceConfigResponse>(
|
||||
'/api/v1/admin/platform-config/cloudtentacles-source',
|
||||
payload,
|
||||
)
|
||||
}
|
||||
|
||||
export function deleteAdminCloudtentaclesSource(sourceKey: string) {
|
||||
return apiDelete<{ success: boolean }>(
|
||||
`/api/v1/admin/platform-config/cloudtentacles-source/${sourceKey}`,
|
||||
)
|
||||
}
|
||||
|
||||
export function sendAdminCloudtentaclesSmsCode(payload: {
|
||||
@@ -32,6 +40,7 @@ export function sendAdminCloudtentaclesSmsCode(payload: {
|
||||
phone?: string
|
||||
deviceId?: string
|
||||
deviceType?: number
|
||||
sourceKey?: string
|
||||
}) {
|
||||
return apiPost<AdminCloudtentaclesSendSmsResult>(
|
||||
'/api/v1/admin/platform-config/cloudtentacles/send-sms-code',
|
||||
@@ -47,6 +56,7 @@ export function testAdminCloudtentaclesLogin(payload: {
|
||||
code?: string
|
||||
deviceId?: string
|
||||
deviceType?: number
|
||||
sourceKey?: string
|
||||
}) {
|
||||
return apiPost<AdminCloudtentaclesLoginTestResult>(
|
||||
'/api/v1/admin/platform-config/cloudtentacles/test-login',
|
||||
@@ -59,6 +69,7 @@ export function validateAdminCloudtentaclesSession(payload: {
|
||||
token?: string
|
||||
deviceId?: string
|
||||
deviceType?: number
|
||||
sourceKey?: string
|
||||
}) {
|
||||
return apiPost<AdminCloudtentaclesValidateSessionResult>(
|
||||
'/api/v1/admin/platform-config/cloudtentacles/validate-session',
|
||||
@@ -71,6 +82,7 @@ export function fetchAdminCloudtentaclesAsset(payload: {
|
||||
token?: string
|
||||
deviceId?: string
|
||||
deviceType?: number
|
||||
sourceKey?: string
|
||||
}) {
|
||||
return apiPost<Record<string, unknown>>(
|
||||
'/api/v1/admin/platform-config/cloudtentacles/asset',
|
||||
@@ -83,6 +95,7 @@ export function fetchAdminCloudtentaclesCategories(payload: {
|
||||
token?: string
|
||||
deviceId?: string
|
||||
deviceType?: number
|
||||
sourceKey?: string
|
||||
}) {
|
||||
return apiPost<Record<string, unknown>>(
|
||||
'/api/v1/admin/platform-config/cloudtentacles/categories',
|
||||
@@ -95,6 +108,7 @@ export function fetchAdminCloudtentaclesSkuList(payload: {
|
||||
token?: string
|
||||
deviceId?: string
|
||||
deviceType?: number
|
||||
sourceKey?: string
|
||||
}) {
|
||||
return apiPost<AdminCloudtentaclesSkuListResult>(
|
||||
'/api/v1/admin/platform-config/cloudtentacles/sku/list',
|
||||
@@ -109,6 +123,7 @@ export function buyAdminCloudtentaclesSku(payload: {
|
||||
deviceType?: number
|
||||
id?: number
|
||||
count?: number
|
||||
sourceKey?: string
|
||||
}) {
|
||||
return apiPost<Record<string, unknown>>(
|
||||
'/api/v1/admin/platform-config/cloudtentacles/sku/buy',
|
||||
@@ -124,6 +139,7 @@ export function useAdminCloudtentaclesSku(payload: {
|
||||
id?: number
|
||||
virtualNumberId?: number
|
||||
phone?: string
|
||||
sourceKey?: string
|
||||
}) {
|
||||
return apiPost<Record<string, unknown>>(
|
||||
'/api/v1/admin/platform-config/cloudtentacles/sku/use',
|
||||
@@ -136,6 +152,7 @@ export function fetchAdminCloudtentaclesKnapsack(payload: {
|
||||
token?: string
|
||||
deviceId?: string
|
||||
deviceType?: number
|
||||
sourceKey?: string
|
||||
}) {
|
||||
return apiPost<Record<string, unknown>>(
|
||||
'/api/v1/admin/platform-config/cloudtentacles/knapsack',
|
||||
@@ -149,6 +166,7 @@ export function fetchAdminCloudtentaclesVnList(payload: {
|
||||
deviceId?: string
|
||||
deviceType?: number
|
||||
key?: string
|
||||
sourceKey?: string
|
||||
}) {
|
||||
return apiPost<Record<string, unknown>>(
|
||||
'/api/v1/admin/platform-config/cloudtentacles/vn/list',
|
||||
@@ -162,6 +180,7 @@ export function appointAdminCloudtentaclesVn(payload: {
|
||||
deviceId?: string
|
||||
deviceType?: number
|
||||
key?: string
|
||||
sourceKey?: string
|
||||
}) {
|
||||
return apiPost<Record<string, unknown>>(
|
||||
'/api/v1/admin/platform-config/cloudtentacles/vn/appoint',
|
||||
@@ -176,6 +195,7 @@ export function generateAdminCloudtentaclesVnLoginCode(payload: {
|
||||
deviceType?: number
|
||||
key?: string
|
||||
id?: number
|
||||
sourceKey?: string
|
||||
}) {
|
||||
return apiPost<Record<string, unknown>>(
|
||||
'/api/v1/admin/platform-config/cloudtentacles/vn/generate-login-code',
|
||||
@@ -190,6 +210,7 @@ export function fetchAdminCloudtentaclesVnCode(payload: {
|
||||
deviceType?: number
|
||||
key?: string
|
||||
phone?: string
|
||||
sourceKey?: string
|
||||
}) {
|
||||
return apiPost<Record<string, unknown>>(
|
||||
'/api/v1/admin/platform-config/cloudtentacles/vn/fetch-code',
|
||||
@@ -205,6 +226,7 @@ export function verifyAdminCloudtentaclesVnCode(payload: {
|
||||
key?: string
|
||||
id?: number
|
||||
code?: string
|
||||
sourceKey?: string
|
||||
}) {
|
||||
return apiPost<Record<string, unknown>>(
|
||||
'/api/v1/admin/platform-config/cloudtentacles/vn/verify-code',
|
||||
@@ -219,6 +241,7 @@ export function fetchAdminCloudtentaclesBindUrl(payload: {
|
||||
deviceType?: number
|
||||
key?: string
|
||||
id?: number
|
||||
sourceKey?: string
|
||||
}) {
|
||||
return apiPost<Record<string, unknown>>(
|
||||
'/api/v1/admin/platform-config/cloudtentacles/vn/bind-url',
|
||||
@@ -233,6 +256,7 @@ export function backAdminCloudtentaclesVn(payload: {
|
||||
deviceType?: number
|
||||
key?: string
|
||||
id?: number
|
||||
sourceKey?: string
|
||||
}) {
|
||||
return apiPost<Record<string, unknown>>(
|
||||
'/api/v1/admin/platform-config/cloudtentacles/vn/back',
|
||||
@@ -248,6 +272,7 @@ export function runAdminCloudtentaclesFullFlow(payload: {
|
||||
skuId?: number
|
||||
skuCount?: number
|
||||
vnKey?: string
|
||||
sourceKey?: string
|
||||
}) {
|
||||
return apiPost<Record<string, unknown>>(
|
||||
'/api/v1/admin/platform-config/cloudtentacles/debug/full-flow',
|
||||
|
||||
@@ -2,12 +2,7 @@
|
||||
export type { AdminPagination } from './common'
|
||||
|
||||
// Auth types
|
||||
export type {
|
||||
AdminRole,
|
||||
AdminUserStatus,
|
||||
AdminLoginResponse,
|
||||
AdminSessionSummary,
|
||||
} from './auth'
|
||||
export type { AdminRole, AdminUserStatus, AdminLoginResponse, AdminSessionSummary } from './auth'
|
||||
|
||||
// Users types
|
||||
export type { AdminUserListItem } from './users'
|
||||
@@ -37,10 +32,7 @@ export type {
|
||||
} from './tasks'
|
||||
|
||||
// Inventory types
|
||||
export type {
|
||||
AdminInventorySkuSuggestion,
|
||||
AdminInventoryItemListItem,
|
||||
} from './inventory'
|
||||
export type { AdminInventorySkuSuggestion, AdminInventoryItemListItem } from './inventory'
|
||||
|
||||
// Manual redeem types
|
||||
export type { AdminManualRedeemDetail } from './manual-redeem'
|
||||
@@ -83,6 +75,10 @@ export type {
|
||||
AdminKuaishouEticketShopInfoResult,
|
||||
AdminKuaishouEticketDetailResult,
|
||||
AdminKuaishouEticketConsumeResult,
|
||||
AdminCloudtentaclesSourceItem,
|
||||
AdminCloudtentaclesSourcesConfig,
|
||||
AdminCloudtentaclesSourceConfigResponse,
|
||||
AdminCloudtentaclesSessionsMap,
|
||||
AdminCloudtentaclesSourceConfig,
|
||||
AdminCloudtentaclesPersistedSession,
|
||||
AdminCloudtentaclesSendSmsResult,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
export interface AdminCloudtentaclesSourceConfig {
|
||||
enabled: boolean
|
||||
export interface AdminCloudtentaclesSourceItem {
|
||||
key: string
|
||||
label: string
|
||||
baseUrl: string
|
||||
username: string
|
||||
password: string
|
||||
@@ -8,6 +9,11 @@ export interface AdminCloudtentaclesSourceConfig {
|
||||
deviceType: number
|
||||
}
|
||||
|
||||
export interface AdminCloudtentaclesSourcesConfig {
|
||||
enabled: boolean
|
||||
sources: AdminCloudtentaclesSourceItem[]
|
||||
}
|
||||
|
||||
export interface AdminCloudtentaclesPersistedSession {
|
||||
token: string
|
||||
tokenMasked: string
|
||||
@@ -20,6 +26,18 @@ export interface AdminCloudtentaclesPersistedSession {
|
||||
hasToken: boolean
|
||||
}
|
||||
|
||||
export interface AdminCloudtentaclesSessionsMap {
|
||||
[sourceKey: string]: AdminCloudtentaclesPersistedSession
|
||||
}
|
||||
|
||||
export interface AdminCloudtentaclesSourceConfigResponse {
|
||||
filePath: string
|
||||
sessionFilePath: string
|
||||
enabled: boolean
|
||||
sources: AdminCloudtentaclesSourceItem[]
|
||||
sessions: AdminCloudtentaclesSessionsMap
|
||||
}
|
||||
|
||||
export interface AdminCloudtentaclesSendSmsResult {
|
||||
baseUrl: string
|
||||
username: string
|
||||
@@ -77,3 +95,14 @@ export interface AdminCloudtentaclesSkuListResult {
|
||||
items: AdminCloudtentaclesSkuItem[]
|
||||
rawItems: Record<string, unknown>[]
|
||||
}
|
||||
|
||||
/** @deprecated Use AdminCloudtentaclesSourceItem + AdminCloudtentaclesSourcesConfig instead */
|
||||
export interface AdminCloudtentaclesSourceConfig {
|
||||
enabled: boolean
|
||||
baseUrl: string
|
||||
username: string
|
||||
password: string
|
||||
phone: string
|
||||
deviceId: string
|
||||
deviceType: number
|
||||
}
|
||||
|
||||
@@ -33,6 +33,10 @@ export type {
|
||||
} from './kuaishou-eticket'
|
||||
|
||||
export type {
|
||||
AdminCloudtentaclesSourceItem,
|
||||
AdminCloudtentaclesSourcesConfig,
|
||||
AdminCloudtentaclesSourceConfigResponse,
|
||||
AdminCloudtentaclesSessionsMap,
|
||||
AdminCloudtentaclesSourceConfig,
|
||||
AdminCloudtentaclesPersistedSession,
|
||||
AdminCloudtentaclesSendSmsResult,
|
||||
|
||||
@@ -132,7 +132,14 @@ const {
|
||||
cloudtentaclesDebugResult,
|
||||
cloudtentaclesPersistedSession,
|
||||
cloudtentaclesStats,
|
||||
sources: cloudtentaclesSources,
|
||||
sessions: cloudtentaclesSessions,
|
||||
selectedSourceKey: selectedCloudtentaclesSourceKey,
|
||||
sourceOptions: cloudtentaclesSourceOptions,
|
||||
hydrateCloudtentaclesConfig,
|
||||
switchSource: switchCloudtentaclesSource,
|
||||
addSource: addCloudtentaclesSource,
|
||||
removeSource: removeCloudtentaclesSource,
|
||||
handleCloudtentaclesSaveSource,
|
||||
handleCloudtentaclesSendSmsCode,
|
||||
handleCloudtentaclesTestLogin,
|
||||
@@ -417,6 +424,13 @@ onMounted(loadConfigs)
|
||||
:cloudtentacles-debug-result="cloudtentaclesDebugResult"
|
||||
:cloudtentacles-persisted-session="cloudtentaclesPersistedSession"
|
||||
:cloudtentacles-stats="cloudtentaclesStats"
|
||||
:sources="cloudtentaclesSources"
|
||||
:sessions="cloudtentaclesSessions"
|
||||
:selected-source-key="selectedCloudtentaclesSourceKey"
|
||||
:source-options="cloudtentaclesSourceOptions"
|
||||
:switch-source="switchCloudtentaclesSource"
|
||||
:add-source="addCloudtentaclesSource"
|
||||
:remove-source="removeCloudtentaclesSource"
|
||||
:handle-cloudtentacles-save-source="handleCloudtentaclesSaveSource"
|
||||
:handle-cloudtentacles-send-sms-code="handleCloudtentaclesSendSmsCode"
|
||||
:handle-cloudtentacles-test-login="handleCloudtentaclesTestLogin"
|
||||
|
||||
+50
-1
@@ -2,6 +2,7 @@
|
||||
import type {
|
||||
AdminCloudtentaclesLoginTestResult,
|
||||
AdminCloudtentaclesSendSmsResult,
|
||||
AdminCloudtentaclesSourceItem,
|
||||
AdminCloudtentaclesValidateSessionResult,
|
||||
} from '@/types/admin'
|
||||
import AdminResultCard from '@/components/admin/AdminResultCard.vue'
|
||||
@@ -22,6 +23,11 @@ type CloudtentaclesForm = {
|
||||
deviceType: number
|
||||
}
|
||||
|
||||
type SourceOption = {
|
||||
key: string
|
||||
label: string
|
||||
}
|
||||
|
||||
type Props = {
|
||||
cloudtentaclesForm: CloudtentaclesForm
|
||||
cloudtentaclesSaving: boolean
|
||||
@@ -32,13 +38,19 @@ type Props = {
|
||||
cloudtentaclesSmsResult: AdminCloudtentaclesSendSmsResult | null
|
||||
cloudtentaclesLoginResult: AdminCloudtentaclesLoginTestResult | null
|
||||
cloudtentaclesValidateResult: AdminCloudtentaclesValidateSessionResult | null
|
||||
selectedSourceKey: string
|
||||
sourceOptions: SourceOption[]
|
||||
sources: AdminCloudtentaclesSourceItem[]
|
||||
handleCloudtentaclesSaveSource: () => void | Promise<void>
|
||||
handleCloudtentaclesSendSmsCode: () => void | Promise<void>
|
||||
handleCloudtentaclesTestLogin: () => void | Promise<void>
|
||||
handleCloudtentaclesValidateSession: () => void | Promise<void>
|
||||
switchSource: (sourceKey: string) => void
|
||||
addSource: () => void
|
||||
removeSource: (sourceKey: string) => void
|
||||
}
|
||||
|
||||
defineProps<Props>()
|
||||
const props = defineProps<Props>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -73,6 +85,32 @@ defineProps<Props>()
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 账号选择器 -->
|
||||
<div class="source-selector">
|
||||
<el-select
|
||||
:model-value="selectedSourceKey"
|
||||
placeholder="选择账号"
|
||||
@change="switchSource"
|
||||
class="source-select"
|
||||
>
|
||||
<el-option
|
||||
v-for="opt in sourceOptions"
|
||||
:key="opt.key"
|
||||
:label="opt.label"
|
||||
:value="opt.key"
|
||||
/>
|
||||
</el-select>
|
||||
<el-button type="primary" plain size="small" @click="addSource">新增账号</el-button>
|
||||
<el-button
|
||||
v-if="selectedSourceKey !== 'default'"
|
||||
type="danger"
|
||||
plain
|
||||
size="small"
|
||||
@click="removeSource(selectedSourceKey)"
|
||||
>删除账号</el-button
|
||||
>
|
||||
</div>
|
||||
|
||||
<el-form label-width="auto" label-position="top">
|
||||
<el-form-item label="Base URL">
|
||||
<el-input v-model="cloudtentaclesForm.baseUrl" placeholder="https://123.207.217.176" />
|
||||
@@ -242,6 +280,17 @@ defineProps<Props>()
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.source-selector {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-2);
|
||||
margin-bottom: var(--space-4);
|
||||
}
|
||||
|
||||
.source-select {
|
||||
width: 180px;
|
||||
}
|
||||
|
||||
.result-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
|
||||
+33
-2
@@ -1,6 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import type {
|
||||
AdminCloudtentaclesPersistedSession,
|
||||
AdminCloudtentaclesSessionItem,
|
||||
AdminCloudtentaclesSessionsMap,
|
||||
} from '@/types/admin'
|
||||
import { formatAdminDateTime } from '@/utils/admin-time'
|
||||
|
||||
@@ -8,9 +10,12 @@ type Props = {
|
||||
cloudtentaclesFilePath: string
|
||||
cloudtentaclesSessionFilePath: string
|
||||
cloudtentaclesPersistedSession: AdminCloudtentaclesPersistedSession | null
|
||||
sources: AdminCloudtentaclesSourceItem[]
|
||||
sessions: AdminCloudtentaclesSessionsMap
|
||||
selectedSourceKey: string
|
||||
}
|
||||
|
||||
defineProps<Props>()
|
||||
const props = defineProps<Props>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -25,17 +30,31 @@ defineProps<Props>()
|
||||
<el-descriptions-item label="会话文件">
|
||||
<code>{{ cloudtentaclesSessionFilePath || '-' }}</code>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="账号数量">
|
||||
{{ sources.length }} 个
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="当前选中账号">
|
||||
{{ selectedSourceKey }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="职责">
|
||||
管理 cloudtentacles 外部履约平台的账号、短信验证码登录与 token
|
||||
探活。该区域不处理订单来源同步。
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="已保存 token">
|
||||
<el-descriptions-item label="当前账号已保存 token">
|
||||
{{
|
||||
cloudtentaclesPersistedSession?.hasToken
|
||||
? `${cloudtentaclesPersistedSession.tokenMasked} / ${formatAdminDateTime(cloudtentaclesPersistedSession.loggedInAt)}`
|
||||
: '未保存'
|
||||
}}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item v-if="Object.keys(sessions).length > 0" label="各账号会话状态">
|
||||
<div class="session-list">
|
||||
<div v-for="(session, key) in sessions" :key="key" class="session-item">
|
||||
<el-tag :type="session.hasToken ? 'success' : 'info'" size="small">{{ key }}</el-tag>
|
||||
<span>{{ session.hasToken ? session.tokenMasked : '未登录' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-card>
|
||||
</template>
|
||||
@@ -50,4 +69,16 @@ defineProps<Props>()
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.session-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-1);
|
||||
}
|
||||
|
||||
.session-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-2);
|
||||
}
|
||||
</style>
|
||||
|
||||
+24
@@ -3,6 +3,8 @@ import type {
|
||||
AdminCloudtentaclesLoginTestResult,
|
||||
AdminCloudtentaclesPersistedSession,
|
||||
AdminCloudtentaclesSendSmsResult,
|
||||
AdminCloudtentaclesSessionItem,
|
||||
AdminCloudtentaclesSessionsMap,
|
||||
AdminCloudtentaclesValidateSessionResult,
|
||||
} from '@/types/admin'
|
||||
import AdminCloudtentaclesInfoCard from './AdminCloudtentaclesInfoCard.vue'
|
||||
@@ -25,10 +27,16 @@ type CloudtentaclesForm = {
|
||||
deviceType: number
|
||||
}
|
||||
|
||||
type SourceOption = {
|
||||
key: string
|
||||
label: string
|
||||
}
|
||||
|
||||
type CloudtentaclesStats = {
|
||||
hasCredential: boolean
|
||||
smsSent: boolean
|
||||
validated: boolean
|
||||
sourceCount: number
|
||||
}
|
||||
|
||||
type Props = {
|
||||
@@ -47,6 +55,10 @@ type Props = {
|
||||
cloudtentaclesDebugResult: string
|
||||
cloudtentaclesPersistedSession: AdminCloudtentaclesPersistedSession | null
|
||||
cloudtentaclesStats: CloudtentaclesStats
|
||||
sources: AdminCloudtentaclesSourceItem[]
|
||||
sessions: AdminCloudtentaclesSessionsMap
|
||||
selectedSourceKey: string
|
||||
sourceOptions: SourceOption[]
|
||||
handleCloudtentaclesSaveSource: () => void | Promise<void>
|
||||
handleCloudtentaclesSendSmsCode: () => void | Promise<void>
|
||||
handleCloudtentaclesTestLogin: () => void | Promise<void>
|
||||
@@ -65,6 +77,9 @@ type Props = {
|
||||
handleCloudtentaclesFetchBindUrl: () => void | Promise<void>
|
||||
handleCloudtentaclesBackVn: () => void | Promise<void>
|
||||
handleCloudtentaclesRunFullFlow: () => void | Promise<void>
|
||||
switchSource: (sourceKey: string) => void
|
||||
addSource: () => void
|
||||
removeSource: (sourceKey: string) => void
|
||||
}
|
||||
|
||||
defineProps<Props>()
|
||||
@@ -76,6 +91,9 @@ defineProps<Props>()
|
||||
:cloudtentacles-file-path="cloudtentaclesFilePath"
|
||||
:cloudtentacles-session-file-path="cloudtentaclesSessionFilePath"
|
||||
:cloudtentacles-persisted-session="cloudtentaclesPersistedSession"
|
||||
:sources="sources"
|
||||
:sessions="sessions"
|
||||
:selected-source-key="selectedSourceKey"
|
||||
/>
|
||||
|
||||
<AdminCloudtentaclesConfigCard
|
||||
@@ -88,10 +106,16 @@ defineProps<Props>()
|
||||
:cloudtentacles-sms-result="cloudtentaclesSmsResult"
|
||||
:cloudtentacles-login-result="cloudtentaclesLoginResult"
|
||||
:cloudtentacles-validate-result="cloudtentaclesValidateResult"
|
||||
:selected-source-key="selectedSourceKey"
|
||||
:source-options="sourceOptions"
|
||||
:sources="sources"
|
||||
:handle-cloudtentacles-save-source="handleCloudtentaclesSaveSource"
|
||||
:handle-cloudtentacles-send-sms-code="handleCloudtentaclesSendSmsCode"
|
||||
:handle-cloudtentacles-test-login="handleCloudtentaclesTestLogin"
|
||||
:handle-cloudtentacles-validate-session="handleCloudtentaclesValidateSession"
|
||||
:switch-source="switchSource"
|
||||
:add-source="addSource"
|
||||
:remove-source="removeSource"
|
||||
/>
|
||||
|
||||
<AdminCloudtentaclesDebugCard
|
||||
|
||||
+181
-42
@@ -2,6 +2,7 @@ import { computed, ref } from 'vue'
|
||||
|
||||
import { showError, showSuccess } from '@/lib/feedback'
|
||||
import {
|
||||
deleteAdminCloudtentaclesSource,
|
||||
saveAdminCloudtentaclesSourceConfig,
|
||||
sendAdminCloudtentaclesSmsCode,
|
||||
testAdminCloudtentaclesLogin,
|
||||
@@ -11,7 +12,10 @@ import type {
|
||||
AdminCloudtentaclesLoginTestResult,
|
||||
AdminCloudtentaclesPersistedSession,
|
||||
AdminCloudtentaclesSendSmsResult,
|
||||
AdminCloudtentaclesSourceConfig,
|
||||
AdminCloudtentaclesSourceItem,
|
||||
AdminCloudtentaclesSessionsMap,
|
||||
AdminCloudtentaclesSourceConfigResponse,
|
||||
AdminCloudtentaclesSourcesConfig,
|
||||
AdminCloudtentaclesValidateSessionResult,
|
||||
} from '@/types/admin'
|
||||
|
||||
@@ -21,6 +25,11 @@ import { useCloudtentaclesDebugActions } from './useCloudtentaclesDebugActions'
|
||||
export function useAdminCloudtentaclesPlatform() {
|
||||
const cloudtentaclesFilePath = ref('')
|
||||
const cloudtentaclesSessionFilePath = ref('')
|
||||
const selectedSourceKey = ref('default')
|
||||
|
||||
const sources = ref<AdminCloudtentaclesSourceItem[]>([])
|
||||
const sessions = ref<AdminCloudtentaclesSessionsMap>({})
|
||||
|
||||
const cloudtentaclesForm = ref<CloudtentaclesForm>({
|
||||
baseUrl: 'https://123.207.217.176',
|
||||
username: '',
|
||||
@@ -45,66 +54,179 @@ export function useAdminCloudtentaclesPlatform() {
|
||||
const cloudtentaclesValidateResult = ref<AdminCloudtentaclesValidateSessionResult | null>(null)
|
||||
const cloudtentaclesPersistedSession = ref<AdminCloudtentaclesPersistedSession | null>(null)
|
||||
|
||||
const debugActions = useCloudtentaclesDebugActions(cloudtentaclesForm, cloudtentaclesResultError)
|
||||
const debugActions = useCloudtentaclesDebugActions(
|
||||
cloudtentaclesForm,
|
||||
cloudtentaclesResultError,
|
||||
selectedSourceKey,
|
||||
)
|
||||
|
||||
const sourceOptions = computed(() =>
|
||||
sources.value.map((s) => ({ key: s.key, label: s.label })),
|
||||
)
|
||||
|
||||
const currentSource = computed(
|
||||
() => sources.value.find((s) => s.key === selectedSourceKey.value) || sources.value[0],
|
||||
)
|
||||
|
||||
const currentSession = computed(
|
||||
() => sessions.value[selectedSourceKey.value] || null,
|
||||
)
|
||||
|
||||
const cloudtentaclesStats = computed(() => ({
|
||||
hasCredential: Boolean(
|
||||
cloudtentaclesForm.value.username.trim() &&
|
||||
cloudtentaclesForm.value.password.trim() &&
|
||||
cloudtentaclesForm.value.phone.trim(),
|
||||
cloudtentaclesForm.value.password.trim() &&
|
||||
cloudtentaclesForm.value.phone.trim(),
|
||||
),
|
||||
smsSent: Boolean(cloudtentaclesSmsResult.value),
|
||||
validated: Boolean(cloudtentaclesValidateResult.value || cloudtentaclesLoginResult.value),
|
||||
sourceCount: sources.value.length,
|
||||
}))
|
||||
|
||||
function hydrateCloudtentaclesConfig(data: {
|
||||
filePath: string
|
||||
sessionFilePath: string
|
||||
session: AdminCloudtentaclesPersistedSession
|
||||
source: {
|
||||
baseUrl?: string
|
||||
username?: string
|
||||
password?: string
|
||||
phone?: string
|
||||
deviceId?: string
|
||||
deviceType?: number
|
||||
}
|
||||
}) {
|
||||
function hydrateCloudtentaclesConfig(data: AdminCloudtentaclesSourceConfigResponse) {
|
||||
cloudtentaclesFilePath.value = data.filePath
|
||||
cloudtentaclesSessionFilePath.value = data.sessionFilePath
|
||||
cloudtentaclesPersistedSession.value = data.session
|
||||
cloudtentaclesForm.value = {
|
||||
baseUrl: data.source.baseUrl || 'https://123.207.217.176',
|
||||
username: data.source.username || '',
|
||||
password: data.source.password || '',
|
||||
phone: data.source.phone || '',
|
||||
code: '',
|
||||
token: data.session?.token || '',
|
||||
vnKey: '1',
|
||||
vnId: 0,
|
||||
skuId: 5,
|
||||
skuCount: 1,
|
||||
deviceId: data.source.deviceId || '-',
|
||||
deviceType: data.source.deviceType || 0,
|
||||
sources.value = data.sources || []
|
||||
sessions.value = data.sessions || {}
|
||||
|
||||
// Ensure 'default' always exists
|
||||
if (!sources.value.length) {
|
||||
sources.value.push({
|
||||
key: 'default',
|
||||
label: '默认账号',
|
||||
baseUrl: 'https://123.207.217.176',
|
||||
username: '',
|
||||
password: '',
|
||||
phone: '',
|
||||
deviceId: '-',
|
||||
deviceType: 0,
|
||||
})
|
||||
}
|
||||
|
||||
// Default selectedSourceKey to 'default' or first source
|
||||
if (!sources.value.find((s) => s.key === selectedSourceKey.value)) {
|
||||
selectedSourceKey.value = sources.value[0].key
|
||||
}
|
||||
|
||||
// Hydrate form from the currently selected source
|
||||
hydrateFormFromSource(selectedSourceKey.value)
|
||||
}
|
||||
|
||||
function hydrateFormFromSource(sourceKey: string) {
|
||||
const source = sources.value.find((s) => s.key === sourceKey)
|
||||
const session = sessions.value[sourceKey]
|
||||
if (source) {
|
||||
cloudtentaclesForm.value = {
|
||||
baseUrl: source.baseUrl || 'https://123.207.217.176',
|
||||
username: source.username || '',
|
||||
password: source.password || '',
|
||||
phone: source.phone || '',
|
||||
code: '',
|
||||
token: session?.token || '',
|
||||
vnKey: '1',
|
||||
vnId: 0,
|
||||
skuId: 5,
|
||||
skuCount: 1,
|
||||
deviceId: source.deviceId || '-',
|
||||
deviceType: source.deviceType || 0,
|
||||
}
|
||||
}
|
||||
cloudtentaclesPersistedSession.value = session || null
|
||||
}
|
||||
|
||||
function switchSource(sourceKey: string) {
|
||||
selectedSourceKey.value = sourceKey
|
||||
// Clear transient results when switching
|
||||
cloudtentaclesSmsResult.value = null
|
||||
cloudtentaclesLoginResult.value = null
|
||||
cloudtentaclesValidateResult.value = null
|
||||
cloudtentaclesResultError.value = ''
|
||||
hydrateFormFromSource(sourceKey)
|
||||
}
|
||||
|
||||
function addSource() {
|
||||
const newKey = `account${sources.value.length + 1}`
|
||||
const newSource: AdminCloudtentaclesSourceItem = {
|
||||
key: newKey,
|
||||
label: `备用账号 ${sources.value.length}`,
|
||||
baseUrl: 'https://123.207.217.176',
|
||||
username: '',
|
||||
password: '',
|
||||
phone: '',
|
||||
deviceId: '-',
|
||||
deviceType: 0,
|
||||
}
|
||||
sources.value.push(newSource)
|
||||
selectedSourceKey.value = newKey
|
||||
hydrateFormFromSource(newKey)
|
||||
}
|
||||
|
||||
async function removeSource(sourceKey: string) {
|
||||
if (sourceKey === 'default') {
|
||||
showError('默认账号不可删除')
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
cloudtentaclesSaving.value = true
|
||||
await deleteAdminCloudtentaclesSource(sourceKey)
|
||||
sources.value = sources.value.filter((s) => s.key !== sourceKey)
|
||||
delete sessions.value[sourceKey]
|
||||
if (selectedSourceKey.value === sourceKey) {
|
||||
selectedSourceKey.value = 'default'
|
||||
hydrateFormFromSource('default')
|
||||
}
|
||||
showSuccess('账号已删除')
|
||||
} catch (error) {
|
||||
showError(error instanceof Error ? error.message : '删除账号失败')
|
||||
} finally {
|
||||
cloudtentaclesSaving.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function buildCloudtentaclesConfigPayload(): AdminCloudtentaclesSourceConfig {
|
||||
function buildCloudtentaclesConfigPayload(): AdminCloudtentaclesSourcesConfig {
|
||||
// Update current source from form
|
||||
const current = sources.value.find((s) => s.key === selectedSourceKey.value)
|
||||
if (current) {
|
||||
current.baseUrl = cloudtentaclesForm.value.baseUrl.trim() || 'https://123.207.217.176'
|
||||
current.username = cloudtentaclesForm.value.username.trim()
|
||||
current.password = cloudtentaclesForm.value.password.trim()
|
||||
current.phone = cloudtentaclesForm.value.phone.trim()
|
||||
current.deviceId = cloudtentaclesForm.value.deviceId.trim() || '-'
|
||||
current.deviceType = Number(cloudtentaclesForm.value.deviceType || 0)
|
||||
}
|
||||
return {
|
||||
enabled: true,
|
||||
sources: sources.value.map((s) => ({
|
||||
key: s.key,
|
||||
label: s.label,
|
||||
baseUrl: s.baseUrl,
|
||||
username: s.username,
|
||||
password: s.password,
|
||||
phone: s.phone,
|
||||
deviceId: s.deviceId,
|
||||
deviceType: s.deviceType,
|
||||
})),
|
||||
}
|
||||
}
|
||||
|
||||
function buildCloudtentaclesLoginPayload() {
|
||||
return {
|
||||
...buildCloudtentaclesSourcePayload(),
|
||||
code: cloudtentaclesForm.value.code.trim(),
|
||||
sourceKey: selectedSourceKey.value,
|
||||
}
|
||||
}
|
||||
|
||||
function buildCloudtentaclesSourcePayload() {
|
||||
return {
|
||||
baseUrl: cloudtentaclesForm.value.baseUrl.trim() || 'https://123.207.217.176',
|
||||
username: cloudtentaclesForm.value.username.trim(),
|
||||
password: cloudtentaclesForm.value.password.trim(),
|
||||
phone: cloudtentaclesForm.value.phone.trim(),
|
||||
deviceId: cloudtentaclesForm.value.deviceId.trim() || '-',
|
||||
deviceType: Number(cloudtentaclesForm.value.deviceType || 0),
|
||||
}
|
||||
}
|
||||
|
||||
function buildCloudtentaclesLoginPayload() {
|
||||
return {
|
||||
...buildCloudtentaclesConfigPayload(),
|
||||
code: cloudtentaclesForm.value.code.trim(),
|
||||
sourceKey: selectedSourceKey.value,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,8 +264,11 @@ export function useAdminCloudtentaclesPlatform() {
|
||||
const response = await saveAdminCloudtentaclesSourceConfig(buildCloudtentaclesConfigPayload())
|
||||
cloudtentaclesFilePath.value = response.data.filePath
|
||||
cloudtentaclesSessionFilePath.value = response.data.sessionFilePath
|
||||
cloudtentaclesPersistedSession.value = response.data.session
|
||||
cloudtentaclesForm.value.token = response.data.session?.token || ''
|
||||
sources.value = response.data.sources
|
||||
sessions.value = response.data.sessions
|
||||
const session = sessions.value[selectedSourceKey.value]
|
||||
cloudtentaclesPersistedSession.value = session || null
|
||||
cloudtentaclesForm.value.token = session?.token || ''
|
||||
showSuccess('cloudtentacles 履约平台配置已保存')
|
||||
} catch (error) {
|
||||
cloudtentaclesResultError.value =
|
||||
@@ -163,7 +288,7 @@ export function useAdminCloudtentaclesPlatform() {
|
||||
cloudtentaclesResultError.value = ''
|
||||
|
||||
try {
|
||||
const response = await sendAdminCloudtentaclesSmsCode(buildCloudtentaclesConfigPayload())
|
||||
const response = await sendAdminCloudtentaclesSmsCode(buildCloudtentaclesSourcePayload())
|
||||
cloudtentaclesSmsResult.value = response.data
|
||||
showSuccess('cloudtentacles 短信验证码已发送')
|
||||
} catch (error) {
|
||||
@@ -198,6 +323,8 @@ export function useAdminCloudtentaclesPlatform() {
|
||||
deviceType: Number(cloudtentaclesForm.value.deviceType || 0),
|
||||
hasToken: Boolean(response.data.token),
|
||||
}
|
||||
// Update sessions map
|
||||
sessions.value[selectedSourceKey.value] = cloudtentaclesPersistedSession.value
|
||||
showSuccess('cloudtentacles 登录测试成功')
|
||||
} catch (error) {
|
||||
cloudtentaclesResultError.value =
|
||||
@@ -224,6 +351,7 @@ export function useAdminCloudtentaclesPlatform() {
|
||||
token,
|
||||
deviceId: cloudtentaclesForm.value.deviceId.trim() || '-',
|
||||
deviceType: Number(cloudtentaclesForm.value.deviceType || 0),
|
||||
sourceKey: selectedSourceKey.value,
|
||||
})
|
||||
cloudtentaclesValidateResult.value = response.data
|
||||
cloudtentaclesPersistedSession.value = {
|
||||
@@ -239,6 +367,8 @@ export function useAdminCloudtentaclesPlatform() {
|
||||
deviceType: Number(cloudtentaclesForm.value.deviceType || 0),
|
||||
hasToken: Boolean(token),
|
||||
}
|
||||
// Update sessions map
|
||||
sessions.value[selectedSourceKey.value] = cloudtentaclesPersistedSession.value
|
||||
showSuccess('cloudtentacles 会话校验成功')
|
||||
} catch (error) {
|
||||
cloudtentaclesResultError.value =
|
||||
@@ -265,7 +395,16 @@ export function useAdminCloudtentaclesPlatform() {
|
||||
cloudtentaclesDebugResult: debugActions.cloudtentaclesDebugResult,
|
||||
cloudtentaclesPersistedSession,
|
||||
cloudtentaclesStats,
|
||||
sources,
|
||||
sessions,
|
||||
selectedSourceKey,
|
||||
sourceOptions,
|
||||
currentSource,
|
||||
currentSession,
|
||||
hydrateCloudtentaclesConfig,
|
||||
switchSource,
|
||||
addSource,
|
||||
removeSource,
|
||||
handleCloudtentaclesSaveSource,
|
||||
handleCloudtentaclesSendSmsCode,
|
||||
handleCloudtentaclesTestLogin,
|
||||
|
||||
+2
@@ -35,6 +35,7 @@ export type CloudtentaclesForm = {
|
||||
export function useCloudtentaclesDebugActions(
|
||||
cloudtentaclesForm: { value: CloudtentaclesForm },
|
||||
cloudtentaclesResultError: { value: string },
|
||||
selectedSourceKey: { value: string },
|
||||
) {
|
||||
const cloudtentaclesDebugLoading = ref(false)
|
||||
const cloudtentaclesDebugResult = ref('')
|
||||
@@ -45,6 +46,7 @@ export function useCloudtentaclesDebugActions(
|
||||
token: cloudtentaclesForm.value.token.trim(),
|
||||
deviceId: cloudtentaclesForm.value.deviceId.trim() || '-',
|
||||
deviceType: Number(cloudtentaclesForm.value.deviceType || 0),
|
||||
sourceKey: selectedSourceKey.value,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user