文件
mashangyoujiu/Application/Retail/Controller/RiderController.class.php

1683 行
57 KiB
PHP

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

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

<?php
namespace Retail\Controller;
use Retail\Model\RiderModel;
use Common\Model\ImageGalleryModel;
//[1.8.50]
/**
* 骑手管理控制器
* Class RiderController
* @package Retail\Controller
*/
class RiderController extends BaseController
{
/**
* 骑手管理主页
*/
public function index()
{
$this->display();
}
/**
* 骑手编辑页面
*/
public function edit()
{
$id = I('get.id', 0, 'intval');
if ($id) {
$this->assign('rider_id', $id);
}
$this->display();
}
/**
* 骑手详情页面
*/
public function detail()
{
$id = I('get.id', 0, 'intval');
if ($id) {
$this->assign('rider_id', $id);
}
$this->display();
}
public function getStatistics()
{
try {
$Rider = M('RiderInfo');
$Order = M('retail_pay_order'); // 修改为正确的订单表名
// 总骑手数
$totalRiders = $Rider->where(array('status' => 1))->count();
// 在线骑手数
$onlineRiders = $Rider->where(array('work_status' => 1, 'status' => 1))->count();
// 今日订单数 - 使用支付订单表统计
$today = date('Y-m-d');
$todayStart = strtotime($today . ' 00:00:00');
$todayEnd = strtotime($today . ' 23:59:59');
$todayOrders = $Order->where(array(
'add_time' => array('BETWEEN', array($todayStart, $todayEnd)),
'order_state' => 'SUCCESS'
))->count();
// 今日收入 - 统计今日成功支付的订单金额
$todayRevenue = $Order->where(array(
'add_time' => array('BETWEEN', array($todayStart, $todayEnd)),
'order_state' => 'SUCCESS'
))->sum('trade_amount');
$result = array(
'code' => 1,
'message' => 'success',
'data' => array(
'totalRiders' => $totalRiders,
'onlineRiders' => $onlineRiders,
'todayOrders' => $todayOrders,
'todayRevenue' => number_format($todayRevenue, 2)
)
);
$this->ajaxReturn($result);
} catch (\Exception $e) {
$this->ajaxReturn(array(
'code' => 0,
'message' => $e->getMessage(),
'data' => null
));
}
}
/**
* 获取骑手列表
*/
public function getRiderList()
{
try {
$page = I('get.page', 1, 'intval');
$pageSize = I('get.pageSize', 20, 'intval');
$keyword = I('get.keyword', '', 'trim');
$status = I('get.status', '', 'trim');
$certification = I('get.certification', '', 'trim');
$where = array();
// 关键词搜索
if (!empty($keyword)) {
$where['_string'] = "(rider_name LIKE '%{$keyword}%' OR rider_phone LIKE '%{$keyword}%')";
}
// 状态筛选
if (!empty($status)) {
$where['status'] = $status;
}
// 认证状态筛选
if (is_numeric($certification)) {
$where['auth_status'] = (int)$certification;
}
$where['status'] = 1;
$Rider = M('RiderInfo');
// 获取总数
$totalCount = $Rider->where($where)->count();
// 获取列表数据
$riders = $Rider->where($where)
->order('add_time DESC')
->page($page, $pageSize)
->select();
// 处理数据
foreach ($riders as &$rider) {
// 获取今日订单数和收入
$todayStats = $this->getTodayStats($rider['id']);
$rider['today_orders'] = $todayStats['orders'];
$rider['today_income'] = $todayStats['income'];
// 获取总订单数和总收入
$totalStats = $this->getTotalStats($rider['id']);
$rider['total_orders'] = $totalStats['orders'];
$rider['total_income'] = $totalStats['income'];
// 格式化头像路径
if (!empty($rider['avatar'])) {
$rider['avatar'] = __ROOT__ . $rider['avatar'];
}
}
$result = array(
'code' => 1,
'message' => 'success',
'data' => array(
'list' => $riders,
'total' => $totalCount,
'page' => $page,
'pageSize' => $pageSize
)
);
$this->ajaxReturn($result);
} catch (\Exception $e) {
$this->ajaxReturn(array(
'code' => 0,
'message' => $e->getMessage(),
'data' => array()
));
}
}
/**
* 搜索骑手 - 用于分配订单时的骑手搜索
*/
public function searchRiders()
{
try {
$keyword = I('post.keyword', '', 'trim');
$page = I('post.page', 1, 'intval');
$size = I('post.size', 20, 'intval');
if (empty($keyword) || strlen($keyword) < 2) {
$this->ajaxReturn(array(
'code' => 0,
'msg' => '搜索关键词至少需要2个字符',
'data' => array('list' => [], 'total' => 0)
));
return;
}
$where = array();
$where['status'] = 1; // 只搜索正常状态的骑手
$where['auth_status'] = 2; // 只搜索已认证的骑手
// 按姓名或手机号搜索
$where['_string'] = "(rider_name LIKE '%{$keyword}%' OR rider_phone LIKE '%{$keyword}%')";
$Rider = M('RiderInfo');
// 获取总数
$totalCount = $Rider->where($where)->count();
// 获取列表数据
$riders = $Rider->where($where)
->field('id, rider_name, rider_phone, rider_avatar as avatar, work_status, rating')
->order('work_status DESC, rating DESC, add_time DESC') // 优先显示在线骑手和高评分骑手
->page($page, $size)
->select();
// 处理数据
foreach ($riders as &$rider) {
// 格式化头像路径
if (!empty($rider['avatar'])) {
$rider['avatar'] = __ROOT__ . $rider['avatar'];
} else {
$rider['avatar'] = '';
}
// 统一字段名,确保前端兼容
$rider['name'] = $rider['rider_name'];
$rider['phone'] = $rider['rider_phone'];
// 格式化工作状态
$rider['work_status'] = $rider['work_status'] == 1 ? 'online' : 'offline';
// 格式化评分
$rider['rating'] = floatval($rider['rating']);
}
$result = array(
'code' => 1,
'msg' => 'success',
'data' => array(
'list' => $riders,
'total' => $totalCount,
'page' => $page,
'size' => $size
)
);
$this->ajaxReturn($result);
} catch (\Exception $e) {
$this->ajaxReturn(array(
'code' => 0,
'msg' => '搜索失败:' . $e->getMessage(),
'data' => array('list' => [], 'total' => 0)
));
}
}
/**
* 获取骑手信息接口 - 用于页面数据显示
*/
public function getRiderInfo()
{
$rider_id = I('post.id', 0, 'intval');
if (!$rider_id) {
$this->ajaxReturn(['code' => 0, 'msg' => '参数错误', 'data' => null]);
}
$RiderModel = new RiderModel();
$ImageGalleryModel = new ImageGalleryModel();
// 构建查询条件
$map = array(
'id' => $rider_id,
'merchant_id' => $this->merchant_id
);
if ($this->store_id) {
$map['store_id'] = $this->store_id;
}
// 获取骑手基本信息
$rider = $RiderModel->getFind($map);
if (empty($rider)) {
$this->ajaxReturn(['code' => 0, 'msg' => '骑手不存在', 'data' => null]);
}
// 处理图片路径
if (!empty($rider['rider_avatar'])) {
$rider['avatar_url'] = $ImageGalleryModel->getOneField(['id' => $rider['rider_avatar']], 'path');
} else {
$rider['avatar_url'] = '';
}
if (!empty($rider['id_card_front'])) {
$rider['id_card_front_url'] = $ImageGalleryModel->getOneField(['id' => $rider['id_card_front']], 'path');
} else {
$rider['id_card_front_url'] = '';
}
if (!empty($rider['id_card_back'])) {
$rider['id_card_back_url'] = $ImageGalleryModel->getOneField(['id' => $rider['id_card_back']], 'path');
} else {
$rider['id_card_back_url'] = '';
}
if (!empty($rider['health_cert'])) {
$rider['health_cert_url'] = $ImageGalleryModel->getOneField(['id' => $rider['health_cert']], 'path');
} else {
$rider['health_cert_url'] = '';
}
// 格式化状态文本
$rider['work_status_text'] = $this->getWorkStatusText($rider['work_status']);
$rider['auth_status_text'] = $this->getAuthStatusText($rider['auth_status']);
$rider['health_status_text'] = $this->getHealthStatusText($rider['health_status']);
$rider['status_text'] = $rider['status'] == 1 ? '正常' : '禁用';
// 获取统计数据
$stats = $this->getRiderStats($rider_id);
$rider['today_orders'] = $stats['today_orders'];
$rider['today_income'] = $stats['today_income'];
$rider['total_income'] = $stats['total_income'];
// 格式化时间显示
if (!empty($rider['add_time'])) {
$rider['add_time_formatted'] = date('Y-m-d H:i:s', strtotime($rider['add_time']));
}
if (!empty($rider['last_login_time'])) {
$rider['last_login_time_formatted'] = date('Y-m-d H:i:s', strtotime($rider['last_login_time']));
}
if (!empty($rider['auth_time'])) {
$rider['auth_time_formatted'] = date('Y-m-d H:i:s', strtotime($rider['auth_time']));
}
if (!empty($rider['health_time'])) {
$rider['health_time_formatted'] = date('Y-m-d H:i:s', strtotime($rider['health_time']));
}
// 格式化金额显示
$rider['balance_formatted'] = number_format($rider['balance'], 2);
$rider['frozen_balance_formatted'] = number_format($rider['frozen_balance'], 2);
$this->ajaxReturn(['code' => 1, 'msg' => '获取成功', 'data' => $rider]);
}
/**
* 获取工作状态文本
*/
private function getWorkStatusText($status)
{
$statusMap = [
0 => '离线',
1 => '在线',
2 => '忙碌'
];
return isset($statusMap[$status]) ? $statusMap[$status] : '未知';
}
/**
* 获取认证状态文本
*/
private function getAuthStatusText($status)
{
$statusMap = [
0 => '未认证',
1 => '认证中',
2 => '已认证',
3 => '认证失败'
];
return isset($statusMap[$status]) ? $statusMap[$status] : '未知';
}
/**
* 获取健康证状态文本
*/
private function getHealthStatusText($status)
{
$statusMap = [
0 => '待审核',
1 => '已通过',
2 => '已拒绝'
];
return isset($statusMap[$status]) ? $statusMap[$status] : '未知';
}
/**
* 获取骑手统计数据
*/
private function getRiderStats($rider_id)
{
$RiderOrder = M('RiderOrder');
$today = date('Y-m-d');
// 今日订单数
$today_orders = $RiderOrder->where([
'rider_id' => $rider_id,
'add_time' => ['like', $today . '%'],
'order_status' => 6 // 已送达
])->count();
// 今日收入
$today_income = $RiderOrder->where([
'rider_id' => $rider_id,
'add_time' => ['like', $today . '%'],
'order_status' => 6
])->sum('delivery_fee');
// 总收入
$total_income = $RiderOrder->where([
'rider_id' => $rider_id,
'order_status' => 6
])->sum('delivery_fee');
return [
'today_orders' => $today_orders ?: 0,
'today_income' => number_format($today_income ?: 0, 2),
'total_income' => number_format($total_income ?: 0, 2)
];
}
/**
* 获取骑手详情
*/
public function getRiderDetail()
{
$rider_id = I('post.rider_id', 0);
if (!$rider_id) {
$this->ajaxReturn(['code' => 0, 'msg' => '参数错误']);
}
$RiderModel = new RiderModel();
$ImageGalleryModel = new ImageGalleryModel();
$map = array(
'id' => $rider_id,
'merchant_id' => $this->merchant_id,
'status' => array('neq', 3)
);
if ($this->store_id) {
$map['store_id'] = $this->store_id;
}
$rider = $RiderModel->getFind($map);
if (empty($rider)) {
$this->ajaxReturn(['code' => 0, 'msg' => '骑手不存在']);
}
// 处理图片路径
if ($rider['rider_avatar']) {
$rider['avatar_url'] = $ImageGalleryModel->getOneField(['id' => $rider['rider_avatar']], 'path');
}
if ($rider['id_card_front']) {
$rider['id_card_front_url'] = $ImageGalleryModel->getOneField(['id' => $rider['id_card_front']], 'path');
}
if ($rider['id_card_back']) {
$rider['id_card_back_url'] = $ImageGalleryModel->getOneField(['id' => $rider['id_card_back']], 'path');
}
if ($rider['health_certificate']) {
$rider['health_certificate_url'] = $ImageGalleryModel->getOneField(['id' => $rider['health_certificate']], 'path');
}
$this->ajaxReturn(['code' => 1, 'data' => $rider]);
}
/**
* 添加骑手
*/
public function addRider()
{
try {
// 获取店铺ID,优先使用表单提交的值
$post_store_id = I('post.store_id', -1, 'intval');
$store_id = 0;
if ($post_store_id >= 0) {
// 表单提交了 store_id
$store_id = $post_store_id;
// 如果 store_id > 0,验证店铺是否存在
if ($store_id > 0) {
$StoreModel = M('retail_store');
$store = $StoreModel->where([
'id' => $store_id,
'merchant_id' => $this->merchant_id,
'status' => 1 // 只允许绑定启用状态的店铺
])->find();
if (empty($store)) {
$this->ajaxReturn(['code' => 0, 'msg' => '店铺不存在或已禁用']);
}
}
} else {
// 未提交 store_id,使用管理员的店铺ID
$store_id = $this->store_id ? $this->store_id : 0;
}
$data = array(
'merchant_id' => $this->merchant_id,
'store_id' => $store_id,
'rider_name' => I('post.rider_name', ''),
'rider_phone' => I('post.rider_phone', ''),
'id_card' => I('post.id_card', ''),
'rider_avatar' => I('post.rider_avatar', ''),
'id_card_front' => I('post.id_card_front', ''),
'id_card_back' => I('post.id_card_back', ''),
'health_cert' => I('post.health_cert', ''),
'health_cert_expire' => I('post.health_cert_expire', ''),
'emergency_name' => I('post.emergency_name', ''),
'emergency_phone' => I('post.emergency_phone', ''),
'emergency_relation' => I('post.emergency_relation', ''),
'work_status' => I('post.work_status', ''), // 默认离线
'auth_status' => I('post.auth_status', ''), // 默认未认证
'health_status' => I('post.health_status', ''), // 默认待审核
'balance' => 0.00,
'frozen_balance' => 0.00,
'total_orders' => 0,
'completed_orders' => 0,
'rating' => 5.00,
'on_time_rate' => 100.00,
'order_notification' => 1,
'voice_broadcast' => 1,
'vibration_alert' => 1,
'auto_accept_order' => 0,
'max_distance' => 5.00,
'min_delivery_fee' => 0.00,
'max_orders_per_time' => 3,
'accept_order_types' => '1,2,3',
'reject_low_rating_store' => 0,
'min_store_rating' => 0.00,
'auto_accept_start_time' => '00:00',
'auto_accept_end_time' => '23:59',
'default_withdraw_type' => 1,
'add_time' => date('Y-m-d H:i:s'),
'status' => 1 // 默认正常状态
);
// 验证必填字段
if (empty($data['rider_name'])) {
$this->ajaxReturn(['code' => 0, 'msg' => '请输入骑手姓名']);
}
if (empty($data['rider_phone'])) {
$this->ajaxReturn(['code' => 0, 'msg' => '请输入骑手手机号']);
}
// 验证手机号格式
if (!preg_match('/^1[3-9]\d{9}$/', $data['rider_phone'])) {
$this->ajaxReturn(['code' => 0, 'msg' => '手机号格式不正确']);
}
// 检查手机号是否已存在
$RiderModel = M('rider_info');
$existRider = $RiderModel->where(array(
'rider_phone' => $data['rider_phone'],
'merchant_id' => $this->merchant_id,
'status' => array('neq', 0) // 排除已删除的记录
))->find();
if ($existRider) {
$this->ajaxReturn(['code' => 0, 'msg' => '该手机号已被注册']);
}
// 生成默认密码和盐值
$salt = substr(md5(time() . rand(1000, 9999)), 0, 8);
$password = '123456'; // 默认密码
$data['salt'] = $salt;
$data['password'] = $this->encryptPassword($password, $salt);
$result = $RiderModel->add($data);
if ($result) {
$this->ajaxReturn(['code' => 1, 'msg' => '添加成功', 'rider_id' => $result]);
} else {
$this->ajaxReturn(['code' => 0, 'msg' => '添加失败']);
}
} catch (\Exception $e) {
$this->ajaxReturn(['code' => 0, 'msg' => $e->getMessage()]);
}
}
/**
* 编辑骑手
*/
public function editRider()
{
$rider_id = I('post.rider_id', 0);
if (!$rider_id) {
$this->ajaxReturn(['code' => 0, 'msg' => '参数错误']);
}
$RiderModel = new RiderModel();
$map = array(
'id' => $rider_id,
'merchant_id' => $this->merchant_id,
'status' => array('neq', 3)
);
if ($this->store_id) {
$map['store_id'] = $this->store_id;
}
$rider = $RiderModel->getFind($map);
if (empty($rider)) {
$this->ajaxReturn(['code' => 0, 'msg' => '骑手不存在']);
}
$data = array(
'rider_name' => I('post.rider_name', ''),
'rider_phone' => I('post.rider_phone', ''),
'id_card' => I('post.id_card', ''),
'emergency_contact' => I('post.emergency_contact', ''),
'emergency_phone' => I('post.emergency_phone', ''),
'work_status' => I('post.work_status', 1)
);
// 验证必填字段
if (empty($data['rider_name'])) {
$this->ajaxReturn(['code' => 0, 'msg' => '请输入骑手姓名']);
}
if (empty($data['rider_phone'])) {
$this->ajaxReturn(['code' => 0, 'msg' => '请输入骑手手机号']);
}
// 验证手机号格式
if (!preg_match('/^1[3-9]\d{9}$/', $data['rider_phone'])) {
$this->ajaxReturn(['code' => 0, 'msg' => '手机号格式不正确']);
}
// 检查手机号是否被其他骑手使用
if ($data['rider_phone'] != $rider['rider_phone']) {
$existRider = $RiderModel->getRiderByPhone($data['rider_phone'], $this->merchant_id);
if ($existRider && $existRider['id'] != $rider_id) {
$this->ajaxReturn(['code' => 0, 'msg' => '该手机号已被其他骑手使用']);
}
}
// 处理图片字段
$avatar = I('post.rider_avatar', 0);
$id_card_front = I('post.id_card_front', 0);
$id_card_back = I('post.id_card_back', 0);
$health_certificate = I('post.health_certificate', 0);
if ($avatar) $data['rider_avatar'] = $avatar;
if ($id_card_front) $data['id_card_front'] = $id_card_front;
if ($id_card_back) $data['id_card_back'] = $id_card_back;
if ($health_certificate) $data['health_certificate'] = $health_certificate;
$result = $RiderModel->updateOrder($map, $data);
if ($result !== false) {
$this->ajaxReturn(['code' => 1, 'msg' => '更新成功']);
} else {
$this->ajaxReturn(['code' => 0, 'msg' => '更新失败']);
}
}
/**
* 删除骑手
*/
public function deleteRider()
{
try {
$rider_id = I('post.id', 0);
if (!$rider_id) {
$this->ajaxReturn(['code' => 0, 'msg' => '参数错误']);
}
$RiderModel = new RiderModel();
$map = array(
'id' => $rider_id,
'merchant_id' => $this->merchant_id
);
if ($this->store_id) {
$map['store_id'] = $this->store_id;
}
$data = array(
'status' => 3
);
$result = $RiderModel->updateOrder($map, $data);
if ($result) {
$this->ajaxReturn(['code' => 1, 'msg' => '删除成功']);
} else {
$this->ajaxReturn(['code' => 0, 'msg' => '删除失败']);
}
} catch (\Exception $e) {
$this->ajaxReturn(['code' => 0, 'msg' => $e->getMessage()]);
}
}
/**
* 认证审核
*/
public function auth_review()
{
if (IS_POST) {
$rider_id = I('post.rider_id', 0);
$auth_status = I('post.auth_status', 0);
if (!$rider_id) {
$this->ajaxReturn(['code' => 0, 'msg' => '参数错误']);
}
if (!in_array($auth_status, [2, 3])) {
$this->ajaxReturn(['code' => 0, 'msg' => '认证状态参数错误']);
}
$RiderModel = new RiderModel();
$map = array(
'id' => $rider_id,
'merchant_id' => $this->merchant_id,
'status' => array('neq', 3)
);
if ($this->store_id) {
$map['store_id'] = $this->store_id;
}
$rider = $RiderModel->getFind($map);
if (empty($rider)) {
$this->ajaxReturn(['code' => 0, 'msg' => '骑手不存在']);
}
$result = $RiderModel->updateAuthStatus($rider_id, $auth_status);
if ($result) {
$status_text = $auth_status == 2 ? '认证通过' : '认证失败';
$this->ajaxReturn(['code' => 1, 'msg' => $status_text]);
} else {
$this->ajaxReturn(['code' => 0, 'msg' => '操作失败']);
}
} else {
$id = I('get.id', 0, 'intval');
if ($id) {
$this->assign('rider_id', $id);
}
$this->display();
}
}
/**
* 更新骑手状态
*/
public function updateStatus()
{
$rider_id = I('post.rider_id', 0);
$status = I('post.status', 1);
if (!$rider_id) {
$this->ajaxReturn(['code' => 0, 'msg' => '参数错误']);
}
if (!in_array($status, [1, 2])) {
$this->ajaxReturn(['code' => 0, 'msg' => '状态参数错误']);
}
$RiderModel = new RiderModel();
$map = array(
'id' => $rider_id,
'merchant_id' => $this->merchant_id
);
if ($this->store_id) {
$map['store_id'] = $this->store_id;
}
$data = array(
'status' => $status
);
$result = $RiderModel->updateOrder($map, $data);
if ($result) {
$status_text = $status == 1 ? '启用' : '禁用';
$this->ajaxReturn(['code' => 1, 'msg' => $status_text . '成功']);
} else {
$this->ajaxReturn(['code' => 0, 'msg' => '操作失败']);
}
}
/**
* 文件上传
*/
public function upload()
{
$upload = new \Think\Upload();
$upload->maxSize = 2097152; // 2MB
$upload->exts = array('jpg', 'gif', 'png', 'jpeg');
$upload->rootPath = './Uploads/';
$upload->savePath = 'rider/';
$upload->saveName = array('uniqid', '');
$upload->autoSub = true;
$upload->subName = array('date', 'Ymd');
$info = $upload->upload();
if (!$info) {
$this->ajaxReturn(array('code' => 0, 'message' => $upload->getError()));
} else {
$file = array_shift($info);
$filePath = '/Uploads/' . $file['savepath'] . $file['savename'];
$this->ajaxReturn(array('code' => 1, 'message' => '上传成功', 'data' => array('url' => $filePath)));
}
}
/**
* 导出骑手数据
*/
public function exportRiders()
{
$keyword = I('get.keyword', '', 'trim');
$status = I('get.status', '', 'trim');
$certification = I('get.certification', '', 'trim');
$where = array('status' => 1);
// 关键词搜索
if (!empty($keyword)) {
$where['_string'] = "(rider_name LIKE '%{$keyword}%' OR rider_phone LIKE '%{$keyword}%')";
}
// 状态筛选
if (!empty($status)) {
$where['work_status'] = $status === 'online' ? 1 : 0;
}
// 认证状态筛选
if (!empty($certification)) {
$where['auth_status'] = $certification === 'certified' ? 1 : ($certification === 'pending' ? 0 : 2);
}
$Rider = M('RiderInfo');
$riders = $Rider->where($where)->order('add_time DESC')->select();
// 处理数据
foreach ($riders as &$rider) {
$todayStats = $this->getTodayStats($rider['id']);
$rider['today_orders'] = $todayStats['orders'];
$rider['today_income'] = $todayStats['income'];
$totalStats = $this->getTotalStats($rider['id']);
$rider['total_orders'] = $totalStats['orders'];
$rider['total_income'] = $totalStats['income'];
}
// 生成CSV文件
$filename = '骑手数据_' . date('YmdHis') . '.csv';
header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename="' . $filename . '"');
$output = fopen('php://output', 'w');
// 写入BOM,解决中文乱码
fwrite($output, "\xEF\xBB\xBF");
// 写入表头
fputcsv($output, array('姓名', '手机号', '身份证号', '车牌号', '状态', '认证状态', '今日订单', '今日收入', '总订单', '总收入', '评分', '注册时间'));
// 写入数据
foreach ($riders as $rider) {
fputcsv($output, array(
$rider['name'],
$rider['phone'],
$rider['id_card'],
$rider['vehicle_number'],
$this->getStatusText($rider['status']),
$this->getCertificationText($rider['certification']),
$rider['today_orders'],
$rider['today_income'],
$rider['total_orders'],
$rider['total_income'],
$rider['rating'],
$rider['created_at']
));
}
fclose($output);
exit;
}
/**
* 获取今日统计数据
*/
private function getTodayStats($riderId)
{
$Order = M('rider_order');
$today = date('Y-m-d');
$where = array(
'rider_id' => $riderId,
'add_time' => array('LIKE', $today . '%')
);
$orders = $Order->where($where)->count();
$income = $Order->where(array_merge($where, array('order_status' => 6)))->sum('delivery_fee'); // 6表示已送达
return array(
'orders' => $orders ?: 0,
'income' => $income ?: 0
);
}
/**
* 获取总统计数据
*/
private function getTotalStats($riderId)
{
$Order = M('rider_order');
$where = array(
'rider_id' => $riderId
);
$orders = $Order->where($where)->count();
$income = $Order->where(array_merge($where, array('order_status' => 6)))->sum('delivery_fee'); // 6表示已送达
return array(
'orders' => $orders ?: 0,
'income' => $income ?: 0
);
}
/**
* 获取状态文本
*/
private function getStatusText($status)
{
$texts = array(
'online' => '在线',
'offline' => '离线',
'busy' => '忙碌'
);
return isset($texts[$status]) ? $texts[$status] : '未知';
}
/**
* 获取认证状态文本
*/
private function getCertificationText($certification)
{
$texts = array(
'certified' => '已认证',
'pending' => '待认证',
'rejected' => '认证失败'
);
return isset($texts[$certification]) ? $texts[$certification] : '未知';
}
/**
* 重置骑手密码
*/
public function password_reset()
{
if (IS_POST) {
$id = I('post.id', 0, 'intval');
$newPassword = I('post.new_password', '', 'trim');
if (empty($id)) {
$this->ajaxReturn(array('code' => 0, 'message' => '参数错误'));
}
if (empty($newPassword)) {
$this->ajaxReturn(array('code' => 0, 'message' => '请输入新密码'));
}
if (strlen($newPassword) < 6) {
$this->ajaxReturn(array('code' => 0, 'message' => '密码长度不能少于6位'));
}
$Rider = M('RiderInfo');
$rider = $Rider->where(array('id' => $id, 'status' => 1))->find();
if (!$rider) {
$this->ajaxReturn(array('code' => 404, 'message' => '骑手不存在'));
}
// 生成新的盐值和加密密码
$salt = $this->generateSalt();
$encryptedPassword = $this->encryptPassword($newPassword, $salt);
$result = $Rider->where(array('id' => $id))->save(array(
'password' => $encryptedPassword,
'salt' => $salt,
'update_time' => date('Y-m-d H:i:s')
));
if ($result !== false) {
$this->ajaxReturn(array('code' => 1, 'message' => '密码重置成功'));
} else {
$this->ajaxReturn(array('code' => 0, 'message' => '密码重置失败'));
}
} else {
$id = I('get.id', 0, 'intval');
if ($id) {
$this->assign('rider_id', $id);
}
$this->display();
}
}
/**
* 修改骑手密码
*/
public function changePassword()
{
if (IS_POST) {
$id = I('post.id', 0, 'intval');
$oldPassword = I('post.old_password', '', 'trim');
$newPassword = I('post.new_password', '', 'trim');
if (empty($id) || empty($oldPassword) || empty($newPassword)) {
$this->ajaxReturn(array('code' => 0, 'message' => '参数不完整'));
}
if (strlen($newPassword) < 6) {
$this->ajaxReturn(array('code' => 0, 'message' => '新密码长度不能少于6位'));
}
$Rider = M('RiderInfo');
$rider = $Rider->where(array('id' => $id, 'status' => 1))->find();
if (!$rider) {
$this->ajaxReturn(array('code' => 404, 'message' => '骑手不存在'));
}
// 验证旧密码
if (!$this->verifyPassword($oldPassword, $rider['password'], $rider['salt'])) {
$this->ajaxReturn(array('code' => 0, 'message' => '原密码错误'));
}
// 生成新的盐值和加密新密码
$newSalt = $this->generateSalt();
$newEncryptedPassword = $this->encryptPassword($newPassword, $newSalt);
$result = $Rider->where(array('id' => $id))->save(array(
'password' => $newEncryptedPassword,
'salt' => $newSalt,
'update_time' => date('Y-m-d H:i:s')
));
if ($result !== false) {
$this->ajaxReturn(array('code' => 1, 'message' => '密码修改成功'));
} else {
$this->ajaxReturn(array('code' => 0, 'message' => '密码修改失败'));
}
}
}
/**
* 重置骑手密码 - 对应前端调用的resetPassword接口
*/
public function resetPassword()
{
if (IS_POST) {
$id = I('post.id', 0, 'intval');
$newPassword = I('post.new_password', '', 'trim');
if (empty($id)) {
$this->ajaxReturn(array('code' => 0, 'message' => '参数错误'));
}
if (empty($newPassword)) {
$this->ajaxReturn(array('code' => 0, 'message' => '请输入新密码'));
}
if (strlen($newPassword) < 6) {
$this->ajaxReturn(array('code' => 0, 'message' => '密码长度不能少于6位'));
}
$Rider = M('RiderInfo');
$rider = $Rider->where(array('id' => $id, 'status' => 1))->find();
if (!$rider) {
$this->ajaxReturn(array('code' => 404, 'message' => '骑手不存在'));
}
// 生成新的盐值和加密密码
$salt = $this->generateSalt();
$encryptedPassword = $this->encryptPassword($newPassword, $salt);
$result = $Rider->where(array('id' => $id))->save(array(
'password' => $encryptedPassword,
'salt' => $salt,
'update_time' => date('Y-m-d H:i:s')
));
if ($result !== false) {
$this->ajaxReturn(array('code' => 1, 'message' => '密码重置成功'));
} else {
$this->ajaxReturn(array('code' => 0, 'message' => '密码重置失败'));
}
}
}
/**
* 生成密码盐值
* @return string
*/
private function generateSalt()
{
return substr(md5(uniqid(rand(), true)), 0, 10);
}
/**
* 加密密码
* @param string $password 原始密码
* @param string $salt 盐值
* @return string
*/
private function encryptPassword($password, $salt)
{
return md5(md5($password) . $salt);
}
/**
* 更新骑手信息接口
*/
public function updateRider()
{
// 检查请求方法
if (!IS_POST) {
$this->ajaxReturn(['code' => 0, 'msg' => '请求方法错误']);
}
$rider_id = I('post.id', 0, 'intval');
if (!$rider_id) {
$this->ajaxReturn(['code' => 0, 'msg' => '参数错误:骑手ID不能为空']);
}
$RiderModel = new RiderModel();
// 构建查询条件
$map = array(
'id' => $rider_id,
'merchant_id' => $this->merchant_id,
'status' => array('neq', 3) // 排除已删除状态
);
if ($this->store_id) {
$map['store_id'] = $this->store_id;
}
// 检查骑手是否存在
$rider = $RiderModel->getFind($map);
if (empty($rider)) {
$this->ajaxReturn(['code' => 0, 'msg' => '骑手不存在或无权限操作']);
}
// 获取要更新的字段
$updateData = array();
// 基本信息字段
$rider_name = I('post.rider_name', '', 'trim');
if (!empty($rider_name)) {
// 防止XSS攻击
$rider_name = htmlspecialchars($rider_name, ENT_QUOTES, 'UTF-8');
if (mb_strlen($rider_name) < 2 || mb_strlen($rider_name) > 20) {
$this->ajaxReturn(['code' => 0, 'msg' => '骑手姓名长度应在2-20个字符之间']);
}
// 检查是否包含特殊字符
if (preg_match('/[<>"\'\&]/', $rider_name)) {
$this->ajaxReturn(['code' => 0, 'msg' => '骑手姓名不能包含特殊字符']);
}
$updateData['rider_name'] = $rider_name;
}
$rider_phone = I('post.rider_phone', '', 'trim');
if (!empty($rider_phone)) {
if (!preg_match('/^1[3-9]\d{9}$/', $rider_phone)) {
$this->ajaxReturn(['code' => 0, 'msg' => '手机号格式不正确']);
}
// 只有当手机号发生变化时才检查是否被其他骑手使用
if ($rider['rider_phone'] !== $rider_phone) {
$existingRider = $RiderModel->getFind([
'rider_phone' => $rider_phone,
'id' => array('neq', $rider_id),
'merchant_id' => $this->merchant_id,
'status' => array('neq', 3)
]);
if (!empty($existingRider)) {
$this->ajaxReturn(['code' => 0, 'msg' => '该手机号已被其他骑手使用']);
}
}
$updateData['rider_phone'] = $rider_phone;
}
$id_card = I('post.id_card', '', 'trim');
if (!empty($id_card)) {
if (!preg_match('/^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/', $id_card)) {
$this->ajaxReturn(['code' => 0, 'msg' => '身份证号格式不正确']);
}
// 只有当身份证号发生变化时才检查是否被其他骑手使用
if ($rider['id_card'] !== $id_card) {
$existingRider = $RiderModel->getFind([
'id_card' => $id_card,
'id' => array('neq', $rider_id),
'merchant_id' => $this->merchant_id,
'status' => array('neq', 3)
]);
if (!empty($existingRider)) {
$this->ajaxReturn(['code' => 0, 'msg' => '该身份证号已被其他骑手使用']);
}
}
$updateData['id_card'] = $id_card;
}
// 图片字段验证
$ImageGalleryModel = new ImageGalleryModel();
$rider_avatar = I('post.rider_avatar', 0, 'intval');
if ($rider_avatar > 0) {
// 验证图片是否存在
$image = $ImageGalleryModel->getFind(['id' => $rider_avatar]);
if (empty($image)) {
$this->ajaxReturn(['code' => 0, 'msg' => '头像图片不存在']);
}
$updateData['rider_avatar'] = $rider_avatar;
}
$id_card_front = I('post.id_card_front', 0, 'intval');
if ($id_card_front > 0) {
$image = $ImageGalleryModel->getFind(['id' => $id_card_front]);
if (empty($image)) {
$this->ajaxReturn(['code' => 0, 'msg' => '身份证正面图片不存在']);
}
$updateData['id_card_front'] = $id_card_front;
}
$id_card_back = I('post.id_card_back', 0, 'intval');
if ($id_card_back > 0) {
$image = $ImageGalleryModel->getFind(['id' => $id_card_back]);
if (empty($image)) {
$this->ajaxReturn(['code' => 0, 'msg' => '身份证反面图片不存在']);
}
$updateData['id_card_back'] = $id_card_back;
}
$health_cert = I('post.health_cert', 0, 'intval');
if ($health_cert > 0) {
$image = $ImageGalleryModel->getFind(['id' => $health_cert]);
if (empty($image)) {
$this->ajaxReturn(['code' => 0, 'msg' => '健康证图片不存在']);
}
$updateData['health_cert'] = $health_cert;
}
// 健康证过期时间
$health_cert_expire = I('post.health_cert_expire', '', 'trim');
if (!empty($health_cert_expire)) {
$expire_time = strtotime($health_cert_expire);
if (!$expire_time) {
$this->ajaxReturn(['code' => 0, 'msg' => '健康证过期时间格式不正确']);
}
// 检查过期时间不能是过去的时间
if ($expire_time < time()) {
$this->ajaxReturn(['code' => 0, 'msg' => '健康证过期时间不能是过去的时间']);
}
$updateData['health_cert_expire'] = $health_cert_expire;
}
// 紧急联系人信息
$emergency_name = I('post.emergency_name', '', 'trim');
if (!empty($emergency_name)) {
$emergency_name = htmlspecialchars($emergency_name, ENT_QUOTES, 'UTF-8');
if (mb_strlen($emergency_name) < 2 || mb_strlen($emergency_name) > 20) {
$this->ajaxReturn(['code' => 0, 'msg' => '紧急联系人姓名长度应在2-20个字符之间']);
}
if (preg_match('/[<>"\'\&]/', $emergency_name)) {
$this->ajaxReturn(['code' => 0, 'msg' => '紧急联系人姓名不能包含特殊字符']);
}
$updateData['emergency_name'] = $emergency_name;
}
$emergency_phone = I('post.emergency_phone', '', 'trim');
if (!empty($emergency_phone)) {
if (!preg_match('/^1[3-9]\d{9}$/', $emergency_phone)) {
$this->ajaxReturn(['code' => 0, 'msg' => '紧急联系人手机号格式不正确']);
}
$updateData['emergency_phone'] = $emergency_phone;
}
$emergency_relation = I('post.emergency_relation', '', 'trim');
if (!empty($emergency_relation)) {
$emergency_relation = htmlspecialchars($emergency_relation, ENT_QUOTES, 'UTF-8');
if (mb_strlen($emergency_relation) > 20) {
$this->ajaxReturn(['code' => 0, 'msg' => '紧急联系人关系长度不能超过20个字符']);
}
$updateData['emergency_relation'] = $emergency_relation;
}
// 绑定店铺
$store_id = I('post.store_id', -1, 'intval');
if ($store_id >= 0) {
// 如果 store_id > 0,验证店铺是否存在
if ($store_id > 0) {
$StoreModel = M('retail_store');
$store = $StoreModel->where([
'id' => $store_id,
'merchant_id' => $this->merchant_id,
'status' => 1 // 只允许绑定启用状态的店铺
])->find();
if (empty($store)) {
$this->ajaxReturn(['code' => 0, 'msg' => '店铺不存在或已禁用']);
}
}
$updateData['store_id'] = $store_id;
}
// 工作状态
$work_status = I('post.work_status', -1, 'intval');
if ($work_status >= 0 && $work_status <= 2) {
$updateData['work_status'] = $work_status;
}
// 状态
$status = I('post.status', -1, 'intval');
if ($status >= 0 && $status <= 2) {
$updateData['status'] = $status;
}
// 位置信息
$last_location_lat = I('post.last_location_lat', '', 'trim');
if (!empty($last_location_lat)) {
if (!is_numeric($last_location_lat) || $last_location_lat < -90 || $last_location_lat > 90) {
$this->ajaxReturn(['code' => 0, 'msg' => '纬度值不正确']);
}
$updateData['last_location_lat'] = floatval($last_location_lat);
}
$last_location_lng = I('post.last_location_lng', '', 'trim');
if (!empty($last_location_lng)) {
if (!is_numeric($last_location_lng) || $last_location_lng < -180 || $last_location_lng > 180) {
$this->ajaxReturn(['code' => 0, 'msg' => '经度值不正确']);
}
$updateData['last_location_lng'] = floatval($last_location_lng);
}
// 如果没有要更新的数据
if (empty($updateData)) {
$this->ajaxReturn(['code' => 0, 'msg' => '没有要更新的数据']);
}
// 执行更新
try {
$result = $RiderModel->updateOrder($map, $updateData);
if ($result !== false) {
// 记录操作日志
$this->addOperationLog('update_rider', $rider_id, '更新骑手信息', json_encode($updateData, JSON_UNESCAPED_UNICODE));
$this->ajaxReturn(['code' => 1, 'msg' => '更新成功', 'data' => ['updated_fields' => array_keys($updateData)]]);
} else {
$this->ajaxReturn(['code' => 0, 'msg' => '更新失败']);
}
} catch (\Exception $e) {
// 记录错误日志
error_log('UpdateRider Error: ' . $e->getMessage() . ' - Data: ' . json_encode($updateData));
$this->ajaxReturn(['code' => 0, 'msg' => $e->getMessage()]);
}
}
/**
* 添加操作日志
*/
private function addOperationLog($action, $rider_id, $description, $data = '')
{
$logData = array(
'admin_id' => session('admin_id') ?: 0,
'action' => $action,
'rider_id' => $rider_id,
'description' => $description,
'data' => $data,
'ip_address' => get_client_ip(),
'add_time' => date('Y-m-d H:i:s')
);
try {
M('RiderOperationLog')->add($logData);
} catch (\Exception $e) {
// 日志记录失败不影响主要操作
}
}
/**
* 验证密码
* @param string $password 输入的密码
* @param string $encryptedPassword 数据库中的加密密码
* @param string $salt 盐值
* @return bool
*/
private function verifyPassword($password, $encryptedPassword, $salt)
{
return $this->encryptPassword($password, $salt) === $encryptedPassword;
}
/**
* 配置管理页面
*/
public function config()
{
$this->display('Rider/config');
}
/**
* 获取配置信息
*/
public function getConfig()
{
$configModel = M('RiderConfig');
$config = $configModel->where(array('merchant_id' => $this->merchant_id))->find();
if (!$config) {
// 创建默认配置
$defaultConfig = array(
'merchant_id' => $this->merchant_id,
'auto_sync_enabled' => 0, // 默认关闭自动同步
'delivery_fee_type' => 1, // 1:按距离计算 2:固定费用 3:阶梯计费
'base_fee' => 5.00, // 基础配送费
'distance_fee' => 1.50, // 每公里费用
'free_distance' => 3, // 免费配送距离(公里)
'max_distance' => 20, // 最大配送距离(公里)
'time_fee_enabled' => 1, // 是否启用时间加价
'night_fee_rate' => 0.5, // 夜间加价比例
'night_start_time' => '22:00', // 夜间开始时间
'night_end_time' => '06:00', // 夜间结束时间
'weather_fee_enabled' => 1, // 是否启用恶劣天气加价
'weather_fee_rate' => 1.0, // 恶劣天气加价
'urgent_fee_enabled' => 1, // 是否启用加急费
'urgent_fee' => 3.00, // 加急费用
'min_order_amount' => 20.00, // 最小起送金额
'packaging_fee' => 2.00, // 包装费
'created_time' => time(),
'updated_time' => time()
);
$configModel->add($defaultConfig);
$config = $defaultConfig;
}
$this->ajaxReturn(array(
'code' => 1,
'msg' => '获取成功',
'data' => $config
));
}
/**
* 保存配置
*/
public function saveConfig()
{
$data = I('post.');
$configModel = M('RiderConfig');
// 验证数据
if (!isset($data['auto_sync_enabled']) || !isset($data['delivery_fee_type'])) {
$this->ajaxReturn(array('code' => 0, 'msg' => '参数不完整'));
}
// 数据处理
$saveData = array(
'auto_sync_enabled' => intval($data['auto_sync_enabled']),
'delivery_fee_type' => intval($data['delivery_fee_type']),
'base_fee' => floatval($data['base_fee']),
'distance_fee' => floatval($data['distance_fee']),
'free_distance' => floatval($data['free_distance']),
'max_distance' => floatval($data['max_distance']),
'time_fee_enabled' => intval($data['time_fee_enabled']),
'night_fee_rate' => floatval($data['night_fee_rate']),
'night_start_time' => $data['night_start_time'],
'night_end_time' => $data['night_end_time'],
'weather_fee_enabled' => intval($data['weather_fee_enabled']),
'weather_fee_rate' => floatval($data['weather_fee_rate']),
'urgent_fee_enabled' => intval($data['urgent_fee_enabled']),
'urgent_fee' => floatval($data['urgent_fee']),
'min_order_amount' => floatval($data['min_order_amount']),
'packaging_fee' => floatval($data['packaging_fee']),
'updated_time' => time()
);
$where = array('merchant_id' => $this->merchant_id);
$exists = $configModel->where($where)->find();
if ($exists) {
$result = $configModel->where($where)->save($saveData);
} else {
$saveData['merchant_id'] = $this->merchant_id;
$saveData['created_time'] = time();
$result = $configModel->add($saveData);
}
if ($result !== false) {
$this->ajaxReturn(array('code' => 1, 'msg' => '保存成功'));
} else {
$this->ajaxReturn(array('code' => 0, 'msg' => '保存失败'));
}
}
/**
* 获取配送费用计算规则
*/
public function getFeeRules()
{
$configModel = M('RiderConfig');
$config = $configModel->where(array('merchant_id' => $this->merchant_id))->find();
if (!$config) {
$this->ajaxReturn(array('code' => 0, 'msg' => '请先配置基础设置'));
}
$rules = array(
'delivery_fee_type' => $config['delivery_fee_type'],
'base_fee' => $config['base_fee'],
'distance_fee' => $config['distance_fee'],
'free_distance' => $config['free_distance'],
'max_distance' => $config['max_distance'],
'time_fee_enabled' => $config['time_fee_enabled'],
'night_fee_rate' => $config['night_fee_rate'],
'night_start_time' => $config['night_start_time'],
'night_end_time' => $config['night_end_time'],
'weather_fee_enabled' => $config['weather_fee_enabled'],
'weather_fee_rate' => $config['weather_fee_rate'],
'urgent_fee_enabled' => $config['urgent_fee_enabled'],
'urgent_fee' => $config['urgent_fee'],
'min_order_amount' => $config['min_order_amount'],
'packaging_fee' => $config['packaging_fee']
);
$this->ajaxReturn(array(
'code' => 1,
'msg' => '获取成功',
'data' => $rules
));
}
/**
* 计算配送费用
*/
public function calculateDeliveryFee()
{
$distance = floatval(I('post.distance')); // 配送距离(公里)
$orderAmount = floatval(I('post.order_amount')); // 订单金额
$isUrgent = intval(I('post.is_urgent', 0)); // 是否加急
$isNight = intval(I('post.is_night', 0)); // 是否夜间
$isBadWeather = intval(I('post.is_bad_weather', 0)); // 是否恶劣天气
$configModel = M('RiderConfig');
$config = $configModel->where(array('merchant_id' => $this->merchant_id))->find();
if (!$config) {
$this->ajaxReturn(array('code' => 0, 'msg' => '请先配置基础设置'));
}
// 检查最大配送距离
if ($distance > $config['max_distance']) {
$this->ajaxReturn(array(
'code' => 0,
'msg' => '超出最大配送距离(' . $config['max_distance'] . '公里)'
));
}
// 检查最小起送金额
if ($orderAmount < $config['min_order_amount']) {
$this->ajaxReturn(array(
'code' => 0,
'msg' => '未达到最小起送金额(' . $config['min_order_amount'] . '元)'
));
}
// 初始化各项费用
$baseFee = floatval($config['base_fee']);
$distanceFee = 0;
$urgentFee = 0;
$nightFee = 0;
$weatherFee = 0;
$packagingFee = floatval($config['packaging_fee']);
$deliveryFee = 0;
$feeDetails = array();
// 基础配送费计算
switch ($config['delivery_fee_type']) {
case 1: // 按距离计算
$deliveryFee = $baseFee;
$feeDetails[] = '基础费用: ' . $baseFee . '元';
if ($distance > $config['free_distance']) {
$extraDistance = $distance - $config['free_distance'];
$distanceFee = $extraDistance * $config['distance_fee'];
$deliveryFee += $distanceFee;
$feeDetails[] = '距离费用: ' . $extraDistance . '公里 × ' . $config['distance_fee'] . '元 = ' . $distanceFee . '元';
}
break;
case 2: // 固定费用
$deliveryFee = $baseFee;
$feeDetails[] = '固定配送费: ' . $baseFee . '元';
break;
case 3: // 阶梯计费
// 可以根据需要实现更复杂的阶梯计费逻辑
$deliveryFee = $baseFee;
$feeDetails[] = '阶梯计费: ' . $baseFee . '元';
break;
}
// 包装费
$deliveryFee += $packagingFee;
$feeDetails[] = '包装费: ' . $packagingFee . '元';
// 加急费
if ($isUrgent && $config['urgent_fee_enabled']) {
$urgentFee = floatval($config['urgent_fee']);
$deliveryFee += $urgentFee;
$feeDetails[] = '加急费: ' . $urgentFee . '元';
}
// 恶劣天气加价(固定金额)
if ($isBadWeather && $config['weather_fee_enabled']) {
$weatherFee = floatval($config['weather_fee_rate']);
$deliveryFee += $weatherFee;
$feeDetails[] = '恶劣天气加价: ' . $weatherFee . '元';
}
// 夜间加价(按比例计算,基于当前总费用)
if ($isNight && $config['time_fee_enabled']) {
$nightFee = $deliveryFee * floatval($config['night_fee_rate']);
$deliveryFee += $nightFee;
$feeDetails[] = '夜间加价: ' . (floatval($config['night_fee_rate']) * 100) . '% = ' . $nightFee . '元';
}
$this->ajaxReturn(array(
'code' => 1,
'msg' => '计算成功',
'data' => array(
'total' => round($deliveryFee, 2),
'baseFee' => round($baseFee, 2),
'distanceFee' => round($distanceFee, 2),
'urgentFee' => round($urgentFee, 2),
'nightFee' => round($nightFee, 2),
'weatherFee' => round($weatherFee, 2),
'packagingFee' => round($packagingFee, 2),
'fee_details' => $feeDetails,
'distance' => $distance,
'order_amount' => $orderAmount
)
));
}
/**
* 测试配送费用计算
*/
public function testFeeCalculation()
{
// 直接调用calculateDeliveryFee方法进行计算
$this->calculateDeliveryFee();
}
}