diff --git a/CHANGELOG.md b/CHANGELOG.md index 51ce29a7..965bfae9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +### [v1.3.4](https://gitee.com/koogua/course-tencent-cloud/releases/v1.3.4)(2021-05-13) + +### 更新 + +- 前台增加问答功能 +- 优化标签功能 +- 优化文章功能以及全文搜索 +- 优化课程评价,咨询,文章等相关统计 +- 后台增加提问和回答审核功能 +- 后台增加查看用户在线记录 修正后台编辑角色权限错误 +- 优化前台界面 + ### [v1.3.3](https://gitee.com/koogua/course-tencent-cloud/releases/v1.3.3)(2021-04-30) ### 更新 diff --git a/app/Http/Admin/Controllers/AnswerController.php b/app/Http/Admin/Controllers/AnswerController.php index f2f3e38e..e22ca8f3 100644 --- a/app/Http/Admin/Controllers/AnswerController.php +++ b/app/Http/Admin/Controllers/AnswerController.php @@ -3,6 +3,7 @@ namespace App\Http\Admin\Controllers; use App\Http\Admin\Services\Answer as AnswerService; +use App\Http\Admin\Services\Question as QuestionService; /** * @RoutePrefix("/admin/answer") @@ -15,7 +16,11 @@ class AnswerController extends Controller */ public function searchAction() { + $answerService = new AnswerService(); + $publishTypes = $answerService->getPublishTypes(); + + $this->view->setVar('publish_types', $publishTypes); } /** @@ -30,6 +35,78 @@ class AnswerController extends Controller $this->view->setVar('pager', $pager); } + /** + * @Get("/add", name="admin.answer.add") + */ + public function addAction() + { + $id = $this->request->getQuery('question_id', 'int', 0); + + $questionService = new QuestionService(); + + $question = $questionService->getQuestion($id); + + $referer = $this->request->getHTTPReferer(); + + $this->view->setVar('question', $question); + $this->view->setVar('referer', $referer); + } + + /** + * @Get("/{id:[0-9]+}/edit", name="admin.answer.edit") + */ + public function editAction($id) + { + $answerService = new AnswerService(); + + $answer = $answerService->getAnswer($id); + + $questionService = new QuestionService(); + + $question = $questionService->getQuestion($answer->question_id); + + $referer = $this->request->getHTTPReferer(); + + $this->view->setVar('referer', $referer); + $this->view->setVar('question', $question); + $this->view->setVar('answer', $answer); + } + + /** + * @Get("/{id:[0-9]+}/show", name="admin.answer.show") + */ + public function showAction($id) + { + $answerService = new AnswerService(); + + $answer = $answerService->getAnswer($id); + + $this->view->setVar('answer', $answer); + } + + /** + * @Post("/create", name="admin.answer.create") + */ + public function createAction() + { + $answerService = new AnswerService(); + + $answerService->createAnswer(); + + $location = $this->request->getPost('referer'); + + if (empty($location)) { + $location = $this->url->get(['for' => 'admin.question.list']); + } + + $content = [ + 'location' => $location, + 'msg' => '回答问题成功', + ]; + + return $this->jsonSuccess($content); + } + /** * @Post("/{id:[0-9]+}/update", name="admin.answer.update") */ @@ -39,7 +116,16 @@ class AnswerController extends Controller $answerService->updateAnswer($id); - $content = ['msg' => '更新回答成功']; + $location = $this->request->getPost('referer'); + + if (empty($location)) { + $location = $this->url->get(['for' => 'admin.answer.list']); + } + + $content = [ + 'location' => $location, + 'msg' => '更新回答成功', + ]; return $this->jsonSuccess($content); } @@ -78,4 +164,38 @@ class AnswerController extends Controller return $this->jsonSuccess($content); } + /** + * @Route("/{id:[0-9]+}/review", name="admin.answer.review") + */ + public function reviewAction($id) + { + $answerService = new AnswerService(); + + $answer = $answerService->getAnswer($id); + + if ($this->request->isPost()) { + + $answerService->reviewAnswer($id); + + $location = $this->url->get(['for' => 'admin.mod.answers']); + + $content = [ + 'location' => $location, + 'msg' => '审核回答成功', + ]; + + return $this->jsonSuccess($content); + } + + $reasons = $answerService->getReasons(); + + $questionService = new QuestionService(); + + $question = $questionService->getQuestion($answer->question_id); + + $this->view->setVar('reasons', $reasons); + $this->view->setVar('question', $question); + $this->view->setVar('answer', $answer); + } + } diff --git a/app/Http/Admin/Controllers/ArticleController.php b/app/Http/Admin/Controllers/ArticleController.php index 26efde1d..26080afb 100644 --- a/app/Http/Admin/Controllers/ArticleController.php +++ b/app/Http/Admin/Controllers/ArticleController.php @@ -189,10 +189,10 @@ class ArticleController extends Controller return $this->jsonSuccess($content); } - $rejectOptions = $articleService->getRejectOptions(); + $reasons = $articleService->getReasons(); $article = $articleService->getArticle($id); - $this->view->setVar('reject_options', $rejectOptions); + $this->view->setVar('reasons', $reasons); $this->view->setVar('article', $article); } diff --git a/app/Http/Admin/Controllers/ModerationController.php b/app/Http/Admin/Controllers/ModerationController.php index f5fb5dbb..0ec36a01 100644 --- a/app/Http/Admin/Controllers/ModerationController.php +++ b/app/Http/Admin/Controllers/ModerationController.php @@ -34,4 +34,16 @@ class ModerationController extends Controller $this->view->setVar('pager', $pager); } + /** + * @Get("/answers", name="admin.mod.answers") + */ + public function answersAction() + { + $modService = new ModerationService(); + + $pager = $modService->getAnswers(); + + $this->view->setVar('pager', $pager); + } + } diff --git a/app/Http/Admin/Controllers/QuestionController.php b/app/Http/Admin/Controllers/QuestionController.php index ac959bfe..ef92e49d 100644 --- a/app/Http/Admin/Controllers/QuestionController.php +++ b/app/Http/Admin/Controllers/QuestionController.php @@ -185,10 +185,10 @@ class QuestionController extends Controller return $this->jsonSuccess($content); } - $rejectOptions = $questionService->getRejectOptions(); + $reasons = $questionService->getReasons(); $question = $questionService->getQuestion($id); - $this->view->setVar('reject_options', $rejectOptions); + $this->view->setVar('reasons', $reasons); $this->view->setVar('question', $question); } diff --git a/app/Http/Admin/Controllers/UserController.php b/app/Http/Admin/Controllers/UserController.php index 5d106768..b53e405d 100644 --- a/app/Http/Admin/Controllers/UserController.php +++ b/app/Http/Admin/Controllers/UserController.php @@ -94,6 +94,18 @@ class UserController extends Controller $this->view->setVar('admin_roles', $adminRoles); } + /** + * @Get("/{id:[0-9]+}/online", name="admin.user.online") + */ + public function onlineAction($id) + { + $userService = new UserService(); + + $pager = $userService->getOnlineLogs($id); + + $this->view->setVar('pager', $pager); + } + /** * @Post("/{id:[0-9]+}/update", name="admin.user.update") */ diff --git a/app/Http/Admin/Services/Answer.php b/app/Http/Admin/Services/Answer.php index 093304e6..b1fd1263 100644 --- a/app/Http/Admin/Services/Answer.php +++ b/app/Http/Admin/Services/Answer.php @@ -4,12 +4,32 @@ namespace App\Http\Admin\Services; use App\Builders\AnswerList as AnswerListBuilder; use App\Library\Paginator\Query as PagerQuery; +use App\Models\Answer as AnswerModel; +use App\Models\Question as QuestionModel; +use App\Models\Reason as ReasonModel; +use App\Models\User as UserModel; use App\Repos\Answer as AnswerRepo; +use App\Repos\Question as QuestionRepo; +use App\Repos\User as UserRepo; +use App\Services\Logic\Notice\System\AnswerApproved as AnswerApprovedNotice; +use App\Services\Logic\Notice\System\AnswerRejected as AnswerRejectedNotice; +use App\Services\Logic\Notice\System\QuestionAnswered as QuestionAnsweredNotice; +use App\Services\Logic\Point\History\AnswerPost as AnswerPostPointHistory; use App\Validators\Answer as AnswerValidator; class Answer extends Service { + public function getPublishTypes() + { + return AnswerModel::publishTypes(); + } + + public function getReasons() + { + return ReasonModel::answerRejectOptions(); + } + public function getAnswers() { $pagerQuery = new PagerQuery(); @@ -34,6 +54,33 @@ class Answer extends Service return $this->findOrFail($id); } + public function createAnswer() + { + $post = $this->request->getPost(); + + $user = $this->getLoginUser(); + + $validator = new AnswerValidator(); + + $question = $validator->checkQuestion($post['question_id']); + + $answer = new AnswerModel(); + + $answer->owner_id = $user->id; + $answer->question_id = $question->id; + $answer->published = AnswerModel::PUBLISH_APPROVED; + $answer->content = $validator->checkContent($post['content']); + + $answer->create(); + + $this->recountQuestionAnswers($question); + $this->recountUserAnswers($user); + $this->handleAnswerPostPoint($answer); + $this->handleQuestionAnsweredNotice($answer); + + return $answer; + } + public function updateAnswer($id) { $answer = $this->findOrFail($id); @@ -49,7 +96,16 @@ class Answer extends Service } if (isset($post['published'])) { + $data['published'] = $validator->checkPublishStatus($post['published']); + + $question = $this->findQuestion($answer->question_id); + + $this->recountQuestionAnswers($question); + + $user = $this->findUser($answer->owner_id); + + $this->recountUserAnswers($user); } $answer->update($data); @@ -59,24 +115,91 @@ class Answer extends Service public function deleteAnswer($id) { - $page = $this->findOrFail($id); + $answer = $this->findOrFail($id); - $page->deleted = 1; + $answer->deleted = 1; - $page->update(); + $answer->update(); - return $page; + $question = $this->findQuestion($answer->question_id); + + $this->recountQuestionAnswers($question); + + $owner = $this->findUser($answer->owner_id); + + $this->recountUserAnswers($owner); + + return $answer; } public function restoreAnswer($id) { - $page = $this->findOrFail($id); + $answer = $this->findOrFail($id); - $page->deleted = 0; + $answer->deleted = 0; - $page->update(); + $answer->update(); - return $page; + $question = $this->findQuestion($answer->question_id); + + $this->recountQuestionAnswers($question); + + $owner = $this->findUser($answer->owner_id); + + $this->recountUserAnswers($owner); + + return $answer; + } + + public function reviewAnswer($id) + { + $type = $this->request->getPost('type', ['trim', 'string']); + $reason = $this->request->getPost('reason', ['trim', 'string']); + + $answer = $this->findOrFail($id); + + $validator = new AnswerValidator(); + + if ($type == 'approve') { + $answer->published = AnswerModel::PUBLISH_APPROVED; + } elseif ($type == 'reject') { + $validator->checkRejectReason($reason); + $answer->published = AnswerModel::PUBLISH_REJECTED; + } + + $answer->update(); + + $question = $this->findQuestion($answer->question_id); + + $this->recountQuestionAnswers($question); + + $owner = $this->findUser($answer->owner_id); + + $this->recountUserAnswers($owner); + + $sender = $this->getLoginUser(); + + if ($type == 'approve') { + + $this->handleAnswerPostPoint($answer); + $this->handleAnswerApprovedNotice($answer, $sender); + + $this->eventsManager->fire('Answer:afterApprove', $this, $answer); + + } elseif ($type == 'reject') { + + $options = ReasonModel::answerRejectOptions(); + + if (array_key_exists($reason, $options)) { + $reason = $options[$reason]; + } + + $this->handleAnswerRejectedNotice($answer, $sender, $reason); + + $this->eventsManager->fire('Answer:afterReject', $this, $answer); + } + + return $answer; } protected function findOrFail($id) @@ -86,13 +209,29 @@ class Answer extends Service return $validator->checkAnswer($id); } + protected function findQuestion($id) + { + $questionRepo = new QuestionRepo(); + + return $questionRepo->findById($id); + } + + protected function findUser($id) + { + $userRepo = new UserRepo(); + + return $userRepo->findById($id); + } + protected function handleAnswers($pager) { if ($pager->total_items > 0) { $builder = new AnswerListBuilder(); - $pipeA = $pager->items->toArray(); + $items = $pager->items->toArray(); + + $pipeA = $builder->handleQuestions($items); $pipeB = $builder->handleUsers($pipeA); $pipeC = $builder->objects($pipeB); @@ -102,4 +241,55 @@ class Answer extends Service return $pager; } + protected function recountQuestionAnswers(QuestionModel $question) + { + $questionRepo = new QuestionRepo(); + + $answerCount = $questionRepo->countAnswers($question->id); + + $question->answer_count = $answerCount; + + $question->update(); + } + + protected function recountUserAnswers(UserModel $user) + { + $userRepo = new UserRepo(); + + $answerCount = $userRepo->countAnswers($user->id); + + $user->answer_count = $answerCount; + + $user->update(); + } + + protected function handleQuestionAnsweredNotice(AnswerModel $answer) + { + $notice = new QuestionAnsweredNotice(); + + $notice->handle($answer); + } + + protected function handleAnswerApprovedNotice(AnswerModel $answer, UserModel $sender) + { + $notice = new AnswerApprovedNotice(); + + $notice->handle($answer, $sender); + } + + protected function handleAnswerRejectedNotice(AnswerModel $answer, UserModel $sender, $reason) + { + $notice = new AnswerRejectedNotice(); + + $notice->handle($answer, $sender, $reason); + + } + + protected function handleAnswerPostPoint(AnswerModel $answer) + { + $service = new AnswerPostPointHistory(); + + $service->handle($answer); + } + } diff --git a/app/Http/Admin/Services/Article.php b/app/Http/Admin/Services/Article.php index 84c2d84a..fa39df84 100644 --- a/app/Http/Admin/Services/Article.php +++ b/app/Http/Admin/Services/Article.php @@ -30,7 +30,7 @@ class Article extends Service { $tagRepo = new TagRepo(); - $allTags = $tagRepo->findAll(['published' => 1], 'priority'); + $allTags = $tagRepo->findAll(['published' => 1]); if ($allTags->count() == 0) return []; @@ -78,7 +78,7 @@ class Article extends Service return ArticleModel::sourceTypes(); } - public function getRejectOptions() + public function getReasons() { return ReasonModel::articleRejectOptions(); } @@ -124,13 +124,14 @@ class Article extends Service $article = new ArticleModel(); + $article->published = ArticleModel::PUBLISH_APPROVED; $article->owner_id = $user->id; $article->category_id = $category->id; $article->title = $title; $article->create(); - $this->incrUserArticleCount($user); + $this->recountUserArticles($user); $this->eventsManager->fire('Article:afterCreate', $this, $article); @@ -168,8 +169,8 @@ class Article extends Service } } - if (isset($post['allow_comment'])) { - $data['allow_comment'] = $post['allow_comment']; + if (isset($post['closed'])) { + $data['closed'] = $validator->checkCloseStatus($post['closed']); } if (isset($post['private'])) { @@ -181,7 +182,12 @@ class Article extends Service } if (isset($post['published'])) { + $data['published'] = $validator->checkPublishStatus($post['published']); + + $owner = $this->findUser($article->owner_id); + + $this->recountUserArticles($owner); } if (isset($post['xm_tag_ids'])) { @@ -209,7 +215,7 @@ class Article extends Service $owner = $userRepo->findById($article->owner_id); - $this->decrUserArticleCount($owner); + $this->recountUserArticles($owner); $this->rebuildArticleIndex($article); @@ -230,7 +236,7 @@ class Article extends Service $owner = $userRepo->findById($article->owner_id); - $this->incrUserArticleCount($owner); + $this->recountUserArticles($owner); $this->rebuildArticleIndex($article); @@ -249,14 +255,22 @@ class Article extends Service $validator = new ArticleValidator(); if ($type == 'approve') { + $article->published = ArticleModel::PUBLISH_APPROVED; + } elseif ($type == 'reject') { + $validator->checkRejectReason($reason); + $article->published = ArticleModel::PUBLISH_REJECTED; } $article->update(); + $owner = $this->findUser($article->owner_id); + + $this->recountUserArticles($owner); + $sender = $this->getLoginUser(); if ($type == 'approve') { @@ -296,6 +310,13 @@ class Article extends Service return $validator->checkArticle($id); } + protected function findUser($id) + { + $userRepo = new UserRepo(); + + return $userRepo->findById($id); + } + protected function handleArticles($pager) { if ($pager->total_items > 0) { @@ -315,21 +336,17 @@ class Article extends Service return $pager; } - protected function incrUserArticleCount(UserModel $user) + protected function recountUserArticles(UserModel $user) { - $user->article_count += 1; + $userRepo = new UserRepo(); + + $articleCount = $userRepo->countArticles($user->id); + + $user->article_count = $articleCount; $user->update(); } - protected function decrUserArticleCount(UserModel $user) - { - if ($user->article_count > 0) { - $user->article_count -= 1; - $user->update(); - } - } - protected function rebuildArticleCache(ArticleModel $article) { $cache = new ArticleCache(); diff --git a/app/Http/Admin/Services/AuthNode.php b/app/Http/Admin/Services/AuthNode.php index 656a2bd4..b62914ae 100644 --- a/app/Http/Admin/Services/AuthNode.php +++ b/app/Http/Admin/Services/AuthNode.php @@ -294,7 +294,7 @@ class AuthNode extends Service ], [ 'id' => '1-10', - 'title' => '问答管理', + 'title' => '问题管理', 'type' => 'menu', 'children' => [ [ @@ -341,6 +341,55 @@ class AuthNode extends Service ], ], ], + [ + 'id' => '1-11', + 'title' => '回答管理', + 'type' => 'menu', + 'children' => [ + [ + 'id' => '1-11-1', + 'title' => '回答列表', + 'type' => 'menu', + 'route' => 'admin.answer.list', + ], + [ + 'id' => '1-11-2', + 'title' => '搜索回答', + 'type' => 'menu', + 'route' => 'admin.answer.search', + ], + [ + 'id' => '1-11-3', + 'title' => '添加答案', + 'type' => 'button', + 'route' => 'admin.answer.add', + ], + [ + 'id' => '1-11-4', + 'title' => '编辑回答', + 'type' => 'button', + 'route' => 'admin.answer.edit', + ], + [ + 'id' => '1-11-5', + 'title' => '删除回答', + 'type' => 'button', + 'route' => 'admin.answer.delete', + ], + [ + 'id' => '1-11-9', + 'title' => '回答详情', + 'type' => 'button', + 'route' => 'admin.answer.show', + ], + [ + 'id' => '1-11-10', + 'title' => '审核回答', + 'type' => 'button', + 'route' => 'admin.answer.review', + ], + ], + ], [ 'id' => '1-8', 'title' => '标签管理', @@ -436,6 +485,12 @@ class AuthNode extends Service 'type' => 'menu', 'route' => 'admin.mod.questions', ], + [ + 'id' => '2-10-3', + 'title' => '回答列表', + 'type' => 'menu', + 'route' => 'admin.mod.answers', + ], ], ], [ @@ -900,7 +955,13 @@ class AuthNode extends Service 'title' => '编辑用户', 'type' => 'button', 'route' => 'admin.user.edit', - ] + ], + [ + 'id' => '4-1-5', + 'title' => '在线记录', + 'type' => 'button', + 'route' => 'admin.user.online', + ], ], ], [ diff --git a/app/Http/Admin/Services/Consult.php b/app/Http/Admin/Services/Consult.php index 667b99a7..cb93d9a5 100644 --- a/app/Http/Admin/Services/Consult.php +++ b/app/Http/Admin/Services/Consult.php @@ -4,7 +4,10 @@ namespace App\Http\Admin\Services; use App\Builders\ConsultList as ConsultListBuilder; use App\Library\Paginator\Query as PagerQuery; +use App\Models\Chapter as ChapterModel; use App\Models\Consult as ConsultModel; +use App\Models\Course as CourseModel; +use App\Repos\Chapter as ChapterRepo; use App\Repos\Consult as ConsultRepo; use App\Repos\Course as CourseRepo; use App\Services\Logic\Notice\ConsultReply as ConsultReplyNotice; @@ -74,6 +77,7 @@ class Consult extends Service if (isset($post['published'])) { $data['published'] = $validator->checkPublishStatus($post['published']); + $this->handleItemConsults($consult); } $consult->update($data); @@ -93,13 +97,7 @@ class Consult extends Service $consult->update(); - $courseRepo = new CourseRepo(); - - $course = $courseRepo->findById($consult->course_id); - - $course->consult_count -= 1; - - $course->update(); + $this->handleItemConsults($consult); } public function restoreConsult($id) @@ -110,13 +108,20 @@ class Consult extends Service $consult->update(); - $courseRepo = new CourseRepo(); + $this->handleItemConsults($consult); + } - $course = $courseRepo->findById($consult->course_id); + protected function handleItemConsults(ConsultModel $consult) + { + if ($consult->course_id > 0) { + $course = $this->findCourse($consult->course_id); + $this->recountCourseConsults($course); + } - $course->consult_count += 1; - - $course->update(); + if ($consult->chapter_id > 0) { + $chapter = $this->findChapter($consult->chapter_id); + $this->recountChapterConsults($chapter); + } } protected function handleReplyNotice(ConsultModel $consult) @@ -133,6 +138,42 @@ class Consult extends Service return $validator->checkConsult($id); } + protected function findCourse($id) + { + $courseRepo = new CourseRepo(); + + return $courseRepo->findById($id); + } + + protected function findChapter($id) + { + $chapterRepo = new ChapterRepo(); + + return $chapterRepo->findById($id); + } + + protected function recountCourseConsults(CourseModel $course) + { + $courseRepo = new CourseRepo(); + + $consultCount = $courseRepo->countConsults($course->id); + + $course->consult_count = $consultCount; + + $course->update(); + } + + protected function recountChapterConsults(ChapterModel $chapter) + { + $chapterRepo = new ChapterRepo(); + + $consultCount = $chapterRepo->countConsults($chapter->id); + + $chapter->consult_count = $consultCount; + + $chapter->update(); + } + protected function handleConsults($pager) { if ($pager->total_items > 0) { diff --git a/app/Http/Admin/Services/Moderation.php b/app/Http/Admin/Services/Moderation.php index bef5a221..fbf3cfa7 100644 --- a/app/Http/Admin/Services/Moderation.php +++ b/app/Http/Admin/Services/Moderation.php @@ -2,11 +2,14 @@ namespace App\Http\Admin\Services; +use App\Builders\AnswerList as AnswerListBuilder; use App\Builders\ArticleList as ArticleListBuilder; use App\Builders\QuestionList as QuestionListBuilder; use App\Library\Paginator\Query as PagerQuery; +use App\Models\Answer as AnswerModel; use App\Models\Article as ArticleModel; use App\Models\Question as QuestionModel; +use App\Repos\Answer as AnswerRepo; use App\Repos\Article as ArticleRepo; use App\Repos\Question as QuestionRepo; @@ -53,6 +56,26 @@ class Moderation extends Service return $this->handleQuestions($pager); } + public function getAnswers() + { + $pagerQuery = new PagerQuery(); + + $params = $pagerQuery->getParams(); + + $params['published'] = AnswerModel::PUBLISH_PENDING; + $params['deleted'] = 0; + + $sort = $pagerQuery->getSort(); + $page = $pagerQuery->getPage(); + $limit = $pagerQuery->getLimit(); + + $answerRepo = new AnswerRepo(); + + $pager = $answerRepo->paginate($params, $sort, $page, $limit); + + return $this->handleAnswers($pager); + } + protected function handleArticles($pager) { if ($pager->total_items > 0) { @@ -91,4 +114,22 @@ class Moderation extends Service return $pager; } + protected function handleAnswers($pager) + { + if ($pager->total_items > 0) { + + $builder = new AnswerListBuilder(); + + $items = $pager->items->toArray(); + + $pipeA = $builder->handleQuestions($items); + $pipeB = $builder->handleUsers($pipeA); + $pipeC = $builder->objects($pipeB); + + $pager->items = $pipeC; + } + + return $pager; + } + } diff --git a/app/Http/Admin/Services/Question.php b/app/Http/Admin/Services/Question.php index 1fe04d72..eda8ffd3 100644 --- a/app/Http/Admin/Services/Question.php +++ b/app/Http/Admin/Services/Question.php @@ -29,7 +29,7 @@ class Question extends Service { $tagRepo = new TagRepo(); - $allTags = $tagRepo->findAll(['published' => 1], 'priority'); + $allTags = $tagRepo->findAll(['published' => 1]); if ($allTags->count() == 0) return []; @@ -72,7 +72,7 @@ class Question extends Service return QuestionModel::publishTypes(); } - public function getRejectOptions() + public function getReasons() { return ReasonModel::questionRejectOptions(); } @@ -117,12 +117,13 @@ class Question extends Service $question = new QuestionModel(); + $question->published = QuestionModel::PUBLISH_APPROVED; $question->owner_id = $user->id; $question->title = $title; $question->create(); - $this->incrUserQuestionCount($user); + $this->recountUserQuestions($user); $this->eventsManager->fire('Question:afterCreate', $this, $question); @@ -161,7 +162,12 @@ class Question extends Service } if (isset($post['published'])) { + $data['published'] = $validator->checkPublishStatus($post['published']); + + $owner = $this->findUser($question->owner_id); + + $this->recountUserQuestions($owner); } if (isset($post['xm_tag_ids'])) { @@ -189,7 +195,7 @@ class Question extends Service $owner = $userRepo->findById($question->owner_id); - $this->decrUserQuestionCount($owner); + $this->recountUserQuestions($owner); $this->rebuildQuestionIndex($question); @@ -210,7 +216,7 @@ class Question extends Service $owner = $userRepo->findById($question->owner_id); - $this->incrUserQuestionCount($owner); + $this->recountUserQuestions($owner); $this->rebuildQuestionIndex($question); @@ -237,6 +243,10 @@ class Question extends Service $question->update(); + $owner = $this->findUser($question->owner_id); + + $this->recountUserQuestions($owner); + $sender = $this->getLoginUser(); if ($type == 'approve') { @@ -276,6 +286,13 @@ class Question extends Service return $validator->checkQuestion($id); } + protected function findUser($id) + { + $userRepo = new UserRepo(); + + return $userRepo->findById($id); + } + protected function handleQuestions($pager) { if ($pager->total_items > 0) { @@ -295,21 +312,17 @@ class Question extends Service return $pager; } - protected function incrUserQuestionCount(UserModel $user) + protected function recountUserQuestions(UserModel $user) { - $user->question_count += 1; + $userRepo = new UserRepo(); + + $questionCount = $userRepo->countQuestions($user->id); + + $user->question_count = $questionCount; $user->update(); } - protected function decrUserQuestionCount(UserModel $user) - { - if ($user->question_count > 0) { - $user->question_count -= 1; - $user->update(); - } - } - protected function rebuildQuestionCache(QuestionModel $question) { $cache = new QuestionCache(); diff --git a/app/Http/Admin/Services/Review.php b/app/Http/Admin/Services/Review.php index 5ae43fb6..e04c41fb 100644 --- a/app/Http/Admin/Services/Review.php +++ b/app/Http/Admin/Services/Review.php @@ -4,6 +4,7 @@ namespace App\Http\Admin\Services; use App\Builders\ReviewList as ReviewListBuilder; use App\Library\Paginator\Query as PagerQuery; +use App\Models\Course as CourseModel; use App\Repos\Course as CourseRepo; use App\Repos\Review as ReviewRepo; use App\Services\CourseStat as CourseStatService; @@ -47,6 +48,8 @@ class Review extends Service { $review = $this->findOrFail($id); + $course = $this->findCourse($review->course_id); + $post = $this->request->getPost(); $validator = new ReviewValidator(); @@ -71,11 +74,12 @@ class Review extends Service if (isset($post['published'])) { $data['published'] = $validator->checkPublishStatus($post['published']); + $this->recountCourseReviews($course); } $review->update($data); - $this->updateCourseRating($review->course_id); + $this->updateCourseRating($course); return $review; } @@ -88,7 +92,9 @@ class Review extends Service $review->update(); - $this->decrCourseReviewCount($review->course_id); + $course = $this->findCourse($review->course_id); + + $this->recountCourseReviews($course); } public function restoreReview($id) @@ -99,7 +105,9 @@ class Review extends Service $review->update(); - $this->incrCourseReviewCount($review->course_id); + $course = $this->findCourse($review->course_id); + + $this->recountCourseReviews($course); } protected function findOrFail($id) @@ -109,33 +117,29 @@ class Review extends Service return $validator->checkReview($id); } - protected function incrCourseReviewCount($courseId) + protected function findCourse($id) { $courseRepo = new CourseRepo(); - $course = $courseRepo->findById($courseId); + return $courseRepo->findById($id); + } - $course->review_count -= 1; + protected function recountCourseReviews(CourseModel $course) + { + $courseRepo = new CourseRepo(); + + $reviewCount = $courseRepo->countReviews($course->id); + + $course->review_count = $reviewCount; $course->update(); } - protected function decrCourseReviewCount($courseId) - { - $courseRepo = new CourseRepo(); - - $course = $courseRepo->findById($courseId); - - $course->review_count += 1; - - $course->update(); - } - - protected function updateCourseRating($courseId) + protected function updateCourseRating(CourseModel $course) { $service = new CourseStatService(); - $service->updateRating($courseId); + $service->updateRating($course->id); } protected function handleReviews($pager) diff --git a/app/Http/Admin/Services/User.php b/app/Http/Admin/Services/User.php index 7ebf83c9..ac95ca4e 100644 --- a/app/Http/Admin/Services/User.php +++ b/app/Http/Admin/Services/User.php @@ -10,6 +10,7 @@ use App\Models\Account as AccountModel; use App\Models\ImUser as ImUserModel; use App\Models\User as UserModel; use App\Repos\Account as AccountRepo; +use App\Repos\Online as OnlineRepo; use App\Repos\Role as RoleRepo; use App\Repos\User as UserRepo; use App\Validators\Account as AccountValidator; @@ -30,6 +31,25 @@ class User extends Service return $roleRepo->findAll(['deleted' => 0]); } + public function getOnlineLogs($id) + { + $user = $this->findOrFail($id); + + $pageQuery = new PaginateQuery(); + + $params = $pageQuery->getParams(); + + $params['user_id'] = $user->id; + + $sort = $pageQuery->getSort(); + $page = $pageQuery->getPage(); + $limit = $pageQuery->getLimit(); + + $onlineRepo = new OnlineRepo(); + + return $onlineRepo->paginate($params, $sort, $page, $limit); + } + public function getUsers() { $pageQuery = new PaginateQuery(); diff --git a/app/Http/Admin/Views/answer/add.volt b/app/Http/Admin/Views/answer/add.volt new file mode 100644 index 00000000..4b6a5dcf --- /dev/null +++ b/app/Http/Admin/Views/answer/add.volt @@ -0,0 +1,41 @@ +{% extends 'templates/main.volt' %} + +{% block content %} + +
+ +{% endblock %} + +{% block link_css %} + + {{ css_link('https://cdn.jsdelivr.net/npm/vditor/dist/index.css', false) }} + +{% endblock %} + +{% block include_js %} + + {{ js_include('https://cdn.jsdelivr.net/npm/vditor/dist/index.min.js', false) }} + {{ js_include('admin/js/vditor.js') }} + +{% endblock %} \ No newline at end of file diff --git a/app/Http/Admin/Views/answer/edit.volt b/app/Http/Admin/Views/answer/edit.volt new file mode 100644 index 00000000..d11df81c --- /dev/null +++ b/app/Http/Admin/Views/answer/edit.volt @@ -0,0 +1,40 @@ +{% extends 'templates/main.volt' %} + +{% block content %} + + + +{% endblock %} + +{% block link_css %} + + {{ css_link('https://cdn.jsdelivr.net/npm/vditor/dist/index.css', false) }} + +{% endblock %} + +{% block include_js %} + + {{ js_include('https://cdn.jsdelivr.net/npm/vditor/dist/index.min.js', false) }} + {{ js_include('admin/js/vditor.js') }} + +{% endblock %} \ No newline at end of file diff --git a/app/Http/Admin/Views/answer/list.volt b/app/Http/Admin/Views/answer/list.volt new file mode 100644 index 00000000..697a5f19 --- /dev/null +++ b/app/Http/Admin/Views/answer/list.volt @@ -0,0 +1,64 @@ +{% extends 'templates/main.volt' %} + +{% block content %} + + {{ partial('macros/answer') }} + +信息 | +评论 | +点赞 | +状态 | +操作 | +
---|---|---|---|---|
+
+ 回答:{{ item.summary }} +作者:{{ item.owner.name }} 创建:{{ date('Y-m-d',item.create_time) }} + |
+ {{ item.comment_count }} | +{{ item.like_count }} | +{{ publish_status(item.published) }} | ++ + | +
评论 | +点赞 | 用户 | -终端 | -发布 | +时间 | 操作 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
- 内容:{{ substr(item.content,0,30) }} -时间:{{ date('Y-m-d H:i',item.create_time) }},点赞:{{ item.like_count }} - |
-
- 昵称:{{ item.owner.name }} -编号:{{ item.owner.id }} - |
-
- 类型:{{ client_type(item.client_type) }} -地址:查看 - |
- + | {{ item.content }} | +{{ item.like_count }} | +{{ item.owner.name }} | +{{ date('Y-m-d',item.create_time) }} |
{% if item.deleted == 0 %}
删除
@@ -54,10 +46,4 @@
{{ partial('partials/pager') }}
-{% endblock %}
-
-{% block include_js %}
-
- {{ js_include('admin/js/ip2region.js') }}
-
{% endblock %}
\ No newline at end of file
diff --git a/app/Http/Admin/Views/macros/answer.volt b/app/Http/Admin/Views/macros/answer.volt
new file mode 100644
index 00000000..05de2d9f
--- /dev/null
+++ b/app/Http/Admin/Views/macros/answer.volt
@@ -0,0 +1,11 @@
+{%- macro publish_status(type) %}
+ {% if type == 1 %}
+ 审核中
+ {% elseif type == 2 %}
+ 已发布
+ {% elseif type == 3 %}
+ 未通过
+ {% else %}
+ 未知
+ {% endif %}
+{%- endmacro %}
\ No newline at end of file
diff --git a/app/Http/Admin/Views/macros/article.volt b/app/Http/Admin/Views/macros/article.volt
index 9d31a831..c904f6ba 100644
--- a/app/Http/Admin/Views/macros/article.volt
+++ b/app/Http/Admin/Views/macros/article.volt
@@ -12,11 +12,11 @@
{%- macro source_info(type,url) %}
{% if type == 1 %}
- 原创
+ 原创
{% elseif type == 2 %}
- 转载
+ 转载
{% elseif type == 3 %}
- 翻译
+ 翻译
{% else %}
N/A
{% endif %}
diff --git a/app/Http/Admin/Views/moderation/answers.volt b/app/Http/Admin/Views/moderation/answers.volt
new file mode 100644
index 00000000..ffeab7d9
--- /dev/null
+++ b/app/Http/Admin/Views/moderation/answers.volt
@@ -0,0 +1,55 @@
+{% extends 'templates/main.volt' %}
+
+{% block content %}
+
+ {{ partial('macros/answer') }}
+
+
+
+
+
+
+
+
@@ -18,14 +17,12 @@
文章 |
作者 |
- 终端 |
时间 |
操作 |
- |
- 标题:{{ item.title }} +标题:{{ item.title }} {{ source_info(item.source_type,item.source_url) }} 编号:{{ item.owner.id }}
- |
- 类型:{{ client_type(item.client_type) }} - -
- {% if item.update_time > 0 %}
- {{ date('Y-m-d H:i:s',item.update_time) }}
- {% else %}
- {{ date('Y-m-d H:i:s',item.create_time) }}
- {% endif %}
- |
+ {{ date('Y-m-d H:i',item.create_time) }} |
详情
|
@@ -69,10 +55,4 @@
{{ partial('partials/pager') }}
-{% endblock %}
-
-{% block include_js %}
-
- {{ js_include('admin/js/ip2region.js') }}
-
{% endblock %}
\ No newline at end of file
diff --git a/app/Http/Admin/Views/moderation/questions.volt b/app/Http/Admin/Views/moderation/questions.volt
index 6e45647a..4d0a0a6e 100644
--- a/app/Http/Admin/Views/moderation/questions.volt
+++ b/app/Http/Admin/Views/moderation/questions.volt
@@ -2,7 +2,6 @@
{% block content %}
- {{ partial('macros/common') }}
{{ partial('macros/question') }}
@@ -18,14 +17,12 @@
问题 |
作者 |
- 终端 |
时间 |
操作 |
编号:{{ item.owner.id }} -
- |
- 类型:{{ client_type(item.client_type) }} - -
- {% if item.update_time > 0 %}
- {{ date('Y-m-d H:i:s',item.update_time) }}
- {% else %}
- {{ date('Y-m-d H:i:s',item.create_time) }}
- {% endif %}
- |
+ {{ date('Y-m-d H:i',item.create_time) }} |
详情
|
@@ -68,10 +55,4 @@
{{ partial('partials/pager') }}
-{% endblock %}
-
-{% block include_js %}
-
- {{ js_include('admin/js/ip2region.js') }}
-
{% endblock %}
\ No newline at end of file
diff --git a/app/Http/Admin/Views/question/list.volt b/app/Http/Admin/Views/question/list.volt
index 7d8d209a..cfabc02a 100644
--- a/app/Http/Admin/Views/question/list.volt
+++ b/app/Http/Admin/Views/question/list.volt
@@ -37,12 +37,12 @@
问题 |
- 状态 |
- 浏览 |
回答 |
+ 浏览 |
点赞 |
收藏 |
- 讨论 |
+ 状态 |
+ 关闭 |
操作 |
|
- 标题:{{ item.title }}({{ item.id }}) @@ -72,12 +73,12 @@ 创建:{{ date('Y-m-d',item.create_time) }}{{ publish_status(item.published) }} |
- {{ item.view_count }} |
{{ item.answer_count }} |
+ {{ item.view_count }} |
{{ item.like_count }} |
{{ item.favorite_count }} |
-
+ | {{ publish_status(item.published) }} |
+
|
|
@@ -117,11 +119,11 @@
var form = layui.form;
var layer = layui.layer;
- form.on('switch(discuss)', function (data) {
+ form.on('switch(closed)', function (data) {
var checked = $(this).is(':checked');
- var allowDiscuss = checked ? 1 : 0;
+ var closed = checked ? 1 : 0;
var url = $(this).data('url');
- var tips = allowDiscuss === 1 ? '确定要开启讨论?' : '确定要关闭讨论?';
+ var tips = closed === 1 ? '确定要关闭讨论?' : '确定要开启讨论?';
layer.confirm(tips, function () {
$.ajax({
type: 'POST',
diff --git a/app/Http/Admin/Views/question/review.volt b/app/Http/Admin/Views/question/review.volt
index 8ad1193b..e1491b8a 100644
--- a/app/Http/Admin/Views/question/review.volt
+++ b/app/Http/Admin/Views/question/review.volt
@@ -36,7 +36,7 @@
diff --git a/app/Http/Admin/Views/user/list.volt b/app/Http/Admin/Views/user/list.volt
index a9ff78cd..76ea12ba 100644
--- a/app/Http/Admin/Views/user/list.volt
+++ b/app/Http/Admin/Views/user/list.volt
@@ -33,6 +33,7 @@
用户角色 |
课程 |
文章 |
- 收藏 |
+ 提问 |
+ 回答 |
活跃时间 |
注册时间 |
操作 |
@@ -51,6 +53,7 @@
{% for item in pager.items %}
{% set preview_url = url({'for':'home.user.show','id':item.id}) %}
+ {% set online_url = url({'for':'admin.user.online','id':item.id}) %}
{% set edit_url = url({'for':'admin.user.edit','id':item.id}) %}
@@ -71,15 +74,17 @@
|
{{ item.course_count }} |
{{ item.article_count }} |
- {{ item.favorite_count }} |
+ {{ item.question_count }} |
+ {{ item.answer_count }} |
{{ date('Y-m-d',item.active_time) }} |
{{ date('Y-m-d',item.create_time) }} |
|
@@ -90,4 +95,29 @@
{{ partial('partials/pager') }}
+{% endblock %}
+
+{% block inline_js %}
+
+
+
{% endblock %}
\ No newline at end of file
diff --git a/app/Http/Admin/Views/user/online.volt b/app/Http/Admin/Views/user/online.volt
new file mode 100644
index 00000000..86f0af78
--- /dev/null
+++ b/app/Http/Admin/Views/user/online.volt
@@ -0,0 +1,42 @@
+{% extends 'templates/main.volt' %}
+
+{% block content %}
+
+ {{ partial('macros/common') }}
+
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/app/Http/Home/Views/article/edit.volt b/app/Http/Home/Views/article/edit.volt
index e19cc01b..f88d3a5f 100644
--- a/app/Http/Home/Views/article/edit.volt
+++ b/app/Http/Home/Views/article/edit.volt
@@ -67,10 +67,10 @@
适合作为回答的+
不该作为回答的+
-
+
-
-
+
+
diff --git a/app/Http/Home/Views/article/show.volt b/app/Http/Home/Views/article/show.volt
index b152742d..7b145569 100644
--- a/app/Http/Home/Views/article/show.volt
+++ b/app/Http/Home/Views/article/show.volt
@@ -65,7 +65,7 @@
{% endif %}
- {% if article.allow_comment == 1 %}
+ {% if article.closed == 0 %}
{{ partial('article/comment') }}
diff --git a/app/Http/Home/Views/macros/notification.volt b/app/Http/Home/Views/macros/notification.volt
index 67415610..1b8e7171 100644
--- a/app/Http/Home/Views/macros/notification.volt
+++ b/app/Http/Home/Views/macros/notification.volt
@@ -16,7 +16,7 @@
评价内容:{{ info.review.content }} {% elseif type == 184 %} {% set article_url = url({'for':'home.article.show','id':info.article.id}) %} -你的文章 {{ info.article.title }} 通过了审核 +你的文章 {{ info.article.title }} 审核已通过 {% elseif type == 185 %} {% set article_url = url({'for':'home.article.show','id':info.article.id}) %}你的文章 {{ info.article.title }} 审核未通过 @@ -33,7 +33,7 @@{{ sender.name }} 喜欢了你的文章 {{ info.article.title }} {% elseif type == 204 %} {% set question_url = url({'for':'home.question.show','id':info.question.id}) %} -你的提问 {{ info.question.title }} 通过了审核 +你的提问 {{ info.question.title }} 审核已通过 {% elseif type == 205 %} {% set question_url = url({'for':'home.question.show','id':info.question.id}) %}你的提问 {{ info.question.title }} 审核未通过 @@ -48,12 +48,18 @@ {% elseif type == 209 %} {% set question_url = url({'for':'home.question.show','id':info.question.id}) %}{{ sender.name }} 喜欢了你的问题 {{ info.question.title }} - {% elseif type == 209 %} + {% elseif type == 224 %} {% set question_url = url({'for':'home.question.show','id':info.question.id}) %} -{{ sender.name }} 喜欢了你的问题 {{ info.question.title }} +你对问题 {{ info.question.title }} 的回答,审核已通过 +回答内容:{{ info.answer.summary }} + {% elseif type == 225 %} + {% set question_url = url({'for':'home.question.show','id':info.question.id}) %} +你对问题 {{ info.question.title }} 的回答,审核未通过 +回答内容:{{ info.answer.summary }} {% elseif type == 228 %} {% set question_url = url({'for':'home.question.show','id':info.question.id}) %}{{ sender.name }} 喜欢了你对问题 {{ info.question.title }} 的回答 +回答内容:{{ info.answer.summary }} {% elseif type == 506 %}{{ sender.name }} 回复了你的评论:{{ info.comment.content }} 回复内容:{{ info.reply.content }} diff --git a/app/Http/Home/Views/question/show.volt b/app/Http/Home/Views/question/show.volt index 985319dc..da806f6a 100644 --- a/app/Http/Home/Views/question/show.volt +++ b/app/Http/Home/Views/question/show.volt @@ -59,21 +59,21 @@ {% endif %} -
- {{ partial('question/answer_tips') }}
+
+ {% if question.me.answered == 0 %}
+
+ {% endif %}
{% if question.answer_count > 0 %}
-
-
diff --git a/app/Library/AppInfo.php b/app/Library/AppInfo.php
index e20d18d7..757a4408 100644
--- a/app/Library/AppInfo.php
+++ b/app/Library/AppInfo.php
@@ -11,7 +11,7 @@ class AppInfo
protected $link = 'https://koogua.com';
- protected $version = '1.3.3';
+ protected $version = '1.3.4';
public function __get($name)
{
diff --git a/app/Models/Article.php b/app/Models/Article.php
index 7f03e9b4..644696cf 100644
--- a/app/Models/Article.php
+++ b/app/Models/Article.php
@@ -144,11 +144,11 @@ class Article extends Model
public $deleted = 0;
/**
- * 允许评论
+ * 关闭标识
*
* @var int
*/
- public $allow_comment = 1;
+ public $closed = 0;
/**
* 文字数
diff --git a/app/Models/Reason.php b/app/Models/Reason.php
index ef5c569d..9b1ea57c 100644
--- a/app/Models/Reason.php
+++ b/app/Models/Reason.php
@@ -41,4 +41,20 @@ class Reason
];
}
+ public static function answerRejectOptions()
+ {
+ return [
+ 101 => '答非所问',
+ 102 => '内容质量差',
+ 103 => '内容不实',
+ 104 => '低俗色情',
+ 105 => '广告软文',
+ 106 => '恶意对比',
+ 107 => '涉嫌歧视,恶意抹黑',
+ 108 => '配图引起不适',
+ 109 => '内容涉嫌违法',
+ 110 => '其它问题',
+ ];
+ }
+
}
\ No newline at end of file
diff --git a/app/Repos/Answer.php b/app/Repos/Answer.php
index 2339c001..8a036a3a 100644
--- a/app/Repos/Answer.php
+++ b/app/Repos/Answer.php
@@ -90,13 +90,16 @@ class Answer extends Repository
public function countAnswers()
{
- return (int)AnswerModel::count(['conditions' => 'deleted = 0']);
+ return (int)AnswerModel::count([
+ 'conditions' => 'published = :published: AND deleted = 0',
+ 'bind' => ['published' => AnswerModel::PUBLISH_APPROVED],
+ ]);
}
public function countLikes($answerId)
{
return (int)AnswerLikeModel::count([
- 'conditions' => 'answer_id = :answer_id:',
+ 'conditions' => 'answer_id = :answer_id: AND deleted = 0',
'bind' => ['answer_id' => $answerId],
]);
}
diff --git a/app/Repos/Article.php b/app/Repos/Article.php
index 0ff01ff4..bbd4f36e 100644
--- a/app/Repos/Article.php
+++ b/app/Repos/Article.php
@@ -64,6 +64,10 @@ class Article extends Repository
$builder->andWhere('published = :published:', ['published' => $where['published']]);
}
+ if (isset($where['closed'])) {
+ $builder->andWhere('closed = :closed:', ['closed' => $where['closed']]);
+ }
+
if (isset($where['deleted'])) {
$builder->andWhere('deleted = :deleted:', ['deleted' => $where['deleted']]);
}
@@ -79,9 +83,6 @@ class Article extends Repository
case 'popular':
$orderBy = 'score DESC';
break;
- case 'comment':
- $orderBy = 'comment_count DESC';
- break;
default:
$orderBy = 'id DESC';
break;
@@ -146,15 +147,15 @@ class Article extends Repository
public function countComments($articleId)
{
return (int)CommentModel::count([
- 'conditions' => 'item_id = ?1 AND item_type = ?2 AND deleted = 0',
- 'bind' => [1 => $articleId, 2 => CommentModel::ITEM_ARTICLE],
+ 'conditions' => 'item_id = ?1 AND item_type = ?2 AND published = ?3 AND deleted = 0',
+ 'bind' => [1 => $articleId, 2 => CommentModel::ITEM_ARTICLE, 3 => CommentModel::PUBLISH_APPROVED],
]);
}
public function countLikes($articleId)
{
return (int)ArticleLikeModel::count([
- 'conditions' => 'article_id = :article_id:',
+ 'conditions' => 'article_id = :article_id: AND deleted = 0',
'bind' => ['article_id' => $articleId],
]);
}
@@ -162,7 +163,7 @@ class Article extends Repository
public function countFavorites($articleId)
{
return (int)ArticleFavoriteModel::count([
- 'conditions' => 'article_id = :article_id:',
+ 'conditions' => 'article_id = :article_id: AND deleted = 0',
'bind' => ['article_id' => $articleId],
]);
}
diff --git a/app/Repos/Chapter.php b/app/Repos/Chapter.php
index e67fa3ef..7e26cef0 100644
--- a/app/Repos/Chapter.php
+++ b/app/Repos/Chapter.php
@@ -10,6 +10,7 @@ use App\Models\ChapterRead as ChapterReadModel;
use App\Models\ChapterUser as ChapterUserModel;
use App\Models\ChapterVod as ChapterVodModel;
use App\Models\Comment as CommentModel;
+use App\Models\Consult as ConsultModel;
use Phalcon\Mvc\Model;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;
@@ -161,6 +162,14 @@ class Chapter extends Repository
]);
}
+ public function countConsults($chapterId)
+ {
+ return (int)ConsultModel::count([
+ 'conditions' => 'chapter_id = :chapter_id: AND published = 1 AND deleted = 0',
+ 'bind' => ['chapter_id' => $chapterId],
+ ]);
+ }
+
public function countUsers($chapterId)
{
return (int)ChapterUserModel::count([
diff --git a/app/Repos/Course.php b/app/Repos/Course.php
index 581c80a8..750afae0 100644
--- a/app/Repos/Course.php
+++ b/app/Repos/Course.php
@@ -294,7 +294,9 @@ class Course extends Repository
public function countCourses()
{
- return (int)CourseModel::count(['conditions' => 'deleted = 0']);
+ return (int)CourseModel::count([
+ 'conditions' => 'published = 1 AND deleted = 0',
+ ]);
}
public function countLessons($courseId)
@@ -324,7 +326,7 @@ class Course extends Repository
public function countConsults($courseId)
{
return (int)ConsultModel::count([
- 'conditions' => 'course_id = :course_id: AND published = 1',
+ 'conditions' => 'course_id = :course_id: AND published = 1 AND deleted = 0',
'bind' => ['course_id' => $courseId],
]);
}
@@ -332,7 +334,7 @@ class Course extends Repository
public function countReviews($courseId)
{
return (int)ReviewModel::count([
- 'conditions' => 'course_id = :course_id: AND published = 1',
+ 'conditions' => 'course_id = :course_id: AND published = 1 AND deleted = 0',
'bind' => ['course_id' => $courseId],
]);
}
@@ -340,7 +342,7 @@ class Course extends Repository
public function countFavorites($courseId)
{
return (int)CourseFavoriteModel::count([
- 'conditions' => 'course_id = :course_id:',
+ 'conditions' => 'course_id = :course_id: AND deleted = 0',
'bind' => ['course_id' => $courseId],
]);
}
diff --git a/app/Repos/Online.php b/app/Repos/Online.php
index 7a16ce30..eebad626 100644
--- a/app/Repos/Online.php
+++ b/app/Repos/Online.php
@@ -2,6 +2,7 @@
namespace App\Repos;
+use App\Library\Paginator\Adapter\QueryBuilder as PagerQueryBuilder;
use App\Models\Online as OnlineModel;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;
@@ -9,6 +10,38 @@ use Phalcon\Mvc\Model\ResultsetInterface;
class Online extends Repository
{
+ public function paginate($where = [], $sort = 'latest', $page = 1, $limit = 15)
+ {
+ $builder = $this->modelsManager->createBuilder();
+
+ $builder->from(OnlineModel::class);
+
+ $builder->where('1 = 1');
+
+ if (!empty($where['user_id'])) {
+ $builder->andWhere('user_id = :user_id:', ['user_id' => $where['user_id']]);
+ }
+
+ switch ($sort) {
+ case 'oldest':
+ $orderBy = 'id ASC';
+ break;
+ default:
+ $orderBy = 'id DESC';
+ break;
+ }
+
+ $builder->orderBy($orderBy);
+
+ $pager = new PagerQueryBuilder([
+ 'builder' => $builder,
+ 'page' => $page,
+ 'limit' => $limit,
+ ]);
+
+ return $pager->paginate();
+ }
+
/**
* @param int $userId
* @param string $activeDate
diff --git a/app/Repos/Question.php b/app/Repos/Question.php
index 4434775a..0e0c99dd 100644
--- a/app/Repos/Question.php
+++ b/app/Repos/Question.php
@@ -147,29 +147,32 @@ class Question extends Repository
public function countQuestions()
{
- return (int)QuestionModel::count(['conditions' => 'deleted = 0']);
+ return (int)QuestionModel::count([
+ 'conditions' => 'published = :published: AND deleted = 0',
+ 'bind' => ['published' => QuestionModel::PUBLISH_APPROVED],
+ ]);
}
public function countAnswers($questionId)
{
return (int)AnswerModel::count([
- 'conditions' => 'question_id = :question_id: AND deleted = 0',
- 'bind' => ['question_id' => $questionId],
+ 'conditions' => 'question_id = ?1 AND published = ?2 AND deleted = 0',
+ 'bind' => [1 => $questionId, 2 => AnswerModel::PUBLISH_APPROVED],
]);
}
public function countComments($questionId)
{
return (int)CommentModel::count([
- 'conditions' => 'item_id = ?1 AND item_type = ?2 AND deleted = 0',
- 'bind' => [1 => $questionId, 2 => CommentModel::ITEM_QUESTION],
+ 'conditions' => 'item_id = ?1 AND item_type = ?2 AND published = ?3 AND deleted = 0',
+ 'bind' => [1 => $questionId, 2 => CommentModel::ITEM_QUESTION, 3 => CommentModel::PUBLISH_APPROVED],
]);
}
public function countFavorites($questionId)
{
return (int)QuestionFavoriteModel::count([
- 'conditions' => 'question_id = :question_id:',
+ 'conditions' => 'question_id = :question_id: AND deleted = 0',
'bind' => ['question_id' => $questionId],
]);
}
@@ -177,7 +180,7 @@ class Question extends Repository
public function countLikes($questionId)
{
return (int)QuestionLikeModel::count([
- 'conditions' => 'question_id = :question_id:',
+ 'conditions' => 'question_id = :question_id: AND deleted = 0',
'bind' => ['question_id' => $questionId],
]);
}
diff --git a/app/Repos/User.php b/app/Repos/User.php
index d1199ce0..c6b19ea9 100644
--- a/app/Repos/User.php
+++ b/app/Repos/User.php
@@ -178,31 +178,31 @@ class User extends Repository
public function countArticles($userId)
{
return (int)ArticleModel::count([
- 'conditions' => 'owner_id = :owner_id: AND published = 1',
- 'bind' => ['owner_id' => $userId],
+ 'conditions' => 'owner_id = ?1 AND published = ?2',
+ 'bind' => [1 => $userId, 2 => ArticleModel::PUBLISH_APPROVED],
]);
}
public function countQuestions($userId)
{
return (int)QuestionModel::count([
- 'conditions' => 'owner_id = :owner_id: AND published = 1',
- 'bind' => ['owner_id' => $userId],
+ 'conditions' => 'owner_id = ?1 AND published = ?2',
+ 'bind' => [1 => $userId, 2 => QuestionModel::PUBLISH_APPROVED],
]);
}
public function countAnswers($userId)
{
return (int)AnswerModel::count([
- 'conditions' => 'owner_id = :owner_id: AND published = 1',
- 'bind' => ['owner_id' => $userId],
+ 'conditions' => 'owner_id = ?1 AND published = ?2',
+ 'bind' => [1 => $userId, 2 => AnswerModel::PUBLISH_APPROVED],
]);
}
public function countCourseFavorites($userId)
{
return (int)CourseFavoriteModel::count([
- 'conditions' => 'user_id = :user_id:',
+ 'conditions' => 'user_id = :user_id: AND deleted = 0',
'bind' => ['user_id' => $userId],
]);
}
@@ -210,7 +210,7 @@ class User extends Repository
public function countArticleFavorites($userId)
{
return (int)ArticleFavoriteModel::count([
- 'conditions' => 'user_id = :user_id:',
+ 'conditions' => 'user_id = :user_id: AND deleted = 0',
'bind' => ['user_id' => $userId],
]);
}
diff --git a/app/Services/Logic/Answer/AnswerCreate.php b/app/Services/Logic/Answer/AnswerCreate.php
index d7d6bf18..ec848439 100644
--- a/app/Services/Logic/Answer/AnswerCreate.php
+++ b/app/Services/Logic/Answer/AnswerCreate.php
@@ -5,11 +5,14 @@ namespace App\Services\Logic\Answer;
use App\Models\Answer as AnswerModel;
use App\Models\Question as QuestionModel;
use App\Models\User as UserModel;
+use App\Repos\Question as QuestionRepo;
+use App\Repos\User as UserRepo;
use App\Services\Logic\AnswerTrait;
use App\Services\Logic\Notice\System\QuestionAnswered as QuestionAnsweredNotice;
use App\Services\Logic\Point\History\AnswerPost as AnswerPostPointHistory;
use App\Services\Logic\QuestionTrait;
use App\Services\Logic\Service as LogicService;
+use App\Services\Sync\QuestionScore as QuestionScoreSync;
use App\Traits\Client as ClientTrait;
use App\Validators\Answer as AnswerValidator;
@@ -28,16 +31,13 @@ class AnswerCreate extends LogicService
$user = $this->getLoginUser();
- $answer = new AnswerModel();
-
$validator = new AnswerValidator();
$validator->checkIfAllowAnswer($question, $user);
- /**
- * @todo 引入自动审核机制
- */
- $answer->published = AnswerModel::PUBLISH_APPROVED;
+ $answer = new AnswerModel();
+
+ $answer->published = $this->getPublishStatus($user);
$answer->content = $validator->checkContent($post['content']);
$answer->client_type = $this->getClientType();
@@ -47,48 +47,74 @@ class AnswerCreate extends LogicService
$answer->create();
- $question->last_answer_id = $answer->id;
- $question->last_replier_id = $answer->owner_id;
- $question->last_reply_time = $answer->create_time;
+ $this->recountQuestionAnswers($question);
+ $this->recountUserAnswers($user);
- $question->update();
+ if ($answer->published == AnswerModel::PUBLISH_APPROVED) {
- $this->incrUserAnswerCount($user);
+ $question->last_answer_id = $answer->id;
+ $question->last_replier_id = $answer->owner_id;
+ $question->last_reply_time = $answer->create_time;
- $this->incrQuestionAnswerCount($question);
+ $question->update();
- $this->handleAnswerPoint($answer);
-
- $this->handleAnswerNotice($answer);
+ $this->syncQuestionScore($question);
+ $this->handleAnswerPostPoint($answer);
+ $this->handleQuestionAnsweredNotice($answer);
+ }
$this->eventsManager->fire('Answer:afterCreate', $this, $answer);
return $answer;
}
- protected function incrQuestionAnswerCount(QuestionModel $question)
+ protected function getPublishStatus(UserModel $user)
{
- $question->answer_count += 1;
+ return $user->answer_count > 2 ? AnswerModel::PUBLISH_APPROVED : AnswerModel::PUBLISH_PENDING;
+ }
+
+ protected function recountQuestionAnswers(QuestionModel $question)
+ {
+ $questionRepo = new QuestionRepo();
+
+ $answerCount = $questionRepo->countAnswers($question->id);
+
+ $question->answer_count = $answerCount;
$question->update();
}
- protected function incrUserAnswerCount(UserModel $user)
+ protected function recountUserAnswers(UserModel $user)
{
- $user->answer_count += 1;
+ $userRepo = new UserRepo();
+
+ $answerCount = $userRepo->countAnswers($user->id);
+
+ $user->answer_count = $answerCount;
$user->update();
}
- protected function handleAnswerNotice(AnswerModel $answer)
+ protected function syncQuestionScore(QuestionModel $question)
{
+ $sync = new QuestionScoreSync();
+
+ $sync->addItem($question->id);
+ }
+
+ protected function handleQuestionAnsweredNotice(AnswerModel $answer)
+ {
+ if ($answer->published != AnswerModel::PUBLISH_APPROVED) return;
+
$notice = new QuestionAnsweredNotice();
$notice->handle($answer);
}
- protected function handleAnswerPoint(AnswerModel $answer)
+ protected function handleAnswerPostPoint(AnswerModel $answer)
{
+ if ($answer->published != AnswerModel::PUBLISH_APPROVED) return;
+
$service = new AnswerPostPointHistory();
$service->handle($answer);
diff --git a/app/Services/Logic/Answer/AnswerDelete.php b/app/Services/Logic/Answer/AnswerDelete.php
index ee9f52bf..a707efb3 100644
--- a/app/Services/Logic/Answer/AnswerDelete.php
+++ b/app/Services/Logic/Answer/AnswerDelete.php
@@ -4,13 +4,14 @@ namespace App\Services\Logic\Answer;
use App\Models\Question as QuestionModel;
use App\Models\User as UserModel;
+use App\Repos\Question as QuestionRepo;
+use App\Repos\User as UserRepo;
use App\Services\Logic\AnswerTrait;
-use App\Services\Logic\Question\QuestionScore as QuestionScoreService;
use App\Services\Logic\QuestionTrait;
use App\Services\Logic\Service as LogicService;
+use App\Services\Sync\QuestionScore as QuestionScoreSync;
use App\Validators\Answer as AnswerValidator;
-
class AnswerDelete extends LogicService
{
@@ -29,40 +30,47 @@ class AnswerDelete extends LogicService
$validator->checkOwner($user->id, $answer->owner_id);
+ $validator->checkIfAllowDelete($answer);
+
$answer->deleted = 1;
$answer->update();
- $this->decrQuestionAnswerCount($question);
-
- $this->updateQuestionScore($question);
+ $this->recountQuestionAnswers($question);
+ $this->recountUserAnswers($user);
$this->eventsManager->fire('Answer:afterDelete', $this, $answer);
return $answer;
}
- protected function decrUserAnswerCount(UserModel $user)
+ protected function recountQuestionAnswers(QuestionModel $question)
{
- if ($user->answer_count > 0) {
- $user->answer_count -= 1;
- $user->update();
- }
+ $questionRepo = new QuestionRepo();
+
+ $answerCount = $questionRepo->countAnswers($question->id);
+
+ $question->answer_count = $answerCount;
+
+ $question->update();
}
- protected function decrQuestionAnswerCount(QuestionModel $question)
+ protected function recountUserAnswers(UserModel $user)
{
- if ($question->answer_count > 0) {
- $question->answer_count -= 1;
- $question->update();
- }
+ $userRepo = new UserRepo();
+
+ $answerCount = $userRepo->countAnswers($user->id);
+
+ $user->answer_count = $answerCount;
+
+ $user->update();
}
- protected function updateQuestionScore(QuestionModel $question)
+ protected function syncQuestionScore(QuestionModel $question)
{
- $service = new QuestionScoreService();
+ $sync = new QuestionScoreSync();
- $service->handle($question);
+ $sync->addItem($question->id);
}
}
diff --git a/app/Services/Logic/Answer/AnswerUpdate.php b/app/Services/Logic/Answer/AnswerUpdate.php
index deaf5c75..2ecf551b 100644
--- a/app/Services/Logic/Answer/AnswerUpdate.php
+++ b/app/Services/Logic/Answer/AnswerUpdate.php
@@ -23,13 +23,13 @@ class AnswerUpdate extends LogicService
$answer = $this->checkAnswer($id);
- $question = $this->checkQuestion($answer->question_id);
-
$user = $this->getLoginUser();
$validator = new AnswerValidator();
- $validator->checkIfAllowEdit($answer, $user);
+ $validator->checkOwner($user->id, $answer->owner_id);
+
+ $validator->checkIfAllowEdit($answer);
$answer->content = $validator->checkContent($post['content']);
$answer->client_type = $this->getClientType();
@@ -37,8 +37,6 @@ class AnswerUpdate extends LogicService
$answer->update();
- $this->syncQuestionScore($question);
-
$this->eventsManager->fire('Answer:afterUpdate', $this, $answer);
return $answer;
diff --git a/app/Services/Logic/Article/ArticleCreate.php b/app/Services/Logic/Article/ArticleCreate.php
index 17b3faaa..616d7857 100644
--- a/app/Services/Logic/Article/ArticleCreate.php
+++ b/app/Services/Logic/Article/ArticleCreate.php
@@ -4,6 +4,7 @@ namespace App\Services\Logic\Article;
use App\Models\Article as ArticleModel;
use App\Models\User as UserModel;
+use App\Repos\User as UserRepo;
use App\Services\Logic\Service as LogicService;
class ArticleCreate extends LogicService
@@ -21,6 +22,7 @@ class ArticleCreate extends LogicService
$data = $this->handlePostData($post);
+ $data['published'] = $this->getPublishStatus($user);
$data['owner_id'] = $user->id;
$article->create($data);
@@ -29,16 +31,25 @@ class ArticleCreate extends LogicService
$this->saveTags($article, $post['xm_tag_ids']);
}
- $this->incrUserArticleCount($user);
+ $this->recountUserArticles($user);
$this->eventsManager->fire('Article:afterCreate', $this, $article);
return $article;
}
- protected function incrUserArticleCount(UserModel $user)
+ protected function getPublishStatus(UserModel $user)
{
- $user->article_count += 1;
+ return $user->article_count > 100 ? ArticleModel::PUBLISH_APPROVED : ArticleModel::PUBLISH_PENDING;
+ }
+
+ protected function recountUserArticles(UserModel $user)
+ {
+ $userRepo = new UserRepo();
+
+ $articleCount = $userRepo->countArticles($user->id);
+
+ $user->article_count = $articleCount;
$user->update();
}
diff --git a/app/Services/Logic/Article/ArticleDataTrait.php b/app/Services/Logic/Article/ArticleDataTrait.php
index 379e0bd6..8dc2bfba 100644
--- a/app/Services/Logic/Article/ArticleDataTrait.php
+++ b/app/Services/Logic/Article/ArticleDataTrait.php
@@ -37,8 +37,8 @@ trait ArticleDataTrait
}
}
- if (isset($post['allow_comment'])) {
- $data['allow_comment'] = $validator->checkAllowCommentStatus($post['allow_comment']);
+ if (isset($post['closed'])) {
+ $data['closed'] = $validator->checkCloseStatus($post['closed']);
}
if (isset($post['private'])) {
diff --git a/app/Services/Logic/Article/ArticleDelete.php b/app/Services/Logic/Article/ArticleDelete.php
index ebb85128..3affcb7c 100644
--- a/app/Services/Logic/Article/ArticleDelete.php
+++ b/app/Services/Logic/Article/ArticleDelete.php
@@ -4,6 +4,7 @@ namespace App\Services\Logic\Article;
use App\Models\Article as ArticleModel;
use App\Models\User as UserModel;
+use App\Repos\User as UserRepo;
use App\Services\Logic\ArticleTrait;
use App\Services\Logic\Service as LogicService;
use App\Services\Sync\ArticleIndex as ArticleIndexSync;
@@ -28,19 +29,22 @@ class ArticleDelete extends LogicService
$article->update();
- $this->decrUserArticleCount($user);
+ $this->recountUserArticles($user);
$this->rebuildArticleIndex($article);
$this->eventsManager->fire('Article:afterDelete', $this, $article);
}
- protected function decrUserArticleCount(UserModel $user)
+ protected function recountUserArticles(UserModel $user)
{
- if ($user->article_count > 0) {
- $user->article_count -= 1;
- $user->update();
- }
+ $userRepo = new UserRepo();
+
+ $articleCount = $userRepo->countArticles($user->id);
+
+ $user->article_count = $articleCount;
+
+ $user->update();
}
protected function rebuildArticleIndex(ArticleModel $article)
diff --git a/app/Services/Logic/Article/ArticleInfo.php b/app/Services/Logic/Article/ArticleInfo.php
index bbf6c933..29d9cb6a 100644
--- a/app/Services/Logic/Article/ArticleInfo.php
+++ b/app/Services/Logic/Article/ArticleInfo.php
@@ -51,7 +51,7 @@ class ArticleInfo extends LogicService
'owner' => $owner,
'me' => $me,
'private' => $article->private,
- 'allow_comment' => $article->allow_comment,
+ 'closed' => $article->closed,
'source_type' => $article->source_type,
'source_url' => $article->source_url,
'word_count' => $article->word_count,
diff --git a/app/Services/Logic/Article/ArticleList.php b/app/Services/Logic/Article/ArticleList.php
index 100b685c..ae58b3ea 100644
--- a/app/Services/Logic/Article/ArticleList.php
+++ b/app/Services/Logic/Article/ArticleList.php
@@ -82,7 +82,7 @@ class ArticleList extends LogicService
'owner' => $owner,
'private' => $article['private'],
'published' => $article['published'],
- 'allow_comment' => $article['allow_comment'],
+ 'closed' => $article['closed'],
'view_count' => $article['view_count'],
'like_count' => $article['like_count'],
'comment_count' => $article['comment_count'],
diff --git a/app/Services/Logic/Consult/ConsultCreate.php b/app/Services/Logic/Consult/ConsultCreate.php
index ff6d8260..6336a490 100644
--- a/app/Services/Logic/Consult/ConsultCreate.php
+++ b/app/Services/Logic/Consult/ConsultCreate.php
@@ -6,6 +6,8 @@ use App\Models\Chapter as ChapterModel;
use App\Models\Consult as ConsultModel;
use App\Models\Course as CourseModel;
use App\Models\User as UserModel;
+use App\Repos\Chapter as ChapterRepo;
+use App\Repos\Course as CourseRepo;
use App\Services\Logic\ChapterTrait;
use App\Services\Logic\CourseTrait;
use App\Services\Logic\Notice\DingTalk\ConsultCreate as ConsultCreateNotice;
@@ -76,10 +78,8 @@ class ConsultCreate extends LogicService
$consult->create();
- $this->incrCourseConsultCount($course);
-
+ $this->recountCourseConsults($course);
$this->incrUserDailyConsultCount($user);
-
$this->handleConsultCreateNotice($consult);
$this->eventsManager->fire('Consult:afterCreate', $this, $consult);
@@ -116,12 +116,9 @@ class ConsultCreate extends LogicService
$consult->create();
- $this->incrCourseConsultCount($course);
-
- $this->incrChapterConsultCount($chapter);
-
+ $this->recountCourseConsults($course);
+ $this->recountChapterConsults($chapter);
$this->incrUserDailyConsultCount($user);
-
$this->handleConsultCreateNotice($consult);
$this->eventsManager->fire('Consult:afterCreate', $this, $consult);
@@ -146,16 +143,24 @@ class ConsultCreate extends LogicService
return $priority;
}
- protected function incrCourseConsultCount(CourseModel $course)
+ protected function recountCourseConsults(CourseModel $course)
{
- $course->consult_count += 1;
+ $courseRepo = new CourseRepo();
+
+ $consultCount = $courseRepo->countConsults($course->id);
+
+ $course->consult_count = $consultCount;
$course->update();
}
- protected function incrChapterConsultCount(ChapterModel $chapter)
+ protected function recountChapterConsults(ChapterModel $chapter)
{
- $chapter->consult_count += 1;
+ $chapterRepo = new ChapterRepo();
+
+ $consultCount = $chapterRepo->countConsults($chapter->id);
+
+ $chapter->consult_count = $consultCount;
$chapter->update();
}
diff --git a/app/Services/Logic/Consult/ConsultDelete.php b/app/Services/Logic/Consult/ConsultDelete.php
index 26aaee0a..42ab290a 100644
--- a/app/Services/Logic/Consult/ConsultDelete.php
+++ b/app/Services/Logic/Consult/ConsultDelete.php
@@ -4,6 +4,8 @@ namespace App\Services\Logic\Consult;
use App\Models\Chapter as ChapterModel;
use App\Models\Course as CourseModel;
+use App\Repos\Chapter as ChapterRepo;
+use App\Repos\Course as CourseRepo;
use App\Services\Logic\ChapterTrait;
use App\Services\Logic\ConsultTrait;
use App\Services\Logic\CourseTrait;
@@ -35,33 +37,39 @@ class ConsultDelete extends LogicService
$course = $this->checkCourse($consult->course_id);
- $this->decrCourseConsultCount($course);
+ $this->recountCourseConsults($course);
}
if ($consult->chapter_id > 0) {
$chapter = $this->checkChapter($consult->chapter_id);
- $this->decrChapterConsultCount($chapter);
+ $this->recountChapterConsults($chapter);
}
$this->eventsManager->fire('Consult:afterDelete', $this, $consult);
}
- protected function decrCourseConsultCount(CourseModel $course)
+ protected function recountCourseConsults(CourseModel $course)
{
- if ($course->consult_count > 0) {
- $course->consult_count -= 1;
- $course->update();
- }
+ $courseRepo = new CourseRepo();
+
+ $consultCount = $courseRepo->countConsults($course->id);
+
+ $course->consult_count = $consultCount;
+
+ $course->update();
}
- protected function decrChapterConsultCount(ChapterModel $chapter)
+ protected function recountChapterConsults(ChapterModel $chapter)
{
- if ($chapter->consult_count > 0) {
- $chapter->consult_count -= 1;
- $chapter->update();
- }
+ $chapterRepo = new ChapterRepo();
+
+ $consultCount = $chapterRepo->countConsults($chapter->id);
+
+ $chapter->consult_count = $consultCount;
+
+ $chapter->update();
}
}
diff --git a/app/Services/Logic/Notice/System/AnswerAccepted.php b/app/Services/Logic/Notice/System/AnswerAccepted.php
index 113b9893..3acd421a 100644
--- a/app/Services/Logic/Notice/System/AnswerAccepted.php
+++ b/app/Services/Logic/Notice/System/AnswerAccepted.php
@@ -13,6 +13,8 @@ class AnswerAccepted extends LogicService
public function handle(AnswerModel $answer, UserModel $sender)
{
+ $answerSummary = kg_substr($answer->summary, 0, 32);
+
$questionRepo = new QuestionRepo();
$question = $questionRepo->findById($answer->question_id);
@@ -25,6 +27,7 @@ class AnswerAccepted extends LogicService
$notification->event_type = NotificationModel::TYPE_ANSWER_ACCEPTED;
$notification->event_info = [
'question' => ['id' => $question->id, 'title' => $question->title],
+ 'answer' => ['id' => $answer->id, 'summary' => $answerSummary],
];
$notification->create();
diff --git a/app/Services/Logic/Notice/System/AnswerApproved.php b/app/Services/Logic/Notice/System/AnswerApproved.php
new file mode 100644
index 00000000..4c882c43
--- /dev/null
+++ b/app/Services/Logic/Notice/System/AnswerApproved.php
@@ -0,0 +1,41 @@
+summary, 0, 32);
+
+ $question = $this->findQuestion($answer->question_id);
+
+ $notification = new NotificationModel();
+
+ $notification->sender_id = $sender->id;
+ $notification->receiver_id = $answer->owner_id;
+ $notification->event_id = $answer->id;
+ $notification->event_type = NotificationModel::TYPE_ANSWER_APPROVED;
+ $notification->event_info = [
+ 'question' => ['id' => $question->id, 'title' => $question->title],
+ 'answer' => ['id' => $answer->id, 'summary' => $answerSummary],
+ ];
+
+ $notification->create();
+ }
+
+ protected function findQuestion($id)
+ {
+ $questionRepo = new QuestionRepo();
+
+ return $questionRepo->findById($id);
+ }
+
+}
diff --git a/app/Services/Logic/Notice/System/AnswerLiked.php b/app/Services/Logic/Notice/System/AnswerLiked.php
index a49bd8c7..40c826ae 100644
--- a/app/Services/Logic/Notice/System/AnswerLiked.php
+++ b/app/Services/Logic/Notice/System/AnswerLiked.php
@@ -13,6 +13,8 @@ class AnswerLiked extends LogicService
public function handle(AnswerModel $answer, UserModel $sender)
{
+ $answerSummary = kg_substr($answer->summary, 0, 32);
+
$questionRepo = new QuestionRepo();
$question = $questionRepo->findById($answer->question_id);
@@ -25,6 +27,7 @@ class AnswerLiked extends LogicService
$notification->event_type = NotificationModel::TYPE_ANSWER_LIKED;
$notification->event_info = [
'question' => ['id' => $question->id, 'title' => $question->title],
+ 'answer' => ['id' => $answer->id, 'summary' => $answerSummary],
];
$notification->create();
diff --git a/app/Services/Logic/Notice/System/AnswerRejected.php b/app/Services/Logic/Notice/System/AnswerRejected.php
new file mode 100644
index 00000000..1df58962
--- /dev/null
+++ b/app/Services/Logic/Notice/System/AnswerRejected.php
@@ -0,0 +1,42 @@
+summary, 0, 32);
+
+ $question = $this->findQuestion($answer->question_id);
+
+ $notification = new NotificationModel();
+
+ $notification->sender_id = $sender->id;
+ $notification->receiver_id = $answer->owner_id;
+ $notification->event_id = $answer->id;
+ $notification->event_type = NotificationModel::TYPE_ANSWER_REJECTED;
+ $notification->event_info = [
+ 'question' => ['id' => $question->id, 'title' => $question->title],
+ 'answer' => ['id' => $answer->id, 'summary' => $answerSummary],
+ 'reason' => $reason,
+ ];
+
+ $notification->create();
+ }
+
+ protected function findQuestion($id)
+ {
+ $questionRepo = new QuestionRepo();
+
+ return $questionRepo->findById($id);
+ }
+
+}
diff --git a/app/Services/Logic/Notice/System/ArticleCommented.php b/app/Services/Logic/Notice/System/ArticleCommented.php
index 4bf1b412..7f5927e7 100644
--- a/app/Services/Logic/Notice/System/ArticleCommented.php
+++ b/app/Services/Logic/Notice/System/ArticleCommented.php
@@ -13,7 +13,7 @@ class ArticleCommented extends LogicService
public function handle(CommentModel $comment)
{
- $comment->content = kg_substr($comment->content, 0, 32);
+ $commentContent = kg_substr($comment->content, 0, 32);
$article = $this->findArticle($comment->item_id);
@@ -25,7 +25,7 @@ class ArticleCommented extends LogicService
$notification->event_type = NotificationModel::TYPE_ARTICLE_COMMENTED;
$notification->event_info = [
'article' => ['id' => $article->id, 'title' => $article->title],
- 'comment' => ['id' => $comment->id, 'content' => $comment->content],
+ 'comment' => ['id' => $comment->id, 'content' => $commentContent],
];
$notification->create();
diff --git a/app/Services/Logic/Notice/System/CommentLiked.php b/app/Services/Logic/Notice/System/CommentLiked.php
index 538f7dfe..8a771b4c 100644
--- a/app/Services/Logic/Notice/System/CommentLiked.php
+++ b/app/Services/Logic/Notice/System/CommentLiked.php
@@ -12,7 +12,7 @@ class CommentLiked extends LogicService
public function handle(CommentModel $comment, UserModel $sender)
{
- $comment->content = kg_substr($comment->content, 0, 32);
+ $commentContent = kg_substr($comment->content, 0, 32);
$notification = new NotificationModel();
@@ -22,7 +22,7 @@ class CommentLiked extends LogicService
$notification->event_type = NotificationModel::TYPE_COMMENT_LIKED;
$notification->event_info = [
'sender' => ['id' => $sender->id, 'name' => $sender->name],
- 'comment' => ['id' => $comment->id, 'content' => $comment->content],
+ 'comment' => ['id' => $comment->id, 'content' => $commentContent],
];
$notification->create();
diff --git a/app/Services/Logic/Notice/System/CommentReplied.php b/app/Services/Logic/Notice/System/CommentReplied.php
index 3c41f672..b4d87513 100644
--- a/app/Services/Logic/Notice/System/CommentReplied.php
+++ b/app/Services/Logic/Notice/System/CommentReplied.php
@@ -13,11 +13,11 @@ class CommentReplied extends LogicService
public function handle(CommentModel $reply)
{
- $reply->content = kg_substr($reply->content, 0, 32);
+ $replyContent = kg_substr($reply->content, 0, 32);
$comment = $this->findComment($reply->parent_id);
- $comment->content = kg_substr($comment->content, 0, 32);
+ $commentContent = kg_substr($comment->content, 0, 32);
$notification = new NotificationModel();
@@ -26,8 +26,8 @@ class CommentReplied extends LogicService
$notification->event_id = $reply->id;
$notification->event_type = NotificationModel::TYPE_COMMENT_REPLIED;
$notification->event_info = [
- 'comment' => ['id' => $comment->id, 'content' => $comment->content],
- 'reply' => ['id' => $reply->id, 'content' => $reply->content],
+ 'comment' => ['id' => $comment->id, 'content' => $commentContent],
+ 'reply' => ['id' => $reply->id, 'content' => $replyContent],
];
$notification->create();
diff --git a/app/Services/Logic/Notice/System/ConsultLiked.php b/app/Services/Logic/Notice/System/ConsultLiked.php
index 759d9661..1503454b 100644
--- a/app/Services/Logic/Notice/System/ConsultLiked.php
+++ b/app/Services/Logic/Notice/System/ConsultLiked.php
@@ -13,7 +13,7 @@ class ConsultLiked extends LogicService
public function handle(ConsultModel $consult, UserModel $sender)
{
- $consult->question = kg_substr($consult->question, 0, 32);
+ $consultQuestion = kg_substr($consult->question, 0, 32);
$course = $this->findCourse($consult->course_id);
@@ -25,7 +25,7 @@ class ConsultLiked extends LogicService
$notification->event_type = NotificationModel::TYPE_CONSULT_LIKED;
$notification->event_info = [
'course' => ['id' => $course->id, 'title' => $course->title],
- 'consult' => ['id' => $consult->id, 'question' => $consult->question],
+ 'consult' => ['id' => $consult->id, 'question' => $consultQuestion],
];
$notification->create();
diff --git a/app/Services/Logic/Notice/System/QuestionAnswered.php b/app/Services/Logic/Notice/System/QuestionAnswered.php
index 0a75087a..a263b376 100644
--- a/app/Services/Logic/Notice/System/QuestionAnswered.php
+++ b/app/Services/Logic/Notice/System/QuestionAnswered.php
@@ -13,6 +13,8 @@ class QuestionAnswered extends LogicService
public function handle(AnswerModel $answer)
{
+ $answerSummary = kg_substr($answer->summary, 0, 32);
+
$question = $this->findQuestion($answer->question_id);
$notification = new NotificationModel();
@@ -23,7 +25,7 @@ class QuestionAnswered extends LogicService
$notification->event_type = NotificationModel::TYPE_QUESTION_ANSWERED;
$notification->event_info = [
'question' => ['id' => $question->id, 'title' => $question->title],
- 'answer' => ['id' => $answer->id, 'summary' => $answer->summary],
+ 'answer' => ['id' => $answer->id, 'summary' => $answerSummary],
];
$notification->create();
diff --git a/app/Services/Logic/Notice/System/ReviewLiked.php b/app/Services/Logic/Notice/System/ReviewLiked.php
index 9de50536..23fce6b9 100644
--- a/app/Services/Logic/Notice/System/ReviewLiked.php
+++ b/app/Services/Logic/Notice/System/ReviewLiked.php
@@ -13,7 +13,7 @@ class ReviewLiked extends LogicService
public function handle(ReviewModel $review, UserModel $sender)
{
- $review->content = kg_substr($review->content, 0, 32);
+ $reviewContent = kg_substr($review->content, 0, 32);
$course = $this->findCourse($review->course_id);
@@ -25,7 +25,7 @@ class ReviewLiked extends LogicService
$notification->event_type = NotificationModel::TYPE_REVIEW_LIKED;
$notification->event_info = [
'course' => ['id' => $course->id, 'title' => $course->title],
- 'review' => ['id' => $review->id, 'content' => $review->content],
+ 'review' => ['id' => $review->id, 'content' => $reviewContent],
];
$notification->create();
diff --git a/app/Services/Logic/Question/QuestionCreate.php b/app/Services/Logic/Question/QuestionCreate.php
index bf0f0cd1..96cd6b92 100644
--- a/app/Services/Logic/Question/QuestionCreate.php
+++ b/app/Services/Logic/Question/QuestionCreate.php
@@ -4,6 +4,7 @@ namespace App\Services\Logic\Question;
use App\Models\Question as QuestionModel;
use App\Models\User as UserModel;
+use App\Repos\User as UserRepo;
use App\Services\Logic\Service as LogicService;
class QuestionCreate extends LogicService
@@ -29,16 +30,25 @@ class QuestionCreate extends LogicService
$this->saveTags($question, $post['xm_tag_ids']);
}
- $this->incrUserQuestionCount($user);
+ $this->recountUserQuestions($user);
$this->eventsManager->fire('Question:afterCreate', $this, $question);
return $question;
}
- protected function incrUserQuestionCount(UserModel $user)
+ protected function getPublishStatus(UserModel $user)
{
- $user->question_count += 1;
+ return $user->question_count > 3 ? QuestionModel::PUBLISH_APPROVED : QuestionModel::PUBLISH_PENDING;
+ }
+
+ protected function recountUserQuestions(UserModel $user)
+ {
+ $userRepo = new UserRepo();
+
+ $questionCount = $userRepo->countQuestions($user->id);
+
+ $user->question_count = $questionCount;
$user->update();
}
diff --git a/app/Services/Logic/Question/QuestionDelete.php b/app/Services/Logic/Question/QuestionDelete.php
index 1409d4e0..85b720bc 100644
--- a/app/Services/Logic/Question/QuestionDelete.php
+++ b/app/Services/Logic/Question/QuestionDelete.php
@@ -4,6 +4,7 @@ namespace App\Services\Logic\Question;
use App\Models\Question as QuestionModel;
use App\Models\User as UserModel;
+use App\Repos\User as UserRepo;
use App\Services\Logic\QuestionTrait;
use App\Services\Logic\Service as LogicService;
use App\Services\Sync\QuestionIndex as QuestionIndexSync;
@@ -30,7 +31,7 @@ class QuestionDelete extends LogicService
$question->update();
- $this->decrUserQuestionCount($user);
+ $this->recountUserQuestions($user);
$this->rebuildQuestionIndex($question);
@@ -39,12 +40,15 @@ class QuestionDelete extends LogicService
return $question;
}
- protected function decrUserQuestionCount(UserModel $user)
+ protected function recountUserQuestions(UserModel $user)
{
- if ($user->question_count > 0) {
- $user->question_count -= 1;
- $user->update();
- }
+ $userRepo = new UserRepo();
+
+ $questionCount = $userRepo->countQuestions($user->id);
+
+ $user->question_count = $questionCount;
+
+ $user->update();
}
protected function rebuildQuestionIndex(QuestionModel $question)
diff --git a/app/Services/Logic/Review/ReviewCreate.php b/app/Services/Logic/Review/ReviewCreate.php
index 3cd6090e..001044a3 100644
--- a/app/Services/Logic/Review/ReviewCreate.php
+++ b/app/Services/Logic/Review/ReviewCreate.php
@@ -5,6 +5,7 @@ namespace App\Services\Logic\Review;
use App\Models\Course as CourseModel;
use App\Models\CourseUser as CourseUserModel;
use App\Models\Review as ReviewModel;
+use App\Repos\Course as CourseRepo;
use App\Services\CourseStat as CourseStatService;
use App\Services\Logic\CourseTrait;
use App\Services\Logic\Point\History\CourseReview as CourseReviewPointHistory;
@@ -48,17 +49,15 @@ class ReviewCreate extends LogicService
$data['rating1'] = $validator->checkRating($post['rating1']);
$data['rating2'] = $validator->checkRating($post['rating2']);
$data['rating3'] = $validator->checkRating($post['rating3']);
+ $data['published'] = 1;
$review = new ReviewModel();
$review->create($data);
$this->updateCourseUserReview($courseUser);
-
- $this->incrCourseReviewCount($course);
-
+ $this->recountCourseReviews($course);
$this->updateCourseRating($course);
-
$this->handleReviewPoint($review);
$this->eventsManager->fire('Review:afterCreate', $this, $review);
@@ -73,13 +72,6 @@ class ReviewCreate extends LogicService
$courseUser->update();
}
- protected function incrCourseReviewCount(CourseModel $course)
- {
- $course->review_count += 1;
-
- $course->update();
- }
-
protected function updateCourseRating(CourseModel $course)
{
$service = new CourseStatService();
@@ -87,6 +79,17 @@ class ReviewCreate extends LogicService
$service->updateRating($course->id);
}
+ protected function recountCourseReviews(CourseModel $course)
+ {
+ $courseRepo = new CourseRepo();
+
+ $reviewCount = $courseRepo->countReviews($course->id);
+
+ $course->review_count = $reviewCount;
+
+ $course->update();
+ }
+
protected function handleReviewPoint(ReviewModel $review)
{
$service = new CourseReviewPointHistory();
diff --git a/app/Services/Logic/Review/ReviewDelete.php b/app/Services/Logic/Review/ReviewDelete.php
index 7553eb36..f40bee79 100644
--- a/app/Services/Logic/Review/ReviewDelete.php
+++ b/app/Services/Logic/Review/ReviewDelete.php
@@ -3,6 +3,7 @@
namespace App\Services\Logic\Review;
use App\Models\Course as CourseModel;
+use App\Repos\Course as CourseRepo;
use App\Services\CourseStat as CourseStatService;
use App\Services\Logic\CourseTrait;
use App\Services\Logic\ReviewTrait;
@@ -31,19 +32,21 @@ class ReviewDelete extends LogicService
$review->update();
- $this->decrCourseReviewCount($course);
-
+ $this->recountCourseReviews($course);
$this->updateCourseRating($course);
$this->eventsManager->fire('Review:afterDelete', $this, $review);
}
- protected function decrCourseReviewCount(CourseModel $course)
+ protected function recountCourseReviews(CourseModel $course)
{
- if ($course->review_count > 0) {
- $course->review_count -= 1;
- $course->update();
- }
+ $courseRepo = new CourseRepo();
+
+ $reviewCount = $courseRepo->countReviews($course->id);
+
+ $course->review_count = $reviewCount;
+
+ $course->update();
}
protected function updateCourseRating(CourseModel $course)
diff --git a/app/Validators/Answer.php b/app/Validators/Answer.php
index a0d3aa0b..0c3cecd5 100644
--- a/app/Validators/Answer.php
+++ b/app/Validators/Answer.php
@@ -6,6 +6,7 @@ use App\Caches\MaxAnswerId as MaxAnswerIdCache;
use App\Exceptions\BadRequest as BadRequestException;
use App\Models\Answer as AnswerModel;
use App\Models\Question as QuestionModel;
+use App\Models\Reason as ReasonModel;
use App\Models\User as UserModel;
use App\Repos\Answer as AnswerRepo;
use App\Repos\Question as QuestionRepo;
@@ -41,6 +42,13 @@ class Answer extends Validator
}
}
+ public function checkQuestion($id)
+ {
+ $validator = new Question();
+
+ return $validator->checkQuestion($id);
+ }
+
public function checkContent($content)
{
$value = $this->filter->sanitize($content, ['trim', 'string']);
@@ -67,6 +75,13 @@ class Answer extends Validator
return $status;
}
+ public function checkRejectReason($reason)
+ {
+ if (!array_key_exists($reason, ReasonModel::answerRejectOptions())) {
+ throw new BadRequestException('answer.invalid_reject_reason');
+ }
+ }
+
public function checkIfAllowAnswer(QuestionModel $question, UserModel $user)
{
$allowed = true;
@@ -88,13 +103,25 @@ class Answer extends Validator
}
}
- public function checkIfAllowEdit(AnswerModel $answer, UserModel $user)
+ public function checkIfAllowEdit(AnswerModel $answer)
{
- $this->checkOwner($user->id, $answer->owner_id);
+ if ($answer->accepted == 1) {
+ throw new BadRequestException('answer.edit_not_allowed');
+ }
- if (time() - $answer->create_time > 3600) {
+ $case1 = $answer->published == AnswerModel::PUBLISH_APPROVED;
+ $case2 = time() - $answer->create_time > 3600;
+
+ if ($case1 && $case2) {
throw new BadRequestException('answer.edit_not_allowed');
}
}
+ public function checkIfAllowDelete(AnswerModel $answer)
+ {
+ if ($answer->accepted == 1) {
+ throw new BadRequestException('answer.delete_not_allowed');
+ }
+ }
+
}
diff --git a/app/Validators/Article.php b/app/Validators/Article.php
index 2155bf3c..077c4c04 100644
--- a/app/Validators/Article.php
+++ b/app/Validators/Article.php
@@ -149,10 +149,10 @@ class Article extends Validator
return $status;
}
- public function checkAllowCommentStatus($status)
+ public function checkCloseStatus($status)
{
if (!in_array($status, [0, 1])) {
- throw new BadRequestException('article.invalid_allow_comment_status');
+ throw new BadRequestException('article.invalid_close_status');
}
return $status;
diff --git a/config/errors.php b/config/errors.php
index 5ccfac7f..c17ca271 100644
--- a/config/errors.php
+++ b/config/errors.php
@@ -120,7 +120,7 @@ $error['article.invalid_source_url'] = '无效的来源网址';
$error['article.invalid_feature_status'] = '无效的推荐状态';
$error['article.invalid_publish_status'] = '无效的发布状态';
$error['article.invalid_private_status'] = '无效的私有状态';
-$error['article.invalid_allow_comment_status'] = '无效的允许评论状态';
+$error['article.invalid_close_status'] = '无效的关闭状态';
$error['article.invalid_reject_reason'] = '无效的拒绝理由';
/**
diff --git a/db/migrations/20210430023157.php b/db/migrations/20210430023157.php
index be24a4c8..e6c6ec3c 100644
--- a/db/migrations/20210430023157.php
+++ b/db/migrations/20210430023157.php
@@ -23,6 +23,7 @@ final class V20210430023157 extends AbstractMigration
$this->handleRoleRoutes();
$this->handleQuestionNav();
$this->handleArticleCover();
+ $this->handleArticleClosed();
}
public function down()
@@ -405,13 +406,29 @@ final class V20210430023157 extends AbstractMigration
'comment' => '用户编号',
'after' => 'question_id',
])
+ ->addColumn('deleted', 'integer', [
+ 'null' => false,
+ 'default' => '0',
+ 'limit' => MysqlAdapter::INT_REGULAR,
+ 'signed' => false,
+ 'comment' => '删除标识',
+ 'after' => 'user_id',
+ ])
->addColumn('create_time', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '创建时间',
- 'after' => 'user_id',
+ 'after' => 'deleted',
+ ])
+ ->addColumn('update_time', 'integer', [
+ 'null' => false,
+ 'default' => '0',
+ 'limit' => MysqlAdapter::INT_REGULAR,
+ 'signed' => false,
+ 'comment' => '更新时间',
+ 'after' => 'create_time',
])
->addIndex(['user_id'], [
'name' => 'user_id',
@@ -458,13 +475,29 @@ final class V20210430023157 extends AbstractMigration
'comment' => '标签编号',
'after' => 'question_id',
])
+ ->addColumn('deleted', 'integer', [
+ 'null' => false,
+ 'default' => '0',
+ 'limit' => MysqlAdapter::INT_REGULAR,
+ 'signed' => false,
+ 'comment' => '删除标识',
+ 'after' => 'user_id',
+ ])
->addColumn('create_time', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '创建时间',
- 'after' => 'user_id',
+ 'after' => 'deleted',
+ ])
+ ->addColumn('update_time', 'integer', [
+ 'null' => false,
+ 'default' => '0',
+ 'limit' => MysqlAdapter::INT_REGULAR,
+ 'signed' => false,
+ 'comment' => '更新时间',
+ 'after' => 'create_time',
])
->addIndex(['question_id', 'user_id'], [
'name' => 'question_user',
@@ -667,13 +700,29 @@ final class V20210430023157 extends AbstractMigration
'comment' => '标签编号',
'after' => 'answer_id',
])
+ ->addColumn('deleted', 'integer', [
+ 'null' => false,
+ 'default' => '0',
+ 'limit' => MysqlAdapter::INT_REGULAR,
+ 'signed' => false,
+ 'comment' => '删除标识',
+ 'after' => 'user_id',
+ ])
->addColumn('create_time', 'integer', [
'null' => false,
'default' => '0',
'limit' => MysqlAdapter::INT_REGULAR,
'signed' => false,
'comment' => '创建时间',
- 'after' => 'user_id',
+ 'after' => 'deleted',
+ ])
+ ->addColumn('update_time', 'integer', [
+ 'null' => false,
+ 'default' => '0',
+ 'limit' => MysqlAdapter::INT_REGULAR,
+ 'signed' => false,
+ 'comment' => '更新时间',
+ 'after' => 'create_time',
])
->addIndex(['answer_id', 'user_id'], [
'name' => 'answer_user',
@@ -824,6 +873,7 @@ final class V20210430023157 extends AbstractMigration
protected function modifyArticleTable()
{
$this->table('kg_article')
+ ->renameColumn('allow_comment', 'closed')
->addColumn('report_count', 'integer', [
'null' => false,
'default' => '0',
@@ -891,6 +941,15 @@ final class V20210430023157 extends AbstractMigration
->execute();
}
+ protected function handleArticleClosed()
+ {
+ $this->getQueryBuilder()
+ ->update('kg_article')
+ ->set('closed', 0)
+ ->where(['closed' => 1])
+ ->execute();
+ }
+
protected function handleQuestionNav()
{
$data = [
diff --git a/public/static/home/css/common.css b/public/static/home/css/common.css
index f6d6707a..48a069ed 100644
--- a/public/static/home/css/common.css
+++ b/public/static/home/css/common.css
@@ -574,11 +574,11 @@
display: flex;
justify-content: space-between;
margin-bottom: 20px;
- color: #999;
+ color: #666;
}
.article-info .meta a {
- color: #999;
+ color: #666;
}
.article-info .meta .left span {
@@ -612,6 +612,8 @@
.answer-tips h3 {
margin-bottom: 5px;
+ font-weight: normal;
+ font-size: inherit;
}
.answer-tips ul {
diff --git a/public/static/home/js/answer.js b/public/static/home/js/answer.js
index 33faccce..f0b0dd36 100644
--- a/public/static/home/js/answer.js
+++ b/public/static/home/js/answer.js
@@ -1,7 +1,6 @@
-layui.use(['jquery', 'layer', 'helper'], function () {
+layui.use(['jquery', 'helper'], function () {
var $ = layui.jquery;
- var layer = layui.layer;
var helper = layui.helper;
$('body').on('click', '.answer-report', function () {
diff --git a/public/static/home/js/article.show.js b/public/static/home/js/article.show.js
index ed9ee605..fa4175ec 100644
--- a/public/static/home/js/article.show.js
+++ b/public/static/home/js/article.show.js
@@ -80,4 +80,10 @@ layui.use(['jquery', 'helper'], function () {
});
});
+ $('.icon-reply').on('click', function () {
+ $('html').animate({
+ scrollTop: $('#comment-anchor').offset().top
+ }, 500);
+ });
+
});
\ No newline at end of file
diff --git a/public/static/home/js/chapter.show.js b/public/static/home/js/chapter.show.js
index 8c778e47..39d33773 100644
--- a/public/static/home/js/chapter.show.js
+++ b/public/static/home/js/chapter.show.js
@@ -58,4 +58,10 @@ layui.use(['jquery', 'helper'], function () {
});
});
+ $('.icon-reply').on('click', function () {
+ $('html').animate({
+ scrollTop: $('#comment-anchor').offset().top
+ }, 500);
+ });
+
});
\ No newline at end of file
diff --git a/public/static/home/js/comment.js b/public/static/home/js/comment.js
index 79b3c699..f40ba9f9 100644
--- a/public/static/home/js/comment.js
+++ b/public/static/home/js/comment.js
@@ -83,12 +83,6 @@ layui.use(['jquery', 'form', 'layer', 'helper'], function () {
return false;
});
- $('.icon-comment').on('click', function () {
- $('html').animate({
- scrollTop: $('#comment-anchor').offset().top
- }, 500);
- });
-
$('#btn-cancel-comment').on('click', function () {
$('#comment-footer').hide();
});
diff --git a/public/static/home/js/question.show.js b/public/static/home/js/question.show.js
index da459caf..e4d39804 100644
--- a/public/static/home/js/question.show.js
+++ b/public/static/home/js/question.show.js
@@ -91,4 +91,10 @@ layui.use(['jquery', 'helper'], function () {
});
});
+ $('.icon-reply').on('click', function () {
+ $('html').animate({
+ scrollTop: $('#answer-anchor').offset().top
+ }, 500);
+ });
+
});
\ No newline at end of file
-
-
- {% if question.me.answered == 0 %}
-
- {% endif %}
-
-
-
+
+
+
@@ -99,11 +99,6 @@
+
+
|