CheckoutGroupbuylb.php 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2017~2021 https://www.yiovo.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
  8. // +----------------------------------------------------------------------
  9. // | Author: 萤火科技 <admin@yiovo.com>
  10. // +----------------------------------------------------------------------
  11. declare (strict_types=1);
  12. namespace app\api\service\order;
  13. use app\api\model\card\UserRiceCard as UserRiceCardModel;
  14. use app\api\model\card\UserRiceCardConsume as UserRiceCardConsumeModel;
  15. use app\api\model\fullsend\FullSendActivity;
  16. use app\api\model\GoodsCategoryRel as GoodsCategoryRelModel;
  17. use app\api\model\GoodsPackage as GoodsPackageModel;
  18. use app\api\model\kj\KjActivityJoin;
  19. use app\api\model\OrderGoodsTaocan as OrderGoodsTaocanModel;
  20. use app\api\model\Order as OrderModel;
  21. use app\api\model\User as UserModel;
  22. use app\api\model\Goods as GoodsModel;
  23. use app\api\model\Setting as SettingModel;
  24. use app\api\model\shop\Shops;
  25. use app\api\model\UserAddress;
  26. use app\api\model\UserCoupon as UserCouponModel;
  27. use app\api\service\User as UserService;
  28. use app\api\service\Payment as PaymentService;
  29. use app\api\service\coupon\GoodsDeduct as GoodsDeductService;
  30. use app\api\service\ricecard\GoodsDeduct as RiceDeductService;
  31. use app\api\service\points\GoodsDeduct as PointsDeductService;
  32. use app\api\service\order\source\checkout\Factory as CheckoutFactory;
  33. use app\common\enum\Setting as SettingEnum;
  34. use app\common\enum\order\PayType as OrderPayTypeEnum;
  35. use app\common\enum\order\OrderStatus as OrderStatusEnum;
  36. use app\common\enum\order\OrderSource as OrderSourceEnum;
  37. use app\common\enum\order\DeliveryType as DeliveryTypeEnum;
  38. use app\common\service\BaseService;
  39. use app\common\service\card\UserRiceCard as UserRiceCardService;
  40. use app\common\service\commission\RecordWaitCommission;
  41. use app\common\service\delivery\Express as ExpressService;
  42. use app\common\service\goods\source\Factory as StockFactory;
  43. use app\common\library\helper;
  44. use app\common\exception\BaseException;
  45. use app\common\enum\order\PayStatus as PayStatusEnum;
  46. use app\common\model\ShopGoodsSku;
  47. use app\common\model\User;
  48. use http\Header\Parser;
  49. use app\api\model\groupbuylb\GroupBuyLbHelp;
  50. use app\api\model\groupbuylb\GroupBuyLbJoin;
  51. use app\api\model\groupbuylb\GroupBuyLbActivity;
  52. use app\api\model\order\GroupBuyLbPay;
  53. /**
  54. * 订单结算台服务类
  55. * Class Checkout
  56. * @package app\api\service\order
  57. */
  58. class CheckoutGroupbuylb extends BaseService
  59. {
  60. /* $model OrderModel 订单模型 */
  61. public $model;
  62. public $buyhelpModel;//参团模型
  63. public $buyjoinModel;//发起团模型
  64. /* @var UserModel $user 当前用户信息 */
  65. private $user;
  66. // 订单结算商品列表
  67. private $goodsList = [];
  68. // 错误信息
  69. protected $error;
  70. // 错误信息状态
  71. protected $errorStatus;
  72. /**
  73. * 订单结算api参数
  74. * @var array
  75. */
  76. private $param = [
  77. 'delivery' => null, // 配送方式 默认:快递配送
  78. 'couponId' => 0, // 优惠券id
  79. 'riceCardId' => 0, // 现金米卡id
  80. 'isUsePoints' => 0, // 是否使用积分抵扣
  81. 'remark' => '', // 买家留言
  82. 'payType' => OrderPayTypeEnum::WECHAT, // 支付方式
  83. 'addressId' => 0, //地址ID
  84. 'staffUserId' => 0, //分享链接用户ID
  85. ];
  86. /**
  87. * 订单结算的规则
  88. * @var array
  89. */
  90. private $checkoutRule = [
  91. 'isUserGrade' => false, // 会员等级折扣
  92. 'isCoupon' => true, // 优惠券抵扣
  93. 'isRiceCard' => true, // 现金米卡抵扣
  94. 'isUsePoints' => false, // 是否使用积分抵扣
  95. ];
  96. /**
  97. * 订单来源
  98. * @var array
  99. */
  100. private $orderSource = [
  101. 'source' => OrderSourceEnum::GROUPBUYLB,
  102. 'source_id' => 0,
  103. ];
  104. /**
  105. * 订单结算数据
  106. * @var array
  107. */
  108. private $orderData = [];
  109. /**
  110. * 构造函数
  111. * Checkout constructor.
  112. * @throws BaseException
  113. */
  114. public function __construct()
  115. {
  116. parent::__construct();
  117. $this->user = UserService::getCurrentLoginUser(true);
  118. $this->model = new OrderModel;
  119. $this->buyhelpModel = new GroupBuyLbHelp;
  120. $this->buyjoinModel = new GroupBuyLbJoin;
  121. $this->storeId = $this->getStoreId();
  122. }
  123. /**
  124. * 设置结算台请求的参数
  125. * @param $param
  126. * @return array
  127. */
  128. public function setParam($param)
  129. {
  130. $this->param = array_merge($this->param, $param);
  131. return $this->getParam();
  132. }
  133. /**
  134. * 获取结算台请求的参数
  135. * @return array
  136. */
  137. public function getParam()
  138. {
  139. return $this->param;
  140. }
  141. /**
  142. * 订单结算的规则
  143. * @param $data
  144. * @return $this
  145. */
  146. public function setCheckoutRule($data)
  147. {
  148. $this->checkoutRule = array_merge($this->checkoutRule, $data);
  149. return $this;
  150. }
  151. /**
  152. * 设置订单来源(普通订单)
  153. * @param $data
  154. * @return $this
  155. */
  156. public function setOrderSource($data)
  157. {
  158. $this->orderSource = array_merge($this->orderSource, $data);
  159. return $this;
  160. }
  161. /**
  162. * 订单确认-结算台
  163. * @param $goodsList
  164. * @return array
  165. * @throws BaseException
  166. * @throws \think\db\exception\DataNotFoundException
  167. * @throws \think\db\exception\DbException
  168. * @throws \think\db\exception\ModelNotFoundException
  169. */
  170. public function onCheckout($goodsList)
  171. {
  172. // 订单确认-立即购买
  173. $this->goodsList = $goodsList;
  174. return $this->checkout();
  175. }
  176. /**
  177. * 订单结算台
  178. * @return array
  179. * @throws BaseException
  180. * @throws \think\db\exception\DataNotFoundException
  181. * @throws \think\db\exception\DbException
  182. * @throws \think\db\exception\ModelNotFoundException
  183. */
  184. private function checkout()
  185. {
  186. // 整理订单数据
  187. $this->orderData = $this->getOrderData();
  188. // 验证商品状态, 是否允许购买
  189. $this->validateGoodsList();
  190. // 设置订单商品总金额()
  191. $this->setOrderTotalPrice();
  192. //订单总运费金额
  193. $this->setOrderExpress();
  194. //获取当前可用的现金卡列表
  195. $userRiceCardList = $this->getUserRiceCardList();
  196. //计算使用米卡现金券抵扣后的金额
  197. $this->setOrderRiceCardMoney($userRiceCardList,(int)$this->param['riceCardId']);
  198. // 计算订单商品的实际付款金额
  199. $this->setOrderGoodsPayPrice();
  200. // 计算订单最终金额+运费
  201. $this->setOrderPayPrice();
  202. //订单商品的所有店铺集合2021年9月28日 10:56:45
  203. $this->setOrderProviderIds();
  204. // 订单商品总数量
  205. $orderTotalNum = helper::getArrayColumnSum($this->goodsList, 'total_num');
  206. // 返回订单数据
  207. return array_merge([
  208. 'goodsList' => $this->goodsList, // 商品信息
  209. 'orderTotalNum' => $orderTotalNum, // 商品总数量
  210. // 'couponList' => array_values($couponList), // 优惠券列表
  211. 'hasError' => $this->hasError(),
  212. 'errorMsg' => $this->getError(),
  213. 'errorStatus' => $this->getErrorStatus(),
  214. ], $this->orderData);
  215. }
  216. //我的可用现金卡
  217. public function getUserRiceCardList(){
  218. $user = UserService::getCurrentLoginUser(true);
  219. $list = UserRiceCardModel::getUserRiceCardList($user['user_id'])->toArray();
  220. $data = [];
  221. foreach ($list as $key=>&$item){
  222. $i = 0;
  223. $exceptGoodsId = helper::getArrayColumn($item['riceCardGoodsExcept'],'goods_id');
  224. foreach ($this->goodsList as $good) {
  225. if(!empty($item['dk_cat_ids']) && strpos((string)$item['dk_cat_ids'],(string)$good['category']['category_id']) === false){
  226. unset($list[$key]);
  227. $i = 1;
  228. }
  229. if(!empty($exceptGoodsId) && in_array($good['goods_id'],$exceptGoodsId)){
  230. unset($list[$key]);
  231. $i = 1;
  232. }
  233. }
  234. if(!$i){
  235. unset($item['riceCardGoodsExcept']);
  236. $data[$item['id']] = $item;
  237. }
  238. }
  239. if($this->param['riceCardId']==0){ //-1表示不使用米卡
  240. $this->param['riceCardId'] = key($data)??0;//若果没有选择米卡,默认使用第一张
  241. }
  242. return $data;
  243. }
  244. /**
  245. * 整理订单数据(结算台初始化)
  246. * @return array
  247. * @throws \think\db\exception\DataNotFoundException
  248. * @throws \think\db\exception\DbException
  249. * @throws \think\db\exception\ModelNotFoundException
  250. */
  251. private function getOrderData()
  252. {
  253. // 系统支持的配送方式 (后台设置)
  254. $deliveryType = SettingModel::getItem(SettingEnum::DELIVERY)['delivery_type'];
  255. return [
  256. // 当前配送类型
  257. 'delivery' => $this->param['delivery'] > 0 ? $this->param['delivery'] : $deliveryType[0],
  258. // 默认地址
  259. 'address' => '',
  260. // 是否存在收货地址
  261. 'existAddress' => $this->user['address_id'] > 0,
  262. // 配送费用
  263. 'expressPrice' => 0.00,
  264. // 当前用户收货城市是否存在配送规则中
  265. 'isIntraRegion' => true,
  266. // 是否允许使用积分抵扣
  267. 'isAllowPoints' => false,
  268. // 是否使用积分抵扣
  269. 'isUsePoints' => $this->param['isUsePoints'],
  270. // 积分抵扣金额
  271. 'pointsMoney' => 0.00,
  272. // 赠送的积分数量
  273. 'pointsBonus' => 0,
  274. // 支付方式
  275. 'payType' => $this->param['payType'],
  276. // 系统设置
  277. 'setting' => $this->getSetting(),
  278. ];
  279. }
  280. /**
  281. * 获取订单页面中使用到的系统设置
  282. * @return array
  283. * @throws \think\db\exception\DataNotFoundException
  284. * @throws \think\db\exception\DbException
  285. * @throws \think\db\exception\ModelNotFoundException
  286. */
  287. private function getSetting()
  288. {
  289. // 系统支持的配送方式 (后台设置)
  290. $deliveryType = SettingModel::getItem(SettingEnum::DELIVERY)['delivery_type'];
  291. // 积分设置
  292. $pointsSetting = SettingModel::getItem(SettingEnum::POINTS);
  293. return [
  294. 'deliveryType' => $deliveryType, // 支持的配送方式
  295. 'points_name' => $pointsSetting['points_name'], // 积分名称
  296. 'points_describe' => $pointsSetting['describe'], // 积分说明
  297. ];
  298. }
  299. /**
  300. * 验证订单商品的状态
  301. * @return bool
  302. */
  303. private function validateGoodsList()
  304. {
  305. $Checkout = CheckoutFactory::getFactory(
  306. $this->user,
  307. $this->goodsList,
  308. $this->orderData['delivery'],
  309. $this->shopInfo['shop_id'] ?? 0,
  310. $this->orderSource['source']
  311. );
  312. $status = $Checkout->validateGoodsList();
  313. if(!$status){
  314. $this->setError($Checkout->getError());
  315. $this->setErrorStatus(422);
  316. }
  317. return $status;
  318. }
  319. /**
  320. * 设置订单的商品总金额(不含优惠折扣)
  321. */
  322. private function setOrderTotalPrice()
  323. {
  324. // 订单商品的总金额
  325. $this->orderData['orderTotalPrice'] = helper::number2(helper::getArrayColumnSum($this->goodsList, 'total_price'));
  326. //拼团总金额
  327. $this->orderData['orderTotalGroupPrice'] = helper::number2(helper::getArrayColumnSum($this->goodsList, 'group_price')*helper::getArrayColumnSum($this->goodsList, 'total_num'));
  328. }
  329. /**
  330. * 订单商品的所有店铺集合
  331. */
  332. private function setOrderProviderIds()
  333. {
  334. // 订单商品的所有店铺集合
  335. $this->orderData['orderProviderIds'] = implode(',',array_values(array_unique(helper::getArrayColumn($this->goodsList, 'provider_id'))));
  336. }
  337. /**
  338. * 设置订单的实际支付金额(含配送费)
  339. */
  340. private function setOrderPayPrice()
  341. {
  342. // 订单金额(含优惠折扣)
  343. //(商品总价 - N件X折 - 优惠券 - 分销员)+ 运费 = 微信支付+米卡抵扣+米卡抵扣运费
  344. //(total_price-coupon_money-distrbutor_total_money)+express_price = pay_price+rice_card_money+rice_card_express_money
  345. $this->orderData['orderPrice'] = helper::number2(helper::getArrayColumnSum($this->goodsList, 'total_pay_price'));
  346. // 订单实付款金额(订单金额 + 运费 - 现金卡运费抵扣金额)
  347. $this->orderData['orderPayPrice'] = helper::number2(helper::bcadd($this->orderData['orderPrice'], $this->orderData['expressPrice']-$this->orderData['riceCardExpressMoney']));
  348. }
  349. /**
  350. * 计算订单商品的实际付款金额
  351. * @return bool
  352. */
  353. private function setOrderGoodsPayPrice()
  354. {
  355. // 商品总价 - 优惠抵扣
  356. foreach ($this->goodsList as &$goods) {
  357. //减去现金米卡抵扣的金额
  358. $value = helper::bcsub($goods['group_price']*$goods['total_num'], $goods['rice_card_money']);
  359. $goods['total_pay_price'] = helper::number2($value);
  360. }
  361. return true;
  362. }
  363. /**
  364. * 设置订单现金米卡抵扣信息
  365. * @param int $riceCardId 可使用米卡列表
  366. * @param int $riceCardId 当前选择的现金米卡id
  367. * @return bool
  368. * @throws BaseException
  369. */
  370. private function setOrderRiceCardMoney($userRiceCardList,int $riceCardId)
  371. {
  372. // 设置默认数据:订单信息
  373. helper::setDataAttribute($this->orderData, [
  374. 'riceCardId' => $riceCardId, // 用户现金米卡id
  375. 'riceCardMoney' => 0, // 现金米卡抵扣总金额
  376. 'riceCardExpressMoney' => 0, // 现金米卡抵扣运费
  377. 'userRiceCardList' => [], // 米卡列表
  378. 'userRiceCard' => [], // 已选择的米卡
  379. ], false);
  380. // 设置默认数据:订单商品列表
  381. helper::setDataAttribute($this->goodsList, [
  382. 'rice_card_id' => 0, // 用户现金米卡id
  383. 'rice_card_money' => 0, // 金米卡抵扣金额
  384. ], true);
  385. if($riceCardId<0){//如果米卡ID小于0表示不使用,但是也要返回可使用列表
  386. $this->orderData['userRiceCardList'] = array_values($userRiceCardList);
  387. return true;
  388. }
  389. // 验证选择的优惠券ID是否合法
  390. if (!$this->verifyUserRiceCard($riceCardId, $userRiceCardList)) {
  391. return false;
  392. }
  393. // 获取优惠券信息
  394. $riceCard = $this->getRiceCardInfo($riceCardId, $userRiceCardList);
  395. $goodsListTemp = [];
  396. foreach ($this->goodsList as $key=> $good){
  397. $goodsListTemp[$key]['total_price'] = $good['group_price']*$good['total_num'];
  398. }
  399. $RiceMoney = new RiceDeductService;
  400. $completed = $RiceMoney->setGoodsCouponMoney($goodsListTemp, $riceCard['balance']);
  401. // 分配订单商品优惠券抵扣金额
  402. $rice_card_money = 0;
  403. foreach ($this->goodsList as $key => &$goods) {
  404. $goods['rice_card_money'] = isset($completed[$key]['rice_card_money']) ? $completed[$key]['rice_card_money'] / 100 : 0;
  405. $goods['rice_card_id'] = $riceCardId;
  406. $rice_card_money += $goods['rice_card_money'];
  407. }
  408. $orderTotalGroupPrice = $this->orderData['orderTotalGroupPrice']; //实际支付金额
  409. //有运费,并且现金米卡可用的金额大于商品总价
  410. $rice_card_express_money = 0;
  411. if($riceCard['balance']>$orderTotalGroupPrice && $this->orderData['expressPrice']>0){
  412. $residueMoney = $riceCard['balance']-$orderTotalGroupPrice;
  413. if($residueMoney-$this->orderData['expressPrice']>0){
  414. $rice_card_express_money += $this->orderData['expressPrice'];
  415. }else{
  416. $rice_card_express_money += $residueMoney;
  417. }
  418. }
  419. // 记录订单现金米卡信息
  420. $this->orderData['userRiceCard'] = $userRiceCardList[$riceCardId];
  421. $this->orderData['riceCardId'] = $riceCardId;
  422. $this->orderData['riceCardMoney'] = helper::bcmul($rice_card_money+$rice_card_express_money,1);
  423. $this->orderData['riceCardExpressMoney'] = helper::bcmul($rice_card_express_money,1);
  424. $this->orderData['userRiceCardList'] = array_values($userRiceCardList);
  425. return true;
  426. }
  427. /**
  428. * 验证用户选择的现金米卡
  429. * @param $riceCard
  430. * @return bool
  431. * @throws BaseException
  432. */
  433. private function verifyUserRiceCard($riceCardId,$userRiceCardList)
  434. {
  435. // 是否开启现金米卡抵扣
  436. if (!$this->checkoutRule['isRiceCard']) {
  437. return false;
  438. }
  439. // 如果没有可用的现金米卡,直接返回
  440. if ($riceCardId <= 0) {
  441. return false;
  442. }
  443. // 判断优惠券是否存在
  444. $riceCard = $this->getRiceCardInfo($riceCardId, $userRiceCardList);
  445. // 如果没有现金米卡,直接返回
  446. if (empty($riceCard)) {
  447. throwError('未找到米卡信息');
  448. }
  449. return true;
  450. }
  451. /**
  452. * 查找指定的优惠券信息
  453. * @param int $couponId 优惠券ID
  454. * @param array $couponList 优惠券列表
  455. * @return false|mixed
  456. */
  457. private function getRiceCardInfo(int $riceCardId, array $userRiceCardList)
  458. {
  459. return helper::getArrayItemByColumn($userRiceCardList, 'id', $riceCardId);
  460. }
  461. /**
  462. * 订单配送-快递配送
  463. * @return bool
  464. * @throws \think\db\exception\DataNotFoundException
  465. * @throws \think\db\exception\DbException
  466. * @throws \think\db\exception\ModelNotFoundException
  467. */
  468. private function setOrderExpress()
  469. {
  470. // 设置默认数据:配送费用
  471. helper::setDataAttribute($this->goodsList, [
  472. 'expressPrice' => 0,
  473. ], true);
  474. // 当前用户收货城市id
  475. if($this->param['addressId']){ //有传参
  476. $addredd = UserAddress::get(['user_id' => $this->user['user_id'], 'address_id' => $this->param['addressId']]);
  477. $cityId = $addredd ? (int)$addredd['city_id'] : 0;
  478. $this->orderData['address'] = $addredd;
  479. }else{ //没有传参读默认地址
  480. $cityId = $this->user['address_default'] ? (int)$this->user['address_default']['city_id'] : 0;
  481. $this->orderData['address'] = $this->user['address_default'];
  482. }
  483. if ($this->param['delivery'] == DeliveryTypeEnum::EXPRESS) { // 普通快递
  484. // 初始化配送服务类
  485. $ExpressService = new ExpressService($cityId, $this->goodsList);
  486. // 验证商品是否在限购配送范围
  487. $isDeliveryLimit = $ExpressService->isDeliveryLimit();
  488. if($cityId > 0){
  489. if ($isDeliveryLimit == false) {
  490. $this->setError("很抱歉,您的收货地址在限购地区的配送范围内");
  491. $this->setErrorStatus(423);
  492. $this->orderData['isIntraRegion'] = $isDeliveryLimit;
  493. }else{
  494. // 验证商品是否在配送范围
  495. $isIntraRegion = $ExpressService->isIntraRegion();
  496. if ($isIntraRegion == false) {
  497. $notInRuleGoodsName = $ExpressService->getNotInRuleGoodsName();
  498. $this->setError("很抱歉,您的收货地址不在商品 [".limit_str((string)$notInRuleGoodsName)."] 的配送范围内");
  499. $this->setErrorStatus(423);
  500. }
  501. $this->orderData['isIntraRegion'] = $isIntraRegion;
  502. }
  503. }
  504. // 订单总运费金额
  505. $this->orderData['expressPrice'] = $ExpressService->getDeliveryFee();
  506. } else { // 门店自提
  507. $this->orderData['expressPrice'] = "0.00";
  508. }
  509. return true;
  510. }
  511. /**
  512. * 创建新订单
  513. * @param array $order 订单信息
  514. * @return bool
  515. */
  516. public function createOrder(array $order)
  517. {
  518. // 表单验证
  519. if (!$this->validateOrderForm($order)) {
  520. return false;
  521. }
  522. // 创建新的订单
  523. $status = $this->buyhelpModel->transaction(function () use ($order) {
  524. // dd($order);
  525. // 创建订单事件
  526. return $this->createOrderEvent($order);
  527. });
  528. // 余额支付标记订单已支付
  529. return $status;
  530. }
  531. /**
  532. * 创建订单事件
  533. * @param $order
  534. * @return bool
  535. * @throws BaseException
  536. * @throws \Exception
  537. */
  538. private function createOrderEvent($order)
  539. {
  540. // 新增订单记录
  541. $status = $this->add($order, $this->param['remark']);
  542. if($order['riceCardId']>0 && $order['riceCardMoney']>0){
  543. //根据支付的金额来判断逻辑
  544. if($order['orderPayPrice']>0){
  545. //冻结现金卡金额
  546. UserRiceCardModel::setIncDecByField($order['riceCardId'],['frozen_amount'=>(float)$order['riceCardMoney']],['balance'=>(float)$order['riceCardMoney']]);
  547. }else{//不需要结算金额
  548. //写现金卡出账记录
  549. UserRiceCardConsumeModel::add($order['userRiceCard'],$this->orderData['order_no'],$order['orderPayPrice'],$order['riceCardMoney']);
  550. //如果可用余额等于要抵扣的金额
  551. if($order['riceCardMoney']==$order['userRiceCard']['balance']){
  552. //现金卡直接减可用余额,并且状态改为已失效
  553. UserRiceCardModel::setIncDecByField($order['riceCardId'],[],['balance'=>(float)$order['riceCardMoney']],['effect_state'=>2]);
  554. }else{
  555. //现金卡直接减可用余额
  556. UserRiceCardModel::setDecByField($order['riceCardId'],'balance',(float)$order['riceCardMoney']);
  557. }
  558. // 更新商品销量(付款后减库存、加销量)
  559. $order['goods'] = $order['goodsList'];
  560. $order['delivery_type'] = $order['delivery'];
  561. StockFactory::getFactory(OrderSourceEnum::GROUPBUYLB)->updateStockSales($order);
  562. }
  563. }
  564. return $status;
  565. }
  566. /**
  567. * 构建支付请求的参数
  568. * @return array
  569. * @throws BaseException
  570. * @throws \think\db\exception\DataNotFoundException
  571. * @throws \think\db\exception\DbException
  572. * @throws \think\db\exception\ModelNotFoundException
  573. */
  574. public function onOrderPayment()
  575. {
  576. return PaymentService::orderPayment($this->model, $this->param['payType']);
  577. }
  578. /**
  579. * 表单验证 (订单提交)
  580. * @param array $order 订单信息
  581. * @return bool
  582. */
  583. private function validateOrderForm(array $order)
  584. {
  585. if ($order['delivery'] == DeliveryTypeEnum::EXPRESS) {
  586. if (empty($order['address'])) {
  587. $this->error = '您还没有选择配送地址';
  588. return false;
  589. }
  590. }
  591. // 余额支付时判断用户余额是否足够
  592. if ($order['payType'] == OrderPayTypeEnum::BALANCE) {
  593. if ($this->user['balance'] < $order['orderPayPrice']) {
  594. $this->error = '您的余额不足,无法使用余额支付';
  595. return false;
  596. }
  597. }
  598. return true;
  599. }
  600. /**
  601. * 当前订单是否存在和使用积分抵扣
  602. * @param $order
  603. * @return bool
  604. */
  605. private function isExistPointsDeduction($order)
  606. {
  607. return $order['isAllowPoints'] && $order['isUsePoints'];
  608. }
  609. /**
  610. * 新增订单记录
  611. * @param $order
  612. * @param string $remark
  613. * @return false|int
  614. */
  615. private function add($order, $remark = ''){
  616. $user = UserModel::where('user_id',$this->user['user_id'])->with(['avatar'])->find();
  617. //发起拼团
  618. $help = [];
  619. if($order['join_id']==0){
  620. $activity = GroupBuyLbActivity::where("id",$order['group_buy_lb_activity_id'])->find();
  621. $share_title = $activity['share_title'];
  622. if($activity->an_share_title==1){
  623. $share_title = $user->nick_name.''.$share_title;
  624. }
  625. $join = [
  626. 'group_buy_lb_activity_id' => $order['group_buy_lb_activity_id'],
  627. 'people_count'=> $activity['people_count'],
  628. 'end_time' => Date("Y-m-d H:i:s",time() + $activity['during_time']*60*60),
  629. 'share_title'=>$share_title,
  630. 'share_copy_writing'=>$activity['share_copy_writing'],
  631. 'create_time'=>time(),
  632. 'update_time'=>time(),
  633. 'user_id'=>$this->user['user_id'],
  634. 'is_virtual'=>0
  635. ];
  636. $this->buyjoinModel->save($join);
  637. $help = [
  638. 'user_id' => $this->user['user_id'],
  639. 'order_no' => $this->model->orderNo('PT'),
  640. 'group_buy_lb_activity_id' => $order['group_buy_lb_activity_id'],
  641. 'join_id'=>$this->buyjoinModel['id'],
  642. 'goods_num' =>$order['orderTotalNum'],
  643. 'head_picture'=>$user->avatar['preview_url']??'',
  644. 'rice_card_id'=>$order['riceCardId']<=0?0:$order['riceCardId'],
  645. 'rice_card_money'=>$order['riceCardMoney'],
  646. 'rice_card_express_money'=>$order['riceCardExpressMoney'],
  647. 'pay_money'=> $order['orderPayPrice'],
  648. 'express_money'=> $order['expressPrice'],
  649. 'order_money'=> helper::bcadd($order['expressPrice'],$order['orderTotalGroupPrice']),
  650. 'provider_ids'=>$order['orderProviderIds'],
  651. 'good_rice_card_money'=>$order['goodsList'][0]['rice_card_money']??0,
  652. 'is_virtual_join_user'=>0
  653. ];
  654. }
  655. //参与拼团
  656. if($order['join_id']>0){
  657. $help = [
  658. 'user_id' => $this->user['user_id'],
  659. 'order_no' => $this->model->orderNo('PT'),
  660. 'group_buy_lb_activity_id' => $order['group_buy_lb_activity_id'],
  661. 'join_id'=>$order['join_id'],
  662. 'goods_num' =>$order['orderTotalNum'],
  663. 'head_picture'=>$user->avatar['preview_url']??'',
  664. 'rice_card_id'=>$order['riceCardId']<=0?0:$order['riceCardId'],
  665. 'rice_card_money'=>$order['riceCardMoney'],
  666. 'rice_card_express_money'=>$order['riceCardExpressMoney'],
  667. 'pay_money'=> $order['orderPayPrice'],
  668. 'express_money'=> $order['expressPrice'],
  669. 'rice_card_express_money'=>$order['riceCardExpressMoney'],
  670. 'order_money'=> helper::bcadd($order['expressPrice'],$order['orderTotalGroupPrice']),
  671. 'provider_ids'=>$order['orderProviderIds'],
  672. 'good_rice_card_money'=>$order['goodsList'][0]['rice_card_money']??0
  673. ];
  674. }
  675. $address['user_name'] = $order['address']['name']??'';
  676. $address['phone'] = $order['address']['phone']??'';
  677. $address['province_id'] = $order['address']['province_id']??0;
  678. $address['city_id'] = $order['address']['city_id']??0;
  679. $address['region_id'] = $order['address']['region_id']??0;
  680. $address['detail'] = $order['address']['detail']??'';
  681. $help = array_merge($help,$address);
  682. $help['pay_type'] = $order['payType']??OrderPayTypeEnum::WECHAT;
  683. $isPay = false;
  684. //米卡兑换直接成功
  685. if($order['orderPayPrice']<=0 || $order['payType']==OrderPayTypeEnum::MICAH_EXCHANGE){
  686. $help['pay_state'] = 1;
  687. $help['pay_time'] = time();
  688. $partJoin = GroupBuyLbJoin::where('id','=',$help['join_id'])->find();
  689. $partJoin->help_count = $partJoin->help_count + 1;
  690. $partJoin->save();
  691. $isPay = true;
  692. }
  693. $this->orderData['order_no'] = $help['order_no'];
  694. // 保存参团记录
  695. $this->buyhelpModel->save($help);
  696. //米卡支付完成并且属于参团的,要看是不是成团了,成团要写订单
  697. if($isPay&&$order['join_id']>0){
  698. if($partJoin->help_count==$partJoin->people_count){
  699. $pay = new GroupBuyLbPay;
  700. $pay->ptSuccessNotify($help['join_id']);
  701. }
  702. }
  703. StockFactory::getFactory(OrderSourceEnum::GROUPBUYLB)->updateGoodsStock($order);
  704. //更新拼团活动库存的数量
  705. StockFactory::getFactory(OrderSourceEnum::GROUPBUYLB)->updateActivityStock($order);
  706. return true;
  707. }
  708. /**
  709. * 更新商品库存 (针对下单减库存的商品)
  710. * 普通快递、门店自提 分开扣库存
  711. * @param $order
  712. * @return mixed
  713. */
  714. private function updateGoodsStockNum($order)
  715. {
  716. return StockFactory::getFactory($this->model['order_source'])->updateGoodsStock($order);
  717. }
  718. /**
  719. * 保存砍价信息
  720. * @param $order
  721. * @return int
  722. */
  723. private function saveKjActivityJoin($order)
  724. {
  725. // 订单商品列表
  726. foreach ($order['goodsList'] as $key=> $goods) {
  727. $data[] = [
  728. 'where' => ['id' => $goods['bargain_id']],
  729. 'data' => [
  730. 'order_id' => $this->model['order_id'],//订单ID
  731. 'order_price' => helper::bcadd($goods['bargain_price'],$this->orderData['expressPrice']),//订单金额+运费
  732. 'is_submit_order'=>1 //是否提交订单 1是
  733. ]
  734. ];
  735. }
  736. return (new KjActivityJoin())->updateAll($data) !== false;
  737. }
  738. /**
  739. * 记录收货地址
  740. * @param $address
  741. * @return false|\think\Model
  742. */
  743. private function saveOrderAddress($address)
  744. {
  745. return $this->model->address()->save([
  746. 'user_id' => $this->user['user_id'],
  747. 'store_id' => $this->storeId,
  748. 'name' => $address['name'],
  749. 'phone' => $address['phone'],
  750. 'province_id' => $address['province_id'],
  751. 'city_id' => $address['city_id'],
  752. 'region_id' => $address['region_id'],
  753. 'detail' => $address['detail'],
  754. ]);
  755. }
  756. /**
  757. * 设置错误信息
  758. * @param $error
  759. */
  760. protected function setError($error)
  761. {
  762. empty($this->error) && $this->error = $error;
  763. }
  764. /**
  765. * 获取错误信息
  766. * @return mixed
  767. */
  768. public function getError()
  769. {
  770. return $this->error ?: '';
  771. }
  772. /**
  773. * 设置错误状态
  774. * @param $errorStatus
  775. */
  776. protected function setErrorStatus($errorStatus)
  777. {
  778. empty($this->errorStatus) && $this->errorStatus = $errorStatus;
  779. }
  780. /**
  781. * 获取错误信息
  782. * @return mixed
  783. */
  784. public function getErrorStatus()
  785. {
  786. return $this->errorStatus ?: 0;
  787. }
  788. /**
  789. * 是否存在错误
  790. * @return bool
  791. */
  792. public function hasError()
  793. {
  794. return !empty($this->error);
  795. }
  796. }