From d7d47e6c8f04bbddfdcbd550aa6791dd7f68f817 Mon Sep 17 00:00:00 2001 From: koogua Date: Sat, 6 Mar 2021 18:28:21 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=89=8B=E7=BB=AD=E8=B4=B9?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Console/Tasks/RefundTask.php | 4 +- app/Http/Admin/Services/Trade.php | 22 ++++++- app/Http/Admin/Views/setting/pay_alipay.volt | 11 ++++ app/Http/Admin/Views/setting/pay_wxpay.volt | 11 ++++ app/Http/Home/Views/order/info.volt | 2 +- app/Http/Home/Views/refund/confirm.volt | 8 ++- app/Services/Logic/Refund/RefundCreate.php | 6 +- app/Services/Refund.php | 59 ++++++++++++++++++- app/Validators/Order.php | 7 +++ .../20210305115507_data_202103051930.php | 39 ++++++++++++ 10 files changed, 154 insertions(+), 15 deletions(-) create mode 100644 db/migrations/20210305115507_data_202103051930.php diff --git a/app/Console/Tasks/RefundTask.php b/app/Console/Tasks/RefundTask.php index 1a3556ff..c85f3ba9 100644 --- a/app/Console/Tasks/RefundTask.php +++ b/app/Console/Tasks/RefundTask.php @@ -39,8 +39,8 @@ class RefundTask extends Task $itemInfo = $task->item_info; $refund = $refundRepo->findById($itemInfo['refund']['id']); - $trade = $tradeRepo->findById($itemInfo['refund']['trade_id']); - $order = $orderRepo->findById($itemInfo['refund']['order_id']); + $trade = $tradeRepo->findById($refund->trade_id); + $order = $orderRepo->findById($refund->order_id); if (!$refund || !$trade || !$order) { $task->status = TaskModel::STATUS_FAILED; diff --git a/app/Http/Admin/Services/Trade.php b/app/Http/Admin/Services/Trade.php index 9b818a81..b8691f9f 100644 --- a/app/Http/Admin/Services/Trade.php +++ b/app/Http/Admin/Services/Trade.php @@ -10,6 +10,7 @@ use App\Repos\Account as AccountRepo; use App\Repos\Order as OrderRepo; use App\Repos\Trade as TradeRepo; use App\Repos\User as UserRepo; +use App\Validators\Refund as RefundValidator; use App\Validators\Trade as TradeValidator; class Trade extends Service @@ -101,10 +102,16 @@ class Trade extends Service $validator->checkIfAllowRefund($trade); + $validator = new RefundValidator(); + + $refundAmount = $this->getRefundAmount($trade); + + $validator->checkAmount($trade->amount, $refundAmount); + $refund = new RefundModel(); + $refund->amount = $refundAmount; $refund->subject = $trade->subject; - $refund->amount = $trade->amount; $refund->owner_id = $trade->owner_id; $refund->order_id = $trade->order_id; $refund->trade_id = $trade->id; @@ -115,6 +122,19 @@ class Trade extends Service return $refund; } + protected function getRefundAmount(TradeModel $trade) + { + $orderRepo = new OrderRepo(); + + $order = $orderRepo->findById($trade->order_id); + + $refund = new \App\Services\Refund(); + + $preview = $refund->preview($order); + + return $preview['refund_amount']; + } + protected function findOrFail($id) { $validator = new TradeValidator(); diff --git a/app/Http/Admin/Views/setting/pay_alipay.volt b/app/Http/Admin/Views/setting/pay_alipay.volt index ebc1bf6c..9f139dd1 100644 --- a/app/Http/Admin/Views/setting/pay_alipay.volt +++ b/app/Http/Admin/Views/setting/pay_alipay.volt @@ -6,6 +6,17 @@ +
+ +
+ +
+
diff --git a/app/Http/Admin/Views/setting/pay_wxpay.volt b/app/Http/Admin/Views/setting/pay_wxpay.volt index 22cdc504..0c544a65 100644 --- a/app/Http/Admin/Views/setting/pay_wxpay.volt +++ b/app/Http/Admin/Views/setting/pay_wxpay.volt @@ -6,6 +6,17 @@
+
+ +
+ +
+
diff --git a/app/Http/Home/Views/order/info.volt b/app/Http/Home/Views/order/info.volt index c4472b16..5e4c5234 100644 --- a/app/Http/Home/Views/order/info.volt +++ b/app/Http/Home/Views/order/info.volt @@ -7,7 +7,7 @@ {% set order_pay_url = url({'for':'home.order.pay'},{'sn':order.sn}) %} {% set refund_confirm_url = url({'for':'home.refund.confirm'},{'sn':order.sn}) %} - +
订单金额:{{ '¥%0.2f'|format(order.amount) }} diff --git a/app/Http/Home/Views/refund/confirm.volt b/app/Http/Home/Views/refund/confirm.volt index c19683f9..51134e64 100644 --- a/app/Http/Home/Views/refund/confirm.volt +++ b/app/Http/Home/Views/refund/confirm.volt @@ -24,16 +24,18 @@ {% endif %} {%- endmacro %} - +
- + + - + +
退款项目退款金额 订单金额手续费退款金额
{{ item_info(confirm) }}{{ '¥%0.2f'|format(confirm.refund_amount) }} {{ '¥%0.2f'|format(order.amount) }}{{ '¥%0.2f'|format(confirm.service_fee) }}{{ '¥%0.2f'|format(confirm.refund_amount) }}

diff --git a/app/Services/Logic/Refund/RefundCreate.php b/app/Services/Logic/Refund/RefundCreate.php index bb9749ec..228e52ab 100644 --- a/app/Services/Logic/Refund/RefundCreate.php +++ b/app/Services/Logic/Refund/RefundCreate.php @@ -70,11 +70,7 @@ class RefundCreate extends Service $task = new TaskModel(); $itemInfo = [ - 'refund' => [ - 'id' => $refund->id, - 'order_id' => $refund->order_id, - 'trade_id' => $refund->trade_id, - ], + 'refund' => ['id' => $refund->id], ]; $task->item_id = $refund->id; diff --git a/app/Services/Refund.php b/app/Services/Refund.php index 124450ea..499634b4 100644 --- a/app/Services/Refund.php +++ b/app/Services/Refund.php @@ -3,15 +3,22 @@ namespace App\Services; use App\Models\Order as OrderModel; +use App\Models\Trade as TradeModel; use App\Repos\Course as CourseRepo; use App\Repos\CourseUser as CourseUserRepo; +use App\Repos\Order as OrderRepo; class Refund extends Service { public function preview(OrderModel $order) { - $result = []; + $result = [ + 'item_type' => 0, + 'item_info' => [], + 'refund_amount' => 0.00, + 'service_fee' => 0.00, + ]; switch ($order->item_type) { case OrderModel::ITEM_COURSE: @@ -20,6 +27,9 @@ class Refund extends Service case OrderModel::ITEM_PACKAGE: $result = $this->previewPackageRefund($order); break; + default: + $result = $this->previewOtherRefund($order); + break; } return $result; @@ -34,12 +44,14 @@ class Refund extends Service $itemInfo['course']['cover'] = kg_cos_cover_url($itemInfo['course']['cover']); + $serviceFee = $this->getServiceFee($order); + $refundPercent = 0.00; $refundAmount = 0.00; if ($itemInfo['course']['refund_expiry_time'] > time()) { $refundPercent = $this->getCourseRefundPercent($order->item_id, $order->owner_id); - $refundAmount = $order->amount * $refundPercent; + $refundAmount = round(($order->amount - $serviceFee) * $refundPercent, 2); } $itemInfo['course']['refund_percent'] = $refundPercent; @@ -49,6 +61,7 @@ class Refund extends Service 'item_type' => $order->item_type, 'item_info' => $itemInfo, 'refund_amount' => $refundAmount, + 'service_fee' => $serviceFee, ]; } @@ -59,6 +72,8 @@ class Refund extends Service */ $itemInfo = $order->item_info; + $serviceFee = $this->getServiceFee($order); + $totalMarketPrice = 0.00; foreach ($itemInfo['courses'] as $course) { @@ -80,7 +95,7 @@ class Refund extends Service if ($course['refund_expiry_time'] > time()) { $pricePercent = round($course['market_price'] / $totalMarketPrice, 4); $refundPercent = $this->getCourseRefundPercent($course['id'], $order->owner_id); - $refundAmount = round($order->amount * $pricePercent * $refundPercent, 2); + $refundAmount = round(($order->amount - $serviceFee) * $pricePercent * $refundPercent, 2); $totalRefundAmount += $refundAmount; } @@ -92,9 +107,47 @@ class Refund extends Service 'item_type' => $order->item_type, 'item_info' => $itemInfo, 'refund_amount' => $totalRefundAmount, + 'service_fee' => $serviceFee, ]; } + protected function previewOtherRefund(OrderModel $order) + { + $serviceFee = $this->getServiceFee($order); + + $refundAmount = round($order->amount - $serviceFee, 2); + + return [ + 'item_type' => $order->item_type, + 'item_info' => [], + 'refund_amount' => $refundAmount, + 'service_fee' => $serviceFee, + ]; + } + + protected function getServiceFee(OrderModel $order) + { + $orderRepo = new OrderRepo(); + + $trade = $orderRepo->findLastTrade($order->id); + + $alipay = $this->getSettings('pay.alipay'); + $wxpay = $this->getSettings('pay.wxpay'); + + $serviceRate = 5; + + switch ($trade->channel) { + case TradeModel::CHANNEL_ALIPAY: + $serviceRate = $alipay['service_rate'] ?: $serviceRate; + break; + case TradeModel::CHANNEL_WXPAY: + $serviceRate = $wxpay['service_rate'] ?: $serviceRate; + break; + } + + return round($order->amount * $serviceRate / 100, 2); + } + protected function getCourseRefundPercent($courseId, $userId) { $courseRepo = new CourseRepo(); diff --git a/app/Validators/Order.php b/app/Validators/Order.php index cdf4f45c..2419dc87 100644 --- a/app/Validators/Order.php +++ b/app/Validators/Order.php @@ -5,6 +5,7 @@ namespace App\Validators; use App\Exceptions\BadRequest as BadRequestException; use App\Models\Order as OrderModel; use App\Models\Refund as RefundModel; +use App\Models\Trade as TradeModel; use App\Repos\Course as CourseRepo; use App\Repos\Order as OrderRepo; use App\Repos\Package as PackageRepo; @@ -154,6 +155,12 @@ class Order extends Validator $orderRepo = new OrderRepo(); + $trade = $orderRepo->findLastTrade($order->id); + + if ($trade->status != TradeModel::STATUS_FINISHED) { + throw new BadRequestException('order.refund_not_allowed'); + } + $refund = $orderRepo->findLastRefund($order->id); $scopes = [ diff --git a/db/migrations/20210305115507_data_202103051930.php b/db/migrations/20210305115507_data_202103051930.php new file mode 100644 index 00000000..1053b337 --- /dev/null +++ b/db/migrations/20210305115507_data_202103051930.php @@ -0,0 +1,39 @@ + 'pay.alipay', + 'item_key' => 'service_rate', + 'item_value' => 5, + ], + [ + 'section' => 'pay.wxpay', + 'item_key' => 'service_rate', + 'item_value' => 5, + ], + ]; + + $this->table('kg_setting')->insert($rows)->save(); + } + + public function down() + { + $this->getQueryBuilder() + ->delete('kg_setting') + ->where(['section' => 'pay.alipay', 'item_key' => 'service_rate']) + ->execute(); + + $this->getQueryBuilder() + ->delete('kg_setting') + ->where(['section' => 'pay.wxpay', 'item_key' => 'service_rate']) + ->execute(); + } + +}