初始上传

This commit is contained in:
2026-04-04 17:27:12 +08:00
parent 4d80d28eb4
commit b7e11774ee
11191 changed files with 1588469 additions and 0 deletions

436
app/model/cart/CartCalculate.php Executable file
View File

@@ -0,0 +1,436 @@
<?php
/**
* Niushop商城系统 - 团队十年电商经验汇集巨献!
* =========================================================
* Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
* ----------------------------------------------
* 官方网址: https://www.niushop.com
* =========================================================
*/
namespace app\model\cart;
use addon\coupon\model\Coupon;
use addon\manjian\model\Manjian;
use app\model\goods\Goods;
use app\model\BaseModel;
/**
* 购物车计算
* Class CartCalculate
* @package app\model\cart
*/
class CartCalculate extends BaseModel
{
private $error = 0; //是否有错误
private $error_msg = ''; //错误描述
/**
* 订单计算
* @param $data
* @return mixed
*/
public function calculate($data)
{
$data = $this->getGoodsList($data);
$data = $this->manjianPromotion($data);
$promotion_money = $data[ 'promotion_money' ] ?? 0;
$order_money = $data[ 'goods_money' ] - $promotion_money;
$data[ 'order_money' ] = $order_money;
$data = $this->couponCalculate($data);
return $data;
}
/**
* 获取购物车商品列表信息
* @param $data
* @return mixed
*/
public function getGoodsList($data)
{
$site_id = $data[ 'site_id' ];
$sku_ids = $data[ 'sku_ids' ] ?? [];
$sku_id_list = array_column($sku_ids, 'sku_id');
$member_id = $data[ 'member_id' ];
$sku_num_list = array_column($sku_ids, 'num', 'sku_id');
$goods_model = new Goods();
//组装商品列表
$field = 'ngs.sku_id, ngs.sku_name, ngs.sku_no, ngs.price, ngs.discount_price, ngs.discount_config, ngs.cost_price, ngs.stock, ngs.sku_image,ngs.goods_id,ngs.goods_name,
ngs.site_id, ns.site_name,ngc.cart_id,ngc.num,ngs.is_consume_discount, ngs.member_price, ngs.discount_method';
$alias = 'ngs';
$join = [
[
'site ns',
'ngs.site_id = ns.site_id',
'inner'
],
[ 'goods_cart ngc', 'ngc.sku_id = ngs.sku_id and ngc.member_id = ' . $member_id, 'inner' ]
];
$condition = [
[ 'ngs.sku_id', 'in', $sku_id_list ],
[ 'ngs.site_id', '=', $site_id ]
];
$store_data = $data[ 'store_data' ] ?? [];
$store_id = $data[ 'store_id' ] ?? 0;
// 如果是连锁运营模式
if (!empty($store_data) && $store_data[ 'config' ][ 'store_business' ] == 'store') {
$join[] = [ 'store_goods_sku sgs', 'ngs.sku_id = sgs.sku_id and sgs.store_id=' . $store_id, 'left' ];
$field .= ',IFNULL(sgs.status, 0) as store_goods_status';
$field = str_replace('ngs.price', 'IFNULL(IF(ngs.is_unify_price = 1,ngs.price,sgs.price), ngs.price) as price', $field);
$field = str_replace('ngs.discount_price', 'IFNULL(IF(ngs.is_unify_price = 1,ngs.discount_price,sgs.price), ngs.discount_price) as discount_price', $field);
if ($store_data[ 'store_info' ][ 'stock_type' ] == 'store') {
$field = str_replace('ngs.stock', 'IFNULL(sgs.stock, 0) as stock', $field);
}
}
$goods_list = model('goods_sku')->getList($condition, $field, '', $alias, $join);
if (!empty($goods_list)) {
$goods_list = $goods_model->getGoodsListMemberPrice($goods_list, $member_id) ?? [];
foreach ($goods_list as $k => $v) {
$item_num = $sku_num_list[ $v[ 'sku_id' ] ];
$price = $v[ 'price' ];
if (isset($v[ 'member_price' ]) && !empty($v[ 'member_price' ]) && $v[ 'member_price' ] < $v[ 'price' ]) {
$price = $v[ 'member_price' ];
}
$v[ 'price' ] = $price;
$v[ 'goods_money' ] = $price * $item_num;
$v[ 'real_goods_money' ] = $v[ 'goods_money' ];
$v[ 'coupon_money' ] = 0; //优惠券金额
$v[ 'promotion_money' ] = 0; //优惠金额
$v[ 'stock' ] = numberFormat($v[ 'stock' ]);
if (!empty($data[ 'goods_list' ])) {
$data[ 'goods_list' ][] = $v;
$data[ 'goods_num' ] += $item_num;
$data[ 'goods_money' ] += $v[ 'goods_money' ];
} else {
$data[ 'site_id' ] = $site_id;
$data[ 'site_name' ] = $v[ 'site_name' ];
$data[ 'goods_money' ] = $v[ 'goods_money' ];
$data[ 'goods_num' ] = $item_num;
$data[ 'goods_list' ][] = $v;
}
}
}
return $data;
}
/****************************************************************************** 满减 start *****************************************************************************/
/**
* 满减优惠
* @param $data
* @return mixed
*/
public function manjianPromotion($data)
{
$site_id = $data[ 'site_id' ];
$promotion_money = $data[ 'promotion_money' ] ?? 0;
//先查询全部商品的满减套餐 进行中
$manjian_model = new Manjian();
$all_info = $manjian_model->getManjianInfo([ [ 'manjian_type', '=', 1 ], [ 'site_id', '=', $site_id ], [ 'status', '=', 1 ] ], 'manjian_name,type,goods_ids,rule_json,manjian_id')[ 'data' ] ?? [];
$goods_list = $data[ 'goods_list' ];
//存在全场满减(不考虑部分满减情况)
if (!empty($all_info)) {
$discount_array = $this->getManjianDiscountMoney($all_info, $data);
$all_info[ 'discount_array' ] = $discount_array;
$discount_money = $discount_array[ 'real_discount_money' ];
$promotion_money += $discount_money;
if (!empty($discount_array[ 'rule' ])) {
$goods_list = array_map(function($item) use ($all_info) {
$item[ 'promotion' ][ 'manjian' ] = $all_info;
return $item;
}, $goods_list);
}
} else {
$goods_ids = array_unique(array_column($data[ 'goods_list' ], 'goods_id'));
$manjian_condition = array (
[ 'goods_id', 'in', $goods_ids ],
[ 'status', '=', 1 ]
);
$manjian_goods_list = $manjian_model->getManjianGoodsList($manjian_condition, 'manjian_id')[ 'data' ];
if (!empty($manjian_goods_list)) {
$discount_money = 0;
$manjian_goods_list = array_column($manjian_goods_list, 'manjian_id');
$manjian_goods_list = array_unique($manjian_goods_list); //去重
sort($manjian_goods_list);
$manjian_list_result = $manjian_model->getManjianList([ [ 'manjian_id', 'in', $manjian_goods_list ], [ 'status', '=', 1 ] ]);
$manjian_list = $manjian_list_result[ 'data' ];
foreach ($manjian_list as $k => $v) {
$manjian_goods_ids = explode(',', $v[ 'goods_ids' ]);
$item_goods_data = [
'goods_money' => 0,
'goods_num' => 0
];
$item_goods_list = [];
$sku_ids = [];
foreach ($goods_list as $goods_k => $goods_item) {
if (in_array($goods_item[ 'goods_id' ], $manjian_goods_ids)) {
$item_goods_data[ 'goods_money' ] += $goods_item[ 'goods_money' ];
$item_goods_data[ 'goods_num' ] += $goods_item[ 'num' ];
$item_goods_list[] = $goods_item;
array_push($sku_ids, $goods_item[ 'sku_id' ]);
$goods_list[ $goods_k ] = $goods_item;
}
}
$discount_array = $this->getManjianDiscountMoney($v, $item_goods_data);
$manjian_list[ $k ][ 'discount_array' ] = $discount_array;
$discount_money += $discount_array[ 'real_discount_money' ];
if (!empty($discount_array[ 'rule' ])) {
$goods_list = array_map(function($item) use ($sku_ids, $v) {
if (in_array($item[ 'sku_id' ], $sku_ids)) {
$item[ 'promotion' ][ 'manjian' ] = $v;
}
return $item;
}, $goods_list);
}
}
$promotion_money += $discount_money;
}
}
$data[ 'goods_list' ] = $goods_list;
$data[ 'promotion_money' ] = $promotion_money;
return $data;
}
/**
* 满减优惠金额
* @param $manjian_info
* @param $data
* @return array
*/
public function getManjianDiscountMoney($manjian_info, $data)
{
$goods_money = $data[ 'goods_money' ];
$value = $manjian_info[ 'type' ] == 0 ? $data[ 'goods_money' ] : $data[ 'goods_num' ];
//阶梯计算优惠
$rule_item = json_decode($manjian_info[ 'rule_json' ], true);
$discount_money = 0;
$money = 0;
$rule = []; // 符合条件的优惠规则
array_multisort(array_column($rule_item, 'limit'), SORT_ASC, $rule_item); //排序根据num 排序
foreach ($rule_item as $k => $v) {
if ($value >= $v[ 'limit' ]) {
$rule = $v;
if (isset($v[ 'discount_money' ])) {
$discount_money = $v[ 'discount_money' ];
$money = $v[ 'limit' ];
}
}
}
$real_discount_money = min($discount_money, $goods_money);
return [ 'discount_money' => $discount_money, 'money' => $money, 'real_discount_money' => $real_discount_money, 'rule' => $rule ];
}
/**
* 处理商品满减
* @param $goods_list
* @param $goods_money
* @param $discount_money
* @param bool $is_free_shipping
* @param array $sku_ids
* @return mixed
*/
public function distributionGoodsDemiscount($goods_list, $goods_money, $discount_money, $is_free_shipping = false, $sku_ids = [])
{
$temp_discount_money = $discount_money;
$last_key = count($goods_list) - 1;
foreach ($goods_list as $k => $v) {
if ($last_key != $k) {
$item_discount_money = round(floor($v[ 'goods_money' ] / $goods_money * $discount_money * 100) / 100, 2);
} else {
$item_discount_money = $temp_discount_money;
}
$temp_discount_money -= $item_discount_money;
$goods_list[ $k ][ 'promotion_money' ] = $item_discount_money;
$real_goods_money = $v[ 'real_goods_money' ] - $item_discount_money;
$real_goods_money = max($real_goods_money, 0);
$goods_list[ $k ][ 'real_goods_money' ] = $real_goods_money; //真实订单项金额
// 满减送包邮
if ($is_free_shipping) {
if (empty($sku_ids) || in_array($v[ 'sku_id' ], $sku_ids)) {
$goods_list[ $k ][ 'is_free_shipping' ] = 1;
}
}
}
return $goods_list;
}
/****************************************************************************** 满减 end *****************************************************************************/
/****************************************************************************** 订单优惠券 start *****************************************************************************/
/**
* 查询可用优惠券
* @param $data
* @return mixed
*/
public function couponCalculate($data)
{
$site_id = $data[ 'site_id' ];
$member_id = $data[ 'member_id' ];
$goods_money = $data[ 'goods_money' ];//商品总额
$coupon_list = [];
$goods_list = $data[ 'goods_list' ];
// 先查询全场通用的优惠券
$member_coupon_model = new Coupon();
$condition = array (
[ 'member_id', '=', $member_id ],
[ 'state', '=', 1 ],
[ 'site_id', '=', $site_id ]
);
$member_coupon_model = new Coupon();
$member_coupon_list = $member_coupon_model->getCouponList($condition)[ 'data' ];
$coupon_array = [];
foreach ($member_coupon_list as $k => $v) {
//全场优惠券
if ($v[ 'goods_type' ] == 1) {
//检测门槛
if ($v[ 'at_least' ] <= $goods_money) {
$coupon_array[] = $v;
}
continue;
}
//指定商品可用优惠券
if ($v[ 'goods_type' ] == 2) {
$coupon_goods_array = explode(",", $v[ 'goods_ids' ]);
$least_money = 0;
foreach ($goods_list as $k_goods => $v_goods) {
if (in_array($v_goods[ 'goods_id' ], $coupon_goods_array)) {
$least_money += $v_goods[ 'goods_money' ];
}
}
if ($v[ 'at_least' ] <= $least_money) {
$coupon_array[] = $v;
}
continue;
}
if ($v[ 'goods_type' ] == 3) {
$coupon_goods_array = explode(",", $v[ 'goods_ids' ]);
$least_money = 0;
foreach ($goods_list as $k_goods => $v_goods) {
if (!in_array($v_goods[ 'goods_id' ], $coupon_goods_array)) {
$least_money += $v_goods[ 'goods_money' ];
}
}
if ($v[ 'at_least' ] <= $least_money) {
$coupon_array[] = $v;
}
// continue;
}
}
//已领取的优惠券id
$ed_coupon_ids = array_column($coupon_array, 'coupon_type_id');
$ing_coupon_condition = array (
[ 'site_id', '=', $site_id ],
[ 'status', '=', 1 ],
[ 'is_show', '=', 1 ]
);
if (!empty($ed_coupon_ids)) {
$ing_coupon_condition[] = [ 'coupon_type_id', 'not in', $ed_coupon_ids ];
}
$ing_coupon_list = $member_coupon_model->getCouponTypeList($ing_coupon_condition)[ 'data' ] ?? [];
if (!empty($ing_coupon_list)) {
foreach ($ing_coupon_list as $item_k => $item_v) {
$goods_type = $item_v[ 'goods_type' ];
$item_goods_money = 0;
if ($goods_type == 1) {
//全局支持优惠券
$item_goods_money = $goods_money;
} elseif ($goods_type == 2) {
// 指定参与商品
$item_goods_ids = explode(',', $item_v[ 'goods_ids' ]);
$item_goods_money = 0;
foreach ($goods_list as $goods_k => $goods_v) {
if (in_array($goods_v[ 'goods_id' ], $item_goods_ids)) {
$item_goods_money += $goods_v[ 'goods_money' ];
}
}
} elseif ($goods_type == 3) {
// continue;
// 指定不参与商品的优惠券
$item_goods_ids = explode(',', $item_v[ 'goods_ids' ]);
// $item_goods_ids = array_diff($goods_ids, $item_goods_ids);
$item_goods_money = 0;
foreach ($goods_list as $goods_k => $goods_v) {
if (!in_array($goods_v[ 'goods_id' ], $item_goods_ids)) {
$item_goods_money += $goods_v[ 'goods_money' ];
}
}
}
if ($item_goods_money >= $item_v[ 'at_least' ]) {
$check_result = $member_coupon_model->checkMemberReceiveCoupon([ 'site_id' => $site_id, 'member_id' => $member_id, 'coupon_type_info' => $item_v ]);
if ($check_result[ 'code' ] >= 0) {//只有还可领取的优惠券才可以
//核验会员是否还可以领取某张优惠券
$item_v[ 'receive_type' ] = 'wait';
$item_v[ 'coupon_goods_money' ] = $item_goods_money;
$coupon_list[] = $this->getCouponPromotionMoney($item_v);
}
}
}
}
//增加查询可以领取的优惠券
$max_coupon_money = 0;
foreach ($coupon_list as $k => $v) {
$item_coupon_money = $v[ 'coupon_money' ] ?? 0;//需修改
if ($item_coupon_money > $max_coupon_money) {
$max_coupon_money = $v[ 'coupon_money' ];
$coupon_info = $v;
}
}
$coupon_money = $coupon_info[ 'coupon_money' ] ?? 0;
if ($coupon_money > 0) {
$data[ 'coupon_info' ] = $coupon_info;
if ($coupon_money > $data[ 'order_money' ]) {
$coupon_money = $data[ 'order_money' ];
}
$data[ 'order_money' ] -= $coupon_money;
$data[ 'coupon_money' ] = $coupon_money;
}
return $data;
}
/**
* 优惠券优惠金额
* @param $coupon_info
* @return mixed
*/
public function getCouponPromotionMoney($coupon_info)
{
$coupon_goods_money = $coupon_info[ 'coupon_goods_money' ];//优惠券支持当前商品的总金额
$coupon_money = 0;
if ($coupon_info[ 'type' ] == 'reward') { //满减优惠券
$coupon_money = min($coupon_info['money'], $coupon_goods_money);
} else if ($coupon_info[ 'type' ] == 'divideticket') { //瓜分优惠券
$coupon_money = min($coupon_info['money'], $coupon_goods_money);
} else if ($coupon_info[ 'type' ] == 'discount') { //折扣优惠券
//计算折扣优惠金额
$coupon_money = $coupon_goods_money * ( 10 - $coupon_info[ 'discount' ] ) / 10;
$coupon_money = $coupon_money > $coupon_info[ 'discount_limit' ] && $coupon_info[ 'discount_limit' ] != 0 ? $coupon_info[ 'discount_limit' ] : $coupon_money;
$coupon_money = min($coupon_money, $coupon_goods_money);
$coupon_money = round(floor($coupon_money * 100) / 100, 2);
}
$coupon_info[ 'coupon_money' ] = $coupon_money;
return $coupon_info;
}
/****************************************************************************** 订单优惠券 end *****************************************************************************/
}