文件
mashangyoujiu/Application/RiderApi/Controller/UserController.class.php

1958 行
69 KiB
PHP

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

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

<?php
namespace RiderApi\Controller;
/**
* 骑手端用户控制器
*/
class UserController extends BaseController
{
/**
* 获取个人信息详情
*/
/**
* 更新个人信息
*/
public function updatePersonalInfo()
{
$riderId = $this->riderId;
$contentType = '';
if (isset($_SERVER['CONTENT_TYPE'])) {
$contentType = $_SERVER['CONTENT_TYPE'];
}
// 使用统一的参数处理方法获取提交的数据
$data = $this->getAllRequestParams();
$updateData = array();
// 姓名
if (isset($data['name'])) {
$name = trim($data['name']);
if (!empty($name)) {
if (mb_strlen($name) < 2 || mb_strlen($name) > 20) {
$this->ajaxReturn(array('code' => 0, 'msg' => '姓名长度应在2-20个字符之间'));
}
$updateData['rider_name'] = $name;
}
}
// 头像
if (isset($data['avatar'])) {
$avatar = trim($data['avatar']);
if (!empty($avatar)) {
$updateData['rider_avatar'] = $avatar;
}
}
// 紧急联系人姓名
if (isset($data['emergency_name'])) {
$emergencyName = trim($data['emergency_name']);
if (!empty($emergencyName) && (mb_strlen($emergencyName) < 2 || mb_strlen($emergencyName) > 20)) {
$this->ajaxReturn(array('code' => 0, 'msg' => '紧急联系人姓名长度应在2-20个字符之间'));
}
$updateData['emergency_name'] = $emergencyName;
}
// 紧急联系人电话
if (isset($data['emergency_phone'])) {
$emergencyPhone = trim($data['emergency_phone']);
if (!empty($emergencyPhone) && !preg_match('/^1[3-9]\d{9}$/', $emergencyPhone)) {
$this->ajaxReturn(array('code' => 0, 'msg' => '请输入正确的紧急联系人电话'));
}
$updateData['emergency_phone'] = $emergencyPhone;
}
// 与本人关系
if (isset($data['emergency_relation'])) {
$updateData['emergency_relation'] = trim($data['emergency_relation']);
}
if (empty($updateData)) {
$this->ajaxReturn(array('code' => 0, 'msg' => '没有需要更新的数据'));
}
$updateData['update_time'] = time();
$riderModel = M('rider_info');
$result = $riderModel->where(array('id' => $riderId))->save($updateData);
if ($result !== false) {
$this->ajaxReturn(array('code' => 1, 'msg' => '更新成功'));
} else {
$this->ajaxReturn(array('code' => 0, 'msg' => '更新失败'));
}
}
/**
* 修改密码
*/
public function changePassword()
{
$riderId = $this->riderId;
$contentType = '';
if (isset($_SERVER['CONTENT_TYPE'])) {
$contentType = $_SERVER['CONTENT_TYPE'];
}
// 使用统一的参数处理方法获取提交的数据
$data = $this->getAllRequestParams();
$oldPassword = isset($data['old_password']) ? trim($data['old_password']) : '';
$newPassword = isset($data['new_password']) ? trim($data['new_password']) : '';
$confirmPassword = isset($data['confirm_password']) ? trim($data['confirm_password']) : '';
// 验证参数
if (empty($oldPassword)) {
$this->ajaxReturn(array('code' => 0, 'msg' => '请输入原密码'));
}
if (empty($newPassword)) {
$this->ajaxReturn(array('code' => 0, 'msg' => '请输入新密码'));
}
if (strlen($newPassword) < 6 || strlen($newPassword) > 20) {
$this->ajaxReturn(array('code' => 0, 'msg' => '新密码长度应在6-20个字符之间'));
}
if ($newPassword !== $confirmPassword) {
$this->ajaxReturn(array('code' => 0, 'msg' => '两次输入的密码不一致'));
}
// 验证原密码
$riderModel = M('rider_info');
$rider = $riderModel->field('password,salt')->find($riderId);
if (!$rider) {
$this->ajaxReturn(array('code' => 0, 'msg' => '用户不存在'));
}
// 使用AuthController相同的验证逻辑
if (!$this->verifyPassword($oldPassword, $rider['password'], $rider['salt'])) {
$this->ajaxReturn(array('code' => 0, 'msg' => '原密码错误'));
}
// 更新密码 - 使用AuthController相同的加密方式
$newSalt = $this->generateSalt();
$encryptedNewPassword = $this->encryptPassword($newPassword, $newSalt);
$updateData = array(
'password' => $encryptedNewPassword,
'salt' => $newSalt,
'update_time' => time()
);
$result = $riderModel->where(array('id' => $riderId))->save($updateData);
if ($result !== false) {
$this->ajaxReturn(array('code' => 1, 'msg' => '密码修改成功'));
} else {
$this->ajaxReturn(array('code' => 0, 'msg' => '密码修改失败'));
}
}
/**
* 绑定手机号(使用session验证验证码)
*/
public function bindPhone()
{
try {
$riderId = $this->riderId;
$contentType = '';
if (isset($_SERVER['CONTENT_TYPE'])) {
$contentType = $_SERVER['CONTENT_TYPE'];
}
// 获取提交的数据
$data = array();
if (strpos($contentType, 'application/json') !== false) {
$input = json_decode(file_get_contents('php://input'), true);
$data = $input ?: array();
} else {
$data = $_POST;
}
$phone = isset($data['phone']) ? trim($data['phone']) : '';
$code = isset($data['code']) ? trim($data['code']) : '';
$type = isset($data['type']) ? trim($data['type']) : 'bind_phone';
// 验证参数
if (empty($phone)) {
$this->ajaxReturn(array('code' => 0, 'msg' => '请输入手机号'));
}
if (!preg_match('/^1[3-9]\d{9}$/', $phone)) {
$this->ajaxReturn(array('code' => 0, 'msg' => '请输入正确的手机号'));
}
if (empty($code)) {
$this->ajaxReturn(array('code' => 0, 'msg' => '请输入验证码'));
}
// 检查是否为调试环境
$isDebug = C('APP_DEBUG') && C('DEBUG_SMS_ENABLED');
$debugCode = C('DEBUG_SMS_CODE');
if (empty($debugCode)) {
$debugCode = '111111'; // 默认验证码
}
if ($isDebug && $code === $debugCode) {
// 调试模式:接受配置的默认验证码,跳过session检查
// 不需要检查session中的验证码
} else {
// 验证验证码(从session中获取)
$sessionCode = session('sms_code_' . $phone . '_' . $type);
if (empty($sessionCode)) {
$this->ajaxReturn(array('code' => 0, 'msg' => '验证码已过期,请重新获取'));
}
if ($sessionCode !== $code) {
$this->ajaxReturn(array('code' => 0, 'msg' => '验证码错误'));
}
}
// 检查手机号是否已被其他骑手使用
$riderModel = M('rider_info');
$existingRider = $riderModel->where(array(
'rider_phone' => $phone,
'id' => array('neq', $riderId),
'status' => array('neq', 3)
))->find();
if ($existingRider) {
$this->ajaxReturn(array('code' => 0, 'msg' => '该手机号已被其他骑手使用'));
}
// 更新手机号
$updateData = array(
'rider_phone' => $phone,
'update_time' => time()
);
$result = $riderModel->where(array('id' => $riderId))->save($updateData);
if ($result !== false) {
// 清除验证码session(仅在非调试模式下)
if (!($isDebug && $code === $debugCode)) {
session('sms_code_' . $phone . '_' . $type, null);
session('sms_send_time_' . $phone, null);
}
$this->ajaxReturn(array('code' => 1, 'msg' => '手机号绑定成功'));
} else {
$this->ajaxReturn(array('code' => 0, 'msg' => '手机号绑定失败'));
}
} catch (\Exception $e) {
$this->ajaxReturn(array('code' => 0, 'msg' => $e->getMessage() . '绑定手机号失败'));
}
}
/**
* 发送短信验证码(使用session存储验证码)
*/
public function sendSmsCode()
{
$contentType = '';
if (isset($_SERVER['CONTENT_TYPE'])) {
$contentType = $_SERVER['CONTENT_TYPE'];
}
// 获取提交的数据
$data = array();
if (strpos($contentType, 'application/json') !== false) {
$input = json_decode(file_get_contents('php://input'), true);
$data = $input ?: array();
} else {
$data = $_POST;
}
$phone = isset($data['phone']) ? trim($data['phone']) : '';
$type = isset($data['type']) ? trim($data['type']) : 'bind_phone';
// 验证手机号
if (empty($phone)) {
$this->ajaxReturn(array('code' => 0, 'msg' => '请输入手机号'));
}
if (!preg_match('/^1[3-9]\d{9}$/', $phone)) {
$this->ajaxReturn(array('code' => 0, 'msg' => '请输入正确的手机号'));
}
// 检查是否为调试环境
$isDebug = C('APP_DEBUG') && C('DEBUG_SMS_ENABLED');
if ($isDebug) {
// 调试环境:使用配置的默认验证码
$code = C('DEBUG_SMS_CODE');
if (empty($code)) {
$code = '111111'; // 默认验证码
}
// 将验证码存储到session中,有效期5分钟
session('sms_code_' . $phone . '_' . $type, $code, 300);
session('sms_send_time_' . $phone, time()); // 记录发送时间
$this->ajaxReturn(array(
'code' => 1,
'msg' => '验证码发送成功(调试模式)',
'data' => array(
'debug' => true,
'code' => $code // 调试模式下返回验证码
)
));
} else {
// 生产环境:检查发送频率限制(60秒内只能发送一次)
$lastSendTime = session('sms_send_time_' . $phone);
if ($lastSendTime && (time() - $lastSendTime) < 60) {
$this->ajaxReturn(array('code' => 0, 'msg' => '验证码发送过于频繁,请稍后再试'));
}
// 生成6位随机验证码
$code = sprintf('%06d', mt_rand(0, 999999));
// 调用现有的阿里云短信服务发送验证码
$smsResult = $this->sendAliyunSms($phone, $code);
if ($smsResult['code'] == 1) {
// 短信发送成功,保存验证码到session
session('sms_code_' . $phone . '_' . $type, $code, 300); // 5分钟过期
session('sms_send_time_' . $phone, time()); // 记录发送时间
$this->ajaxReturn(array(
'code' => 1,
'msg' => '验证码发送成功',
'data' => array(
'debug' => false
)
));
} else {
$this->ajaxReturn(array('code' => 0, 'msg' => $smsResult['msg'] ?: '验证码发送失败'));
}
}
}
/**
* 调用阿里云短信服务发送验证码
* @param string $phone 手机号
* @param string $code 验证码
* @return array
*/
private function sendAliyunSms($phone, $code)
{
try {
// 获取系统短信配置
$smsConfig = M('system_sms')->find();
if (empty($smsConfig)) {
return array('code' => 0, 'msg' => '系统暂不支持发送验证码功能');
}
if (
empty($smsConfig['accesskeyid']) || empty($smsConfig['accesskeysecret'])
|| empty($smsConfig['accessname']) || empty($smsConfig['accesscode'])
) {
return array('code' => 0, 'msg' => '系统短信配置有误');
}
// 调用现有的阿里大鱼短信服务
$alidayuController = new \Api\Controller\AlidayuController();
$result = $alidayuController->sendSmsCode($phone, $code);
if ($result && isset($result['status']) && $result['status'] == 1) {
return array('code' => 1, 'msg' => '发送成功');
} else {
$errorMsg = isset($result['msg']) ? $result['msg'] : '短信发送失败';
return array('code' => 0, 'msg' => $errorMsg);
}
} catch (\Exception $e) {
return array('code' => 0, 'msg' => '短信发送异常:' . $e->getMessage());
}
}
/**
* 获取当前工作区域
*/
public function getCurrentWorkArea()
{
$riderId = $this->riderId;
$riderModel = M('rider_info');
$rider = $riderModel->field('work_area_id')->find($riderId);
if (!$rider || !$rider['work_area_id']) {
$this->ajaxReturn(array('code' => 1, 'msg' => '暂未设置工作区域', 'data' => null));
}
$areaModel = M('work_area');
$area = $areaModel->find($rider['work_area_id']);
if (!$area) {
$this->ajaxReturn(array('code' => 0, 'msg' => '工作区域不存在'));
}
// 检查是否有电子围栏数据
$fenceModel = M('store_delivery_fence');
$fenceData = $fenceModel->where(array(
'store_id' => $area['id'],
'is_active' => 1
))->select();
$areaData = array(
'id' => $area['id'],
'name' => $area['area_name'],
'address' => $area['area_address'],
'range' => $area['delivery_range'],
'has_fence' => !empty($fenceData),
'fence_data' => array()
);
// 如果有电子围栏数据,添加围栏信息
if (!empty($fenceData)) {
foreach ($fenceData as $fence) {
$areaData['fence_data'][] = array(
'fence_id' => $fence['id'],
'fence_name' => $fence['fence_name'],
'fence_type' => $fence['fence_type'],
'coordinates' => json_decode($fence['fence_data'], true)
);
}
}
$this->ajaxReturn(array(
'code' => 1,
'msg' => '获取成功',
'data' => $areaData
));
}
/**
* 获取工作区域列表
*/
public function getWorkAreaList()
{
$areaModel = M('work_area');
$areaList = $areaModel->where(array('status' => 1))->order('sort_order asc, id asc')->select();
$data = array();
if ($areaList) {
foreach ($areaList as $area) {
// 检查是否有电子围栏数据
$fenceModel = M('store_delivery_fence');
$fenceData = $fenceModel->where(array(
'store_id' => $area['id'],
'is_active' => 1
))->select();
$areaInfo = array(
'id' => $area['id'],
'name' => $area['area_name'],
'address' => $area['area_address'],
'range' => $area['delivery_range'],
'has_fence' => !empty($fenceData),
'fence_data' => array()
);
// 如果有电子围栏数据,添加围栏信息
if (!empty($fenceData)) {
foreach ($fenceData as $fence) {
$areaInfo['fence_data'][] = array(
'fence_id' => $fence['id'],
'fence_name' => $fence['fence_name'],
'fence_type' => $fence['fence_type'],
'coordinates' => json_decode($fence['fence_data'], true)
);
}
}
$data[] = $areaInfo;
}
}
$this->ajaxReturn(array(
'code' => 1,
'msg' => '获取成功',
'data' => $data
));
}
/**
* 设置工作区域
*/
public function setWorkArea()
{
$riderId = $this->riderId;
$contentType = '';
if (isset($_SERVER['CONTENT_TYPE'])) {
$contentType = $_SERVER['CONTENT_TYPE'];
}
// 获取提交的数据
$data = array();
if (strpos($contentType, 'application/json') !== false) {
$input = json_decode(file_get_contents('php://input'), true);
$data = $input ?: array();
} else {
$data = $_POST;
}
$areaId = isset($data['area_id']) ? intval($data['area_id']) : 0;
if (!$areaId) {
$this->ajaxReturn(array('code' => 0, 'msg' => '请选择工作区域'));
}
// 验证区域是否存在且可用
$areaModel = M('work_area');
$area = $areaModel->where(array('id' => $areaId, 'status' => 1))->find();
if (!$area) {
$this->ajaxReturn(array('code' => 0, 'msg' => '选择的工作区域不存在或已停用'));
}
// 更新骑手工作区域
$riderModel = M('rider_info');
$updateData = array(
'work_area_id' => $areaId,
'update_time' => time()
);
$result = $riderModel->where(array('id' => $riderId))->save($updateData);
if ($result !== false) {
$this->ajaxReturn(array('code' => 1, 'msg' => '设置成功'));
} else {
$this->ajaxReturn(array('code' => 0, 'msg' => '设置失败'));
}
}
/**
* 获取工作时间设置
*/
public function getWorkTime()
{
try {
$riderId = $this->riderId;
$workTimeModel = M('rider_work_time');
$workTimeList = $workTimeModel->where(array('rider_id' => $riderId))->order('week_day asc')->select();
// 初始化一周的工作时间
$weekDays = array(
1 => '周一',
2 => '周二',
3 => '周三',
4 => '周四',
5 => '周五',
6 => '周六',
7 => '周日' // 修正周日为7,与数据库表结构一致
);
$workTimeData = array();
foreach ($weekDays as $day => $dayName) {
$workTimeData[] = array(
'week_day' => $day,
'day_name' => $dayName,
'is_work' => 1, // 默认为工作日
'start_time' => '09:00',
'end_time' => '18:00'
);
}
// 填充已设置的工作时间
if ($workTimeList) {
foreach ($workTimeList as $workTime) {
$dayIndex = array_search($workTime['week_day'], array_column($workTimeData, 'week_day'));
if ($dayIndex !== false) {
$workTimeData[$dayIndex] = array(
'week_day' => $workTime['week_day'],
'day_name' => $weekDays[$workTime['week_day']],
'is_work' => $workTime['is_work'],
'start_time' => $workTime['start_time'],
'end_time' => $workTime['end_time']
);
}
}
} else {
// 如果没有工作时间记录,创建默认的7天记录
foreach ($workTimeData as $workTime) {
$defaultData = array(
'rider_id' => $riderId,
'week_day' => $workTime['week_day'],
'is_work' => 1,
'start_time' => '09:00',
'end_time' => '18:00',
'add_time' => time(),
'update_time' => time()
);
$workTimeModel->add($defaultData);
}
}
$this->ajaxReturn(array(
'code' => 1,
'msg' => '获取成功',
'data' => $workTimeData
));
} catch (\Exception $e) {
$this->ajaxReturn(array('code' => 0, 'msg' => $e->getMessage()));
}
}
/**
* 设置工作时间
*/
public function setWorkTime()
{
$riderId = $this->riderId;
$contentType = '';
if (isset($_SERVER['CONTENT_TYPE'])) {
$contentType = $_SERVER['CONTENT_TYPE'];
}
// 获取提交的数据
$data = array();
if (strpos($contentType, 'application/json') !== false) {
$input = json_decode(file_get_contents('php://input'), true);
$data = $input ?: array();
} else {
$data = $_POST;
}
// 支持两种数据格式:work_time_list 和 work_times
$workTimeList = isset($data['work_time_list']) ? $data['work_time_list'] : (isset($data['work_times']) ? $data['work_times'] : array());
if (empty($workTimeList) || !is_array($workTimeList)) {
$this->ajaxReturn(array('code' => 0, 'msg' => '工作时间数据不能为空'));
}
$workTimeModel = M('rider_work_time');
// 开启事务
$workTimeModel->startTrans();
try {
foreach ($workTimeList as $workTime) {
$weekDay = isset($workTime['week_day']) ? intval($workTime['week_day']) : -1;
$isWork = isset($workTime['is_work']) ? intval($workTime['is_work']) : 0;
$startTime = isset($workTime['start_time']) ? trim($workTime['start_time']) : '09:00';
$endTime = isset($workTime['end_time']) ? trim($workTime['end_time']) : '18:00';
// 验证星期几 (1-7)
if ($weekDay < 1 || $weekDay > 7) {
throw new \Exception('无效的星期数据,必须在1-7之间');
}
// 只对工作日验证时间格式
if ($isWork == 1) {
// 验证时间格式
if (
!preg_match('/^([01]?[0-9]|2[0-3]):[0-5][0-9]$/', $startTime) ||
!preg_match('/^([01]?[0-9]|2[0-3]):[0-5][0-9]$/', $endTime)
) {
throw new \Exception('时间格式不正确');
}
}
// 检查记录是否存在
$existingRecord = $workTimeModel->where(array(
'rider_id' => $riderId,
'week_day' => $weekDay
))->find();
$updateData = array(
'is_work' => $isWork,
'start_time' => $startTime,
'end_time' => $endTime,
'update_time' => time()
);
if ($existingRecord) {
// 更新现有记录
$result = $workTimeModel->where(array(
'rider_id' => $riderId,
'week_day' => $weekDay
))->save($updateData);
} else {
// 创建新记录
$updateData['rider_id'] = $riderId;
$updateData['week_day'] = $weekDay;
$updateData['add_time'] = time();
$result = $workTimeModel->add($updateData);
}
if ($result === false) {
throw new \Exception('保存工作时间失败');
}
}
// 提交事务
$workTimeModel->commit();
$this->ajaxReturn(array('code' => 1, 'msg' => '设置成功'));
} catch (\Exception $e) {
// 回滚事务
$workTimeModel->rollback();
$this->ajaxReturn(array('code' => 0, 'msg' => $e->getMessage()));
}
}
/**
* 获取骑手统计数据
*/
public function getUserStats()
{
$riderId = $this->riderId;
$rider = $this->riderInfo;
if (!$rider) {
$this->ajaxReturn(array('code' => 0, 'msg' => '用户信息获取失败'));
}
try {
// 获取今日统计数据
$todayStats = $this->getTodayStats($riderId);
// 获取本月统计数据
$monthStats = $this->getMonthStats($riderId);
// 获取总统计数据
$totalStats = $this->getTotalStats($riderId);
// 获取骑手基本信息
$userInfo = array(
'id' => $rider['id'],
'name' => $rider['name'],
'phone' => $rider['phone'],
'avatar' => $rider['avatar'] ? __ROOT__ . $rider['avatar'] : '',
'rating' => floatval($rider['rating'] ?: 0),
'work_status' => $rider['work_status'] ?: 'offline',
'auth_status' => intval($rider['auth_status']),
'health_status' => intval($rider['health_status'])
);
// 组装返回数据
$result = array(
'code' => 1,
'msg' => '获取成功',
'data' => array(
'user_info' => $userInfo,
'today_stats' => $todayStats,
'month_stats' => $monthStats,
'total_stats' => $totalStats
)
);
$this->ajaxReturn($result);
} catch (\Exception $e) {
$this->ajaxReturn(array('code' => 0, 'msg' => '获取统计数据失败:' . $e->getMessage()));
}
}
/**
* 获取今日统计数据
*/
private function getTodayStats($riderId)
{
$today = date('Y-m-d');
$todayStart = $today . ' 00:00:00';
$todayEnd = $today . ' 23:59:59';
$orderModel = M('rider_order');
$incomeModel = M('rider_income');
// 今日订单统计
$orderWhere = array(
'rider_id' => $riderId,
'add_time' => array('between', array($todayStart, $todayEnd))
);
$todayOrders = $orderModel->where($orderWhere)->count();
$completedOrders = $orderModel->where(array_merge($orderWhere, array('order_status' => 6)))->count();
$cancelledOrders = $orderModel->where(array_merge($orderWhere, array('order_status' => 8)))->count();
// 今日收入 - 从收入表读取已结算的收入
$incomeWhere = array(
'rider_id' => $riderId,
'status' => 1, // 已结算
'settle_time' => array('between', array($todayStart, $todayEnd))
);
$todayIncome = $incomeModel->where($incomeWhere)->sum('amount') ?: 0;
// 今日配送距离
$todayDistance = $orderModel->where(array_merge($orderWhere, array('order_status' => 6)))->sum('distance') ?: 0;
// 计算完成率
$completionRate = $todayOrders > 0 ? round(($completedOrders / $todayOrders) * 100, 2) : 0;
return array(
'order_count' => intval($todayOrders),
'completed_count' => intval($completedOrders),
'cancelled_count' => intval($cancelledOrders),
'income' => floatval($todayIncome),
'distance' => floatval($todayDistance),
'completion_rate' => floatval($completionRate)
);
}
/**
* 获取本月统计数据
*/
private function getMonthStats($riderId)
{
$monthStart = date('Y-m-01 00:00:00');
$monthEnd = date('Y-m-t 23:59:59');
$orderModel = M('rider_order');
$incomeModel = M('rider_income');
// 本月订单统计
$orderWhere = array(
'rider_id' => $riderId,
'add_time' => array('between', array($monthStart, $monthEnd))
);
$monthOrders = $orderModel->where($orderWhere)->count();
$completedOrders = $orderModel->where(array_merge($orderWhere, array('order_status' => 6)))->count();
$cancelledOrders = $orderModel->where(array_merge($orderWhere, array('order_status' => 8)))->count();
// 本月收入 - 从收入表读取已结算的收入
$incomeWhere = array(
'rider_id' => $riderId,
'status' => 1, // 已结算
'settle_time' => array('between', array($monthStart, $monthEnd))
);
$monthIncome = $incomeModel->where($incomeWhere)->sum('amount') ?: 0;
// 本月配送距离
$monthDistance = $orderModel->where(array_merge($orderWhere, array('order_status' => 6)))->sum('distance') ?: 0;
// 计算完成率
$completionRate = $monthOrders > 0 ? round(($completedOrders / $monthOrders) * 100, 2) : 0;
// 计算平均每日收入
$daysInMonth = date('j');
$avgDailyIncome = $daysInMonth > 0 ? round($monthIncome / $daysInMonth, 2) : 0;
return array(
'order_count' => intval($monthOrders),
'completed_count' => intval($completedOrders),
'cancelled_count' => intval($cancelledOrders),
'income' => floatval($monthIncome),
'distance' => floatval($monthDistance),
'completion_rate' => floatval($completionRate),
'avg_daily_income' => floatval($avgDailyIncome)
);
}
/**
* 获取总统计数据
*/
private function getTotalStats($riderId)
{
$orderModel = M('rider_order');
$incomeModel = M('rider_income');
// 总订单统计
$orderWhere = array('rider_id' => $riderId);
$totalOrders = $orderModel->where($orderWhere)->count();
$completedOrders = $orderModel->where(array_merge($orderWhere, array('order_status' => 6)))->count();
$cancelledOrders = $orderModel->where(array_merge($orderWhere, array('order_status' => 8)))->count();
// 总收入 - 从收入表读取已结算的收入
$incomeWhere = array(
'rider_id' => $riderId,
'status' => 1 // 已结算
);
$totalIncome = $incomeModel->where($incomeWhere)->sum('amount') ?: 0;
// 总配送距离
$totalDistance = $orderModel->where(array_merge($orderWhere, array('order_status' => 6)))->sum('distance') ?: 0;
// 计算完成率
$completionRate = $totalOrders > 0 ? round(($completedOrders / $totalOrders) * 100, 2) : 0;
// 获取注册天数
$registerTime = strtotime($this->riderInfo['add_time']);
$currentTime = time();
$workDays = ceil(($currentTime - $registerTime) / (24 * 3600));
// 计算平均每日收入
$avgDailyIncome = $workDays > 0 ? round($totalIncome / $workDays, 2) : 0;
return array(
'order_count' => intval($totalOrders),
'completed_count' => intval($completedOrders),
'cancelled_count' => intval($cancelledOrders),
'income' => floatval($totalIncome),
'distance' => floatval($totalDistance),
'completion_rate' => floatval($completionRate),
'work_days' => intval($workDays),
'avg_daily_income' => floatval($avgDailyIncome)
);
}
/**
* 获取用户基本信息
*/
public function getUserInfo()
{
$rider = $this->riderInfo;
if (!$rider) {
$this->ajaxReturn(array('code' => 0, 'msg' => '用户信息获取失败'));
}
$userInfo = array(
'id' => $rider['id'],
'name' => $rider['name'],
'phone' => $rider['phone'],
'avatar' => $rider['avatar'] ? __ROOT__ . $rider['avatar'] : '',
'rating' => floatval($rider['rating'] ?: 0),
'work_status' => $rider['work_status'] ?: 'offline',
'auth_status' => intval($rider['auth_status']),
'health_status' => intval($rider['health_status']),
'add_time' => $rider['add_time']
);
$this->ajaxReturn(array(
'code' => 1,
'msg' => '获取成功',
'data' => $userInfo
));
}
/**
* 获取认证信息
*/
public function getAuthInfo()
{
$riderId = $this->riderId;
$rider = $this->riderInfo;
if (!$rider) {
$this->ajaxReturn(array('code' => 0, 'msg' => '用户信息获取失败'));
}
try {
// 获取认证状态文本映射
$statusMap = array(
0 => 'not_verified', // 未认证
1 => 'pending', // 认证中
2 => 'verified', // 已认证
3 => 'rejected' // 认证失败
);
$authStatus = intval($rider['auth_status']);
$statusText = isset($statusMap[$authStatus]) ? $statusMap[$authStatus] : 'not_verified';
// 查询auth_log表,判断是否已提交过审核资料
$authLogModel = M('rider_auth_log');
$hasSubmitted = false;
$lastSubmitTime = '';
if ($authLogModel) {
// 查询是否有提交记录(action为submit或resubmit)
$submitLog = $authLogModel->where(array(
'rider_id' => $riderId,
'action' => array('in', array('submit', 'resubmit'))
))->order('add_time desc')->find();
if ($submitLog) {
$hasSubmitted = true;
$lastSubmitTime = $submitLog['add_time'];
}
}
// 组装认证信息
$authInfo = array(
'status' => $statusText,
'name' => $rider['rider_name'] ?: '',
'id_card' => $rider['id_card'] ?: '',
'phone' => $rider['rider_phone'] ?: '',
'id_card_front' => $rider['id_card_front'] ? __ROOT__ . $rider['id_card_front'] : '',
'id_card_back' => $rider['id_card_back'] ? __ROOT__ . $rider['id_card_back'] : '',
'handheld_photo' => '', // 手持身份证照片字段,如果数据库有对应字段可以添加
'emergency_name' => '', // 紧急联系人姓名,如果数据库有对应字段可以添加
'emergency_phone' => '', // 紧急联系人电话,如果数据库有对应字段可以添加
'emergency_relation' => '', // 与本人关系,如果数据库有对应字段可以添加
'reject_reason' => $rider['auth_remark'] ?: '', // 审核失败原因
'auth_time' => $rider['auth_time'] ?: '', // 认证时间
'auth_status' => $authStatus, // 原始状态码
'has_submitted' => $hasSubmitted, // 是否已提交过审核资料
'last_submit_time' => $lastSubmitTime // 最后提交时间
);
$this->ajaxReturn(array(
'code' => 1,
'msg' => '获取成功',
'data' => $authInfo
));
} catch (\Exception $e) {
$this->ajaxReturn(array('code' => 0, 'msg' => '获取认证信息失败:' . $e->getMessage()));
}
}
/**
* 更新用户信息
*/
public function updateUserInfo()
{
$riderId = $this->riderId;
$contentType = '';
if (isset($_SERVER['CONTENT_TYPE'])) {
$contentType = $_SERVER['CONTENT_TYPE'];
}
// 初始化变量
$name = '';
$avatar = '';
$onlineStartTime = null;
if (strpos($contentType, 'application/json') !== false) {
$input = json_decode(file_get_contents('php://input'), true);
if (isset($input['name'])) {
$name = trim($input['name']);
}
if (isset($input['avatar'])) {
$avatar = trim($input['avatar']);
}
if (isset($input['online_start_time'])) {
$onlineStartTime = $input['online_start_time'];
}
} else {
$name = $this->getRequestParam('name', '');
$avatar = $this->getRequestParam('avatar', '');
$onlineStartTime = $this->getRequestParam('online_start_time', null);
}
$updateData = array();
if (!empty($name)) {
$updateData['name'] = $name;
}
if (!empty($avatar)) {
$updateData['avatar'] = $avatar;
}
// 处理在线开始时间
if ($onlineStartTime !== null) {
if ($onlineStartTime === 0 || $onlineStartTime === '0' || $onlineStartTime === '') {
// 离线时清空在线开始时间
$updateData['online_start_time'] = null;
} else {
// 在线时设置在线开始时间戳
$updateData['online_start_time'] = intval($onlineStartTime);
}
}
if (empty($updateData)) {
$this->ajaxReturn(array('code' => 0, 'msg' => '没有需要更新的数据'));
}
$riderModel = M('rider_info');
$result = $riderModel->where(array('id' => $riderId))->save($updateData);
if ($result !== false) {
$this->ajaxReturn(array('code' => 1, 'msg' => '更新成功'));
} else {
$this->ajaxReturn(array('code' => 0, 'msg' => '更新失败'));
}
}
/**
* 文件上传
*/
public function uploadFile()
{
$riderId = $this->riderId;
$rider = $this->riderInfo;
if (!$rider) {
$this->ajaxReturn(array('code' => 0, 'msg' => '用户信息获取失败'));
}
// 检查是否有上传的文件
if (empty($_FILES)) {
$this->ajaxReturn(array('code' => 0, 'msg' => '没有上传的文件'));
}
try {
// 设置上传参数
$item = array(
'add_time' => time(),
'from_type_id' => 29, // 骑手端文件上传类型ID
'localUrl' => 'RiderApi/User',
'user_type' => 5, // 骑手用户类型
'rider_id' => $riderId
);
// 调用文件上传函数
$uploads = uploadFiles($item);
if (!empty($uploads['file'])) {
$result = array(
'code' => 1,
'msg' => '上传成功',
'data' => array(
'file_id' => $uploads['file']['id'],
'file_path' => $uploads['file']['path'] ?: $uploads['file']['id'],
'file_url' => getServerUrl() . ($uploads['file']['path'] ?: $uploads['file']['id'])
)
);
} else {
$result = array(
'code' => 0,
'msg' => $uploads['msg'] ?: '文件上传失败'
);
}
$this->ajaxReturn($result);
} catch (\Exception $e) {
$this->ajaxReturn(array(
'code' => 0,
'msg' => '文件上传异常:' . $e->getMessage()
));
}
}
/**
* 加密密码
* @param string $password 原始密码
* @param string $salt 盐值
* @return string
*/
private function encryptPassword($password, $salt)
{
return md5(md5($password) . $salt);
}
/**
* 验证密码
* @param string $password 输入的密码
* @param string $encryptedPassword 数据库中的加密密码
* @param string $salt 盐值
* @return bool
*/
private function verifyPassword($password, $encryptedPassword, $salt)
{
return $this->encryptPassword($password, $salt) === $encryptedPassword;
}
/**
* 生成密码盐值
* @return string
*/
private function generateSalt()
{
return substr(md5(uniqid(rand(), true)), 0, 10);
}
/**
* 更新通知设置
*/
public function updateNotificationSettings()
{
$riderId = $this->riderId;
// 检查Content-Type并获取参数
$contentType = '';
if (isset($_SERVER['CONTENT_TYPE'])) {
$contentType = $_SERVER['CONTENT_TYPE'];
}
$orderNotification = null;
$voiceBroadcast = null;
$vibrationAlert = null;
if (strpos($contentType, 'application/json') !== false) {
// JSON格式请求
$input = json_decode(file_get_contents('php://input'), true);
if (isset($input['order_notification'])) {
$orderNotification = $input['order_notification'];
}
if (isset($input['voice_broadcast'])) {
$voiceBroadcast = $input['voice_broadcast'];
}
if (isset($input['vibration_alert'])) {
$vibrationAlert = $input['vibration_alert'];
}
} else {
// 表单格式请求
$orderNotification = $this->getRequestParam('order_notification', null);
$voiceBroadcast = $this->getRequestParam('voice_broadcast', null);
$vibrationAlert = $this->getRequestParam('vibration_alert', null);
}
// 验证参数
if ($orderNotification === null && $voiceBroadcast === null && $vibrationAlert === null) {
$this->ajaxReturn(array('code' => 0, 'msg' => '请提供要更新的设置项'));
}
$updateData = array();
// 验证并设置订单通知
if ($orderNotification !== null) {
if (!in_array($orderNotification, array('0', '1', 0, 1))) {
$this->ajaxReturn(array('code' => 0, 'msg' => '订单通知设置值无效'));
}
$updateData['order_notification'] = intval($orderNotification);
}
// 验证并设置语音播报
if ($voiceBroadcast !== null) {
if (!in_array($voiceBroadcast, array('0', '1', 0, 1))) {
$this->ajaxReturn(array('code' => 0, 'msg' => '语音播报设置值无效'));
}
$updateData['voice_broadcast'] = intval($voiceBroadcast);
}
// 验证并设置震动提醒
if ($vibrationAlert !== null) {
if (!in_array($vibrationAlert, array('0', '1', 0, 1))) {
$this->ajaxReturn(array('code' => 0, 'msg' => '震动提醒设置值无效'));
}
$updateData['vibration_alert'] = intval($vibrationAlert);
}
if (empty($updateData)) {
$this->ajaxReturn(array('code' => 0, 'msg' => '没有有效的设置项需要更新'));
}
$riderModel = M('rider_info');
$result = $riderModel->where(array('id' => $riderId))->save($updateData);
if ($result !== false) {
$this->ajaxReturn(array(
'code' => 1,
'msg' => '设置更新成功',
'data' => $updateData
));
} else {
$this->ajaxReturn(array('code' => 0, 'msg' => '设置更新失败'));
}
}
/**
* 获取自动接单配置
*/
public function getAutoAcceptConfig()
{
$rider = $this->riderInfo;
if (!$rider) {
$this->ajaxReturn(array('code' => 0, 'msg' => '用户信息获取失败'));
}
// 获取骑手工作时间设置
$workTimeModel = M('rider_work_time');
$workTimes = $workTimeModel->where(array('rider_id' => $rider['rider_id']))->select();
// 构建工作日数组(基于工作时间表)
$workDays = array();
if ($workTimes) {
foreach ($workTimes as $workTime) {
if ($workTime['is_work'] == 1) {
// 将数据库中的week_day(0-6)转换为前端使用的格式(1-7)
$workDays[] = $workTime['week_day'] == 0 ? 7 : $workTime['week_day'];
}
}
}
// 如果没有设置工作时间,默认全周工作
if (empty($workDays)) {
$workDays = array(1, 2, 3, 4, 5, 6, 7);
}
$config = array(
'auto_accept_order' => intval($rider['auto_accept_order']),
'max_distance' => floatval($rider['max_distance']),
'min_delivery_fee' => floatval($rider['min_delivery_fee']),
'max_orders_per_time' => intval($rider['max_orders_per_time']),
'accept_order_types' => $rider['accept_order_types'] ? explode(',', $rider['accept_order_types']) : array('1', '2', '3'),
'reject_low_rating_store' => intval($rider['reject_low_rating_store']),
'min_store_rating' => floatval($rider['min_store_rating']),
'auto_accept_start_time' => $rider['auto_accept_start_time'] ?: '00:00',
'auto_accept_end_time' => $rider['auto_accept_end_time'] ?: '23:59',
'work_days' => $workDays
);
$this->ajaxReturn(array(
'code' => 1,
'msg' => '获取成功',
'data' => $config
));
}
/**
* 更新订单设置
*/
public function updateOrderSettings()
{
$riderId = $this->riderInfo['id'];
if (!$riderId) {
$this->ajaxReturn(array('code' => 0, 'msg' => '用户信息获取失败'));
}
$data = $this->getAllRequestParams();
if (empty($data)) {
$this->ajaxReturn(array('code' => 0, 'msg' => '参数不能为空'));
}
$updateData = array();
// 工作状态
if (isset($data['work_status'])) {
// 处理布尔值和字符串
$workStatus = $data['work_status'];
if (is_bool($workStatus)) {
$workStatus = $workStatus ? 1 : 0;
} else {
$workStatus = intval($workStatus);
}
if (!in_array($workStatus, array(0, 1))) {
$this->ajaxReturn(array('code' => 0, 'msg' => '工作状态值无效'));
}
$updateData['work_status'] = $workStatus;
}
// 工作开始时间
if (isset($data['start_time'])) {
$startTime = trim($data['start_time']);
if (!preg_match('/^([01]?[0-9]|2[0-3]):[0-5][0-9]$/', $startTime)) {
$this->ajaxReturn(array('code' => 0, 'msg' => '开始时间格式错误,应为HH:MM'));
}
$updateData['work_start_time'] = $startTime;
}
// 工作结束时间
if (isset($data['end_time'])) {
$endTime = trim($data['end_time']);
if (!preg_match('/^([01]?[0-9]|2[0-3]):[0-5][0-9]$/', $endTime)) {
$this->ajaxReturn(array('code' => 0, 'msg' => '结束时间格式错误,应为HH:MM'));
}
$updateData['work_end_time'] = $endTime;
}
// 自动接单配置
if (isset($data['auto_accept_config']) && is_array($data['auto_accept_config'])) {
$autoConfig = $data['auto_accept_config'];
// 自动接单开关
if (isset($autoConfig['auto_accept_order'])) {
$autoAccept = $autoConfig['auto_accept_order'];
if (is_bool($autoAccept)) {
$autoAccept = $autoAccept ? 1 : 0;
} else {
$autoAccept = intval($autoAccept);
}
if (!in_array($autoAccept, array(0, 1))) {
$this->ajaxReturn(array('code' => 0, 'msg' => '自动接单设置值无效'));
}
$updateData['auto_accept_order'] = $autoAccept;
}
// 最大接单距离
if (isset($autoConfig['max_distance'])) {
$maxDistance = floatval($autoConfig['max_distance']);
if ($maxDistance < 0 || $maxDistance > 50) {
$this->ajaxReturn(array('code' => 0, 'msg' => '最大接单距离应在0-50公里之间'));
}
$updateData['max_distance'] = $maxDistance;
}
// 最低配送费
if (isset($autoConfig['min_delivery_fee'])) {
$minDeliveryFee = floatval($autoConfig['min_delivery_fee']);
if ($minDeliveryFee < 0 || $minDeliveryFee > 999.99) {
$this->ajaxReturn(array('code' => 0, 'msg' => '最低配送费设置无效'));
}
$updateData['min_delivery_fee'] = $minDeliveryFee;
}
// 同时最大接单数量
if (isset($autoConfig['max_orders_per_time'])) {
$maxOrders = intval($autoConfig['max_orders_per_time']);
if ($maxOrders < 1 || $maxOrders > 10) {
$this->ajaxReturn(array('code' => 0, 'msg' => '同时最大接单数量应在1-10之间'));
}
$updateData['max_orders_per_time'] = $maxOrders;
}
// 接受的订单类型(自动接单用)
if (is_array($autoConfig['accept_order_types'])) {
$updateData['accept_order_types'] = implode(',', $autoConfig['accept_order_types']);
}
// 拒绝低评分商家
if (isset($autoConfig['reject_low_rating_store'])) {
$rejectLowRating = $autoConfig['reject_low_rating_store'];
if (is_bool($rejectLowRating)) {
$rejectLowRating = $rejectLowRating ? 1 : 0;
} else {
$rejectLowRating = intval($rejectLowRating);
}
if (!in_array($rejectLowRating, array(0, 1))) {
$this->ajaxReturn(array('code' => 0, 'msg' => '拒绝低评分商家设置值无效'));
}
$updateData['reject_low_rating_store'] = $rejectLowRating;
}
// 商家最低评分要求
if (isset($autoConfig['min_store_rating'])) {
$minRating = floatval($autoConfig['min_store_rating']);
if ($minRating < 0 || $minRating > 5) {
$this->ajaxReturn(array('code' => 0, 'msg' => '商家最低评分应在0-5之间'));
}
$updateData['min_store_rating'] = $minRating;
}
// 自动接单时间段
if (isset($autoConfig['start_time'])) {
$startTime = trim($autoConfig['start_time']);
if (!preg_match('/^([01]?[0-9]|2[0-3]):[0-5][0-9]$/', $startTime)) {
$this->ajaxReturn(array('code' => 0, 'msg' => '自动接单开始时间格式错误,应为HH:MM'));
}
$updateData['auto_accept_start_time'] = $startTime;
}
if (isset($autoConfig['end_time'])) {
$endTime = trim($autoConfig['end_time']);
if (!preg_match('/^([01]?[0-9]|2[0-3]):[0-5][0-9]$/', $endTime)) {
$this->ajaxReturn(array('code' => 0, 'msg' => '自动接单结束时间格式错误,应为HH:MM'));
}
$updateData['auto_accept_end_time'] = $endTime;
}
}
if (empty($updateData)) {
$this->ajaxReturn(array('code' => 0, 'msg' => '没有有效的设置项需要更新'));
}
$riderModel = M('rider_info');
$result = $riderModel->where(array('id' => $riderId))->save($updateData);
if ($result !== false) {
$this->ajaxReturn(array(
'code' => 1,
'msg' => '订单设置更新成功',
'data' => $updateData
));
} else {
$this->ajaxReturn(array('code' => 0, 'msg' => '订单设置更新失败'));
}
}
/**
* 获取银行卡列表
*/
public function getBankCards() {
// 检查骑手登录状态
if (!$this->riderId) {
$this->ajaxReturn(array(
'code' => 0,
'msg' => '请先登录'
));
}
try {
$bankCardModel = M('rider_bank_card');
$cards = $bankCardModel->where(array(
'rider_id' => $this->riderId,
'status' => 1
))->order('is_default DESC, add_time DESC')->select();
$list = array();
foreach ($cards as $card) {
$item = array(
'id' => intval($card['id']),
'holder_name' => $card['holder_name'],
'card_number' => $this->maskBankCard($card['card_number']),
'card_number_full' => $card['card_number'], // 完整卡号,用于提现
'bank_name' => $card['bank_name'],
'branch_name' => $card['branch_name'] ?: '',
'card_type' => intval($card['card_type']),
'card_type_text' => $this->getCardTypeText($card['card_type']),
'is_default' => intval($card['is_default']) === 1,
'add_time' => $card['add_time']
);
$list[] = $item;
}
$this->ajaxReturn(array(
'code' => 1,
'msg' => '获取成功',
'data' => $list
));
} catch (\Exception $e) {
\Think\Log::write("获取银行卡列表失败:" . $e->getMessage(), 'ERROR');
$this->ajaxReturn(array(
'code' => 0,
'msg' => '获取失败,请稍后重试'
));
}
}
/**
* 添加银行卡
*/
public function addBankCard() {
// 检查骑手登录状态
if (!$this->riderId) {
$this->ajaxReturn(array(
'code' => 0,
'msg' => '请先登录'
));
}
try {
// 获取请求参数
$holderName = $this->getRequestParam('holder_name', '', 'trim');
$cardNo = $this->getRequestParam('card_no', '', 'trim');
$bankName = $this->getRequestParam('bank_name', '', 'trim');
$branchName = $this->getRequestParam('branch_name', '', 'trim');
// 参数验证
if (empty($holderName)) {
$this->ajaxReturn(array('code' => 0, 'msg' => '请输入持卡人姓名'));
}
if (empty($cardNo)) {
$this->ajaxReturn(array('code' => 0, 'msg' => '请输入银行卡号'));
}
if (empty($bankName)) {
$this->ajaxReturn(array('code' => 0, 'msg' => '请输入开户银行'));
}
// 验证银行卡号格式
if (!preg_match('/^\d{16,19}$/', $cardNo)) {
$this->ajaxReturn(array('code' => 0, 'msg' => '银行卡号格式不正确'));
}
$bankCardModel = M('rider_bank_card');
// 检查是否已存在相同卡号
$existCard = $bankCardModel->where(array(
'rider_id' => $this->riderId,
'card_number' => $cardNo,
'status' => 1
))->find();
if ($existCard) {
$this->ajaxReturn(array('code' => 0, 'msg' => '该银行卡已存在'));
}
// 检查是否是第一张卡(设为默认)
$cardCount = $bankCardModel->where(array(
'rider_id' => $this->riderId,
'status' => 1
))->count();
$isDefault = $cardCount === 0 ? 1 : 0;
// 插入银行卡记录
$cardData = array(
'rider_id' => $this->riderId,
'holder_name' => $holderName,
'card_number' => $cardNo,
'bank_name' => $bankName,
'branch_name' => $branchName,
'card_type' => 1, // 默认储蓄卡
'is_default' => $isDefault,
'status' => 1,
'add_time' => date('Y-m-d H:i:s'),
'update_time' => date('Y-m-d H:i:s')
);
$cardId = $bankCardModel->add($cardData);
if ($cardId) {
// 返回新添加的银行卡信息
$newCard = array(
'id' => intval($cardId),
'holder_name' => $holderName,
'card_number' => $this->maskBankCard($cardNo),
'card_number_full' => $cardNo,
'bank_name' => $bankName,
'branch_name' => $branchName,
'card_type' => 1,
'card_type_text' => '储蓄卡',
'is_default' => $isDefault === 1,
'add_time' => $cardData['add_time']
);
$this->ajaxReturn(array(
'code' => 1,
'msg' => '添加成功',
'data' => $newCard
));
} else {
$this->ajaxReturn(array('code' => 0, 'msg' => '添加失败,请稍后重试'));
}
} catch (\Exception $e) {
\Think\Log::write("添加银行卡失败:" . $e->getMessage(), 'ERROR');
$this->ajaxReturn(array(
'code' => 0,
'msg' => '添加失败,请稍后重试'
));
}
}
/**
* 更新支付宝/微信账号信息
*/
public function updatePaymentAccount() {
// 检查骑手登录状态
if (!$this->riderId) {
$this->ajaxReturn(array(
'code' => 0,
'msg' => '请先登录'
));
}
try {
// 获取请求参数
$type = intval($this->getRequestParam('type', 0));
$name = $this->getRequestParam('name', '', 'trim');
$number = $this->getRequestParam('number', '', 'trim');
// 参数验证
if (!in_array($type, [2, 3])) {
$this->ajaxReturn(array('code' => 0, 'msg' => '账号类型错误'));
}
if (empty($name)) {
$this->ajaxReturn(array('code' => 0, 'msg' => '请输入账户姓名'));
}
if (empty($number)) {
$this->ajaxReturn(array('code' => 0, 'msg' => '请输入账号'));
}
// 验证姓名长度
if (mb_strlen($name) < 2 || mb_strlen($name) > 20) {
$this->ajaxReturn(array('code' => 0, 'msg' => '账户姓名长度应在2-20个字符之间'));
}
$riderModel = M('rider_info');
$updateData = array();
if ($type === 2) {
// 支付宝账号
// 验证支付宝账号格式(手机号或邮箱)
if (!preg_match('/^1[3-9]\d{9}$/', $number) && !filter_var($number, FILTER_VALIDATE_EMAIL)) {
$this->ajaxReturn(array('code' => 0, 'msg' => '请输入正确的支付宝账号(手机号或邮箱)'));
}
$updateData['alipay_name'] = $name;
$updateData['alipay_account'] = $number;
} else if ($type === 3) {
// 微信账号
// 验证微信账号格式(手机号或微信号)
if (!preg_match('/^1[3-9]\d{9}$/', $number) && !preg_match('/^[a-zA-Z][a-zA-Z0-9_-]{5,19}$/', $number)) {
$this->ajaxReturn(array('code' => 0, 'msg' => '请输入正确的微信账号(手机号或微信号)'));
}
$updateData['wechat_name'] = $name;
$updateData['wechat_account'] = $number;
}
$updateData['update_time'] = time();
// 更新数据库
$result = $riderModel->where(array('id' => $this->riderId))->save($updateData);
if ($result !== false) {
// 获取更新后的用户信息
$userInfo = $riderModel->where(array('id' => $this->riderId))->find();
$this->ajaxReturn(array(
'code' => 1,
'msg' => '更新成功',
'data' => array(
'type' => $type,
'name' => $name,
'number' => $number,
'alipay_name' => $userInfo['alipay_name'] ?: '',
'alipay_account' => $userInfo['alipay_account'] ?: '',
'wechat_name' => $userInfo['wechat_name'] ?: '',
'wechat_account' => $userInfo['wechat_account'] ?: '',
'default_withdraw_type' => intval($userInfo['default_withdraw_type'])
)
));
} else {
$this->ajaxReturn(array('code' => 0, 'msg' => '更新失败,请稍后重试'));
}
} catch (\Exception $e) {
\Think\Log::write("更新支付账号失败:" . $e->getMessage(), 'ERROR');
$this->ajaxReturn(array(
'code' => 0,
'msg' => '更新失败,请稍后重试'
));
}
}
/**
* 设置默认提现方式
*/
public function setDefaultWithdrawType() {
// 检查骑手登录状态
if (!$this->riderId) {
$this->ajaxReturn(array(
'code' => 0,
'msg' => '请先登录'
));
}
try {
// 获取请求参数
$type = intval($this->getRequestParam('type', 0));
// 参数验证
if (!in_array($type, [1, 2, 3])) {
$this->ajaxReturn(array('code' => 0, 'msg' => '提现方式类型错误'));
}
// 如果设置银行卡为默认,检查是否有银行卡
if ($type === 1) {
$bankCardModel = M('rider_bank_card');
$bankCardCount = $bankCardModel->where(array(
'rider_id' => $this->riderId,
'status' => 1
))->count();
if ($bankCardCount === 0) {
$this->ajaxReturn(array('code' => 0, 'msg' => '请先添加银行卡'));
}
}
// 如果设置支付宝为默认,检查是否已设置支付宝账号
if ($type === 2) {
$riderInfo = M('rider_info')->where(array('id' => $this->riderId))->find();
if (empty($riderInfo['alipay_account'])) {
$this->ajaxReturn(array('code' => 0, 'msg' => '请先设置支付宝账号'));
}
}
// 如果设置微信为默认,检查是否已设置微信账号
if ($type === 3) {
$riderInfo = M('rider_info')->where(array('id' => $this->riderId))->find();
if (empty($riderInfo['wechat_account'])) {
$this->ajaxReturn(array('code' => 0, 'msg' => '请先设置微信账号'));
}
}
$riderModel = M('rider_info');
$updateData = array(
'default_withdraw_type' => $type,
'update_time' => time()
);
// 更新数据库
$result = $riderModel->where(array('id' => $this->riderId))->save($updateData);
if ($result !== false) {
$typeNames = array(1 => '银行卡', 2 => '支付宝', 3 => '微信');
$this->ajaxReturn(array(
'code' => 1,
'msg' => '设置成功',
'data' => array(
'default_withdraw_type' => $type,
'type_name' => $typeNames[$type]
)
));
} else {
$this->ajaxReturn(array('code' => 0, 'msg' => '设置失败,请稍后重试'));
}
} catch (\Exception $e) {
\Think\Log::write("设置默认提现方式失败:" . $e->getMessage(), 'ERROR');
$this->ajaxReturn(array(
'code' => 0,
'msg' => '设置失败,请稍后重试'
));
}
}
/**
* 删除银行卡
*/
public function deleteBankCard() {
// 检查骑手登录状态
if (!$this->riderId) {
$this->ajaxReturn(array(
'code' => 0,
'msg' => '请先登录'
));
}
try {
$cardId = $this->getRequestParam('card_id', 0, 'intval');
if (!$cardId) {
$this->ajaxReturn(array('code' => 0, 'msg' => '请选择要删除的银行卡'));
}
$bankCardModel = M('rider_bank_card');
// 检查银行卡是否存在且属于当前骑手
$card = $bankCardModel->where(array(
'id' => $cardId,
'rider_id' => $this->riderId,
'status' => 1
))->find();
if (!$card) {
$this->ajaxReturn(array('code' => 0, 'msg' => '银行卡不存在'));
}
// 软删除银行卡
$result = $bankCardModel->where(array('id' => $cardId))->save(array(
'status' => 0,
'update_time' => date('Y-m-d H:i:s')
));
if ($result !== false) {
// 如果删除的是默认卡,需要设置其他卡为默认
if ($card['is_default'] == 1) {
$otherCard = $bankCardModel->where(array(
'rider_id' => $this->riderId,
'status' => 1,
'id' => array('neq', $cardId)
))->find();
if ($otherCard) {
$bankCardModel->where(array('id' => $otherCard['id']))->save(array(
'is_default' => 1,
'update_time' => date('Y-m-d H:i:s')
));
}
}
$this->ajaxReturn(array(
'code' => 1,
'msg' => '删除成功'
));
} else {
$this->ajaxReturn(array('code' => 0, 'msg' => '删除失败,请稍后重试'));
}
} catch (\Exception $e) {
\Think\Log::write("删除银行卡失败:" . $e->getMessage(), 'ERROR');
$this->ajaxReturn(array(
'code' => 0,
'msg' => '删除失败,请稍后重试'
));
}
}
/**
* 设置默认银行卡
*/
public function setDefaultBankCard() {
// 检查骑手登录状态
if (!$this->riderId) {
$this->ajaxReturn(array(
'code' => 0,
'msg' => '请先登录'
));
}
try {
$cardId = $this->getRequestParam('card_id', 0, 'intval');
if (!$cardId) {
$this->ajaxReturn(array('code' => 0, 'msg' => '请选择银行卡'));
}
$bankCardModel = M('rider_bank_card');
// 检查银行卡是否存在且属于当前骑手
$card = $bankCardModel->where(array(
'id' => $cardId,
'rider_id' => $this->riderId,
'status' => 1
))->find();
if (!$card) {
$this->ajaxReturn(array('code' => 0, 'msg' => '银行卡不存在'));
}
// 开启事务
$bankCardModel->startTrans();
try {
// 取消其他卡的默认状态
$bankCardModel->where(array(
'rider_id' => $this->riderId,
'status' => 1
))->save(array(
'is_default' => 0,
'update_time' => date('Y-m-d H:i:s')
));
// 设置当前卡为默认
$bankCardModel->where(array('id' => $cardId))->save(array(
'is_default' => 1,
'update_time' => date('Y-m-d H:i:s')
));
$bankCardModel->commit();
$this->ajaxReturn(array(
'code' => 1,
'msg' => '设置成功'
));
} catch (\Exception $e) {
$bankCardModel->rollback();
throw $e;
}
} catch (\Exception $e) {
\Think\Log::write("设置默认银行卡失败:" . $e->getMessage(), 'ERROR');
$this->ajaxReturn(array(
'code' => 0,
'msg' => '设置失败,请稍后重试'
));
}
}
/**
* 银行卡号脱敏
*/
private function maskBankCard($cardNumber) {
if (strlen($cardNumber) <= 8) {
return $cardNumber;
}
return substr($cardNumber, 0, 4) . '****' . substr($cardNumber, -4);
}
/**
* 获取卡片类型文本
*/
private function getCardTypeText($type) {
$types = array(
1 => '储蓄卡',
2 => '信用卡'
);
return isset($types[$type]) ? $types[$type] : '储蓄卡';
}
}