476 lines
20 KiB
PHP
476 lines
20 KiB
PHP
<?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' => '']);
|
||
}
|
||
|
||
} |