1
0
mirror of https://gitee.com/koogua/course-tencent-cloud.git synced 2025-06-26 12:23:06 +08:00

Merge branch 'koogua/v1.6.9' into demo

# Conflicts:
#	app/Validators/Security.php
This commit is contained in:
xiaochong0302 2024-04-10 19:44:07 +08:00
commit ad96fe604e
26 changed files with 908 additions and 555 deletions

View File

@ -1,3 +1,21 @@
### [v1.6.9](https://gitee.com/koogua/course-tencent-cloud/releases/v1.6.9)(2024-04-15)
- 增加用户删除和还原功能
- 增加unauthorized响应
- 增加post方式传递csrf_token
- 删除chapter中resource_count,consult_count属性
- 精简csrf_token白名单
- 拆解优化migrations创建表脚本
- 修正chapter_user时长重复计数问题
- 修正后台刷新首页缓存问题
- 修正home模块中编辑器图片上传
- 优化文章和提问搜索条件
- 优化课程详情页排版
- 优化storage上传
- 优化CategoryTreeList
- 优化CourseUserTrait
- 更新layui-v2.9.7
### [v1.6.8](https://gitee.com/koogua/course-tencent-cloud/releases/v1.6.8)(2024-01-30) ### [v1.6.8](https://gitee.com/koogua/course-tencent-cloud/releases/v1.6.8)(2024-01-30)
- 修正course_user中active_time未更新问题 - 修正course_user中active_time未更新问题

View File

@ -40,7 +40,7 @@ class UploadController extends Controller
} }
$data = [ $data = [
'src' => $service->getImageUrl($file->path), 'url' => $service->getImageUrl($file->path),
'title' => $file->name, 'title' => $file->name,
]; ];
@ -61,7 +61,7 @@ class UploadController extends Controller
} }
$data = [ $data = [
'src' => $service->getImageUrl($file->path), 'url' => $service->getImageUrl($file->path),
'title' => $file->name, 'title' => $file->name,
]; ];
@ -82,7 +82,7 @@ class UploadController extends Controller
} }
$data = [ $data = [
'src' => $service->getImageUrl($file->path), 'url' => $service->getImageUrl($file->path),
'title' => $file->name, 'title' => $file->name,
]; ];

View File

