huwhois 2 years ago
parent
commit
22e7339c75

+ 9 - 1
app/common/model/Tag.php

@@ -22,7 +22,7 @@ class Tag extends Base
         return self::where('tagname','LIKE', '%'.$tagname.'%')->field('tagid, tagname')->select();
     }
 
-    public static function saveTags(array $tags, int $infoid=0)
+    public static function saveTags(array $tags, int $infoid=0, int $cid = 0)
     {
         foreach ($tags as  $tagname) {
             $tag = self::where('tagname', $tagname)->find();
@@ -33,6 +33,12 @@ class Tag extends Base
             }
             $tag->nums += 1;
             $tag->save();
+
+            TagArticle::create([
+                'infoid' => $infoid,
+                'cid'    => $cid,
+                'tagid'  => $tag->tagid
+            ]);
         }
     }
 
@@ -45,6 +51,8 @@ class Tag extends Base
                 $tag->nums = $tag->nums - 1;
                 
                 $tag->save();
+
+                TagArticle::where(['infoid'=>$infoid, 'tagid'=>$tag->tagid])->delete();
             }
         }
     }

+ 38 - 0
app/common/model/TagArticle.php

@@ -0,0 +1,38 @@
+<?php
+declare(strict_types=1);
+
+namespace app\common\model;
+
+use think\facade\Config;
+use think\facade\Db;
+
+use app\common\model\Base;
+
+class TagArticle extends Base
+{
+    protected $schema = [
+        'id'     => "int",
+        "infoid" => "int",
+        "cid"    => "int",
+        "tagid"  => "int",
+    ];
+
+    protected $autoWriteTimestamp = false;
+
+    public function article()
+    {
+        return $this->belongsTo('Article', 'infoid', 'id')->bind(['id','cid','title','titlepic','summary','hits','create_time','username']);
+    }
+
+    public function category()
+    {
+        return $this->belongsTo('Category', 'cid', 'id')->bind(['category_url'=>'url','category_name'=>'name']);
+    }
+
+    public static function queryList($tagid)
+    {
+        $limit = Config::get('app.page_size', 20);
+
+        return self::with(['article','category'])->where('tagid', $tagid)->limit($limit)->paginate();
+    }
+}

+ 88 - 0
app/common/utils/ParsedownUtils.php

@@ -0,0 +1,88 @@
+<?php
+
+declare(strict_types=1);
+
+namespace app\common\utils;
+
+use \Parsedown;
+
+/**
+ * markdown 解析
+ */
+class ParsedownUtils extends Parsedown
+{
+    protected $isTocEnabled = false;
+
+    protected $rawTocList = [];
+
+    protected $findTocSyntaxRule = '#^<p> *\[TOC\]\s*</p>$#m';
+
+    public function setTocEnabled($isTocEnable)
+    {
+        $this->isTocEnabled = $isTocEnable;
+
+        return $this;
+    }
+
+    public function setTocSyntaxRule($findTocSyntaxRule)
+    {
+        $this->findTocSyntaxRule = $findTocSyntaxRule;
+
+        return $this;
+    }
+
+    public function text($text)
+    {
+        $content = parent::text($text);
+        
+        if (!$this->isTocEnabled || empty($this->rawTocList) || !preg_match($this->findTocSyntaxRule, $content)) {
+            return ["toc"=>"","content"=>$content];
+        }
+
+        $content = preg_replace($this->findTocSyntaxRule, "", $content);
+        return ["toc"=>$this->buildToc(), "content"=>$content];
+    }
+
+    protected function buildToc()
+    {
+        $tocMarkdownContent = '';
+        $topHeadLevel       = min(array_column($this->rawTocList, 'level'));
+
+        foreach ($this->rawTocList as $id => $tocItem) {
+            $tocMarkdownContent .= sprintf('%s- [%s](#%s)' . PHP_EOL, str_repeat('  ', $tocItem['level'] - $topHeadLevel), $this->line($tocItem['text']), $tocItem['id']);
+        }
+
+        return parent::text($tocMarkdownContent);
+    }
+
+    protected function blockHeader($line)
+    {
+        $block = parent::blockHeader($line);
+        $text  = $block['element']['handler']['argument'];
+        $no = 0;
+        foreach ($this->rawTocList as $key => $value) {
+            if ($text == $value['text']) {
+                $no = $value['no'] + 1;
+            }
+        }
+        
+        $id    = urlencode($this->line($text));
+        
+        if ($no != 0) {
+            $id .= '-' . $no;
+        }
+        
+        $block['element']['attributes'] = [
+            'id' => $id,
+        ];
+
+        $this->rawTocList[] = [
+            'id' => $id,
+            'text'  => $text,
+            'level' => str_replace('h', '', $block['element']['name']),
+            'no'=> $no,
+        ];
+
+        return $block;
+    }
+}

