文件
mashangyoujiu/Application/Api/Controller/RiderOrderController.class.php

499 行
16 KiB
PHP

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

<?php
namespace Api\Controller;
use Api\Controller\BaseController;
use Common\Business\RiderOrderDispatch;
/**
* 骑手端订单API控制器
* Class RiderOrderController
* @package Api\Controller
*/
class RiderOrderController extends BaseController
{
/**
* 获取骑手订单列表
* @return void
*/
public function getOrderList()
{
$param = I('post.');
// 验证骑手身份
$riderInfo = $this->checkRiderAuth();
if ($riderInfo['status'] != 1) {
$this->ajaxReturn($riderInfo);
}
$riderId = $riderInfo['data']['id'];
// 设置默认参数
$page = isset($param['page']) ? intval($param['page']) : 1;
$pageSize = isset($param['page_size']) ? intval($param['page_size']) : 20;
$orderStatus = isset($param['order_status']) ? $param['order_status'] : '';
$riderOrderModel = D('RiderOrder');
// 构建查询条件
$where = ['rider_id' => $riderId];
if ($orderStatus !== '') {
$where['order_status'] = $orderStatus;
}
// 获取订单列表
$orders = $riderOrderModel->getOrderList($where, $page, $pageSize);
$this->ajaxReturn(callBack(statusCode()['success'], '获取订单列表成功', $orders));
}
/**
* 接受订单
* @return void
*/
public function acceptOrder()
{
$param = I('post.');
// 验证骑手身份
$riderInfo = $this->checkRiderAuth();
if ($riderInfo['status'] != 1) {
$this->ajaxReturn($riderInfo);
}
$riderId = $riderInfo['data']['id'];
if (empty($param['rider_order_id'])) {
$this->ajaxReturn(callBack(statusCode()['error'], '订单ID不能为空'));
}
$riderOrderModel = D('RiderOrder');
// 获取订单信息
$orderInfo = $riderOrderModel->getFind(['id' => $param['rider_order_id'], 'rider_id' => $riderId]);
if (empty($orderInfo)) {
$this->ajaxReturn(callBack(statusCode()['error'], '订单不存在'));
}
// 检查订单状态
if ($orderInfo['order_status'] != 0) {
$this->ajaxReturn(callBack(statusCode()['error'], '订单状态不允许接受'));
}
// 检查骑手当前订单数量
import('@.Common.Business.OrderStatusUtil');
$inProgress = \Common\Business\OrderStatusUtil::getInProgressStatuses();
$currentOrders = $riderOrderModel->getCount([
'rider_id' => $riderId,
'order_status' => ['in', implode(',', $inProgress)]
]);
$riderInfoModel = D('RiderInfo');
$rider = $riderInfoModel->getFind(['id' => $riderId]);
if ($currentOrders >= $rider['max_orders_per_time']) {
$this->ajaxReturn(callBack(statusCode()['error'], '当前订单数量已达上限'));
}
// 更新订单状态为已接单
$updateData = [
'order_status' => 1,
'accept_time' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s')
];
$result = $riderOrderModel->updateOrder(['id' => $param['rider_order_id']], $updateData);
if ($result) {
// 同步更新原订单状态
$this->syncOrderStatus($orderInfo['bill_id'], 'accepted');
$this->ajaxReturn(callBack(statusCode()['success'], '接受订单成功'));
} else {
$this->ajaxReturn(callBack(statusCode()['error'], '接受订单失败'));
}
}
/**
* 拒绝订单
* @return void
*/
public function rejectOrder()
{
$param = I('post.');
// 验证骑手身份
$riderInfo = $this->checkRiderAuth();
if ($riderInfo['status'] != 1) {
$this->ajaxReturn($riderInfo);
}
$riderId = $riderInfo['data']['id'];
if (empty($param['rider_order_id'])) {
$this->ajaxReturn(callBack(statusCode()['error'], '订单ID不能为空'));
}
$riderOrderModel = D('RiderOrder');
// 获取订单信息
$orderInfo = $riderOrderModel->getFind(['id' => $param['rider_order_id'], 'rider_id' => $riderId]);
if (empty($orderInfo)) {
$this->ajaxReturn(callBack(statusCode()['error'], '订单不存在'));
}
// 检查订单状态
if ($orderInfo['order_status'] != 0) {
$this->ajaxReturn(callBack(statusCode()['error'], '订单状态不允许拒绝'));
}
// 更新订单状态为已拒绝
$updateData = [
'order_status' => -1,
'reject_time' => date('Y-m-d H:i:s'),
'reject_reason' => $param['reject_reason'] ?? '骑手拒绝接单',
'updated_at' => date('Y-m-d H:i:s')
];
$result = $riderOrderModel->updateOrder(['id' => $param['rider_order_id']], $updateData);
if ($result) {
// 重新分配订单
$this->reassignOrder($orderInfo['bill_id'], $riderId);
$this->ajaxReturn(callBack(statusCode()['success'], '拒绝订单成功'));
} else {
$this->ajaxReturn(callBack(statusCode()['error'], '拒绝订单失败'));
}
}
/**
* 开始配送
* @return void
*/
public function startDelivery()
{
$param = I('post.');
// 验证骑手身份
$riderInfo = $this->checkRiderAuth();
if ($riderInfo['status'] != 1) {
$this->ajaxReturn($riderInfo);
}
$riderId = $riderInfo['data']['id'];
if (empty($param['rider_order_id'])) {
$this->ajaxReturn(callBack(statusCode()['error'], '订单ID不能为空'));
}
$riderOrderModel = D('RiderOrder');
// 获取订单信息
$orderInfo = $riderOrderModel->getFind(['id' => $param['rider_order_id'], 'rider_id' => $riderId]);
if (empty($orderInfo)) {
$this->ajaxReturn(callBack(statusCode()['error'], '订单不存在'));
}
// 检查订单状态
if ($orderInfo['order_status'] != 2) {
$this->ajaxReturn(callBack(statusCode()['error'], '订单状态不允许开始配送'));
}
// 更新订单状态为配送中
$updateData = [
'order_status' => 3,
'delivery_start_time' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s')
];
$result = $riderOrderModel->updateOrder(['id' => $param['rider_order_id']], $updateData);
if ($result) {
// 同步更新原订单状态
$this->syncOrderStatus($orderInfo['bill_id'], 'delivering');
$this->ajaxReturn(callBack(statusCode()['success'], '开始配送成功'));
} else {
$this->ajaxReturn(callBack(statusCode()['error'], '开始配送失败'));
}
}
/**
* 完成配送
* @return void
*/
public function completeDelivery()
{
$param = I('post.');
// 验证骑手身份
$riderInfo = $this->checkRiderAuth();
if ($riderInfo['status'] != 1) {
$this->ajaxReturn($riderInfo);
}
$riderId = $riderInfo['data']['id'];
if (empty($param['rider_order_id'])) {
$this->ajaxReturn(callBack(statusCode()['error'], '订单ID不能为空'));
}
$riderOrderModel = D('RiderOrder');
// 获取订单信息
$orderInfo = $riderOrderModel->getFind(['id' => $param['rider_order_id'], 'rider_id' => $riderId]);
if (empty($orderInfo)) {
$this->ajaxReturn(callBack(statusCode()['error'], '订单不存在'));
}
// 检查订单状态:必须处于配送中(5)才允许完成
if ($orderInfo['order_status'] != 5) {
$this->ajaxReturn(callBack(statusCode()['error'], '订单状态不允许完成配送'));
}
// 更新订单状态为已送达(6)
$updateData = [
'order_status' => 6,
'delivery_time' => date('Y-m-d H:i:s'),
'delivery_proof' => $param['delivery_proof'] ?? '', // 配送凭证
'updated_at' => date('Y-m-d H:i:s')
];
$result = $riderOrderModel->updateOrder(['id' => $param['rider_order_id']], $updateData);
if ($result) {
// 同步更新原订单状态
$this->syncOrderStatus($orderInfo['bill_id'], 'completed');
// 更新骑手统计信息
$this->updateRiderStats($riderId, array_merge($orderInfo, ['delivery_time' => $updateData['delivery_time']]));
$this->ajaxReturn(callBack(statusCode()['success'], '完成配送成功'));
} else {
$this->ajaxReturn(callBack(statusCode()['error'], '完成配送失败'));
}
}
/**
* 更新骑手位置
* @return void
*/
public function updateLocation()
{
$param = I('post.');
// 验证骑手身份
$riderInfo = $this->checkRiderAuth();
if ($riderInfo['status'] != 1) {
$this->ajaxReturn($riderInfo);
}
$riderId = $riderInfo['data']['id'];
if (empty($param['lat']) || empty($param['lng'])) {
$this->ajaxReturn(callBack(statusCode()['error'], '位置信息不能为空'));
}
$riderInfoModel = D('RiderInfo');
// 更新骑手位置
$updateData = [
'last_location_lat' => $param['lat'],
'last_location_lng' => $param['lng'],
'last_location_time' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s')
];
$result = $riderInfoModel->updateRider(['id' => $riderId], $updateData);
if ($result) {
// 记录位置轨迹
$this->recordLocationTrack($riderId, $param['lat'], $param['lng']);
$this->ajaxReturn(callBack(statusCode()['success'], '位置更新成功'));
} else {
$this->ajaxReturn(callBack(statusCode()['error'], '位置更新失败'));
}
}
/**
* 获取订单详情
* @return void
*/
public function getOrderDetail()
{
$param = I('post.');
// 验证骑手身份
$riderInfo = $this->checkRiderAuth();
if ($riderInfo['status'] != 1) {
$this->ajaxReturn($riderInfo);
}
$riderId = $riderInfo['data']['id'];
if (empty($param['rider_order_id'])) {
$this->ajaxReturn(callBack(statusCode()['error'], '订单ID不能为空'));
}
$riderOrderModel = D('RiderOrder');
// 获取订单详情
$orderDetail = $riderOrderModel->getOrderDetail($param['rider_order_id'], $riderId);
if (empty($orderDetail)) {
$this->ajaxReturn(callBack(statusCode()['error'], '订单不存在'));
}
$this->ajaxReturn(callBack(statusCode()['success'], '获取订单详情成功', $orderDetail));
}
/**
* 验证骑手身份
* @return array
*/
private function checkRiderAuth()
{
$token = I('post.token', '');
if (empty($token)) {
return callBack(statusCode()['error'], '请先登录');
}
$riderTokenModel = D('RiderToken');
$tokenInfo = $riderTokenModel->getFind(['token' => $token]);
if (empty($tokenInfo)) {
return callBack(statusCode()['error'], '登录已过期,请重新登录');
}
// 检查token是否过期
if (strtotime($tokenInfo['expire_time']) < time()) {
return callBack(statusCode()['error'], '登录已过期,请重新登录');
}
// 获取骑手信息
$riderInfoModel = D('RiderInfo');
$riderInfo = $riderInfoModel->getFind(['id' => $tokenInfo['rider_id']]);
if (empty($riderInfo)) {
return callBack(statusCode()['error'], '骑手信息不存在');
}
if ($riderInfo['status'] != 1) {
return callBack(statusCode()['error'], '账号已被禁用');
}
return callBack(statusCode()['success'], '验证成功', $riderInfo);
}
/**
* 同步订单状态到原系统
* @param int $billId 原订单ID
* @param string $action 操作类型
* @return void
*/
private function syncOrderStatus($billId, $action)
{
$billOnlineModel = D('RetailBillOnline');
switch ($action) {
case 'accepted':
// 骑手接单,更新为已发货状态
$billOnlineModel->updateBill(['bill_id' => $billId], [
'status' => 2, // 已发货
'delivery_type' => 1, // 门店自己配送
'updated_at' => date('Y-m-d H:i:s')
]);
break;
case 'delivering':
// 开始配送,保持已发货状态
break;
case 'completed':
// 配送完成,更新为已收货状态
$billOnlineModel->updateBill(['bill_id' => $billId], [
'status' => 3, // 已收货
'updated_at' => date('Y-m-d H:i:s')
]);
break;
}
}
/**
* 重新分配订单
* @param int $billId 原订单ID
* @param int $excludeRiderId 排除的骑手ID
* @return void
*/
private function reassignOrder($billId, $excludeRiderId)
{
// 这里可以实现重新分配逻辑
// 比如分配给其他可用骑手,或者标记为待分配状态
$riderOrderDispatch = new RiderOrderDispatch();
// 获取订单信息
$billOrderModel = D('RetailBillOrder');
$orderInfo = $billOrderModel->getFind(['id' => $billId]);
if (!empty($orderInfo)) {
// 尝试自动重新分配
$param = [
'bill_id' => $billId,
'merchant_id' => $orderInfo['merchant_id'],
'store_id' => $orderInfo['store_id'],
'auto_assign' => true,
'exclude_rider_id' => $excludeRiderId
];
$riderOrderDispatch->dispatchOrder($param);
}
}
/**
* 记录位置轨迹
* @param int $riderId 骑手ID
* @param float $lat 纬度
* @param float $lng 经度
* @return void
*/
private function recordLocationTrack($riderId, $lat, $lng)
{
$riderLocationModel = D('RiderLocation');
$locationData = [
'rider_id' => $riderId,
'lat' => $lat,
'lng' => $lng,
'record_time' => date('Y-m-d H:i:s'),
'add_time' => date('Y-m-d H:i:s')
];
$riderLocationModel->addLocation($locationData);
}
/**
* 更新骑手统计信息
* @param int $riderId 骑手ID
* @param array $orderInfo 订单信息
* @return void
*/
private function updateRiderStats($riderId, $orderInfo)
{
$riderInfoModel = D('RiderInfo');
// 计算配送时长
$deliveryDuration = 0;
if (!empty($orderInfo['accept_time']) && !empty($orderInfo['delivery_time'])) {
$deliveryDuration = strtotime($orderInfo['delivery_time']) - strtotime($orderInfo['accept_time']);
}
// 更新统计信息
$riderInfoModel->updateStats($riderId, [
'total_orders' => 1,
'total_delivery_time' => $deliveryDuration,
'total_delivery_fee' => $orderInfo['delivery_fee']
]);
}
}