diff --git a/app/api/model/Cart.php b/app/api/model/Cart.php new file mode 100644 index 00000000..a9a95e98 --- /dev/null +++ b/app/api/model/Cart.php @@ -0,0 +1,189 @@ + +// +---------------------------------------------------------------------- +declare (strict_types=1); + +namespace app\api\model; + +use app\api\model\Goods as GoodsModel; +use app\api\model\GoodsSku as GoodsSkuModel; +use app\api\service\User as UserService; +use app\common\model\Cart as CartModel; +use app\common\enum\goods\Status as GoodsStatusEnum; +use app\common\enum\goods\GoodsType as GoodsTypeEnum; +use cores\exception\BaseException; + +/** + * 购物车管理 + * Class Cart + * @package app\api\model + */ +class Cart extends CartModel +{ + /** + * 隐藏字段 + * @var array + */ + protected $hidden = [ + 'is_delete', + 'store_id', + 'create_time', + 'update_time' + ]; + + /** + * 加入购物车 + * @param int $goodsId 商品ID + * @param string $goodsSkuId 商品sku唯一标识 + * @param int $goodsNum 商品数量 + * @return bool + * @throws \cores\exception\BaseException + * @throws \cores\exception\BaseException + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + */ + public function add(int $goodsId, string $goodsSkuId, int $goodsNum): bool + { + // 判断是否已存在购物车记录 + $detail = $this->getInfo($goodsId, $goodsSkuId, false); + // 如果已存在购物车记录, 则累计商品数量 + !empty($detail) && $goodsNum += $detail['goods_num']; + // 验证商品的状态 + $this->checkGoodsStatus($goodsId, $goodsSkuId, $goodsNum); + // 获取当前用户ID + $userId = UserService::getCurrentLoginUserId(); + // 实例化模型 + $model = $detail ?: (new static); + return $model->save([ + 'goods_id' => $goodsId, + 'goods_sku_id' => $goodsSkuId, + 'goods_num' => $goodsNum, + 'user_id' => $userId, + 'store_id' => self::$storeId, + ]); + } + + /** + * 更新购物车记录 + * @param int $goodsId 商品ID + * @param string $goodsSkuId 商品sku唯一标识 + * @param int $goodsNum 商品数量 + * @return bool + * @throws BaseException + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + */ + public function sUpdate(int $goodsId, string $goodsSkuId, int $goodsNum): bool + { + // 验证商品的状态 + $this->checkGoodsStatus($goodsId, $goodsSkuId, $goodsNum); + // 获取购物车记录 + $model = $this->getInfo($goodsId, $goodsSkuId, true); + // 更新记录 + return $model->save(['goods_num' => $goodsNum]); + } + + /** + * 验证商品的状态 + * @param int $goodsId 商品ID + * @param string $goodsSkuId 商品sku唯一标识 + * @param int $goodsNum 商品数量 + * @return void + * @throws BaseException + */ + private function checkGoodsStatus(int $goodsId, string $goodsSkuId, int $goodsNum): void + { + // 获取商品详情 + $goods = GoodsModel::detail($goodsId); + // 商品不存在 + if (empty($goods) || $goods['is_delete']) { + throwError('很抱歉, 商品信息不存在'); + } + // 判断商品类型 + if ($goods['goods_type'] == GoodsTypeEnum::VIRTUAL) { + throwError('很抱歉, 虚拟商品不支持加入购物车'); + } + // 商品已下架 + if ($goods['status'] == GoodsStatusEnum::OFF_SALE) { + throwError('很抱歉, 该商品已经下架'); + } + // 获取SKU信息 + $skuInfo = GoodsSkuModel::detail($goodsId, $goodsSkuId); + if ($skuInfo['stock_num'] < $goodsNum) { + throwError('很抱歉, 该商品库存数量不足'); + } + } + + /** + * 获取购物车记录 + * @param int $goodsId 商品ID + * @param string $goodsSkuId 商品sku唯一标识 + * @param bool $isForce + * @return static|bool + * @throws BaseException + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + */ + private function getInfo(int $goodsId, string $goodsSkuId, bool $isForce = true) + { + // 获取当前用户ID + $userId = UserService::getCurrentLoginUserId(); + // 获取购物车记录 + $model = static::detail($userId, $goodsId, $goodsSkuId); + if (empty($model)) { + $isForce && throwError('购物车中没有该记录'); + return false; + } + return $model; + } + + /** + * 删除购物车中指定记录 + * @param array $cartIds 购物车ID集, 如果为空删除所有 + * @return bool + * @throws BaseException + */ + public function clear(array $cartIds = []): bool + { + // 获取当前用户ID + $userId = UserService::getCurrentLoginUserId(); + // 设置更新条件 + $where = [['user_id', '=', $userId]]; + // 购物车ID集 + !empty($cartIds) && $where[] = ['id', 'in', $cartIds]; + // 更新记录 + return $this->updateBase(['is_delete' => 1], $where); + } + + /** + * 获取当前用户购物车商品总数量 + * @return float + * @throws BaseException + */ + public function getCartTotal() + { + if (!UserService::isLogin()) return 0; + $userId = UserService::getCurrentLoginUserId(); + return $this->where('user_id', '=', $userId) + ->where('is_delete', '=', 0) + ->sum('goods_num'); + } + + public static function getCount() { + if (!UserService::isLogin()) return 0; + $userId = UserService::getCurrentLoginUserId(); + return self::where('user_id', '=', $userId) + ->where('is_delete', '=', 0) + ->sum('goods_num'); + } +}