diff --git a/CHANGELOG.md b/CHANGELOG.md index a0e862e6..de2c556d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +### [v1.5.0](https://gitee.com/koogua/course-tencent-cloud/releases/v1.5.0)(2022-01-01) + +- 调整对内部人员通知任务类型的前缀 +- 调整微信和短信通知发送判断逻辑 +- 支付后解除秒杀商品锁定 +- 加强支付流程数据验证 +- 加强退款流程数据验证 +- 优化账户创建数据流 +- 优化课程创建数据流 +- 优化章节创建数据流 +- 优化发货逻辑 + ### [v1.4.9](https://gitee.com/koogua/course-tencent-cloud/releases/v1.4.9)(2022-01-01) - 修正订单消费未奖励积分问题 diff --git a/README.md b/README.md index dda2a478..dbf933d0 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,15 @@ ## 酷瓜云课堂 -![酷瓜云网课GPL协议开源](https://portal-1255691183.file.myqcloud.com/img/content/60e7aea40966f.png) +![酷瓜云课堂](https://portal-1255691183.file.myqcloud.com/img/content/61dd395c053e5.png) ### 系统介绍 酷瓜云课堂,依托腾讯云基础服务架构,采用C扩展框架Phalcon开发,GPL-2.0开源协议,致力开源网课系统,开源网校系统,开源知识付费系统,开源在线教育系统。 -![star](https://svg.hamm.cn/gitee.svg?user=koogua&project=course-tencent-cloud&type=star) -![fork](https://svg.hamm.cn/gitee.svg?user=koogua&project=course-tencent-cloud&type=fork) -![license](https://svg.hamm.cn/gitee.svg?user=koogua&project=course-tencent-cloud&type=license) -![release](https://svg.hamm.cn/gitee.svg?user=koogua&project=course-tencent-cloud&type=release) +![star](https://koogua.com/gitee/badge?user=koogua&project=course-tencent-cloud&type=star) +![fork](https://koogua.com/gitee/badge?user=koogua&project=course-tencent-cloud&type=fork) +![license](https://koogua.com/gitee/badge?user=koogua&project=course-tencent-cloud&type=license) +![release](https://koogua.com/gitee/badge?user=koogua&project=course-tencent-cloud&type=release) ### 系统功能 diff --git a/app/Console/Tasks/DeliverTask.php b/app/Console/Tasks/DeliverTask.php index 091790bc..521847a2 100644 --- a/app/Console/Tasks/DeliverTask.php +++ b/app/Console/Tasks/DeliverTask.php @@ -7,19 +7,18 @@ namespace App\Console\Tasks; -use App\Models\Course as CourseModel; -use App\Models\CourseUser as CourseUserModel; -use App\Models\ImGroupUser as ImGroupUserModel; use App\Models\Order as OrderModel; use App\Models\Refund as RefundModel; use App\Models\Task as TaskModel; use App\Models\Trade as TradeModel; use App\Repos\Course as CourseRepo; -use App\Repos\ImGroup as ImGroupRepo; -use App\Repos\ImGroupUser as ImGroupUserRepo; -use App\Repos\ImUser as ImUserRepo; use App\Repos\Order as OrderRepo; +use App\Repos\Package as PackageRepo; use App\Repos\User as UserRepo; +use App\Repos\Vip as VipRepo; +use App\Services\Logic\Deliver\CourseDeliver as CourseDeliverService; +use App\Services\Logic\Deliver\PackageDeliver as PackageDeliverService; +use App\Services\Logic\Deliver\VipDeliver as VipDeliverService; use App\Services\Logic\Notice\OrderFinish as OrderFinishNotice; use App\Services\Logic\Point\History\OrderConsume as OrderConsumePointHistory; use Phalcon\Mvc\Model; @@ -31,8 +30,6 @@ class DeliverTask extends Task public function mainAction() { - $logger = $this->getLogger('order'); - $tasks = $this->findTasks(30); echo sprintf('pending tasks: %s', $tasks->count()) . PHP_EOL; @@ -45,15 +42,7 @@ class DeliverTask extends Task foreach ($tasks as $task) { - $orderId = $task->item_info['order']['id'] ?? 0; - - $order = $orderRepo->findById($orderId); - - if (!$order) { - $task->status = TaskModel::STATUS_FAILED; - $task->update(); - continue; - } + $order = $orderRepo->findById($task->item_id); try { @@ -72,16 +61,10 @@ class DeliverTask extends Task } $order->status = OrderModel::STATUS_FINISHED; - - if ($order->update() === false) { - throw new \RuntimeException('Update Order Status Failed'); - } + $order->update(); $task->status = TaskModel::STATUS_FINISHED; - - if ($task->update() === false) { - throw new \RuntimeException('Update Task Status Failed'); - } + $task->update(); $this->db->commit(); @@ -98,7 +81,9 @@ class DeliverTask extends Task $task->update(); - $logger->error('Order Process Exception ' . kg_json_encode([ + $logger = $this->getLogger('deliver'); + + $logger->error('Deliver Task Exception ' . kg_json_encode([ 'file' => $e->getFile(), 'line' => $e->getLine(), 'message' => $e->getMessage(), @@ -119,126 +104,47 @@ class DeliverTask extends Task protected function handleCourseOrder(OrderModel $order) { - $course = $order->item_info['course']; - - if ($course['model'] == CourseModel::MODEL_OFFLINE) { - $expiryTime = strtotime($course['attrs']['end_date']); - } else { - $expiryTime = $course['study_expiry_time']; - } - - $courseUser = new CourseUserModel(); - - $courseUser->user_id = $order->owner_id; - $courseUser->course_id = $order->item_id; - $courseUser->expiry_time = $expiryTime; - $courseUser->role_type = CourseUserModel::ROLE_STUDENT; - $courseUser->source_type = CourseUserModel::SOURCE_CHARGE; - - $courseUser->create(); - $courseRepo = new CourseRepo(); - $course = $courseRepo->findById($course['id']); - - $course->user_count += 1; - - $course->update(); - - $groupRepo = new ImGroupRepo(); - - $group = $groupRepo->findByCourseId($course->id); - - $imUserRepo = new ImUserRepo(); - - $imUser = $imUserRepo->findById($order->owner_id); - - $groupUserRepo = new ImGroupUserRepo(); - - $groupUser = $groupUserRepo->findGroupUser($group->id, $order->owner_id); - - if (!$groupUser) { - - $groupUser = new ImGroupUserModel(); - - $groupUser->group_id = $group->id; - $groupUser->user_id = $order->owner_id; - $groupUser->create(); - - $imUser->group_count += 1; - $imUser->update(); - - $group->user_count += 1; - $group->update(); - } - } - - protected function handlePackageOrder(OrderModel $order) - { - $itemInfo = $order->item_info; - - foreach ($itemInfo['courses'] as $course) { - - $courseUser = new CourseUserModel(); - - $courseUser->user_id = $order->owner_id; - $courseUser->course_id = $course['id']; - $courseUser->expiry_time = $course['study_expiry_time']; - $courseUser->role_type = CourseUserModel::ROLE_STUDENT; - $courseUser->source_type = CourseUserModel::SOURCE_CHARGE; - - $courseUser->create(); - - $courseRepo = new CourseRepo(); - - $course = $courseRepo->findById($course['id']); - - $course->user_count += 1; - - $course->update(); - - $groupRepo = new ImGroupRepo(); - - $group = $groupRepo->findByCourseId($course->id); - - $imUserRepo = new ImUserRepo(); - - $imUser = $imUserRepo->findById($order->owner_id); - - $groupUserRepo = new ImGroupUserRepo(); - - $groupUser = $groupUserRepo->findGroupUser($group->id, $order->owner_id); - - if (!$groupUser) { - - $groupUser = new ImGroupUserModel(); - - $groupUser->group_id = $group->id; - $groupUser->user_id = $order->owner_id; - $groupUser->create(); - - $imUser->group_count += 1; - $imUser->update(); - - $group->user_count += 1; - $group->update(); - } - } - } - - protected function handleVipOrder(OrderModel $order) - { - $itemInfo = $order->item_info; + $course = $courseRepo->findById($order->item_id); $userRepo = new UserRepo(); $user = $userRepo->findById($order->owner_id); - $user->vip_expiry_time = $itemInfo['vip']['expiry_time']; + $service = new CourseDeliverService(); - $user->vip = 1; + $service->handle($course, $user); + } - $user->update(); + protected function handlePackageOrder(OrderModel $order) + { + $packageRepo = new PackageRepo(); + + $package = $packageRepo->findById($order->item_id); + + $userRepo = new UserRepo(); + + $user = $userRepo->findById($order->owner_id); + + $service = new PackageDeliverService(); + + $service->handle($package, $user); + } + + protected function handleVipOrder(OrderModel $order) + { + $vipRepo = new VipRepo(); + + $vip = $vipRepo->findById($order->item_id); + + $userRepo = new UserRepo(); + + $user = $userRepo->findById($order->owner_id); + + $service = new VipDeliverService(); + + $service->handle($vip, $user); } protected function handleOrderConsumePoint(OrderModel $order) @@ -311,7 +217,7 @@ class DeliverTask extends Task { $itemType = TaskModel::TYPE_DELIVER; $status = TaskModel::STATUS_PENDING; - $createTime = strtotime('-1 days'); + $createTime = strtotime('-7 days'); return TaskModel::query() ->where('item_type = :item_type:', ['item_type' => $itemType]) diff --git a/app/Console/Tasks/NoticeTask.php b/app/Console/Tasks/NoticeTask.php index 1f8eac73..d8ec1d8b 100644 --- a/app/Console/Tasks/NoticeTask.php +++ b/app/Console/Tasks/NoticeTask.php @@ -26,8 +26,6 @@ class NoticeTask extends Task public function mainAction() { - $logger = $this->getLogger('notice'); - $tasks = $this->findTasks(300); if ($tasks->count() == 0) return; @@ -55,16 +53,16 @@ class NoticeTask extends Task case TaskModel::TYPE_NOTICE_POINT_GOODS_DELIVER: $this->handlePointGoodsDeliverNotice($task); break; - case TaskModel::TYPE_NOTICE_CONSULT_CREATE: + case TaskModel::TYPE_STAFF_NOTICE_CONSULT_CREATE: $this->handleConsultCreateNotice($task); break; - case TaskModel::TYPE_NOTICE_TEACHER_LIVE: + case TaskModel::TYPE_STAFF_NOTICE_TEACHER_LIVE: $this->handleTeacherLiveNotice($task); break; - case TaskModel::TYPE_NOTICE_SERVER_MONITOR: + case TaskModel::TYPE_STAFF_NOTICE_SERVER_MONITOR: $this->handleServerMonitorNotice($task); break; - case TaskModel::TYPE_NOTICE_CUSTOM_SERVICE: + case TaskModel::TYPE_STAFF_NOTICE_CUSTOM_SERVICE: $this->handleCustomServiceNotice($task); break; } @@ -84,6 +82,8 @@ class NoticeTask extends Task $task->update(); + $logger = $this->getLogger('notice'); + $logger->error('Notice Process Exception ' . kg_json_encode([ 'file' => $e->getFile(), 'line' => $e->getLine(), @@ -178,10 +178,10 @@ class NoticeTask extends Task TaskModel::TYPE_NOTICE_CONSULT_REPLY, TaskModel::TYPE_NOTICE_POINT_GOODS_DELIVER, TaskModel::TYPE_NOTICE_LUCKY_GOODS_DELIVER, - TaskModel::TYPE_NOTICE_CONSULT_CREATE, - TaskModel::TYPE_NOTICE_TEACHER_LIVE, - TaskModel::TYPE_NOTICE_SERVER_MONITOR, - TaskModel::TYPE_NOTICE_CUSTOM_SERVICE, + TaskModel::TYPE_STAFF_NOTICE_CONSULT_CREATE, + TaskModel::TYPE_STAFF_NOTICE_TEACHER_LIVE, + TaskModel::TYPE_STAFF_NOTICE_SERVER_MONITOR, + TaskModel::TYPE_STAFF_NOTICE_CUSTOM_SERVICE, ]; $status = TaskModel::STATUS_PENDING; diff --git a/app/Console/Tasks/RefundTask.php b/app/Console/Tasks/RefundTask.php index 53386a5a..34fdd257 100644 --- a/app/Console/Tasks/RefundTask.php +++ b/app/Console/Tasks/RefundTask.php @@ -29,8 +29,6 @@ class RefundTask extends Task public function mainAction() { - $logger = $this->getLogger('refund'); - $tasks = $this->findTasks(30); echo sprintf('pending tasks: %s', $tasks->count()) . PHP_EOL; @@ -45,14 +43,12 @@ class RefundTask extends Task foreach ($tasks as $task) { - $itemInfo = $task->item_info; - - $refund = $refundRepo->findById($itemInfo['refund']['id']); + $refund = $refundRepo->findById($task->item_id); $trade = $tradeRepo->findById($refund->trade_id); $order = $orderRepo->findById($refund->order_id); - if (!$refund || !$trade || !$order) { - $task->status = TaskModel::STATUS_FAILED; + if ($refund->status != RefundModel::STATUS_APPROVED) { + $task->status = TaskModel::STATUS_CANCELED; $task->update(); continue; } @@ -62,32 +58,19 @@ class RefundTask extends Task $this->db->begin(); $this->handleTradeRefund($trade, $refund); - $this->handleOrderRefund($order); $refund->status = RefundModel::STATUS_FINISHED; - - if ($refund->update() === false) { - throw new \RuntimeException('Update Refund Status Failed'); - } + $refund->update(); $trade->status = TradeModel::STATUS_REFUNDED; - - if ($trade->update() === false) { - throw new \RuntimeException('Update Trade Status Failed'); - } + $trade->update(); $order->status = OrderModel::STATUS_REFUNDED; - - if ($order->update() === false) { - throw new \RuntimeException('Update Order Status Failed'); - } + $order->update(); $task->status = TaskModel::STATUS_FINISHED; - - if ($task->update() === false) { - throw new \RuntimeException('Update Task Status Failed'); - } + $task->update(); $this->db->commit(); @@ -106,7 +89,9 @@ class RefundTask extends Task $task->update(); - $logger->info('Refund Task Exception ' . kg_json_encode([ + $logger = $this->getLogger('refund'); + + $logger->error('Refund Task Exception ' . kg_json_encode([ 'file' => $e->getFile(), 'line' => $e->getLine(), 'message' => $e->getMessage(), diff --git a/app/Http/Admin/Services/Chapter.php b/app/Http/Admin/Services/Chapter.php index 8536b080..8af518a0 100644 --- a/app/Http/Admin/Services/Chapter.php +++ b/app/Http/Admin/Services/Chapter.php @@ -11,10 +11,6 @@ use App\Builders\ResourceList as ResourceListBuilder; use App\Caches\Chapter as ChapterCache; use App\Caches\CourseChapterList as CatalogCache; use App\Models\Chapter as ChapterModel; -use App\Models\ChapterLive as ChapterLiveModel; -use App\Models\ChapterOffline as ChapterOfflineModel; -use App\Models\ChapterRead as ChapterReadModel; -use App\Models\ChapterVod as ChapterVodModel; use App\Models\Course as CourseModel; use App\Repos\Chapter as ChapterRepo; use App\Repos\Course as CourseRepo; @@ -75,17 +71,14 @@ class Chapter extends Service $chapterRepo = new ChapterRepo(); - $parentId = 0; - if (isset($post['parent_id'])) { $parent = $validator->checkParent($post['parent_id']); $data['parent_id'] = $parent->id; $data['free'] = $validator->checkFreeStatus($post['free']); $data['priority'] = $chapterRepo->maxLessonPriority($post['parent_id']); - $parentId = $parent->id; } else { $data['priority'] = $chapterRepo->maxChapterPriority($post['course_id']); - $data['parent_id'] = $parentId; + $data['parent_id'] = 0; } $data['priority'] += 1; @@ -100,39 +93,6 @@ class Chapter extends Service throw new \RuntimeException('Create Chapter Failed'); } - $data = [ - 'course_id' => $course->id, - 'chapter_id' => $chapter->id, - ]; - - if ($parentId > 0) { - - $attrs = false; - - switch ($course->model) { - case CourseMOdel::MODEL_VOD: - $chapterVod = new ChapterVodModel(); - $attrs = $chapterVod->create($data); - break; - case CourseModel::MODEL_LIVE: - $chapterLive = new ChapterLiveModel(); - $attrs = $chapterLive->create($data); - break; - case CourseModel::MODEL_READ: - $chapterRead = new ChapterReadModel(); - $attrs = $chapterRead->create($data); - break; - case CourseModel::MODEL_OFFLINE: - $chapterOffline = new ChapterOfflineModel(); - $attrs = $chapterOffline->create($data); - break; - } - - if ($attrs === false) { - throw new \RuntimeException("Create Chapter Related Attrs Failed"); - } - } - $this->db->commit(); $this->updateChapterStats($chapter); diff --git a/app/Http/Admin/Services/Course.php b/app/Http/Admin/Services/Course.php index 0cbf5d44..0c5d3298 100644 --- a/app/Http/Admin/Services/Course.php +++ b/app/Http/Admin/Services/Course.php @@ -16,10 +16,8 @@ use App\Library\Paginator\Query as PagerQuery; use App\Models\Category as CategoryModel; use App\Models\Course as CourseModel; use App\Models\CourseCategory as CourseCategoryModel; -use App\Models\CourseRating as CourseRatingModel; use App\Models\CourseRelated as CourseRelatedModel; use App\Models\CourseUser as CourseUserModel; -use App\Models\ImGroup as ImGroupModel; use App\Models\ImGroupUser as ImGroupUserModel; use App\Repos\Category as CategoryRepo; use App\Repos\Chapter as ChapterRepo; @@ -90,25 +88,6 @@ class Course extends Service throw new \RuntimeException('Create Course Failed'); } - $courseRating = new CourseRatingModel(); - - $courseRating->course_id = $course->id; - - if ($courseRating->create() === false) { - throw new \RuntimeException('Create CourseRating Failed'); - } - - $imGroup = new ImGroupModel(); - - $imGroup->type = ImGroupModel::TYPE_COURSE; - $imGroup->course_id = $course->id; - $imGroup->name = $course->title; - $imGroup->about = $course->summary; - - if ($imGroup->create() === false) { - throw new \RuntimeException('Create ImGroup Failed'); - } - $this->db->commit(); return $course; diff --git a/app/Http/Admin/Services/User.php b/app/Http/Admin/Services/User.php index fdc20f23..8ed17c4e 100644 --- a/app/Http/Admin/Services/User.php +++ b/app/Http/Admin/Services/User.php @@ -12,7 +12,6 @@ use App\Caches\User as UserCache; use App\Library\Paginator\Query as PaginateQuery; use App\Library\Utils\Password as PasswordUtil; use App\Models\Account as AccountModel; -use App\Models\ImUser as ImUserModel; use App\Models\User as UserModel; use App\Repos\Account as AccountRepo; use App\Repos\Online as OnlineRepo; @@ -118,24 +117,13 @@ class User extends Service throw new \RuntimeException('Create Account Failed'); } - $user = new UserModel(); + $user = $this->findOrFail($account->id); - $user->id = $account->id; - $user->name = "user_{$account->id}"; - $user->edu_role = $eduRole; $user->admin_role = $adminRole; + $user->edu_role = $eduRole; - if ($user->create() === false) { - throw new \RuntimeException('Create User Failed'); - } - - $imUser = new ImUserModel(); - - $imUser->id = $user->id; - $imUser->name = $user->name; - - if ($imUser->create() === false) { - throw new \RuntimeException('Create Im User Failed'); + if ($user->update() === false) { + throw new \RuntimeException('Update User Failed'); } $this->db->commit(); @@ -148,6 +136,14 @@ class User extends Service $this->db->rollback(); + $logger = $this->getLogger('http'); + + $logger->error('Create User Error ' . kg_json_encode([ + 'file' => $e->getFile(), + 'line' => $e->getLine(), + 'message' => $e->getMessage(), + ])); + throw new \RuntimeException('sys.trans_rollback'); } } diff --git a/app/Library/AppInfo.php b/app/Library/AppInfo.php index 3273b320..8ae50148 100644 --- a/app/Library/AppInfo.php +++ b/app/Library/AppInfo.php @@ -16,7 +16,7 @@ class AppInfo protected $link = 'https://koogua.com'; - protected $version = '1.4.9'; + protected $version = '1.5.0'; public function __get($name) { diff --git a/app/Listeners/Trade.php b/app/Listeners/Trade.php index bcbefea3..c400e327 100644 --- a/app/Listeners/Trade.php +++ b/app/Listeners/Trade.php @@ -11,6 +11,7 @@ use App\Models\Order as OrderModel; use App\Models\Task as TaskModel; use App\Models\Trade as TradeModel; use App\Repos\Order as OrderRepo; +use App\Services\Logic\FlashSale\UserOrderCache as FlashSaleLockCache; use Phalcon\Events\Event as PhEvent; use Phalcon\Logger\Adapter\File as FileLogger; @@ -34,20 +35,13 @@ class Trade extends Listener $this->db->begin(); $trade->status = TradeModel::STATUS_FINISHED; - - if ($trade->update() === false) { - throw new \RuntimeException('Update Trade Status Failed'); - } + $trade->update(); $orderRepo = new OrderRepo(); - $order = $orderRepo->findById($trade->order_id); $order->status = OrderModel::STATUS_DELIVERING; - - if ($order->update() === false) { - throw new \RuntimeException('Update Order Status Failed'); - } + $order->update(); $task = new TaskModel(); @@ -58,13 +52,18 @@ class Trade extends Listener $task->item_id = $order->id; $task->item_info = $itemInfo; $task->item_type = TaskModel::TYPE_DELIVER; - - if ($task->create() === false) { - throw new \RuntimeException('Create Order Process Task Failed'); - } + $task->create(); $this->db->commit(); + /** + * 解除秒杀锁定 + */ + if ($order->promotion_type == OrderModel::PROMOTION_FLASH_SALE) { + $cache = new FlashSaleLockCache(); + $cache->delete($order->owner_id, $order->promotion_id); + } + } catch (\Exception $e) { $this->db->rollback(); @@ -72,7 +71,6 @@ class Trade extends Listener $this->logger->error('After Pay Event Error ' . kg_json_encode([ 'file' => $e->getFile(), 'line' => $e->getLine(), - 'code' => $e->getCode(), 'message' => $e->getMessage(), ])); diff --git a/app/Models/Account.php b/app/Models/Account.php index de5e44a3..923e9067 100644 --- a/app/Models/Account.php +++ b/app/Models/Account.php @@ -95,4 +95,33 @@ class Account extends Model $this->update_time = time(); } + public function afterCreate() + { + $user = new User(); + + $user->id = $this->id; + $user->name = "user:{$this->id}"; + + if ($user->create() === false) { + throw new \RuntimeException('Create User Failed'); + } + + $userBalance = new UserBalance(); + + $userBalance->user_id = $user->id; + + if ($userBalance->create() === false) { + throw new \RuntimeException('Create User Balance Failed'); + } + + $imUser = new ImUser(); + + $imUser->id = $user->id; + $imUser->name = $user->name; + + if ($imUser->create() === false) { + throw new \RuntimeException('Create Im User Failed'); + } + } + } diff --git a/app/Models/Chapter.php b/app/Models/Chapter.php index 4cbfaac0..07a19a2c 100644 --- a/app/Models/Chapter.php +++ b/app/Models/Chapter.php @@ -261,6 +261,40 @@ class Chapter extends Model $cache = new MaxChapterIdCache(); $cache->rebuild(); + + if ($this->parent_id > 0) { + + $data = [ + 'course_id' => $this->course_id, + 'chapter_id' => $this->id, + 'model' => $this->model, + ]; + + $extend = false; + + switch ($this->model) { + case Course::MODEL_VOD: + $vod = new ChapterVod(); + $extend = $vod->create($data); + break; + case Course::MODEL_LIVE: + $live = new ChapterLive(); + $extend = $live->create($data); + break; + case Course::MODEL_READ: + $read = new ChapterRead(); + $extend = $read->create($data); + break; + case Course::MODEL_OFFLINE: + $offline = new ChapterOffline(); + $extend = $offline->create($data); + break; + } + + if ($extend === false) { + throw new \RuntimeException("Create Chapter Extend Failed"); + } + } } public function afterFetch() diff --git a/app/Models/Course.php b/app/Models/Course.php index f460a13d..29d68ce0 100644 --- a/app/Models/Course.php +++ b/app/Models/Course.php @@ -382,6 +382,24 @@ class Course extends Model $cache = new MaxCourseIdCache(); $cache->rebuild(); + + $courseRating = new CourseRating(); + + $courseRating->course_id = $this->id; + + if ($courseRating->create() === false) { + throw new \RuntimeException('Create Course Rating Failed'); + } + + $imGroup = new ImGroup(); + + $imGroup->course_id = $this->id; + $imGroup->name = $this->title; + $imGroup->type = ImGroup::TYPE_COURSE; + + if ($imGroup->create() === false) { + throw new \RuntimeException('Create Im Group Failed'); + } } public function afterFetch() diff --git a/app/Models/Task.php b/app/Models/Task.php index 0c108f69..f3d5f3de 100644 --- a/app/Models/Task.php +++ b/app/Models/Task.php @@ -32,12 +32,12 @@ class Task extends Model /** * 针对内部人员 */ - const TYPE_NOTICE_CONSULT_CREATE = 31; // 咨询创建通知 - const TYPE_NOTICE_TEACHER_LIVE = 32; // 直播讲师通知 - const TYPE_NOTICE_SERVER_MONITOR = 33; // 服务监控通知 - const TYPE_NOTICE_CUSTOM_SERVICE = 34; // 客服消息通知 - const TYPE_NOTICE_POINT_REDEEM = 35; // 积分兑换通知 - const TYPE_NOTICE_LUCKY_REDEEM = 36; // 抽奖兑换通知 + const TYPE_STAFF_NOTICE_CONSULT_CREATE = 31; // 咨询创建通知 + const TYPE_STAFF_NOTICE_TEACHER_LIVE = 32; // 直播讲师通知 + const TYPE_STAFF_NOTICE_SERVER_MONITOR = 33; // 服务监控通知 + const TYPE_STAFF_NOTICE_CUSTOM_SERVICE = 34; // 客服消息通知 + const TYPE_STAFF_NOTICE_POINT_REDEEM = 35; // 积分兑换通知 + const TYPE_STAFF_NOTICE_LUCKY_REDEEM = 36; // 抽奖兑换通知 /** * 优先级 diff --git a/app/Services/Logic/Account/Register.php b/app/Services/Logic/Account/Register.php index c1cb2202..e2c36e02 100644 --- a/app/Services/Logic/Account/Register.php +++ b/app/Services/Logic/Account/Register.php @@ -10,8 +10,6 @@ namespace App\Services\Logic\Account; use App\Library\Utils\Password as PasswordUtil; use App\Library\Validators\Common as CommonValidator; use App\Models\Account as AccountModel; -use App\Models\ImUser as ImUserModel; -use App\Models\User as UserModel; use App\Services\Logic\Service as LogicService; use App\Validators\Account as AccountValidator; use App\Validators\Verify as VerifyValidator; @@ -62,24 +60,6 @@ class Register extends LogicService throw new \RuntimeException('Create Account Failed'); } - $user = new UserModel(); - - $user->id = $account->id; - $user->name = "user_{$account->id}"; - - if ($user->create() === false) { - throw new \RuntimeException('Create User Failed'); - } - - $imUser = new ImUserModel(); - - $imUser->id = $user->id; - $imUser->name = $user->name; - - if ($imUser->create() === false) { - throw new \RuntimeException('Create Im User Failed'); - } - $this->db->commit(); return $account; diff --git a/app/Services/Logic/Deliver/CourseDeliver.php b/app/Services/Logic/Deliver/CourseDeliver.php new file mode 100644 index 00000000..4645a5c7 --- /dev/null +++ b/app/Services/Logic/Deliver/CourseDeliver.php @@ -0,0 +1,70 @@ +model == CourseModel::MODEL_OFFLINE) { + $expiryTime = strtotime($course->attrs['end_date']); + } else { + $expiryTime = strtotime("+{$course->study_expiry} months"); + } + + $courseUser = new CourseUserModel(); + + $courseUser->user_id = $user->id; + $courseUser->course_id = $course->id; + $courseUser->expiry_time = $expiryTime; + $courseUser->role_type = CourseUserModel::ROLE_STUDENT; + $courseUser->source_type = CourseUserModel::SOURCE_CHARGE; + $courseUser->create(); + + $course->user_count += 1; + $course->update(); + + $groupRepo = new ImGroupRepo(); + + $group = $groupRepo->findByCourseId($course->id); + + $imUserRepo = new ImUserRepo(); + + $imUser = $imUserRepo->findById($user->id); + + $groupUserRepo = new ImGroupUserRepo(); + + $groupUser = $groupUserRepo->findGroupUser($group->id, $user->id); + + if (!$groupUser) { + + $groupUser = new ImGroupUserModel(); + + $groupUser->group_id = $group->id; + $groupUser->user_id = $user->id; + $groupUser->create(); + + $imUser->group_count += 1; + $imUser->update(); + + $group->user_count += 1; + $group->update(); + } + } + +} diff --git a/app/Services/Logic/Deliver/PackageDeliver.php b/app/Services/Logic/Deliver/PackageDeliver.php new file mode 100644 index 00000000..36586f7a --- /dev/null +++ b/app/Services/Logic/Deliver/PackageDeliver.php @@ -0,0 +1,70 @@ +findCourses($package->id); + + foreach ($courses as $course) { + + $courseUser = new CourseUserModel(); + + $courseUser->user_id = $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_CHARGE; + $courseUser->create(); + + $course->user_count += 1; + $course->update(); + + $imUserRepo = new ImUserRepo(); + + $imUser = $imUserRepo->findById($user->id); + + $groupRepo = new ImGroupRepo(); + + $group = $groupRepo->findByCourseId($course->id); + + $groupUserRepo = new ImGroupUserRepo(); + + $groupUser = $groupUserRepo->findGroupUser($group->id, $user->id); + + if (!$groupUser) { + $groupUser = new ImGroupUserModel(); + $groupUser->group_id = $group->id; + $groupUser->user_id = $user->id; + $groupUser->create(); + + $imUser->group_count += 1; + $imUser->update(); + + $group->user_count += 1; + $group->update(); + } + } + } + +} diff --git a/app/Services/Logic/Deliver/VipDeliver.php b/app/Services/Logic/Deliver/VipDeliver.php new file mode 100644 index 00000000..ca18c1c2 --- /dev/null +++ b/app/Services/Logic/Deliver/VipDeliver.php @@ -0,0 +1,28 @@ +vip_expiry_time > time() ? $user->vip_expiry_time : time(); + + $user->vip_expiry_time = strtotime("+{$vip->expiry} months", $baseTime); + + $user->vip = 1; + + $user->update(); + } + +} diff --git a/app/Services/Logic/FlashSale/OrderCreate.php b/app/Services/Logic/FlashSale/OrderCreate.php index 8e02a728..137568b3 100644 --- a/app/Services/Logic/FlashSale/OrderCreate.php +++ b/app/Services/Logic/FlashSale/OrderCreate.php @@ -28,11 +28,11 @@ class OrderCreate extends OrderCreateService $sale = $this->checkFlashSale($id); - $validator = new FlashSaleValidator; + $saleValidator = new FlashSaleValidator(); - $validator->checkIfExpired($sale->end_time); - $validator->checkIfOutSchedules($sale->schedules); - $validator->checkIfNotPaid($user->id, $sale->id); + $saleValidator->checkIfExpired($sale->end_time); + $saleValidator->checkIfOutSchedules($sale->schedules); + $saleValidator->checkIfNotPaid($user->id, $sale->id); $queue = new Queue(); @@ -50,31 +50,33 @@ class OrderCreate extends OrderCreateService ] ]; + $orderValidator = new OrderValidator(); + + $orderValidator->checkAmount($this->amount); + try { $order = new OrderModel(); - $validator = new OrderValidator(); - if ($sale->item_type == FlashSaleModel::ITEM_COURSE) { - $course = $validator->checkCourse($sale->item_id); + $course = $orderValidator->checkCourse($sale->item_id); - $validator->checkIfBoughtCourse($user->id, $course->id); + $orderValidator->checkIfBoughtCourse($user->id, $course->id); $order = $this->createCourseOrder($course, $user); } elseif ($sale->item_type == FlashSaleModel::ITEM_PACKAGE) { - $package = $validator->checkPackage($sale->item_id); + $package = $orderValidator->checkPackage($sale->item_id); - $validator->checkIfBoughtPackage($user->id, $package->id); + $orderValidator->checkIfBoughtPackage($user->id, $package->id); $order = $this->createPackageOrder($package, $user); } elseif ($sale->item_type == FlashSaleModel::ITEM_VIP) { - $vip = $validator->checkVip($sale->item_id); + $vip = $orderValidator->checkVip($sale->item_id); $order = $this->createVipOrder($vip, $user); } diff --git a/app/Services/Logic/Notice/ConsultReply.php b/app/Services/Logic/Notice/ConsultReply.php index a0c552a2..290feb73 100644 --- a/app/Services/Logic/Notice/ConsultReply.php +++ b/app/Services/Logic/Notice/ConsultReply.php @@ -74,8 +74,9 @@ class ConsultReply extends LogicService $notice = new WeChatConsultReplyNotice(); return $notice->handle($subscribe, $params); + } - } elseif ($smsNoticeEnabled) { + if ($smsNoticeEnabled) { $notice = new SmsConsultReplyNotice(); diff --git a/app/Services/Logic/Notice/DingTalk/ConsultCreate.php b/app/Services/Logic/Notice/DingTalk/ConsultCreate.php index 0331f6ce..f0f348e7 100644 --- a/app/Services/Logic/Notice/DingTalk/ConsultCreate.php +++ b/app/Services/Logic/Notice/DingTalk/ConsultCreate.php @@ -64,7 +64,7 @@ class ConsultCreate extends DingTalkNotice $task->item_id = $consult->id; $task->item_info = $itemInfo; - $task->item_type = TaskModel::TYPE_NOTICE_CONSULT_CREATE; + $task->item_type = TaskModel::TYPE_STAFF_NOTICE_CONSULT_CREATE; $task->priority = TaskModel::PRIORITY_LOW; $task->status = TaskModel::STATUS_PENDING; diff --git a/app/Services/Logic/Notice/DingTalk/CustomService.php b/app/Services/Logic/Notice/DingTalk/CustomService.php index 858faf71..aa04eda8 100644 --- a/app/Services/Logic/Notice/DingTalk/CustomService.php +++ b/app/Services/Logic/Notice/DingTalk/CustomService.php @@ -58,7 +58,7 @@ class CustomService extends DingTalkNotice $task->item_id = $message->id; $task->item_info = $itemInfo; - $task->item_type = TaskModel::TYPE_NOTICE_CUSTOM_SERVICE; + $task->item_type = TaskModel::TYPE_STAFF_NOTICE_CUSTOM_SERVICE; $task->priority = TaskModel::PRIORITY_MIDDLE; $task->status = TaskModel::STATUS_PENDING; diff --git a/app/Services/Logic/Notice/DingTalk/PointRedeem.php b/app/Services/Logic/Notice/DingTalk/PointRedeem.php index 26bd080b..99c02c2f 100644 --- a/app/Services/Logic/Notice/DingTalk/PointRedeem.php +++ b/app/Services/Logic/Notice/DingTalk/PointRedeem.php @@ -46,7 +46,7 @@ class PointRedeem extends DingTalkNotice $task->item_id = $redeem->id; $task->item_info = $itemInfo; - $task->item_type = TaskModel::TYPE_NOTICE_POINT_REDEEM; + $task->item_type = TaskModel::TYPE_STAFF_NOTICE_POINT_REDEEM; $task->priority = TaskModel::PRIORITY_MIDDLE; $task->status = TaskModel::STATUS_PENDING; diff --git a/app/Services/Logic/Notice/DingTalk/ServerMonitor.php b/app/Services/Logic/Notice/DingTalk/ServerMonitor.php index e6a5795f..c64d1e69 100644 --- a/app/Services/Logic/Notice/DingTalk/ServerMonitor.php +++ b/app/Services/Logic/Notice/DingTalk/ServerMonitor.php @@ -34,7 +34,7 @@ class ServerMonitor extends DingTalkNotice $task->item_id = time(); $task->item_info = $itemInfo; - $task->item_type = TaskModel::TYPE_NOTICE_SERVER_MONITOR; + $task->item_type = TaskModel::TYPE_STAFF_NOTICE_SERVER_MONITOR; $task->priority = TaskModel::PRIORITY_HIGH; $task->status = TaskModel::STATUS_PENDING; $task->max_try_count = 1; diff --git a/app/Services/Logic/Notice/DingTalk/TeacherLive.php b/app/Services/Logic/Notice/DingTalk/TeacherLive.php index 7fb7ce20..df9e62f9 100644 --- a/app/Services/Logic/Notice/DingTalk/TeacherLive.php +++ b/app/Services/Logic/Notice/DingTalk/TeacherLive.php @@ -48,7 +48,7 @@ class TeacherLive extends DingTalkNotice $task->item_id = $live->id; $task->item_info = $itemInfo; - $task->item_type = TaskModel::TYPE_NOTICE_TEACHER_LIVE; + $task->item_type = TaskModel::TYPE_STAFF_NOTICE_TEACHER_LIVE; $task->priority = TaskModel::PRIORITY_LOW; $task->status = TaskModel::STATUS_PENDING; diff --git a/app/Services/Logic/Notice/LiveBegin.php b/app/Services/Logic/Notice/LiveBegin.php index 6452106b..7c9b2178 100644 --- a/app/Services/Logic/Notice/LiveBegin.php +++ b/app/Services/Logic/Notice/LiveBegin.php @@ -72,8 +72,9 @@ class LiveBegin extends LogicService $notice = new WeChatLiveBeginNotice(); return $notice->handle($subscribe, $params); + } - } elseif ($smsNoticeEnabled) { + if ($smsNoticeEnabled) { $notice = new SmsLiveBeginNotice(); diff --git a/app/Services/Logic/Notice/OrderFinish.php b/app/Services/Logic/Notice/OrderFinish.php index f7661815..cc4029f3 100644 --- a/app/Services/Logic/Notice/OrderFinish.php +++ b/app/Services/Logic/Notice/OrderFinish.php @@ -59,8 +59,9 @@ class OrderFinish extends LogicService $notice = new WeChatOrderFinishNotice(); return $notice->handle($subscribe, $params); + } - } elseif ($smsNoticeEnabled) { + if ($smsNoticeEnabled) { $notice = new SmsOrderFinishNotice(); diff --git a/app/Services/Logic/Notice/PointGoodsDeliver.php b/app/Services/Logic/Notice/PointGoodsDeliver.php index ce5685ee..8ff61e00 100644 --- a/app/Services/Logic/Notice/PointGoodsDeliver.php +++ b/app/Services/Logic/Notice/PointGoodsDeliver.php @@ -55,8 +55,9 @@ class PointGoodsDeliver extends LogicService $notice = new WeChatGoodsDeliverNotice(); return $notice->handle($subscribe, $params); + } - } elseif ($smsNoticeEnabled) { + if ($smsNoticeEnabled) { $notice = new SmsGoodsDeliverNotice(); diff --git a/app/Services/Logic/Notice/RefundFinish.php b/app/Services/Logic/Notice/RefundFinish.php index 0a278c63..7bd9428c 100644 --- a/app/Services/Logic/Notice/RefundFinish.php +++ b/app/Services/Logic/Notice/RefundFinish.php @@ -59,8 +59,9 @@ class RefundFinish extends LogicService $notice = new WeChatRefundFinishNotice(); return $notice->handle($subscribe, $params); + } - } elseif ($smsNoticeEnabled) { + if ($smsNoticeEnabled) { $notice = new SmsRefundFinishNotice(); diff --git a/app/Services/Logic/Order/OrderCreate.php b/app/Services/Logic/Order/OrderCreate.php index fe1345f2..685a2961 100644 --- a/app/Services/Logic/Order/OrderCreate.php +++ b/app/Services/Logic/Order/OrderCreate.php @@ -55,9 +55,9 @@ class OrderCreate extends LogicService $validator->checkDailyOrderLimit($user); - $validator = new OrderValidator(); + $orderValidator = new OrderValidator(); - $validator->checkItemType($post['item_type']); + $orderValidator->checkItemType($post['item_type']); $orderRepo = new OrderRepo(); @@ -70,41 +70,49 @@ class OrderCreate extends LogicService if ($post['item_type'] == OrderModel::ITEM_COURSE) { - $course = $validator->checkCourse($post['item_id']); + $course = $orderValidator->checkCourse($post['item_id']); - $validator->checkIfBoughtCourse($user->id, $course->id); + $orderValidator->checkIfBoughtCourse($user->id, $course->id); $this->amount = $user->vip ? $course->vip_price : $course->market_price; + $orderValidator->checkAmount($this->amount); + $order = $this->createCourseOrder($course, $user); } elseif ($post['item_type'] == OrderModel::ITEM_PACKAGE) { - $package = $validator->checkPackage($post['item_id']); + $package = $orderValidator->checkPackage($post['item_id']); - $validator->checkIfBoughtPackage($user->id, $package->id); + $orderValidator->checkIfBoughtPackage($user->id, $package->id); $this->amount = $user->vip ? $package->vip_price : $package->market_price; + $orderValidator->checkAmount($this->amount); + $order = $this->createPackageOrder($package, $user); } elseif ($post['item_type'] == OrderModel::ITEM_REWARD) { list($courseId, $rewardId) = explode('-', $post['item_id']); - $course = $validator->checkCourse($courseId); - $reward = $validator->checkReward($rewardId); + $course = $orderValidator->checkCourse($courseId); + $reward = $orderValidator->checkReward($rewardId); $this->amount = $reward->price; + $orderValidator->checkAmount($this->amount); + $order = $this->createRewardOrder($course, $reward, $user); } elseif ($post['item_type'] == OrderModel::ITEM_VIP) { - $vip = $validator->checkVip($post['item_id']); + $vip = $orderValidator->checkVip($post['item_id']); $this->amount = $vip->price; + $orderValidator->checkAmount($this->amount); + $order = $this->createVipOrder($vip, $user); } diff --git a/app/Validators/Article.php b/app/Validators/Article.php index 6e34431e..fc1a5d62 100644 --- a/app/Validators/Article.php +++ b/app/Validators/Article.php @@ -79,7 +79,7 @@ class Article extends Validator $length = kg_strlen($value); - if ($length < 5) { + if ($length < 2) { throw new BadRequestException('article.title_too_short'); } diff --git a/config/errors.php b/config/errors.php index 4874ac4a..717a66ca 100644 --- a/config/errors.php +++ b/config/errors.php @@ -118,7 +118,7 @@ $error['nav.has_child_node'] = '不允许相关操作(存在子节点)'; * 文章相关 */ $error['article.not_found'] = '文章不存在'; -$error['article.title_too_short'] = '标题太短(少于5个字符)'; +$error['article.title_too_short'] = '标题太短(少于2个字符)'; $error['article.title_too_long'] = '标题太长(多于50个字符)'; $error['article.content_too_short'] = '内容太短(少于10个字符)'; $error['article.content_too_long'] = '内容太长(多于30000个字符)';