StoreOrderBatch.php 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610
  1. <?php
  2. namespace app\models\store;
  3. use crmeb\basic\BaseModel;
  4. use think\facade\Cache;
  5. use crmeb\traits\ModelTrait;
  6. use app\models\system\SystemStore;
  7. use app\models\user\{
  8. User,
  9. UserAddress,
  10. UserBill,
  11. WechatUser
  12. };
  13. use crmeb\repositories\{
  14. GoodsRepository,
  15. PaymentRepositories,
  16. OrderRepository,
  17. ShortLetterRepositories,
  18. UserRepository
  19. };
  20. use EasyWeChat\Store\Store;
  21. /**
  22. * 正常情況, 一次性下單購物車中多個商品,只產生一個訂單。 支付,積分,發貨,退貨,等等都是基於這一個訂單操作。
  23. * 一個明顯的問題是:當此訂單中多個商品不能在一個快遞中發貨時,訂單就變得不易管理
  24. *
  25. * 這個類的目的就是。已最小的侵入性來實現:一個訂單中包含多個商品時,自動按照一定的邏輯把這個訂單拆分爲若幹個訂單
  26. * 每個訂單中的商品可在同一個快遞中發貨。
  27. *
  28. * 有點類似一個電商平臺多個商家的情況,肯定是各個商家派發購物車中屬於自己家的商品。
  29. *
  30. * 實現:
  31. *
  32. * 單獨建一個表,此表只記錄一個大訂單號(用於支付接口傳遞訂單參數)和關聯的所有子訂單
  33. * 支付接口按大訂單號走,發貨等訂單管理按子訂單走。
  34. * 這樣有一個問題:子訂單退貨沒法執行三方支付退款(暫定)
  35. */
  36. class StoreOrderBatch extends BaseModel
  37. {
  38. /**
  39. * 数据表主键
  40. * @var string
  41. */
  42. protected $pk = 'id';
  43. /**
  44. * 模型名称
  45. * @var string
  46. */
  47. protected $name = 'store_order_batch';
  48. use ModelTrait;
  49. /**
  50. * 获取订单各项金额
  51. *
  52. */
  53. public static function getOrderPriceGroup($cartInfo, $addr)
  54. {
  55. return StoreOrder::getOrderPriceGroup($cartInfo, $addr);
  56. }
  57. /**
  58. * 缓存订单信息
  59. * @param $uid
  60. * @param $cartInfo
  61. * @param $priceGroup
  62. * @param array $other
  63. * @param int $cacheTime
  64. * @return string 总订单ID
  65. * @throws \Psr\SimpleCache\InvalidArgumentException
  66. */
  67. public static function cacheOrderInfo($uid, $cartInfo, $priceGroup, $other = [], $cacheTime = 600)
  68. {
  69. $key = md5(time() . $uid);
  70. Cache::set('user_order_' . $uid . $key, compact('cartInfo', 'priceGroup', 'other'), $cacheTime);
  71. return $key;
  72. }
  73. /**
  74. * 获取订单缓存信息
  75. * @param $uid
  76. * @param $key
  77. * @return mixed|null
  78. * @throws \Psr\SimpleCache\InvalidArgumentException
  79. */
  80. public static function getCacheOrderInfo($uid, $key)
  81. {
  82. $cacheName = 'user_order_' . $uid . $key;
  83. if (!Cache::has($cacheName)) return null;
  84. return Cache::get($cacheName);
  85. }
  86. /**
  87. * 生成总订单唯一id
  88. * @param $uid 用户uid
  89. * @return string
  90. */
  91. public static function getNewPOrderId()
  92. {
  93. $prefix = 'wxcn';
  94. list($msec, $sec) = explode(' ', microtime());
  95. $msectime = number_format((floatval($msec) + floatval($sec)) * 1000, 0, '', '');
  96. $porderId = $prefix . $msectime . mt_rand(10000, 99999);
  97. if (self::be(['porder_id' => $porderId])) {
  98. $porderId = $prefix . $msectime . mt_rand(10000, 99999);
  99. }
  100. return $porderId;
  101. }
  102. /**
  103. * 获取所有子订单
  104. * @param string $porderId: porder_id
  105. */
  106. public static function getAllSubOrders(string $porderId): array
  107. {
  108. $subOrders = self::alias('b')->join('StoreOrder o', 'o.id=b.oid')
  109. ->where('b.porder_id', $porderId)->select()->toArray();
  110. foreach ($subOrders as &$subOrder) {
  111. $subOrder['cart_id'] = json_decode($subOrder['cart_id'], true);
  112. }
  113. return $subOrders;
  114. }
  115. /**
  116. * 字段累加
  117. * @param Array $subOrders
  118. * @param Array $field_name_list
  119. * @return Array
  120. */
  121. public static function sumFields(array $marr, array $field_name_list): array
  122. {
  123. $sums = [];
  124. foreach ($marr as $row) {
  125. foreach ($field_name_list as $fname) {
  126. $fv = $row[$fname] ?? 0; // field value
  127. $sums[$fname] = (float)bcadd($sums[$fname] ?? 0, $fv, 2);
  128. }
  129. }
  130. return $sums;
  131. }
  132. /**
  133. * 微信支付 为 0元时
  134. * @param $order_id
  135. * @param $uid
  136. * @param string $formId
  137. * @return bool
  138. * @throws \think\Exception
  139. * @throws \think\db\exception\DataNotFoundException
  140. * @throws \think\db\exception\ModelNotFoundException
  141. * @throws \think\exception\DbException
  142. */
  143. public static function jsPayPriceBatch($porder_id, $uid, $formId = '')
  144. {
  145. $subOrders = self::getAllSubOrders($porder_id);
  146. if (!$subOrders) return self::setErrorInfo('订单不存在!');
  147. $fieldValues = self::sumFields($subOrders, ['paid']);
  148. if ($fieldValues['paid']) return self::setErrorInfo('该订单已支付!');
  149. $userInfo = User::getUserInfo($uid);
  150. self::beginTrans();
  151. $res1 = $res2 = true;
  152. foreach ($subOrders as $orderInfo) {
  153. $res1 = $res1 && UserBill::expend('购买商品', $uid, 'now_money', 'pay_product', $orderInfo['pay_price'], $orderInfo['id'], $userInfo['now_money'], '微信支付' . floatval($orderInfo['pay_price']) . '元购买商品');
  154. $res2 = $res2 && StoreOrder::paySuccess($orderInfo['order_id'], 'weixin', $formId); //微信支付为0时
  155. }
  156. $res = $res1 && $res2;
  157. self::checkTrans($res);
  158. return $res;
  159. }
  160. /**
  161. * 查找购物车里的所有产品标题
  162. * @param $cartId 购物车id
  163. * @return bool|string
  164. */
  165. public static function getProductTitleBatch($subOrders)
  166. {
  167. $title = '';
  168. $cartId = [];
  169. foreach ($subOrders as $order) {
  170. $cartId = array_merge($cartId, $order['cart_id']);
  171. }
  172. try {
  173. $orderCart = StoreOrderCartInfo::where('cart_id', 'in', $cartId)->field('cart_info')->select();
  174. foreach ($orderCart as $item) {
  175. if (isset($item['cart_info']['productInfo']['store_name'])) {
  176. $title .= $item['cart_info']['productInfo']['store_name'] . '|';
  177. }
  178. }
  179. unset($item);
  180. if (!$title) {
  181. $productIds = StoreCart::where('id', 'in', $cartId)->column('product_id');
  182. $productlist = ($productlist = StoreProduct::getProductField($productIds, 'store_name')) ? $productlist->toArray() : [];
  183. foreach ($productlist as $item) {
  184. if (isset($item['store_name'])) $title .= $item['store_name'] . '|';
  185. }
  186. }
  187. if ($title) $title = substr($title, 0, strlen($title) - 1);
  188. unset($item);
  189. } catch (\Exception $e) {
  190. }
  191. return $title;
  192. }
  193. /**
  194. * 余额支付
  195. * @param $order_id
  196. * @param $uid
  197. * @param string $formId
  198. * @return bool
  199. * @throws \think\Exception
  200. * @throws \think\db\exception\DataNotFoundException
  201. * @throws \think\db\exception\ModelNotFoundException
  202. * @throws \think\exception\DbException
  203. */
  204. public static function yuePayBatch($porder_id, $uid, $formId = '')
  205. {
  206. $porderInfo = self::where('uid', $uid)->where('porder_id', $porder_id)->find();
  207. if (!$porderInfo) {
  208. return self::setErrorInfo('订单不存在!');
  209. }
  210. $subOrders = self::getAllSubOrders($porder_id);
  211. if (!$subOrders) {
  212. return self::setErrorInfo('订单不存在!');
  213. }
  214. $fieldValues = self::sumFields($subOrders, ['paid']);
  215. if ($fieldValues['paid']) {
  216. return self::setErrorInfo('该订单已支付!');
  217. }
  218. $userInfo = User::getUserInfo($uid);
  219. if ($userInfo['now_money'] < $porderInfo['total_price'])
  220. return self::setErrorInfo(['status' => 'pay_deficiency', 'msg' => '余额不足' . floatval($porderInfo['total_price'])]);
  221. self::beginTrans();
  222. $res1 = $res2 = $res3 = true;
  223. foreach ($subOrders as $orderInfo) {
  224. $res1 = $res1 && (false !== User::bcDec($uid, 'now_money', $orderInfo['pay_price'], 'uid'));
  225. $res2 = $res2 && UserBill::expend('购买商品', $uid, 'now_money', 'pay_product', $orderInfo['pay_price'], $orderInfo['id'], $userInfo['now_money'], '余额支付' . floatval($orderInfo['pay_price']) . '元购买商品');
  226. $res3 = $res3 && StoreOrder::paySuccess($orderInfo['order_id'], 'yue', $formId); //余额支付成功
  227. try {
  228. PaymentRepositories::yuePayProduct($userInfo, $orderInfo);
  229. } catch (\Exception $e) {
  230. self::rollbackTrans();
  231. return self::setErrorInfo($e->getMessage());
  232. }
  233. }
  234. $res = $res1 && $res2 && $res3;
  235. self::checkTrans($res);
  236. return $res;
  237. }
  238. public static function paySuccessBatch($porderId, $paytype = 'weixin', $formId = '')
  239. {
  240. $subOrders = self::getAllSubOrders($porderId);
  241. $res = true;
  242. foreach ($subOrders as $order) {
  243. $res = $res && StoreOrder::paySuccess($order['order_id'], $paytype, $formId);
  244. }
  245. return $res;
  246. }
  247. /**
  248. * 生成订单
  249. * @param $uid
  250. * @param $key orderKey 由客户端传入,总订单ID
  251. * @param $addressId
  252. * @param $payType weixin / yue
  253. * @param bool $useIntegral: 是否使用积分
  254. * @param int $couponId
  255. * @param string $mark: 订单留言
  256. * @param int $combinationId
  257. * @param int $pinkId
  258. * @param int $seckill_id
  259. * @param int $bargain_id
  260. * @param bool $test
  261. * @param int $isChannel 1, 0, 2 : routine, weixin, weixinh5
  262. * @param int $shipping_type
  263. * @param string $real_name
  264. * @param string $phone
  265. * @param int $storeId: 门店ID
  266. * @return StoreOrder|bool|\think\Model
  267. * @throws \think\Exception
  268. * @throws \think\db\exception\DataNotFoundException
  269. * @throws \think\db\exception\ModelNotFoundException
  270. * @throws \think\exception\DbException
  271. */
  272. public static function cacheKeyCreateOrderBatch(
  273. $uid,
  274. $key,
  275. $addressId,
  276. $payType,
  277. $useIntegral = false,
  278. $couponId = 0,
  279. $mark = '',
  280. $combinationId = 0,
  281. $pinkId = 0,
  282. $seckill_id = 0,
  283. $bargain_id = 0,
  284. $test = false,
  285. $isChannel = 0,
  286. $shipping_type = 1,
  287. $real_name = '',
  288. $phone = '',
  289. $storeId = 0
  290. ) {
  291. StoreOrder::beginTrans();
  292. try {
  293. $shipping_type = (int)$shipping_type;
  294. // 支付方式判断
  295. $offlinePayStatus = (int)sys_config('offline_pay_status') ?? (int)2; //线下支付状态 2 关闭
  296. if ($offlinePayStatus == 2) {
  297. unset(StoreOrder::$payType['offline']);
  298. }
  299. if (!array_key_exists($payType, StoreOrder::$payType)) {
  300. return self::setErrorInfo('选择支付方式有误!', true);
  301. }
  302. // 查总订单 sql-1
  303. if (self::be(['unique' => $key, 'uid' => $uid])) {
  304. return self::setErrorInfo('请勿重复提交订单', true);
  305. }
  306. // 用户信息 sql-2
  307. $userInfo = User::getUserInfo($uid);
  308. if (!$userInfo) return self::setErrorInfo('用户不存在!', true);
  309. // 取订单缓存
  310. $cartGroup = self::getCacheOrderInfo($uid, $key);
  311. if (!$cartGroup) return self::setErrorInfo('订单已过期,请刷新当前页面!', true);
  312. $cartInfo = $cartGroup['cartInfo'];
  313. $priceGroup = $cartGroup['priceGroup'];
  314. $other = $cartGroup['other'];
  315. // $payPrice = (float)$priceGroup['totalPrice'];
  316. // 收货地址 sql-3
  317. $addr = UserAddress::where('uid', $uid)->where('id', $addressId)->find();
  318. // if ($payType == 'offline' && sys_config('offline_postage') == 1) {
  319. // $payPostage = 0;
  320. // } else {
  321. // $payPostage = $priceGroup['storePostage'];
  322. // }
  323. if ($shipping_type === 1) {
  324. if (!$test && !$addressId) {
  325. return self::setErrorInfo('请选择收货地址!', true);
  326. }
  327. // sql-4,5
  328. if (!$test && (!UserAddress::be(['uid' => $uid, 'id' => $addressId, 'is_del' => 0]) || !($addressInfo = UserAddress::find($addressId))))
  329. return self::setErrorInfo('地址选择有误!', true);
  330. } else {
  331. if ((!$real_name || !$phone) && !$test) {
  332. return self::setErrorInfo('请填写姓名和电话', true);
  333. }
  334. $addressInfo['real_name'] = $real_name;
  335. $addressInfo['phone'] = $phone;
  336. $addressInfo['province'] = '';
  337. $addressInfo['city'] = '';
  338. $addressInfo['district'] = '';
  339. $addressInfo['detail'] = '';
  340. }
  341. $totalPrice = 0.0;
  342. $totalPayPrice = 0.0;
  343. $SurplusIntegral = 0;
  344. $totalPostage = 0.0;
  345. $totalDeductionPrice = 0.0;
  346. $totalCouponPrice = 0.0;
  347. $counter = 0;
  348. $subOrders = [];
  349. // 子订单逐个处理
  350. foreach ($cartInfo as $ci) {
  351. $counter += 1;
  352. // 一个订单的购物车
  353. $subOrderCart = [$ci];
  354. $subOrderId = StoreOrder::getNewOrderId();
  355. $subPriceGroup = StoreOrder::getOrderPriceGroup($subOrderCart, $addr);
  356. if (!$subPriceGroup) {
  357. return false;
  358. }
  359. $payPrice = (float)$subPriceGroup['totalPrice'];
  360. $totalPrice = (float)bcadd($totalPrice, $payPrice, 2);
  361. $cartIds = []; // 子订单购物车ID
  362. $totalNum = 0; // 总数量
  363. $gainIntegral = 0; // 总可得积分
  364. foreach ($subOrderCart as $cart) {
  365. // sql-6 x n
  366. if (!$test && !StoreOrder::checkProductStock($uid, $cart['product_id'], $cart['cart_num'], $cart['product_attr_unique'], $cart['combination_id'], $cart['seckill_id'], $cart['bargain_id'])) {
  367. return false;
  368. }
  369. $cartIds[] = $cart['id'];
  370. $totalNum += $cart['cart_num'];
  371. if (!$seckill_id) $seckill_id = $cart['seckill_id'];
  372. if (!$bargain_id) $bargain_id = $cart['bargain_id'];
  373. if (!$combinationId) $combinationId = $cart['combination_id'];
  374. // 可赚积分
  375. $cartInfoGainIntegral = isset($cart['productInfo']['give_integral']) ? bcmul($cart['cart_num'], $cart['productInfo']['give_integral'], 2) : 0;
  376. // 汇总
  377. $gainIntegral = bcadd($gainIntegral, $cartInfoGainIntegral, 2);
  378. } // foreach
  379. // 活动
  380. $deduction = $seckill_id || $bargain_id || $combinationId;
  381. if ($deduction) {
  382. $couponId = 0;
  383. $useIntegral = false;
  384. if (!$test) {
  385. unset(StoreOrder::$payType['offline']);
  386. if (!array_key_exists($payType, StoreOrder::$payType)) {
  387. return self::setErrorInfo('营销产品不能使用线下支付!', true);
  388. }
  389. }
  390. } //
  391. //使用优惠劵
  392. $res1 = true;
  393. if ($couponId) {
  394. $couponInfo = StoreCouponUser::validAddressWhere()->where('id', $couponId)->where('uid', $uid)->find();
  395. if (!$couponInfo) return self::setErrorInfo('选择的优惠劵无效!', true);
  396. $coupons = StoreCouponUser::getUsableCouponList($uid, ['valid' => $subOrderCart], $payPrice);
  397. $flag = false;
  398. foreach ($coupons as $coupon) {
  399. if ($coupon['id'] == $couponId) {
  400. $flag = true;
  401. continue;
  402. }
  403. }
  404. if (!$flag)
  405. return self::setErrorInfo('不满足优惠劵的使用条件!', true);
  406. $payPrice = (float)bcsub($payPrice, $couponInfo['coupon_price'], 2);
  407. $res1 = StoreCouponUser::useCoupon($couponId);
  408. $couponPrice = $couponInfo['coupon_price'];
  409. } else {
  410. $couponId = 0;
  411. $couponPrice = 0;
  412. }
  413. if (!$res1) {
  414. return self::setErrorInfo('使用优惠劵失败!', true);
  415. }
  416. $totalCouponPrice = (float)bcadd($totalCouponPrice, $couponPrice, 2);
  417. //$shipping_type = 1 快递发货 $shipping_type = 2 门店自提
  418. $store_self_mention = sys_config('store_self_mention') ?? 0;
  419. if (!$store_self_mention) $shipping_type = 1;
  420. $payPostage = 0;
  421. if ($shipping_type === 1) {
  422. //是否包邮
  423. if ((isset($other['offlinePostage']) && $other['offlinePostage'] && $payType == 'offline')) {
  424. $payPostage = 0;
  425. }
  426. $payPrice = (float)bcadd($payPrice, $payPostage, 2);
  427. } else if ($shipping_type === 2) {
  428. //门店自提没有邮费支付
  429. $subPriceGroup['storePostage'] = 0;
  430. $payPostage = 0;
  431. if (!$storeId && !$test) {
  432. return self::setErrorInfo('请选择门店', true);
  433. }
  434. }
  435. $totalPostage = (float)bcadd($totalPostage, $payPostage, 2);
  436. //积分抵扣
  437. $res2 = true;
  438. $usedIntegral = 0.0;
  439. if ($useIntegral && $userInfo['integral'] > 0) {
  440. $deductionPrice = (float)bcmul($userInfo['integral'], $other['integralRatio'], 2);
  441. if ($deductionPrice < $payPrice) {
  442. $payPrice = bcsub($payPrice, $deductionPrice, 2);
  443. $usedIntegral = $userInfo['integral'];
  444. $SurplusIntegral = 0;
  445. // sql
  446. $res2 = false !== User::edit(['integral' => 0], $userInfo['uid'], 'uid');
  447. } else {
  448. $deductionPrice = $payPrice;
  449. $usedIntegral = (float)bcdiv($payPrice, $other['integralRatio'], 2);
  450. $SurplusIntegral = bcsub($userInfo['integral'], $usedIntegral, 2);
  451. $res2 = false !== User::bcDec($userInfo['uid'], 'integral', $usedIntegral, 'uid');
  452. $payPrice = 0;
  453. }
  454. $res2 = $res2 && false != UserBill::expend('积分抵扣', $uid, 'integral', 'deduction', $usedIntegral, $subOrderId, $userInfo['integral'], '购买商品使用' . floatval($usedIntegral) . '积分抵扣' . floatval($deductionPrice) . '元');
  455. } else {
  456. $deductionPrice = 0;
  457. $usedIntegral = 0;
  458. }
  459. if (!$res2) {
  460. return self::setErrorInfo('使用积分抵扣失败!', true);
  461. }
  462. // fix at runtime
  463. $userInfo['integral'] = (float)bcsub($userInfo['integral'], $usedIntegral, 2);
  464. if ($userInfo['integral'] < 0) {
  465. $userInfo['integral'] = 0;
  466. }
  467. $totalDeductionPrice = (float)bcadd($totalDeductionPrice, $deductionPrice, 2);
  468. $totalPayPrice = (float)bcadd($totalPayPrice, $payPrice, 2);
  469. if ($test) {
  470. continue;
  471. }
  472. $unique = mb_substr($key, 0, mb_strlen($key) - 3) . $counter;
  473. // 增加子订单
  474. $orderInfo = [
  475. 'uid' => $uid,
  476. 'order_id' => $test ? 0 : $subOrderId,
  477. 'real_name' => $addressInfo['real_name'],
  478. 'user_phone' => $addressInfo['phone'],
  479. 'user_address' => $addressInfo['province'] . ' ' . $addressInfo['city'] . ' ' . $addressInfo['district'] . ' ' . $addressInfo['detail'],
  480. 'cart_id' => $cartIds,
  481. 'total_num' => $totalNum,
  482. 'total_price' => $subPriceGroup['totalPrice'],
  483. 'total_postage' => $subPriceGroup['storePostage'],
  484. 'coupon_id' => $couponId,
  485. 'coupon_price' => $couponPrice,
  486. 'pay_price' => $payPrice,
  487. 'pay_postage' => $payPostage,
  488. 'deduction_price' => $deductionPrice,
  489. 'paid' => 0,
  490. 'pay_type' => $payType,
  491. 'use_integral' => $usedIntegral,
  492. 'gain_integral' => $gainIntegral,
  493. 'mark' => htmlspecialchars($mark),
  494. 'combination_id' => $combinationId,
  495. 'pink_id' => $pinkId,
  496. 'seckill_id' => $seckill_id,
  497. 'bargain_id' => $bargain_id,
  498. 'cost' => $subPriceGroup['costPrice'],
  499. 'is_channel' => $isChannel,
  500. 'add_time' => time(),
  501. 'unique' => $unique,
  502. 'shipping_type' => $shipping_type,
  503. ];
  504. if ($shipping_type === 2) {
  505. $orderInfo['verify_code'] = StoreOrder::getStoreCode();
  506. $orderInfo['store_id'] = SystemStore::getStoreDispose($storeId, 'id');
  507. if (!$orderInfo['store_id']) return self::setErrorInfo('暂无门店无法选择门店自提!', true);
  508. }
  509. $order = StoreOrder::create($orderInfo);
  510. if (!$order) {
  511. return self::setErrorInfo('订单生成失败!', true);
  512. }
  513. $res5 = true;
  514. foreach ($subOrderCart as $cart) {
  515. //减库存加销量
  516. if ($combinationId) {
  517. $res5 = $res5 && StoreCombination::decCombinationStock($cart['cart_num'], $combinationId, isset($cart['productInfo']['attrInfo']) ? $cart['productInfo']['attrInfo']['unique'] : '');
  518. } else if ($seckill_id) {
  519. $res5 = $res5 && StoreSeckill::decSeckillStock($cart['cart_num'], $seckill_id, isset($cart['productInfo']['attrInfo']) ? $cart['productInfo']['attrInfo']['unique'] : '');
  520. } else if ($bargain_id) {
  521. $res5 = $res5 && StoreBargain::decBargainStock($cart['cart_num'], $bargain_id, isset($cart['productInfo']['attrInfo']) ? $cart['productInfo']['attrInfo']['unique'] : '');
  522. } else {
  523. $res5 = $res5 && StoreProduct::decProductStock($cart['cart_num'], $cart['productInfo']['id'], isset($cart['productInfo']['attrInfo']) ? $cart['productInfo']['attrInfo']['unique'] : '');
  524. }
  525. }
  526. //保存购物车商品信息
  527. $res4 = false !== StoreOrderCartInfo::setCartInfo($order['id'], $subOrderCart);
  528. //购物车状态修改
  529. $res6 = false !== StoreCart::where('id', 'IN', $cartIds)->update(['is_pay' => 1]);
  530. if (!$res4 || !$res5 || !$res6) {
  531. return self::setErrorInfo('订单生成失败!', true);
  532. }
  533. StoreOrderStatus::status($order['id'], 'cache_key_create_order', '订单生成');
  534. $subOrders[] = $order;
  535. } // foreach
  536. if ($totalPayPrice <= 0) $totalPayPrice = 0;
  537. if ($test) {
  538. StoreOrder::rollbackTrans();
  539. return [
  540. 'total_price' => $totalPrice,
  541. 'pay_price' => $totalPayPrice,
  542. 'pay_postage' => $totalPostage,
  543. 'coupon_price' => $totalCouponPrice,
  544. 'deduction_price' => $totalDeductionPrice,
  545. 'SurplusIntegral' => $SurplusIntegral,
  546. ];
  547. }
  548. $pOrderId = self::getNewPOrderId();
  549. foreach ($subOrders as $subOrder) {
  550. $porderInfo = [
  551. 'porder_id' => $pOrderId,
  552. 'oid' => $subOrder['id'],
  553. 'total_price' => $totalPayPrice,
  554. 'unique' => $key,
  555. 'uid' => $uid,
  556. ];
  557. $porder = self::create($porderInfo);
  558. if (!$porder) {
  559. return self::setErrorInfo('订单生成失败!', true);
  560. }
  561. }
  562. //自动设置默认地址
  563. if (count($subOrders)) {
  564. UserRepository::storeProductOrderCreateEbApi($subOrders[0], compact('cartInfo', 'addressId'));
  565. }
  566. StoreOrder::clearCacheOrderInfo($uid, $key);
  567. StoreOrder::commitTrans();
  568. return $pOrderId;
  569. } catch (\PDOException $e) {
  570. StoreOrder::rollbackTrans();
  571. return self::setErrorInfo('生成订单时SQL执行错误错误原因:' . $e->getMessage());
  572. } catch (\Exception $e) {
  573. StoreOrder::rollbackTrans();
  574. return self::setErrorInfo('生成订单时系统错误错误原因:' . $e->getMessage());
  575. }
  576. }
  577. }