mirror of
https://gitee.com/koogua/course-tencent-cloud.git
synced 2025-06-24 20:06:09 +08:00
增加问题推荐
This commit is contained in:
parent
4c3436dc95
commit
12ceda62df
@ -75,7 +75,7 @@ class FeaturedArticleList extends Cache
|
||||
->where('featured = 1')
|
||||
->andWhere('published = 1')
|
||||
->andWhere('deleted = 0')
|
||||
->orderBy('id DESC')
|
||||
->orderBy('RAND()')
|
||||
->limit($limit)
|
||||
->execute();
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ class FeaturedCourseList extends Cache
|
||||
->where('featured = 1')
|
||||
->andWhere('published = 1')
|
||||
->andWhere('deleted = 0')
|
||||
->orderBy('id DESC')
|
||||
->orderBy('RAND()')
|
||||
->limit($limit)
|
||||
->execute();
|
||||
}
|
||||
|
74
app/Caches/FeaturedQuestionList.php
Normal file
74
app/Caches/FeaturedQuestionList.php
Normal file
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2023 深圳市酷瓜软件有限公司
|
||||
* @license https://opensource.org/licenses/GPL-2.0
|
||||
* @link https://www.koogua.com
|
||||
*/
|
||||
|
||||
namespace App\Caches;
|
||||
|
||||
use App\Models\Question as QuestionModel;
|
||||
use Phalcon\Mvc\Model\Resultset;
|
||||
use Phalcon\Mvc\Model\ResultsetInterface;
|
||||
|
||||
class FeaturedQuestionList extends Cache
|
||||
{
|
||||
|
||||
protected $lifetime = 86400;
|
||||
|
||||
public function getLifetime()
|
||||
{
|
||||
$tomorrow = strtotime('tomorrow');
|
||||
|
||||
return $tomorrow - time();
|
||||
}
|
||||
|
||||
public function getKey($id = null)
|
||||
{
|
||||
return 'featured_question_list';
|
||||
}
|
||||
|
||||
public function getContent($id = null)
|
||||
{
|
||||
$limit = 5;
|
||||
|
||||
$questions = $this->findQuestions($limit);
|
||||
|
||||
if ($questions->count() == 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($questions as $question) {
|
||||
|
||||
$result[] = [
|
||||
'id' => $question->id,
|
||||
'title' => $question->title,
|
||||
'cover' => $question->cover,
|
||||
'favorite_count' => $question->favorite_count,
|
||||
'answer_count' => $question->answer_count,
|
||||
'view_count' => $question->view_count,
|
||||
'like_count' => $question->like_count,
|
||||
];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $limit
|
||||
* @return ResultsetInterface|Resultset|QuestionModel[]
|
||||
*/
|
||||
protected function findQuestions($limit = 5)
|
||||
{
|
||||
return QuestionModel::query()
|
||||
->where('featured = 1')
|
||||
->andWhere('published = 1')
|
||||
->andWhere('deleted = 0')
|
||||
->orderBy('RAND()')
|
||||
->limit($limit)
|
||||
->execute();
|
||||
}
|
||||
|
||||
}
|
@ -170,6 +170,10 @@ class Question extends Service
|
||||
$data['anonymous'] = $validator->checkAnonymousStatus($post['anonymous']);
|
||||
}
|
||||
|
||||
if (isset($post['featured'])) {
|
||||
$data['featured'] = $validator->checkFeatureStatus($post['featured']);
|
||||
}
|
||||
|
||||
if (isset($post['closed'])) {
|
||||
$data['closed'] = $validator->checkCloseStatus($post['closed']);
|
||||
}
|
||||
|
@ -33,10 +33,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">匿名提问</label>
|
||||
<label class="layui-form-label">推荐问题</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="anonymous" value="1" title="是" {% if question.anonymous == 1 %}checked="checked"{% endif %}>
|
||||
<input type="radio" name="anonymous" value="0" title="否" {% if question.anonymous == 0 %}checked="checked"{% endif %}>
|
||||
<input type="radio" name="featured" value="1" title="是" {% if question.featured == 1 %}checked="checked"{% endif %}>
|
||||
<input type="radio" name="featured" value="0" title="否" {% if question.featured == 0 %}checked="checked"{% endif %}>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
|
@ -37,6 +37,7 @@
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
<col width="10%">
|
||||
</colgroup>
|
||||
<thead>
|
||||
@ -46,6 +47,7 @@
|
||||
<th>问题信息</th>
|
||||
<th>统计信息</th>
|
||||
<th>状态</th>
|
||||
<th>推荐</th>
|
||||
<th>关闭</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
@ -87,6 +89,8 @@
|
||||
</p>
|
||||
</td>
|
||||
<td>{{ publish_status(item.published) }}</td>
|
||||
<td><input type="checkbox" name="featured" value="1" lay-text="是|否" lay-skin="switch" lay-filter="go" data-url="{{ update_url }}"
|
||||
{% if item.featured == 1 %}checked="checked"{% endif %}></td>
|
||||
<td><input type="checkbox" name="closed" value="1" lay-text="是|否" lay-skin="switch" lay-filter="go" data-url="{{ update_url }}"
|
||||
{% if item.closed == 1 %}checked="checked"{% endif %}></td>
|
||||
<td class="center">
|
||||
|
@ -54,10 +54,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">匿名</label>
|
||||
<label class="layui-form-label">推荐</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="anonymous" value="1" title="是">
|
||||
<input type="radio" name="anonymous" value="0" title="否">
|
||||
<input type="radio" name="featured" value="1" title="是">
|
||||
<input type="radio" name="featured" value="0" title="否">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
|
@ -8,13 +8,13 @@
|
||||
{% set type = request.get('type','trim','course') %}
|
||||
{% set query = request.get('query','striptags','') %}
|
||||
|
||||
<form class="layui-form" method="GET" action="{{ url({'for':'home.search.index'}) }}">
|
||||
<form class="layui-form search-form" method="GET" action="{{ url({'for':'home.search.index'}) }}">
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-inline">
|
||||
<input class="layui-input query-input" type="text" name="query" value="{{ query }}" lay-verify="required">
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<button class="layui-btn" lay-submit="true" lay-filter="search">搜索</button>
|
||||
<button class="layui-btn search-btn" lay-submit="true" lay-filter="search">搜索</button>
|
||||
<input type="hidden" name="type" value="{{ type }}">
|
||||
</div>
|
||||
</div>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<div class="sidebar-article-list">
|
||||
{% for article in articles %}
|
||||
{% set article_url = url({'for':'home.article.show','id':article.id}) %}
|
||||
<div class="title">
|
||||
<div class="title layui-elip">
|
||||
<a href="{{ article_url }}" target="_blank">{{ article.title }}</a>
|
||||
</div>
|
||||
<div class="meta">
|
||||
|
20
app/Http/Home/Views/widget/featured_questions.volt
Normal file
20
app/Http/Home/Views/widget/featured_questions.volt
Normal file
@ -0,0 +1,20 @@
|
||||
{% if questions|length > 0 %}
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">推荐问题</div>
|
||||
<div class="layui-card-body">
|
||||
<div class="sidebar-question-list">
|
||||
{% for question in questions %}
|
||||
{% set question_url = url({'for':'home.question.show','id':question.id}) %}
|
||||
<div class="title layui-elip">
|
||||
<a href="{{ question_url }}" target="_blank">{{ question.title }}</a>
|
||||
</div>
|
||||
<div class="meta">
|
||||
<span class="view">{{ question.view_count }} 浏览</span>
|
||||
<span class="like">{{ question.like_count }} 点赞</span>
|
||||
<span class="comment">{{ question.comment_count }} 评论</span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
@ -149,6 +149,13 @@ class Question extends Model
|
||||
*/
|
||||
public $published = self::PUBLISH_PENDING;
|
||||
|
||||
/**
|
||||
* 推荐标识
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
public $featured = 0;
|
||||
|
||||
/**
|
||||
* 删除标识
|
||||
*
|
||||
@ -318,9 +325,10 @@ class Question extends Model
|
||||
public static function sortTypes()
|
||||
{
|
||||
return [
|
||||
'latest' => '最新提问',
|
||||
'latest' => '最新问题',
|
||||
'active' => '最新回答',
|
||||
'unanswered' => '尚未回答',
|
||||
'featured' => '推荐问题',
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -58,6 +58,20 @@ class Question extends Repository
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($where['published'])) {
|
||||
if (is_array($where['published'])) {
|
||||
$builder->inWhere('published', $where['published']);
|
||||
} else {
|
||||
$builder->andWhere('published = :published:', ['published' => $where['published']]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($where['create_time'][0]) && !empty($where['create_time'][1])) {
|
||||
$startTime = strtotime($where['create_time'][0]);
|
||||
$endTime = strtotime($where['create_time'][1]);
|
||||
$builder->betweenWhere('create_time', $startTime, $endTime);
|
||||
}
|
||||
|
||||
if (!empty($where['owner_id'])) {
|
||||
$builder->andWhere('owner_id = :owner_id:', ['owner_id' => $where['owner_id']]);
|
||||
}
|
||||
@ -74,33 +88,23 @@ class Question extends Repository
|
||||
$builder->andWhere('closed = :closed:', ['closed' => $where['closed']]);
|
||||
}
|
||||
|
||||
if (isset($where['featured'])) {
|
||||
$builder->andWhere('featured = :featured:', ['featured' => $where['featured']]);
|
||||
}
|
||||
|
||||
if (isset($where['solved'])) {
|
||||
$builder->andWhere('solved = :solved:', ['solved' => $where['solved']]);
|
||||
}
|
||||
|
||||
if (!empty($where['published'])) {
|
||||
if (is_array($where['published'])) {
|
||||
$builder->inWhere('published', $where['published']);
|
||||
} else {
|
||||
$builder->andWhere('published = :published:', ['published' => $where['published']]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($where['create_time'][0]) && !empty($where['create_time'][1])) {
|
||||
$startTime = strtotime($where['create_time'][0]);
|
||||
$endTime = strtotime($where['create_time'][1]);
|
||||
$builder->betweenWhere('create_time', $startTime, $endTime);
|
||||
}
|
||||
|
||||
if (isset($where['deleted'])) {
|
||||
$builder->andWhere('deleted = :deleted:', ['deleted' => $where['deleted']]);
|
||||
}
|
||||
|
||||
if ($sort == 'unanswered') {
|
||||
if ($sort == 'featured') {
|
||||
$builder->andWhere('featured = 1');
|
||||
} elseif ($sort == 'unanswered') {
|
||||
$builder->andWhere('answer_count = 0');
|
||||
}
|
||||
|
||||
if ($sort == 'reported') {
|
||||
} elseif ($sort == 'reported') {
|
||||
$builder->andWhere('report_count > 0');
|
||||
}
|
||||
|
||||
|
@ -82,8 +82,8 @@ class ArticleList extends LogicService
|
||||
|
||||
foreach ($articles as $article) {
|
||||
|
||||
if (!empty($question['cover']) && !Text::startsWith($question['cover'], 'http')) {
|
||||
$question['cover'] = $cosUrl . $question['cover'];
|
||||
if (!empty($article['cover']) && !Text::startsWith($article['cover'], 'http')) {
|
||||
$article['cover'] = $cosUrl . $article['cover'];
|
||||
}
|
||||
|
||||
$article['tags'] = json_decode($article['tags'], true);
|
||||
|
@ -11,7 +11,6 @@ use App\Caches\MaxQuestionId as MaxQuestionIdCache;
|
||||
use App\Caches\Question as QuestionCache;
|
||||
use App\Exceptions\BadRequest as BadRequestException;
|
||||
use App\Models\Question as QuestionModel;
|
||||
use App\Models\Reason as ReasonModel;
|
||||
use App\Repos\Question as QuestionRepo;
|
||||
use App\Services\EditorStorage as EditorStorageService;
|
||||
|
||||
@ -151,6 +150,15 @@ class Question extends Validator
|
||||
return $status;
|
||||
}
|
||||
|
||||
public function checkFeatureStatus($status)
|
||||
{
|
||||
if (!in_array($status, [0, 1])) {
|
||||
throw new BadRequestException('question.invalid_feature_status');
|
||||
}
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
||||
public function checkCloseStatus($status)
|
||||
{
|
||||
if (!in_array($status, [0, 1])) {
|
||||
|
@ -14,6 +14,7 @@ final class V20231108085025 extends AbstractMigration
|
||||
public function up()
|
||||
{
|
||||
$this->alterVipTable();
|
||||
$this->alterQuestionTable();
|
||||
$this->alterArticleTable();
|
||||
$this->alterConsultTable();
|
||||
$this->alterResourceTable();
|
||||
@ -45,6 +46,24 @@ final class V20231108085025 extends AbstractMigration
|
||||
$table->save();
|
||||
}
|
||||
|
||||
protected function alterQuestionTable()
|
||||
{
|
||||
$table = $this->table('kg_question');
|
||||
|
||||
if (!$table->hasColumn('featured')) {
|
||||
$table->addColumn('featured', 'integer', [
|
||||
'null' => false,
|
||||
'default' => '0',
|
||||
'limit' => MysqlAdapter::INT_REGULAR,
|
||||
'signed' => false,
|
||||
'comment' => '推荐标识',
|
||||
'after' => 'published',
|
||||
]);
|
||||
}
|
||||
|
||||
$table->save();
|
||||
}
|
||||
|
||||
protected function alterArticleTable()
|
||||
{
|
||||
$table = $this->table('kg_article');
|
||||
|
@ -330,8 +330,12 @@
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.query-input {
|
||||
width: 720px;
|
||||
.search-form .query-input {
|
||||
width: 696px;
|
||||
}
|
||||
|
||||
.search-form .search-btn {
|
||||
padding: 0 30px;
|
||||
}
|
||||
|
||||
.search-tab {
|
||||
|
Loading…
x
Reference in New Issue
Block a user