where('endtime', '>=', $hour) ->where([ 'switch' => FlashSale::SWITCH_YES, 'status' => FlashSale::STATUS_NO, ]) ->with([ 'product' => function ($query) { //$query->with('product')->where(['switch' => FlashProduct::SWITCH_ON]); $query->alias('fp')->join('unishop_product p', 'fp.product_id = p.id') ->field('fp.id,fp.flash_id,fp.product_id,p.image,p.title,p.sales_price') ->where([ 'fp.switch' => FlashProduct::SWITCH_ON, 'p.deletetime' => NULL ]); } ]) ->order('starttime ASC') ->find(); if ($flash) { $flash = $flash->toArray(); foreach ($flash['product'] as &$product) { $product['image'] = Config::getImagesFullUrl($product['image']); } // 寻找下一场的倒计时 $nextFlash = $flashSaleModel ->where('starttime', '>', $hour) ->where([ 'switch' => FlashSale::SWITCH_YES, 'status' => FlashSale::STATUS_NO, ]) ->order("starttime ASC") ->cache(10) ->find(); $flash['starttime'] = $nextFlash['starttime']; $flash['countdown'] = FlashSale::countdown($flash['starttime']); } $this->success('', $flash); } /** * 获取秒杀时间段 */ public function navbar() { $flashSaleModel = new FlashSale(); $flash = $flashSaleModel ->where('endtime', '>', time()) ->where([ 'switch' => FlashSale::SWITCH_YES, 'status' => FlashSale::STATUS_NO ]) ->field('id,starttime,title,introdution,endtime') ->order('starttime ASC') ->cache(2) ->select(); $this->success('', $flash); } /** * 获取秒杀的产品列表 */ public function product() { $flash_id = $this->request->request('flash_id', 0); $page = $this->request->request('page', 1); $pagesize = $this->request->request('pagesize', 15); $flash_id = Hashids::decodeHex($flash_id); $productModel = new FlashProduct(); $products = $productModel ->with('product') ->where(['flash_id' => $flash_id, 'switch' => FlashProduct::SWITCH_ON]) ->limit(($page - 1) * $pagesize, $pagesize) ->cache(2) ->select(); foreach ($products as &$product) { $product['sold'] = $product['sold'] > $product['number'] ? $product['number'] : $product['sold']; } $this->success('', $products); } /** * 获取产品数据 */ public function productDetail() { $productId = $this->request->get('id'); $productId = \addons\unishop\extend\Hashids::decodeHex($productId); $flashId = $this->request->get('flash_id'); $flashId = \addons\unishop\extend\Hashids::decodeHex($flashId); try { $productModel = new Product(); $data = $productModel->where(['id' => $productId])->cache(true, 20, 'flashProduct')->find(); if (!$data) { $this->error(__('Product not exist')); } // 真实浏览量加一 $data->real_look++; $data->look++; $data->save(); //服务 $server = explode(',', $data->server); $configServer = json_decode(Config::getByName('server')['value'],true); $serverValue = []; foreach ($server as $k => $v) { if (isset($configServer[$v])) { $serverValue[] = $configServer[$v]; } } $data->server = count($serverValue) ? implode(' · ', $serverValue) : ''; // 默认没有收藏 $data->favorite = false; // 评价 $data['evaluate_data'] = (new Evaluate)->where(['product_id' => $productId]) ->field('COUNT(*) as count, IFNULL(CEIL(AVG(rate)/5*100),0) as avg') ->cache(true, 20, 'flashEvaluate')->find(); $redis = new Redis(); $flash['starttime'] = $redis->handler->hGet('flash_sale_' . $flashId . '_' . $productId, 'starttime'); $flash['endtime'] = $redis->handler->hGet('flash_sale_' . $flashId . '_' . $productId, 'endtime'); $flash['sold'] = $redis->handler->hGet('flash_sale_' . $flashId . '_' . $productId, 'sold'); $flash['number'] = $redis->handler->hGet('flash_sale_' . $flashId . '_' . $productId, 'number'); $flash['sold'] = $flash['sold'] > $flash['number'] ? $flash['number'] : $flash['sold']; $flash['text'] = $flash['starttime'] > time() ? '距开始:' : '距结束:'; // 秒杀类型不加载优惠券、促销活动、是否已收藏、评价等等,会影响返回速度 $targetTime = $flash['starttime'] > time() ? $flash['starttime'] : $flash['endtime']; $flash['countdown'] = FlashSale::countdown($targetTime); $data['coupon'] = []; // 秒杀数据 $data['flash'] = $flash; $data->append(['images_text', 'spec_list', 'spec_table_list'])->toArray(); // 购物车数量 $data['cart_num'] = (new \addons\unishop\model\Cart)->where(['user_id' => $this->auth->id])->count(); $this->success('', $data); } catch (Exception $e) { $this->error($e->getMessage()); } } /** * 创建订单 */ public function createOrder() { $productId = $this->request->post('id', 0); $flashId = $this->request->post('flash_id', 0); $flashId = \addons\unishop\extend\Hashids::decodeHex($flashId); $productId = \addons\unishop\extend\Hashids::decodeHex($productId); try { $redis = new Redis(); $sold = $redis->handler->hGet('flash_sale_' . $flashId . '_' . $productId, 'sold'); $number = $redis->handler->hGet('flash_sale_' . $flashId . '_' . $productId, 'number'); $switch = $redis->handler->hGet('flash_sale_' . $flashId . '_' . $productId, 'switch'); $starttime = $redis->handler->hGet('flash_sale_' . $flashId . '_' . $productId, 'starttime'); $endtime = $redis->handler->hGet('flash_sale_' . $flashId . '_' . $productId, 'endtime'); //判断是否开始或结束 if (time() < $starttime) { $this->error(__('Activity not started')); } if ($endtime < time()) { $this->error(__('Activity ended')); } // 截流 if ($sold >= $number) { $this->error(__('Item sold out')); } if ($switch == FlashSale::SWITCH_NO || $switch == false) { $this->error(__('Item is off the shelves')); } $product = (new Product)->where(['id' => $productId, 'deletetime' => null])->find(); /** 产品基础数据 **/ $spec = $this->request->post('spec', ''); $productData[0] = $product->getDataOnCreateOrder($spec); if (!$productData) { $this->error(__('Product not exist')); } $productData[0]['image'] = Config::getImagesFullUrl($productData[0]['image']); $productData[0]['sales_price'] = number_format($productData[0]['sales_price'], 2); $productData[0]['market_price'] = number_format($productData[0]['market_price'], 2); /** 默认地址 **/ $address = AddressModel::get(['user_id' => $this->auth->id, 'is_default' => AddressModel::IS_DEFAULT_YES]); if ($address) { $area = (new Area)->whereIn('id', [$address->province_id, $address->city_id, $address->area_id])->column('name', 'id'); $address = $address->toArray(); $address['province']['name'] = $area[$address['province_id']]; $address['city']['name'] = $area[$address['city_id']]; $address['area']['name'] = $area[$address['area_id']]; } /** 运费数据 **/ $cityId = $address['city_id'] ? $address['city_id'] : 0; $delivery = (new DeliveryRuleModel())->getDelivetyByArea($cityId); $msg = ''; // if ($delivery['status'] == 0) { // $msg = __('Your receiving address is not within the scope of delivery'); // } $redis = new Redis(); //$flash['starttime'] = $redis->handler->hGet('flash_sale_' . $flashId . '_' . $productId, 'starttime'); //$flash['endtime'] = $redis->handler->hGet('flash_sale_' . $flashId . '_' . $productId, 'endtime'); $flash['sold'] = $redis->handler->hGet('flash_sale_' . $flashId . '_' . $productId, 'sold'); $flash['number'] = $redis->handler->hGet('flash_sale_' . $flashId . '_' . $productId, 'number'); $flash['sold'] = $flash['sold'] > $flash['number'] ? $flash['number'] : $flash['sold']; //$flash['text'] = $flash['starttime'] > time() ? '距开始:' : '距结束:'; // 秒杀类型不加载优惠券、促销活动、是否已收藏、评价等等,会影响返回速度 //$targetTime = $flash['starttime'] > time() ? $flash['starttime'] : $flash['endtime']; //$flash['countdown'] = FlashSale::countdown($targetTime); $this->success($msg, [ 'product' => $productData, 'address' => $address, 'delivery' => $delivery['list'], 'flash' => $flash ]); } catch (Exception $e) { $this->error($e->getMessage(), false); } } /** * 提交订单 */ public function submitOrder() { $data = $this->request->post(); try { $validate = Loader::validate('\\addons\\unishop\\validate\\Order'); if (!$validate->check($data, [], 'submitFlash')) { throw new Exception($validate->getError()); } Db::startTrans(); // 判断创建订单的条件 if (empty(Hook::get('create_order_before'))) { // 由于自动化测试的时候会注册多个同名行为 Hook::add('create_order_before', 'addons\\unishop\\behavior\\OrderFlash'); } if (empty(Hook::get('create_order_after'))) { Hook::add('create_order_after', 'addons\\unishop\\behavior\\OrderFlash'); } $data['flash_id'] = Hashids::decodeHex($data['flash_id']); $data['product_id'] = Hashids::decodeHex($data['product_id']); $orderModel = new \addons\unishop\model\Order(); $result = $orderModel->createOrder($this->auth->id, $data); Db::commit(); $this->success('', $result); } catch (Exception $e) { Db::rollback(); $this->error($e->getMessage(), false); } } }