后端迁移快手电子券平台服务
This commit is contained in:
+32
-16
@@ -1,10 +1,23 @@
|
||||
// @ts-check
|
||||
|
||||
import { createHttpError } from '../../../utils/http.js'
|
||||
import { kuaishouEticketRequest } from './http-client.js'
|
||||
import { resolveKuaishouEticketConfig } from './shared.js'
|
||||
|
||||
export async function queryKuaishouEticketConsumeDetail(payload = {}) {
|
||||
type JsonObject = Record<string, any>
|
||||
|
||||
type KuaishouEticketDetailPayload = {
|
||||
eTicketId: string
|
||||
oid: string
|
||||
formToken: string
|
||||
leftCount: number
|
||||
[key: string]: unknown
|
||||
}
|
||||
|
||||
type KuaishouEticketDetailResult = {
|
||||
detail: KuaishouEticketDetailPayload | null
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
export async function queryKuaishouEticketConsumeDetail(payload: JsonObject = {}) {
|
||||
const context = resolveKuaishouEticketActionContext(payload)
|
||||
const response = await kuaishouEticketRequest(context.detailPath, {
|
||||
baseUrl: context.baseUrl,
|
||||
@@ -21,7 +34,7 @@ export async function queryKuaishouEticketConsumeDetail(payload = {}) {
|
||||
})
|
||||
}
|
||||
|
||||
export async function consumeKuaishouEticket(payload = {}) {
|
||||
export async function consumeKuaishouEticket(payload: JsonObject = {}) {
|
||||
const context = resolveKuaishouEticketActionContext(payload)
|
||||
const detailResult = shouldResolveConsumeDetail(payload)
|
||||
? await queryKuaishouEticketConsumeDetail({
|
||||
@@ -51,7 +64,7 @@ export async function consumeKuaishouEticket(payload = {}) {
|
||||
})
|
||||
}
|
||||
|
||||
export function mapKuaishouEticketDetailResult(payload = {}, context = {}) {
|
||||
export function mapKuaishouEticketDetailResult(payload: JsonObject = {}, context: JsonObject = {}) {
|
||||
const normalized = normalizeKuaishouEticketApiResult(payload)
|
||||
const detail = mapKuaishouEticketDetailPayload(payload?.data?.eTicket)
|
||||
const goods = mapKuaishouEticketGoodsPayload(payload?.data?.goods)
|
||||
@@ -71,7 +84,7 @@ export function mapKuaishouEticketDetailResult(payload = {}, context = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
export function mapKuaishouEticketConsumeResult(payload = {}, context = {}) {
|
||||
export function mapKuaishouEticketConsumeResult(payload: JsonObject = {}, context: JsonObject = {}) {
|
||||
const normalized = normalizeKuaishouEticketApiResult(payload)
|
||||
|
||||
return {
|
||||
@@ -93,7 +106,10 @@ export function mapKuaishouEticketConsumeResult(payload = {}, context = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
export function resolveKuaishouEticketConsumePayload(payload = {}, detailResult = null) {
|
||||
export function resolveKuaishouEticketConsumePayload(
|
||||
payload: JsonObject = {},
|
||||
detailResult: KuaishouEticketDetailResult | null = null,
|
||||
) {
|
||||
const detail = detailResult?.detail || null
|
||||
const eTicketId = pickFirstNonEmpty([payload.eTicketId, detail?.eTicketId])
|
||||
const oid = pickFirstNonEmpty([payload.oid, detail?.oid])
|
||||
@@ -131,7 +147,7 @@ export function resolveKuaishouEticketConsumePayload(payload = {}, detailResult
|
||||
}
|
||||
}
|
||||
|
||||
export function normalizeKuaishouEticketApiResult(payload = {}) {
|
||||
export function normalizeKuaishouEticketApiResult(payload: JsonObject = {}) {
|
||||
const result = Number(payload?.result || 0)
|
||||
|
||||
return {
|
||||
@@ -143,7 +159,7 @@ export function normalizeKuaishouEticketApiResult(payload = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
export function mapKuaishouEticketDetailPayload(value = {}) {
|
||||
export function mapKuaishouEticketDetailPayload(value: unknown): KuaishouEticketDetailPayload | null {
|
||||
if (!isPlainObject(value)) {
|
||||
return null
|
||||
}
|
||||
@@ -164,7 +180,7 @@ export function mapKuaishouEticketDetailPayload(value = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
export function mapKuaishouEticketGoodsPayload(value = {}) {
|
||||
export function mapKuaishouEticketGoodsPayload(value: unknown) {
|
||||
if (!isPlainObject(value)) {
|
||||
return null
|
||||
}
|
||||
@@ -179,7 +195,7 @@ export function mapKuaishouEticketGoodsPayload(value = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
function resolveKuaishouEticketActionContext(payload = {}) {
|
||||
function resolveKuaishouEticketActionContext(payload: JsonObject = {}) {
|
||||
const config = resolveKuaishouEticketConfig(payload)
|
||||
const eTicketId = String(payload.eTicketId || '').trim()
|
||||
|
||||
@@ -203,11 +219,11 @@ function resolveKuaishouEticketActionContext(payload = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
function shouldResolveConsumeDetail(payload = {}) {
|
||||
function shouldResolveConsumeDetail(payload: JsonObject = {}): boolean {
|
||||
return !String(payload.oid || '').trim() || !String(payload.formToken || '').trim()
|
||||
}
|
||||
|
||||
function pickFirstNonEmpty(values) {
|
||||
function pickFirstNonEmpty(values: unknown[]): string {
|
||||
for (const value of values) {
|
||||
const normalized = String(value || '').trim()
|
||||
if (normalized) {
|
||||
@@ -218,16 +234,16 @@ function pickFirstNonEmpty(values) {
|
||||
return ''
|
||||
}
|
||||
|
||||
function normalizePositiveInteger(value, fallback) {
|
||||
function normalizePositiveInteger(value: unknown, fallback: number): number {
|
||||
const parsed = Number(value)
|
||||
return Number.isInteger(parsed) && parsed > 0 ? parsed : fallback
|
||||
}
|
||||
|
||||
function normalizeInteger(value, fallback) {
|
||||
function normalizeInteger(value: unknown, fallback: number): number {
|
||||
const parsed = Number(value)
|
||||
return Number.isInteger(parsed) ? parsed : fallback
|
||||
}
|
||||
|
||||
function isPlainObject(value) {
|
||||
function isPlainObject(value: unknown): value is JsonObject {
|
||||
return Object.prototype.toString.call(value) === '[object Object]'
|
||||
}
|
||||
+39
-10
@@ -1,14 +1,35 @@
|
||||
// @ts-check
|
||||
|
||||
import http from 'node:http'
|
||||
import https from 'node:https'
|
||||
import type { IncomingHttpHeaders } from 'node:http'
|
||||
|
||||
import { parseJsonObject } from '../../../utils/json.js'
|
||||
import { createHttpError } from '../../../utils/http.js'
|
||||
import { logInfo } from '../../../utils/logger.js'
|
||||
import { buildKuaishouEticketHeaders, buildKuaishouEticketUrl, resolveKuaishouEticketConfig } from './shared.js'
|
||||
|
||||
export async function kuaishouEticketRequest(pathname, options = {}) {
|
||||
type JsonObject = Record<string, any>
|
||||
|
||||
type KuaishouEticketRequestOptions = JsonObject & {
|
||||
method?: string
|
||||
body?: unknown
|
||||
headers?: Record<string, unknown>
|
||||
timeoutMs?: number | string
|
||||
cookie?: string
|
||||
contentType?: string | null
|
||||
}
|
||||
|
||||
type HeaderAdapter = {
|
||||
get(name: string): string | null
|
||||
}
|
||||
|
||||
type NodeHttpResponse = {
|
||||
ok: boolean
|
||||
status: number
|
||||
headers: HeaderAdapter
|
||||
bodyText: string
|
||||
}
|
||||
|
||||
export async function kuaishouEticketRequest(pathname: string, options: KuaishouEticketRequestOptions = {}) {
|
||||
const config = resolveKuaishouEticketConfig(options)
|
||||
const url = buildKuaishouEticketUrl(config.baseUrl, pathname)
|
||||
const timeoutMs = Number(options.timeoutMs || config.timeoutMs || 8000)
|
||||
@@ -69,7 +90,7 @@ export async function kuaishouEticketRequest(pathname, options = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
function inferContentType(body) {
|
||||
function inferContentType(body: unknown): string {
|
||||
if (body == null) {
|
||||
return ''
|
||||
}
|
||||
@@ -81,7 +102,7 @@ function inferContentType(body) {
|
||||
return 'application/json'
|
||||
}
|
||||
|
||||
function normalizeRequestBody(body, contentType) {
|
||||
function normalizeRequestBody(body: unknown, contentType: unknown): string | undefined {
|
||||
if (body == null) {
|
||||
return undefined
|
||||
}
|
||||
@@ -97,7 +118,15 @@ function normalizeRequestBody(body, contentType) {
|
||||
return String(body)
|
||||
}
|
||||
|
||||
async function requestViaNodeHttp(url, { method, headers, body, signal }) {
|
||||
async function requestViaNodeHttp(
|
||||
url: URL,
|
||||
{ method, headers, body, signal }: {
|
||||
method: string
|
||||
headers: Record<string, string>
|
||||
body?: string
|
||||
signal: AbortSignal
|
||||
},
|
||||
): Promise<NodeHttpResponse> {
|
||||
const isHttps = url.protocol === 'https:'
|
||||
const transport = isHttps ? https : http
|
||||
|
||||
@@ -107,7 +136,7 @@ async function requestViaNodeHttp(url, { method, headers, body, signal }) {
|
||||
headers,
|
||||
rejectUnauthorized: false,
|
||||
}, (response) => {
|
||||
const chunks = []
|
||||
const chunks: Buffer[] = []
|
||||
|
||||
response.on('data', (chunk) => {
|
||||
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk))
|
||||
@@ -148,8 +177,8 @@ async function requestViaNodeHttp(url, { method, headers, body, signal }) {
|
||||
})
|
||||
}
|
||||
|
||||
function createHeaderAdapter(headers) {
|
||||
const normalized = new Map()
|
||||
function createHeaderAdapter(headers: IncomingHttpHeaders): HeaderAdapter {
|
||||
const normalized = new Map<string, string>()
|
||||
|
||||
for (const [key, value] of Object.entries(headers || {})) {
|
||||
if (Array.isArray(value)) {
|
||||
@@ -163,7 +192,7 @@ function createHeaderAdapter(headers) {
|
||||
}
|
||||
|
||||
return {
|
||||
get(name) {
|
||||
get(name: string) {
|
||||
return normalized.get(String(name || '').toLowerCase()) || null
|
||||
},
|
||||
}
|
||||
+6
-6
@@ -1,10 +1,10 @@
|
||||
// @ts-check
|
||||
|
||||
import { createHttpError } from '../../../utils/http.js'
|
||||
import { kuaishouEticketRequest } from './http-client.js'
|
||||
import { resolveKuaishouEticketConfig } from './shared.js'
|
||||
|
||||
export async function queryKuaishouEticketStableInfo(payload = {}) {
|
||||
type JsonObject = Record<string, any>
|
||||
|
||||
export async function queryKuaishouEticketStableInfo(payload: JsonObject = {}) {
|
||||
const config = resolveKuaishouEticketConfig(payload)
|
||||
const cookie = String(payload.cookie || config.cookie || '').trim()
|
||||
|
||||
@@ -29,7 +29,7 @@ export async function queryKuaishouEticketStableInfo(payload = {}) {
|
||||
})
|
||||
}
|
||||
|
||||
export function mapKuaishouEticketStableInfoResult(payload = {}, context = {}) {
|
||||
export function mapKuaishouEticketStableInfoResult(payload: JsonObject = {}, context: JsonObject = {}) {
|
||||
const result = Number(payload?.result || 0)
|
||||
const userInfo = isPlainObject(payload?.data?.userInfo) ? payload.data.userInfo : {}
|
||||
const bizStatus = isPlainObject(payload?.data?.bizStatus) ? payload.data.bizStatus : {}
|
||||
@@ -51,11 +51,11 @@ export function mapKuaishouEticketStableInfoResult(payload = {}, context = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeInteger(value, fallback) {
|
||||
function normalizeInteger(value: unknown, fallback: number): number {
|
||||
const parsed = Number(value)
|
||||
return Number.isInteger(parsed) ? parsed : fallback
|
||||
}
|
||||
|
||||
function isPlainObject(value) {
|
||||
function isPlainObject(value: unknown): value is JsonObject {
|
||||
return Object.prototype.toString.call(value) === '[object Object]'
|
||||
}
|
||||
+40
-9
@@ -1,10 +1,41 @@
|
||||
// @ts-check
|
||||
|
||||
const DEFAULT_BASE_URL = 'https://s.kwaixiaodian.com'
|
||||
const DEFAULT_REFERER_PATH = '/zone/industry/voucher/verify-list'
|
||||
const DEFAULT_USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36'
|
||||
|
||||
export function resolveKuaishouEticketConfig(overrides = {}) {
|
||||
export type KuaishouEticketConfigInput = {
|
||||
enabled?: boolean
|
||||
baseUrl?: string
|
||||
cookie?: string
|
||||
timeoutMs?: number | string
|
||||
infoPath?: string
|
||||
detailPath?: string
|
||||
consumePath?: string
|
||||
refererPath?: string
|
||||
userAgent?: string
|
||||
}
|
||||
|
||||
export type KuaishouEticketConfig = {
|
||||
enabled: boolean
|
||||
baseUrl: string
|
||||
cookie: string
|
||||
timeoutMs: number
|
||||
infoPath: string
|
||||
detailPath: string
|
||||
consumePath: string
|
||||
refererPath: string
|
||||
userAgent: string
|
||||
}
|
||||
|
||||
type HeaderInput = {
|
||||
baseUrl?: string
|
||||
refererPath?: string
|
||||
userAgent?: string
|
||||
cookie?: string
|
||||
contentType?: string
|
||||
extra?: Record<string, unknown>
|
||||
}
|
||||
|
||||
export function resolveKuaishouEticketConfig(overrides: KuaishouEticketConfigInput = {}): KuaishouEticketConfig {
|
||||
return {
|
||||
enabled: overrides.enabled !== false,
|
||||
baseUrl: normalizeBaseUrl(overrides.baseUrl || DEFAULT_BASE_URL) || DEFAULT_BASE_URL,
|
||||
@@ -18,7 +49,7 @@ export function resolveKuaishouEticketConfig(overrides = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
export function buildKuaishouEticketUrl(baseUrl, pathname) {
|
||||
export function buildKuaishouEticketUrl(baseUrl: unknown, pathname: unknown): URL {
|
||||
return new URL(normalizePath(pathname, '/'), normalizeBaseUrl(baseUrl) || DEFAULT_BASE_URL)
|
||||
}
|
||||
|
||||
@@ -29,7 +60,7 @@ export function buildKuaishouEticketHeaders({
|
||||
cookie = '',
|
||||
contentType = 'application/json',
|
||||
extra = {},
|
||||
} = {}) {
|
||||
}: HeaderInput = {}): Record<string, string> {
|
||||
return {
|
||||
accept: 'application/json',
|
||||
'accept-language': 'zh-CN,zh;q=0.9',
|
||||
@@ -44,11 +75,11 @@ export function buildKuaishouEticketHeaders({
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeBaseUrl(value) {
|
||||
function normalizeBaseUrl(value: unknown): string {
|
||||
return String(value || '').trim().replace(/\/+$/, '')
|
||||
}
|
||||
|
||||
function normalizePath(value, fallback) {
|
||||
function normalizePath(value: unknown, fallback: string): string {
|
||||
const normalized = String(value || '').trim()
|
||||
if (!normalized) {
|
||||
return fallback
|
||||
@@ -57,12 +88,12 @@ function normalizePath(value, fallback) {
|
||||
return normalized.startsWith('/') ? normalized : `/${normalized}`
|
||||
}
|
||||
|
||||
function normalizePositiveInteger(value, fallback) {
|
||||
function normalizePositiveInteger(value: unknown, fallback: number): number {
|
||||
const parsed = Number(value)
|
||||
return Number.isInteger(parsed) && parsed > 0 ? parsed : fallback
|
||||
}
|
||||
|
||||
function normalizeHeaderMap(extra) {
|
||||
function normalizeHeaderMap(extra: unknown): Record<string, string> {
|
||||
if (!extra || typeof extra !== 'object') {
|
||||
return {}
|
||||
}
|
||||
+32
-18
@@ -1,5 +1,3 @@
|
||||
// @ts-check
|
||||
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
|
||||
@@ -8,26 +6,42 @@ import { PROJECT_ROOT } from '../../../config/runtime.js'
|
||||
const KUAISHOU_ETICKET_SOURCE_FILE_PATH = path.join(PROJECT_ROOT, 'data', 'kuaishou-eticket-source.json')
|
||||
const DEFAULT_BASE_URL = 'https://s.kwaixiaodian.com'
|
||||
|
||||
export function getKuaishouEticketSourceFilePath() {
|
||||
type JsonObject = Record<string, any>
|
||||
|
||||
export type KuaishouEticketShopConfig = {
|
||||
shopId: string
|
||||
kshopName: string
|
||||
cookie: string
|
||||
userAvatar: string
|
||||
enabled: boolean
|
||||
}
|
||||
|
||||
export type KuaishouEticketSourceConfig = {
|
||||
enabled: boolean
|
||||
baseUrl: string
|
||||
shops: KuaishouEticketShopConfig[]
|
||||
}
|
||||
|
||||
export function getKuaishouEticketSourceFilePath(): string {
|
||||
return KUAISHOU_ETICKET_SOURCE_FILE_PATH
|
||||
}
|
||||
|
||||
export function getKuaishouEticketSourceConfig() {
|
||||
export function getKuaishouEticketSourceConfig(): KuaishouEticketSourceConfig {
|
||||
return loadKuaishouEticketSourceConfigFromFile()
|
||||
}
|
||||
|
||||
export function saveKuaishouEticketSourceConfig(rawValue) {
|
||||
export function saveKuaishouEticketSourceConfig(rawValue: unknown): KuaishouEticketSourceConfig {
|
||||
const normalized = normalizeKuaishouEticketSourceConfig(rawValue)
|
||||
fs.mkdirSync(path.dirname(KUAISHOU_ETICKET_SOURCE_FILE_PATH), { recursive: true })
|
||||
fs.writeFileSync(KUAISHOU_ETICKET_SOURCE_FILE_PATH, `${JSON.stringify(normalized, null, 2)}\n`, 'utf8')
|
||||
return normalized
|
||||
}
|
||||
|
||||
export function listKuaishouEticketShopConfigs(source = getKuaishouEticketSourceConfig()) {
|
||||
export function listKuaishouEticketShopConfigs(source: KuaishouEticketSourceConfig = getKuaishouEticketSourceConfig()): KuaishouEticketShopConfig[] {
|
||||
return Array.isArray(source?.shops) ? source.shops : []
|
||||
}
|
||||
|
||||
export function findKuaishouEticketShopConfig(shopId, source = getKuaishouEticketSourceConfig()) {
|
||||
export function findKuaishouEticketShopConfig(shopId: unknown, source: KuaishouEticketSourceConfig = getKuaishouEticketSourceConfig()): KuaishouEticketShopConfig | null {
|
||||
const normalizedShopId = String(shopId || '').trim()
|
||||
if (!normalizedShopId) {
|
||||
return null
|
||||
@@ -36,7 +50,7 @@ export function findKuaishouEticketShopConfig(shopId, source = getKuaishouEticke
|
||||
return listKuaishouEticketShopConfigs(source).find((item) => String(item.shopId || '').trim() === normalizedShopId) || null
|
||||
}
|
||||
|
||||
export function findKuaishouEticketShopConfigByName(kshopName, source = getKuaishouEticketSourceConfig()) {
|
||||
export function findKuaishouEticketShopConfigByName(kshopName: unknown, source: KuaishouEticketSourceConfig = getKuaishouEticketSourceConfig()): KuaishouEticketShopConfig | null {
|
||||
const normalizedName = String(kshopName || '').trim()
|
||||
if (!normalizedName) {
|
||||
return null
|
||||
@@ -46,9 +60,9 @@ export function findKuaishouEticketShopConfigByName(kshopName, source = getKuais
|
||||
}
|
||||
|
||||
export function resolveKuaishouEticketShopConfig(
|
||||
{ shopId = '', kshopName = '', shopName = '' } = {},
|
||||
source = getKuaishouEticketSourceConfig(),
|
||||
) {
|
||||
{ shopId = '', kshopName = '', shopName = '' }: { shopId?: unknown, kshopName?: unknown, shopName?: unknown } = {},
|
||||
source: KuaishouEticketSourceConfig = getKuaishouEticketSourceConfig(),
|
||||
): KuaishouEticketShopConfig | null {
|
||||
const byId = findKuaishouEticketShopConfig(shopId, source)
|
||||
if (byId) {
|
||||
return byId
|
||||
@@ -62,11 +76,11 @@ export function resolveKuaishouEticketShopConfig(
|
||||
return findKuaishouEticketShopConfigByName(normalizedName, source)
|
||||
}
|
||||
|
||||
export function getFirstAvailableKuaishouEticketShop(source = getKuaishouEticketSourceConfig()) {
|
||||
export function getFirstAvailableKuaishouEticketShop(source: KuaishouEticketSourceConfig = getKuaishouEticketSourceConfig()): KuaishouEticketShopConfig | null {
|
||||
return listKuaishouEticketShopConfigs(source).find((item) => item.enabled !== false && String(item.cookie || '').trim()) || null
|
||||
}
|
||||
|
||||
function loadKuaishouEticketSourceConfigFromFile() {
|
||||
function loadKuaishouEticketSourceConfigFromFile(): KuaishouEticketSourceConfig {
|
||||
if (!fs.existsSync(KUAISHOU_ETICKET_SOURCE_FILE_PATH)) {
|
||||
return createDefaultKuaishouEticketSourceConfig()
|
||||
}
|
||||
@@ -79,7 +93,7 @@ function loadKuaishouEticketSourceConfigFromFile() {
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeKuaishouEticketSourceConfig(rawValue) {
|
||||
function normalizeKuaishouEticketSourceConfig(rawValue: unknown): KuaishouEticketSourceConfig {
|
||||
const source = isPlainObject(rawValue) ? rawValue : {}
|
||||
const shops = Array.isArray(source.shops)
|
||||
? source.shops
|
||||
@@ -94,7 +108,7 @@ function normalizeKuaishouEticketSourceConfig(rawValue) {
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeKuaishouEticketShopConfig(rawValue) {
|
||||
function normalizeKuaishouEticketShopConfig(rawValue: unknown): KuaishouEticketShopConfig | null {
|
||||
if (!isPlainObject(rawValue)) {
|
||||
return null
|
||||
}
|
||||
@@ -118,7 +132,7 @@ function normalizeKuaishouEticketShopConfig(rawValue) {
|
||||
}
|
||||
}
|
||||
|
||||
function buildLegacySingleShopList(source) {
|
||||
function buildLegacySingleShopList(source: JsonObject): JsonObject[] {
|
||||
const cookie = String(source.cookie || '').trim()
|
||||
if (!cookie) {
|
||||
return []
|
||||
@@ -135,7 +149,7 @@ function buildLegacySingleShopList(source) {
|
||||
]
|
||||
}
|
||||
|
||||
function createDefaultKuaishouEticketSourceConfig() {
|
||||
function createDefaultKuaishouEticketSourceConfig(): KuaishouEticketSourceConfig {
|
||||
return {
|
||||
enabled: true,
|
||||
baseUrl: DEFAULT_BASE_URL,
|
||||
@@ -143,6 +157,6 @@ function createDefaultKuaishouEticketSourceConfig() {
|
||||
}
|
||||
}
|
||||
|
||||
function isPlainObject(value) {
|
||||
function isPlainObject(value: unknown): value is JsonObject {
|
||||
return Object.prototype.toString.call(value) === '[object Object]'
|
||||
}
|
||||
@@ -795,6 +795,19 @@
|
||||
- `npm run build`
|
||||
- `npm test` 共 139 个用例通过
|
||||
204. `src/services/admin` 目录下非测试 `.js` 服务文件已全部迁移为 `.ts`
|
||||
205. 快手电子券平台服务迁移到 `.ts`:
|
||||
- `src/services/platforms/kuaishou-eticket/shared.ts`
|
||||
- `src/services/platforms/kuaishou-eticket/http-client.ts`
|
||||
- `src/services/platforms/kuaishou-eticket/source-config-service.ts`
|
||||
- `src/services/platforms/kuaishou-eticket/info-service.ts`
|
||||
- `src/services/platforms/kuaishou-eticket/consume-service.ts`
|
||||
206. 快手小店核销配置、Node HTTP 请求、店铺来源配置读写、店铺稳定信息查询、电子券详情查询与核销 payload / result 映射已进入 TS 编译链路;config、headers、HTTP response、source/shop config、detail result 与动态 payload 补齐类型
|
||||
207. Docker 内验证通过:
|
||||
- `src/services/platforms/kuaishou-eticket/*.test.js` 共 4 个用例通过
|
||||
- `npm run typecheck`
|
||||
- `npm run build`
|
||||
- `npm test` 共 139 个用例通过
|
||||
208. `src/services` 目录下非测试 `.js` 服务文件已全部迁移为 `.ts`
|
||||
|
||||
## 下一步建议
|
||||
|
||||
|
||||
Reference in New Issue
Block a user