1,//单个商品 'shop' => 2,//按店铺 'all' => 3,//全选 ]; /** * @var array 阶梯价 */ private static $enabledLadder = [ 'open' => 1,//启用阶梯价 'close' => 0,//未启用阶梯价 ]; /** * @var MCashierSettings */ private $objMCashierSettings; /** * MCashierCart constructor. * @param $onlineUserId * @param $onlineEnterpriseId * @param $cashierUid * @throws \Exception */ public function __construct($onlineUserId, $onlineEnterpriseId,$cashierUid) { $this->onlineUserId = $onlineUserId; $this->onlineEnterpriseId = $onlineEnterpriseId; $this->cashierUid = $cashierUid; $this->objMGoods = new MGoods($this->onlineEnterpriseId,true,$this->onlineUserId); $this->objDCashierCart = new DCashierCart(); $this->objDCashierCart->setTable('qianniao_cashier_cart_'.$this->onlineEnterpriseId); $this->objActivityLimitCache = new ActivityLimitCache($this->onlineEnterpriseId); $this->objMSku = new MSku($this->onlineUserId, $this->onlineEnterpriseId); $this->objMCustomer = new MCustomer($this->onlineEnterpriseId,$this->onlineUserId); $this->objDCashierCustomerPrice = new DCashierCustomerPrice(); $this->objDCashierCustomerPrice->setTable('qianniao_cashier_customer_price_'.$this->onlineEnterpriseId); $this->objMCashierSettings = new MCashierSettings($this->onlineUserId,$this->onlineEnterpriseId); } /** * 获取客户id,匿名用户使用匿名客户id */ private function getCustomerInfo() { if ($this->onlineUserId == StatusCode::$noneUserCenter){ $this->customerId = StatusCode::$noneCustomer; }else{ $this->customerId = $this->objMCustomer->getCustomerIdByUserCenterId($this->onlineUserId); } } /** * Doc: (des="收银台加入购物车") * User: XMing * Date: 2020/9/17 * Time: 2:24 下午 * @param array $params * @return ResultWrapper * @throws \Exception */ public function addCartApi($params) { $data = $params['goodsData']; if (empty($data)){ return ResultWrapper::fail('加入购物车数据为空',ErrorCode::$paramError); } $data = array_shift($data);//小程序端加入购物车都是单个 //验证此商品是否有效 $goodsInfoResult = $this->objMGoods->getGoodsInfo($data['goodsId']); if (!$goodsInfoResult->isSuccess()){ return ResultWrapper::fail($goodsInfoResult->getData(),$goodsInfoResult->getErrorCode()); } $goodsInfo = $goodsInfoResult->getData(); $checkResult = self::checkGoods($goodsInfo,$data); unset($data); if (!$checkResult->isSuccess()){ return ResultWrapper::fail($checkResult->getData(),$checkResult->getErrorCode()); } $data = $checkResult->getData(); $addMap = [ 'cashierUid' => $this->cashierUid, 'goodsBasicId' => $data['goodsBasicId'], 'goodsId' => $data['goodsId'], 'skuId' => $data['skuId'], 'buyNum' => $data['buyNum'], 'shopId' => $data['shopId'], 'source' => $data['source'], 'setNum' => $data['setNum'], 'activityId' => 0, 'goodsCode' => $data['goodsCode'], 'warehouseId' => $data['warehouseId'] ]; $groupResult = self::existCartAndGroup([$addMap]); if (!$groupResult->isSuccess()){ return ResultWrapper::fail($groupResult->getData(),$groupResult->getErrorCode()); } $groupData = $groupResult->getData(); if (empty($groupData)){ return ResultWrapper::fail('数组分组失败',ErrorCode::$paramError); } Logger::logs(E_USER_ERROR,'收银台加入购物车数据',__CLASS__,__LINE__,$groupData); $updates = isset($groupData['old']) ? $groupData['old'] : []; $inserts = isset($groupData['now']) ? $groupData['now'] : []; //操作数据库 $this->objDCashierCart->beginTransaction(); //需要更新的数据 if (!empty($updates)){ $update = array_shift($updates); $tableName = 'qianniao_cashier_cart_'.$this->onlineEnterpriseId; $sql = 'UPDATE '.$tableName.' SET buyNum = buyNum+'.$update['buyNum'].' WHERE goodsId = '.$update['goodsId'].' AND skuId = '.$update['skuId'].' AND activityId = '.$update['activityId'] .' AND cashierUid = '.$update['cashierUid']; $updateRes = $this->objDCashierCart->query($sql); if ($updateRes === false){ $this->objDCashierCart->rollBack(); return ResultWrapper::fail($this->objDCashierCart->error(),ErrorCode::$dberror); } } //需要插入的数据 if (!empty($inserts)){ $insert = array_shift($inserts); $insertMap = [ 'cashierUid' => $this->cashierUid, 'selection' => StatusCode::$standard, 'goodsBasicId' => $insert['goodsBasicId'], 'goodsId' => $insert['goodsId'], 'skuId' => $insert['skuId'], 'buyNum' => $insert['buyNum'], 'shopId' => $insert['shopId'], 'source' => $insert['source'], 'activityId' => $insert['activityId'], 'goodsCode' => $insert['goodsCode'], 'warehouseId' => $insert['warehouseId'] ];//要插入的数据 $insertRes = $this->objDCashierCart->insert($insertMap); if ($insertRes === false){ $this->objDCashierCart->rollBack(); return ResultWrapper::fail($this->objDCashierCart->error(),ErrorCode::$dberror); } } $this->objDCashierCart->commit(); return ResultWrapper::success('加入成功'); } /** * Doc: (des="更新购车商品数量") * User: XMing * Date: 2020/8/6 * Time: 9:43 上午 * @param array $params * @return ResultWrapper * @throws \Exception */ public function updateBuyNumApi($params) { if ($params['buyNum'] == 0){ $dbResult = $this->objDCashierCart->delete(['id' => $params['cartId']]); if ($dbResult === false) { return ResultWrapper::fail($this->objDCashierCart->error(), ErrorCode::$dberror); } return ResultWrapper::success('操作成功'); } $dbResult = $this->objDCashierCart->update(['buyNum' => $params['buyNum']], $params['cartId']); if ($dbResult === false) { return ResultWrapper::fail($this->objDCashierCart->error(), ErrorCode::$dberror); } return ResultWrapper::success('操作成功'); } /** * 删除购物车中商品(可批量) * @param $ids * @param boolean $order 是否是来自订单 * @return ResultWrapper */ public function delCart($ids, $order = false) { $dbResult = $this->objDCashierCart->select($ids, 'id,goodsId,buyNum,skuId,activityId'); if ($dbResult === false) { return ResultWrapper::fail($this->objDCashierCart->error(), ErrorCode::$dberror); } //限购减对应数据 if ($order === true) { foreach ($dbResult as $goods) { if ($goods['activityId'] != 0) { $userSurplusNum = $this->objActivityLimitCache->getLimit($goods['activityId'], $goods['goodsId'], $goods['skuId'], $this->onlineUserId); $mapping[] = [ 'activityId' => $goods['activityId'], 'goodsId' => $goods['goodsId'], 'skuId' => $goods['skuId'], 'buyNum' => $userSurplusNum + $goods['buyNum'], ]; self::userLimit($mapping); } } } $dbResult = $this->objDCashierCart->delete($ids); if ($dbResult === false) { return ResultWrapper::fail($this->objDCashierCart->error(), ErrorCode::$dberror); } return ResultWrapper::success($dbResult); } /** * Doc: (des="收银台购物车数据") * User: XMing * Date: 2020/9/16 * Time: 4:02 下午 * @param int $isZero * @param string $userCouponId * @return ResultWrapper * @throws \Exception */ public function getCashierCartByUserCenterIdApi($isZero = 4,$userCouponId = '') { $cartList = $this->objDCashierCart->select(['cashierUid' => $this->cashierUid], 'id,goodsId,goodsCode,buyNum,shopId,source,goodsBasicId,selection,skuId,warehouseId,activityId,cashierUid', 'createTime DESC'); if ($cartList === false) { return ResultWrapper::fail($this->objDCashierCart->error(), ErrorCode::$dberror); } if(empty($cartList)){ return ResultWrapper::success(['data' => [],'total' => 0]); } $data = self::formatGoodsAndShop($cartList,$userCouponId); //是否有改价操作,收银台,操作 $formatResult = self::buildSetPriceCart($data); if (!$formatResult->isSuccess()){ return ResultWrapper::fail($formatResult->getData(),$formatResult->getErrorCode()); } $data = $formatResult->getData();//最终数据 $zeroResult = $this->buildZero($data,$isZero); if (!$zeroResult->isSuccess()){ return ResultWrapper::fail($zeroResult->getData(),$zeroResult->getErrorCode()); } $data = $zeroResult->getData();//最终数据 //订单使用的优惠券 $userCouponInfo = []; if (!empty($userCouponId)) { $objMUserCoupon = new MUserCoupon($this->onlineUserId, $this->onlineEnterpriseId); $dbResult = $objMUserCoupon->getUserCoupon(['id' => $userCouponId]); if ($dbResult->isSuccess()) $userCouponInfo = $dbResult->getData(); $userCouponInfo = isset($userCouponInfo[0]) ? $userCouponInfo[0] : []; } $data['useCoupon'] = $userCouponInfo; //优惠券数据 $data = self::findCoupon($data); $return = [ 'data' => $data, 'total' => empty($data) ? 0 : count($data), ]; return ResultWrapper::success($return); } /** * Doc: (des="判断字符串是否是一个整数") * User: XMing * Date: 2020/10/12 * Time: 10:29 上午 * @param $num * @return bool */ private static function isInteger($num) { if ($num - floor($num) != 0){ return false; } return true; } /** * 后台--清空用户购物车 */ public function clearCart() { $where['cashierUid'] = $this->cashierUid; $dbResult = $this->objDCashierCart->delete($where); if ($dbResult === false) { return ResultWrapper::fail($this->objDCashierCart->error(), ErrorCode::$dberror); } return ResultWrapper::success($dbResult); } /** * 判断在使用范围的店铺,指定商品是否满足最小金额 * 查询可用的优惠券 * @param $data * @return mixed * @throws \Exception */ private function findCoupon($data) { $objMUserCoupon = new MUserCoupon($this->onlineUserId, $this->onlineEnterpriseId); $objGoodsBasicRelevant = new GoodsBasicRelevant($this->onlineEnterpriseId); $payAmount = $data['payMoney']; if ($data['activityMoney'] != 0) { $payAmount = bcsub($payAmount, $data['activityMoney'], 2); } $dbResult = $objMUserCoupon->availableCoupon([ 'payAmount' => $payAmount ]); if (!$dbResult->isSuccess()) { return ResultWrapper::fail($dbResult->getData(), ErrorCode::$dberror); } $coupon = $dbResult->getData(); foreach ($coupon as $key => $val) { $useShop = explode(',', $val['useShop']);//此优惠券可以使用的店铺 $applyRange = $val['applyRange'];//优惠券使用范围 $cart[$val['id']]['money'] = 0; foreach ($data['goodsData'] as $shopGoodsData) { foreach ($shopGoodsData['shopGoodsData'] as $goodsDetail) { $categoryId = $objGoodsBasicRelevant->getNameByBasicId($goodsDetail['goodsBasicId'], 'categoryId'); $brandId = $objGoodsBasicRelevant->getNameByBasicId($goodsDetail['goodsBasicId'], 'brandId'); if ( in_array($shopGoodsData['shopId'], $useShop) && ($applyRange == StatusCode::$applyRange['allGoods'] || in_array($categoryId, explode(',', $val['categoryCollect'])) || in_array($goodsDetail['goodsId'],explode(',',$val['goodsCollect'])) ) ) { $cart[$val['id']]['money'] = bcadd($cart[$val['id']]['money'], $goodsDetail['totalMoney']);//规定范围内的商品总金额 } } } if ($val['minPrice'] != 0 && $cart[$val['id']]['money'] < $val['minPrice']) { unset($coupon[$key]);//不符合要求 } } $data['coupon'] = array_values($coupon); return $data; } /** * Doc: (des="抹零操作") * User: XMing * Date: 2020/9/12 * Time: 7:08 下午 * @param array $data * @param int $isZero * @return ResultWrapper */ private function buildZero($data,$isZero) { //是否开启抹零 $data['rem_money'] = '0.00'; $settingResult = $this->objMCashierSettings->get(); if (!$settingResult->isSuccess()){ return ResultWrapper::fail($settingResult->getData(),$settingResult->getErrorCode()); } $setting = $settingResult->getData(); if (!is_array($setting)){ //不是数组时,说明未配置 return ResultWrapper::success($data); } if (!isset($setting['add_form'])){ return ResultWrapper::fail('收银台配置错误',ErrorCode::$paramError); } if (!isset($setting['add_form']['zero_set'])){ return ResultWrapper::fail('收银台参数配置错误',ErrorCode::$paramError); } $zeroSet = $setting['add_form']['zero_set']; if ($zeroSet['status'] == StatusCode::$delete){ //没有开启抹零,前台需要在抹零那判断是否开启 return ResultWrapper::success($data); } $payMoney = $data['payMoney']; if ($zeroSet['auto_zero'] == StatusCode::$standard){ //开启了自动抹零 switch ($zeroSet['type']){ case 1: //分 $newPatMoney = bcadd($payMoney,0,1); break; case 2: //角 $newPatMoney = bcadd($payMoney,0,0); break; case 3: //到角 $newPatMoney = round($payMoney, 1); break; case 4: //到元 $newPatMoney = round($payMoney, 0); break; default: $newPatMoney = 0; break; } $rem_money = bcsub($payMoney,$newPatMoney,2); $data['payMoney'] = $newPatMoney; $data['rem_money'] = $rem_money; }else{ if ($isZero == StatusCode::$standard){ //手动抹零 switch ($zeroSet['type']){ case 1: //分 $newPatMoney = bcadd($payMoney,0,1); break; case 2: //角 $newPatMoney = bcadd($payMoney,0,0); break; case 3: //到角 $newPatMoney = round($payMoney, 1); break; case 4: //到元 $newPatMoney = round($payMoney, 0); break; default: $newPatMoney = 0; break; } $rem_money = bcsub($payMoney,$newPatMoney,2); $data['payMoney'] = $newPatMoney; $data['rem_money'] = $rem_money; } } return ResultWrapper::success($data); } /** * Doc: (des="修改价格") * User: XMing * Date: 2020/9/12 * Time: 2:48 下午 * @param $data * @return ResultWrapper */ private function buildSetPriceCart($data) { $allGoodsData = $data['goodsData']; $goodsData = array_shift($allGoodsData); $shopGoodsData = $goodsData['shopGoodsData']; $skuIds = []; foreach ($shopGoodsData as $item){ $skuIds[] = $item['skuId']; } if (empty($skuIds)){ return ResultWrapper::success($data); } //获取本收银员有没有对商品设置过价格 $priceLists = $this->objDCashierCustomerPrice->select( [ 'skuId' => $skuIds, 'cashierUid' => $this->cashierUid, 'customerUid' => $this->onlineUserId ], 'price,skuId' ); if ($priceLists === false){ return ResultWrapper::fail($this->objDCashierCustomerPrice->error(),ErrorCode::$dberror); } if (empty($priceLists)){ return ResultWrapper::success($data); } $customerPriceMap = []; foreach ($priceLists as $val){ $customerPriceMap[$val['skuId']] = $val['price']; } if (empty($customerPriceMap)){ return ResultWrapper::success($data); } foreach ($shopGoodsData as $key => &$item){ $item['subPrice'] = 0; if (!isset($customerPriceMap[$item['skuId']])){ //没有修改价格 continue; } $oldPrice = $item['price']; $changePrice = $customerPriceMap[$item['skuId']]; $item['price'] = $changePrice; $item['subUnitPrice'] = bcsub($oldPrice,$changePrice,2); $item['subPrice'] = bcmul($item['subUnitPrice'],$item['buyNum'],2); $item['totalMoney'] = bcmul($item['price'],$item['buyNum'],2); } $totalMoney = array_sum(array_column($shopGoodsData,'totalMoney')); $setPriceSubMoney = bcadd(array_sum(array_column($shopGoodsData,'subPrice')),0,2); $goodsData['totalMoney'] = $totalMoney; $goodsData['subPrice'] = $setPriceSubMoney; $goodsData['payMoney'] = $totalMoney; $goodsData['shopGoodsData'] = array_values($shopGoodsData); $data['totalMoney'] = $totalMoney; $data['subPrice'] = $setPriceSubMoney; $data['payMoney'] = $totalMoney; $data['goodsData'] = [$goodsData]; return ResultWrapper::success($data); } /** * 拼装购物车数据(商铺->商品->规格->库存->价格->分组) * 此方法正在修改,勿动 * @param $data * @param $userCouponId * @param $vipCardId * @return array|mixed * @throws \Exception */ private function formatGoodsAndShop($data, $userCouponId = null, $vipCardId = null) { foreach ($data as &$value){ $value['buyNum'] = self::isInteger($value['buyNum']) ? (int)$value['buyNum'] : $value['buyNum']; } unset($value); $result = self::formatShop($data);//格式化店铺数据 $result = self::formatGoods($result);//格式化商品数据 /*if ($this->isFront === true){ $result = self::calExpress($result); if(!$result->isSuccess()){ return ResultWrapper::fail($result->getData(),$result->getErrorCode()); } $result = $result->getData(); }*/ $result = self::formatPrice($result);//处理价格 $result = self::formatSkuInventory($result);//处理库存 $result = self::formatGroup($result, $userCouponId, $vipCardId); /**foreach ($result as &$row){ * $row['basicGoodsId'] = $row['goodsBasicId']; * $row = $objMGoods->formatMultipleSkuMapping($row, StatusCode::$standard);//处理属性 * $row['skuData'] = $row['specMultiple']; * //unset($row['specMultiple']); * }**/ return $result; } /** * 数据分组 * * @param $data * @param null $userCouponId * @param null $vipCardId * @return array * @throws \Exception */ private function formatGroup($data, $userCouponId = null, $vipCardId = null) { static $checkNum = 0;//购物车中选中商品数量 static $totalMoney = 0;//原总额 static $payMoney = 0;//实际支付金额 static $preferential = 0;//优惠券优惠 static $cartNum = 0; static $goodsNum = 0;//购物车商品数量 static $vipDiscount = 0;//会员卡优惠金额 static $vipDoubleDiscount = 0;//会员卡折上折优惠金额 static $activityMoney = 0;//互斥活动商品总金额 static $expressMoney = 0;//运费 $goodsData = []; foreach ($data as $key => $val) { if (!isset($val['expressMoney'])){ $val['expressMoney'] = '0.00'; } $shopGoodsData[$val['shopId']][] = $val; if (!isset($goodsData[$val['shopId']]['totalMoney'])) { $goodsData[$val['shopId']]['totalMoney'] = '0.00'; } if (!isset($goodsData[$val['shopId']]['preferential'])) { $goodsData[$val['shopId']]['preferential'] = '0.00'; } if (!isset($goodsData[$val['shopId']]['expressMoney'])){ $goodsData[$val['shopId']]['expressMoney'] = '0.00'; } $goodsData[$val['shopId']] = [ 'shopId' => $val['shopId'], 'shopName' => $val['shopName'], 'shopLogo' => $val['shopLogo'], 'expressMoney' => bcadd($goodsData[$val['shopId']]['expressMoney'],$val['expressMoney'],2), 'totalMoney' => bcadd($goodsData[$val['shopId']]['totalMoney'], $val['totalMoney'], 2),//(购物车总金额) 'preferential' => bcadd($goodsData[$val['shopId']]['preferential'], bcmul($val['preferential'], $val['buyNum']), 2),//店铺总优惠金额 'payMoney' => bcsub(bcadd($goodsData[$val['shopId']]['totalMoney'], $val['totalMoney']), bcadd($goodsData[$val['shopId']]['preferential'], bcmul($val['preferential'], $val['buyNum'])), 2),//(购物实付金额) 'shopGoodsData' => $shopGoodsData[$val['shopId']],//商品数据 ]; //统计选中商品总数 if ($val['selection'] == StatusCode::$standard) { $checkNum = bcadd($checkNum, 1); $totalMoney = bcadd($totalMoney, $val['totalMoney'], 2); $payMoney =bcadd(bcadd($expressMoney,$val['expressMoney'],2),bcadd($payMoney, bcsub($val['totalMoney'], bcmul($val['buyNum'], $val['preferential'])), 2),2); $preferential = bcadd($preferential, bcmul($val['buyNum'], $val['preferential']), 2); $activityMoney = bcadd($activityMoney, $val['activityMoney'], 2);//互斥商品总金额 $expressMoney = bcadd($expressMoney,$val['expressMoney'],2); } $cartNum = bcadd($cartNum, 1); $goodsNum = bcadd($goodsNum, $val['buyNum']); } //处理运费 if (!empty($this->startDeliveryPrice) && $expressMoney != 0 && $this->startDeliveryPrice <= $payMoney && $this->startDeliveryPrice > 0.01){ $payMoney = bcsub($payMoney,$expressMoney,2); foreach($goodsData as &$datum){ $datum['expressMoney'] = '0.00'; $shopGoodsLists = $datum['shopGoodsData']; foreach ($shopGoodsLists as &$val){ $val['expressMoney'] = '0.00'; } $datum['shopGoodsData'] = $shopGoodsLists; } $expressMoney = '0.00'; } unset($datum); unset($val); $result = [ 'totalMoney' => $totalMoney, 'payMoney' => $payMoney, 'preferential' => $preferential, 'vipDiscount' => $vipDiscount, 'vipDoubleDiscount' => $vipDoubleDiscount, 'activityMoney' => $activityMoney, 'expressMoney' => $expressMoney, 'checkNum' => (int)$checkNum, 'cartNum' => (int)$cartNum, 'goodsNum' => (int)$goodsNum, 'goodsData' => array_values($goodsData), 'invalidData' => array_values($this->invalidData) ]; //会员卡计算 //if (!empty($vipCardId) && $vipCardId != 0) $result = self::vipCardRec($result, $vipCardId); //优惠券计算 if (!empty($userCouponId) && $userCouponId != 0) $result = self::couponRec($result, $userCouponId); if ( (!empty($vipCardId) && $vipCardId != 0) || (!empty($userCouponId) && $userCouponId != 0) ) { //优惠券优惠,会员卡优惠分摊到商品 $result = self::calAvg($result); } return $result; } /** * 获取商品价格,及计算价格 ,(有促销活动的用促销价) * (原数据+price+originPrice+preferential+totalMoney) * @param $data * @return mixed * @throws \Exception */ private function formatPrice($data) { if (empty($data)) return $data; $objMPrice = new MPrice($this->onlineUserId, $this->onlineEnterpriseId); $objMActivity = new MActivity($this->onlineUserId, $this->onlineEnterpriseId); $objMCustomer = new MCustomer($this->onlineEnterpriseId, $this->onlineUserId); $selectParam['material'] = []; $allGoodsId = []; foreach ($data as &$goods) { $allGoodsId[] = $goods['goodsId']; $selectParam['material'][$goods['shopId']][] = $goods['goodsId']; $goods['originPrice'] = 0;//原价 $goods['price'] = 0;//单价 $goods['preferential'] = 0;//优惠差价 $goods['totalMoney'] = 0;//小计(unitPrice*buyNum) $goods['activityMoney'] = 0;//互斥活动商品总金额 $goods['isMutex'] = StatusCode::$delete;//初始化互斥状态 } unset($goods); $selectParam['customerId'] = $this->customerId; $dbResult = $objMPrice->getPrice($selectParam); if (!$dbResult->isSuccess()) { return $data; } $priceResult = $dbResult->getData(); unset($dbResult); $customerResult = $objMCustomer->getCustomerInfoByUserCenterId($this->onlineUserId); $activityArr = []; if ($customerResult->isSuccess()) { $customer = $customerResult->getData(); //获取促销活动价格 $dbResult = $objMActivity->getActivity([ 'goodsId' => implode(',', $allGoodsId), 'customerType' => isset($customer['type']) ? $customer['type'] : 0, ]);//TODO $activityResult = $dbResult->getData(); unset($dbResult); foreach ($activityResult as $activity) { $activityArr[$activity['goodsId'] . $activity['skuId']] = $activity; } } //print_r($activityArr); //商品价格信息 $goodsArr = []; foreach ($priceResult as $shopPriceArr) { foreach ($shopPriceArr as $goodsId => $goodsSkuArr) { $goodsArr[$goodsId] = $goodsSkuArr; } } //print_r($data);die; foreach ($data as &$goods) { //此商品存在促销价 if (isset($activityArr[$goods['goodsId'] . $goods['skuId']])) { $price = $goodsArr[$goods['goodsId']][$goods['skuId']]['salePrice'];//商品正常销售价格 //从缓存中获取活动详情 if (isset($goods['activityId']) && !empty($goods['activityId'])) { $price = $activityArr[$goods['goodsId'] . $goods['skuId']]['price'];//商品活动价格 $activityDetail = $this->objActivityLimitCache->getActivity($goods['activityId']); if (!empty($activityDetail) && $activityDetail['isMutex'] == StatusCode::$standard) { //开启互斥商品的总金额 $goods['activityMoney'] = bcmul($price, $goods['buyNum'], 2); $goods['isMutex'] = StatusCode::$standard; } } } else { if (isset($goodsArr[$goods['goodsId']][$goods['skuId']])) { $priceInfo = $goodsArr[$goods['goodsId']][$goods['skuId']];//此商品规格的价格信息 $price = isset($priceInfo['salePrice']) ? $priceInfo['salePrice'] : 0; // 开启阶梯价 if ($priceInfo['enabledLadder']) { foreach ($priceInfo['ladderPrice'] as $ladder) { if ($goods['buyNum'] >= $ladder['from'] && $goods['buyNum'] <= $ladder['to']) { $price = isset($ladder['price']) ? $ladder['price'] : 0; } } } } } if (!isset($price)) $price = 0; $price = floatval($price); $goods['price'] = sprintf("%.2f", $price); $goods['originPrice'] = sprintf("%.2f", $price);//没有优惠活动暂时原价=销售价 $goods['preferential'] = 0;//优惠券优惠金额 $goods['totalMoney'] = bcmul($price, $goods['buyNum'], 2);//商品小计金额 $goods['vipDiscount'] = 0;//会员卡优惠金额 } return $data; } /** * 获取店铺信息 * (原数据上+店铺名称+店铺logo) * @param $data * @return mixed * @throws \Exception */ private function formatShop($data) { if (empty($data)) return $data; $objMGoods = new MShop($this->onlineEnterpriseId, $this->onlineUserId); $shopData = $objMGoods->getShopName(array_unique(array_column($data, 'shopId'))); if (!empty($shopData)) { foreach ($data as &$shop) { $shop['shopName'] = isset($shopData[$shop['shopId']]['name']) ? $shopData[$shop['shopId']]['name'] : ''; $shop['shopLogo'] = isset($shopData[$shop['shopId']]['logo']) ? $shopData[$shop['shopId']]['logo'] : ''; $shop['cartId'] = $shop['id']; } } return $data; } /** * 商品信息 * (原数据基础上+商品名称+商品图片)商品的状态 下架商品计入失效 * @param $data * @return mixed * @throws \Exception */ private function formatGoods($data) { if (empty($data)) return $data; $objGoodsBasicRelevantCache = new GoodsBasicRelevant($this->onlineEnterpriseId); $objMGoods = new MGoods($this->onlineEnterpriseId, false, $this->onlineUserId); $goodsData = $objMGoods->getGoodsNames(array_unique(array_column($data, 'goodsId'))); if (!empty($goodsData)) { $dbResult = $objMGoods->getNameByGoodsIds(array_values(array_unique(array_column($goodsData, 'basicGoodsId')))); if ($dbResult->isSuccess()) { $basicData = $dbResult->getData(); foreach ($goodsData as &$goods) { $goods['goodsName'] = isset($basicData[$goods['basicGoodsId']]['title']) ? $basicData[$goods['basicGoodsId']]['title'] : ''; $goods['describe'] = isset($basicData[$goods['basicGoodsId']]['describe']) ? $basicData[$goods['basicGoodsId']]['describe'] : ''; $goods['categoryId'] = isset($basicData[$goods['basicGoodsId']]['categoryId']) ? $basicData[$goods['basicGoodsId']]['categoryId'] : ''; $goods['brandId'] = isset($basicData[$goods['basicGoodsId']]['brandId']) ? $basicData[$goods['basicGoodsId']]['brandId'] : ''; $goods['categoryPath'] = isset($basicData[$goods['basicGoodsId']]['categoryPath']) ? $basicData[$goods['basicGoodsId']]['categoryPath'] : ''; $goods['specType'] = isset($basicData[$goods['basicGoodsId']]['specType']) ? $basicData[$goods['basicGoodsId']]['specType'] : StatusCode::$specType['single']; $goods['storageCode'] = isset($basicData[$goods['basicGoodsId']]['storageCode']) ? $basicData[$goods['basicGoodsId']]['storageCode'] : ''; $goods['categoryName'] = empty($goods['categoryId']) ? '' : $objGoodsBasicRelevantCache->getNameByCategoryId($goods['categoryId']); $goods['brandName'] = empty($goods['brandId']) ? '' : $objGoodsBasicRelevantCache->getNameByBrandId($goods['brandId']); } } } $objMSku = new MSku($this->onlineUserId, $this->onlineEnterpriseId); $specNameMapping = $objMSku->getSpecNameBySkuId(array_column($data, 'skuId')); if (!$specNameMapping->isSuccess()) { Logger::logs(E_USER_ERROR,'获取sku错误',__CLASS__,__LINE__,$specNameMapping->getData()); $specNameMapping = []; } else { $specNameMapping = $specNameMapping->getData(); } foreach ($data as $key => &$val) { $val['brandName'] = isset($goodsData[$val['goodsId']]) ? $goodsData[$val['goodsId']]['brandName'] : ''; $val['categoryName'] = isset($goodsData[$val['goodsId']]) ? $goodsData[$val['goodsId']]['categoryName'] : ''; $val['barCode'] = isset($specNameMapping[$val['skuId']]) ? $specNameMapping[$val['skuId']]['barCode'] : ''; $val['storageCode'] = isset($goodsData[$val['goodsId']]['storageCode']) ? $goodsData[$val['goodsId']]['storageCode'] : ''; $val['goodsName'] = isset($goodsData[$val['goodsId']]['goodsName']) ? $goodsData[$val['goodsId']]['goodsName'] : ''; $images = isset($goodsData[$val['goodsId']]['images']) ? json_decode($goodsData[$val['goodsId']]['images'], true) : ''; $val['goodsImages'] = empty($images) ? '' : $images[0]; $val['isInvalid'] = isset($goodsData[$val['goodsId']]) ? $goodsData[$val['goodsId']]['enableStatus'] : StatusCode::$delete;//4=>失效商品 $val['describe'] = isset($goodsData[$val['goodsId']]) ? $goodsData[$val['goodsId']]['describe'] : ''; $val['categoryId'] = isset($goodsData[$val['goodsId']]) ? $goodsData[$val['goodsId']]['categoryId'] : ''; $val['brandId'] = isset($goodsData[$val['goodsId']]) ? $goodsData[$val['goodsId']]['brandId'] : ''; $val['categoryPath'] = isset($goodsData[$val['goodsId']]) ? $goodsData[$val['goodsId']]['categoryPath'] : ''; $val['isActivity'] = empty($val['activityId']) ? StatusCode::$delete : StatusCode::$standard;//是否是活动商品 $val['specType'] = isset($goodsData[$val['goodsId']]) ? $goodsData[$val['goodsId']]['specType'] : StatusCode::$specType['single']; $val['unitName'] = isset($specNameMapping[$val['skuId']]) ? $specNameMapping[$val['skuId']]['unitName'] : ''; $val['specGroup'] = isset($specNameMapping[$val['skuId']]) ? $specNameMapping[$val['skuId']]['specGroup'] : []; $val['notExpress'] = StatusCode::$standard; $val['express'] = [ 'weight' => isset($specNameMapping[$val['skuId']]) ? $specNameMapping[$val['skuId']]['weight'] : 0, 'expressType' => isset($goodsData[$val['goodsId']]) ? $goodsData[$val['goodsId']]['expressType'] : 0, 'ruleId' => isset($goodsData[$val['goodsId']]) ? $goodsData[$val['goodsId']]['ruleId'] : 0, 'expressFee' => isset($goodsData[$val['goodsId']]) ? $goodsData[$val['goodsId']]['expressFee'] : 0, ]; if (isset($goodsData[$val['goodsId']]) && ($goodsData[$val['goodsId']]['enableStatus'] == StatusCode::$delete || $goodsData[$val['goodsId']]['deleteStatus'] == StatusCode::$delete)) { $val['invalidMsg'] = '此商品已下架'; $this->invalidData[] = $val;//失效商品集合 unset($data[$key]); } } return $data; } /** * 查询库存以及成本(*goodsBasicId *warehouseId) 库存不足的商品计入失效 * (原数据+costPrice+inventoryNum) * @param $data * @return mixed * @throws \Exception */ private function formatSkuInventory($data) { $inventorySelectParams = []; $skuIds = []; foreach ($data as &$goods) { $skuIds[] = $goods['skuId']; $goods['inventory'] = 0; $inventorySelectParams[$goods['shopId']][] = $goods['skuId']; } unset($goods); $objMInventory = new MInventory($this->onlineEnterpriseId, $this->onlineUserId); $inventoryMap = []; foreach ($inventorySelectParams as $shopId => $skuIds){ $inventoryResult = $objMInventory->getInventoryByShopIdAndSkuIds($shopId,$skuIds); if (!$inventoryResult->isSuccess()) { return $data; } $inventoryMap[$shopId] = $inventoryResult->getData(); } $objMSku = new MSku($this->onlineUserId, $this->onlineEnterpriseId); foreach ($data as $key => &$goods) { $h=['id'=>$goods['skuId']]; $specNameMapping = $objMSku->getSpecNameBySkuId($h); $specNameMapping = $specNameMapping->getData(); foreach ($specNameMapping as $v){ $thisSku=$v; } //兼容带属性的 $goods['costPrice'] = 0; $goods['inventoryNum'] = isset($inventoryMap[$goods['shopId']][$goods['skuId']]['num']) ? $inventoryMap[$goods['shopId']][$goods['skuId']]['num'] : 0; $goods['conversion'] = $thisSku['conversion'];//换算比例 if ($goods['inventoryNum'] < $goods['buyNum']) { $goods['isInvalid'] = StatusCode::$delete; $goods['invalidMsg'] = '商品库存不足'; $this->invalidData[] = $goods; unset($data[$key]); } } return $data; } /** * 缓存用户限购 * @param $data * @return mixed */ private function userLimit($data) { $result = false; foreach ($data as $goods) { $result = $this->objActivityLimitCache->writeLimit($goods['activityId'], $goods['goodsId'], $goods['skuId'], $this->onlineUserId, $goods['buyNum']); } return $result; } /** * Doc: (des="检测商品") * User: XMing * Date: 2020/8/4 * Time: 3:21 下午 * @param array $goodsData * @param array $addCart * @return ResultWrapper */ private static function checkGoods(array $goodsData,array $addCart) { if (empty($goodsData)){ return ResultWrapper::fail('商品信息为空',ErrorCode::$paramError); } //验证商品的状态以及库存 if ($goodsData['enableStatus'] == StatusCode::$delete || $goodsData['deleteStatus'] == StatusCode::$delete){ return ResultWrapper::fail('商品已下架',ErrorCode::$paramError); } $specMultiple = $goodsData['specMultiple'];//spec数据 if (empty($specMultiple)){ return ResultWrapper::fail('商品规格信息获取失败',ErrorCode::$paramError); } $specMultipleMap = [];//商品规格映射数据 foreach ($specMultiple as $value){ $specMultipleMap[$value['id']] = $value; } if (!isset($specMultipleMap[$addCart['skuId']])) { return ResultWrapper::fail('规格信息不存在', ErrorCode::$paramError); } if ($specMultipleMap[$addCart['skuId']]['inventory'] < $addCart['buyNum']) { return ResultWrapper::fail('商品库存不足', ErrorCode::$paramError); } $addCart['isActivity'] = $specMultipleMap[$addCart['skuId']]['isActivity'];//是否是活动商品 $addCart['setNum'] = $specMultipleMap[$addCart['skuId']]['setNum'];//起订数量 $addCart['warehouseId'] = $addCart['warehouseId']; switch ($specMultipleMap[$addCart['skuId']]['isActivity']){ case StatusCode::$standard: $addCart['activityId'] = $specMultipleMap[$addCart['skuId']]['activity']['activityId']; $addCart['limitNum'] = $specMultipleMap[$addCart['skuId']]['activity']['limitNum'];//商品活动限购数量 break; case StatusCode::$delete: $addCart['activityId'] = 0; break; } return ResultWrapper::success($addCart); } /** * 将加入购物车的数据进行分组[old=>在购物车中已存在,now=>新加入购物车商品] * @param $nowData [加入购物车的数据] * @return ResultWrapper */ private function existCartAndGroup($nowData) { $dbResult = self::getCartByUid(); if (!$dbResult->isSuccess()) { return ResultWrapper::fail('获取购物车数据失败', ErrorCode::$dberror); } $oldCartData = $dbResult->getData(); $allHash = []; foreach ($oldCartData as $key => $val) { $allHash[] = md5($val['goodsId'] . $val['shopId'] . $val['skuId'] . $val['activityId']); } $old = [];//旧的数据 $now = [];//新的数据 foreach ($nowData as $key => &$val) { $md5 = md5($val['goodsId'] . $val['shopId'] . $val['skuId'] . $val['activityId']); if (in_array($md5, $allHash)) { $old[] = $val; } else { //之前购物车中没有此商品,检查起订量 if ($val['setNum'] != 0) { //具有起订量 if ($val['buyNum'] < $val['setNum']){ $val['buyNum'] = $val['setNum']; } } $now[] = $val; } } $groupData = [ 'old' => $old, 'now' => $now ]; return ResultWrapper::success($groupData); } /** * 获取当前用户的购物车数据 */ private function getCartByUid() { $result = $this->objDCashierCart->select(['cashierUid' => $this->cashierUid], 'id,goodsId,goodsCode,buyNum,shopId,goodsBasicId,selection,skuId,warehouseId,activityId,cashierUid', 'createTime DESC'); if ($result === false) { return ResultWrapper::fail($this->objDCashierCart->error(), ErrorCode::$dberror); } return ResultWrapper::success($result); } /** * * 优惠计算分摊规则 * A商品 100元 * B商品 300元 * 商品总价 400元 * * A商品享受的优惠 = 优惠券金额*(A商品原价/商品总价) * B商品享受的优惠 = 优惠券金额*(B商品原价/商品总价) * * 5折会员卡 400*0.5=200元 -200 * 优惠券(满100减20) -20 * 共 -220 * 实际付款 180 * A总(220*(100/400)=55) 优惠券(20*(100/400)=5) 会员卡(200*(100/400)=50) * B总(220*(300/400)=165) 优惠券(20*(300/400)=15) 会员卡(200*(300/400)=150) * @param $data * @return mixed */ private function calAvg($data) { $account = 0; $vipAccount = 0; foreach ($data['goodsData'] as &$shops) { $count = count($shops['shopGoodsData']); foreach ($shops['shopGoodsData'] as $key => &$goods) { if ($goods['isMutex'] == StatusCode::$delete) { //活动商品不分摊 if ($data['preferential'] != 0) { //有优惠券优惠,分摊金额 if ($key+1 != $count) { $goods['preferential'] = bcmul($data['preferential'], bcdiv($goods['totalMoney'], $data['totalMoney'], 2), 2); $account = bcadd($account,$goods['preferential'],2); }else{ //最后一个商品分摊金额=总优惠-其他均摊 $goods['preferential'] = bcsub($data['preferential'],$account,2); } } } if ($data['vipDiscount'] != 0) { //有会员卡折扣,分摊金额 if ($key+1 != $count){ $goods['vipDiscount'] = bcmul($data['vipDiscount'], bcdiv($goods['totalMoney'], $data['totalMoney'], 2), 2); $vipAccount = bcadd($vipAccount,$goods['vipDiscount'],2); }else{ $goods['vipDiscount'] = bcsub($data['vipDiscount'],$vipAccount,2); } } } } return $data; } /** * 优惠券优惠 * @param $data * @param $userCouponId * @return mixed * @throws \Exception */ private function couponRec($data, $userCouponId) { //优惠券 $userCouponInfo = []; if (!empty($userCouponId)) { $objMUserCoupon = new MUserCoupon($this->onlineUserId, $this->onlineEnterpriseId); $dbResult = $objMUserCoupon->getUserCoupon(['id' => $userCouponId]); if ($dbResult->isSuccess()) $userCouponInfo = $dbResult->getData(); $userCouponInfo = isset($userCouponInfo[0]) ? $userCouponInfo[0] : []; $isMutex = $userCouponInfo['isMutex'];//是否与活动互斥 if ($userCouponInfo['applyRange'] == StatusCode::$applyRange['allGoods']) { //优惠券的使用范围所有商品 if ($userCouponInfo['minPrice'] == 0 || $data['payMoney'] >= $userCouponInfo['minPrice']) { //满足最低消费金额 $data['payMoney'] = bcsub($data['payMoney'], $userCouponInfo['reducePrice'], 2); if ($data['payMoney'] < 0) { $data['payMoney'] = 0;//优惠券面值不合理导致优惠后价格小于0 } $data['preferential'] = bcadd($data['preferential'], $userCouponInfo['reducePrice'], 2); } } else if ($userCouponInfo['applyRange'] == StatusCode::$applyRange['appointCategory']) { //优惠券使用范围指定分类 $couponCategory = $userCouponInfo['categoryCollect']; if (!empty($couponCategory)) { $goodsAmount = 0; //满足特定商品分类的(商品总额),初始化 $couponCategory = explode(',', $couponCategory); //计算符合分类中商品价格总和 foreach (array_values($data['goodsData']) as $shop) { foreach ($shop['shopGoodsData'] as $value) { //$value['categoryId'] if (in_array($value['categoryId'], $couponCategory)) { //满足特定商品分类的(商品总额) $goodsAmount = bcadd($goodsAmount, $value['totalMoney']); } } } //商品总额是否满足最低金额 if ($userCouponInfo['minPrice'] == 0 || $goodsAmount >= $userCouponInfo['minPrice']) { $data['payMoney'] = bcsub($data['payMoney'], $userCouponInfo['reducePrice'], 2); if ($data['payMoney'] < 0) { $data['payMoney'] = 0;//优惠券面值不合理导致优惠后价格小于0 } $data['preferential'] = bcadd($data['preferential'], $userCouponInfo['reducePrice'], 2); } } } else if ($userCouponInfo['applyRange'] == StatusCode::$applyRange['appointBrand']) { //优惠券使用范围指定品牌 $couponBrand = $userCouponInfo['brandCollect']; if (!empty($couponBrand)) { $goodsAmount = 0; //满足特定商品品牌的(商品总额),初始化 $couponBrand = explode(',', $couponBrand); //计算符合品牌中商品价格总和 foreach (array_values($data['goodsData']) as $shop) { foreach ($shop['shopGoodsData'] as $value) { //$value['categoryId'] if (in_array($value['brandId'], $couponBrand)) { //满足特定商品品牌的(商品总额) $goodsAmount = bcadd($goodsAmount, $value['totalMoney']); } } } //商品总额是否满足最低金额 if ($userCouponInfo['minPrice'] == 0 || $goodsAmount >= $userCouponInfo['minPrice']) { $data['payMoney'] = bcsub($data['payMoney'], $userCouponInfo['reducePrice'], 2); if ($data['payMoney'] < 0) { $data['payMoney'] = 0;//优惠券面值不合理导致优惠后价格小于0 } $data['preferential'] = bcadd($data['preferential'], $userCouponInfo['reducePrice'], 2); } } } unset($dbResult); } return $data; } }