TeamEnd.php 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  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. class TeamEnd extends Command
  39. {
  40. protected function configure()
  41. {
  42. $this->setName('team_end')
  43. ->setDescription('结束已超时的拼团');
  44. }
  45. /**
  46. * @notes 处理失败的团
  47. * @param Input $input
  48. * @param Output $output
  49. * @return bool|int|null
  50. * @throws Exception
  51. * @author 张无忌
  52. * @date 2021/8/4 15:43
  53. */
  54. protected function execute(Input $input, Output $output)
  55. {
  56. Db::startTrans();
  57. try {
  58. $time = time();
  59. // 1、获取并关闭已结束的活动
  60. $team_ids = (new TeamActivity())->where(['status' => TeamEnum::TEAM_STATUS_CONDUCT])->where([['end_time', '<=', $time]])->column('id');
  61. (new TeamActivity())->whereIn('id', $team_ids)->update(['status' => TeamEnum::TEAM_STATUS_END, 'update_time' => $time]);
  62. // 2、找出拼团中&&拼团有效期结束的拼团记录
  63. $map1 = array(['invalid_time', '<=', $time], ['status', '=', 0]);
  64. $map2 = array(['team_id', 'in', $team_ids], ['status', '=', 0]);
  65. $teamFound1 = (new TeamFound())->withoutField('goods_snap')
  66. ->whereOr([$map1, $map2])
  67. ->select()->toArray();
  68. $teamFound2 = (new TeamFound())->alias('TF')
  69. ->withoutField('goods_snap')
  70. ->where('TF.people', 'exp', ' <= TF.join')
  71. ->where([['TF.invalid_time', '>', $time]])
  72. ->where('status', '=', 0)
  73. ->select()->toArray();
  74. $teamFounds = array_merge($teamFound1, $teamFound2);
  75. // 3、处理拼团的状态
  76. foreach ($teamFounds as $teamFound) {
  77. $teamActivity = (new TeamActivity())->findOrEmpty($teamFound['team_id'])->toArray();
  78. $is_automatic = $teamActivity['is_automatic'];
  79. // 获取参团记录数据
  80. $teamJoin = (new TeamJoin())->alias('TJ')
  81. ->field('TJ.*,O.order_status,O.pay_status')
  82. ->join('order O', 'O.id = TJ.order_id')
  83. ->where(['TJ.found_id' => $teamFound['id']])
  84. ->select()->toArray();
  85. // 获取该团的已支付数量
  86. $payTeamCount = 0;
  87. foreach ($teamJoin as $item) {
  88. if ($item['order_status'] == 1 and $item['pay_status'] == 1) {
  89. $payTeamCount += 1;
  90. }
  91. }
  92. // 如果已满员,但是存在未支付订单,团时间结束时间未到,则不处理
  93. if (($teamFound['people'] == $teamFound['join'] && $teamFound['people'] > $payTeamCount)
  94. and $teamFound['invalid_time'] >= $time) {
  95. continue;
  96. }
  97. // 判断此团的订单状态: 如果存在未支付订单则直接标记失败
  98. if (in_array(0, array_column($teamJoin, 'pay_status'))) {
  99. $this->teamFail($teamJoin, $teamFound, $time);
  100. } else {
  101. // 自动成团/拼团成功
  102. if ($is_automatic or ($teamFound['people'] == $teamFound['join'] && $teamFound['people'] == $payTeamCount)) {
  103. $this->teamSuccess($teamJoin, $teamFound, $time);
  104. } else {
  105. $this->teamFail($teamJoin, $teamFound, $time);
  106. }
  107. }
  108. }
  109. // 删除商品活动信息表的数据
  110. $goodsActivityIds = GoodsActivity::where([
  111. ['activity_type', '=', ActivityEnum::TEAM],
  112. ['activity_id', 'in', $team_ids],
  113. ])->column('id');
  114. if (count($goodsActivityIds)) {
  115. GoodsActivity::destroy($goodsActivityIds);
  116. }
  117. Db::commit();
  118. return true;
  119. } catch (Exception $e) {
  120. Db::rollback();
  121. throw new Exception($e->getMessage());
  122. }
  123. }
  124. /**
  125. * @notes 拼团成功
  126. * @param $teamJoin
  127. * @param $teamFound
  128. * @param $time
  129. * @author 张无忌
  130. * @date 2021/8/4 16:47
  131. */
  132. public function teamSuccess($teamJoin, $teamFound, $time)
  133. {
  134. // 把团标记成功
  135. TeamFound::update([
  136. 'status' => TeamEnum::TEAM_FOUND_SUCCESS,
  137. 'team_end_time' => $time,
  138. ], ['id'=>$teamFound['id']]);
  139. // 把团记录以及订单标记成功
  140. foreach ($teamJoin as $item) {
  141. // 标记拼团状态为成功
  142. TeamJoin::update([
  143. 'status' => TeamEnum::TEAM_FOUND_SUCCESS,
  144. 'update_time' => $time,
  145. 'team_end_time' => time()
  146. ], ['id' => $item['id']]);
  147. // 标记拼团订单状态成功
  148. Order::update([
  149. 'is_team_success' => 1,
  150. 'update_time' => $time
  151. ], ['id' => $item['order_id']]);
  152. }
  153. }
  154. /**
  155. * @notes 拼团失败,给已支付的订单退款
  156. * @param $teamJoin
  157. * @param $teamFound
  158. * @param $time
  159. * @throws @\think\Exception
  160. * @throws @\think\db\exception\DataNotFoundException
  161. * @throws @\think\db\exception\DbException
  162. * @throws @\think\db\exception\ModelNotFoundException
  163. * @author 张无忌
  164. * @date 2021/8/4 15:27
  165. */
  166. public function teamFail($teamJoin, $teamFound, $time)
  167. {
  168. // 把团标记失败
  169. TeamFound::update([
  170. 'status' => TeamEnum::TEAM_FOUND_FAIL,
  171. 'team_end_time' => $time,
  172. ], ['id'=>$teamFound['id']]);
  173. // 把团记录以及订单标记失败,并进行退款
  174. foreach ($teamJoin as $item) {
  175. // 1、拼团记录标记为失败
  176. TeamJoin::update([
  177. 'status' => TeamEnum::TEAM_FOUND_FAIL,
  178. 'team_end_time' => $time,
  179. 'update_time' => time()
  180. ], ['id'=>$item['id']]);
  181. // 2、订单拼团状态标记失败
  182. Order::update([
  183. 'is_team_success' => 2,
  184. 'update_time' => time()
  185. ], ['id'=>$item['order_id']]);
  186. // 获取团的订单
  187. $teamOrder = (new Order())->where(['id'=>$item['order_id']])->findOrEmpty()->toArray();
  188. // 处于已支付状态的发起整单售后
  189. if ($teamOrder['pay_status'] == PayEnum::ISPAID) {
  190. AfterSaleService::orderRefund([
  191. 'order_id' => $teamOrder['id'],
  192. 'scene' => AfterSaleLogEnum::BUYER_CANCEL_ORDER
  193. ]);
  194. }
  195. //更新订单为已关闭
  196. Order::update([
  197. 'is_team_success' => 2,
  198. 'order_status' => OrderEnum::STATUS_CLOSE,
  199. 'cancel_time' => time()
  200. ], ['id' => $teamOrder['id']]);
  201. // 订单日志
  202. (new OrderLog())->record([
  203. 'type' => OrderLogEnum::TYPE_USER,
  204. 'channel' => OrderLogEnum::USER_CANCEL_ORDER,
  205. 'order_id' => $teamOrder['id'],
  206. 'operator_id' => $teamOrder['user_id'],
  207. ]);
  208. }
  209. }
  210. }