diff --git a/composer.json b/composer.json index fbd2873..a2417d9 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "laravel/lumen", - "version": "4.5.0", + "version": "4.5.1", "description": "The Laravel Lumen Framework.", "keywords": [ "framework", diff --git a/config/migrations.php b/config/migrations.php index 0db29e8..9294fd7 100644 --- a/config/migrations.php +++ b/config/migrations.php @@ -76,7 +76,7 @@ return [ | */ 'schema' => [ - 'filter' => '/^(?!password_resets|failed_jobs|.*_lang_enCN|.*_lang_zhCN|.*_lang_encn|.*_lang_zhcn|.*_lang_[a-z]{2}[A-Z]{2}).*$/' + 'filter' => '/^(?!password_resets|failed_jobs|.*_lang_enCN|.*_lang_zhCN|.*_lang_encn|.*_lang_zhcn|.*_lang_[a-z]{2}[A-Z]{2}|outside_item_multi_lang_mod_lang_.*|item_multi_lang_mod_lang_.*).*$/' ], /* |-------------------------------------------------------------------------- diff --git a/src/DistributionBundle/Http/Api/V1/Action/PickupLocation.php b/src/DistributionBundle/Http/Api/V1/Action/PickupLocation.php index 33da113..4d811e6 100644 --- a/src/DistributionBundle/Http/Api/V1/Action/PickupLocation.php +++ b/src/DistributionBundle/Http/Api/V1/Action/PickupLocation.php @@ -249,12 +249,14 @@ class PickupLocation extends Controller $filter['distributor_id'] = 0; if ($operatorType == 'distributor') { //店铺端 $filter['distributor_id'] = $request->get('distributor_id'); + }else{ + unset($filter['distributor_id']); } - if (isset($params['rel_distributor_id']) && $params['rel_distributor_id']) { - $filter['rel_distributor_id'] = $params['rel_distributor_id']; - unset($filter['distributor_id']); //总部 - } + // if (isset($params['rel_distributor_id']) && $params['rel_distributor_id']) { + // $filter['rel_distributor_id'] = $params['rel_distributor_id']; + // unset($filter['distributor_id']); //总部 + // } if (isset($params['name']) && $params['name']) { $filter['name|contains'] = $params['name']; @@ -327,6 +329,8 @@ class PickupLocation extends Controller $filter['distributor_id'] = 0; if ($operatorType == 'distributor') { //店铺端 $filter['distributor_id'] = $request->get('distributor_id'); + }else{ + unset($filter['distributor_id']); } $pickupLocationService = new PickupLocationService(); $pickupLocationService->deleteBy($filter); diff --git a/src/GoodsBundle/ApiServices/ItemsCategoryService.php b/src/GoodsBundle/ApiServices/ItemsCategoryService.php index 28134bb..88ce08a 100644 --- a/src/GoodsBundle/ApiServices/ItemsCategoryService.php +++ b/src/GoodsBundle/ApiServices/ItemsCategoryService.php @@ -24,6 +24,7 @@ use Dingo\Api\Exception\ResourceException; use GoodsBundle\Events\ItemCategoryAddEvent; use GoodsBundle\Services\ItemsAttributesService; use GoodsBundle\Services\ItemsRelCatsService; +use Doctrine\DBAL\Connection; class ItemsCategoryService { @@ -319,6 +320,11 @@ class ItemsCategoryService throw new ResourceException('分类下存在商品'); } } + // 校验供应商商品销售分类关联 + $supplierSaleCategoryTotal = $this->countSupplierItemsBySaleCategoryTree((int)$filter['company_id'], (int)$filter['category_id']); + if ($supplierSaleCategoryTotal > 0) { + throw new ResourceException('分类下存在供应商商品'); + } $mainCatIds = $this->getMainCatChildIdsBy($filter['category_id'], $filter['company_id']); $mainCatIds[] = $filter['category_id']; @@ -327,6 +333,11 @@ class ItemsCategoryService if ($itemTotalCount > 0) { throw new ResourceException('类目下存在商品'); } + // 校验供应商商品管理分类关联 + $supplierMainCategoryTotal = $this->countSupplierItemsByMainCategory((int)$filter['company_id'], $mainCatIds); + if ($supplierMainCategoryTotal > 0) { + throw new ResourceException('类目下存在供应商商品'); + } if ($ids) { $itemsService = new ItemsRelCatsService(); @@ -361,6 +372,83 @@ class ItemsCategoryService } } + /** + * 统计供应商商品在销售分类树中的关联数量(一级/二级/三级) + */ + private function countSupplierItemsBySaleCategoryTree(int $companyId, int $categoryId): int + { + $categoryIds = $this->getItemsCategoryIds($categoryId, $companyId); + $categoryIds = array_values(array_unique(array_map('intval', (array)$categoryIds))); + if (!$categoryIds) { + return 0; + } + + $conn = app('registry')->getConnection('default'); + $targetCategoryIds = array_fill_keys($categoryIds, true); + + // 分批扫描,命中即返回,避免一次性拉取全量数据。 + $lastId = 0; + $batchSize = 500; + while (true) { + $qb = $conn->createQueryBuilder(); + $qb->select('sa.id, sa.attr_data') + ->from('supplier_items_attr', 'sa') + ->innerJoin('sa', 'supplier_items', 'si', 'sa.item_id = si.item_id AND si.company_id = :company_id') + ->where('sa.company_id = :company_id') + ->andWhere('sa.attribute_type = :attribute_type') + ->andWhere('sa.id > :last_id') + ->orderBy('sa.id', 'ASC') + ->setMaxResults($batchSize) + ->setParameter('company_id', $companyId) + ->setParameter('attribute_type', 'category') + ->setParameter('last_id', $lastId); + $rows = $qb->execute()->fetchAll(); + if (!$rows) { + return 0; + } + + foreach ($rows as $row) { + $lastId = (int)$row['id']; + if (empty($row['attr_data'])) { + continue; + } + $attrData = json_decode($row['attr_data'], true); + $saleCategoryIds = $attrData['category'] ?? []; + if (!is_array($saleCategoryIds) || !$saleCategoryIds) { + continue; + } + foreach ($saleCategoryIds as $saleCategoryId) { + if (isset($targetCategoryIds[(int)$saleCategoryId])) { + return 1; + } + } + } + } + } + + /** + * 统计供应商商品在管理分类树中的关联数量(一级/二级/三级) + */ + private function countSupplierItemsByMainCategory(int $companyId, array $mainCategoryIds): int + { + $mainCategoryIds = array_values(array_unique(array_map('intval', (array)$mainCategoryIds))); + if (!$mainCategoryIds) { + return 0; + } + + $conn = app('registry')->getConnection('default'); + $qb = $conn->createQueryBuilder(); + $qb->select('si.item_id') + ->from('supplier_items', 'si') + ->where('si.company_id = :company_id') + ->andWhere('si.item_category IN (:item_category)') + ->setMaxResults(1) + ->setParameter('company_id', $companyId) + ->setParameter('item_category', $mainCategoryIds, Connection::PARAM_INT_ARRAY); + $row = $qb->execute()->fetch(); + return $row ? 1 : 0; + } + /** * 递归实现无限极分类 * @param array $array 分类数据 diff --git a/src/GoodsBundle/Services/ItemsService.php b/src/GoodsBundle/Services/ItemsService.php index ff1b20a..b2896b2 100644 --- a/src/GoodsBundle/Services/ItemsService.php +++ b/src/GoodsBundle/Services/ItemsService.php @@ -54,6 +54,7 @@ use CompanysBundle\Services\ArticleService; use CompanysBundle\Services\SettingService as CompanysSettingService; use WechatBundle\Services\Material as MaterialService; +use PromotionsBundle\Services\PromotionSeckillActivityService; use PromotionsBundle\Services\MemberPriceService; use MembersBundle\Services\MemberService; use KaquanBundle\Services\VipGradeService; @@ -2889,6 +2890,8 @@ class ItemsService ]; $marketingService = new MarketingActivityService(); + $seckillActivityService = new PromotionSeckillActivityService(); + $seckillActivityCache = []; foreach ($itemList as &$items) { if (!isset($items['goods_id'])) { continue; @@ -2897,6 +2900,7 @@ class ItemsService if (isset($newTags['all']) && $newTags['all']) { $promotion_activity = array_merge($promotion_activity, $newTags['all']); } + $promotionSeckillActivityService = new PromotionSeckillActivityService(); foreach ($promotion_activity as $data) { $itemDistributorId = $items['distributor_id'] ?? 0;//商品所属的店铺 if (in_array($data['tag_type'], $allTagType)) { @@ -2931,8 +2935,51 @@ class ItemsService continue; } } + } elseif ($data['tag_type'] == 'limited_time_sale') { + if (!isset($seckillActivityCache[$data['promotion_id']])) { + $seckillActivityCache[$data['promotion_id']] = $seckillActivityService->getInfo([ + 'company_id' => $companyId, + 'seckill_id' => $data['promotion_id'], + 'disabled' => 0, + ]); + } + $seckillActivity = $seckillActivityCache[$data['promotion_id']]; + if (!$seckillActivity) { + continue; + } + + // 平台活动和店铺活动互斥展示,和详情页活动校验保持一致。 + $activitySourceId = (int)($seckillActivity['source_id'] ?? 0); + if ($activitySourceId !== (int)$itemDistributorId) { + continue; + } + + $activityDistributorIds = $seckillActivity['distributor_id'] ?? []; + if (!is_array($activityDistributorIds)) { + $activityDistributorIds = explode(',', trim($activityDistributorIds, ',')); + } + $activityDistributorIds = array_values(array_filter(array_map('intval', $activityDistributorIds), function ($id) { + return $id >= 0; + })); + + if ($activityDistributorIds && !in_array((int)$itemDistributorId, $activityDistributorIds, true)) { + continue; + } } + /* if ($data['tag_type'] == 'limited_time_sale') { + $limitActivity = $promotionSeckillActivityService->getInfoById($data['promotion_id']); + if ($itemDistributorId > 0) { + if (!$limitActivity) { + continue; + } + // 店铺和平台的限时特惠各自独立 + if (($limitActivity['source_id'] ?? 0) != $itemDistributorId) { + continue; + } + } + } */ + $items['promotion_activity'][] = $data; if (in_array($data['tag_type'], ['single_group', 'normal', 'limited_time_sale'])) { $items['activity_price'] = $data['activity_price']; diff --git a/src/KaquanBundle/Repositories/MembercardGradeRepository.php b/src/KaquanBundle/Repositories/MembercardGradeRepository.php index f71ec20..a2afb27 100644 --- a/src/KaquanBundle/Repositories/MembercardGradeRepository.php +++ b/src/KaquanBundle/Repositories/MembercardGradeRepository.php @@ -17,6 +17,8 @@ namespace KaquanBundle\Repositories; +use CompanysBundle\MultiLang\MultiLangItem; +use Doctrine\Common\Collections\Criteria; use Doctrine\ORM\EntityRepository; use GoodsBundle\Services\MultiLang\MagicLangTrait; use GoodsBundle\Services\MultiLang\MultiLangService; @@ -170,6 +172,110 @@ class MembercardGradeRepository extends EntityRepository return $this->findOneBy($filter); } + /** + * 按等级名称查询列表(参考 GoodsBundle\Repositories\ItemsAttributesRepository::listsByAttributeName) + * 若 filter 含 grade_name,先查多语言表得到 grade_id,再交给 getList;多语言未命中时保留 grade_name 由主表默认语言匹配。 + * + * @param array $filter 查询条件 + * @param int $offset + * @param int $limit + * @param mixed $OrderBy + * @return array + */ + public function getListByGradeName($filter = [], $offset = 0, $limit = -1, $OrderBy = null) + { + if (isset($filter['grade_name']) && $filter['grade_name'] !== '' && $filter['grade_name'] !== null) { + $gradeNames = is_array($filter['grade_name']) ? $filter['grade_name'] : [$filter['grade_name']]; + $gradeIds = $this->getGradeIdsByNames($gradeNames, $filter); + if (!empty($gradeIds)) { + if (isset($filter['grade_id'])) { + $existingIds = is_array($filter['grade_id']) ? $filter['grade_id'] : [$filter['grade_id']]; + $gradeIds = array_values(array_intersect($existingIds, $gradeIds)); + } + if (!empty($gradeIds)) { + unset($filter['grade_name']); + $filter['grade_id'] = $gradeIds; + } + } + } + + return $this->getList('*', $filter, $offset, $limit, $OrderBy); + } + + /** + * 按等级名称解析单条等级(主表 + 多语言),用于导入等场景。 + */ + public function getByGradeNameWithMultiLang($companyId, $gradeName): ?MemberCardGrade + { + if ($gradeName === null || $gradeName === '') { + return null; + } + $rows = $this->getListByGradeName(['company_id' => $companyId, 'grade_name' => $gradeName], 0, 1); + if (empty($rows)) { + return null; + } + $gradeId = $rows[0]['grade_id'] ?? null; + if ($gradeId === null) { + return null; + } + + return $this->findOneBy(['company_id' => $companyId, 'grade_id' => $gradeId]); + } + + /** + * 根据等级名称(多语言 attribute_value)解析 grade_id,并在主表按 company_id 校验。 + * + * @param string[] $gradeNames + * @param array $filter 须含 company_id 等主表条件 + * @return int[] + */ + private function getGradeIdsByNames(array $gradeNames, array $filter = []): array + { + if (empty($gradeNames)) { + return []; + } + $lang = $this->getLang(); + $multiLangItem = new MultiLangItem($lang); + $langFilter = [ + 'table_name' => $this->table, + 'field' => 'grade_name', + 'attribute_value|in' => $gradeNames, + ]; + $langList = $multiLangItem->getListByFilter($langFilter, -1); + if (empty($langList)) { + return []; + } + $gradeIds = array_column($langList, 'data_id'); + $gradeIds = array_unique($gradeIds); + if (empty($gradeIds)) { + return []; + } + $verifyFilter = ['grade_id' => $gradeIds]; + foreach (['company_id'] as $key) { + if (isset($filter[$key])) { + $verifyFilter[$key] = $filter[$key]; + } + } + if (count($verifyFilter) === 1) { + return array_values(array_map('intval', $gradeIds)); + } + $criteria = Criteria::create(); + foreach ($verifyFilter as $field => $value) { + if (is_array($value)) { + $criteria = $criteria->andWhere(Criteria::expr()->in($field, $value)); + } else { + $criteria = $criteria->andWhere(Criteria::expr()->eq($field, $value)); + } + } + $entityList = $this->matching($criteria); + $verifiedIds = []; + foreach ($entityList as $entity) { + $verifiedIds[] = (int) $entity->getGradeId(); + } + + return $verifiedIds; + } + public function getList($cols = '*', $filter = array(), $offset = 0, $limit = -1, $OrderBy = null) { $conn = app('registry')->getConnection('default'); diff --git a/src/KaquanBundle/Services/MemberCardService.php b/src/KaquanBundle/Services/MemberCardService.php index ab1caf2..ffd2e2b 100644 --- a/src/KaquanBundle/Services/MemberCardService.php +++ b/src/KaquanBundle/Services/MemberCardService.php @@ -64,6 +64,15 @@ class MemberCardService return null; } + /** + * 按等级名称解析 grade_id(主表默认语言 + 多语言表),逻辑见 MembercardGradeRepository::getListByGradeName。 + */ + public function getGradeIdByNameWithMultiLang($companyId, $gradeName): ?int + { + $grade = $this->memberCardGradeRepository->getByGradeNameWithMultiLang($companyId, $gradeName); + return $grade ? $grade->getGradeId() : null; + } + /** * 创建会员卡默认等级 */ diff --git a/src/MembersBundle/Services/MemberRegSettingService.php b/src/MembersBundle/Services/MemberRegSettingService.php index fb7b1a9..acc74c4 100644 --- a/src/MembersBundle/Services/MemberRegSettingService.php +++ b/src/MembersBundle/Services/MemberRegSettingService.php @@ -232,7 +232,7 @@ class MemberRegSettingService //保存验证码 $this->saveSmsVcode($phone, $companyId, $vcode, $type); //发送短信 - $this->sendSmsVcode($companyId, $phone, $vcode); + $this->sendSmsVcode($companyId, $phone, $vcode, $type); return true; } @@ -272,11 +272,11 @@ class MemberRegSettingService } //短信验证码的发送动作 - private function sendSmsVcode($companyId, $phone, $code) + private function sendSmsVcode($companyId, $phone, $code, $type) { $data = ['code' => $code]; $smsManagerService = new SmsManagerService($companyId); - $smsManagerService->send($phone, $companyId, 'verification_code', $data); + $smsManagerService->send($phone, $companyId, $type, $data); // verification_code return true; } } diff --git a/src/MembersBundle/Services/MemberUploadService.php b/src/MembersBundle/Services/MemberUploadService.php index 99e6aae..f6cda40 100644 --- a/src/MembersBundle/Services/MemberUploadService.php +++ b/src/MembersBundle/Services/MemberUploadService.php @@ -291,7 +291,7 @@ class MemberUploadService private function getGradeIdByName($companyId, $gradeName) { $memberCardService = new MemberCardService(); - $gradeId = $memberCardService->getGradeIdByName($companyId, $gradeName); + $gradeId = $memberCardService->getGradeIdByNameWithMultiLang($companyId, $gradeName); if (!$gradeId) { throw new BadRequestHttpException(trans('MembersBundle/Members.member_level_not_exists', ['{0}' => $gradeName])); } diff --git a/src/MembersBundle/Services/MemberUploadUpdateService.php b/src/MembersBundle/Services/MemberUploadUpdateService.php index 129403d..2490e32 100644 --- a/src/MembersBundle/Services/MemberUploadUpdateService.php +++ b/src/MembersBundle/Services/MemberUploadUpdateService.php @@ -234,7 +234,7 @@ class MemberUploadUpdateService private function getGradeIdByName($companyId, $gradeName) { $memberCardService = new MemberCardService(); - $gradeId = $memberCardService->getGradeIdByName($companyId, $gradeName); + $gradeId = $memberCardService->getGradeIdByNameWithMultiLang($companyId, $gradeName); if (!$gradeId) { throw new BadRequestHttpException(trans('MembersBundle/Members.member_level_not_exists', ['{0}' => $gradeName])); } diff --git a/src/OrdersBundle/Services/OrderService.php b/src/OrdersBundle/Services/OrderService.php index 9f7e4cc..ae9d8fd 100644 --- a/src/OrdersBundle/Services/OrderService.php +++ b/src/OrdersBundle/Services/OrderService.php @@ -992,59 +992,7 @@ class OrderService $orderData = $specificCrowdDiscountService->getUserOrientationDiscount($params['company_id'], $params['user_id'], $orderData); } - // 赠品金额分摊 - if ($orderData['order_type'] == 'normal' && isset($orderData['items_promotion'])) { - $giftActivitys = []; - foreach ($orderData['items_promotion'] as $itemPromotion) { - if ($itemPromotion['activity_type'] == 'full_gift') { - if (!isset($giftActivitys[$itemPromotion['activity_id']])) { - $giftActivitys[$itemPromotion['activity_id']] = $itemPromotion['activity_desc']; - } - } - } - foreach ($giftActivitys as $activityId => $giftActivity) { - $itemsTotalFee = []; - $totalGiftFee = 0; - foreach ($orderData['items'] as $key => $item) { - if ($item['order_item_type'] == 'normal' && in_array($item['item_id'], $giftActivity['activity_item_ids'])) { - $itemsTotalFee[$key] = $item['total_fee']; - } - if ($item['order_item_type'] == 'gift' && $item['activity_id'] == $activityId) { - $itemsTotalFee[$key] = $item['item_fee']; - $totalGiftFee += $item['item_fee']; - } - } - asort($itemsTotalFee); - - $percent = bcdiv($totalGiftFee, array_sum($itemsTotalFee), 5); - $i = 1; - foreach ($itemsTotalFee as $key => $itemTotalFee) { - if ($i++ == count($itemsTotalFee)) { - $discountFee = $totalGiftFee; - } else { - $discountFee = bcmul($itemTotalFee, $percent); - $totalGiftFee -= $discountFee; - } - - if ($orderData['items'][$key]['order_item_type'] == 'normal') { - $orderData['items'][$key]['discount_fee'] += $discountFee; - $orderData['items'][$key]['total_fee'] -= $discountFee; - } - - if ($orderData['items'][$key]['order_item_type'] == 'gift') { - $orderData['items'][$key]['discount_fee'] = $discountFee; - $orderData['items'][$key]['total_fee'] = $orderData['items'][$key]['item_fee'] - $discountFee; - } - - $itemDiscountInfo = $giftActivity['discount_desc']; - $itemDiscountInfo['discount_fee'] = $discountFee; - if (!isset($orderData['items'][$key]['discount_info'])) { - $orderData['items'][$key]['discount_info'] = []; - } - array_push($orderData['items'][$key]['discount_info'], $itemDiscountInfo); - } - } - } + $orderData = $this->allocateFullGiftDiscounts($orderData); //余额支付 if ('deposit' == $params['pay_type']) { @@ -1085,6 +1033,82 @@ class OrderService return $orderData; } + protected function allocateFullGiftDiscounts(array $orderData): array + { + if (($orderData['order_type'] ?? '') !== 'normal' || !isset($orderData['items_promotion'])) { + return $orderData; + } + + $giftActivitys = []; + foreach ($orderData['items_promotion'] as $itemPromotion) { + if (($itemPromotion['activity_type'] ?? '') !== 'full_gift') { + continue; + } + + $activityId = $itemPromotion['activity_id'] ?? 0; + if (!$activityId || isset($giftActivitys[$activityId])) { + continue; + } + + $giftActivitys[$activityId] = $itemPromotion['activity_desc'] ?? []; + } + + foreach ($giftActivitys as $activityId => $giftActivity) { + $activityItemIds = $giftActivity['activity_item_ids'] ?? []; + $itemsTotalFee = []; + $totalGiftFee = 0; + foreach ($orderData['items'] as $key => $item) { + if (($item['order_item_type'] ?? '') == 'normal' && in_array($item['item_id'], $activityItemIds)) { + $itemsTotalFee[$key] = $item['total_fee']; + } + if (($item['order_item_type'] ?? '') == 'gift' && (($item['activity_id'] ?? 0) == $activityId)) { + $itemsTotalFee[$key] = $item['item_fee']; + $totalGiftFee += $item['item_fee']; + } + } + + if (!$itemsTotalFee || $totalGiftFee <= 0) { + continue; + } + + asort($itemsTotalFee); + $sumItemTotalFee = array_sum($itemsTotalFee); + if ($sumItemTotalFee <= 0) { + continue; + } + + $percent = bcdiv($totalGiftFee, $sumItemTotalFee, 5); + $i = 1; + foreach ($itemsTotalFee as $key => $itemTotalFee) { + if ($i++ == count($itemsTotalFee)) { + $discountFee = $totalGiftFee; + } else { + $discountFee = bcmul($itemTotalFee, $percent); + $totalGiftFee -= $discountFee; + } + + if ($orderData['items'][$key]['order_item_type'] == 'normal') { + $orderData['items'][$key]['discount_fee'] += $discountFee; + $orderData['items'][$key]['total_fee'] -= $discountFee; + } + + if ($orderData['items'][$key]['order_item_type'] == 'gift') { + $orderData['items'][$key]['discount_fee'] = $discountFee; + $orderData['items'][$key]['total_fee'] = $orderData['items'][$key]['item_fee'] - $discountFee; + } + + $itemDiscountInfo = $giftActivity['discount_desc'] ?? []; + $itemDiscountInfo['discount_fee'] = $discountFee; + if (!isset($orderData['items'][$key]['discount_info'])) { + $orderData['items'][$key]['discount_info'] = []; + } + array_push($orderData['items'][$key]['discount_info'], $itemDiscountInfo); + } + } + + return $orderData; + } + // 设置和返回千人千码的最新参数 private function getTrackIds($companyId, $params) { diff --git a/src/OrdersBundle/Services/Orders/AbstractNormalOrder.php b/src/OrdersBundle/Services/Orders/AbstractNormalOrder.php index 05145a7..31ba045 100644 --- a/src/OrdersBundle/Services/Orders/AbstractNormalOrder.php +++ b/src/OrdersBundle/Services/Orders/AbstractNormalOrder.php @@ -4025,7 +4025,7 @@ class AbstractNormalOrder implements OrderInterface if ($item == end($orderInfo['items'])) { $newItemTotalFee = $leftTotalFee; } else { - $newItemTotalFee = bcmul($totalFee, $item['total_fee'] / $oldTotalFee); + $newItemTotalFee = $this->multiplyByRatio($totalFee, $item['total_fee'], $oldTotalFee); } if ($newItemTotalFee != $item['total_fee']) { $itemMarkDownFee = bcsub($item['total_fee'], $newItemTotalFee); @@ -4068,7 +4068,7 @@ class AbstractNormalOrder implements OrderInterface foreach ($orderInfo['items'] as $key => $item) { if (isset($items[$item['item_id']])) { if (isset($items[$item['item_id']]['discount'])) { - $newItemTotalFee = bcmul($item['total_fee'], $items[$item['item_id']]['discount'] / 100); + $newItemTotalFee = $this->multiplyByRatio($item['total_fee'], $items[$item['item_id']]['discount'], 100); } else { $newItemTotalFee = $items[$item['item_id']]['total_fee']; } @@ -4110,6 +4110,17 @@ class AbstractNormalOrder implements OrderInterface return $orderInfo; } + private function multiplyByRatio($amount, $numerator, $denominator, int $ratioScale = 10, int $resultScale = 0) + { + if ((string) $denominator === '0' || (string) $denominator === '') { + return '0'; + } + + $ratio = bcdiv((string) $numerator, (string) $denominator, $ratioScale); + + return bcmul((string) $amount, $ratio, $resultScale); + } + public function saveMarkDown($orderInfo, $params) { $oldOrderInfo = $orderInfo; $orderInfo = $this->markDown($orderInfo, $params); diff --git a/src/PromotionsBundle/Services/PackageService.php b/src/PromotionsBundle/Services/PackageService.php index 3886c6d..906e6e7 100644 --- a/src/PromotionsBundle/Services/PackageService.php +++ b/src/PromotionsBundle/Services/PackageService.php @@ -50,6 +50,11 @@ class PackageService $this->packageItemRepository = app('registry')->getManager('default')->getRepository(PackageItemPromotions::class); } + protected function makeItemsService(): ItemsService + { + return new ItemsService(); + } + /** * 获取组合商品信息 * @param int $companyId 公司id @@ -79,7 +84,7 @@ class PackageService $info['new_price'][$v['item_id']] = (int)$v['package_price']; } //获取组合活动包含的商品的所有明细 - $itemService = new ItemsService(); + $itemService = $this->makeItemsService(); $filter = ['company_id' => $companyId, 'item_id' => $itemIds]; $itemsList = $itemService->getSkuItemsList($filter); foreach ($itemsList['list'] as $key => &$items) { @@ -98,9 +103,14 @@ class PackageService $relItems[] = $itemdata[$value['item_id']]; } } - $itemdata[$info['main_item_id']]['price'] = (int)$info['main_item_price']; + if (isset($itemdata[$info['main_item_id']])) { + $itemdata[$info['main_item_id']]['price'] = (int)$info['main_item_price']; + } $info['items'] = $itemsList['list']; - $info['mainItem'][] = $itemdata[$info['main_item_id']]; + $info['mainItem'] = []; + if (isset($itemdata[$info['main_item_id']])) { + $info['mainItem'][] = $itemdata[$info['main_item_id']]; + } $info['itemTreeLists'] = $relItems ?? []; if ($info['itemTreeLists']) { $info['itemTreeLists'] = $this->formatItemsList($info['itemTreeLists']); @@ -171,7 +181,7 @@ class PackageService if (!$info) { throw new ResourceException(trans('PromotionsBundle.package_product_not_found')); } - $itemService = new ItemsService(); + $itemService = $this->makeItemsService(); // 查询主商品的skuList start $packageMainItemParams = [ 'package_id' => $packageId, @@ -186,14 +196,15 @@ class PackageService $mainRelItems = []; foreach ($main_item_list['list'] as $value) { - if (!($mainItemdata[$value['main_item_id']] ?? [])) { + $mainItem = $mainItemdata[$value['main_item_id']] ?? null; + if (!$mainItem) { $value['status'] = 'invalid'; } else { $value['status'] = 'valid'; - $mainRelItems[] = $mainItemdata[$value['main_item_id']]; + $mainRelItems[] = $mainItem; + $mainPackagePrice[$value['main_item_id']]['market_price'] = (int) $mainItem['price'];// 组合的原价 + $mainPackagePrice[$value['main_item_id']]['price'] = (int) $value['main_item_price'];// 组合的销售价 } - $mainPackagePrice[$value['main_item_id']]['market_price'] = (int)$mainItemdata[$value['main_item_id']]['price'];// 组合的原价 - $mainPackagePrice[$value['main_item_id']]['price'] = (int)$value['main_item_price'];// 组合的销售价 } $mainItemTreeLists = $mainRelItems ?? []; $mainItemInfo = []; @@ -209,13 +220,17 @@ class PackageService } } // 最低的原价 - $_mainPackageMarketPrice = array_column($mainPackagePrice, 'market_price'); - $mainItemInfo['price'] = min($_mainPackageMarketPrice); + $_mainPackageMarketPrice = array_column($mainPackagePrice ?? [], 'market_price'); + if ($_mainPackageMarketPrice) { + $mainItemInfo['price'] = min($_mainPackageMarketPrice); + } // 最低销售价 - $_mainPackagePrice = array_column($mainPackagePrice, 'price'); - $mainItemInfo['package_price'] = min($_mainPackagePrice); + $_mainPackagePrice = array_column($mainPackagePrice ?? [], 'price'); + if ($_mainPackagePrice) { + $mainItemInfo['package_price'] = min($_mainPackagePrice); + } $info['mainItem'] = $mainItemInfo; - $info['main_package_price'] = $mainPackagePrice; + $info['main_package_price'] = $mainPackagePrice ?? []; // 查询主商品的skuList end $packageItemParams = [ @@ -231,19 +246,19 @@ class PackageService $relItems = []; $package_markte_price = $package_price = []; foreach ($relLists['list'] as $value) { - if (!($itemdata[$value['item_id']] ?? [])) { + $item = $itemdata[$value['item_id']] ?? null; + if (!$item) { $value['status'] = 'invalid'; } else { $value['status'] = 'valid'; - $relItems[] = $itemdata[$value['item_id']]; + $relItems[] = $item; + // 原价 + $info['package_price'][$value['item_id']]['market_price'] = (int) $value['price']; + $default_item_id = $item['default_item_id']; + $package_markte_price[$default_item_id][] = (int) $value['price']; + $info['package_price'][$value['item_id']]['price'] = (int) $value['package_price']; + $package_price[$default_item_id][] = (int) $value['package_price']; } - // 原价 - $info['package_price'][$value['item_id']]['market_price'] = (int)$value['price']; - - $default_item_id = $itemdata[$value['item_id']]['default_item_id']; - $package_markte_price[$default_item_id][] = (int)$value['price']; - $info['package_price'][$value['item_id']]['price'] = (int)$value['package_price']; - $package_price[$default_item_id][] = (int)$value['package_price']; } $info['itemLists'] = []; $itemTreeLists = $relItems ?? []; @@ -254,8 +269,10 @@ class PackageService $limitItemIds = array_column($v['spec_items'], 'item_id'); unset($v['spec_items']); $itemInfo = $itemService->getItemsDetail($v['itemId'], $authorizerAppId, $limitItemIds, $companyId); + $itemInfo['itemName'] = $itemInfo['item_name']; } else { $itemInfo = $itemService->getItemsDetail($v['itemId'], $authorizerAppId); + $itemInfo['itemName'] = $itemInfo['item_name']; } $itemInfo['price'] = min($package_markte_price[$itemInfo['default_item_id']]); $itemInfo['package_price'] = min($package_price[$itemInfo['default_item_id']]);