mirror of
https://gitee.com/koogua/course-tencent-cloud.git
synced 2025-07-16 13:16:14 +08:00
增加im_group后台管理,user_id->owner_id
This commit is contained in:
parent
b7bd710cd9
commit
7f2d3b793e
@ -25,7 +25,7 @@ class ConsultList extends Builder
|
||||
$users = $this->getUsers($consults);
|
||||
|
||||
foreach ($consults as $key => $consult) {
|
||||
$consults[$key]['user'] = $users[$consult['user_id']] ?? new \stdClass();
|
||||
$consults[$key]['owner'] = $users[$consult['owner_id']] ?? new \stdClass();
|
||||
}
|
||||
|
||||
return $consults;
|
||||
@ -67,7 +67,7 @@ class ConsultList extends Builder
|
||||
|
||||
public function getUsers(array $consults)
|
||||
{
|
||||
$ids = kg_array_column($consults, 'user_id');
|
||||
$ids = kg_array_column($consults, 'owner_id');
|
||||
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
|
@ -7,7 +7,7 @@ use App\Models\Course as CourseModel;
|
||||
use Phalcon\Mvc\Model\Resultset;
|
||||
use Phalcon\Mvc\Model\ResultsetInterface;
|
||||
|
||||
class ChapterTreeList extends Builder
|
||||
class CourseCatalog extends Builder
|
||||
{
|
||||
|
||||
/**
|
@ -36,7 +36,7 @@ class DanmuList extends Builder
|
||||
$users = $this->getUsers($danmus);
|
||||
|
||||
foreach ($danmus as $key => $danmu) {
|
||||
$danmus[$key]['user'] = $users[$danmu['user_id']] ?? new \stdClass();
|
||||
$danmus[$key]['owner'] = $users[$danmu['owner_id']] ?? new \stdClass();
|
||||
}
|
||||
|
||||
return $danmus;
|
||||
@ -78,7 +78,7 @@ class DanmuList extends Builder
|
||||
|
||||
public function getUsers(array $danmus)
|
||||
{
|
||||
$ids = kg_array_column($danmus, 'user_id');
|
||||
$ids = kg_array_column($danmus, 'owner_id');
|
||||
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
|
70
app/Builders/ImGroupList.php
Normal file
70
app/Builders/ImGroupList.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace App\Builders;
|
||||
|
||||
use App\Repos\Course as CourseRepo;
|
||||
use App\Repos\User as UserRepo;
|
||||
|
||||
class ImGroupList extends Builder
|
||||
{
|
||||
|
||||
public function handleCourses(array $groups)
|
||||
{
|
||||
$courses = $this->getCourses($groups);
|
||||
|
||||
foreach ($groups as $key => $group) {
|
||||
$groups[$key]['course'] = $courses[$group['course_id']] ?? new \stdClass();
|
||||
}
|
||||
|
||||
return $groups;
|
||||
}
|
||||
|
||||
public function handleUsers(array $groups)
|
||||
{
|
||||
$users = $this->getUsers($groups);
|
||||
|
||||
foreach ($groups as $key => $group) {
|
||||
$groups[$key]['owner'] = $users[$group['owner_id']] ?? new \stdClass();
|
||||
}
|
||||
|
||||
return $groups;
|
||||
}
|
||||
|
||||
public function getCourses(array $groups)
|
||||
{
|
||||
$ids = kg_array_column($groups, 'course_id');
|
||||
|
||||
$courseRepo = new CourseRepo();
|
||||
|
||||
$courses = $courseRepo->findByIds($ids, ['id', 'title']);
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($courses->toArray() as $course) {
|
||||
$result[$course['id']] = $course;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getUsers(array $groups)
|
||||
{
|
||||
$ids = kg_array_column($groups, 'owner_id');
|
||||
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
$users = $userRepo->findByIds($ids, ['id', 'name', 'avatar']);
|
||||
|
||||
$baseUrl = kg_ci_base_url();
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($users->toArray() as $user) {
|
||||
$user['avatar'] = $baseUrl . $user['avatar'];
|
||||
$result[$user['id']] = $user;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
@ -24,7 +24,7 @@ class ReviewList extends Builder
|
||||
$users = $this->getUsers($reviews);
|
||||
|
||||
foreach ($reviews as $key => $review) {
|
||||
$reviews[$key]['user'] = $users[$review['user_id']] ?? new \stdClass();
|
||||
$reviews[$key]['owner'] = $users[$review['owner_id']] ?? new \stdClass();
|
||||
}
|
||||
|
||||
return $reviews;
|
||||
@ -49,7 +49,7 @@ class ReviewList extends Builder
|
||||
|
||||
public function getUsers(array $reviews)
|
||||
{
|
||||
$ids = kg_array_column($reviews, 'user_id');
|
||||
$ids = kg_array_column($reviews, 'owner_id');
|
||||
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
|
@ -2,9 +2,9 @@
|
||||
|
||||
namespace App\Caches;
|
||||
|
||||
use App\Builders\ChapterTreeList as ChapterTreeListBuilder;
|
||||
use App\Builders\CourseCatalog as CourseCatalogBuilder;
|
||||
|
||||
class CourseChapterList extends Cache
|
||||
class CourseCatalog extends Cache
|
||||
{
|
||||
|
||||
protected $lifetime = 7 * 86400;
|
||||
@ -16,12 +16,12 @@ class CourseChapterList extends Cache
|
||||
|
||||
public function getKey($id = null)
|
||||
{
|
||||
return "course_chapter_list:{$id}";
|
||||
return "course_catalog:{$id}";
|
||||
}
|
||||
|
||||
public function getContent($id = null)
|
||||
{
|
||||
$builder = new ChapterTreeListBuilder();
|
||||
$builder = new CourseCatalogBuilder();
|
||||
|
||||
$list = $builder->handle($id);
|
||||
|
@ -22,7 +22,6 @@ class UserDailyCounter extends Counter
|
||||
public function getContent($id = null)
|
||||
{
|
||||
return [
|
||||
'favorite_count' => 0,
|
||||
'danmu_count' => 0,
|
||||
'consult_count' => 0,
|
||||
'order_count' => 0,
|
||||
|
132
app/Http/Admin/Controllers/GroupController.php
Normal file
132
app/Http/Admin/Controllers/GroupController.php
Normal file
@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Admin\Controllers;
|
||||
|
||||
use App\Http\Admin\Services\ImGroup as ImGroupService;
|
||||
|
||||
/**
|
||||
* @RoutePrefix("/admin/group")
|
||||
*/
|
||||
class GroupController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* @Get("/list", name="admin.group.list")
|
||||
*/
|
||||
public function listAction()
|
||||
{
|
||||
$groupService = new ImGroupService();
|
||||
|
||||
$pager = $groupService->getGroups();
|
||||
|
||||
$this->view->setVar('pager', $pager);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Get("/search", name="admin.group.search")
|
||||
*/
|
||||
public function searchAction()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @Get("/add", name="admin.group.add")
|
||||
*/
|
||||
public function addAction()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @Post("/create", name="admin.group.create")
|
||||
*/
|
||||
public function createAction()
|
||||
{
|
||||
$groupService = new ImGroupService();
|
||||
|
||||
$group = $groupService->createGroup();
|
||||
|
||||
$location = $this->url->get([
|
||||
'for' => 'admin.group.edit',
|
||||
'id' => $group->id,
|
||||
]);
|
||||
|
||||
$content = [
|
||||
'location' => $location,
|
||||
'msg' => '创建群组成功',
|
||||
];
|
||||
|
||||
return $this->jsonSuccess($content);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Get("/{id:[0-9]+}/edit", name="admin.group.edit")
|
||||
*/
|
||||
public function editAction($id)
|
||||
{
|
||||
$groupService = new ImGroupService();
|
||||
|
||||
$group = $groupService->getGroup($id);
|
||||
|
||||
$this->view->setVar('group', $group);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Post("/{id:[0-9]+}/update", name="admin.group.update")
|
||||
*/
|
||||
public function updateAction($id)
|
||||
{
|
||||
$groupService = new ImGroupService();
|
||||
|
||||
$groupService->updateGroup($id);
|
||||
|
||||
$location = $this->url->get(['for' => 'admin.group.list']);
|
||||
|
||||
$content = [
|
||||
'location' => $location,
|
||||
'msg' => '更新群组成功',
|
||||
];
|
||||
|
||||
return $this->jsonSuccess($content);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Post("/{id:[0-9]+}/delete", name="admin.group.delete")
|
||||
*/
|
||||
public function deleteAction($id)
|
||||
{
|
||||
$groupService = new ImGroupService();
|
||||
|
||||
$groupService->deleteGroup($id);
|
||||
|
||||
$location = $this->request->getHTTPReferer();
|
||||
|
||||
$content = [
|
||||
'location' => $location,
|
||||
'msg' => '删除群组成功',
|
||||
];
|
||||
|
||||
return $this->jsonSuccess($content);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Post("/{id:[0-9]+}/restore", name="admin.group.restore")
|
||||
*/
|
||||
public function restoreAction($id)
|
||||
{
|
||||
$groupService = new ImGroupService();
|
||||
|
||||
$groupService->restoreGroup($id);
|
||||
|
||||
$location = $this->request->getHTTPReferer();
|
||||
|
||||
$content = [
|
||||
'location' => $location,
|
||||
'msg' => '还原群组成功',
|
||||
];
|
||||
|
||||
return $this->jsonSuccess($content);
|
||||
}
|
||||
|
||||
}
|
@ -325,6 +325,43 @@ class AuthNode extends Service
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'id' => '2-4',
|
||||
'title' => '群组管理',
|
||||
'type' => 'menu',
|
||||
'children' => [
|
||||
[
|
||||
'id' => '2-4-1',
|
||||
'title' => '群组列表',
|
||||
'type' => 'menu',
|
||||
'route' => 'admin.group.list',
|
||||
],
|
||||
[
|
||||
'id' => '2-4-2',
|
||||
'title' => '搜索群组',
|
||||
'type' => 'menu',
|
||||
'route' => 'admin.group.search',
|
||||
],
|
||||
[
|
||||
'id' => '2-4-3',
|
||||
'title' => '添加群组',
|
||||
'type' => 'menu',
|
||||
'route' => 'admin.group.add',
|
||||
],
|
||||
[
|
||||
'id' => '2-4-4',
|
||||
'title' => '编辑群组',
|
||||
'type' => 'button',
|
||||
'route' => 'admin.group.edit',
|
||||
],
|
||||
[
|
||||
'id' => '2-4-5',
|
||||
'title' => '删除群组',
|
||||
'type' => 'button',
|
||||
'route' => 'admin.group.delete',
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'id' => '2-5',
|
||||
'title' => '轮播管理',
|
||||
|
@ -3,7 +3,7 @@
|
||||
namespace App\Http\Admin\Services;
|
||||
|
||||
use App\Caches\Chapter as ChapterCache;
|
||||
use App\Caches\CourseChapterList as CourseChapterListCache;
|
||||
use App\Caches\CourseCatalog as CourseCatalogCache;
|
||||
use App\Models\Chapter as ChapterModel;
|
||||
use App\Models\ChapterLive as ChapterLiveModel;
|
||||
use App\Models\ChapterRead as ChapterReadModel;
|
||||
@ -166,6 +166,8 @@ class Chapter extends Service
|
||||
|
||||
$this->updateCourseStats($chapter);
|
||||
|
||||
$this->rebuildCatalogCache($chapter);
|
||||
|
||||
return $chapter;
|
||||
}
|
||||
|
||||
@ -185,6 +187,8 @@ class Chapter extends Service
|
||||
|
||||
$this->updateCourseStats($chapter);
|
||||
|
||||
$this->rebuildCatalogCache($chapter);
|
||||
|
||||
return $chapter;
|
||||
}
|
||||
|
||||
@ -200,6 +204,8 @@ class Chapter extends Service
|
||||
|
||||
$this->updateCourseStats($chapter);
|
||||
|
||||
$this->rebuildCatalogCache($chapter);
|
||||
|
||||
return $chapter;
|
||||
}
|
||||
|
||||
@ -240,8 +246,11 @@ class Chapter extends Service
|
||||
$cache = new ChapterCache();
|
||||
|
||||
$cache->rebuild($chapter->id);
|
||||
}
|
||||
|
||||
$cache = new CourseChapterListCache();
|
||||
protected function rebuildCatalogCache(ChapterModel $chapter)
|
||||
{
|
||||
$cache = new CourseCatalogCache();
|
||||
|
||||
$cache->rebuild($chapter->course_id);
|
||||
}
|
||||
|
@ -52,11 +52,11 @@ class Consult extends Service
|
||||
|
||||
$data = [];
|
||||
|
||||
if (isset($post['question'])) {
|
||||
if (!empty($post['question'])) {
|
||||
$data['question'] = $validator->checkQuestion($post['question']);
|
||||
}
|
||||
|
||||
if (isset($post['answer'])) {
|
||||
if (!empty($post['answer'])) {
|
||||
$data['answer'] = $validator->checkAnswer($post['answer']);
|
||||
}
|
||||
|
||||
|
@ -96,6 +96,7 @@ class Course extends Service
|
||||
$imGroup->course_id = $course->id;
|
||||
$imGroup->name = $course->title;
|
||||
$imGroup->about = $course->summary;
|
||||
$imGroup->published = 1;
|
||||
|
||||
if ($imGroup->create() === false) {
|
||||
throw new \RuntimeException('Create ImGroup Failed');
|
||||
|
159
app/Http/Admin/Services/ImGroup.php
Normal file
159
app/Http/Admin/Services/ImGroup.php
Normal file
@ -0,0 +1,159 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Admin\Services;
|
||||
|
||||
use App\Builders\ImGroupList as ImGroupListBuilder;
|
||||
use App\Library\Paginator\Query as PagerQuery;
|
||||
use App\Models\ImGroup as ImGroupModel;
|
||||
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\Validators\ImGroup as ImGroupValidator;
|
||||
|
||||
class ImGroup extends Service
|
||||
{
|
||||
|
||||
public function getGroups()
|
||||
{
|
||||
$pagerQuery = new PagerQuery();
|
||||
|
||||
$params = $pagerQuery->getParams();
|
||||
|
||||
$params['deleted'] = $params['deleted'] ?? 0;
|
||||
|
||||
$sort = $pagerQuery->getSort();
|
||||
$page = $pagerQuery->getPage();
|
||||
$limit = $pagerQuery->getLimit();
|
||||
|
||||
$groupRepo = new ImGroupRepo();
|
||||
|
||||
$pager = $groupRepo->paginate($params, $sort, $page, $limit);
|
||||
|
||||
return $this->handleGroups($pager);
|
||||
}
|
||||
|
||||
public function getGroup($id)
|
||||
{
|
||||
return $this->findOrFail($id);
|
||||
}
|
||||
|
||||
public function createGroup()
|
||||
{
|
||||
$post = $this->request->getPost();
|
||||
|
||||
$validator = new ImGroupValidator();
|
||||
|
||||
$data = [];
|
||||
|
||||
$data['name'] = $validator->checkName($post['name']);
|
||||
$data['about'] = $validator->checkAbout($post['about']);
|
||||
$data['type'] = $validator->checkType($post['type']);
|
||||
|
||||
$group = new ImGroupModel();
|
||||
|
||||
$group->create($data);
|
||||
|
||||
return $group;
|
||||
}
|
||||
|
||||
public function updateGroup($id)
|
||||
{
|
||||
$group = $this->findOrFail($id);
|
||||
|
||||
$post = $this->request->getPost();
|
||||
|
||||
$validator = new ImGroupValidator();
|
||||
|
||||
$data = [];
|
||||
|
||||
if (isset($post['name'])) {
|
||||
$data['name'] = $validator->checkName($post['name']);
|
||||
}
|
||||
|
||||
if (isset($post['about'])) {
|
||||
$data['about'] = $validator->checkAbout($post['about']);
|
||||
}
|
||||
|
||||
if (isset($post['avatar'])) {
|
||||
$data['avatar'] = $validator->checkAvatar($post['avatar']);
|
||||
}
|
||||
|
||||
if (isset($post['published'])) {
|
||||
$data['published'] = $validator->checkPublishStatus($post['published']);
|
||||
}
|
||||
|
||||
if (isset($post['owner_id'])) {
|
||||
$owner = $validator->checkGroupOwner($post['owner_id']);
|
||||
$data['owner_id'] = $owner->id;
|
||||
$this->handleGroupOwner($group, $owner);
|
||||
}
|
||||
|
||||
$group->update($data);
|
||||
|
||||
return $group;
|
||||
}
|
||||
|
||||
public function deleteGroup($id)
|
||||
{
|
||||
$group = $this->findOrFail($id);
|
||||
|
||||
$group->deleted = 1;
|
||||
|
||||
$group->update();
|
||||
|
||||
return $group;
|
||||
}
|
||||
|
||||
public function restoreGroup($id)
|
||||
{
|
||||
$group = $this->findOrFail($id);
|
||||
|
||||
$group->deleted = 0;
|
||||
|
||||
$group->update();
|
||||
|
||||
return $group;
|
||||
}
|
||||
|
||||
protected function handleGroupOwner(ImGroupModel $group, UserModel $user)
|
||||
{
|
||||
$repo = new ImGroupUserRepo();
|
||||
|
||||
$groupUser = $repo->findGroupUser($group->id, $user->id);
|
||||
|
||||
if ($groupUser) return;
|
||||
|
||||
$groupUser = new ImGroupUserModel();
|
||||
$groupUser->group_id = $group->id;
|
||||
$groupUser->user_id = $user->id;
|
||||
$groupUser->create();
|
||||
|
||||
$group->user_count += 1;
|
||||
$group->update();
|
||||
}
|
||||
|
||||
protected function handleGroups($pager)
|
||||
{
|
||||
if ($pager->total_items > 0) {
|
||||
|
||||
$builder = new ImGroupListBuilder();
|
||||
|
||||
$pipeA = $pager->items->toArray();
|
||||
$pipeB = $builder->handleUsers($pipeA);
|
||||
$pipeC = $builder->objects($pipeB);
|
||||
|
||||
$pager->items = $pipeC;
|
||||
}
|
||||
|
||||
return $pager;
|
||||
}
|
||||
|
||||
protected function findOrFail($id)
|
||||
{
|
||||
$validator = new ImGroupValidator();
|
||||
|
||||
return $validator->checkGroup($id);
|
||||
}
|
||||
|
||||
}
|
@ -52,7 +52,7 @@
|
||||
<td><span class="layui-badge layui-bg-gray">{{ item.level }}</span></td>
|
||||
<td><span class="layui-badge layui-bg-gray">{{ item.child_count }}</span></td>
|
||||
<td><span class="layui-badge layui-bg-gray">{{ item.course_count }}</span></td>
|
||||
<td><input class="layui-input kg-priority-input" type="text" name="priority" title="数值越小排序越靠前" value="{{ item.priority }}" data-url="{{ url({'for':'admin.category.update','id':item.id}) }}"></td>
|
||||
<td><input class="layui-input kg-priority" type="text" name="priority" title="数值越小排序越靠前" value="{{ item.priority }}" data-url="{{ url({'for':'admin.category.update','id':item.id}) }}"></td>
|
||||
<td><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否" lay-filter="published" data-url="{{ url({'for':'admin.category.update','id':item.id}) }}" {% if item.published == 1 %}checked{% endif %}></td>
|
||||
<td align="center">
|
||||
<div class="layui-dropdown">
|
||||
|
@ -34,7 +34,7 @@
|
||||
<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="true">
|
||||
<input type="radio" name="free" value="0" title="否" checked="checked">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -24,8 +24,8 @@
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">免费</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="free" value="1" title="是" {% if chapter.free == 1 %}checked="true"{% endif %}>
|
||||
<input type="radio" name="free" value="0" title="否" {% if chapter.free == 0 %}checked="true"{% endif %}>
|
||||
<input type="radio" name="free" value="1" title="是" {% if chapter.free == 1 %}checked="checked"{% endif %}>
|
||||
<input type="radio" name="free" value="0" title="否" {% if chapter.free == 0 %}checked="checked"{% endif %}>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
{% for item in play_urls %}
|
||||
<tr>
|
||||
<td>{{ item.format }}</td>
|
||||
<td>{{ item.duration|play_duration }}</td>
|
||||
<td>{{ item.duration|duration }}</td>
|
||||
<td>{{ item.width }} x {{ item.height }}</td>
|
||||
<td>{{ item.rate }}kbps</td>
|
||||
<td>{{ item.size }}M</td>
|
||||
|
@ -37,7 +37,7 @@
|
||||
<span class="layui-badge layui-bg-green">课</span>
|
||||
</td>
|
||||
<td>{{ live_time_info(item.attrs) }}</td>
|
||||
<td><input class="layui-input kg-priority-input" type="text" name="priority" title="数值越小排序越靠前" value="{{ item.priority }}" data-url="{{ url({'for':'admin.chapter.update','id':item.id}) }}"></td>
|
||||
<td><input class="layui-input kg-priority" type="text" name="priority" title="数值越小排序越靠前" value="{{ item.priority }}" data-url="{{ url({'for':'admin.chapter.update','id':item.id}) }}"></td>
|
||||
<td><input type="checkbox" name="free" value="1" lay-skin="switch" lay-text="是|否" lay-filter="free" data-url="{{ url({'for':'admin.chapter.update','id':item.id}) }}" {% if item.free == 1 %}checked{% endif %}></td>
|
||||
<td><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否" lay-filter="published" data-url="{{ url({'for':'admin.chapter.update','id':item.id}) }}" {% if item.published == 1 %}checked{% endif %}></td>
|
||||
<td align="center">
|
||||
|
@ -28,7 +28,7 @@
|
||||
<span class="layui-badge layui-bg-green">课</span>
|
||||
</td>
|
||||
<td><span class="layui-badge layui-bg-gray">{{ item.attrs['word_count'] }}</span></td>
|
||||
<td><input class="layui-input kg-priority-input" type="text" name="priority" title="数值越小排序越靠前" value="{{ item.priority }}" data-url="{{ url({'for':'admin.chapter.update','id':item.id}) }}"></td>
|
||||
<td><input class="layui-input kg-priority" type="text" name="priority" title="数值越小排序越靠前" value="{{ item.priority }}" data-url="{{ url({'for':'admin.chapter.update','id':item.id}) }}"></td>
|
||||
<td><input type="checkbox" name="free" value="1" lay-skin="switch" lay-text="是|否" lay-filter="free" data-url="{{ url({'for':'admin.chapter.update','id':item.id}) }}" {% if item.free == 1 %}checked{% endif %}></td>
|
||||
<td><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否" lay-filter="published" data-url="{{ url({'for':'admin.chapter.update','id':item.id}) }}" {% if item.published == 1 %}checked{% endif %}></td>
|
||||
<td align="center">
|
||||
|
@ -44,8 +44,8 @@
|
||||
<span class="layui-badge layui-bg-green">课</span>
|
||||
</td>
|
||||
<td>{{ file_status(item.attrs['file_status']) }}</td>
|
||||
<td>{{ item.attrs['duration']|play_duration }}</td>
|
||||
<td><input class="layui-input kg-priority-input" type="text" name="priority" title="数值越小排序越靠前" value="{{ item.priority }}" data-url="{{ url({'for':'admin.chapter.update','id':item.id}) }}"></td>
|
||||
<td>{{ item.attrs['duration']|duration }}</td>
|
||||
<td><input class="layui-input kg-priority" type="text" name="priority" title="数值越小排序越靠前" value="{{ item.priority }}" data-url="{{ url({'for':'admin.chapter.update','id':item.id}) }}"></td>
|
||||
<td><input type="checkbox" name="free" value="1" lay-skin="switch" lay-text="是|否" lay-filter="free" data-url="{{ url({'for':'admin.chapter.update','id':item.id}) }}" {% if item.free == 1 %}checked{% endif %}></td>
|
||||
<td><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否" lay-filter="published" data-url="{{ url({'for':'admin.chapter.update','id':item.id}) }}" {% if item.published == 1 %}checked{% endif %}></td>
|
||||
<td align="center">
|
||||
|
@ -14,23 +14,23 @@
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">回复</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="answer" class="layui-textarea" lay-verify="required">{{ consult.answer }}</textarea>
|
||||
<textarea name="answer" class="layui-textarea">{{ consult.answer }}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">私密</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="private" value="1" title="是" {% if consult.private == 1 %}checked="true"{% endif %}>
|
||||
<input type="radio" name="private" value="0" title="否" {% if consult.private == 0 %}checked="true"{% endif %}>
|
||||
<input type="radio" name="private" value="1" title="是" {% if consult.private == 1 %}checked="checked"{% endif %}>
|
||||
<input type="radio" name="private" value="0" title="否" {% if consult.private == 0 %}checked="checked"{% endif %}>
|
||||
</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="是" {% if consult.published == 1 %}checked="true"{% endif %}>
|
||||
<input type="radio" name="published" value="0" title="否" {% if consult.published == 0 %}checked="true"{% endif %}>
|
||||
<input type="radio" name="published" value="1" title="是" {% if consult.published == 1 %}checked="checked"{% endif %}>
|
||||
<input type="radio" name="published" value="0" title="否" {% if consult.published == 0 %}checked="checked"{% endif %}>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -49,8 +49,8 @@
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
<p>昵称:{{ item.user.name }}</p>
|
||||
<p>编号:{{ item.user.id }}</p>
|
||||
<p>昵称:{{ item.owner.name }}</p>
|
||||
<p>编号:{{ item.owner.id }}</p>
|
||||
</td>
|
||||
<td>{{ date('Y-m-d H:i:s',item.create_time) }}</td>
|
||||
<td><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否" lay-filter="published" data-url="{{ url({'for':'admin.consult.update','id':item.id}) }}" {% if item.published == 1 %}checked{% endif %}></td>
|
||||
|
@ -21,7 +21,7 @@
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">用户编号</label>
|
||||
<div class="layui-input-block">
|
||||
<input class="layui-input" type="text" name="author_id" placeholder="用户编号精确匹配">
|
||||
<input class="layui-input" type="text" name="owner_id" placeholder="用户编号精确匹配">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -42,7 +42,7 @@
|
||||
<span class="layui-badge layui-bg-green">{{ item.lesson_count }}</span>
|
||||
</a>
|
||||
</td>
|
||||
<td><input class="layui-input kg-priority-input" type="text" name="priority" value="{{ item.priority }}" data-url="{{ url({'for':'admin.chapter.update','id':item.id}) }}"></td>
|
||||
<td><input class="layui-input kg-priority" type="text" name="priority" value="{{ item.priority }}" data-url="{{ url({'for':'admin.chapter.update','id':item.id}) }}"></td>
|
||||
<td align="center">
|
||||
<div class="layui-dropdown">
|
||||
<button class="layui-btn layui-btn-sm">操作 <span class="layui-icon layui-icon-triangle-d"></span></button>
|
||||
|
@ -11,9 +11,9 @@
|
||||
<label class="layui-form-label">封面</label>
|
||||
<div class="layui-input-inline">
|
||||
{% if course.cover %}
|
||||
<img id="cover-img" class="kg-cover" src="{{ course.cover }}">
|
||||
<img id="img-cover" class="kg-cover" src="{{ course.cover }}">
|
||||
{% else %}
|
||||
{{ image('id':'cover-img','class':'kg-cover','src':'admin/img/default_cover.png') }}
|
||||
{{ image('id':'img-cover','class':'kg-cover','src':'admin/img/default_cover.png') }}
|
||||
{% endif %}
|
||||
<input type="hidden" name="cover" value="{{ course.cover }}">
|
||||
</div>
|
||||
|
37
app/Http/Admin/Views/group/add.volt
Normal file
37
app/Http/Admin/Views/group/add.volt
Normal file
@ -0,0 +1,37 @@
|
||||
<form class="layui-form kg-form" method="POST" action="{{ url({'for':'admin.group.create'}) }}">
|
||||
|
||||
<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="name" lay-verify="required">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">简介</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea class="layui-textarea" name="about"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">类型</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="type" value="course" title="课程" disabled="disabled">
|
||||
<input type="radio" name="type" value="chat" title="聊天" checked="checked">
|
||||
</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" lay-filter="go">提交</button>
|
||||
<button type="button" class="kg-back layui-btn layui-btn-primary">返回</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
61
app/Http/Admin/Views/group/edit.volt
Normal file
61
app/Http/Admin/Views/group/edit.volt
Normal file
@ -0,0 +1,61 @@
|
||||
<form class="layui-form kg-form" method="POST" action="{{ url({'for':'admin.group.update','id':group.id}) }}">
|
||||
|
||||
<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-inline" style="width: 110px;">
|
||||
{% if group.avatar %}
|
||||
<img id="img-cover" class="kg-avatar" src="{{ group.avatar }}">
|
||||
{% else %}
|
||||
{{ image('id':'img-cover','class':'kg-cover','src':'admin/img/default_cover.png') }}
|
||||
{% endif %}
|
||||
<input type="hidden" name="cover" value="{{ group.avatar }}">
|
||||
</div>
|
||||
<div class="layui-input-inline" style="padding-top:35px;">
|
||||
<a href="javascript:" class="layui-btn layui-btn-sm" id="choose-cover">编辑</a>
|
||||
</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="name" value="{{ group.name }}" lay-verify="required">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">简介</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea class="layui-textarea" name="about">{{ group.about }}</textarea>
|
||||
</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="owner_id" value="{{ group.owner_id }}" lay-verify="number">
|
||||
</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="是" {% if group.published == 1 %}checked{% endif %}>
|
||||
<input type="radio" name="published" value="0" title="否" {% if group.published == 0 %}checked{% endif %}>
|
||||
</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" lay-filter="go">提交</button>
|
||||
<button type="button" class="kg-back layui-btn layui-btn-primary">返回</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
{{ partial('partials/cover_uploader') }}
|
63
app/Http/Admin/Views/group/list.volt
Normal file
63
app/Http/Admin/Views/group/list.volt
Normal file
@ -0,0 +1,63 @@
|
||||
{%- macro owner_info(owner) %}
|
||||
{% if owner %}
|
||||
{{ owner.name }}({{ owner.id }})
|
||||
{% else %}
|
||||
未设置
|
||||
{% endif %}
|
||||
{%- endmacro %}
|
||||
|
||||
<div class="kg-nav">
|
||||
<div class="kg-nav-left">
|
||||
<span class="layui-breadcrumb">
|
||||
<a><cite>群组管理</cite></a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="kg-nav-right">
|
||||
<a class="layui-btn layui-btn-sm" href="{{ url({'for':'admin.group.add'}) }}">
|
||||
<i class="layui-icon layui-icon-add-1"></i>添加群组
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="kg-table layui-table layui-form">
|
||||
<colgroup>
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
<col width="12%">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>编号</th>
|
||||
<th>名称</th>
|
||||
<th>群主</th>
|
||||
<th>成员</th>
|
||||
<th>发布</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for item in pager.items %}
|
||||
<tr>
|
||||
<td>{{ item.id }}</td>
|
||||
<td>{{ item.name }}</td>
|
||||
<td>{{ owner_info(item.owner) }}</td>
|
||||
<td><span class="layui-badge layui-bg-gray">{{ item.user_count }}</span></td>
|
||||
<td><input type="checkbox" name="published" value="1" lay-filter="published" lay-skin="switch" lay-text="是|否" data-url="{{ url({'for':'admin.group.update','id':item.id}) }}" {% if item.published == 1 %}checked{% endif %}></td>
|
||||
<td align="center">
|
||||
<div class="layui-dropdown">
|
||||
<button class="layui-btn layui-btn-sm">操作 <span class="layui-icon layui-icon-triangle-d"></span></button>
|
||||
<ul>
|
||||
<li><a href="{{ url({'for':'admin.group.edit','id':item.id}) }}">编辑</a></li>
|
||||
<li><a href="javascript:" class="kg-delete" data-url="{{ url({'for':'admin.group.delete','id':item.id}) }}">删除</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{{ partial('partials/pager') }}
|
67
app/Http/Admin/Views/group/search.volt
Normal file
67
app/Http/Admin/Views/group/search.volt
Normal file
@ -0,0 +1,67 @@
|
||||
<form class="layui-form kg-form" method="GET" action="{{ url({'for':'admin.group.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="name" 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="user_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="course_id" placeholder="课程编号精确匹配">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">类型</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="type" value="course" title="课程">
|
||||
<input type="radio" name="type" value="chat" title="聊天">
|
||||
</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>
|
@ -39,7 +39,7 @@
|
||||
<td>{{ item.title }}</td>
|
||||
<td>{{ date('Y-m-d H:i',item.create_time) }}</td>
|
||||
<td>{{ date('Y-m-d H:i',item.update_time) }}</td>
|
||||
<td><input class="layui-input kg-priority-input" type="text" name="priority" title="数值越小排序越靠前" value="{{ item.priority }}" data-url="{{ url({'for':'admin.help.update','id':item.id}) }}"></td>
|
||||
<td><input class="layui-input kg-priority" type="text" name="priority" title="数值越小排序越靠前" value="{{ item.priority }}" data-url="{{ url({'for':'admin.help.update','id':item.id}) }}"></td>
|
||||
<td><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否" lay-filter="published" data-url="{{ url({'for':'admin.help.update','id':item.id}) }}" {% if item.published == 1 %}checked{% endif %}>
|
||||
</td>
|
||||
<td align="center">
|
||||
|
@ -71,7 +71,7 @@
|
||||
<td><span class="layui-badge layui-bg-gray">{{ item.child_count }}</span></td>
|
||||
<td>{{ position_info(item.position) }}</td>
|
||||
<td>{{ target_info(item.target) }}</td>
|
||||
<td><input class="layui-input kg-priority-input" type="text" name="priority" title="数值越小排序越靠前" value="{{ item.priority }}" data-url="{{ url({'for':'admin.nav.update','id':item.id}) }}"></td>
|
||||
<td><input class="layui-input kg-priority" type="text" name="priority" title="数值越小排序越靠前" value="{{ item.priority }}" data-url="{{ url({'for':'admin.nav.update','id':item.id}) }}"></td>
|
||||
<td><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否" lay-filter="published" data-url="{{ url({'for':'admin.nav.update','id':item.id}) }}" {% if item.published == 1 %}checked{% endif %}></td>
|
||||
<td align="center">
|
||||
<div class="layui-dropdown">
|
||||
|
@ -15,7 +15,7 @@
|
||||
layer.load();
|
||||
},
|
||||
done: function (res, index, upload) {
|
||||
$('#cover-img').attr('src', res.data.src);
|
||||
$('#img-cover').attr('src', res.data.src);
|
||||
$('input[name=cover]').val(res.data.src);
|
||||
layer.closeAll('loading');
|
||||
},
|
||||
|
@ -1,8 +1,10 @@
|
||||
{% if pager.total_pages > 1 %}
|
||||
<div class="layui-box layui-laypage layui-laypage-default">
|
||||
<a href="{{ pager.first }}">首页</a>
|
||||
<a href="{{ pager.previous }}">上页</a>
|
||||
<a href="{{ pager.next }}">下页</a>
|
||||
<a href="{{ pager.last }}">尾页</a>
|
||||
<div class="kg-pager">
|
||||
<div class="layui-box layui-laypage layui-laypage-default">
|
||||
<a href="{{ pager.first }}">首页</a>
|
||||
<a href="{{ pager.previous }}">上页</a>
|
||||
<a href="{{ pager.next }}">下页</a>
|
||||
<a href="{{ pager.last }}">尾页</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
@ -22,8 +22,8 @@
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">发布</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="published" value="1" title="是" {% if review.published == 1 %}checked="true"{% endif %}>
|
||||
<input type="radio" name="published" value="0" title="否" {% if review.published == 0 %}checked="true"{% endif %}>
|
||||
<input type="radio" name="published" value="1" title="是" {% if review.published == 1 %}checked="checked"{% endif %}>
|
||||
<input type="radio" name="published" value="0" title="否" {% if review.published == 0 %}checked="checked"{% endif %}>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -41,8 +41,8 @@
|
||||
<p>评价:<a href="javascript:" title="{{ item.content }}">{{ substr(item.content,0,30) }}</a></p>
|
||||
</td>
|
||||
<td>
|
||||
<p>昵称:{{ item.user.name }}</p>
|
||||
<p>编号:{{ item.user.id }}</p>
|
||||
<p>昵称:{{ item.owner.name }}</p>
|
||||
<p>编号:{{ item.owner.id }}</p>
|
||||
</td>
|
||||
<td>{{ date('Y-m-d H:i:s',item.create_time) }}</td>
|
||||
<td><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否" lay-filter="published" data-url="{{ url({'for':'admin.review.update','id':item.id}) }}" {% if item.published == 1 %}checked{% endif %}></td>
|
||||
|
@ -21,7 +21,7 @@
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">用户编号</label>
|
||||
<div class="layui-input-block">
|
||||
<input class="layui-input" type="text" name="author_id" placeholder="用户编号精确匹配">
|
||||
<input class="layui-input" type="text" name="owner_id" placeholder="用户编号精确匹配">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -18,9 +18,9 @@
|
||||
<label class="layui-form-label">封面</label>
|
||||
<div class="layui-input-inline">
|
||||
{% if slide.cover %}
|
||||
<img id="cover-img" class="kg-cover" src="{{ slide.cover }}">
|
||||
<img id="img-cover" class="kg-cover" src="{{ slide.cover }}">
|
||||
{% else %}
|
||||
{{ image('id':'cover-img','class':'kg-cover','src':'admin/img/default_cover.png') }}
|
||||
{{ image('id':'img-cover','class':'kg-cover','src':'admin/img/default_cover.png') }}
|
||||
{% endif %}
|
||||
<input type="hidden" name="cover" value="{{ slide.cover }}">
|
||||
</div>
|
||||
|
@ -46,8 +46,8 @@
|
||||
<td>{{ item.id }}</td>
|
||||
<td>{{ item.title }}</td>
|
||||
<td>{{ target_info(item.target) }}</td>
|
||||
<td><input class="layui-input kg-priority-input" type="text" name="priority" title="数值越小排序越靠前" value="{{ item.priority }}" data-url="{{ url({'for':'admin.slide.update','id':item.id}) }}"></td>
|
||||
<td><input type="checkbox" name="published" value="1" lay-filter="switch-published" lay-skin="switch" lay-text="是|否" data-url="{{ url({'for':'admin.slide.update','id':item.id}) }}" {% if item.published == 1 %}checked{% endif %}></td>
|
||||
<td><input class="layui-input kg-priority" type="text" name="priority" title="数值越小排序越靠前" value="{{ item.priority }}" data-url="{{ url({'for':'admin.slide.update','id':item.id}) }}"></td>
|
||||
<td><input type="checkbox" name="published" value="1" lay-filter="published" lay-skin="switch" lay-text="是|否" data-url="{{ url({'for':'admin.slide.update','id':item.id}) }}" {% if item.published == 1 %}checked{% endif %}></td>
|
||||
<td align="center">
|
||||
<div class="layui-dropdown">
|
||||
<button class="layui-btn layui-btn-sm">操作 <span class="layui-icon layui-icon-triangle-d"></span></button>
|
||||
|
@ -4,10 +4,9 @@ namespace App\Http\Web\Controllers;
|
||||
|
||||
use App\Services\Frontend\Chapter\ChapterInfo as ChapterInfoService;
|
||||
use App\Services\Frontend\Chapter\ChapterLike as ChapterLikeService;
|
||||
use App\Services\Frontend\Chapter\CommentList as ChapterCommentListService;
|
||||
use App\Services\Frontend\Chapter\DanmuList as ChapterDanmuListService;
|
||||
use App\Services\Frontend\Chapter\Learning as ChapterLearningService;
|
||||
use App\Services\Frontend\Course\ChapterList as CourseChapterListService;
|
||||
use App\Services\Frontend\Course\ChapterList as CourseCatalogService;
|
||||
|
||||
/**
|
||||
* @RoutePrefix("/chapter")
|
||||
@ -33,7 +32,7 @@ class ChapterController extends Controller
|
||||
]);
|
||||
}
|
||||
|
||||
$service = new CourseChapterListService();
|
||||
$service = new CourseCatalogService();
|
||||
|
||||
$contents = $service->handle($chapter['course']['id']);
|
||||
|
||||
@ -65,18 +64,6 @@ class ChapterController extends Controller
|
||||
return $this->jsonSuccess(['items' => $items]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Get("/{id:[0-9]+}/comments", name="web.chapter.comments")
|
||||
*/
|
||||
public function commentsAction($id)
|
||||
{
|
||||
$service = new ChapterCommentListService();
|
||||
|
||||
$comments = $service->handle($id);
|
||||
|
||||
return $this->jsonSuccess(['comments' => $comments]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Post("/{id:[0-9]+}/like", name="web.chapter.like")
|
||||
*/
|
||||
@ -84,9 +71,13 @@ class ChapterController extends Controller
|
||||
{
|
||||
$service = new ChapterLikeService();
|
||||
|
||||
$service->handle($id);
|
||||
$like = $service->handle($id);
|
||||
|
||||
return $this->jsonSuccess();
|
||||
$msg = $like->deleted == 0 ? '点赞成功' : '取消点赞成功';
|
||||
|
||||
$content = ['msg' => $msg];
|
||||
|
||||
return $this->jsonSuccess($content);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -6,6 +6,7 @@ use App\Services\Frontend\Consult\ConsultCreate as ConsultCreateService;
|
||||
use App\Services\Frontend\Consult\ConsultDelete as ConsultDeleteService;
|
||||
use App\Services\Frontend\Consult\ConsultInfo as ConsultInfoService;
|
||||
use App\Services\Frontend\Consult\ConsultLike as ConsultLikeService;
|
||||
use App\Services\Frontend\Consult\ConsultRating as ConsultRatingService;
|
||||
use App\Services\Frontend\Consult\ConsultUpdate as ConsultUpdateService;
|
||||
use Phalcon\Mvc\View;
|
||||
|
||||
@ -108,9 +109,27 @@ class ConsultController extends Controller
|
||||
{
|
||||
$service = new ConsultLikeService();
|
||||
|
||||
$like = $service->handle($id);
|
||||
|
||||
$msg = $like->deleted == 0 ? '点赞成功' : '取消点赞成功';
|
||||
|
||||
$content = ['msg' => $msg];
|
||||
|
||||
return $this->jsonSuccess($content);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Post("/{id:[0-9]+}/rating", name="web.consult.rating")
|
||||
*/
|
||||
public function ratingAction($id)
|
||||
{
|
||||
$service = new ConsultRatingService();
|
||||
|
||||
$service->handle($id);
|
||||
|
||||
return $this->jsonSuccess();
|
||||
$content = ['msg' => '评价成功'];
|
||||
|
||||
return $this->jsonSuccess($content);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
namespace App\Http\Web\Controllers;
|
||||
|
||||
use App\Http\Web\Services\CourseQuery as CourseQueryService;
|
||||
use App\Services\Frontend\Course\ChapterList as CourseChapterListService;
|
||||
use App\Services\Frontend\Course\ChapterList as CourseCatalogService;
|
||||
use App\Services\Frontend\Course\ConsultList as CourseConsultListService;
|
||||
use App\Services\Frontend\Course\CourseInfo as CourseInfoService;
|
||||
use App\Services\Frontend\Course\CourseList as CourseListService;
|
||||
@ -102,7 +102,7 @@ class CourseController extends Controller
|
||||
*/
|
||||
public function chaptersAction($id)
|
||||
{
|
||||
$service = new CourseChapterListService();
|
||||
$service = new CourseCatalogService();
|
||||
|
||||
$chapters = $service->handle($id);
|
||||
|
||||
@ -206,9 +206,11 @@ class CourseController extends Controller
|
||||
{
|
||||
$service = new CourseFavoriteService();
|
||||
|
||||
$service->handle($id);
|
||||
$favorite = $service->handle($id);
|
||||
|
||||
return $this->jsonSuccess(['msg' => '收藏课程成功']);
|
||||
$msg = $favorite->deleted == 0 ? '收藏成功' : '取消收藏成功';
|
||||
|
||||
return $this->jsonSuccess(['msg' => $msg]);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ namespace App\Http\Web\Controllers;
|
||||
use App\Services\Frontend\My\AccountInfo as AccountInfoService;
|
||||
use App\Services\Frontend\My\ConsultList as MyConsultListService;
|
||||
use App\Services\Frontend\My\CourseList as MyCourseListService;
|
||||
use App\Services\Frontend\My\FavoriteList as MyFavoriteListService;
|
||||
use App\Services\Frontend\My\ImFriendDelete as MyFriendDeleteService;
|
||||
use App\Services\Frontend\My\ImGroupDelete as MyGroupDeleteService;
|
||||
use App\Services\Frontend\My\OrderList as MyOrderListService;
|
||||
@ -84,10 +85,12 @@ class MyController extends Controller
|
||||
*/
|
||||
public function favoritesAction()
|
||||
{
|
||||
$service = new MyConsultListService();
|
||||
$service = new MyFavoriteListService();
|
||||
|
||||
$pager = $service->handle();
|
||||
|
||||
$pager->items = kg_array_object($pager->items);
|
||||
|
||||
$this->view->setVar('pager', $pager);
|
||||
}
|
||||
|
||||
|
@ -111,9 +111,13 @@ class ReviewController extends Controller
|
||||
{
|
||||
$service = new ReviewLikeService();
|
||||
|
||||
$service->handle($id);
|
||||
$like = $service->handle($id);
|
||||
|
||||
return $this->jsonSuccess();
|
||||
$msg = $like->deleted == 0 ? '点赞成功' : '取消点赞成功';
|
||||
|
||||
$content = ['msg' => $msg];
|
||||
|
||||
return $this->jsonSuccess($content);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -64,12 +64,16 @@ Trait ImFriendTrait
|
||||
$friendUser = $friendUserRepo->findFriendUser($user->id, $sender->id);
|
||||
|
||||
if (!$friendUser) {
|
||||
|
||||
$friendUserModel = new ImFriendUserModel();
|
||||
|
||||
$friendUserModel->create([
|
||||
'user_id' => $user->id,
|
||||
'friend_id' => $sender->id,
|
||||
'group_id' => $groupId,
|
||||
]);
|
||||
|
||||
$this->incrUserFriendCount($user);
|
||||
}
|
||||
|
||||
$friendUser = $friendUserRepo->findFriendUser($sender->id, $user->id);
|
||||
@ -77,12 +81,16 @@ Trait ImFriendTrait
|
||||
$groupId = $message->item_info['group']['id'] ?: 0;
|
||||
|
||||
if (!$friendUser) {
|
||||
|
||||
$friendUserModel = new ImFriendUserModel();
|
||||
|
||||
$friendUserModel->create([
|
||||
'user_id' => $sender->id,
|
||||
'friend_id' => $user->id,
|
||||
'group_id' => $groupId,
|
||||
]);
|
||||
|
||||
$this->incrUserFriendCount($sender);
|
||||
}
|
||||
|
||||
$itemInfo = $message->item_info;
|
||||
@ -245,4 +253,18 @@ Trait ImFriendTrait
|
||||
}
|
||||
}
|
||||
|
||||
protected function incrUserFriendCount(ImUserModel $user)
|
||||
{
|
||||
$user->friend_count += 1;
|
||||
$user->update();
|
||||
}
|
||||
|
||||
protected function decrUserFriendCount(ImUserModel $user)
|
||||
{
|
||||
if ($user->friend_count > 0) {
|
||||
$user->friend_count -= 1;
|
||||
$user->update();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -67,13 +67,17 @@ Trait ImGroupTrait
|
||||
$groupUser = $groupUserRepo->findGroupUser($group->id, $applicant->id);
|
||||
|
||||
if (!$groupUser) {
|
||||
|
||||
$groupUserModel = new ImGroupUserModel();
|
||||
|
||||
$groupUserModel->create([
|
||||
'group_id' => $group->id,
|
||||
'user_id' => $applicant->id,
|
||||
]);
|
||||
$group->user_count += 1;
|
||||
$group->update();
|
||||
|
||||
$this->incrGroupUserCount($group);
|
||||
|
||||
$this->incrUserGroupCount($applicant);
|
||||
}
|
||||
|
||||
$itemInfo = $message->item_info;
|
||||
@ -264,4 +268,32 @@ Trait ImGroupTrait
|
||||
}
|
||||
}
|
||||
|
||||
protected function incrUserGroupCount(ImUserModel $user)
|
||||
{
|
||||
$user->group_count += 1;
|
||||
$user->update();
|
||||
}
|
||||
|
||||
protected function decrUserGroupCount(ImUserModel $user)
|
||||
{
|
||||
if ($user->group_count > 0) {
|
||||
$user->group_count -= 1;
|
||||
$user->update();
|
||||
}
|
||||
}
|
||||
|
||||
protected function incrGroupUserCount(ImGroupModel $group)
|
||||
{
|
||||
$group->user_count += 1;
|
||||
$group->update();
|
||||
}
|
||||
|
||||
protected function decrGroupUserCount(ImGroupModel $group)
|
||||
{
|
||||
if ($group->user_count > 0) {
|
||||
$group->user_count -= 1;
|
||||
$group->update();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
{% block content %}
|
||||
<form class="layui-form" method="post" action="{{ url({'for':'web.consult.create'}) }}">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">咨询内容</label>
|
||||
<label class="layui-form-label">问题</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="question" class="layui-textarea" placeholder="请详细描述问题,我们会尽快回复您" lay-verify="required"></textarea>
|
||||
</div>
|
||||
|
@ -14,7 +14,7 @@
|
||||
<div class="layui-form-mid">{{ consult.chapter.title }}</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">咨询内容</label>
|
||||
<label class="layui-form-label">问题</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="question" class="layui-textarea" lay-verify="required">{{ consult.question }}</textarea>
|
||||
</div>
|
||||
@ -34,4 +34,5 @@
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
@ -1,27 +1,60 @@
|
||||
{% extends 'templates/layer.volt' %}
|
||||
|
||||
{% block content %}
|
||||
<form class="layui-form" method="post" action="{{ url({'for':'web.consult.create'}) }}">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">咨询内容</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="question" class="layui-textarea" placeholder="请详细描述问题,我们会尽快回复您" lay-verify="required"></textarea>
|
||||
</div>
|
||||
|
||||
{% set rating_url = url({'for':'web.consult.rating','id':consult.id}) %}
|
||||
{% set answer = consult.answer ? consult.answer : '<span class="gray">稍安勿燥,请耐心等待回复吧</span>' %}
|
||||
|
||||
<form class="layui-form review-form">
|
||||
<div class="layui-form-item mb0">
|
||||
<label class="layui-form-label">课程:</label>
|
||||
<div class="layui-form-mid">{{ consult.course.title }}</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">私密问题</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="private" value="1" title="是">
|
||||
<input type="radio" name="private" value="0" title="否" checked="checked">
|
||||
</div>
|
||||
<div class="layui-form-item mb0">
|
||||
<label class="layui-form-label">章节:</label>
|
||||
<div class="layui-form-mid">{{ consult.chapter.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" lay-filter="go">提交</button>
|
||||
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
|
||||
<input type="hidden" name="chapter_id" value="{{ request.get('chapter_id') }}">
|
||||
</div>
|
||||
<div class="layui-form-item mb0">
|
||||
<label class="layui-form-label">提问:</label>
|
||||
<div class="layui-form-mid">{{ consult.question }}</div>
|
||||
</div>
|
||||
<div class="layui-form-item mb0">
|
||||
<label class="layui-form-label">回复:</label>
|
||||
<div class="layui-form-mid">{{ answer }}</div>
|
||||
</div>
|
||||
{% if consult.answer %}
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">评分:</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="hidden" name="rating" value="{{ consult.rating }}">
|
||||
<input type="hidden" name="rating_url" value="{{ rating_url }}">
|
||||
<div id="rating"></div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block inline_js %}
|
||||
|
||||
<script>
|
||||
layui.use(['jquery', 'layer', 'rate'], function () {
|
||||
var $ = layui.jquery;
|
||||
var layer = layui.layer;
|
||||
var rate = layui.rate;
|
||||
var rating = $('input[name=rating]').val();
|
||||
var ratingUrl = $('input[name=rating_url]').val();
|
||||
rate.render({
|
||||
elem: '#rating',
|
||||
value: rating,
|
||||
choose: function (value) {
|
||||
$.post(ratingUrl, {rating: value}, function () {
|
||||
layer.msg('评价成功');
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
@ -1,17 +1,21 @@
|
||||
{{ partial('partials/macro_course') }}
|
||||
|
||||
{% if pager.total_pages > 0 %}
|
||||
<div class="review-list">
|
||||
{% for item in pager.items %}
|
||||
{% set user_url = url({'for':'web.user.show','id':item.id}) %}
|
||||
{% set item.answer = item.answer ? item.answer : '稍安勿燥,请耐心等待回复吧' %}
|
||||
{% set owner_url = url({'for':'web.user.show','id':item.id}) %}
|
||||
{% set like_url = url({'for':'web.consult.like','id':item.id}) %}
|
||||
<div class="review-card clearfix">
|
||||
<div class="avatar">
|
||||
<a href="{{ user_url }}">
|
||||
<img src="{{ item.user.avatar }}" alt="{{ item.user.name }}" title="{{ item.user.name }}">
|
||||
<a href="{{ owner_url }}">
|
||||
<img src="{{ item.owner.avatar }}" alt="{{ item.owner.name }}" title="{{ item.owner.name }}">
|
||||
</a>
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="rating">{{ star_info(item.rating) }}</div>
|
||||
<div class="title">{{ item.question }}</div>
|
||||
<div class="content">{% if item.answer %} {{ item.answer }} {% else %} 稍安勿燥,请耐心等待我们的回复吧 {% endif %}</div>
|
||||
<div class="content">{{ item.answer }}</div>
|
||||
<div class="footer">
|
||||
<span class="time">{{ item.create_time|time_ago }}</span>
|
||||
<a href="javascript:" class="like" title="点赞" data-url="{{ like_url }}">
|
||||
|
@ -3,16 +3,16 @@
|
||||
{% if pager.total_pages > 0 %}
|
||||
<div class="review-list">
|
||||
{% for item in pager.items %}
|
||||
{% set user_url = url({'for':'web.user.show','id':item.user.id}) %}
|
||||
{% set owner_url = url({'for':'web.user.show','id':item.owner.id}) %}
|
||||
{% set like_url = url({'for':'web.review.like','id':item.id}) %}
|
||||
<div class="review-card clearfix">
|
||||
<div class="avatar">
|
||||
<img src="{{ item.user.avatar }}" alt="{{ item.user.name }}">
|
||||
<img src="{{ item.owner.avatar }}" alt="{{ item.owner.name }}">
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="rating">{{ star_info(item.rating) }}</div>
|
||||
<div class="user">
|
||||
<a href="{{ user_url }}">{{ item.user.name }}</a>
|
||||
<a href="{{ owner_url }}">{{ item.owner.name }}</a>
|
||||
</div>
|
||||
<div class="content">{{ item.content }}</div>
|
||||
<div class="footer">
|
||||
|
@ -10,7 +10,7 @@
|
||||
<div class="wrap">
|
||||
<div class="my-nav-title">我的咨询</div>
|
||||
{% if pager.total_pages > 0 %}
|
||||
<table class="layui-table review-table">
|
||||
<table class="layui-table consult-table">
|
||||
<colgroup>
|
||||
<col>
|
||||
<col>
|
||||
@ -25,14 +25,14 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for item in pager.items %}
|
||||
{% set item.answer = item.answer ? item.answer : '请耐心等待我们的回复吧' %}
|
||||
{% set answer = item.answer ? item.answer : '<span class="gray">稍安勿燥,请耐心等待回复吧</span>' %}
|
||||
{% set show_url = url({'for':'web.consult.show','id':item.id}) %}
|
||||
{% set edit_url = url({'for':'web.consult.edit','id':item.id}) %}
|
||||
{% set delete_url = url({'for':'web.consult.delete','id':item.id}) %}
|
||||
<tr>
|
||||
<td>
|
||||
<p class="content layui-elip" title="{{ item.question|e }}">提问:{{ item.question }}</p>
|
||||
<p class="content layui-elip" title="{{ item.answer|e }}">回复:{{ item.answer }}</p>
|
||||
<p class="question layui-elip" title="{{ item.question }}">提问:{{ item.question }}</p>
|
||||
<p class="answer layui-elip" title="{{ item.answer }}">回复:{{ answer }}</p>
|
||||
</td>
|
||||
<td>{{ date('Y-m-d',item.create_time) }}</td>
|
||||
<td>
|
||||
|
@ -2,24 +2,24 @@
|
||||
|
||||
{% block content %}
|
||||
|
||||
{{ partial('partials/macro_course') }}
|
||||
|
||||
<div class="layout-main">
|
||||
<div class="my-sidebar">{{ partial('my/menu') }}</div>
|
||||
<div class="my-content">
|
||||
<div class="wrap">
|
||||
<div class="my-nav-title">我的课程</div>
|
||||
{% if pager.total_pages > 0 %}
|
||||
<table class="layui-table" lay-size="lg">
|
||||
<table class="layui-table">
|
||||
<colgroup>
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
<col width="15%">
|
||||
<col width="12%">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>课程</th>
|
||||
<th>进度</th>
|
||||
<th>过期时间</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -28,13 +28,15 @@
|
||||
{% set course_url = url({'for':'web.course.show','id':item.course.id}) %}
|
||||
{% set review_url = url({'for':'web.review.add'},{'id':item.course.id}) %}
|
||||
<tr>
|
||||
<td><a href="{{ course_url }}">{{ item.course.title }}</a></td>
|
||||
<td>
|
||||
<p>标题:<a href="{{ course_url }}">{{ item.course.title }}</a> {{ model_info(item.course.model) }}</p>
|
||||
<p>期限:{{ date('Y-m-d',item.expiry_time) }}</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>用时:{{ item.duration|duration }}</p>
|
||||
<p>进度:{{ item.progress }}%</p>
|
||||
</td>
|
||||
<td>{{ date('Y-m-d', item.expiry_time) }}</td>
|
||||
<td>
|
||||
<td align="center">
|
||||
<button class="layui-btn layui-btn-sm btn-add-review" data-url="{{ review_url }}">评价</button>
|
||||
</td>
|
||||
</tr>
|
||||
|
55
app/Http/Web/Views/my/favorites.volt
Normal file
55
app/Http/Web/Views/my/favorites.volt
Normal file
@ -0,0 +1,55 @@
|
||||
{% extends 'templates/full.volt' %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{{ partial('partials/macro_course') }}
|
||||
|
||||
<div class="layout-main">
|
||||
<div class="my-sidebar">{{ partial('my/menu') }}</div>
|
||||
<div class="my-content">
|
||||
<div class="wrap">
|
||||
<div class="my-nav-title">我的收藏</div>
|
||||
{% if pager.total_pages > 0 %}
|
||||
<table class="layui-table" lay-size="lg">
|
||||
<colgroup>
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
<col width="12%">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>课程</th>
|
||||
<th>人气</th>
|
||||
<th>评分</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for item in pager.items %}
|
||||
{% set course_url = url({'for':'web.course.show','id':item.id}) %}
|
||||
{% set favorite_url = url({'for':'web.course.favorite','id':item.id}) %}
|
||||
<tr>
|
||||
<td><a href="{{ course_url }}">{{ item.title }}</a> {{ model_info(item.model) }}</td>
|
||||
<td><span class="layui-badge-rim">{{ item.user_count }}</span></td>
|
||||
<td>{{ star_info(item.rating) }}</td>
|
||||
<td align="center">
|
||||
<button class="layui-btn layui-btn-sm kg-delete" data-tips="确定要取消收藏吗?" data-url="{{ favorite_url }}">取消</button>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{{ partial('partials/pager') }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block include_js %}
|
||||
|
||||
{{ js_include('web/js/my.js') }}
|
||||
|
||||
{% endblock %}
|
@ -4,11 +4,11 @@
|
||||
|
||||
{%- macro gender_info(value) %}
|
||||
{% if value == 1 %}
|
||||
男
|
||||
<span class="layui-badge layui-bg-red">男</span>
|
||||
{% elseif value == 2 %}
|
||||
女
|
||||
<span class="layui-badge layui-bg-green">女</span>
|
||||
{% elseif value == 3 %}
|
||||
保密
|
||||
<span class="layui-badge layui-bg-gray">密</span>
|
||||
{% endif %}
|
||||
{%- endmacro %}
|
||||
|
||||
|
@ -2,12 +2,14 @@
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% set update_profile_url = url({'for':'web.my.update_profile'}) %}
|
||||
|
||||
<div class="layout-main">
|
||||
<div class="my-sidebar">{{ partial('my/menu') }}</div>
|
||||
<div class="my-content">
|
||||
<div class="wrap">
|
||||
<div class="my-nav-title">个人信息</div>
|
||||
<form class="layui-form my-form" method="post" action="{{ url({'for':'web.my.update_profile'}) }}">
|
||||
<form class="layui-form my-form" method="post" action="{{ update_profile_url }}">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">昵称</label>
|
||||
<div class="layui-input-block">
|
||||
@ -38,7 +40,7 @@
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-input-inline" style="width: 200px;">
|
||||
<select name="area[county]" class="county-selector" data-value="{{ user.area.county }}" lay-verify="required">
|
||||
<select name="area[county]" class="county-selector" data-value="{{ user.area.county }}">
|
||||
<option value="">请选择区</option>
|
||||
</select>
|
||||
</div>
|
||||
|
@ -40,7 +40,7 @@ class Consult extends Model
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $user_id;
|
||||
public $owner_id;
|
||||
|
||||
/**
|
||||
* 提问
|
||||
@ -56,6 +56,13 @@ class Consult extends Model
|
||||
*/
|
||||
public $answer;
|
||||
|
||||
/**
|
||||
* 评分
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $rating;
|
||||
|
||||
/**
|
||||
* 赞成数
|
||||
*
|
||||
@ -91,6 +98,13 @@ class Consult extends Model
|
||||
*/
|
||||
public $deleted;
|
||||
|
||||
/**
|
||||
* 回复时间
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $answer_time;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*
|
||||
@ -131,6 +145,10 @@ class Consult extends Model
|
||||
{
|
||||
$this->update_time = time();
|
||||
|
||||
if (!empty($this->answer) && $this->answer_time == 0) {
|
||||
$this->answer_time = time();
|
||||
}
|
||||
|
||||
if ($this->deleted == 1) {
|
||||
$this->published = 0;
|
||||
}
|
||||
|
@ -42,6 +42,13 @@ class ConsultLike extends Model
|
||||
*/
|
||||
public $create_time;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $update_time;
|
||||
|
||||
public function getSource(): string
|
||||
{
|
||||
return 'kg_consult_like';
|
||||
|
@ -269,10 +269,10 @@ class Course extends Model
|
||||
break;
|
||||
}
|
||||
|
||||
if (Text::startsWith($this->cover, 'http')) {
|
||||
$this->cover = self::getCoverPath($this->cover);
|
||||
} elseif (empty($this->cover)) {
|
||||
if (empty($this->cover)) {
|
||||
$this->cover = kg_default_cover_path();
|
||||
} elseif (Text::startsWith($this->cover, 'http')) {
|
||||
$this->cover = self::getCoverPath($this->cover);
|
||||
}
|
||||
|
||||
if (!empty($attrs)) {
|
||||
|
@ -55,7 +55,7 @@ class Danmu extends Model
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $user_id;
|
||||
public $owner_id;
|
||||
|
||||
/**
|
||||
* 内容
|
||||
|
@ -33,7 +33,7 @@ class ImGroup extends Model
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $user_id;
|
||||
public $owner_id;
|
||||
|
||||
/**
|
||||
* 群组类型
|
||||
@ -119,10 +119,10 @@ class ImGroup extends Model
|
||||
{
|
||||
$this->create_time = time();
|
||||
|
||||
if (Text::startsWith($this->avatar, 'http')) {
|
||||
$this->avatar = self::getAvatarPath($this->avatar);
|
||||
} elseif (empty($this->avatar)) {
|
||||
if (empty($this->avatar)) {
|
||||
$this->avatar = kg_default_avatar_path();
|
||||
} elseif (Text::startsWith($this->avatar, 'http')) {
|
||||
$this->avatar = self::getAvatarPath($this->avatar);
|
||||
}
|
||||
}
|
||||
|
||||
@ -151,5 +151,13 @@ class ImGroup extends Model
|
||||
return $url;
|
||||
}
|
||||
|
||||
public static function types()
|
||||
{
|
||||
return [
|
||||
self::TYPE_COURSE => '课程',
|
||||
self::TYPE_CHAT => '聊天',
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -65,6 +65,20 @@ class ImUser extends Model
|
||||
*/
|
||||
public $deleted;
|
||||
|
||||
/**
|
||||
* 好友数
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $friend_count;
|
||||
|
||||
/**
|
||||
* 群组数
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $group_count;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*
|
||||
@ -100,10 +114,10 @@ class ImUser extends Model
|
||||
{
|
||||
$this->create_time = time();
|
||||
|
||||
if (Text::startsWith($this->avatar, 'http')) {
|
||||
$this->avatar = self::getAvatarPath($this->avatar);
|
||||
} elseif (empty($this->avatar)) {
|
||||
if (empty($this->avatar)) {
|
||||
$this->avatar = kg_default_avatar_path();
|
||||
} elseif (Text::startsWith($this->avatar, 'http')) {
|
||||
$this->avatar = self::getAvatarPath($this->avatar);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ class Review extends Model
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $user_id;
|
||||
public $owner_id;
|
||||
|
||||
/**
|
||||
* 评价内容
|
||||
|
@ -42,6 +42,13 @@ class ReviewLike extends Model
|
||||
*/
|
||||
public $create_time;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $update_time;
|
||||
|
||||
public function getSource(): string
|
||||
{
|
||||
return 'kg_review_like';
|
||||
|
@ -120,10 +120,10 @@ class Slide extends Model
|
||||
{
|
||||
$this->create_time = time();
|
||||
|
||||
if (Text::startsWith($this->cover, 'http')) {
|
||||
$this->cover = self::getCoverPath($this->cover);
|
||||
} elseif (empty($this->cover)) {
|
||||
if (empty($this->cover)) {
|
||||
$this->cover = kg_default_cover_path();
|
||||
} elseif (Text::startsWith($this->cover, 'http')) {
|
||||
$this->cover = self::getCoverPath($this->cover);
|
||||
}
|
||||
|
||||
if (is_array($this->style) && !empty($this->style)) {
|
||||
|
@ -107,7 +107,21 @@ class User extends Model
|
||||
public $deleted;
|
||||
|
||||
/**
|
||||
* VIP期限
|
||||
* 课程数
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $course_count;
|
||||
|
||||
/**
|
||||
* 收藏数
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $favorite_count;
|
||||
|
||||
/**
|
||||
* 会员期限
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
@ -162,12 +176,10 @@ class User extends Model
|
||||
{
|
||||
$this->create_time = time();
|
||||
|
||||
$this->im = kg_json_encode($this->_im);
|
||||
|
||||
if (Text::startsWith($this->avatar, 'http')) {
|
||||
$this->avatar = self::getAvatarPath($this->avatar);
|
||||
} elseif (empty($this->avatar)) {
|
||||
if (empty($this->avatar)) {
|
||||
$this->avatar = kg_default_avatar_path();
|
||||
} elseif (Text::startsWith($this->avatar, 'http')) {
|
||||
$this->avatar = self::getAvatarPath($this->avatar);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,8 +28,8 @@ class Consult extends Repository
|
||||
$builder->andWhere('course_id = :course_id:', ['course_id' => $where['course_id']]);
|
||||
}
|
||||
|
||||
if (!empty($where['user_id'])) {
|
||||
$builder->andWhere('user_id = :user_id:', ['user_id' => $where['user_id']]);
|
||||
if (!empty($where['owner_id'])) {
|
||||
$builder->andWhere('owner_id = :owner_id:', ['owner_id' => $where['owner_id']]);
|
||||
}
|
||||
|
||||
if (isset($where['private'])) {
|
||||
@ -94,7 +94,7 @@ class Consult extends Repository
|
||||
public function findUserLastChapterConsult($chapterId, $userId)
|
||||
{
|
||||
return ConsultModel::findFirst([
|
||||
'conditions' => 'chapter_id = ?1 AND user_id = ?2 AND deleted = 0',
|
||||
'conditions' => 'chapter_id = ?1 AND owner_id = ?2 AND deleted = 0',
|
||||
'bind' => [1 => $chapterId, 2 => $userId],
|
||||
'order' => 'id DESC',
|
||||
]);
|
||||
|
@ -6,7 +6,6 @@ use App\Library\Paginator\Adapter\QueryBuilder as PagerQueryBuilder;
|
||||
use App\Models\Category as CategoryModel;
|
||||
use App\Models\Chapter as ChapterModel;
|
||||
use App\Models\ChapterUser as ChapterUserModel;
|
||||
use App\Models\Comment as CommentModel;
|
||||
use App\Models\Consult as ConsultModel;
|
||||
use App\Models\Course as CourseModel;
|
||||
use App\Models\CourseCategory as CourseCategoryModel;
|
||||
@ -290,14 +289,6 @@ class Course extends Repository
|
||||
]);
|
||||
}
|
||||
|
||||
public function countComments($courseId)
|
||||
{
|
||||
return (int)CommentModel::count([
|
||||
'conditions' => 'course_id = :course_id: AND published = 1',
|
||||
'bind' => ['course_id' => $courseId],
|
||||
]);
|
||||
}
|
||||
|
||||
public function countFavorites($courseId)
|
||||
{
|
||||
return (int)CourseFavoriteModel::count([
|
||||
|
@ -31,8 +31,8 @@ class Danmu extends Repository
|
||||
$builder->andWhere('chapter_id = :chapter_id:', ['chapter_id' => $where['chapter_id']]);
|
||||
}
|
||||
|
||||
if (!empty($where['user_id'])) {
|
||||
$builder->andWhere('user_id = :user_id:', ['user_id' => $where['user_id']]);
|
||||
if (!empty($where['owner_id'])) {
|
||||
$builder->andWhere('owner_id = :owner_id:', ['owner_id' => $where['owner_id']]);
|
||||
}
|
||||
|
||||
if (isset($where['published'])) {
|
||||
@ -100,8 +100,8 @@ class Danmu extends Repository
|
||||
$query->andWhere('chapter_id = :chapter_id:', ['chapter_id' => $where['chapter_id']]);
|
||||
}
|
||||
|
||||
if (!empty($where['user_id'])) {
|
||||
$query->andWhere('user_id = :user_id:', ['user_id' => $where['user_id']]);
|
||||
if (!empty($where['owner_id'])) {
|
||||
$query->andWhere('owner_id = :owner_id:', ['owner_id' => $where['owner_id']]);
|
||||
}
|
||||
|
||||
if (!empty($where['start_time']) && !empty($where['end_time'])) {
|
||||
@ -123,7 +123,7 @@ class Danmu extends Repository
|
||||
|
||||
public function countDanmus()
|
||||
{
|
||||
return (int)DanmuModel::count(['conditions' => 'deleted = 0']);
|
||||
return (int)DanmuModel::count(['conditions' => 'published = 1']);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -21,14 +21,26 @@ class ImGroup extends Repository
|
||||
|
||||
$builder->where('1 = 1');
|
||||
|
||||
if (!empty($where['course_id'])) {
|
||||
$builder->andWhere('sender_id = :sender_id:', ['sender_id' => $where['sender_id']]);
|
||||
if (!empty($where['id'])) {
|
||||
$builder->andWhere('id = :id:', ['id' => $where['id']]);
|
||||
}
|
||||
|
||||
if (!empty($where['name'])) {
|
||||
$builder->andWhere('name LIKE :name:', ['name' => "%{$where['name']}%"]);
|
||||
}
|
||||
|
||||
if (!empty($where['course_id'])) {
|
||||
$builder->andWhere('course_id = :course_id:', ['course_id' => $where['course_id']]);
|
||||
}
|
||||
|
||||
if (!empty($where['owner_id'])) {
|
||||
$builder->andWhere('owner_id = :owner_id:', ['owner_id' => $where['owner_id']]);
|
||||
}
|
||||
|
||||
if (isset($where['published'])) {
|
||||
$builder->andWhere('published = :published:', ['published' => $where['published']]);
|
||||
}
|
||||
|
||||
if (isset($where['deleted'])) {
|
||||
$builder->andWhere('deleted = :deleted:', ['deleted' => $where['deleted']]);
|
||||
}
|
||||
|
@ -28,8 +28,8 @@ class Review extends Repository
|
||||
$builder->andWhere('course_id = :course_id:', ['course_id' => $where['course_id']]);
|
||||
}
|
||||
|
||||
if (!empty($where['user_id'])) {
|
||||
$builder->andWhere('user_id = :user_id:', ['user_id' => $where['user_id']]);
|
||||
if (!empty($where['owner_id'])) {
|
||||
$builder->andWhere('owner_id = :owner_id:', ['owner_id' => $where['owner_id']]);
|
||||
}
|
||||
|
||||
if (isset($where['published'])) {
|
||||
@ -88,8 +88,8 @@ class Review extends Repository
|
||||
public function findReview($courseId, $userId)
|
||||
{
|
||||
return ReviewModel::findFirst([
|
||||
'conditions' => 'course_id = :course_id: AND user_id = :user_id:',
|
||||
'bind' => ['course_id' => $courseId, 'user_id' => $userId],
|
||||
'conditions' => 'course_id = :course_id: AND owner_id = :owner_id:',
|
||||
'bind' => ['course_id' => $courseId, 'owner_id' => $userId],
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -114,6 +114,8 @@ class ChapterInfo extends FrontendService
|
||||
$this->joinedCourse = true;
|
||||
|
||||
$this->incrCourseUserCount($course);
|
||||
|
||||
$this->incrUserCourseCount($course);
|
||||
}
|
||||
|
||||
protected function handleChapterUser(ChapterModel $chapter, UserModel $user)
|
||||
@ -142,6 +144,12 @@ class ChapterInfo extends FrontendService
|
||||
$this->incrChapterUserCount($chapter);
|
||||
}
|
||||
|
||||
protected function incrUserCourseCount(UserModel $user)
|
||||
{
|
||||
$user->course_count += 1;
|
||||
$user->update();
|
||||
}
|
||||
|
||||
protected function incrCourseUserCount(CourseModel $course)
|
||||
{
|
||||
$course->user_count += 1;
|
||||
|
@ -8,7 +8,7 @@ use App\Models\User as UserModel;
|
||||
use App\Repos\ChapterLike as ChapterLikeRepo;
|
||||
use App\Services\Frontend\ChapterTrait;
|
||||
use App\Services\Frontend\Service as FrontendService;
|
||||
use App\Validators\UserDailyLimit as UserDailyLimitValidator;
|
||||
use App\Validators\UserLimit as UserLimitValidator;
|
||||
|
||||
class ChapterLike extends FrontendService
|
||||
{
|
||||
@ -21,9 +21,9 @@ class ChapterLike extends FrontendService
|
||||
|
||||
$user = $this->getLoginUser();
|
||||
|
||||
$validator = new UserDailyLimitValidator();
|
||||
$validator = new UserLimitValidator();
|
||||
|
||||
$validator->checkChapterLikeLimit($user);
|
||||
$validator->checkDailyChapterLikeLimit($user);
|
||||
|
||||
$likeRepo = new ChapterLikeRepo();
|
||||
|
||||
@ -58,7 +58,7 @@ class ChapterLike extends FrontendService
|
||||
|
||||
$this->incrUserDailyChapterLikeCount($user);
|
||||
|
||||
return $chapter;
|
||||
return $chapterLike;
|
||||
}
|
||||
|
||||
protected function incrLikeCount(ChapterModel $chapter)
|
||||
|
@ -48,7 +48,7 @@ class DanmuList extends FrontendService
|
||||
|
||||
foreach ($items as $item) {
|
||||
|
||||
$user = $users[$item['user_id']] ?? new \stdClass();
|
||||
$owner = $users[$item['owner_id']] ?? new \stdClass();
|
||||
|
||||
$result[] = [
|
||||
'id' => $item['id'],
|
||||
@ -57,7 +57,7 @@ class DanmuList extends FrontendService
|
||||
'size' => $item['size'],
|
||||
'time' => $item['time'],
|
||||
'position' => $item['position'],
|
||||
'user' => $user,
|
||||
'owner' => $owner,
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ use App\Services\Frontend\ChapterTrait;
|
||||
use App\Services\Frontend\CourseTrait;
|
||||
use App\Services\Frontend\Service as FrontendService;
|
||||
use App\Validators\Consult as ConsultValidator;
|
||||
use App\Validators\UserDailyLimit as UserDailyLimitValidator;
|
||||
use App\Validators\UserLimit as UserLimitValidator;
|
||||
|
||||
class ConsultCreate extends FrontendService
|
||||
{
|
||||
@ -28,15 +28,15 @@ class ConsultCreate extends FrontendService
|
||||
|
||||
$course = $this->checkCourse($chapter->course_id);
|
||||
|
||||
$validator = new UserDailyLimitValidator();
|
||||
$validator = new UserLimitValidator();
|
||||
|
||||
$validator->checkConsultLimit($user);
|
||||
$validator->checkDailyConsultLimit($user);
|
||||
|
||||
$validator = new ConsultValidator();
|
||||
|
||||
$question = $validator->checkQuestion($post['question']);
|
||||
|
||||
$validator->checkIfDuplicated($chapter->id, $user->id, $question);
|
||||
$validator->checkIfDuplicated($question, $chapter->id, $user->id);
|
||||
|
||||
$priority = $this->getPriority($course, $user);
|
||||
|
||||
@ -46,7 +46,7 @@ class ConsultCreate extends FrontendService
|
||||
$consult->priority = $priority;
|
||||
$consult->course_id = $course->id;
|
||||
$consult->chapter_id = $chapter->id;
|
||||
$consult->user_id = $user->id;
|
||||
$consult->owner_id = $user->id;
|
||||
$consult->published = 1;
|
||||
|
||||
$consult->create();
|
||||
|
@ -29,7 +29,7 @@ class ConsultDelete extends FrontendService
|
||||
|
||||
$validator = new ConsultValidator();
|
||||
|
||||
$validator->checkOwner($user->id, $consult->user_id);
|
||||
$validator->checkOwner($user->id, $consult->owner_id);
|
||||
|
||||
$consult->update(['deleted' => 1]);
|
||||
|
||||
|
@ -28,6 +28,7 @@ class ConsultInfo extends FrontendService
|
||||
'question' => $consult->question,
|
||||
'answer' => $consult->answer,
|
||||
'private' => $consult->private,
|
||||
'rating' => $consult->rating,
|
||||
'like_count' => $consult->like_count,
|
||||
'create_time' => $consult->create_time,
|
||||
'update_time' => $consult->update_time,
|
||||
@ -53,12 +54,12 @@ class ConsultInfo extends FrontendService
|
||||
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
$user = $userRepo->findById($consult->user_id);
|
||||
$owner = $userRepo->findById($consult->owner_id);
|
||||
|
||||
$result['user'] = [
|
||||
'id' => $user->id,
|
||||
'name' => $user->name,
|
||||
'avatar' => $user->avatar,
|
||||
$result['owner'] = [
|
||||
'id' => $owner->id,
|
||||
'name' => $owner->name,
|
||||
'avatar' => $owner->avatar,
|
||||
];
|
||||
|
||||
return $result;
|
||||
|
@ -8,7 +8,7 @@ use App\Models\User as UserModel;
|
||||
use App\Services\Frontend\ConsultTrait;
|
||||
use App\Services\Frontend\Service as FrontendService;
|
||||
use App\Validators\Consult as ConsultValidator;
|
||||
use App\Validators\UserDailyLimit as UserDailyLimitValidator;
|
||||
use App\Validators\UserLimit as UserLimitValidator;
|
||||
|
||||
class ConsultLike extends FrontendService
|
||||
{
|
||||
@ -21,9 +21,9 @@ class ConsultLike extends FrontendService
|
||||
|
||||
$user = $this->getLoginUser();
|
||||
|
||||
$validator = new UserDailyLimitValidator();
|
||||
$validator = new UserLimitValidator();
|
||||
|
||||
$validator->checkConsultLikeLimit($user);
|
||||
$validator->checkDailyConsultLikeLimit($user);
|
||||
|
||||
$validator = new ConsultValidator();
|
||||
|
||||
@ -58,7 +58,7 @@ class ConsultLike extends FrontendService
|
||||
|
||||
$this->incrUserDailyConsultLikeCount($user);
|
||||
|
||||
return $consult;
|
||||
return $consultLike;
|
||||
}
|
||||
|
||||
protected function incrLikeCount(ConsultModel $consult)
|
||||
|
37
app/Services/Frontend/Consult/ConsultRating.php
Normal file
37
app/Services/Frontend/Consult/ConsultRating.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Frontend\Consult;
|
||||
|
||||
use App\Services\Frontend\ConsultTrait;
|
||||
use App\Services\Frontend\Service as FrontendService;
|
||||
use App\Validators\Consult as ConsultValidator;
|
||||
|
||||
class ConsultRating extends FrontendService
|
||||
{
|
||||
|
||||
use ConsultTrait;
|
||||
|
||||
public function handle($id)
|
||||
{
|
||||
$post = $this->request->getPost();
|
||||
|
||||
$user = $this->getLoginUser();
|
||||
|
||||
$consult = $this->checkConsult($id);
|
||||
|
||||
$validator = new ConsultValidator();
|
||||
|
||||
$validator->checkOwner($user->id, $consult->user_id);
|
||||
|
||||
$validator->checkIfAllowRate($consult);
|
||||
|
||||
$rating = $validator->checkRating($post['rating']);
|
||||
|
||||
$consult->rating = $rating;
|
||||
|
||||
$consult->update();
|
||||
|
||||
return $consult;
|
||||
}
|
||||
|
||||
}
|
@ -21,7 +21,9 @@ class ConsultUpdate extends FrontendService
|
||||
|
||||
$validator = new ConsultValidator();
|
||||
|
||||
$validator->checkOwner($user->id, $consult->user_id);
|
||||
$validator->checkOwner($user->id, $consult->owner_id);
|
||||
|
||||
$validator->checkIfAllowEdit($consult);
|
||||
|
||||
$question = $validator->checkQuestion($post['question']);
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace App\Services\Frontend\Course;
|
||||
|
||||
use App\Caches\CourseChapterList as CourseChapterListCache;
|
||||
use App\Caches\CourseCatalog as CourseCatalogCache;
|
||||
use App\Models\Course as CourseModel;
|
||||
use App\Models\User as UserModel;
|
||||
use App\Repos\Course as CourseRepo;
|
||||
@ -27,7 +27,7 @@ class ChapterList extends FrontendService
|
||||
|
||||
protected function getChapters(CourseModel $course, UserModel $user)
|
||||
{
|
||||
$cache = new CourseChapterListCache();
|
||||
$cache = new CourseCatalogCache();
|
||||
|
||||
$chapters = $cache->get($course->id);
|
||||
|
||||
|
@ -52,16 +52,17 @@ class ConsultList extends FrontendService
|
||||
|
||||
foreach ($consults as $consult) {
|
||||
|
||||
$user = $users[$consult['user_id']] ?? new \stdClass();
|
||||
$owner = $users[$consult['owner_id']] ?? new \stdClass();
|
||||
|
||||
$items[] = [
|
||||
'id' => $consult['id'],
|
||||
'question' => $consult['question'],
|
||||
'answer' => $consult['answer'],
|
||||
'rating' => $consult['rating'],
|
||||
'like_count' => $consult['like_count'],
|
||||
'create_time' => $consult['create_time'],
|
||||
'update_time' => $consult['update_time'],
|
||||
'user' => $user,
|
||||
'owner' => $owner,
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@ use App\Models\User as UserModel;
|
||||
use App\Repos\CourseFavorite as CourseFavoriteRepo;
|
||||
use App\Services\Frontend\CourseTrait;
|
||||
use App\Services\Frontend\Service as FrontendService;
|
||||
use App\Validators\UserDailyLimit as UserDailyLimitValidator;
|
||||
use App\Validators\UserLimit as UserLimitValidator;
|
||||
|
||||
class Favorite extends FrontendService
|
||||
{
|
||||
@ -21,7 +21,7 @@ class Favorite extends FrontendService
|
||||
|
||||
$user = $this->getLoginUser();
|
||||
|
||||
$validator = new UserDailyLimitValidator();
|
||||
$validator = new UserLimitValidator();
|
||||
|
||||
$validator->checkFavoriteLimit($user);
|
||||
|
||||
@ -48,15 +48,19 @@ class Favorite extends FrontendService
|
||||
|
||||
$this->decrCourseFavoriteCount($course);
|
||||
|
||||
$this->decrUserFavoriteCount($user);
|
||||
|
||||
} else {
|
||||
|
||||
$favorite->update(['deleted' => 0]);
|
||||
|
||||
$this->incrCourseFavoriteCount($course);
|
||||
|
||||
$this->incrUserFavoriteCount($user);
|
||||
}
|
||||
}
|
||||
|
||||
$this->incrUserDailyFavoriteCount($user);
|
||||
return $favorite;
|
||||
}
|
||||
|
||||
protected function incrCourseFavoriteCount(CourseModel $course)
|
||||
@ -73,9 +77,18 @@ class Favorite extends FrontendService
|
||||
}
|
||||
}
|
||||
|
||||
protected function incrUserDailyFavoriteCount(UserModel $user)
|
||||
protected function incrUserFavoriteCount(UserModel $user)
|
||||
{
|
||||
$this->eventsManager->fire('userDailyCounter:incrFavoriteCount', $this, $user);
|
||||
$user->favorite_count += 1;
|
||||
$user->update();
|
||||
}
|
||||
|
||||
protected function decrUserFavoriteCount(UserModel $user)
|
||||
{
|
||||
if ($user->favorite_count > 0) {
|
||||
$user->favorite_count -= 1;
|
||||
$user->update();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ class ReviewList extends FrontendService
|
||||
|
||||
foreach ($reviews as $review) {
|
||||
|
||||
$user = $users[$review['user_id']] ?? new \stdClass();
|
||||
$owner = $users[$review['owner_id']] ?? new \stdClass();
|
||||
|
||||
$items[] = [
|
||||
'id' => $review['id'],
|
||||
@ -59,7 +59,7 @@ class ReviewList extends FrontendService
|
||||
'content' => $review['content'],
|
||||
'like_count' => $review['like_count'],
|
||||
'create_time' => $review['create_time'],
|
||||
'user' => $user,
|
||||
'owner' => $owner,
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@ use App\Models\User as UserModel;
|
||||
use App\Services\Frontend\ChapterTrait;
|
||||
use App\Services\Frontend\Service as FrontendService;
|
||||
use App\Validators\Danmu as DanmuValidator;
|
||||
use App\Validators\UserDailyLimit as UserDailyLimitValidator;
|
||||
use App\Validators\UserLimit as UserLimitValidator;
|
||||
|
||||
class DanmuCreate extends FrontendService
|
||||
{
|
||||
@ -22,9 +22,9 @@ class DanmuCreate extends FrontendService
|
||||
|
||||
$chapter = $this->checkChapter($post['chapter_id']);
|
||||
|
||||
$validator = new UserDailyLimitValidator();
|
||||
$validator = new UserLimitValidator();
|
||||
|
||||
$validator->checkDanmuLimit($user);
|
||||
$validator->checkDailyDanmuLimit($user);
|
||||
|
||||
$validator = new DanmuValidator();
|
||||
|
||||
@ -40,7 +40,7 @@ class DanmuCreate extends FrontendService
|
||||
|
||||
$data['course_id'] = $chapter->course_id;
|
||||
$data['chapter_id'] = $chapter->id;
|
||||
$data['user_id'] = $user->id;
|
||||
$data['owner_id'] = $user->id;
|
||||
|
||||
$data['published'] = 1;
|
||||
|
||||
|
@ -32,12 +32,12 @@ class DanmuInfo extends FrontendService
|
||||
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
$user = $userRepo->findById($danmu->user_id);
|
||||
$owner = $userRepo->findById($danmu->user_id);
|
||||
|
||||
$result['user'] = [
|
||||
'id' => $user->id,
|
||||
'name' => $user->name,
|
||||
'avatar' => $user->avatar,
|
||||
$result['owner'] = [
|
||||
'id' => $owner->id,
|
||||
'name' => $owner->name,
|
||||
'avatar' => $owner->avatar,
|
||||
];
|
||||
|
||||
return $result;
|
||||
|
@ -56,6 +56,7 @@ class ConsultList extends FrontendService
|
||||
'id' => $consult['id'],
|
||||
'question' => $consult['question'],
|
||||
'answer' => $consult['answer'],
|
||||
'rating' => $consult['rating'],
|
||||
'like_count' => $consult['like_count'],
|
||||
'create_time' => $consult['create_time'],
|
||||
'update_time' => $consult['update_time'],
|
||||
|
@ -2,63 +2,19 @@
|
||||
|
||||
namespace App\Services\Frontend\My;
|
||||
|
||||
use App\Builders\CourseFavoriteList as CourseFavoriteListBuilder;
|
||||
use App\Library\Paginator\Query as PagerQuery;
|
||||
use App\Repos\CourseFavorite as CourseFavoriteRepo;
|
||||
use App\Services\Frontend\Service as FrontendService;
|
||||
use App\Services\Frontend\UserTrait;
|
||||
use App\Services\Frontend\User\FavoriteList as UserFavoriteListService;
|
||||
|
||||
class FavoriteList extends FrontendService
|
||||
{
|
||||
|
||||
use UserTrait;
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$user = $this->getLoginUser();
|
||||
|
||||
$pagerQuery = new PagerQuery();
|
||||
$service = new UserFavoriteListService();
|
||||
|
||||
$params = $pagerQuery->getParams();
|
||||
|
||||
$params['user_id'] = $user->id;
|
||||
$params['deleted'] = 0;
|
||||
|
||||
$sort = $pagerQuery->getSort();
|
||||
$page = $pagerQuery->getPage();
|
||||
$limit = $pagerQuery->getLimit();
|
||||
|
||||
$favoriteRepo = new CourseFavoriteRepo();
|
||||
|
||||
$pager = $favoriteRepo->paginate($params, $sort, $page, $limit);
|
||||
|
||||
return $this->handleCourses($pager);
|
||||
}
|
||||
|
||||
protected function handleCourses($pager)
|
||||
{
|
||||
if ($pager->total_items == 0) {
|
||||
return $pager;
|
||||
}
|
||||
|
||||
$builder = new CourseFavoriteListBuilder();
|
||||
|
||||
$relations = $pager->items->toArray();
|
||||
|
||||
$courses = $builder->getCourses($relations);
|
||||
|
||||
$items = [];
|
||||
|
||||
foreach ($relations as $relation) {
|
||||
|
||||
$course = $courses[$relation['course_id']] ?? new \stdClass();
|
||||
|
||||
$items[] = $course;
|
||||
}
|
||||
|
||||
$pager->items = $items;
|
||||
|
||||
return $pager;
|
||||
return $service->handle($user->id);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ use App\Repos\Order as OrderRepo;
|
||||
use App\Repos\Package as PackageRepo;
|
||||
use App\Services\Frontend\Service as FrontendService;
|
||||
use App\Validators\Order as OrderValidator;
|
||||
use App\Validators\UserDailyLimit as UserDailyLimitValidator;
|
||||
use App\Validators\UserLimit as UserLimitValidator;
|
||||
|
||||
class OrderCreate extends FrontendService
|
||||
{
|
||||
@ -23,9 +23,9 @@ class OrderCreate extends FrontendService
|
||||
|
||||
$user = $this->getLoginUser();
|
||||
|
||||
$validator = new UserDailyLimitValidator();
|
||||
$validator = new UserLimitValidator();
|
||||
|
||||
$validator->checkOrderLimit($user);
|
||||
$validator->checkDailyOrderLimit($user);
|
||||
|
||||
$validator = new OrderValidator();
|
||||
|
||||
|
@ -4,13 +4,11 @@ namespace App\Services\Frontend\Review;
|
||||
|
||||
use App\Models\Course as CourseModel;
|
||||
use App\Models\Review as ReviewModel;
|
||||
use App\Models\User as UserModel;
|
||||
use App\Services\Frontend\CourseTrait;
|
||||
use App\Services\Frontend\ReviewTrait;
|
||||
use App\Services\Frontend\Service as FrontendService;
|
||||
use App\Validators\CourseUser as CourseUserValidator;
|
||||
use App\Validators\Review as ReviewValidator;
|
||||
use App\Validators\UserDailyLimit as UserDailyLimitValidator;
|
||||
|
||||
class ReviewCreate extends FrontendService
|
||||
{
|
||||
@ -26,10 +24,6 @@ class ReviewCreate extends FrontendService
|
||||
|
||||
$user = $this->getLoginUser();
|
||||
|
||||
$validator = new UserDailyLimitValidator();
|
||||
|
||||
$validator->checkReviewLimit($user);
|
||||
|
||||
$validator = new CourseUserValidator();
|
||||
|
||||
$validator->checkCourseUser($course->id, $user->id);
|
||||
@ -39,7 +33,7 @@ class ReviewCreate extends FrontendService
|
||||
|
||||
$data = [
|
||||
'course_id' => $course->id,
|
||||
'user_id' => $user->id,
|
||||
'owner_id' => $user->id,
|
||||
];
|
||||
|
||||
$data['content'] = $validator->checkContent($post['content']);
|
||||
@ -55,8 +49,6 @@ class ReviewCreate extends FrontendService
|
||||
|
||||
$this->incrCourseReviewCount($course);
|
||||
|
||||
$this->incrUserDailyReviewCount($user);
|
||||
|
||||
return $review;
|
||||
}
|
||||
|
||||
@ -66,9 +58,4 @@ class ReviewCreate extends FrontendService
|
||||
$course->update();
|
||||
}
|
||||
|
||||
protected function incrUserDailyReviewCount(UserModel $user)
|
||||
{
|
||||
$this->eventsManager->fire('userDailyCounter:incrReviewCount', $this, $user);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -24,9 +24,9 @@ class ReviewDelete extends FrontendService
|
||||
|
||||
$validator = new ReviewValidator();
|
||||
|
||||
$validator->checkOwner($user->id, $review->user_id);
|
||||
$validator->checkOwner($user->id, $review->owner_id);
|
||||
|
||||
$review->delete();
|
||||
$review->update(['deleted' => 1]);
|
||||
|
||||
$this->decrCourseReviewCount($course);
|
||||
|
||||
|
@ -36,9 +36,9 @@ class ReviewInfo extends FrontendService
|
||||
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
$owner = $userRepo->findById($review->user_id);
|
||||
$owner = $userRepo->findById($review->owner_id);
|
||||
|
||||
$result['user'] = [
|
||||
$result['owner'] = [
|
||||
'id' => $owner->id,
|
||||
'name' => $owner->name,
|
||||
'avatar' => $owner->avatar,
|
||||
|
@ -8,7 +8,7 @@ use App\Models\User as UserModel;
|
||||
use App\Services\Frontend\ReviewTrait;
|
||||
use App\Services\Frontend\Service as FrontendService;
|
||||
use App\Validators\Review as ReviewValidator;
|
||||
use App\Validators\UserDailyLimit as UserDailyLimitValidator;
|
||||
use App\Validators\UserLimit as UserLimitValidator;
|
||||
|
||||
class ReviewLike extends FrontendService
|
||||
{
|
||||
@ -21,9 +21,9 @@ class ReviewLike extends FrontendService
|
||||
|
||||
$user = $this->getLoginUser();
|
||||
|
||||
$validator = new UserDailyLimitValidator();
|
||||
$validator = new UserLimitValidator();
|
||||
|
||||
$validator->checkReviewLikeLimit($user);
|
||||
$validator->checkDailyReviewLikeLimit($user);
|
||||
|
||||
$validator = new ReviewValidator();
|
||||
|
||||
@ -58,7 +58,7 @@ class ReviewLike extends FrontendService
|
||||
|
||||
$this->incrUserDailyReviewLikeCount($user);
|
||||
|
||||
return $review;
|
||||
return $reviewLike;
|
||||
}
|
||||
|
||||
protected function incrLikeCount(ReviewModel $review)
|
||||
|
@ -25,7 +25,9 @@ class ReviewUpdate extends FrontendService
|
||||
|
||||
$validator = new ReviewValidator();
|
||||
|
||||
$validator->checkOwner($user->id, $review->user_id);
|
||||
$validator->checkOwner($user->id, $review->owner_id);
|
||||
|
||||
$validator->checkIfAllowEdit($review);
|
||||
|
||||
$data = [];
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace App\Validators;
|
||||
|
||||
use App\Exceptions\BadRequest as BadRequestException;
|
||||
use App\Models\Consult as ConsultModel;
|
||||
use App\Repos\Consult as ConsultRepo;
|
||||
use App\Repos\ConsultLike as ConsultLikeRepo;
|
||||
|
||||
@ -70,6 +71,15 @@ class Consult extends Validator
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function checkRating($rating)
|
||||
{
|
||||
if (!in_array($rating, [1, 2, 3, 4, 5])) {
|
||||
throw new BadRequestException('consult.invalid_rating');
|
||||
}
|
||||
|
||||
return $rating;
|
||||
}
|
||||
|
||||
public function checkPrivateStatus($status)
|
||||
{
|
||||
if (!in_array($status, [0, 1])) {
|
||||
@ -88,7 +98,41 @@ class Consult extends Validator
|
||||
return $status;
|
||||
}
|
||||
|
||||
public function checkIfDuplicated($chapterId, $userId, $question)
|
||||
public function checkIfAllowEdit(ConsultModel $consult)
|
||||
{
|
||||
/**
|
||||
* (1)已回复不允许修改提问
|
||||
* (2)发表三天以后不能修改提问
|
||||
*/
|
||||
$case1 = !empty($consult->answer);
|
||||
$case2 = time() - $consult->create_time > 3 * 86400;
|
||||
|
||||
if ($case1 || $case2) {
|
||||
throw new BadRequestException('consult.edit_not_allowed');
|
||||
}
|
||||
}
|
||||
|
||||
public function checkIfAllowRate(ConsultModel $consult)
|
||||
{
|
||||
/**
|
||||
* 未回复不允许评价
|
||||
*/
|
||||
if (empty($consult->answer)) {
|
||||
throw new BadRequestException('consult.rate_not_allowed');
|
||||
}
|
||||
|
||||
/**
|
||||
* 已评价,三天后不能更改评价
|
||||
*/
|
||||
$case1 = $consult->rating > 0;
|
||||
$case2 = time() - $consult->answer_time > 3 * 86400;
|
||||
|
||||
if ($case1 && $case2) {
|
||||
throw new BadRequestException('consult.rate_not_allowed');
|
||||
}
|
||||
}
|
||||
|
||||
public function checkIfDuplicated($question, $chapterId, $userId)
|
||||
{
|
||||
$repo = new ConsultRepo();
|
||||
|
||||
|
@ -5,6 +5,7 @@ namespace App\Validators;
|
||||
use App\Caches\ImGroup as ImGroupCache;
|
||||
use App\Caches\MaxImGroupId as MaxImGroupIdCache;
|
||||
use App\Exceptions\BadRequest as BadRequestException;
|
||||
use App\Library\Validators\Common as CommonValidator;
|
||||
use App\Models\ImGroup as ImGroupModel;
|
||||
use App\Repos\ImGroup as ImGroupRepo;
|
||||
|
||||
@ -28,7 +29,7 @@ class ImGroup extends Validator
|
||||
* 防止缓存穿透
|
||||
*/
|
||||
if ($id < 1 || $id > $maxGroupId) {
|
||||
throw new BadRequestException('im_chat_group.not_found');
|
||||
throw new BadRequestException('im_group.not_found');
|
||||
}
|
||||
|
||||
$groupCache = new ImGroupCache();
|
||||
@ -36,7 +37,7 @@ class ImGroup extends Validator
|
||||
$group = $groupCache->get($id);
|
||||
|
||||
if (!$group) {
|
||||
throw new BadRequestException('im_chat_group.not_found');
|
||||
throw new BadRequestException('im_group.not_found');
|
||||
}
|
||||
|
||||
return $group;
|
||||
@ -49,7 +50,7 @@ class ImGroup extends Validator
|
||||
$group = $groupRepo->findById($id);
|
||||
|
||||
if (!$group) {
|
||||
throw new BadRequestException('im_chat_group.not_found');
|
||||
throw new BadRequestException('im_group.not_found');
|
||||
}
|
||||
|
||||
return $group;
|
||||
@ -62,11 +63,11 @@ class ImGroup extends Validator
|
||||
$length = kg_strlen($value);
|
||||
|
||||
if ($length < 2) {
|
||||
throw new BadRequestException('im_chat_group.name_too_short');
|
||||
throw new BadRequestException('im_group.name_too_short');
|
||||
}
|
||||
|
||||
if ($length > 30) {
|
||||
throw new BadRequestException('im_chat_group.name_too_long');
|
||||
throw new BadRequestException('im_group.name_too_long');
|
||||
}
|
||||
|
||||
return $value;
|
||||
@ -79,10 +80,48 @@ class ImGroup extends Validator
|
||||
$length = kg_strlen($value);
|
||||
|
||||
if ($length > 255) {
|
||||
throw new BadRequestException('im_chat_group.about_too_long');
|
||||
throw new BadRequestException('im_group.about_too_long');
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function checkAvatar($avatar)
|
||||
{
|
||||
$value = $this->filter->sanitize($avatar, ['trim', 'string']);
|
||||
|
||||
if (!CommonValidator::url($value)) {
|
||||
throw new BadRequestException('im_group.invalid_avatar');
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function checkType($type)
|
||||
{
|
||||
$list = ImGroupModel::types();
|
||||
|
||||
if (!isset($list[$type])) {
|
||||
throw new BadRequestException('im_group.invalid_type');
|
||||
}
|
||||
|
||||
return $type;
|
||||
}
|
||||
|
||||
public function checkPublishStatus($status)
|
||||
{
|
||||
if (!in_array($status, [0, 1])) {
|
||||
throw new BadRequestException('im_group.invalid_publish_status');
|
||||
}
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
||||
public function checkGroupOwner($userId)
|
||||
{
|
||||
$validator = new User();
|
||||
|
||||
return $validator->checkUser($userId);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ namespace App\Validators;
|
||||
|
||||
use App\Exceptions\BadRequest;
|
||||
use App\Exceptions\BadRequest as BadRequestException;
|
||||
use App\Models\Review as ReviewModel;
|
||||
use App\Repos\Review as ReviewRepo;
|
||||
use App\Repos\ReviewLike as ReviewLikeRepo;
|
||||
|
||||
@ -65,6 +66,15 @@ class Review extends Validator
|
||||
return $status;
|
||||
}
|
||||
|
||||
public function checkIfAllowEdit(ReviewModel $review)
|
||||
{
|
||||
$case = time() - $review->create_time > 7 * 86400;
|
||||
|
||||
if ($case) {
|
||||
throw new BadRequestException('review.edit_not_allowed');
|
||||
}
|
||||
}
|
||||
|
||||
public function checkIfLiked($reviewId, $userId)
|
||||
{
|
||||
$repo = new ReviewLikeRepo();
|
||||
|
@ -114,10 +114,14 @@ class User extends Validator
|
||||
|
||||
public function checkArea($area)
|
||||
{
|
||||
if (empty($area['province'] || empty($area['city']) || empty($area['county']))) {
|
||||
if (empty($area['province'] || empty($area['city']))) {
|
||||
throw new BadRequestException('user.invalid_area');
|
||||
}
|
||||
|
||||
if (empty($area['county'])) {
|
||||
$area['county'] = '***';
|
||||
}
|
||||
|
||||
return join('/', $area);
|
||||
}
|
||||
|
||||
|
@ -1,103 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Validators;
|
||||
|
||||
use App\Caches\UserDailyCounter as CacheUserDailyCounter;
|
||||
use App\Exceptions\BadRequest as BadRequestException;
|
||||
use App\Models\User as UserModel;
|
||||
|
||||
class UserDailyLimit extends Validator
|
||||
{
|
||||
|
||||
protected $counter;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->counter = new CacheUserDailyCounter();
|
||||
}
|
||||
|
||||
public function checkFavoriteLimit(UserModel $user)
|
||||
{
|
||||
$count = $this->counter->hGet($user->id, 'favorite_count');
|
||||
|
||||
$limit = $user->vip ? 100 : 50;
|
||||
|
||||
if ($count > $limit) {
|
||||
throw new BadRequestException('user_daily_limit.reach_favorite_limit');
|
||||
}
|
||||
}
|
||||
|
||||
public function checkDanmuLimit(UserModel $user)
|
||||
{
|
||||
$count = $this->counter->hGet($user->id, 'danmu_count');
|
||||
|
||||
$limit = $user->vip ? 100 : 50;
|
||||
|
||||
if ($count > $limit) {
|
||||
throw new BadRequestException('user_daily_limit.reach_danmu_limit');
|
||||
}
|
||||
}
|
||||
|
||||
public function checkConsultLimit(UserModel $user)
|
||||
{
|
||||
$count = $this->counter->hGet($user->id, 'consult_count');
|
||||
|
||||
$limit = $user->vip ? 20 : 10;
|
||||
|
||||
if ($count > $limit) {
|
||||
throw new BadRequestException('user_daily_limit.reach_consult_limit');
|
||||
}
|
||||
}
|
||||
|
||||
public function checkReviewLimit(UserModel $user)
|
||||
{
|
||||
$count = $this->counter->hGet($user->id, 'review_count');
|
||||
|
||||
if ($count > 10) {
|
||||
throw new BadRequestException('user_daily_limit.reach_review_limit');
|
||||
}
|
||||
}
|
||||
|
||||
public function checkOrderLimit(UserModel $user)
|
||||
{
|
||||
$count = $this->counter->hGet($user->id, 'order_count');
|
||||
|
||||
if ($count > 10) {
|
||||
throw new BadRequestException('user_daily_limit.reach_order_limit');
|
||||
}
|
||||
}
|
||||
|
||||
public function checkChapterLikeLimit(UserModel $user)
|
||||
{
|
||||
$count = $this->counter->hGet($user->id, 'chapter_like_count');
|
||||
|
||||
$limit = $user->vip ? 200 : 100;
|
||||
|
||||
if ($count > $limit) {
|
||||
throw new BadRequestException('user_daily_limit.reach_like_limit');
|
||||
}
|
||||
}
|
||||
|
||||
public function checkConsultLikeLimit(UserModel $user)
|
||||
{
|
||||
$count = $this->counter->hGet($user->id, 'consult_like_count');
|
||||
|
||||
$limit = $user->vip ? 200 : 100;
|
||||
|
||||
if ($count > $limit) {
|
||||
throw new BadRequestException('user_daily_limit.reach_like_limit');
|
||||
}
|
||||
}
|
||||
|
||||
public function checkReviewLikeLimit(UserModel $user)
|
||||
{
|
||||
$count = $this->counter->hGet($user->id, 'review_like_count');
|
||||
|
||||
$limit = $user->vip ? 200 : 100;
|
||||
|
||||
if ($count > $limit) {
|
||||
throw new BadRequestException('user_daily_limit.reach_like_limit');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
92
app/Validators/UserLimit.php
Normal file
92
app/Validators/UserLimit.php
Normal file
@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
namespace App\Validators;
|
||||
|
||||
use App\Caches\UserDailyCounter as CacheUserDailyCounter;
|
||||
use App\Exceptions\BadRequest as BadRequestException;
|
||||
use App\Models\User as UserModel;
|
||||
|
||||
class UserLimit extends Validator
|
||||
{
|
||||
|
||||
protected $counter;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->counter = new CacheUserDailyCounter();
|
||||
}
|
||||
|
||||
public function checkFavoriteLimit(UserModel $user)
|
||||
{
|
||||
$limit = $user->vip ? 1000 : 500;
|
||||
|
||||
if ($user->favorite_count > $limit) {
|
||||
throw new BadRequestException('user_limit.reach_favorite_limit');
|
||||
}
|
||||
}
|
||||
|
||||
public function checkDailyDanmuLimit(UserModel $user)
|
||||
{
|
||||
$count = $this->counter->hGet($user->id, 'danmu_count');
|
||||
|
||||
$limit = $user->vip ? 100 : 50;
|
||||
|
||||
if ($count > $limit) {
|
||||
throw new BadRequestException('user_limit.reach_daily_danmu_limit');
|
||||
}
|
||||
}
|
||||
|
||||
public function checkDailyConsultLimit(UserModel $user)
|
||||
{
|
||||
$count = $this->counter->hGet($user->id, 'consult_count');
|
||||
|
||||
$limit = $user->vip ? 20 : 10;
|
||||
|
||||
if ($count > $limit) {
|
||||
throw new BadRequestException('user_limit.reach_daily_consult_limit');
|
||||
}
|
||||
}
|
||||
|
||||
public function checkDailyOrderLimit(UserModel $user)
|
||||
{
|
||||
$count = $this->counter->hGet($user->id, 'order_count');
|
||||
|
||||
if ($count > 10) {
|
||||
throw new BadRequestException('user_limit.reach_daily_order_limit');
|
||||
}
|
||||
}
|
||||
|
||||
public function checkDailyChapterLikeLimit(UserModel $user)
|
||||
{
|
||||
$count = $this->counter->hGet($user->id, 'chapter_like_count');
|
||||
|
||||
$limit = $user->vip ? 200 : 100;
|
||||
|
||||
if ($count > $limit) {
|
||||
throw new BadRequestException('user_limit.reach_daily_like_limit');
|
||||
}
|
||||
}
|
||||
|
||||
public function checkDailyConsultLikeLimit(UserModel $user)
|
||||
{
|
||||
$count = $this->counter->hGet($user->id, 'consult_like_count');
|
||||
|
||||
$limit = $user->vip ? 200 : 100;
|
||||
|
||||
if ($count > $limit) {
|
||||
throw new BadRequestException('user_limit.reach_daily_like_limit');
|
||||
}
|
||||
}
|
||||
|
||||
public function checkDailyReviewLikeLimit(UserModel $user)
|
||||
{
|
||||
$count = $this->counter->hGet($user->id, 'review_like_count');
|
||||
|
||||
$limit = $user->vip ? 200 : 100;
|
||||
|
||||
if ($count > $limit) {
|
||||
throw new BadRequestException('user_limit.reach_daily_like_limit');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -30,6 +30,10 @@ class ConsoleErrorHandler extends Component
|
||||
$logger = $this->getLogger();
|
||||
|
||||
$logger->error($content);
|
||||
|
||||
if ($this->config->env == ENV_DEV) {
|
||||
echo $content;
|
||||
}
|
||||
}
|
||||
|
||||
protected function getLogger()
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user