TeamLogic.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  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\shopapi\logic;
  20. use app\common\enum\AfterSaleLogEnum;
  21. use app\common\enum\OrderEnum;
  22. use app\common\enum\OrderLogEnum;
  23. use app\common\enum\PayEnum;
  24. use app\common\enum\TeamEnum;
  25. use app\common\model\Goods;
  26. use app\common\model\GoodsItem;
  27. use app\common\model\GoodsServiceGuarantee;
  28. use app\common\model\Order;
  29. use app\common\model\OrderGoods;
  30. use app\common\model\OrderLog;
  31. use app\common\model\TeamActivity;
  32. use app\common\model\TeamFound;
  33. use app\common\model\TeamGoods;
  34. use app\common\model\TeamGoodsItem;
  35. use app\common\model\TeamJoin;
  36. use app\common\model\User;
  37. use app\common\model\UserAddress;
  38. use app\common\service\after_sale\AfterSaleService;
  39. use app\common\service\ConfigService;
  40. use app\common\service\FileService;
  41. use app\shopapi\service\CouponService;
  42. use Exception;
  43. use think\facade\Db;
  44. class TeamLogic
  45. {
  46. /**
  47. * @notes 拼团商品详细
  48. * @param $id
  49. * @return array|string
  50. * @author 张无忌
  51. * @date 2021/8/3 15:53
  52. */
  53. public static function detail($id, $userId)
  54. {
  55. try {
  56. // 查询校验商品获取活动
  57. $teamGoods = (new TeamGoods())->alias('TG')
  58. ->field(['TG.*,TA.name,TA.people_num,TA.min_buy,TA.max_buy,TG.min_team_price',
  59. 'TA.is_coupon,TA.is_distribution,TA.start_time,TA.end_time,TG.browse_volume,TG.virtual_sales_num,TG.virtual_click_num'])
  60. ->join('team_activity TA', 'TA.id = TG.team_id')
  61. ->where('TA.start_time', '<=', time())
  62. ->where('TA.end_time', '>=', time())
  63. ->where('TA.status', '>=', TeamEnum::TEAM_STATUS_CONDUCT)
  64. ->findOrEmpty($id)->toArray();
  65. if (!$teamGoods) {
  66. throw new Exception('当前拼团活动已结束');
  67. }
  68. // 查询活动商品的规格
  69. $teamGoodsItem = (new TeamGoodsItem())->withoutField('item_snap')
  70. ->where('team_id', '=', $teamGoods['team_id'])
  71. ->where('team_gid', '=', $teamGoods['id'])
  72. ->select()->toArray();
  73. // 查询基础商品信息
  74. $goods = (new Goods())
  75. ->field([
  76. 'id,name,code,image,video,video_cover,min_price,
  77. min_lineation_price,total_stock,sales_num,spec_type,content,unit_id,express_type,express_money,express_template_id,type,service_guarantee_ids'
  78. ])->with(['spec_value.spec_list', 'spec_value_list'])
  79. ->append(['goods_image'])
  80. ->findOrEmpty($teamGoods['goods_id']);
  81. $stockShow = ConfigService::get('goods_set', 'is_show', 0);
  82. $goods['stock_show'] = $stockShow ? true : false;
  83. // 替换基础商品信息
  84. foreach ($goods['spec_value_list'] as &$item) {
  85. $item['image'] = $item['image'] ? $item['image'] : $goods['image'];
  86. foreach ($teamGoodsItem as $value) {
  87. if ($item['goods_id'] == $value['goods_id']
  88. and $item['id'] == $value['item_id'])
  89. {
  90. $item['cost_price'] = $value['sell_price'];
  91. $item['sell_price'] = $value['team_price'];
  92. unset($value);
  93. }
  94. }
  95. }
  96. $goods['unit_name'] = '';
  97. if($goods['unit_id']){
  98. $goods['unit_name'] = $goods->unit->name;
  99. }
  100. // 商品信息上扩展活动信息
  101. $goods['activity'] = [
  102. 'id' => $teamGoods['team_id'],
  103. 'name' => $teamGoods['name'],
  104. 'people_num' => $teamGoods['people_num'],
  105. 'min_buy' => $teamGoods['min_buy'],
  106. 'max_buy' => $teamGoods['max_buy'],
  107. 'min_team_price' => $teamGoods['min_team_price'],
  108. 'is_coupon' => $teamGoods['is_coupon'],
  109. 'is_distribution' => $teamGoods['is_distribution'],
  110. 'start_time' => $teamGoods['start_time'],
  111. 'end_time' => $teamGoods['end_time'],
  112. 'surplus_time' => $teamGoods['end_time'] - time(),
  113. 'browse_volume' => $teamGoods['browse_volume'] + $teamGoods['virtual_click_num']
  114. ];
  115. //销量
  116. $goods['sales_num'] = (new TeamGoodsItem())->where(['team_gid'=>$teamGoods['id']])->sum('sales_volume') + $teamGoods['virtual_sales_num'];
  117. // 获取正在进行中的团
  118. $teamFound = (new TeamFound())->alias('TF')
  119. ->field(['TF.*', 'U.nickname,U.avatar'])
  120. ->limit(8)
  121. ->order('id desc')
  122. ->where('TF.team_id', '=', $teamGoods['team_id'])
  123. ->where('TF.people','exp',' > TF.join ')
  124. ->where([
  125. ['status', '=', 0],
  126. ['invalid_time', '>=', time()]
  127. ])->join('user U', 'U.id=TF.user_id')
  128. ->select()->toArray();
  129. foreach ($teamFound as &$found) {
  130. unset($found['shop_id']);
  131. unset($found['team_sn']);
  132. unset($found['goods_snap']);
  133. unset($found['team_end_time']);
  134. $found['avatar'] = FileService::getFileUrl($found['avatar']);
  135. $found['surplus_time'] = intval($found['invalid_time'] - time());
  136. }
  137. $goods['found'] = $teamFound;
  138. //商品评价
  139. $goods['goods_comment'] = GoodsLogic::getComment($goods['id']);
  140. // 地址
  141. $address_id = input('address_id/d', 0);
  142. $address = $address_id ? UserAddress::getAddressById($userId, $address_id) : UserAddress::getDefaultAddress($userId);
  143. if ($address) {
  144. $goods->address = $address;
  145. }
  146. // 服务保障
  147. $goods->service_guarantee = GoodsServiceGuarantee::getApiList($goods->service_guarantee_ids);
  148. // 包邮信息
  149. if ($goods['express_type'] == 1) {
  150. $goods['free_shipping_tips'] = '免运费';
  151. } else {
  152. $goods['free_shipping_tips'] = GoodsLogic::getFreeShippingTips($userId, $goods);
  153. }
  154. // 记录浏览数
  155. TeamGoods::update(['browse_volume'=>['inc', 1]], ['id'=>$id]);
  156. return $goods->hidden(['unit','unit_id'])->toArray();
  157. } catch (Exception $e) {
  158. return $e->getMessage();
  159. }
  160. }
  161. /**
  162. * @notes 验证团是否成功(支付回调时调用)
  163. * @param $found_id
  164. * @author 张无忌
  165. * @date 2021/8/4 11:56
  166. */
  167. public static function checkTeamSuccess($found_id)
  168. {
  169. Db::startTrans();
  170. try {
  171. $time = time();
  172. $teamFound = (new TeamFound())->findOrEmpty($found_id)->toArray();
  173. if ($teamFound['people'] == $teamFound['join']) {
  174. // 获取参团记录数据
  175. $teamJoin = (new TeamJoin())->alias('TJ')
  176. ->field('TJ.*,O.order_status,O.pay_status')
  177. ->join('order O', 'O.id = TJ.order_id')
  178. ->where(['TJ.found_id' => $found_id])
  179. ->select()->toArray();
  180. // 获取参团已支付数量
  181. $payTeamCount = 0;
  182. foreach ($teamJoin as $item) {
  183. if ($item['order_status'] == 1 and $item['pay_status'] == 1) {
  184. $payTeamCount += 1;
  185. }
  186. }
  187. // 满足条件: 拼团成功
  188. if ($payTeamCount == $teamFound['people']) {
  189. TeamFound::update([
  190. 'status' => TeamEnum::TEAM_FOUND_SUCCESS,
  191. 'team_end_time' => $time
  192. ], ['id' => $found_id]);
  193. foreach ($teamJoin as $item) {
  194. // 标记拼团状态为成功
  195. TeamJoin::update([
  196. 'status' => TeamEnum::TEAM_FOUND_SUCCESS,
  197. 'team_end_time' => time(),
  198. 'update_time' => $time
  199. ], ['id' => $item['id']]);
  200. // 标记拼团订单状态成功
  201. Order::update([
  202. 'is_team_success' => 1,
  203. 'update_time' => $time
  204. ], ['id' => $item['order_id']]);
  205. }
  206. }
  207. }
  208. Db::commit();
  209. } catch (Exception $e) {
  210. Db::rollback();
  211. }
  212. }
  213. /**
  214. * @notes 标记失败团
  215. * @param $order_id
  216. * @return bool
  217. * @throws @\think\db\exception\DataNotFoundException
  218. * @throws @\think\db\exception\DbException
  219. * @throws @\think\db\exception\ModelNotFoundException
  220. * @author 张无忌
  221. * @date 2021/10/12 15:52
  222. */
  223. public static function signFailTeam($order_id)
  224. {
  225. // 获取拼团订单信息
  226. $order = (new Order())->where(['id'=>$order_id])->findOrEmpty()->toArray();
  227. if ($order['order_type'] != OrderEnum::TEAM_ORDER) {
  228. return false;
  229. }
  230. // 获取开团信息
  231. $teamFound = (new TeamFound())->where(['id'=>$order['team_found_id']])->findOrEmpty()->toArray();
  232. // 如果团不是成功的团,则结束团,并且退款, 否则是成功的团,只给当前订单退款
  233. if ($teamFound['status'] != TeamEnum::TEAM_FOUND_SUCCESS) {
  234. // 结束拼团标记失败
  235. TeamFound::update(['status' => TeamEnum::TEAM_FOUND_FAIL, 'team_end_time' => time()], ['id' => $order['team_found_id']]);
  236. // 参团的人标记失败
  237. $teamJoin = (new TeamJoin())->where(['found_id' => $teamFound['id']])->select()->toArray();
  238. foreach ($teamJoin as $item) {
  239. // 标记参团失败
  240. TeamJoin::update([
  241. 'status' => TeamEnum::TEAM_FOUND_FAIL,
  242. 'team_end_time' => time()
  243. ], ['id' => $item['id']]);
  244. // 获取团的订单
  245. $teamOrder = (new Order())->where(['id' => $item['order_id']])->findOrEmpty()->toArray();
  246. // 处于已支付状态的发起整单售后
  247. if ($teamOrder['pay_status'] == PayEnum::ISPAID) {
  248. AfterSaleService::orderRefund([
  249. 'order_id' => $teamOrder['id'],
  250. 'scene' => AfterSaleLogEnum::BUYER_CANCEL_ORDER
  251. ]);
  252. }
  253. //更新订单为已关闭
  254. Order::update([
  255. 'is_team_success' => 2,
  256. 'order_status' => OrderEnum::STATUS_CLOSE,
  257. 'cancel_time' => time()
  258. ], ['id' => $teamOrder['id']]);
  259. // 订单日志
  260. (new OrderLog())->record([
  261. 'type' => OrderLogEnum::TYPE_USER,
  262. 'channel' => OrderLogEnum::USER_CANCEL_ORDER,
  263. 'order_id' => $teamOrder['id'],
  264. 'operator_id' => $teamOrder['user_id'],
  265. ]);
  266. }
  267. } else {
  268. // 处于已支付状态的发起整单售后
  269. if ($order['pay_status'] == PayEnum::ISPAID) {
  270. AfterSaleService::orderRefund([
  271. 'order_id' => $order['id'],
  272. 'scene' => AfterSaleLogEnum::BUYER_CANCEL_ORDER
  273. ]);
  274. }
  275. //更新订单为已关闭
  276. Order::update([
  277. 'is_team_success' => 2,
  278. 'order_status' => OrderEnum::STATUS_CLOSE,
  279. 'cancel_time' => time()
  280. ], ['id' => $order['id']]);
  281. // 订单日志
  282. (new OrderLog())->record([
  283. 'type' => OrderLogEnum::TYPE_USER,
  284. 'channel' => OrderLogEnum::USER_CANCEL_ORDER,
  285. 'order_id' => $order['id'],
  286. 'operator_id' => $order['user_id'],
  287. ]);
  288. }
  289. return true;
  290. }
  291. }