model = new OrderAftersaleModel; $this->orderModel = new OrderModel; } /** * 售后单列表 * * @return \think\Response */ public function index() { if (!$this->request->isAjax()) { return $this->view->fetch(); } // 查询主表是订单表 $orders = $this->orderModel->withTrashed()->sheepFilter()->with(['user', 'aftersales' => function ($query) { $query->removeOption('soft_delete'); }])->paginate(request()->param('list_rows', 10)); $this->success('获取成功', null, $orders); } // 获取数据类型 public function getType() { $type = $this->model->typeList(); $dispatchStatus = $this->model->dispatchStatusList(); $aftersaleStatus = $this->model->aftersaleStatusList(); $refundStatus = $this->model->refundStatusList(); $result = [ 'type' => $type, 'dispatch_status' => $dispatchStatus, 'aftersale_status' => $aftersaleStatus, 'refund_status' => $refundStatus, ]; $data = []; foreach ($result as $key => $list) { $data[$key][] = ['name' => '全部', 'type' => 'all']; foreach ($list as $k => $v) { $data[$key][] = [ 'name' => $v, 'type' => $k ]; } } $this->success('获取成功', null, $data); } /** * 售后单详情 * * @param $id * @return \think\Response */ public function detail($id) { if (!$this->request->isAjax()) { return $this->view->fetch(); } $aftersale = $this->model->withTrashed()->with(['user', 'order' => function ($query) { $query->removeOption('soft_delete'); }, 'logs'])->where('id', $id)->find(); if (!$aftersale) { $this->error(__('No Results were found')); } // 建议退款金额 $aftersale->suggest_refund_fee = $aftersale->suggest_refund_fee; // 多态关联 oper $morphs = [ 'user' => \app\admin\model\shopro\user\User::class, 'admin' => \app\admin\model\Admin::class, 'system' => \app\admin\model\Admin::class, ]; $aftersale['logs'] = morph_to($aftersale['logs'], $morphs, ['oper_type', 'oper_id']); $aftersale = $aftersale->toArray(); foreach ($aftersale['logs'] as &$log) { $log['oper'] = Operator::info($log['oper_type'], $log['oper'] ?? null); } $this->success('获取成功', null, $aftersale); } /** * 完成售后 */ public function completed($id) { $admin = $this->auth->getUserInfo(); $aftersale = $this->model->withTrashed()->canOper()->where('id', $id)->find(); if (!$aftersale) { $this->error('售后单不存在或不可完成'); } $order = $this->orderModel->withTrashed()->find($aftersale->order_id); $orderItem = OrderItemModel::find($aftersale->order_item_id); if (!$order || !$orderItem) { $this->error('订单或订单商品不存在'); } $aftersale = Db::transaction(function () use ($aftersale, $order, $orderItem, $admin) { $aftersale->aftersale_status = OrderAftersaleModel::AFTERSALE_STATUS_COMPLETED; // 售后完成 $aftersale->save(); // 增加售后单变动记录、 OrderAftersaleLogModel::add($order, $aftersale, $admin, 'admin', [ 'log_type' => 'completed', 'content' => '售后订单已完成', 'images' => [] ]); $orderItem->aftersale_status = OrderItemModel::AFTERSALE_STATUS_COMPLETED; $orderItem->save(); OrderActionModel::add($order, $orderItem, $admin, 'admin', '管理员完成售后'); // 售后单完成之后 $data = ['aftersale' => $aftersale, 'order' => $order, 'item' => $orderItem]; \think\Hook::listen('order_aftersale_completed', $data); return $aftersale; }); $this->success('操作成功', null, $aftersale); } /** * 拒绝售后 */ public function refuse($id = 0) { if (!$this->request->isAjax()) { return $this->view->fetch(); } $admin = $this->auth->getUserInfo(); $params = $this->request->param(); $this->svalidate($params, '.refuse'); $aftersale = $this->model->withTrashed()->canOper()->where('id', $id)->find(); if (!$aftersale) { $this->error('售后单不存在或不可拒绝'); } $order = $this->orderModel->withTrashed()->find($aftersale->order_id); $orderItem = OrderItemModel::find($aftersale->order_item_id); if (!$order || !$orderItem) { $this->error('订单或订单商品不存在'); } $aftersale = Db::transaction(function () use ($aftersale, $order, $orderItem, $params, $admin) { $aftersale->aftersale_status = OrderAftersaleModel::AFTERSALE_STATUS_REFUSE; // 售后拒绝 $aftersale->save(); // 增加售后单变动记录 OrderAftersaleLogModel::add($order, $aftersale, $admin, 'admin', [ 'log_type' => 'refuse', 'content' => $params['refuse_msg'], 'images' => [] ]); $orderItem->aftersale_status = OrderItemModel::AFTERSALE_STATUS_REFUSE; // 拒绝售后 $orderItem->save(); OrderActionModel::add($order, $orderItem, $admin, 'admin', '管理员拒绝订单售后:' . $params['refuse_msg']); // 售后单拒绝后 $data = ['aftersale' => $aftersale, 'order' => $order, 'item' => $orderItem]; \think\Hook::listen('order_aftersale_refuse', $data); return $aftersale; }); $this->success('操作成功', null, $aftersale); } /** * 同意退款 */ public function refund($id) { if (!$this->request->isAjax()) { return $this->view->fetch(); } $admin = $this->auth->getUserInfo(); $params = $this->request->param(); $this->svalidate($params, '.refund'); $refund_money = round(floatval($params['refund_money']), 2); $refund_type = $params['refund_type'] ?? 'back'; if ($refund_money <= 0) { $this->error('请输入正确的退款金额'); } $aftersale = $this->model->withTrashed()->canOper()->where('id', $id)->find(); if (!$aftersale) { $this->error('售后单不存在或不可退款'); } $order = $this->orderModel->withTrashed()->with('items')->find($aftersale->order_id); if (!$order) { $this->error('订单不存在'); } $items = $order->items; $items = array_column($items, null, 'id'); // 当前订单已退款总金额 $refunded_money = array_sum(array_column($items, 'refund_fee')); // 剩余可退款金额 $refund_surplus_money = bcsub($order->pay_fee, (string)$refunded_money, 2); // 如果退款金额大于订单支付总金额 if (bccomp((string)$refund_money, $refund_surplus_money, 2) === 1) { $this->error('退款总金额不能大于实际支付金额'); } $orderItem = $items[$aftersale['order_item_id']]; if (!$orderItem || in_array($orderItem['refund_status'], [ OrderItemModel::REFUND_STATUS_AGREE, OrderItemModel::REFUND_STATUS_COMPLETED, ])) { $this->error('订单商品已退款,不能重复退款'); } $aftersale = Db::transaction(function () use ($aftersale, $order, $orderItem, $refund_money, $refund_type, $refund_surplus_money, $admin) { $aftersale->aftersale_status = OrderAftersaleModel::AFTERSALE_STATUS_COMPLETED; // 售后同意 $aftersale->refund_status = OrderAftersaleModel::REFUND_STATUS_AGREE; // 同意退款 $aftersale->refund_fee = $refund_money; // 退款金额 $aftersale->save(); // 增加售后单变动记录 OrderAftersaleLogModel::add($order, $aftersale, $admin, 'admin', [ 'log_type' => 'refund', 'content' => '售后订单已退款', 'images' => [] ]); $orderItem->aftersale_status = OrderItemModel::AFTERSALE_STATUS_COMPLETED; $orderItem->save(); OrderActionModel::add($order, $orderItem, $admin, 'admin', '管理员同意售后退款'); // 开始退款 $orderRefund = new OrderRefund($order); $orderRefund->refund($orderItem, $refund_money, $admin, [ 'refund_type' => $refund_type, 'remark' => '管理员同意售后退款' ]); $data = ['aftersale' => $aftersale, 'order' => $order, 'item' => $orderItem]; \think\Hook::listen('order_aftersale_completed', $data); return $aftersale; }); $this->success('操作成功', null, $aftersale); } /** * 留言 */ public function addLog($id = 0) { if (!$this->request->isAjax()) { return $this->view->fetch(); } $admin = $this->auth->getUserInfo(); $params = $this->request->param(); $this->svalidate($params, '.add_log'); $aftersale = $this->model->withTrashed()->where('id', $id)->find(); if (!$aftersale) { $this->error('售后单不存在'); } $order = $this->orderModel->withTrashed()->with('items')->find($aftersale->order_id); if (!$order) { $this->error('订单不存在'); } $aftersale = Db::transaction(function () use ($order, $aftersale, $params, $admin) { if ($aftersale['aftersale_status'] == 0) { $aftersale->aftersale_status = OrderAftersaleModel::AFTERSALE_STATUS_ING; // 售后处理中 $aftersale->save(); } // 增加售后单变动记录 OrderAftersaleLogModel::add($order, $aftersale, $admin, 'admin', [ 'log_type' => 'add_log', 'content' => $params['content'], 'images' => $params['images'] ?? [] ]); return $aftersale; }); $this->success('操作成功', null, $aftersale); } }