统一前后端代码格式化配置
This commit is contained in:
@@ -1,8 +1,6 @@
|
||||
import { getAffiliateDashConfig } from '../../platforms/affiliate-dash/config.js'
|
||||
import type { JsonObject } from '../../../types/json.js'
|
||||
import {
|
||||
getAffiliateDashWallet,
|
||||
} from '../../platforms/affiliate-dash/order-service.js'
|
||||
import { getAffiliateDashWallet } from '../../platforms/affiliate-dash/order-service.js'
|
||||
import { listAffiliateDashProducts } from '../../platforms/affiliate-dash/product-service.js'
|
||||
import {
|
||||
getAffiliateDashSourceConfig,
|
||||
@@ -35,9 +33,7 @@ export async function updateAdminAffiliateDashConfig(payload: JsonObject = {}) {
|
||||
export function matchAdminAffiliateDashSku(payload: JsonObject = {}) {
|
||||
const productNo = String(payload.productNo || payload.product_no || '').trim()
|
||||
const source = getAdminEditableAffiliateDashConfig()
|
||||
const sku = productNo
|
||||
? String(source.skuMapping[productNo] || '').trim()
|
||||
: ''
|
||||
const sku = productNo ? String(source.skuMapping[productNo] || '').trim() : ''
|
||||
|
||||
return {
|
||||
productNo,
|
||||
|
||||
@@ -52,7 +52,13 @@ test('resolveCloudtentaclesAdminContext merges payload source and persisted sess
|
||||
test('hasCloudtentaclesCredentialContextChanged detects normalized credential changes', () => {
|
||||
assert.equal(
|
||||
hasCloudtentaclesCredentialContextChanged(
|
||||
{ baseUrl: ' https://a ', username: 'u1', phone: '13812345678', deviceId: 'd1', deviceType: 1 },
|
||||
{
|
||||
baseUrl: ' https://a ',
|
||||
username: 'u1',
|
||||
phone: '13812345678',
|
||||
deviceId: 'd1',
|
||||
deviceType: 1,
|
||||
},
|
||||
{ baseUrl: 'https://a', username: 'u1', phone: '13812345678', deviceId: 'd1', deviceType: 1 },
|
||||
),
|
||||
false,
|
||||
|
||||
@@ -1,70 +1,57 @@
|
||||
export function pickFirstNonEmpty(values: unknown[]) {
|
||||
for (const value of values) {
|
||||
const normalized = String(value || "").trim();
|
||||
const normalized = String(value || '').trim()
|
||||
if (normalized) {
|
||||
return normalized;
|
||||
return normalized
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
return ''
|
||||
}
|
||||
|
||||
export function isPlainObject(value: unknown): value is JsonObject {
|
||||
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
||||
return Boolean(value) && typeof value === 'object' && !Array.isArray(value)
|
||||
}
|
||||
|
||||
import { getCloudtentaclesSourceByKey } from "../../../platforms/cloudtentacles/source-config-service.js";
|
||||
import { getCloudtentaclesSessionStateByKey } from "../../../platforms/cloudtentacles/session-state-service.js";
|
||||
import { getCloudtentaclesSourceByKey } from '../../../platforms/cloudtentacles/source-config-service.js'
|
||||
import { getCloudtentaclesSessionStateByKey } from '../../../platforms/cloudtentacles/session-state-service.js'
|
||||
import type { JsonObject } from '../../../../types/json.js'
|
||||
import {
|
||||
normalizeCloudtentaclesDeviceId,
|
||||
normalizeCloudtentaclesDeviceType,
|
||||
} from "../../../platforms/cloudtentacles/defaults.js";
|
||||
} from '../../../platforms/cloudtentacles/defaults.js'
|
||||
|
||||
export function resolveCloudtentaclesAdminContext(payload: JsonObject = {}, options: JsonObject = {}) {
|
||||
const sourceKey = String(
|
||||
payload.sourceKey || options.sourceKey || "default"
|
||||
).trim();
|
||||
const savedSource = options.savedSource || getCloudtentaclesSourceByKey(sourceKey) || {};
|
||||
const persistedSession = options.persistedSession ||
|
||||
getCloudtentaclesSessionStateByKey(sourceKey) ||
|
||||
{};
|
||||
const defaultBaseUrl = String(
|
||||
options.defaultBaseUrl || "https://123.207.217.176"
|
||||
).trim();
|
||||
export function resolveCloudtentaclesAdminContext(
|
||||
payload: JsonObject = {},
|
||||
options: JsonObject = {},
|
||||
) {
|
||||
const sourceKey = String(payload.sourceKey || options.sourceKey || 'default').trim()
|
||||
const savedSource = options.savedSource || getCloudtentaclesSourceByKey(sourceKey) || {}
|
||||
const persistedSession =
|
||||
options.persistedSession || getCloudtentaclesSessionStateByKey(sourceKey) || {}
|
||||
const defaultBaseUrl = String(options.defaultBaseUrl || 'https://123.207.217.176').trim()
|
||||
return {
|
||||
sourceKey,
|
||||
baseUrl: pickFirstNonEmpty([
|
||||
payload.baseUrl,
|
||||
savedSource.baseUrl,
|
||||
defaultBaseUrl,
|
||||
]),
|
||||
baseUrl: pickFirstNonEmpty([payload.baseUrl, savedSource.baseUrl, defaultBaseUrl]),
|
||||
token: pickFirstNonEmpty([payload.token, persistedSession.token]),
|
||||
deviceId: normalizeCloudtentaclesDeviceId(
|
||||
pickFirstNonEmpty([
|
||||
payload.deviceId,
|
||||
savedSource.deviceId,
|
||||
persistedSession.deviceId,
|
||||
])
|
||||
pickFirstNonEmpty([payload.deviceId, savedSource.deviceId, persistedSession.deviceId]),
|
||||
),
|
||||
deviceType: normalizeCloudtentaclesDeviceType(
|
||||
payload.deviceType ?? savedSource.deviceType ?? persistedSession.deviceType
|
||||
payload.deviceType ?? savedSource.deviceType ?? persistedSession.deviceType,
|
||||
),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export function hasCloudtentaclesCredentialContextChanged(
|
||||
current: JsonObject = {},
|
||||
next: JsonObject = {}
|
||||
next: JsonObject = {},
|
||||
) {
|
||||
return (
|
||||
String(current.baseUrl || "").trim() !==
|
||||
String(next.baseUrl || "").trim() ||
|
||||
String(current.username || "").trim() !==
|
||||
String(next.username || "").trim() ||
|
||||
String(current.phone || "").trim() !== String(next.phone || "").trim() ||
|
||||
String(current.deviceId || "").trim() !==
|
||||
String(next.deviceId || "").trim() ||
|
||||
String(current.baseUrl || '').trim() !== String(next.baseUrl || '').trim() ||
|
||||
String(current.username || '').trim() !== String(next.username || '').trim() ||
|
||||
String(current.phone || '').trim() !== String(next.phone || '').trim() ||
|
||||
String(current.deviceId || '').trim() !== String(next.deviceId || '').trim() ||
|
||||
Number(current.deviceType || 0) !== Number(next.deviceType || 0)
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,11 +1,7 @@
|
||||
import test from 'node:test'
|
||||
import assert from 'node:assert/strict'
|
||||
|
||||
import {
|
||||
mapAdminCloudtentaclesSession,
|
||||
maskPhone,
|
||||
maskSecret,
|
||||
} from './mappers.js'
|
||||
import { mapAdminCloudtentaclesSession, maskPhone, maskSecret } from './mappers.js'
|
||||
|
||||
test('maskSecret preserves edges while hiding middle characters', () => {
|
||||
assert.equal(maskSecret('abcdef1234567890'), 'abcdef****567890')
|
||||
|
||||
@@ -2,44 +2,44 @@ import type { JsonObject } from '../../../../types/json.js'
|
||||
import {
|
||||
maskPhone as maskPhoneValue,
|
||||
maskSecret as maskSecretValue,
|
||||
} from "../../../../utils/masking.js";
|
||||
} from '../../../../utils/masking.js'
|
||||
import {
|
||||
normalizeCloudtentaclesDeviceId,
|
||||
normalizeCloudtentaclesDeviceType,
|
||||
} from "../../../platforms/cloudtentacles/defaults.js";
|
||||
} from '../../../platforms/cloudtentacles/defaults.js'
|
||||
|
||||
export function maskSecret(value: unknown) {
|
||||
return maskSecretValue(value);
|
||||
return maskSecretValue(value)
|
||||
}
|
||||
|
||||
export function maskPhone(value: unknown) {
|
||||
return maskPhoneValue(value, { maskShort: false });
|
||||
return maskPhoneValue(value, { maskShort: false })
|
||||
}
|
||||
|
||||
export function mapAdminCloudtentaclesSourceConfig(config: JsonObject = {}) {
|
||||
return {
|
||||
key: String(config.key || "").trim(),
|
||||
label: String(config.label || "").trim(),
|
||||
key: String(config.key || '').trim(),
|
||||
label: String(config.label || '').trim(),
|
||||
enabled: config.enabled !== false,
|
||||
baseUrl: String(config.baseUrl || "").trim(),
|
||||
username: String(config.username || "").trim(),
|
||||
password: String(config.password || "").trim(),
|
||||
phone: String(config.phone || "").trim(),
|
||||
baseUrl: String(config.baseUrl || '').trim(),
|
||||
username: String(config.username || '').trim(),
|
||||
password: String(config.password || '').trim(),
|
||||
phone: String(config.phone || '').trim(),
|
||||
deviceId: normalizeCloudtentaclesDeviceId(config.deviceId),
|
||||
deviceType: normalizeCloudtentaclesDeviceType(config.deviceType),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export function mapAdminCloudtentaclesSession(session: JsonObject = {}) {
|
||||
return {
|
||||
token: String(session.token || "").trim(),
|
||||
token: String(session.token || '').trim(),
|
||||
tokenMasked: maskSecret(session.token),
|
||||
baseUrl: String(session.baseUrl || "").trim(),
|
||||
username: String(session.username || "").trim(),
|
||||
baseUrl: String(session.baseUrl || '').trim(),
|
||||
username: String(session.username || '').trim(),
|
||||
phoneMasked: maskPhone(session.phone),
|
||||
loggedInAt: String(session.loggedInAt || "").trim(),
|
||||
loggedInAt: String(session.loggedInAt || '').trim(),
|
||||
deviceId: normalizeCloudtentaclesDeviceId(session.deviceId),
|
||||
deviceType: normalizeCloudtentaclesDeviceType(session.deviceType),
|
||||
hasToken: Boolean(String(session.token || "").trim()),
|
||||
};
|
||||
hasToken: Boolean(String(session.token || '').trim()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,96 +1,80 @@
|
||||
import { getCloudtentaclesSourceByKey } from "../../../platforms/cloudtentacles/source-config-service.js";
|
||||
import { getCloudtentaclesSessionStateByKey } from "../../../platforms/cloudtentacles/session-state-service.js";
|
||||
import { getCloudtentaclesSourceByKey } from '../../../platforms/cloudtentacles/source-config-service.js'
|
||||
import { getCloudtentaclesSessionStateByKey } from '../../../platforms/cloudtentacles/session-state-service.js'
|
||||
import type { JsonObject } from '../../../../types/json.js'
|
||||
import {
|
||||
normalizeCloudtentaclesDeviceId,
|
||||
normalizeCloudtentaclesDeviceType,
|
||||
} from "../../../platforms/cloudtentacles/defaults.js";
|
||||
import {
|
||||
pickFirstNonEmpty,
|
||||
resolveCloudtentaclesAdminContext,
|
||||
} from "./context.js";
|
||||
import { maskPhone, maskSecret } from "./mappers.js";
|
||||
} from '../../../platforms/cloudtentacles/defaults.js'
|
||||
import { pickFirstNonEmpty, resolveCloudtentaclesAdminContext } from './context.js'
|
||||
import { maskPhone, maskSecret } from './mappers.js'
|
||||
|
||||
const DEFAULT_CLOUDTENTACLES_BASE_URL = "https://123.207.217.176";
|
||||
const DEFAULT_CLOUDTENTACLES_BASE_URL = 'https://123.207.217.176'
|
||||
|
||||
function _resolveSourceKey(payload: JsonObject = {}) {
|
||||
return String(payload.sourceKey || "").trim() || "default";
|
||||
return String(payload.sourceKey || '').trim() || 'default'
|
||||
}
|
||||
|
||||
export function resolveAdminCloudtentaclesCredentialPayload(
|
||||
payload: JsonObject = {},
|
||||
options: JsonObject = {}
|
||||
options: JsonObject = {},
|
||||
) {
|
||||
const sourceKey = _resolveSourceKey(payload);
|
||||
const savedSource = options.savedSource || getCloudtentaclesSourceByKey(sourceKey) || {};
|
||||
const defaultBaseUrl = String(
|
||||
options.defaultBaseUrl || DEFAULT_CLOUDTENTACLES_BASE_URL
|
||||
).trim();
|
||||
const sourceKey = _resolveSourceKey(payload)
|
||||
const savedSource = options.savedSource || getCloudtentaclesSourceByKey(sourceKey) || {}
|
||||
const defaultBaseUrl = String(options.defaultBaseUrl || DEFAULT_CLOUDTENTACLES_BASE_URL).trim()
|
||||
|
||||
return {
|
||||
sourceKey,
|
||||
baseUrl: pickFirstNonEmpty([
|
||||
payload.baseUrl,
|
||||
savedSource.baseUrl,
|
||||
defaultBaseUrl,
|
||||
]),
|
||||
baseUrl: pickFirstNonEmpty([payload.baseUrl, savedSource.baseUrl, defaultBaseUrl]),
|
||||
username: pickFirstNonEmpty([payload.username, savedSource.username]),
|
||||
password: pickFirstNonEmpty([payload.password, savedSource.password]),
|
||||
phone: pickFirstNonEmpty([payload.phone, savedSource.phone]),
|
||||
deviceId: normalizeCloudtentaclesDeviceId(
|
||||
pickFirstNonEmpty([payload.deviceId, savedSource.deviceId])
|
||||
pickFirstNonEmpty([payload.deviceId, savedSource.deviceId]),
|
||||
),
|
||||
deviceType: normalizeCloudtentaclesDeviceType(
|
||||
payload.deviceType ?? savedSource.deviceType
|
||||
),
|
||||
};
|
||||
deviceType: normalizeCloudtentaclesDeviceType(payload.deviceType ?? savedSource.deviceType),
|
||||
}
|
||||
}
|
||||
|
||||
export function resolveAdminCloudtentaclesSessionPayload(
|
||||
payload: JsonObject = {},
|
||||
options: JsonObject = {}
|
||||
options: JsonObject = {},
|
||||
) {
|
||||
const sourceKey = _resolveSourceKey(payload);
|
||||
const savedSource = options.savedSource || getCloudtentaclesSourceByKey(sourceKey) || {};
|
||||
const persistedSession = options.persistedSession ||
|
||||
getCloudtentaclesSessionStateByKey(sourceKey) ||
|
||||
{};
|
||||
const sourceKey = _resolveSourceKey(payload)
|
||||
const savedSource = options.savedSource || getCloudtentaclesSourceByKey(sourceKey) || {}
|
||||
const persistedSession =
|
||||
options.persistedSession || getCloudtentaclesSessionStateByKey(sourceKey) || {}
|
||||
|
||||
return resolveCloudtentaclesAdminContext(payload, {
|
||||
savedSource,
|
||||
persistedSession,
|
||||
sourceKey,
|
||||
defaultBaseUrl: options.defaultBaseUrl || DEFAULT_CLOUDTENTACLES_BASE_URL,
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
export function buildAdminCloudtentaclesPersistedSessionPayload(
|
||||
session: JsonObject = {},
|
||||
options: JsonObject = {}
|
||||
options: JsonObject = {},
|
||||
) {
|
||||
return {
|
||||
token: String(session.token || "").trim(),
|
||||
baseUrl: String(session.baseUrl || "").trim(),
|
||||
token: String(session.token || '').trim(),
|
||||
baseUrl: String(session.baseUrl || '').trim(),
|
||||
username: pickFirstNonEmpty([options.username, session.username]),
|
||||
phone: pickFirstNonEmpty([options.phone, session.phone]),
|
||||
loggedInAt: String(session.loggedInAt || "").trim(),
|
||||
loggedInAt: String(session.loggedInAt || '').trim(),
|
||||
deviceId: normalizeCloudtentaclesDeviceId(
|
||||
pickFirstNonEmpty([options.deviceId, session.deviceId])
|
||||
pickFirstNonEmpty([options.deviceId, session.deviceId]),
|
||||
),
|
||||
deviceType: normalizeCloudtentaclesDeviceType(
|
||||
options.deviceType ?? session.deviceType
|
||||
),
|
||||
};
|
||||
deviceType: normalizeCloudtentaclesDeviceType(options.deviceType ?? session.deviceType),
|
||||
}
|
||||
}
|
||||
|
||||
export function buildAdminCloudtentaclesSessionSummary(
|
||||
session: JsonObject = {},
|
||||
savedSession: JsonObject = {},
|
||||
sourceKey = "default"
|
||||
sourceKey = 'default',
|
||||
) {
|
||||
const permissions = Array.isArray(session.permissions)
|
||||
? session.permissions
|
||||
: [];
|
||||
const permissions = Array.isArray(session.permissions) ? session.permissions : []
|
||||
|
||||
return {
|
||||
sourceKey,
|
||||
@@ -98,47 +82,39 @@ export function buildAdminCloudtentaclesSessionSummary(
|
||||
permissionCount: permissions.length,
|
||||
permissions,
|
||||
persisted: Boolean(savedSession.token),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export function buildAdminCloudtentaclesLoginResult(
|
||||
session: JsonObject = {},
|
||||
savedSession: JsonObject = {},
|
||||
sourceKey = "default"
|
||||
sourceKey = 'default',
|
||||
) {
|
||||
return {
|
||||
sourceKey,
|
||||
baseUrl: String(session.baseUrl || "").trim(),
|
||||
username: String(session.username || "").trim(),
|
||||
baseUrl: String(session.baseUrl || '').trim(),
|
||||
username: String(session.username || '').trim(),
|
||||
phoneMasked: maskPhone(session.phone),
|
||||
loggedInAt: String(session.loggedInAt || "").trim(),
|
||||
responseMessage: String(session.responseMessage || "").trim(),
|
||||
token: String(session.token || "").trim(),
|
||||
session: buildAdminCloudtentaclesSessionSummary(
|
||||
session,
|
||||
savedSession,
|
||||
sourceKey
|
||||
),
|
||||
loggedInAt: String(session.loggedInAt || '').trim(),
|
||||
responseMessage: String(session.responseMessage || '').trim(),
|
||||
token: String(session.token || '').trim(),
|
||||
session: buildAdminCloudtentaclesSessionSummary(session, savedSession, sourceKey),
|
||||
userInfo: session.userInfo,
|
||||
asset: session.asset,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export function buildAdminCloudtentaclesValidateResult(
|
||||
session: JsonObject = {},
|
||||
savedSession: JsonObject = {},
|
||||
sourceKey = "default"
|
||||
sourceKey = 'default',
|
||||
) {
|
||||
return {
|
||||
sourceKey,
|
||||
baseUrl: String(session.baseUrl || "").trim(),
|
||||
loggedInAt: String(session.loggedInAt || "").trim(),
|
||||
session: buildAdminCloudtentaclesSessionSummary(
|
||||
session,
|
||||
savedSession,
|
||||
sourceKey
|
||||
),
|
||||
baseUrl: String(session.baseUrl || '').trim(),
|
||||
loggedInAt: String(session.loggedInAt || '').trim(),
|
||||
session: buildAdminCloudtentaclesSessionSummary(session, savedSession, sourceKey),
|
||||
userInfo: session.userInfo,
|
||||
asset: session.asset,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,22 +2,19 @@ import type { JsonObject } from '../../../../types/json.js'
|
||||
import {
|
||||
normalizeCloudtentaclesDeviceId,
|
||||
normalizeCloudtentaclesDeviceType,
|
||||
} from "../../../platforms/cloudtentacles/defaults.js";
|
||||
} from '../../../platforms/cloudtentacles/defaults.js'
|
||||
|
||||
export function normalizeAdminCloudtentaclesSourceConfigPayload(
|
||||
payload: JsonObject = {}
|
||||
) {
|
||||
const sourceKey =
|
||||
String(payload.sourceKey || payload.key || "").trim() || "default";
|
||||
export function normalizeAdminCloudtentaclesSourceConfigPayload(payload: JsonObject = {}) {
|
||||
const sourceKey = String(payload.sourceKey || payload.key || '').trim() || 'default'
|
||||
return {
|
||||
key: sourceKey,
|
||||
label: String(payload.label || "").trim(),
|
||||
label: String(payload.label || '').trim(),
|
||||
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(),
|
||||
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: normalizeCloudtentaclesDeviceId(payload.deviceId),
|
||||
deviceType: normalizeCloudtentaclesDeviceType(payload.deviceType),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,14 +60,18 @@ export async function listAdminKuaishouFeifeiProducts(payload: JsonObject = {})
|
||||
page: Number(payload.page || 1) || 1,
|
||||
perPage: Number(payload.perPage || payload.per_page || 20) || 20,
|
||||
status: String(payload.status || 'on_sale').trim(),
|
||||
supplyProductName: String(payload.supplyProductName || payload.supply_product_name || '').trim(),
|
||||
supplyProductName: String(
|
||||
payload.supplyProductName || payload.supply_product_name || '',
|
||||
).trim(),
|
||||
})
|
||||
}
|
||||
|
||||
export async function syncAdminKuaishouFeifeiProductRules(payload: JsonObject = {}) {
|
||||
const source = getAdminEditableKuaishouFeifeiConfig()
|
||||
const status = String(payload.status || 'on_sale').trim() || 'on_sale'
|
||||
const supplyProductName = String(payload.supplyProductName || payload.supply_product_name || '').trim()
|
||||
const supplyProductName = String(
|
||||
payload.supplyProductName || payload.supply_product_name || '',
|
||||
).trim()
|
||||
const products = await listAllKuaishouFeifeiProducts({
|
||||
status,
|
||||
supplyProductName,
|
||||
@@ -185,10 +189,7 @@ function mapEffectiveKuaishouFeifeiConfig(config: ReturnType<typeof getKuaishouF
|
||||
}
|
||||
}
|
||||
|
||||
async function listAllKuaishouFeifeiProducts(input: {
|
||||
status: string
|
||||
supplyProductName: string
|
||||
}) {
|
||||
async function listAllKuaishouFeifeiProducts(input: { status: string; supplyProductName: string }) {
|
||||
const perPage = 100
|
||||
const firstPage = await listKuaishouFeifeiProducts({
|
||||
page: 1,
|
||||
|
||||
@@ -14,16 +14,9 @@ import {
|
||||
refreshKuaishouIndustryAccessToken,
|
||||
} from '../../platforms/kuaishou-industry/token-service.js'
|
||||
|
||||
const SECRET_FIELDS = [
|
||||
'appSecret',
|
||||
'signSecret',
|
||||
'messageSecret',
|
||||
] as const
|
||||
const SECRET_FIELDS = ['appSecret', 'signSecret', 'messageSecret'] as const
|
||||
|
||||
const SHOP_SECRET_FIELDS = [
|
||||
'accessToken',
|
||||
'refreshToken',
|
||||
] as const
|
||||
const SHOP_SECRET_FIELDS = ['accessToken', 'refreshToken'] as const
|
||||
|
||||
export function getAdminKuaishouIndustrySourceConfig() {
|
||||
const config = getKuaishouIndustrySourceConfig()
|
||||
@@ -38,15 +31,23 @@ export async function updateAdminKuaishouIndustrySourceConfig(payload: JsonObjec
|
||||
const current = getKuaishouIndustrySourceConfig()
|
||||
const saved = await saveKuaishouIndustrySourceConfig({
|
||||
...current,
|
||||
enabled: hasPayloadField(payload, 'enabled') ? payload.enabled !== false : current.enabled !== false,
|
||||
enabled: hasPayloadField(payload, 'enabled')
|
||||
? payload.enabled !== false
|
||||
: current.enabled !== false,
|
||||
baseUrl: readConfigString(payload, 'baseUrl', current.baseUrl),
|
||||
authBaseUrl: readConfigString(payload, 'authBaseUrl', current.authBaseUrl),
|
||||
redirectUri: readConfigString(payload, 'redirectUri', current.redirectUri, { allowBlank: true }),
|
||||
scopes: normalizeScopeText(readConfigString(payload, 'scopes', current.scopes, { allowBlank: true })),
|
||||
redirectUri: readConfigString(payload, 'redirectUri', current.redirectUri, {
|
||||
allowBlank: true,
|
||||
}),
|
||||
scopes: normalizeScopeText(
|
||||
readConfigString(payload, 'scopes', current.scopes, { allowBlank: true }),
|
||||
),
|
||||
authState: readConfigString(payload, 'authState', current.authState, { allowBlank: true }),
|
||||
appKey: readConfigString(payload, 'appKey', current.appKey, { allowBlank: true }),
|
||||
openId: readConfigString(payload, 'openId', current.openId, { allowBlank: true }),
|
||||
grantedScopes: normalizeScopeText(readConfigString(payload, 'grantedScopes', current.grantedScopes, { allowBlank: true })),
|
||||
grantedScopes: normalizeScopeText(
|
||||
readConfigString(payload, 'grantedScopes', current.grantedScopes, { allowBlank: true }),
|
||||
),
|
||||
sellerId: readConfigString(payload, 'sellerId', current.sellerId, { allowBlank: true }),
|
||||
provider: readConfigString(payload, 'provider', current.provider),
|
||||
platform: readConfigString(payload, 'platform', current.platform),
|
||||
@@ -245,33 +246,77 @@ function normalizeShopConfigPayload(
|
||||
|
||||
const payload = rawShop as JsonObject
|
||||
const current = resolveCurrentShopConfig(payload, index, currentShops)
|
||||
const sellerId = readConfigString(payload, 'sellerId', current?.sellerId || '', { allowBlank: true })
|
||||
const shopId = readConfigString(payload, 'shopId', current?.shopId || sellerId, { allowBlank: true }) || sellerId
|
||||
const shopName = readConfigString(payload, 'shopName', current?.shopName || '', { allowBlank: true })
|
||||
const customShopName = readConfigString(payload, 'customShopName', current?.customShopName || '', { allowBlank: true })
|
||||
const sellerId = readConfigString(payload, 'sellerId', current?.sellerId || '', {
|
||||
allowBlank: true,
|
||||
})
|
||||
const shopId =
|
||||
readConfigString(payload, 'shopId', current?.shopId || sellerId, { allowBlank: true }) ||
|
||||
sellerId
|
||||
const shopName = readConfigString(payload, 'shopName', current?.shopName || '', {
|
||||
allowBlank: true,
|
||||
})
|
||||
const customShopName = readConfigString(
|
||||
payload,
|
||||
'customShopName',
|
||||
current?.customShopName || '',
|
||||
{ allowBlank: true },
|
||||
)
|
||||
const accessToken = readSecretString(payload, 'accessToken', current?.accessToken || '')
|
||||
const refreshToken = readSecretString(payload, 'refreshToken', current?.refreshToken || '')
|
||||
const openId = readConfigString(payload, 'openId', current?.openId || '', { allowBlank: true })
|
||||
|
||||
if (!sellerId && !shopId && !shopName && !customShopName && !accessToken && !refreshToken && !openId) {
|
||||
if (
|
||||
!sellerId &&
|
||||
!shopId &&
|
||||
!shopName &&
|
||||
!customShopName &&
|
||||
!accessToken &&
|
||||
!refreshToken &&
|
||||
!openId
|
||||
) {
|
||||
return null
|
||||
}
|
||||
|
||||
return {
|
||||
enabled: hasPayloadField(payload, 'enabled') ? payload.enabled !== false : current?.enabled !== false,
|
||||
enabled: hasPayloadField(payload, 'enabled')
|
||||
? payload.enabled !== false
|
||||
: current?.enabled !== false,
|
||||
sellerId,
|
||||
shopId,
|
||||
shopName,
|
||||
customShopName,
|
||||
authState: readConfigString(payload, 'authState', current?.authState || '', { allowBlank: true }),
|
||||
authState: readConfigString(payload, 'authState', current?.authState || '', {
|
||||
allowBlank: true,
|
||||
}),
|
||||
accessToken,
|
||||
refreshToken,
|
||||
accessTokenExpiresAt: readConfigString(payload, 'accessTokenExpiresAt', current?.accessTokenExpiresAt || '', { allowBlank: true }),
|
||||
refreshTokenExpiresAt: readConfigString(payload, 'refreshTokenExpiresAt', current?.refreshTokenExpiresAt || '', { allowBlank: true }),
|
||||
accessTokenExpiresAt: readConfigString(
|
||||
payload,
|
||||
'accessTokenExpiresAt',
|
||||
current?.accessTokenExpiresAt || '',
|
||||
{ allowBlank: true },
|
||||
),
|
||||
refreshTokenExpiresAt: readConfigString(
|
||||
payload,
|
||||
'refreshTokenExpiresAt',
|
||||
current?.refreshTokenExpiresAt || '',
|
||||
{ allowBlank: true },
|
||||
),
|
||||
openId,
|
||||
grantedScopes: normalizeScopeText(readConfigString(payload, 'grantedScopes', current?.grantedScopes || '', { allowBlank: true })),
|
||||
lastRefreshedAt: readConfigString(payload, 'lastRefreshedAt', current?.lastRefreshedAt || '', { allowBlank: true }),
|
||||
lastRefreshError: readConfigString(payload, 'lastRefreshError', current?.lastRefreshError || '', { allowBlank: true }),
|
||||
grantedScopes: normalizeScopeText(
|
||||
readConfigString(payload, 'grantedScopes', current?.grantedScopes || '', {
|
||||
allowBlank: true,
|
||||
}),
|
||||
),
|
||||
lastRefreshedAt: readConfigString(payload, 'lastRefreshedAt', current?.lastRefreshedAt || '', {
|
||||
allowBlank: true,
|
||||
}),
|
||||
lastRefreshError: readConfigString(
|
||||
payload,
|
||||
'lastRefreshError',
|
||||
current?.lastRefreshError || '',
|
||||
{ allowBlank: true },
|
||||
),
|
||||
...resolveShopSecretPatch(payload, current),
|
||||
}
|
||||
}
|
||||
@@ -305,16 +350,14 @@ function resolveShopSecretPatch(
|
||||
return patch
|
||||
}
|
||||
|
||||
function readSecretString(
|
||||
payload: JsonObject,
|
||||
field: string,
|
||||
fallback: string,
|
||||
): string {
|
||||
function readSecretString(payload: JsonObject, field: string, fallback: string): string {
|
||||
const text = String(payload[field] || '').trim()
|
||||
return text || fallback
|
||||
}
|
||||
|
||||
function resolveAccessTokenStatus(config: Pick<KuaishouIndustrySourceConfig, 'accessToken' | 'accessTokenExpiresAt'>) {
|
||||
function resolveAccessTokenStatus(
|
||||
config: Pick<KuaishouIndustrySourceConfig, 'accessToken' | 'accessTokenExpiresAt'>,
|
||||
) {
|
||||
if (!config.accessToken) {
|
||||
return {
|
||||
status: 'missing',
|
||||
|
||||
@@ -94,23 +94,27 @@ function mapAdminNotificationConfig(config: JsonObject = {}) {
|
||||
bark: {
|
||||
enabled: bark.enabled !== false,
|
||||
serverUrl: String(bark.serverUrl || 'https://api.day.app').trim(),
|
||||
recipients: (Array.isArray(bark.recipients) ? bark.recipients : []).map((item: JsonObject) => ({
|
||||
id: String(item.id || '').trim(),
|
||||
name: String(item.name || '').trim(),
|
||||
deviceKey: String(item.deviceKey || '').trim(),
|
||||
deviceKeyMasked: maskSecret(item.deviceKey),
|
||||
enabled: item.enabled !== false,
|
||||
})),
|
||||
recipients: (Array.isArray(bark.recipients) ? bark.recipients : []).map(
|
||||
(item: JsonObject) => ({
|
||||
id: String(item.id || '').trim(),
|
||||
name: String(item.name || '').trim(),
|
||||
deviceKey: String(item.deviceKey || '').trim(),
|
||||
deviceKeyMasked: maskSecret(item.deviceKey),
|
||||
enabled: item.enabled !== false,
|
||||
}),
|
||||
),
|
||||
},
|
||||
wpush: {
|
||||
enabled: wpush.enabled !== false,
|
||||
recipients: (Array.isArray(wpush.recipients) ? wpush.recipients : []).map((item: JsonObject) => ({
|
||||
id: String(item.id || '').trim(),
|
||||
name: String(item.name || '').trim(),
|
||||
apiKey: String(item.apiKey || item.apikey || '').trim(),
|
||||
apiKeyMasked: maskSecret(item.apiKey || item.apikey),
|
||||
enabled: item.enabled !== false,
|
||||
})),
|
||||
recipients: (Array.isArray(wpush.recipients) ? wpush.recipients : []).map(
|
||||
(item: JsonObject) => ({
|
||||
id: String(item.id || '').trim(),
|
||||
name: String(item.name || '').trim(),
|
||||
apiKey: String(item.apiKey || item.apikey || '').trim(),
|
||||
apiKeyMasked: maskSecret(item.apiKey || item.apikey),
|
||||
enabled: item.enabled !== false,
|
||||
}),
|
||||
),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -118,8 +122,7 @@ function mapAdminNotificationConfig(config: JsonObject = {}) {
|
||||
|
||||
function mapAdminScheduledJobsConfig(config: JsonObject = {}) {
|
||||
const cloudtentaclesAccountMap = new Map(
|
||||
listAdminCloudtentaclesMonitorAccounts()
|
||||
.map((item) => [item.sourceKey, item]),
|
||||
listAdminCloudtentaclesMonitorAccounts().map((item) => [item.sourceKey, item]),
|
||||
)
|
||||
|
||||
return {
|
||||
@@ -147,21 +150,23 @@ function listAdminCloudtentaclesMonitorAccounts() {
|
||||
const sessionsConfig = getAllCloudtentaclesSessionStates()
|
||||
const sessions: Record<string, JsonObject> = sessionsConfig.sessions || {}
|
||||
|
||||
return (Array.isArray(sourcesConfig.sources) ? sourcesConfig.sources : []).map((source) => {
|
||||
const sourceKey = String(source.key || '').trim()
|
||||
const session = sessions[sourceKey] || {}
|
||||
const label = String(source.label || source.username || sourceKey).trim() || sourceKey
|
||||
return (Array.isArray(sourcesConfig.sources) ? sourcesConfig.sources : [])
|
||||
.map((source) => {
|
||||
const sourceKey = String(source.key || '').trim()
|
||||
const session = sessions[sourceKey] || {}
|
||||
const label = String(source.label || source.username || sourceKey).trim() || sourceKey
|
||||
|
||||
return {
|
||||
sourceKey,
|
||||
label,
|
||||
enabled: source.enabled !== false,
|
||||
username: String(source.username || '').trim(),
|
||||
phoneMasked: maskPhone(source.phone || session.phone),
|
||||
hasToken: Boolean(String(session.token || '').trim()),
|
||||
loggedInAt: String(session.loggedInAt || '').trim(),
|
||||
}
|
||||
}).filter((item) => item.sourceKey)
|
||||
return {
|
||||
sourceKey,
|
||||
label,
|
||||
enabled: source.enabled !== false,
|
||||
username: String(source.username || '').trim(),
|
||||
phoneMasked: maskPhone(source.phone || session.phone),
|
||||
hasToken: Boolean(String(session.token || '').trim()),
|
||||
loggedInAt: String(session.loggedInAt || '').trim(),
|
||||
}
|
||||
})
|
||||
.filter((item) => item.sourceKey)
|
||||
}
|
||||
|
||||
function mapScheduledJobCloudtentaclesAccounts(
|
||||
@@ -193,30 +198,35 @@ function mapScheduledJobCloudtentaclesAccounts(
|
||||
},
|
||||
] as const
|
||||
})
|
||||
.filter(Boolean) as Array<readonly [string, {
|
||||
sourceKey: string
|
||||
label: string
|
||||
enabled: boolean
|
||||
assetThreshold: number
|
||||
}]>,
|
||||
.filter(Boolean) as Array<
|
||||
readonly [
|
||||
string,
|
||||
{
|
||||
sourceKey: string
|
||||
label: string
|
||||
enabled: boolean
|
||||
assetThreshold: number
|
||||
},
|
||||
]
|
||||
>,
|
||||
)
|
||||
|
||||
// 读配置时合并全部 kuaishou-lewan 账号,避免前端/任务只看到历史 default。
|
||||
const merged = Array.from(cloudtentaclesAccountMap.values()).map((option) => {
|
||||
const sourceKey = String(option.sourceKey || '').trim()
|
||||
const configured = configuredMap.get(sourceKey)
|
||||
return {
|
||||
sourceKey,
|
||||
label: String(configured?.label || option.label || sourceKey).trim(),
|
||||
enabled: configured
|
||||
? configured.enabled !== false
|
||||
: option.enabled !== false,
|
||||
assetThreshold: normalizeNonNegativeNumber(
|
||||
configured?.assetThreshold,
|
||||
defaultAssetThreshold,
|
||||
),
|
||||
}
|
||||
}).filter((item) => item.sourceKey)
|
||||
const merged = Array.from(cloudtentaclesAccountMap.values())
|
||||
.map((option) => {
|
||||
const sourceKey = String(option.sourceKey || '').trim()
|
||||
const configured = configuredMap.get(sourceKey)
|
||||
return {
|
||||
sourceKey,
|
||||
label: String(configured?.label || option.label || sourceKey).trim(),
|
||||
enabled: configured ? configured.enabled !== false : option.enabled !== false,
|
||||
assetThreshold: normalizeNonNegativeNumber(
|
||||
configured?.assetThreshold,
|
||||
defaultAssetThreshold,
|
||||
),
|
||||
}
|
||||
})
|
||||
.filter((item) => item.sourceKey)
|
||||
|
||||
const mergedKeys = new Set(merged.map((item) => item.sourceKey))
|
||||
for (const [sourceKey, configured] of configuredMap.entries()) {
|
||||
|
||||
Reference in New Issue
Block a user