按平台拆分后台平台配置服务
This commit is contained in:
@@ -0,0 +1,68 @@
|
|||||||
|
// @ts-check
|
||||||
|
|
||||||
|
import { query } from '../../../db/client.js'
|
||||||
|
import {
|
||||||
|
getAgisoMessagingDefaults,
|
||||||
|
getAgisoShopConfigMap,
|
||||||
|
getAgisoShopsFilePath,
|
||||||
|
saveAgisoMessagingConfig,
|
||||||
|
} from '../../platforms/agiso/shop-config-service.js'
|
||||||
|
import { resolveDisplayShopName } from '../admin-read-shared-helpers.js'
|
||||||
|
import {
|
||||||
|
mapAdminAgisoMessagingDefaults,
|
||||||
|
mapAdminAgisoShopConfigItem,
|
||||||
|
} from './domain.js'
|
||||||
|
import { buildAdminAgisoMessagingSavePayload } from './writes.js'
|
||||||
|
|
||||||
|
/** @typedef {import('../../../types/admin-write-inputs.js').AdminAgisoShopConfigSaveInput} AdminAgisoShopConfigSaveInput */
|
||||||
|
|
||||||
|
export async function getAdminAgisoShopConfigs() {
|
||||||
|
const configMap = getAgisoShopConfigMap()
|
||||||
|
const defaults = getAgisoMessagingDefaults()
|
||||||
|
const rowsResult = await query(
|
||||||
|
`
|
||||||
|
SELECT
|
||||||
|
shop_id,
|
||||||
|
MAX(CASE WHEN trim(shop_name) != '' THEN shop_name ELSE '' END) AS detected_shop_name,
|
||||||
|
MAX(created_at) AS latest_seen_at,
|
||||||
|
COUNT(*)::int AS webhook_event_count
|
||||||
|
FROM webhook_events
|
||||||
|
WHERE provider = 'agiso' AND trim(shop_id) != ''
|
||||||
|
GROUP BY shop_id
|
||||||
|
ORDER BY latest_seen_at DESC, shop_id DESC
|
||||||
|
`,
|
||||||
|
)
|
||||||
|
const rows = rowsResult.rows
|
||||||
|
|
||||||
|
return {
|
||||||
|
filePath: getAgisoShopsFilePath(),
|
||||||
|
defaults: mapAdminAgisoMessagingDefaults(defaults),
|
||||||
|
shops: Object.entries(configMap)
|
||||||
|
.sort(([left], [right]) => left.localeCompare(right))
|
||||||
|
.map(([shopId, config]) => mapAdminAgisoShopConfigItem(shopId, config)),
|
||||||
|
observedShops: rows.map((row) => ({
|
||||||
|
shopId: String(row.shop_id || '').trim(),
|
||||||
|
detectedShopName: String(row.detected_shop_name || '').trim(),
|
||||||
|
displayShopName: resolveDisplayShopName('agiso', row.shop_id, row.detected_shop_name),
|
||||||
|
latestSeenAt: row.latest_seen_at || null,
|
||||||
|
webhookEventCount: Number(row.webhook_event_count || 0),
|
||||||
|
configured: Boolean(configMap[String(row.shop_id || '').trim()]),
|
||||||
|
})),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {AdminAgisoShopConfigSaveInput} [payload] */
|
||||||
|
export function updateAdminAgisoShopConfigs(payload = /** @type {AdminAgisoShopConfigSaveInput} */ ({})) {
|
||||||
|
const saved = saveAgisoMessagingConfig(buildAdminAgisoMessagingSavePayload(payload, {
|
||||||
|
currentDefaults: getAgisoMessagingDefaults(),
|
||||||
|
currentMap: getAgisoShopConfigMap(),
|
||||||
|
}))
|
||||||
|
|
||||||
|
return {
|
||||||
|
filePath: getAgisoShopsFilePath(),
|
||||||
|
defaults: mapAdminAgisoMessagingDefaults(saved.defaults),
|
||||||
|
shops: Object.entries(saved.shops)
|
||||||
|
.sort(([left], [right]) => left.localeCompare(right))
|
||||||
|
.map(([shopId, config]) => mapAdminAgisoShopConfigItem(shopId, config)),
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,250 @@
|
|||||||
|
// @ts-check
|
||||||
|
|
||||||
|
import {
|
||||||
|
getCloudtentaclesSourceConfig,
|
||||||
|
getCloudtentaclesSourcesFilePath,
|
||||||
|
saveCloudtentaclesSourceConfig,
|
||||||
|
} from '../../platforms/cloudtentacles/source-config-service.js'
|
||||||
|
import {
|
||||||
|
clearCloudtentaclesSessionState,
|
||||||
|
getCloudtentaclesSessionFilePath,
|
||||||
|
getCloudtentaclesSessionState,
|
||||||
|
saveCloudtentaclesSessionState,
|
||||||
|
} from '../../platforms/cloudtentacles/session-state-service.js'
|
||||||
|
import {
|
||||||
|
loginCloudtentaclesSession,
|
||||||
|
sendCloudtentaclesSmsCode,
|
||||||
|
validateCloudtentaclesSession,
|
||||||
|
} from '../../platforms/cloudtentacles/session-service.js'
|
||||||
|
import {
|
||||||
|
buyCloudtentaclesSku,
|
||||||
|
getCloudtentaclesAsset,
|
||||||
|
getCloudtentaclesCategories,
|
||||||
|
listCloudtentaclesSku,
|
||||||
|
useCloudtentaclesSku,
|
||||||
|
} from '../../platforms/cloudtentacles/catalog-service.js'
|
||||||
|
import { getCloudtentaclesKnapsack } from '../../platforms/cloudtentacles/knapsack-service.js'
|
||||||
|
import {
|
||||||
|
appointCloudtentaclesVirtualNumber,
|
||||||
|
backCloudtentaclesVirtualNumber,
|
||||||
|
fetchCloudtentaclesVirtualNumberCode,
|
||||||
|
generateCloudtentaclesLoginCode,
|
||||||
|
getCloudtentaclesBindUrl,
|
||||||
|
listCloudtentaclesVirtualNumbers,
|
||||||
|
verifyCloudtentaclesLoginCode,
|
||||||
|
} from '../../platforms/cloudtentacles/virtual-number-service.js'
|
||||||
|
import { runCloudtentaclesFullDebugFlow } from '../../platforms/cloudtentacles/debug-flow-service.js'
|
||||||
|
import { hasCloudtentaclesCredentialContextChanged, pickFirstNonEmpty } from './context.js'
|
||||||
|
import {
|
||||||
|
buildAdminCloudtentaclesLoginResult,
|
||||||
|
buildAdminCloudtentaclesPersistedSessionPayload,
|
||||||
|
buildAdminCloudtentaclesValidateResult,
|
||||||
|
resolveAdminCloudtentaclesCredentialPayload,
|
||||||
|
resolveAdminCloudtentaclesSessionPayload,
|
||||||
|
} from './cloudtentacles.js'
|
||||||
|
import { normalizeAdminCloudtentaclesSourceConfigPayload } from './writes.js'
|
||||||
|
import {
|
||||||
|
mapAdminCloudtentaclesSession,
|
||||||
|
mapAdminCloudtentaclesSourceConfig,
|
||||||
|
maskPhone,
|
||||||
|
} from './mappers.js'
|
||||||
|
|
||||||
|
/** @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').AdminCloudtentaclesCatalogQueryInput} AdminCloudtentaclesCatalogQueryInput */
|
||||||
|
/** @typedef {import('../../../types/admin-write-inputs.js').AdminCloudtentaclesSkuBuyInput} AdminCloudtentaclesSkuBuyInput */
|
||||||
|
/** @typedef {import('../../../types/admin-write-inputs.js').AdminCloudtentaclesSkuUseInput} AdminCloudtentaclesSkuUseInput */
|
||||||
|
/** @typedef {import('../../../types/admin-write-inputs.js').AdminCloudtentaclesVirtualNumberInput} AdminCloudtentaclesVirtualNumberInput */
|
||||||
|
/** @typedef {import('../../../types/admin-write-inputs.js').AdminCloudtentaclesFullFlowInput} AdminCloudtentaclesFullFlowInput */
|
||||||
|
|
||||||
|
export function getAdminCloudtentaclesSourceConfig() {
|
||||||
|
const config = getCloudtentaclesSourceConfig()
|
||||||
|
const session = getCloudtentaclesSessionState()
|
||||||
|
|
||||||
|
return {
|
||||||
|
filePath: getCloudtentaclesSourcesFilePath(),
|
||||||
|
sessionFilePath: getCloudtentaclesSessionFilePath(),
|
||||||
|
source: mapAdminCloudtentaclesSourceConfig(config),
|
||||||
|
session: mapAdminCloudtentaclesSession(session),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {AdminCloudtentaclesSourceConfigInput} [payload] */
|
||||||
|
export function updateAdminCloudtentaclesSourceConfig(payload = /** @type {AdminCloudtentaclesSourceConfigInput} */ ({})) {
|
||||||
|
const current = getCloudtentaclesSourceConfig()
|
||||||
|
const saved = saveCloudtentaclesSourceConfig(normalizeAdminCloudtentaclesSourceConfigPayload(payload))
|
||||||
|
const shouldClearSession = hasCloudtentaclesCredentialContextChanged(current, saved)
|
||||||
|
const session = shouldClearSession ? clearCloudtentaclesSessionState() : getCloudtentaclesSessionState()
|
||||||
|
|
||||||
|
return {
|
||||||
|
filePath: getCloudtentaclesSourcesFilePath(),
|
||||||
|
sessionFilePath: getCloudtentaclesSessionFilePath(),
|
||||||
|
source: mapAdminCloudtentaclesSourceConfig(saved),
|
||||||
|
session: mapAdminCloudtentaclesSession(session),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {AdminCloudtentaclesSendSmsCodeInput} [payload] */
|
||||||
|
export async function sendAdminCloudtentaclesSmsCode(payload = /** @type {AdminCloudtentaclesSendSmsCodeInput} */ ({})) {
|
||||||
|
const result = await sendCloudtentaclesSmsCode(resolveAdminCloudtentaclesCredentialPayload(payload))
|
||||||
|
|
||||||
|
return {
|
||||||
|
...result,
|
||||||
|
phoneMasked: maskPhone(result.phone),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {AdminCloudtentaclesTestLoginInput} [payload] */
|
||||||
|
export async function testAdminCloudtentaclesLogin(payload = /** @type {AdminCloudtentaclesTestLoginInput} */ ({})) {
|
||||||
|
const savedSource = getCloudtentaclesSourceConfig()
|
||||||
|
const credentialContext = resolveAdminCloudtentaclesCredentialPayload(payload, { savedSource })
|
||||||
|
const session = await loginCloudtentaclesSession({
|
||||||
|
...credentialContext,
|
||||||
|
code: String(payload.code || '').trim(),
|
||||||
|
})
|
||||||
|
const savedSession = saveCloudtentaclesSessionState(buildAdminCloudtentaclesPersistedSessionPayload(session, {
|
||||||
|
deviceId: credentialContext.deviceId,
|
||||||
|
deviceType: credentialContext.deviceType,
|
||||||
|
}))
|
||||||
|
|
||||||
|
return buildAdminCloudtentaclesLoginResult(session, savedSession)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {AdminCloudtentaclesValidateSessionInput} [payload] */
|
||||||
|
export async function validateAdminCloudtentaclesSession(payload = /** @type {AdminCloudtentaclesValidateSessionInput} */ ({})) {
|
||||||
|
const savedSource = getCloudtentaclesSourceConfig()
|
||||||
|
const persistedSession = getCloudtentaclesSessionState()
|
||||||
|
const sessionContext = resolveAdminCloudtentaclesSessionPayload(payload, { savedSource, persistedSession })
|
||||||
|
const session = await validateCloudtentaclesSession(sessionContext)
|
||||||
|
const savedSession = saveCloudtentaclesSessionState(buildAdminCloudtentaclesPersistedSessionPayload(session, {
|
||||||
|
username: pickFirstNonEmpty([persistedSession.username, savedSource.username]),
|
||||||
|
phone: pickFirstNonEmpty([persistedSession.phone, savedSource.phone]),
|
||||||
|
deviceId: sessionContext.deviceId,
|
||||||
|
deviceType: sessionContext.deviceType,
|
||||||
|
}))
|
||||||
|
|
||||||
|
return buildAdminCloudtentaclesValidateResult(session, savedSession)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {AdminCloudtentaclesCatalogQueryInput} [payload] */
|
||||||
|
export async function getAdminCloudtentaclesAsset(payload = /** @type {AdminCloudtentaclesCatalogQueryInput} */ ({})) {
|
||||||
|
return getCloudtentaclesAsset(resolveAdminCloudtentaclesSessionPayload(payload))
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {AdminCloudtentaclesCatalogQueryInput} [payload] */
|
||||||
|
export async function getAdminCloudtentaclesCategories(payload = /** @type {AdminCloudtentaclesCatalogQueryInput} */ ({})) {
|
||||||
|
return getCloudtentaclesCategories(resolveAdminCloudtentaclesSessionPayload(payload))
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {AdminCloudtentaclesCatalogQueryInput} [payload] */
|
||||||
|
export async function getAdminCloudtentaclesSkuList(payload = /** @type {AdminCloudtentaclesCatalogQueryInput} */ ({})) {
|
||||||
|
return listCloudtentaclesSku(resolveAdminCloudtentaclesSessionPayload(payload))
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {AdminCloudtentaclesSkuBuyInput} [payload] */
|
||||||
|
export async function buyAdminCloudtentaclesSku(payload = /** @type {AdminCloudtentaclesSkuBuyInput} */ ({})) {
|
||||||
|
const context = resolveAdminCloudtentaclesSessionPayload(payload)
|
||||||
|
return buyCloudtentaclesSku({
|
||||||
|
...context,
|
||||||
|
id: payload.id,
|
||||||
|
count: payload.count,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {AdminCloudtentaclesSkuUseInput} [payload] */
|
||||||
|
export async function useAdminCloudtentaclesSku(payload = /** @type {AdminCloudtentaclesSkuUseInput} */ ({})) {
|
||||||
|
const context = resolveAdminCloudtentaclesSessionPayload(payload)
|
||||||
|
return useCloudtentaclesSku({
|
||||||
|
...context,
|
||||||
|
id: payload.id,
|
||||||
|
virtualNumberId: payload.virtualNumberId,
|
||||||
|
phone: payload.phone,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {AdminCloudtentaclesCatalogQueryInput} [payload] */
|
||||||
|
export async function getAdminCloudtentaclesKnapsack(payload = /** @type {AdminCloudtentaclesCatalogQueryInput} */ ({})) {
|
||||||
|
return getCloudtentaclesKnapsack(resolveAdminCloudtentaclesSessionPayload(payload))
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {AdminCloudtentaclesVirtualNumberInput} [payload] */
|
||||||
|
export async function listAdminCloudtentaclesVirtualNumbers(payload = /** @type {AdminCloudtentaclesVirtualNumberInput} */ ({})) {
|
||||||
|
const context = resolveAdminCloudtentaclesSessionPayload(payload)
|
||||||
|
return listCloudtentaclesVirtualNumbers({
|
||||||
|
...context,
|
||||||
|
key: payload.key,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {AdminCloudtentaclesVirtualNumberInput} [payload] */
|
||||||
|
export async function appointAdminCloudtentaclesVirtualNumber(payload = /** @type {AdminCloudtentaclesVirtualNumberInput} */ ({})) {
|
||||||
|
const context = resolveAdminCloudtentaclesSessionPayload(payload)
|
||||||
|
return appointCloudtentaclesVirtualNumber({
|
||||||
|
...context,
|
||||||
|
key: payload.key,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {AdminCloudtentaclesVirtualNumberInput} [payload] */
|
||||||
|
export async function generateAdminCloudtentaclesLoginCode(payload = /** @type {AdminCloudtentaclesVirtualNumberInput} */ ({})) {
|
||||||
|
const context = resolveAdminCloudtentaclesSessionPayload(payload)
|
||||||
|
return generateCloudtentaclesLoginCode({
|
||||||
|
...context,
|
||||||
|
key: payload.key,
|
||||||
|
id: payload.id,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {AdminCloudtentaclesVirtualNumberInput} [payload] */
|
||||||
|
export async function fetchAdminCloudtentaclesVirtualNumberCode(payload = /** @type {AdminCloudtentaclesVirtualNumberInput} */ ({})) {
|
||||||
|
const context = resolveAdminCloudtentaclesSessionPayload(payload)
|
||||||
|
return fetchCloudtentaclesVirtualNumberCode({
|
||||||
|
...context,
|
||||||
|
key: payload.key,
|
||||||
|
phone: payload.phone,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {AdminCloudtentaclesVirtualNumberInput} [payload] */
|
||||||
|
export async function verifyAdminCloudtentaclesLoginCode(payload = /** @type {AdminCloudtentaclesVirtualNumberInput} */ ({})) {
|
||||||
|
const context = resolveAdminCloudtentaclesSessionPayload(payload)
|
||||||
|
return verifyCloudtentaclesLoginCode({
|
||||||
|
...context,
|
||||||
|
key: payload.key,
|
||||||
|
id: payload.id,
|
||||||
|
code: payload.code,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {AdminCloudtentaclesVirtualNumberInput} [payload] */
|
||||||
|
export async function getAdminCloudtentaclesBindUrl(payload = /** @type {AdminCloudtentaclesVirtualNumberInput} */ ({})) {
|
||||||
|
const context = resolveAdminCloudtentaclesSessionPayload(payload)
|
||||||
|
return getCloudtentaclesBindUrl({
|
||||||
|
...context,
|
||||||
|
key: payload.key,
|
||||||
|
id: payload.id,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {AdminCloudtentaclesVirtualNumberInput} [payload] */
|
||||||
|
export async function backAdminCloudtentaclesVirtualNumber(payload = /** @type {AdminCloudtentaclesVirtualNumberInput} */ ({})) {
|
||||||
|
const context = resolveAdminCloudtentaclesSessionPayload(payload)
|
||||||
|
return backCloudtentaclesVirtualNumber({
|
||||||
|
...context,
|
||||||
|
key: payload.key,
|
||||||
|
id: payload.id,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {AdminCloudtentaclesFullFlowInput} [payload] */
|
||||||
|
export async function runAdminCloudtentaclesFullFlow(payload = /** @type {AdminCloudtentaclesFullFlowInput} */ ({})) {
|
||||||
|
const context = resolveAdminCloudtentaclesSessionPayload(payload)
|
||||||
|
return runCloudtentaclesFullDebugFlow({
|
||||||
|
...context,
|
||||||
|
skuId: payload.skuId,
|
||||||
|
skuCount: payload.skuCount,
|
||||||
|
vnKey: payload.vnKey,
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
// @ts-check
|
||||||
|
|
||||||
|
import { getAgisoShopConfig } from '../../platforms/agiso/shop-config-service.js'
|
||||||
|
import {
|
||||||
|
getOrderFulfillmentBindingConfigs,
|
||||||
|
getOrderFulfillmentBindingsFilePath,
|
||||||
|
saveOrderFulfillmentBindingConfigs,
|
||||||
|
} from '../../order/fulfillment-binding-config-service.js'
|
||||||
|
import { enrichAgisoXianyuTradeOrder } from '../../platforms/agiso/xianyu/order-detail-service.js'
|
||||||
|
import { getKuaishouEticketSourceConfig, resolveKuaishouEticketShopConfig } from '../../platforms/kuaishou-eticket/source-config-service.js'
|
||||||
|
import { syncConfiguredFulfillmentBindings } from '../../bootstrap/fulfillment-bootstrap-service.js'
|
||||||
|
import { getFulfillmentProfileByKey } from '../../../repositories/fulfillment-profile-repo.js'
|
||||||
|
import {
|
||||||
|
buildFulfillmentLookupResult,
|
||||||
|
normalizeFulfillmentLookupPayload,
|
||||||
|
resolveFulfillmentLookupDetail,
|
||||||
|
} from './fulfillment.js'
|
||||||
|
import { listAdminObservedProducts } from './observed-products.js'
|
||||||
|
import { validateAdminFulfillmentBindingConfigs } from './validation.js'
|
||||||
|
import { mapAdminFulfillmentBindingConfigItem } from './domain.js'
|
||||||
|
|
||||||
|
/** @typedef {import('../../../types/admin-write-inputs.js').AdminFulfillmentBindingConfigSaveInput} AdminFulfillmentBindingConfigSaveInput */
|
||||||
|
/** @typedef {import('../../../types/admin-write-inputs.js').AdminFulfillmentBindingLookupInput} AdminFulfillmentBindingLookupInput */
|
||||||
|
|
||||||
|
export async function getAdminFulfillmentBindingConfigs() {
|
||||||
|
const bindings = getOrderFulfillmentBindingConfigs()
|
||||||
|
|
||||||
|
return {
|
||||||
|
filePath: getOrderFulfillmentBindingsFilePath(),
|
||||||
|
bindings: bindings.map(mapAdminFulfillmentBindingConfigItem),
|
||||||
|
observedProducts: await listAdminObservedProducts(bindings),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {AdminFulfillmentBindingLookupInput} [payload] */
|
||||||
|
export async function lookupAdminFulfillmentBindingOrder(payload = /** @type {AdminFulfillmentBindingLookupInput} */ ({})) {
|
||||||
|
const { provider, platform, shopId, platformOrderId } = normalizeFulfillmentLookupPayload(payload)
|
||||||
|
|
||||||
|
const detailResult = await enrichAgisoXianyuTradeOrder({
|
||||||
|
provider,
|
||||||
|
platform,
|
||||||
|
shopId,
|
||||||
|
shopName: '',
|
||||||
|
platformOrderId,
|
||||||
|
orderStatus: 'created',
|
||||||
|
payStatus: 'unpaid',
|
||||||
|
buyerId: '',
|
||||||
|
buyerName: '',
|
||||||
|
receiverContact: '',
|
||||||
|
totalAmount: 0,
|
||||||
|
currency: 'CNY',
|
||||||
|
paidAt: null,
|
||||||
|
rawPayload: {},
|
||||||
|
items: [],
|
||||||
|
}, {
|
||||||
|
requestId: `admin-fulfillment-lookup:${shopId}:${platformOrderId}`,
|
||||||
|
})
|
||||||
|
|
||||||
|
const { detail } = resolveFulfillmentLookupDetail(detailResult, platformOrderId)
|
||||||
|
const bindings = getOrderFulfillmentBindingConfigs()
|
||||||
|
return buildFulfillmentLookupResult({
|
||||||
|
provider,
|
||||||
|
platform,
|
||||||
|
shopId,
|
||||||
|
platformOrderId,
|
||||||
|
detail,
|
||||||
|
detailResult,
|
||||||
|
bindings,
|
||||||
|
fallbackShopName: getAgisoShopConfig(shopId)?.shopName,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {AdminFulfillmentBindingConfigSaveInput} [payload] */
|
||||||
|
export async function updateAdminFulfillmentBindingConfigs(
|
||||||
|
payload = /** @type {AdminFulfillmentBindingConfigSaveInput} */ ({}),
|
||||||
|
) {
|
||||||
|
const bindingsInput = Array.isArray(payload.bindings) ? payload.bindings : []
|
||||||
|
const normalizedBindings = await validateAdminFulfillmentBindingConfigs(bindingsInput, {
|
||||||
|
kuaishouEticketSource: getKuaishouEticketSourceConfig(),
|
||||||
|
resolveKuaishouEticketShopConfig,
|
||||||
|
getFulfillmentProfileByKey,
|
||||||
|
})
|
||||||
|
const saved = saveOrderFulfillmentBindingConfigs(normalizedBindings)
|
||||||
|
await syncConfiguredFulfillmentBindings()
|
||||||
|
|
||||||
|
return {
|
||||||
|
filePath: getOrderFulfillmentBindingsFilePath(),
|
||||||
|
bindings: saved.map(mapAdminFulfillmentBindingConfigItem),
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
// @ts-check
|
||||||
|
|
||||||
|
import { queryKhhaoOrderList } from '../../platforms/khhao/order-query-service.js'
|
||||||
|
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 {
|
||||||
|
buildAdminKhhaoLoginPayload,
|
||||||
|
buildAdminKhhaoLoginResult,
|
||||||
|
buildAdminKhhaoOrderQueryResult,
|
||||||
|
buildAdminKhhaoSyncPayload,
|
||||||
|
resolveAdminKhhaoCredentialPayload,
|
||||||
|
} from './khhao.js'
|
||||||
|
import { normalizeAdminKhhaoSourceConfigPayload } from './writes.js'
|
||||||
|
import {
|
||||||
|
mapAdminKhhaoSourceConfig,
|
||||||
|
mapAdminKhhaoSyncState,
|
||||||
|
} from './mappers.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 */
|
||||||
|
|
||||||
|
export function getAdminKhhaoSourceConfig() {
|
||||||
|
const config = getKhhaoSourceConfig()
|
||||||
|
const syncState = getKhhaoSyncState()
|
||||||
|
|
||||||
|
return {
|
||||||
|
filePath: getKhhaoSourcesFilePath(),
|
||||||
|
stateFilePath: getKhhaoSyncStateFilePath(),
|
||||||
|
source: mapAdminKhhaoSourceConfig(config),
|
||||||
|
syncState: mapAdminKhhaoSyncState(syncState),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {AdminKhhaoSourceConfigInput} [payload] */
|
||||||
|
export function updateAdminKhhaoSourceConfig(payload = /** @type {AdminKhhaoSourceConfigInput} */ ({})) {
|
||||||
|
const saved = saveKhhaoSourceConfig(normalizeAdminKhhaoSourceConfigPayload(payload))
|
||||||
|
const syncState = saved.autoSync?.enabled ? ensureKhhaoSyncBaseline() : getKhhaoSyncState()
|
||||||
|
|
||||||
|
return {
|
||||||
|
filePath: getKhhaoSourcesFilePath(),
|
||||||
|
stateFilePath: getKhhaoSyncStateFilePath(),
|
||||||
|
source: mapAdminKhhaoSourceConfig(saved),
|
||||||
|
syncState: mapAdminKhhaoSyncState(syncState),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {AdminKhhaoTestLoginInput} [payload] */
|
||||||
|
export async function testAdminKhhaoLogin(payload = /** @type {AdminKhhaoTestLoginInput} */ ({})) {
|
||||||
|
const session = await loginKhhaoSession(buildAdminKhhaoLoginPayload(payload))
|
||||||
|
return buildAdminKhhaoLoginResult(session)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {AdminKhhaoOrderQueryInput} [payload] */
|
||||||
|
export async function queryAdminKhhaoOrders(payload = /** @type {AdminKhhaoOrderQueryInput} */ ({})) {
|
||||||
|
const credential = resolveAdminKhhaoCredentialPayload(payload)
|
||||||
|
const session = await loginKhhaoSession(buildAdminKhhaoLoginPayload(payload, {
|
||||||
|
requestIdScope: 'query-orders',
|
||||||
|
}))
|
||||||
|
|
||||||
|
const result = await queryKhhaoOrderList({
|
||||||
|
baseUrl: credential.baseUrl,
|
||||||
|
page: payload.page,
|
||||||
|
limit: payload.limit,
|
||||||
|
session,
|
||||||
|
})
|
||||||
|
|
||||||
|
return buildAdminKhhaoOrderQueryResult(session, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {AdminKhhaoOrderQueryInput} [payload] */
|
||||||
|
export async function syncAdminKhhaoOrders(payload = /** @type {AdminKhhaoOrderQueryInput} */ ({})) {
|
||||||
|
return syncKhhaoOrders(buildAdminKhhaoSyncPayload(payload))
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
// @ts-check
|
||||||
|
|
||||||
|
import {
|
||||||
|
getKuaishouCloudFulfillmentConfig,
|
||||||
|
getKuaishouCloudFulfillmentFilePath,
|
||||||
|
saveKuaishouCloudFulfillmentConfig,
|
||||||
|
} from '../../order/kuaishou-cloud-fulfillment-config-service.js'
|
||||||
|
import { syncConfiguredFulfillmentBindings } from '../../bootstrap/fulfillment-bootstrap-service.js'
|
||||||
|
import { mapAdminKuaishouCloudFulfillmentSource } from './mappers.js'
|
||||||
|
|
||||||
|
/** @typedef {import('../../../types/admin-write-inputs.js').AdminKuaishouCloudFulfillmentConfigInput} AdminKuaishouCloudFulfillmentConfigInput */
|
||||||
|
|
||||||
|
export function getAdminKuaishouCloudFulfillmentConfig() {
|
||||||
|
const config = getKuaishouCloudFulfillmentConfig()
|
||||||
|
|
||||||
|
return {
|
||||||
|
filePath: getKuaishouCloudFulfillmentFilePath(),
|
||||||
|
source: mapAdminKuaishouCloudFulfillmentSource(config),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {AdminKuaishouCloudFulfillmentConfigInput} [payload] */
|
||||||
|
export async function updateAdminKuaishouCloudFulfillmentConfig(
|
||||||
|
payload = /** @type {AdminKuaishouCloudFulfillmentConfigInput} */ ({}),
|
||||||
|
) {
|
||||||
|
const saved = saveKuaishouCloudFulfillmentConfig({
|
||||||
|
enabled: payload.enabled !== false,
|
||||||
|
items: Array.isArray(payload.items) ? payload.items : [],
|
||||||
|
})
|
||||||
|
|
||||||
|
await syncConfiguredFulfillmentBindings()
|
||||||
|
|
||||||
|
return {
|
||||||
|
filePath: getKuaishouCloudFulfillmentFilePath(),
|
||||||
|
source: mapAdminKuaishouCloudFulfillmentSource(saved),
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
// @ts-check
|
||||||
|
|
||||||
|
import {
|
||||||
|
consumeKuaishouEticket,
|
||||||
|
queryKuaishouEticketConsumeDetail,
|
||||||
|
} from '../../platforms/kuaishou-eticket/consume-service.js'
|
||||||
|
import {
|
||||||
|
findKuaishouEticketShopConfig,
|
||||||
|
getFirstAvailableKuaishouEticketShop,
|
||||||
|
getKuaishouEticketSourceConfig,
|
||||||
|
getKuaishouEticketSourceFilePath,
|
||||||
|
listKuaishouEticketShopConfigs,
|
||||||
|
saveKuaishouEticketSourceConfig,
|
||||||
|
} from '../../platforms/kuaishou-eticket/source-config-service.js'
|
||||||
|
import { queryKuaishouEticketStableInfo } from '../../platforms/kuaishou-eticket/info-service.js'
|
||||||
|
import { resolveKuaishouEticketAdminContext } from './context.js'
|
||||||
|
import { mapAdminKuaishouEticketSourceConfig } from './mappers.js'
|
||||||
|
|
||||||
|
/** @typedef {import('../../../types/admin-write-inputs.js').AdminKuaishouEticketSourceConfigInput} AdminKuaishouEticketSourceConfigInput */
|
||||||
|
/** @typedef {import('../../../types/admin-write-inputs.js').AdminKuaishouEticketShopInfoInput} AdminKuaishouEticketShopInfoInput */
|
||||||
|
/** @typedef {import('../../../types/admin-write-inputs.js').AdminKuaishouEticketDetailQueryInput} AdminKuaishouEticketDetailQueryInput */
|
||||||
|
/** @typedef {import('../../../types/admin-write-inputs.js').AdminKuaishouEticketConsumeInput} AdminKuaishouEticketConsumeInput */
|
||||||
|
|
||||||
|
function resolveAdminKuaishouEticketContext(payload = {}) {
|
||||||
|
return resolveKuaishouEticketAdminContext(payload, {
|
||||||
|
savedSource: getKuaishouEticketSourceConfig(),
|
||||||
|
findShopConfig: findKuaishouEticketShopConfig,
|
||||||
|
getFirstAvailableShop: getFirstAvailableKuaishouEticketShop,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getAdminKuaishouEticketSourceConfig() {
|
||||||
|
const config = getKuaishouEticketSourceConfig()
|
||||||
|
|
||||||
|
return {
|
||||||
|
filePath: getKuaishouEticketSourceFilePath(),
|
||||||
|
source: mapAdminKuaishouEticketSourceConfig(config, listKuaishouEticketShopConfigs(config)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {AdminKuaishouEticketSourceConfigInput} [payload] */
|
||||||
|
export function updateAdminKuaishouEticketSourceConfig(payload = /** @type {AdminKuaishouEticketSourceConfigInput} */ ({})) {
|
||||||
|
const saved = saveKuaishouEticketSourceConfig({
|
||||||
|
enabled: payload.enabled !== false,
|
||||||
|
baseUrl: String(payload.baseUrl || '').trim() || 'https://s.kwaixiaodian.com',
|
||||||
|
shops: Array.isArray(payload.shops) ? payload.shops : [],
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
filePath: getKuaishouEticketSourceFilePath(),
|
||||||
|
source: mapAdminKuaishouEticketSourceConfig(saved, listKuaishouEticketShopConfigs(saved)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {AdminKuaishouEticketDetailQueryInput} [payload] */
|
||||||
|
export async function queryAdminKuaishouEticketDetail(payload = /** @type {AdminKuaishouEticketDetailQueryInput} */ ({})) {
|
||||||
|
const context = resolveAdminKuaishouEticketContext(payload)
|
||||||
|
|
||||||
|
return queryKuaishouEticketConsumeDetail({
|
||||||
|
baseUrl: context.baseUrl,
|
||||||
|
cookie: context.cookie,
|
||||||
|
eTicketId: String(payload.eTicketId || '').trim(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {AdminKuaishouEticketShopInfoInput} [payload] */
|
||||||
|
export async function queryAdminKuaishouEticketShopInfo(payload = /** @type {AdminKuaishouEticketShopInfoInput} */ ({})) {
|
||||||
|
const context = resolveAdminKuaishouEticketContext(payload)
|
||||||
|
|
||||||
|
return queryKuaishouEticketStableInfo({
|
||||||
|
baseUrl: context.baseUrl,
|
||||||
|
cookie: context.cookie,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {AdminKuaishouEticketConsumeInput} [payload] */
|
||||||
|
export async function consumeAdminKuaishouEticket(payload = /** @type {AdminKuaishouEticketConsumeInput} */ ({})) {
|
||||||
|
const context = resolveAdminKuaishouEticketContext(payload)
|
||||||
|
|
||||||
|
return consumeKuaishouEticket({
|
||||||
|
baseUrl: context.baseUrl,
|
||||||
|
cookie: context.cookie,
|
||||||
|
eTicketId: String(payload.eTicketId || '').trim(),
|
||||||
|
oid: String(payload.oid || '').trim(),
|
||||||
|
formToken: String(payload.formToken || '').trim(),
|
||||||
|
num: payload.num,
|
||||||
|
storeId: String(payload.storeId || '').trim(),
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -1,603 +1,53 @@
|
|||||||
// @ts-check
|
export {
|
||||||
|
getAdminAgisoShopConfigs,
|
||||||
|
updateAdminAgisoShopConfigs,
|
||||||
|
} from './agiso-service.js'
|
||||||
|
|
||||||
import { query } from '../../../db/client.js'
|
export {
|
||||||
import {
|
getAdminKhhaoSourceConfig,
|
||||||
getAgisoMessagingDefaults,
|
updateAdminKhhaoSourceConfig,
|
||||||
getAgisoShopConfig,
|
testAdminKhhaoLogin,
|
||||||
getAgisoShopConfigMap,
|
queryAdminKhhaoOrders,
|
||||||
getAgisoShopsFilePath,
|
syncAdminKhhaoOrders,
|
||||||
saveAgisoMessagingConfig,
|
} from './khhao-service.js'
|
||||||
} from '../../platforms/agiso/shop-config-service.js'
|
|
||||||
import { enrichAgisoXianyuTradeOrder } from '../../platforms/agiso/xianyu/order-detail-service.js'
|
|
||||||
import { queryKhhaoOrderList } from '../../platforms/khhao/order-query-service.js'
|
|
||||||
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 {
|
|
||||||
consumeKuaishouEticket,
|
|
||||||
queryKuaishouEticketConsumeDetail,
|
|
||||||
} from '../../platforms/kuaishou-eticket/consume-service.js'
|
|
||||||
import {
|
|
||||||
findKuaishouEticketShopConfig,
|
|
||||||
getFirstAvailableKuaishouEticketShop,
|
|
||||||
getKuaishouEticketSourceConfig,
|
|
||||||
getKuaishouEticketSourceFilePath,
|
|
||||||
listKuaishouEticketShopConfigs,
|
|
||||||
resolveKuaishouEticketShopConfig,
|
|
||||||
saveKuaishouEticketSourceConfig,
|
|
||||||
} from '../../platforms/kuaishou-eticket/source-config-service.js'
|
|
||||||
import { queryKuaishouEticketStableInfo } from '../../platforms/kuaishou-eticket/info-service.js'
|
|
||||||
import {
|
|
||||||
getCloudtentaclesSourceConfig,
|
|
||||||
getCloudtentaclesSourcesFilePath,
|
|
||||||
saveCloudtentaclesSourceConfig,
|
|
||||||
} from '../../platforms/cloudtentacles/source-config-service.js'
|
|
||||||
import {
|
|
||||||
clearCloudtentaclesSessionState,
|
|
||||||
getCloudtentaclesSessionFilePath,
|
|
||||||
getCloudtentaclesSessionState,
|
|
||||||
saveCloudtentaclesSessionState,
|
|
||||||
} from '../../platforms/cloudtentacles/session-state-service.js'
|
|
||||||
import {
|
|
||||||
loginCloudtentaclesSession,
|
|
||||||
sendCloudtentaclesSmsCode,
|
|
||||||
validateCloudtentaclesSession,
|
|
||||||
} from '../../platforms/cloudtentacles/session-service.js'
|
|
||||||
import {
|
|
||||||
buyCloudtentaclesSku,
|
|
||||||
getCloudtentaclesAsset,
|
|
||||||
getCloudtentaclesCategories,
|
|
||||||
listCloudtentaclesSku,
|
|
||||||
useCloudtentaclesSku,
|
|
||||||
} from '../../platforms/cloudtentacles/catalog-service.js'
|
|
||||||
import { getCloudtentaclesKnapsack } from '../../platforms/cloudtentacles/knapsack-service.js'
|
|
||||||
import {
|
|
||||||
appointCloudtentaclesVirtualNumber,
|
|
||||||
backCloudtentaclesVirtualNumber,
|
|
||||||
fetchCloudtentaclesVirtualNumberCode,
|
|
||||||
generateCloudtentaclesLoginCode,
|
|
||||||
getCloudtentaclesBindUrl,
|
|
||||||
listCloudtentaclesVirtualNumbers,
|
|
||||||
verifyCloudtentaclesLoginCode,
|
|
||||||
} from '../../platforms/cloudtentacles/virtual-number-service.js'
|
|
||||||
import { runCloudtentaclesFullDebugFlow } from '../../platforms/cloudtentacles/debug-flow-service.js'
|
|
||||||
import {
|
|
||||||
getOrderFulfillmentBindingConfigs,
|
|
||||||
getOrderFulfillmentBindingsFilePath,
|
|
||||||
saveOrderFulfillmentBindingConfigs,
|
|
||||||
} from '../../order/fulfillment-binding-config-service.js'
|
|
||||||
import {
|
|
||||||
getKuaishouCloudFulfillmentConfig,
|
|
||||||
getKuaishouCloudFulfillmentFilePath,
|
|
||||||
saveKuaishouCloudFulfillmentConfig,
|
|
||||||
} from '../../order/kuaishou-cloud-fulfillment-config-service.js'
|
|
||||||
import { getFulfillmentProfileByKey } from '../../../repositories/fulfillment-profile-repo.js'
|
|
||||||
import { syncConfiguredFulfillmentBindings } from '../../bootstrap/fulfillment-bootstrap-service.js'
|
|
||||||
import { resolveDisplayShopName } from '../admin-read-shared-helpers.js'
|
|
||||||
import {
|
|
||||||
hasCloudtentaclesCredentialContextChanged,
|
|
||||||
isPlainObject,
|
|
||||||
pickFirstNonEmpty,
|
|
||||||
resolveKuaishouEticketAdminContext,
|
|
||||||
} from './context.js'
|
|
||||||
import {
|
|
||||||
buildFulfillmentLookupResult,
|
|
||||||
normalizeFulfillmentLookupPayload,
|
|
||||||
resolveFulfillmentLookupDetail,
|
|
||||||
} from './fulfillment.js'
|
|
||||||
import {
|
|
||||||
buildAdminKhhaoLoginPayload,
|
|
||||||
buildAdminKhhaoLoginResult,
|
|
||||||
buildAdminKhhaoOrderQueryResult,
|
|
||||||
buildAdminKhhaoSyncPayload,
|
|
||||||
resolveAdminKhhaoCredentialPayload,
|
|
||||||
} from './khhao.js'
|
|
||||||
import {
|
|
||||||
buildAdminCloudtentaclesLoginResult,
|
|
||||||
buildAdminCloudtentaclesPersistedSessionPayload,
|
|
||||||
buildAdminCloudtentaclesValidateResult,
|
|
||||||
resolveAdminCloudtentaclesCredentialPayload,
|
|
||||||
resolveAdminCloudtentaclesSessionPayload,
|
|
||||||
} from './cloudtentacles.js'
|
|
||||||
import { listAdminObservedProducts } from './observed-products.js'
|
|
||||||
import {
|
|
||||||
validateAdminFulfillmentBindingConfigs,
|
|
||||||
} from './validation.js'
|
|
||||||
import {
|
|
||||||
buildAdminAgisoMessagingSavePayload,
|
|
||||||
normalizeAdminCloudtentaclesSourceConfigPayload,
|
|
||||||
normalizeAdminKhhaoSourceConfigPayload,
|
|
||||||
} from './writes.js'
|
|
||||||
import {
|
|
||||||
mapAdminAgisoMessagingDefaults,
|
|
||||||
mapAdminAgisoShopConfigItem,
|
|
||||||
mapAdminFulfillmentBindingConfigItem,
|
|
||||||
} from './domain.js'
|
|
||||||
import {
|
|
||||||
mapAdminCloudtentaclesSession,
|
|
||||||
mapAdminCloudtentaclesSourceConfig,
|
|
||||||
mapAdminKhhaoSourceConfig,
|
|
||||||
mapAdminKhhaoSyncState,
|
|
||||||
mapAdminKuaishouCloudFulfillmentSource,
|
|
||||||
mapAdminKuaishouEticketSourceConfig,
|
|
||||||
maskPhone,
|
|
||||||
} from './mappers.js'
|
|
||||||
|
|
||||||
/** @typedef {import('../../../types/admin-write-inputs.js').AdminAgisoShopConfigSaveInput} AdminAgisoShopConfigSaveInput */
|
export {
|
||||||
/** @typedef {import('../../../types/admin-write-inputs.js').AdminKhhaoSourceConfigInput} AdminKhhaoSourceConfigInput */
|
getAdminKuaishouEticketSourceConfig,
|
||||||
/** @typedef {import('../../../types/admin-write-inputs.js').AdminKuaishouEticketSourceConfigInput} AdminKuaishouEticketSourceConfigInput */
|
updateAdminKuaishouEticketSourceConfig,
|
||||||
/** @typedef {import('../../../types/admin-write-inputs.js').AdminKuaishouEticketShopInfoInput} AdminKuaishouEticketShopInfoInput */
|
queryAdminKuaishouEticketDetail,
|
||||||
/** @typedef {import('../../../types/admin-write-inputs.js').AdminKuaishouEticketDetailQueryInput} AdminKuaishouEticketDetailQueryInput */
|
queryAdminKuaishouEticketShopInfo,
|
||||||
/** @typedef {import('../../../types/admin-write-inputs.js').AdminKuaishouEticketConsumeInput} AdminKuaishouEticketConsumeInput */
|
consumeAdminKuaishouEticket,
|
||||||
/** @typedef {import('../../../types/admin-write-inputs.js').AdminKhhaoOrderQueryInput} AdminKhhaoOrderQueryInput */
|
} from './kuaishou-eticket-service.js'
|
||||||
/** @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').AdminKuaishouCloudFulfillmentConfigInput} AdminKuaishouCloudFulfillmentConfigInput */
|
|
||||||
/** @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').AdminCloudtentaclesCatalogQueryInput} AdminCloudtentaclesCatalogQueryInput */
|
|
||||||
/** @typedef {import('../../../types/admin-write-inputs.js').AdminCloudtentaclesSkuBuyInput} AdminCloudtentaclesSkuBuyInput */
|
|
||||||
/** @typedef {import('../../../types/admin-write-inputs.js').AdminCloudtentaclesSkuUseInput} AdminCloudtentaclesSkuUseInput */
|
|
||||||
/** @typedef {import('../../../types/admin-write-inputs.js').AdminCloudtentaclesVirtualNumberInput} AdminCloudtentaclesVirtualNumberInput */
|
|
||||||
/** @typedef {import('../../../types/admin-write-inputs.js').AdminCloudtentaclesFullFlowInput} AdminCloudtentaclesFullFlowInput */
|
|
||||||
/** @typedef {import('../../../types/admin-write-inputs.js').AdminFulfillmentBindingConfigSaveInput} AdminFulfillmentBindingConfigSaveInput */
|
|
||||||
/** @typedef {import('../../../types/admin-write-inputs.js').AdminFulfillmentBindingLookupInput} AdminFulfillmentBindingLookupInput */
|
|
||||||
|
|
||||||
export async function getAdminAgisoShopConfigs() {
|
export {
|
||||||
const configMap = getAgisoShopConfigMap()
|
getAdminCloudtentaclesSourceConfig,
|
||||||
const defaults = getAgisoMessagingDefaults()
|
updateAdminCloudtentaclesSourceConfig,
|
||||||
const rowsResult = await query(
|
sendAdminCloudtentaclesSmsCode,
|
||||||
`
|
testAdminCloudtentaclesLogin,
|
||||||
SELECT
|
validateAdminCloudtentaclesSession,
|
||||||
shop_id,
|
getAdminCloudtentaclesAsset,
|
||||||
MAX(CASE WHEN trim(shop_name) != '' THEN shop_name ELSE '' END) AS detected_shop_name,
|
getAdminCloudtentaclesCategories,
|
||||||
MAX(created_at) AS latest_seen_at,
|
getAdminCloudtentaclesSkuList,
|
||||||
COUNT(*)::int AS webhook_event_count
|
buyAdminCloudtentaclesSku,
|
||||||
FROM webhook_events
|
useAdminCloudtentaclesSku,
|
||||||
WHERE provider = 'agiso' AND trim(shop_id) != ''
|
getAdminCloudtentaclesKnapsack,
|
||||||
GROUP BY shop_id
|
listAdminCloudtentaclesVirtualNumbers,
|
||||||
ORDER BY latest_seen_at DESC, shop_id DESC
|
appointAdminCloudtentaclesVirtualNumber,
|
||||||
`,
|
generateAdminCloudtentaclesLoginCode,
|
||||||
)
|
fetchAdminCloudtentaclesVirtualNumberCode,
|
||||||
const rows = rowsResult.rows
|
verifyAdminCloudtentaclesLoginCode,
|
||||||
|
getAdminCloudtentaclesBindUrl,
|
||||||
|
backAdminCloudtentaclesVirtualNumber,
|
||||||
|
runAdminCloudtentaclesFullFlow,
|
||||||
|
} from './cloudtentacles-service.js'
|
||||||
|
|
||||||
return {
|
export {
|
||||||
filePath: getAgisoShopsFilePath(),
|
getAdminFulfillmentBindingConfigs,
|
||||||
defaults: mapAdminAgisoMessagingDefaults(defaults),
|
lookupAdminFulfillmentBindingOrder,
|
||||||
shops: Object.entries(configMap)
|
updateAdminFulfillmentBindingConfigs,
|
||||||
.sort(([left], [right]) => left.localeCompare(right))
|
} from './fulfillment-bindings-service.js'
|
||||||
.map(([shopId, config]) => mapAdminAgisoShopConfigItem(shopId, config)),
|
|
||||||
observedShops: rows.map((row) => ({
|
|
||||||
shopId: String(row.shop_id || '').trim(),
|
|
||||||
detectedShopName: String(row.detected_shop_name || '').trim(),
|
|
||||||
displayShopName: resolveDisplayShopName('agiso', row.shop_id, row.detected_shop_name),
|
|
||||||
latestSeenAt: row.latest_seen_at || null,
|
|
||||||
webhookEventCount: Number(row.webhook_event_count || 0),
|
|
||||||
configured: Boolean(configMap[String(row.shop_id || '').trim()]),
|
|
||||||
})),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {AdminAgisoShopConfigSaveInput} [payload] */
|
export {
|
||||||
export function updateAdminAgisoShopConfigs(payload = /** @type {AdminAgisoShopConfigSaveInput} */ ({})) {
|
getAdminKuaishouCloudFulfillmentConfig,
|
||||||
const saved = saveAgisoMessagingConfig(buildAdminAgisoMessagingSavePayload(payload, {
|
updateAdminKuaishouCloudFulfillmentConfig,
|
||||||
currentDefaults: getAgisoMessagingDefaults(),
|
} from './kuaishou-cloud-fulfillment-service.js'
|
||||||
currentMap: getAgisoShopConfigMap(),
|
|
||||||
}))
|
|
||||||
|
|
||||||
return {
|
|
||||||
filePath: getAgisoShopsFilePath(),
|
|
||||||
defaults: mapAdminAgisoMessagingDefaults(saved.defaults),
|
|
||||||
shops: Object.entries(saved.shops)
|
|
||||||
.sort(([left], [right]) => left.localeCompare(right))
|
|
||||||
.map(([shopId, config]) => mapAdminAgisoShopConfigItem(shopId, config)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getAdminKhhaoSourceConfig() {
|
|
||||||
const config = getKhhaoSourceConfig()
|
|
||||||
const syncState = getKhhaoSyncState()
|
|
||||||
|
|
||||||
return {
|
|
||||||
filePath: getKhhaoSourcesFilePath(),
|
|
||||||
stateFilePath: getKhhaoSyncStateFilePath(),
|
|
||||||
source: mapAdminKhhaoSourceConfig(config),
|
|
||||||
syncState: mapAdminKhhaoSyncState(syncState),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getAdminKuaishouEticketSourceConfig() {
|
|
||||||
const config = getKuaishouEticketSourceConfig()
|
|
||||||
|
|
||||||
return {
|
|
||||||
filePath: getKuaishouEticketSourceFilePath(),
|
|
||||||
source: mapAdminKuaishouEticketSourceConfig(config, listKuaishouEticketShopConfigs(config)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {AdminKuaishouEticketSourceConfigInput} [payload] */
|
|
||||||
export function updateAdminKuaishouEticketSourceConfig(payload = /** @type {AdminKuaishouEticketSourceConfigInput} */ ({})) {
|
|
||||||
const saved = saveKuaishouEticketSourceConfig({
|
|
||||||
enabled: payload.enabled !== false,
|
|
||||||
baseUrl: String(payload.baseUrl || '').trim() || 'https://s.kwaixiaodian.com',
|
|
||||||
shops: Array.isArray(payload.shops) ? payload.shops : [],
|
|
||||||
})
|
|
||||||
|
|
||||||
return {
|
|
||||||
filePath: getKuaishouEticketSourceFilePath(),
|
|
||||||
source: mapAdminKuaishouEticketSourceConfig(saved, listKuaishouEticketShopConfigs(saved)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {AdminKhhaoSourceConfigInput} [payload] */
|
|
||||||
export function updateAdminKhhaoSourceConfig(payload = /** @type {AdminKhhaoSourceConfigInput} */ ({})) {
|
|
||||||
const saved = saveKhhaoSourceConfig(normalizeAdminKhhaoSourceConfigPayload(payload))
|
|
||||||
const syncState = saved.autoSync?.enabled ? ensureKhhaoSyncBaseline() : getKhhaoSyncState()
|
|
||||||
|
|
||||||
return {
|
|
||||||
filePath: getKhhaoSourcesFilePath(),
|
|
||||||
stateFilePath: getKhhaoSyncStateFilePath(),
|
|
||||||
source: mapAdminKhhaoSourceConfig(saved),
|
|
||||||
syncState: mapAdminKhhaoSyncState(syncState),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {AdminKhhaoTestLoginInput} [payload] */
|
|
||||||
export async function testAdminKhhaoLogin(payload = /** @type {AdminKhhaoTestLoginInput} */ ({})) {
|
|
||||||
const session = await loginKhhaoSession(buildAdminKhhaoLoginPayload(payload))
|
|
||||||
return buildAdminKhhaoLoginResult(session)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {AdminKhhaoOrderQueryInput} [payload] */
|
|
||||||
export async function queryAdminKhhaoOrders(payload = /** @type {AdminKhhaoOrderQueryInput} */ ({})) {
|
|
||||||
const credential = resolveAdminKhhaoCredentialPayload(payload)
|
|
||||||
const session = await loginKhhaoSession(buildAdminKhhaoLoginPayload(payload, {
|
|
||||||
requestIdScope: 'query-orders',
|
|
||||||
}))
|
|
||||||
|
|
||||||
const result = await queryKhhaoOrderList({
|
|
||||||
baseUrl: credential.baseUrl,
|
|
||||||
page: payload.page,
|
|
||||||
limit: payload.limit,
|
|
||||||
session,
|
|
||||||
})
|
|
||||||
|
|
||||||
return buildAdminKhhaoOrderQueryResult(session, result)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {AdminKhhaoOrderQueryInput} [payload] */
|
|
||||||
export async function syncAdminKhhaoOrders(payload = /** @type {AdminKhhaoOrderQueryInput} */ ({})) {
|
|
||||||
return syncKhhaoOrders(buildAdminKhhaoSyncPayload(payload))
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {AdminKuaishouEticketDetailQueryInput} [payload] */
|
|
||||||
export async function queryAdminKuaishouEticketDetail(payload = /** @type {AdminKuaishouEticketDetailQueryInput} */ ({})) {
|
|
||||||
const context = resolveKuaishouEticketAdminContext(payload, {
|
|
||||||
savedSource: getKuaishouEticketSourceConfig(),
|
|
||||||
findShopConfig: findKuaishouEticketShopConfig,
|
|
||||||
getFirstAvailableShop: getFirstAvailableKuaishouEticketShop,
|
|
||||||
})
|
|
||||||
|
|
||||||
return queryKuaishouEticketConsumeDetail({
|
|
||||||
baseUrl: context.baseUrl,
|
|
||||||
cookie: context.cookie,
|
|
||||||
eTicketId: String(payload.eTicketId || '').trim(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {AdminKuaishouEticketShopInfoInput} [payload] */
|
|
||||||
export async function queryAdminKuaishouEticketShopInfo(payload = /** @type {AdminKuaishouEticketShopInfoInput} */ ({})) {
|
|
||||||
const context = resolveKuaishouEticketAdminContext(payload, {
|
|
||||||
savedSource: getKuaishouEticketSourceConfig(),
|
|
||||||
findShopConfig: findKuaishouEticketShopConfig,
|
|
||||||
getFirstAvailableShop: getFirstAvailableKuaishouEticketShop,
|
|
||||||
})
|
|
||||||
return queryKuaishouEticketStableInfo({
|
|
||||||
baseUrl: context.baseUrl,
|
|
||||||
cookie: context.cookie,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {AdminKuaishouEticketConsumeInput} [payload] */
|
|
||||||
export async function consumeAdminKuaishouEticket(payload = /** @type {AdminKuaishouEticketConsumeInput} */ ({})) {
|
|
||||||
const context = resolveKuaishouEticketAdminContext(payload, {
|
|
||||||
savedSource: getKuaishouEticketSourceConfig(),
|
|
||||||
findShopConfig: findKuaishouEticketShopConfig,
|
|
||||||
getFirstAvailableShop: getFirstAvailableKuaishouEticketShop,
|
|
||||||
})
|
|
||||||
|
|
||||||
return consumeKuaishouEticket({
|
|
||||||
baseUrl: context.baseUrl,
|
|
||||||
cookie: context.cookie,
|
|
||||||
eTicketId: String(payload.eTicketId || '').trim(),
|
|
||||||
oid: String(payload.oid || '').trim(),
|
|
||||||
formToken: String(payload.formToken || '').trim(),
|
|
||||||
num: payload.num,
|
|
||||||
storeId: String(payload.storeId || '').trim(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getAdminCloudtentaclesSourceConfig() {
|
|
||||||
const config = getCloudtentaclesSourceConfig()
|
|
||||||
const session = getCloudtentaclesSessionState()
|
|
||||||
|
|
||||||
return {
|
|
||||||
filePath: getCloudtentaclesSourcesFilePath(),
|
|
||||||
sessionFilePath: getCloudtentaclesSessionFilePath(),
|
|
||||||
source: mapAdminCloudtentaclesSourceConfig(config),
|
|
||||||
session: mapAdminCloudtentaclesSession(session),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {AdminCloudtentaclesSourceConfigInput} [payload] */
|
|
||||||
export function updateAdminCloudtentaclesSourceConfig(payload = /** @type {AdminCloudtentaclesSourceConfigInput} */ ({})) {
|
|
||||||
const current = getCloudtentaclesSourceConfig()
|
|
||||||
const saved = saveCloudtentaclesSourceConfig(normalizeAdminCloudtentaclesSourceConfigPayload(payload))
|
|
||||||
const shouldClearSession = hasCloudtentaclesCredentialContextChanged(current, saved)
|
|
||||||
const session = shouldClearSession ? clearCloudtentaclesSessionState() : getCloudtentaclesSessionState()
|
|
||||||
|
|
||||||
return {
|
|
||||||
filePath: getCloudtentaclesSourcesFilePath(),
|
|
||||||
sessionFilePath: getCloudtentaclesSessionFilePath(),
|
|
||||||
source: mapAdminCloudtentaclesSourceConfig(saved),
|
|
||||||
session: mapAdminCloudtentaclesSession(session),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {AdminCloudtentaclesSendSmsCodeInput} [payload] */
|
|
||||||
export async function sendAdminCloudtentaclesSmsCode(payload = /** @type {AdminCloudtentaclesSendSmsCodeInput} */ ({})) {
|
|
||||||
const result = await sendCloudtentaclesSmsCode(resolveAdminCloudtentaclesCredentialPayload(payload))
|
|
||||||
|
|
||||||
return {
|
|
||||||
...result,
|
|
||||||
phoneMasked: maskPhone(result.phone),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {AdminCloudtentaclesTestLoginInput} [payload] */
|
|
||||||
export async function testAdminCloudtentaclesLogin(payload = /** @type {AdminCloudtentaclesTestLoginInput} */ ({})) {
|
|
||||||
const savedSource = getCloudtentaclesSourceConfig()
|
|
||||||
const credentialContext = resolveAdminCloudtentaclesCredentialPayload(payload, { savedSource })
|
|
||||||
const session = await loginCloudtentaclesSession({
|
|
||||||
...credentialContext,
|
|
||||||
code: String(payload.code || '').trim(),
|
|
||||||
})
|
|
||||||
const savedSession = saveCloudtentaclesSessionState(buildAdminCloudtentaclesPersistedSessionPayload(session, {
|
|
||||||
deviceId: credentialContext.deviceId,
|
|
||||||
deviceType: credentialContext.deviceType,
|
|
||||||
}))
|
|
||||||
|
|
||||||
return buildAdminCloudtentaclesLoginResult(session, savedSession)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {AdminCloudtentaclesValidateSessionInput} [payload] */
|
|
||||||
export async function validateAdminCloudtentaclesSession(payload = /** @type {AdminCloudtentaclesValidateSessionInput} */ ({})) {
|
|
||||||
const savedSource = getCloudtentaclesSourceConfig()
|
|
||||||
const persistedSession = getCloudtentaclesSessionState()
|
|
||||||
const sessionContext = resolveAdminCloudtentaclesSessionPayload(payload, { savedSource, persistedSession })
|
|
||||||
const session = await validateCloudtentaclesSession(sessionContext)
|
|
||||||
const savedSession = saveCloudtentaclesSessionState(buildAdminCloudtentaclesPersistedSessionPayload(session, {
|
|
||||||
username: pickFirstNonEmpty([persistedSession.username, savedSource.username]),
|
|
||||||
phone: pickFirstNonEmpty([persistedSession.phone, savedSource.phone]),
|
|
||||||
deviceId: sessionContext.deviceId,
|
|
||||||
deviceType: sessionContext.deviceType,
|
|
||||||
}))
|
|
||||||
|
|
||||||
return buildAdminCloudtentaclesValidateResult(session, savedSession)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {AdminCloudtentaclesCatalogQueryInput} [payload] */
|
|
||||||
export async function getAdminCloudtentaclesAsset(payload = /** @type {AdminCloudtentaclesCatalogQueryInput} */ ({})) {
|
|
||||||
return getCloudtentaclesAsset(resolveAdminCloudtentaclesSessionPayload(payload))
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {AdminCloudtentaclesCatalogQueryInput} [payload] */
|
|
||||||
export async function getAdminCloudtentaclesCategories(payload = /** @type {AdminCloudtentaclesCatalogQueryInput} */ ({})) {
|
|
||||||
return getCloudtentaclesCategories(resolveAdminCloudtentaclesSessionPayload(payload))
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {AdminCloudtentaclesCatalogQueryInput} [payload] */
|
|
||||||
export async function getAdminCloudtentaclesSkuList(payload = /** @type {AdminCloudtentaclesCatalogQueryInput} */ ({})) {
|
|
||||||
return listCloudtentaclesSku(resolveAdminCloudtentaclesSessionPayload(payload))
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {AdminCloudtentaclesSkuBuyInput} [payload] */
|
|
||||||
export async function buyAdminCloudtentaclesSku(payload = /** @type {AdminCloudtentaclesSkuBuyInput} */ ({})) {
|
|
||||||
const context = resolveAdminCloudtentaclesSessionPayload(payload)
|
|
||||||
return buyCloudtentaclesSku({
|
|
||||||
...context,
|
|
||||||
id: payload.id,
|
|
||||||
count: payload.count,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {AdminCloudtentaclesSkuUseInput} [payload] */
|
|
||||||
export async function useAdminCloudtentaclesSku(payload = /** @type {AdminCloudtentaclesSkuUseInput} */ ({})) {
|
|
||||||
const context = resolveAdminCloudtentaclesSessionPayload(payload)
|
|
||||||
return useCloudtentaclesSku({
|
|
||||||
...context,
|
|
||||||
id: payload.id,
|
|
||||||
virtualNumberId: payload.virtualNumberId,
|
|
||||||
phone: payload.phone,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {AdminCloudtentaclesCatalogQueryInput} [payload] */
|
|
||||||
export async function getAdminCloudtentaclesKnapsack(payload = /** @type {AdminCloudtentaclesCatalogQueryInput} */ ({})) {
|
|
||||||
return getCloudtentaclesKnapsack(resolveAdminCloudtentaclesSessionPayload(payload))
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {AdminCloudtentaclesVirtualNumberInput} [payload] */
|
|
||||||
export async function listAdminCloudtentaclesVirtualNumbers(payload = /** @type {AdminCloudtentaclesVirtualNumberInput} */ ({})) {
|
|
||||||
const context = resolveAdminCloudtentaclesSessionPayload(payload)
|
|
||||||
return listCloudtentaclesVirtualNumbers({
|
|
||||||
...context,
|
|
||||||
key: payload.key,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {AdminCloudtentaclesVirtualNumberInput} [payload] */
|
|
||||||
export async function appointAdminCloudtentaclesVirtualNumber(payload = /** @type {AdminCloudtentaclesVirtualNumberInput} */ ({})) {
|
|
||||||
const context = resolveAdminCloudtentaclesSessionPayload(payload)
|
|
||||||
return appointCloudtentaclesVirtualNumber({
|
|
||||||
...context,
|
|
||||||
key: payload.key,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {AdminCloudtentaclesVirtualNumberInput} [payload] */
|
|
||||||
export async function generateAdminCloudtentaclesLoginCode(payload = /** @type {AdminCloudtentaclesVirtualNumberInput} */ ({})) {
|
|
||||||
const context = resolveAdminCloudtentaclesSessionPayload(payload)
|
|
||||||
return generateCloudtentaclesLoginCode({
|
|
||||||
...context,
|
|
||||||
key: payload.key,
|
|
||||||
id: payload.id,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {AdminCloudtentaclesVirtualNumberInput} [payload] */
|
|
||||||
export async function fetchAdminCloudtentaclesVirtualNumberCode(payload = /** @type {AdminCloudtentaclesVirtualNumberInput} */ ({})) {
|
|
||||||
const context = resolveAdminCloudtentaclesSessionPayload(payload)
|
|
||||||
return fetchCloudtentaclesVirtualNumberCode({
|
|
||||||
...context,
|
|
||||||
key: payload.key,
|
|
||||||
phone: payload.phone,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {AdminCloudtentaclesVirtualNumberInput} [payload] */
|
|
||||||
export async function verifyAdminCloudtentaclesLoginCode(payload = /** @type {AdminCloudtentaclesVirtualNumberInput} */ ({})) {
|
|
||||||
const context = resolveAdminCloudtentaclesSessionPayload(payload)
|
|
||||||
return verifyCloudtentaclesLoginCode({
|
|
||||||
...context,
|
|
||||||
key: payload.key,
|
|
||||||
id: payload.id,
|
|
||||||
code: payload.code,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {AdminCloudtentaclesVirtualNumberInput} [payload] */
|
|
||||||
export async function getAdminCloudtentaclesBindUrl(payload = /** @type {AdminCloudtentaclesVirtualNumberInput} */ ({})) {
|
|
||||||
const context = resolveAdminCloudtentaclesSessionPayload(payload)
|
|
||||||
return getCloudtentaclesBindUrl({
|
|
||||||
...context,
|
|
||||||
key: payload.key,
|
|
||||||
id: payload.id,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {AdminCloudtentaclesVirtualNumberInput} [payload] */
|
|
||||||
export async function backAdminCloudtentaclesVirtualNumber(payload = /** @type {AdminCloudtentaclesVirtualNumberInput} */ ({})) {
|
|
||||||
const context = resolveAdminCloudtentaclesSessionPayload(payload)
|
|
||||||
return backCloudtentaclesVirtualNumber({
|
|
||||||
...context,
|
|
||||||
key: payload.key,
|
|
||||||
id: payload.id,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {AdminCloudtentaclesFullFlowInput} [payload] */
|
|
||||||
export async function runAdminCloudtentaclesFullFlow(payload = /** @type {AdminCloudtentaclesFullFlowInput} */ ({})) {
|
|
||||||
const context = resolveAdminCloudtentaclesSessionPayload(payload)
|
|
||||||
return runCloudtentaclesFullDebugFlow({
|
|
||||||
...context,
|
|
||||||
skuId: payload.skuId,
|
|
||||||
skuCount: payload.skuCount,
|
|
||||||
vnKey: payload.vnKey,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getAdminFulfillmentBindingConfigs() {
|
|
||||||
const bindings = getOrderFulfillmentBindingConfigs()
|
|
||||||
|
|
||||||
return {
|
|
||||||
filePath: getOrderFulfillmentBindingsFilePath(),
|
|
||||||
bindings: bindings.map(mapAdminFulfillmentBindingConfigItem),
|
|
||||||
observedProducts: await listAdminObservedProducts(bindings),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getAdminKuaishouCloudFulfillmentConfig() {
|
|
||||||
const config = getKuaishouCloudFulfillmentConfig()
|
|
||||||
|
|
||||||
return {
|
|
||||||
filePath: getKuaishouCloudFulfillmentFilePath(),
|
|
||||||
source: mapAdminKuaishouCloudFulfillmentSource(config),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {AdminKuaishouCloudFulfillmentConfigInput} [payload] */
|
|
||||||
export async function updateAdminKuaishouCloudFulfillmentConfig(
|
|
||||||
payload = /** @type {AdminKuaishouCloudFulfillmentConfigInput} */ ({}),
|
|
||||||
) {
|
|
||||||
const saved = saveKuaishouCloudFulfillmentConfig({
|
|
||||||
enabled: payload.enabled !== false,
|
|
||||||
items: Array.isArray(payload.items) ? payload.items : [],
|
|
||||||
})
|
|
||||||
|
|
||||||
await syncConfiguredFulfillmentBindings()
|
|
||||||
|
|
||||||
return {
|
|
||||||
filePath: getKuaishouCloudFulfillmentFilePath(),
|
|
||||||
source: mapAdminKuaishouCloudFulfillmentSource(saved),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {AdminFulfillmentBindingLookupInput} [payload] */
|
|
||||||
export async function lookupAdminFulfillmentBindingOrder(payload = /** @type {AdminFulfillmentBindingLookupInput} */ ({})) {
|
|
||||||
const { provider, platform, shopId, platformOrderId } = normalizeFulfillmentLookupPayload(payload)
|
|
||||||
|
|
||||||
const detailResult = await enrichAgisoXianyuTradeOrder({
|
|
||||||
provider,
|
|
||||||
platform,
|
|
||||||
shopId,
|
|
||||||
shopName: '',
|
|
||||||
platformOrderId,
|
|
||||||
orderStatus: 'created',
|
|
||||||
payStatus: 'unpaid',
|
|
||||||
buyerId: '',
|
|
||||||
buyerName: '',
|
|
||||||
receiverContact: '',
|
|
||||||
totalAmount: 0,
|
|
||||||
currency: 'CNY',
|
|
||||||
paidAt: null,
|
|
||||||
rawPayload: {},
|
|
||||||
items: [],
|
|
||||||
}, {
|
|
||||||
requestId: `admin-fulfillment-lookup:${shopId}:${platformOrderId}`,
|
|
||||||
})
|
|
||||||
|
|
||||||
const { detail } = resolveFulfillmentLookupDetail(detailResult, platformOrderId)
|
|
||||||
const bindings = getOrderFulfillmentBindingConfigs()
|
|
||||||
return buildFulfillmentLookupResult({
|
|
||||||
provider,
|
|
||||||
platform,
|
|
||||||
shopId,
|
|
||||||
platformOrderId,
|
|
||||||
detail,
|
|
||||||
detailResult,
|
|
||||||
bindings,
|
|
||||||
fallbackShopName: getAgisoShopConfig(shopId)?.shopName,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {AdminFulfillmentBindingConfigSaveInput} [payload] */
|
|
||||||
export async function updateAdminFulfillmentBindingConfigs(
|
|
||||||
payload = /** @type {AdminFulfillmentBindingConfigSaveInput} */ ({}),
|
|
||||||
) {
|
|
||||||
const bindingsInput = Array.isArray(payload.bindings) ? payload.bindings : []
|
|
||||||
const normalizedBindings = await validateAdminFulfillmentBindingConfigs(bindingsInput, {
|
|
||||||
kuaishouEticketSource: getKuaishouEticketSourceConfig(),
|
|
||||||
resolveKuaishouEticketShopConfig,
|
|
||||||
getFulfillmentProfileByKey,
|
|
||||||
})
|
|
||||||
const saved = saveOrderFulfillmentBindingConfigs(normalizedBindings)
|
|
||||||
await syncConfiguredFulfillmentBindings()
|
|
||||||
|
|
||||||
return {
|
|
||||||
filePath: getOrderFulfillmentBindingsFilePath(),
|
|
||||||
bindings: saved.map(mapAdminFulfillmentBindingConfigItem),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user