CheckoutZa.php 47 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205
  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\member\DeductionLimit as DeductionLimitModel;
  19. use app\api\model\member\GoldRice as GoldRiceModel;
  20. use app\api\model\OrderGoodsTaocan as OrderGoodsTaocanModel;
  21. use app\api\model\Order as OrderModel;
  22. use app\api\model\PromotionMonitor;
  23. use app\api\model\User as UserModel;
  24. use app\api\model\Goods as GoodsModel;
  25. use app\api\model\Setting as SettingModel;
  26. use app\api\model\shop\Shops;
  27. use app\api\model\UserAddress;
  28. use app\api\model\UserCoupon as UserCouponModel;
  29. use app\api\service\User as UserService;
  30. use app\api\service\Payment as PaymentService;
  31. use app\api\service\coupon\GoodsDeduct as GoodsDeductService;
  32. use app\api\service\ricecard\GoodsDeduct as RiceDeductService;
  33. use app\api\service\points\GoodsDeduct as PointsDeductService;
  34. use app\api\service\order\source\checkout\Factory as CheckoutFactory;
  35. use app\common\enum\Setting as SettingEnum;
  36. use app\common\enum\order\PayType as OrderPayTypeEnum;
  37. use app\common\enum\order\OrderStatus as OrderStatusEnum;
  38. use app\common\enum\order\OrderSource as OrderSourceEnum;
  39. use app\common\enum\order\DeliveryType as DeliveryTypeEnum;
  40. use app\common\service\BaseService;
  41. use app\common\service\card\UserRiceCard as UserRiceCardService;
  42. use app\common\service\commission\RecordWaitCommission;
  43. use app\common\service\delivery\Express as ExpressService;
  44. use app\common\service\goods\source\Factory as StockFactory;
  45. use app\common\library\helper;
  46. use app\common\exception\BaseException;
  47. use app\common\enum\order\PayStatus as PayStatusEnum;
  48. use app\common\model\ShopGoodsSku;
  49. use app\common\model\User;
  50. use http\Header\Parser;
  51. use app\api\model\za\{ZaActivityRelation,ZaActivityGood,ZaActivity};
  52. /**
  53. * 订单结算台服务类
  54. * Class Checkout
  55. * @package app\api\service\order
  56. */
  57. class CheckoutZa extends BaseService
  58. {
  59. /* $model OrderModel 订单模型 */
  60. public $model;
  61. /* @var UserModel $user 当前用户信息 */
  62. private $user;
  63. // 订单结算商品列表
  64. private $goodsList = [];
  65. // 错误信息
  66. protected $error;
  67. // 错误信息状态
  68. protected $errorStatus;
  69. /**
  70. * 订单结算api参数
  71. * @var array
  72. */
  73. private $param = [
  74. 'delivery' => null, // 配送方式 默认:快递配送
  75. 'couponId' => 0, // 优惠券id
  76. 'riceCardId' => 0, // 现金米卡id
  77. 'isUsePoints' => 0, // 是否使用积分抵扣
  78. 'isUseGoldRice' => 1, // 默认使用金米粒
  79. 'remark' => '', // 买家留言
  80. 'payType' => OrderPayTypeEnum::WECHAT, // 支付方式
  81. 'addressId' => 0, //地址ID
  82. 'staffUserId' => 0, //分享链接用户ID
  83. ];
  84. /**
  85. * 订单结算的规则
  86. * @var array
  87. */
  88. private $checkoutRule = [
  89. 'isUserGrade' => false, // 会员等级折扣
  90. 'isCoupon' => true, // 优惠券抵扣
  91. 'isRiceCard' => true, // 现金米卡抵扣
  92. 'isUsePoints' => false, // 是否使用积分抵扣
  93. ];
  94. /**
  95. * 订单来源
  96. * @var array
  97. */
  98. private $orderSource = [
  99. 'source' => OrderSourceEnum::ZA,
  100. 'source_id' => 0,
  101. ];
  102. /**
  103. * 订单结算数据
  104. * @var array
  105. */
  106. private $orderData = [];
  107. /**
  108. * 构造函数
  109. * Checkout constructor.
  110. * @throws BaseException
  111. */
  112. public function __construct()
  113. {
  114. parent::__construct();
  115. $this->user = UserService::getCurrentLoginUser(true);
  116. $this->model = new OrderModel;
  117. $this->storeId = $this->getStoreId();
  118. }
  119. /**
  120. * 设置结算台请求的参数
  121. * @param $param
  122. * @return array
  123. */
  124. public function setParam($param)
  125. {
  126. $this->param = array_merge($this->param, $param);
  127. return $this->getParam();
  128. }
  129. /**
  130. * 获取结算台请求的参数
  131. * @return array
  132. */
  133. public function getParam()
  134. {
  135. return $this->param;
  136. }
  137. /**
  138. * 订单结算的规则
  139. * @param $data
  140. * @return $this
  141. */
  142. public function setCheckoutRule($data)
  143. {
  144. $this->checkoutRule = array_merge($this->checkoutRule, $data);
  145. return $this;
  146. }
  147. /**
  148. * 设置订单来源(普通订单)
  149. * @param $data
  150. * @return $this
  151. */
  152. public function setOrderSource($data)
  153. {
  154. $this->orderSource = array_merge($this->orderSource, $data);
  155. return $this;
  156. }
  157. /**
  158. * 订单确认-结算台
  159. * @param $goodsList
  160. * @return array
  161. * @throws BaseException
  162. * @throws \think\db\exception\DataNotFoundException
  163. * @throws \think\db\exception\DbException
  164. * @throws \think\db\exception\ModelNotFoundException
  165. */
  166. public function onCheckout($goodsList)
  167. {
  168. // 订单确认-立即购买
  169. $this->goodsList = $goodsList;
  170. return $this->checkout();
  171. }
  172. /**
  173. * 订单结算台
  174. * @return array
  175. * @throws BaseException
  176. * @throws \think\db\exception\DataNotFoundException
  177. * @throws \think\db\exception\DbException
  178. * @throws \think\db\exception\ModelNotFoundException
  179. */
  180. private function checkout()
  181. {
  182. // 整理订单数据
  183. $this->orderData = $this->getOrderData();
  184. // 验证商品状态, 是否允许购买
  185. $this->validateGoodsList();
  186. $this->setShopPickupData();
  187. // 设置订单商品总金额()
  188. $this->setOrderTotalPrice();
  189. //订单总运费金额
  190. $this->setOrderExpress();
  191. //金米粒抵扣-V1.4.0版本添加2022年6月6日
  192. $this->setOrderGolRiceAmount();
  193. //获取当前可用的现金卡列表
  194. $userRiceCardList = $this->getUserRiceCardList();
  195. //计算使用米卡现金券抵扣后的金额
  196. $this->setOrderRiceCardMoney($userRiceCardList,(int)$this->param['riceCardId']);
  197. // 计算订单商品的实际付款金额
  198. $this->setOrderGoodsPayPrice();
  199. // 计算订单最终金额+运费
  200. $this->setOrderPayPrice();
  201. //订单商品的所有店铺集合2021年9月28日 10:56:45
  202. $this->setOrderProviderIds();
  203. // 订单商品总数量
  204. $orderTotalNum = helper::getArrayColumnSum($this->goodsList, 'total_num');
  205. // 返回订单数据
  206. return array_merge([
  207. 'goodsList' => $this->goodsList, // 商品信息
  208. 'orderTotalNum' => $orderTotalNum, // 商品总数量
  209. // 'couponList' => array_values($couponList), // 优惠券列表
  210. 'hasError' => $this->hasError(),
  211. 'errorMsg' => $this->getError(),
  212. 'errorStatus' => $this->getErrorStatus(),
  213. ], $this->orderData);
  214. }
  215. /**
  216. * 门店自提处理
  217. */
  218. public function setShopPickupData() {
  219. $deliveryType = $this->param['delivery'];
  220. // 返回商品处理
  221. $normalGoodsList = []; // 正常状态商品
  222. $invalidGoodsList = []; // 无货状态商品
  223. // 门店信息
  224. $userStaff = User::detail($this->param['staffUserId']);
  225. $shopInfo = [];
  226. $isPickup = false;
  227. if (!empty($userStaff) && $userStaff['role'] == User::SHOP_SELLER) {
  228. $shopInfo = Shops::find($userStaff['shop_id']);
  229. if ($shopInfo['is_pickup']) {
  230. $isPickup = true;
  231. }
  232. }
  233. if ($deliveryType == DeliveryTypeEnum::SHOPS_DELIVERY) {
  234. if (empty($shopInfo)) {
  235. // 门店自提方式 且门店不存在
  236. throwError("不支持门店自提方式");
  237. }
  238. if (!$shopInfo['is_pickup']) {
  239. // 门店自提开关
  240. throwError("不支持门店自提方式");
  241. }
  242. }
  243. // 门店库存总和
  244. $shopStockTotal = 0;
  245. foreach($this->goodsList as &$item) {
  246. // 获取商品门店库存
  247. if ($shopInfo) {
  248. $shopGoodsSku = ShopGoodsSku::with('shopGoods')->where(['shop_id' => $shopInfo['shop_id'], 'goods_id' => $item['goods_id'], 'goods_sku_id' => $item['goods_sku_id']])->find();
  249. if (!empty($shopGoodsSku) && $shopGoodsSku['stock_num'] > 0) {
  250. $shopStockTotal += $shopGoodsSku['stock_num'];
  251. }
  252. }
  253. // 判断配送方式
  254. if ($deliveryType == DeliveryTypeEnum::EXPRESS) { // 快递配送
  255. $normalGoodsList[] = $item;
  256. // 判断库存 todo 购买数量大于实际库存 取实际库存
  257. // 有库存
  258. if ($item['skuInfo']['stock_num'] >= $item['total_num']) {
  259. $item['stock_enough'] = true;
  260. } else {
  261. $item['stock_enough'] = false;
  262. $item['total_num'] = $item['skuInfo']['stock_num']; // 库存不够时,取最大库存
  263. $item['total_price'] = helper::bcmul($item['goods_price'], $item['total_num']);
  264. }
  265. if($item['skuInfo']['stock_num'] < 2){
  266. $item['stock_enough'] = false;
  267. }
  268. $item['is_pickup_invalid'] = false;
  269. } elseif ($deliveryType == DeliveryTypeEnum::SHOPS_DELIVERY) { // 门店自提
  270. // 判断有无库存
  271. if (!empty($shopGoodsSku)) {
  272. $item['stock_total'] = $shopGoodsSku['shopGoods']['stock_total'];
  273. $item['alarm_stock_total'] = $shopGoodsSku['shopGoods']['alarm_stock_total'];
  274. $item['skuInfo']['stock_num'] = $shopGoodsSku['stock_num'];
  275. $item['skuInfo']['alarm_stock_num'] = $shopGoodsSku['alarm_stock_num'];
  276. if ($shopGoodsSku['stock_num'] > 0) {
  277. // 有库存
  278. if ($shopGoodsSku['stock_num'] >= $item['total_num']) {
  279. $item['stock_enough'] = true;
  280. } else {
  281. $item['stock_enough'] = false;
  282. $item['total_num'] = $shopGoodsSku['stock_num']; // 库存不够时,取最大库存
  283. $item['total_price'] = helper::bcmul($item['goods_price'], $item['total_num']);
  284. }
  285. $normalGoodsList[] = $item;
  286. } else {
  287. // 没有库存
  288. $item['stock_enough'] = false;
  289. $item['is_pickup_invalid'] = true;
  290. $invalidGoodsList[] = $item;
  291. }
  292. } else {
  293. // 无库存
  294. // $item['stock_total'] = 0;
  295. // $item['alarm_stock_total'] = 0;
  296. // $item['skuInfo']['stock_num'] = 0;
  297. // $item['skuInfo']['alarm_stock_num'] = 0;
  298. $item['stock_enough'] = false;
  299. // $item['total_num'] = 0; // 无门店库存
  300. // $item['total_price'] = 0;
  301. $item['is_pickup_invalid'] = true;
  302. $invalidGoodsList[] = $item;
  303. }
  304. }
  305. }
  306. if ($shopStockTotal <= 0) { // 门店总库存不大于0
  307. $isPickup = false;
  308. }
  309. $this->shopInfo = $shopInfo; // 门店信息
  310. $this->isPickup = $isPickup; // 是否支持门店自提
  311. $this->orderData['shopInfo'] = $shopInfo;
  312. // $this->goodsList = $normalGoodsList;
  313. // $this->invalidGoodsList = $invalidGoodsList;
  314. }
  315. /**
  316. * 设置订单使用金米粒抵扣信息
  317. * @return bool
  318. * @throws BaseException
  319. */
  320. private function setOrderGolRiceAmount()
  321. {
  322. // 设置默认数据:订单信息
  323. helper::setDataAttribute($this->orderData, [
  324. 'goldRiceAmount' => 0, // 金米粒抵扣总数量 1金米粒=0.01元
  325. 'goldRiceMoney' => 0.00, // 金米粒抵扣总金额
  326. ], false);
  327. // 设置默认数据:订单商品列表
  328. helper::setDataAttribute($this->goodsList, [
  329. 'gold_rice_amount' => 0, // 金米粒抵扣数量
  330. 'gold_rice_money' => 0, // 金米粒抵扣金额
  331. ], true);
  332. $this->orderData['isUseGoldRice'] = -1;
  333. return false;
  334. // if($this->orderData['isUseGoldRice']<1){//没有使用金米粒
  335. // return false;
  336. // }
  337. // $orderTotalPrice = $this->orderData['orderTotalBargainPrice']; //实际支付金额
  338. // // 如果没有可用的金米粒,直接返回
  339. // $DeductionLimit = DeductionLimitModel::where('id','>',0)->find();
  340. // $score = floor($DeductionLimit['discount']*$orderTotalPrice);
  341. // //不够起用数量
  342. // if($score<$DeductionLimit['score']){
  343. // $this->orderData['isUseGoldRice'] = -1;
  344. // return false;
  345. // }
  346. // //用户可用金米粒数量不够起用数量
  347. // if($this->user['gold_rice']<$DeductionLimit['score']){
  348. // $this->orderData['isUseGoldRice'] = -1;
  349. // return false;
  350. // }
  351. // if($score>$this->user['gold_rice']){
  352. // $score = $this->user['gold_rice'];
  353. // }
  354. // // 获取优惠券信息
  355. // $goodsListTemp = [];
  356. // foreach ($this->goodsList as $key=> $good){
  357. // $goodsListTemp[$key]['total_price'] = helper::bcsub($good['bargain_price'],0);
  358. // }
  359. // $RiceMoney = new RiceDeductService;
  360. // $gold_rice_money = helper::bcdiv($score,100);
  361. // $completed = $RiceMoney->setGoodsCouponMoney($goodsListTemp, $gold_rice_money);
  362. // // 分配订单商品抵扣的金米粒数量
  363. // foreach ($this->goodsList as $key => &$goods) {
  364. // $goods['gold_rice_amount'] = isset($completed[$key]['rice_card_money']) ? $completed[$key]['rice_card_money'] : 0;
  365. // $goods['gold_rice_money'] = helper::bcdiv($goods['gold_rice_amount'],100);
  366. // }
  367. // // 记录订单抵扣的金米粒数量
  368. // $this->orderData['goldRiceAmount'] = $score;
  369. // $this->orderData['goldRiceMoney'] = $gold_rice_money;
  370. // return true;
  371. }
  372. //我的可用现金卡
  373. public function getUserRiceCardList(){
  374. $user = UserService::getCurrentLoginUser(true);
  375. $list = UserRiceCardModel::getUserRiceCardList($user['user_id'])->toArray();
  376. $data = [];
  377. foreach ($list as $key=>&$item){
  378. $i = 0;
  379. $exceptGoodsId = helper::getArrayColumn($item['riceCardGoodsExcept'],'goods_id');
  380. foreach ($this->goodsList as $good) {
  381. if(!empty($item['dk_cat_ids']) && strpos((string)$item['dk_cat_ids'],(string)$good['category']['category_id']) === false){
  382. unset($list[$key]);
  383. $i = 1;
  384. }
  385. if(!empty($exceptGoodsId) && in_array($good['goods_id'],$exceptGoodsId)){
  386. unset($list[$key]);
  387. $i = 1;
  388. }
  389. }
  390. if(!$i){
  391. unset($item['riceCardGoodsExcept']);
  392. $data[$item['id']] = $item;
  393. }
  394. }
  395. if($this->param['riceCardId']==0){ //-1表示不使用米卡
  396. $this->param['riceCardId'] = key($data)??0;//若果没有选择米卡,默认使用第一张
  397. }
  398. return $data;
  399. }
  400. /**
  401. * 整理订单数据(结算台初始化)
  402. * @return array
  403. * @throws \think\db\exception\DataNotFoundException
  404. * @throws \think\db\exception\DbException
  405. * @throws \think\db\exception\ModelNotFoundException
  406. */
  407. private function getOrderData()
  408. {
  409. // 系统支持的配送方式 (后台设置)
  410. $deliveryType = SettingModel::getItem(SettingEnum::DELIVERY)['delivery_type'];
  411. return [
  412. 'order_source_id'=>$this->param['zaGoodsId'],
  413. // 当前配送类型
  414. 'delivery' => $this->param['delivery'] > 0 ? $this->param['delivery'] : $deliveryType[0],
  415. // 默认地址
  416. 'address' => '',
  417. // 是否存在收货地址
  418. 'existAddress' => $this->user['address_id'] > 0,
  419. // 配送费用
  420. 'expressPrice' => 0.00,
  421. //是否使用了金米粒
  422. 'isUseGoldRice' => $this->param['isUseGoldRice'],
  423. //金米粒数量
  424. 'userGoldRiceNum' => $this->user['gold_rice']??0,
  425. // 当前用户收货城市是否存在配送规则中
  426. 'isIntraRegion' => true,
  427. // 是否允许使用积分抵扣
  428. 'isAllowPoints' => false,
  429. // 是否使用积分抵扣
  430. 'isUsePoints' => $this->param['isUsePoints'],
  431. // 积分抵扣金额
  432. 'pointsMoney' => 0.00,
  433. // 赠送的积分数量
  434. 'pointsBonus' => 0,
  435. // 支付方式
  436. 'payType' => $this->param['payType'],
  437. // 系统设置
  438. 'setting' => $this->getSetting(),
  439. // 推广监控ID
  440. "promotionMonitorId" => $this->param['promotionMonitorId'] ?? 0
  441. ];
  442. }
  443. /**
  444. * 获取订单页面中使用到的系统设置
  445. * @return array
  446. * @throws \think\db\exception\DataNotFoundException
  447. * @throws \think\db\exception\DbException
  448. * @throws \think\db\exception\ModelNotFoundException
  449. */
  450. private function getSetting()
  451. {
  452. // 系统支持的配送方式 (后台设置)
  453. $deliveryType = SettingModel::getItem(SettingEnum::DELIVERY)['delivery_type'];
  454. // 积分设置
  455. $pointsSetting = SettingModel::getItem(SettingEnum::POINTS);
  456. return [
  457. 'deliveryType' => $deliveryType, // 支持的配送方式
  458. 'points_name' => $pointsSetting['points_name'], // 积分名称
  459. 'points_describe' => $pointsSetting['describe'], // 积分说明
  460. ];
  461. }
  462. /**
  463. * 验证订单商品的状态
  464. * @return bool
  465. */
  466. private function validateGoodsList()
  467. {
  468. $Checkout = CheckoutFactory::getFactory(
  469. $this->user,
  470. $this->goodsList,
  471. $this->orderData['delivery'],
  472. $this->shopInfo['shop_id'] ?? 0,
  473. $this->orderSource['source']
  474. );
  475. $status = $Checkout->validateGoodsList();
  476. if(!$status){
  477. $this->setError($Checkout->getError());
  478. $this->setErrorStatus(422);
  479. }
  480. return $status;
  481. }
  482. /**
  483. * 设置订单的商品总金额(不含优惠折扣)
  484. */
  485. private function setOrderTotalPrice()
  486. {
  487. // 订单商品的总金额
  488. $this->orderData['orderTotalPrice'] = helper::number2(helper::getArrayColumnSum($this->goodsList, 'total_price'));
  489. // //砍价总金额
  490. // $this->orderData['orderTotalBargainPrice'] = helper::number2(helper::getArrayColumnSum($this->goodsList, 'bargain_price'));
  491. }
  492. /**
  493. * 订单商品的所有店铺集合
  494. */
  495. private function setOrderProviderIds()
  496. {
  497. // 订单商品的所有店铺集合
  498. $this->orderData['orderProviderIds'] = implode(',',array_values(array_unique(helper::getArrayColumn($this->goodsList, 'provider_id'))));
  499. }
  500. /**
  501. * 设置订单的实际支付金额(含配送费)
  502. */
  503. private function setOrderPayPrice()
  504. {
  505. // 订单金额(含优惠折扣)
  506. //(商品总价 - N件X折 - 优惠券 - 分销员)+ 运费 = 微信支付+米卡抵扣+米卡抵扣运费
  507. //(total_price-coupon_money-distrbutor_total_money)+express_price = pay_price+rice_card_money+rice_card_express_money
  508. $this->orderData['orderPrice'] = helper::number2(helper::getArrayColumnSum($this->goodsList, 'total_pay_price'));
  509. // 订单实付款金额(订单金额 + 运费 - 金米粒抵扣金额 - 现金卡运费抵扣金额)
  510. $this->orderData['orderPayPrice'] = helper::number2(helper::bcadd($this->orderData['orderPrice'], $this->orderData['expressPrice']-$this->orderData['riceCardExpressMoney']));
  511. }
  512. /**
  513. * 计算订单商品的实际付款金额
  514. * @return bool
  515. */
  516. private function setOrderGoodsPayPrice()
  517. {
  518. // 商品总价 - 优惠抵扣
  519. foreach ($this->goodsList as &$goods) {
  520. //减去金米粒抵扣金额和现金米卡抵扣的金额
  521. $value = helper::bcsub($goods['total_price'], $goods['rice_card_money']+$goods['gold_rice_money']);
  522. $goods['total_pay_price'] = helper::number2($value);
  523. }
  524. return true;
  525. }
  526. /**
  527. * 设置订单现金米卡抵扣信息
  528. * @param int $riceCardId 可使用米卡列表
  529. * @param int $riceCardId 当前选择的现金米卡id
  530. * @return bool
  531. * @throws BaseException
  532. */
  533. private function setOrderRiceCardMoney($userRiceCardList,int $riceCardId)
  534. {
  535. // 设置默认数据:订单信息
  536. helper::setDataAttribute($this->orderData, [
  537. 'riceCardId' => $riceCardId, // 用户现金米卡id
  538. 'riceCardMoney' => 0, // 现金米卡抵扣总金额
  539. 'riceCardExpressMoney' => 0, // 现金米卡抵扣运费
  540. 'userRiceCardList' => [], // 米卡列表
  541. 'userRiceCard' => [], // 已选择的米卡
  542. ], false);
  543. // 设置默认数据:订单商品列表
  544. helper::setDataAttribute($this->goodsList, [
  545. 'rice_card_id' => 0, // 用户现金米卡id
  546. 'rice_card_money' => 0, // 金米卡抵扣金额
  547. ], true);
  548. if($riceCardId<0){//如果米卡ID小于0表示不使用,但是也要返回可使用列表
  549. $this->orderData['userRiceCardList'] = array_values($userRiceCardList);
  550. return true;
  551. }
  552. // 验证选择的优惠券ID是否合法
  553. if (!$this->verifyUserRiceCard($riceCardId, $userRiceCardList)) {
  554. return false;
  555. }
  556. // 获取优惠券信息
  557. $riceCard = $this->getRiceCardInfo($riceCardId, $userRiceCardList);
  558. $goodsListTemp = [];
  559. foreach ($this->goodsList as $key=> $good){
  560. $goodsListTemp[$key]['total_price'] = helper::bcsub($good['total_price'],$good['gold_rice_money']);
  561. }
  562. $RiceMoney = new RiceDeductService;
  563. $completed = $RiceMoney->setGoodsCouponMoney($goodsListTemp, $riceCard['balance']);
  564. // 分配订单商品优惠券抵扣金额
  565. $rice_card_money = 0;
  566. foreach ($this->goodsList as $key => &$goods) {
  567. $goods['rice_card_money'] = isset($completed[$key]['rice_card_money']) ? $completed[$key]['rice_card_money'] / 100 : 0;
  568. $goods['rice_card_id'] = $riceCardId;
  569. $rice_card_money += $goods['rice_card_money'];
  570. }
  571. $orderPrice = $this->orderData['orderTotalPrice']-$this->orderData['goldRiceMoney']; //实际支付金额
  572. //有运费,并且现金米卡可用的金额大于商品总价
  573. $rice_card_express_money = 0;
  574. if($riceCard['balance']>$orderPrice && $this->orderData['expressPrice']>0){
  575. $residueMoney = $riceCard['balance']-$orderPrice;
  576. if($residueMoney-$this->orderData['expressPrice']>0){
  577. $rice_card_express_money += $this->orderData['expressPrice'];
  578. }else{
  579. $rice_card_express_money += $residueMoney;
  580. }
  581. }
  582. // 记录订单现金米卡信息
  583. $this->orderData['userRiceCard'] = $userRiceCardList[$riceCardId];
  584. $this->orderData['riceCardId'] = $riceCardId;
  585. $this->orderData['riceCardMoney'] = helper::bcmul($rice_card_money+$rice_card_express_money,1);
  586. $this->orderData['riceCardExpressMoney'] = helper::bcmul($rice_card_express_money,1);
  587. $this->orderData['userRiceCardList'] = array_values($userRiceCardList);
  588. return true;
  589. }
  590. /**
  591. * 验证用户选择的现金米卡
  592. * @param $riceCard
  593. * @return bool
  594. * @throws BaseException
  595. */
  596. private function verifyUserRiceCard($riceCardId,$userRiceCardList)
  597. {
  598. // 是否开启现金米卡抵扣
  599. if (!$this->checkoutRule['isRiceCard']) {
  600. return false;
  601. }
  602. // 如果没有可用的现金米卡,直接返回
  603. if ($riceCardId <= 0) {
  604. return false;
  605. }
  606. // 判断优惠券是否存在
  607. $riceCard = $this->getRiceCardInfo($riceCardId, $userRiceCardList);
  608. // 如果没有现金米卡,直接返回
  609. if (empty($riceCard)) {
  610. throwError('未找到米卡信息');
  611. }
  612. return true;
  613. }
  614. /**
  615. * 查找指定的优惠券信息
  616. * @param int $couponId 优惠券ID
  617. * @param array $couponList 优惠券列表
  618. * @return false|mixed
  619. */
  620. private function getRiceCardInfo(int $riceCardId, array $userRiceCardList)
  621. {
  622. return helper::getArrayItemByColumn($userRiceCardList, 'id', $riceCardId);
  623. }
  624. /**
  625. * 订单配送-快递配送
  626. * @return bool
  627. * @throws \think\db\exception\DataNotFoundException
  628. * @throws \think\db\exception\DbException
  629. * @throws \think\db\exception\ModelNotFoundException
  630. */
  631. private function setOrderExpress()
  632. {
  633. // 设置默认数据:配送费用
  634. helper::setDataAttribute($this->goodsList, [
  635. 'expressPrice' => 0,
  636. ], true);
  637. $cityId = 0;
  638. // 当前用户收货城市id
  639. if($this->param['addressId']){ //有传参
  640. $addredd = UserAddress::get(['user_id' => $this->user['user_id'], 'address_id' => $this->param['addressId']]);
  641. $cityId = $addredd ? (int)$addredd['city_id'] : 0;
  642. $this->orderData['address'] = $addredd;
  643. }else{ //没有传参读默认地址
  644. // $cityId = $this->user['address_default'] ? (int)$this->user['address_default']['city_id'] : 0;
  645. // var_dump('default');
  646. // var_dump($this->user['address_default']);
  647. // die();
  648. if($this->user['address_id']){
  649. $addredd = UserAddress::get(['user_id' => $this->user['user_id'], 'address_id' => $this->user['address_id']]);
  650. $cityId = $addredd ? (int)$addredd['city_id'] : 0;
  651. $this->orderData['address'] = $addredd;
  652. }else{
  653. $addredd = UserAddress::where(['user_id' => $this->user['user_id'],'default'=>1,'is_delete'=>0])->find();
  654. $cityId = $addredd ? (int)$addredd['city_id'] : 0;
  655. $this->orderData['address'] = $addredd;
  656. }
  657. }
  658. if ($this->param['delivery'] == DeliveryTypeEnum::EXPRESS) { // 普通快递
  659. // 初始化配送服务类
  660. $ExpressService = new ExpressService($cityId, $this->goodsList);
  661. // 验证商品是否在限购配送范围
  662. $isDeliveryLimit = $ExpressService->isDeliveryLimit();
  663. if($cityId > 0){
  664. if ($isDeliveryLimit == false) {
  665. $this->setError("很抱歉,您的收货地址在限购地区的配送范围内");
  666. $this->setErrorStatus(423);
  667. $this->orderData['isIntraRegion'] = $isDeliveryLimit;
  668. }else{
  669. // 验证商品是否在配送范围
  670. $isIntraRegion = $ExpressService->isIntraRegion();
  671. if ($isIntraRegion == false) {
  672. $notInRuleGoodsName = $ExpressService->getNotInRuleGoodsName();
  673. $this->setError("很抱歉,您的收货地址不在商品 [".limit_str((string)$notInRuleGoodsName)."] 的配送范围内");
  674. $this->setErrorStatus(423);
  675. }
  676. $this->orderData['isIntraRegion'] = $isIntraRegion;
  677. }
  678. }
  679. // 订单总运费金额
  680. $this->orderData['expressPrice'] = $ExpressService->getDeliveryFee();
  681. } else { // 门店自提
  682. $this->orderData['expressPrice'] = "0.00";
  683. }
  684. return true;
  685. }
  686. /**
  687. * 创建新订单
  688. * @param array $order 订单信息
  689. * @return bool
  690. */
  691. public function createOrder(array $order)
  692. {
  693. // 表单验证
  694. if (!$this->validateOrderForm($order)) {
  695. return false;
  696. }
  697. // 创建新的订单
  698. $status = $this->model->transaction(function () use ($order) {
  699. // dd($order);
  700. // 创建订单事件
  701. return $this->createOrderEvent($order);
  702. });
  703. // 余额支付标记订单已支付
  704. if ($status && $order['payType'] == OrderPayTypeEnum::BALANCE) {
  705. return $this->model->onPaymentByBalance($this->model['order_no']);
  706. }
  707. return $status;
  708. }
  709. /**
  710. * 创建订单事件
  711. * @param $order
  712. * @return bool
  713. * @throws BaseException
  714. * @throws \Exception
  715. */
  716. private function createOrderEvent($order)
  717. {
  718. // 门店自提
  719. if ($order['delivery'] == DeliveryTypeEnum::SHOPS_DELIVERY) {
  720. $order['hx_code'] = $this->model->hxCode();
  721. $order['pickup_deadline'] = time() + OrderModel::getPickupDeadline() * 60; // 提货截止时间:提交订单2天内
  722. $order['shop_id'] = $order['shopInfo']['shop_id']; // 订单自提门店id
  723. }
  724. // 新增订单记录
  725. $status = $this->add($order, $this->param['remark']);
  726. if ($order['delivery'] == DeliveryTypeEnum::EXPRESS) {
  727. // 记录收货地址
  728. $this->saveOrderAddress($order['address']);
  729. }
  730. // 保存订单商品信息
  731. $this->saveOrderGoods($order);
  732. // 保存订单套餐商品信息
  733. $this->saveOrderGoodsTaocan($order);
  734. if($order['payType']!=OrderPayTypeEnum::ACTIVITY){
  735. // 更新商品库存 (针对下单减库存的商品)
  736. $this->updateGoodsStockNum($order);
  737. // 更新多个活动的活动库存
  738. $this->updateActivityStock($order);
  739. //写入买一赠一信息
  740. $this->saveActivityRel($order);
  741. }
  742. //金米粒处理逻辑
  743. if($order['orderPayPrice']>0){
  744. //冻结金米粒数量
  745. if($order['goldRiceAmount']>0) UserModel::setIncDecByField($this->user['user_id'],['gold_rice_frozen'=>(float)$order['goldRiceAmount']],['gold_rice'=>(float)$order['goldRiceAmount']]);
  746. }else{
  747. if($order['goldRiceAmount']>0){
  748. //写金米粒出账记录
  749. GoldRiceModel::add($this->user['user_id'],$this->model['order_no'],'下单抵扣',$order['goldRiceAmount'],0);
  750. //用户直接扣除金米粒
  751. UserModel::setDecByField($this->user['user_id'],'gold_rice',(float)$order['goldRiceAmount']);
  752. }
  753. }
  754. if($order['riceCardId']>0 && $order['riceCardMoney']>0){
  755. //根据支付的金额来判断逻辑
  756. if($order['orderPayPrice']>0){
  757. //冻结现金卡金额
  758. UserRiceCardModel::setIncDecByField($order['riceCardId'],['frozen_amount'=>(float)$order['riceCardMoney']],['balance'=>(float)$order['riceCardMoney']]);
  759. }else{//不需要结算金额
  760. //写现金卡出账记录
  761. UserRiceCardConsumeModel::add($order['userRiceCard'],$this->model['order_no'],$order['orderPayPrice'],$order['riceCardMoney']);
  762. //如果可用余额等于要抵扣的金额
  763. if($order['riceCardMoney']==$order['userRiceCard']['balance']){
  764. //现金卡直接减可用余额,并且状态改为已失效
  765. UserRiceCardModel::setIncDecByField($order['riceCardId'],[],['balance'=>(float)$order['riceCardMoney']],['effect_state'=>2]);
  766. }else{
  767. //现金卡直接减可用余额
  768. UserRiceCardModel::setDecByField($order['riceCardId'],'balance',(float)$order['riceCardMoney']);
  769. }
  770. // 更新商品库存、销量(付款后减库存、加销量)
  771. $order['goods'] = $order['goodsList'];
  772. $order['delivery_type'] = $order['delivery'];
  773. StockFactory::getFactory($this->orderSource['source'])->updateStockSales($order);
  774. }
  775. }
  776. //待结算佣金计算
  777. $RecordWaitCommission = new RecordWaitCommission;
  778. //分销记录放入队列
  779. $RecordWaitCommission->recordWaitCommission($this->model['order_id']);
  780. return $status;
  781. }
  782. /**
  783. * 构建支付请求的参数
  784. * @return array
  785. * @throws BaseException
  786. * @throws \think\db\exception\DataNotFoundException
  787. * @throws \think\db\exception\DbException
  788. * @throws \think\db\exception\ModelNotFoundException
  789. */
  790. public function onOrderPayment()
  791. {
  792. return PaymentService::orderPayment($this->model, $this->param['payType']);
  793. }
  794. /**
  795. * 表单验证 (订单提交)
  796. * @param array $order 订单信息
  797. * @return bool
  798. */
  799. private function validateOrderForm(array $order)
  800. {
  801. if ($order['delivery'] == DeliveryTypeEnum::EXPRESS) {
  802. if (empty($order['address'])) {
  803. $this->error = '您还没有选择配送地址';
  804. return false;
  805. }
  806. }
  807. // 余额支付时判断用户余额是否足够
  808. if ($order['payType'] == OrderPayTypeEnum::BALANCE) {
  809. if ($this->user['balance'] < $order['orderPayPrice']) {
  810. $this->error = '您的余额不足,无法使用余额支付';
  811. return false;
  812. }
  813. }
  814. return true;
  815. }
  816. /**
  817. * 当前订单是否存在和使用积分抵扣
  818. * @param $order
  819. * @return bool
  820. */
  821. private function isExistPointsDeduction($order)
  822. {
  823. return $order['isAllowPoints'] && $order['isUsePoints'];
  824. }
  825. /**
  826. * 新增订单记录
  827. * @param $order
  828. * @param string $remark
  829. * @return false|int
  830. */
  831. private function add($order, $remark = '')
  832. {
  833. // 根据推广监控ID判断活动效果归属
  834. // $promotionMonitorId = PromotionMonitor::checkActEffectOwner(5, $order['promotionMonitorId'] ?? 0, $order['goodsList'][0]['bargain_id'] ?? 0);
  835. if($order['payType']==OrderPayTypeEnum::ACTIVITY){
  836. $pay_type = OrderPayTypeEnum::ACTIVITY;
  837. }else{
  838. $pay_type = $order['orderPayPrice'] > 0 ? $order['payType'] : OrderPayTypeEnum::MICAH_EXCHANGE;
  839. }
  840. // 订单数据
  841. $data = [
  842. 'user_id' => $this->user['user_id'],
  843. 'order_no' => $this->model->orderNo(),
  844. 'total_price' => $order['orderTotalPrice'],
  845. 'order_price' => $order['orderPrice'],
  846. 'pay_price' => $order['orderPayPrice'],
  847. 'delivery_type' => $order['delivery'],
  848. 'pay_type' => $pay_type,
  849. 'buyer_remark' => trim($remark),
  850. 'order_source' => $this->orderSource['source'],
  851. 'order_source_id' => $order['goodsList'][0]['za_goods_id'] ?? 0,
  852. // 'bargain_money' => helper::bcsub($this->orderData['orderTotalPrice'],$this->orderData['orderTotalBargainPrice']),
  853. 'order_status' => OrderStatusEnum::NORMAL,
  854. 'store_id' => $this->storeId,
  855. 'provider_ids' => $order['orderProviderIds']??0,
  856. 'gold_rice_amount' => $order['goldRiceAmount']??0,
  857. 'gold_rice_money' => $order['goldRiceMoney']??0,
  858. 'distributor_total_money' => $order['distributorTotalMoney']??0,
  859. 'rice_card_id' => $order['riceCardId']>0?$order['riceCardId']:0,
  860. 'rice_card_money' => $order['riceCardMoney']??0,
  861. 'rice_card_express_money' => $order['riceCardExpressMoney']??0,
  862. // 'promotion_monitor_id' => $promotionMonitorId,
  863. 'staff_user_id' => $order['goodsList'][0]['staffUserId'] ?? 0,
  864. 'staff_shop_id' => $order['goodsList'][0]['shopId'] ?? 0,
  865. ];
  866. //米卡兑换直接成功
  867. if($order['orderPayPrice']<=0 || $order['payType']==OrderPayTypeEnum::MICAH_EXCHANGE){
  868. $data['pay_status'] = PayStatusEnum::SUCCESS;
  869. $data['pay_time'] = time();
  870. $data['invoice_deadline'] = time() + OrderModel::getInvoiceDeadline() * 60; // 申请开票截止时间:订单付款后的40天内可以申请开票
  871. }
  872. //活动赠送的
  873. if($order['orderPayPrice']<=0 && $order['payType']==OrderPayTypeEnum::ACTIVITY){
  874. $data['pay_status'] = PayStatusEnum::SUCCESS;
  875. $data['pay_time'] = time();
  876. $data['invoice_deadline'] = time() + OrderModel::getInvoiceDeadline() * 60; // 申请开票截止时间:订单付款后的40天内可以申请开票
  877. }
  878. if ($order['delivery'] == DeliveryTypeEnum::EXPRESS) {
  879. $data['express_price'] = $order['expressPrice'];
  880. }
  881. // 保存订单记录
  882. return $this->model->save($data);
  883. }
  884. /**
  885. * 保存订单商品信息
  886. * @param $order
  887. * @return int
  888. */
  889. private function saveOrderGoods($order)
  890. {
  891. // 当前订单是否存在和使用积分抵扣
  892. $isExistPointsDeduction = $this->isExistPointsDeduction($order);
  893. // 订单商品列表
  894. $goodsList = [];
  895. foreach ($order['goodsList'] as $goods) {
  896. $item = [
  897. 'user_id' => $this->user['user_id'],
  898. 'store_id' => $this->storeId,
  899. 'goods_id' => $goods['goods_id'],
  900. 'goods_name' => $goods['goods_name'],
  901. 'goods_no' => $goods['goods_no'] ?: '',
  902. 'image_id' => (int)current($goods['goods_images'])['file_id'],
  903. 'deduct_stock_type' => $goods['deduct_stock_type'],
  904. 'spec_type' => $goods['spec_type'],
  905. 'goods_sku_id' => $goods['skuInfo']['goods_sku_id'],
  906. 'goods_props' => $goods['skuInfo']['goods_props'] ?: '',
  907. 'content' => $goods['content'] ?? '',
  908. 'goods_sku_no' => $goods['skuInfo']['goods_sku_no'] ?: '',
  909. 'goods_price' => $goods['skuInfo']['goods_price'],
  910. 'specs' => $goods['skuInfo']['specs'],
  911. 'supplier' => $goods['supplier'],
  912. 'line_price' => $goods['skuInfo']['line_price'],
  913. 'goods_weight' => $goods['skuInfo']['goods_weight'],
  914. 'is_user_grade' => (int)$goods['is_user_grade'],
  915. 'grade_ratio' => $goods['grade_ratio']??0,
  916. 'grade_goods_price' => $goods['grade_goods_price']??0,
  917. 'grade_total_money' => $goods['grade_total_money']??0,
  918. 'total_num' => $goods['total_num'],
  919. 'total_price' => $goods['total_price'],
  920. 'total_pay_price' => $goods['total_pay_price']??0,
  921. 'provider_id' => $goods['provider_id'],
  922. 'brand' => $goods['brand'],
  923. 'province_id' => $goods['province_id'],
  924. 'city_id' => $goods['city_id'],
  925. 'storage' => $goods['storage'],
  926. 'unit' => $goods['unit'],
  927. 'clearing_price' => $goods['skuInfo']['clearing_price']??'0.00',
  928. 'platform_rate' => $goods['skuInfo']['platform_rate']??'0.00',
  929. 'rice_card_id' => $goods['rice_card_id']??0,
  930. 'rice_card_money' => $goods['rice_card_money']??0,
  931. // 'bargain_id' => $goods['bargain_activity_id']??0,
  932. ];
  933. // 记录订单商品来源id
  934. $item['goods_source_id'] = isset($goods['goods_source_id']) ? $goods['goods_source_id'] : 0;
  935. $goodsList[] = $item;
  936. }
  937. return $this->model->goods()->saveAll($goodsList) !== false;
  938. }
  939. /**
  940. * 保存订单套餐商品信息
  941. * @param $order
  942. * @return int
  943. */
  944. private function saveOrderGoodsTaocan($order)
  945. {
  946. // 当前订单是否存在和使用积分抵扣
  947. $isExistPointsDeduction = $this->isExistPointsDeduction($order);
  948. // 订单商品列表
  949. $goodsList = [];
  950. foreach ($order['goodsList'] as $key=> $goods) {
  951. if($goods['goods_type']!=30){//是套餐商品
  952. continue;
  953. }
  954. $relGoodList = GoodsPackageModel::with(['relGood'=>['images','skuList']])->where('goods_id',$goods['goods_id'])->select();
  955. foreach ($relGoodList as $relGood){
  956. $relGood['skuList'] = [];
  957. foreach ($relGood['relGood']['skuList'] as $sku){
  958. if($sku['goods_sku_id']==$relGood['rel_goods_sku_id']){
  959. $relGood['skuList'] = $sku;
  960. }
  961. }
  962. $item = [
  963. 'user_id' => $this->user['user_id'],
  964. 'order_id' => $this->model['order_id'],
  965. 'order_goods_id' => $this->model->goods[$key]['order_goods_id'],
  966. 'store_id' => $this->storeId,
  967. 'goods_id' => $relGood['relGood']['goods_id'],
  968. 'goods_name' => $relGood['relGood']['goods_name'],
  969. 'goods_no' => $relGood['relGood']['goods_no'] ?: '',
  970. 'image_id' => (int)$relGood['relGood']['images'][0]['image_id']??0,
  971. 'deduct_stock_type' => $relGood['relGood']['deduct_stock_type'],
  972. 'spec_type' => $relGood['relGood']['spec_type'],
  973. 'goods_sku_id' => $relGood['skuList']['goods_sku_id']??0,
  974. 'goods_props' => $relGood['skuList']['goods_props'] ?? '',
  975. 'content' => $relGood['relGood']['content'] ?? '',
  976. 'goods_sku_no' => $relGood['skuList']['goods_sku_no'] ?? '',
  977. 'goods_price' => $relGood['skuList']['goods_price']??'0.00',
  978. 'line_price' => $relGood['skuList']['line_price']??'0.00',
  979. 'goods_weight' => $relGood['skuList']['goods_weight']??'0.00',
  980. 'is_user_grade' => (int)$relGood['relGood']['is_user_grade'],
  981. 'grade_ratio' => $relGood['relGood']['grade_ratio']??0,
  982. 'grade_goods_price' => $relGood['relGood']['grade_goods_price']??0,
  983. 'grade_total_money' => $relGood['relGood']['grade_total_money']??0,
  984. 'coupon_id' => $relGood['relGood']['coupon_id']??0,
  985. 'coupon_money' => $relGood['relGood']['coupon_money']??0,
  986. 'points_money' => $isExistPointsDeduction ? $relGood['relGood']['points_money'] : 0.00,
  987. 'points_num' => $isExistPointsDeduction ? $relGood['relGood']['points_num'] : 0,
  988. 'points_bonus' => $relGood['relGood']['points_bonus']??0,
  989. 'total_num' => 1,
  990. 'total_price' => $relGood['relGood']['total_price']??0,
  991. 'total_pay_price' => $relGood['relGood']['total_pay_price']??0,
  992. 'provider_id' => $relGood['relGood']['provider_id'],
  993. 'brand' => $relGood['relGood']['brand'],
  994. 'province_id' => $goods['province_id'],
  995. 'city_id' => $relGood['relGood']['city_id'],
  996. 'storage' => $relGood['relGood']['storage'],
  997. 'unit' => $relGood['relGood']['unit'],
  998. 'clearing_price' => $relGood['skuList']['clearing_price']??'0.00',
  999. 'platform_rate' => $relGood['skuList']['platform_rate']??'0.00',
  1000. 'goods_type' => 30,
  1001. ];
  1002. // 记录订单商品来源id
  1003. $item['goods_source_id'] = isset($relGood['goods_source_id']) ? $relGood['goods_source_id'] : 0;
  1004. $goodsList[] = $item;
  1005. }
  1006. }
  1007. return (new OrderGoodsTaocanModel())->saveAll($goodsList) !== false;
  1008. }
  1009. /**
  1010. * 更新商品库存 (针对下单减库存的商品)
  1011. * 普通快递、门店自提 分开扣库存
  1012. * @param $order
  1013. * @return mixed
  1014. */
  1015. private function updateGoodsStockNum($order)
  1016. {
  1017. return StockFactory::getFactory($this->model['order_source'])->updateGoodsStock($order);
  1018. }
  1019. /**
  1020. * 更新商品库存 (针对下单减库存的商品)
  1021. * 普通快递、门店自提 分开扣库存
  1022. * @param $order
  1023. * @return mixed
  1024. */
  1025. private function updateActivityStock($order)
  1026. {
  1027. return StockFactory::getFactory($this->model['order_source'])->updateActivityStock($order);
  1028. }
  1029. /**
  1030. * 保存买一赠一信息
  1031. * @param $order
  1032. * @return int
  1033. */
  1034. private function saveActivityRel($order){
  1035. $id = $order['order_source_id'];
  1036. $activityGood = ZaActivityGood::where("id",$id)->find();
  1037. if($activityGood){
  1038. $activity = ZaActivity::where("id", $activityGood->za_activity_id)->find();
  1039. $rel['is_pay'] =0;
  1040. $rel['order_price'] = $order['orderTotalPrice'];
  1041. $rel['za_goods_id'] = $id;
  1042. $rel['order_id'] = $this->model['order_id'];
  1043. $expire_day = $activity->expire_day??0;
  1044. $rel['expire_time'] = Date("Y-m-d H:i:s",$expire_day*86400+time());
  1045. $rel['za_activity_id'] = $activityGood->za_activity_id;
  1046. $sign_str = md5(md5(http_build_query($rel)));
  1047. $rel['sign_str'] = $sign_str;
  1048. ZaActivityRelation::create($rel);
  1049. $this->model['sign_str'] = $sign_str;
  1050. }
  1051. }
  1052. /**
  1053. * 记录收货地址
  1054. * @param $address
  1055. * @return false|\think\Model
  1056. */
  1057. private function saveOrderAddress($address)
  1058. {
  1059. return $this->model->address()->save([
  1060. 'user_id' => $this->user['user_id'],
  1061. 'store_id' => $this->storeId,
  1062. 'name' => $address['name'],
  1063. 'phone' => $address['phone'],
  1064. 'province_id' => $address['province_id'],
  1065. 'city_id' => $address['city_id'],
  1066. 'region_id' => $address['region_id'],
  1067. 'detail' => $address['detail'],
  1068. ]);
  1069. }
  1070. /**
  1071. * 设置错误信息
  1072. * @param $error
  1073. */
  1074. protected function setError($error)
  1075. {
  1076. empty($this->error) && $this->error = $error;
  1077. }
  1078. /**
  1079. * 获取错误信息
  1080. * @return mixed
  1081. */
  1082. public function getError()
  1083. {
  1084. return $this->error ?: '';
  1085. }
  1086. /**
  1087. * 设置错误状态
  1088. * @param $errorStatus
  1089. */
  1090. protected function setErrorStatus($errorStatus)
  1091. {
  1092. empty($this->errorStatus) && $this->errorStatus = $errorStatus;
  1093. }
  1094. /**
  1095. * 获取错误信息
  1096. * @return mixed
  1097. */
  1098. public function getErrorStatus()
  1099. {
  1100. return $this->errorStatus ?: 0;
  1101. }
  1102. /**
  1103. * 是否存在错误
  1104. * @return bool
  1105. */
  1106. public function hasError()
  1107. {
  1108. return !empty($this->error);
  1109. }
  1110. }