CRMEB 单商户系统运费模版

165 阅读2分钟

很多人在使用了CRMEB单商户系统之后,对于系统内的运费模版功能不会进行设置,在这篇文章内,我会对运费模版的设计与计算流程进行详细的解释,看过这篇文章的小伙伴们,就能按照自己的想法随意的设置运费模版啦!

运费模版添加

后台添加运费模版的页面,填写运费模版的名称,选择该运费模版是按照那种计费方式进行计费(件数,重量,体积),选择对应的城市数据,添加运费和包邮信息等。

image.png

运费模版的计算逻辑

如上图所示,如果购买的商品设置的是该运费模版,在计算运费的时候,会经过如下几个步骤。

1.先获取到用户订单的商品和地址信息,将所有的商品按照运费模版进行分组整理,得到每个运费模版的商品总数,总价和此运费模版的运费金额,指定包邮信息等。

$cartInfo变量里面存储的就是该订单下所有的商品信息,包括金额,件数或体积或重量,对应的运费模版ID等信息。

$addr里面包含用户现在选择的的地址信息,用于最后查询包邮或者运费。

$temp_num = [];
foreach ($cartInfo as $cart) {
    $tempId = $cart['productInfo']['temp_id'] ?? 1;
    $type = isset($temp[$tempId]['type']) ? $temp[$tempId]['type'] : $temp[1]['type'];
    if ($type == 1) {
        $num = $cart['cart_num'];
    } elseif ($type == 2) {
        $num = $cart['cart_num'] * $cart['productInfo']['attrInfo']['weight'];
    } else {
        $num = $cart['cart_num'] * $cart['productInfo']['attrInfo']['volume'];
    }
    $region = isset($regions[$tempId]) ? $regions[$tempId] : $regions[1];
    if (!isset($temp_num[$cart['productInfo']['temp_id']])) {
        $temp_num[$cart['productInfo']['temp_id']]['number'] = $num;
        $temp_num[$cart['productInfo']['temp_id']]['price'] = bcmul($cart['cart_num'], $cart['truePrice'], 2);
        $temp_num[$cart['productInfo']['temp_id']]['first'] = $region['first'];
        $temp_num[$cart['productInfo']['temp_id']]['first_price'] = $region['first_price'];
        $temp_num[$cart['productInfo']['temp_id']]['continue'] = $region['continue'];
        $temp_num[$cart['productInfo']['temp_id']]['continue_price'] = $region['continue_price'];
        $temp_num[$cart['productInfo']['temp_id']]['temp_id'] = $cart['productInfo']['temp_id'];
        $temp_num[$cart['productInfo']['temp_id']]['city_id'] = $addr['city_id'];
    } else {
        $temp_num[$cart['productInfo']['temp_id']]['number'] += $num;
        $temp_num[$cart['productInfo']['temp_id']]['price'] += bcmul($cart['cart_num'], $cart['truePrice'], 2);
    }
}

2.按照用户当前选择的地址,根据当前地址数据内的city_id查询当前地址是否在指定包邮的地区内,然后在判断商品件数和金额是否大于设定的件数和金额,满足条件在运费模版的数组中删除此运费模版的数据。

/** @var ShippingTemplatesFreeServices $freeServices */
$freeServices = app()->make(ShippingTemplatesFreeServices::class);
foreach ($temp_num as $k => $v) {
    if (isset($temp[$v['temp_id']]['appoint']) && $temp[$v['temp_id']]['appoint']) {
        if ($freeServices->isFree($v['temp_id'], $v['city_id'], $v['number'], $v['price'])) {
            unset($temp_num[$k]);
        }
    }
}

3.经过步骤2,$temp_num数组中,只会剩下需要计算运费的数据,系统接下来会在先计算出首件运费最大值,设置初始运费为0开始计算订单所需运费。

//首件运费最大值
$maxFirstPrice = $temp_num ? max(array_column($temp_num, 'first_price')) : 0;
//初始运费为0
$storePostage = 0;

4.循环计算运费,将首件最大的运费模版设置为首件计算,剩余的模版都按照续件进行金额的计算,如果有多个首件金额等于最大值,会将多个运费模版当作首件进行计算,最后取得运费最大值返回。

foreach ($temp_num as $fk => $fv) {
    //找到首件运费等于最大值
    if ($fv['first_price'] == $maxFirstPrice) {
        //每次循环设置初始值
        $tempArr = $temp_num;
        $Postage = 0;
        //计算首件运费
        if ($fv['number'] <= $fv['first']) {
            $Postage = bcadd($Postage, $fv['first_price'], 2);
        } else {
            if ($fv['continue'] <= 0) {
                $Postage = $Postage;
            } else {
                $Postage = bcadd(bcadd($Postage, $fv['first_price'], 2), bcmul(ceil(bcdiv(bcsub($fv['number'], $fv['first'], 2), $fv['continue'] ?? 0, 2)), $fv['continue_price'], 4), 2);
            }
        }
        //删除计算过的首件数据
        unset($tempArr[$fk]);
        //循环计算剩余运费
        foreach ($tempArr as $cv) {
            if ($cv['continue'] <= 0) {
                $Postage = $Postage;
            } else {
                $Postage = bcadd($Postage, bcmul(ceil(bcdiv($cv['number'], $cv['continue'] ?? 0, 2)), $cv['continue_price'], 2), 2);
            }
        }
        //获取运费计算中的最大值
        if ($Postage > $storePostage) $storePostage = $Postage;
    }
}