GroupBuyLbPay.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. <?php
  2. namespace app\api\model\order;
  3. use app\common\service\Order;
  4. use app\api\model\Order as CheckOrder;
  5. use app\common\enum\OrderType as OrderTypeEnum;
  6. use app\api\model\User as UserModel;
  7. use app\api\model\groupbuylb\GroupBuyLbJoin;
  8. use app\api\model\groupbuylb\GroupBuyLbHelp;
  9. use app\api\model\groupbuylb\GroupBuyLbGoods;
  10. use app\common\model\Order as OrderModel;
  11. use app\common\model\OrderGoods as OrderGoodsModel;
  12. use app\common\enum\order\OrderSource as OrderSourceEnum;
  13. use app\common\enum\order\PayStatus as PayStatusEnum;
  14. use app\common\enum\order\OrderStatus as OrderStatusEnum;
  15. use app\common\enum\order\DeliveryType as DeliveryTypeEnum;
  16. use app\api\model\Goods as GoodsModel;
  17. use app\api\model\GoodsSku as GoodsSkuModel;
  18. use app\common\enum\order\PayType as OrderPayTypeEnum;
  19. use app\common\library\helper;
  20. use app\common\model\OrderAddress as OrderAddressModel;
  21. use app\common\service\goods\source\Factory as StockFactory;
  22. use think\facade\Db;
  23. use app\api\model\card\UserRiceCard as UserRiceCardModel;
  24. use app\api\model\card\UserRiceCardConsume as UserRiceCardConsumeModel;
  25. use app\common\model\groupbuylb\GroupBuyLbCoupon as GroupBuyLbCouponModel;
  26. use app\common\model\Coupon;
  27. use app\api\model\UserCoupon;
  28. use app\common\model\Wechat;
  29. use think\cache\driver\Redis;
  30. use app\common\model\PushLog;
  31. class GroupBuyLbPay implements IOrder {
  32. private $error = '';
  33. public function getError(){
  34. return $this->error;
  35. }
  36. public function prePay($args){
  37. }
  38. //重新支付
  39. public function repay($args){
  40. }
  41. //回调逻辑处理
  42. public function notifyPay($pay_data){
  43. $order_no = $pay_data['out_trade_no'];
  44. $model = GroupBuyLbHelp::getPayDetail($order_no);
  45. if(empty($model)){
  46. return false;
  47. }
  48. //已支付
  49. if($model['pay_state']==1){
  50. return false;
  51. }
  52. $user = UserModel::detail($model['user_id']);
  53. // Db::startTrans();
  54. $res = $model->transaction(function () use ($model,$pay_data,$user) {
  55. $model->save([
  56. 'pay_state'=> 1,
  57. 'pay_time' => time(),
  58. 'transaction_id'=>$pay_data['transaction_id']??''
  59. ]
  60. );
  61. $this->writeUserRiceCard($model);
  62. $join = GroupBuyLbJoin::where('id',$model['join_id'])->find();
  63. $join->help_count += 1; // 拼团人数+1
  64. $flag = false;
  65. //拼团人数够了
  66. if($join->help_count==$join->people_count){
  67. $flag = true;
  68. }
  69. $join->save();
  70. if($flag){ //成功了话写真实订单
  71. $this->ptSuccessNotify($join->id);
  72. }
  73. if($model['user_id']!=$join->user_id){
  74. $mobile = UserModel::where("user_id",$model['user_id'])->value("mobile")??'';
  75. $content ='恭喜您参与公明腊肠拼团,成功后给您安排发货。现在您可点击成为新团长,无需支付费用即可组织拼团,成团后享受平台奖励78元现金券。';
  76. PushLog::addSmsMon($content,$mobile,1);
  77. }
  78. });
  79. //发放优惠
  80. $join = GroupBuyLbJoin::where('id',$model['join_id'])->find();
  81. if($join->status==1 && $join->user_id>0){
  82. $this->receiveCoupon($join->user_id,$join->group_buy_lb_activity_id);
  83. }
  84. $groupgoods = GroupBuyLbGoods::where('group_buy_lb_activity_id',$model['group_buy_lb_activity_id'])->find();//拼团付款成功后加销量
  85. if($groupgoods){
  86. StockFactory::getFactory(OrderSourceEnum::GROUPBUYLB)->updateStockSalesExpress($groupgoods->goods_id,$model['goods_num']);
  87. }
  88. // Db::commit();
  89. return $res;
  90. }
  91. /**
  92. * 写入米卡记录
  93. * @param int $payType
  94. * @return false|int
  95. * @throws \Exception
  96. */
  97. private function writeUserRiceCard($help){
  98. if($help['rice_card_id']>0){
  99. //写现金卡出账记录
  100. $userRiceCard = UserRiceCardModel::find($help['rice_card_id']);
  101. UserRiceCardConsumeModel::add($userRiceCard,$help['order_no'],$help['pay_money'],$help['rice_card_money']);
  102. //如果可用余额为0并且冻结余额等于要抵扣的金额
  103. if($userRiceCard['balance']==0 && $help['rice_card_money']==$userRiceCard['frozen_amount']){
  104. //现金卡直接减冻结余额,并且状态改为已失效
  105. UserRiceCardModel::setIncDecByField($help['rice_card_id'],[],['frozen_amount'=>(float)$help['rice_card_money']],['effect_state'=>2]);
  106. }else{
  107. //现金卡直接减冻结余额
  108. UserRiceCardModel::setDecByField($help['rice_card_id'],'frozen_amount',(float)$help['rice_card_money']);
  109. }
  110. }
  111. }
  112. //拼团领券
  113. public function receiveCoupon($user_id,$activity_id){
  114. $couponArray = GroupBuyLbCouponModel::where('group_buy_lb_activity_id',$activity_id)->column("coupon_id");
  115. if(isset($couponArray)){
  116. $param[] = ['coupon_id','in',$couponArray];
  117. $avaiableCoupon = (new Coupon)->getCouponGroupBuyLblist($param);
  118. if(isset($avaiableCoupon)){
  119. foreach($avaiableCoupon as $row){
  120. $coupon_id = $row['coupon_id'];
  121. $userCoupon = new UserCoupon;
  122. $userCoupon->userreceive($coupon_id,$user_id);
  123. }
  124. }
  125. }
  126. }
  127. //拼团成功,写入订单逻辑
  128. public function ptSuccessNotify(int $join_id){
  129. $join = GroupBuyLbJoin::where('id',$join_id)->find();
  130. // $help = GroupBuyHelp::where('id',$help_id)->find();
  131. //假的订单 order_id = -1
  132. if($join->status==0&&$join->help_count==$join->people_count){
  133. //虚拟团不写订单,记得这个条件is_virtual_join_user=0
  134. $helpList = GroupBuyLbHelp::where('join_id',$join_id)->where('order_id',0)
  135. ->where('fans',0)
  136. ->where('pay_state',1)->where('is_virtual_join_user',0)->select();
  137. foreach($helpList as $help){
  138. $order_id = $this->add($help,'');
  139. GroupBuyLbHelp::where('order_id',0)->where('id',$help['id'])->update(['order_id'=>$order_id]);
  140. }
  141. }
  142. $join->status = 1;
  143. $join->success_time = Date("Y-m-d H:i:s",time());
  144. $join->save();
  145. //通知
  146. if($join->is_virtual==0){
  147. $this->activityEnd($join->user_id,$join->id);
  148. }else{
  149. $this->virtualActivityEnd($join->user_id,$join->id);
  150. }
  151. }
  152. //检查有没有订阅
  153. public function checkSub($open_id,$template_id){
  154. $key ='subscribe:open_id:'.$open_id.'template_id:'.$template_id;
  155. $rds = new Redis(config('cache.stores.redis'));
  156. $value = $rds->get($key);
  157. if($value=="1"){
  158. return true;
  159. }
  160. return false;
  161. }
  162. //下单并发起拼团,拼团成功后发送
  163. public function activityEnd($user_id,$join_id){
  164. $openid = UserModel::where('user_id',$user_id)->value('open_id');
  165. $template_id = 'M4Nw40B4Hpn4C8NkCiBDajEqz1St_CRRjGlkxDOVP1g';
  166. $weixinToken = (new Wechat)->weixinTokenCache();
  167. $accessToken = $weixinToken['access_token'];
  168. $url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" . $accessToken;
  169. $data['touser']= $openid;
  170. $data['template_id'] = $template_id;
  171. $data['page'] = 'pages/activity/pages/groupShopping/groupFission/groupFission?shareId='.$join_id;
  172. $data['miniprogram_state'] = env('APP_ENV')=="production"?'formal':'trial';
  173. $data['data']= ['thing1'=>["value"=>"拼团有礼"],'thing3'=>["value"=>'活动已结束,去看看活动结果']];
  174. if($this->checkSub($openid,$template_id)){
  175. post_curl($url,json_encode($data));
  176. }
  177. $this->helpEnd($join_id);
  178. }
  179. //虚拟团,拼团成功后发送
  180. public function virtualActivityEnd($user_id,$join_id){
  181. $openid = UserModel::where('user_id',$user_id)->value('open_id');
  182. $template_id = 'VG3VUaZKE4NkhSt9rn7xFhYlAjtopXACI1Y7HbIOf28';
  183. $weixinToken = (new Wechat)->weixinTokenCache();
  184. $accessToken = $weixinToken['access_token'];
  185. $url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" . $accessToken;
  186. $data['touser']= $openid;
  187. $data['template_id'] = $template_id;
  188. $data['page'] = 'pages/activity/pages/groupShopping/groupFission/groupFission?shareId='.$join_id;
  189. $data['miniprogram_state'] = env('APP_ENV')=="production"?'formal':'trial';
  190. $data['data']= ['thing2'=>["value"=>"拼团有礼"],'thing6'=>["value"=>'活动已结束,去看看活动结果']];
  191. if($this->checkSub($openid,$template_id)){
  192. post_curl($url,json_encode($data));
  193. }
  194. $this->helpEnd($join_id);
  195. }
  196. //团员结束
  197. public function helpEnd($join_id){
  198. $user_id_arr = GroupBuyLbHelp::where("join_id",$join_id)->column('user_id');
  199. $open_id_arr = UserModel::where("user_id",'in',$user_id_arr)->column("open_id");
  200. $template_id = 'AgOUjZCUMRo0hwPgLrVSwztkrPys3FAq9OgL4waBaCI';
  201. $weixinToken = (new Wechat)->weixinTokenCache();
  202. $accessToken = $weixinToken['access_token'];
  203. $url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" . $accessToken;
  204. $data['template_id'] = $template_id;
  205. $data['page'] = 'pages/activity/pages/groupShopping/groupFission/groupFission?shareId='.$join_id;
  206. $data['miniprogram_state'] = env('APP_ENV')=="production"?'formal':'trial';
  207. $data['data']= ['thing1'=>["value"=>"拼团有礼"],'thing2'=>["value"=>'活动已结束,去看看活动结果']];
  208. foreach($open_id_arr as $openid){
  209. $data['touser']= $openid;
  210. if($this->checkSub($openid,$template_id)){
  211. post_curl($url,json_encode($data));
  212. }
  213. }
  214. }
  215. //测试
  216. public function test(){
  217. $help = GroupBuyLbHelp::where('id',100)->find();
  218. $this->add($help,'');
  219. }
  220. /**
  221. * 新增订单记录
  222. * @param $order
  223. * @param string $remark
  224. * @return false|int
  225. */
  226. private function add($help, $remark = ''){
  227. $groupgoods = GroupBuyLbGoods::where('group_buy_lb_activity_id',$help['group_buy_lb_activity_id'])->find();
  228. $goods_id = $groupgoods->goods_id;
  229. $group_price = $groupgoods->group_price;
  230. $goodsSkuId = $groupgoods->goods_sku_id;
  231. $goodsNum = $help['goods_num'];
  232. $model = new GoodsModel;
  233. $goodsList = $model->getListByIdsFromApi([$goods_id]);
  234. // 隐藏冗余的属性
  235. $goodsList->hidden(array_merge($model->hidden, ['content', 'goods_images', 'images']));
  236. //返回商品处理
  237. foreach ($goodsList as &$item) {
  238. // 商品sku信息
  239. $item['skuInfo'] = GoodsSkuModel::detail($item['goods_id'], $goodsSkuId);
  240. // 商品单价
  241. $item['goods_price'] = $item['skuInfo']['goods_price'];
  242. // 商品购买数量
  243. $item['total_num'] = $goodsNum;
  244. // 商品SKU索引
  245. $item['goods_sku_id'] = $item['skuInfo']['goods_sku_id'];
  246. // 商品购买总金额
  247. $item['total_price'] = helper::bcmul($item['goods_price'], $goodsNum);
  248. // 获取最终拼团单价金额
  249. $item['group_price'] = $groupgoods['group_price'];
  250. }
  251. // 订单数据
  252. $data = [
  253. 'user_id' => $help['user_id'],
  254. 'order_no' => $help['order_no'],
  255. 'total_price' => $goodsList[0]['total_price'],//商品原总价,不包含折扣
  256. 'order_price' => $help['order_money'],//订单优惠完金额 商品优惠完金额+运费
  257. 'pay_price' => $help['pay_money'], //微信支付金额
  258. 'delivery_type' => DeliveryTypeEnum::EXPRESS,
  259. 'pay_type' => $help['pay_money'] > 0 ? OrderPayTypeEnum::WECHAT : OrderPayTypeEnum::MICAH_EXCHANGE,
  260. 'buyer_remark' => trim($remark),
  261. 'order_source' => OrderSourceEnum::GROUPBUYLB,
  262. 'order_source_id' => $help['id'],
  263. 'groupbuy_money' => helper::bcsub($goodsList[0]['total_price'],$goodsList[0]['group_price']*$goodsNum),
  264. 'order_status' => OrderStatusEnum::NORMAL,
  265. 'store_id' => 10001,
  266. 'provider_ids' => $help['provider_ids']??0,
  267. 'distributor_total_money' => 0,
  268. 'rice_card_id' => $help['rice_card_id']??0,
  269. 'rice_card_money' => $help['rice_card_money']??0,
  270. 'rice_card_express_money' => $help['rice_card_express_money']??0,
  271. 'pay_status' => PayStatusEnum::SUCCESS,
  272. 'pay_time' => time(),
  273. 'invoice_deadline'=> time() + OrderModel::getInvoiceDeadline() * 60,
  274. 'express_price'=> $help['express_money'],
  275. 'transaction_id'=>$help['transaction_id']
  276. ];
  277. // 保存订单记录
  278. $orderModel = new OrderModel;
  279. $orderModel->save($data);
  280. $order_id = $orderModel->order_id;
  281. $newGoodsList = [];
  282. foreach ($goodsList as $key=>$goods) {
  283. $total_pay_price = helper::bcsub
  284. ($help['pay_money'],$help['express_money']) > 0 ? helper::bcsub($help['pay_money'],$help['express_money']):0;
  285. $item = [
  286. 'order_id'=>$order_id,
  287. 'user_id' => $help['user_id'],
  288. 'store_id' => 10001,
  289. 'goods_id' => $goods['goods_id'],
  290. 'goods_name' => $goods['goods_name'],
  291. 'goods_no' => $goods['goods_no'] ?: '',
  292. 'image_id' => (int)current($goods['goods_images'])['file_id'],
  293. 'deduct_stock_type' => $goods['deduct_stock_type'],
  294. 'spec_type' => $goods['spec_type'],
  295. 'goods_sku_id' => $goods['skuInfo']['goods_sku_id'],
  296. 'goods_props' => $goods['skuInfo']['goods_props'] ?: '',
  297. 'content' => $goods['content'] ?? '',
  298. 'goods_sku_no' => $goods['skuInfo']['goods_sku_no'] ?: '',
  299. 'goods_price' => $goods['skuInfo']['goods_price'],
  300. 'specs' => $goods['skuInfo']['specs'],
  301. 'supplier' => $goods['supplier'],
  302. 'line_price' => $goods['skuInfo']['line_price'],
  303. 'goods_weight' => $goods['skuInfo']['goods_weight'],
  304. 'is_user_grade' => (int)$goods['is_user_grade'],
  305. 'grade_ratio' => $goods['grade_ratio']??0,
  306. 'grade_goods_price' => $goods['grade_goods_price']??0,
  307. 'grade_total_money' => $goods['grade_total_money']??0,
  308. 'coupon_id' => $goods['coupon_id']??0,
  309. 'coupon_money' => $goods['coupon_money']??0,
  310. 'points_bonus' => $goods['points_bonus']??0,
  311. 'total_num' => $goods['total_num'],
  312. 'total_price' => $goods['total_price'],
  313. 'total_pay_price' => $total_pay_price,
  314. 'provider_id' => $goods['provider_id'],
  315. 'brand' => $goods['brand'],
  316. 'province_id' => $goods['province_id'],
  317. 'city_id' => $goods['city_id'],
  318. 'storage' => $goods['storage'],
  319. 'unit' => $goods['unit'],
  320. 'clearing_price' => $goods['skuInfo']['clearing_price']??'0.00',
  321. 'platform_rate' => $goods['skuInfo']['platform_rate']??'0.00',
  322. 'staff_user_id' => $goods['staffUserId'],
  323. 'shop_id' => $goods['shopId'],
  324. 'distributor_radio' => $goods['distributor_radio']??0,
  325. 'distributor_goods_price' => $goods['distributor_goods_price']??0,
  326. 'distributor_total_money' => $goods['distributor_total_money']??0,
  327. 'rice_card_id' => $help['rice_card_id']??0,
  328. 'goods_type' => $goods['goods_type']??10,
  329. 'shop_id'=>0,
  330. 'rice_card_money'=>$help['good_rice_card_money']
  331. ];
  332. $newGoodsList[] = $item;
  333. }
  334. $orderGoodModel = new OrderGoodsModel;
  335. $orderGoodModel->saveAll($newGoodsList);
  336. $address = [
  337. 'order_id'=>$order_id,
  338. 'user_id' => $help['user_id'],
  339. 'store_id' =>10001,
  340. 'name' => $help['user_name'],
  341. 'phone' => $help['phone'],
  342. 'province_id' => $help['province_id'],
  343. 'city_id' => $help['city_id'],
  344. 'region_id' => $help['region_id'],
  345. 'detail' => $help['detail']
  346. ];
  347. $orderAddressModel = new OrderAddressModel;
  348. $orderAddressModel->save($address);
  349. return $order_id;
  350. }
  351. /**
  352. * 记录收货地址
  353. * @param $address
  354. * @return false|\think\Model
  355. */
  356. private function saveOrderAddress($address)
  357. {
  358. return $this->model->address()->save();
  359. }
  360. }