1
0
mirror of https://gitee.com/koogua/course-tencent-cloud.git synced 2025-06-28 05:11:39 +08:00

完成同一课程多次购买学习逻辑

This commit is contained in:
xiaochong0302 2020-06-02 18:54:42 +08:00
parent cf5cd3ea51
commit 533b0eaad5
30 changed files with 298 additions and 128 deletions

View File

@ -32,10 +32,7 @@ abstract class Cache extends Component
$content = $this->getContent($id); $content = $this->getContent($id);
/** $lifetime = $this->getLifetime();
* 原始内容为空,设置较短的生存时间,简单防止穿透
*/
$lifetime = $content ? $this->getLifetime() : 5 * 60;
$this->cache->save($key, $content, $lifetime); $this->cache->save($key, $content, $lifetime);

View File

@ -40,11 +40,9 @@ abstract class Counter extends Component
if (!$this->cache->exists($key)) { if (!$this->cache->exists($key)) {
$content = $this->getContent($id); $content = $this->getContent($id);
$lifetime = $this->getLifetime(); $lifetime = $this->getLifetime();
$this->redis->hMSet($key, $content); $this->redis->hMSet($key, $content);
$this->redis->expire($key, $lifetime); $this->redis->expire($key, $lifetime);
} }

33
app/Caches/CourseUser.php Normal file
View File

@ -0,0 +1,33 @@
<?php
namespace App\Caches;
use App\Repos\CourseUser as CourseUserRepo;
class CourseUser extends Cache
{
protected $lifetime = 1 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return "course_user:{$id}";
}
public function getContent($id = null)
{
list($courseId, $userId) = explode('_', $id);
$repo = new CourseUserRepo();
$courseUser = $repo->findCourseUser($courseId, $userId);
return $courseUser ?: null;
}
}

View File

