diff --git a/app/Caches/MaxPointGiftId.php b/app/Caches/MaxPointGiftId.php new file mode 100644 index 00000000..6c85c10a --- /dev/null +++ b/app/Caches/MaxPointGiftId.php @@ -0,0 +1,29 @@ +lifetime; + } + + public function getKey($id = null) + { + return 'max_point_gift_id'; + } + + public function getContent($id = null) + { + $gift = PointGiftModel::findFirst(['order' => 'id DESC']); + + return $gift->id ?? 0; + } + +} diff --git a/app/Caches/PointGift.php b/app/Caches/PointGift.php new file mode 100644 index 00000000..6a027a71 --- /dev/null +++ b/app/Caches/PointGift.php @@ -0,0 +1,31 @@ +lifetime; + } + + public function getKey($id = null) + { + return "point_gift:{$id}"; + } + + public function getContent($id = null) + { + $giftRepo = new PointGiftRepo(); + + $gift = $giftRepo->findById($id); + + return $gift ?: null; + } + +} diff --git a/app/Caches/PointHotGiftList.php b/app/Caches/PointHotGiftList.php new file mode 100644 index 00000000..30ae8aa6 --- /dev/null +++ b/app/Caches/PointHotGiftList.php @@ -0,0 +1,79 @@ +limit = $limit; + } + + public function getLifetime() + { + return $this->lifetime; + } + + public function getKey($id = null) + { + return 'point_hot_gift_list'; + } + + public function getContent($id = null) + { + $gifts = $this->findGifts($this->limit); + + if (count($gifts) == 0) { + return []; + } + + $result = []; + + foreach ($gifts as $gift) { + $result[] = [ + 'id' => $gift->id, + 'name' => $gift->name, + 'cover' => $gift->cover, + 'details' => $gift->details, + 'type' => $gift->type, + 'point' => $gift->point, + 'redeem_count' => $gift->redeem_count, + ]; + } + + return $result; + } + + /** + * @param int $limit + * @return ResultsetInterface|Resultset|PointGiftModel[] + */ + protected function findGifts($limit = 5) + { + return PointGiftModel::query() + ->where('published = 1') + ->orderBy('redeem_count DESC') + ->limit($limit) + ->execute(); + } + +} diff --git a/app/Console/Tasks/CleanLogTask.php b/app/Console/Tasks/CleanLogTask.php index 725dfa6c..e198d702 100644 --- a/app/Console/Tasks/CleanLogTask.php +++ b/app/Console/Tasks/CleanLogTask.php @@ -25,6 +25,7 @@ class CleanLogTask extends Task $this->cleanWxpayLog(); $this->cleanOrderLog(); $this->cleanRefundLog(); + $this->cleanPointLog(); $this->cleanNoticeLog(); $this->cleanOtherLog(); } @@ -221,6 +222,18 @@ class CleanLogTask extends Task $this->whitelist[] = $type; } + /** + * 清理积分日志 + */ + protected function cleanPointLog() + { + $type = 'point'; + + $this->cleanLog($type, 7); + + $this->whitelist[] = $type; + } + /** * 清理通知日志 */ diff --git a/app/Console/Tasks/CloseTradeTask.php b/app/Console/Tasks/CloseTradeTask.php index 3918d40c..efe84b3a 100644 --- a/app/Console/Tasks/CloseTradeTask.php +++ b/app/Console/Tasks/CloseTradeTask.php @@ -48,7 +48,7 @@ class CloseTradeTask extends Task */ if ($alipayTrade->trade_status == 'TRADE_SUCCESS') { - $this->eventsManager->fire('pay:afterPay', $this, $trade); + $this->eventsManager->fire('Trade:afterPay', $this, $trade); $allowClosed = false; @@ -85,7 +85,7 @@ class CloseTradeTask extends Task */ if ($wxpayTrade->trade_state == 'SUCCESS') { - $this->eventsManager->fire('pay:afterPay', $this, $trade); + $this->eventsManager->fire('Trade:afterPay', $this, $trade); $allowClosed = false; diff --git a/app/Console/Tasks/DeliverTask.php b/app/Console/Tasks/DeliverTask.php index 874401a4..d41a22b7 100644 --- a/app/Console/Tasks/DeliverTask.php +++ b/app/Console/Tasks/DeliverTask.php @@ -13,6 +13,7 @@ use App\Repos\ImGroupUser as ImGroupUserRepo; use App\Repos\Order as OrderRepo; use App\Repos\User as UserRepo; use App\Services\Logic\Notice\OrderFinish as OrderFinishNotice; +use App\Services\Logic\Point\PointHistory as PointHistoryService; use Phalcon\Mvc\Model; use Phalcon\Mvc\Model\Resultset; use Phalcon\Mvc\Model\ResultsetInterface; @@ -36,17 +37,20 @@ class DeliverTask extends Task foreach ($tasks as $task) { - /** - * @var array $itemInfo - */ - $itemInfo = $task->item_info; + $orderId = $task->item_info['order']['id'] ?? 0; - $order = $orderRepo->findById($itemInfo['order']['id']); + $order = $orderRepo->findById($orderId); - if (!$order) continue; + if (!$order) { + $task->status = TaskModel::STATUS_FAILED; + $task->update(); + continue; + } try { + $this->db->begin(); + switch ($order->item_type) { case OrderModel::ITEM_COURSE: $this->handleCourseOrder($order); @@ -59,14 +63,24 @@ class DeliverTask extends Task break; } - $this->finishOrder($order); + $order->status = OrderModel::STATUS_FINISHED; + + if ($order->update() === false) { + throw new \RuntimeException('Update Order Status Failed'); + } $task->status = TaskModel::STATUS_FINISHED; - $task->update(); + if ($task->update() === false) { + throw new \RuntimeException('Update Task Status Failed'); + } + + $this->db->commit(); } catch (\Exception $e) { + $this->db->rollback(); + $task->try_count += 1; $task->priority += 1; @@ -76,14 +90,16 @@ class DeliverTask extends Task $task->update(); - $logger->info('Order Process Exception ' . kg_json_encode([ - 'code' => $e->getCode(), + $logger->error('Order Process Exception ' . kg_json_encode([ + 'file' => $e->getFile(), + 'line' => $e->getLine(), 'message' => $e->getMessage(), 'task' => $task->toArray(), ])); } if ($task->status == TaskModel::STATUS_FINISHED) { + $this->handleOrderConsumePoint($order); $this->handleOrderFinishNotice($order); } elseif ($task->status == TaskModel::STATUS_FAILED) { $this->handleOrderRefund($order); @@ -91,20 +107,8 @@ class DeliverTask extends Task } } - protected function finishOrder(OrderModel $order) - { - $order->status = OrderModel::STATUS_FINISHED; - - if ($order->update() === false) { - throw new \RuntimeException('Finish Order Failed'); - } - } - protected function handleCourseOrder(OrderModel $order) { - /** - * @var array $itemInfo - */ $itemInfo = $order->item_info; $courseUser = new CourseUserModel(); @@ -127,23 +131,21 @@ class DeliverTask extends Task $groupUser = $groupUserRepo->findGroupUser($group->id, $order->owner_id); - if ($groupUser) return; + if (!$groupUser) { - $groupUser = new ImGroupUserModel(); + $groupUser = new ImGroupUserModel(); - $groupUser->group_id = $group->id; - $groupUser->user_id = $order->owner_id; + $groupUser->group_id = $group->id; + $groupUser->user_id = $order->owner_id; - if ($groupUser->create() === false) { - throw new \RuntimeException('Create Group User Failed'); + if ($groupUser->create() === false) { + throw new \RuntimeException('Create Group User Failed'); + } } } protected function handlePackageOrder(OrderModel $order) { - /** - * @var array $itemInfo - */ $itemInfo = $order->item_info; foreach ($itemInfo['courses'] as $course) { @@ -168,24 +170,24 @@ class DeliverTask extends Task $groupUser = $groupUserRepo->findGroupUser($group->id, $order->owner_id); - if ($groupUser) continue; + if (!$groupUser) { - $groupUser = new ImGroupUserModel(); + $groupUser = new ImGroupUserModel(); - $groupUser->group_id = $group->id; - $groupUser->user_id = $order->owner_id; + $groupUser->group_id = $group->id; + $groupUser->user_id = $order->owner_id; - if ($groupUser->create() === false) { - throw new \RuntimeException('Create Group User Failed'); + if ($groupUser->create() === false) { + throw new \RuntimeException('Create Group User Failed'); + } + + continue; } } } protected function handleVipOrder(OrderModel $order) { - /** - * @var array $itemInfo - */ $itemInfo = $order->item_info; $userRepo = new UserRepo(); @@ -199,6 +201,13 @@ class DeliverTask extends Task } } + protected function handleOrderConsumePoint(OrderModel $order) + { + $service = new PointHistoryService(); + + $service->handleOrderConsume($order); + } + protected function handleOrderFinishNotice(OrderModel $order) { $notice = new OrderFinishNotice(); diff --git a/app/Console/Tasks/NoticeTask.php b/app/Console/Tasks/NoticeTask.php index b736b80c..7d17318d 100644 --- a/app/Console/Tasks/NoticeTask.php +++ b/app/Console/Tasks/NoticeTask.php @@ -66,7 +66,6 @@ class NoticeTask extends Task $logger->info('Notice Process Exception ' . kg_json_encode([ 'file' => $e->getFile(), 'line' => $e->getLine(), - 'code' => $e->getCode(), 'message' => $e->getMessage(), 'task' => $task->toArray(), ])); diff --git a/app/Console/Tasks/PointGiftDeliverTask.php b/app/Console/Tasks/PointGiftDeliverTask.php new file mode 100644 index 00000000..0f8baac9 --- /dev/null +++ b/app/Console/Tasks/PointGiftDeliverTask.php @@ -0,0 +1,209 @@ +getLogger('point'); + + $tasks = $this->findTasks(30); + + if ($tasks->count() == 0) { + return; + } + + $redeemRepo = new PointRedeemRepo(); + + foreach ($tasks as $task) { + + $redeemId = $task->item_info['point_redeem']['id'] ?? 0; + + $redeem = $redeemRepo->findById($redeemId); + + if (!$redeem) { + $task->status = TaskModel::STATUS_FAILED; + $task->update(); + break; + } + + try { + + $this->db->begin(); + + switch ($redeem->gift_type) { + case PointGiftModel::TYPE_COURSE: + $this->handleCourseRedeem($redeem); + break; + case PointGiftModel::TYPE_GOODS: + $this->handleGoodsRedeem($redeem); + break; + case PointGiftModel::TYPE_CASH: + $this->handleCashRedeem($redeem); + break; + } + + $task->status = TaskModel::STATUS_FINISHED; + + if ($task->update() === false) { + throw new \RuntimeException('Update Task Status Failed'); + } + + $this->db->commit(); + + } catch (\Exception $e) { + + $this->db->rollback(); + + $task->try_count += 1; + $task->priority += 1; + + if ($task->try_count > self::TRY_COUNT) { + $task->status = TaskModel::STATUS_FAILED; + } + + $task->update(); + + $logger->error('Point Gift Deliver Exception ' . kg_json_encode([ + 'file' => $e->getFile(), + 'line' => $e->getLine(), + 'message' => $e->getMessage(), + 'task' => $task->toArray(), + ])); + } + + if ($task->status == TaskModel::STATUS_FAILED) { + $this->handlePointRefund($redeem); + } + } + } + + protected function handleCourseRedeem(PointRedeemModel $redeem) + { + $giftRepo = new PointGiftRepo(); + + $gift = $giftRepo->findById($redeem->gift_id); + + if (!$gift) { + throw new \RuntimeException('Gift Not Found'); + } + + $courseRepo = new CourseRepo(); + + $course = $courseRepo->findById($gift->attrs['id']); + + if (!$course) { + throw new \RuntimeException('Course Not Found'); + } + + $groupRepo = new ImGroupRepo(); + + $group = $groupRepo->findByCourseId($course->id); + + if (!$group) { + throw new \RuntimeException('Im Group Not Found'); + } + + $courseUserRepo = new CourseUserRepo(); + + $courseUser = $courseUserRepo->findCourseUser($course->id, $redeem->user_id); + + if (!$courseUser) { + + $courseUser = new CourseUserModel(); + + $courseUser->user_id = $redeem->user_id; + $courseUser->course_id = $course->id; + $courseUser->expiry_time = strtotime("+{$course->study_expiry} months"); + $courseUser->role_type = CourseUserModel::ROLE_STUDENT; + $courseUser->source_type = CourseUserModel::SOURCE_POINT_REDEEM; + + if ($courseUser->create() === false) { + throw new \RuntimeException('Create Course User Failed'); + } + } + + $groupUserRepo = new ImGroupUserRepo(); + + $groupUser = $groupUserRepo->findGroupUser($group->id, $redeem->user_id); + + if (!$groupUser) { + + $groupUser = new ImGroupUserModel(); + + $groupUser->group_id = $group->id; + $groupUser->user_id = $redeem->user_id; + + if ($groupUser->create() === false) { + throw new \RuntimeException('Create Group User Failed'); + } + } + + $redeem->status = PointRedeemModel::STATUS_FINISHED; + + if ($redeem->update() === false) { + throw new \RuntimeException('Update Redeem Status Failed'); + } + } + + protected function handleGoodsRedeem(PointRedeemModel $redeem) + { + + } + + protected function handleCashRedeem(PointRedeemModel $redeem) + { + + } + + protected function handlePointRefund(PointRedeemModel $redeem) + { + $service = new PointHistoryService(); + + $service->handlePointRefund($redeem); + } + + protected function handleRedeemFinishNotice(PointRedeemModel $redeem) + { + + } + + /** + * @param int $limit + * @return ResultsetInterface|Resultset|TaskModel[] + */ + protected function findTasks($limit = 30) + { + $itemType = TaskModel::TYPE_POINT_GIFT_DELIVER; + $status = TaskModel::STATUS_PENDING; + $createTime = strtotime('-3 days'); + + return TaskModel::query() + ->where('item_type = :item_type:', ['item_type' => $itemType]) + ->andWhere('status = :status:', ['status' => $status]) + ->andWhere('create_time > :create_time:', ['create_time' => $createTime]) + ->orderBy('priority ASC') + ->limit($limit) + ->execute(); + } + +} diff --git a/app/Console/Tasks/RefundTask.php b/app/Console/Tasks/RefundTask.php index 7529c242..4abc568e 100644 --- a/app/Console/Tasks/RefundTask.php +++ b/app/Console/Tasks/RefundTask.php @@ -41,9 +41,6 @@ class RefundTask extends Task foreach ($tasks as $task) { - /** - * @var array $itemInfo - */ $itemInfo = $task->item_info; $refund = $refundRepo->findById($itemInfo['refund']['id']); @@ -51,6 +48,8 @@ class RefundTask extends Task $order = $orderRepo->findById($itemInfo['refund']['order_id']); if (!$refund || !$trade || !$order) { + $task->status = TaskModel::STATUS_FAILED; + $task->update(); continue; } @@ -111,7 +110,8 @@ class RefundTask extends Task $task->update(); $logger->info('Refund Task Exception ' . kg_json_encode([ - 'code' => $e->getCode(), + 'file' => $e->getFile(), + 'line' => $e->getLine(), 'message' => $e->getMessage(), 'task' => $task->toArray(), ])); @@ -148,7 +148,7 @@ class RefundTask extends Task } if (!$response) { - throw new \RuntimeException('Pay Refund Failed'); + throw new \RuntimeException('Trade Refund Failed'); } } @@ -208,9 +208,6 @@ class RefundTask extends Task { $courseUserRepo = new CourseUserRepo(); - /** - * @var array $itemInfo - */ $itemInfo = $order->item_info; foreach ($itemInfo['courses'] as $course) { @@ -239,9 +236,6 @@ class RefundTask extends Task $user = $userRepo->findById($order->owner_id); - /** - * @var array $itemInfo - */ $itemInfo = $order->item_info; $diffTime = "-{$itemInfo['vip']['expiry']} months"; diff --git a/app/Console/Tasks/SyncLearningTask.php b/app/Console/Tasks/SyncLearningTask.php index af1f41aa..2ba7a0e8 100644 --- a/app/Console/Tasks/SyncLearningTask.php +++ b/app/Console/Tasks/SyncLearningTask.php @@ -2,6 +2,7 @@ namespace App\Console\Tasks; +use App\Models\ChapterUser as ChapterUserModel; use App\Models\Course as CourseModel; use App\Models\Learning as LearningModel; use App\Repos\Chapter as ChapterRepo; @@ -9,7 +10,8 @@ use App\Repos\ChapterUser as ChapterUserRepo; use App\Repos\Course as CourseRepo; use App\Repos\CourseUser as CourseUserRepo; use App\Repos\Learning as LearningRepo; -use App\Services\Sync\Learning as LearningSync; +use App\Services\Logic\Point\PointHistory as PointHistoryService; +use App\Services\Sync\Learning as LearningSyncService; class SyncLearningTask extends Task { @@ -18,7 +20,7 @@ class SyncLearningTask extends Task { $redis = $this->getRedis(); - $sync = new LearningSync(); + $sync = new LearningSyncService(); $syncKey = $sync->getSyncKey(); @@ -120,7 +122,10 @@ class SyncLearningTask extends Task $chapterUser->update(); if ($chapterUser->consumed == 1) { + $this->updateCourseUser($learning); + + $this->handleStudyPoint($chapterUser); } } @@ -174,4 +179,14 @@ class SyncLearningTask extends Task $courseUser->update(); } + /** + * @param ChapterUserModel $chapterUser + */ + protected function handleStudyPoint(ChapterUserModel $chapterUser) + { + $service = new PointHistoryService(); + + $service->handleChapterStudy($chapterUser); + } + } diff --git a/app/Http/Admin/Controllers/Controller.php b/app/Http/Admin/Controllers/Controller.php index 25899d50..9cfeb456 100644 --- a/app/Http/Admin/Controllers/Controller.php +++ b/app/Http/Admin/Controllers/Controller.php @@ -37,8 +37,6 @@ class Controller extends \Phalcon\Mvc\Controller $this->checkCsrfToken(); } - $this->checkRateLimit(); - $this->authInfo = $this->getAuthInfo(); if (!$this->authInfo) { diff --git a/app/Http/Admin/Controllers/PointGiftController.php b/app/Http/Admin/Controllers/PointGiftController.php new file mode 100644 index 00000000..fafda241 --- /dev/null +++ b/app/Http/Admin/Controllers/PointGiftController.php @@ -0,0 +1,128 @@ +getGifts(); + + $this->view->pick('point/gift/list'); + + $this->view->setVar('pager', $pager); + } + + /** + * @Get("/add", name="admin.point_gift.add") + */ + public function addAction() + { + $this->view->pick('point/gift/add'); + } + + /** + * @Get("/{id:[0-9]+}/edit", name="admin.point_gift.edit") + */ + public function editAction($id) + { + $giftService = new PointGiftService(); + + $gift = $giftService->getGift($id); + + $this->view->pick('point/gift/edit'); + + $this->view->setVar('gift', $gift); + } + + /** + * @Post("/create", name="admin.point_gift.create") + */ + public function createAction() + { + $giftService = new PointGiftService(); + + $gift = $giftService->createGift(); + + $location = $this->url->get([ + 'for' => 'admin.point_gift.edit', + 'id' => $gift->id, + ]); + + $content = [ + 'location' => $location, + 'msg' => '添加礼品成功', + ]; + + return $this->jsonSuccess($content); + } + + /** + * @Post("/{id:[0-9]+}/update", name="admin.point_gift.update") + */ + public function updateAction($id) + { + $giftService = new PointGiftService(); + + $giftService->updateGift($id); + + $location = $this->url->get(['for' => 'admin.point_gift.list']); + + $content = [ + 'location' => $location, + 'msg' => '更新礼品成功', + ]; + + return $this->jsonSuccess($content); + } + + /** + * @Post("/{id:[0-9]+}/delete", name="admin.point_gift.delete") + */ + public function deleteAction($id) + { + $giftService = new PointGiftService(); + + $giftService->deleteGift($id); + + $location = $this->request->getHTTPReferer(); + + $content = [ + 'location' => $location, + 'msg' => '删除礼品成功', + ]; + + return $this->jsonSuccess($content); + } + + /** + * @Post("/{id:[0-9]+}/restore", name="admin.point_gift.restore") + */ + public function restoreAction($id) + { + $giftService = new PointGiftService(); + + $giftService->restoreGift($id); + + $location = $this->request->getHTTPReferer(); + + $content = [ + 'location' => $location, + 'msg' => '还原礼品成功', + ]; + + return $this->jsonSuccess($content); + } + +} diff --git a/app/Http/Admin/Controllers/PointRedeemController.php b/app/Http/Admin/Controllers/PointRedeemController.php new file mode 100644 index 00000000..707403d3 --- /dev/null +++ b/app/Http/Admin/Controllers/PointRedeemController.php @@ -0,0 +1,47 @@ +view->pick('point/redeem/search'); + } + + /** + * @Get("/list", name="admin.point_redeem.list") + */ + public function listAction() + { + $redeemService = new PointRedeemService(); + + $pager = $redeemService->getRedeems(); + + $this->view->pick('point/redeem/list'); + + $this->view->setVar('pager', $pager); + } + + /** + * @Post("/{id:[0-9]+}/deliver", name="admin.point_redeem.deliver") + */ + public function deliverAction($id) + { + $redeemService = new PointRedeemService(); + + $redeemService->deliver($id); + + return $this->jsonSuccess(['msg' => '发货成功']); + } + +} diff --git a/app/Http/Admin/Controllers/SettingController.php b/app/Http/Admin/Controllers/SettingController.php index 7d949a67..76cff636 100644 --- a/app/Http/Admin/Controllers/SettingController.php +++ b/app/Http/Admin/Controllers/SettingController.php @@ -50,7 +50,7 @@ class SettingController extends Controller $data = $this->request->getPost(); - $settingService->updateStorageSettings($section, $data); + $settingService->updateSettings($section, $data); return $this->jsonSuccess(['msg' => '更新配置成功']); @@ -248,6 +248,31 @@ class SettingController extends Controller } } + /** + * @Route("/point", name="admin.setting.point") + */ + public function pointAction() + { + $section = 'point'; + + $settingService = new SettingService(); + + if ($this->request->isPost()) { + + $data = $this->request->getPost(); + + $settingService->updatePointSettings($section, $data); + + return $this->jsonSuccess(['msg' => '更新配置成功']); + + } else { + + $point = $settingService->getSettings($section); + + $this->view->setVar('point', $point); + } + } + /** * @Route("/vip", name="admin.setting.vip") */ diff --git a/app/Http/Admin/Services/AuthNode.php b/app/Http/Admin/Services/AuthNode.php index 77104b1d..f29c29dc 100644 --- a/app/Http/Admin/Services/AuthNode.php +++ b/app/Http/Admin/Services/AuthNode.php @@ -476,6 +476,43 @@ class AuthNode extends Service ], ], ], + [ + 'id' => '2-8', + 'title' => '积分商城', + 'type' => 'menu', + 'children' => [ + [ + 'id' => '2-8-1', + 'title' => '兑换记录', + 'type' => 'menu', + 'route' => 'admin.point_redeem.list', + ], + [ + 'id' => '2-8-2', + 'title' => '礼品列表', + 'type' => 'menu', + 'route' => 'admin.point_gift.list', + ], + [ + 'id' => '2-8-3', + 'title' => '添加礼品', + 'type' => 'menu', + 'route' => 'admin.point_gift.add', + ], + [ + 'id' => '2-8-4', + 'title' => '编辑礼品', + 'type' => 'button', + 'route' => 'admin.point_gift.edit', + ], + [ + 'id' => '2-8-5', + 'title' => '删除礼品', + 'type' => 'button', + 'route' => 'admin.point_gift.delete', + ], + ], + ], ], ]; } @@ -763,6 +800,12 @@ class AuthNode extends Service 'type' => 'menu', 'route' => 'admin.setting.wechat_oa', ], + [ + 'id' => '5-1-14', + 'title' => '积分设置', + 'type' => 'menu', + 'route' => 'admin.setting.point', + ], ], ], ], diff --git a/app/Http/Admin/Services/PointGift.php b/app/Http/Admin/Services/PointGift.php new file mode 100644 index 00000000..4a78efc0 --- /dev/null +++ b/app/Http/Admin/Services/PointGift.php @@ -0,0 +1,159 @@ +getParams(); + + $params['deleted'] = $params['deleted'] ?? 0; + + $sort = $pagerQuery->getSort(); + $page = $pagerQuery->getPage(); + $limit = $pagerQuery->getLimit(); + + $giftRepo = new PointGiftRepo(); + + return $giftRepo->paginate($params, $sort, $page, $limit); + } + + public function getGift($id) + { + return $this->findOrFail($id); + } + + public function createGift() + { + $post = $this->request->getPost(); + + $validator = new PointGiftValidator(); + + $post['type'] = $validator->checkType($post['type']); + + $gift = new PointGiftModel(); + + switch ($post['type']) { + case PointGiftModel::TYPE_COURSE: + $gift = $this->createCourseGift($post); + break; + case PointGiftModel::TYPE_GOODS: + $gift = $this->createCommodityGift($post); + break; + } + + return $gift; + } + + public function updateGift($id) + { + $gift = $this->findOrFail($id); + + $post = $this->request->getPost(); + + $validator = new PointGiftValidator(); + + $data = []; + + if (isset($post['cover'])) { + $data['cover'] = $validator->checkCover($post['cover']); + } + + if (isset($post['name'])) { + $data['name'] = $validator->checkName($post['name']); + } + + if (isset($post['details'])) { + $data['details'] = $validator->checkDetails($post['details']); + } + + if (isset($post['point'])) { + $data['point'] = $validator->checkPoint($post['point']); + } + + if (isset($post['stock'])) { + $data['stock'] = $validator->checkStock($post['stock']); + } + + if (isset($post['redeem_limit'])) { + $data['redeem_limit'] = $validator->checkRedeemLimit($post['redeem_limit']); + } + + if (isset($post['published'])) { + $data['published'] = $validator->checkPublishStatus($post['published']); + } + + $gift->update($data); + + return $gift; + } + + public function deleteGift($id) + { + $gift = $this->findOrFail($id); + + $gift->deleted = 1; + + $gift->update(); + + return $gift; + } + + public function restoreGift($id) + { + $gift = $this->findOrFail($id); + + $gift->deleted = 0; + + $gift->update(); + + return $gift; + } + + protected function createCourseGift($post) + { + $validator = new PointGiftValidator(); + + $course = $validator->checkCourse($post['course_id']); + + $gift = new PointGiftModel(); + + $gift->type = PointGiftModel::TYPE_COURSE; + $gift->name = $course->title; + + $gift->create(); + + return $gift; + } + + protected function createCommodityGift($post) + { + $validator = new PointGiftValidator(); + + $gift = new PointGiftModel(); + + $gift->type = PointGiftModel::TYPE_GOODS; + $gift->name = $validator->checkName($post['name']); + + $gift->create(); + + return $gift; + } + + protected function findOrFail($id) + { + $validator = new PointGiftValidator(); + + return $validator->checkGift($id); + } + +} diff --git a/app/Http/Admin/Services/PointRedeem.php b/app/Http/Admin/Services/PointRedeem.php new file mode 100644 index 00000000..f3812807 --- /dev/null +++ b/app/Http/Admin/Services/PointRedeem.php @@ -0,0 +1,58 @@ +getParams(); + + $params['deleted'] = $params['deleted'] ?? 0; + + $sort = $pagerQuery->getSort(); + $page = $pagerQuery->getPage(); + $limit = $pagerQuery->getLimit(); + + $redeemRepo = new PointRedeemRepo(); + + return $redeemRepo->paginate($params, $sort, $page, $limit); + } + + public function getRedeem($id) + { + return $this->findOrFail($id); + } + + public function deliver($id) + { + $redeem = $this->findOrFail($id); + + if ($redeem->gift_type != PointGiftModel::TYPE_GOODS) { + return $redeem; + } + + $redeem->status = PointRedeemModel::STATUS_FINISHED; + + $redeem->update(); + + return $redeem; + } + + protected function findOrFail($id) + { + $validator = new PointRedeemValidator(); + + return $validator->checkRedeem($id); + } + +} diff --git a/app/Http/Admin/Services/Session.php b/app/Http/Admin/Services/Session.php index fae5222b..b89a1499 100644 --- a/app/Http/Admin/Services/Session.php +++ b/app/Http/Admin/Services/Session.php @@ -50,11 +50,17 @@ class Session extends Service $this->handleLoginNotice($user); $this->auth->saveAuthInfo($user); + + $this->eventsManager->fire('Account:afterLogin', $this, $user); } public function logout() { + $user = $this->getLoginUser(); + $this->auth->clearAuthInfo(); + + $this->eventsManager->fire('Account:afterLogout', $this, $user); } protected function handleLoginNotice(UserModel $user) diff --git a/app/Http/Admin/Services/Setting.php b/app/Http/Admin/Services/Setting.php index 3ce3f6ac..35ff796c 100644 --- a/app/Http/Admin/Services/Setting.php +++ b/app/Http/Admin/Services/Setting.php @@ -189,6 +189,19 @@ class Setting extends Service $this->updateSettings($section, $settings); } + public function updatePointSettings($section, $settings) + { + if (isset($settings['event_rule'])) { + $settings['event_rule'] = kg_json_encode($settings['event_rule']); + } + + if (isset($settings['consume_rule'])) { + $settings['consume_rule'] = kg_json_encode($settings['consume_rule']); + } + + $this->updateSettings($section, $settings); + } + public function updateVipSettings($items) { $vipRepo = new VipRepo(); diff --git a/app/Http/Admin/Services/Topic.php b/app/Http/Admin/Services/Topic.php index ac8289bf..7b0f2544 100644 --- a/app/Http/Admin/Services/Topic.php +++ b/app/Http/Admin/Services/Topic.php @@ -3,7 +3,6 @@ namespace App\Http\Admin\Services; use App\Caches\Topic as TopicCache; -use App\Caches\TopicCourseList as TopicCourseListCache; use App\Library\Paginator\Query as PagerQuery; use App\Models\CourseTopic as CourseTopicModel; use App\Models\Topic as TopicModel; @@ -66,8 +65,8 @@ class Topic extends Service $data = []; - if (isset($post['name'])) { - $data['name'] = $validator->checkName($post['name']); + if (isset($post['title'])) { + $data['title'] = $validator->checkTitle($post['title']); } if (isset($post['summary'])) { @@ -194,10 +193,6 @@ class Topic extends Service $cache = new TopicCache(); $cache->rebuild($topic->id); - - $cache = new TopicCourseListCache(); - - $cache->rebuild($topic->id); } protected function findOrFail($id) diff --git a/app/Http/Admin/Views/macros/point.volt b/app/Http/Admin/Views/macros/point.volt new file mode 100644 index 00000000..8b2d6093 --- /dev/null +++ b/app/Http/Admin/Views/macros/point.volt @@ -0,0 +1,61 @@ +{%- macro redeem_status_info(value) %} + {% if value == 1 %} + 处理中 + {% elseif value == 2 %} + 已完成 + {% elseif value == 3 %} + 已失败 + {% endif %} +{%- endmacro %} + +{%- macro gift_type_info(value) %} + {% if value == 1 %} + 课程 + {% elseif value == 2 %} + 商品 + {% elseif value == 3 %} + 现金 + {% endif %} +{%- endmacro %} + +{%- macro event_type_info(value) %} + {% if value == 1 %} + 订单消费 + {% elseif value == 2 %} + 积分兑换 + {% elseif value == 3 %} + 积分退款 + {% elseif value == 4 %} + 帐号注册 + {% elseif value == 5 %} + 站点访问 + {% elseif value == 6 %} + 课时学习 + {% elseif value == 7 %} + 课程评价 + {% elseif value == 8 %} + 微聊讨论 + {% endif %} +{%- endmacro %} + +{%- macro event_detail_info(history) %} + {% set event_info = history.event_info %} + {% if history.event_type == 1 %} +

{{ event_info.order.subject }}

+ {% elseif history.event_type == 2 %} +

{{ event_info.point_redeem.gift_name }}

+ {% elseif history.event_type == 3 %} + {{ event_info.point_redeem.gift_name }} + {% elseif history.event_type == 4 %} + N/A + {% elseif history.event_type == 5 %} + N/A + {% elseif history.event_type == 6 %} +

课程:{{ event_info.course.title }}

+

章节:{{ event_info.chapter.title }}

+ {% elseif history.event_type == 7 %} +

{{ event_info.course.title }}

+ {% elseif history.event_type == 8 %} + N/A + {% endif %} +{%- endmacro %} \ No newline at end of file diff --git a/app/Http/Admin/Views/point/gift/add.volt b/app/Http/Admin/Views/point/gift/add.volt new file mode 100644 index 00000000..f4ea046a --- /dev/null +++ b/app/Http/Admin/Views/point/gift/add.volt @@ -0,0 +1,62 @@ +{% extends 'templates/main.volt' %} + +{% block content %} + +
+
+ 添加礼品 +
+
+ +
+ + +
+
+ + +
+ +
+ + +
+
+
+ +{% endblock %} + +{% block inline_js %} + + + +{% endblock %} \ No newline at end of file diff --git a/app/Http/Admin/Views/point/gift/edit.volt b/app/Http/Admin/Views/point/gift/edit.volt new file mode 100644 index 00000000..a2560c51 --- /dev/null +++ b/app/Http/Admin/Views/point/gift/edit.volt @@ -0,0 +1,114 @@ +{% extends 'templates/main.volt' %} + +{% block content %} + + {% set update_url = url({'for':'admin.point_gift.update','id':gift.id}) %} + + {% if gift.type == 1 %} +
+
+ 编辑礼品 +
+
+ +
+ +
+
+
+ +
{{ gift.name }}
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ + +
+
+
+ {% endif %} + + {% if gift.type == 2 %} +
+
+ 编辑礼品 +
+
+ +
+ + +
+
+ +
+
+
+ +
+ +
+
+
+ +
+
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ + +
+
+
+ {% endif %} + +{% endblock %} + +{% block link_css %} + + {{ css_link('https://cdn.jsdelivr.net/npm/vditor/dist/index.css', false) }} + +{% endblock %} + +{% block include_js %} + + {{ js_include('https://cdn.jsdelivr.net/npm/vditor/dist/index.min.js', false) }} + {{ js_include('admin/js/cover.upload.js') }} + {{ js_include('admin/js/vditor.js') }} + +{% endblock %} \ No newline at end of file diff --git a/app/Http/Admin/Views/point/gift/list.volt b/app/Http/Admin/Views/point/gift/list.volt new file mode 100644 index 00000000..2089f1bc --- /dev/null +++ b/app/Http/Admin/Views/point/gift/list.volt @@ -0,0 +1,83 @@ +{% extends 'templates/main.volt' %} + +{% block content %} + + {{ partial('macros/point') }} + + {% set add_url = url({'for':'admin.point_gift.add'}) %} + +
+
+ + 礼品管理 + +
+
+ + 添加礼品 + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + {% for item in pager.items %} + {% set redeem_url = url({'for':'admin.point_redeem.list'},{'gift_id':item.id}) %} + {% set preview_url = url({'for':'home.point_gift.show','id':item.id}) %} + {% set edit_url = url({'for':'admin.point_gift.edit','id':item.id}) %} + {% set update_url = url({'for':'admin.point_gift.update','id':item.id}) %} + {% set delete_url = url({'for':'admin.point_gift.delete','id':item.id}) %} + {% set restore_url = url({'for':'admin.point_gift.restore','id':item.id}) %} + + + + + + + + + + + {% endfor %} + +
编号物品名称所需积分库存数量兑换限额兑换人次发布操作
{{ item.id }}{{ item.name }} {{ gift_type_info(item.type) }}{{ item.point }}{{ item.stock }}{{ item.redeem_limit }}{{ item.redeem_count }} +
+ + +
+
+ + {{ partial('partials/pager') }} + +{% endblock %} \ No newline at end of file diff --git a/app/Http/Admin/Views/point/gift/search.volt b/app/Http/Admin/Views/point/gift/search.volt new file mode 100644 index 00000000..9ce882e2 --- /dev/null +++ b/app/Http/Admin/Views/point/gift/search.volt @@ -0,0 +1,64 @@ +{% extends 'templates/main.volt' %} + +{% block content %} + +
+
+ 搜索群组 +
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ + + +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +{% endblock %} \ No newline at end of file diff --git a/app/Http/Admin/Views/point/redeem/list.volt b/app/Http/Admin/Views/point/redeem/list.volt new file mode 100644 index 00000000..c86b4b1b --- /dev/null +++ b/app/Http/Admin/Views/point/redeem/list.volt @@ -0,0 +1,100 @@ +{% extends 'templates/main.volt' %} + +{% block content %} + + {{ partial('macros/point') }} + + {% set search_url = url({'for':'admin.point_redeem.search'}) %} + +
+
+ + 兑换记录 + +
+
+ + 搜索兑换 + +
+
+ + + + + + + + + + + + + + + + + + + + {% for item in pager.items %} + {% set user_filter_url = url({'for':'admin.point_redeem.list'},{'user_id':item.user_id}) %} + {% set deliver_url = url({'for':'admin.point_redeem.deliver','id':item.id}) %} + {% set gift_url = url({'for':'home.point_gift.show','id':item.gift_id}) %} + + + + + + + + {% endfor %} + +
物品名称消耗积分兑换状态兑换时间操作
+

{{ item.gift_name }}({{ item.gift_id }}){{ gift_type_info(item.gift_type) }}

+

用户名称:{{ item.user_name }} ({{ item.user_id }}) 联系方式: + +

+
{{ item.gift_point }}{{ redeem_status_info(item.status) }}{{ date('Y-m-d H:i',item.create_time) }} + {% if item.gift_type == 2 %} + + {% else %} + N/A + {% endif %} +
+ + {{ partial('partials/pager') }} + +{% endblock %} + +{% block inline_js %} + + + +{% endblock %} + +{% block include_js %} + + {{ js_include('admin/js/contact.js') }} + +{% endblock %} \ No newline at end of file diff --git a/app/Http/Admin/Views/point/redeem/search.volt b/app/Http/Admin/Views/point/redeem/search.volt new file mode 100644 index 00000000..49a91340 --- /dev/null +++ b/app/Http/Admin/Views/point/redeem/search.volt @@ -0,0 +1,46 @@ +{% extends 'templates/main.volt' %} + +{% block content %} + +
+
+ 搜索兑换 +
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ + + +
+
+
+ +
+ + + +
+
+
+ +
+ + +
+
+
+ +{% endblock %} \ No newline at end of file diff --git a/app/Http/Admin/Views/setting/point.volt b/app/Http/Admin/Views/setting/point.volt new file mode 100644 index 00000000..e3fd8ed8 --- /dev/null +++ b/app/Http/Admin/Views/setting/point.volt @@ -0,0 +1,112 @@ +{% extends 'templates/main.volt' %} + +{% block content %} + + {% set consume_rule = point.consume_rule|json_decode %} + {% set event_rule = point.event_rule|json_decode %} + +
+
+ 积分设置 +
+
+ +
+ + +
+
+
+ 消费奖励规则 +
+
+ +
+ + +
+
+
+ +
+ +
+
奖励积分 = 消费金额 X 奖励倍率
+
+
+ 行为奖励规则 +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
行为类型奖励积分每日上限启用规则
帐号注册N/A + + +
站点访问N/A + + +
课程评价N/A + + +
课时学习N/A + + +
微聊讨论N/A + + +
+
+
+ +
+ + +
+
+
+ +{% endblock %} \ No newline at end of file diff --git a/app/Http/Admin/Views/student/list.volt b/app/Http/Admin/Views/student/list.volt index bc673b7b..16d92f20 100644 --- a/app/Http/Admin/Views/student/list.volt +++ b/app/Http/Admin/Views/student/list.volt @@ -6,9 +6,15 @@ {% if value == 1 %} 免费 {% elseif value == 2 %} - 付费 + 付费 {% elseif value == 3 %} 导入 + {% elseif value == 4 %} + 会员 + {% elseif value == 5 %} + 积分 + {% elseif value == 6 %} + 抽奖 {% endif %} {%- endmacro %} @@ -58,8 +64,8 @@ {{ source_type_info(item.source_type) }} -

开始:{{ date('Y-m-d H:i:s',item.create_time) }}

-

结束:{{ date('Y-m-d H:i:s',item.expiry_time) }}

+

开始:{{ date('Y-m-d H:i',item.create_time) }}

+

结束:{{ date('Y-m-d H:i',item.expiry_time) }}

diff --git a/app/Http/Api/Controllers/Controller.php b/app/Http/Api/Controllers/Controller.php index d33b4eeb..12d00f18 100644 --- a/app/Http/Api/Controllers/Controller.php +++ b/app/Http/Api/Controllers/Controller.php @@ -2,7 +2,8 @@ namespace App\Http\Api\Controllers; -use App\Services\Auth\Api as AppAuth; +use App\Models\User as UserModel; +use App\Services\Auth\Api as ApiAuth; use App\Traits\Response as ResponseTrait; use App\Traits\Security as SecurityTrait; use Phalcon\Mvc\Dispatcher; @@ -10,6 +11,11 @@ use Phalcon\Mvc\Dispatcher; class Controller extends \Phalcon\Mvc\Controller { + /** + * @var UserModel + */ + protected $authUser; + use ResponseTrait; use SecurityTrait; @@ -19,17 +25,22 @@ class Controller extends \Phalcon\Mvc\Controller $this->setCors(); } - if (!$this->request->isOptions()) { - $this->checkRateLimit(); - } + $this->checkRateLimit(); return true; } + public function initialize() + { + $this->authUser = $this->getAuthUser(); + + $this->eventsManager->fire('Site:afterView', $this, $this->authUser); + } + protected function getAuthUser() { /** - * @var AppAuth $auth + * @var ApiAuth $auth */ $auth = $this->getDI()->get('auth'); diff --git a/app/Http/Api/Services/Account.php b/app/Http/Api/Services/Account.php index 9ce43137..b10af251 100644 --- a/app/Http/Api/Services/Account.php +++ b/app/Http/Api/Services/Account.php @@ -6,8 +6,9 @@ use App\Models\User as UserModel; use App\Repos\User as UserRepo; use App\Services\Auth\Api as AuthService; use App\Services\Logic\Account\Register as RegisterService; -use App\Services\Logic\Notice\AccountLogin as AccountLoginNoticeService; use App\Validators\Account as AccountValidator; +use Phalcon\Di as Di; +use Phalcon\Events\Manager as EventsManager; class Account extends Service { @@ -32,7 +33,11 @@ class Account extends Service $user = $userRepo->findById($account->id); - return $this->auth->saveAuthInfo($user); + $token = $this->auth->saveAuthInfo($user); + + $this->fireAfterRegisterEvent($user); + + return $token; } public function loginByPassword() @@ -52,9 +57,11 @@ class Account extends Service $user = $validator->checkUserLogin($post['account'], $post['password']); - $this->handleLoginNotice($user); + $token = $this->auth->saveAuthInfo($user); - return $this->auth->saveAuthInfo($user); + $this->fireAfterLoginEvent($user); + + return $token; } public function loginByVerify() @@ -74,21 +81,50 @@ class Account extends Service $user = $validator->checkVerifyLogin($post['account'], $post['verify_code']); - $this->handleLoginNotice($user); + $token = $this->auth->saveAuthInfo($user); - return $this->auth->saveAuthInfo($user); + $this->fireAfterLoginEvent($user); + + return $token; } public function logout() { + $user = $this->getLoginUser(); + $this->auth->clearAuthInfo(); + + $this->fireAfterLogoutEvent($user); } - protected function handleLoginNotice(UserModel $user) + protected function fireAfterRegisterEvent(UserModel $user) { - $service = new AccountLoginNoticeService(); + /** + * @var EventsManager $eventsManager + */ + $eventsManager = Di::getDefault()->getShared('eventsManager'); - $service->createTask($user); + $eventsManager->fire('Account:afterRegister', $this, $user); + } + + protected function fireAfterLoginEvent(UserModel $user) + { + /** + * @var EventsManager $eventsManager + */ + $eventsManager = Di::getDefault()->getShared('eventsManager'); + + $eventsManager->fire('Account:afterLogin', $this, $user); + } + + protected function fireAfterLogoutEvent(UserModel $user) + { + /** + * @var EventsManager $eventsManager + */ + $eventsManager = Di::getDefault()->getShared('eventsManager'); + + $eventsManager->fire('Account:afterLogout', $this, $user); } } diff --git a/app/Http/Home/Controllers/ChapterController.php b/app/Http/Home/Controllers/ChapterController.php index 4cc0cc3c..b23e6454 100644 --- a/app/Http/Home/Controllers/ChapterController.php +++ b/app/Http/Home/Controllers/ChapterController.php @@ -9,6 +9,7 @@ use App\Services\Logic\Chapter\ChapterLike as ChapterLikeService; use App\Services\Logic\Chapter\DanmuList as ChapterDanmuListService; use App\Services\Logic\Chapter\Learning as ChapterLearningService; use App\Services\Logic\Chapter\ResourceList as ChapterResourceListService; +use App\Services\Logic\Course\BasicInfo as CourseInfoService; use App\Services\Logic\Course\ChapterList as CourseChapterListService; /** @@ -50,20 +51,24 @@ class ChapterController extends Controller $chapter = $service->handle($id); + $service = new CourseInfoService(); + + $course = $service->handle($chapter['course']['id']); + $owned = $chapter['me']['owned'] ?? false; if (!$owned) { $this->response->redirect([ 'for' => 'home.course.show', - 'id' => $chapter['course']['id'], + 'id' => $course['id'], ]); } $service = new CourseChapterListService(); - $catalog = $service->handle($chapter['course']['id']); + $catalog = $service->handle($course['id']); - $this->seo->prependTitle(['章节', $chapter['title'], $chapter['course']['title']]); + $this->seo->prependTitle(['章节', $chapter['title'], $course['title']]); if (!empty($chapter['summary'])) { $this->seo->setDescription($chapter['summary']); @@ -83,6 +88,7 @@ class ChapterController extends Controller } } + $this->view->setVar('course', $course); $this->view->setVar('chapter', $chapter); $this->view->setVar('catalog', $catalog); } diff --git a/app/Http/Home/Controllers/Controller.php b/app/Http/Home/Controllers/Controller.php index df84d9d2..301b0191 100644 --- a/app/Http/Home/Controllers/Controller.php +++ b/app/Http/Home/Controllers/Controller.php @@ -66,17 +66,15 @@ class Controller extends \Phalcon\Mvc\Controller $this->checkCsrfToken(); } - $config = $this->getConfig(); - - if ($config->path('throttle.enabled')) { - $this->checkRateLimit(); - } + $this->checkRateLimit(); return true; } public function initialize() { + $this->eventsManager->fire('Site:afterView', $this, $this->authUser); + $this->seo = $this->getSeo(); $this->navs = $this->getNavs(); $this->appInfo = $this->getAppInfo(); diff --git a/app/Http/Home/Controllers/PointGiftController.php b/app/Http/Home/Controllers/PointGiftController.php new file mode 100644 index 00000000..6fab4cdc --- /dev/null +++ b/app/Http/Home/Controllers/PointGiftController.php @@ -0,0 +1,103 @@ +authUser->id == 0) { + $this->response->redirect(['for' => 'home.account.login']); + return false; + } + + return true; + } + + /** + * @Get("/list", name="home.point_gift.list") + */ + public function listAction() + { + $this->seo->prependTitle('积分兑换'); + + $this->view->pick('point/gift/list'); + } + + /** + * @Get("/pager", name="home.point_gift.pager") + */ + public function pagerAction() + { + $service = new GiftListService(); + + $pager = $service->handle(); + + $pager->target = 'gift-list'; + + $this->view->setRenderLevel(View::LEVEL_ACTION_VIEW); + $this->view->pick('point/gift/pager'); + $this->view->setVar('pager', $pager); + } + + /** + * @Get("/{id:[0-9]+}", name="home.point_gift.show") + */ + public function showAction($id) + { + $service = new GiftInfoService(); + + $gift = $service->handle($id); + + $hotGifts = $this->getHotGifts(); + $userBalance = $this->getUserBalance(); + + $this->seo->prependTitle(['积分兑换', $gift['name']]); + + $this->view->pick('point/gift/show'); + $this->view->setVar('gift', $gift); + $this->view->setVar('hot_gifts', $hotGifts); + $this->view->setVar('user_balance', $userBalance); + } + + /** + * @Post("/redeem", name="home.point_gift.redeem") + */ + public function redeemAction() + { + $service = new GiftRedeemService(); + + $service->handle(); + + return $this->jsonSuccess(['msg' => '兑换成功']); + } + + protected function getHotGifts() + { + $service = new HotGiftListService(); + + return $service->handle(); + } + + protected function getUserBalance() + { + $service = new BalanceInfoService(); + + return $service->handle(); + } + +} diff --git a/app/Http/Home/Controllers/PointRedeemController.php b/app/Http/Home/Controllers/PointRedeemController.php new file mode 100644 index 00000000..37b99430 --- /dev/null +++ b/app/Http/Home/Controllers/PointRedeemController.php @@ -0,0 +1,25 @@ +handle(); + + return $this->jsonSuccess(['msg' => '兑换成功']); + } + +} diff --git a/app/Http/Home/Controllers/UserConsoleController.php b/app/Http/Home/Controllers/UserConsoleController.php index 12ed2de5..16f22f8f 100644 --- a/app/Http/Home/Controllers/UserConsoleController.php +++ b/app/Http/Home/Controllers/UserConsoleController.php @@ -8,11 +8,15 @@ use App\Services\Logic\User\Console\AccountInfo as AccountInfoService; use App\Services\Logic\User\Console\ConnectDelete as ConnectDeleteService; use App\Services\Logic\User\Console\ConnectList as ConnectListService; use App\Services\Logic\User\Console\ConsultList as ConsultListService; +use App\Services\Logic\User\Console\ContactInfo as ContactInfoService; +use App\Services\Logic\User\Console\ContactUpdate as ContactUpdateService; use App\Services\Logic\User\Console\CourseList as CourseListService; use App\Services\Logic\User\Console\FavoriteList as FavoriteListService; use App\Services\Logic\User\Console\FriendList as FriendListService; use App\Services\Logic\User\Console\GroupList as GroupListService; use App\Services\Logic\User\Console\OrderList as OrderListService; +use App\Services\Logic\User\Console\PointHistory as PointHistoryService; +use App\Services\Logic\User\Console\PointRedeemList as PointRedeemListService; use App\Services\Logic\User\Console\ProfileInfo as ProfileInfoService; use App\Services\Logic\User\Console\ProfileUpdate as ProfileUpdateService; use App\Services\Logic\User\Console\RefundList as RefundListService; @@ -67,6 +71,19 @@ class UserConsoleController extends Controller $this->view->setVar('user', $user); } + /** + * @Get("/contact", name="home.uc.contact") + */ + public function contactAction() + { + $service = new ContactInfoService(); + + $contact = $service->handle(); + + $this->view->pick('user/console/contact'); + $this->view->setVar('contact', $contact); + } + /** * @Get("/account", name="home.uc.account") */ @@ -182,6 +199,32 @@ class UserConsoleController extends Controller $this->view->setVar('pager', $pager); } + /** + * @Get("/point/history", name="home.uc.point_history") + */ + public function pointHistoryAction() + { + $service = new PointHistoryService(); + + $pager = $service->handle(); + + $this->view->pick('user/console/point_history'); + $this->view->setVar('pager', $pager); + } + + /** + * @Get("/point/redeems", name="home.uc.point_redeems") + */ + public function pointRedeemsAction() + { + $service = new PointRedeemListService(); + + $pager = $service->handle(); + + $this->view->pick('user/console/point_redeems'); + $this->view->setVar('pager', $pager); + } + /** * @Get("/friends", name="home.uc.friends") */ @@ -249,6 +292,20 @@ class UserConsoleController extends Controller return $this->jsonSuccess($content); } + /** + * @Post("/contact/update", name="home.uc.update_contact") + */ + public function updateContactAction() + { + $service = new ContactUpdateService(); + + $service->handle(); + + $content = ['msg' => '更新收货信息成功']; + + return $this->jsonSuccess($content); + } + /** * @Post("/connect/{id:[0-9]+}/delete", name="home.uc.unconnect") */ diff --git a/app/Http/Home/Services/Account.php b/app/Http/Home/Services/Account.php index 7f7fb06f..af36e107 100644 --- a/app/Http/Home/Services/Account.php +++ b/app/Http/Home/Services/Account.php @@ -9,6 +9,8 @@ use App\Services\Logic\Account\Register as RegisterService; use App\Services\Logic\Notice\AccountLogin as AccountLoginNoticeService; use App\Validators\Account as AccountValidator; use App\Validators\Captcha as CaptchaValidator; +use Phalcon\Di as Di; +use Phalcon\Events\Manager as EventsManager; class Account extends Service { @@ -35,6 +37,8 @@ class Account extends Service $this->auth->saveAuthInfo($user); + $this->fireAfterRegisterEvent($user); + return $user; } @@ -53,6 +57,8 @@ class Account extends Service $this->handleLoginNotice($user); $this->auth->saveAuthInfo($user); + + $this->fireAfterLoginEvent($user); } public function loginByVerify() @@ -66,11 +72,47 @@ class Account extends Service $this->handleLoginNotice($user); $this->auth->saveAuthInfo($user); + + $this->fireAfterLoginEvent($user); } public function logout() { + $user = $this->getLoginUser(); + $this->auth->clearAuthInfo(); + + $this->fireAfterLogoutEvent($user); + } + + protected function fireAfterRegisterEvent(UserModel $user) + { + /** + * @var EventsManager $eventsManager + */ + $eventsManager = Di::getDefault()->getShared('eventsManager'); + + $eventsManager->fire('Account:afterRegister', $this, $user); + } + + protected function fireAfterLoginEvent(UserModel $user) + { + /** + * @var EventsManager $eventsManager + */ + $eventsManager = Di::getDefault()->getShared('eventsManager'); + + $eventsManager->fire('Account:afterLogin', $this, $user); + } + + protected function fireAfterLogoutEvent(UserModel $user) + { + /** + * @var EventsManager $eventsManager + */ + $eventsManager = Di::getDefault()->getShared('eventsManager'); + + $eventsManager->fire('Account:afterLogout', $this, $user); } protected function handleLoginNotice(UserModel $user) diff --git a/app/Http/Home/Services/ImMessageTrait.php b/app/Http/Home/Services/ImMessageTrait.php index c0d99dbe..5a4842bb 100644 --- a/app/Http/Home/Services/ImMessageTrait.php +++ b/app/Http/Home/Services/ImMessageTrait.php @@ -98,6 +98,8 @@ Trait ImMessageTrait Gateway::$registerAddress = $this->getRegisterAddress(); + $imMessage = new ImMessageModel(); + if ($to['type'] == 'friend') { $validator = new ImFriendUserValidator(); @@ -106,9 +108,9 @@ Trait ImMessageTrait $online = Gateway::isUidOnline($to['id']); - $messageModel = new ImMessageModel(); + $imMessage = new ImMessageModel(); - $messageModel->create([ + $imMessage->create([ 'sender_id' => $from['id'], 'receiver_id' => $to['id'], 'receiver_type' => ImMessageModel::TYPE_FRIEND, @@ -136,9 +138,9 @@ Trait ImMessageTrait $relation = $validator->checkGroupUser($group->id, $user->id); - $messageModel = new ImMessageModel(); + $imMessage = new ImMessageModel(); - $messageModel->create([ + $imMessage->create([ 'sender_id' => $from['id'], 'receiver_id' => $to['id'], 'receiver_type' => ImMessageModel::TYPE_GROUP, @@ -162,6 +164,8 @@ Trait ImMessageTrait Gateway::sendToGroup($groupName, $content, $excludeClientId); } + + $this->eventsManager->fire('ImMessage:afterCreate', $this, $imMessage); } public function sendCsMessage($from, $to) diff --git a/app/Http/Home/Views/chapter/read.volt b/app/Http/Home/Views/chapter/read.volt index b40eebb8..ee858df5 100644 --- a/app/Http/Home/Views/chapter/read.volt +++ b/app/Http/Home/Views/chapter/read.volt @@ -18,7 +18,9 @@ {{ chapter.user_count }} - + {% if course.market_price > 0 %} + + {% endif %} {% if chapter.resource_count > 0 and chapter.me.owned == 1 %} {% endif %} diff --git a/app/Http/Home/Views/chapter/vod.volt b/app/Http/Home/Views/chapter/vod.volt index ae448a92..4e10cb46 100644 --- a/app/Http/Home/Views/chapter/vod.volt +++ b/app/Http/Home/Views/chapter/vod.volt @@ -19,7 +19,9 @@