ShopCart.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: Administrator
  5. * Date: 2021/4/12
  6. * Time: 16:45
  7. */
  8. namespace app\frontend\modules\cart\models;
  9. use app\common\models\BaseModel;
  10. use app\framework\Http\Request;
  11. use app\frontend\modules\cart\discount\models\PreCartDiscount;
  12. use app\frontend\modules\cart\manager\CartGoodsCollection;
  13. /**
  14. * Class ShopCart
  15. * @property CartGoodsCollection carts
  16. * @package app\frontend\modules\cart\models
  17. */
  18. class ShopCart extends BaseModel
  19. {
  20. protected $member;
  21. protected $request;
  22. protected $disable;
  23. /**
  24. * @var CartGoodsCollection
  25. */
  26. protected $allCartGoods;
  27. protected $failureCart;
  28. public function init(CartGoodsCollection $carts, $member = null, $request = null)
  29. {
  30. $this->member = $member;
  31. $this->setRequest($request);
  32. $this->allCartGoods($carts);
  33. $this->setCarts();
  34. $this->cartValidate();
  35. $this->setInitAttributes();
  36. }
  37. public function allCartGoods(CartGoodsCollection $carts)
  38. {
  39. $this->allCartGoods = $carts;
  40. }
  41. //注入店铺的购物车商品记录
  42. public function setCarts()
  43. {
  44. $normalCarts = $this->allCartGoods->filterNormalGoods();
  45. $this->setRelation('carts', $normalCarts);
  46. $this->carts->setShop($this);
  47. }
  48. //注入店铺的购物车商品记录
  49. public function setFailureCart()
  50. {
  51. return $this->allCartGoods->filterInvalidGoods();
  52. }
  53. public function getFailureCart()
  54. {
  55. if (!isset($this->failureCart)) {
  56. $this->failureCart = $this->setFailureCart();
  57. }
  58. return $this->failureCart;
  59. }
  60. public function cartValidate()
  61. {
  62. $this->carts->cartValidate();
  63. }
  64. public function setRequest(Request $request)
  65. {
  66. $this->request = $request;
  67. }
  68. /**
  69. * 获取request对象
  70. * @return Request
  71. */
  72. public function getRequest()
  73. {
  74. if (!isset($this->request)) {
  75. $this->request = request();
  76. }
  77. return $this->request;
  78. }
  79. /**
  80. * 获取url中关于本订单的参数
  81. * @param null $key
  82. * @return mixed
  83. */
  84. public function getParams($key = null)
  85. {
  86. $result = collect(json_decode($this->getRequest()->input('orders'), true))->where('pre_id', $this->pre_id)->first();
  87. if (isset($key)) {
  88. return $result[$key];
  89. }
  90. return $result;
  91. }
  92. public function isCheckedCartGoods()
  93. {
  94. return $this->carts->isCheckedCartGoods();
  95. }
  96. /**
  97. * 设置前端是否可选状态
  98. * @param ShopCart $firstShop 首选购物车店铺
  99. *
  100. */
  101. public function setDisable($firstShop)
  102. {
  103. $isDisable = is_null($firstShop)?false:$firstShop->isAlone();
  104. //是特殊店铺、已有勾选商品
  105. if ($this->isAlone() && !is_null($firstShop)) {
  106. //勾选的商品与未勾选的商品得店铺对应
  107. $bool = !($isDisable && $firstShop->getShopId() == $this->getShopId());
  108. $this->special($bool); //特殊商品
  109. } else {
  110. $this->normal($isDisable); //正常商品
  111. }
  112. }
  113. /**
  114. * 特殊商品是否可选状态
  115. */
  116. public function special($isDisable)
  117. {
  118. $this->disable = $isDisable;
  119. $this->setCartDisable($isDisable);
  120. }
  121. /**
  122. * 正常商品是否可选状态
  123. */
  124. public function normal($isDisable)
  125. {
  126. $this->disable = $isDisable;
  127. $this->setCartDisable($isDisable);
  128. }
  129. /**
  130. * 禁用购物车商品选择
  131. * @return mixed
  132. */
  133. public function setCartDisable($isDisable)
  134. {
  135. return $this->carts->setCartDisable($isDisable);
  136. }
  137. /**
  138. * 判断这个店铺只能单独下单
  139. * @return bool
  140. */
  141. public function isAlone()
  142. {
  143. return false;
  144. }
  145. //店铺活动优惠满减
  146. public function getDiscountActivity()
  147. {
  148. if(!\Setting::get('enoughReduce.open')){
  149. return [];
  150. }
  151. // 获取满减设置,按enough倒序
  152. $settings = \Setting::get('enoughReduce.enoughReduce');
  153. if (empty($settings)) {
  154. return [];
  155. }
  156. $str = '';
  157. foreach ($settings as $setting) {
  158. $str .= empty($str) ? '满'.$setting['enough'].'减'.$setting['reduce']:',满'.$setting['enough'].'减'.$setting['reduce'];
  159. }
  160. if (\Setting::get('enoughReduce.freeFreight.open')) {
  161. // 设置为0 全额包邮
  162. if (\Setting::get('enoughReduce.freeFreight.enough') === 0 || \Setting::get('enoughReduce.freeFreight.enough') === '0') {
  163. $str.= empty($str) ? '全额包邮':',全额包邮';
  164. } elseif(\Setting::get('enoughReduce.freeFreight.enough')) {
  165. $str.= empty($str) ? '满额'.\Setting::get('enoughReduce.freeFreight.enough').'包邮':',满额'.\Setting::get('enoughReduce.freeFreight.enough').'包邮';
  166. }
  167. }
  168. return [[
  169. 'name'=> '满减',
  170. 'code'=> 'enoughReduce',
  171. 'type'=> 'string',
  172. 'desc'=> $str,
  173. ]];
  174. }
  175. /**
  176. * 获取总金额
  177. * @return int|mixed
  178. * @throws \app\common\exceptions\AppException
  179. */
  180. public function getDiscountAmount($total)
  181. {
  182. if(!\Setting::get('enoughReduce.open')){
  183. return 0;
  184. }
  185. // 获取满减设置,按enough倒序
  186. $settings = collect(\Setting::get('enoughReduce.enoughReduce'));
  187. if (empty($settings)) {
  188. return 0;
  189. }
  190. $settings = $settings->sortByDesc(function ($setting) {
  191. return $setting['enough'];
  192. });
  193. // 订单总价满足金额,则返回优惠金额
  194. foreach ($settings as $setting) {
  195. if ($total >= $setting['enough']) {
  196. return min($setting['reduce'],$total);
  197. }
  198. }
  199. return 0;
  200. }
  201. protected $cartDiscounts;
  202. public function cartDiscounts()
  203. {
  204. if (isset($this->cartDiscounts)) {
  205. return $this->cartDiscounts;
  206. }
  207. $cartGoodsDiscounts = $this->carts->getCartGoodsDiscounts();
  208. $discountsItems = collect([]);
  209. // 按每个种类的优惠分组 求金额的和
  210. $cartGoodsDiscounts->each(function ($cartGoodsDiscount) use ($discountsItems) {
  211. // 新类型添加
  212. if ($discountsItems->where('code', $cartGoodsDiscount->code)->isEmpty()) {
  213. $preCartDiscount = new PreCartDiscount([
  214. 'code' => $cartGoodsDiscount->code,
  215. 'amount' => $cartGoodsDiscount->amount,
  216. 'name' => $cartGoodsDiscount->name,
  217. ]);
  218. $discountsItems->push($preCartDiscount);
  219. return;
  220. }
  221. // 已存在的类型累加
  222. $discountsItems->where('code', $cartGoodsDiscount->code)->first()->amount += $cartGoodsDiscount->amount;
  223. });
  224. return $this->cartDiscounts = $discountsItems;
  225. }
  226. protected $cartExtraCharges;
  227. /**
  228. * 其他费用
  229. * @return \Illuminate\Support\Collection
  230. */
  231. public function cartExtraCharges()
  232. {
  233. if (isset($this->cartExtraCharges)) {
  234. return $this->cartExtraCharges;
  235. }
  236. $cartGoodsExtraCharges = $this->carts->getCartGoodsExtraCharges();
  237. $itemsAggregate = collect([]);
  238. // 按每个种类分组 求金额的和
  239. $cartGoodsExtraCharges->each(function ($cartGoodsItem) use ($itemsAggregate) {
  240. // 新类型添加
  241. if ($itemsAggregate->where('code', $cartGoodsItem->code)->isEmpty()) {
  242. $model = new CartBaseModel([
  243. 'code' => $cartGoodsItem->code,
  244. 'amount' => $cartGoodsItem->amount,
  245. 'name' => $cartGoodsItem->name,
  246. ]);
  247. $itemsAggregate->push($model);
  248. return;
  249. }
  250. // 已存在的类型累加
  251. $itemsAggregate->where('code', $cartGoodsItem->code)->first()->amount += $cartGoodsItem->amount;
  252. });
  253. return $this->cartExtraCharges = $itemsAggregate;
  254. }
  255. protected $cartDeductions;
  256. /**
  257. * 抵扣
  258. * @return \Illuminate\Support\Collection
  259. */
  260. public function cartDeductions()
  261. {
  262. if (isset($this->cartDeductions)) {
  263. return $this->cartDeductions;
  264. }
  265. $cartDeductions = $this->carts->getCartGoodsDeductions();
  266. $itemsAggregate = collect([]);
  267. // 按每个种类分组 求金额的和
  268. $cartDeductions->each(function ($cartGoodsItem) use ($itemsAggregate) {
  269. // 新类型添加
  270. if ($itemsAggregate->where('code', $cartGoodsItem->code)->isEmpty()) {
  271. $model = new CartBaseModel([
  272. 'code' => $cartGoodsItem->code,
  273. 'amount' => $cartGoodsItem->amount,
  274. 'name' => $cartGoodsItem->name,
  275. ]);
  276. $itemsAggregate->push($model);
  277. return;
  278. }
  279. // 已存在的类型累加
  280. $itemsAggregate->where('code', $cartGoodsItem->code)->first()->amount += $cartGoodsItem->amount;
  281. });
  282. return $this->cartDeductions = $itemsAggregate;
  283. }
  284. public function getGoodsPrice()
  285. {
  286. return $this->carts->getPrice();
  287. }
  288. public function getPrice()
  289. {
  290. //商品总价
  291. return $this->getEstimatedPrice();
  292. }
  293. public function getEstimatedPrice()
  294. {
  295. return $this->carts->getEstimatedPrice();
  296. }
  297. public function getCode()
  298. {
  299. return 'shop';
  300. }
  301. public function getName()
  302. {
  303. return \Setting::get('shop.shop')['name']?:'自营';
  304. }
  305. public function getShopId()
  306. {
  307. return md5('shop');
  308. }
  309. public function getLink()
  310. {
  311. return '';
  312. }
  313. public function getMerchantId()
  314. {
  315. return 0;
  316. }
  317. public function setInitAttributes()
  318. {
  319. $attributes = array(
  320. 'is_alone' => $this->isAlone(),
  321. 'link' => $this->getLink(),
  322. 'code' => $this->getCode(),
  323. 'name' => $this->getName(),
  324. 'merchant_id' => $this->getMerchantId(),
  325. 'shop_id' => $this->getShopId(),
  326. 'discount_activity' => $this->getDiscountActivity(),
  327. 'price' => sprintf('%.2f', $this->getPrice()),
  328. );
  329. $this->setRawAttributes($attributes);
  330. }
  331. public function beforeFormat()
  332. {
  333. $this->setAttribute('disable',$this->disable);
  334. }
  335. /**
  336. * @return array
  337. */
  338. public function toArray()
  339. {
  340. $this->beforeFormat();
  341. return parent::toArray();
  342. }
  343. public function goods()
  344. {
  345. return $this->carts->first()->goods;
  346. }
  347. public function getPriceAttribute()
  348. {
  349. return sprintf('%.2f', $this->getPrice());
  350. }
  351. public function getDiscountActivityAttribute()
  352. {
  353. return $this->getDiscountActivity();
  354. }
  355. public function getCodeAttribute()
  356. {
  357. return $this->getCode();
  358. }
  359. public function getNameAttribute()
  360. {
  361. return $this->getName();
  362. }
  363. public function getShopIdAttribute()
  364. {
  365. return $this->getShopId();
  366. }
  367. }