@ -2,14 +2,11 @@
namespace App\Console\Tasks; namespace App\Console\Tasks;
use App\Models\ChapterUser as ChapterUserModel;
use App\Models\CourseUser as CourseUserModel; use App\Models\CourseUser as CourseUserModel;
use App\Models\Learning as LearningModel;
use App\Models\Order as OrderModel; use App\Models\Order as OrderModel;
use App\Models\Refund as RefundModel; use App\Models\Refund as RefundModel;
use App\Models\Task as TaskModel; use App\Models\Task as TaskModel;
use App\Models\Trade as TradeModel; use App\Models\Trade as TradeModel;
use App\Repos\CourseUser as CourseUserRepo;
use App\Repos\Order as OrderRepo; use App\Repos\Order as OrderRepo;
use App\Repos\User as UserRepo; use App\Repos\User as UserRepo;
use App\Services\Smser\Order as OrderSmser; use App\Services\Smser\Order as OrderSmser;
@ -116,8 +113,6 @@ class OrderTask extends Task
if ($courseUser->create($data) === false) { if ($courseUser->create($data) === false) {
throw new \RuntimeException('Create CourseQuery User Failed'); throw new \RuntimeException('Create CourseQuery User Failed');
} }
$this->handleCourseHistory($data['course_id'], $data['user_id']);
} }
protected function handlePackageOrder(OrderModel $order) protected function handlePackageOrder(OrderModel $order)
@ -140,10 +135,8 @@ class OrderTask extends Task
$courseUser = new CourseUserModel(); $courseUser = new CourseUserModel();
if ($courseUser->create($data) === false) { if ($courseUser->create($data) === false) {
throw new \RuntimeException('Create CourseQuery User Failed'); throw new \RuntimeException('Create Course User Failed');
} }
$this->handleCourseHistory($data['course_id'], $data['user_id']);
} }
} }
@ -196,57 +189,6 @@ class OrderTask extends Task
$refund->create(); $refund->create();
} }
protected function handleCourseHistory($courseId, $userId)
{
$courseUserRepo = new CourseUserRepo();
$courseUser = $courseUserRepo->findCourseStudent($courseId, $userId);
if ($courseUser) {
$courseUser->update(['deleted' => 1]);
}
$chapterUsers = $this->findPlanChapterUsers($courseId, $userId);
if ($chapterUsers->count() > 0) {
$chapterUsers->update(['deleted' => 1]);
}
$learnings = $this->findPlanLearnings($courseId, $userId);
if ($learnings->count() > 0) {
$learnings->update(['deleted' => 1]);
}
}
/**
* @param int $courseId
* @param int $userId
* @return ResultsetInterface|Resultset|CourseUserModel[]
*/
protected function findPlanChapterUsers($courseId, $userId)
{
return ChapterUserModel::query()
->where('course_id = :course_id:', ['course_id' => $courseId])
->andWhere('user_id = :user_id:', ['user_id' => $userId])
->andWhere('deleted = 0')
->execute();
}
/**
* @param int $courseId
* @param int $userId
* @return ResultsetInterface|Resultset|CourseUserModel[]
*/
protected function findPlanLearnings($courseId, $userId)
{
return LearningModel::query()
->where('course_id = :course_id:', ['course_id' => $courseId])
->andWhere('user_id = :user_id:', ['user_id' => $userId])
->andWhere('deleted = 0')
->execute();
}
/** /**
* @param int $orderId * @param int $orderId
* @return Model|TradeModel * @return Model|TradeModel

View File

@ -153,21 +153,34 @@ class SyncLearningTask extends Task
return; return;
} }
$userLearnings = $courseRepo->findConsumedUserLearnings($courseId, $userId); $userLearnings = $courseRepo->findUserLearnings($courseId, $userId, $courseUser->plan_id);
if ($userLearnings->count() == 0) { if ($userLearnings->count() == 0) {
return; return;
} }
/**
* @var array $consumedUserLearnings
*/
$consumedUserLearnings = $userLearnings->filter(function ($item) {
if ($item->consumed == 1) {
return $item;
}
});
if (count($consumedUserLearnings) == 0) {
return;
}
$duration = 0; $duration = 0;
foreach ($userLearnings as $learning) { foreach ($consumedUserLearnings as $learning) {
$duration += $learning->duration; $duration += $learning['duration'];
} }
$courseLessonIds = kg_array_column($courseLessons->toArray(), 'id'); $courseLessonIds = kg_array_column($courseLessons->toArray(), 'id');
$userLessonIds = kg_array_column($userLearnings->toArray(), 'chapter_id'); $consumedUserLessonIds = kg_array_column($consumedUserLearnings, 'chapter_id');
$consumedLessonIds = array_intersect($courseLessonIds, $userLessonIds); $consumedLessonIds = array_intersect($courseLessonIds, $consumedUserLessonIds);
$totalCount = count($courseLessonIds); $totalCount = count($courseLessonIds);
$consumedCount = count($consumedLessonIds); $consumedCount = count($consumedLessonIds);

View File

