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} 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} 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} 响应数据 */ 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: 1 }); 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); }); }