StoreOrderCartInfoServices.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  8. // +----------------------------------------------------------------------
  9. // | Author: CRMEB Team <admin@crmeb.com>
  10. // +----------------------------------------------------------------------
  11. namespace app\services\order;
  12. use crmeb\utils\Str;
  13. use app\services\BaseServices;
  14. use crmeb\services\CacheService;
  15. use app\dao\order\StoreOrderCartInfoDao;
  16. use think\exception\ValidateException;
  17. /**
  18. * Class StoreOrderCartInfoServices
  19. * @package app\services\order
  20. * @method array getCartColunm(array $where, string $field, ?string $key) 获取购物车信息以数组返回
  21. * @method array getCartInfoList(array $where, array $field) 获取购物车详情列表
  22. * @method getSplitCartNum(array $cart_id)
  23. * @method getOne(array $where, ?string $field = '*', array $with = []) 根据条件获取一条数据
  24. */
  25. class StoreOrderCartInfoServices extends BaseServices
  26. {
  27. /**
  28. * StoreOrderCartInfoServices constructor.
  29. * @param StoreOrderCartInfoDao $dao
  30. */
  31. public function __construct(StoreOrderCartInfoDao $dao)
  32. {
  33. $this->dao = $dao;
  34. }
  35. /**
  36. * 获取指定订单下的商品详情
  37. * @param int $oid
  38. * @return array|mixed
  39. */
  40. public function getOrderCartInfo(int $oid)
  41. {
  42. $cartInfo = CacheService::get(md5('store_order_cart_info_' . $oid));
  43. if ($cartInfo) return $cartInfo;
  44. $cart_info = $this->dao->getColumn(['oid' => $oid], 'cart_info', 'cart_id');
  45. $info = [];
  46. foreach ($cart_info as $k => $v) {
  47. $_info = is_string($v) ? json_decode($v, true) : $v;
  48. if (!isset($_info['productInfo'])) $_info['productInfo'] = [];
  49. //缩略图处理
  50. if (isset($_info['productInfo']['attrInfo'])) {
  51. $_info['productInfo']['attrInfo'] = get_thumb_water($_info['productInfo']['attrInfo']);
  52. }
  53. $_info['productInfo'] = get_thumb_water($_info['productInfo']);
  54. $info[$k]['cart_info'] = $_info;
  55. unset($_info);
  56. }
  57. CacheService::set(md5('store_order_cart_info_' . $oid), $info);
  58. return $info;
  59. }
  60. /**
  61. * 查找购物车里的所有商品标题
  62. * @param int $oid
  63. * @param $cartId
  64. * @param false $goodsNum
  65. * @return bool|mixed|string
  66. * @throws \think\db\exception\DataNotFoundException
  67. * @throws \think\db\exception\DbException
  68. * @throws \think\db\exception\ModelNotFoundException
  69. */
  70. public function getCarIdByProductTitle(int $oid, $cartId, $goodsNum = false)
  71. {
  72. $key = md5('store_order_cart_product_title_' . $oid . '_' . is_array($cartId) ? implode('_', $cartId) : $cartId);
  73. $title = CacheService::get($key);
  74. if (!$title) {
  75. $orderCart = $this->dao->getCartInfoList(['oid' => $oid, 'cart_id' => $cartId], ['cart_info']);
  76. foreach ($orderCart as $item) {
  77. if (isset($item['cart_info']['productInfo']['store_name'])) {
  78. if ($goodsNum && isset($item['cart_info']['cart_num'])) {
  79. $title .= $item['cart_info']['productInfo']['store_name'] . ' * ' . $item['cart_info']['cart_num'] . ' | ';
  80. } else {
  81. $title .= $item['cart_info']['productInfo']['store_name'] . '|';
  82. }
  83. }
  84. }
  85. if ($title) {
  86. $title = substr($title, 0, strlen($title) - 1);
  87. }
  88. CacheService::set($key, $title);
  89. }
  90. return $title ? $title : '';
  91. }
  92. /**
  93. * 获取打印订单的商品信息
  94. * @param array $cartId
  95. * @return array
  96. * @throws \think\db\exception\DataNotFoundException
  97. * @throws \think\db\exception\DbException
  98. * @throws \think\db\exception\ModelNotFoundException
  99. */
  100. public function getCartInfoPrintProduct(array $cartId)
  101. {
  102. $cartInfo = $this->dao->getCartInfoList(['cart_id' => $cartId], ['cart_info']);
  103. $product = [];
  104. foreach ($cartInfo as $item) {
  105. $value = is_string($item['cart_info']) ? json_decode($item['cart_info'], true) : $item['cart_info'];
  106. $value['productInfo']['store_name'] = $value['productInfo']['store_name'] ?? "";
  107. $value['productInfo']['store_name'] = Str::substrUTf8($value['productInfo']['store_name'], 10, 'UTF-8', '');
  108. $product[] = $value;
  109. }
  110. return $product;
  111. }
  112. /**
  113. * 获取产品返佣金额
  114. * @param array $cartId
  115. * @param bool $type true = 一级返佣, fasle = 二级返佣
  116. * @return string
  117. */
  118. public function getProductBrokerage(array $cartId, bool $type = true)
  119. {
  120. $cartInfo = $this->dao->getCartInfoList(['cart_id' => $cartId], ['cart_info']);
  121. $oneBrokerage = '0';//一级返佣金额
  122. $twoBrokerage = '0';//二级返佣金额
  123. $sumProductPrice = '0';//非指定返佣商品总金额
  124. foreach ($cartInfo as $value) {
  125. $cartNum = $value['cart_info']['cart_num'] ?? 0;
  126. if (isset($value['cart_info']['productInfo'])) {
  127. $productInfo = $value['cart_info']['productInfo'];
  128. //指定返佣金额
  129. if (isset($productInfo['is_sub']) && $productInfo['is_sub'] == 1) {
  130. $oneBrokerage = bcadd($oneBrokerage, bcmul($cartNum, $productInfo['attrInfo']['brokerage'] ?? 0, 2), 2);
  131. $twoBrokerage = bcadd($twoBrokerage, bcmul($cartNum, $productInfo['attrInfo']['brokerage_two'] ?? 0, 2), 2);
  132. } else {
  133. //比例返佣
  134. if (isset($productInfo['attrInfo'])) {
  135. $sumProductPrice = bcadd($sumProductPrice, bcmul($cartNum, $productInfo['attrInfo']['price'] ?? 0, 2), 2);
  136. } else {
  137. $sumProductPrice = bcadd($sumProductPrice, bcmul($cartNum, $productInfo['price'] ?? 0, 2), 2);
  138. }
  139. }
  140. }
  141. }
  142. if ($type) {
  143. //获取后台一级返佣比例
  144. $storeBrokerageRatio = sys_config('store_brokerage_ratio');
  145. //一级返佣比例 小于等于零时直接返回 不返佣
  146. if ($storeBrokerageRatio <= 0) {
  147. return $oneBrokerage;
  148. }
  149. //计算获取一级返佣比例
  150. $brokerageRatio = bcdiv($storeBrokerageRatio, 100, 4);
  151. $brokeragePrice = bcmul($sumProductPrice, $brokerageRatio, 2);
  152. //固定返佣 + 比例返佣 = 一级总返佣金额
  153. return bcadd($oneBrokerage, $brokeragePrice, 2);
  154. } else {
  155. //获取二级返佣比例
  156. $storeBrokerageTwo = sys_config('store_brokerage_two');
  157. //二级返佣比例小于等于0 直接返回
  158. if ($storeBrokerageTwo <= 0) {
  159. return $twoBrokerage;
  160. }
  161. //计算获取二级返佣比例
  162. $brokerageRatio = bcdiv($storeBrokerageTwo, 100, 4);
  163. $brokeragePrice = bcmul($sumProductPrice, $brokerageRatio, 2);
  164. //固定返佣 + 比例返佣 = 二级总返佣金额
  165. return bcadd($twoBrokerage, $brokeragePrice, 2);
  166. }
  167. }
  168. /**
  169. * 保存购物车info
  170. * @param $oid
  171. * @param array $cartInfo
  172. * @return int
  173. */
  174. public function setCartInfo($oid, array $cartInfo)
  175. {
  176. $group = [];
  177. foreach ($cartInfo as $cart) {
  178. $group[] = [
  179. 'oid' => $oid,
  180. 'cart_id' => $cart['id'],
  181. 'product_id' => $cart['productInfo']['id'],
  182. 'cart_info' => json_encode($cart),
  183. 'cart_num' => $cart['cart_num'],
  184. 'surplus_num' => $cart['cart_num'],
  185. 'unique' => md5($cart['id'] . '' . $oid)
  186. ];
  187. }
  188. return $this->dao->saveAll($group);
  189. }
  190. /**
  191. * 订单创建成功之后计算订单(实际优惠、积分、佣金、上级、上上级)
  192. * @param $oid
  193. * @param array $cartInfo
  194. * @return bool
  195. */
  196. public function updateCartInfo($oid, array $cartInfo)
  197. {
  198. foreach ($cartInfo as $cart) {
  199. $group = [
  200. 'cart_info' => json_encode($cart)
  201. ];
  202. $this->dao->update(['oid' => $oid, 'cart_id' => $cart['id']], $group);
  203. }
  204. return true;
  205. }
  206. /**
  207. * 商品编号
  208. * @param $cartId
  209. * @return array
  210. */
  211. public function getCartIdsProduct($cartId)
  212. {
  213. return $this->dao->getColumn([['cart_id', 'in', $cartId]], 'product_id', 'oid');
  214. }
  215. /**
  216. * 获取某个订单还可以拆分商品 split_status 0:未拆分1:部分拆分2:拆分完成
  217. * @param int $oid
  218. * @param string $field
  219. * @param string $key
  220. * @return array
  221. */
  222. public function getSplitCartList(int $oid, string $field = '*', string $key = 'cart_id')
  223. {
  224. $cartInfo = $this->dao->getColumn([['oid', '=', $oid], ['split_status', 'IN', [0, 1]]], $field, $key);
  225. foreach ($cartInfo as &$item) {
  226. if ($field == 'cart_info') {
  227. $item = is_string($item) ? json_decode($item, true) : $item;
  228. } else {
  229. if (isset($item['cart_info'])) $item['cart_info'] = is_string($item['cart_info']) ? json_decode($item['cart_info'], true) : $item['cart_info'];
  230. if (isset($item['cart_num']) && !$item['cart_num']) {//兼容之前老数据
  231. $item['cart_num'] = $item['cart_info']['cart_num'] ?? 0;
  232. }
  233. }
  234. }
  235. return $cartInfo;
  236. }
  237. /**
  238. * 检测这些商品是否还可以拆分
  239. * @param int $oid
  240. * @param array $cart_data
  241. * @return bool
  242. * @throws \think\db\exception\DataNotFoundException
  243. * @throws \think\db\exception\DbException
  244. * @throws \think\db\exception\ModelNotFoundException
  245. */
  246. public function checkCartIdsIsSplit(int $oid, array $cart_data)
  247. {
  248. if (!$cart_data) return false;
  249. $ids = array_unique(array_column($cart_data, 'cart_id'));
  250. if ($this->dao->getCartInfoList(['oid' => $oid, 'cart_id' => $ids, 'split_status' => 2], ['cart_id'])) {
  251. throw new ValidateException('您选择的商品已经拆分完成,请刷新或稍后重新选择');
  252. }
  253. $cartInfo = $this->getSplitCartList($oid, 'surplus_num,cart_info,cart_num', 'cart_id');
  254. if (!$cartInfo) {
  255. throw new ValidateException('该订单已发货完成');
  256. }
  257. foreach ($cart_data as $cart) {
  258. $surplus_num = $cartInfo[$cart['cart_id']]['surplus_num'] ?? 0;
  259. if (!$surplus_num) {//兼容之前老数据
  260. $_info = $cartInfo[$cart['cart_id']]['cart_info'];
  261. $surplus_num = $_info['cart_num'] ?? 0;
  262. }
  263. if ($cart['cart_num'] > $surplus_num) {
  264. throw new ValidateException('您选择商品拆分数量大于购买数量');
  265. }
  266. }
  267. return true;
  268. }
  269. }