From 7c64ed4438ce36c4fec15e539f1be48024cf61dc Mon Sep 17 00:00:00 2001 From: 15090180611 <215509543@qq.com> Date: Thu, 5 Dec 2024 18:41:08 +0800 Subject: [PATCH] =?UTF-8?q?=E9=80=80=E6=AC=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../school/classes/order/service_order.php | 3 +- .../classes/order/service_order_log.php | 3 +- .../school/classes/order/ServiceOrder.php | 2 +- .../school/classes/order/ServiceOrderLog.php | 2 +- application/api/controller/Index.php | 56 ++ application/api/controller/school/Pay.php | 76 ++ .../api/controller/school/ServiceOrder.php | 37 +- .../controller/school/worker/ServiceOrder.php | 39 +- application/common/hooks.php | 21 + .../listener/serviceorder/OrderHook.php | 189 +++++ .../model/school/classes/ClassesLib.php | 6 +- .../model/school/classes/hourorder/Order.php | 13 +- .../school/classes/order/ServiceOrder.php | 716 +++++++++++++++++- .../school/classes/order/ServiceOrderLog.php | 24 +- .../school/classes/order/service_order.php | 3 +- .../classes/order/service_order_log.php | 3 +- .../school/classes/order/ServiceOrder.php | 2 +- .../school/classes/order/ServiceOrderLog.php | 2 +- .../school/classes/order/service_order.js | 2 +- .../school/classes/order/service_order_log.js | 2 +- .../school/classes/order/service_order.js | 2 +- .../school/classes/order/service_order_log.js | 2 +- 22 files changed, 1161 insertions(+), 44 deletions(-) diff --git a/application/admin/lang/zh-cn/school/classes/order/service_order.php b/application/admin/lang/zh-cn/school/classes/order/service_order.php index 1e81ee8..213eba4 100644 --- a/application/admin/lang/zh-cn/school/classes/order/service_order.php +++ b/application/admin/lang/zh-cn/school/classes/order/service_order.php @@ -21,7 +21,8 @@ return [ 'Service_stauts' => '售后处理状态', 'Service_stauts 1' => '待机构处理', 'Service_stauts 4' => '待用户确认', - 'Service_stauts 7' => '售后通过结单', + 'Service_stauts 7' => '售后通过结单中', + 'Service_stauts 10' => '售后通过结单', 'Service_stauts -3' => '售后驳回结单', 'Sales_type' => '结单类型', 'Sales_type -3' => '未结单', diff --git a/application/admin/lang/zh-cn/school/classes/order/service_order_log.php b/application/admin/lang/zh-cn/school/classes/order/service_order_log.php index c8accc7..04d5e2f 100644 --- a/application/admin/lang/zh-cn/school/classes/order/service_order_log.php +++ b/application/admin/lang/zh-cn/school/classes/order/service_order_log.php @@ -20,7 +20,8 @@ return [ 'Service_stauts' => '售后处理状态', 'Service_stauts 1' => '待机构处理', 'Service_stauts 4' => '待用户确认', - 'Service_stauts 7' => '售后通过结单', + 'Service_stauts 7' => '售后通过结单中', + 'Service_stauts 10' => '售后通过结单', 'Service_stauts -3' => '售后驳回结单', 'Sales_type' => '结单类型', 'Sales_type -3' => '未结单', diff --git a/application/admin/model/school/classes/order/ServiceOrder.php b/application/admin/model/school/classes/order/ServiceOrder.php index e491808..4fe0a4a 100644 --- a/application/admin/model/school/classes/order/ServiceOrder.php +++ b/application/admin/model/school/classes/order/ServiceOrder.php @@ -50,7 +50,7 @@ class ServiceOrder extends Model public function getServiceStautsList() { - return ['1' => __('Service_stauts 1'), '4' => __('Service_stauts 4'), '7' => __('Service_stauts 7'), '-3' => __('Service_stauts -3')]; + return ['1' => __('Service_stauts 1'), '4' => __('Service_stauts 4'), '7' => __('Service_stauts 7'),'10' => __('Service_stauts 10'), '-3' => __('Service_stauts -3')]; } public function getSalesTypeList() diff --git a/application/admin/model/school/classes/order/ServiceOrderLog.php b/application/admin/model/school/classes/order/ServiceOrderLog.php index dff936e..44e0c00 100644 --- a/application/admin/model/school/classes/order/ServiceOrderLog.php +++ b/application/admin/model/school/classes/order/ServiceOrderLog.php @@ -40,7 +40,7 @@ class ServiceOrderLog extends Model public function getServiceStautsList() { - return ['1' => __('Service_stauts 1'), '4' => __('Service_stauts 4'), '7' => __('Service_stauts 7'), '-3' => __('Service_stauts -3')]; + return ['1' => __('Service_stauts 1'), '4' => __('Service_stauts 4'), '7' => __('Service_stauts 7'),'10' => __('Service_stauts 10'), '-3' => __('Service_stauts -3')]; } public function getSalesTypeList() diff --git a/application/api/controller/Index.php b/application/api/controller/Index.php index a4a1a26..a3192f3 100644 --- a/application/api/controller/Index.php +++ b/application/api/controller/Index.php @@ -3,6 +3,7 @@ namespace app\api\controller; use app\common\controller\Api; +use app\common\model\school\Area; use app\common\model\style\HomeImages; /** @@ -75,5 +76,60 @@ class Index extends Api $this->success('',["upload_config"=>$upload_config,"base_info"=>$base_info,"home_data"=>$home_data]); } + /** + * @ApiTitle(省市区数据) + * @ApiSummary(省市区数据) + * @ApiRoute(/api/index/area) + * @ApiMethod(GET) + * @ApiReturn({ + "code" => 1, + "msg" => "获取成功", + "data" => {} + *}) + */ + public function area() + { + $data['provinceData'] = Area::where('level', 1)->order('id asc')->field('id as value, name as label, pid, level')->select(); + foreach ($data['provinceData'] as $k => $p) { + $data['cityData'][$k] = Area::where(['level' => 2, 'pid' => $p->value])->order('id asc')->field('id as value, name as label, pid, level')->select(); + foreach ($data['cityData'][$k] as $i => $c) { + $data['areaData'][$k][$i] = Area::where(['level' => 3, 'pid' => $c->value])->order('id asc')->field('id as value, name as label, pid, level')->select(); + } + } + $this->success('省市区', $data); + + } + + + /** + * @ApiTitle(省市区数据预加载接口) + * @ApiSummary(省市区数据预加载接口) + * @ApiRoute(/api/index/get_area) + * @ApiMethod(GET) + * @ApiParams(name = "province", type = "string",required=false,description = "省编号") + * @ApiParams(name = "city", type = "string",required=false,description = "市编号") + * @ApiReturn({ + "code" => 1, + "msg" => "获取成功", + "data" => {} + *}) + */ + public function get_area() + { + $province = $this->request->get('province/s', ''); //机构店铺id + $city = $this->request->get('city/s', ''); //机构店铺id + $model = new Area(); + if($province && !$city){ + $model = $model->where("pid",$province)->where("level",2); + }elseif ($city){ + $model = $model->where("pid",$city)->where("level",3); + }else{ + $model = $model->where("level",1); + } + $data = $model->order('id asc')->field('id as value, name as label, pid, level')->select(); + + $this->success('省市区', $data); + + } } diff --git a/application/api/controller/school/Pay.php b/application/api/controller/school/Pay.php index ba61630..9ee4416 100644 --- a/application/api/controller/school/Pay.php +++ b/application/api/controller/school/Pay.php @@ -243,5 +243,81 @@ class Pay extends Base } + public function notifyRefund($callback) + { + $pay = $this->getPay(); + + try { + $data = $pay->verify(null, true); // 是的,验签就这么简单! + + $result = $callback($data, $pay); + + // Log::debug('Wechat notify', $data->all()); + } catch (\Exception $e) { + // $e->getMessage(); + } + + return $result; + } + + + /** + * 退款成功回调 + */ + public function notifyr() + { + Log::write('notifyreturn-comein:'); + + $payment = $this->request->param('payment'); + $platform = $this->request->param('platform'); + + $config = Service::getConfig('wechat'); + + $notify_url = request()->domain() . '/api/school/pay/notifyr/payment/' . $payment . '/platform/' . $platform; + + $config['notify_url'] = $notify_url; + $pay = \Yansongda\Pay\Pay::wechat($config); + + try { + $data = $pay->verify(null, true); // 是的,验签就这么简单! + + Log::write('notifyr-result:' . json_encode($data)); + + $out_refund_no = $data['out_refund_no']; + $out_trade_no = $data['out_trade_no']; + + // 退款 + $this->refundFinish($out_trade_no, $out_refund_no,$platform); + + + return $pay->success()->send(); + // Log::debug('Wechat notify', $data->all()); + } catch (\Exception $e) { + Log::write('notifyreturn-error:' . json_encode($e->getMessage())); + } + return $pay->success()->send(); + } + + + private function refundFinish($out_trade_no, $out_refund_no,$platform) { + +// $order = Order::where('order_sn', $out_trade_no)->find(); +// $refundLog = \app\admin\model\shopro\order\RefundLog::where('refund_sn', $out_refund_no)->find(); +// +// if (!$order || !$refundLog || $refundLog->status != 0) { +// // 订单不存在,或者订单已退款 +// return true; +// } +// +// $item = \app\admin\model\shopro\order\OrderItem::where('id', $refundLog->order_item_id)->find(); +// +// Db::transaction(function () use ($order, $item, $refundLog) { +// \app\admin\model\shopro\order\Order::refundFinish($order, $item, $refundLog); +// }); + \app\common\model\school\classes\order\ServiceOrder::refundSuccess($out_refund_no,true); + return true; + } + + } \ No newline at end of file diff --git a/application/api/controller/school/ServiceOrder.php b/application/api/controller/school/ServiceOrder.php index d8c11da..25ce894 100644 --- a/application/api/controller/school/ServiceOrder.php +++ b/application/api/controller/school/ServiceOrder.php @@ -114,6 +114,8 @@ class ServiceOrder extends Base + + /** * @ApiTitle( 我的售后订单列表接口) * @ApiSummary(我的售后订单列表接口) @@ -122,7 +124,7 @@ class ServiceOrder extends Base * @ApiParams(name = "page", type = "string",required=true,description = "页数") * @ApiParams(name = "limit", type = "string",required=true,description = "条数") * @ApiParams(name = "status", type = "string",required=false,description = "状态搜索条件:售后状态:1=待处理,4=处理中,7=已结单,-3=已取消") - * @ApiParams(name = "service_stauts", type = "string",required=false,description = "售后处理状态:1=待机构处理,4=待用户确认,7=售后通过结单,-3=售后驳回结单") + * @ApiParams(name = "service_stauts", type = "string",required=false,description = "售后处理状态:1=待机构处理,4=待用户确认,7=售后通过结单中,10=售后结单完成,-3=售后驳回结单") * @ApiParams(name = "sales_type", type = "string",required=false,description = "结单类型:-3=未结单,1=机构驳回,4=用户驳回,7=平台驳回,10=成功退款") * @ApiParams(name = "classes_lib_id", type = "int",required=false,description = "课程id") * @ApiParams(name = "classes_order_id", type = "int",required=false,description = "课程订单id") @@ -198,7 +200,7 @@ class ServiceOrder extends Base * @ApiParams(name = "page", type = "string",required=true,description = "页数") * @ApiParams(name = "limit", type = "string",required=true,description = "条数") * @ApiParams(name = "status", type = "string",required=false,description = "状态搜索条件:售后状态:1=待处理,4=处理中,7=已结单,-3=已取消") - * @ApiParams(name = "service_stauts", type = "string",required=false,description = "售后处理状态:1=待机构处理,4=待用户确认,7=售后通过结单,-3=售后驳回结单") + * @ApiParams(name = "service_stauts", type = "string",required=false,description = "售后处理状态:1=待机构处理,4=待用户确认,7=售后通过结单中,10=售后结单完成,-3=售后驳回结单") * @ApiParams(name = "sales_type", type = "string",required=false,description = "结单类型:-3=未结单,1=机构驳回,4=用户驳回,7=平台驳回,10=成功退款") * @ApiParams(name = "classes_service_order_id", type = "int",required=false,description = "售后订单id") * @ApiReturn({ @@ -232,5 +234,36 @@ class ServiceOrder extends Base } + + /** + * @ApiTitle( 用户处理售后接口) + * @ApiSummary(用户处理售后接口) + * @ApiMethod(POST) + * @ApiParams(name = "order_no", type = "string",required=true,description = "售后订单id或售后订号") + * @ApiParams(name = "status", type = "string",required=true,description = "yes=同意,no=驳回") + * @ApiParams(name = "reject_reason", type = "string",required=false,description = "驳回原因") + * @ApiParams(name = "reject_images", type = "string",required=false,description = "(非必填)驳回图片说明:多图逗号拼接") + * @ApiReturn({ + * + *}) + */ + public function user_confirmation(){ + $user_id = 0; + $user = $this->auth->getUser();//登录用户 + if($user)$user_id = $user['id']; + $order_no = $this->request->post('order_no/s', ''); //订单号 + $status = $this->request->post('status/s', 0); //审核状态 + $reject_reason = $this->request->post('reject_reason/s', ''); + $reject_images = $this->request->post('reject_images/s', ''); + + try{ + //当前申请状态 + $res = $this->model->userConfirmation($order_no,$status,$reject_reason,$reject_images,$user_id,true,'user',$user_id,true); + }catch (\Throwable $e){ + $this->error($e->getMessage()); + } + $this->success('调用成功', $res); + } + } diff --git a/application/api/controller/school/worker/ServiceOrder.php b/application/api/controller/school/worker/ServiceOrder.php index 41d1d0e..94f3f53 100644 --- a/application/api/controller/school/worker/ServiceOrder.php +++ b/application/api/controller/school/worker/ServiceOrder.php @@ -66,7 +66,7 @@ class ServiceOrder extends Base * @ApiParams(name = "page", type = "string",required=true,description = "页数") * @ApiParams(name = "limit", type = "string",required=true,description = "条数") * @ApiParams(name = "status", type = "string",required=false,description = "状态搜索条件:售后状态:1=待处理,4=处理中,7=已结单,-3=已取消") - * @ApiParams(name = "service_stauts", type = "string",required=false,description = "售后处理状态:1=待机构处理,4=待用户确认,7=售后通过结单,-3=售后驳回结单") + * @ApiParams(name = "service_stauts", type = "string",required=false,description = "售后处理状态:1=待机构处理,4=待用户确认,7=售后通过结单中,10=售后结单完成,-3=售后驳回结单") * @ApiParams(name = "sales_type", type = "string",required=false,description = "结单类型:-3=未结单,1=机构驳回,4=用户驳回,7=平台驳回,10=成功退款") * @ApiParams(name = "classes_lib_id", type = "int",required=false,description = "课程id") * @ApiParams(name = "classes_order_id", type = "int",required=false,description = "课程订单id") @@ -140,7 +140,7 @@ class ServiceOrder extends Base * @ApiParams(name = "page", type = "string",required=true,description = "页数") * @ApiParams(name = "limit", type = "string",required=true,description = "条数") * @ApiParams(name = "status", type = "string",required=false,description = "状态搜索条件:售后状态:1=待处理,4=处理中,7=已结单,-3=已取消") - * @ApiParams(name = "service_stauts", type = "string",required=false,description = "售后处理状态:1=待机构处理,4=待用户确认,7=售后通过结单,-3=售后驳回结单") + * @ApiParams(name = "service_stauts", type = "string",required=false,description = "售后处理状态:1=待机构处理,4=待用户确认,7=售后通过结单中,10=售后结单完成,-3=售后驳回结单") * @ApiParams(name = "sales_type", type = "string",required=false,description = "结单类型:-3=未结单,1=机构驳回,4=用户驳回,7=平台驳回,10=成功退款") * @ApiParams(name = "classes_service_order_id", type = "int",required=false,description = "售后订单id") * @ApiReturn({ @@ -174,5 +174,40 @@ class ServiceOrder extends Base } + + + /** + * @ApiTitle( 机构处理售后接口) + * @ApiSummary(机构处理售后接口) + * @ApiMethod(POST) + * @ApiParams(name = "order_no", type = "string",required=true,description = "售后订单id或售后订号") + * @ApiParams(name = "status", type = "string",required=true,description = "yes=同意,no=驳回") + * @ApiParams(name = "price", type = "string",required=false,description = "同意的售后金额") + * @ApiParams(name = "reject_reason", type = "string",required=false,description = "驳回原因") + * @ApiParams(name = "reject_images", type = "string",required=false,description = "(非必填)驳回图片说明:多图逗号拼接") + * @ApiReturn({ + * + *}) + */ + public function shop_confirmation(){ + $user_id = 0; + $user = $this->auth->getUser();//登录用户 + if($user)$user_id = $user['id']; + $order_no = $this->request->post('order_no/s', ''); //订单号 + $status = $this->request->post('status/s', 0); //审核状态 + $price = $this->request->post('price/f', 0); + $reject_reason = $this->request->post('reject_reason/s', ''); + $reject_images = $this->request->post('reject_images/s', ''); + + try{ + //当前申请状态 + $res = $this->model->shopConfirmation($order_no,$status,$price,$reject_reason,$reject_images,0,true,'user',$user_id,true); + }catch (\Throwable $e){ + $this->error($e->getMessage()); + } + $this->success('调用成功', $res); + } + + } diff --git a/application/common/hooks.php b/application/common/hooks.php index 2856d63..64d0ef6 100644 --- a/application/common/hooks.php +++ b/application/common/hooks.php @@ -133,6 +133,27 @@ $serviceHooks = [ 'classes_serviceorder_cancel_after' => [ // 订单取消后 'app\\common\\listener\\serviceorder\\OrderHook' ], + 'classes_serviceorder_shop_confirm_after'=> [ // 课程订单售后机构处理后 + 'app\\common\\listener\\serviceorder\\OrderHook' + ], + 'classes_serviceorder_shop_reject_after'=> [ // 课程订单售后机构驳回后 + 'app\\common\\listener\\serviceorder\\OrderHook' + ], + 'classes_serviceorder_user_confirm_after'=> [ // 课程订单售后机构处理后 + 'app\\common\\listener\\serviceorder\\OrderHook' + ], + 'classes_serviceorder_user_reject_after'=> [ // 课程订单售后机构驳回后 + 'app\\common\\listener\\serviceorder\\OrderHook' + ], + + + 'classes_serviceorder_system_confirm_after'=> [ // 课程订单售后机构处理后 + 'app\\common\\listener\\serviceorder\\OrderHook' + ], + + 'classes_serviceorder_system_reject_after'=> [ // 课程订单售后机构驳回后 + 'app\\common\\listener\\serviceorder\\OrderHook' + ], ]; diff --git a/application/common/listener/serviceorder/OrderHook.php b/application/common/listener/serviceorder/OrderHook.php index cb9000e..89ac0ca 100644 --- a/application/common/listener/serviceorder/OrderHook.php +++ b/application/common/listener/serviceorder/OrderHook.php @@ -72,4 +72,193 @@ class OrderHook + + // 课程订单机构同意售后 + public function classesServiceorderShopConfirmAfter(&$params) + { + ['serviceorder' => $serviceorder,"user_id"=>$user_id,"oper_type"=>$oper_type,"oper_id"=>$oper_id] = $params; + + $detail = $serviceorder->detail; + //记录订单日志 + + $desc = "课程{$detail["title"]}订单机构已同意售后,待您确认售后金额是否同意"; + + $title = "课程订单机构同意售后"; + $mini_type = "aftercare"; + $to_type="user"; + $to_id = $serviceorder["user_id"]; + $status ="classes"; + $platform="user"; + $oper_id=0; + $oper_type="system"; + $params=[ + "event"=>"classes_serviceorder_shop_confirm_after", + "order_id"=>$serviceorder["id"], + "classes_order_id"=>$serviceorder["classes_order_id"], + "order_no"=>$serviceorder["order_no"], + ]; + Message::$event_name = $params["event"]; + Message::send($title,$desc,$mini_type,$to_id,$to_type,$status,$platform,$params,$oper_id,$oper_type); + + } + + + + // 课程订单机构售后驳回 + public function classesServiceorderShopRejectAfter(&$params) + { + ['serviceorder' => $serviceorder,"user_id"=>$user_id,"oper_type"=>$oper_type,"oper_id"=>$oper_id] = $params; + + $detail = $serviceorder->detail; + //记录订单日志 + + $desc = "课程{$detail["title"]}订单机构售后已驳回,原因:{$serviceorder["reject_reason"]}"; + + $title = "课程订单机构售后驳回"; + $mini_type = "aftercare"; + $to_type="user"; + $to_id = $serviceorder["user_id"]; + $status ="classes"; + $platform="user"; + $oper_id=0; + $oper_type="system"; + $params=[ + "event"=>"classes_serviceorder_shop_reject_after", + "order_id"=>$serviceorder["id"], + "classes_order_id"=>$serviceorder["classes_order_id"], + "order_no"=>$serviceorder["order_no"], + ]; + Message::$event_name = $params["event"]; + Message::send($title,$desc,$mini_type,$to_id,$to_type,$status,$platform,$params,$oper_id,$oper_type); + + } + + + + + + // 课程订单用户同意售后 + public function classesServiceorderUserConfirmAfter(&$params) + { + ['serviceorder' => $serviceorder,"user_id"=>$user_id,"oper_type"=>$oper_type,"oper_id"=>$oper_id] = $params; + + $detail = $serviceorder->detail; + //记录订单日志 + + $desc = "课程{$detail["title"]}订单用户已同意售后,系统正在结算资金中,请耐心等待"; + + $title = "课程订单用户售后已确认"; + $mini_type = "aftercare"; + $to_type="user"; + $to_id = $serviceorder["user_id"]; + $status ="classes"; + $platform="user"; + $oper_id=0; + $oper_type="system"; + $params=[ + "event"=>"classes_serviceorder_user_confirm_after", + "order_id"=>$serviceorder["id"], + "classes_order_id"=>$serviceorder["classes_order_id"], + "order_no"=>$serviceorder["order_no"], + ]; + Message::$event_name = $params["event"]; + Message::send($title,$desc,$mini_type,$to_id,$to_type,$status,$platform,$params,$oper_id,$oper_type); + + } + + + + // 课程订单用户售后驳回 + public function classesServiceorderUserRejectAfter(&$params) + { + ['serviceorder' => $serviceorder,"user_id"=>$user_id,"oper_type"=>$oper_type,"oper_id"=>$oper_id] = $params; + + $detail = $serviceorder->detail; + //记录订单日志 + + $desc = "课程{$detail["title"]}订单用户售后已驳回,原因:{$serviceorder["reject_reason"]}"; + + $title = "课程订单用户售后驳回"; + $mini_type = "aftercare"; + $to_type="user"; + $to_id = $serviceorder["user_id"]; + $status ="classes"; + $platform="user"; + $oper_id=0; + $oper_type="system"; + $params=[ + "event"=>"classes_serviceorder_user_reject_after", + "order_id"=>$serviceorder["id"], + "classes_order_id"=>$serviceorder["classes_order_id"], + "order_no"=>$serviceorder["order_no"], + ]; + Message::$event_name = $params["event"]; + Message::send($title,$desc,$mini_type,$to_id,$to_type,$status,$platform,$params,$oper_id,$oper_type); + + } + + + + + // 课程订单用户同意售后 + public function classesServiceorderSystemConfirmAfter(&$params) + { + ['serviceorder' => $serviceorder,"user_id"=>$user_id,"oper_type"=>$oper_type,"oper_id"=>$oper_id] = $params; + + $detail = $serviceorder->detail; + //记录订单日志 + + $desc = "课程{$detail["title"]}订单售后金额已原路退回到您的账户中{$serviceorder["real_refundprice"]}元,请注意查看"; + + $title = "课程订单售后金额已退回"; + $mini_type = "aftercare"; + $to_type="user"; + $to_id = $serviceorder["user_id"]; + $status ="classes"; + $platform="user"; + $oper_id=0; + $oper_type="system"; + $params=[ + "event"=>"classes_serviceorder_system_confirm_after", + "order_id"=>$serviceorder["id"], + "classes_order_id"=>$serviceorder["classes_order_id"], + "order_no"=>$serviceorder["order_no"], + ]; + Message::$event_name = $params["event"]; + Message::send($title,$desc,$mini_type,$to_id,$to_type,$status,$platform,$params,$oper_id,$oper_type); + + } + + + + // 课程订单用户售后驳回 + public function classesServiceorderSystemRejectAfter(&$params) + { + ['serviceorder' => $serviceorder,"user_id"=>$user_id,"oper_type"=>$oper_type,"oper_id"=>$oper_id] = $params; + + $detail = $serviceorder->detail; + //记录订单日志 + + $desc = "课程{$detail["title"]}订单售后记录异常,系统已强制终止售后,原因:{$serviceorder["reject_reason"]}"; + + $title = "课程订单异常系统终止售后"; + $mini_type = "aftercare"; + $to_type="user"; + $to_id = $serviceorder["user_id"]; + $status ="classes"; + $platform="user"; + $oper_id=0; + $oper_type="system"; + $params=[ + "event"=>"classes_serviceorder_system_reject_after", + "order_id"=>$serviceorder["id"], + "classes_order_id"=>$serviceorder["classes_order_id"], + "order_no"=>$serviceorder["order_no"], + ]; + Message::$event_name = $params["event"]; + Message::send($title,$desc,$mini_type,$to_id,$to_type,$status,$platform,$params,$oper_id,$oper_type); + + } + + } \ No newline at end of file diff --git a/application/common/model/school/classes/ClassesLib.php b/application/common/model/school/classes/ClassesLib.php index 5d3b5cb..94b128f 100644 --- a/application/common/model/school/classes/ClassesLib.php +++ b/application/common/model/school/classes/ClassesLib.php @@ -647,8 +647,8 @@ $user_unpaid_order = $user_paid_order =null; $selfetch = $selfetch->field($field); - if (isset($keyword) && $keyword) { - $selfetch = $selfetch->where("{$a}title|{$a}address|{$a}address_detail|{$a}address_city", 'like', '%' . $keyword . '%'); + if (isset($keywords) && $keywords) { + $selfetch = $selfetch->where("{$a}title|{$a}address|{$a}address_detail|{$a}address_city", 'like', '%' . $keywords . '%'); } if (isset($manystore_id) && $manystore_id) { @@ -1144,6 +1144,8 @@ $user_unpaid_order = $user_paid_order =null; //如果存在课程规格,验证每个课时规格的合法性 if(isset($params["spec"])){ + //如果存在"的HTML转义字符,先反转义再解析json + $params["spec"] = html_entity_decode($params["spec"]); $spec = json_decode($params["spec"],true); if(empty($spec))throw new \Exception("请至少添加一个课时规格"); diff --git a/application/common/model/school/classes/hourorder/Order.php b/application/common/model/school/classes/hourorder/Order.php index 587ac4b..8f5c101 100644 --- a/application/common/model/school/classes/hourorder/Order.php +++ b/application/common/model/school/classes/hourorder/Order.php @@ -1075,7 +1075,7 @@ class Order extends BaseModel * @throws \think\db\exception\ModelNotFoundException * @throws \think\exception\DbException */ - public static function checkOptionAuth($classes_order_id,$oper_id,$oper_type){ + public static function checkOptionAuth($classes_order_id,$oper_id,$oper_type,$only_user=false,$only_shop=false,$only_admin=false){ //课程是否存在并上架 $classesOrder = \app\common\model\school\classes\order\Order::where("id",$classes_order_id)->find(); @@ -1083,14 +1083,21 @@ class Order extends BaseModel switch ($oper_type) { case 'user': + if($only_admin)throw new \Exception("您无权操作该订单!"); + //自己或操作员 if($oper_id != $classesOrder["user_id"]){ + if($only_user) throw new \Exception("您无权操作该订单!"); //说明是操作员 $help_user_info = User::where('id',$oper_id)->find(); if(!$help_user_info) throw new \Exception("代下单员工不存在!"); $classes_lib_ids = (new ClassesLib)->getClassesAuthIds($oper_id); //判断当前订单课程是否在此课程授权范围内 if(!in_array($classesOrder["classes_lib_id"],$classes_lib_ids)) throw new \Exception("该课程不在您的授权范围内,无法代操作!"); + }else{ + $classes_lib_ids = (new ClassesLib)->getClassesAuthIds($oper_id); + //不是员工并且想操作只有机构能操作的单 + if(!in_array($classesOrder["classes_lib_id"],$classes_lib_ids) && $only_shop)throw new \Exception("您无权操作该订单!"); } break; case 'admin': @@ -1098,6 +1105,10 @@ class Order extends BaseModel if(!$admin_info) throw new \Exception("代下单管理员不存在!"); break; case 'shop': + if($only_admin)throw new \Exception("您无权操作该订单!"); + + if($only_user) throw new \Exception("您无权操作该订单!"); + $admin_info = Manystore::where('id',$oper_id)->find(); if(!$admin_info) throw new \Exception("代下单管理员不存在!"); $classes_lib_ids = ClassesLib::where("manystore_id",$oper_id)->column("id"); diff --git a/application/common/model/school/classes/order/ServiceOrder.php b/application/common/model/school/classes/order/ServiceOrder.php index a1da81e..1d7048d 100644 --- a/application/common/model/school/classes/order/ServiceOrder.php +++ b/application/common/model/school/classes/order/ServiceOrder.php @@ -3,6 +3,7 @@ namespace app\common\model\school\classes\order; +use addons\epay\library\Service; use app\admin\model\Admin; use app\common\model\BaseModel; use app\common\model\dyqc\ManystoreShop; @@ -13,6 +14,11 @@ use app\common\model\User; use app\manystore\model\Manystore; use think\Model; use traits\model\SoftDelete; +use think\Session; +use Yansongda\Pay\Exceptions\GatewayException; +use Yansongda\Pay\Pay; + + class ServiceOrder extends BaseModel { @@ -55,7 +61,7 @@ class ServiceOrder extends BaseModel public function getServiceStautsList() { - return ['1' => __('Service_stauts 1'), '4' => __('Service_stauts 4'), '7' => __('Service_stauts 7'), '-3' => __('Service_stauts -3')]; + return ['1' => __('Service_stauts 1'), '4' => __('Service_stauts 4'), '7' => __('Service_stauts 7'),'10' => __('Service_stauts 10'), '-3' => __('Service_stauts -3')]; } public function getSalesTypeList() @@ -174,6 +180,23 @@ class ServiceOrder extends BaseModel } + public function getRejectImagesAttr($value, $data) + { + $imagesArray = []; + if (!empty($value)) { + $imagesArray = explode(',', $value); + foreach ($imagesArray as &$v) { + $v = cdnurl($v, true); + } + return $imagesArray; + } + return $imagesArray; + } + + + + + public function classesorder() { return $this->belongsTo(Order::class, 'classes_order_id', 'id', [], 'LEFT')->setEagerlyType(0); @@ -366,8 +389,10 @@ class ServiceOrder extends BaseModel $classes_order_data["classes_service_order_id"] = $serverorder["id"]; //更新课程订单 $classes_order->allowField(true)->save($classes_order_data); + //记录订单日志 - ServiceOrderLog::log($classes_order['id'],$mark ?:"售后单申请已提交,等待商家处理",$oper_type,$oper_id); + ServiceOrderLog::log($serverorder['id'],$mark ?:"售后单申请已提交,等待商家处理",$oper_type,$oper_id); + //7事件 $data = ['serviceorder' => $serverorder,"oper_type"=>$oper_type,"oper_id"=>$oper_id]; \think\Hook::listen('classes_serviceorder_create_after', $data); @@ -449,9 +474,11 @@ class ServiceOrder extends BaseModel if($order_info) throw new \Exception("订单已生成,如需重新下单请退出页面重新进入!"); } $user_id = $classes_order["user_id"]; + + //校验订单参数 //操作人权限验证 - self::checkOptionAuth($classes_order["id"],$oper_id ?:$user_id,$oper_type); + self::checkOptionAuth($classes_order["id"],$oper_id ?:$user_id,$oper_type,true); //免费单无法申请售后 if($classes_order["payprice"]==0 && $classes_order["totalprice"] == 0 ) throw new \Exception("免费课程无法申请售后!"); @@ -472,7 +499,7 @@ class ServiceOrder extends BaseModel } - /** 课程售后操作权限检测 + /** 课时订单操作权限检测 * @param $order 订单 * @param $oper_id 操作人id * @param $oper_type 操作人类型:user-用户或员工,admin-管理员 @@ -481,7 +508,7 @@ class ServiceOrder extends BaseModel * @throws \think\db\exception\ModelNotFoundException * @throws \think\exception\DbException */ - public static function checkOptionAuth($classes_order_id,$oper_id,$oper_type){ + public static function checkOptionAuth($classes_order_id,$oper_id,$oper_type,$only_user=false,$only_shop=false,$only_admin=false){ //课程是否存在并上架 $classesOrder = \app\common\model\school\classes\order\Order::where("id",$classes_order_id)->find(); @@ -489,14 +516,21 @@ class ServiceOrder extends BaseModel switch ($oper_type) { case 'user': + if($only_admin)throw new \Exception("您无权操作该订单!"); + //自己或操作员 if($oper_id != $classesOrder["user_id"]){ + if($only_user) throw new \Exception("您无权操作该订单!"); //说明是操作员 $help_user_info = User::where('id',$oper_id)->find(); if(!$help_user_info) throw new \Exception("代下单员工不存在!"); $classes_lib_ids = (new ClassesLib)->getClassesAuthIds($oper_id); //判断当前订单课程是否在此课程授权范围内 if(!in_array($classesOrder["classes_lib_id"],$classes_lib_ids)) throw new \Exception("该课程不在您的授权范围内,无法代操作!"); + }else{ + $classes_lib_ids = (new ClassesLib)->getClassesAuthIds($oper_id); + //不是员工并且想操作只有机构能操作的单 + if(!in_array($classesOrder["classes_lib_id"],$classes_lib_ids) && $only_shop)throw new \Exception("您无权操作该订单!"); } break; case 'admin': @@ -504,9 +538,13 @@ class ServiceOrder extends BaseModel if(!$admin_info) throw new \Exception("代下单管理员不存在!"); break; case 'shop': + if($only_admin)throw new \Exception("您无权操作该订单!"); + + if($only_user) throw new \Exception("您无权操作该订单!"); + $admin_info = Manystore::where('id',$oper_id)->find(); if(!$admin_info) throw new \Exception("代下单管理员不存在!"); - $classes_lib_ids = ClassesLib::where("manystore_id",$oper_id)->column("id"); + $classes_lib_ids = ClassesLib::where("manystore_id",$oper_id)->column("id"); //判断当前订单课程是否在此课程授权范围内 if(!in_array($classesOrder["classes_lib_id"],$classes_lib_ids)) throw new \Exception("该课程不在您的授权范围内,无法代操作!"); @@ -584,7 +622,7 @@ class ServiceOrder extends BaseModel $order = self::getHaveCancelOrder($order_no); if($check){ //用户操作权限检测 - \app\common\model\school\classes\hourorder\Order::checkOptionAuth($order['id'],$user_id ?: $oper_id,$oper_type); + self::checkOptionAuth($order['classes_order_id'],$user_id ?: $oper_id,$oper_type,true); } @@ -659,10 +697,10 @@ class ServiceOrder extends BaseModel } - if (isset($whereData['status'])) $model = $model->where("{$alisa}status", 'in', $whereData['status']); + if (isset($whereData['status']) && $whereData['status']) $model = $model->where("{$alisa}status", 'in', $whereData['status']); - if (isset($whereData['service_stauts'])) $model = $model->where("{$alisa}service_stauts", 'in', $whereData['service_stauts']); - if (isset($whereData['sales_type'])) $model = $model->where("{$alisa}sales_type", 'in', $whereData['sales_type']); + if (isset($whereData['service_stauts']) && $whereData['service_stauts']) $model = $model->where("{$alisa}service_stauts", 'in', $whereData['service_stauts']); + if (isset($whereData['sales_type']) && $whereData['sales_type']) $model = $model->where("{$alisa}sales_type", 'in', $whereData['sales_type']); if (isset($whereData['not_status'])) $model = $model->where("{$alisa}status", 'not in', $whereData['not_status']); if (isset($whereData['keywords'])&&$whereData['keywords']) $model = $model->where("{$alisa}order_no|{$alisa}id|{$alisa}reason", '=', $whereData['keywords']); @@ -768,20 +806,72 @@ class ServiceOrder extends BaseModel + + /**得到机构售后提交确认订单 + * @param $order_no + * @return array|false|\PDOStatement|string|Model + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public static function getHaveShopConfirmationOrder($order_no){ +// $where = [self::STATUS_NOPAY,self::STATUS_PAYED]; + $order = self::where('order_no|id',$order_no) + ->where("status","in",['1']) + ->where("service_stauts","in",['1']) + ->find(); + if(!$order)throw new \Exception("只有待机构确认订单可提交!"); + + return $order; + } + + + /**机构售后提交确认信息 * @param $order_no * @param int $user_id + * @param string $status yes同意 no拒绝 + *@param string $price 商定价格 + *@param string $reject_reason 拒绝原因 + *@param string $reject_images 拒绝图片说明 * @param bool $check * @param bool $trans * @return bool * @throws \Exception */ - public function shopConfirmation($order_no,$user_id=0,$check=false,$oper_type='user',$oper_id=0,$trans=false){ + public function shopConfirmation($order_no,$status,$price,$reject_reason,$reject_images,$user_id=0,$check=false,$oper_type='user',$oper_id=0,$trans=false){ //得到机构售后提交确认订单 $order = self::getHaveShopConfirmationOrder($order_no); if($check){ //用户操作权限检测 - \app\common\model\school\classes\hourorder\Order::checkOptionAuth($order['id'],$user_id ?: $oper_id,$oper_type); + self::checkOptionAuth($order['classes_order_id'],$user_id ?: $oper_id,$oper_type,false,true); + } + $classesorder = $order->classesorder; + if(!$classesorder)throw new \Exception("订单不存在!"); + switch ($status){ + case 'yes': + //同意 + //验证价格正确性 + //金额必须小于等于剩余未退全额 + $price = floatval($price); + if($price > $classesorder['sub_refundprice']){ + throw new \Exception("价格必须小于等于剩余应退全额!"); + } + //数据修正大于剩余未退全额 则等于剩余未退 + $price = $price > $classesorder['sub_refundprice'] ? $classesorder['sub_refundprice'] : $price; + if($price<=0)throw new \Exception("同意退款必须大于0!"); + + break; + case 'no': + //拒绝 + //拒绝原因必填 + if(!$reject_reason)throw new \Exception("拒绝原因必填!"); + + + + break; + default: + throw new \Exception("参数错误!"); } @@ -793,20 +883,54 @@ class ServiceOrder extends BaseModel try{ //事务逻辑 //更新售后为取消状态 - $order = self::updateCancel($order); - //还原课程订单 - self::orderRestore($order["classes_order_id"]); - //插入订单取消日志 + switch ($status){ + case 'yes': + //同意 + + //更新订单状态为同意 + $order = self::updateShopConfirmationOrder($order,$price); + + //插入订单日志 if(!$user_id ||$order["user_id"] !=$user_id ){ - ServiceOrderLog::log($order['id'],"[系统操作]课程订单已取消售后",$oper_type ?: 'user', $oper_id ?: $order['user_id']); + ServiceOrderLog::log($order['id'],"[系统操作]课程订单售后机构已处理,待用户同意",$oper_type ?: 'user', $oper_id ?: $order['user_id']); }else{ - ServiceOrderLog::log($order['id'],"课程订单已取消售后",$oper_type ?: 'user', $oper_id ?: $order['user_id']); + ServiceOrderLog::log($order['id'],"课程订单售后机构已处理,待用户同意",$oper_type ?: 'user', $oper_id ?: $order['user_id']); } //调用订单取消事件 $data = ['serviceorder' => $order,"user_id"=>$user_id,"oper_type"=>$oper_type,"oper_id"=>$oper_id]; - \think\Hook::listen('classes_serviceorder_cancel_after', $data); - //执行课时数更新 + \think\Hook::listen('classes_serviceorder_shop_confirm_after', $data); + + + break; + case 'no': + //拒绝 + + //更新 + //更新售后为机构驳回结单状态 + $order = self::updateShopRejectCancel($order,$reject_reason,$reject_images); + //还原课程订单 + self::orderRestore($order["classes_order_id"]); + + + + //插入订单日志 + if(!$user_id ||$order["user_id"] !=$user_id ){ + ServiceOrderLog::log($order['id'],"[系统操作]课程订单售后机构驳回",$oper_type ?: 'user', $oper_id ?: $order['user_id']); + }else{ + ServiceOrderLog::log($order['id'],"课程订单售后机构驳回",$oper_type ?: 'user', $oper_id ?: $order['user_id']); + } + + //调用订单取消事件 + $data = ['serviceorder' => $order,"user_id"=>$user_id,"oper_type"=>$oper_type,"oper_id"=>$oper_id]; + \think\Hook::listen('classes_serviceorder_shop_reject_after', $data); + + + break; + default: + throw new \Exception("参数错误!"); + } + //执行课时数更新 $res1 = order::statisticsAndUpdateClassesNumber($order['classes_order_id']); @@ -824,4 +948,556 @@ class ServiceOrder extends BaseModel + /**机构同意并确认价格 + * @param $order + * @return array|false|\PDOStatement|string|Model + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public static function updateShopConfirmationOrder($order,$price){ + if(is_string($order))$order = self::getHaveShopConfirmationOrder($order); + $order->status = "4";//refund_status + $order->service_stauts = "4"; + $order->sales_type = "-3"; + $order->tbc_price = $price; + $order->handletime = time(); + $order->save(); + return $order; + } + + + + /** 售后驳回结单 + * @param $order + * @return array|false|\PDOStatement|string|Model + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public static function updateShopRejectCancel($order,$reject_reason,$reject_images){ + if(is_string($order))$order = self::getHaveShopConfirmationOrder($order); + $order->status = "7";//refund_status + $order->service_stauts = "-3"; + $order->sales_type = "1"; + $order->reject_reason = $reject_reason; + $order->reject_images = $reject_images; + $order->rejecttime = time(); + $order->checkouttime = time(); + $order->save(); + return $order; + } + + + + + + /**得到机构售后提交确认订单 + * @param $order_no + * @return array|false|\PDOStatement|string|Model + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public static function getHaveUserConfirmationOrder($order_no){ +// $where = [self::STATUS_NOPAY,self::STATUS_PAYED]; + $order = self::where('order_no|id',$order_no) + ->where("status","in",['4']) + ->where("service_stauts","in",['4']) + ->find(); + if(!$order)throw new \Exception("只有待用户确认订单可提交!"); + + return $order; + } + + + + + /**用户同意并确认价格 + * @param $order + * @return array|false|\PDOStatement|string|Model + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public static function updateUserConfirmationOrder($order){ + if(is_string($order))$order = self::getHaveUserConfirmationOrder($order); + $order->status = "4";//refund_status + $order->service_stauts = "7"; + $order->sales_type = "-3"; + $order->c_price = $order->tbc_price; + $order->confirmtime = time(); + $order->save(); + return $order; + } + + + + /** 用户售后驳回结单 + * @param $order + * @return array|false|\PDOStatement|string|Model + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public static function updateUserRejectCancel($order,$reject_reason,$reject_images){ + if(is_string($order))$order = self::getHaveUserConfirmationOrder($order); + $order->status = "7";//refund_status + $order->service_stauts = "-3"; + $order->sales_type = "4"; + $order->reject_reason = $reject_reason; + $order->reject_images = $reject_images; + $order->rejecttime = time(); + $order->checkouttime = time(); + $order->save(); + return $order; + } + + + + + + /**用户售后提交确认信息 + * @param $order_no + * @param int $user_id + * @param string $status yes同意 no拒绝 + *@param string $reject_reason 拒绝原因 + *@param string $reject_images 拒绝图片说明 + * @param bool $check + * @param bool $trans + * @return bool + * @throws \Exception + */ + public function userConfirmation($order_no,$status,$reject_reason,$reject_images,$user_id=0,$check=false,$oper_type='user',$oper_id=0,$trans=false){ + //得到机构售后提交确认订单 + $order = self::getHaveUserConfirmationOrder($order_no); + if($check){ + //用户操作权限检测 + self::checkOptionAuth($order['classes_order_id'],$user_id ?: $oper_id,$oper_type,true); + } + $classesorder = $order->classesorder; + if(!$classesorder)throw new \Exception("订单不存在!"); + switch ($status){ + case 'yes': + //同意 + + break; + case 'no': + //拒绝 + //拒绝原因必填 + if(!$reject_reason)throw new \Exception("拒绝原因必填!"); + + + break; + default: + throw new \Exception("参数错误!"); + } + + + //判断逻辑 + if($trans){ + self::beginTrans(); + } + $res = true; + try{ + //事务逻辑 + //更新售后为取消状态 + switch ($status){ + case 'yes': + //同意 + + //更新订单状态为同意 + $order = self::updateUserConfirmationOrder($order); + + //插入订单日志 + if(!$user_id ||$order["user_id"] !=$user_id ){ + ServiceOrderLog::log($order['id'],"[系统操作]课程订单售后用户已同意售后退款,系统退款结算中",$oper_type ?: 'user', $oper_id ?: $order['user_id']); + }else{ + ServiceOrderLog::log($order['id'],"课程订单售后用户已同意售后退款,系统退款结算中",$oper_type ?: 'user', $oper_id ?: $order['user_id']); + } + + //调用订单取消事件 + $data = ['serviceorder' => $order,"user_id"=>$user_id,"oper_type"=>$oper_type,"oper_id"=>$oper_id]; + \think\Hook::listen('classes_serviceorder_user_confirm_after', $data); + + + break; + case 'no': + //拒绝 + + //更新 + //更新售后为机构驳回结单状态 + $order = self::updateUserRejectCancel($order,$reject_reason,$reject_images); + //还原课程订单 + self::orderRestore($order["classes_order_id"]); + + + //插入订单日志 + if(!$user_id ||$order["user_id"] !=$user_id ){ + ServiceOrderLog::log($order['id'],"[系统操作]课程订单售后用户驳回",$oper_type ?: 'user', $oper_id ?: $order['user_id']); + }else{ + ServiceOrderLog::log($order['id'],"课程订单售后用户驳回",$oper_type ?: 'user', $oper_id ?: $order['user_id']); + } + + //调用订单取消事件 + $data = ['serviceorder' => $order,"user_id"=>$user_id,"oper_type"=>$oper_type,"oper_id"=>$oper_id]; + \think\Hook::listen('classes_serviceorder_user_reject_after', $data); + + + break; + default: + throw new \Exception("参数错误!"); + } + //执行课时数更新 + $res1 = order::statisticsAndUpdateClassesNumber($order['classes_order_id']); + + + if($trans){ + self::commitTrans(); + } + }catch (\Exception $e){ + if($trans){ + self::rollbackTrans(); + } + throw new \Exception($e->getMessage()); + } + return $res1; + } + + + + /**得到机构售后提交确认订单 + * @param $order_no + * @return array|false|\PDOStatement|string|Model + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public static function getHaveAdminConfirmationOrder($order_no){ +// $where = [self::STATUS_NOPAY,self::STATUS_PAYED]; + $order = self::where('order_no|id',$order_no) + ->where("status","in",['4']) + ->where("service_stauts","in",['7']) + ->find(); + if(!$order)throw new \Exception("只有售后通过待结算订单可提交!"); + + return $order; + } + + + /**平台同意并发放退款金额 + * @param $order + * @return array|false|\PDOStatement|string|Model + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public static function updateAdminConfirmationOrder($order,$pay_json=[]){ + if(is_string($order))$order = self::getHaveAdminConfirmationOrder($order); + $order->status = "7";//refund_status + $order->service_stauts = "10"; + $order->sales_type = "10"; + $order->real_refundprice = $order->c_price; + $order->sub_refundprice = bcsub($order->sub_refundprice,$order->real_refundprice,2); + $order->refundtime = time(); + $order->checkouttime = time(); + $order->pay_json = $pay_json; + $order->save(); + return $order; + } + + + + /** 平台售后驳回结单 + * @param $order + * @return array|false|\PDOStatement|string|Model + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public static function updateAdminRejectCancel($order,$reject_reason,$reject_images){ + if(is_string($order))$order = self::getHaveAdminConfirmationOrder($order); + $order->status = "7";//refund_status + $order->service_stauts = "-3"; + $order->sales_type = "7"; + $order->reject_reason = $reject_reason; + $order->reject_images = $reject_images; + $order->rejecttime = time(); + $order->checkouttime = time(); + $order->save(); + return $order; + } + + + + /**平台售后提交确认信息 + * @param $order_no + * @param int $user_id + * @param string $status yes同意 no拒绝 + *@param string $reject_reason 拒绝原因 + *@param string $reject_images 拒绝图片说明 + * @param bool $check + * @param bool $trans + * @return bool + * @throws \Exception + */ + public function adminConfirmation($order_no,$status,$reject_reason,$reject_images,$user_id=0,$check=false,$oper_type='user',$oper_id=0,$trans=false){ + //得到机构售后提交确认订单 + $order = self::getHaveAdminConfirmationOrder($order_no); + if($check){ + //用户操作权限检测 + self::checkOptionAuth($order['classes_order_id'],$user_id ?: $oper_id,$oper_type,true); + } + $classesorder = $order->classesorder; + if(!$classesorder)throw new \Exception("订单不存在!"); + switch ($status){ + case 'yes': + //同意 + + break; + case 'no': + //拒绝 + //拒绝原因必填 + if(!$reject_reason)throw new \Exception("拒绝原因必填!"); + + + break; + default: + throw new \Exception("参数错误!"); + } + + + //判断逻辑 + if($trans){ + self::beginTrans(); + } + $res = true; + try{ + //事务逻辑 + //更新售后为取消状态 + switch ($status){ + case 'yes': + //同意 + self::orderRefund($order,$order['c_price'],$oper_type,$oper_id,$trans=false,$admin=false); + + + //更新订单状态为同意 +// $order = self::updateAdminConfirmationOrder($order); +// +// //插入订单日志 +// if(!$user_id ||$order["user_id"] !=$user_id ){ +// ServiceOrderLog::log($order['id'],"[系统操作]课程订单售后系统退款已原路退回",$oper_type ?: 'user', $oper_id ?: $order['user_id']); +// }else{ +// ServiceOrderLog::log($order['id'],"课程订单售后系统退款已原路退回",$oper_type ?: 'user', $oper_id ?: $order['user_id']); +// } +// +// //调用订单取消事件 +// $data = ['serviceorder' => $order,"user_id"=>$user_id,"oper_type"=>$oper_type,"oper_id"=>$oper_id]; +// \think\Hook::listen('classes_serviceorder_system_confirm_after', $data); + + + break; + case 'no': + //拒绝 + + //更新 + //更新售后为机构驳回结单状态 + $order = self::updateAdminRejectCancel($order,$reject_reason,$reject_images); + //还原课程订单 + self::orderRestore($order["classes_order_id"]); + + + //插入订单日志 + if(!$user_id ||$order["user_id"] !=$user_id ){ + ServiceOrderLog::log($order['id'],"[系统操作]课程订单售后记录异常,系统已强制终止售后",$oper_type ?: 'user', $oper_id ?: $order['user_id']); + }else{ + ServiceOrderLog::log($order['id'],"课程订单售后记录异常,系统已强制终止售后",$oper_type ?: 'user', $oper_id ?: $order['user_id']); + } + + //调用订单取消事件 + $data = ['serviceorder' => $order,"user_id"=>$user_id,"oper_type"=>$oper_type,"oper_id"=>$oper_id]; + \think\Hook::listen('classes_serviceorder_system_reject_after', $data); + + + break; + default: + throw new \Exception("参数错误!"); + } + //执行课时数更新 + $res1 = order::statisticsAndUpdateClassesNumber($order['classes_order_id']); + + + if($trans){ + self::commitTrans(); + } + }catch (\Exception $e){ + if($trans){ + self::rollbackTrans(); + } + throw new \Exception($e->getMessage()); + } + return $res1; + } + + + + /**微信退款 + * @param $order + * @param $refund_money + */ + public static function wechatRefund($order,$refund_money,$refund_desc="",$oper_type='user',$oper_id=0,$trans=false){ + //判断逻辑 + if($trans){ + self::beginTrans(); + } + $res = true; + try{ + //事务逻辑 + //创建订单退款订单 + + + $classesorder = $order->classesorder; + $detail = $order->detail; + + //执行微信退款sdk + $order_data = [ + 'out_trade_no' => $classesorder->order_no + ]; + $total_fee = $classesorder->payprice * 100; + $refund_fee = $refund_money * 100; + + $order_data = array_merge($order_data, [ + 'out_refund_no' => $order->order_no, + 'total_fee' => $total_fee, + 'refund_fee' => $refund_fee, + 'refund_desc' => $refund_desc ?: "课程[{$detail["title"]}]订单[ID:{$classesorder['id']}]退款{$refund_money}已到账户", + ]); + + $config = Service::getConfig('wechat'); + + $notify_url = request()->domain() . '/api/school/pay/notifyr/payment/' . $classesorder->pay_type . '/platform/' . $classesorder->platform; + + $config['notify_url'] = $notify_url; + $pay = Pay::wechat($config); + + + $result = $pay->refund($order_data); + + \think\Log::write('refund-result' . json_encode($result)); + + + if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') { + $res = true; + } else { + throw new \Exception($result['return_msg']); + } + + if($trans){ + self::commitTrans(); + } + }catch (\Exception $e){ + if($trans){ + self::rollbackTrans(); + } + throw new \Exception($e->getMessage()); + } + return $res; + } + + + + /**退款成功处理逻辑 + * @param $refund_sn + * @param bool $trans + * @return bool + * @throws \Exception + */ + public static function refundSuccess($refund_sn,$trans=false){ + //得到机构售后提交确认订单 + $order = self::getHaveAdminConfirmationOrder($refund_sn); + + //判断逻辑 + if($trans){ + self::beginTrans(); + } + $res = true; + try{ + //事务逻辑 + //更新订单状态为同意 + $order = self::updateAdminConfirmationOrder($order); + + //插入订单日志 + ServiceOrderLog::log($order['id'],"[系统操作]课程订单售后系统退款已原路退回", 'admin', 0); + + + //调用订单取消事件 + $data = ['serviceorder' => $order,"user_id"=>$order['user_id'],"oper_type"=>'admin',"oper_id"=>0]; + \think\Hook::listen('classes_serviceorder_system_confirm_after', $data); + + + + if($trans){ + self::commitTrans(); + } + }catch (\Exception $e){ + if($trans){ + self::rollbackTrans(); + } + throw new \Exception($e->getMessage()); + } + return $res; + + } + + + + + + /**预约订单退款 + * @param $order + * @param $refund_money + * @param $trans + */ + public static function orderRefund($order,$refund_money,$oper_type='user',$oper_id=0,$trans=false,$admin=false){ + if(is_numeric($order))$order = self::getBaseWhere(['id'=>$order])->find(); + if(!$order)throw new \Exception("找不到订单"); + //判断逻辑 + if($trans){ + self::beginTrans(); + } + $res = true; + try{ + //事务逻辑 + switch ($order['pay_type']) { + case "wechat": //微信退款 + self::wechatRefund($order,$refund_money,$oper_type,$oper_id); + break; +// case "alipay": //支付宝退款 +// self::alipayRefund($order,$refund_money,$oper_type,$oper_id); +// break; +// case "wallet": //钱包支付退款 +// self::walletRefund($order,$refund_money,$oper_type,$oper_id); +// break; +// case "offline": //线下支付退款 +// +// break; + default: + throw new \Exception("订单币种异常!"); + } + + if($trans){ + self::commitTrans(); + } + }catch (\Exception $e){ + if($trans){ + self::rollbackTrans(); + } + throw new \Exception($e->getMessage()); + } + return $res; + } + + + + } diff --git a/application/common/model/school/classes/order/ServiceOrderLog.php b/application/common/model/school/classes/order/ServiceOrderLog.php index 2be308a..6e0e8c0 100644 --- a/application/common/model/school/classes/order/ServiceOrderLog.php +++ b/application/common/model/school/classes/order/ServiceOrderLog.php @@ -41,7 +41,7 @@ class ServiceOrderLog extends BaseModel public function getServiceStautsList() { - return ['1' => __('Service_stauts 1'), '4' => __('Service_stauts 4'), '7' => __('Service_stauts 7'), '-3' => __('Service_stauts -3')]; + return ['1' => __('Service_stauts 1'), '4' => __('Service_stauts 4'), '7' => __('Service_stauts 7'),'10' => __('Service_stauts 10'), '-3' => __('Service_stauts -3')]; } public function getSalesTypeList() @@ -74,6 +74,20 @@ class ServiceOrderLog extends BaseModel } + public function getRejectImagesAttr($value, $data) + { + $imagesArray = []; + if (!empty($value)) { + $imagesArray = explode(',', $value); + foreach ($imagesArray as &$v) { + $v = cdnurl($v, true); + } + return $imagesArray; + } + return $imagesArray; + } + + public function serviceorder() @@ -114,7 +128,7 @@ class ServiceOrderLog extends BaseModel */ public static function log($order,$mark='更新订单状态',$oper_type='user',$oper_id = 0,$trans=false){ // var_dump($order); - if(is_numeric($order)||is_string($order))$order = Order::where('order_no|id',$order)->find(); + if(is_numeric($order)||is_string($order))$order = ServiceOrder::where('order_no|id',$order)->find(); if(!$order)throw new \Exception("找不到订单"); @@ -184,10 +198,10 @@ class ServiceOrderLog extends BaseModel } } - if (isset($whereData['status'])) $model = $model->where("{$alisa}status", 'in', $whereData['status']); + if (isset($whereData['status']) && $whereData['status']) $model = $model->where("{$alisa}status", 'in', $whereData['status']); - if (isset($whereData['service_stauts'])) $model = $model->where("{$alisa}service_stauts", 'in', $whereData['service_stauts']); - if (isset($whereData['sales_type'])) $model = $model->where("{$alisa}sales_type", 'in', $whereData['sales_type']); + if (isset($whereData['service_stauts']) && $whereData['service_stauts']) $model = $model->where("{$alisa}service_stauts", 'in', $whereData['service_stauts']); + if (isset($whereData['sales_type']) && $whereData['sales_type']) $model = $model->where("{$alisa}sales_type", 'in', $whereData['sales_type']); if (isset($whereData['not_status'])) $model = $model->where("{$alisa}status", 'not in', $whereData['not_status']); diff --git a/application/manystore/lang/zh-cn/school/classes/order/service_order.php b/application/manystore/lang/zh-cn/school/classes/order/service_order.php index 4cced36..568e510 100644 --- a/application/manystore/lang/zh-cn/school/classes/order/service_order.php +++ b/application/manystore/lang/zh-cn/school/classes/order/service_order.php @@ -17,7 +17,8 @@ return [ 'Service_stauts' => '售后处理状态', 'Service_stauts 1' => '待机构处理', 'Service_stauts 4' => '待用户确认', - 'Service_stauts 7' => '售后通过结单', + 'Service_stauts 7' => '售后通过结单中', + 'Service_stauts 10' => '售后通过结单', 'Service_stauts -3' => '售后驳回结单', 'Sales_type' => '结单类型', 'Sales_type -3' => '未结单', diff --git a/application/manystore/lang/zh-cn/school/classes/order/service_order_log.php b/application/manystore/lang/zh-cn/school/classes/order/service_order_log.php index f859a6b..b4b6b3d 100644 --- a/application/manystore/lang/zh-cn/school/classes/order/service_order_log.php +++ b/application/manystore/lang/zh-cn/school/classes/order/service_order_log.php @@ -16,7 +16,8 @@ return [ 'Service_stauts' => '售后处理状态', 'Service_stauts 1' => '待机构处理', 'Service_stauts 4' => '待用户确认', - 'Service_stauts 7' => '售后通过结单', + 'Service_stauts 7' => '售后通过结单中', + 'Service_stauts 10' => '售后通过结单', 'Service_stauts -3' => '售后驳回结单', 'Sales_type' => '结单类型', 'Sales_type -3' => '未结单', diff --git a/application/manystore/model/school/classes/order/ServiceOrder.php b/application/manystore/model/school/classes/order/ServiceOrder.php index 002f350..93ff719 100644 --- a/application/manystore/model/school/classes/order/ServiceOrder.php +++ b/application/manystore/model/school/classes/order/ServiceOrder.php @@ -49,7 +49,7 @@ class ServiceOrder extends Model public function getServiceStautsList() { - return ['1' => __('Service_stauts 1'), '4' => __('Service_stauts 4'), '7' => __('Service_stauts 7'), '-3' => __('Service_stauts -3')]; + return ['1' => __('Service_stauts 1'), '4' => __('Service_stauts 4'), '7' => __('Service_stauts 7'),'10' => __('Service_stauts 10'), '-3' => __('Service_stauts -3')]; } public function getSalesTypeList() diff --git a/application/manystore/model/school/classes/order/ServiceOrderLog.php b/application/manystore/model/school/classes/order/ServiceOrderLog.php index 7ae062c..8a38432 100644 --- a/application/manystore/model/school/classes/order/ServiceOrderLog.php +++ b/application/manystore/model/school/classes/order/ServiceOrderLog.php @@ -40,7 +40,7 @@ class ServiceOrderLog extends Model public function getServiceStautsList() { - return ['1' => __('Service_stauts 1'), '4' => __('Service_stauts 4'), '7' => __('Service_stauts 7'), '-3' => __('Service_stauts -3')]; + return ['1' => __('Service_stauts 1'), '4' => __('Service_stauts 4'), '7' => __('Service_stauts 7'),'10' => __('Service_stauts 10'), '-3' => __('Service_stauts -3')]; } public function getSalesTypeList() diff --git a/public/assets/js/backend/school/classes/order/service_order.js b/public/assets/js/backend/school/classes/order/service_order.js index dae8296..3d09577 100644 --- a/public/assets/js/backend/school/classes/order/service_order.js +++ b/public/assets/js/backend/school/classes/order/service_order.js @@ -38,7 +38,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin {field: 'manystore_id', title: __('Manystore_id')}, {field: 'shop_id', title: __('Shop_id')}, {field: 'status', title: __('Status'), searchList: {"1":__('Status 1'),"4":__('Status 4'),"7":__('Status 7'),"-3":__('Status -3')}, formatter: Table.api.formatter.status}, - {field: 'service_stauts', title: __('Service_stauts'), searchList: {"1":__('Service_stauts 1'),"4":__('Service_stauts 4'),"7":__('Service_stauts 7'),"-3":__('Service_stauts -3')}, formatter: Table.api.formatter.normal}, + {field: 'service_stauts', title: __('Service_stauts'), searchList: {"1":__('Service_stauts 1'),"4":__('Service_stauts 4'),"7":__('Service_stauts 7'),"10":__('Service_stauts 10'),"-3":__('Service_stauts -3')}, formatter: Table.api.formatter.normal}, {field: 'sales_type', title: __('Sales_type'), searchList: {"-3":__('Sales_type -3'),"1":__('Sales_type 1'),"4":__('Sales_type 4'),"7":__('Sales_type 7'),"10":__('Sales_type 10')}, formatter: Table.api.formatter.normal}, {field: 'reject_reason', title: __('Reject_reason'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content}, {field: 'reject_images', title: __('Reject_images'), operate: false, events: Table.api.events.image, formatter: Table.api.formatter.images}, diff --git a/public/assets/js/backend/school/classes/order/service_order_log.js b/public/assets/js/backend/school/classes/order/service_order_log.js index 10dfcdb..ce0848f 100644 --- a/public/assets/js/backend/school/classes/order/service_order_log.js +++ b/public/assets/js/backend/school/classes/order/service_order_log.js @@ -36,7 +36,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin {field: 'manystore_id', title: __('Manystore_id')}, {field: 'shop_id', title: __('Shop_id')}, {field: 'status', title: __('Status'), searchList: {"1":__('Status 1'),"4":__('Status 4'),"7":__('Status 7'),"-3":__('Status -3')}, formatter: Table.api.formatter.status}, - {field: 'service_stauts', title: __('Service_stauts'), searchList: {"1":__('Service_stauts 1'),"4":__('Service_stauts 4'),"7":__('Service_stauts 7'),"-3":__('Service_stauts -3')}, formatter: Table.api.formatter.normal}, + {field: 'service_stauts', title: __('Service_stauts'), searchList: {"1":__('Service_stauts 1'),"4":__('Service_stauts 4'),"7":__('Service_stauts 7'),"10":__('Service_stauts 10'),"-3":__('Service_stauts -3')}, formatter: Table.api.formatter.normal}, {field: 'sales_type', title: __('Sales_type'), searchList: {"-3":__('Sales_type -3'),"1":__('Sales_type 1'),"4":__('Sales_type 4'),"7":__('Sales_type 7'),"10":__('Sales_type 10')}, formatter: Table.api.formatter.normal}, {field: 'log_text', title: __('Log_text'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content}, {field: 'oper_id', title: __('Oper_id')}, diff --git a/public/assets/js/manystore/school/classes/order/service_order.js b/public/assets/js/manystore/school/classes/order/service_order.js index a86bbc5..093242f 100644 --- a/public/assets/js/manystore/school/classes/order/service_order.js +++ b/public/assets/js/manystore/school/classes/order/service_order.js @@ -35,7 +35,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin {field: 'manystore_id', title: __('Manystore_id')}, {field: 'shop_id', title: __('Shop_id')}, {field: 'status', title: __('Status'), searchList: {"1":__('Status 1'),"4":__('Status 4'),"7":__('Status 7'),"-3":__('Status -3')}, formatter: Table.api.formatter.status}, - {field: 'service_stauts', title: __('Service_stauts'), searchList: {"1":__('Service_stauts 1'),"4":__('Service_stauts 4'),"7":__('Service_stauts 7'),"-3":__('Service_stauts -3')}, formatter: Table.api.formatter.normal}, + {field: 'service_stauts', title: __('Service_stauts'), searchList: {"1":__('Service_stauts 1'),"4":__('Service_stauts 4'),"7":__('Service_stauts 7'),"10":__('Service_stauts 10'),"-3":__('Service_stauts -3')}, formatter: Table.api.formatter.normal}, {field: 'sales_type', title: __('Sales_type'), searchList: {"-3":__('Sales_type -3'),"1":__('Sales_type 1'),"4":__('Sales_type 4'),"7":__('Sales_type 7'),"10":__('Sales_type 10')}, formatter: Table.api.formatter.normal}, {field: 'reject_reason', title: __('Reject_reason'), operate: 'LIKE'}, {field: 'reject_images', title: __('Reject_images'), operate: false, events: Table.api.events.image, formatter: Table.api.formatter.images}, diff --git a/public/assets/js/manystore/school/classes/order/service_order_log.js b/public/assets/js/manystore/school/classes/order/service_order_log.js index 958215b..1420b5e 100644 --- a/public/assets/js/manystore/school/classes/order/service_order_log.js +++ b/public/assets/js/manystore/school/classes/order/service_order_log.js @@ -34,7 +34,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin {field: 'manystore_id', title: __('Manystore_id')}, {field: 'shop_id', title: __('Shop_id')}, {field: 'status', title: __('Status'), searchList: {"1":__('Status 1'),"4":__('Status 4'),"7":__('Status 7'),"-3":__('Status -3')}, formatter: Table.api.formatter.status}, - {field: 'service_stauts', title: __('Service_stauts'), searchList: {"1":__('Service_stauts 1'),"4":__('Service_stauts 4'),"7":__('Service_stauts 7'),"-3":__('Service_stauts -3')}, formatter: Table.api.formatter.normal}, + {field: 'service_stauts', title: __('Service_stauts'), searchList: {"1":__('Service_stauts 1'),"4":__('Service_stauts 4'),"7":__('Service_stauts 7'),"10":__('Service_stauts 10'),"-3":__('Service_stauts -3')}, formatter: Table.api.formatter.normal}, {field: 'sales_type', title: __('Sales_type'), searchList: {"-3":__('Sales_type -3'),"1":__('Sales_type 1'),"4":__('Sales_type 4'),"7":__('Sales_type 7'),"10":__('Sales_type 10')}, formatter: Table.api.formatter.normal}, {field: 'log_text', title: __('Log_text'), operate: 'LIKE'}, {field: 'oper_id', title: __('Oper_id')},