SyncVerifyCard.php 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. <?php
  2. /**
  3. * @file SyncVerifyCard
  4. * @editor Created by vscode
  5. * @author WPing丶
  6. * @date 2024/11/19
  7. * @time 14:22:25
  8. *
  9. * 备注:同步储值卡消费记录
  10. */
  11. namespace app\commands;
  12. use app\models\Order;
  13. use app\models\OrderRefund;
  14. use app\models\User;
  15. use app\models\VerifyCard;
  16. use app\models\VerifyCardLog;
  17. use app\models\VerifyCardSale;
  18. use yii\console\Controller;
  19. class SyncVerifyCard extends Controller
  20. {
  21. /**
  22. * 模块名:index
  23. * 代码描述:同步储值卡消费记录
  24. * 作者:WPing丶
  25. * 请求方式:GET
  26. * 创建时间:2024/11/19 14:31:15
  27. */
  28. public function actionIndex()
  29. {
  30. //清空所有储值卡的消费记录数据(兼容有脏数据的情况,一般情况下注释)
  31. VerifyCardLog::updateAll([
  32. 'use_price' => 0,
  33. 'use_order_ids' => null,
  34. 'is_complete' => 0,
  35. ]);
  36. $usersWithBalancePay = User::find()
  37. ->alias('u') // 给 User 表起一个别名
  38. ->leftJoin(['o' => Order::tableName()], 'u.id = o.user_id') // 连接 Order 表
  39. ->leftJoin(['r' => OrderRefund::tableName()], 'r.order_id = o.id') // 连接 OrderRefund 表
  40. ->leftJoin(['vcl' => VerifyCardLog::tableName()], 'vcl.user_id = u.id') // 连接 VerifyCardLog 表
  41. ->where([
  42. 'o.is_pay' => 1, // 订单已支付
  43. 'o.is_delete' => 0, // 未删除
  44. 'o.is_recycle' => 0 // 未被回收
  45. ])
  46. ->andWhere([
  47. 'or',
  48. ['o.pay_type' => 3], // 使用余额支付
  49. [
  50. 'or',
  51. [
  52. 'and',
  53. 'o.is_combine_pay' => 1, // 组合支付
  54. ['>', 'combine_money', 0] // 且余额抵扣大于0
  55. ],
  56. ['>', 'o.balance', 0]
  57. ]
  58. ])
  59. ->andWhere(['<>', 'o.trade_status', 1]) // 排除交易状态为 1 的订单
  60. ->andWhere(['IS NOT', 'vcl.id', null]) // 排除没有储值卡的用户
  61. ->andWhere([
  62. 'or',
  63. ['r.id' => null], // 没有退款记录
  64. ['<>', 'r.status', 1] // 或者退款状态不是 1
  65. ])
  66. ->select('u.id') // 查询用户的 ID
  67. ->distinct() // 去重
  68. ->column(); // 获取所有用户 ID
  69. debug_log('待同步的User_id:'.implode(',', $usersWithBalancePay) , 'VerifyCard.log');
  70. foreach($usersWithBalancePay as $user_id) {
  71. //查询出用户所有的储值卡
  72. $card_list = VerifyCardLog::find()->alias('vcl')
  73. ->leftJoin(['vcs' => VerifyCardSale::tableName()], 'vcl.sale_id=vcs.id')
  74. ->leftJoin(['vc' => VerifyCard::tableName()], 'vcs.verify_card_id=vc.id')
  75. ->where([
  76. 'vcl.store_id' => 1,
  77. 'vc.type' => 3,
  78. 'vcl.user_id' => $user_id,
  79. 'vcl.type' => VerifyCardLog::WRITE_TYPE_EXCHANGE,
  80. 'vcl.is_complete' => 0,
  81. ])
  82. ->select('vc.total_price as price, vcl.*')
  83. ->orderBy(['vcl.use_time' => SORT_ASC])
  84. ->asArray()
  85. ->all();
  86. debug_log('用户User_id:'.$user_id.',的已激活储值卡' , 'VerifyCard.log');
  87. debug_log(json_encode($card_list,JSON_UNESCAPED_UNICODE), 'VerifyCard.log');
  88. // if(count($card_list) == 0) {
  89. // //用户没有储值卡的跳出循环
  90. // continue;
  91. // }
  92. $order_balance = 0;
  93. $last_order_id = 0;
  94. $last_order_ids = [];
  95. foreach($card_list as $card) {
  96. $time = $card['use_time'];
  97. $order_list = Order::find()->alias('o')
  98. ->leftJoin(['r' => OrderRefund::tableName()], 'r.order_id = o.id') // 连接 OrderRefund 表
  99. ->where([
  100. 'o.is_pay' => 1, // 订单已支付
  101. 'o.is_delete' => 0, // 未删除
  102. 'o.is_recycle' => 0, // 未被回收
  103. 'o.user_id' => $user_id,
  104. ])
  105. ->andWhere([
  106. 'or',
  107. ['o.pay_type' => 3], // 使用余额支付
  108. [
  109. 'or',
  110. [
  111. 'and',
  112. 'o.is_combine_pay' => 1, // 组合支付
  113. ['>', 'combine_money', 0] // 且余额抵扣大于0
  114. ],
  115. ['>', 'o.balance', 0]
  116. ]
  117. ])
  118. ->andWhere(['<>', 'o.trade_status', 1]) // 排除交易状态为 1 的订单
  119. ->andWhere(['>', 'o.pay_time', $time]) // 订单支付时间要大于储值卡的激活时间
  120. ->andWhere(['NOT IN', 'o.id', $last_order_ids]) // 订单支付时间要大于储值卡的激活时间
  121. ->andWhere([
  122. 'or',
  123. ['r.id' => null], // 没有退款记录
  124. ['<>', 'r.status', 1] // 或者退款状态不是 1
  125. ])
  126. ->select('o.*')
  127. ->orderBy(['o.pay_time' => SORT_ASC])
  128. ->asArray()
  129. ->all();
  130. // if(count($order_list) == 0) {
  131. // //用户有储值卡但未下单的跳出循环
  132. // continue 2;
  133. // }
  134. foreach($order_list as $order) {
  135. $pay_price = $order['combine_money'] > 0 ? $order['combine_money'] : $order['pay_price'];
  136. $log = VerifyCardLog::findOne($card['id']);
  137. $card_balance = bcsub($card['price'],$log->use_price,2);//卡内余额
  138. if($order['id'] == $last_order_id) {
  139. $pay_price = $order_balance;
  140. }
  141. if($pay_price <= $card_balance) {
  142. //储值卡内余额足以支付这笔订单
  143. $log->use_price += $pay_price;
  144. if($log->use_order_ids) {
  145. $use_order_ids = explode(',', $log->use_order_ids);
  146. $use_order_ids[] = $order['id'];
  147. $log->use_order_ids = implode(',', $use_order_ids);
  148. } else {
  149. $log->use_order_ids = $order['id'];
  150. }
  151. if($pay_price == $card_balance) {//如果储值卡内余额刚好够支付当前订单
  152. $log->is_complete = 1;
  153. }
  154. if (!$log->save()) {
  155. debug_log('储值卡消费记录保存失败', 'VerifyCard.log');
  156. debug_log($log->errors, 'VerifyCard.log');
  157. }
  158. $order_balance = 0;
  159. $last_order_id = 0;
  160. debug_log('OKOKOKOKOKOKOKOKOKOK,用户User_id:'.$user_id.'的用户于'.date('Y-m-d H:i:s',$order['pay_time']).'使用card_id为'.$card['id'].'的储值卡,支付了order_no为'.$order['order_no'].'的订单后,储值卡还剩下:¥'.bcsub($card_balance,$pay_price,2).'元' , 'VerifyCard.log');
  161. $last_order_ids[] = $order['id'];
  162. if($pay_price == $card_balance) {
  163. continue 2;
  164. }
  165. } else {
  166. //储值卡内余额不足支付这笔订单
  167. $log->use_price += $card_balance;
  168. if($log->use_order_ids) {
  169. $use_order_ids = explode(',', $log->use_order_ids);
  170. $use_order_ids[] = $order['id'];
  171. $log->use_order_ids = implode(',', $use_order_ids);
  172. } else {
  173. $log->use_order_ids = $order['id'];
  174. }
  175. $log->is_complete = 1;
  176. if (!$log->save()) {
  177. debug_log('储值卡消费记录保存失败', 'VerifyCard.log');
  178. debug_log($log->errors, 'VerifyCard.log');
  179. }
  180. $order_balance = bcsub($pay_price, $card_balance, 2);
  181. $last_order_id = $order['id'];
  182. debug_log('NONONONONONONONONONO,用户User_id:'.$user_id.'的用户于'.date('Y-m-d H:i:s',$order['pay_time']).'使用card_id为'.$card['id'].'的储值卡,支付了order_no为'.$order['order_no'].'的订单后,储值卡还剩下:¥0元' , 'VerifyCard.log');
  183. continue 2;
  184. }
  185. }
  186. }
  187. }
  188. }
  189. }