@liuliang520500/jd-sdk
Version:
325 lines (281 loc) • 11.4 kB
JavaScript
/**
* 京东联盟开放平台SDK
*/
const path = require('path');
require('dotenv').config({ path: path.resolve(__dirname, '.env') });
const { BaseApi, JdApiError } = require('./lib/api');
const { UnionOpenPositionQueryRequest } = require('./lib/union/UnionOpenPositionQueryRequest');
const { UnionOpenPositionCreateRequest } = require('./lib/union/UnionOpenPositionCreateRequest');
const { UnionOpenPromotionByUnionidGetRequest } = require('./lib/union/UnionOpenPromotionByUnionidGetRequest');
const { UnionOpenGoodsQueryRequest } = require('./lib/union/UnionOpenGoodsQueryRequest');
const { UnionOpenCouponQueryRequest } = require('./lib/union/UnionOpenCouponQueryRequest');
const { UnionOpenOrderQueryRequest } = require('./lib/union/UnionOpenOrderQueryRequest');
const { UnionOpenOrderRowQueryRequest } = require('./lib/union/UnionOpenOrderRowQueryRequest');
const { UnionOpenGoodsJingfenQueryRequest } = require('./lib/union/UnionOpenGoodsJingfenQueryRequest');
const { UnionOpenCategoryGoodsGetRequest } = require('./lib/union/UnionOpenCategoryGoodsGetRequest');
const { UnionOpenActivityQueryRequest } = require('./lib/union/UnionOpenActivityQueryRequest');
// 所有API类型的映射,方便引用
const ApiTypes = {
UnionOpenPositionQueryRequest,
UnionOpenPositionCreateRequest,
UnionOpenPromotionByUnionidGetRequest,
UnionOpenGoodsQueryRequest,
UnionOpenCouponQueryRequest,
UnionOpenOrderQueryRequest,
UnionOpenOrderRowQueryRequest,
UnionOpenGoodsJingfenQueryRequest,
UnionOpenCategoryGoodsGetRequest,
UnionOpenActivityQueryRequest
// 后续可以继续添加更多API
};
// API名称到类的映射表
const API_NAME_MAP = {
'jd.union.open.position.query': ApiTypes.UnionOpenPositionQueryRequest,
'jd.union.open.position.create': ApiTypes.UnionOpenPositionCreateRequest,
'jd.union.open.promotion.byunionid.get': ApiTypes.UnionOpenPromotionByUnionidGetRequest,
'jd.union.open.goods.query': ApiTypes.UnionOpenGoodsQueryRequest,
'jd.union.open.coupon.query': ApiTypes.UnionOpenCouponQueryRequest,
'jd.union.open.order.query': ApiTypes.UnionOpenOrderQueryRequest,
'jd.union.open.order.row.query': ApiTypes.UnionOpenOrderRowQueryRequest,
'jd.union.open.goods.jingfen.query': ApiTypes.UnionOpenGoodsJingfenQueryRequest,
'jd.union.open.category.goods.get': ApiTypes.UnionOpenCategoryGoodsGetRequest,
'jd.union.open.activity.query': ApiTypes.UnionOpenActivityQueryRequest
};
/**
* 京东开放平台客户端
*/
class JdClient {
/**
* 创建京东客户端实例
* @param {Object} config 配置选项
* @param {string} [config.appKey] 应用Key,如不传则从环境变量获取
* @param {string} [config.secretKey] 应用密钥,如不传则从环境变量获取
* @param {string} [config.accessToken] 访问令牌,如不传则从环境变量获取
*/
constructor(config = {}) {
// 添加调试日志
console.log('JdClient构造函数:');
console.log('- 传入的config:', config);
// 只有当config中没有明确设置相应属性时,才从环境变量中获取
this.config = {
appKey: config.appKey !== undefined ? config.appKey : process.env.appkey,
secretKey: config.secretKey !== undefined ? config.secretKey : process.env.secretkey,
accessToken: config.accessToken !== undefined ? config.accessToken : process.env.access_token
};
console.log('- 最终的config:');
console.log(' - appKey:', this.config.appKey);
console.log(' - accessToken是否设置:', this.config.accessToken ? '是' : '否');
// 检查必要配置
if (!this.config.appKey) {
throw new Error('缺少appKey配置');
}
if (!this.config.secretKey) {
throw new Error('缺少secretKey配置');
}
}
/**
* 创建API实例
* @param {Function} ApiClass API类
* @returns {Object} API实例
*/
createAPI(ApiClass) {
return new ApiClass(this.config);
}
/**
* 获取推广位查询API
* @returns {UnionOpenPositionQueryRequest} 推广位查询API实例
* @deprecated 推荐使用execute方法
*/
position() {
return this.createAPI(ApiTypes.UnionOpenPositionQueryRequest);
}
/**
* 获取推广位创建API
* @returns {UnionOpenPositionCreateRequest} 推广位创建API实例
* @deprecated 推荐使用execute方法
*/
positionCreate() {
return this.createAPI(ApiTypes.UnionOpenPositionCreateRequest);
}
/**
* 获取推广链接API
* @returns {UnionOpenPromotionByUnionidGetRequest} 推广链接获取API实例
* @deprecated 推荐使用execute方法
*/
promotion() {
return this.createAPI(ApiTypes.UnionOpenPromotionByUnionidGetRequest);
}
/**
* 获取商品查询API
* @returns {UnionOpenGoodsQueryRequest} 商品查询API实例
* @deprecated 推荐使用execute方法
*/
goods() {
return this.createAPI(ApiTypes.UnionOpenGoodsQueryRequest);
}
/**
* 获取优惠券查询API
* @returns {UnionOpenCouponQueryRequest} 优惠券查询API实例
* @deprecated 推荐使用execute方法
*/
coupon() {
return this.createAPI(ApiTypes.UnionOpenCouponQueryRequest);
}
/**
* 获取订单查询API
* @returns {UnionOpenOrderQueryRequest} 订单查询API实例
* @deprecated 推荐使用execute方法
*/
order() {
return this.createAPI(ApiTypes.UnionOpenOrderQueryRequest);
}
/**
* 获取订单行查询API
* @returns {UnionOpenOrderRowQueryRequest} 订单行查询API实例
* @deprecated 推荐使用execute方法
*/
orderRow() {
return this.createAPI(ApiTypes.UnionOpenOrderRowQueryRequest);
}
/**
* 获取京粉精选商品查询API
* @returns {UnionOpenGoodsJingfenQueryRequest} 京粉精选商品查询API实例
* @deprecated 推荐使用execute方法
*/
goodsJingfen() {
return this.createAPI(ApiTypes.UnionOpenGoodsJingfenQueryRequest);
}
/**
* 获取商品类目查询API
* @returns {UnionOpenCategoryGoodsGetRequest} 商品类目查询API实例
* @deprecated 推荐使用execute方法
*/
category() {
return this.createAPI(ApiTypes.UnionOpenCategoryGoodsGetRequest);
}
/**
* 获取活动查询API
* @returns {UnionOpenActivityQueryRequest} 活动查询API实例
* @deprecated 推荐使用execute方法
*/
activity() {
return this.createAPI(ApiTypes.UnionOpenActivityQueryRequest);
}
/**
* 执行API调用
* @param {string} apiName API名称,例如 jd.union.open.promotion.common.get
* @param {Object} params 业务参数
* @param {Object} [options] 请求选项
* @returns {Promise<Object>} API返回结果
*/
async execute(apiName, params, options = {}) {
console.log(`JdClient.execute调用:
- API名称: ${apiName}
- 参数: ${JSON.stringify(params, (key, value) => {
if (key === 'key' && typeof value === 'string') {
return value ? `已设置(长度:${value.length})` : '未设置';
}
return value;
}, 2)}
`);
// 检查参数
if (!params) {
console.log('警告: 参数为空,已自动初始化为空对象');
params = {};
}
// 处理参数包装
params = this.preprocessApiParams(apiName, params);
// 加载相应的API处理类
let apiInstance;
try {
// 尝试从映射表中获取API类
const ApiClass = API_NAME_MAP[apiName];
if (ApiClass) {
console.log(`从映射表中找到API类: ${ApiClass.name}`);
apiInstance = new ApiClass(this.config);
} else {
// 如果映射表中没有,则尝试动态加载
console.log(`映射表中找不到API: ${apiName},尝试动态加载`);
// 将API名称转换为类名
const apiNameParts = apiName.split('.');
const apiType = apiNameParts[1]; // 取第二部分,如"union"
// 把剩余部分转换为驼峰格式
const apiMethod = apiNameParts.slice(2)
.map(part => part.charAt(0).toUpperCase() + part.slice(1))
.join('');
// 构建类名,例如: UnionOpenPositionQueryRequest
const className = apiType.charAt(0).toUpperCase() + apiType.slice(1) +
apiMethod + 'Request';
// 构建路径,例如: ./lib/union/UnionOpenPositionQueryRequest
const modulePath = `./lib/${apiType}/${className}`;
console.log(`尝试加载API模块: ${modulePath}`);
// 动态导入模块
const ApiModule = require(modulePath);
const ApiClass = ApiModule[className];
if (!ApiClass) {
throw new Error(`找不到API类: ${className}`);
}
// 创建API实例
apiInstance = new ApiClass(this.config);
}
} catch (error) {
console.error(`加载API模块出错: ${error.message}`);
throw new Error(`API "${apiName}" 不存在或模块加载失败: ${error.message}`);
}
try {
// 执行API调用
console.log(`准备调用API: ${apiName}`);
const result = await apiInstance.execute(params, options);
console.log(`API调用成功: ${apiName}`);
return result;
} catch (error) {
console.error(`API调用失败: ${error.message}`);
throw error;
}
}
/**
* 预处理API参数,根据API类型包装参数
* @param {string} apiName API名称
* @param {Object} params 原始参数
* @returns {Object} 处理后的参数
* @private
*/
preprocessApiParams(apiName, params) {
// 对于API特定的参数包装
switch(apiName) {
case 'jd.union.open.position.query':
return { positionReq: params };
case 'jd.union.open.position.create':
return { positionReq: params };
case 'jd.union.open.promotion.byunionid.get':
return { promotionCodeReq: params };
case 'jd.union.open.goods.query':
return { goodsReqDTO: params };
case 'jd.union.open.coupon.query':
// 对于优惠券查询,如果已经传入了couponUrls、unionId和key,则不再嵌套包装
if (params.couponUrls) {
console.log('检测到couponUrls参数,使用直接传递参数的方式');
return params; // 直接使用参数,不再包装
}
return { couponReq: params };
case 'jd.union.open.order.query':
return { orderReq: params };
case 'jd.union.open.order.row.query':
return { orderReq: params };
case 'jd.union.open.goods.jingfen.query':
return { goodsReq: params };
case 'jd.union.open.category.goods.get':
return { categoryReq: params };
case 'jd.union.open.activity.query':
return { activityReq: params };
default:
// 如果没有特殊处理,保持原样
return params;
}
}
}
module.exports = {
JdClient,
JdApiError,
ApiTypes // 导出API类型,方便用户直接引用
};