LhcSettlementService.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. <?php
  2. namespace App\Services;
  3. use App\Models\LhcLottery;
  4. use App\Models\LhcOrder;
  5. use Illuminate\Support\Facades\DB;
  6. //六合彩开奖结算相关
  7. class LhcSettlementService
  8. {
  9. //根据期号结算订单
  10. public static function settle($issue)
  11. {
  12. // 1. 获取开奖结果
  13. $lottery = LhcLottery::where('issue', $issue)->first();
  14. if (!$lottery) throw new \Exception("未找到期号 {$issue} 的开奖数据");
  15. $numbers = is_array($lottery->numbers) ? $lottery->numbers : json_decode($lottery->numbers, true);
  16. $specialNum = (int)end($numbers); // 最后一个是特码
  17. // 预计算特码属性
  18. $attr = [
  19. 'num' => $specialNum,
  20. 'zodiac' => self::getZodiac($specialNum, date('Y', strtotime($lottery->open_time))),
  21. 'color' => self::getColor($specialNum),
  22. 'ds' => $specialNum % 2 === 0 ? '双' : '单',
  23. 'dx' => $specialNum >= 25 ? '大' : '小', // 49通常算和局或按规则定义
  24. ];
  25. // 2. 批量获取待结算订单 (Chunk 处理防止内存溢出)
  26. LhcOrder::where('issue', $issue)->where('lottery_status', 'pending')
  27. ->chunk(100, function ($orders) use ($attr) {
  28. foreach ($orders as $order) {
  29. $this->processOrder($order, $attr);
  30. }
  31. });
  32. }
  33. private function processOrder($order, $attr)
  34. {
  35. DB::transaction(function () use ($order, $attr) {
  36. $isWin = false;
  37. // 3. 根据玩法判断中奖
  38. switch ($order->gameplay) {
  39. case '特码': // 特码
  40. $isWin = (int)$order->number === $attr['num'];
  41. break;
  42. case '正肖': // 生肖-正肖
  43. $isWin = $order->number === $attr['zodiac'];
  44. break;
  45. case '三色波': // 色波-三色波
  46. $isWin = $order->number === $attr['color'];
  47. break;
  48. case 'tm_ds': // 特码单双
  49. $isWin = $order->number === $attr['ds'];
  50. break;
  51. case 'tm_dx': // 特码大小
  52. // 49 一般不计大小或算和,根据实际规则改写
  53. if ($attr['num'] === 49) {
  54. $this->refundOrder($order); // 49退本金
  55. return;
  56. }
  57. $isWin = $order->number === $attr['dx'];
  58. break;
  59. }
  60. // 4. 执行结算
  61. if ($isWin) {
  62. $bonus = $order->amount * $order->odds;
  63. $order->update(['lottery_status' => '2', 'win_amount' => $bonus]);
  64. $order->user->increment('balance', $bonus); // 派奖
  65. } else {
  66. $order->update(['lottery_status' => '1']);
  67. }
  68. });
  69. }
  70. private function refundOrder($order) {
  71. $order->update(['lottery_status' => '3', 'win_amount' => $order->amount]);
  72. $order->user->increment('balance', $order->amount);
  73. }
  74. /**
  75. * 获取特码对应的生肖
  76. * 六合彩生肖逻辑:当年的生肖对应 01, 13, 25, 37, 49
  77. * @param int $number 号码 (1-49)
  78. * @param int $year 农历年份 (如 2024)
  79. */
  80. public static function getZodiac($number, $year = null)
  81. {
  82. $year = $year ?: date('Y');
  83. // 生肖对应索引 (固定顺序)
  84. $zodiacList = ['鼠', '牛', '虎', '兔', '龙', '蛇', '马', '羊', '猴', '鸡', '狗', '猪'];
  85. // 计算当年的本命生肖索引 (以 2024 龙年为例)
  86. // 简易逻辑:(年份 - 4) % 12。2024 -> index 8 (龙)
  87. $currentYearZodiacIndex = ($year - 4) % 12;
  88. // 六合彩号码是从 1 开始逆推的
  89. // 公式:(本命索引 - (号码 - 1) % 12 + 12) % 12
  90. $targetIndex = ($currentYearZodiacIndex - ($number - 1) % 12 + 12) % 12;
  91. return $zodiacList[$targetIndex];
  92. }
  93. /**
  94. * 获取号码对应的波色
  95. */
  96. public static function getColor($number)
  97. {
  98. $red = [1, 2, 7, 8, 12, 13, 18, 19, 23, 24, 29, 30, 34, 35, 40, 45, 46];
  99. $blue = [3, 4, 9, 10, 14, 15, 20, 25, 26, 31, 36, 37, 41, 42, 47, 48];
  100. $green = [5, 6, 11, 16, 17, 21, 22, 27, 28, 32, 33, 38, 39, 43, 44, 49];
  101. if (in_array($number, $red)) return '红波';
  102. if (in_array($number, $blue)) return '蓝波';
  103. if (in_array($number, $green)) return '绿波';
  104. return '未知';
  105. }
  106. /**
  107. * 获取五行 (金木水火土)
  108. */
  109. public static function getElement($number)
  110. {
  111. // 五行通常每年也会微调,此处为通用映射逻辑(示意)
  112. $elements = [
  113. '金' => [1, 2, 15, 16, 23, 24, 31, 32, 45, 46],
  114. '木' => [5, 6, 13, 14, 27, 28, 35, 36, 43, 44],
  115. '水' => [11, 12, 19, 20, 33, 34, 41, 42, 49],
  116. '火' => [7, 8, 21, 22, 29, 30, 37, 38],
  117. '土' => [3, 4, 9, 10, 17, 18, 25, 26, 39, 40, 47, 48],
  118. ];
  119. foreach ($elements as $name => $nums) {
  120. if (in_array($number, $nums)) return $name;
  121. }
  122. }
  123. }