@ -178,7 +178,6 @@ class Article extends Service
if (isset($post['content'])) { if (isset($post['content'])) {
$data['content'] = $validator->checkContent($post['content']); $data['content'] = $validator->checkContent($post['content']);
$data['word_count'] = WordUtil::getWordCount($data['content']);
} }
if (isset($post['source_type'])) { if (isset($post['source_type'])) {

View File

@ -48,14 +48,12 @@ class Chapter extends Service
$data['course_id'] = $course->id; $data['course_id'] = $course->id;
$data['title'] = $validator->checkTitle($post['title']); $data['title'] = $validator->checkTitle($post['title']);
$data['summary'] = $validator->checkSummary($post['summary']);
$chapterRepo = new ChapterRepo(); $chapterRepo = new ChapterRepo();
if (isset($post['parent_id'])) { if (isset($post['parent_id'])) {
$parent = $validator->checkParent($post['parent_id']); $parent = $validator->checkParent($post['parent_id']);
$data['parent_id'] = $parent->id; $data['parent_id'] = $parent->id;
$data['free'] = $validator->checkFreeStatus($post['free']);
$data['priority'] = $chapterRepo->maxLessonPriority($post['parent_id']); $data['priority'] = $chapterRepo->maxLessonPriority($post['parent_id']);
} else { } else {
$data['priority'] = $chapterRepo->maxChapterPriority($post['course_id']); $data['priority'] = $chapterRepo->maxChapterPriority($post['course_id']);

View File

@ -23,19 +23,6 @@
<input class="layui-input" type="text" name="title" lay-verify="required"> <input class="layui-input" type="text" name="title" lay-verify="required">
</div> </div>
</div> </div>
<div class="layui-form-item">
<label class="layui-form-label">简介</label>
<div class="layui-input-block">
<textarea class="layui-textarea" name="summary"></textarea>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">免费</label>
<div class="layui-input-block">
<input type="radio" name="free" value="1" title="是">
<input type="radio" name="free" value="0" title="否" checked="checked">
</div>
</div>
<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">

View File

@ -8,7 +8,6 @@
namespace App\Http\Api\Controllers; namespace App\Http\Api\Controllers;
use App\Caches\IndexArticleList; use App\Caches\IndexArticleList;
use App\Caches\IndexFlashSaleList;
use App\Caches\IndexLiveList; use App\Caches\IndexLiveList;
use App\Caches\IndexQuestionList; use App\Caches\IndexQuestionList;
use App\Caches\IndexSimpleFeaturedCourseList; use App\Caches\IndexSimpleFeaturedCourseList;

View File

@ -30,7 +30,7 @@ class UploadController extends Controller
} }
$data = [ $data = [
'src' => $service->getImageUrl($file->path), 'url' => $service->getImageUrl($file->path),
'title' => $file->name, 'title' => $file->name,
]; ];

View File

@ -39,7 +39,7 @@ class UploadController extends Controller
} }
$data = [ $data = [
'src' => $service->getImageUrl($file->path), 'url' => $service->getImageUrl($file->path),
'title' => $file->name, 'title' => $file->name,
]; ];
@ -47,9 +47,9 @@ class UploadController extends Controller
} }
/** /**
* @Post("/content/img", name="home.upload.content_img") * @Post("/editor/img", name="home.upload.editor_img")
*/ */
public function uploadContentImageAction() public function uploadEditorImageAction()
{ {
$service = new StorageService(); $service = new StorageService();

View File

@ -79,7 +79,7 @@
{% block include_js %} {% block include_js %}
{{ js_include('home/js/upload.avatar.js') }} {{ js_include('home/js/user.avatar.upload.js') }}
{{ js_include('home/js/user.console.profile.js') }} {{ js_include('home/js/user.console.profile.js') }}
{% endblock %} {% endblock %}

View File

@ -38,7 +38,7 @@ class Question extends Model
public $category_id = 0; public $category_id = 0;
/** /**
* 提问者 * 提问者编号
* *
* @var integer * @var integer
*/ */

View File

@ -57,6 +57,14 @@ class Article extends Repository
} }
} }
if (!empty($where['owner_id'])) {
if (is_array($where['owner_id'])) {
$builder->inWhere('owner_id', $where['owner_id']);
} else {
$builder->andWhere('owner_id = :owner_id:', ['owner_id' => $where['owner_id']]);
}
}
if (!empty($where['source_type'])) { if (!empty($where['source_type'])) {
if (is_array($where['source_type'])) { if (is_array($where['source_type'])) {
$builder->inWhere('source_type', $where['source_type']); $builder->inWhere('source_type', $where['source_type']);
@ -73,10 +81,6 @@ class Article extends Repository
} }
} }
if (!empty($where['owner_id'])) {
$builder->andWhere('owner_id = :owner_id:', ['owner_id' => $where['owner_id']]);
}
if (!empty($where['title'])) { if (!empty($where['title'])) {
$builder->andWhere('title LIKE :title:', ['title' => "%{$where['title']}%"]); $builder->andWhere('title LIKE :title:', ['title' => "%{$where['title']}%"]);
} }

View File

