UNPKG

@liuliang520500/jd-sdk

Version:
143 lines (121 loc) 4.28 kB
const axios = require('axios'); const { sign } = require('./sign'); const API_BASE_DOMAIN = 'https://api.jd.com'; const API_ENDPOINT = '/routerjson'; function getCurrentTimestamp() { const now = new Date(); const year = now.getFullYear(); const month = String(now.getMonth() + 1).padStart(2, '0'); const day = String(now.getDate()).padStart(2, '0'); const hours = String(now.getHours()).padStart(2, '0'); const minutes = String(now.getMinutes()).padStart(2, '0'); const seconds = String(now.getSeconds()).padStart(2, '0'); return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; } class JdApiError extends Error { constructor(code, message, subCode, subMessage) { super(message); this.name = 'JdApiError'; this.code = code; this.subCode = subCode; this.subMessage = subMessage; } } class BaseApi { constructor(config) { this.appKey = config.appKey; this.secretKey = config.secretKey; this.accessToken = config.accessToken; this.apiVersion = config.apiVersion || '1.0'; this.format = config.format || 'json'; this.domain = API_BASE_DOMAIN; console.log('BaseApi初始化:'); console.log('- appKey:', this.appKey); console.log('- accessToken是否设置:', this.accessToken ? '是' : '否'); } getApiName() { throw new Error('子类必须实现getApiName方法'); } async execute(params = {}, options = {}) { const timestamp = getCurrentTimestamp(); const systemParams = { timestamp, method: this.getApiName(), app_key: this.appKey, v: this.apiVersion, sign_method: 'md5', format: this.format }; console.log('Execute方法中:'); console.log('- 方法名称:', this.getApiName()); console.log('- 传入参数:', JSON.stringify(params, (key, value) => { // 过滤敏感信息 if (key === 'key' && typeof value === 'string') { return value ? '已设置(长度:' + value.length + ')' : '未设置'; } return value; }, 2)); // access_token是系统参数,非必填 if (this.accessToken) { console.log('- 添加系统参数access_token'); systemParams.access_token = this.accessToken; } else { console.log('- 不添加系统参数access_token'); } // 这里是关键部分:检查参数中是否含有key,尤其是在positionReq对象内部 if (params.positionReq && typeof params.positionReq === 'object') { console.log('- 发现positionReq对象:'); console.log(' - unionId:', params.positionReq.unionId); console.log(' - key:', params.positionReq.key ? '已设置(长度:' + params.positionReq.key.length + ')' : '未设置'); console.log(' - unionType:', params.positionReq.unionType); } const jsonParams = JSON.stringify(params); systemParams['360buy_param_json'] = jsonParams; systemParams.sign = sign(this.secretKey, systemParams); const url = `${this.domain}${API_ENDPOINT}`; try { // 打印请求参数,便于调试 console.log('请求参数:', { url, systemParams: { ...systemParams, sign: '已生成', '360buy_param_json': '已生成' } }); const response = await axios.post(url, null, { params: systemParams, timeout: options.timeout || 30000, headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Cache-Control': 'no-cache' } }); const result = response.data; const responseKey = this.getResponseKey(); console.log('API响应结果:', JSON.stringify(result, null, 2)); if (result.error_response) { const error = result.error_response; throw new JdApiError( error.code, error.zh_desc || '未知错误', error.sub_code, error.sub_msg ); } return result[responseKey] || result; } catch (error) { if (error instanceof JdApiError) { throw error; } throw new Error(`API请求失败: ${error.message}`); } } getResponseKey() { return this.getApiName().replace(/\./g, '_') + '_response'; } } module.exports = { BaseApi, JdApiError };