mirror of
https://gitee.com/koogua/course-tencent-cloud.git
synced 2025-07-17 13:46:21 +08:00
Merge branch 'koogua/v1.3.6'
This commit is contained in:
commit
c994c9e05e
23
CHANGELOG.md
23
CHANGELOG.md
@ -1,3 +1,26 @@
|
||||
### [v1.3.6](https://gitee.com/koogua/course-tencent-cloud/releases/v1.3.6)(2021-06-04)
|
||||
|
||||
### 更新
|
||||
|
||||
- 清理没有用到的引用
|
||||
- 优化界面和CSS样式
|
||||
- 优化视频无法获取时长处理逻辑
|
||||
- 优化视频无法转码处理逻辑
|
||||
- 优化评论审核机制
|
||||
- 优化评论相关数据更新逻辑
|
||||
- 优化文章,问答,评论数据更新
|
||||
- 优化内容标签的更新逻辑
|
||||
- 优化首页H5的跳转判断
|
||||
- 优化单页的浏览权限
|
||||
- 优化Model中的事件方法
|
||||
- 优化kg_parse_summary函数
|
||||
- 用户主页加入问答列表
|
||||
- 修复无法关闭问题讨论
|
||||
- 修复编辑群组的路由
|
||||
- 直播去除FLV方式拉流
|
||||
- xs.question.ini加入忽略列表
|
||||
- kg_user表增加comment_count字段
|
||||
|
||||
### [v1.3.5](https://gitee.com/koogua/course-tencent-cloud/releases/v1.3.5)(2021-05-20)
|
||||
|
||||
### 更新
|
||||
|
@ -84,5 +84,5 @@ Tips: 请用手机注册一个新账号,用户中心 -> 关注订阅,扫码
|
||||
|
||||
### 开源助力
|
||||
|
||||
毫无保留的真开源不容易,如果对你有帮助,请给我们 **STAR** !!!
|
||||
毫无保留的真开源不容易,不要吝啬您的赞许和鼓励,请给我们 **STAR** !!!
|
||||
|
||||
|
@ -1,31 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Caches;
|
||||
|
||||
use App\Repos\App as AppRepo;
|
||||
|
||||
class App extends Cache
|
||||
{
|
||||
|
||||
protected $lifetime = 365 * 86400;
|
||||
|
||||
public function getLifetime()
|
||||
{
|
||||
return $this->lifetime;
|
||||
}
|
||||
|
||||
public function getKey($id = null)
|
||||
{
|
||||
return "app:{$id}";
|
||||
}
|
||||
|
||||
public function getContent($id = null)
|
||||
{
|
||||
$appRepo = new AppRepo();
|
||||
|
||||
$result = $appRepo->findByAppKey($id);
|
||||
|
||||
return $result ?: null;
|
||||
}
|
||||
|
||||
}
|
32
app/Caches/AppInfo.php
Normal file
32
app/Caches/AppInfo.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Caches;
|
||||
|
||||
class AppInfo extends Cache
|
||||
{
|
||||
|
||||
protected $lifetime = 365 * 86400;
|
||||
|
||||
public function getLifetime()
|
||||
{
|
||||
return $this->lifetime;
|
||||
}
|
||||
|
||||
public function getKey($id = null)
|
||||
{
|
||||
return "_APP_INFO_";
|
||||
}
|
||||
|
||||
public function getContent($id = null)
|
||||
{
|
||||
$appInfo = new \App\Library\AppInfo();
|
||||
|
||||
return [
|
||||
'name' => $appInfo->name,
|
||||
'alias' => $appInfo->alias,
|
||||
'link' => $appInfo->link,
|
||||
'version' => $appInfo->version,
|
||||
];
|
||||
}
|
||||
|
||||
}
|
@ -44,10 +44,12 @@ class VodEventTask extends Task
|
||||
|
||||
protected function handleNewFileUploadEvent($event)
|
||||
{
|
||||
$fileId = $event['FileUploadEvent']['FileId'];
|
||||
$width = $event['FileUploadEvent']['MetaData']['Height'];
|
||||
$height = $event['FileUploadEvent']['MetaData']['Width'];
|
||||
$duration = $event['FileUploadEvent']['MetaData']['Duration'];
|
||||
$fileId = $event['FileUploadEvent']['FileId'] ?? 0;
|
||||
$width = $event['FileUploadEvent']['MetaData']['Height'] ?? 0;
|
||||
$height = $event['FileUploadEvent']['MetaData']['Width'] ?? 0;
|
||||
$duration = $event['FileUploadEvent']['MetaData']['Duration'] ?? 0;
|
||||
|
||||
if ($fileId == 0) return;
|
||||
|
||||
$chapterRepo = new ChapterRepo();
|
||||
|
||||
@ -55,6 +57,18 @@ class VodEventTask extends Task
|
||||
|
||||
if (!$chapter) return;
|
||||
|
||||
$attrs = $chapter->attrs;
|
||||
|
||||
/**
|
||||
* 获取不到时长视为失败
|
||||
*/
|
||||
if ($duration == 0) {
|
||||
$attrs['file']['id'] = $fileId;
|
||||
$attrs['file']['status'] = ChapterModel::FS_FAILED;
|
||||
$chapter->update(['attrs' => $attrs]);
|
||||
return;
|
||||
}
|
||||
|
||||
$vodService = new VodService();
|
||||
|
||||
if ($width == 0 && $height == 0) {
|
||||
@ -63,13 +77,8 @@ class VodEventTask extends Task
|
||||
$vodService->createTransVideoTask($fileId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @var array $attrs
|
||||
*/
|
||||
$attrs = $chapter->attrs;
|
||||
|
||||
$attrs['file']['id'] = $fileId;
|
||||
$attrs['file']['status'] = ChapterModel::FS_TRANSLATING;
|
||||
|
||||
$attrs['duration'] = (int)$duration;
|
||||
|
||||
$chapter->update(['attrs' => $attrs]);
|
||||
@ -79,9 +88,9 @@ class VodEventTask extends Task
|
||||
|
||||
protected function handleProcedureStateChangedEvent($event)
|
||||
{
|
||||
$fileId = $event['ProcedureStateChangeEvent']['FileId'];
|
||||
$fileId = $event['ProcedureStateChangeEvent']['FileId'] ?? 0;
|
||||
|
||||
$processResult = $event['ProcedureStateChangeEvent']['MediaProcessResultSet'];
|
||||
if ($fileId == 0) return;
|
||||
|
||||
$chapterRepo = new ChapterRepo();
|
||||
|
||||
@ -89,6 +98,20 @@ class VodEventTask extends Task
|
||||
|
||||
if (!$chapter) return;
|
||||
|
||||
$attrs = $chapter->attrs;
|
||||
|
||||
$processResult = $event['ProcedureStateChangeEvent']['MediaProcessResultSet'] ?? [];
|
||||
|
||||
/**
|
||||
* 获取不到处理结果视为失败
|
||||
*/
|
||||
if (empty($processResult)) {
|
||||
$attrs['file']['id'] = $fileId;
|
||||
$attrs['file']['status'] = ChapterModel::FS_FAILED;
|
||||
$chapter->update(['attrs' => $attrs]);
|
||||
return;
|
||||
}
|
||||
|
||||
$failCount = $successCount = 0;
|
||||
|
||||
foreach ($processResult as $item) {
|
||||
@ -112,15 +135,9 @@ class VodEventTask extends Task
|
||||
$fileStatus = ChapterModel::FS_FAILED;
|
||||
}
|
||||
|
||||
if ($fileStatus == ChapterModel::FS_TRANSLATING) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @var array $attrs
|
||||
*/
|
||||
$attrs = $chapter->attrs;
|
||||
if ($fileStatus == ChapterModel::FS_TRANSLATING) return;
|
||||
|
||||
$attrs['file']['id'] = $fileId;
|
||||
$attrs['file']['status'] = $fileStatus;
|
||||
|
||||
$chapter->update(['attrs' => $attrs]);
|
||||
|
@ -14,6 +14,7 @@ use App\Repos\Answer as AnswerRepo;
|
||||
use App\Repos\Question as QuestionRepo;
|
||||
use App\Repos\Report as ReportRepo;
|
||||
use App\Repos\User as UserRepo;
|
||||
use App\Services\Logic\Answer\AnswerDataTrait;
|
||||
use App\Services\Logic\Answer\AnswerInfo as AnswerInfoService;
|
||||
use App\Services\Logic\Notice\System\AnswerApproved as AnswerApprovedNotice;
|
||||
use App\Services\Logic\Notice\System\AnswerRejected as AnswerRejectedNotice;
|
||||
@ -24,6 +25,8 @@ use App\Validators\Answer as AnswerValidator;
|
||||
class Answer extends Service
|
||||
{
|
||||
|
||||
use AnswerDataTrait;
|
||||
|
||||
public function getPublishTypes()
|
||||
{
|
||||
return AnswerModel::publishTypes();
|
||||
@ -94,13 +97,16 @@ class Answer extends Service
|
||||
|
||||
$answer = new AnswerModel();
|
||||
|
||||
$answer->owner_id = $user->id;
|
||||
$answer->question_id = $question->id;
|
||||
$answer->published = AnswerModel::PUBLISH_APPROVED;
|
||||
$answer->client_type = $this->getClientType();
|
||||
$answer->client_ip = $this->getClientIp();
|
||||
$answer->content = $validator->checkContent($post['content']);
|
||||
$answer->question_id = $question->id;
|
||||
$answer->owner_id = $user->id;
|
||||
|
||||
$answer->create();
|
||||
|
||||
$this->saveDynamicAttrs($answer);
|
||||
$this->recountQuestionAnswers($question);
|
||||
$this->recountUserAnswers($user);
|
||||
$this->handleAnswerPostPoint($answer);
|
||||
@ -126,20 +132,21 @@ 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);
|
||||
|
||||
$this->saveDynamicAttrs($answer);
|
||||
|
||||
$question = $this->findQuestion($answer->question_id);
|
||||
|
||||
$this->recountQuestionAnswers($question);
|
||||
|
||||
$owner = $this->findUser($answer->owner_id);
|
||||
|
||||
$this->recountUserAnswers($owner);
|
||||
|
||||
$this->eventsManager->fire('Answer:afterUpdate', $this, $answer);
|
||||
|
||||
return $answer;
|
||||
|
@ -15,10 +15,10 @@ use App\Models\User as UserModel;
|
||||
use App\Repos\Article as ArticleRepo;
|
||||
use App\Repos\Category as CategoryRepo;
|
||||
use App\Repos\Report as ReportRepo;
|
||||
use App\Repos\Tag as TagRepo;
|
||||
use App\Repos\User as UserRepo;
|
||||
use App\Services\Logic\Article\ArticleDataTrait;
|
||||
use App\Services\Logic\Article\ArticleInfo as ArticleInfoService;
|
||||
use App\Services\Logic\Article\XmTagList as XmTagListService;
|
||||
use App\Services\Logic\Notice\System\ArticleApproved as ArticleApprovedNotice;
|
||||
use App\Services\Logic\Notice\System\ArticleRejected as ArticleRejectedNotice;
|
||||
use App\Services\Logic\Point\History\ArticlePost as ArticlePostPointHistory;
|
||||
@ -32,33 +32,9 @@ class Article extends Service
|
||||
|
||||
public function getXmTags($id)
|
||||
{
|
||||
$tagRepo = new TagRepo();
|
||||
$service = new XmTagListService();
|
||||
|
||||
$allTags = $tagRepo->findAll(['published' => 1]);
|
||||
|
||||
if ($allTags->count() == 0) return [];
|
||||
|
||||
$articleTagIds = [];
|
||||
|
||||
if ($id > 0) {
|
||||
$article = $this->findOrFail($id);
|
||||
if (!empty($article->tags)) {
|
||||
$articleTagIds = kg_array_column($article->tags, 'id');
|
||||
}
|
||||
}
|
||||
|
||||
$list = [];
|
||||
|
||||
foreach ($allTags as $tag) {
|
||||
$selected = in_array($tag->id, $articleTagIds);
|
||||
$list[] = [
|
||||
'name' => $tag->name,
|
||||
'value' => $tag->id,
|
||||
'selected' => $selected,
|
||||
];
|
||||
}
|
||||
|
||||
return $list;
|
||||
return $service->handle($id);
|
||||
}
|
||||
|
||||
public function getCategories()
|
||||
@ -152,11 +128,15 @@ class Article extends Service
|
||||
$article = new ArticleModel();
|
||||
|
||||
$article->published = ArticleModel::PUBLISH_APPROVED;
|
||||
$article->client_type = $this->getClientType();
|
||||
$article->client_ip = $this->getClientIp();
|
||||
$article->owner_id = $user->id;
|
||||
$article->title = $title;
|
||||
|
||||
$article->create();
|
||||
|
||||
$this->saveDynamicAttrs($article);
|
||||
|
||||
$this->recountUserArticles($user);
|
||||
|
||||
$this->eventsManager->fire('Article:afterCreate', $this, $article);
|
||||
@ -208,12 +188,7 @@ 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'])) {
|
||||
@ -222,8 +197,14 @@ class Article extends Service
|
||||
|
||||
$article->update($data);
|
||||
|
||||
$this->saveDynamicAttrs($article);
|
||||
|
||||
$this->rebuildArticleIndex($article);
|
||||
|
||||
$owner = $this->findUser($article->owner_id);
|
||||
|
||||
$this->recountUserArticles($owner);
|
||||
|
||||
$this->eventsManager->fire('Article:afterUpdate', $this, $article);
|
||||
|
||||
return $article;
|
||||
@ -237,14 +218,14 @@ class Article extends Service
|
||||
|
||||
$article->update();
|
||||
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
$owner = $userRepo->findById($article->owner_id);
|
||||
|
||||
$this->recountUserArticles($owner);
|
||||
$this->saveDynamicAttrs($article);
|
||||
|
||||
$this->rebuildArticleIndex($article);
|
||||
|
||||
$owner = $this->findUser($article->owner_id);
|
||||
|
||||
$this->recountUserArticles($owner);
|
||||
|
||||
$this->eventsManager->fire('Article:afterDelete', $this, $article);
|
||||
|
||||
return $article;
|
||||
@ -258,14 +239,14 @@ class Article extends Service
|
||||
|
||||
$article->update();
|
||||
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
$owner = $userRepo->findById($article->owner_id);
|
||||
|
||||
$this->recountUserArticles($owner);
|
||||
$this->saveDynamicAttrs($article);
|
||||
|
||||
$this->rebuildArticleIndex($article);
|
||||
|
||||
$owner = $this->findUser($article->owner_id);
|
||||
|
||||
$this->recountUserArticles($owner);
|
||||
|
||||
$this->eventsManager->fire('Article:afterRestore', $this, $article);
|
||||
|
||||
return $article;
|
||||
|
@ -10,7 +10,6 @@ class AuthMenu extends Component
|
||||
|
||||
protected $authInfo;
|
||||
protected $authNodes = [];
|
||||
protected $ownedRoutes = [];
|
||||
protected $owned1stLevelIds = [];
|
||||
protected $owned2ndLevelIds = [];
|
||||
protected $owned3rdLevelIds = [];
|
||||
|
@ -530,7 +530,7 @@ class AuthNode extends Service
|
||||
],
|
||||
],
|
||||
[
|
||||
'id' => '2-10',
|
||||
'id' => '2-11',
|
||||
'title' => '举报队列',
|
||||
'type' => 'menu',
|
||||
'children' => [
|
||||
|
@ -2,8 +2,9 @@
|
||||
|
||||
namespace App\Http\Admin\Services;
|
||||
|
||||
use App\Caches\SiteGlobalStat;
|
||||
use App\Caches\SiteTodayStat;
|
||||
use App\Caches\AppInfo as AppInfoCache;
|
||||
use App\Caches\SiteGlobalStat as SiteGlobalStatCache;
|
||||
use App\Caches\SiteTodayStat as SiteTodayStatCache;
|
||||
use App\Library\AppInfo;
|
||||
use App\Library\Utils\ServerInfo;
|
||||
use App\Repos\Stat as StatRepo;
|
||||
@ -28,7 +29,17 @@ class Index extends Service
|
||||
|
||||
public function getAppInfo()
|
||||
{
|
||||
return new AppInfo();
|
||||
$cache = new AppInfoCache();
|
||||
|
||||
$content = $cache->get();
|
||||
|
||||
$appInfo = new AppInfo();
|
||||
|
||||
if ($appInfo->version != $content['version']) {
|
||||
$cache->rebuild();
|
||||
}
|
||||
|
||||
return $appInfo;
|
||||
}
|
||||
|
||||
public function getServerInfo()
|
||||
@ -42,14 +53,14 @@ class Index extends Service
|
||||
|
||||
public function getGlobalStat()
|
||||
{
|
||||
$cache = new SiteGlobalStat();
|
||||
$cache = new SiteGlobalStatCache();
|
||||
|
||||
return $cache->get();
|
||||
}
|
||||
|
||||
public function getTodayStat()
|
||||
{
|
||||
$cache = new SiteTodayStat();
|
||||
$cache = new SiteTodayStatCache();
|
||||
|
||||
return $cache->get();
|
||||
}
|
||||
|
@ -14,13 +14,13 @@ use App\Models\User as UserModel;
|
||||
use App\Repos\Category as CategoryRepo;
|
||||
use App\Repos\Question as QuestionRepo;
|
||||
use App\Repos\Report as ReportRepo;
|
||||
use App\Repos\Tag as TagRepo;
|
||||
use App\Repos\User as UserRepo;
|
||||
use App\Services\Logic\Notice\System\QuestionApproved as QuestionApprovedNotice;
|
||||
use App\Services\Logic\Notice\System\QuestionRejected as QuestionRejectedNotice;
|
||||
use App\Services\Logic\Point\History\QuestionPost as QuestionPostPointHistory;
|
||||
use App\Services\Logic\Question\QuestionDataTrait;
|
||||
use App\Services\Logic\Question\QuestionInfo as QuestionInfoService;
|
||||
use App\Services\Logic\Question\XmTagList as XmTagListService;
|
||||
use App\Services\Sync\QuestionIndex as QuestionIndexSync;
|
||||
use App\Validators\Question as QuestionValidator;
|
||||
|
||||
@ -31,33 +31,9 @@ class Question extends Service
|
||||
|
||||
public function getXmTags($id)
|
||||
{
|
||||
$tagRepo = new TagRepo();
|
||||
$service = new XmTagListService();
|
||||
|
||||
$allTags = $tagRepo->findAll(['published' => 1]);
|
||||
|
||||
if ($allTags->count() == 0) return [];
|
||||
|
||||
$questionTagIds = [];
|
||||
|
||||
if ($id > 0) {
|
||||
$question = $this->findOrFail($id);
|
||||
if (!empty($question->tags)) {
|
||||
$questionTagIds = kg_array_column($question->tags, 'id');
|
||||
}
|
||||
}
|
||||
|
||||
$list = [];
|
||||
|
||||
foreach ($allTags as $tag) {
|
||||
$selected = in_array($tag->id, $questionTagIds);
|
||||
$list[] = [
|
||||
'name' => $tag->name,
|
||||
'value' => $tag->id,
|
||||
'selected' => $selected,
|
||||
];
|
||||
}
|
||||
|
||||
return $list;
|
||||
return $service->handle($id);
|
||||
}
|
||||
|
||||
public function getCategories()
|
||||
@ -146,11 +122,15 @@ class Question extends Service
|
||||
$question = new QuestionModel();
|
||||
|
||||
$question->published = QuestionModel::PUBLISH_APPROVED;
|
||||
$question->client_type = $this->getClientType();
|
||||
$question->client_ip = $this->getClientIp();
|
||||
$question->owner_id = $user->id;
|
||||
$question->title = $title;
|
||||
|
||||
$question->create();
|
||||
|
||||
$this->saveDynamicAttrs($question);
|
||||
|
||||
$this->recountUserQuestions($user);
|
||||
|
||||
$this->eventsManager->fire('Question:afterCreate', $this, $question);
|
||||
@ -190,12 +170,7 @@ 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'])) {
|
||||
@ -204,8 +179,14 @@ class Question extends Service
|
||||
|
||||
$question->update($data);
|
||||
|
||||
$this->saveDynamicAttrs($question);
|
||||
|
||||
$this->rebuildQuestionIndex($question);
|
||||
|
||||
$owner = $this->findUser($question->owner_id);
|
||||
|
||||
$this->recountUserQuestions($owner);
|
||||
|
||||
$this->eventsManager->fire('Question:afterUpdate', $this, $question);
|
||||
|
||||
return $question;
|
||||
@ -219,14 +200,14 @@ class Question extends Service
|
||||
|
||||
$question->update();
|
||||
|
||||
$userRepo = new UserRepo();
|
||||
|
||||
$owner = $userRepo->findById($question->owner_id);
|
||||
|
||||
$this->recountUserQuestions($owner);
|
||||
$this->saveDynamicAttrs($question);
|
||||
|
||||
$this->rebuildQuestionIndex($question);
|
||||
|
||||
$owner = $this->findUser($question->owner_id);
|
||||
|
||||
$this->recountUserQuestions($owner);
|
||||
|
||||
$this->eventsManager->fire('Question:afterDelete', $this, $question);
|
||||
|
||||
return $question;
|
||||
@ -240,14 +221,12 @@ class Question extends Service
|
||||
|
||||
$question->update();
|
||||
|
||||
$userRepo = new UserRepo();
|
||||
$this->rebuildQuestionIndex($question);
|
||||
|
||||
$owner = $userRepo->findById($question->owner_id);
|
||||
$owner = $this->findUser($question->owner_id);
|
||||
|
||||
$this->recountUserQuestions($owner);
|
||||
|
||||
$this->rebuildQuestionIndex($question);
|
||||
|
||||
$this->eventsManager->fire('Question:afterRestore', $this, $question);
|
||||
|
||||
return $question;
|
||||
|
@ -50,4 +50,4 @@
|
||||
<button type="button" class="kg-back layui-btn layui-btn-primary">返回</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</form>
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
{% set back_url = url({'for':'admin.category.list'},{'type':type}) %}
|
||||
{% set add_url = url({'for':'admin.category.add'},{'type':type,'parent_id':parent.id}) %}
|
||||
{% set allow_add = (type == 1 and parent.level < 2) or (type == 2 and parent.level < 1) or (type == 3 and parent.level < 1) %}
|
||||
{% set allow_add = (type == 1 and parent.level < 2) or (type == 2 and parent.level < 1) %}
|
||||
|
||||
<div class="kg-nav">
|
||||
<div class="kg-nav-left">
|
||||
@ -55,14 +55,12 @@
|
||||
<td>{{ item.id }}</td>
|
||||
{% if item.type == 1 %}
|
||||
{% if item.level == 1 %}
|
||||
<td><a href="{{ child_url }}">{{ item.name }}</a></td>
|
||||
<td><a href="{{ child_url }}"><i class="layui-icon layui-icon-add-circle"></i> {{ item.name }}</a></td>
|
||||
{% else %}
|
||||
<td><a href="{{ edit_url }}">{{ item.name }}</a></td>
|
||||
{% endif %}
|
||||
{% elseif item.type == 2 %}
|
||||
<td><a href="{{ edit_url }}">{{ item.name }}</a></td>
|
||||
{% elseif item.type == 3 %}
|
||||
<td><a href="{{ edit_url }}">{{ item.name }}</a></td>
|
||||
{% endif %}
|
||||
<td>{{ item.level }}</td>
|
||||
<td>{{ item.child_count }}</td>
|
||||
|
@ -55,7 +55,7 @@
|
||||
<tr>
|
||||
<td>{{ item.id }}</td>
|
||||
<td>
|
||||
<a href="{{ child_url }}">{{ item.title }}</a>
|
||||
<a href="{{ child_url }}"><i class="layui-icon layui-icon-add-circle"></i> {{ item.title }}</a>
|
||||
<span class="layui-badge layui-bg-green">章</span>
|
||||
</td>
|
||||
<td>{{ item.lesson_count }}</td>
|
||||
|
@ -87,8 +87,8 @@
|
||||
<li><a href="{{ review_url }}">审核问题</a></li>
|
||||
{% elseif item.published == 2 %}
|
||||
<li><a href="{{ preview_url }}" target="_blank">预览问题</a></li>
|
||||
<li><a href="{{ answer_add_url }}">回答问题</a></li>
|
||||
{% endif %}
|
||||
<li><a href="{{ answer_add_url }}">回答问题</a></li>
|
||||
<li><a href="{{ edit_url }}">编辑问题</a></li>
|
||||
{% if item.deleted == 0 %}
|
||||
<li><a href="javascript:" class="kg-delete" data-url="{{ delete_url }}">删除问题</a></li>
|
||||
@ -128,7 +128,7 @@
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: url,
|
||||
data: {closed: data.value},
|
||||
data: {closed: closed},
|
||||
success: function (res) {
|
||||
layer.msg(res.msg, {icon: 1});
|
||||
},
|
||||
|
@ -47,13 +47,19 @@ class AnswerController extends Controller
|
||||
*/
|
||||
public function showAction($id)
|
||||
{
|
||||
$service = new AnswerService();
|
||||
$service = new AnswerInfoService();
|
||||
|
||||
$answer = $service->getAnswer($id);
|
||||
$answer = $service->handle($id);
|
||||
|
||||
$questionId = $answer['question']['id'];
|
||||
|
||||
if ($answer['me']['owned'] == 0) {
|
||||
$this->response->redirect(['for' => 'home.error.403']);
|
||||
}
|
||||
|
||||
$location = $this->url->get(
|
||||
['for' => 'home.question.show', 'id' => $answer->question_id],
|
||||
['answer_id' => $answer->id],
|
||||
['for' => 'home.question.show', 'id' => $questionId],
|
||||
['answer_id' => $id],
|
||||
);
|
||||
|
||||
$this->response->redirect($location);
|
||||
|
@ -13,7 +13,7 @@ class IndexController extends Controller
|
||||
|
||||
public function beforeExecuteRoute(Dispatcher $dispatcher)
|
||||
{
|
||||
if ($this->isMobileBrowser()) {
|
||||
if ($this->isMobileBrowser() && $this->h5Enabled()) {
|
||||
|
||||
$this->response->redirect('/h5', true);
|
||||
|
||||
@ -66,4 +66,11 @@ class IndexController extends Controller
|
||||
$this->view->setVar('vip_courses', $service->getSimpleVipCourses());
|
||||
}
|
||||
|
||||
protected function h5Enabled()
|
||||
{
|
||||
$file = public_path('h5/index.html');
|
||||
|
||||
return file_exists($file);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -20,6 +20,10 @@ class PageController extends Controller
|
||||
|
||||
$page = $service->handle($id);
|
||||
|
||||
if ($page['me']['owned'] == 0) {
|
||||
$this->response->redirect(['for' => 'home.error.403']);
|
||||
}
|
||||
|
||||
$featuredCourses = $this->getFeaturedCourses();
|
||||
|
||||
$this->seo->prependTitle($page['title']);
|
||||
|
@ -2,10 +2,12 @@
|
||||
|
||||
namespace App\Http\Home\Controllers;
|
||||
|
||||
use App\Services\Logic\User\AnswerList as UserAnswerListService;
|
||||
use App\Services\Logic\User\ArticleList as UserArticleListService;
|
||||
use App\Services\Logic\User\CourseList as UserCourseListService;
|
||||
use App\Services\Logic\User\FriendList as UserFriendListService;
|
||||
use App\Services\Logic\User\GroupList as UserGroupListService;
|
||||
use App\Services\Logic\User\QuestionList as UserQuestionListService;
|
||||
use App\Services\Logic\User\UserInfo as UserInfoService;
|
||||
use Phalcon\Mvc\View;
|
||||
|
||||
@ -61,6 +63,38 @@ class UserController extends Controller
|
||||
$this->view->setVar('pager', $pager);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Get("/{id:[0-9]+}/questions", name="home.user.questions")
|
||||
*/
|
||||
public function questionsAction($id)
|
||||
{
|
||||
$service = new UserQuestionListService();
|
||||
|
||||
$pager = $service->handle($id);
|
||||
|
||||
$pager->target = 'tab-questions';
|
||||
|
||||
$this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
|
||||
$this->view->pick('user/questions');
|
||||
$this->view->setVar('pager', $pager);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Get("/{id:[0-9]+}/answers", name="home.user.answers")
|
||||
*/
|
||||
public function answersAction($id)
|
||||
{
|
||||
$service = new UserAnswerListService();
|
||||
|
||||
$pager = $service->handle($id);
|
||||
|
||||
$pager->target = 'tab-answers';
|
||||
|
||||
$this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
|
||||
$this->view->pick('user/answers');
|
||||
$this->view->setVar('pager', $pager);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Get("/{id:[0-9]+}/friends", name="home.user.friends")
|
||||
*/
|
||||
|
@ -6,7 +6,7 @@ use App\Models\Article as ArticleModel;
|
||||
use App\Models\Category as CategoryModel;
|
||||
use App\Models\Reason as ReasonModel;
|
||||
use App\Repos\Category as CategoryRepo;
|
||||
use App\Repos\Tag as TagRepo;
|
||||
use App\Services\Logic\Article\XmTagList as XmTagListService;
|
||||
use App\Services\Logic\ArticleTrait;
|
||||
|
||||
class Article extends Service
|
||||
@ -25,33 +25,9 @@ class Article extends Service
|
||||
|
||||
public function getXmTags($id)
|
||||
{
|
||||
$tagRepo = new TagRepo();
|
||||
$service = new XmTagListService();
|
||||
|
||||
$allTags = $tagRepo->findAll(['published' => 1], 'priority');
|
||||
|
||||
if ($allTags->count() == 0) return [];
|
||||
|
||||
$articleTagIds = [];
|
||||
|
||||
if ($id > 0) {
|
||||
$article = $this->checkArticle($id);
|
||||
if (!empty($article->tags)) {
|
||||
$articleTagIds = kg_array_column($article->tags, 'id');
|
||||
}
|
||||
}
|
||||
|
||||
$list = [];
|
||||
|
||||
foreach ($allTags as $tag) {
|
||||
$selected = in_array($tag->id, $articleTagIds);
|
||||
$list[] = [
|
||||
'name' => $tag->name,
|
||||
'value' => $tag->id,
|
||||
'selected' => $selected,
|
||||
];
|
||||
}
|
||||
|
||||
return $list;
|
||||
return $service->handle($id);
|
||||
}
|
||||
|
||||
public function getCategories()
|
||||
|
@ -5,7 +5,7 @@ namespace App\Http\Home\Services;
|
||||
use App\Models\Category as CategoryModel;
|
||||
use App\Models\Question as QuestionModel;
|
||||
use App\Repos\Category as CategoryRepo;
|
||||
use App\Repos\Tag as TagRepo;
|
||||
use App\Services\Logic\Question\XmTagList as XmTagListService;
|
||||
use App\Services\Logic\QuestionTrait;
|
||||
use App\Services\Logic\Service as LogicService;
|
||||
|
||||
@ -36,33 +36,9 @@ class Question extends LogicService
|
||||
|
||||
public function getXmTags($id)
|
||||
{
|
||||
$tagRepo = new TagRepo();
|
||||
$service = new XmTagListService();
|
||||
|
||||
$allTags = $tagRepo->findAll(['published' => 1], 'priority');
|
||||
|
||||
if ($allTags->count() == 0) return [];
|
||||
|
||||
$questionTagIds = [];
|
||||
|
||||
if ($id > 0) {
|
||||
$question = $this->checkQuestion($id);
|
||||
if (!empty($question->tags)) {
|
||||
$questionTagIds = kg_array_column($question->tags, 'id');
|
||||
}
|
||||
}
|
||||
|
||||
$list = [];
|
||||
|
||||
foreach ($allTags as $tag) {
|
||||
$selected = in_array($tag->id, $questionTagIds);
|
||||
$list[] = [
|
||||
'name' => $tag->name,
|
||||
'value' => $tag->id,
|
||||
'selected' => $selected,
|
||||
];
|
||||
}
|
||||
|
||||
return $list;
|
||||
return $service->handle($id);
|
||||
}
|
||||
|
||||
public function getQuestion($id)
|
||||
|
@ -12,19 +12,19 @@
|
||||
<div class="layout-main">
|
||||
<div class="writer-content wrap">
|
||||
<form class="layui-form" method="POST" action="{{ url({'for':'home.answer.create'}) }}">
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block" style="margin:0;">
|
||||
<input class="layui-input" type="text" name="title" value="{{ question.title }}" readonly="readonly">
|
||||
<div class="layui-form-item first-form-item">
|
||||
<div class="layui-input-block">
|
||||
<input class="layui-input" type="text" name="title" value="{{ question.title }}" disabled="disabled">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block" style="margin:0;">
|
||||
<div class="layui-input-block">
|
||||
<div id="vditor"></div>
|
||||
<textarea name="content" class="layui-hide" id="vditor-textarea"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item center">
|
||||
<div class="layui-input-block" style="margin:0;">
|
||||
<div class="layui-input-block">
|
||||
<button class="layui-btn kg-submit" lay-submit="true" lay-filter="go">发布回答</button>
|
||||
<input type="hidden" name="question_id" value="{{ question.id }}">
|
||||
</div>
|
||||
|
@ -12,19 +12,19 @@
|
||||
<div class="layout-main">
|
||||
<div class="writer-content wrap">
|
||||
<form class="layui-form" method="POST" action="{{ url({'for':'home.answer.update','id':answer.id}) }}">
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block" style="margin:0;">
|
||||
<input class="layui-input" type="text" name="title" value="{{ question.title }}" readonly="readonly">
|
||||
<div class="layui-form-item first-form-item">
|
||||
<div class="layui-input-block">
|
||||
<input class="layui-input" type="text" name="title" value="{{ question.title }}" disabled="disabled">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block" style="margin:0;">
|
||||
<div class="layui-input-block">
|
||||
<div id="vditor"></div>
|
||||
<textarea name="content" class="layui-hide" id="vditor-textarea">{{ answer.content }}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item center">
|
||||
<div class="layui-input-block" style="margin:0;">
|
||||
<div class="layui-input-block">
|
||||
<button class="layui-btn kg-submit" lay-submit="true" lay-filter="go">发布回答</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -16,10 +16,10 @@
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<form class="layui-form" method="POST" action="{{ action_url }}">
|
||||
<div class="layout-main">
|
||||
<div class="layout-main">
|
||||
<form class="layui-form" method="POST" action="{{ action_url }}">
|
||||
<div class="writer-content wrap">
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-form-item first-form-item">
|
||||
<div class="layui-input-block">
|
||||
<input class="layui-input" type="text" name="title" value="{{ article.title }}" placeholder="请输入标题..." lay-verify="required">
|
||||
</div>
|
||||
@ -31,57 +31,57 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="layer-publish" style="display:none;">
|
||||
<div class="writer-sidebar">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">分类标签</label>
|
||||
<div class="layui-input-block">
|
||||
<div id="xm-tag-ids"></div>
|
||||
<input type="hidden" name="xm_tags" value='{{ xm_tags|json_encode }}'>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">来源类型</label>
|
||||
<div class="layui-input-block">
|
||||
<select name="source_type" lay-filter="source_type" lay-verify="required">
|
||||
<option value="">请选择</option>
|
||||
{% for value,title in source_types %}
|
||||
<option value="{{ value }}" {% if article.source_type == value %}selected="selected"{% endif %}>{{ title }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div id="source-url-block" style="{{ source_url_display }}">
|
||||
<div id="layer-publish" style="display:none;">
|
||||
<div class="writer-sidebar">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">来源网址</label>
|
||||
<label class="layui-form-label">分类标签</label>
|
||||
<div class="layui-input-block">
|
||||
<input class="layui-input" type="text" name="source_url" value="{{ article.source_url }}">
|
||||
<div id="xm-tag-ids"></div>
|
||||
<input type="hidden" name="xm_tags" value='{{ xm_tags|json_encode }}'>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">来源类型</label>
|
||||
<div class="layui-input-block">
|
||||
<select name="source_type" lay-filter="source_type" lay-verify="required">
|
||||
<option value="">请选择</option>
|
||||
{% for value,title in source_types %}
|
||||
<option value="{{ value }}" {% if article.source_type == value %}selected="selected"{% endif %}>{{ title }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div id="source-url-block" style="{{ source_url_display }}">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">来源网址</label>
|
||||
<div class="layui-input-block">
|
||||
<input class="layui-input" type="text" name="source_url" value="{{ article.source_url }}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">关闭评论</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="closed" value="1" title="是" {% if article.closed == 1 %}checked="checked"{% endif %}>
|
||||
<input type="radio" name="closed" value="0" title="否" {% if article.closed == 0 %}checked="checked"{% endif %}>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">仅我可见</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="private" value="1" title="是" {% if article.private == 1 %}checked="checked"{% endif %}>
|
||||
<input type="radio" name="private" value="0" title="否" {% if article.private == 0 %}checked="checked"{% endif %}>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item last-form-item">
|
||||
<div class="layui-input-block">
|
||||
<button class="layui-btn layui-btn-fluid kg-submit" lay-submit="true" lay-filter="go">确认发布</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">关闭评论</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="closed" value="1" title="是" {% if article.closed == 1 %}checked="checked"{% endif %}>
|
||||
<input type="radio" name="closed" value="0" title="否" {% if article.closed == 0 %}checked="checked"{% endif %}>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">仅我可见</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="private" value="1" title="是" {% if article.private == 1 %}checked="checked"{% endif %}>
|
||||
<input type="radio" name="private" value="0" title="否" {% if article.private == 0 %}checked="checked"{% endif %}>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item last-form-item">
|
||||
<div class="layui-input-block">
|
||||
<button class="layui-btn layui-btn-fluid kg-submit" lay-submit="true" lay-filter="go">确认发布</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% set update_url = url({'for':'home.igm.update','id':group.id}) %}
|
||||
{% set update_url = url({'for':'home.im_group.update','id':group.id}) %}
|
||||
{% set name_readonly = group.type == 1 ? 'readonly="readonly"' : '' %}
|
||||
|
||||
<form class="layui-form" method="post" action="{{ update_url }}">
|
||||
|
@ -15,10 +15,10 @@
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<form class="layui-form" method="POST" action="{{ action_url }}">
|
||||
<div class="layout-main clearfix">
|
||||
<div class="layout-main">
|
||||
<form class="layui-form" method="POST" action="{{ action_url }}">
|
||||
<div class="writer-content wrap">
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-form-item first-form-item">
|
||||
<div class="layui-input-block">
|
||||
<input class="layui-input" type="text" name="title" value="{{ question.title }}" placeholder="请输入标题..." lay-verify="required">
|
||||
</div>
|
||||
@ -30,24 +30,24 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="layer-publish" style="display:none;">
|
||||
<div class="writer-sidebar">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">分类标签</label>
|
||||
<div class="layui-input-block">
|
||||
<div id="xm-tag-ids"></div>
|
||||
<input type="hidden" name="xm_tags" value='{{ xm_tags|json_encode }}'>
|
||||
<div id="layer-publish" style="display:none;">
|
||||
<div class="writer-sidebar">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">分类标签</label>
|
||||
<div class="layui-input-block">
|
||||
<div id="xm-tag-ids"></div>
|
||||
<input type="hidden" name="xm_tags" value='{{ xm_tags|json_encode }}'>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item last-form-item">
|
||||
<div class="layui-input-block">
|
||||
<button class="layui-btn layui-btn-fluid kg-submit" lay-submit="true" lay-filter="go">确认发布</button>
|
||||
<div class="layui-form-item last-form-item">
|
||||
<div class="layui-input-block">
|
||||
<button class="layui-btn layui-btn-fluid kg-submit" lay-submit="true" lay-filter="go">确认发布</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
|
@ -3,7 +3,6 @@
|
||||
{% for item in pager.items %}
|
||||
{% set owner_url = url({'for':'home.user.show','id':item.owner.id}) %}
|
||||
{% set question_url = url({'for':'home.question.show','id':item.id}) %}
|
||||
{% set solved_class = item.solved ? 'column solved' : 'column' %}
|
||||
<div class="search-question-card article-card question-card">
|
||||
<div class="info">
|
||||
<div class="title layui-elip">
|
||||
|
25
app/Http/Home/Views/user/answers.volt
Normal file
25
app/Http/Home/Views/user/answers.volt
Normal file
@ -0,0 +1,25 @@
|
||||
{% if pager.total_pages > 0 %}
|
||||
<div class="question-list">
|
||||
<div class="layui-row layui-col-space20">
|
||||
{% for item in pager.items %}
|
||||
{% set answer_url = url({'for':'home.answer.show','id':item.id}) %}
|
||||
<div class="layui-col-md6">
|
||||
<div class="article-card wrap">
|
||||
<div class="info">
|
||||
<div class="title layui-elip">
|
||||
<a href="{{ answer_url }}" target="_blank">{{ item.question.title }}</a>
|
||||
</div>
|
||||
<div class="summary">{{ substr(item.summary,0,80) }}</div>
|
||||
<div class="meta">
|
||||
<span class="time">{{ item.create_time|time_ago }}</span>
|
||||
<span class="like">{{ item.like_count }} 点赞</span>
|
||||
<span class="comment">{{ item.comment_count }} 评论</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{{ partial('partials/pager_ajax') }}
|
||||
{% endif %}
|
@ -1,23 +1,19 @@
|
||||
{{ partial('macros/article') }}
|
||||
|
||||
{% if pager.total_pages > 0 %}
|
||||
<div class="article-list clearfix">
|
||||
<div class="article-list">
|
||||
<div class="layui-row layui-col-space20">
|
||||
{% for item in pager.items %}
|
||||
{% set article_url = url({'for':'home.article.show','id':item.id}) %}
|
||||
<div class="layui-col-md3">
|
||||
<div class="course-card">
|
||||
<span class="type layui-badge layui-bg-green">{{ source_type(item.source_type) }}</span>
|
||||
<div class="cover">
|
||||
<a href="{{ article_url }}" target="_blank">
|
||||
<img src="{{ item.cover }}!cover_270" alt="{{ item.title }}" title="{{ item.title }}">
|
||||
</a>
|
||||
</div>
|
||||
<div class="layui-col-md6">
|
||||
<div class="article-card wrap">
|
||||
<div class="info">
|
||||
<div class="title layui-elip">
|
||||
<a href="{{ article_url }}" title="{{ item.title }}" target="_blank">{{ item.title }}</a>
|
||||
</div>
|
||||
<div class="summary">{{ substr(item.summary,0,80) }}</div>
|
||||
<div class="meta">
|
||||
<span class="time">{{ item.create_time|time_ago }}</span>
|
||||
<span class="view">{{ item.view_count }} 浏览</span>
|
||||
<span class="like">{{ item.like_count }} 点赞</span>
|
||||
<span class="comment">{{ item.comment_count }} 评论</span>
|
||||
|
@ -35,13 +35,12 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for item in pager.items %}
|
||||
{% set question_url = url({'for':'home.question.show','id':item.question.id}) %}
|
||||
{% set answer_url = url({'for':'home.answer.show','id':item.id}) %}
|
||||
{% set show_url = url({'for':'home.answer.show','id':item.id}) %}
|
||||
{% set edit_url = url({'for':'home.answer.edit','id':item.id}) %}
|
||||
{% set delete_url = url({'for':'home.answer.delete','id':item.id}) %}
|
||||
<tr>
|
||||
<td>
|
||||
<p>提问:<a href="{{ question_url }}" target="_blank">{{ item.question.title }}</a></p>
|
||||
<p>提问:<a href="{{ show_url }}" target="_blank">{{ item.question.title }}</a></p>
|
||||
<p>回答:{{ substr(item.summary,0,32) }}</p>
|
||||
<p class="meta">
|
||||
创建:<span class="layui-badge layui-bg-gray">{{ item.create_time|time_ago }}</span>
|
||||
@ -50,7 +49,6 @@
|
||||
</td>
|
||||
<td>{{ item.like_count }}</td>
|
||||
<td>
|
||||
<a href="{{ answer_url }}" class="layui-btn layui-btn-xs">详情</a>
|
||||
<a href="{{ edit_url }}" class="layui-btn layui-btn-xs layui-bg-blue">修改</a>
|
||||
<a href="javascript:" class="layui-btn layui-btn-xs layui-bg-red kg-delete" data-url="{{ delete_url }}">删除</a>
|
||||
</td>
|
||||
|
@ -67,10 +67,4 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block include_js %}
|
||||
|
||||
{{ js_include('home/js/user.console.js') }}
|
||||
|
||||
{% endblock %}
|
@ -63,10 +63,4 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block include_js %}
|
||||
|
||||
{{ js_include('home/js/user.console.js') }}
|
||||
|
||||
{% endblock %}
|
@ -28,10 +28,4 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block include_js %}
|
||||
|
||||
{{ js_include('home/js/user.console.js') }}
|
||||
|
||||
{% endblock %}
|
@ -44,7 +44,7 @@
|
||||
<td>{{ item.area }}</td>
|
||||
<td>{{ item.active_time|time_ago }}</td>
|
||||
<td class="center">
|
||||
<button class="layui-btn layui-btn-sm kg-delete" data-url="{{ delete_url }}">删除</button>
|
||||
<button class="layui-btn layui-btn-sm layui-bg-red kg-delete" data-url="{{ delete_url }}">删除</button>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
@ -56,10 +56,4 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block include_js %}
|
||||
|
||||
{{ js_include('home/js/my.im.js') }}
|
||||
|
||||
{% endblock %}
|
@ -42,10 +42,4 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block include_js %}
|
||||
|
||||
{{ js_include('home/js/user.console.js') }}
|
||||
|
||||
{% endblock %}
|
26
app/Http/Home/Views/user/questions.volt
Normal file
26
app/Http/Home/Views/user/questions.volt
Normal file
@ -0,0 +1,26 @@
|
||||
{% if pager.total_pages > 0 %}
|
||||
<div class="question-list">
|
||||
<div class="layui-row layui-col-space20">
|
||||
{% for item in pager.items %}
|
||||
{% set question_url = url({'for':'home.question.show','id':item.id}) %}
|
||||
<div class="layui-col-md6">
|
||||
<div class="article-card wrap">
|
||||
<div class="info">
|
||||
<div class="title layui-elip">
|
||||
<a href="{{ question_url }}" target="_blank">{{ item.title }}</a>
|
||||
</div>
|
||||
<div class="summary">{{ substr(item.summary,0,80) }}</div>
|
||||
<div class="meta">
|
||||
<span class="time">{{ item.create_time|time_ago }}</span>
|
||||
<span class="view">{{ item.view_count }} 浏览</span>
|
||||
<span class="like">{{ item.like_count }} 点赞</span>
|
||||
<span class="answer">{{ item.answer_count }} 回答</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{{ partial('partials/pager_ajax') }}
|
||||
{% endif %}
|
@ -43,11 +43,15 @@
|
||||
|
||||
{% set show_tab_courses = user.course_count > 0 %}
|
||||
{% set show_tab_articles = user.article_count > 0 %}
|
||||
{% set show_tab_questions = user.question_count > 0 %}
|
||||
{% set show_tab_answers = user.answer_count > 0 %}
|
||||
{% set show_tab_friends = user.friend_count > 0 %}
|
||||
{% set show_tab_groups = user.group_count > 0 %}
|
||||
|
||||
{% set courses_url = url({'for':'home.user.courses','id':user.id}) %}
|
||||
{% set articles_url = url({'for':'home.user.articles','id':user.id}) %}
|
||||
{% set questions_url = url({'for':'home.user.questions','id':user.id}) %}
|
||||
{% set answers_url = url({'for':'home.user.answers','id':user.id}) %}
|
||||
{% set friends_url = url({'for':'home.user.friends','id':user.id}) %}
|
||||
{% set groups_url = url({'for':'home.user.groups','id':user.id}) %}
|
||||
|
||||
@ -58,6 +62,12 @@
|
||||
{% if show_tab_articles %}
|
||||
<li>文章</li>
|
||||
{% endif %}
|
||||
{% if show_tab_questions %}
|
||||
<li>提问</li>
|
||||
{% endif %}
|
||||
{% if show_tab_answers %}
|
||||
<li>回答</li>
|
||||
{% endif %}
|
||||
{% if show_tab_friends %}
|
||||
<li>好友</li>
|
||||
{% endif %}
|
||||
@ -70,6 +80,12 @@
|
||||
{% if show_tab_articles %}
|
||||
<div class="layui-tab-item" id="tab-articles" data-url="{{ articles_url }}"></div>
|
||||
{% endif %}
|
||||
{% if show_tab_questions %}
|
||||
<div class="layui-tab-item" id="tab-questions" data-url="{{ questions_url }}"></div>
|
||||
{% endif %}
|
||||
{% if show_tab_answers %}
|
||||
<div class="layui-tab-item" id="tab-answers" data-url="{{ answers_url }}"></div>
|
||||
{% endif %}
|
||||
{% if show_tab_friends %}
|
||||
<div class="layui-tab-item" id="tab-friends" data-url="{{ friends_url }}"></div>
|
||||
{% endif %}
|
||||
|
@ -11,7 +11,7 @@ class AppInfo
|
||||
|
||||
protected $link = 'https://koogua.com';
|
||||
|
||||
protected $version = '1.3.5';
|
||||
protected $version = '1.3.6';
|
||||
|
||||
public function __get($name)
|
||||
{
|
||||
|
@ -449,6 +449,8 @@ function kg_parse_summary($content, $length = 100)
|
||||
|
||||
$content = strip_tags($content);
|
||||
|
||||
$content = trim($content);
|
||||
|
||||
return kg_substr($content, 0, $length);
|
||||
}
|
||||
|
||||
|
@ -153,27 +153,11 @@ class Answer extends Model
|
||||
|
||||
public function beforeCreate()
|
||||
{
|
||||
if (empty($this->cover)) {
|
||||
$this->cover = kg_parse_first_content_image($this->content);
|
||||
}
|
||||
|
||||
if (empty($this->summary)) {
|
||||
$this->summary = kg_parse_summary($this->content);
|
||||
}
|
||||
|
||||
$this->create_time = time();
|
||||
}
|
||||
|
||||
public function beforeUpdate()
|
||||
{
|
||||
if (empty($this->cover)) {
|
||||
$this->cover = kg_parse_first_content_image($this->content);
|
||||
}
|
||||
|
||||
if (empty($this->summary)) {
|
||||
$this->summary = kg_parse_summary($this->content);
|
||||
}
|
||||
|
||||
$this->update_time = time();
|
||||
}
|
||||
|
||||
|
@ -225,14 +225,6 @@ class Article extends Model
|
||||
|
||||
public function beforeCreate()
|
||||
{
|
||||
if (empty($this->cover)) {
|
||||
$this->cover = kg_parse_first_content_image($this->content);
|
||||
}
|
||||
|
||||
if (is_array($this->tags) || is_object($this->tags)) {
|
||||
$this->tags = kg_json_encode($this->tags);
|
||||
}
|
||||
|
||||
$this->create_time = time();
|
||||
}
|
||||
|
||||
@ -246,19 +238,14 @@ class Article extends Model
|
||||
$sync->addItem($this->id);
|
||||
}
|
||||
|
||||
if (empty($this->cover)) {
|
||||
$this->cover = kg_parse_first_content_image($this->content);
|
||||
}
|
||||
$this->update_time = time();
|
||||
}
|
||||
|
||||
if (empty($this->summary)) {
|
||||
$this->summary = kg_parse_summary($this->content);
|
||||
}
|
||||
|
||||
if (is_array($this->tags) || is_array($this->tags)) {
|
||||
public function beforeSave()
|
||||
{
|
||||
if (is_array($this->tags) || is_object($this->tags)) {
|
||||
$this->tags = kg_json_encode($this->tags);
|
||||
}
|
||||
|
||||
$this->update_time = time();
|
||||
}
|
||||
|
||||
public function afterCreate()
|
||||
|
@ -89,7 +89,7 @@ class Consult extends Model
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $priority = 0;
|
||||
public $priority = self::PRIORITY_LOW;
|
||||
|
||||
/**
|
||||
* 私密标识
|
||||
|
@ -129,7 +129,7 @@ class Course extends Model
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
public $origin_price;
|
||||
public $origin_price = 0.00;
|
||||
|
||||
/**
|
||||
* 优惠价格
|
||||
@ -313,12 +313,6 @@ class Course extends Model
|
||||
$this->attrs = kg_json_encode($this->attrs);
|
||||
}
|
||||
|
||||
if (empty($this->cover)) {
|
||||
$this->cover = kg_default_course_cover_path();
|
||||
} elseif (Text::startsWith($this->cover, 'http')) {
|
||||
$this->cover = self::getCoverPath($this->cover);
|
||||
}
|
||||
|
||||
$this->create_time = time();
|
||||
}
|
||||
|
||||
@ -332,22 +326,10 @@ class Course extends Model
|
||||
$sync->addItem($this->id);
|
||||
}
|
||||
|
||||
if (Text::startsWith($this->cover, 'http')) {
|
||||
$this->cover = self::getCoverPath($this->cover);
|
||||
}
|
||||
|
||||
if (empty($this->summary)) {
|
||||
$this->summary = kg_parse_summary($this->details);
|
||||
}
|
||||
|
||||
if (is_array($this->attrs) || is_object($this->attrs)) {
|
||||
$this->attrs = kg_json_encode($this->attrs);
|
||||
}
|
||||
|
||||
if (empty($this->origin_price)) {
|
||||
$this->origin_price = 1.5 * $this->market_price;
|
||||
}
|
||||
|
||||
if ($this->deleted == 1) {
|
||||
$this->published = 0;
|
||||
}
|
||||
@ -355,6 +337,23 @@ class Course extends Model
|
||||
$this->update_time = time();
|
||||
}
|
||||
|
||||
public function beforeSave()
|
||||
{
|
||||
if (empty($this->cover)) {
|
||||
$this->cover = kg_default_course_cover_path();
|
||||
} elseif (Text::startsWith($this->cover, 'http')) {
|
||||
$this->cover = self::getCoverPath($this->cover);
|
||||
}
|
||||
|
||||
if (empty($this->summary)) {
|
||||
$this->summary = kg_parse_summary($this->details);
|
||||
}
|
||||
|
||||
if (empty($this->origin_price)) {
|
||||
$this->origin_price = 1.5 * $this->market_price;
|
||||
}
|
||||
}
|
||||
|
||||
public function afterCreate()
|
||||
{
|
||||
$cache = new MaxCourseIdCache();
|
||||
|
@ -125,18 +125,19 @@ class FlashSale extends Model
|
||||
|
||||
public function beforeCreate()
|
||||
{
|
||||
if (is_array($this->item_info) || is_object($this->item_info)) {
|
||||
$this->item_info = kg_json_encode($this->item_info);
|
||||
}
|
||||
|
||||
if (is_array($this->schedules) || is_object($this->schedules)) {
|
||||
$this->schedules = kg_json_encode($this->schedules);
|
||||
}
|
||||
|
||||
$this->create_time = time();
|
||||
}
|
||||
|
||||
public function beforeUpdate()
|
||||
{
|
||||
if ($this->deleted == 1) {
|
||||
$this->published = 0;
|
||||
}
|
||||
|
||||
$this->update_time = time();
|
||||
}
|
||||
|
||||
public function beforeSave()
|
||||
{
|
||||
if (is_array($this->item_info) || is_object($this->item_info)) {
|
||||
$this->item_info = kg_json_encode($this->item_info);
|
||||
@ -145,12 +146,6 @@ class FlashSale extends Model
|
||||
if (is_array($this->schedules) || is_object($this->schedules)) {
|
||||
$this->schedules = kg_json_encode($this->schedules);
|
||||
}
|
||||
|
||||
if ($this->deleted == 1) {
|
||||
$this->published = 0;
|
||||
}
|
||||
|
||||
$this->update_time = time();
|
||||
}
|
||||
|
||||
public function afterCreate()
|
||||
|
@ -127,12 +127,6 @@ class ImGroup extends Model
|
||||
|
||||
public function beforeCreate()
|
||||
{
|
||||
if (empty($this->avatar)) {
|
||||
$this->avatar = kg_default_group_avatar_path();
|
||||
} elseif (Text::startsWith($this->avatar, 'http')) {
|
||||
$this->avatar = self::getAvatarPath($this->avatar);
|
||||
}
|
||||
|
||||
$this->create_time = time();
|
||||
}
|
||||
|
||||
@ -143,10 +137,6 @@ class ImGroup extends Model
|
||||
$sync->addItem($this->id);
|
||||
}
|
||||
|
||||
if (Text::startsWith($this->avatar, 'http')) {
|
||||
$this->avatar = self::getAvatarPath($this->avatar);
|
||||
}
|
||||
|
||||
if ($this->deleted == 1) {
|
||||
$this->published = 0;
|
||||
}
|
||||
@ -154,6 +144,15 @@ class ImGroup extends Model
|
||||
$this->update_time = time();
|
||||
}
|
||||
|
||||
public function beforeSave()
|
||||
{
|
||||
if (empty($this->avatar)) {
|
||||
$this->avatar = kg_default_group_avatar_path();
|
||||
} elseif (Text::startsWith($this->avatar, 'http')) {
|
||||
$this->avatar = self::getAvatarPath($this->avatar);
|
||||
}
|
||||
}
|
||||
|
||||
public function afterCreate()
|
||||
{
|
||||
$cache = new MaxImGroupIdCache();
|
||||
|
@ -85,20 +85,19 @@ class ImNotice extends Model
|
||||
|
||||
public function beforeCreate()
|
||||
{
|
||||
if (is_array($this->item_info)) {
|
||||
$this->item_info = kg_json_encode($this->item_info);
|
||||
}
|
||||
|
||||
$this->create_time = time();
|
||||
}
|
||||
|
||||
public function beforeUpdate()
|
||||
{
|
||||
$this->update_time = time();
|
||||
}
|
||||
|
||||
public function beforeSave()
|
||||
{
|
||||
if (is_array($this->item_info)) {
|
||||
$this->item_info = kg_json_encode($this->item_info);
|
||||
}
|
||||
|
||||
$this->update_time = time();
|
||||
}
|
||||
|
||||
public function afterFetch()
|
||||
|
@ -112,22 +112,21 @@ class ImUser extends Model
|
||||
|
||||
public function beforeCreate()
|
||||
{
|
||||
if (empty($this->avatar)) {
|
||||
$this->avatar = kg_default_user_avatar_path();
|
||||
} elseif (Text::startsWith($this->avatar, 'http')) {
|
||||
$this->avatar = self::getAvatarPath($this->avatar);
|
||||
}
|
||||
|
||||
$this->create_time = time();
|
||||
}
|
||||
|
||||
public function beforeUpdate()
|
||||
{
|
||||
if (Text::startsWith($this->avatar, 'http')) {
|
||||
$this->update_time = time();
|
||||
}
|
||||
|
||||
public function beforeSave()
|
||||
{
|
||||
if (empty($this->avatar)) {
|
||||
$this->avatar = kg_default_user_avatar_path();
|
||||
} elseif (Text::startsWith($this->avatar, 'http')) {
|
||||
$this->avatar = self::getAvatarPath($this->avatar);
|
||||
}
|
||||
|
||||
$this->update_time = time();
|
||||
}
|
||||
|
||||
public function afterFetch()
|
||||
|
@ -180,20 +180,19 @@ class Notification extends Model
|
||||
|
||||
public function beforeCreate()
|
||||
{
|
||||
if (is_array($this->event_info) || is_object($this->event_info)) {
|
||||
$this->event_info = kg_json_encode($this->event_info);
|
||||
}
|
||||
|
||||
$this->create_time = time();
|
||||
}
|
||||
|
||||
public function beforeUpdate()
|
||||
{
|
||||
$this->update_time = time();
|
||||
}
|
||||
|
||||
public function beforeSave()
|
||||
{
|
||||
if (is_array($this->event_info) || is_object($this->event_info)) {
|
||||
$this->event_info = kg_json_encode($this->event_info);
|
||||
}
|
||||
|
||||
$this->update_time = time();
|
||||
}
|
||||
|
||||
public function afterFetch()
|
||||
|
@ -170,18 +170,15 @@ class Order extends Model
|
||||
{
|
||||
$this->sn = date('YmdHis') . rand(1000, 9999);
|
||||
|
||||
if (is_array($this->item_info) || is_object($this->item_info)) {
|
||||
$this->item_info = kg_json_encode($this->item_info);
|
||||
}
|
||||
|
||||
if (is_array($this->promotion_info) || is_object($this->promotion_info)) {
|
||||
$this->promotion_info = kg_json_encode($this->promotion_info);
|
||||
}
|
||||
|
||||
$this->create_time = time();
|
||||
}
|
||||
|
||||
public function beforeUpdate()
|
||||
{
|
||||
$this->update_time = time();
|
||||
}
|
||||
|
||||
public function beforeSave()
|
||||
{
|
||||
if (is_array($this->item_info) || is_object($this->item_info)) {
|
||||
$this->item_info = kg_json_encode($this->item_info);
|
||||
@ -190,8 +187,6 @@ class Order extends Model
|
||||
if (is_array($this->promotion_info) || is_object($this->promotion_info)) {
|
||||
$this->promotion_info = kg_json_encode($this->promotion_info);
|
||||
}
|
||||
|
||||
$this->update_time = time();
|
||||
}
|
||||
|
||||
public function afterSave()
|
||||
|
@ -105,21 +105,11 @@ class Package extends Model
|
||||
|
||||
public function beforeCreate()
|
||||
{
|
||||
if (empty($this->cover)) {
|
||||
$this->cover = kg_default_package_cover_path();
|
||||
} elseif (Text::startsWith($this->cover, 'http')) {
|
||||
$this->cover = self::getCoverPath($this->cover);
|
||||
}
|
||||
|
||||
$this->create_time = time();
|
||||
}
|
||||
|
||||
public function beforeUpdate()
|
||||
{
|
||||
if (Text::startsWith($this->cover, 'http')) {
|
||||
$this->cover = self::getCoverPath($this->cover);
|
||||
}
|
||||
|
||||
if ($this->deleted == 1) {
|
||||
$this->published = 0;
|
||||
}
|
||||
@ -127,6 +117,15 @@ class Package extends Model
|
||||
$this->update_time = time();
|
||||
}
|
||||
|
||||
public function beforeSave()
|
||||
{
|
||||
if (empty($this->cover)) {
|
||||
$this->cover = kg_default_package_cover_path();
|
||||
} elseif (Text::startsWith($this->cover, 'http')) {
|
||||
$this->cover = self::getCoverPath($this->cover);
|
||||
}
|
||||
}
|
||||
|
||||
public function afterCreate()
|
||||
{
|
||||
$cache = new MaxPackageIdCache();
|
||||
|
@ -166,21 +166,11 @@ class PointGift extends Model
|
||||
$this->attrs = kg_json_encode($this->attrs);
|
||||
}
|
||||
|
||||
if (empty($this->cover)) {
|
||||
$this->cover = kg_default_gift_cover_path();
|
||||
} elseif (Text::startsWith($this->cover, 'http')) {
|
||||
$this->cover = self::getCoverPath($this->cover);
|
||||
}
|
||||
|
||||
$this->create_time = time();
|
||||
}
|
||||
|
||||
public function beforeUpdate()
|
||||
{
|
||||
if (Text::startsWith($this->cover, 'http')) {
|
||||
$this->cover = self::getCoverPath($this->cover);
|
||||
}
|
||||
|
||||
if (is_array($this->attrs) || is_object($this->attrs)) {
|
||||
$this->attrs = kg_json_encode($this->attrs);
|
||||
}
|
||||
@ -192,6 +182,15 @@ class PointGift extends Model
|
||||
$this->update_time = time();
|
||||
}
|
||||
|
||||
public function beforeSave()
|
||||
{
|
||||
if (empty($this->cover)) {
|
||||
$this->cover = kg_default_gift_cover_path();
|
||||
} elseif (Text::startsWith($this->cover, 'http')) {
|
||||
$this->cover = self::getCoverPath($this->cover);
|
||||
}
|
||||
}
|
||||
|
||||
public function afterCreate()
|
||||
{
|
||||
$cache = new MaxPointGiftIdCache();
|
||||
|
@ -95,20 +95,19 @@ class PointHistory extends Model
|
||||
|
||||
public function beforeCreate()
|
||||
{
|
||||
if (is_array($this->event_info) || is_object($this->event_info)) {
|
||||
$this->event_info = kg_json_encode($this->event_info);
|
||||
}
|
||||
|
||||
$this->create_time = time();
|
||||
}
|
||||
|
||||
public function beforeUpdate()
|
||||
{
|
||||
$this->update_time = time();
|
||||
}
|
||||
|
||||
public function beforeSave()
|
||||
{
|
||||
if (is_array($this->event_info) || is_object($this->event_info)) {
|
||||
$this->event_info = kg_json_encode($this->event_info);
|
||||
}
|
||||
|
||||
$this->update_time = time();
|
||||
}
|
||||
|
||||
public function afterFetch()
|
||||
|
@ -239,14 +239,6 @@ class Question extends Model
|
||||
|
||||
public function beforeCreate()
|
||||
{
|
||||
if (is_array($this->tags) || is_object($this->tags)) {
|
||||
$this->tags = kg_json_encode($this->tags);
|
||||
}
|
||||
|
||||
if (empty($this->cover)) {
|
||||
$this->cover = kg_parse_first_content_image($this->content);
|
||||
}
|
||||
|
||||
$this->create_time = time();
|
||||
}
|
||||
|
||||
@ -260,19 +252,14 @@ class Question extends Model
|
||||
$sync->addItem($this->id);
|
||||
}
|
||||
|
||||
$this->update_time = time();
|
||||
}
|
||||
|
||||
public function beforeSave()
|
||||
{
|
||||
if (is_array($this->tags) || is_object($this->tags)) {
|
||||
$this->tags = kg_json_encode($this->tags);
|
||||
}
|
||||
|
||||
if (empty($this->cover)) {
|
||||
$this->cover = kg_parse_first_content_image($this->content);
|
||||
}
|
||||
|
||||
if (empty($this->summary)) {
|
||||
$this->summary = kg_parse_summary($this->content);
|
||||
}
|
||||
|
||||
$this->update_time = time();
|
||||
}
|
||||
|
||||
public function afterCreate()
|
||||
|
@ -152,15 +152,11 @@ class Review extends Model
|
||||
|
||||
public function beforeCreate()
|
||||
{
|
||||
$this->rating = $this->getAvgRating();
|
||||
|
||||
$this->create_time = time();
|
||||
}
|
||||
|
||||
public function beforeUpdate()
|
||||
{
|
||||
$this->rating = $this->getAvgRating();
|
||||
|
||||
if ($this->deleted == 1) {
|
||||
$this->published = 0;
|
||||
}
|
||||
@ -168,6 +164,11 @@ class Review extends Model
|
||||
$this->update_time = time();
|
||||
}
|
||||
|
||||
public function beforeSave()
|
||||
{
|
||||
$this->rating = $this->getAvgRating();
|
||||
}
|
||||
|
||||
protected function getAvgRating()
|
||||
{
|
||||
$sumRating = $this->rating1 + $this->rating2 + $this->rating3;
|
||||
|
@ -103,20 +103,19 @@ class Role extends Model
|
||||
|
||||
public function beforeCreate()
|
||||
{
|
||||
if (is_array($this->routes) || is_object($this->routes)) {
|
||||
$this->routes = kg_json_encode($this->routes);
|
||||
}
|
||||
|
||||
$this->create_time = time();
|
||||
}
|
||||
|
||||
public function beforeUpdate()
|
||||
{
|
||||
$this->update_time = time();
|
||||
}
|
||||
|
||||
public function beforeSave()
|
||||
{
|
||||
if (is_array($this->routes) || is_object($this->routes)) {
|
||||
$this->routes = kg_json_encode($this->routes);
|
||||
}
|
||||
|
||||
$this->update_time = time();
|
||||
}
|
||||
|
||||
public function afterFetch()
|
||||
|
@ -124,6 +124,20 @@ class Slide extends Model
|
||||
}
|
||||
|
||||
public function beforeCreate()
|
||||
{
|
||||
$this->create_time = time();
|
||||
}
|
||||
|
||||
public function beforeUpdate()
|
||||
{
|
||||
if ($this->deleted == 1) {
|
||||
$this->published = 0;
|
||||
}
|
||||
|
||||
$this->update_time = time();
|
||||
}
|
||||
|
||||
public function beforeSave()
|
||||
{
|
||||
if (empty($this->cover)) {
|
||||
$this->cover = kg_default_slide_cover_path();
|
||||
@ -134,25 +148,6 @@ class Slide extends Model
|
||||
if (is_array($this->target_attrs) || is_object($this->target_attrs)) {
|
||||
$this->target_attrs = kg_json_encode($this->target_attrs);
|
||||
}
|
||||
|
||||
$this->create_time = time();
|
||||
}
|
||||
|
||||
public function beforeUpdate()
|
||||
{
|
||||
if (Text::startsWith($this->cover, 'http')) {
|
||||
$this->cover = self::getCoverPath($this->cover);
|
||||
}
|
||||
|
||||
if (is_array($this->target_attrs) || is_object($this->target_attrs)) {
|
||||
$this->target_attrs = kg_json_encode($this->target_attrs);
|
||||
}
|
||||
|
||||
if ($this->deleted == 1) {
|
||||
$this->published = 0;
|
||||
}
|
||||
|
||||
$this->update_time = time();
|
||||
}
|
||||
|
||||
public function afterFetch()
|
||||
|
@ -98,21 +98,11 @@ class Tag extends Model
|
||||
|
||||
public function beforeCreate()
|
||||
{
|
||||
if (empty($this->icon)) {
|
||||
$this->icon = kg_default_icon_path();
|
||||
} elseif (Text::startsWith($this->icon, 'http')) {
|
||||
$this->icon = self::getIconPath($this->icon);
|
||||
}
|
||||
|
||||
$this->create_time = time();
|
||||
}
|
||||
|
||||
public function beforeUpdate()
|
||||
{
|
||||
if (Text::startsWith($this->icon, 'http')) {
|
||||
$this->icon = self::getIconPath($this->icon);
|
||||
}
|
||||
|
||||
if ($this->deleted == 1) {
|
||||
$this->published = 0;
|
||||
}
|
||||
@ -120,6 +110,15 @@ class Tag extends Model
|
||||
$this->update_time = time();
|
||||
}
|
||||
|
||||
public function beforeSave()
|
||||
{
|
||||
if (empty($this->icon)) {
|
||||
$this->icon = kg_default_icon_path();
|
||||
} elseif (Text::startsWith($this->icon, 'http')) {
|
||||
$this->icon = self::getIconPath($this->icon);
|
||||
}
|
||||
}
|
||||
|
||||
public function afterCreate()
|
||||
{
|
||||
$cache = new MaxTagIdCache();
|
||||
|
@ -126,20 +126,19 @@ class Task extends Model
|
||||
|
||||
public function beforeCreate()
|
||||
{
|
||||
if (is_array($this->item_info) || is_object($this->item_info)) {
|
||||
$this->item_info = kg_json_encode($this->item_info);
|
||||
}
|
||||
|
||||
$this->create_time = time();
|
||||
}
|
||||
|
||||
public function beforeUpdate()
|
||||
{
|
||||
$this->update_time = time();
|
||||
}
|
||||
|
||||
public function beforeSave()
|
||||
{
|
||||
if (is_array($this->item_info) || is_object($this->item_info)) {
|
||||
$this->item_info = kg_json_encode($this->item_info);
|
||||
}
|
||||
|
||||
$this->update_time = time();
|
||||
}
|
||||
|
||||
public function afterFetch()
|
||||
|
@ -136,6 +136,13 @@ class User extends Model
|
||||
*/
|
||||
public $answer_count;
|
||||
|
||||
/**
|
||||
* 评论数
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $comment_count;
|
||||
|
||||
/**
|
||||
* 收藏数
|
||||
*
|
||||
@ -199,12 +206,6 @@ class User extends Model
|
||||
|
||||
public function beforeCreate()
|
||||
{
|
||||
if (empty($this->avatar)) {
|
||||
$this->avatar = kg_default_user_avatar_path();
|
||||
} elseif (Text::startsWith($this->avatar, 'http')) {
|
||||
$this->avatar = self::getAvatarPath($this->avatar);
|
||||
}
|
||||
|
||||
$this->create_time = time();
|
||||
}
|
||||
|
||||
@ -215,11 +216,16 @@ class User extends Model
|
||||
$sync->addItem($this->id);
|
||||
}
|
||||
|
||||
if (Text::startsWith($this->avatar, 'http')) {
|
||||
$this->update_time = time();
|
||||
}
|
||||
|
||||
public function beforeSave()
|
||||
{
|
||||
if (empty($this->avatar)) {
|
||||
$this->avatar = kg_default_user_avatar_path();
|
||||
} elseif (Text::startsWith($this->avatar, 'http')) {
|
||||
$this->avatar = self::getAvatarPath($this->avatar);
|
||||
}
|
||||
|
||||
$this->update_time = time();
|
||||
}
|
||||
|
||||
public function afterCreate()
|
||||
|
@ -5,8 +5,7 @@ namespace App\Repos;
|
||||
use App\Library\Paginator\Adapter\QueryBuilder as PagerQueryBuilder;
|
||||
use App\Models\Answer as AnswerModel;
|
||||
use App\Models\Article as ArticleModel;
|
||||
use App\Models\ArticleFavorite as ArticleFavoriteModel;
|
||||
use App\Models\CourseFavorite as CourseFavoriteModel;
|
||||
use App\Models\Comment as CommentModel;
|
||||
use App\Models\CourseUser as CourseUserModel;
|
||||
use App\Models\ImUser as ImUserModel;
|
||||
use App\Models\Notification as NotificationModel;
|
||||
@ -199,19 +198,11 @@ class User extends Repository
|
||||
]);
|
||||
}
|
||||
|
||||
public function countCourseFavorites($userId)
|
||||
public function countComments($userId)
|
||||
{
|
||||
return (int)CourseFavoriteModel::count([
|
||||
'conditions' => 'user_id = :user_id: AND deleted = 0',
|
||||
'bind' => ['user_id' => $userId],
|
||||
]);
|
||||
}
|
||||
|
||||
public function countArticleFavorites($userId)
|
||||
{
|
||||
return (int)ArticleFavoriteModel::count([
|
||||
'conditions' => 'user_id = :user_id: AND deleted = 0',
|
||||
'bind' => ['user_id' => $userId],
|
||||
return (int)CommentModel::count([
|
||||
'conditions' => 'owner_id = ?1 AND published = ?2',
|
||||
'bind' => [1 => $userId, 2 => CommentModel::PUBLISH_APPROVED],
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -12,16 +12,15 @@ 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\Traits\Client as ClientTrait;
|
||||
use App\Validators\Answer as AnswerValidator;
|
||||
use App\Validators\UserLimit as UserLimitValidator;
|
||||
|
||||
class AnswerCreate extends LogicService
|
||||
{
|
||||
|
||||
use ClientTrait;
|
||||
use QuestionTrait;
|
||||
use AnswerTrait;
|
||||
use AnswerDataTrait;
|
||||
|
||||
public function handle()
|
||||
{
|
||||
@ -41,15 +40,15 @@ class AnswerCreate extends LogicService
|
||||
|
||||
$answer = new AnswerModel();
|
||||
|
||||
$answer->published = $this->getPublishStatus($user);
|
||||
$answer->content = $validator->checkContent($post['content']);
|
||||
$answer->client_type = $this->getClientType();
|
||||
$answer->client_ip = $this->getClientIp();
|
||||
$answer->question_id = $question->id;
|
||||
$answer->owner_id = $user->id;
|
||||
$data = $this->handlePostData($post);
|
||||
|
||||
$answer->create();
|
||||
$data['published'] = $this->getPublishStatus($user);
|
||||
$data['question_id'] = $question->id;
|
||||
$data['owner_id'] = $user->id;
|
||||
|
||||
$answer->create($data);
|
||||
|
||||
$this->saveDynamicAttrs($answer);
|
||||
$this->incrUserDailyAnswerCount($user);
|
||||
$this->recountQuestionAnswers($question);
|
||||
$this->recountUserAnswers($user);
|
||||
@ -73,11 +72,6 @@ class AnswerCreate extends LogicService
|
||||
return $answer;
|
||||
}
|
||||
|
||||
protected function getPublishStatus(UserModel $user)
|
||||
{
|
||||
return $user->answer_count > 2 ? AnswerModel::PUBLISH_APPROVED : AnswerModel::PUBLISH_PENDING;
|
||||
}
|
||||
|
||||
protected function incrUserDailyAnswerCount(UserModel $user)
|
||||
{
|
||||
$this->eventsManager->fire('UserDailyCounter:incrAnswerCount', $this, $user);
|
||||
|
43
app/Services/Logic/Answer/AnswerDataTrait.php
Normal file
43
app/Services/Logic/Answer/AnswerDataTrait.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Logic\Answer;
|
||||
|
||||
use App\Models\Answer as AnswerModel;
|
||||
use App\Models\User as UserModel;
|
||||
use App\Traits\Client as ClientTrait;
|
||||
use App\Validators\Answer as AnswerValidator;
|
||||
|
||||
trait AnswerDataTrait
|
||||
{
|
||||
|
||||
use ClientTrait;
|
||||
|
||||
protected function handlePostData($post)
|
||||
{
|
||||
$data = [];
|
||||
|
||||
$data['client_type'] = $this->getClientType();
|
||||
$data['client_ip'] = $this->getClientIp();
|
||||
|
||||
$validator = new AnswerValidator();
|
||||
|
||||
$data['content'] = $validator->checkContent($post['content']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function getPublishStatus(UserModel $user)
|
||||
{
|
||||
return $user->answer_count > 2 ? AnswerModel::PUBLISH_APPROVED : AnswerModel::PUBLISH_PENDING;
|
||||
}
|
||||
|
||||
protected function saveDynamicAttrs(AnswerModel $answer)
|
||||
{
|
||||
$answer->cover = kg_parse_first_content_image($answer->content);
|
||||
|
||||
$answer->summary = kg_parse_summary($answer->content);
|
||||
|
||||
$answer->update();
|
||||
}
|
||||
|
||||
}
|
@ -75,8 +75,16 @@ class AnswerInfo extends LogicService
|
||||
{
|
||||
$me = [
|
||||
'liked' => 0,
|
||||
'owned' => 0,
|
||||
];
|
||||
|
||||
$isOwner = $user->id == $answer->owner_id;
|
||||
$approved = $answer->published = AnswerModel::PUBLISH_APPROVED;
|
||||
|
||||
if ($isOwner || $approved) {
|
||||
$me['owned'] = 1;
|
||||
}
|
||||
|
||||
if ($user->id > 0) {
|
||||
|
||||
$likeRepo = new AnswerLikeRepo();
|
||||
|
72
app/Services/Logic/Answer/AnswerList.php
Normal file
72
app/Services/Logic/Answer/AnswerList.php
Normal file
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Logic\Answer;
|
||||
|
||||
use App\Builders\AnswerList as AnswerListBuilder;
|
||||
use App\Library\Paginator\Query as PagerQuery;
|
||||
use App\Repos\Answer as AnswerRepo;
|
||||
use App\Services\Logic\Service as LogicService;
|
||||
|
||||
class AnswerList extends LogicService
|
||||
{
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$pagerQuery = new PagerQuery();
|
||||
|
||||
$params = $pagerQuery->getParams();
|
||||
|
||||
$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);
|
||||
}
|
||||
|
||||
public function handleAnswers($pager)
|
||||
{
|
||||
if ($pager->total_items == 0) {
|
||||
return $pager;
|
||||
}
|
||||
|
||||
$builder = new AnswerListBuilder();
|
||||
|
||||
$answers = $pager->items->toArray();
|
||||
|
||||
$questions = $builder->getQuestions($answers);
|
||||
|
||||
$users = $builder->getUsers($answers);
|
||||
|
||||
$items = [];
|
||||
|
||||
foreach ($answers as $answer) {
|
||||
|
||||
$question = $questions[$answer['question_id']] ?? new \stdClass();
|
||||
$owner = $users[$answer['owner_id']] ?? new \stdClass();
|
||||
|
||||
$items[] = [
|
||||
'id' => $answer['id'],
|
||||
'summary' => $answer['summary'],
|
||||
'published' => $answer['published'],
|
||||
'accepted' => $answer['accepted'],
|
||||
'comment_count' => $answer['comment_count'],
|
||||
'like_count' => $answer['like_count'],
|
||||
'create_time' => $answer['create_time'],
|
||||
'update_time' => $answer['update_time'],
|
||||
'question' => $question,
|
||||
'owner' => $owner,
|
||||
];
|
||||
}
|
||||
|
||||
$pager->items = $items;
|
||||
|
||||
return $pager;
|
||||
}
|
||||
|
||||
}
|
@ -14,6 +14,7 @@ class AnswerUpdate extends LogicService
|
||||
use ClientTrait;
|
||||
use QuestionTrait;
|
||||
use AnswerTrait;
|
||||
use AnswerDataTrait;
|
||||
|
||||
public function handle($id)
|
||||
{
|
||||
@ -29,11 +30,11 @@ class AnswerUpdate extends LogicService
|
||||
|
||||
$validator->checkIfAllowEdit($answer);
|
||||
|
||||
$answer->content = $validator->checkContent($post['content']);
|
||||
$answer->client_type = $this->getClientType();
|
||||
$answer->client_ip = $this->getClientIp();
|
||||
$data = $this->handlePostData($post);
|
||||
|
||||
$answer->update();
|
||||
$answer->update($data);
|
||||
|
||||
$this->saveDynamicAttrs($answer);
|
||||
|
||||
$this->eventsManager->fire('Answer:afterUpdate', $this, $answer);
|
||||
|
||||
|
@ -29,7 +29,6 @@ class ArticleCreate extends LogicService
|
||||
$data = $this->handlePostData($post);
|
||||
|
||||
$data['published'] = $this->getPublishStatus($user);
|
||||
|
||||
$data['owner_id'] = $user->id;
|
||||
|
||||
$article->create($data);
|
||||
@ -38,6 +37,7 @@ class ArticleCreate extends LogicService
|
||||
$this->saveTags($article, $post['xm_tag_ids']);
|
||||
}
|
||||
|
||||
$this->saveDynamicAttrs($article);
|
||||
$this->incrUserDailyArticleCount($user);
|
||||
$this->recountUserArticles($user);
|
||||
|
||||
@ -50,11 +50,6 @@ class ArticleCreate extends LogicService
|
||||
return $article;
|
||||
}
|
||||
|
||||
protected function getPublishStatus(UserModel $user)
|
||||
{
|
||||
return $user->article_count > 100 ? ArticleModel::PUBLISH_APPROVED : ArticleModel::PUBLISH_PENDING;
|
||||
}
|
||||
|
||||
protected function incrUserDailyArticleCount(UserModel $user)
|
||||
{
|
||||
$this->eventsManager->fire('UserDailyCounter:incrArticleCount', $this, $user);
|
||||
|
@ -5,6 +5,7 @@ namespace App\Services\Logic\Article;
|
||||
use App\Library\Utils\Word as WordUtil;
|
||||
use App\Models\Article as ArticleModel;
|
||||
use App\Models\ArticleTag as ArticleTagModel;
|
||||
use App\Models\User as UserModel;
|
||||
use App\Repos\ArticleTag as ArticleTagRepo;
|
||||
use App\Repos\Tag as TagRepo;
|
||||
use App\Traits\Client as ClientTrait;
|
||||
@ -19,6 +20,9 @@ trait ArticleDataTrait
|
||||
{
|
||||
$data = [];
|
||||
|
||||
$data['client_type'] = $this->getClientType();
|
||||
$data['client_ip'] = $this->getClientIp();
|
||||
|
||||
$validator = new ArticleValidator();
|
||||
|
||||
$data['title'] = $validator->checkTitle($post['title']);
|
||||
@ -48,6 +52,25 @@ trait ArticleDataTrait
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function getPublishStatus(UserModel $user)
|
||||
{
|
||||
return $user->article_count > 100 ? ArticleModel::PUBLISH_APPROVED : ArticleModel::PUBLISH_PENDING;
|
||||
}
|
||||
|
||||
protected function saveDynamicAttrs(ArticleModel $article)
|
||||
{
|
||||
$article->cover = kg_parse_first_content_image($article->content);
|
||||
|
||||
$article->summary = kg_parse_summary($article->content);
|
||||
|
||||
$article->update();
|
||||
|
||||
/**
|
||||
* 重新执行afterFetch
|
||||
*/
|
||||
$article->afterFetch();
|
||||
}
|
||||
|
||||
protected function saveTags(ArticleModel $article, $tagIds)
|
||||
{
|
||||
$originTagIds = [];
|
||||
|
@ -8,7 +8,6 @@ use App\Models\Article as ArticleModel;
|
||||
use App\Repos\Article as ArticleRepo;
|
||||
use App\Services\Logic\Service as LogicService;
|
||||
use App\Validators\ArticleQuery as ArticleQueryValidator;
|
||||
use Phalcon\Text;
|
||||
|
||||
class ArticleList extends LogicService
|
||||
{
|
||||
@ -52,18 +51,8 @@ class ArticleList extends LogicService
|
||||
|
||||
$items = [];
|
||||
|
||||
$baseUrl = kg_cos_url();
|
||||
|
||||
foreach ($articles as $article) {
|
||||
|
||||
if (!empty($article['cover']) && !Text::startsWith($article['cover'], 'http')) {
|
||||
$article['cover'] = $baseUrl . $article['cover'];
|
||||
}
|
||||
|
||||
if (empty($article['summary'])) {
|
||||
$article['summary'] = kg_parse_summary($article['content']);
|
||||
}
|
||||
|
||||
$article['tags'] = json_decode($article['tags'], true);
|
||||
|
||||
$category = $categories[$article['category_id']] ?? new \stdClass();
|
||||
|
@ -44,6 +44,8 @@ class ArticleUpdate extends LogicService
|
||||
$this->saveTags($article, $post['xm_tag_ids']);
|
||||
}
|
||||
|
||||
$this->saveDynamicAttrs($article);
|
||||
|
||||
$this->eventsManager->fire('Article:afterUpdate', $this, $article);
|
||||
|
||||
return $article;
|
||||
|
50
app/Services/Logic/Article/XmTagList.php
Normal file
50
app/Services/Logic/Article/XmTagList.php
Normal file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Logic\Article;
|
||||
|
||||
use App\Repos\Article as ArticleRepo;
|
||||
use App\Repos\Tag as TagRepo;
|
||||
use App\Services\Logic\Service as LogicService;
|
||||
|
||||
class XmTagList extends LogicService
|
||||
{
|
||||
|
||||
public function handle($id)
|
||||
{
|
||||
$tagRepo = new TagRepo();
|
||||
|
||||
$allTags = $tagRepo->findAll(['published' => 1]);
|
||||
|
||||
if ($allTags->count() == 0) return [];
|
||||
|
||||
$articleTagIds = [];
|
||||
|
||||
if ($id > 0) {
|
||||
$article = $this->findArticle($id);
|
||||
if (!empty($article->tags)) {
|
||||
$articleTagIds = kg_array_column($article->tags, 'id');
|
||||
}
|
||||
}
|
||||
|
||||
$list = [];
|
||||
|
||||
foreach ($allTags as $tag) {
|
||||
$selected = in_array($tag->id, $articleTagIds);
|
||||
$list[] = [
|
||||
'name' => $tag->name,
|
||||
'value' => $tag->id,
|
||||
'selected' => $selected,
|
||||
];
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
protected function findArticle($id)
|
||||
{
|
||||
$articleRepo = new ArticleRepo();
|
||||
|
||||
return $articleRepo->findById($id);
|
||||
}
|
||||
|
||||
}
|
@ -4,6 +4,7 @@ namespace App\Services\Logic\Comment;
|
||||
|
||||
use App\Models\Answer as AnswerModel;
|
||||
use App\Models\Article as ArticleModel;
|
||||
use App\Models\Chapter as ChapterModel;
|
||||
use App\Models\Comment as CommentModel;
|
||||
use App\Models\Question as QuestionModel;
|
||||
use App\Models\User as UserModel;
|
||||
@ -17,24 +18,38 @@ trait AfterCreateTrait
|
||||
|
||||
use CountTrait;
|
||||
|
||||
protected function incrItemCommentCount($item, CommentModel $comment, UserModel $user)
|
||||
{
|
||||
if ($comment->published != CommentModel::PUBLISH_APPROVED) return;
|
||||
|
||||
if ($item instanceof ChapterModel) {
|
||||
$this->incrChapterCommentCount($item);
|
||||
} elseif ($item instanceof ArticleModel) {
|
||||
$this->incrArticleCommentCount($item);
|
||||
} elseif ($item instanceof QuestionModel) {
|
||||
$this->incrQuestionCommentCount($item);
|
||||
} elseif ($item instanceof AnswerModel) {
|
||||
$this->incrAnswerCommentCount($item);
|
||||
}
|
||||
|
||||
$this->incrUserCommentCount($user);
|
||||
}
|
||||
|
||||
protected function handleNoticeAndPoint($item, CommentModel $comment, UserModel $user)
|
||||
{
|
||||
if ($comment->published != CommentModel::PUBLISH_APPROVED) return;
|
||||
|
||||
if ($item instanceof ArticleModel) {
|
||||
$this->incrArticleCommentCount($item);
|
||||
if ($user->id != $item->owner_id) {
|
||||
$this->handleArticleCommentedNotice($item, $comment);
|
||||
$this->handleCommentPostPoint($comment);
|
||||
}
|
||||
} elseif ($item instanceof QuestionModel) {
|
||||
$this->incrQuestionCommentCount($item);
|
||||
if ($user->id != $item->owner_id) {
|
||||
$this->handleQuestionCommentedNotice($item, $comment);
|
||||
$this->handleCommentPostPoint($comment);
|
||||
}
|
||||
} elseif ($item instanceof AnswerModel) {
|
||||
$this->incrAnswerCommentCount($item);
|
||||
if ($user->id != $item->owner_id) {
|
||||
$this->handleAnswerCommentedNotice($item, $comment);
|
||||
$this->handleCommentPostPoint($comment);
|
||||
|
@ -4,7 +4,6 @@ namespace App\Services\Logic\Comment;
|
||||
|
||||
use App\Models\Comment as CommentModel;
|
||||
use App\Services\Logic\Service as LogicService;
|
||||
use App\Traits\Client as ClientTrait;
|
||||
use App\Validators\Comment as CommentValidator;
|
||||
use App\Validators\UserLimit as UserLimitValidator;
|
||||
|
||||
@ -12,8 +11,8 @@ class CommentCreate extends LogicService
|
||||
{
|
||||
|
||||
use AfterCreateTrait;
|
||||
use CommentDataTrait;
|
||||
use CountTrait;
|
||||
use ClientTrait;
|
||||
|
||||
public function handle()
|
||||
{
|
||||
@ -31,26 +30,19 @@ class CommentCreate extends LogicService
|
||||
|
||||
$comment = new CommentModel();
|
||||
|
||||
$data = [
|
||||
'item_id' => $post['item_id'],
|
||||
'item_type' => $post['item_type'],
|
||||
'owner_id' => $user->id,
|
||||
];
|
||||
$data = $this->handlePostData($post);
|
||||
|
||||
$data['content'] = $validator->checkContent($post['content']);
|
||||
$data['client_type'] = $this->getClientType();
|
||||
$data['client_ip'] = $this->getClientIp();
|
||||
|
||||
/**
|
||||
* @todo 引入自动审核机制
|
||||
*/
|
||||
$data['published'] = CommentModel::PUBLISH_APPROVED;
|
||||
$data['item_id'] = $post['item_id'];
|
||||
$data['item_type'] = $post['item_type'];
|
||||
$data['owner_id'] = $user->id;
|
||||
$data['published'] = $this->getPublishStatus($user);
|
||||
|
||||
$comment->create($data);
|
||||
|
||||
$this->incrUserDailyCommentCount($user);
|
||||
|
||||
if ($comment->published == CommentModel::PUBLISH_APPROVED) {
|
||||
$this->incrItemCommentCount($item, $comment, $user);
|
||||
$this->handleNoticeAndPoint($item, $comment, $user);
|
||||
}
|
||||
|
||||
|
45
app/Services/Logic/Comment/CommentDataTrait.php
Normal file
45
app/Services/Logic/Comment/CommentDataTrait.php
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Logic\Comment;
|
||||
|
||||
use App\Models\Comment as CommentModel;
|
||||
use App\Models\User as UserModel;
|
||||
use App\Traits\Client as ClientTrait;
|
||||
use App\Validators\Comment as CommentValidator;
|
||||
|
||||
trait CommentDataTrait
|
||||
{
|
||||
|
||||
use ClientTrait;
|
||||
|
||||
protected function handlePostData($post)
|
||||
{
|
||||
$data = [];
|
||||
|
||||
$data['client_type'] = $this->getClientType();
|
||||
$data['client_ip'] = $this->getClientIp();
|
||||
|
||||
$validator = new CommentValidator();
|
||||
|
||||
$data['content'] = $validator->checkContent($post['content']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function getPublishStatus(UserModel $user)
|
||||
{
|
||||
$case1 = $user->article_count > 2;
|
||||
$case2 = $user->question_count > 2;
|
||||
$case3 = $user->answer_count > 2;
|
||||
$case4 = $user->comment_count > 2;
|
||||
|
||||
$status = CommentModel::PUBLISH_PENDING;
|
||||
|
||||
if ($case1 || $case2 || $case3 || $case4) {
|
||||
$status = CommentModel::PUBLISH_APPROVED;
|
||||
}
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
||||
}
|
@ -5,7 +5,6 @@ namespace App\Services\Logic\Comment;
|
||||
use App\Models\Comment as CommentModel;
|
||||
use App\Services\Logic\CommentTrait;
|
||||
use App\Services\Logic\Service as LogicService;
|
||||
use App\Traits\Client as ClientTrait;
|
||||
use App\Validators\Comment as CommentValidator;
|
||||
use App\Validators\UserLimit as UserLimitValidator;
|
||||
|
||||
@ -13,9 +12,9 @@ class CommentReply extends LogicService
|
||||
{
|
||||
|
||||
use AfterCreateTrait;
|
||||
use CommentDataTrait;
|
||||
use CommentTrait;
|
||||
use CountTrait;
|
||||
use ClientTrait;
|
||||
|
||||
public function handle($id)
|
||||
{
|
||||
@ -33,14 +32,15 @@ class CommentReply extends LogicService
|
||||
|
||||
$validator = new CommentValidator();
|
||||
|
||||
$data = [
|
||||
'parent_id' => $parent->id,
|
||||
'item_id' => $comment->item_id,
|
||||
'item_type' => $comment->item_type,
|
||||
'owner_id' => $user->id,
|
||||
];
|
||||
$data = $this->handlePostData($post);
|
||||
|
||||
$item = $validator->checkItem($comment->item_type, $comment->item_id);
|
||||
$data['parent_id'] = $parent->id;
|
||||
$data['item_id'] = $comment->item_id;
|
||||
$data['item_type'] = $comment->item_type;
|
||||
$data['owner_id'] = $user->id;
|
||||
$data['published'] = $this->getPublishStatus($user);
|
||||
|
||||
$item = $validator->checkItem($comment->item_id, $comment->item_type);
|
||||
|
||||
/**
|
||||
* 子评论中回复用户
|
||||
@ -51,15 +51,6 @@ class CommentReply extends LogicService
|
||||
$data['to_user_id'] = $comment->owner_id;
|
||||
}
|
||||
|
||||
$data['content'] = $validator->checkContent($post['content']);
|
||||
$data['client_type'] = $this->getClientType();
|
||||
$data['client_ip'] = $this->getClientIp();
|
||||
|
||||
/**
|
||||
* @todo 引入自动审核机制
|
||||
*/
|
||||
$data['published'] = CommentModel::PUBLISH_APPROVED;
|
||||
|
||||
$reply = new CommentModel();
|
||||
|
||||
$reply->create($data);
|
||||
@ -68,6 +59,7 @@ class CommentReply extends LogicService
|
||||
|
||||
if ($reply->published == CommentModel::PUBLISH_APPROVED) {
|
||||
$this->incrCommentReplyCount($parent);
|
||||
$this->incrItemCommentCount($item, $reply, $user);
|
||||
$this->handleNoticeAndPoint($item, $reply, $user);
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,13 @@ trait CountTrait
|
||||
$answer->update();
|
||||
}
|
||||
|
||||
protected function incrUserCommentCount(UserModel $user)
|
||||
{
|
||||
$user->comment_count += 1;
|
||||
|
||||
$user->update();
|
||||
}
|
||||
|
||||
protected function decrCommentReplyCount(CommentModel $comment)
|
||||
{
|
||||
if ($comment->reply_count > 0) {
|
||||
@ -98,11 +105,19 @@ trait CountTrait
|
||||
protected function decrAnswerCommentCount(AnswerModel $answer)
|
||||
{
|
||||
if ($answer->comment_count > 0) {
|
||||
$answer->comment_count += 1;
|
||||
$answer->comment_count -= 1;
|
||||
$answer->update();
|
||||
}
|
||||
}
|
||||
|
||||
protected function decrUserCommentCount(UserModel $user)
|
||||
{
|
||||
if ($user->comment_count > 0) {
|
||||
$user->comment_count -= 1;
|
||||
$user->update();
|
||||
}
|
||||
}
|
||||
|
||||
protected function incrUserDailyCommentCount(UserModel $user)
|
||||
{
|
||||
/**
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace App\Services\Logic\Page;
|
||||
|
||||
use App\Models\Page as PageModel;
|
||||
use App\Models\User as UserModel;
|
||||
use App\Services\Logic\PageTrait;
|
||||
use App\Services\Logic\Service as LogicService;
|
||||
|
||||
@ -13,22 +14,38 @@ class PageInfo extends LogicService
|
||||
|
||||
public function handle($id)
|
||||
{
|
||||
$user = $this->getCurrentUser(true);
|
||||
|
||||
$page = $this->checkPage($id);
|
||||
|
||||
return $this->handlePage($page);
|
||||
return $this->handlePage($page, $user);
|
||||
}
|
||||
|
||||
protected function handlePage(PageModel $page)
|
||||
protected function handlePage(PageModel $page, UserModel $user)
|
||||
{
|
||||
$page->content = kg_parse_markdown($page->content);
|
||||
|
||||
$me = $this->handleMeInfo($page, $user);
|
||||
|
||||
return [
|
||||
'id' => $page->id,
|
||||
'title' => $page->title,
|
||||
'content' => $page->content,
|
||||
'create_time' => $page->create_time,
|
||||
'update_time' => $page->update_time,
|
||||
'me' => $me,
|
||||
];
|
||||
}
|
||||
|
||||
protected function handleMeInfo(PageModel $page, UserModel $user)
|
||||
{
|
||||
$me = ['owned' => 0];
|
||||
|
||||
if ($page->published == 1) {
|
||||
$me['owned'] = 1;
|
||||
}
|
||||
|
||||
return $me;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -28,7 +28,6 @@ class QuestionCreate extends LogicService
|
||||
$data = $this->handlePostData($post);
|
||||
|
||||
$data['published'] = $this->getPublishStatus($user);
|
||||
|
||||
$data['owner_id'] = $user->id;
|
||||
|
||||
$question->create($data);
|
||||
@ -37,6 +36,7 @@ class QuestionCreate extends LogicService
|
||||
$this->saveTags($question, $post['xm_tag_ids']);
|
||||
}
|
||||
|
||||
$this->saveDynamicAttrs($question);
|
||||
$this->incrUserDailyQuestionCount($user);
|
||||
$this->recountUserQuestions($user);
|
||||
|
||||
@ -45,11 +45,6 @@ class QuestionCreate extends LogicService
|
||||
return $question;
|
||||
}
|
||||
|
||||
protected function getPublishStatus(UserModel $user)
|
||||
{
|
||||
return $user->question_count > 100 ? QuestionModel::PUBLISH_APPROVED : QuestionModel::PUBLISH_PENDING;
|
||||
}
|
||||
|
||||
protected function incrUserDailyQuestionCount(UserModel $user)
|
||||
{
|
||||
$this->eventsManager->fire('UserDailyCounter:incrQuestionCount', $this, $user);
|
||||
|
@ -4,6 +4,7 @@ namespace App\Services\Logic\Question;
|
||||
|
||||
use App\Models\Question as QuestionModel;
|
||||
use App\Models\QuestionTag as QuestionTagModel;
|
||||
use App\Models\User as UserModel;
|
||||
use App\Repos\QuestionTag as QuestionTagRepo;
|
||||
use App\Repos\Tag as TagRepo;
|
||||
use App\Traits\Client as ClientTrait;
|
||||
@ -36,7 +37,26 @@ trait QuestionDataTrait
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
protected function getPublishStatus(UserModel $user)
|
||||
{
|
||||
return $user->question_count > 100 ? QuestionModel::PUBLISH_APPROVED : QuestionModel::PUBLISH_PENDING;
|
||||
}
|
||||
|
||||
protected function saveDynamicAttrs(QuestionModel $question)
|
||||
{
|
||||
$question->cover = kg_parse_first_content_image($question->content);
|
||||
|
||||
$question->summary = kg_parse_summary($question->content);
|
||||
|
||||
$question->update();
|
||||
|
||||
/**
|
||||
* 重新执行afterFetch
|
||||
*/
|
||||
$question->afterFetch();
|
||||
}
|
||||
|
||||
protected function saveTags(QuestionModel $question, $tagIds)
|
||||
{
|
||||
$originTagIds = [];
|
||||
|
@ -8,7 +8,6 @@ use App\Models\Question as QuestionModel;
|
||||
use App\Repos\Question as QuestionRepo;
|
||||
use App\Services\Logic\Service as LogicService;
|
||||
use App\Validators\QuestionQuery as QuestionQueryValidator;
|
||||
use Phalcon\Text;
|
||||
|
||||
class QuestionList extends LogicService
|
||||
{
|
||||
@ -49,21 +48,12 @@ class QuestionList extends LogicService
|
||||
|
||||
$items = [];
|
||||
|
||||
$baseUrl = kg_cos_url();
|
||||
|
||||
foreach ($questions as $question) {
|
||||
|
||||
if (!empty($question['cover']) && !Text::startsWith($question['cover'], 'http')) {
|
||||
$question['cover'] = $baseUrl . $question['cover'];
|
||||
}
|
||||
|
||||
if (empty($question['summary'])) {
|
||||
$question['summary'] = kg_parse_summary($question['content'], 80);
|
||||
}
|
||||
|
||||
$question['tags'] = json_decode($question['tags'], true);
|
||||
|
||||
$owner = $users[$question['owner_id']] ?? new \stdClass();
|
||||
|
||||
$lastReplier = $users[$question['last_replier_id']] ?? new \stdClass();
|
||||
|
||||
$items[] = [
|
||||
|
@ -50,6 +50,8 @@ class QuestionUpdate extends LogicService
|
||||
$this->saveTags($question, $post['xm_tag_ids']);
|
||||
}
|
||||
|
||||
$this->saveDynamicAttrs($question);
|
||||
|
||||
$this->eventsManager->fire('Question:afterUpdate', $this, $question);
|
||||
|
||||
return $question;
|
||||
|
50
app/Services/Logic/Question/XmTagList.php
Normal file
50
app/Services/Logic/Question/XmTagList.php
Normal file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Logic\Question;
|
||||
|
||||
use App\Repos\Question as QuestionRepo;
|
||||
use App\Repos\Tag as TagRepo;
|
||||
use App\Services\Logic\Service as LogicService;
|
||||
|
||||
class XmTagList extends LogicService
|
||||
{
|
||||
|
||||
public function handle($id)
|
||||
{
|
||||
$tagRepo = new TagRepo();
|
||||
|
||||
$allTags = $tagRepo->findAll(['published' => 1]);
|
||||
|
||||
if ($allTags->count() == 0) return [];
|
||||
|
||||
$questionTagIds = [];
|
||||
|
||||
if ($id > 0) {
|
||||
$question = $this->findQuestion($id);
|
||||
if (!empty($question->tags)) {
|
||||
$questionTagIds = kg_array_column($question->tags, 'id');
|
||||
}
|
||||
}
|
||||
|
||||
$list = [];
|
||||
|
||||
foreach ($allTags as $tag) {
|
||||
$selected = in_array($tag->id, $questionTagIds);
|
||||
$list[] = [
|
||||
'name' => $tag->name,
|
||||
'value' => $tag->id,
|
||||
'selected' => $selected,
|
||||
];
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
protected function findQuestion($id)
|
||||
{
|
||||
$questionRepo = new QuestionRepo();
|
||||
|
||||
return $questionRepo->findById($id);
|
||||
}
|
||||
|
||||
}
|
47
app/Services/Logic/User/AnswerList.php
Normal file
47
app/Services/Logic/User/AnswerList.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Logic\User;
|
||||
|
||||
use App\Library\Paginator\Query as PagerQuery;
|
||||
use App\Models\Answer as AnswerModel;
|
||||
use App\Repos\Answer as AnswerRepo;
|
||||
use App\Services\Logic\Answer\AnswerList as AnswerListService;
|
||||
use App\Services\Logic\Service as LogicService;
|
||||
use App\Services\Logic\UserTrait;
|
||||
|
||||
class AnswerList extends LogicService
|
||||
{
|
||||
|
||||
use UserTrait;
|
||||
|
||||
public function handle($id)
|
||||
{
|
||||
$user = $this->checkUser($id);
|
||||
|
||||
$pagerQuery = new PagerQuery();
|
||||
|
||||
$params = $pagerQuery->getParams();
|
||||
|
||||
$params['owner_id'] = $user->id;
|
||||
$params['published'] = AnswerModel::PUBLISH_APPROVED;
|
||||
$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 handleAnswers($pager)
|
||||
{
|
||||
$service = new AnswerListService();
|
||||
|
||||
return $service->handleAnswers($pager);
|
||||
}
|
||||
|
||||
}
|
@ -2,9 +2,9 @@
|
||||
|
||||
namespace App\Services\Logic\User\Console;
|
||||
|
||||
use App\Builders\AnswerList as AnswerListBuilder;
|
||||
use App\Library\Paginator\Query as PagerQuery;
|
||||
use App\Repos\Answer as AnswerRepo;
|
||||
use App\Services\Logic\Answer\AnswerList as AnswerListService;
|
||||
use App\Services\Logic\Service as LogicService;
|
||||
|
||||
class AnswerList extends LogicService
|
||||
@ -34,44 +34,9 @@ class AnswerList extends LogicService
|
||||
|
||||
protected function handleAnswers($pager)
|
||||
{
|
||||
if ($pager->total_items == 0) {
|
||||
return $pager;
|
||||
}
|
||||
$service = new AnswerListService();
|
||||
|
||||
$builder = new AnswerListBuilder();
|
||||
|
||||
$answers = $pager->items->toArray();
|
||||
|
||||
$questions = $builder->getQuestions($answers);
|
||||
|
||||
$users = $builder->getUsers($answers);
|
||||
|
||||
$items = [];
|
||||
|
||||
foreach ($answers as $answer) {
|
||||
|
||||
$answer['summary'] = kg_parse_summary($answer['content'], 64);
|
||||
|
||||
$question = $questions[$answer['question_id']] ?? new \stdClass();
|
||||
$owner = $users[$answer['owner_id']] ?? new \stdClass();
|
||||
|
||||
$items[] = [
|
||||
'id' => $answer['id'],
|
||||
'summary' => $answer['summary'],
|
||||
'published' => $answer['published'],
|
||||
'accepted' => $answer['accepted'],
|
||||
'comment_count' => $answer['comment_count'],
|
||||
'like_count' => $answer['like_count'],
|
||||
'create_time' => $answer['create_time'],
|
||||
'update_time' => $answer['update_time'],
|
||||
'question' => $question,
|
||||
'owner' => $owner,
|
||||
];
|
||||
}
|
||||
|
||||
$pager->items = $items;
|
||||
|
||||
return $pager;
|
||||
return $service->handleAnswers($pager);
|
||||
}
|
||||
|
||||
}
|
||||
|
47
app/Services/Logic/User/QuestionList.php
Normal file
47
app/Services/Logic/User/QuestionList.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Logic\User;
|
||||
|
||||
use App\Library\Paginator\Query as PagerQuery;
|
||||
use App\Models\Question as QuestionModel;
|
||||
use App\Repos\Question as QuestionRepo;
|
||||
use App\Services\Logic\Question\QuestionList as QuestionListService;
|
||||
use App\Services\Logic\Service as LogicService;
|
||||
use App\Services\Logic\UserTrait;
|
||||
|
||||
class QuestionList extends LogicService
|
||||
{
|
||||
|
||||
use UserTrait;
|
||||
|
||||
public function handle($id)
|
||||
{
|
||||
$user = $this->checkUser($id);
|
||||
|
||||
$pagerQuery = new PagerQuery();
|
||||
|
||||
$params = $pagerQuery->getParams();
|
||||
|
||||
$params['owner_id'] = $user->id;
|
||||
$params['published'] = QuestionModel::PUBLISH_APPROVED;
|
||||
$params['deleted'] = 0;
|
||||
|
||||
$sort = $pagerQuery->getSort();
|
||||
$page = $pagerQuery->getPage();
|
||||
$limit = $pagerQuery->getLimit();
|
||||
|
||||
$articleRepo = new QuestionRepo();
|
||||
|
||||
$pager = $articleRepo->paginate($params, $sort, $page, $limit);
|
||||
|
||||
return $this->handleQuestions($pager);
|
||||
}
|
||||
|
||||
protected function handleQuestions($pager)
|
||||
{
|
||||
$service = new QuestionListService();
|
||||
|
||||
return $service->handleQuestions($pager);
|
||||
}
|
||||
|
||||
}
|
@ -37,6 +37,8 @@ class UserInfo extends LogicService
|
||||
'locked' => $user->locked,
|
||||
'course_count' => $user->course_count,
|
||||
'article_count' => $user->article_count,
|
||||
'question_count' => $user->question_count,
|
||||
'answer_count' => $user->answer_count,
|
||||
'friend_count' => $imUser->friend_count,
|
||||
'group_count' => $imUser->group_count,
|
||||
'active_time' => $user->active_time,
|
||||
|
@ -35,10 +35,6 @@ class ArticleDocument extends Component
|
||||
*/
|
||||
public function formatDocument(ArticleModel $article)
|
||||
{
|
||||
if (empty($article->summary)) {
|
||||
$article->summary = kg_parse_summary($article->content);
|
||||
}
|
||||
|
||||
if (is_array($article->tags) || is_object($article->tags)) {
|
||||
$article->tags = kg_json_encode($article->tags);
|
||||
}
|
||||
|
@ -61,10 +61,6 @@ class CourseDocument extends Component
|
||||
|
||||
$course->cover = CourseModel::getCoverPath($course->cover);
|
||||
|
||||
if (empty($course->summary)) {
|
||||
$course->summary = kg_parse_summary($course->details);
|
||||
}
|
||||
|
||||
return [
|
||||
'id' => $course->id,
|
||||
'title' => $course->title,
|
||||
|
@ -36,10 +36,6 @@ class QuestionDocument extends Component
|
||||
*/
|
||||
public function formatDocument(QuestionModel $question)
|
||||
{
|
||||
if (empty($question->summary)) {
|
||||
$question->summary = kg_parse_summary($question->content);
|
||||
}
|
||||
|
||||
if (is_array($question->tags) || is_object($question->tags)) {
|
||||
$question->tags = kg_json_encode($question->tags);
|
||||
}
|
||||
|
34
db/migrations/20210602034627.php
Normal file
34
db/migrations/20210602034627.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
use Phinx\Db\Adapter\MysqlAdapter;
|
||||
use Phinx\Migration\AbstractMigration;
|
||||
|
||||
final class V20210602034627 extends AbstractMigration
|
||||
{
|
||||
|
||||
public function up()
|
||||
{
|
||||
$this->modifyUserTable();
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
$this->table('kg_user')
|
||||
->removeColumn('comment_count')
|
||||
->save();
|
||||
}
|
||||
|
||||
protected function modifyUserTable()
|
||||
{
|
||||
$this->table('kg_user')
|
||||
->addColumn('comment_count', 'integer', [
|
||||
'null' => false,
|
||||
'default' => '0',
|
||||
'limit' => MysqlAdapter::INT_REGULAR,
|
||||
'signed' => false,
|
||||
'comment' => '评论数量',
|
||||
'after' => 'answer_count',
|
||||
])->save();
|
||||
}
|
||||
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 64 KiB |
@ -132,20 +132,20 @@
|
||||
list-style: decimal;
|
||||
}
|
||||
|
||||
.writer-sidebar {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.writer-content .first-form-item {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.writer-content .layui-input-block,
|
||||
.writer-sidebar .layui-input-block,
|
||||
.report-form .layui-input-block {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.writer-content {
|
||||
padding-top: 30px;
|
||||
}
|
||||
|
||||
.writer-sidebar {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.writer-sidebar .layui-form-label,
|
||||
.report-form .layui-form-label {
|
||||
float: none;
|
||||
@ -265,6 +265,8 @@
|
||||
|
||||
.page-info {
|
||||
min-height: 500px;
|
||||
padding-top: 30px;
|
||||
padding-bottom: 30px;
|
||||
}
|
||||
|
||||
.help-list li {
|
||||
@ -1763,6 +1765,20 @@
|
||||
padding: 10px 8px;
|
||||
}
|
||||
|
||||
.user-tab .article-card {
|
||||
height: 110px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.user-tab .article-card .title {
|
||||
border-bottom: 1px solid #f2f2f2;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.user-tab .article-card .summary {
|
||||
max-height: 3em;
|
||||
}
|
||||
|
||||
.user-card {
|
||||
float: left;
|
||||
width: 100%;
|
||||
@ -1956,7 +1972,7 @@
|
||||
}
|
||||
|
||||
.layui-table p {
|
||||
line-height: 1.8em;
|
||||
line-height: 2em;
|
||||
}
|
||||
|
||||
.layui-table .center {
|
||||
|
@ -14,12 +14,11 @@ layui.use(['jquery', 'helper'], function () {
|
||||
var options = {
|
||||
live: true,
|
||||
autoplay: true,
|
||||
h5_flv: true,
|
||||
width: 760,
|
||||
height: 428,
|
||||
};
|
||||
|
||||
var formats = ['rtmp', 'flv', 'm3u8'];
|
||||
var formats = ['m3u8'];
|
||||
var rates = ['od', 'hd', 'sd'];
|
||||
|
||||
$.each(formats, function (i, format) {
|
||||
|
@ -1,45 +0,0 @@
|
||||
layui.use(['jquery', 'layer'], function () {
|
||||
|
||||
var $ = layui.jquery;
|
||||
var layer = layui.layer;
|
||||
|
||||
$('.btn-edit-pwd').on('click', function () {
|
||||
var url = $(this).data('url');
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: '修改密码',
|
||||
content: [url, 'no'],
|
||||
area: ['640px', '320px'],
|
||||
cancel: function () {
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('.btn-edit-phone').on('click', function () {
|
||||
var url = $(this).data('url');
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: '修改手机',
|
||||
content: [url, 'no'],
|
||||
area: ['640px', '420px'],
|
||||
cancel: function () {
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('.btn-edit-email').on('click', function () {
|
||||
var url = $(this).data('url');
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: '修改邮箱',
|
||||
content: [url, 'no'],
|
||||
area: ['640px', '420px'],
|
||||
cancel: function () {
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
});
|
@ -1,8 +1,7 @@
|
||||
layui.use(['jquery', 'layer', 'helper'], function () {
|
||||
layui.use(['jquery', 'layer'], function () {
|
||||
|
||||
var $ = layui.jquery;
|
||||
var layer = layui.layer;
|
||||
var helper = layui.helper;
|
||||
|
||||
/**
|
||||
* 查看咨询
|
||||
@ -124,14 +123,4 @@ layui.use(['jquery', 'layer', 'helper'], function () {
|
||||
});
|
||||
});
|
||||
|
||||
if ($('#tab-courses').length > 0) {
|
||||
var $tabCourses = $('#tab-courses');
|
||||
helper.ajaxLoadHtml($tabCourses.data('url'), $tabCourses.attr('id'));
|
||||
}
|
||||
|
||||
if ($('#tab-users').length > 0) {
|
||||
var $tabUsers = $('#tab-users');
|
||||
helper.ajaxLoadHtml($tabUsers.data('url'), $tabUsers.attr('id'));
|
||||
}
|
||||
|
||||
});
|
@ -13,6 +13,16 @@ layui.use(['jquery', 'helper'], function () {
|
||||
helper.ajaxLoadHtml($tabArticles.data('url'), $tabArticles.attr('id'));
|
||||
}
|
||||
|
||||
if ($('#tab-questions').length > 0) {
|
||||
var $tabQuestions = $('#tab-questions');
|
||||
helper.ajaxLoadHtml($tabQuestions.data('url'), $tabQuestions.attr('id'));
|
||||
}
|
||||
|
||||
if ($('#tab-answers').length > 0) {
|
||||
var $tabAnswers = $('#tab-answers');
|
||||
helper.ajaxLoadHtml($tabAnswers.data('url'), $tabAnswers.attr('id'));
|
||||
}
|
||||
|
||||
if ($('#tab-friends').length > 0) {
|
||||
var $tabFriends = $('#tab-friends');
|
||||
helper.ajaxLoadHtml($tabFriends.data('url'), $tabFriends.attr('id'));
|
||||
|
Loading…
x
Reference in New Issue
Block a user