175 lines
6.5 KiB
JavaScript
175 lines
6.5 KiB
JavaScript
import fs from 'node:fs'
|
|
import path from 'node:path'
|
|
|
|
import { PROJECT_ROOT } from '../../config/runtime.js'
|
|
import { resolveKuaishouEticketShopConfig } from '../platforms/kuaishou-eticket/source-config-service.js'
|
|
|
|
const KUAISHOU_CLOUD_FULFILLMENT_FILE_PATH = path.join(PROJECT_ROOT, 'data', 'kuaishou-cloud-fulfillment.json')
|
|
|
|
export function getKuaishouCloudFulfillmentFilePath() {
|
|
return KUAISHOU_CLOUD_FULFILLMENT_FILE_PATH
|
|
}
|
|
|
|
export function getKuaishouCloudFulfillmentConfig() {
|
|
return loadKuaishouCloudFulfillmentConfigFromFile()
|
|
}
|
|
|
|
export function saveKuaishouCloudFulfillmentConfig(rawValue) {
|
|
const normalized = normalizeKuaishouCloudFulfillmentConfig(rawValue)
|
|
fs.mkdirSync(path.dirname(KUAISHOU_CLOUD_FULFILLMENT_FILE_PATH), { recursive: true })
|
|
fs.writeFileSync(
|
|
KUAISHOU_CLOUD_FULFILLMENT_FILE_PATH,
|
|
`${JSON.stringify(normalized, null, 2)}\n`,
|
|
'utf8',
|
|
)
|
|
return normalized
|
|
}
|
|
|
|
export function mapKuaishouCloudFulfillmentItemsToBindings(config = {}) {
|
|
const items = Array.isArray(config.items) ? config.items : []
|
|
|
|
return items
|
|
.filter((item) => item && item.enabled !== false)
|
|
.map((item) => ({
|
|
provider: String(item.provider || '91kaquan').trim() || '91kaquan',
|
|
platform: String(item.platform || 'kuaishou').trim() || 'kuaishou',
|
|
shopId: String(item.shopId || '').trim(),
|
|
skuCode: String(item.internalSkuCode || '').trim(),
|
|
skuName: String(item.internalSkuName || '').trim(),
|
|
profileKey: 'kuaishou_ct_assisted',
|
|
enabled: item.enabled !== false,
|
|
priority: normalizePriority(item.priority),
|
|
config: {
|
|
flowType: 'kuaishou_cloud_fulfillment',
|
|
configId: String(item.id || '').trim(),
|
|
cloudtentacles: {
|
|
cloudSourceKey: String(item.cloudSourceKey || 'default').trim() || 'default',
|
|
skuId: normalizePositiveInteger(item.cloudSkuId),
|
|
skuName: String(item.cloudSkuName || '').trim(),
|
|
vnKey: '1',
|
|
autoBuyEnabled: item.autoBuyEnabled !== false,
|
|
minAssetReserve: normalizeNonNegativeInteger(item.minAssetReserve, 0),
|
|
autoReturnNumberAfterDispatch: item.autoReturnNumberAfterDispatch === true,
|
|
},
|
|
kuaishouConsume: {
|
|
shopId: String(item.kuaishouConsumeShopId || '').trim(),
|
|
shopName: String(item.kuaishouConsumeShopName || '').trim(),
|
|
autoConsumeAfterDispatch: item.autoConsumeAfterDispatch === true,
|
|
},
|
|
notes: String(item.notes || '').trim(),
|
|
},
|
|
match: {
|
|
externalSkuCode: String(item.externalSkuCode || '').trim(),
|
|
externalItemId: String(item.externalItemId || '').trim(),
|
|
externalSkuName: String(item.externalSkuName || '').trim(),
|
|
config: {
|
|
resolvedSkuName: String(item.resolvedSkuName || item.internalSkuName || '').trim(),
|
|
},
|
|
},
|
|
}))
|
|
.filter((item) => item.skuCode && (item.match.externalSkuCode || item.match.externalItemId || item.match.externalSkuName))
|
|
}
|
|
|
|
function loadKuaishouCloudFulfillmentConfigFromFile() {
|
|
if (!fs.existsSync(KUAISHOU_CLOUD_FULFILLMENT_FILE_PATH)) {
|
|
return normalizeKuaishouCloudFulfillmentConfig({})
|
|
}
|
|
|
|
try {
|
|
const rawText = fs.readFileSync(KUAISHOU_CLOUD_FULFILLMENT_FILE_PATH, 'utf8')
|
|
const parsed = JSON.parse(rawText)
|
|
return normalizeKuaishouCloudFulfillmentConfig(parsed)
|
|
} catch {
|
|
return normalizeKuaishouCloudFulfillmentConfig({})
|
|
}
|
|
}
|
|
|
|
function normalizeKuaishouCloudFulfillmentConfig(rawValue) {
|
|
const source = isPlainObject(rawValue) ? rawValue : {}
|
|
return {
|
|
enabled: source.enabled !== false,
|
|
items: Array.isArray(source.items)
|
|
? source.items.map((item) => normalizeKuaishouCloudFulfillmentItem(item)).filter(Boolean)
|
|
: [],
|
|
}
|
|
}
|
|
|
|
function normalizeKuaishouCloudFulfillmentItem(rawValue) {
|
|
if (!isPlainObject(rawValue)) {
|
|
return null
|
|
}
|
|
|
|
const internalSkuCode = String(rawValue.internalSkuCode || '').trim()
|
|
const cloudSkuId = normalizePositiveInteger(rawValue.cloudSkuId)
|
|
const externalSkuCode = String(rawValue.externalSkuCode || '').trim()
|
|
const externalItemId = String(rawValue.externalItemId || '').trim()
|
|
const externalSkuName = String(rawValue.externalSkuName || '').trim()
|
|
const kuaishouConsumeShopId = String(rawValue.kuaishouConsumeShopId || '').trim()
|
|
const kuaishouConsumeShopName = String(rawValue.kuaishouConsumeShopName || '').trim()
|
|
const kuaishouShopConfig = resolveKuaishouEticketShopConfig({
|
|
shopId: kuaishouConsumeShopId,
|
|
shopName: kuaishouConsumeShopName,
|
|
})
|
|
|
|
if (!internalSkuCode) {
|
|
return null
|
|
}
|
|
|
|
if (!cloudSkuId) {
|
|
return null
|
|
}
|
|
|
|
if (!externalSkuCode && !externalItemId && !externalSkuName) {
|
|
return null
|
|
}
|
|
|
|
return {
|
|
id: String(rawValue.id || internalSkuCode).trim() || internalSkuCode,
|
|
enabled: rawValue.enabled !== false,
|
|
priority: normalizePriority(rawValue.priority),
|
|
provider: String(rawValue.provider || '91kaquan').trim() || '91kaquan',
|
|
platform: String(rawValue.platform || 'kuaishou').trim() || 'kuaishou',
|
|
shopId: String(rawValue.shopId || '').trim(),
|
|
internalSkuCode,
|
|
internalSkuName: String(rawValue.internalSkuName || '').trim() || internalSkuCode,
|
|
externalSkuCode,
|
|
externalItemId,
|
|
externalSkuName,
|
|
resolvedSkuName: String(rawValue.resolvedSkuName || rawValue.internalSkuName || '').trim(),
|
|
cloudSourceKey: String(rawValue.cloudSourceKey || 'default').trim() || 'default',
|
|
cloudSkuId,
|
|
cloudSkuName: String(rawValue.cloudSkuName || '').trim(),
|
|
vnKey: '1',
|
|
autoBuyEnabled: rawValue.autoBuyEnabled !== false,
|
|
minAssetReserve: normalizeNonNegativeInteger(rawValue.minAssetReserve, 0),
|
|
autoReturnNumberAfterDispatch: rawValue.autoReturnNumberAfterDispatch === true,
|
|
autoConsumeAfterDispatch: rawValue.autoConsumeAfterDispatch === true,
|
|
kuaishouConsumeShopId: String(kuaishouShopConfig?.shopId || kuaishouConsumeShopId).trim(),
|
|
kuaishouConsumeShopName: String(kuaishouShopConfig?.kshopName || kuaishouConsumeShopName).trim(),
|
|
notes: String(rawValue.notes || '').trim(),
|
|
}
|
|
}
|
|
|
|
function normalizePositiveInteger(value) {
|
|
const parsed = Number(value)
|
|
return Number.isInteger(parsed) && parsed > 0 ? parsed : 0
|
|
}
|
|
|
|
function normalizeNonNegativeInteger(value, fallback) {
|
|
const parsed = Number(value)
|
|
return Number.isInteger(parsed) && parsed >= 0 ? parsed : fallback
|
|
}
|
|
|
|
function normalizePriority(value) {
|
|
const parsed = Number(value)
|
|
if (!Number.isFinite(parsed)) {
|
|
return 100
|
|
}
|
|
|
|
return Math.max(1, Math.round(parsed))
|
|
}
|
|
|
|
function isPlainObject(value) {
|
|
return Object.prototype.toString.call(value) === '[object Object]'
|
|
}
|