You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
aquaculture/app/Http/Controllers/User/OrderController.php

354 lines
14 KiB

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\User; // 定义命名空间
use App\Admin\Transforms\OrderShipStatusTransform; // 引入订单发货状态转换类
use App\Admin\Transforms\OrderStatusTransform; // 引入订单状态转换类
use App\Enums\OrderShipStatusEnum; // 引入订单发货状态枚举
use App\Enums\OrderStatusEnum; // 引入订单状态枚举
use App\Enums\ScoreRuleIndexEnum; // 引入积分规则索引枚举
use App\Http\Controllers\Controller; // 引入基础控制器类
use App\Models\Address; // 引入地址模型
use App\Models\Comment; // 引入评论模型
use App\Models\Order; // 引入订单模型
use App\Models\OrderDetail; // 引入订单详情模型
use App\Models\ScoreRule; // 引入积分规则模型
use App\Models\User; // 引入用户模型
use App\Services\OrderStatusButtonServe; // 引入订单状态按钮服务类
use App\Services\ScoreLogServe; // 引入积分日志服务类
use Illuminate\Http\Request; // 引入请求类
use Illuminate\Support\Facades\DB; // 引入数据库门面
use Yansongda\Pay\Pay; // 引入支付类
/**
* 用户订单控制器
*
* 该控制器处理用户的订单相关操作,包括订单列表展示、订单详情、完成订单、确认收货等功能。
*/
class OrderController extends Controller
{
/**
* 显示用户的订单列表
*
* @return \Illuminate\View\View
*/
public function index()
{
// 获取积分比例
$scoreRatio = $this->getScoreRatio();
/**
* @var $user User
*/
$user = auth()->user(); // 获取当前用户
$query = $user->orders(); // 获取用户的订单查询构建器
// 根据请求的 tab 参数筛选订单状态
switch (request('tab', 0)) {
case 0:
break; // 默认显示所有订单
case 1:
// 待付款
$query->where('status', OrderStatusEnum::UN_PAY);
break;
case 2:
// 未发货
$query->where('status', OrderStatusEnum::PAID)
->where('ship_status', OrderShipStatusEnum::PENDING);
break;
case 3:
// 待收货
$query->where('status', OrderStatusEnum::PAID)
->where('ship_status', OrderShipStatusEnum::DELIVERED);
break;
case 4:
// 待评价
$query->where('status', OrderStatusEnum::PAID)
->where('ship_status', OrderShipStatusEnum::RECEIVED);
break;
}
// 获取订单列表并进行处理
$orders = $query->latest() // 按照创建时间降序排列
->with('details', 'details.product') // 预加载订单详情和产品
->get()
->map(
function (Order $order) use ($scoreRatio) {
// 计算可以获得的积分
$order->score = ceil($order->amount * $scoreRatio);
// 设置订单状态文本
$order->status_text = OrderStatusTransform::trans($order->status);
// 如果订单已付款,则显示发货状态
if ($order->status == OrderStatusEnum::PAID) {
// 如果已发货,则显示发货信息
$order->status_text = OrderShipStatusTransform::trans($order->ship_status);
}
// 创建订单状态按钮服务实例
$buttonServe = new OrderStatusButtonServe($order);
switch ($order->status) {
// 未支付的订单
case OrderStatusEnum::UN_PAY:
$buttonServe->payButton()->cancelOrderButton(); // 添加支付和取消订单按钮
break;
case OrderStatusEnum::PAID:
// 已确认收货
if ($order->ship_status == OrderShipStatusEnum::RECEIVED) {
$buttonServe->completeButton(); // 添加完成按钮
} elseif ($order->ship_status == OrderShipStatusEnum::DELIVERED) {
$buttonServe->shipButton(); // 添加发货按钮
} else {
$buttonServe->refundButton(); // 添加退款按钮
}
break;
// 手动取消的订单、已完成的订单、超时取消的订单
case OrderStatusEnum::UN_PAY_CANCEL:
case OrderStatusEnum::COMPLETED:
case OrderStatusEnum::TIMEOUT_CANCEL:
$buttonServe->replyBuyButton()->deleteButton(); // 添加重新购买和删除按钮
break;
}
// 获取按钮集合
$order->buttons = $buttonServe->getButtons();
return $order; // 返回处理后的订单
}
);
// 查询不同状态的订单数量
$unPayCount = $user->orders()->where('status', OrderStatusEnum::UN_PAY)->count();
$shipPendingCount = $user->orders()->where('status', OrderStatusEnum::PAID)->where('ship_status', OrderShipStatusEnum::PENDING)->count();
$shipDeliveredCount = $user->orders()->where('status', OrderStatusEnum::PAID)->where('ship_status', OrderShipStatusEnum::DELIVERED)->count();
$shipReceivedCount = $user->orders()->where('status', OrderStatusEnum::PAID)->where('ship_status', OrderShipStatusEnum::RECEIVED)->count();
$ordersCount = $user->orders()->count(); // 获取订单总数
// 返回订单列表视图
return view('user.orders.index', compact('orders', 'unPayCount', 'shipPendingCount', 'shipDeliveredCount', 'shipReceivedCount', 'ordersCount'));
}
/**
* 显示指定订单的详细信息
*
* @param Order $order
* @return \Illuminate\View\View|\Illuminate\Http\Response
*/
public function show(Order $order)
{
// 检查当前用户是否有权限查看该订单
if ($order->isNotUser(auth()->id())) {
abort(403, '你没有权限'); // 返回403错误
}
// 设置发货和确认收货状态
$order->ship_send = $order->ship_status == OrderShipStatusEnum::DELIVERED;
$order->confirm_ship = $order->ship_status == OrderShipStatusEnum::RECEIVED;
// 如果已确认收货,标记为已发货
if ($order->confirm_ship) {
$order->ship_send = true;
}
// 设置订单是否已完成
$order->completed = $order->status == OrderStatusEnum::RECEIVED;
// 返回订单详情视图
return view('user.orders.show', compact('order'));
}
/**
* 完成订单并添加评论
*
* @param Order $order
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function completeOrder(Order $order, Request $request)
{
// 获取评分和评论内容
$star = intval($request->input('star'));
$content = $request->input('content');
// 验证评分范围
if ($star < 0 || $star > 5) {
return responseJsonAsBadRequest('无效的评分'); // 返回错误响应
}
// 验证评论内容
if (empty($content)) {
return responseJsonAsBadRequest('请至少写一些内容吧'); // 返回错误响应
}
// 检查当前用户是否有权限完成该订单
$user = auth()->user();
if ($order->isNotUser($user->id)) {
return responseJsonAsBadRequest('你没有权限'); // 返回错误响应
}
// 只有已付款且确认收货的订单才能完成
if (!($order->status == OrderStatusEnum::PAID && $order->ship_status == OrderShipStatusEnum::RECEIVED)) {
return responseJsonAsBadRequest('订单当前状态不能完成'); // 返回错误响应
}
// 获取订单详情
$orderDetails = $order->details()->get();
// 构建评论数据
$comments = $orderDetails->map(function (OrderDetail $orderDetail) use ($user, $content, $star) {
return [
'order_id' => $orderDetail->order_id,
'order_detail_id' => $orderDetail->id,
'product_id' => $orderDetail->product_id,
'user_id' => $user->id,
'score' => $star,
'content' => $content,
];
});
DB::beginTransaction(); // 开始数据库事务
try {
// 更新订单状态为完成
$order->status = OrderStatusEnum::COMPLETED;
$order->save();
// 保存评论内容
Comment::query()->insert($comments->all());
// 更新订单详情为已评论
OrderDetail::query()->where('order_id', $order->id)->update(['is_commented' => true]);
// 完成订单增加积分
(new ScoreLogServe)->completeOrderAddScore($order);
DB::commit(); // 提交事务
} catch (\Exception $e) {
DB::rollBack(); // 回滚事务
return responseJsonAsServerError('服务器异常,请稍后再试'); // 返回错误响应
}
return responseJson(200, '完成订单已增加积分'); // 返回成功响应
}
/**
* 确认收货
*
* @param Order $order
* @return \Illuminate\Http\RedirectResponse
*/
public function confirmShip(Order $order)
{
// 检查当前用户是否有权限确认收货
if ($order->isNotUser(auth()->id())) {
abort(403, '你没有权限'); // 返回403错误
}
// 验证订单状态
if ($order->status != OrderStatusEnum::PAID) {
return back()->withErrors('订单未付款'); // 返回错误
}
if ($order->ship_status != OrderShipStatusEnum::DELIVERED) {
return back()->withErrors('订单未发货'); // 返回错误
}
// 更新订单发货状态为已收货
$order->ship_status = OrderShipStatusEnum::RECEIVED;
$order->save();
return back()->with('status', '收货成功'); // 返回成功消息
}
/**
* 取消订单
*
* @param Order $order
* @return \Illuminate\Http\RedirectResponse
*/
public function cancelOrder(Order $order)
{
// 检查当前用户是否有权限取消订单
if ($order->isNotUser(auth()->id())) {
abort(403, '你没有权限'); // 返回403错误
}
// 验证订单状态
if ($order->status != OrderStatusEnum::UN_PAY) {
return back()->withErrors('未付款的订单才能取消'); // 返回错误
}
$pay = Pay::alipay(config('pay.ali')); // 获取支付宝支付实例
try {
// 取消订单
$orderData = [
'out_trade_no' => $order->no,
];
$result = $pay->cancel($orderData); // 调用支付取消接口
// 更新订单状态为未支付取消
$order->status = OrderStatusEnum::UN_PAY_CANCEL;
$order->save();
} catch (\Exception $e) {
return back()->withErrors('服务器异常,请稍后再试'); // 返回错误
}
return back()->with('status', '取消成功'); // 返回成功消息
}
/**
* 获取积分和钱的换比例
*
* @return mixed
*/
protected function getScoreRatio()
{
// 查询积分规则
$scoreRule = ScoreRule::query()->where('index_code', ScoreRuleIndexEnum::COMPLETE_ORDER)->firstOrFail();
return $scoreRule->score ?? 1; // 返回积分比例默认为1
}
/**
* 检查地址是否存在
*
* @param $address
* @return bool
*/
protected function hasAddress($address)
{
// 查询用户是否拥有该地址
return Address::query()
->where('user_id', auth()->id())
->where('id', $address)
->exists();
}
/**
* 删除订单
*
* @param int $id 订单 ID
* @return \Illuminate\Http\RedirectResponse
*/
public function destroy($id)
{
/**
* @var $order Order
*/
$order = Order::query()->findOrFail($id); // 查找订单
// 检查当前用户是否有权限删除该订单
if ($order->isNotUser(auth()->id())) {
abort(403, '你没有权限'); // 返回403错误
}
// 检查订单状态,支付的订单不能删除
if (!in_array($order->status, [OrderStatusEnum::UN_PAY_CANCEL, OrderStatusEnum::TIMEOUT_CANCEL, OrderStatusEnum::COMPLETED])) {
abort(403, '订单不能删除'); // 返回403错误
}
$order->delete(); // 删除订单
return back()->with('status', '删除成功'); // 返回成功消息
}
}