TeamEnd.php 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | likeshop100%开源免费商用商城系统
  4. // +----------------------------------------------------------------------
  5. // | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
  6. // | 开源版本可自由商用,可去除界面版权logo
  7. // | 商业版本务必购买商业授权,以免引起法律纠纷
  8. // | 禁止对系统程序代码以任何目的,任何形式的再发布
  9. // | gitee下载:https://gitee.com/likeshop_gitee
  10. // | github下载:https://github.com/likeshop-github
  11. // | 访问官网:https://www.likeshop.cn
  12. // | 访问社区:https://home.likeshop.cn
  13. // | 访问手册:http://doc.likeshop.cn
  14. // | 微信公众号:likeshop技术社区
  15. // | likeshop团队 版权所有 拥有最终解释权
  16. // +----------------------------------------------------------------------
  17. // | author: likeshopTeam
  18. // +----------------------------------------------------------------------
  19. namespace app\common\command;
  20. use app\common\enum\ActivityEnum;
  21. use app\common\enum\AfterSaleLogEnum;
  22. use app\common\enum\OrderEnum;
  23. use app\common\enum\OrderLogEnum;
  24. use app\common\enum\PayEnum;
  25. use app\common\enum\TeamEnum;
  26. use app\common\model\GoodsActivity;
  27. use app\common\model\Order;
  28. use app\common\model\OrderLog;
  29. use app\common\model\TeamActivity;
  30. use app\common\model\TeamFound;
  31. use app\common\model\TeamJoin;
  32. use app\common\service\after_sale\AfterSaleService;
  33. use Exception;
  34. use think\console\Command;
  35. use think\console\Input;
  36. use think\console\Output;
  37. use think\facade\Db;
  38. use think\facade\Log;
  39. class TeamEnd extends Command
  40. {
  41. protected function configure()
  42. {
  43. $this->setName('team_end')
  44. ->setDescription('结束已超时的拼团');
  45. }
  46. /**
  47. * @notes 处理失败的团
  48. * @param Input $input
  49. * @param Output $output
  50. * @return bool|int|null
  51. * @throws Exception
  52. * @author 张无忌
  53. * @date 2021/8/4 15:43
  54. */
  55. protected function execute(Input $input, Output $output)
  56. {
  57. Db::startTrans();
  58. try {
  59. $time = time();
  60. // 1、获取并关闭已结束的活动
  61. $team_ids = (new TeamActivity())->where(['status' => TeamEnum::TEAM_STATUS_CONDUCT])->where([['end_time', '<=', $time]])->column('id');
  62. (new TeamActivity())->whereIn('id', $team_ids)->update(['status' => TeamEnum::TEAM_STATUS_END, 'update_time' => $time]);
  63. // 2、找出拼团中&&拼团有效期结束的拼团记录
  64. $map1 = array(['invalid_time', '<=', $time], ['status', '=', 0]);
  65. $map2 = array(['team_id', 'in', $team_ids], ['status', '=', 0]);
  66. $teamFound1 = (new TeamFound())->withoutField('goods_snap')
  67. ->whereOr([$map1, $map2])
  68. ->select()->toArray();
  69. $teamFound2 = (new TeamFound())->alias('TF')
  70. ->withoutField('goods_snap')
  71. ->where('TF.people', 'exp', ' <= TF.join')
  72. ->where([['TF.invalid_time', '>', $time]])
  73. ->where('status', '=', 0)
  74. ->select()->toArray();
  75. $teamFounds = array_merge($teamFound1, $teamFound2);
  76. // 3、处理拼团的状态
  77. foreach ($teamFounds as $teamFound) {
  78. $teamActivity = (new TeamActivity())->findOrEmpty($teamFound['team_id'])->toArray();
  79. $is_automatic = $teamActivity['is_automatic'];
  80. // 获取参团记录数据
  81. $teamJoin = (new TeamJoin())->alias('TJ')
  82. ->field('TJ.*,O.order_status,O.pay_status')
  83. ->join('order O', 'O.id = TJ.order_id')
  84. ->where(['TJ.found_id' => $teamFound['id']])
  85. ->select()->toArray();
  86. // 获取该团的已支付数量
  87. $payTeamCount = 0;
  88. foreach ($teamJoin as $item) {
  89. if ($item['order_status'] == 1 and $item['pay_status'] == 1) {
  90. $payTeamCount += 1;
  91. }
  92. }
  93. // 如果已满员,但是存在未支付订单,团时间结束时间未到,则不处理
  94. if (($teamFound['people'] == $teamFound['join'] && $teamFound['people'] > $payTeamCount)
  95. and $teamFound['invalid_time'] >= $time) {
  96. continue;
  97. }
  98. // 判断此团的订单状态: 如果存在未支付订单则直接标记失败
  99. if (in_array(0, array_column($teamJoin, 'pay_status'))) {
  100. $this->teamFail($teamJoin, $teamFound, $time);
  101. } else {
  102. // 自动成团/拼团成功
  103. if ($is_automatic or ($teamFound['people'] == $teamFound['join'] && $teamFound['people'] == $payTeamCount)) {
  104. $this->teamSuccess($teamJoin, $teamFound, $time);
  105. } else {
  106. $this->teamFail($teamJoin, $teamFound, $time);
  107. }
  108. }
  109. }
  110. // 删除商品活动信息表的数据
  111. $goodsActivityIds = GoodsActivity::where([
  112. ['activity_type', '=', ActivityEnum::TEAM],
  113. ['activity_id', 'in', $team_ids],
  114. ])->column('id');
  115. if (count($goodsActivityIds)) {
  116. GoodsActivity::destroy($goodsActivityIds);
  117. }
  118. Db::commit();
  119. return true;
  120. } catch (Exception $e) {
  121. Db::rollback();
  122. Log::write('结束已超时的拼团失败,失败原因:' . $e->getMessage());
  123. return false;
  124. }
  125. }
  126. /**
  127. * @notes 拼团成功
  128. * @param $teamJoin
  129. * @param $teamFound
  130. * @param $time
  131. * @author 张无忌
  132. * @date 2021/8/4 16:47
  133. */
  134. public function teamSuccess($teamJoin, $teamFound, $time)
  135. {
  136. // 把团标记成功
  137. TeamFound::update([
  138. 'status' => TeamEnum::TEAM_FOUND_SUCCESS,
  139. 'team_end_time' => $time,
  140. ], ['id'=>$teamFound['id']]);
  141. // 把团记录以及订单标记成功
  142. foreach ($teamJoin as $item) {
  143. // 标记拼团状态为成功
  144. TeamJoin::update([
  145. 'status' => TeamEnum::TEAM_FOUND_SUCCESS,
  146. 'update_time' => $time,
  147. 'team_end_time' => time()
  148. ], ['id' => $item['id']]);
  149. // 标记拼团订单状态成功
  150. Order::update([
  151. 'is_team_success' => 1,
  152. 'update_time' => $time
  153. ], ['id' => $item['order_id']]);
  154. }
  155. }
  156. /**
  157. * @notes 拼团失败,给已支付的订单退款
  158. * @param $teamJoin
  159. * @param $teamFound
  160. * @param $time
  161. * @throws @\think\Exception
  162. * @throws @\think\db\exception\DataNotFoundException
  163. * @throws @\think\db\exception\DbException
  164. * @throws @\think\db\exception\ModelNotFoundException
  165. * @author 张无忌
  166. * @date 2021/8/4 15:27
  167. */
  168. public function teamFail($teamJoin, $teamFound, $time)
  169. {
  170. // 把团标记失败
  171. TeamFound::update([
  172. 'status' => TeamEnum::TEAM_FOUND_FAIL,
  173. 'team_end_time' => $time,
  174. ], ['id'=>$teamFound['id']]);
  175. // 把团记录以及订单标记失败,并进行退款
  176. foreach ($teamJoin as $item) {
  177. // 1、拼团记录标记为失败
  178. TeamJoin::update([
  179. 'status' => TeamEnum::TEAM_FOUND_FAIL,
  180. 'team_end_time' => $time,
  181. 'update_time' => time()
  182. ], ['id'=>$item['id']]);
  183. // 2、订单拼团状态标记失败
  184. Order::update([
  185. 'is_team_success' => 2,
  186. 'update_time' => time()
  187. ], ['id'=>$item['order_id']]);
  188. // 获取团的订单
  189. $teamOrder = (new Order())->where(['id'=>$item['order_id']])->findOrEmpty()->toArray();
  190. // 处于已支付状态的发起整单售后
  191. if ($teamOrder['pay_status'] == PayEnum::ISPAID) {
  192. AfterSaleService::orderRefund([
  193. 'order_id' => $teamOrder['id'],
  194. 'scene' => AfterSaleLogEnum::BUYER_CANCEL_ORDER
  195. ]);
  196. }
  197. //更新订单为已关闭
  198. Order::update([
  199. 'is_team_success' => 2,
  200. 'order_status' => OrderEnum::STATUS_CLOSE,
  201. 'cancel_time' => time()
  202. ], ['id' => $teamOrder['id']]);
  203. // 订单日志
  204. (new OrderLog())->record([
  205. 'type' => OrderLogEnum::TYPE_USER,
  206. 'channel' => OrderLogEnum::USER_CANCEL_ORDER,
  207. 'order_id' => $teamOrder['id'],
  208. 'operator_id' => $teamOrder['user_id'],
  209. ]);
  210. }
  211. }
  212. }