增加 cloudtentacles发货平台

This commit is contained in:
yml2213
2026-05-02 21:41:43 +08:00
parent dc32eef08b
commit 5b747c7460
20 changed files with 2698 additions and 9 deletions
@@ -15,6 +15,16 @@ import { syncKhhaoOrders } from '../platforms/khhao/order-sync-service.js'
import { getKhhaoSourceConfig, getKhhaoSourcesFilePath, saveKhhaoSourceConfig } from '../platforms/khhao/source-config-service.js'
import { ensureKhhaoSyncBaseline, getKhhaoSyncState, getKhhaoSyncStateFilePath } from '../platforms/khhao/sync-state-service.js'
import { loginKhhaoSession } from '../platforms/khhao/session-service.js'
import {
getCloudtentaclesSourceConfig,
getCloudtentaclesSourcesFilePath,
saveCloudtentaclesSourceConfig,
} from '../platforms/cloudtentacles/source-config-service.js'
import {
loginCloudtentaclesSession,
sendCloudtentaclesSmsCode,
validateCloudtentaclesSession,
} from '../platforms/cloudtentacles/session-service.js'
import { normalizeAgisoMessageTemplate } from '../platforms/agiso/xianyu/message-service.js'
import {
getOrderFulfillmentBindingConfigs,
@@ -32,6 +42,10 @@ import { resolveDisplayShopName } from './admin-read-shared-helpers.js'
/** @typedef {import('../../types/admin-write-inputs.js').AdminKhhaoSourceConfigInput} AdminKhhaoSourceConfigInput */
/** @typedef {import('../../types/admin-write-inputs.js').AdminKhhaoOrderQueryInput} AdminKhhaoOrderQueryInput */
/** @typedef {import('../../types/admin-write-inputs.js').AdminKhhaoTestLoginInput} AdminKhhaoTestLoginInput */
/** @typedef {import('../../types/admin-write-inputs.js').AdminCloudtentaclesSourceConfigInput} AdminCloudtentaclesSourceConfigInput */
/** @typedef {import('../../types/admin-write-inputs.js').AdminCloudtentaclesSendSmsCodeInput} AdminCloudtentaclesSendSmsCodeInput */
/** @typedef {import('../../types/admin-write-inputs.js').AdminCloudtentaclesTestLoginInput} AdminCloudtentaclesTestLoginInput */
/** @typedef {import('../../types/admin-write-inputs.js').AdminCloudtentaclesValidateSessionInput} AdminCloudtentaclesValidateSessionInput */
/** @typedef {import('../../types/admin-write-inputs.js').AdminFulfillmentBindingConfigSaveInput} AdminFulfillmentBindingConfigSaveInput */
/** @typedef {import('../../types/admin-write-inputs.js').AdminFulfillmentBindingLookupInput} AdminFulfillmentBindingLookupInput */
@@ -336,6 +350,119 @@ export async function syncAdminKhhaoOrders(payload = /** @type {AdminKhhaoOrderQ
})
}
export function getAdminCloudtentaclesSourceConfig() {
const config = getCloudtentaclesSourceConfig()
return {
filePath: getCloudtentaclesSourcesFilePath(),
source: {
enabled: config.enabled !== false,
baseUrl: String(config.baseUrl || '').trim(),
username: String(config.username || '').trim(),
password: String(config.password || '').trim(),
phone: String(config.phone || '').trim(),
deviceId: String(config.deviceId || '-').trim() || '-',
deviceType: Number(config.deviceType || 0),
},
}
}
/** @param {AdminCloudtentaclesSourceConfigInput} [payload] */
export function updateAdminCloudtentaclesSourceConfig(payload = /** @type {AdminCloudtentaclesSourceConfigInput} */ ({})) {
const saved = saveCloudtentaclesSourceConfig({
enabled: payload.enabled !== false,
baseUrl: String(payload.baseUrl || '').trim() || 'https://123.207.217.176',
username: String(payload.username || '').trim(),
password: String(payload.password || '').trim(),
phone: String(payload.phone || '').trim(),
deviceId: String(payload.deviceId || '-').trim() || '-',
deviceType: Number(payload.deviceType || 0),
})
return {
filePath: getCloudtentaclesSourcesFilePath(),
source: {
enabled: saved.enabled !== false,
baseUrl: String(saved.baseUrl || '').trim(),
username: String(saved.username || '').trim(),
password: String(saved.password || '').trim(),
phone: String(saved.phone || '').trim(),
deviceId: String(saved.deviceId || '-').trim() || '-',
deviceType: Number(saved.deviceType || 0),
},
}
}
/** @param {AdminCloudtentaclesSendSmsCodeInput} [payload] */
export async function sendAdminCloudtentaclesSmsCode(payload = /** @type {AdminCloudtentaclesSendSmsCodeInput} */ ({})) {
const savedSource = getCloudtentaclesSourceConfig()
const result = await sendCloudtentaclesSmsCode({
baseUrl: pickFirstNonEmpty([payload.baseUrl, savedSource.baseUrl, 'https://123.207.217.176']),
username: pickFirstNonEmpty([payload.username, savedSource.username]),
phone: pickFirstNonEmpty([payload.phone, savedSource.phone]),
deviceId: pickFirstNonEmpty([payload.deviceId, savedSource.deviceId, '-']),
deviceType: payload.deviceType ?? savedSource.deviceType,
})
return {
...result,
phoneMasked: maskPhone(result.phone),
}
}
/** @param {AdminCloudtentaclesTestLoginInput} [payload] */
export async function testAdminCloudtentaclesLogin(payload = /** @type {AdminCloudtentaclesTestLoginInput} */ ({})) {
const savedSource = getCloudtentaclesSourceConfig()
const session = await loginCloudtentaclesSession({
baseUrl: pickFirstNonEmpty([payload.baseUrl, savedSource.baseUrl, 'https://123.207.217.176']),
username: pickFirstNonEmpty([payload.username, savedSource.username]),
password: pickFirstNonEmpty([payload.password, savedSource.password]),
phone: pickFirstNonEmpty([payload.phone, savedSource.phone]),
code: String(payload.code || '').trim(),
deviceId: pickFirstNonEmpty([payload.deviceId, savedSource.deviceId, '-']),
deviceType: payload.deviceType ?? savedSource.deviceType,
})
return {
baseUrl: session.baseUrl,
username: session.username,
phoneMasked: maskPhone(session.phone),
loggedInAt: session.loggedInAt,
responseMessage: session.responseMessage,
token: session.token,
session: {
tokenMasked: maskSecret(session.token),
permissionCount: session.permissions.length,
permissions: session.permissions,
},
userInfo: session.userInfo,
asset: session.asset,
}
}
/** @param {AdminCloudtentaclesValidateSessionInput} [payload] */
export async function validateAdminCloudtentaclesSession(payload = /** @type {AdminCloudtentaclesValidateSessionInput} */ ({})) {
const savedSource = getCloudtentaclesSourceConfig()
const session = await validateCloudtentaclesSession({
baseUrl: pickFirstNonEmpty([payload.baseUrl, savedSource.baseUrl, 'https://123.207.217.176']),
token: String(payload.token || '').trim(),
deviceId: pickFirstNonEmpty([payload.deviceId, savedSource.deviceId, '-']),
deviceType: payload.deviceType ?? savedSource.deviceType,
})
return {
baseUrl: session.baseUrl,
loggedInAt: session.loggedInAt,
session: {
tokenMasked: maskSecret(session.token),
permissionCount: session.permissions.length,
permissions: session.permissions,
},
userInfo: session.userInfo,
asset: session.asset,
}
}
export async function getAdminFulfillmentBindingConfigs() {
const bindings = getOrderFulfillmentBindingConfigs()
const rowsResult = await query(
@@ -685,6 +812,19 @@ function maskSecret(value) {
return `${normalized.slice(0, 6)}****${normalized.slice(-6)}`
}
function maskPhone(value) {
const normalized = String(value || '').trim()
if (!normalized) {
return ''
}
if (normalized.length < 7) {
return normalized
}
return `${normalized.slice(0, 3)}****${normalized.slice(-4)}`
}
function isPlainObject(value) {
return Boolean(value) && typeof value === 'object' && !Array.isArray(value)
}