1
0
mirror of https://gitee.com/koogua/course-tencent-cloud.git synced 2025-06-23 03:50:56 +08:00
This commit is contained in:
koogua 2022-01-13 11:00:16 +08:00
parent 495057e8ce
commit 6e90d04da9
32 changed files with 409 additions and 329 deletions

View File

@ -1,3 +1,15 @@
### [v1.5.0](https://gitee.com/koogua/course-tencent-cloud/releases/v1.5.0)(2022-01-13)
- 调整对内部人员通知任务类型的前缀
- 调整微信和短信通知发送判断逻辑
- 支付后解除秒杀商品锁定
- 加强支付流程数据验证
- 加强退款流程数据验证
- 优化账户创建数据流
- 优化课程创建数据流
- 优化章节创建数据流
- 优化发货逻辑
### [v1.4.9](https://gitee.com/koogua/course-tencent-cloud/releases/v1.4.9)(2022-01-01)
- 修正订单消费未奖励积分问题

View File

@ -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)
### 系统功能

View File

@ -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])

View File

@ -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;

View File

@ -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(),

View File

@ -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);

View File

@ -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;

View File

@ -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');
}
}

View File

@ -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)
{

View File

@ -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(),
]));

View File

@ -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');
}
}
}

View File

@ -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()

View File

@ -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()

View File

@ -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; // 抽奖兑换通知
/**
* 优先级

View File

@ -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;

View File

@ -0,0 +1,70 @@
<?php
/**
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.koogua.com
*/
namespace App\Services\Logic\Deliver;
use App\Models\Course as CourseModel;
use App\Models\CourseUser as CourseUserModel;
use App\Models\ImGroupUser as ImGroupUserModel;
use App\Models\User as UserModel;
use App\Repos\ImGroup as ImGroupRepo;
use App\Repos\ImGroupUser as ImGroupUserRepo;
use App\Repos\ImUser as ImUserRepo;
use App\Services\Logic\Service as LogicService;
class CourseDeliver extends LogicService
{
public function handle(CourseModel $course, UserModel $user)
{
if ($course->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();
}
}
}

View File

@ -0,0 +1,70 @@
<?php
/**
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.koogua.com
*/
namespace App\Services\Logic\Deliver;
use App\Models\CourseUser as CourseUserModel;
use App\Models\ImGroupUser as ImGroupUserModel;
use App\Models\Package as PackageModel;
use App\Models\User as UserModel;
use App\Repos\ImGroup as ImGroupRepo;
use App\Repos\ImGroupUser as ImGroupUserRepo;
use App\Repos\ImUser as ImUserRepo;
use App\Repos\Package as PackageRepo;
use App\Services\Logic\Service as LogicService;
class PackageDeliver extends LogicService
{
public function handle(PackageModel $package, UserModel $user)
{
$packageRepo = new PackageRepo();
$courses = $packageRepo->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();
}
}
}
}

View File

@ -0,0 +1,28 @@
<?php
/**
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.koogua.com
*/
namespace App\Services\Logic\Deliver;
use App\Models\User as UserModel;
use App\Models\Vip as VipModel;
use App\Services\Logic\Service as LogicService;
class VipDeliver extends LogicService
{
public function handle(VipModel $vip, UserModel $user)
{
$baseTime = $user->vip_expiry_time > time() ? $user->vip_expiry_time : time();
$user->vip_expiry_time = strtotime("+{$vip->expiry} months", $baseTime);
$user->vip = 1;
$user->update();
}
}

View File

@ -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);
}

View File

@ -74,8 +74,9 @@ class ConsultReply extends LogicService
$notice = new WeChatConsultReplyNotice();
return $notice->handle($subscribe, $params);
}
} elseif ($smsNoticeEnabled) {
if ($smsNoticeEnabled) {
$notice = new SmsConsultReplyNotice();

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -72,8 +72,9 @@ class LiveBegin extends LogicService
$notice = new WeChatLiveBeginNotice();
return $notice->handle($subscribe, $params);
}
} elseif ($smsNoticeEnabled) {
if ($smsNoticeEnabled) {
$notice = new SmsLiveBeginNotice();

View File

@ -59,8 +59,9 @@ class OrderFinish extends LogicService
$notice = new WeChatOrderFinishNotice();
return $notice->handle($subscribe, $params);
}
} elseif ($smsNoticeEnabled) {
if ($smsNoticeEnabled) {
$notice = new SmsOrderFinishNotice();

View File

@ -55,8 +55,9 @@ class PointGoodsDeliver extends LogicService
$notice = new WeChatGoodsDeliverNotice();
return $notice->handle($subscribe, $params);
}
} elseif ($smsNoticeEnabled) {
if ($smsNoticeEnabled) {
$notice = new SmsGoodsDeliverNotice();

View File

@ -59,8 +59,9 @@ class RefundFinish extends LogicService
$notice = new WeChatRefundFinishNotice();
return $notice->handle($subscribe, $params);
}
} elseif ($smsNoticeEnabled) {
if ($smsNoticeEnabled) {
$notice = new SmsRefundFinishNotice();

View File

@ -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);
}

View File

@ -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');
}

View File

@ -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个字符';