parseGameData.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /**
  2. * 解析让球方
  3. */
  4. const ratioAccept = (ratio) => {
  5. if (ratio > 0) {
  6. return 'a';
  7. }
  8. return '';
  9. }
  10. /**
  11. * 将比率转换为字符串
  12. * @param {*} ratio
  13. * @returns
  14. */
  15. const ratioString = (ratio) => {
  16. ratio = Math.abs(ratio);
  17. ratio = ratio.toString();
  18. ratio = ratio.replace(/\./, '');
  19. return ratio;
  20. }
  21. /**
  22. * 解析胜平负盘口
  23. * @param {*} moneyline
  24. * @returns
  25. */
  26. const parseMoneyline = (moneyline, maxMoneyline) => {
  27. // 胜平负
  28. if (!moneyline) {
  29. return null;
  30. }
  31. const { home, away, draw } = moneyline;
  32. const max = maxMoneyline;
  33. return {
  34. 'ior_mh': { v: home, m: max },
  35. 'ior_mc': { v: away, m: max },
  36. 'ior_mn': { v: draw, m: max },
  37. }
  38. }
  39. /**
  40. * 解析让分盘口
  41. * @param {*} spreads
  42. * @param {*} wm
  43. * @returns
  44. */
  45. const parseSpreads = (spreads, wm, maxSpread) => {
  46. // 让分盘
  47. if (!spreads?.length) {
  48. return null;
  49. }
  50. const events = {};
  51. spreads.forEach(spread => {
  52. const { hdp, home, away, max=maxSpread } = spread;
  53. // if (!(hdp % 1) || !!(hdp % 0.5)) {
  54. // // 整数或不能被0.5整除的让分盘不处理
  55. // return;
  56. // }
  57. const ratio_ro = hdp;
  58. const ratio_r = ratio_ro - wm;
  59. events[`ior_r${ratioAccept(ratio_r)}h_${ratioString(ratio_r)}`] = {
  60. v: home,
  61. r: wm != 0 ? `ior_r${ratioAccept(ratio_ro)}h_${ratioString(ratio_ro)}` : undefined,
  62. m: max,
  63. };
  64. events[`ior_r${ratioAccept(-ratio_r)}c_${ratioString(ratio_r)}`] = {
  65. v: away,
  66. r: wm != 0 ? `ior_r${ratioAccept(-ratio_ro)}c_${ratioString(ratio_ro)}` : undefined,
  67. m: max,
  68. };
  69. });
  70. return events;
  71. }
  72. /**
  73. * 解析大小球盘口
  74. * @param {*} totals
  75. * @returns
  76. */
  77. const parseTotals = (totals, maxTotal) => {
  78. // 大小球盘
  79. if (!totals?.length) {
  80. return null;
  81. }
  82. const events = {};
  83. totals.forEach(total => {
  84. const { points, over, under, max=maxTotal } = total;
  85. events[`ior_ouc_${ratioString(points)}`] = { v: over, m: max };
  86. events[`ior_ouh_${ratioString(points)}`] = { v: under, m: max };
  87. });
  88. return events;
  89. }
  90. /**
  91. * 解析直赛盘口
  92. * @param {*} straight
  93. * @param {*} wm
  94. * @returns
  95. */
  96. const parseStraight = (straight, wm) => {
  97. if (!straight) {
  98. return null;
  99. }
  100. const { cutoff='', status=0, spreads=[], moneyline={}, totals=[], maxSpread, maxMoneyline, maxTotal } = straight;
  101. const cutoffTime = new Date(cutoff).getTime();
  102. const nowTime = Date.now();
  103. if (status != 1 || cutoffTime < nowTime) {
  104. return null;
  105. }
  106. const events = {};
  107. Object.assign(events, parseSpreads(spreads, wm, maxSpread));
  108. Object.assign(events, parseMoneyline(moneyline, maxMoneyline));
  109. Object.assign(events, parseTotals(totals, maxTotal));
  110. return events;
  111. }
  112. /**
  113. * 解析净胜球盘口
  114. * @param {*} winningMargin
  115. * @param {*} home
  116. * @param {*} away
  117. * @returns
  118. */
  119. const parseWinningMargin = (winningMargin, home, away) => {
  120. if (!winningMargin) {
  121. return null;
  122. }
  123. const { cutoff='', status='', contestants=[] } = winningMargin;
  124. const cutoffTime = new Date(cutoff).getTime();
  125. const nowTime = Date.now();
  126. if (status != 'O' || cutoffTime < nowTime || !contestants?.length) {
  127. return null;
  128. }
  129. const events = {};
  130. contestants.forEach(contestant => {
  131. const { name, price, max } = contestant;
  132. const nr = name.match(/\d+$/)?.[0];
  133. if (!nr) {
  134. return;
  135. }
  136. let side;
  137. if (name.startsWith(home)) {
  138. side = 'h';
  139. }
  140. else if (name.startsWith(away)) {
  141. side = 'c';
  142. }
  143. else {
  144. return;
  145. }
  146. events[`ior_wm${side}_${nr}`] = { v: price, m: max };
  147. });
  148. return events;
  149. }
  150. /**
  151. * 解析进球数盘口
  152. * @param {*} exactTotalGoals
  153. * @returns
  154. */
  155. const parseExactTotalGoals = (exactTotalGoals) => {
  156. if (!exactTotalGoals) {
  157. return null;
  158. }
  159. const { cutoff='', status='', contestants=[] } = exactTotalGoals;
  160. const cutoffTime = new Date(cutoff).getTime();
  161. const nowTime = Date.now();
  162. if (status != 'O' || cutoffTime < nowTime || !contestants?.length) {
  163. return null;
  164. }
  165. const events = {};
  166. contestants.forEach(contestant => {
  167. const { name, price, max } = contestant;
  168. if (+name >= 1 && +name <= 7) {
  169. events[`ior_ot_${name}`] = { v: price, m: max };
  170. }
  171. });
  172. return events;
  173. }
  174. /**
  175. * 解析滚球场次状态
  176. * @param {*} state
  177. * @returns
  178. */
  179. const parseRbState = (state) => {
  180. let stage = null;
  181. if (state == 1) {
  182. stage = '1H';
  183. }
  184. else if (state == 2) {
  185. stage = 'HT';
  186. }
  187. else if (state == 3) {
  188. stage = '2H';
  189. }
  190. else if (state >= 4) {
  191. stage = 'ET';
  192. }
  193. return stage;
  194. }
  195. /**
  196. * 解析比赛数据
  197. * @param {*} game
  198. * @returns
  199. */
  200. const parseGame = (game) => {
  201. const { id=0, originId=0, periods={}, specials={}, home, away, marketType, state, elapsed, homeScore=0, awayScore=0 } = game;
  202. const { straight } = periods;
  203. const { winningMargin={}, exactTotalGoals={} } = specials;
  204. const wm = homeScore - awayScore;
  205. const score = `${homeScore}-${awayScore}`;
  206. const odds = parseStraight(straight, wm) ?? {};
  207. const stage = parseRbState(state);
  208. const retime = elapsed ? `${elapsed}'` : '';
  209. const evtime = Date.now();
  210. Object.assign(odds, parseWinningMargin(winningMargin, home, away));
  211. Object.assign(odds, parseExactTotalGoals(exactTotalGoals));
  212. return { id, originId, odds, evtime, stage, retime, score, wm, marketType }
  213. }
  214. export default parseGame;