Files
CompanyProject/金壶/ydyd_service/application/common/tools/Cart.php
2024-09-27 01:32:49 +08:00

267 lines
9.0 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace app\common\tools;
use app\ydyd_service\model\ShoppingCartModel;
use think\facade\Cache;
class Cart
{
// 个人购物车标记前缀
protected $cartName = 'USER_CART_INFO_';
// 商品数据
protected $goods = [];
// 当前用户
protected $user_id = 0;
public function __construct()
{
$init_flag = false;
$this->user_id = session('user_id');
$this->cartName .= $this->user_id;
$default_data = Cache::get($this->cartName)['goods_list']??[];//缓存数据索引goods_list
if (!$default_data){
$_where[] = ['user_id',"=",$this->user_id];
$_where[] = ['type',"=",''];//type为空自营否则如 hy华源(目前统一标记为extend)
//购物车数据--shopping_cart表
$cart_data = ShoppingCartModel::field("batch_id as id,goods_number as num, unit_price as price")->where($_where)->select()->toArray();
if ($cart_data){
$init_flag = true;//trueshopping_cart表存在该用户的数据
foreach ($cart_data as $item){
$this->add($item, true);//添加到购物车数据缓存,返回值(类型:布尔)未处理
}
}
}
if (!$init_flag){
$this->setGoods($default_data);//缓存数据存在时,$this->goods = 缓存数据;
}
}
public function getGoods()
{
return $this->goods;
}
public function setGoods($goods)
{
$this->goods = $goods;
}
/**
* @todo 现有业务逻辑待厘清
* 添加购物车 同时更新model
* @access public
* @param array $data
* $data为数组包含以下几个值
* $Data= [
* "id"=>1, //批次ID
* "num"=>2, //商品数量
* "options"=>array() //其他参数,如价格、颜色可以是数组或字符串|可以不添加
* ]
*
* @throws \Exception
* @return void
*/
public function add($data,$init_flag = false)
{
if (!is_array($data) || !isset($data['id']) || !isset($data['num']) || !isset($data['price']) || ($data['price'] <0)) {
throw new \Exception('购物车ADD方法参数设置错误');//抛出异常keys捕获异常--异常处理
}
//添加商品支持多商品添加
//$options = isset($data['options']) ? $data['options'] : '';
//$sid = md5($data['id']);
$sid = $data['id'];//batch_id
$_where[] = ['user_id',"=",$this->user_id];
$_where[] = ["batch_id","=",$sid];
//生成唯一ID用于处理相同商品有不同属性时
if (isset($this->goods[$sid])) {//缓存已存在?
//如果数量为0删除商品
if ($data['num'] == 0) {
unset($this->goods[$sid]);
if (!$init_flag){//缓存发起删除shopping_cart记录
//user_id+batch_id校验足矣
ShoppingCartModel::where($_where)->delete();//模型delete模型对象or数据表软删除
}
} else {//不为0 增加
//已经存在相同商品时增加商品数量
$this->goods[$sid]['num'] = $this->goods[$sid]['num'] + $data['num'];
$this->goods[$sid]['total'] = $this->goods[$sid]['num'] * $this->goods[$sid]['price'];//两次添加,销售价格不一样未处理
if (!$init_flag){
if ($this->goods[$sid]['num'] > 0){
$update_data['goods_number'] = $this->goods[$sid]['num'];
$update_data['unit_price'] = $this->goods[$sid]['price'];
ShoppingCartModel::where($_where)->update($update_data);
}else{
ShoppingCartModel::where($_where)->delete();
}
}
}
} else {//不存在 写入
if ($data['num'] > 0) {
$this->goods[$sid] = $data;//batch_id索引对应商品数据
$this->goods[$sid]['total'] = $data['num'] * $data['price'];//金额
if (!$init_flag) {
$add_data['user_id'] = $this->user_id;
$add_data['batch_id'] = $sid;
$add_data['unit_price'] = $data['price'];
$add_data['goods_number'] = $data['num'];
ShoppingCartModel::create($add_data);
}
}
}
//存在问题每add一条数据即缓存一次。
//修改方案放到__construct方法内所有数据add之后(foreach结束后)设置一次缓存
return $this->store();
}
/**
* 保存到缓存
*
* 缓存数据结构
* $cart =
* [
* 'goods_list'=>[
* 'batch_id'=>['batch_id'=>$batch_id,'goods_num'=>$num,'price'=>$price],//新增shopping_cart_id 用于匹配shopping_cart表记录
* 'batch_id'=>['batch_id'=>$batch_id,'goods_num'=>$num,'price'=>$price],
* ],
* 'total_num' =>$num,//batch_id数量相同batch_id合并处理
* 'total_price'=>$total_price,//总金额
* ]
*
* 重点 $goods 赋值逻辑!
*/
private function store()
{
$cart = [
'goods_list' => $this->goods,
'total_num' => $this->getTotalNums(),
'total_price' => $this->getTotalPrice(),
];
return Cache::set($this->cartName,$cart,config('SYSTEM_CONSTANT')['USER_INFO_CACHE_TIME']);
}
/**
* 统计购物车中商品分类数量
*/
public function getTotalNums()
{
$rows = 0;
foreach ($this->goods as $v) {
//$rows += $v['num'];
$rows ++;
}
return $rows;
}
/**
* 获得商品汇总价格
*/
public function getTotalPrice()
{
$total = 0;
foreach ($this->goods as $v) {
$total += $v['price'] * $v['num'];
}
return $total;
}
/**
* 更新购物车数量(update+delete操作)
* 适用场景:
* 1.删除购物车数据传值goods_number=0
* 2.更新shopping_cart表中价格和数量信息
*
* @param $data
* $data=[
* "sid"=>'', //商品的唯一SID
* "num"=>2, //商品数量
* ]
* @return bool
* @throws \Exception
*/
public function update($data)
{
if ( ! isset($data['sid']) || ! isset($data['num'])) {
throw new \Exception('购物车update方法参数错误缺少sid或num值');
}
$sid = $data['sid'];
$_where[] = ['user_id',"=",$this->user_id];
$_where[] = ["batch_id","=",$sid];
if (isset($this->goods[$sid])) {
if ($data['num'] == 0) {
unset($this->goods[$sid]);
ShoppingCartModel::where($_where)->delete();
} else {
$this->goods[$sid]['num'] = $data['num'];
if (isset($data['price']) && is_numeric($data['price']) && $data['price'] > 0){
$this->goods[$sid]['price'] = $data['price'];
}
$this->goods[$sid]['total'] = $data['num'] * $this->goods[$sid]['price'];
$update_data['goods_number'] = $this->goods[$sid]['num'];
$update_data['unit_price'] = $this->goods[$sid]['price'];
ShoppingCartModel::where($_where)->update($update_data);
}
return $this->store();
}
return false;
}
/**
* 获得购物车中的所有数据(缓存中取出,初始状态为空)
* @return mixed
*/
public function getAllData()
{
$this->store();//缓存数据,此处已有返回值下一行冗余直接return 本行,方法体改为: return $this->store();
return Cache::get($this->cartName);//cartName格式前缀+user_id缓存值(session)
}
/**
* 获取购物车内所有商品的ID信息(batch_id)
* @return array
*/
public function getAllId()
{
$id_arr = [];
foreach ($this->goods as $k => $item) {
$id_arr[] = $k;
}
return $id_arr;
}
/**
* 删除购物车,同步删除数据库表记录
* @param $sid 商品SID编号
* @return bool
* @throws \Exception
*/
public function del($sid)
{
if (isset($this->goods[$sid])) {
unset($this->goods[$sid]);
$_where[] = ['user_id',"=",$this->user_id];
$_where[] = ["batch_id","=",$sid];
ShoppingCartModel::where($_where)->delete();
$this->store();
return true;
}
return false;
}
/**
* 删除所有商品
* @return bool
* @throws \Exception
*/
public function flush()
{
ShoppingCartModel::where("user_id",$this->user_id)->delete();
$this->setGoods([]);
$this->store();
return true;
}
}