// +---------------------------------------------------------------------- namespace App\Services\Common; use App\Models\AccountLogModel; use App\Models\ActionLogModel; use App\Models\GoodsModel; use App\Models\MemberModel; use App\Models\MessageModel; use App\Models\OrderModel; use App\Services\BaseService; use App\Services\RedisService; use Illuminate\Support\Facades\DB; /** * 订单管理-服务类 * @author laravel开发员 * @since 2020/11/11 * Class OrderService * @package App\Services\Common */ class OrderService extends BaseService { // 静态对象 protected static $instance = null; /** * 构造函数 * @author laravel开发员 * @since 2020/11/11 * OrderService constructor. */ public function __construct() { $this->model = new OrderModel(); } /** * 静态入口 * @return static|null */ public static function make() { if (!self::$instance) { self::$instance = (new static()); } return self::$instance; } /** * @param $params * @param int $pageSize * @return array */ public function getDataList($params, $pageSize = 15) { $query = $this->getQuery($params); $countModel = clone $query; $countModel1 = clone $query; $status = isset($params['status']) ? $params['status'] : 0; if($status==0){ $counts = [ 'status2'=> $countModel->where('a.status',2)->count('a.id'), 'status3'=> $countModel1->where('a.status',3)->count('a.id'), ]; }else { $counts = []; } $list = $query->select(['a.*']) ->orderBy('a.status', 'asc') ->orderBy('a.create_time', 'desc') ->orderBy('a.id', 'desc') ->paginate($pageSize > 0 ? $pageSize : 9999999); $list = $list ? $list->toArray() : []; if ($list) { foreach ($list['data'] as &$item) { $item['create_time'] = $item['create_time'] ? datetime($item['create_time'], 'Y-m-d H:i:s') : ''; $item['goods'] = isset($item['goods'])? $item['goods'] : []; $item['user'] = isset($item['user'])? $item['user'] : []; if($item['goods']){ $item['goods']['shipper_city'] = isset($item['goods']['shipper_city'])? $item['goods']['shipper_city'] : []; $item['goods']['shipper_district'] = isset($item['goods']['shipper_district'])? $item['goods']['shipper_district'] : []; $city = []; if(isset($item['goods']['shipper_city']['name']) && $item['goods']['shipper_city']['name']){ $city[] = $item['goods']['shipper_city']['name']; } if(isset($item['goods']['shipper_district']['name']) && $item['goods']['shipper_district']['name']){ $city[] = $item['goods']['shipper_district']['name']; } $item['goods']['shipper_area'] = ($city? implode(' ', $city) :''); $item['goods']['receiver_city'] = isset($item['goods']['receiver_city'])? $item['goods']['receiver_city'] : []; $item['goods']['receiver_district'] = isset($item['goods']['receiver_district'])? $item['goods']['receiver_district'] : []; $city = []; if(isset($item['goods']['receiver_city']['name']) && $item['goods']['receiver_city']['name']){ $city[] = $item['goods']['receiver_city']['name']; } if(isset($item['goods']['receiver_district']['name']) && $item['goods']['receiver_district']['name']){ $city[] = $item['goods']['receiver_district']['name']; } $item['goods']['receiver_area'] = ($city? implode(' ', $city) :''); } } // 消息已读 if($status>0){ MessageModel::where(['is_read'=>2,'type'=>5,'mark'=>1])->update(['is_read'=>1,'update_time'=>time()]); } } return [ 'pageSize' => $pageSize, 'total' => isset($counts['count']) ? $counts['count'] : 0, 'counts' => $counts, 'list' => isset($list['data']) ? $list['data'] : [] ]; } /** * 查询 * @param $params * @return \Illuminate\Database\Eloquent\Builder */ public function getQuery($params) { $where = ['a.mark' => 1]; $userId = isset($params['user_id']) ? $params['user_id'] : 0; return $this->model->with(['user','goods'])->from('orders as a') ->leftJoin('member as b', 'a.user_id', '=', 'b.id') ->leftJoin('goods as c', 'c.id', '=', 'a.goods_id') ->where($where) ->where(function ($query) use ($params) { $keyword = isset($params['keyword']) ? $params['keyword'] : ''; if ($keyword) { $query->where('a.order_no', 'like', "%{$keyword}%"); } // 接单人 $account = isset($params['account']) ? $params['account'] : ''; if ($account) { $query->where(function($query) use($account){ $query->where('b.nickname', 'like', "%{$account}%")->orWhere('b.mobile', 'like', "%{$account}%"); }); } // 商品 $goodsId = isset($params['goods_id']) ? intval($params['goods_id']) : 0; $goods = isset($params['goods']) ? trim($params['goods']) : ''; if ($goods) { $query->where(function($query) use($goods){ $query->where('c.goods_name', 'like', "%{$goods}%"); if(preg_match("/^(1[0-9]+|[1-9]+)$/", $goods)){ $query->where('a.goods_id', intval($goods)); }else{ $query->where('c.goods_name', 'like', "%{$goods}%"); } }); } if($goodsId>0){ $query->where('a.goods_id', intval($goodsId)); } }) ->where(function ($query) use ($params) { $status = isset($params['status']) ? $params['status'] : 0; if($status==0){ $query->whereIn('a.status',[2,3]); }else if($status){ $query->where('a.status', $status); } }) ->where(function ($query) use ($userId) { if($userId){ $query->where('a.user_id', '=', $userId); } }); } /** * 按日期统计订单数 * @param string $beginAt 开始时间 * @param string $endAt 结束时间 * @param int[] $status 状态:数组或数值 * @return mixed */ public function getCountByTime($beginAt='', $endAt='', $status=3) { $cacheKey = "caches:orders:count_{$status}_{$beginAt}_{$endAt}"; $data = RedisService::get($cacheKey); if($data){ return $data; } $where = ['mark' => 1]; $data = $this->model->where($where)->where(function($query) use($beginAt,$endAt,$status){ if($beginAt && $endAt){ $query->whereBetween('create_time', [strtotime($beginAt), strtotime($endAt)]); }else if($beginAt){ $query->where('create_time','>=', strtotime($beginAt)); } if($status && is_array($status)){ $query->whereIn('status',$status); }else if($status){ $query->where('status',$status); } })->count('id'); if($data){ RedisService::set($cacheKey, $data, rand(300, 600)); } return $data; } /** * 按日期统计订单金额 * @param string $beginAt 开始时间 * @param string $endAt 结束时间 * @param int[] $status 状态:数组或数值 * @return mixed */ public function getTotalByTime($beginAt='', $endAt='', $status=3) { $cacheKey = "caches:orders:total_{$status}_{$beginAt}_{$endAt}"; $data = RedisService::get($cacheKey); if($data){ return $data; } $where = ['mark' => 1]; $data = $this->model->where($where)->where(function($query) use($beginAt,$endAt,$status){ if($beginAt && $endAt){ $query->whereBetween('create_time', [strtotime($beginAt), strtotime($endAt)]); }else if($beginAt){ $query->where('create_time','>=', strtotime($beginAt)); } if($status && is_array($status)){ $query->whereIn('status',$status); }else if($status){ $query->where('status',$status); } })->sum('total'); if($data){ RedisService::set($cacheKey, $data, rand(300, 600)); } return $data; } /** * 添加或编辑 * @return array * @since 2020/11/11 * @author laravel开发员 */ public function edit() { $params = request()->post(); return parent::edit($params); // TODO: Change the autogenerated stub } /** * 订单审核 * @return bool */ public function confirm($adminId, $params) { $id = isset($params['id'])? intval($params['id']) : 0; $remark = isset($params['remark'])? trim($params['remark']) : ''; $info = $this->model->with(['user','goods'])->where(['id'=> $id,'mark'=>1])->first(); $userInfo = isset($info['user'])? $info['user'] : []; $goods = isset($info['goods'])? $info['goods'] : []; $status = isset($info['status'])? $info['status'] : 0; $orderUserId = isset($info['user_id'])? $info['user_id'] : 0; $goodsId = isset($info['goods_id'])? $info['goods_id'] : 0; if(empty($info) || empty($goods) || empty($userInfo) || $goodsId<=0 || $orderUserId<=0){ $this->error = '订单信息不存在或参数错误'; return false; } if($status != 1){ $this->error = '订单状态不可操作'; return false; } if($this->model->where(['goods_id'=> $goodsId,'status'=>3,'mark'=>1])->value('id')){ $this->error = '该货物订单已完成'; return false; } if($this->model->where(['goods_id'=> $goodsId,'status'=>2,'mark'=>1])->value('id')){ $this->error = '该货物存在订单进行中'; return false; } DB::beginTransaction(); if(!$this->model->where(['id'=> $id])->update(['status'=>2,'confirm_admin_id'=>$adminId,'confirm_at'=>date('Y-m-d H:i:s'),'remark'=> $remark,'update_time'=>time()])){ DB::rollBack(); $this->error = '订单审核失败'; return false; } $this->model->where(['goods_id'=> $goodsId,'status'=> 1])->whereNotIn('id',[$id])->update(['status'=>4,'confirm_admin_id'=>$adminId,'confirm_at'=>date('Y-m-d H:i:s'),'remark'=> '订单无效','update_time'=>time()]); if(!MemberModel::where(['id'=>$orderUserId])->update(['picker_order_num'=>DB::raw("picker_order_num + 1"),'update_time'=>time()])){ DB::rollBack(); $this->error = '订单审核失败'; return false; } if(!GoodsModel::where(['id'=>$goodsId])->update(['picker_status'=>2,'update_time'=>time()])){ DB::rollBack(); $this->error = '订单审核失败'; return false; } DB::commit(); $this->error = '订单审核成功'; return ['id'=> $id]; } /** * 订单取消 * @return bool */ public function cancel($adminId, $params) { $id = isset($params['id'])? intval($params['id']) : 0; $remark = isset($params['remark'])? trim($params['remark']) : ''; $info = $this->model->with(['user','goods'])->where(['id'=> $id,'mark'=>1])->first(); $userInfo = isset($info['user'])? $info['user'] : []; $goods = isset($info['goods'])? $info['goods'] : []; $status = isset($info['status'])? $info['status'] : 0; $orderUserId = isset($info['user_id'])? $info['user_id'] : 0; $goodsId = isset($info['goods_id'])? $info['goods_id'] : 0; if(empty($info) || empty($goods) || empty($userInfo) || $goodsId<=0 || $orderUserId<=0){ $this->error = '订单信息不存在或参数错误'; return false; } if($status ==4){ $this->error = '订单已完成'; return false; } DB::beginTransaction(); if(!$this->model->where(['id'=> $id])->update(['status'=>4,'confirm_admin_id'=>$adminId,'confirm_at'=>date('Y-m-d H:i:s'),'remark'=> $remark,'update_time'=>time()])){ DB::rollBack(); $this->error = '订单取消失败'; return false; } $pickerOrderNum = isset($userInfo['picker_order_num'])? $userInfo['picker_order_num'] : 0; if(!MemberModel::where(['id'=>$orderUserId])->update(['picker_order_num'=>$pickerOrderNum?DB::raw("picker_order_num - 1"): 0,'update_time'=>time()])){ DB::rollBack(); $this->error = '订单取消失败'; return false; } if(!GoodsModel::where(['id'=>$goodsId])->update(['picker_status'=>1,'update_time'=>time()])){ DB::rollBack(); $this->error = '订单取消失败'; return false; } DB::commit(); $this->error = '订单取消成功'; return ['id'=> $id]; } /** * 订单完成 * @return bool */ public function complete($adminId, $params) { $id = isset($params['id'])? intval($params['id']) : 0; $remark = isset($params['remark'])? trim($params['remark']) : ''; $info = $this->model->with(['user','goods'])->where(['id'=> $id,'mark'=>1])->first(); $userInfo = isset($info['user'])? $info['user'] : []; $goods = isset($info['goods'])? $info['goods'] : []; $status = isset($info['status'])? $info['status'] : 0; $orderUserId = isset($info['user_id'])? $info['user_id'] : 0; $goodsId = isset($info['goods_id'])? $info['goods_id'] : 0; $bonus = isset($info['bonus'])? $info['bonus'] : 0; if(empty($info) || empty($goods) || empty($userInfo) || $goodsId<=0 || $orderUserId<=0){ $this->error = '订单信息不存在或参数错误'; return false; } if($status != 2){ $this->error = '订单状态不可操作'; return false; } DB::beginTransaction(); if(!$this->model->where(['id'=> $id])->update(['status'=>3,'confirm_admin_id'=>$adminId,'confirm_at'=>date('Y-m-d H:i:s'),'remark'=> $remark,'update_time'=>time()])){ DB::rollBack(); $this->error = '订单确认完成失败'; return false; } // 收入结算 if($bonus>0){ $updateData = [ 'balance'=>DB::raw("balance + {$bonus}"), 'income_total'=>DB::raw("income_total + {$bonus}"), 'complete_order_num'=>DB::raw("complete_order_num + 1"), 'update_time'=>time() ]; if(!MemberModel::where(['id'=>$orderUserId])->update($updateData)){ DB::rollBack(); $this->error = '订单确认完成收入结算失败'; return false; } // 收入记录 $balance = isset($userInfo['balance'])? $userInfo['balance'] : 0; $log = [ 'user_id' => $orderUserId, 'source_order_no' => isset($info['order_no']) ? $info['order_no'] : '', 'type' => 1, 'money' => $bonus, 'before_money' => $balance, 'date'=> date('Y-m-d'), 'create_time' => time(), 'remark' => '订单收入', 'status' => 1, 'mark' => 1, ]; if(!AccountLogModel::insertGetId($log)){ DB::rollBack(); $this->error = '订单确认完成收入结算失败'; return false; } } if(!GoodsModel::where(['id'=>$goodsId])->update(['picker_status'=>3,'update_time'=>time()])){ DB::rollBack(); $this->error = '订单确认完成失败'; return false; } DB::commit(); $this->error = '订单确认完成成功'; return ['id'=> $id]; } /** * 删除 * @return array */ public function delete() { // 设置日志标题 ActionLogModel::setRecord(session('userId'), ['type' => 1, 'title' => "删除订单信息", 'content' => json_encode(request()->post(), 256), 'module' => 'admin']); ActionLogModel::record(); $this->model->where('mark', 0)->where('update_time', '<=', time() - 7 * 86400)->delete(); return parent::delete(); // TODO: Change the autogenerated stub } }