GroupBuyPay.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. <?php
  2. namespace app\api\model\order;
  3. use app\api\model\member\GoldRice as GoldRiceModel;
  4. use app\common\service\Order;
  5. use app\api\model\Order as CheckOrder;
  6. use app\common\enum\OrderType as OrderTypeEnum;
  7. use app\api\model\User as UserModel;
  8. use app\api\model\groupbuy\GroupBuyJoin;
  9. use app\api\model\groupbuy\GroupBuyHelp;
  10. use app\api\model\groupbuy\GroupBuyGoods;
  11. use app\common\model\Order as OrderModel;
  12. use app\common\model\OrderGoods as OrderGoodsModel;
  13. use app\common\enum\order\OrderSource as OrderSourceEnum;
  14. use app\common\enum\order\PayStatus as PayStatusEnum;
  15. use app\common\enum\order\OrderStatus as OrderStatusEnum;
  16. use app\common\enum\order\DeliveryType as DeliveryTypeEnum;
  17. use app\api\model\Goods as GoodsModel;
  18. use app\api\model\GoodsSku as GoodsSkuModel;
  19. use app\common\enum\order\PayType as OrderPayTypeEnum;
  20. use app\common\library\helper;
  21. use app\common\model\OrderAddress as OrderAddressModel;
  22. use app\common\service\goods\source\Factory as StockFactory;
  23. use think\facade\Db;
  24. use app\api\model\card\UserRiceCard as UserRiceCardModel;
  25. use app\api\model\card\UserRiceCardConsume as UserRiceCardConsumeModel;
  26. use app\api\model\subscribe\WechatSub;
  27. use app\common\service\commission\RecordWaitCommission;
  28. class GroupBuyPay implements IOrder {
  29. private $error = '';
  30. public function getError(){
  31. return $this->error;
  32. }
  33. public function prePay($args){
  34. }
  35. //重新支付
  36. public function repay($args){
  37. }
  38. //回调逻辑处理
  39. public function notifyPay($pay_data){
  40. $order_no = $pay_data['out_trade_no'];
  41. $model = GroupBuyHelp::getPayDetail($order_no);
  42. if(empty($model)){
  43. return false;
  44. }
  45. //已支付
  46. if($model['pay_state']==1){
  47. return false;
  48. }
  49. $user = UserModel::detail($model['user_id']);
  50. // Db::startTrans();
  51. $res = $model->transaction(function () use ($model,$pay_data,$user) {
  52. $model->save([
  53. 'pay_state'=> 1,
  54. 'pay_time' => time(),
  55. 'transaction_id'=>$pay_data['transaction_id']??''
  56. ]
  57. );
  58. //写入金米粒记录
  59. $this->writeUserGoldRice($model);
  60. $this->writeUserRiceCard($model);//写入金米粒逻辑
  61. $join = GroupBuyJoin::where('id',$model['join_id'])->find();
  62. $join->help_count += 1; // 拼团人数+1
  63. $flag = false;
  64. //拼团人数够了
  65. if($join->help_count==$join->people_count){
  66. $flag = true;
  67. }
  68. $join->save();
  69. if($flag){ //成功了话写真实订单
  70. $this->ptSuccessNotify($join->id);
  71. }
  72. });
  73. $groupgoods = GroupBuyGoods::where('group_buy_activity_id',$model['group_buy_activity_id'])->find();//拼团付款成功后加销量
  74. if($groupgoods){
  75. StockFactory::getFactory(OrderSourceEnum::GROUPBUY)->updateStockSalesExpress($groupgoods->goods_id,$model['goods_num']);
  76. }
  77. // Db::commit();
  78. return $res;
  79. }
  80. /**
  81. * 写入金米粒记录
  82. * @param int $payType
  83. * @return false|int
  84. * @throws \Exception
  85. */
  86. private function writeUserGoldRice($model)
  87. {
  88. if($model['gold_rice_amount']>0){
  89. //写金米粒出账记录
  90. GoldRiceModel::add($model['user_id'],$model['order_no'],'下单抵扣',$model['gold_rice_amount'],0);
  91. //扣除冻结中的金米粒
  92. UserModel::setDecByField($model['user_id'],'gold_rice_frozen',(float)$model['gold_rice_amount']);
  93. }
  94. }
  95. /**
  96. * 写入米卡记录
  97. * @param int $payType
  98. * @return false|int
  99. * @throws \Exception
  100. */
  101. private function writeUserRiceCard($help){
  102. if($help['rice_card_id']>0){
  103. //写现金卡出账记录
  104. $userRiceCard = UserRiceCardModel::find($help['rice_card_id']);
  105. UserRiceCardConsumeModel::add($userRiceCard,$help['order_no'],$help['pay_money'],$help['rice_card_money']);
  106. //如果可用余额为0并且冻结余额等于要抵扣的金额
  107. if($userRiceCard['balance']==0 && $help['rice_card_money']==$userRiceCard['frozen_amount']){
  108. //现金卡直接减冻结余额,并且状态改为已失效
  109. UserRiceCardModel::setIncDecByField($help['rice_card_id'],[],['frozen_amount'=>(float)$help['rice_card_money']],['effect_state'=>2]);
  110. }else{
  111. //现金卡直接减冻结余额
  112. UserRiceCardModel::setDecByField($help['rice_card_id'],'frozen_amount',(float)$help['rice_card_money']);
  113. }
  114. }
  115. }
  116. //拼团成功,写入订单逻辑
  117. public function ptSuccessNotify(int $join_id){
  118. $join = GroupBuyJoin::where('id',$join_id)->find();
  119. // $help = GroupBuyHelp::where('id',$help_id)->find();
  120. //假的订单 order_id = -1
  121. if($join->status==0&&$join->help_count==$join->people_count){
  122. $helpList = GroupBuyHelp::where('join_id',$join_id)->where('fans',0)->where('order_id',0)->where('pay_state',1)->select();
  123. foreach($helpList as $help){
  124. $order_id = $this->add($help,'');
  125. GroupBuyHelp::where('order_id',0)->where('id',$help['id'])->update(['order_id'=>$order_id]);
  126. }
  127. }
  128. $join->status = 1;
  129. $join->success_time = Date("Y-m-d H:i:s",time());
  130. $join->save();
  131. $this->activityEnd($join->user_id,$join->id);
  132. }
  133. //测试
  134. public function test(){
  135. $help = GroupBuyHelp::where('id',100)->find();
  136. $this->add($help,'');
  137. }
  138. //下单并发起拼团,拼团成功后发送
  139. public function activityEnd($user_id,$join_id){
  140. $template_type = 'normal_xia_dan_faqi_tuan';//
  141. $sub = new WechatSub($template_type);
  142. $page = 'pages/activity/pages/groupShopping/groupShopping/groupShopping?shareId='.$join_id;
  143. $data = ['thing2'=>["value"=>"拼团活动"],'thing3'=>["value"=>'活动已结束,去看看活动结果']];
  144. $sub->pushSub($user_id,$page,$data);
  145. $this->helpEnd($join_id);
  146. }
  147. //团员结束
  148. public function helpEnd($join_id){
  149. $user_id_arr = GroupBuyHelp::where("join_id",$join_id)->column('user_id');
  150. $template_type = 'normal_li_ji_can_tuan'; //normal_xia_dan_faqi_tuan
  151. $sub = new WechatSub($template_type);
  152. $page = 'pages/activity/pages/groupShopping/groupShopping/groupShopping?shareId='.$join_id;
  153. $data =['thing1'=>["value"=>"拼团活动"],'thing3'=>["value"=>'活动已结束,去看看活动结果']];
  154. foreach($user_id_arr as $user_id){
  155. $res = $sub->pushSub($user_id,$page,$data);
  156. // var_dump($res);
  157. }
  158. }
  159. /**
  160. * 新增订单记录
  161. * @param $order
  162. * @param string $remark
  163. * @return false|int
  164. */
  165. public function add($help, $remark = ''){
  166. $groupgoods = GroupBuyGoods::where('group_buy_activity_id',$help['group_buy_activity_id'])->find();
  167. $goods_id = $groupgoods->goods_id;
  168. $group_price = $groupgoods->group_price;
  169. $goodsSkuId = $groupgoods->goods_sku_id;
  170. $goodsNum = $help['goods_num'];
  171. $model = new GoodsModel;
  172. $goodsList = $model->getListByIdsFromApi([$goods_id]);
  173. // 隐藏冗余的属性
  174. $goodsList->hidden(array_merge($model->hidden, ['content', 'goods_images', 'images']));
  175. //返回商品处理
  176. foreach ($goodsList as &$item) {
  177. // 商品sku信息
  178. $item['skuInfo'] = GoodsSkuModel::detail($item['goods_id'], $goodsSkuId);
  179. // 商品单价
  180. $item['goods_price'] = $item['skuInfo']['goods_price'];
  181. // 商品购买数量
  182. $item['total_num'] = $goodsNum;
  183. // 商品SKU索引
  184. $item['goods_sku_id'] = $item['skuInfo']['goods_sku_id'];
  185. // 商品购买总金额
  186. $item['total_price'] = helper::bcmul($item['goods_price'], $goodsNum);
  187. // 获取最终拼团单价金额
  188. $item['group_price'] = $groupgoods['group_price'];
  189. }
  190. $groupbuy_money = helper::bcsub($goodsList[0]['total_price'],$goodsList[0]['group_price']*$goodsNum);
  191. if($groupbuy_money<0){
  192. $groupbuy_money = 0;
  193. }
  194. // 订单数据
  195. $data = [
  196. 'user_id' => $help['user_id'],
  197. 'order_no' => $help['order_no'],
  198. 'total_price' => $goodsList[0]['total_price'],//商品原总价,不包含折扣
  199. 'order_price' => $help['order_money'],//订单优惠完金额 商品优惠完金额+运费
  200. 'pay_price' => $help['pay_money'], //微信支付金额
  201. 'delivery_type' => DeliveryTypeEnum::EXPRESS,
  202. 'pay_type' => $help['pay_money'] > 0 ? OrderPayTypeEnum::WECHAT : OrderPayTypeEnum::MICAH_EXCHANGE,
  203. 'buyer_remark' => trim($remark),
  204. 'order_source' => OrderSourceEnum::GROUPBUY,
  205. 'order_source_id' => $help['id'],
  206. 'groupbuy_money' =>$groupbuy_money,
  207. 'order_status' => OrderStatusEnum::NORMAL,
  208. 'store_id' => 10001,
  209. 'provider_ids' => $help['provider_ids']??0,
  210. 'distributor_total_money' => 0,
  211. 'gold_rice_amount' => $help['gold_rice_amount']??0,
  212. 'gold_rice_money' => $help['gold_rice_money']??0,
  213. 'rice_card_id' => $help['rice_card_id']??0,
  214. 'rice_card_money' => $help['rice_card_money']??0,
  215. 'rice_card_express_money' => $help['rice_card_express_money']??0,
  216. 'pay_status' => PayStatusEnum::SUCCESS,
  217. 'pay_time' => time(),
  218. 'invoice_deadline'=> time() + OrderModel::getInvoiceDeadline() * 60,
  219. 'express_price'=> $help['express_money'],
  220. 'transaction_id'=>$help['transaction_id'],
  221. 'promotion_monitor_id'=>$help['promotion_monitor_id'],
  222. 'staff_user_id' => $help['staff_user_id']?? 0,
  223. 'staff_shop_id' => $help['staff_shop_id']?? 0
  224. ];
  225. // 保存订单记录
  226. $orderModel = new OrderModel;
  227. $orderModel->save($data);
  228. $order_id = $orderModel->order_id;
  229. $newGoodsList = [];
  230. foreach ($goodsList as $key=>$goods) {
  231. $total_pay_price = helper::bcsub
  232. ($help['pay_money'],$help['express_money']) > 0 ? helper::bcsub($help['pay_money'],$help['express_money']):0;
  233. $item = [
  234. 'order_id'=>$order_id,
  235. 'user_id' => $help['user_id'],
  236. 'store_id' => 10001,
  237. 'goods_id' => $goods['goods_id'],
  238. 'goods_name' => $goods['goods_name'],
  239. 'goods_no' => $goods['goods_no'] ?: '',
  240. 'image_id' => (int)current($goods['goods_images'])['file_id'],
  241. 'deduct_stock_type' => $goods['deduct_stock_type'],
  242. 'spec_type' => $goods['spec_type'],
  243. 'goods_sku_id' => $goods['skuInfo']['goods_sku_id'],
  244. 'goods_props' => $goods['skuInfo']['goods_props'] ?: '',
  245. 'content' => $goods['content'] ?? '',
  246. 'goods_sku_no' => $goods['skuInfo']['goods_sku_no'] ?: '',
  247. 'goods_price' => $goods['skuInfo']['goods_price'],
  248. 'specs' => $goods['skuInfo']['specs'],
  249. 'supplier' => $goods['supplier'],
  250. 'line_price' => $goods['skuInfo']['line_price'],
  251. 'goods_weight' => $goods['skuInfo']['goods_weight'],
  252. 'is_user_grade' => (int)$goods['is_user_grade'],
  253. 'grade_ratio' => $goods['grade_ratio']??0,
  254. 'grade_goods_price' => $goods['grade_goods_price']??0,
  255. 'grade_total_money' => $goods['grade_total_money']??0,
  256. 'coupon_id' => $goods['coupon_id']??0,
  257. 'coupon_money' => $goods['coupon_money']??0,
  258. 'points_bonus' => $goods['points_bonus']??0,
  259. 'total_num' => $goods['total_num'],
  260. 'total_price' => $goods['total_price'],
  261. 'total_pay_price' => $total_pay_price,
  262. 'provider_id' => $goods['provider_id'],
  263. 'brand' => $goods['brand'],
  264. 'province_id' => $goods['province_id'],
  265. 'city_id' => $goods['city_id'],
  266. 'storage' => $goods['storage'],
  267. 'unit' => $goods['unit'],
  268. 'clearing_price' => $goods['skuInfo']['clearing_price']??'0.00',
  269. 'platform_rate' => $goods['skuInfo']['platform_rate']??'0.00',
  270. 'staff_user_id' => $goods['staffUserId'],
  271. 'shop_id' => $goods['shopId'],
  272. 'distributor_radio' => $goods['distributor_radio']??0,
  273. 'distributor_goods_price' => $goods['distributor_goods_price']??0,
  274. 'distributor_total_money' => $goods['distributor_total_money']??0,
  275. 'gold_rice_amount' => $help['gold_rice_amount']??0,
  276. 'gold_rice_money' => $help['gold_rice_money']??0,
  277. 'rice_card_id' => $help['rice_card_id']??0,
  278. 'group_buy_id' => $help['group_buy_activity_id']??0,
  279. 'goods_type' => $goods['goods_type']??10,
  280. 'shop_id'=>0,
  281. 'rice_card_money'=>$help['good_rice_card_money']
  282. ];
  283. $newGoodsList[] = $item;
  284. }
  285. $orderGoodModel = new OrderGoodsModel;
  286. $orderGoodModel->saveAll($newGoodsList);
  287. $address = [
  288. 'order_id'=>$order_id,
  289. 'user_id' => $help['user_id'],
  290. 'store_id' =>10001,
  291. 'name' => $help['user_name'],
  292. 'phone' => $help['phone'],
  293. 'province_id' => $help['province_id'],
  294. 'city_id' => $help['city_id'],
  295. 'region_id' => $help['region_id'],
  296. 'detail' => $help['detail']
  297. ];
  298. $orderAddressModel = new OrderAddressModel;
  299. $orderAddressModel->save($address);
  300. // $order['goodsList'] = $goodsList;
  301. // $order['goods'] = $goodsList;
  302. // $order['delivery'] = DeliveryTypeEnum::EXPRESS;
  303. // $order['delivery_type'] = DeliveryTypeEnum::EXPRESS;
  304. // StockFactory::getFactory(OrderSourceEnum::GROUPBUY)->updateGoodsStock($order);
  305. // StockFactory::getFactory(OrderSourceEnum::GROUPBUY)->updateStockSales($order);
  306. //待结算佣金计算
  307. $RecordWaitCommission = new RecordWaitCommission;
  308. //分销记录放入队列
  309. $RecordWaitCommission->recordWaitCommission($order_id);
  310. return $order_id;
  311. }
  312. /**
  313. * 记录收货地址
  314. * @param $address
  315. * @return false|\think\Model
  316. */
  317. private function saveOrderAddress($address)
  318. {
  319. return $this->model->address()->save();
  320. }
  321. }