verify_sign(); // 验证参数 $request->scene('create')->validate(); // 检查登录 $uid = $this->checkLogin(); // 接收参数 $isCart = request('is_cart',0); $productList = request('product_list','[]'); $customCouponId = request('custom_coupon_id',0); $addrId = request('addr_id',0); // 如果不存在数据 if( !$addrId ) return json_send(['code'=>'error','msg'=>'请选择收货地址','data'=>['error'=>'请选择收货地址']]); // 解码购买信息 $buyList = json_decode($productList,true); // 如果不存在数据 if( empty($buyList) ) return json_send(['code'=>'error','msg'=>'没有需下单的产品','data'=>['error'=>'产品列表为空']]); // 选择地址 $addr = $CustomAddr->getOne($addrId); // 如果不存在数据 if( !$addr ) return json_send(['code'=>'error','msg'=>'地址有误,请核对','data'=>['error'=>'没有找到对应的地址']]); // 重组数据 $addr = ['contact_name'=>$addr['contact_name'],'contact_shop'=>$addr['contact_shop'],'contact_phone'=>$addr['contact_phone'],'contact_province'=>$addr['contact_province'],'contact_city'=>$addr['contact_city'],'contact_area'=>$addr['contact_area'],'contact_addr'=>$addr['contact_addr']]; // 获取客户城市ID $custom = $Custom->getOne($uid); // 如果不存在的话 if( !$custom ) return json_send(['code'=>'no_login','msg'=>'用户不存在,请重新登录','data'=>['error'=>'用户不存在,请重新登录']]); // 如果不存在的话 if( !$custom['city_id'] ) return json_send(['code'=>'error','msg'=>'请选择所在城市后下单','data'=>['error'=>'请选择所在城市后下单']]); // 获取城市ID $cityId = $custom['city_id']; $cityName = $City->getOne($cityId,'name'); $pid = $City->getOne($cityId,'pid'); $province = $City->getOne($pid,'name'); // 判断选择的城市名称是不是一致 if( $cityName != $addr['contact_city'] ) return json_send(['code'=>'error','msg'=>'收货地址请选择'.$province.'/'.$cityName,'data'=>['error'=>'收货地址需与您所选城市一致']]); // 商品购买数量 $buyNum = []; // 循环购买信息 foreach ($buyList as $key => $value) { // 获取每个商品的总量 $buyNum[$value['product_id']] = isset($buyNum[$value['product_id']]) ? ($buyNum[$value['product_id']] + $value['buy_num']) : $value['buy_num']; } // 查询用户标签 $tags = $WeiBanTags->getListByWeibanExtid($custom['weiban_extid']); // 查询产品信息 $productList = $Product->getListByIds(array_column($buyList,'product_id')); $skusList = $ProductSkus->getListByIds(array_column($buyList,'product_skuid')); // 当前时间 $time = time(); // 产品以商业公司分组,方便写入订单 $orderProduct = []; // 产品价格同级,用于优惠券计算 $productPrice = []; // 循环处理购买信息 foreach ($buyList as $buyInfo) { // 如果产品不存在 if( empty($productList[$buyInfo['product_id']]) ) return json_send(['code'=>'error','msg'=>'产品不存在或已下架','data'=>['error'=>'产品不存在或已下架=>'.$buyInfo['product_id']]]); // 获取产信息 $productInfo = $productList[$buyInfo['product_id']]; // 判断是不是可以参与 if( $productInfo['tag_scope'] ) { // 解析数组 $productInfo['tag_scope'] = explode(',',$productInfo['tag_scope']); // 标签范围限定时,默认不能参与 $allowJoin = 0; // 判断标签是不是存在 foreach ($tags as $value) { // 标签范围内,允许参加 if( in_array($value['name'],$productInfo['tag_scope']) ) $allowJoin = 1; } // 如果不能参与 if( !$allowJoin ) return json_send(['code'=>'error','msg'=>'不在 '.$productInfo['product_name'].' 参与范围','data'=>['error'=>'不在标签范围内']]); } // 判断是不是可以参与 if( $productInfo['tag_exclude'] ) { // 解析数组 $productInfo['tag_exclude'] = explode(',',$productInfo['tag_exclude']); // 判断标签是不是存在 foreach ($tags as $value) { // 标签排除范围内,不允许参加 if( in_array($value['name'],$productInfo['tag_exclude']) ) return json_send(['code'=>'error','msg'=>'不在 '.$productInfo['product_name'].' 可参与范围','data'=>['error'=>'用户在标签排除范围']]); } } // 如果产品限购 if( $productInfo['quota'] ) { // 是否在限购时间,当前时间大于开始时间,并且小于结束时间 if( $productInfo['quota_start'] <= $time && $time <= $productInfo['quota_end'] ){ // 通过时间查询商品的购买总数 $total = $OrdersProduct->query()->where([['custom_uid','=',$uid],['product_id','=',$productInfo['id']],['insert_time','>=',$productInfo['quota_start']],['insert_time','<=',$productInfo['quota_end']]])->sum('buy_num'); // 判断限购数量 $total = $buyNum[$buyInfo['product_id']] + $total; // 如果超过数量 if( $total > $productInfo['quota'] ) return json_send(['code'=>'error','msg'=>'限购'.$productInfo['quota'].'套-'.$productInfo['product_name'],'data'=>['error'=>'已超限=>'.($total - $productInfo['quota'])]]); } } // 如果存在SKU if( $buyInfo['product_skuid'] ) { // 判断SKU信息存不存在 if( empty($skusList[$buyInfo['product_skuid']]) ) return json_send(['code'=>'error','msg'=>'该产品规格不存在或已下架','data'=>['error'=>'SKU不存在或已下架=>'.$buyInfo['product_skuid']]]); // 产品ID不匹配的话 if( $skusList[$buyInfo['product_skuid']]['product_id'] != $buyInfo['product_id'] ) return json_send(['code'=>'error','msg'=>'该产品规格不存在或已下架','data'=>['error'=>'SKU不匹配=>'.$buyInfo['product_skuid']]]); // 如果SKU存在,合并产品信息 $productInfo = array_merge($productInfo,$skusList[$buyInfo['product_skuid']]); // 需要扣除的库存 $skusList[$buyInfo['product_skuid']]['decr'] = empty($skusList[$buyInfo['product_skuid']]['decr']) ? $buyInfo['buy_num'] : $skusList[$buyInfo['product_skuid']]['decr'] + $buyInfo['buy_num']; } // 需要扣除的库存 $productList[$buyInfo['product_id']]['decr'] = empty($productList[$buyInfo['product_id']]['decr']) ? $buyInfo['buy_num'] : $productList[$buyInfo['product_id']]['decr'] + $buyInfo['buy_num']; // 判断库存 if( $productInfo['stock'] < $productList[$buyInfo['product_id']]['decr'] ) return json_send(['code'=>'error','msg'=>$productInfo['product_name'].'-库存不足','data'=>['error'=>'产品库存不足=>'.$buyInfo['product_id']]]); // 计算价值 $priceTotal = $buyInfo['buy_num'] * $productInfo['price']; // 购买信息 $buyInfo = ['is_rebate'=>0,'custom_uid'=>$uid,'business_id'=>$productInfo['business_id'],'product_id'=>$buyInfo['product_id'],'buy_num'=>$buyInfo['buy_num'],'price_total'=>$priceTotal,'pay_total'=>$priceTotal,'coupon_total'=>0,'product_name'=>$productInfo['product_name'],'sku_attr_names'=>$productInfo['sku_attr_names'],'product_thumb'=>$productInfo['product_thumb']]; // 获取信息 if( !isset($orderProduct[$buyInfo['business_id']]) ) $orderProduct[$buyInfo['business_id']] = ['business_id'=>$buyInfo['business_id'],'custom_uid'=>$buyInfo['custom_uid'],'price_total'=>0,'pay_total'=>0,'coupon_total'=>0,'product_list'=>[]]; // 订单产品 $orderProduct[$buyInfo['business_id']]['price_total'] += $buyInfo['price_total']; $orderProduct[$buyInfo['business_id']]['pay_total'] += $buyInfo['price_total']; $orderProduct[$buyInfo['business_id']]['product_list'][] = $buyInfo; // 商品优惠信息不存在,创建 if( !isset($productPrice[$buyInfo['product_id']]) ) $productPrice[$buyInfo['product_id']] = ['price_total'=>0,'rebate_price'=>0]; // 计算总价 $productPrice[$buyInfo['product_id']]['price_total'] = $productPrice[$buyInfo['product_id']]['price_total'] + $priceTotal; } // 优惠券数据 $couponRebate = $CustomCoupon->getRebatePrice($customCouponId,$uid,$productPrice); // 判断是否使用了优惠券 $usedCoupon = $couponRebate['is_used']; // 获取优惠券扣减金额 $productPrice = $couponRebate['product_price']; // 获取优惠券赠品信息 $rebateProduct = $couponRebate['rebate_product']; // 组合订单数据 foreach ($orderProduct as $key => $order) { // 判断哪一家的赠品 if( isset($rebateProduct[$order['business_id']]) ){ // 循环赠品 foreach ( $rebateProduct[$order['business_id']] as $value) { // 没有对应的产品 if( !isset($productList[$value['product_id']]) ) $productList[$value['product_id']] = ['id'=>$value['id'],'stock'=>$value['stock']]; // 判断库存,如果库存不足,只赠送最后的库存 if( $productList[$value['product_id']]['stock'] <= $value['buy_num'] ) $value['buy_num'] = $productList[$value['product_id']]['stock']; // 库存扣减 $productList[$value['product_id']]['decr'] = empty($productList[$value['product_id']]['decr']) ? $value['buy_num'] : $productList[$value['product_id']]['decr'] + $value['buy_num']; // 追加到订单表 $order['product_list'][] = ['is_rebate'=>1,'custom_uid'=>$uid,'business_id'=>$value['business_id'],'product_id'=>$value['product_id'],'buy_num'=>$value['buy_num'],'price_total'=>$value['price_total'],'pay_total'=>$value['pay_total'],'coupon_total'=>$value['coupon_total'],'product_name'=>$value['product_name'],'sku_attr_names'=>$value['sku_attr_names'],'product_thumb'=>$value['product_thumb']]; } } // 计算总价格 foreach ($order['product_list'] as $k=>$product) { // 商品不存在,不进行扣减 if( empty($productPrice[$product['product_id']]['rebate_price']) ) { // 重组 $order['product_list'][$k] = $product; continue; } // 总优惠增加 $order['coupon_total'] = $order['coupon_total'] + $productPrice[$product['product_id']]['rebate_price']; // 当前商品的优惠折扣计算 $product['coupon_total'] = number_format( $productPrice[$product['product_id']]['rebate_price'] * ($product['price_total'] / $productPrice[$product['product_id']]['price_total']) , 2 , '.' ,''); // 成交小计 $product['pay_total'] = $product['pay_total'] - $product['coupon_total']; // 重组 $order['product_list'][$k] = $product; } // 成交总价 $order['pay_total'] = $order['pay_total'] - $order['coupon_total']; // 赠送积分 $order['order_score'] = (config('order_score_send',0) && floor( $order['pay_total'] * 1 ) > 0 ) ? floor( $order['pay_total'] * 1 ) : 0; // 成交总价 $order['custom_uid'] = $uid; // 重组 $orderProduct[$key] = $order; } // 组合数据,写入订单表,子表 DB::beginTransaction(); // 写入数据 try { // 扣减商品库存 foreach ($productList as $key => $value) { // 扣减库存 $result = $Product->edit($value['id'],['stock'=>DB::raw('stock+-'.$value['decr'])]); // 判断结果 if( !$result ) { // 回退数据 DB::rollBack(); // 错误提示 return json_send(['code'=>'error','msg'=>'库存扣减失败','data'=>['error'=>'库存扣减失败']]); } } // 扣减商品库存 foreach ($skusList as $key => $value) { // 扣减库存 $result = $ProductSkus->edit($value['sku_id'],['stock'=>DB::raw('stock+-'.$value['decr'])]); // 判断结果 if( !$result ) { // 回退数据 DB::rollBack(); // 错误提示 return json_send(['code'=>'error','msg'=>'库存扣减失败','data'=>['error'=>'库存扣减失败']]); } } // 循环订单数据 foreach ($orderProduct as $order) { // 先获取产品列表,并去除key $productItem = array_values($order['product_list']); // 删除非必要数据 unset($order['product_list']); // 创建总订单 $orderId = $Model->add($order); // 如果订单写入失败 if( !$orderId ) { // 回退数据 DB::rollBack(); // 错误提示 return json_send(['code'=>'error','msg'=>'下单失败','data'=>['error'=>'订单创建失败']]); } // 创建子订单 foreach ($productItem as $key=>$value) { // 增加订单ID $value['order_id'] = $orderId; // 增加订单ID $value['insert_time']= $time; $value['update_time']= $time; // 结果 $productItem[$key] = $value; } // 写入子表 $result = $OrdersProduct->query()->insert($productItem); // 如果扣减失败 if( !$result ) { // 回退数据 DB::rollBack(); // 提示信息 return json_send(['code'=>'error','msg'=>'子订单创建失败','data'=>['error'=>'子订单创建失败']]); } // 写入订单地址表 $addr['order_id'] = $orderId; // 写入订单地址表 $result = $OrdersAddr->add($addr); // 地址写入失败 if( !$result ) { // 回退数据 DB::rollBack(); // 提示信息 return json_send(['code'=>'error','msg'=>'地址写入失败','data'=>['error'=>'地址写入失败']]); } // 赠送积分 if( $order['order_score'] > 0 ) $CustomScore->trade($order['custom_uid'],$orderId,$order['order_score'],5,1); // 如果使用了优惠券 if( $usedCoupon ) $CustomCoupon->edit($usedCoupon,['status'=>1,'order_id'=>$orderId]); // 购物车 if( $isCart ) $ShopCart->query()->where([['custom_uid','=',$uid]])->whereIn('skuid',array_column($buyList,'product_skuid'))->delete(); } // 自动发放优惠券 $this->autoCoupon($uid); // 提交数据 DB::commit(); // 返回结果 return json_send(['code'=>'success','msg'=>'下单成功','data'=>['id'=>null]]); // 返回结果 } catch (\Throwable $th) { // 回退数据 DB::rollBack(); // 判断结果,如果库存扣减失败的话 if( stripos($th->getMessage(),'UNSIGNED') ) return json_send(['code'=>'error','msg'=>'库存不足','data'=>['error'=>'产品库存扣减失败']]); // 下单失败提示 return json_send(['code'=>'error','msg'=>'系统异常,请稍后再试','data'=>['error'=>$th->getMessage().$th->getLine()]]); } } /** * 获取列表 /api/orders/get_list * * @param string $name 产品名称 * @param int $page 页码,默认1 * @param int $limit 每页条数,默认10条 * * */ public function get_list(Request $request,Model $Model,OrdersProduct $OrdersProduct,Business $Business){ // 接口验签 // $this->verify_sign(); // 验证参数 $request->scene('get_list')->validate(); // 检查登录 $uid = $this->checkLogin(); // 接收参数 $status = request('status',0); $limit = request('limit',10); // 显示 $map = [['custom_uid','=',$uid]]; // 查询状态 if( $status ) $map[] = ['status','=',$status]; // 查询 $Paginator = $Model->query()->where($map)->orderByDesc('id')->paginate($limit,['id','pay_total','status','price_total','coupon_total','business_id','pay_total','weizan_orderid','insert_time']); // 订单产品 $productList = $OrdersProduct->query()->whereIn('order_id', array_column($Paginator->items(),'id'))->select(['id as item_id','order_id','product_id','buy_num','is_rebate','sku_attr_names as product_spec','product_name','product_thumb'])->get()->toArray(); // 循环处理 foreach ($Paginator as $key => $order) { // 商品列表 $itemList = []; // 返回结果 foreach ($productList as $item) { // 产品图路径 $item['product_thumb'] = path_compat($item['product_thumb']); // 如果是订单的 if( $item['order_id'] == $order['id'] ) $itemList[] = $item; } // 获取子列表 $order['state'] = (string) $Model->getState($order['status'],'state'); // 获取子列表 $order['business_name'] = (string) ($order['business_id'] ? $Business->getOne($order['business_id'],'name') : ($order['weizan_orderid'] ? '微赞订单' : '')); // 获取子列表 $order['contents_class']= 0; // 获取子列表 $order['product_list'] = $itemList; // 重组 $Paginator[$key] = $order; } // 获取数据 $data['total'] = $Paginator->total(); $data['current_page'] = $Paginator->currentPage(); $data['per_page'] = $Paginator->perPage(); $data['last_page'] = $Paginator->lastPage(); $data['data'] = $Paginator->items(); // 返回结果 return json_send(['code'=>'success','msg'=>'获取成功','data'=>$data]); } /** * 自动发放优惠券 * */ private function autoCoupon($uid){ // 模型实例 $Rule = new \App\Models\CouponRewardRule(); // 获取配置列表 $ruleList = $Rule->getList(); // 如果没有信息的话 if( !$ruleList ) return ['success'=>'暂无活动']; // 其他实例 $RuleProduct = new \App\Models\CouponRewardProduct(); $OrdersProduct = new \App\Models\OrdersProduct(); $Custom = new \App\Models\Custom(); $Coupon = new \App\Models\Coupon(); $CustomCoupon = new \App\Models\CustomCoupon(); // 获取客户城市ID $customCityId = (int) $Custom->getValue($uid,'city_id'); // 循环配置列表 foreach ( $ruleList as $value ) { // 如果存在城市范围,并且不在城市范围,不参与这个活动 if( $value['city_ids'] && !in_array($customCityId,explode(',',$value['city_ids'])) ) continue; // 未到开始时间 if( $value['start_time'] > time() ) continue; // 通过配置ID获取对应的商品范围 $productList = $RuleProduct->getListByRule($value['id']); // 如果不存在产品范围,跳过 if( !$productList ) continue; // 获取客户 规定时段内订单的商品ID以及购买数量 $orderList = $OrdersProduct->query()->where([['custom_uid','=',$uid],['status','=',1],['insert_time','>=',$value['start_time']],['insert_time','<=',$value['end_time']]])->get(['product_id','buy_num'])->toArray(); // 如果没有订单总数 if( !$orderList ) continue; // 计算商品总量 $total = 0; // 循环商品范围 foreach ($productList as $scope) { // 循环订单产品 foreach ($orderList as $order) { // 如果产品不相等 if( $scope['product_id'] != $order['product_id'] ) continue; // 相等的计算总量 $total += $scope['product_units'] * $order['buy_num']; } } // 判断总数是不是达标 if( $total < $value['std_num'] ) continue; // 达标的是否已经发送过优惠券 $havaCoupon = $CustomCoupon->query()->where([['custom_uid','=',$uid],['coupon_id','=',$value['coupon_id']]])->first(['status']); // 已经发过优惠券的,不发 if( $havaCoupon ) continue; // 获取优惠券的可用时间 $expTime = $Coupon->query()->where([['id','=',$value['coupon_id']]])->value('exp_time'); // 时间转时间 $expTime = $Coupon->getExpTime($expTime); // 发送优惠券 $CustomCoupon->add(['coupon_id'=>$value['coupon_id'],'custom_uid'=>$uid,'exp_time'=>$expTime]); } // 返回成功 return ['success'=>'操作成功']; } /** * 取消 /api/orders/cancel * * */ public function cancel( Request $request, Model $Model,OrdersProduct $OrdersProduct,CustomScore $CustomScore){ // 验证参数 $request->scene('cancel')->validate(); // 检查登录 $uid = $this->checkLogin(); // 接收参数 $id = request('id',0); $status = 4; // 获取产品和数量 $oldData = $Model->query()->where([['id','=',$id],['custom_uid','=',$uid]])->first(['id','order_score','status','custom_uid','insert_time']); // 如果用户不存在 if( !$oldData ) return json_send(['code'=>'error','msg'=>'订单不存在']); // 如果已经取消 if( $oldData['status'] == 4 ) return json_send(['code'=>'error','msg'=>'订单已取消']); // 组合数据,写入订单表,子表 DB::beginTransaction(); try{ // 查询数据 $result = $Model->setOrderStatus($id,$status,$OrdersProduct); // 提示新增失败 if( isset($result['error']) ) { // 回退数据 DB::rollBack(); // 提示信息 return json_send(['code'=>'error','msg'=>$result['error'],'data'=>['error'=>$result['error']]]); } if( $status == 4 ){ // 取消积分 if( $oldData['order_score'] > 0 ) { // 如果扣减失败 $result = $CustomScore->trade($oldData['custom_uid'],$oldData['id'],($oldData['order_score']*-1),6,1); // 提示新增失败 if( isset($result['error']) ) { // 回退数据 DB::rollBack(); // 提示信息 return json_send(['code'=>'error','msg'=>'取消赠送积分失败','data'=>['error'=>$result['error']]]); } } // 取消关联订单 $result = $Model->cancelRelate($oldData['insert_time'],$oldData['custom_uid'],$OrdersProduct,$CustomScore); // 提示新增失败 if( isset($result['error']) ) { // 回退数据 DB::rollBack(); // 提示信息 return json_send(['code'=>'error','msg'=>'取消关联订单失败','data'=>['error'=>$result['error']]]); } } // 提交数据 DB::commit(); // 告知结果 return json_send(['code'=>'success','msg'=>'取消成功']); // 返回结果 } catch (\Throwable $th) { // 回退数据 DB::rollBack(); // 下单失败提示 return json_send(['code'=>'error','msg'=>'取消失败','data'=>['error'=>$th->getMessage().$th->getLine()]]); } } /** * 获取订单子数据 /api/orders/get_item * * @param string $name 产品名称 * @param int $page 页码,默认1 * @param int $limit 每页条数,默认10条 * * */ public function get_item(Request $request,Model $Model,OrdersProduct $OrdersProduct,Business $Business){ // 接口验签 // $this->verify_sign(); // 验证参数 $request->scene('get_item')->validate(); // 检查登录 $uid = $this->checkLogin(); // 接收参数 $id = request('id',0); // 查询 $orderInfo = $Model->query()->where([['id','=',$id],['custom_uid','=',$uid]])->first(['id','pay_total','status','price_total','coupon_total','business_id','pay_total','weizan_orderid','insert_time']); // 如果用户不存在 if( !$orderInfo ) return json_send(['code'=>'error','msg'=>'订单不存在']); // 转数组 $orderInfo = $orderInfo->toArray(); // 订单产品 $orderInfo['product_list'] = $OrdersProduct->query()->where([['order_id','=',$id]])->select(['id as item_id','order_id','product_id','buy_num','is_rebate','sku_attr_names as product_spec','product_name','product_thumb'])->get()->toArray(); // 循环处理 foreach ($orderInfo['product_list'] as $key => $item) { // 产品图路径 $item['product_thumb'] = path_compat($item['product_thumb']); // 重组 $orderInfo['product_list'][$key] = $item; } // 获取子列表 $orderInfo['state'] = (string) $Model->getState($orderInfo['status'],'state'); // 获取子列表 $orderInfo['business_name'] = (string) ($orderInfo['business_id'] ? $Business->getOne($orderInfo['business_id'],'name') : ($orderInfo['weizan_orderid'] ? '微赞订单' : '')); // 返回结果 return json_send(['code'=>'success','msg'=>'获取成功','data'=>$orderInfo]); } /** * 创建拼团订单 /api/orders/create_regiment * * */ public function create_regiment(Request $request,Custom $Custom,City $City,Model $Model,WeiBanTags $WeiBanTags,OrdersAddr $OrdersAddr,OrdersProduct $OrdersProduct,Product $Product,ProductSkus $ProductSkus,CustomCoupon $CustomCoupon,ShopCart $ShopCart,CustomAddr $CustomAddr,CustomScore $CustomScore){ // 接口验签 // $this->verify_sign(); // 验证参数 $request->scene('create')->validate(); // 检查登录 $uid = $this->checkLogin(); // 接收参数 $isCart = request('is_cart',0); $productList = request('product_list','[]'); $customCouponId = request('custom_coupon_id',0); $addrId = request('addr_id',0); $regimentId = request('regiment_id',0); $regimentActiveId = request('regiment_active_id',0); $btnType = request('btn_type',0); // 如果不存在数据 if( !$addrId ) return json_send(['code'=>'error','msg'=>'请选择收货地址','data'=>['error'=>'请选择收货地址']]); // 解码购买信息 $buyList = json_decode($productList,true); // 如果不存在数据 if( empty($buyList) ) return json_send(['code'=>'error','msg'=>'没有需下单的产品','data'=>['error'=>'产品列表为空']]); $time = time(); // 选择地址 $addr = $CustomAddr->getOne($addrId); // 如果不存在数据 if( !$addr ) return json_send(['code'=>'error','msg'=>'地址有误,请核对','data'=>['error'=>'没有找到对应的地址']]); // 重组数据 $addr = ['contact_name'=>$addr['contact_name'],'contact_shop'=>$addr['contact_shop'],'contact_phone'=>$addr['contact_phone'],'contact_province'=>$addr['contact_province'],'contact_city'=>$addr['contact_city'],'contact_area'=>$addr['contact_area'],'contact_addr'=>$addr['contact_addr']]; // 获取客户城市ID $custom = $Custom->getOne($uid); // 如果不存在的话 if( !$custom ) return json_send(['code'=>'no_login','msg'=>'用户不存在,请重新登录','data'=>['error'=>'用户不存在,请重新登录']]); // 如果不存在的话 if( !$custom['city_id'] ) return json_send(['code'=>'error','msg'=>'请选择所在城市后下单','data'=>['error'=>'请选择所在城市后下单']]); // 获取城市ID $cityId = $custom['city_id']; $cityName = $City->getOne($cityId,'name'); $pid = $City->getOne($cityId,'pid'); $province = $City->getOne($pid,'name'); // 判断选择的城市名称是不是一致 if( $cityName != $addr['contact_city'] ) return json_send(['code'=>'error','msg'=>'收货地址请选择'.$province.'/'.$cityName,'data'=>['error'=>'收货地址需与您所选城市一致']]); //获取团活动信息 $regimentActiveInfo = RegimentActive::query() ->where([['id','=',$regimentActiveId],['status','=',1],['start_time','<=',$time],['end_time','>=',$time]]) ->first(); if (!$regimentActiveInfo) return json_send(['code'=>'error','msg'=>'拼团活动不存在','data'=>['error'=>'拼团活动不存在']]); //是否符合开团条件 if($btnType == 3){ if ($regimentActiveInfo['open_people'] == 1){ if ($custom['insert_time'] > $regimentActiveInfo['start_time']) return json_send(['code'=>'error','msg'=>'此活动只允许老用户开团','data'=>['error'=>'此活动只允许老用户开团']]); } if ($regimentActiveInfo['open_people'] == 2){ if ($custom['insert_time'] < $regimentActiveInfo['start_time']) return json_send(['code'=>'error','msg'=>'此活动只允许新用户开团','data'=>['error'=>'此活动只允许新用户开团']]); } } //是否符合参团条件 if($btnType == 4){ if ($regimentActiveInfo['partake_people'] == 1){ if ($custom['insert_time'] > $regimentActiveInfo['start_time']) return json_send(['code'=>'error','msg'=>'此活动只允许老用户参与','data'=>['error'=>'此活动只允许老用户开团']]); } if ($regimentActiveInfo['open_people'] == 2){ if ($custom['insert_time'] < $regimentActiveInfo['start_time']) return json_send(['code'=>'error','msg'=>'此活动只允许新用户参与','data'=>['error'=>'此活动只允许新用户开团']]); } //查询团信息 $regimentInfo = Regiment::query() ->where([['id','=',$regimentId],['status','=',1],['start_time','<=',$time],['end_time','>=',$time]]) ->first(); if (!$regimentInfo) return json_send(['code'=>'error','msg'=>'拼团活动不存在','data'=>['error'=>'拼团活动不存在']]); } //查询用户参团记录 $regimentRecordCount = RegimentRecord::query() ->where([['custom_uid','=',$uid],['active_id','=',$regimentActiveInfo['id']]]) ->count('id'); if ($regimentRecordCount >= $regimentActiveInfo['participation_number']) return json_send(['code'=>'error','msg'=>'该活动每人仅限参与'.$regimentActiveInfo['participation_number'].'次','data'=>['error'=>'该活动每人仅限参与'.$regimentActiveInfo['participation_number'].'次']]); $tags = $WeiBanTags->getListByWeibanExtid($custom['weiban_extid']); // 查询产品信息 $productList = $Product->getListByIds(array_column($buyList,'product_id')); // 当前时间 $time = time(); // 产品以商业公司分组,方便写入订单 $orderProduct = []; // 产品价格同级,用于优惠券计算 $productPrice = []; $priceTotal = 0; $payTotal = 0; $buyInfo = $buyList[0]; if ($buyInfo){ if( empty($productList[$buyInfo['product_id']]) ) return json_send(['code'=>'error','msg'=>'产品不存在或已下架','data'=>['error'=>'产品不存在或已下架=>'.$buyInfo['product_id']]]); // 获取产信息 $productInfo = $productList[$buyInfo['product_id']]; // 判断是不是可以参与 if( $productInfo['tag_scope'] ) { // 解析数组 $productInfo['tag_scope'] = explode(',',$productInfo['tag_scope']); // 标签范围限定时,默认不能参与 $allowJoin = 0; // 判断标签是不是存在 foreach ($tags as $value) { // 标签范围内,允许参加 if( in_array($value['name'],$productInfo['tag_scope']) ) $allowJoin = 1; } // 如果不能参与 if( !$allowJoin ) return json_send(['code'=>'error','msg'=>'不在 '.$productInfo['product_name'].' 参与范围','data'=>['error'=>'不在标签范围内']]); } // 判断是不是可以参与 if( $productInfo['tag_exclude'] ) { // 解析数组 $productInfo['tag_exclude'] = explode(',',$productInfo['tag_exclude']); // 判断标签是不是存在 foreach ($tags as $value) { // 标签排除范围内,不允许参加 if( in_array($value['name'],$productInfo['tag_exclude']) ) return json_send(['code'=>'error','msg'=>'不在 '.$productInfo['product_name'].' 可参与范围','data'=>['error'=>'用户在标签排除范围']]); } } //拼团活动限购 if ($regimentActiveInfo['quota']){ if ($buyInfo['buy_num'] > $regimentActiveInfo['quota']) return json_send(['code'=>'error','msg'=>'超过拼团限购','data'=>['error'=>'拼团限购=>'.$buyInfo['product_id']]]); } // 如果产品限购 if( $productInfo['quota'] ) { // 是否在限购时间,当前时间大于开始时间,并且小于结束时间 if( $productInfo['quota_start'] <= $time && $time <= $productInfo['quota_end'] ){ // 通过时间查询商品的购买总数 $total = $OrdersProduct->query()->where([['custom_uid','=',$uid],['product_id','=',$productInfo['id']],['insert_time','>=',$productInfo['quota_start']],['insert_time','<=',$productInfo['quota_end']]])->sum('buy_num'); // 判断限购数量 $total = $buyInfo['buy_num'] + $total; // 如果超过数量 if( $total > $productInfo['quota'] ) return json_send(['code'=>'error','msg'=>'限购'.$productInfo['quota'].'套-'.$productInfo['product_name'],'data'=>['error'=>'已超限=>'.($total - $productInfo['quota'])]]); } } // 需要扣除的库存 $productList[$buyInfo['product_id']]['decr'] = $buyInfo['buy_num']; // 判断库存 if( $productInfo['stock'] < $productList[$buyInfo['product_id']]['decr'] ) return json_send(['code'=>'error','msg'=>$productInfo['product_name'].'-库存不足','data'=>['error'=>'产品库存不足=>'.$buyInfo['product_id']]]); // 计算价值 $priceTotal = $buyInfo['buy_num'] * $regimentActiveInfo['regiment_price']; $payTotal = $buyInfo['buy_num'] * $productInfo['price']; } $orderInfo = [ 'custom_uid' => $uid, 'status' => 10, 'pay_total' => $payTotal, 'price_total' => $priceTotal, 'business_id' => $productList[$buyInfo['product_id']]['business_id'], ]; // 赠送积分 $orderInfo['order_score'] = (config('order_score_send',0) && floor( $orderInfo['pay_total'] * 1 ) > 0 ) ? floor( $orderInfo['pay_total'] * 1 ) : 0; $orderProductInfo = [ 'product_name' => $productList[$buyInfo['product_id']]['product_name'], 'sku_attr_names' => $productList[$buyInfo['product_id']]['sku_attr_names'], 'product_thumb' => $productList[$buyInfo['product_id']]['product_thumb'], 'buy_num' => $buyInfo['buy_num'], 'price_total' => $priceTotal, 'pay_total' => $buyInfo['buy_num'] * $productList[$buyInfo['product_id']]['price'], 'product_id' => $buyInfo['product_id'], 'custom_uid' => $uid, 'business_id' => $productList[$buyInfo['product_id']]['business_id'], ]; // 组合数据,写入订单表,子表 DB::beginTransaction(); // 写入数据 try { // 扣减商品库存 foreach ($productList as $key => $value) { // 扣减库存 $result = $Product->edit($value['id'],['stock'=>DB::raw('stock+-'.$value['decr'])]); // 判断结果 if( !$result ) { // 回退数据 DB::rollBack(); // 错误提示 return json_send(['code'=>'error','msg'=>'库存扣减失败','data'=>['error'=>'库存扣减失败']]); } } //创建拼团 if($btnType == 3){ $regimentInfo = [ 'custom_uid' => $uid, 'active_id' => $regimentActiveInfo['id'], 'product_id' => $buyInfo['product_id'], 'people_number' => 1, 'status' => 1, 'start_time' => $time, 'end_time' => $time + $regimentActiveInfo['expiration']*3600, 'update_time' => $time, 'insert_time' => $time, ]; $regimentId = Regiment::query()->insert($regimentInfo); if( !$regimentId ) { // 回退数据 DB::rollBack(); // 提示信息 return json_send(['code'=>'error','msg'=>'创建拼团失败','data'=>['error'=>'创建拼团失败']]); } } $orderInfo['regiment_id'] = $regimentId; // 创建总订单 $orderId = $Model->add($orderInfo); // 如果订单写入失败 if( !$orderId ) { // 回退数据 DB::rollBack(); // 错误提示 return json_send(['code'=>'error','msg'=>'下单失败','data'=>['error'=>'订单创建失败']]); } $orderProductInfo['order_id'] = $orderId; // 写入子表 $result = $OrdersProduct->query()->insert($orderProductInfo); // 如果扣减失败 if( !$result ) { // 回退数据 DB::rollBack(); // 提示信息 return json_send(['code'=>'error','msg'=>'子订单创建失败','data'=>['error'=>'子订单创建失败']]); } // 写入订单地址表 $addr['order_id'] = $orderId; // 写入订单地址表 $result = $OrdersAddr->add($addr); // 地址写入失败 if( !$result ) { // 回退数据 DB::rollBack(); // 提示信息 return json_send(['code'=>'error','msg'=>'地址写入失败','data'=>['error'=>'地址写入失败']]); } if($btnType == 4){ // 拼团人数加1 $inc = Regiment::query()->where('id','=',$regimentId)->increment('people_number',1); if( !$inc ) { // 回退数据 DB::rollBack(); // 提示信息 return json_send(['code'=>'error','msg'=>'创建拼团失败','data'=>['error'=>'创建拼团失败']]); } //团满 if ((($regimentInfo['people_number'] + 1) == $regimentActiveInfo['number']) && $regimentActiveInfo == 1) { $res = regiment::query()->where('id','=',$regimentId)->update(['status'=>3]); if( !$res ) { // 回退数据 DB::rollBack(); // 提示信息 return json_send(['code'=>'error','msg'=>'创建拼团失败','data'=>['error'=>'创建拼团失败']]); } //修改订单 $orderRes = $Model::query()->where('regiment_id','=',$regimentId)->update(['status'=>'1']); if( !$orderRes ) { // 回退数据 DB::rollBack(); // 提示信息 return json_send(['code'=>'error','msg'=>'创建拼团失败','data'=>['error'=>'创建拼团失败']]); } //赠送积分 $orderList = $Model::query()->where('regiment_id','=',$regimentId)->get(); foreach ($orderList as $key => $value) { if( $value['order_score'] > 0 ) $CustomScore->trade($orderInfo['custom_uid'],$value['id'],$value['order_score'],5,1); } } } //拼团记录 $regimentRecordInfo = [ 'custom_uid' => $uid, 'regiment_id' => $regimentId, 'active_id' => $regimentActiveInfo['id'], 'product_id' => $buyInfo['product_id'], 'order_id' => $orderId, 'update_time' => $time, 'insert_time' => $time, ]; $result = RegimentRecord::query()->insert($regimentRecordInfo); if( !$result ) { // 回退数据 DB::rollBack(); // 提示信息 return json_send(['code'=>'error','msg'=>'创建拼团记录失败','data'=>['error'=>'创建拼团记录失败']]); } // 提交数据 DB::commit(); // 返回结果 return json_send(['code'=>'success','msg'=>'下单成功','data'=>['id'=>null]]); // 返回结果 } catch (\Throwable $th) { // 回退数据 DB::rollBack(); // 判断结果,如果库存扣减失败的话 if( stripos($th->getMessage(),'UNSIGNED') ) return json_send(['code'=>'error','msg'=>'库存不足','data'=>['error'=>'产品库存扣减失败']]); // 下单失败提示 return json_send(['code'=>'error','msg'=>'系统异常,请稍后再试','data'=>['error'=>$th->getMessage().$th->getLine()]]); } } /** * 取消拼团 /api/orders/cancel_regiment * * */ public function cancel_regiment( Request $request, Model $Model,OrdersProduct $OrdersProduct,CustomScore $CustomScore){ // 验证参数 $request->scene('cancel')->validate(); // 检查登录 $uid = $this->checkLogin(); // 接收参数 $id = request('id',0); $status = 4; // 获取产品和数量 $oldData = $Model->query()->where([['id','=',$id],['custom_uid','=',$uid]])->first(['id','order_score','status','custom_uid','insert_time']); // 如果用户不存在 if( !$oldData ) return json_send(['code'=>'error','msg'=>'订单不存在']); // 如果已经取消 if( $oldData['status'] == 4 ) return json_send(['code'=>'error','msg'=>'订单已取消']); // 如果团不存在 if( !$oldData['regiment_id'] ) return json_send(['code'=>'error','msg'=>'拼团不存在']); // 组合数据,写入订单表,子表 DB::beginTransaction(); try{ // 查询数据 $result = $Model->setOrderStatus($id,$status,$OrdersProduct); // 提示新增失败 if( isset($result['error']) ) { // 回退数据 DB::rollBack(); // 提示信息 return json_send(['code'=>'error','msg'=>$result['error'],'data'=>['error'=>$result['error']]]); } //取消加入团 $regimentRes = Regiment::query()->where('id','=',$oldData['regiment_id'])->decrement('people_number',1); if( !$regimentRes ) { // 回退数据 DB::rollBack(); // 提示信息 return json_send(['code'=>'error','msg'=>'取消拼团失败']); } //修改拼团记录 $regimentRes = RegimentRecord::query()->where([['order_id','=',$oldData['id'],]])->update(['status'=>'2']); if( !$regimentRes ) { // 回退数据 DB::rollBack(); // 提示信息 return json_send(['code'=>'error','msg'=>'取消拼团失败']); } // 提交数据 DB::commit(); // 告知结果 return json_send(['code'=>'success','msg'=>'取消成功']); // 返回结果 } catch (\Throwable $th) { // 回退数据 DB::rollBack(); // 下单失败提示 return json_send(['code'=>'error','msg'=>'取消失败','data'=>['error'=>$th->getMessage().$th->getLine()]]); } } }