+ 11 - 21
app/index/controller/Article.php

@@ -18,6 +18,9 @@ use app\common\model\Category as CategoryModel;
 use app\common\model\Article as ArticleModel;
 use app\common\model\ArticleTags as ArticleTagsModel;
 use app\common\model\ArticleDolikeLog;
+use app\common\model\Tag;
+use app\common\model\TagArticle;
+use app\common\utils\ParsedownUtils;
 
 /**
  * 文章管理  
@@ -77,7 +80,7 @@ class Article extends Base
         $prev_next = ArticleModel::getNextPrev($id, $data->cid);
 
         if ($data->content_type == 1) {
-            $parsedownExtension = new \ParsedownExtension();
+            $parsedownExtension = new ParsedownUtils();
             // $parsedownExtension->setTocEnabled(true);
             $res = $parsedownExtension->text($data->content);
             // $data->toc = $res['toc'];
@@ -131,39 +134,26 @@ class Article extends Base
     /**
      * 标签列表
      */
-    public function tags($name = null)
+    public function tag($name = null)
     {
         if (!$name) {
             throw new HttpException(404, '标签不可为空');
         }
 
-        $list = ArticleTagsModel::tagsList($name);
-
-        View::assign([
-            'list' => $list,
-            'tag'  => $name
-        ]);
-
-        return View::fetch();
-    }
+        $tag = Tag::where('tagname', $name)->find();
 
-    /**
-     * 标签列表
-     */
-    public function tag($name = null)
-    {
-        if (!$name) {
-            throw new HttpException(404, '标签不可为空');
+        if (!$tag) {
+            throw new HttpException(404, '标签不存在');
         }
 
-        // $list = ArticleTagsModel::tagsList($name);
+        $list = TagArticle::queryList($tag->tagid);
 
         View::assign([
-            'list' => [],
+            'list' => $list,
             'tag'  => $name
         ]);
 
-        return View::fetch('tags');
+        return View::fetch();
     }
 
     /**

+ 1 - 1
app/index/route/app.php

@@ -29,7 +29,7 @@ Route::get('/about', 'index/index/about')->append(['_aside' => true]);
 Route::get('/guest_book', 'index/index/guestBook');
 Route::post('/save_guest_book', 'index/index/saveGuestBook');
 
-Route::get('/tags/:name', 'index/article/tags');
+Route::get('/tags/:name', 'index/article/tag');
 Route::get('/tag/:name', 'index/article/tag');
 Route::get('/all-<page?>', 'index/article/index')->append(['cid' => 0]);
 Route::post('/dolike', 'index/article/dolike');

+ 1 - 1
composer.json

@@ -26,7 +26,7 @@
         "topthink/think-multi-app": "^1.0",
         "liliuwei/thinkphp-jump": "^1.5",
         "topthink/think-image": "^1.0",
-        "erusev/parsedown": "^1.7"
+        "erusev/parsedown": "^1.8.0-beta-7"
     },
     "require-dev": {
         "symfony/var-dumper": "^4.2",

+ 4 - 0
config/app.php

@@ -31,6 +31,10 @@ return [
     // 异常页面的模板文件
     'exception_tmpl'   => app()->getThinkPath() . 'tpl/think_exception.tpl',
 
+    // 404异常页面
+    'http_exception_template' => [
+        404 => app()->getRootPath() . 'view/index/404.html',
+    ],
     // 错误显示信息,非调试模式有效
     'error_message'    => '页面错误!请稍后再试~',
     // 显示错误信息

+ 1 - 1
view/index/404.html

@@ -47,7 +47,7 @@
   <div class="page-404 text-c" style="margin-top:80px;">
     <p class="error-title"><i class="Hui-iconfont va-m" style="font-size:80px">&#xe656;</i><span class="va-m">
         404</span></p>
-    <p class="error-description">不好意思,您访问的页面不存在~</p>
+    <p class="error-description">{$e->getMessage() ?? '不好意思,您访问的页面不存在~'}</p>
     <p class="error-info">
       您可以:<a href="javascript:;" onclick="history.go(-1)" class="c-primary">&lt; 返回上一页</a>
       <span class="ml-20">|</span><a href="/" class="c-primary ml-20">去首页 &gt;</a></p>

+ 1 - 1
view/index/article/read.html

@@ -17,7 +17,7 @@
         {if $data->keywords != ""}
         {php}$tags = explode(',',$data->keywords);{/php}
         {foreach $tags as $value}
-        <a href="/tags/{$value}"  rel="tag" data-wpel-link="internal">{$value}</a> &nbsp;
+        <a href="/tag/{$value}"  rel="tag" data-wpel-link="internal">{$value}</a> &nbsp;
         {/foreach}
         {/if}
       </div>

+ 0 - 0
view/index/article/tags.html → view/index/article/tag.html