diff --git a/app/Http/Admin/Controllers/StudentController.php b/app/Http/Admin/Controllers/StudentController.php index 38da8553..5ef6e5d2 100644 --- a/app/Http/Admin/Controllers/StudentController.php +++ b/app/Http/Admin/Controllers/StudentController.php @@ -27,7 +27,7 @@ class StudentController extends Controller $studentService = new StudentService(); - $pager = $studentService->getPlans(); + $pager = $studentService->getRelations(); $course = null; @@ -64,7 +64,7 @@ class StudentController extends Controller { $studentService = new StudentService(); - $student = $studentService->createPlan(); + $student = $studentService->createRelation(); $location = $this->url->get( ['for' => 'admin.student.list'], @@ -84,15 +84,15 @@ class StudentController extends Controller */ public function editAction() { - $planId = $this->request->getQuery('plan_id'); + $relationId = $this->request->getQuery('relation_id'); $studentService = new StudentService(); - $plan = $studentService->getPlan($planId); - $course = $studentService->getCourse($plan->course_id); - $student = $studentService->getStudent($plan->user_id); + $relation = $studentService->getRelation($relationId); + $course = $studentService->getCourse($relation->course_id); + $student = $studentService->getStudent($relation->user_id); - $this->view->setVar('plan', $plan); + $this->view->setVar('relation', $relation); $this->view->setVar('course', $course); $this->view->setVar('student', $student); } @@ -104,7 +104,7 @@ class StudentController extends Controller { $studentService = new StudentService(); - $studentService->updatePlan(); + $studentService->updateRelation(); $location = $this->url->get(['for' => 'admin.student.list']); diff --git a/app/Http/Admin/Services/Order.php b/app/Http/Admin/Services/Order.php index 23ea85b2..858214c1 100644 --- a/app/Http/Admin/Services/Order.php +++ b/app/Http/Admin/Services/Order.php @@ -17,6 +17,9 @@ class Order extends Service $pageQuery = new PaginateQuery(); $params = $pageQuery->getParams(); + + $params['deleted'] = $params['deleted'] ?? 0; + $sort = $pageQuery->getSort(); $page = $pageQuery->getPage(); $limit = $pageQuery->getLimit(); diff --git a/app/Http/Admin/Services/Refund.php b/app/Http/Admin/Services/Refund.php index 4efb9972..29a5201d 100644 --- a/app/Http/Admin/Services/Refund.php +++ b/app/Http/Admin/Services/Refund.php @@ -4,6 +4,7 @@ namespace App\Http\Admin\Services; use App\Builders\RefundList as RefundListBuilder; use App\Library\Paginator\Query as PaginateQuery; +use App\Models\Refund as RefundModel; use App\Models\Task as TaskModel; use App\Repos\Account as AccountRepo; use App\Repos\Order as OrderRepo; @@ -86,20 +87,20 @@ class Refund extends Service $validator->checkIfAllowReview($refund); - $data['status'] = $validator->checkReviewStatus($post['status']); + $data['status'] = $validator->checkReviewStatus($post['review_status']); $data['review_note'] = $validator->checkReviewNote($post['review_note']); $refund->update($data); - $task = new TaskModel(); - - $task->item_id = $refund->id; - $task->item_type = TaskModel::TYPE_REFUND; - $task->item_info = ['refund' => $refund->toArray()]; - $task->priority = TaskModel::PRIORITY_HIGH; - $task->status = TaskModel::STATUS_PENDING; - - $task->create(); + if ($post['status'] == RefundModel::STATUS_APPROVED) { + $task = new TaskModel(); + $task->item_id = $refund->id; + $task->item_type = TaskModel::TYPE_REFUND; + $task->item_info = ['refund' => $refund->toArray()]; + $task->priority = TaskModel::PRIORITY_HIGH; + $task->status = TaskModel::STATUS_PENDING; + $task->create(); + } return $refund; } diff --git a/app/Http/Admin/Services/Student.php b/app/Http/Admin/Services/Student.php index 9b2f8bb1..1b77f702 100644 --- a/app/Http/Admin/Services/Student.php +++ b/app/Http/Admin/Services/Student.php @@ -30,7 +30,7 @@ class Student extends Service return $repo->findById($userId); } - public function getPlans() + public function getRelations() { $pagerQuery = new PagerQuery(); @@ -47,7 +47,7 @@ class Student extends Service $pager = $courseUserRepo->paginate($params, $sort, $page, $limit); - return $this->handlePlans($pager); + return $this->handleRelations($pager); } public function getLearnings() @@ -69,12 +69,12 @@ class Student extends Service return $this->handleLearnings($pager); } - public function getPlan($id) + public function getRelation($id) { return $this->findOrFail($id); } - public function createPlan() + public function createRelation() { $post = $this->request->getPost(); @@ -100,11 +100,11 @@ class Student extends Service return $courseUser; } - public function updatePlan() + public function updateRelation() { $post = $this->request->getPost(); - $plan = $this->findOrFail($post['plan_id']); + $relation = $this->findOrFail($post['relation_id']); $validator = new CourseUserValidator(); @@ -114,9 +114,9 @@ class Student extends Service $data['expiry_time'] = $validator->checkExpiryTime($post['expiry_time']); } - $plan->update($data); + $relation->update($data); - return $plan; + return $relation; } protected function updateUserCount($courseId) @@ -137,7 +137,7 @@ class Student extends Service return $validator->checkCourseUser($id); } - protected function handlePlans($pager) + protected function handleRelations($pager) { if ($pager->total_items > 0) { diff --git a/app/Http/Admin/Views/refund/show.volt b/app/Http/Admin/Views/refund/show.volt index c633b624..57400d7d 100644 --- a/app/Http/Admin/Views/refund/show.volt +++ b/app/Http/Admin/Views/refund/show.volt @@ -10,14 +10,21 @@ 退款序号 退款金额 - 退款原因 + 退款备注 退款状态 创建时间 {{ refund.sn }} ¥{{ refund.amount }} - {{ substr(refund.apply_note,0,15) }} + + {% if refund.apply_note %} +

{{ refund.apply_note }}

+ {% endif %} + {% if refund.review_note %} +

{{ refund.review_note }}

+ {% endif %} + {{ refund_status(refund) }} {{ date('Y-m-d H:i:s',refund.create_time) }} @@ -33,8 +40,8 @@
- - + +
diff --git a/app/Http/Admin/Views/student/edit.volt b/app/Http/Admin/Views/student/edit.volt index ead53bfb..3df2370f 100644 --- a/app/Http/Admin/Views/student/edit.volt +++ b/app/Http/Admin/Views/student/edit.volt @@ -21,7 +21,7 @@
- +
@@ -30,7 +30,7 @@
- +
diff --git a/app/Http/Admin/Views/student/list.volt b/app/Http/Admin/Views/student/list.volt index b9906304..cc1e60cd 100644 --- a/app/Http/Admin/Views/student/list.volt +++ b/app/Http/Admin/Views/student/list.volt @@ -53,6 +53,7 @@ {% for item in pager.items %} + {% set learning_url = url({'for':'admin.student.learning'},{'course_id':item.course_id,'user_id':item.user_id,'plan_id':item.plan_id}) %}

课程:{{ item.course.title }}({{ item.course.id }})

@@ -71,8 +72,8 @@
diff --git a/app/Http/Web/Controllers/MyController.php b/app/Http/Web/Controllers/MyController.php index 2331ef7b..2bcf4c0b 100644 --- a/app/Http/Web/Controllers/MyController.php +++ b/app/Http/Web/Controllers/MyController.php @@ -21,7 +21,7 @@ class MyController extends Controller */ public function homeAction() { - $this->dispatcher->forward([ + $this->response->redirect([ 'for' => 'web.user.show', 'id' => $this->authUser->id, ]); diff --git a/app/Http/Web/Controllers/RefundController.php b/app/Http/Web/Controllers/RefundController.php index 3f78f2c5..5d8a4b73 100644 --- a/app/Http/Web/Controllers/RefundController.php +++ b/app/Http/Web/Controllers/RefundController.php @@ -40,13 +40,14 @@ class RefundController extends Controller { $service = new RefundCreateService(); - $refund = $service->handle(); + $service->handle(); - $service = new RefundInfoService(); + $content = [ + 'location' => $this->url->get(['for' => 'web.my.orders']), + 'msg' => '申请退款成功', + ]; - $refund = $service->handle($refund->sn); - - return $this->jsonSuccess(['refund' => $refund]); + return $this->jsonSuccess($content); } /** diff --git a/app/Http/Web/Views/order/info.volt b/app/Http/Web/Views/order/info.volt index e57b2a8f..a892d21e 100644 --- a/app/Http/Web/Views/order/info.volt +++ b/app/Http/Web/Views/order/info.volt @@ -13,9 +13,6 @@
- - - @@ -28,15 +25,17 @@ - +
订单编号:{{ order.sn }}
基本信息 订单金额{{ '¥%0.2f'|format(order.amount) }} {{ item_type(order.item_type) }} {{ order_status(order.status) }}{{ history_info(order.history) }}{{ status_history(order.status_history) }}

返回上页 + {% if order.status == 'pending' %} + 立即支付 + {% endif %} {% if (order.item_type in ['course','package']) and (order.status == 'finished') %} - {% set confirm_url = url({'for':'web.refund.confirm'},{'sn':order.sn}) %} - 申请退款 + 申请退款 {% endif %}

diff --git a/app/Http/Web/Views/order/pay.volt b/app/Http/Web/Views/order/pay.volt index 74c9925f..2f2217d0 100644 --- a/app/Http/Web/Views/order/pay.volt +++ b/app/Http/Web/Views/order/pay.volt @@ -11,7 +11,7 @@
订单名称:{{ order.subject }} 订单编号:{{ order.sn }} - 支付金额:¥{{ order.amount }} + 支付金额:{{ '¥%0.2f'|format(order.amount) }}
{% set create_url = url({'for':'web.trade.create'}) %} diff --git a/app/Http/Web/Views/partials/macro_order.volt b/app/Http/Web/Views/partials/macro_order.volt index f6cb1bbe..7bbac80d 100644 --- a/app/Http/Web/Views/partials/macro_order.volt +++ b/app/Http/Web/Views/partials/macro_order.volt @@ -39,7 +39,7 @@ {% endif %} {%- endmacro %} -{%- macro history_info(items) %} +{%- macro status_history(items) %} {% for item in items %} {% if item.status == 'pending' %}

创建时间:{{ date('Y-m-d H:i:s',item.create_time) }}

diff --git a/app/Http/Web/Views/refund/confirm.volt b/app/Http/Web/Views/refund/confirm.volt index 28450ce7..83c82868 100644 --- a/app/Http/Web/Views/refund/confirm.volt +++ b/app/Http/Web/Views/refund/confirm.volt @@ -9,7 +9,7 @@

课程名称:{{ course.title }}

退款期限:{{ date('Y-m-d H:i:s',course.refund_expiry_time) }}

-

退款金额:{{ '¥%0.2f'|format(course.refund_amount) }}退款比例:{{ 100 * course.refund_percent }}%

+

退款金额:{{ '¥%0.2f'|format(course.refund_amount) }}退款比例:{{ 100 * course.refund_percent }}%

{% elseif confirm.item_type == 'package' %} {% set courses = confirm.item_info.courses %} @@ -18,7 +18,7 @@

课程名称:{{ course.title }}

退款期限:{{ date('Y-m-d H:i:s',course.refund_expiry_time) }}

-

退款金额:{{ '¥%0.2f'|format(course.refund_amount) }}退款比例:{{ 100 * course.refund_percent }}%

+

退款金额:{{ '¥%0.2f'|format(course.refund_amount) }}退款比例:{{ 100 * course.refund_percent }}%

{% endfor %} {% endif %} @@ -34,10 +34,7 @@
- - - - + @@ -48,11 +45,20 @@
订单编号:{{ order.sn }}
基本信息订单编号:{{ order.sn }} 订单金额 退款金额

- -
+
+
+ +
+ +
+
+
+
+ + + +
+
{% endblock %} \ No newline at end of file diff --git a/app/Http/Web/Views/user/courses.volt b/app/Http/Web/Views/user/courses.volt index 724c78c3..484a9141 100644 --- a/app/Http/Web/Views/user/courses.volt +++ b/app/Http/Web/Views/user/courses.volt @@ -1,10 +1,14 @@ {{ partial('partials/macro_course') }} {% if pager.total_pages > 0 %} -
- {% for item in pager.items %} - {{ learning_course_card(item) }} - {% endfor %} +
+
+ {% for item in pager.items %} +
+ {{ learning_course_card(item) }} +
+ {% endfor %} +
{{ partial('partials/pager_ajax') }} {% endif %} \ No newline at end of file diff --git a/app/Http/Web/Views/user/favorites.volt b/app/Http/Web/Views/user/favorites.volt index 4d0fc711..5bd3e409 100644 --- a/app/Http/Web/Views/user/favorites.volt +++ b/app/Http/Web/Views/user/favorites.volt @@ -2,9 +2,13 @@ {% if pager.total_pages > 0 %}
- {% for item in pager.items %} - {{ course_card(item) }} - {% endfor %} +
+ {% for item in pager.items %} +
+ {{ course_card(item) }} +
+ {% endfor %} +
{{ partial('partials/pager_ajax') }} {% endif %} \ No newline at end of file diff --git a/app/Http/Web/Views/user/show.volt b/app/Http/Web/Views/user/show.volt index 7cb896d0..f512eeff 100644 --- a/app/Http/Web/Views/user/show.volt +++ b/app/Http/Web/Views/user/show.volt @@ -20,11 +20,11 @@ {% endif %}
- {% set course_url = url({'for':'web.user.courses','id':user.id}) %} - {% set favorite_url = url({'for':'web.user.favorites','id':user.id}) %} - {% set friend_url = url({'for':'web.user.friends','id':user.id}) %} + {% set courses_url = url({'for':'web.user.courses','id':user.id},{'limit':12}) %} + {% set favorites_url = url({'for':'web.user.favorites','id':user.id},{'limit':12}) %} + {% set friends_url = url({'for':'web.user.friends','id':user.id},{'limit':12}) %} -
+
  • 课程
  • @@ -32,9 +32,9 @@
  • 好友
-
-
-
+
+
+
diff --git a/app/Repos/Learning.php b/app/Repos/Learning.php index fdc32181..9cee3196 100644 --- a/app/Repos/Learning.php +++ b/app/Repos/Learning.php @@ -17,6 +17,10 @@ class Learning extends Repository $builder->where('1 = 1'); + if (!empty($where['plan_id'])) { + $builder->andWhere('plan_id = :plan_id:', ['plan_id' => $where['plan_id']]); + } + if (!empty($where['course_id'])) { $builder->andWhere('course_id = :course_id:', ['course_id' => $where['course_id']]); } diff --git a/app/Repos/Order.php b/app/Repos/Order.php index ce2f8f87..5dff0b1f 100644 --- a/app/Repos/Order.php +++ b/app/Repos/Order.php @@ -169,11 +169,37 @@ class Order extends Repository * @param $orderId * @return ResultsetInterface|Resultset|OrderStatusModel[] */ - public function findHistory($orderId) + public function findStatusHistory($orderId) { return OrderStatusModel::query() ->where('order_id = :order_id:', ['order_id' => $orderId]) ->execute(); } + /** + * @param int $orderId + * @return TradeModel|Model|bool + */ + public function findLastTrade($orderId) + { + return TradeModel::findFirst([ + 'conditions' => 'order_id = :order_id:', + 'bind' => ['order_id' => $orderId], + 'order' => 'id DESC', + ]); + } + + /** + * @param int $orderId + * @return RefundModel|Model|bool + */ + public function findLastRefund($orderId) + { + return RefundModel::findFirst([ + 'conditions' => 'order_id = :order_id:', + 'bind' => ['order_id' => $orderId], + 'order' => 'id DESC', + ]); + } + } diff --git a/app/Repos/Refund.php b/app/Repos/Refund.php index 6edcf017..aeb1b304 100644 --- a/app/Repos/Refund.php +++ b/app/Repos/Refund.php @@ -31,6 +31,10 @@ class Refund extends Repository $builder->andWhere('status = :status:', ['status' => $where['status']]); } + if (isset($where['deleted'])) { + $builder->andWhere('deleted = :deleted:', ['deleted' => $where['deleted']]); + } + if (!empty($where['start_time']) && !empty($where['end_time'])) { $startTime = strtotime($where['start_time']); $endTime = strtotime($where['end_time']); diff --git a/app/Repos/Trade.php b/app/Repos/Trade.php index 0d1f558a..082c5541 100644 --- a/app/Repos/Trade.php +++ b/app/Repos/Trade.php @@ -44,6 +44,10 @@ class Trade extends Repository $builder->andWhere('status = :status:', ['status' => $where['status']]); } + if (isset($where['deleted'])) { + $builder->andWhere('deleted = :deleted:', ['deleted' => $where['deleted']]); + } + if (!empty($where['start_time']) && !empty($where['end_time'])) { $startTime = strtotime($where['start_time']); $endTime = strtotime($where['end_time']); diff --git a/app/Services/Frontend/Order/OrderInfo.php b/app/Services/Frontend/Order/OrderInfo.php index fb3cad10..d9695b95 100644 --- a/app/Services/Frontend/Order/OrderInfo.php +++ b/app/Services/Frontend/Order/OrderInfo.php @@ -23,25 +23,25 @@ class OrderInfo extends FrontendService { $order->item_info = $this->handleItemInfo($order); - $history = $this->handleHistory($order); + $statusHistory = $this->handleStatusHistory($order); return [ 'sn' => $order->sn, 'subject' => $order->subject, 'amount' => $order->amount, 'status' => $order->status, + 'status_history' => $statusHistory, 'item_id' => $order->item_id, 'item_type' => $order->item_type, 'item_info' => $order->item_info, - 'history' => $history, ]; } - protected function handleHistory(OrderModel $order) + protected function handleStatusHistory(OrderModel $order) { $orderRepo = new OrderRepo(); - $records = $orderRepo->findHistory($order->id); + $records = $orderRepo->findStatusHistory($order->id); if ($records->count() == 0) { return []; diff --git a/app/Services/Frontend/Refund/RefundCreate.php b/app/Services/Frontend/Refund/RefundCreate.php index 8a26b643..0b835144 100644 --- a/app/Services/Frontend/Refund/RefundCreate.php +++ b/app/Services/Frontend/Refund/RefundCreate.php @@ -3,6 +3,7 @@ namespace App\Services\Frontend\Refund; use App\Models\Refund as RefundModel; +use App\Repos\Order as OrderRepo; use App\Services\Frontend\OrderTrait; use App\Services\Frontend\Service as FrontendService; use App\Services\Refund as RefundService; @@ -22,27 +23,35 @@ class RefundCreate extends FrontendService $user = $this->getLoginUser(); + $orderRepo = new OrderRepo(); + + $trade = $orderRepo->findLastTrade($order->id); + $validator = new OrderValidator(); + $validator->checkOwner($user->id, $order->user_id); + $validator->checkIfAllowRefund($order); $refundService = new RefundService(); - $refundAmount = $refundService->getRefundAmount($order); + $preview = $refundService->preview($order); + + $refundAmount = $preview['refund_amount']; $validator = new RefundValidator(); - $validator->checkAmount($order->amount, $refundAmount); - $applyNote = $validator->checkApplyNote($post['apply_note']); + $validator->checkAmount($order->amount, $refundAmount); + $refund = new RefundModel(); $refund->subject = $order->subject; - $refund->amount = $order->amount; + $refund->amount = $refundAmount; $refund->apply_note = $applyNote; $refund->order_id = $order->id; - $refund->trade_id = $order->id; + $refund->trade_id = $trade->id; $refund->user_id = $user->id; $refund->create(); diff --git a/app/Validators/Order.php b/app/Validators/Order.php index bf7498dd..0504728d 100644 --- a/app/Validators/Order.php +++ b/app/Validators/Order.php @@ -4,6 +4,7 @@ namespace App\Validators; use App\Exceptions\BadRequest as BadRequestException; use App\Models\Order as OrderModel; +use App\Models\Refund as RefundModel; use App\Repos\Course as CourseRepo; use App\Repos\Order as OrderRepo; use App\Repos\Package as PackageRepo; @@ -137,7 +138,20 @@ class Order extends Validator ]; if (!in_array($order->item_type, $types)) { - throw new BadRequestException('order.refund_not_allowed'); + throw new BadRequestException('order.refund_item_unsupported'); + } + + $orderRepo = new OrderRepo(); + + $refund = $orderRepo->findLastRefund($order->id); + + $scopes = [ + RefundModel::STATUS_PENDING, + RefundModel::STATUS_APPROVED, + ]; + + if ($refund && in_array($refund->status, $scopes)) { + throw new BadRequestException('order.refund_apply_existed'); } } diff --git a/app/Validators/Trade.php b/app/Validators/Trade.php index 57707d5e..e497cb25 100644 --- a/app/Validators/Trade.php +++ b/app/Validators/Trade.php @@ -75,7 +75,7 @@ class Trade extends Validator ]; if ($refund && in_array($refund->status, $scopes)) { - throw new BadRequestException('trade.refund_existed'); + throw new BadRequestException('trade.refund_apply_existed'); } } diff --git a/config/errors.php b/config/errors.php index ea046e04..864618eb 100644 --- a/config/errors.php +++ b/config/errors.php @@ -259,10 +259,13 @@ $error['slide.invalid_publish_status'] = '无效的发布状态'; */ $error['order.not_found'] = '订单不存在'; $error['order.item_not_found'] = '商品不存在'; -$error['order.close_not_allowed'] = '当前不允许关闭订单'; -$error['order.has_bought_course'] = '已经够买过该课程'; -$error['order.has_bought_package'] = '已经够买过该套餐'; $error['order.trade_expired'] = '交易已过期'; +$error['order.has_bought_course'] = '已经购买过该课程'; +$error['order.has_bought_package'] = '已经购买过该套餐'; +$error['order.close_not_allowed'] = '当前不允许关闭订单'; +$error['order.refund_not_allowed'] = '当前不允许申请退款'; +$error['order.refund_item_unsupported'] = '该品类不支持退款'; +$error['order.refund_apply_existed'] = '退款申请已经存在'; /** * 交易相关 @@ -272,7 +275,7 @@ $error['trade.create_failed'] = '创建交易失败'; $error['trade.invalid_channel'] = '无效的平台类型'; $error['trade.close_not_allowed'] = '当前不允许关闭交易'; $error['trade.refund_not_allowed'] = '当前不允许交易退款'; -$error['trade.refund_existed'] = '退款申请已经存在,请等待处理结果'; +$error['trade.refund_apply_existed'] = '退款申请已经存在,请等待处理结果'; /** * 退款相关 diff --git a/public/static/web/css/common.css b/public/static/web/css/common.css index e8165626..31c69c3b 100644 --- a/public/static/web/css/common.css +++ b/public/static/web/css/common.css @@ -983,15 +983,16 @@ } .learning-course-card { - height: 230px; + height: 260px; } .learning-course-card .progress { - width: 210px; - padding: 15px 0; + width: 260px; + padding: 15px 0 15px 5px; } .learning-course-card .duration { + padding: 0 5px; font-size: 12px; color: #666; }