order-food-admin/app/Http/Controllers/Api/Miniprogram/OrderController.php

476 lines
20 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
namespace App\Http\Controllers\Api\Miniprogram;
use DB;
use Carbon\Carbon;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use App\Models\{Order,PayLog,ActivityUser,ReserveEditLog,ActivityOption,UserTicket,TicketGoodsValue,TicketCateValue};
use App\Http\Resources\{OrderResource, OrderInfoResource,UserTicketResource};
use App\Services\OrderService;
use App\Traits\WechatPay;
use App\Jobs\{PayOrderJob,PrintOrderJob};
class OrderController extends Controller
{
protected $order_service;
public function __construct(OrderService $order_service){
$this->order_service = $order_service;
}
/**
* 确认创建订单
* 购物车下单to_cart/直接兑换to_exchange
* 返回订单信息
*/
public function createOrder(Request $request){
$type = $request->input('type', 'to_cart');
$goods_info = $request->input('goods_info', '{}');//{"goods_id":1,"goods_attr":[1,2,3]}
$goods_info = json_decode($goods_info, true);
$user = auth('api')->user();
//检测是否绑定昵称头像
if(!$user->avatar || !$user->nick_name){
return $this->error('未绑定昵称头像', 501);
}
//检测是否绑定手机号
if(!$user->phone){
return $this->error('未绑定手机号', 502);
}
$order = false;
switch($type){
case 'to_cart':
$order = $this->order_service->createOrderToCart($user);
break;
case 'to_exchange':
$order = $this->order_service->createOrderToExchange($user, $goods_info);
break;
case 'to_reserve':
$reserve_data = [
'activity_id' => $request->input('activity_id', 0),
'reserve_time' => $request->input('reserve_time', ''),
'goods_num' => $request->input('goods_num', 0),
];
//判断时间是否有效当前时间后的7天内
$reserve_time = Carbon::parse($reserve_data['reserve_time'])->endOfDay();
if( empty($reserve_data['reserve_time']) ||
( $reserve_time < Carbon::now()->startOfDay() ||
$reserve_time > Carbon::now()->addDays(7)->endOfDay())
){
return $this->error('请选择有效的预约时间');
}
$order = $this->order_service->createOrderToReserve($user, $goods_info, $reserve_data);
break;
}
if(isset($order['status']) && $order['status'] == false){
return $this->error($order['message']);
}
return OrderInfoResource::make($order);
}
/**
* 支付订单
*/
public function payOrder(Request $request){
$user = auth('api')->user();
$order_sn = $request->input('order_sn', '');
$ticket_id = $request->input('ticket_id', 0);
//查看当前支付类型;
$order = Order::where([
'user_id'=>$user->id,
'order_sn'=>$order_sn,
'order_status'=>1,
'pay_status'=>0,
])->first();
if($order){
$pay_data = [];
switch($order->pay_type){
case 1://微信支付
/** 使用优惠券,更新订单结算信息 start **/
$update_order = false;
//如果是已经优惠的订单则不能使用优惠券
if($ticket_id > 0 && $order->ticket_value > 0 && $order->ticket_id ==0){
return $this->error('已享受其他满减优惠,无法再使用优惠券');
}
if($ticket_id > 0 && $ticket_id!=$order->ticket_id){
$now_time = Carbon::now();
$user_ticket = UserTicket::with('quanTicket')->where([
'user_id'=>$user->id,
'id'=>$ticket_id,
'ticket_status'=>0,
])->where('start_time', '<', $now_time)->where('end_time', '>', $now_time)->first();
if($user_ticket){
try {
DB::beginTransaction();
$old_ticket = $order->ticket_id;
$old_pay_price = $order->pay_price;
$order->ticket_id = $user_ticket->id;
$order->ticket_value = $user_ticket->quanTicket->ticket_value;
$order->pay_price = number_format((intval($order->order_price*100) - intval($order->ticket_value*100))/100, 2);
if($order->pay_price <= 0 || env('APP_ENV', 'local') == 'local'){
$order->pay_price = 0.01;
}
//处理商品优惠
$goods_list = $order->goods;
$goods_ids = $cate_ids = [];
foreach($goods_list as $goods){
//整理商品数量
$goods_ids[] = $goods->goods_id;
$cate_ids[] = $goods->goods->category_id;
}
$num = $times = 0;
$order_goods_ids = [];
if($user_ticket->quanTicket->the_type == 1){//指定商品
$a_goods_ids = TicketGoodsValue::where('quan_id', $user_ticket->quanTicket->id)->whereIn('goods_id', $goods_ids)->pluck('goods_id')->toArray();
foreach($goods_list as $goods){
if(in_array($goods->goods_id, $a_goods_ids)){
$num+= $goods->goods_num;
$times++;
$order_goods_ids[] = $goods->id;
}
}
}elseif($user_ticket->quanTicket->the_type == 2){//指定分类
$a_cate_ids = TicketCateValue::where('quan_id', $user_ticket->quanTicket->id)->whereIn('category_id', $cate_ids)->pluck('category_id')->toArray();
foreach($goods_list as $goods){
if(in_array($goods->goods->category_id, $a_cate_ids)){
$num+= $goods->goods_num;
$times++;
$order_goods_ids[] = $goods->id;
}
}
}else{
foreach($goods_list as $goods){
$num+= $goods->goods_num;
$times++;
$order_goods_ids[] = $goods->id;
}
}
$one_price = number_format((intval($user_ticket->quanTicket->ticket_value*100)/$num)/100, 2);
$i = 1;
foreach ($order->goods as $key =>$goods){
if(in_array($goods->id, $order_goods_ids)){
if($times == $i){
$order->goods[$key]->special_value = number_format((intval($user_ticket->quanTicket->ticket_value*100)-intval($one_price*100)*($num-$goods->goods_num))/100, 2);
}else{
$order->goods[$key]->special_value = number_format(intval($one_price*100)*$goods->goods_num/100, 2);
}
$order->goods[$key]->ticket_id = $user_ticket->id;
$i++;
}else{
$order->goods[$key]->special_value = 0;
$order->goods[$key]->ticket_id = 0;
}
}
$user_ticket->ticket_status = 1;
$user_ticket->save();
//检查历史支付的金额和本次支付金额是否一致不一致生成新的订单号以及paylog
if($old_pay_price!=$order->pay_price ){
$order->order_sn = $this->order_service->createOrderSn($user->id);
//插入支付记录
PayLog::create([
'type' => $order->pay_type,
'order_sn' => $order->order_sn,
'status' => 0,
]);
$update_order = true;
}
$order->push();
if($old_ticket){
UserTicket::where('id', $old_ticket)->update(['ticket_status'=>0]);
}
DB::commit();
} catch (\Throwable $th) {
DB::rollback();
return $this->error($th->getMessage());
}
}else{
return $this->error('优惠券不能使用');
}
}
/** 使用优惠券,更新订单结算信息 end **/
$wechat_pay = new WechatPay();
if($update_order){//若更新订单号,则需要重新创建预付单
$res = $wechat_pay->createOrder($order);
if($res['return_code'] == 'SUCCESS'){
//记录perpay_id;
PayLog::where(['order_sn'=>$order->order_sn, 'status'=>0])->update(['pay_ext'=>$res['prepay_id']]);
$prepay_id = $res['prepay_id'];
}else{
return $this->error($res['return_msg']);
}
}else{
$pay_log = PayLog::where(['order_sn'=>$order->order_sn,'status'=>0])->first();
$prepay_id = $pay_log->pay_ext;
}
$pay_data = $wechat_pay->createPayConfig($prepay_id);
$pay_data['order_sn'] = $order->order_sn;
break;
case 2://兑换
//扣除对应奖品;
$pay_log = PayLog::where([
'order_sn'=>$order->order_sn,
'status'=>0
])->first();
foreach(json_decode($pay_log->pay_ext) as $award_id){
$key = 'award_'.$award_id;
$user->activity->decrement($key);
}
//支付订单;
PayOrderJob::dispatch($order);
break;
}
return $this->success($pay_data, '支付成功');
}else{
return $this->error('订单不存在');
}
}
/**
* 订单列表
*/
public function orderList(Request $request){
$user = auth('api')->user();
$per_page = $request->input('per_page', 10);
$query = Order::with('goods')->where([
'user_id'=>$user->id,
'order_status'=>1
]);
$order_type = $request->input('order_type', 'all');
switch($order_type){
case 'wait_pay':
//获取待支付
$query->where([
'pay_status'=>0,
'shipping_status'=>0,
]);
break;
case 'wait_pickup':
//获取待取餐
$query->where([
'pay_status'=>1,
'shipping_status'=>0,
]);
break;
case 'finish':
//获取已完成
$query->where([
'pay_status'=>1,
'shipping_status'=>1,
]);
break;
}
$list = $query->orderBy('created_at', 'desc')->paginate($per_page);
return OrderResource::collection($list)->additional(['code' => Response::HTTP_OK, 'message' => '']);
}
/**
* 订单详情
*/
public function orderInfo($order_sn){
$user = auth('api')->user();
$order = Order::where([
'user_id' => $user->id,
'order_sn' => $order_sn,
'order_status'=> 1
])->first();
if($order){
return OrderInfoResource::make($order);
}else{
return $this->error('订单不存在', 404);
}
}
/**
* 预约订单修改时间
*/
public function editReserveTime($order_sn, Request $request){
$user = auth('api')->user();
$order = Order::where([
'user_id' => $user->id,
'order_sn' => $order_sn,
'order_status'=> 1,
'pay_status'=> 1,
'is_reserve'=> 1
])->first();
if(!$order){
return $this->error('订单不存在', 404);
}
//检查是否已经生成取餐码
if($order->order_number){
return $this->error('已生成取餐码,无法修改预约时间');
}
//修改时间是否已经改过一次
if(ReserveEditLog::where('order_sn', $order_sn)->exists()){
return $this->error('您已修改过预约时间,无法再次修改');
}
//当前时间是否在有效时间范围内上次预约时间的14天内
if(Carbon::now() > Carbon::parse($order->reserve_time)->addDays(14)->endOfDay()){
return $this->error('订单已过期,无法修改');
}
//修改的时间是否在有效的时间范围内
$reserve_time = $request->input('reserve_time', '');
if(empty($reserve_time) ||
( Carbon::parse($reserve_time)->endOfDay() < Carbon::now()->startOfDay() ||
Carbon::parse($reserve_time)->endOfDay() > Carbon::now()->addDays(7)->endOfDay())){
return $this->error('请选择有效的预约时间');
}
if(Carbon::parse($reserve_time)->startOfDay() == $order->reserve_time){
return $this->error('与当前预约时间一致,无需修改');
}
$old_reserve_time = $order->reserve_time;
try {
DB::beginTransaction();
$order->reserve_time = $reserve_time;
$order->save();
ReserveEditLog::create([
'order_sn' => $order->order_sn,
'old_reserve_time' => $old_reserve_time,
'to_reserve_time' => $order->reserve_time,
]);
DB::commit();
} catch (\Throwable $th) {
DB::rollback();
return $this->error($th->getMessage());
}
return $this->success('修改成功');
}
/**
* 生成预约单取餐码
*/
public function reserveCreateOrderNumber($order_sn){
$user = auth('api')->user();
$order = Order::where([
'user_id' => $user->id,
'order_sn' => $order_sn,
'order_status'=> 1,
'pay_status'=> 1,
'is_reserve'=> 1
])->first();
if(!$order){
return $this->error('订单不存在', 404);
}
//检查是否已经生成取餐码
if($order->order_number){
return $this->error('已生成取餐码,无法再次生成');
}
//检测是否当天
if($order->reserve_time > Carbon::now()->startOfDay()){
return $this->error('未到预约时间');
}
//
if($order->shipping_status == 1){
return $this->error('已过期');
}
if($order->reserve_time < Carbon::now()->startOfDay()){
return $this->error('已超过预约时间,请修改预约时间');
}
$order->order_number = $this->order_service->createOrderNumber();
//处理订单吹牛逻辑,是否幸运号
$luck_number = ActivityOption::findOrFail(11)->key_value;
$luck_number = explode(',', $luck_number);
if(in_array($order->order_number, $luck_number)){
$order->is_niu = 1;
}
$order->number_time = now();
$order->save();
$this->order_service->insertBigScreenNumber($order->order_number);
if(env('APP_ENV', 'local') == 'production'){
//打印订单
PrintOrderJob::dispatch($order);
}
return OrderInfoResource::make($order);
}
public function cancelOrder($order_sn){
$user = auth('api')->user();
$order = Order::where([
'user_id' => $user->id,
'order_sn' => $order_sn,
'order_status'=> 1,
'pay_status'=> 0,
])->first();
if(!$order){
return $this->error('订单不存在', 404);
}
if($this->order_service->cancleOrder($order)){
return $this->success('取消成功');
}else{
return $this->error('取消失败');
}
}
/**
* 获取可用优惠券
*/
public function getUserTicket($order_sn){
$user = auth('api')->user();
$order = Order::with(['goods'])->where([
'user_id' => $user->id,
'order_sn' => $order_sn,
'order_status'=> 1,
'pay_status'=> 0,
])->first();
if(!$order){
return $this->error('订单不存在', 404);
}
//获取用户的有效优惠券
$user_tickets = UserTicket::with('quanTicket')->where([
'user_id'=>$user->id,
])->where('ticket_status', 0)->where('start_time', '<', Carbon::now())->where('end_time', '>', Carbon::now())->get();
$quan_ids = $user_tickets->pluck('quan_id');
//获取订单商品;
$goods_list = $order->goods;
//遍历商品获取商品和分类ID
$goods_ids = $cate_ids = [];
foreach ($goods_list as $goods){
$goods_ids[] = $goods->goods_id;
$cate_ids[] = $goods->goods->category_id;
}
$goods_quan_ids = TicketGoodsValue::whereIn('quan_id', $quan_ids)->whereIn('goods_id', array_unique($goods_ids))->pluck('quan_id')->toArray();
$cate_quan_ids = TicketCateValue::whereIn('quan_id', $quan_ids)->whereIn('category_id', array_unique($cate_ids))->pluck('quan_id')->toArray();
//合并数组,并去重
$can_quan_ids = array_unique(array_merge($goods_quan_ids, $cate_quan_ids));
//比较价格,筛选可用优惠券
// dd($can_quan_ids);
foreach ($user_tickets as $key => $ticket){
if($ticket->quanTicket->the_type!=0 && !in_array($ticket->quan_id, $can_quan_ids)){
unset($user_tickets[$key]);
}else{
if($ticket->quanTicket->use_limit > $order->order_price){
unset($user_tickets[$key]);
}
}
}
return UserTicketResource::collection($user_tickets)->additional(['code' => Response::HTTP_OK, 'message' => '']);
}
}