@ -58,6 +58,14 @@ class Question extends Repository
} }
} }
if (!empty($where['owner_id'])) {
if (is_array($where['owner_id'])) {
$builder->inWhere('owner_id', $where['owner_id']);
} else {
$builder->andWhere('owner_id = :owner_id:', ['owner_id' => $where['owner_id']]);
}
}
if (!empty($where['published'])) { if (!empty($where['published'])) {
if (is_array($where['published'])) { if (is_array($where['published'])) {
$builder->inWhere('published', $where['published']); $builder->inWhere('published', $where['published']);
@ -72,10 +80,6 @@ class Question extends Repository
$builder->betweenWhere('create_time', $startTime, $endTime); $builder->betweenWhere('create_time', $startTime, $endTime);
} }
if (!empty($where['owner_id'])) {
$builder->andWhere('owner_id = :owner_id:', ['owner_id' => $where['owner_id']]);
}
if (!empty($where['title'])) { if (!empty($where['title'])) {
$builder->andWhere('title LIKE :title:', ['title' => "%{$where['title']}%"]); $builder->andWhere('title LIKE :title:', ['title' => "%{$where['title']}%"]);
} }

View File

@ -11,7 +11,6 @@ use App\Library\Paginator\Adapter\QueryBuilder as PagerQueryBuilder;
use App\Models\Chapter as ChapterModel; use App\Models\Chapter as ChapterModel;
use App\Models\ChapterLive as ChapterLiveModel; use App\Models\ChapterLive as ChapterLiveModel;
use App\Models\Course as CourseModel; use App\Models\Course as CourseModel;
use App\Models\CourseUser as CourseUserModel;
class TeacherLive extends Repository class TeacherLive extends Repository
{ {
@ -33,7 +32,6 @@ class TeacherLive extends Repository
->join(ChapterLiveModel::class, 'chapter.id = cl.chapter_id', 'cl') ->join(ChapterLiveModel::class, 'chapter.id = cl.chapter_id', 'cl')
->join(CourseModel::class, 'chapter.course_id = course.id', 'course') ->join(CourseModel::class, 'chapter.course_id = course.id', 'course')
->where('course.teacher_id = :teacher_id:', ['teacher_id' => $userId]) ->where('course.teacher_id = :teacher_id:', ['teacher_id' => $userId])
->andWhere('course.model = :model:', ['model' => CourseModel::MODEL_LIVE])
->andWhere('cl.start_time > :start_time:', ['start_time' => strtotime('today')]) ->andWhere('cl.start_time > :start_time:', ['start_time' => strtotime('today')])
->orderBy('cl.start_time ASC'); ->orderBy('cl.start_time ASC');

View File

@ -1,22 +0,0 @@
<?php
/**
* @copyright Copyright (c) 2021 深圳市酷瓜软件有限公司
* @license https://opensource.org/licenses/GPL-2.0
* @link https://www.koogua.com
*/
namespace App\Services\Logic;
use App\Validators\Danmu as DanmuValidator;
trait DanmuTrait
{
public function checkDanmu($id)
{
$validator = new DanmuValidator();
return $validator->checkDanmu($id);
}
}

View File

@ -140,7 +140,7 @@ class MyStorage extends Storage
*/ */
public function uploadCoverImage() public function uploadCoverImage()
{ {
return $this->upload('/img/cover/', self::MIME_IMAGE, UploadModel::TYPE_COVER_IMG); return $this->upload('/img/cover', self::MIME_IMAGE, UploadModel::TYPE_COVER_IMG);
} }
/** /**
@ -150,7 +150,7 @@ class MyStorage extends Storage
*/ */
public function uploadContentImage() public function uploadContentImage()
{ {
return $this->upload('/img/content/', self::MIME_IMAGE, UploadModel::TYPE_CONTENT_IMG); return $this->upload('/img/content', self::MIME_IMAGE, UploadModel::TYPE_CONTENT_IMG);
} }
/** /**
@ -160,7 +160,7 @@ class MyStorage extends Storage
*/ */
public function uploadAvatarImage() public function uploadAvatarImage()
{ {
return $this->upload('/img/avatar/', self::MIME_IMAGE, UploadModel::TYPE_AVATAR_IMG); return $this->upload('/img/avatar', self::MIME_IMAGE, UploadModel::TYPE_AVATAR_IMG);
} }
/** /**
@ -170,7 +170,7 @@ class MyStorage extends Storage
*/ */
public function uploadIconImage() public function uploadIconImage()
{ {
return $this->upload('/img/icon/', self::MIME_IMAGE, UploadModel::TYPE_ICON_IMG); return $this->upload('/img/icon', self::MIME_IMAGE, UploadModel::TYPE_ICON_IMG);
} }
/** /**
@ -180,7 +180,7 @@ class MyStorage extends Storage
*/ */
public function uploadResource() public function uploadResource()
{ {
return $this->upload('/resource/', self::MIME_FILE, UploadModel::TYPE_RESOURCE); return $this->upload('/resource', self::MIME_FILE, UploadModel::TYPE_RESOURCE);
} }
/** /**
@ -221,7 +221,7 @@ class MyStorage extends Storage
if (empty($fileName)) { if (empty($fileName)) {
$keyName = $this->generateFileName($extension, $prefix); $keyName = $this->generateFileName($extension, $prefix);
} else { } else {
$keyName = $prefix . $fileName; $keyName = $prefix .'/'. $fileName;
} }
$path = $this->putFile($keyName, $file->getTempName()); $path = $this->putFile($keyName, $file->getTempName());

View File

@ -259,7 +259,7 @@ class Storage extends Service
$dot = $extension ? '.' : ''; $dot = $extension ? '.' : '';
return sprintf('%s%s%s%s', $prefix, $name, $dot, $extension); return sprintf('%s/%s%s%s', $prefix, $name, $dot, $extension);
} }
/** /**

View File

@ -18,16 +18,22 @@ class Security extends Validator
public function checkCsrfToken() public function checkCsrfToken()
{ {
$route = $this->router->getMatchedRoute(); $route = $this->router->getMatchedRoute();
$headerToken = $this->request->getHeader('X-Csrf-Token');
$postToken = $this->request->getPost('csrf_token');
if (in_array($route->getName(), $this->getCsrfWhitelist())) { if (in_array($route->getName(), $this->getCsrfWhitelist())) {
return; return;
} }
$token = $this->request->getHeader('X-Csrf-Token');
$service = new CsrfTokenService(); $service = new CsrfTokenService();
$result = $service->checkToken($token); $result = false;
if ($headerToken) {
$result = $service->checkToken($headerToken);
} elseif ($postToken) {
$result = $service->checkToken($postToken);
}
if (!$result) { if (!$result) {
throw new BadRequestException('security.invalid_csrf_token'); throw new BadRequestException('security.invalid_csrf_token');
@ -58,10 +64,7 @@ class Security extends Validator
protected function getCsrfWhitelist() protected function getCsrfWhitelist()
{ {
return [ return [];
'admin.upload.content_img',
'home.upload.content_img',
];
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -32,8 +32,8 @@ layui.use(['jquery', 'layer', 'upload'], function () {
}); });
}, },
done: function (res, index, upload) { done: function (res, index, upload) {
$('#img-avatar').attr('src', res.data.src); $('#img-avatar').attr('src', res.data.url);
$('input[name=avatar]').val(res.data.src); $('input[name=avatar]').val(res.data.url);
layer.closeAll('loading'); layer.closeAll('loading');
}, },
error: function (index, upload) { error: function (index, upload) {

View File

@ -18,6 +18,9 @@ layui.use(['jquery'], function () {
'superscript', 'subscript', '|', 'image', 'link', 'unlink', '|', 'superscript', 'subscript', '|', 'image', 'link', 'unlink', '|',
'source', 'about' 'source', 'about'
], ],
extraFileUploadParams: {
csrf_token: $('meta[name="csrf-token"]').attr('content')
}
}; };
KindEditor.ready(function (K) { KindEditor.ready(function (K) {

View File

@ -13,8 +13,8 @@ layui.use(['jquery', 'layer', 'upload'], function () {
layer.load(); layer.load();
}, },
done: function (res, index, upload) { done: function (res, index, upload) {
$('#img-cover').attr('src', res.data.src); $('#img-cover').attr('src', res.data.url);
$('input[name=cover]').val(res.data.src); $('input[name=cover]').val(res.data.url);
layer.closeAll('loading'); layer.closeAll('loading');
}, },
error: function (index, upload) { error: function (index, upload) {

View File

@ -13,8 +13,8 @@ layui.use(['jquery', 'layer', 'upload'], function () {
layer.load(); layer.load();
}, },
done: function (res, index, upload) { done: function (res, index, upload) {
$('#img-icon').attr('src', res.data.src); $('#img-icon').attr('src', res.data.url);
$('input[name=icon]').val(res.data.src); $('input[name=icon]').val(res.data.url);
layer.closeAll('loading'); layer.closeAll('loading');
}, },
error: function (index, upload) { error: function (index, upload) {

View File

@ -18,6 +18,9 @@ layui.use(['jquery'], function () {
'superscript', 'subscript', '|', 'image', 'link', 'unlink', '|', 'superscript', 'subscript', '|', 'image', 'link', 'unlink', '|',
'source', 'about' 'source', 'about'
], ],
extraFileUploadParams: {
csrf_token: $('meta[name="csrf-token"]').attr('content')
}
}; };
KindEditor.ready(function (K) { KindEditor.ready(function (K) {

View File

@ -17,7 +17,6 @@ layui.use(['jquery', 'layer', 'upload'], function () {
choose: function (obj) { choose: function (obj) {
var flag = true; var flag = true;
obj.preview(function (index, file, result) { obj.preview(function (index, file, result) {
console.log(file);
var img = new Image(); var img = new Image();
img.src = result; img.src = result;
img.onload = function () { img.onload = function () {
@ -33,8 +32,8 @@ layui.use(['jquery', 'layer', 'upload'], function () {
}); });
}, },
done: function (res, index, upload) { done: function (res, index, upload) {
$('#img-avatar').attr('src', res.data.src); $('#img-avatar').attr('src', res.data.url);
$('input[name=avatar]').val(res.data.src); $('input[name=avatar]').val(res.data.url);
layer.closeAll('loading'); layer.closeAll('loading');
}, },
error: function (index, upload) { error: function (index, upload) {

View File

@ -16,7 +16,7 @@ layui.define(['jquery', 'layer'], function (exports) {
helper.getRequestId = function () { helper.getRequestId = function () {
var id = Date.now().toString(36); var id = Date.now().toString(36);
id += Math.random().toString(36).substr(3); id += Math.random().toString(36).substring(3);
return id; return id;
}; };