发货与退还增加

This commit is contained in:
yml
2026-05-03 17:15:48 +08:00
parent b568d70e64
commit 063c3fd8a1
12 changed files with 188 additions and 5 deletions
@@ -4,6 +4,7 @@ import { Router } from 'express'
import {
appointAdminCloudtentaclesVirtualNumber,
backAdminCloudtentaclesVirtualNumber,
buyAdminCloudtentaclesSku,
fetchAdminCloudtentaclesVirtualNumberCode,
generateAdminCloudtentaclesLoginCode,
@@ -14,6 +15,7 @@ import {
getAdminCloudtentaclesKnapsack,
getAdminCloudtentaclesSourceConfig,
getAdminCloudtentaclesSkuList,
useAdminCloudtentaclesSku,
getAdminAgisoShopConfigs,
getAdminFulfillmentBindingConfigs,
getAdminKhhaoSourceConfig,
@@ -54,6 +56,7 @@ import { createJsonHandler, requireAdminRoles } from './shared.js'
/** @typedef {import('../../types/admin-route-inputs.js').AdminCloudtentaclesValidateSessionRouteBody} AdminCloudtentaclesValidateSessionRouteBody */
/** @typedef {import('../../types/admin-route-inputs.js').AdminCloudtentaclesCatalogQueryRouteBody} AdminCloudtentaclesCatalogQueryRouteBody */
/** @typedef {import('../../types/admin-route-inputs.js').AdminCloudtentaclesSkuBuyRouteBody} AdminCloudtentaclesSkuBuyRouteBody */
/** @typedef {import('../../types/admin-route-inputs.js').AdminCloudtentaclesSkuUseRouteBody} AdminCloudtentaclesSkuUseRouteBody */
/** @typedef {import('../../types/admin-route-inputs.js').AdminCloudtentaclesVirtualNumberRouteBody} AdminCloudtentaclesVirtualNumberRouteBody */
/** @typedef {import('../../types/admin-route-inputs.js').AdminCloudtentaclesFullFlowRouteBody} AdminCloudtentaclesFullFlowRouteBody */
/** @typedef {import('../../types/admin-write-models.js').AdminAgisoShopConfigSaveResponse} AdminAgisoShopConfigSaveResponse */
@@ -429,6 +432,15 @@ router.post('/platform-config/cloudtentacles/sku/buy', createJsonHandler(
},
))
router.post('/platform-config/cloudtentacles/sku/use', createJsonHandler(
(req) => useAdminCloudtentaclesSku(/** @type {AdminCloudtentaclesSkuUseRouteBody} */ (req.body)),
{
successMessage: 'cloudtentacles 发货成功',
errorMessage: 'cloudtentacles 发货失败',
scope: '[admin/platform-config/cloudtentacles/sku/use]',
},
))
router.post('/platform-config/cloudtentacles/knapsack', createJsonHandler(
(req) => getAdminCloudtentaclesKnapsack(/** @type {AdminCloudtentaclesCatalogQueryRouteBody} */ (req.body)),
{
@@ -492,6 +504,15 @@ router.post('/platform-config/cloudtentacles/vn/bind-url', createJsonHandler(
},
))
router.post('/platform-config/cloudtentacles/vn/back', createJsonHandler(
(req) => backAdminCloudtentaclesVirtualNumber(/** @type {AdminCloudtentaclesVirtualNumberRouteBody} */ (req.body)),
{
successMessage: 'cloudtentacles 号码退还成功',
errorMessage: 'cloudtentacles 号码退还失败',
scope: '[admin/platform-config/cloudtentacles/vn/back]',
},
))
router.post('/platform-config/cloudtentacles/debug/full-flow', createJsonHandler(
(req) => runAdminCloudtentaclesFullFlow(/** @type {AdminCloudtentaclesFullFlowRouteBody} */ (req.body)),
{
@@ -49,10 +49,12 @@ import {
getCloudtentaclesAsset,
getCloudtentaclesCategories,
listCloudtentaclesSku,
useCloudtentaclesSku,
} from '../platforms/cloudtentacles/catalog-service.js'
import { getCloudtentaclesKnapsack } from '../platforms/cloudtentacles/knapsack-service.js'
import {
appointCloudtentaclesVirtualNumber,
backCloudtentaclesVirtualNumber,
fetchCloudtentaclesVirtualNumberCode,
generateCloudtentaclesLoginCode,
getCloudtentaclesBindUrl,
@@ -87,6 +89,7 @@ import { resolveDisplayShopName } from './admin-read-shared-helpers.js'
/** @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 */
@@ -629,6 +632,17 @@ export async function buyAdminCloudtentaclesSku(payload = /** @type {AdminCloudt
})
}
/** @param {AdminCloudtentaclesSkuUseInput} [payload] */
export async function useAdminCloudtentaclesSku(payload = /** @type {AdminCloudtentaclesSkuUseInput} */ ({})) {
const context = resolveCloudtentaclesAdminContext(payload)
return useCloudtentaclesSku({
...context,
id: payload.id,
virtualNumberId: payload.virtualNumberId,
phone: payload.phone,
})
}
/** @param {AdminCloudtentaclesCatalogQueryInput} [payload] */
export async function getAdminCloudtentaclesKnapsack(payload = /** @type {AdminCloudtentaclesCatalogQueryInput} */ ({})) {
const context = resolveCloudtentaclesAdminContext(payload)
@@ -694,6 +708,16 @@ export async function getAdminCloudtentaclesBindUrl(payload = /** @type {AdminCl
})
}
/** @param {AdminCloudtentaclesVirtualNumberInput} [payload] */
export async function backAdminCloudtentaclesVirtualNumber(payload = /** @type {AdminCloudtentaclesVirtualNumberInput} */ ({})) {
const context = resolveCloudtentaclesAdminContext(payload)
return backCloudtentaclesVirtualNumber({
...context,
key: payload.key,
id: payload.id,
})
}
/** @param {AdminCloudtentaclesFullFlowInput} [payload] */
export async function runAdminCloudtentaclesFullFlow(payload = /** @type {AdminCloudtentaclesFullFlowInput} */ ({})) {
const context = resolveCloudtentaclesAdminContext(payload)
@@ -96,6 +96,50 @@ export async function buyCloudtentaclesSku(payload = {}) {
}
}
export async function useCloudtentaclesSku(payload = {}) {
const token = requireToken(payload.token, 'cloudtentacles 发货缺少 token', 'cloudtentacles_sku_use_missing_token')
const skuId = requireId(payload.id, 'cloudtentacles 发货缺少商品 id', 'cloudtentacles_sku_use_missing_id')
const virtualNumberId = requireId(
payload.virtualNumberId,
'cloudtentacles 发货缺少虚拟号 id',
'cloudtentacles_sku_use_missing_virtual_number_id',
)
const phone = String(payload.phone || '').trim()
if (!phone) {
throw createHttpError('cloudtentacles 发货缺少手机号', {
statusCode: 400,
errorCode: 'cloudtentacles_sku_use_missing_phone',
})
}
const config = resolveCloudtentaclesConfig(payload)
const result = await cloudtentaclesRequest(config.skuUsePath, {
...config,
method: 'POST',
token,
body: {
id: skuId,
virtual_number_id: virtualNumberId,
phone,
},
businessErrorStatusCode: 401,
businessErrorCode: 'cloudtentacles_sku_use_failed',
})
const responseData = isPlainObject(result.payload?.data) ? result.payload.data : {}
return {
baseUrl: config.baseUrl,
id: skuId,
virtualNumberId,
phone,
sendType: Number(responseData.send_type || 0),
note: String(responseData.note || '').trim(),
responseMessage: String(result.payload?.message || result.payload?.msg || 'success'),
raw: result.payload ?? null,
}
}
function mapCategoryItem(item) {
const source = isPlainObject(item) ? item : {}
@@ -17,6 +17,7 @@ export function resolveCloudtentaclesConfig(overrides = {}) {
categoriesPath: '/categories/get',
skuListPath: '/sku/list',
skuBuyPath: '/sku/buy',
skuUsePath: '/sku/use',
knapsackPath: '/user/get_knapsack',
vnListPath: '/vn/list',
vnAppointPath: '/vn/appoint',
@@ -24,6 +25,7 @@ export function resolveCloudtentaclesConfig(overrides = {}) {
vnVerifCodePath: '/public/vn_verif_code',
vnVerifyLoginCodePath: '/vn/verify_login_code',
vnBindUrlPath: '/vn/bind_url',
vnBackPath: '/vn/back',
publicKeyPem: '',
clientSource: 'ct-client',
deviceId: '-',
@@ -41,6 +43,7 @@ export function resolveCloudtentaclesConfig(overrides = {}) {
categoriesPath: normalizePath(overrides.categoriesPath || baseConfig.categoriesPath, '/categories/get'),
skuListPath: normalizePath(overrides.skuListPath || baseConfig.skuListPath, '/sku/list'),
skuBuyPath: normalizePath(overrides.skuBuyPath || baseConfig.skuBuyPath, '/sku/buy'),
skuUsePath: normalizePath(overrides.skuUsePath || baseConfig.skuUsePath, '/sku/use'),
knapsackPath: normalizePath(overrides.knapsackPath || baseConfig.knapsackPath, '/user/get_knapsack'),
vnListPath: normalizePath(overrides.vnListPath || baseConfig.vnListPath, '/vn/list'),
vnAppointPath: normalizePath(overrides.vnAppointPath || baseConfig.vnAppointPath, '/vn/appoint'),
@@ -54,6 +57,7 @@ export function resolveCloudtentaclesConfig(overrides = {}) {
'/vn/verify_login_code',
),
vnBindUrlPath: normalizePath(overrides.vnBindUrlPath || baseConfig.vnBindUrlPath, '/vn/bind_url'),
vnBackPath: normalizePath(overrides.vnBackPath || baseConfig.vnBackPath, '/vn/back'),
publicKeyPem: normalizePem(overrides.publicKeyPem || baseConfig.publicKeyPem),
clientSource: String(overrides.clientSource || baseConfig.clientSource || 'ct-client').trim() || 'ct-client',
deviceId: String(overrides.deviceId ?? baseConfig.deviceId ?? '-').trim() || '-',
@@ -159,6 +159,30 @@ export async function getCloudtentaclesBindUrl(payload = {}) {
}
}
export async function backCloudtentaclesVirtualNumber(payload = {}) {
const token = requireToken(payload.token, 'cloudtentacles 退还号码缺少 token', 'cloudtentacles_vn_back_missing_token')
const key = requireKey(payload.key, 'cloudtentacles 退还号码缺少 key', 'cloudtentacles_vn_back_missing_key')
const id = requireId(payload.id, 'cloudtentacles 退还号码缺少 id', 'cloudtentacles_vn_back_missing_id')
const config = resolveCloudtentaclesConfig(payload)
const result = await cloudtentaclesRequest(config.vnBackPath, {
...config,
method: 'POST',
token,
body: { key, id },
businessErrorStatusCode: 401,
businessErrorCode: 'cloudtentacles_vn_back_failed',
})
return {
baseUrl: config.baseUrl,
key,
id,
responseMessage: String(result.payload?.message || result.payload?.msg || 'success'),
raw: result.payload ?? null,
}
}
function mapVirtualNumberItem(item) {
const source = isPlainObject(item) ? item : {}
const bindInfoText = String(source.bind_info || '').trim()
@@ -86,6 +86,10 @@ export {}
* @typedef {import('./admin-write-inputs.js').AdminCloudtentaclesSkuBuyInput} AdminCloudtentaclesSkuBuyRouteBody
*/
/**
* @typedef {import('./admin-write-inputs.js').AdminCloudtentaclesSkuUseInput} AdminCloudtentaclesSkuUseRouteBody
*/
/**
* @typedef {import('./admin-write-inputs.js').AdminCloudtentaclesVirtualNumberInput} AdminCloudtentaclesVirtualNumberRouteBody
*/
@@ -215,6 +215,18 @@ export {}
* }} AdminCloudtentaclesSkuBuyInput
*/
/**
* @typedef {{
* baseUrl?: string
* token?: string
* deviceId?: string
* deviceType?: number | string
* id?: number | string
* virtualNumberId?: number | string
* phone?: string
* }} AdminCloudtentaclesSkuUseInput
*/
/**
* @typedef {{
* baseUrl?: string
+2
View File
@@ -107,6 +107,7 @@ export {}
* categoriesPath: string
* skuListPath: string
* skuBuyPath: string
* skuUsePath: string
* knapsackPath: string
* vnListPath: string
* vnAppointPath: string
@@ -114,6 +115,7 @@ export {}
* vnVerifCodePath: string
* vnVerifyLoginCodePath: string
* vnBindUrlPath: string
* vnBackPath: string
* publicKeyPem: string
* clientSource: string
* deviceId: string