const axios = require('axios'); const Logs = require('../libs/logs'); const PS_IOR_KEYS = [ ['0', 'ior_mh', 'ior_mn', 'ior_mc'], // ['0', 'ior_rh_05', 'ior_mn', 'ior_rc_05'], ['-1', 'ior_rh_15', 'ior_wmh_1', 'ior_rac_05'], ['-2', 'ior_rh_25', 'ior_wmh_2', 'ior_rac_15'], ['+1', 'ior_rah_05', 'ior_wmc_1', 'ior_rc_15'], ['+2', 'ior_rah_15', 'ior_wmc_2', 'ior_rc_25'], ]; const BASE_URL = 'https://api.isthe.me/api/p'; const IS_DEV = process.env.NODE_ENV == 'development'; const GAMES = { Leagues: {}, List: {}, Baselist: {} }; /** * 精确浮点数字 * @param {number} number * @param {number} x * @returns {number} */ const fixFloat = (number, x=2) => { return parseFloat(number.toFixed(x)); } /** * 获取市场类型 */ const getMarketType = (mk) => { return mk == 0 ? 'early' : 'today'; } /** * 同步联赛列表 */ const syncLeaguesList = ({ mk, leagues }) => { if (IS_DEV) { return Logs.out('syncLeaguesList', { mk, leagues }); } axios.post(`${BASE_URL}/syncLeague`, { mk, leagues }) .then(res => { Logs.out('syncLeaguesList', res.data); }) .catch(err => { Logs.out('syncLeaguesList', err.message); }); } /** * 更新联赛列表 */ const updateLeaguesList = ({ mk, leagues }) => { const leaguesList = GAMES.Leagues; if (JSON.stringify(leaguesList[mk]) != JSON.stringify(leagues)) { leaguesList[mk] = leagues; syncLeaguesList({ mk, leagues }); return leagues.length; } return 0; } /** * 获取筛选过的联赛 */ const getFilteredLeagues = async (mk) => { return axios.get(`${BASE_URL}/getLeagueTast?mk=${mk}`) .then(res => { if (res.data.code == 0) { return res.data.data; } return Promise.reject(new Error(res.data.message)); }); } /** * 同步比赛列表到服务器 */ const syncGamesList = ({ platform, mk, games }) => { if (IS_DEV) { return Logs.out('syncGamesList', { platform, mk, games }); } axios.post(`${BASE_URL}/syncGames`, { platform, mk, games }) .then(res => { Logs.out('syncGamesList', { platform, mk, count: games.length }, res.data); }) .catch(err => { Logs.out('syncGamesList', { platform, mk }, err.message); }); } /** * 同步基准比赛列表 */ const syncBaseList = ({ marketType, games }) => { const baseList = GAMES.Baselist; if (!baseList[marketType]) { baseList[marketType] = games; } const newMap = new Map(games.map(item => [item.eventId, item])); // 删除不存在的项 for (let i = baseList[marketType].length - 1; i >= 0; i--) { if (!newMap.has(baseList[marketType][i].eventId)) { baseList[marketType].splice(i, 1); } } // 添加或更新 const oldIds = new Set(baseList[marketType].map(item => item.eventId)); games.forEach(game => { if (!oldIds.has(game.eventId)) { // 添加新项 baseList[marketType].push(game); } }); } /** * 更新比赛列表 */ const updateGamesList = (({ platform, mk, games } = {}) => { return new Promise((resolve, reject) => { if (!platform || !games) { return reject(new Error('PLATFORM_GAMES_INVALID')); } const marketType = getMarketType(mk); syncGamesList({ platform, mk, games }); if (platform == 'ps') { syncBaseList({ marketType, games }); } resolve(); }); }); /** * 提交盘口数据 */ const submitOdds = ({ platform, mk, games }) => { if (IS_DEV) { return Logs.out('syncOdds', { platform, mk, games }); } axios.post(`${BASE_URL}/syncOdds`, { platform, mk, games}) .then(res => { Logs.out('syncOdds', { platform, mk, count: games.length }, res.data); }) .catch(err => { Logs.out('syncOdds', { platform, mk }, err.message); }); } /** * 同步基准盘口 */ const syncBaseEvents = ({ mk, games, outrights }) => { const marketType = getMarketType(mk); const baseList = GAMES.Baselist; if (!baseList[marketType]) { return; } const baseMap = new Map(baseList[marketType].map(item => [item.eventId, item])); games?.forEach(game => { const { eventId, evtime, events } = game; const baseGame = baseMap.get(eventId); if (baseGame) { baseGame.evtime = evtime; baseGame.events = events; } }); outrights?.forEach(outright => { const { parentId, sptime, special } = outright; const baseGame = baseMap.get(parentId); if (baseGame) { baseGame.sptime = sptime; baseGame.special = special; } }); if (games?.length) { const gamesList = baseList[marketType]?.map(game => { const { evtime, events, sptime, special, ...gameInfo } = game; const expireTime = Date.now() - 15000; let odds = {}; if (evtime > expireTime) { odds = { ...odds, ...events }; } if (sptime > expireTime) { odds = { ...odds, ...special }; } const matches = PS_IOR_KEYS.map(([label, ...keys]) => { const match = keys.map(key => ({ key, value: odds[key] ?? 0 })); return { label, match }; }).filter(item => item.match.every(entry => entry.value !== 0)); return { ...gameInfo, matches }; }); // Logs.out('baseList', baseList[marketType]); submitOdds({ platform: 'ps', mk, games: gamesList }); } } /** * 更新比赛盘口 */ const updateGamesEvents = ({ platform, mk, games, outrights }) => { return new Promise((resolve, reject) => { if (!platform || (!games && !outrights)) { return reject(new Error('PLATFORM_GAMES_INVALID')); } if (platform == 'ps') { syncBaseEvents({ mk, games, outrights }); } Logs.out('updateGamesEvents', { platform, mk, games, outrights }); resolve(); }); } /** * 获取关联比赛 */ const getGamesRelation = async (mk) => { return axios.get(`${BASE_URL}/getGameTast?mk=${mk}`) .then(res => { if (res.data.code == 0) { return res.data.data; } return Promise.reject(new Error(res.data.message)); }); } /** * 同步比赛结果 */ const syncGamesResult = async (result) => { if (IS_DEV) { return Logs.out('updateGamesResult', result); } axios.post(`${BASE_URL}/syncMatchResult`, result) .then(res => { Logs.out('syncMatchResult', res.data); }) .catch(err => { Logs.out('syncMatchResult', err.message); }); } /** * 更新比赛结果 */ const updateGamesResult = (result) => { syncGamesResult(result); return Promise.resolve(); } module.exports = { updateLeaguesList, getFilteredLeagues, updateGamesList, updateGamesEvents, getGamesRelation, updateGamesResult, }