Files
steel_prices_service/commonApi.js
2026-01-06 18:00:43 +08:00

361 lines
10 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const axios = require('axios');
const login = require('./loginApi.js');
/**
* 钢材价格数据采集服务配置
* @typedef {Object} SteelPriceConfig
* @property {string} baseURL - 基础 URL
* @property {string} pageId - 页面 ID
* @property {string} menuId - 菜单 ID
*/
/**
* 预定义的接口配置
* 根据接口cURL.txt中的三个接口定义
*/
const API_ENDPOINTS = {
/**
* 接口 1: 默认钢材价格查询
*/
DEFAULT: {
name: '默认钢材价格查询',
pageId: 'PG-D615-D8E2-2FD84B8D',
menuId: 'MK-A8B8-109E-13D34116'
},
/**
* 接口 2: 备用钢材价格查询
*/
BACKUP: {
name: '备用钢材价格查询',
pageId: 'PG-B9F4-CDC8-6EDE4F14',
menuId: 'MK-0967-9408-F5D4430C'
},
/**
* 接口 3: 扩展钢材价格查询
*/
EXTENDED: {
name: '扩展钢材价格查询',
pageId: 'PG-3705-8CD5-7B6F4EB8',
menuId: 'MK-32E1-6A12-66314921'
}
};
/**
* 默认配置
* @type {SteelPriceConfig}
*/
const DEFAULT_CONFIG = {
baseURL: 'https://xdwlgyl.yciccloud.com',
pageId: 'PG-D615-D8E2-2FD84B8D',
menuId: 'MK-A8B8-109E-13D34116'
};
/**
* 钢材价格数据采集服务
* 从德钢云平台获取价格数据
* @class SteelPriceCollector
*/
class SteelPriceCollector {
/**
* 构造函数
* @param {SteelPriceConfig} config - 服务配置
*/
constructor(config = {}) {
/**
* 服务配置
* @type {SteelPriceConfig}
* @private
*/
this._config = {
baseURL: config.baseURL || DEFAULT_CONFIG.baseURL,
pageId: config.pageId || DEFAULT_CONFIG.pageId,
menuId: config.menuId || DEFAULT_CONFIG.menuId
};
}
/**
* 获取配置
* @returns {SteelPriceConfig} 当前配置
*/
getConfig() {
return { ...this._config };
}
/**
* 更新配置
* @param {Partial<SteelPriceConfig>} config - 要更新的配置
*/
updateConfig(config) {
this._config = {
...this._config,
...config
};
}
/**
* 使用预定义的接口配置
* @param {string} endpointKey - 接口键名 ('DEFAULT' | 'BACKUP' | 'EXTENDED')
*/
useEndpoint(endpointKey) {
const endpoint = API_ENDPOINTS[endpointKey];
if (!endpoint) {
throw new Error(`未知的接口端点: ${endpointKey}。可用选项: ${Object.keys(API_ENDPOINTS).join(', ')}`);
}
console.log(`🔄 切换到接口: ${endpoint.name}`);
console.log(` Page ID: ${endpoint.pageId}`);
console.log(` Menu ID: ${endpoint.menuId}`);
this.updateConfig({
pageId: endpoint.pageId,
menuId: endpoint.menuId
});
}
/**
* 获取可用的接口列表
* @returns {Object} 接口列表
*/
getAvailableEndpoints() {
return Object.keys(API_ENDPOINTS).reduce((acc, key) => {
acc[key] = {
name: API_ENDPOINTS[key].name,
pageId: API_ENDPOINTS[key].pageId,
menuId: API_ENDPOINTS[key].menuId
};
return acc;
}, {});
}
/**
* 构建请求配置(先获取 Token
* @param {Object} params - 查询参数
* @param {string} params.startDate - 开始日期 (YYYY-MM-DD)
* @param {string} params.endDate - 结束日期 (YYYY-MM-DD)
* @param {number} params.page - 页码默认1
* @param {number} params.pageSize - 每页大小默认1000
* @returns {Promise<Object>} Axios请求配置
* @private
*/
async _buildConfig(params = {}) {
const {
startDate = new Date().toISOString().split('T')[0],
endDate = new Date(Date.now() + 365 * 24 * 60 * 60 * 1000).toISOString().split('T')[0],
page = 1,
pageSize = 10
} = params;
// 先获取 Token
console.log('🔐 正在获取 Token...');
const tokenResult = await login.getToken();
if (!tokenResult.success) {
throw new Error(`Token 获取失败: ${tokenResult.error}`);
}
const tokenId = tokenResult.data;
console.log('✅ Token 获取成功:', tokenId);
// 构建查询条件对象
const searchParams = {
_PIRCE_DATE_DATE_START_: startDate,
_PIRCE_DATE_DATE_END_: endDate,
PARTSNAME_NAME: null,
_PARTSNAME_NAME_ADVANCE_SEARCH_: null,
_PARTSNAME_NAME_IS_LIKE_: '1',
GOODS_MATERIAL: null,
_GOODS_MATERIAL_ADVANCE_SEARCH_: null,
_GOODS_MATERIAL_IS_LIKE_: '1',
GOODS_SPEC: null,
_GOODS_SPEC_ADVANCE_SEARCH_: null,
_GOODS_SPEC_IS_LIKE_: '1',
PRODUCTAREA_NAME: null,
_PRODUCTAREA_NAME_ADVANCE_SEARCH_: null,
_PRODUCTAREA_NAME_IS_LIKE_: '1',
PNTREE_NAME: null,
_PNTREE_NAME_ADVANCE_SEARCH_: null,
_PNTREE_NAME_IS_LIKE_: '1',
OPERATOR_NAME: null,
_OPERATOR_NAME_ADVANCE_SEARCH_: null,
PR_PRICE_REGION: null,
_PR_PRICE_REGION_ADVANCE_SEARCH_: null,
OPERATOR_CODE: null,
PRICE_ID: null,
_orderFields_: []
};
// 构建URL编码的请求体
const requestData = new URLSearchParams({
pageId: this._config.pageId,
pageSize: pageSize.toString(),
page: page.toString(),
isPageNoChange: '0',
ctrlId: 'mainTable',
json: JSON.stringify(searchParams),
searchBoxId: 'searchForm',
groupSumFields: JSON.stringify([])
});
// 使用获取到的 Token 构建 Cookie
const cookie = `SameSite=Lax; HWWAFSESTIME=1767596069712; HWWAFSESID=e2b2773ee2641b98e5; SameSite=Lax; SYS-A7EE-D0E8-BE614B80=1108@${tokenId}; JSESSIONID=2389858DBE6A7EDAF695C767A764995B; SameSite=Lax`;
return {
method: 'POST',
url: `${this._config.baseURL}/gdpaas/mainpage/findPage.htm?_p_=${this._config.pageId}`,
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Accept': 'application/json, text/javascript, */*; q=0.01',
'X-Requested-With': 'XMLHttpRequest',
'Pageid': this._config.pageId,
'Menuid': this._config.menuId,
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
'Referer': `${this._config.baseURL}/gdpaas/home/index.htm`,
'Origin': this._config.baseURL,
'Accept-Language': 'zh-CN,zh;q=0.9',
'Accept-Encoding': 'gzip, deflate, br',
'Sec-Fetch-Site': 'same-origin',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Dest': 'empty',
'Sec-Ch-Ua': '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"',
'Sec-Ch-Ua-Mobile': '?0',
'Sec-Ch-Ua-Platform': '"Windows"',
'cookie': cookie
},
data: requestData.toString()
};
}
/**
* 获取钢材价格数据
* @param {Object} params - 查询参数
* @returns {Promise<Object>} 响应数据
*/
async fetchPrices(params = {}) {
try {
const config = await this._buildConfig(params);
const response = await axios.request(config);
// 验证响应数据
if (!response.data) {
throw new Error('响应数据为空');
}
return {
success: true,
data: response.data,
timestamp: new Date().toISOString()
};
} catch (error) {
return {
success: false,
error: error.message,
timestamp: new Date().toISOString()
};
}
}
}
/**
* 导出类和默认实例
*/
module.exports = SteelPriceCollector;
module.exports.default = new SteelPriceCollector();
module.exports.API_ENDPOINTS = API_ENDPOINTS;
/**
* 如果直接运行此文件,执行示例请求
*/
if (require.main === module) {
const SteelPriceCollector = require('./commonApi.js');
async function testAllEndpoints() {
console.log('🚀 测试三个接口\n');
const collector = new SteelPriceCollector();
// 显示可用接口
console.log('📋 可用接口列表:');
const endpoints = collector.getAvailableEndpoints();
Object.entries(endpoints).forEach(([key, info]) => {
console.log(` ${key}: ${info.name}`);
console.log(` Page ID: ${info.pageId}`);
console.log(` Menu ID: ${info.menuId}\n`);
});
// 测试接口 1: DEFAULT
console.log('\n' + '='.repeat(60));
console.log('测试接口 1: DEFAULT默认钢材价格查询');
console.log('='.repeat(60) + '\n');
collector.useEndpoint('DEFAULT');
const result1 = await collector.fetchPrices({
startDate: '2025-01-06',
endDate: '2026-01-06',
page: 1,
pageSize: 100000
});
if (result1.success) {
console.log('✅ 接口 1 调用成功');
console.log('📊 返回数据:', JSON.stringify(result1.data, null, 2));
} else {
console.error('❌ 接口 1 调用失败:', result1.error);
}
// 测试接口 2: BACKUP
console.log('\n' + '='.repeat(60));
console.log('测试接口 2: BACKUP备用钢材价格查询');
console.log('='.repeat(60) + '\n');
// collector.useEndpoint('BACKUP');
// const result2 = await collector.fetchPrices({
// startDate: '2025-01-06',
// endDate: '2026-01-06',
// page: 1,
// pageSize: 1
// });
// if (result2.success) {
// console.log('✅ 接口 2 调用成功');
// console.log('📊 返回数据:', JSON.stringify(result2.data, null, 2));
// } else {
// console.error('❌ 接口 2 调用失败:', result2.error);
// }
// // 测试接口 3: EXTENDED
// console.log('\n' + '='.repeat(60));
// console.log('测试接口 3: EXTENDED扩展钢材价格查询');
// console.log('='.repeat(60) + '\n');
// collector.useEndpoint('EXTENDED');
// const result3 = await collector.fetchPrices({
// startDate: '2025-01-06',
// endDate: '2026-01-06',
// page: 1,
// pageSize: 1
// });
// if (result3.success) {
// console.log('✅ 接口 3 调用成功');
// console.log('📊 返回数据:', JSON.stringify(result3.data, null, 2));
// } else {
// console.error('❌ 接口 3 调用失败:', result3.error);
// }
console.log('\n' + '='.repeat(60));
console.log('✅ 所有接口测试完成!');
console.log('='.repeat(60) + '\n');
}
// 运行测试
testAllEndpoints().catch(error => {
console.error('💥 测试失败:', error);
});
}