data['shipping_type']) && $form->data['shipping_type']==ShippingTypeEnum::PICKUP){ return $item; } // 获取用户收货地址信息 if (empty($extra['address'])) { $address = UserAddress::getOne([['id' => $form['address_id']], ['user_id' => $form['user_id']]], true); $extra['address'] = $address; } else { $address = $extra['address']; } // 收货地址 if(empty($address)){ $address['province_id'] = $address['city_id'] = $address['district_id'] = $address['town_id'] = $address['community_id'] = 0; $address['province'] = $address['city'] = $address['district'] = $address['town'] = $address['community'] = $address['detail'] = $address['name'] = $address['mobile'] =''; } // 收货地址 $item['mch_order_info']['province'] = $address['province_id']; $item['mch_order_info']['city'] = $address['city_id']; $item['mch_order_info']['area'] = $address['district_id']; $item['mch_order_info']['town'] = $address['town_id']; $item['mch_order_info']['community'] = $address['community_id']; $item['mch_order_info']['region_name'] = $address['province'] .' '. $address['city'] .' '. $address['district'].' '.$address['town'].' '.$address['community']; $item['mch_order_info']['address'] = $address['detail']; $item['mch_order_info']['receiver_name'] = $address['name']; $item['mch_order_info']['mobile'] = $address['mobile']; $shipping_fee = 0;// 订单总运费初始化 $group_order_fee = 0;// 单个商户订单运费 $is_free = false;// 是否免邮 $compute_shipping = [];// 运费计算,配合运费规则compute_type == 2使用 // 获取包邮地区 $feeShippingRules = FreeShippingRules::getFreeShippingRulesArea($item['mch_order_info']['mall_id'], $item['mch_order_info']['mch_id']); // 获取运费模板 $freightRules = FreightRules::getFreightRulesArea($item['mch_order_info']['mall_id'], $item['mch_order_info']['mch_id']); // 包邮计算 foreach ($feeShippingRules as $fee) { // 如果包邮金额<=购买商品金额,并且地区符合收货地址则免邮 if ($fee['money'] <= $item['mch_order_info']['goods_price'] && self::isInArea($address, $fee['district_ids'])) { $is_free = true; continue; } } // 不免邮处理 if ($is_free == false) { foreach ($item['goods'] as $good_id => $good) { $good_info = Goods::findOne(['id' => $good_id]); if($good_info['goods_type'] == GoodsTypeEnum::GoodsTypeVirtual) continue; $good_num = 0;// 第N个商品 if ($good['num'] > 1) { $good_num+= $good['num']; } else { $good_num++; } // 物流方式 if (!in_array(ShippingTypeEnum::LOGISTICS, explode(',', $form['sku'][$good_id]['goods']['freight_type']))) continue; // 计算满件包邮 if ($form['sku'][$good_id]['goods']['free_shipping_num'] > 0 && $good['num'] >= $form['sku'][$good_id]['goods']['free_shipping_num']) continue; // 计算满元包邮 if ($form['sku'][$good_id]['goods']['free_shipping_money'] > 0 && $good['goods_price'] >= $form['sku'][$good_id]['goods']['free_shipping_money']) continue; // 运费规则 if ($form['sku'][$good_id]['goods']['freight_rules_type'] == 1) { // 根据商品id获取对应的规则 $thisRules = isset($freightRules[$form['sku'][$good_id]['goods']['freight_id']]) ? $freightRules[$form['sku'][$good_id]['goods']['freight_id']] : []; // 运费模板ID $rule_id = $thisRules['id'] ?? 0; if(!empty($thisRules['rule'])){ foreach ($thisRules['rule'] as $rule) { // 获取该模板的所有地区id $areaArr = array_column($rule['list'], 'id'); // 判断收货地址是否在模板中 if (self::isInArea($address, $areaArr)) { if ($thisRules['type'] == 1) {// 按重计费 $new_num_weight = $form['sku'][$good_id]['weight'] * $good['num']; } else {// 按件计费 $new_num_weight = $good['num']; } // 计算[首件/首重]收费,只要商品有重量并且运费有首重设置就需要给运费 if ($new_num_weight > 0 && $rule['first'] > 0) { if ($thisRules['compute_type'] == 1) { $group_order_fee += $rule['firstPrice']; $shipping_fee += $rule['firstPrice']; } } if ($thisRules['type'] == 1) {// 计算续重收费 if ($thisRules['compute_type'] == 2) {// 按同件商品计算,扣除首重后,剩余不同商品都按续重计算 self::getShopFee($rule_id, $thisRules['type'], $rule, $new_num_weight, $compute_shipping); } else { $surplus_weight = $new_num_weight - $rule['first'];// 剩余重量 = 总重量 - 首重重量 // 续重运费 = (剩余重量 / 续件重量)[向上取整] * 续重费用 [向下取整] if($surplus_weight > 0 && isset($rule['second'])&&$rule['second']>0) { $fee = floor(ceil($surplus_weight / $rule['second']) * $rule['secondPrice']); $shipping_fee += $fee; $group_order_fee += $fee; } } } else {// 计算续件收费 if ($thisRules['compute_type'] == 2) {// 按同件商品计算,扣除首件后,剩余不同商品都按续件计算 self::getShopFee($rule_id, $thisRules['type'], $rule, $new_num_weight, $compute_shipping); } else { $surplus_num = $good_num - $rule['first'];// 减扣首件数量 if ($surplus_num > 0 && $rule['second'] > 0) { // 续费 * (减扣首件数量 / 续件数量)[向下取整] if(isset($rule['second']) && $rule['second'] > 0){ $fee = $rule['secondPrice'] * floor($surplus_num / $rule['second']); $shipping_fee += $fee; $group_order_fee += $fee; } } } } continue;// 已计算好运费则跳出循环 } } } } else { // 自定义运费 if ($form['sku'][$good_id]['goods']['shipping_fee'] >= 0) { $shipping_fee+= $form['sku'][$good_id]['goods']['shipping_fee']; $group_order_fee+= $form['sku'][$good_id]['goods']['shipping_fee']; } } } // 按同件商品运费计算 if ($compute_shipping) { $shop_fee_assignment = self::shopFeeAssignment($compute_shipping); $shipping_fee += $shop_fee_assignment['shipping_fee'] ?? 0; $group_order_fee += $shop_fee_assignment['group_order_fee'] ?? 0; } // 单个商户订单运费计算 $item['mch_order_info']['shipping_type'] = $form['data']['shipping_type'] ?? ShippingTypeEnum::LOGISTICS; $item['mch_order_info']['shipping_money'] = $group_order_fee; } // 运费赋值 $item['mch_order_info']['pay_money'] = $item['mch_order_info']['pay_money'] + $shipping_fee; $prev_shipping_fee = $form->marketing['deduct']['shipping_fee']['money'] ?? 0; $form->marketing['deduct']['shipping_fee'] = ['name' => '运费', 'money' => $prev_shipping_fee + $shipping_fee]; return $item; } /** * 判断收货地址是否在地区中 * @Author: lun * @DateTime: 2021/9/30 0030 14:45 * @Copyright: copyright (c) 2021 广东七件事集团 * @param $address * @param $areaArr * @return bool */ private static function isInArea($address, $areaArr) { $return = false; if(in_array($address['province_id'], $areaArr) || in_array($address['city_id'], $areaArr) || in_array($address['district_id'], $areaArr)) $return = true; return $return; } /** * 运费模板为:按同件商品计算 * 目的:不同商品使用不同的模板情况下的混合计算,主要算出:首件/重 + 续件/重 运费费用 * @Author: lun * @DateTime: 2023/8/12 0012 17:11 * @Copyright: copyright (c) 2021 广东七件事集团 * @param $rule_id * @param $rule * @param $goods_weight_or_num * @param array $data */ private static function getShopFee($rule_id, $type, $rule, $goods_weight_or_num, &$data = []) { $data[$rule_id]['total_weight_or_num'] = empty($data[$rule_id]['total_weight_or_num']) ? $goods_weight_or_num : $data[$rule_id]['total_weight_or_num'] + $goods_weight_or_num; if (empty($data[$rule_id]['first_fee'])) $data[$rule_id]['first_fee'] = $rule['firstPrice'];// 首重/件 费用 if (empty($data[$rule_id]['group_first_fee'])) $data[$rule_id]['group_first_fee'] = $rule['firstPrice'];// 首重/件 费用 if (empty($data[$rule_id]['first_weight_or_num'])) $data[$rule_id]['first_weight_or_num'] = $rule['first'];// 同模板商品首重 if (empty($data[$rule_id]['renew_price'])) $data[$rule_id]['renew_price'] = 0;// 续重/件 费用 $surplus_weight_or_num = $data[$rule_id]['total_weight_or_num'] - $data[$rule_id]['first_weight_or_num'];// 总重量/总数量 - 首重/件 = 续重/件 // 续重/件运费 = (剩余重量 / 续件重量)[向上取整] * 续重费用 [向下取整] if($surplus_weight_or_num > 0 && isset($rule['second']) && $rule['second'] > 0) { if ($type == 2) {// 按件计费 $fee = $rule['secondPrice'] * floor($surplus_weight_or_num / $rule['second']); } else {// 按重计费 $fee = floor(ceil($surplus_weight_or_num / $rule['second']) * $rule['secondPrice']); } $data[$rule_id]['renew_price'] = $fee;// 每次都覆盖之前的值,为了重新算出最后的续重/件费用 } } /** * 将计算好的不同运费模板运费加起来 * @Author: lun * @DateTime: 2023/8/12 0012 17:13 * @Copyright: copyright (c) 2021 广东七件事集团 * @param $shopFeeList * @return array */ private static function shopFeeAssignment($shopFeeList) { $shop_fee = 0; $group_order_fee = 0; foreach ($shopFeeList as $item) { $shop_fee += $item['first_fee'] + $item['renew_price']; $group_order_fee += $item['group_first_fee'] + $item['renew_price']; } return ['shipping_fee' => $shop_fee, 'group_order_fee' => $group_order_fee]; } }