@ -10,6 +10,14 @@ use App\Http\Admin\Services\Package as PackageService;
class PackageController extends Controller class PackageController extends Controller
{ {
/**
* @Get("/search", name="admin.package.search")
*/
public function searchAction()
{
}
/** /**
* @Get("/guiding", name="admin.package.guiding") * @Get("/guiding", name="admin.package.guiding")
*/ */

View File

@ -105,18 +105,24 @@ class AuthNode extends Service
], ],
[ [
'id' => '1-3-2', 'id' => '1-3-2',
'title' => '搜索套餐',
'type' => 'menu',
'route' => 'admin.package.search',
],
[
'id' => '1-3-3',
'title' => '添加套餐', 'title' => '添加套餐',
'type' => 'menu', 'type' => 'menu',
'route' => 'admin.package.add', 'route' => 'admin.package.add',
], ],
[ [
'id' => '1-3-3', 'id' => '1-3-4',
'title' => '编辑套餐', 'title' => '编辑套餐',
'type' => 'button', 'type' => 'button',
'route' => 'admin.package.edit', 'route' => 'admin.package.edit',
], ],
[ [
'id' => '1-3-4', 'id' => '1-3-5',
'title' => '删除套餐', 'title' => '删除套餐',
'type' => 'button', 'type' => 'button',
'route' => 'admin.package.delete', 'route' => 'admin.package.delete',

View File

@ -358,7 +358,7 @@ class Course extends Service
} }
} }
$newTeacherIds = explode(',', $teacherIds); $newTeacherIds = $teacherIds ? explode(',', $teacherIds) : [];
$addedTeacherIds = array_diff($newTeacherIds, $originTeacherIds); $addedTeacherIds = array_diff($newTeacherIds, $originTeacherIds);
if ($addedTeacherIds) { if ($addedTeacherIds) {
@ -412,7 +412,7 @@ class Course extends Service
} }
} }
$newCategoryIds = explode(',', $categoryIds); $newCategoryIds = $categoryIds ? explode(',', $categoryIds) : [];
$addedCategoryIds = array_diff($newCategoryIds, $originCategoryIds); $addedCategoryIds = array_diff($newCategoryIds, $originCategoryIds);
if ($addedCategoryIds) { if ($addedCategoryIds) {
@ -463,7 +463,7 @@ class Course extends Service
} }
} }
$newRelatedIds = explode(',', $courseIds); $newRelatedIds = $courseIds ? explode(',', $courseIds) : [];
$addedRelatedIds = array_diff($newRelatedIds, $originRelatedIds); $addedRelatedIds = array_diff($newRelatedIds, $originRelatedIds);
$courseRelatedRepo = new CourseRelatedRepo(); $courseRelatedRepo = new CourseRelatedRepo();

View File

