first commit

This commit is contained in:
编码猿
2024-09-27 01:32:49 +08:00
commit 28ebe05a64
7399 changed files with 1174529 additions and 0 deletions

View File

@@ -0,0 +1,267 @@
<?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;
}
}