@ -2,6 +2,7 @@
namespace App\Http\Admin\Services; namespace App\Http\Admin\Services;
use App\Caches\CoursePackageList as CoursePackageListCache;
use App\Caches\Package as PackageCache; use App\Caches\Package as PackageCache;
use App\Caches\PackageCourseList as PackageCourseListCache; use App\Caches\PackageCourseList as PackageCourseListCache;
use App\Library\Paginator\Query as PagerQuery; use App\Library\Paginator\Query as PagerQuery;
@ -93,7 +94,7 @@ class Package extends Service
$package->update($data); $package->update($data);
$this->updateCourseCount($package); $this->updatePackageCourseCount($package);
$this->rebuildPackageCache($package); $this->rebuildPackageCache($package);
@ -193,7 +194,7 @@ class Package extends Service
} }
} }
$newCourseIds = explode(',', $courseIds); $newCourseIds = $courseIds ? explode(',', $courseIds) : [];
$addedCourseIds = array_diff($newCourseIds, $originCourseIds); $addedCourseIds = array_diff($newCourseIds, $originCourseIds);
if ($addedCourseIds) { if ($addedCourseIds) {
@ -203,6 +204,8 @@ class Package extends Service
'course_id' => $courseId, 'course_id' => $courseId,
'package_id' => $package->id, 'package_id' => $package->id,
]); ]);
$this->updateCoursePackageCount($courseId);
$this->rebuildCoursePackageCache($courseId);
} }
} }
@ -212,14 +215,14 @@ class Package extends Service
$coursePackageRepo = new CoursePackageRepo(); $coursePackageRepo = new CoursePackageRepo();
foreach ($deletedCourseIds as $courseId) { foreach ($deletedCourseIds as $courseId) {
$coursePackage = $coursePackageRepo->findCoursePackage($courseId, $package->id); $coursePackage = $coursePackageRepo->findCoursePackage($courseId, $package->id);
if ($coursePackage) { $coursePackage->delete();
$coursePackage->delete(); $this->updateCoursePackageCount($courseId);
} $this->rebuildCoursePackageCache($courseId);
} }
} }
} }
protected function updateCourseCount(PackageModel $package) protected function updatePackageCourseCount(PackageModel $package)
{ {
$packageRepo = new PackageRepo(); $packageRepo = new PackageRepo();
@ -230,6 +233,19 @@ class Package extends Service
$package->update(); $package->update();
} }
protected function updateCoursePackageCount($courseId)
{
$courseRepo = new CourseRepo();
$course = $courseRepo->findById($courseId);
$packageCount = $courseRepo->countPackages($courseId);
$course->package_count = $packageCount;
$course->update();
}
protected function rebuildPackageCache(PackageModel $package) protected function rebuildPackageCache(PackageModel $package)
{ {
$cache = new PackageCache(); $cache = new PackageCache();
@ -241,6 +257,13 @@ class Package extends Service
$cache->rebuild($package->id); $cache->rebuild($package->id);
} }
protected function rebuildCoursePackageCache($courseId)
{
$cache = new CoursePackageListCache();
$cache->rebuild($courseId);
}
protected function findOrFail($id) protected function findOrFail($id)
{ {
$validator = new PackageValidator(); $validator = new PackageValidator();

View File

@ -5,9 +5,9 @@
</fieldset> </fieldset>
<div class="layui-form-item"> <div class="layui-form-item">
<label class="layui-form-label">课程编号</label> <label class="layui-form-label">编号</label>
<div class="layui-input-block"> <div class="layui-input-block">
<input class="layui-input" type="text" name="id" placeholder="课程编号精确匹配"> <input class="layui-input" type="text" name="id" placeholder="编号精确匹配">
</div> </div>
</div> </div>

View File

@ -0,0 +1,45 @@
<form class="layui-form kg-form" method="GET" action="{{ url({'for':'admin.package.list'}) }}">
<fieldset class="layui-elem-field layui-field-title">
<legend>搜索套餐</legend>
</fieldset>
<div class="layui-form-item">
<label class="layui-form-label">编号</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="id" placeholder="编号精确匹配">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">标题</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="title" placeholder="标题模糊匹配">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">发布</label>
<div class="layui-input-block">
<input type="radio" name="published" value="1" title="是">
<input type="radio" name="published" value="0" title="否">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">删除</label>
<div class="layui-input-block">
<input type="radio" name="deleted" value="1" title="是">
<input type="radio" name="deleted" value="0" title="否">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"></label>
<div class="layui-input-block">
<button class="layui-btn" lay-submit="true">提交</button>
<button type="button" class="kg-back layui-btn layui-btn-primary">返回</button>
</div>
</div>
</form>

View File

@ -23,6 +23,9 @@
<div class="cover"><img src="{{ course.cover }}!cover_270" alt="{{ course.title }}"></div> <div class="cover"><img src="{{ course.cover }}!cover_270" alt="{{ course.title }}"></div>
<div class="title"><a href="{{ course_url }}">{{ course.title }}</a></div> <div class="title"><a href="{{ course_url }}">{{ course.title }}</a></div>
</div> </div>
{% if loop.first %}
<div class="separator"><i class="layui-icon layui-icon-add-1"></i></div>
{% endif %}
{% endfor %} {% endfor %}
</div> </div>
</div> </div>

View File

@ -21,7 +21,7 @@
<div class="layout-main clearfix"> <div class="layout-main clearfix">
{% set show_tab_packages = 1 %} {% set show_tab_packages = course.package_count > 0 ? 1 : 0 %}
{% set show_tab_consults = course.consult_count > 0 ? 1 : 0 %} {% set show_tab_consults = course.consult_count > 0 ? 1 : 0 %}
{% set show_tab_reviews = course.review_count > 0 ? 1 : 0 %} {% set show_tab_reviews = course.review_count > 0 ? 1 : 0 %}

View File

@ -15,7 +15,7 @@ class ChapterUser extends Model
public $id; public $id;
/** /**
* 计划编号(course_user主键) * 计划编号
* *
* @var int * @var int
*/ */

View File

@ -178,6 +178,13 @@ class Course extends Model
*/ */
public $lesson_count; public $lesson_count;
/**
* 套餐数
*
* @var int
*/
public $package_count;
/** /**
* 评论数 * 评论数
* *
@ -349,6 +356,7 @@ class Course extends Model
'rating' => '评价', 'rating' => '评价',
'latest' => '最新', 'latest' => '最新',
'popular' => '最热', 'popular' => '最热',
'free' => '免费',
]; ];
} }

View File

@ -27,6 +27,13 @@ class CourseUser extends Model
*/ */
public $id; public $id;
/**
* 计划编号
*
* @var int
*/
public $plan_id;
/** /**
* 课程编号 * 课程编号
* *
@ -123,6 +130,8 @@ class CourseUser extends Model
public function beforeCreate() public function beforeCreate()
{ {
$this->plan_id = (int)date('Y-m-d');
$this->create_time = time(); $this->create_time = time();
} }

View File

@ -28,7 +28,7 @@ class Learning extends Model
public $request_id; public $request_id;
/** /**
* 计划编号(course_user主键) * 计划编号
* *
* @var int * @var int
*/ */

View File

@ -45,6 +45,7 @@ class ChapterUser extends Repository
return ChapterUserModel::findFirst([ return ChapterUserModel::findFirst([
'conditions' => 'chapter_id = ?1 AND user_id = ?2 AND deleted = 0', 'conditions' => 'chapter_id = ?1 AND user_id = ?2 AND deleted = 0',
'bind' => [1 => $chapterId, 2 => $userId], 'bind' => [1 => $chapterId, 2 => $userId],
'order' => 'id DESC',
]); ]);
} }

View File

@ -60,6 +60,10 @@ class Course extends Repository
$builder->andWhere('level = :level:', ['level' => $where['level']]); $builder->andWhere('level = :level:', ['level' => $where['level']]);
} }
if ($sort == 'free') {
$where['free'] = 1;
}
if (isset($where['free'])) { if (isset($where['free'])) {
if ($where['free'] == 1) { if ($where['free'] == 1) {
$builder->andWhere('market_price = 0'); $builder->andWhere('market_price = 0');
@ -215,28 +219,15 @@ class Course extends Repository
/** /**
* @param int $courseId * @param int $courseId
* @param int $userId * @param int $userId
* @param int $planId
* @return ResultsetInterface|Resultset|ChapterUserModel[] * @return ResultsetInterface|Resultset|ChapterUserModel[]
*/ */
public function findUserLearnings($courseId, $userId) public function findUserLearnings($courseId, $userId, $planId)
{ {
return ChapterUserModel::query() return ChapterUserModel::query()
->where('course_id = :course_id:', ['course_id' => $courseId]) ->where('course_id = :course_id:', ['course_id' => $courseId])
->andWhere('user_id = :user_id:', ['user_id' => $userId]) ->andWhere('user_id = :user_id:', ['user_id' => $userId])
->andWhere('deleted = 0') ->andWhere('plan_id = :plan_id:', ['plan_id' => $planId])
->execute();
}
/**
* @param int $courseId
* @param int $userId
* @return ResultsetInterface|Resultset|ChapterUserModel[]
*/
public function findConsumedUserLearnings($courseId, $userId)
{
return ChapterUserModel::query()
->where('course_id = :course_id:', ['course_id' => $courseId])
->andWhere('user_id = :user_id:', ['user_id' => $userId])
->andWhere('consumed = 1 AND deleted = 0')
->execute(); ->execute();
} }
@ -280,6 +271,14 @@ class Course extends Repository
]); ]);
} }
public function countPackages($courseId)
{
return CoursePackageModel::count([
'conditions' => 'course_id = :course_id:',
'bind' => ['course_id' => $courseId],
]);
}
public function countUsers($courseId) public function countUsers($courseId)
{ {
return CourseUserModel::count([ return CourseUserModel::count([

View File

@ -21,8 +21,12 @@ class Package extends Repository
$builder->where('1 = 1'); $builder->where('1 = 1');
if (!empty($where['user_id'])) { if (!empty($where['id'])) {
$builder->andWhere('user_id = :user_id:', ['user_id' => $where['user_id']]); $builder->andWhere('id = :id:', ['id' => $where['id']]);
}
if (!empty($where['title'])) {
$builder->andWhere('title LIKE :title:', ['title' => "%{$where['title']}%"]);
} }
if (isset($where['published'])) { if (isset($where['published'])) {

View File

@ -170,7 +170,7 @@ class ChapterInfo extends FrontendService
protected function handleCourseUser(CourseModel $course, UserModel $user) protected function handleCourseUser(CourseModel $course, UserModel $user)
{ {
if (empty($user->id)) return; if ($user->id == 0) return;
if ($this->joinedCourse) return; if ($this->joinedCourse) return;
@ -182,7 +182,6 @@ class ChapterInfo extends FrontendService
$courseUser->user_id = $user->id; $courseUser->user_id = $user->id;
$courseUser->source_type = CourseUserModel::SOURCE_FREE; $courseUser->source_type = CourseUserModel::SOURCE_FREE;
$courseUser->role_type = CourseUserModel::ROLE_STUDENT; $courseUser->role_type = CourseUserModel::ROLE_STUDENT;
$courseUser->expiry_time = strtotime('+3 years');
$courseUser->create(); $courseUser->create();
@ -191,14 +190,22 @@ class ChapterInfo extends FrontendService
protected function handleChapterUser(ChapterModel $chapter, UserModel $user) protected function handleChapterUser(ChapterModel $chapter, UserModel $user)
{ {
if (empty($user->id)) return; if ($user->id == 0) return;
if ($this->joinedChapter) return; /**
* 一个课程可能购买学习多次
*/
if ($this->chapterUser && $this->courseUser) {
if ($this->chapterUser->plan_id == $this->courseUser->plan_id) {
return;
}
}
if (!$this->ownedChapter) return; if (!$this->ownedChapter) return;
$chapterUser = new ChapterUserModel(); $chapterUser = new ChapterUserModel();
$chapterUser->plan_id = $this->courseUser->plan_id;
$chapterUser->course_id = $chapter->course_id; $chapterUser->course_id = $chapter->course_id;
$chapterUser->chapter_id = $chapter->id; $chapterUser->chapter_id = $chapter->id;
$chapterUser->user_id = $user->id; $chapterUser->user_id = $user->id;

View File

@ -3,6 +3,7 @@
namespace App\Services\Frontend; namespace App\Services\Frontend;
use App\Models\Chapter as ChapterModel; use App\Models\Chapter as ChapterModel;
use App\Models\ChapterUser as ChapterUserModel;
use App\Models\User as UserModel; use App\Models\User as UserModel;
use App\Repos\ChapterUser as ChapterUserRepo; use App\Repos\ChapterUser as ChapterUserRepo;
use App\Validators\Chapter as ChapterValidator; use App\Validators\Chapter as ChapterValidator;
@ -20,6 +21,11 @@ trait ChapterTrait
*/ */
protected $joinedChapter = false; protected $joinedChapter = false;
/**
* @var ChapterUserModel
*/
protected $chapterUser;
public function checkChapter($id) public function checkChapter($id)
{ {
$validator = new ChapterValidator(); $validator = new ChapterValidator();
@ -41,6 +47,7 @@ trait ChapterTrait
$chapterUser = $chapterUserRepo->findChapterUser($chapter->id, $user->id); $chapterUser = $chapterUserRepo->findChapterUser($chapter->id, $user->id);
if ($chapterUser) { if ($chapterUser) {
$this->chapterUser = $chapterUser;
$this->joinedChapter = true; $this->joinedChapter = true;
} }

View File

@ -31,7 +31,7 @@ class ChapterList extends FrontendService
$chapters = $cache->get($course->id); $chapters = $cache->get($course->id);
if (empty($chapters)) { if (count($chapters) == 0) {
return []; return [];
} }
@ -46,7 +46,7 @@ class ChapterList extends FrontendService
} }
} }
} else { } else {
$mappings = $this->getLearningMappings($course, $user); $mappings = $this->getLearningMappings($course->id, $user->id, $this->courseUser->plan_id);
foreach ($chapters as &$chapter) { foreach ($chapters as &$chapter) {
foreach ($chapter['children'] as &$lesson) { foreach ($chapter['children'] as &$lesson) {
$lesson['me'] = [ $lesson['me'] = [
@ -61,11 +61,11 @@ class ChapterList extends FrontendService
return $chapters; return $chapters;
} }
protected function getLearningMappings(CourseModel $course, UserModel $user) protected function getLearningMappings($courseId, $userId, $planId)
{ {
$courseRepo = new CourseRepo(); $courseRepo = new CourseRepo();
$userLearnings = $courseRepo->findUserLearnings($course->id, $user->id); $userLearnings = $courseRepo->findUserLearnings($courseId, $userId, $planId);
if ($userLearnings->count() == 0) { if ($userLearnings->count() == 0) {
return []; return [];

View File

@ -45,6 +45,7 @@ class CourseInfo extends FrontendService
'attrs' => $course->attrs, 'attrs' => $course->attrs,
'user_count' => $course->user_count, 'user_count' => $course->user_count,
'lesson_count' => $course->lesson_count, 'lesson_count' => $course->lesson_count,
'package_count' => $course->package_count,
'review_count' => $course->review_count, 'review_count' => $course->review_count,
'comment_count' => $course->comment_count, 'comment_count' => $course->comment_count,
'consult_count' => $course->consult_count, 'consult_count' => $course->consult_count,

View File

@ -28,18 +28,21 @@ class PackageList extends FrontendService
$result = []; $result = [];
$firstCourseId = $course->id;
foreach ($packages as $package) { foreach ($packages as $package) {
$courses = $cache->get($package['id']); $courses = $cache->get($package['id']);
$package['origin_price'] = 0.00; $package['origin_price'] = 0.00;
$package['courses'] = []; $package['courses'] = [];
if ($courses) { if ($courses) {
foreach ($courses as $course) { foreach ($courses as $course) {
$package['origin_price'] += $course['market_price']; $package['origin_price'] += $course['market_price'];
} }
$package['courses'] = $courses; $package['courses'] = $this->sortCourses($courses, $firstCourseId);
} }
$result[] = $package; $result[] = $package;
@ -48,4 +51,36 @@ class PackageList extends FrontendService
return $result; return $result;
} }
/**
* 把特定课程排在第一位
*
* @param array $courses
* @param int $firstCourseId
* @return array
*/
protected function sortCourses(array $courses, $firstCourseId)
{
$firstCourse = [];
foreach ($courses as $course) {
if ($course['id'] == $firstCourseId) {
$firstCourse = $course;
}
}
$result = [];
if ($firstCourse) {
$result[] = $firstCourse;
}
foreach ($courses as $course) {
if ($course['id'] != $firstCourseId) {
$result[] = $course;
}
}
return $result;
}
} }

View File

@ -22,7 +22,7 @@ trait CourseTrait
protected $joinedCourse = false; protected $joinedCourse = false;
/** /**
* @var CourseUserModel * @var CourseUserModel|null
*/ */
protected $courseUser; protected $courseUser;
@ -42,12 +42,16 @@ trait CourseTrait
public function setCourseUser(CourseModel $course, UserModel $user) public function setCourseUser(CourseModel $course, UserModel $user)
{ {
$courseUserRepo = new CourseUserRepo(); $courseUser = null;
$courseUser = $courseUserRepo->findCourseUser($course->id, $user->id); if ($user->id > 0) {
$courseUserRepo = new CourseUserRepo();
$courseUser = $courseUserRepo->findCourseUser($course->id, $user->id);
}
$this->courseUser = $courseUser;
if ($courseUser) { if ($courseUser) {
$this->courseUser = $courseUser;
$this->joinedCourse = true; $this->joinedCourse = true;
} }

View File

@ -4,6 +4,7 @@ namespace App\Services;
use App\Models\Order as OrderModel; use App\Models\Order as OrderModel;
use App\Repos\Course as CourseRepo; use App\Repos\Course as CourseRepo;
use App\Repos\CourseUser as CourseUserRepo;
class Refund extends Service class Refund extends Service
{ {
@ -104,15 +105,36 @@ class Refund extends Service
return 1.00; return 1.00;
} }
$userLearnings = $courseRepo->findConsumedUserLearnings($courseId, $userId); $courseUserRepo = new CourseUserRepo();
$courseUser = $courseUserRepo->findCourseUser($courseId, $userId);
if (!$courseUser) {
return 1.00;
}
$userLearnings = $courseRepo->findUserLearnings($courseId, $userId, $courseUser->plan_id);
if ($userLearnings->count() == 0) { if ($userLearnings->count() == 0) {
return 1.00; return 1.00;
} }
/**
* @var array $consumedUserLearnings
*/
$consumedUserLearnings = $userLearnings->filter(function ($item) {
if ($item->consumed == 1) {
return $item;
}
});
if (count($consumedUserLearnings) == 0) {
return 1.00;
}
$courseLessonIds = kg_array_column($courseLessons->toArray(), 'id'); $courseLessonIds = kg_array_column($courseLessons->toArray(), 'id');
$userLessonIds = kg_array_column($userLearnings->toArray(), 'chapter_id'); $consumedUserLessonIds = kg_array_column($consumedUserLearnings, 'chapter_id');
$consumedLessonIds = array_intersect($courseLessonIds, $userLessonIds); $consumedLessonIds = array_intersect($courseLessonIds, $consumedUserLessonIds);
$totalCount = count($courseLessonIds); $totalCount = count($courseLessonIds);
$consumedCount = count($consumedLessonIds); $consumedCount = count($consumedLessonIds);

View File

@ -4,7 +4,6 @@ namespace App\Traits;
use App\Caches\User as UserCache; use App\Caches\User as UserCache;
use App\Models\User as UserModel; use App\Models\User as UserModel;
use App\Repos\User as UserRepo;
use App\Services\Auth as AuthService; use App\Services\Auth as AuthService;
use App\Validators\Validator as AppValidator; use App\Validators\Validator as AppValidator;
use Phalcon\Di; use Phalcon\Di;
@ -33,10 +32,6 @@ trait Auth
*/ */
public function getLoginUser() public function getLoginUser()
{ {
$userRepo = new UserRepo();
return $userRepo->findById(100015);
$authUser = $this->getAuthUser(); $authUser = $this->getAuthUser();
$validator = new AppValidator(); $validator = new AppValidator();

View File

@ -419,7 +419,7 @@ body {
} }
.package-item { .package-item {
margin-bottom: 15px; margin-bottom: 25px;
border-bottom: 1px dashed #ccc; border-bottom: 1px dashed #ccc;
} }
@ -468,16 +468,24 @@ body {
} }
.package-course-list { .package-course-list {
width: 560px; width: 580px;
height: 170px; height: 170px;
overflow-x: auto; overflow-x: auto;
white-space: nowrap; white-space: nowrap;
} }
.separator {
color: #666;
display: inline-block;
padding-top: 35px;
margin-left: -5px;
margin-right: 4px;
}
.package-course-card { .package-course-card {
width: 175px; width: 175px;
display: inline-block; display: inline-block;
margin-right: 5px; margin-right: 8px;
vertical-align: top; vertical-align: top;
} }

2
storage/cache/annotations/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*
!.gitignore