Browse Source

Merge branch 'master' of http://39.100.116.245:3000/huwhois/blog_tp6

Conflicts:
	app/common/command/FileConsole.php
	app/common/facade/FileUtils.php
	app/common/model/Article.php
	app/common/model/FileManager.php
	app/common/service/FileService.php
	app/index/route/app.php
	app/sys/controller/Article.php
	app/sys/controller/FileManager.php
	public/static/index/css/index.css
	view/sys/article/savemd.html
	view/sys/file_manager/explorer.html
	view/sys/file_manager/index.html
	view/sys/file_manager/uploadimg copy.html
	view/sys/file_manager/uploadimg.html
huwhois 2 years ago
parent
commit
244ab52a76

+ 2 - 1
.gitignore

@@ -9,4 +9,5 @@
 /public/index
 /public/static/plugins/ueditor
 /public/static/plugins/Swiper
-/public/static/plugins/jquery.SuperSlide
+/public/static/plugins/jquery.SuperSlide
+/public/storage

+ 86 - 86
app/common/command/FileConsole.php

@@ -1,86 +1,86 @@
-<?php
-declare (strict_types = 1);
-
-namespace app\common\command;
-
-use DirectoryIterator;
-use SplFileInfo;
-
-// 引入框架内置类
-use think\console\Command;
-use think\console\Input;
-use think\console\input\Argument;
-use think\console\input\Option;
-use think\console\Output;
-use think\facade\Config;
-use think\File;
-
-use app\common\model\FileManager;
-
-class FileConsole extends Command
-{
-    protected function configure()
-    {
-        // 指令配置
-        $this->setName('fileconsole')
-            ->addArgument('name', Argument::OPTIONAL, "console name")
-            ->addOption('dir', null, Option::VALUE_REQUIRED, 'directory name')
-            ->setDescription('the fileconsole command');
-    }
-
-    protected function execute(Input $input, Output $output)
-    {
-        $name = trim($input->getArgument('name'));
-      	$name = $name ?: 'thinkphp';
-
-		if ($input->hasOption('dir')) {
-        	$dir = str_replace("\\", '/', app()->getRootPath() . $input->getOption('dir'));
-        } else {
-        	$dir = str_replace("\\", '/', Config::get('filesystem.disks.public.root')) .'/';
-        }
-
-        // 指令输出
-        $output->writeln('fileconsole :' . $name . "--dir: " . $dir);
-        
-        $this->$name($dir);
-
-        $output->writeln('..ok');
-    }
-
-    /**
-     * 建立文件管理目录索引(递归遍历目录)
-     */
-    public function scan($dir)
-    {
-        if (is_file($dir)) {
-            $file = new File($dir);
-
-            FileManager::saveFileInfo($file);
-        } else {
-            $dirs = new DirectoryIterator($dir);
-            
-            foreach ($dirs as $fileInfo) {
-                if($fileInfo->isDot() || $fileInfo->getFilename() == '.gitignore') {
-                    continue;
-                }
-                
-                $this->scan($dirs->getPath() . '/' . $fileInfo->getFilename());
-            }
-        }
-    }
-
-    /**
-     * 清除无效目录索引
-     */
-    public function clear($dir = '')
-    {
-        $list = FileManager::select();
-        
-        foreach ($list as $value) {
-            $file = app()->getRootPath() . 'public/' . $value->filepath;
-            if (!is_file($file)) {
-                FileManager::destroy($value->fileid);
-            }
-        }
-    }
-}
+<?php
+declare (strict_types = 1);
+
+namespace app\common\command;
+
+use DirectoryIterator;
+use SplFileInfo;
+
+// 引入框架内置类
+use think\console\Command;
+use think\console\Input;
+use think\console\input\Argument;
+use think\console\input\Option;
+use think\console\Output;
+use think\facade\Config;
+use think\File;
+
+use app\common\model\FileManager;
+
+class FileConsole extends Command
+{
+    protected function configure()
+    {
+        // 指令配置
+        $this->setName('fileconsole')
+            ->addArgument('name', Argument::OPTIONAL, "console name")
+            ->addOption('dir', null, Option::VALUE_REQUIRED, 'directory name')
+            ->setDescription('the fileconsole command');
+    }
+
+    protected function execute(Input $input, Output $output)
+    {
+        $name = trim($input->getArgument('name'));
+      	$name = $name ?: 'thinkphp';
+
+		if ($input->hasOption('dir')) {
+        	$dir = str_replace("\\", '/', app()->getRootPath() . $input->getOption('dir'));
+        } else {
+        	$dir = str_replace("\\", '/', Config::get('filesystem.disks.public.root')) .'/';
+        }
+
+        // 指令输出
+        $output->writeln('fileconsole :' . $name . "--dir: " . $dir);
+        
+        $this->$name($dir);
+
+        $output->writeln('..ok');
+    }
+
+    /**
+     * 建立文件管理目录索引(递归遍历目录)
+     */
+    public function scan($dir)
+    {
+        if (is_file($dir)) {
+            $file = new File($dir);
+
+            FileManager::saveFileInfo($file);
+        } else {
+            $dirs = new DirectoryIterator($dir);
+            
+            foreach ($dirs as $fileInfo) {
+                if($fileInfo->isDot() || $fileInfo->getFilename() == '.gitignore') {
+                    continue;
+                }
+                
+                $this->scan($dirs->getPath() . '/' . $fileInfo->getFilename());
+            }
+        }
+    }
+
+    /**
+     * 清除无效目录索引
+     */
+    public function clear($dir = '')
+    {
+        $list = FileManager::select();
+        
+        foreach ($list as $value) {
+            $file = app()->getRootPath() . 'public/' . $value->filepath;
+            if (!is_file($file)) {
+                FileManager::destroy($value->fileid);
+            }
+        }
+    }
+}

+ 25 - 0
app/common/facade/FileUtils.php

@@ -1,3 +1,4 @@
+<<<<<<< HEAD
 <?php
 declare(strict_types=1);
 
@@ -20,3 +21,27 @@ class FileUtils extends Facade
         return 'app\common\utils\FileUtils';
     }
 }
+=======
+<?php
+declare(strict_types=1);
+
+namespace app\common\facade;
+
+use think\Facade;
+
+/**
+ * @see \app\common\utils\FileUtils
+ * @package app\common\facade
+ * @mixin \app\common\utils\FileUtils
+ * @method static \think\Image waterMark()
+ * @method static \think\Image thumbnail()
+ * @method static \think\file\UploadedFile downloadUrlImg()
+ */
+class FileUtils extends Facade
+{
+    protected static function getFacadeClass()
+    {
+        return 'app\common\utils\FileUtils';
+    }
+}
+>>>>>>> 78b76253c8ce5873016cf837373af5e30ac80c86

+ 211 - 0
app/common/model/Article.php

@@ -1,3 +1,4 @@
+<<<<<<< HEAD
 <?php
 
 declare(strict_types=1);
@@ -170,3 +171,213 @@ class Article extends Base
         return $timeList;
     }
 }
+=======
+<?php
+
+declare(strict_types=1);
+
+namespace app\common\model;
+
+use think\exception\HttpException;
+
+use app\common\model\Base;
+use think\facade\Config;
+
+class Article extends Base
+{
+    protected $schema = [
+        "id"          => "int",
+        "cid"         => "int",
+        "title"       => "varchar",
+        "writer"      => "varchar",
+        "source"      => "varchar",
+        "titlepic"    => "varchar",
+        "keywords"    => "varchar",
+        "summary"     => "varchar",
+        "content"     => "varchar",
+        "discussed"   => "int",
+        "status"      => "int",
+        "top"         => "int",
+        "sort"       => "int",
+        "hits"        => "int",
+        "likes"       => "int",
+        "content_type"=> "int",
+        "userid"      => "int",
+        "username"    => "varchar",
+        "create_time" => "int",
+        "update_time" => "int"
+    ];
+
+    protected $disuse = ['top','discussed'];
+
+    public function category()
+    {
+        return $this->belongsTo('Category', 'cid')->bind(['category_name' => 'name', 'category_url' => 'url', 'route' => 'route']);
+    }
+
+    public static function queryPage($params)
+    {
+        $where = [];
+
+        if (isset($params['status'])) {
+            $where[] = ['status', '=', (int) $params['status']];
+        }
+
+        if (!empty($params['cid'])) {
+            $where[] = ['cid', '=', (int) $params['cid']];
+        }
+
+        if (!empty($params['key'])) {
+            $where[] = ['title|keywords', 'LIKE', '%' . (string)$params['key'] . '%'];
+        }
+
+        if (!empty($params['yearMonth'])) {
+            if (!preg_match("/^([0-9]{4})\/([0-9]{1,2})$/", $params['yearMonth']) && !preg_match("/^([0-9]{4})-([0-9]{1,2})$/", $params['yearMonth'])) {
+                throw new HttpException(404, '日期格式不正确');
+            }
+            $separator = strrpos('/', $params['yearMonth']) ? '/' : '-';
+            
+            $year = $month = '';
+            
+            if (strnatcasecmp(PHP_VERSION, '7.0.0') >= 0) {
+                list($year, $month) = explode($separator, $params['yearMonth']);
+            } else {
+                list($month, $year) = explode($separator, $params['yearMonth']);
+            }
+            
+            if ((int) $month < 1 || (int) $month > 12) {
+                throw new HttpException(404, '日期格式不正确');
+            }
+            
+            $days = month_frist_and_last_day($year, $month);
+            
+            // $where['create_time'] = ['between', [$days['firstday'], $days['lastday']]];
+            $where[] = ['create_time','between', [$days['firstday'], $days['lastday']]];
+        }
+
+        $limit = empty($params['limit']) ? Config::get('app.page_size', 20) : (int)$params['limit'];
+        
+        $order = ['id desc'];
+        if (!empty($params['order'])) {
+            if (is_array($params['order'])) {
+                $order = array_unique(array_merge($params['order']));
+            } else {
+                array_push($order, $params['order']);
+                $order = array_unique($order);
+            }
+        }
+
+        $list = self::where($where)
+            ->field('id,cid,title,titlepic,username,summary,content_type,hits,sort,status,create_time')
+            ->with(['category'])
+            ->order($order)->paginate(['list_rows'=>$limit, 'query' => $params]);
+
+        return $list;
+    }
+
+    public static function getListByCid($cid = 0, $limit = 10, $order = "")
+    {
+        $where = [];
+
+        if ($cid != 0) {
+            if ($cid < 0) {
+                $where[] = ['cid', '<>', abs($cid)];
+            } else {
+                $where[] = ['cid', '=', $cid];
+            }
+        }
+        
+        $where[] = ['status', '=', 1];
+
+        $order = $order ?? "sort ASC,id DESC";
+
+        return self::with('category')->where($where)
+            ->field('id,cid,title,titlepic,username,summary,hits,sort,status,create_time')
+            ->order($order)->limit($limit)->select();
+    }
+
+    public static function getTop($limit)
+    {
+        return self::with('category')->field('id,cid,title,titlepic,summary,username,hits,sort,status,create_time')
+            ->order('sort ASC, id DESC')->limit($limit)->select();
+    }
+
+    public static function getOne($id)
+    {
+        if (!$id) {
+            throw new HttpException(404, '页面不存在');
+        }
+
+        return self::with('category')->find($id);
+    }
+
+    public static function getNextPrev($id, $cid = null)
+    {
+        $whereP = [];
+        $whereN = [];
+
+        $whereP[] = ['status', '=', 1];
+        $whereN[] = ['status', '=', 1];
+        
+        if ($cid) {
+            $whereP[] = ['cid', '=', $cid];
+            $whereN[] = ['cid', '=', $cid];
+        }
+
+        $whereP[] = ['id', ">", $id];
+        $whereN[] = ['id', "<", $id];
+
+        $data_P = self::where($whereP)->order("id desc")->limit(1)->find();
+        $data_N = self::where($whereN)->order("id desc")->limit(1)->find();
+
+        return ['prev' => $data_P, 'next' => $data_N];
+    }
+
+    public static function createTimeArchive($limit = 0)
+    {
+        if ($limit == 0) {
+            $timeList = self::distinct(true)->fieldRaw("FROM_UNIXTIME(`create_time`, '%Y-%m') as pubmonth")->order('pubmonth desc')->select();
+        } else {
+            $timeList = self::distinct(true)->fieldRaw("FROM_UNIXTIME(`create_time`, '%Y-%m') as pubmonth")->order('pubmonth desc')->limit($limit)->select();
+        }
+
+        return $timeList;
+    }
+
+    public static function createOne($data)
+    {
+        $article = new static;
+
+        $article->allowField(['cid','title','writer','source','titlepic','keywords','summary','content',
+            'status','sort','hits','content_type','userid','username'])->save($data);
+
+        FileManager::saveInfoid($article->id, $data['cjid']);
+
+        $keys = explode(',', $data['keywords']);
+
+        Tag::saveTags($keys, (int) $article->id);
+    }
+
+    public static function updateOne($data)
+    {
+        $article = self::find($data['id']);
+        
+        $oldkeys = explode(',', $article->keywords);
+
+        $article->allowField(['cid','title','writer','source','titlepic','keywords','summary','content',
+            'status','sort','hits','content_type','userid','username'])->save($data);
+
+        FileManager::saveInfoid($article->id, $data['cjid']);
+
+        $newkeys = explode(',', $data['keywords']);
+
+        $keys = array_diff($newkeys, $oldkeys);
+
+        $dec  = array_diff($oldkeys, $newkeys);
+
+        Tag::saveTags($keys, (int) $article->id);
+
+        Tag::decNums($dec, (int) $article->id);
+    }
+}
+>>>>>>> 78b76253c8ce5873016cf837373af5e30ac80c86

+ 122 - 0
app/common/model/FileManager.php

@@ -1,3 +1,4 @@
+<<<<<<< HEAD
 <?php
 declare(strict_types=1);
 
@@ -62,3 +63,124 @@ class FileManager extends \think\Model
         $fileinfo->save();
     }
 }
+=======
+<?php
+declare(strict_types=1);
+
+namespace app\common\model;
+
+use think\facade\Config;
+use think\File;
+use think\exception\FileException;
+
+class FileManager extends \think\Model
+{
+    protected $pk = "fileid";
+
+    protected $schema = [
+        'fileid'        => "int",      // '文件id'
+        'filename'      => "varchar",  // '文件名称'
+        'filesize'      => "int",      // '文件大小字节'
+        'filetime'      => "int",      // '文件上传时间'
+        'filepath'      => "varchar",  // '文件路径'
+        'fileextension' => "varchar",  // '文件扩展名'
+        'title'         => "varchar",  // '文件title'
+        'type'          => "int",      // '0为附件,1为图片,2为Flash文件,3为多媒体文件'
+        'onclick'       => "int",      // '下载量'
+        'username'      => "varchar",  // '上传者'
+        'infoid'        => "int",      // '信息ID', 
+        'cjid'          => "int",       // '信息临时ID'
+        'hash_md5'       => "varcahr"       // hash值(MD5)
+    ];
+
+    protected $autoWriteTimestamp = false;
+
+    public static function queryPage(array $param = [])
+    {
+        $limit = (int)$param['limit'];
+
+        $where = [];
+
+        return self::where($where)->field('fileid,filename,filesize,filetime,filepath,fileextension,title,username')->order('fileid DESC')->paginate(['list_rows'=>$limit, 'query' => $param]);
+    }
+
+    public static function queryList(array $param = [])
+    {
+        $where = [];
+
+        $cjid = isset($param['cjid']) ? (int) $param['cjid'] : 0;
+
+        $infoid = isset($param['infoid']) ? (int) $param['infoid'] : 0;
+
+        if ($cjid) {
+            $where[] = ['cjid', '=', $cjid];
+        }
+
+        if ($infoid) {
+            $where[] = ['infoid', '=', $infoid];
+        }
+
+        return self::where($where)->field('fileid,filename,filesize,filetime,filepath,fileextension,title,username')->order('fileid DESC')->select();
+    }
+
+    public static function saveFile(File $file)
+    {
+        $fileinfo = self::where('hash_md5', $file->md5())->find();
+
+        $publicRootPath = str_replace('\\', '/', Config::get('filesystem.disks.public.root'));
+
+        $publicUrlPath =  Config::get('filesystem.disks.public.url');
+
+        if ($fileinfo == null) {
+            $fileinfo = new static();
+        } elseif ($publicRootPath . $fileinfo->filepath == $file->getPathname())  { // 路径不同的文件
+            $fileinfo = new static();
+        }
+
+        $fileinfo->filename      = $file->getFilename();
+        $fileinfo->filesize      = $file->getSize();
+        $fileinfo->filetime      = $file->getCTime();
+        $fileinfo->filepath      = $publicUrlPath . str_replace($publicRootPath, '', $file->getPathname());
+        $fileinfo->fileextension = $file->getExtension();
+        $fileinfo->hash_md5      = $file->md5();
+        $fileinfo->username      = 'system';
+
+        $fileinfo->save();
+    }
+
+    public static function saveFileInfo($file, $savename, $originalName = '', $id = 0, $cjid = 0, $username = 'system')
+    {
+        if (is_string($file)) {
+            $file = new File($file);
+        }
+
+        if (!$file->isFile()) {
+            throw new FileException('file not exist');
+        }
+
+        $publicUrlPath =  Config::get('filesystem.disks.public.url');
+
+        $fileinfo = new static();
+                
+        $fileinfo->filename      = basename($savename);
+        $fileinfo->filepath      = $publicUrlPath . '/'. $savename;
+        $fileinfo->title         = $originalName;
+        $fileinfo->id            = $id;
+        $fileinfo->cjid          = $cjid;
+        $fileinfo->username      = $username;
+        $fileinfo->filesize      = $file->getSize();
+        $fileinfo->filetime      = $file->getCTime();
+        $fileinfo->fileextension = $file->extension();
+        $fileinfo->hash_md5      = $file->md5();
+        
+        $fileinfo->save();
+
+        return $fileinfo;
+    }
+
+    public static function saveInfoid($infoid, $cjid)
+    {
+        self::where('cjid', 'IN', $cjid)->data(['infoid'=>$infoid, 'cjid'=>0])->update();
+    }
+}
+>>>>>>> 78b76253c8ce5873016cf837373af5e30ac80c86

+ 59 - 0
app/common/model/Tag.php

@@ -0,0 +1,59 @@
+<?php
+declare(strict_types=1);
+
+namespace app\common\model;
+
+use app\common\model\Base;
+
+class Tag extends Base
+{
+    protected $pk = 'tagid';
+
+    protected $schema = [
+        "tagid"       => "int",
+        "tagname"     => "varchar",
+        "nums"        => "int",
+        "create_time" => "int",
+        "update_time" => "int"
+    ];
+
+    public static function queryList($tagname)
+    {
+        return self::where('tagname','LIKE', '%'.$tagname.'%')->field('tagid, tagname')->select();
+    }
+
+    public static function saveTags(array $tags, int $infoid = 0, int $cid = 0)
+    {
+        foreach ($tags as  $tagname) {
+            $tag = self::where('tagname', $tagname)->find();
+
+            if ($tag == null) {
+                $tag = new static;
+                $tag->tagname = $tagname;
+            }
+            $tag->nums += 1;
+            $tag->save();
+
+            TagArticle::create([
+                'infoid' => $infoid,
+                'cid'    => $cid,
+                'tagid'  => $tag->tagid
+            ]);
+        }
+    }
+
+    public static function decNums(array $tags, int $infoid=0)
+    {
+        foreach ($tags as  $tagname) {
+            $tag = self::where('tagname', $tagname)->find();
+
+            if ($tag != null) {
+                $tag->nums = $tag->nums - 1;
+                
+                $tag->save();
+
+                TagArticle::where(['infoid'=>$infoid, 'tagid'=>$tag->tagid])->delete();
+            }
+        }
+    }
+}

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

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

+ 176 - 0
app/common/service/FileService.php

@@ -1,3 +1,4 @@
+<<<<<<< HEAD
 <?php
 declare(strict_types=1);
 
@@ -181,3 +182,178 @@ class FileService
         return $files;
     }
 }
+=======
+<?php
+declare(strict_types=1);
+
+/**
+ * 文件 service
+ *
+ * @version      0.0.1
+ * @author      by huwhois
+ * @time        2021/12/28
+ */
+
+namespace app\common\service;
+
+use think\Image;
+use think\Exception;
+use think\File;
+use think\image\Exception as ImageException;
+use think\facade\Config;
+
+class FileService
+{
+    /**
+     * 图片添加水印
+     * @param File $file  要处理的文件
+     * @param int $type  水印类型 0 图片水印, 1 文字水印 
+     * @param string $waterimg  图片水印内容
+     * @param string $watertext  文字水印内容
+     * @param string $fonttype  水印文字类型
+     * @param int $fontsize  水印文字大小
+     * @param string $fontcolor  水印文字颜色
+     * @return Image  返回图片对象
+     */
+    public function waterMark(Image $image, int $type = 0, string $watermark = '', string $watertext = '', 
+        string $fonttype = '', int $fontsize = 0, string $fontcolor = '#ffffff30'): Image
+    {
+        if ($type == 0) {
+            $watermark = $watermark ?: Config::get('filesystem.water.watermark');
+            $image->water($watermark);
+        } else {
+            $watetext = $watertext ?: Config::get('filesystem.water.watertext');
+            $fonttype = $fonttype ?: Config::get('filesystem.water.fonttype');
+            $fontsize = $fontsize ?: (int) Config::get('filesystem.water.fontsize');
+            $fontcolor = $fontcolor ?: (int) Config::get('filesystem.water.fontcolor');
+
+            $image->text($watetext, $fonttype, $fontsize, $fontcolor);
+        }
+
+        return $image;
+    }
+
+    /**
+     * 生成缩略图
+     * @param Image $image  要处理的文件
+     * @param int $width 缩略图宽值, 默认 384px;
+     * @param int $height 缩略图高值, 默认 224px;
+     * @param int $type 缩略图裁剪方式, 默认值 1,固定尺寸缩放; 其他: 1,等比例缩放;2,缩放后填充;3,居中裁剪;4,左上角裁剪;5,右下角裁剪
+     * @param string $t_suffix  缩略图后缀
+     * @return Image  返回图片对象
+     */
+    public function thumbnail(Image $image, string $thumbname, int $width = 384, int $height = 224, int $type = 1)
+    {
+        $image->thumb($width, $height, $type)->save('./storage/' . $thumbname);
+
+        return $image;
+    }
+
+    /**
+     * 保存远程图片到本地
+     */
+    public function downloadUrlImg(string $url)
+    {
+        $ch = curl_init($url);
+        curl_setopt($ch, CURLOPT_HEADER, 0);
+        curl_setopt($ch, CURLOPT_NOBODY, 0); // 只取body头
+        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
+        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
+        curl_setopt($ch, CURLOPT_NOSIGNAL, 1);
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ 
+        $package = curl_exec($ch);
+        $httpinfo = curl_getinfo($ch);
+        
+        curl_close($ch);
+
+        $imageAll = array_merge(array(
+            'imgBody' => $package
+        ), $httpinfo);
+        if ($httpinfo['download_content_length'] > 4 * 1024 * 1024) {
+            throw new Exception("文件太大", 1);
+        }
+
+        $type = null;
+
+        switch ($imageAll['content_type']) {
+            case 'image/gif':
+                $type = "gif";
+                break;
+            case 'image/webp':
+                $type = "webp";
+                break;
+            case 'image/jpeg':
+                $type = "jpg";
+                break;
+            case 'image/png':
+                $type = "png";
+                break;
+            default:
+                $type = null;
+                break;
+        }
+
+        // 腾讯公众号图片
+        if(strpos($url,'qpic.cn') !== false){
+            $urls = parse_url($url);
+        
+            if (isset($urls['query'])) {
+                $query_arr = [];
+                
+                parse_str($urls['query'], $query_arr);
+        
+                $type = isset($query_arr['wx_fmt']) ? $query_arr['wx_fmt'] : null;
+        
+                $type = $type == 'jpeg' ? 'jpg' : $type;
+            }
+        }
+
+        if (!$type) {
+            throw new Exception("不支持的文件后缀", 1);
+        }
+
+        $temp = app()->getRuntimePath() . 'temp';
+
+        if (!file_exists($temp)) {
+            mkdir($temp, 0755);
+        }
+
+        $tempname = $temp . '/php.' . $type;
+
+        file_put_contents($tempname, $imageAll["imgBody"]);
+
+        return new File($tempname);
+    }
+
+    /**
+     * 遍历获取目录下的指定类型的文件
+     * @param $path
+     * @param $allowFiles  png|jpg|jpeg|gif|bmp|webp
+     * @param array $files
+     * @return array
+     */
+    public function getFiles($path, $allowFiles = 'png|jpg|jpeg|gif|bmp|webp', &$files = array())
+    {
+        if (!is_dir($path)) return null;
+        if (substr($path, strlen($path) - 1) != '/') $path .= '/';
+        $handle = opendir($path);
+        while (false !== ($file = readdir($handle))) {
+            if ($file != '.' && $file != '..') {
+                $path2 = $path . $file;
+                if (is_dir($path2)) {
+                    self::getFiles($path2, $allowFiles, $files);
+                } else {
+                    if (preg_match("/\.(" . $allowFiles . ")$/i", $file)) {
+                        $files[] = array(
+                            'url' => substr($path2, strlen(app()->getRootPath().'/public') - 1),
+                            'mtime' => filemtime($path2)
+                        );
+                    }
+                }
+            }
+        }
+        return $files;
+    }
+}
+>>>>>>> 78b76253c8ce5873016cf837373af5e30ac80c86

+ 186 - 0
app/common/utils/FileUtils.php

@@ -0,0 +1,186 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * 文件 utils
+ *
+ * @version      0.0.1
+ * @author      by huwhois
+ * @time        20228/10
+ */
+
+namespace app\common\utils;
+
+use think\Image;
+use think\Exception;
+use think\File;
+use think\image\Exception as ImageException;
+use think\facade\Config;
+use think\file\UploadedFile;
+
+class FileUtils
+{
+    /**
+     * 图片添加水印
+     * @param File $file  要处理的文件
+     * @param int $type  水印类型 0 图片水印, 1 文字水印 
+     * @param string $waterimg  图片水印内容
+     * @param string $watertext  文字水印内容
+     * @param string $fonttype  水印文字类型
+     * @param int $fontsize  水印文字大小
+     * @param string $fontcolor  水印文字颜色
+     * @return Image  返回图片对象
+     */
+    public function waterMark(
+        Image $image,
+        int $type = 0,
+        string $watermark = '',
+        string $watertext = '',
+        string $fonttype = '',
+        int $fontsize = 0,
+        string $fontcolor = '#ffffff30'
+    ): Image {
+        if ($type == 0) {
+            $watermark = $watermark ?: Config::get('filesystem.water.watermark');
+            $image->water($watermark);
+        } else {
+            $watetext = $watertext ?: Config::get('filesystem.water.watertext');
+            $fonttype = $fonttype ?: Config::get('filesystem.water.fonttype');
+            $fontsize = $fontsize ?: (int) Config::get('filesystem.water.fontsize');
+            $fontcolor = $fontcolor ?: (int) Config::get('filesystem.water.fontcolor');
+
+            $image->text($watetext, $fonttype, $fontsize, $fontcolor);
+        }
+
+        return $image;
+    }
+
+    /**
+     * 生成缩略图
+     * @param Image $image  要处理的文件
+     * @param int $width 缩略图宽值, 默认 384px;
+     * @param int $height 缩略图高值, 默认 224px;
+     * @param int $type 缩略图裁剪方式, 默认值 1,固定尺寸缩放; 其他: 1,等比例缩放;2,缩放后填充;3,居中裁剪;4,左上角裁剪;5,右下角裁剪
+     * @param string $t_suffix  缩略图后缀
+     * @return Image  返回图片对象
+     */
+    public function thumbnail(Image $image, string $thumbname, int $width = 384, int $height = 224, int $type = 1)
+    {
+        $image->thumb($width, $height, $type)->save('./storage/' . $thumbname);
+
+        return $image;
+    }
+
+    /**
+     * 保存远程图片到本地
+     */
+    public function downloadUrlImg(string $url)
+    {
+        $ch = curl_init($url);
+        curl_setopt($ch, CURLOPT_HEADER, 0);
+        curl_setopt($ch, CURLOPT_NOBODY, 0); // 只取body头
+        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
+        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
+        curl_setopt($ch, CURLOPT_NOSIGNAL, 1);
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+
+        $package = curl_exec($ch);
+        $httpinfo = curl_getinfo($ch);
+
+        curl_close($ch);
+
+        // halt($httpinfo);
+        $imageAll = array_merge(array(
+            'imgBody' => $package
+        ), $httpinfo);
+        if ($httpinfo['download_content_length'] > 4 * 1024 * 1024) {
+            throw new Exception("文件太大", 1);
+        }
+
+        $type = null;
+
+        $originalName = "";
+
+        switch ($imageAll['content_type']) {
+            case 'image/gif':
+                $type = "gif";
+                break;
+            case 'image/webp':
+                $type = "webp";
+                break;
+            case 'image/jpeg':
+                $type = "jpg";
+                break;
+            case 'image/png':
+                $type = "png";
+                break;
+            default:
+                $type = null;
+                break;
+        }
+
+        // 腾讯公众号图片
+        if (strpos($url, 'qpic.cn') !== false) {
+            $urls = parse_url($url);
+
+            if (isset($urls['query'])) {
+                $query_arr = [];
+
+                parse_str($urls['query'], $query_arr);
+
+                $type = isset($query_arr['wx_fmt']) ? $query_arr['wx_fmt'] : null;
+
+                $type = $type == 'jpeg' ? 'jpg' : $type;
+            }
+        }
+
+        if (!$type) {
+            throw new Exception("不支持的文件后缀", 1);
+        }
+
+        $originalName = pathinfo($url, PATHINFO_EXTENSION) ? basename($url) : basename($url) . '.' . $type;
+
+        $temp =  app()->getRuntimePath() . 'temp';
+
+        if (!file_exists($temp)) {
+            mkdir($temp, 0755);
+        }
+        
+        $tempname = $temp . DIRECTORY_SEPARATOR . 'php' . substr(str_shuffle('0123456789abcdefghijklmnopqrstuvwxyz'), 0, 6) . '.tmp';
+
+        file_put_contents($tempname, $imageAll["imgBody"]);
+
+        return new UploadedFile($tempname, $originalName, $imageAll["content_type"]);
+    }
+
+    /**
+     * 遍历获取目录下的指定类型的文件
+     * @param $path
+     * @param $allowFiles  png|jpg|jpeg|gif|bmp|webp
+     * @param array $files
+     * @return array
+     */
+    public static function getFiles($path, $allowFiles = 'png|jpg|jpeg|gif|bmp|webp', &$files = array())
+    {
+        if (!is_dir($path)) return null;
+        if (substr($path, strlen($path) - 1) != '/') $path .= '/';
+        $handle = opendir($path);
+        while (false !== ($file = readdir($handle))) {
+            if ($file != '.' && $file != '..') {
+                $path2 = $path . $file;
+                if (is_dir($path2)) {
+                    self::getFiles($path2, $allowFiles, $files);
+                } else {
+                    if (preg_match("/\.(" . $allowFiles . ")$/i", $file)) {
+                        $files[] = array(
+                            'url' => substr($path2, strlen(app()->getRootPath() . '/public') - 1),
+                            'mtime' => filemtime($path2)
+                        );
+                    }
+                }
+            }
+        }
+        return $files;
+    }
+}

+ 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;
+    }
+}

+ 13 - 4
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;
 
 /**
  * 文章管理  
@@ -72,12 +75,12 @@ class Article extends Base
 
         $data->hits += 1;
 
-        $data->save();
+        $data->isAutoWriteTimestamp(false)->save();
 
         $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,13 +134,19 @@ class Article extends Base
     /**
      * 标签列表
      */
-    public function tags($name = null)
+    public function tag($name = null)
     {
         if (!$name) {
             throw new HttpException(404, '标签不可为空');
         }
 
-        $list = ArticleTagsModel::tagsList($name);
+        $tag = Tag::where('tagname', $name)->find();
+
+        if (!$tag) {
+            throw new HttpException(404, '标签不存在');
+        }
+
+        $list = TagArticle::queryList($tag->tagid);
 
         View::assign([
             'list' => $list,

+ 46 - 0
app/index/route/app.php

@@ -1,3 +1,4 @@
+<<<<<<< HEAD
 <?php
 // +----------------------------------------------------------------------
 // | ThinkPHP [ WE CAN DO IT JUST THINK ]
@@ -40,3 +41,48 @@ $list = Category::getList();
 foreach ($list as $key => $value) {
     Route::get($value->url . '-<page?>', $value->route)->append(['cid' => $value->id]);
 }
+=======
+<?php
+// +----------------------------------------------------------------------
+// | ThinkPHP [ WE CAN DO IT JUST THINK ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: liu21st <liu21st@gmail.com>
+// +----------------------------------------------------------------------
+use think\facade\Route;
+use app\common\model\Category;
+use think\facade\Template;
+
+Route::pattern([
+    'name' => '\w+',
+    'id' => '\d+',
+    'cid' => '\d+',
+    'page' => '\d+',
+    'year' => '\d+',
+    'month' => '\d+',
+    'day' => '\d+',
+]); 
+
+Route::get('/index', 'index/index/index');
+Route::get('/', 'index/index/index');
+Route::view('/404', '404');
+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/tag');
+Route::get('/tag/:name', 'index/article/tag');
+Route::get('/all-<page?>', 'index/article/index')->append(['cid' => 0]);
+Route::post('/dolike', 'index/article/dolike');
+Route::get('/:year/<month>-<day>/:id', 'index/article/read');
+Route::get('/:year/<month>-<page?>', 'index/article/archive');
+
+$list = Category::getList();
+
+foreach ($list as $key => $value) {
+    Route::get($value->url . '-<page?>', $value->route)->append(['cid' => $value->id]);
+}
+>>>>>>> 78b76253c8ce5873016cf837373af5e30ac80c86

+ 136 - 0
app/sys/controller/Article.php

@@ -1,3 +1,4 @@
+<<<<<<< HEAD
 <?php
 
 declare(strict_types=1);
@@ -125,3 +126,138 @@ class Article extends Base
         return $content;
     }
 }
+=======
+<?php
+
+declare(strict_types=1);
+/**
+ * +----------------------------------------------------------------------
+ * 后台文章控制制器
+ * @author huwhis@163.com
+ * @version   0.0.1
+ * +----------------------------------------------------------------------
+ */
+
+namespace app\sys\controller;
+
+// 引入框架内置类
+use think\facade\View;
+use think\facade\Config;
+
+use app\common\model\Category as CategoryModel;
+use app\common\model\Article as ArticleModel;
+use app\common\facade\FileUtils;
+use app\common\model\FileManager as FileManagerModel;
+
+class Article extends Base
+{
+    protected $modelName = "Article";
+
+    public function index()
+    {
+        $categories = CategoryModel::select();
+
+        $category_tree = list_tree($categories);
+
+        $cid = $this->app->request->param('cid');
+
+        $params = $this->app->request->param();
+
+        $list = ArticleModel::queryPage($params);
+
+        View::assign([
+            'category_tree' => $category_tree,
+            'list' => $list,
+            'cid' => $cid
+        ]);
+
+        return View::fetch();
+    }
+
+    public function save($content_type = 0, $id = 0)
+    {
+        if ($this->app->request->isPost()) {
+            $params = $this->app->request->param();
+
+            if (!$params['cid']) {
+                $this->error('请选择栏目');
+            }
+            if ($params['title'] == '') {
+                $this->error("标题不能为空");
+            }
+
+            $params['content'] =  isset($params['content']) ? $params['content'] : '';
+            if ($content_type == 0) {
+                $username = $this->getSysUser()->username;
+                $params['content'] = $this->saveRomteImage($params['content'],(int)$params['id'],(int) $params['cjid'], $username);
+            }
+
+            $params['keywords'] = trim($params['keywords']);
+
+            try {
+                if ($params['id'] != 0) {
+                    ArticleModel::updateOne($params);
+                } else {
+                    $params['userid'] = $this->getSysUser()->userid;
+                    $params['username'] = $this->getSysUser()->nickname;
+                    unset($params['id']);
+                    ArticleModel::createOne($params);
+                }
+            } catch (\Exception $e) {
+                $msg = $e->getMessage();
+
+                $this->error("错误提示:" . $msg);
+            }
+            $this->success('操作成功', (string) url('index?cid=' . $params['cid']));
+        } else {
+            if ($id) {
+                $data = ArticleModel::find($id);
+            } else {
+                $data = new ArticleModel();
+                $data->content_type = $content_type;
+            }
+
+            $data->cjid = time();
+
+            $categories = CategoryModel::field('id, parent_id, name')->select();
+
+            View::assign('category_tree', list_tree($categories));
+            View::assign('data', $data);
+
+            $template = $content_type ? 'savemd' : 'save';
+
+            return View::fetch($template);
+        }
+    }
+
+    protected function saveRomteImage($content, $infoid=0, $cjid=0, $username='system')
+    {
+        $content = stripslashes ($content);
+        $img_array = [];
+        // 匹配所有远程图片
+        $pattern = '/src="(http[s]:\/\/.*)"/isU';
+        preg_match_all ($pattern,$content,$img_array);
+        
+        // 删除重复 url
+        $img_arrays = array_unique ($img_array[1]);
+
+        foreach ($img_arrays as $value) {
+            $file = FileUtils::downloadUrlImg($value);
+            
+            $savename = \think\facade\Filesystem::disk('public')->putFile('/', $file);
+
+            FileManagerModel::saveFileInfo($file, $savename, $file->getOriginalName, $infoid, $cjid, $username);
+
+            // 删除临时文件
+            @unlink($file->getRealPath());
+            
+            $filename = Config::get('filesystem.disks.public.url') . '/' . str_replace('\\', '/', $savename);
+
+            // dump($filename);
+            $content = str_replace($value, $filename, $content);
+        }
+
+        return $content;
+    }
+}
+>>>>>>> 78b76253c8ce5873016cf837373af5e30ac80c86

+ 542 - 0
app/sys/controller/FileManager.php

@@ -1,3 +1,4 @@
+<<<<<<< HEAD
 <?php
 
 declare(strict_types=1);
@@ -582,3 +583,544 @@ class FileManager extends Base
         }
     }
 }
+=======
+<?php
+
+declare(strict_types=1);
+
+/**
+ * upload文件管理
+ *
+ * @version      0.0.0
+ * @author      by huwhois
+ * @time        2017/11/27
+ */
+
+namespace app\sys\controller;
+
+use Exception;
+use UnexpectedValueException;
+use DirectoryIterator;
+use think\facade\View;
+use think\facade\Config;
+use think\File;
+use think\Image;
+use think\exception\ValidateException;
+use think\file\UploadedFile;
+
+use app\common\service\FileService;
+use app\common\model\FileManager as FileManagerModel;
+use app\common\facade\FileUtils;
+
+class FileManager extends Base
+{
+    protected $modelName = 'FileManager';
+    protected $t_suffix = '_thumb';
+    protected $width = 400;  // 缩略图高度
+    protected $height = 300;
+    protected $storage_path = 'public/storage';
+    
+    public function index()
+    {
+        $param = $this->request->param();
+
+        $param['limit'] = isset($param['limit']) ? (int) $param['limit'] : Config::get('app.page_size');
+
+        $list = FileManagerModel::queryPage($param);
+
+        View::assign('list', $list);
+        
+        return View::fetch();
+    }
+
+    public function queryList()
+    {
+        $param = $this->request->param();
+
+        $list = FileManagerModel::queryList($param);
+
+        return json(['code'=>0, 'list'=>$list]);
+    }
+
+    /**
+     * 浏览文件
+     */
+    public function explorer()
+    {
+        $param = $this->request->param();
+
+        $activepath =  isset($param['activepath']) ? $param['activepath'] : '';
+
+        $realpath = $this->app->getRootPath() . $this->storage_path . $activepath;
+
+        try {
+            $dirhandle = new DirectoryIterator($realpath);
+
+            $dirs = $files = [];
+
+            foreach ($dirhandle as $fileInfo) {
+                if($fileInfo->isDot() || $fileInfo->getFilename() == '.gitignore') {
+                    continue;
+                } elseif ($fileInfo->isDir()) {
+                    $dirs[] = $fileInfo->getFilename();
+                } elseif ($fileInfo->isFile()) {
+                    $files[] = [
+                        'filename'  => $fileInfo->getFilename(),
+                        'extension' => strtolower($fileInfo->getExtension()),
+                        'size' => format_bytes($fileInfo->getSize()),
+                        'time' => $fileInfo->getCTime(),
+                    ];
+                }
+            }
+            
+            $counts = count($dirs) + count($files);
+
+            $activeurl = preg_replace("#[\/][^\/]*$#i", "", $activepath);
+            // halt($activeurl);
+            if ($this->request->isAjax()) {
+                return json([
+                    'code'      => 0,
+                    'dirs'      => $dirs,
+                    'files'     => $files,
+                    'counts'    => $counts,
+                    'activeurl' => $activeurl,
+                    'activepath'=> $activepath,
+                ]);
+            } else {
+                View::assign([
+                    'dirs'      => $dirs,
+                    'files'     => $files,
+                    'counts'    => $counts,
+                    'activeurl' => $activeurl,
+                    'activepath'=> $activepath,
+                ]);
+                
+                return View::fetch();
+            }
+            
+        } catch(UnexpectedValueException $uve) {
+            $this->error($uve->getMessage());
+        }
+    }
+
+    /**
+     * 附件上传
+     */
+    public function uploadFile()
+    {
+        $activepath = $this->request->has('activepath') ? $this->request->param('activepath') : '';
+
+        $files = $this->request->file('upload_file');
+
+        if ($files) {
+            try {
+                validate(
+                    [
+                        'file' => [
+                            // 限制文件大小(单位b),这里限制为10M
+                            'fileSize' => 10 * 1024 * 1024,
+                            // 限制文件后缀,多个后缀以英文逗号分割
+                            'fileExt'  => 'jpg,png,gif,jpeg,webp,jfif,pdf,doc,docx,xls,xlsx,ppt,pptx,txt'
+                        ]
+                    ],
+                    [
+                        'file.fileSize' => '文件太大',
+                        'file.fileExt' => '不支持的文件后缀',
+                    ]
+                )->check(['file' => $files]);
+
+                $savenames = [];
+
+                $uploadFiles = [];
+                
+                if (!is_array($files) && $files instanceof UploadedFile) {
+                    $uploadFiles[] = $files;
+                } else {
+                    $uploadFiles = $files;
+                }
+
+                $url = Config::get('filesystem.disks.public.url');
+
+                foreach ($uploadFiles as $file) {
+                    $fileinfo = new FileManagerModel();
+                    
+                    $fileinfo->title         = $file->getOriginalName();
+                    $fileinfo->filesize      = $file->getSize();
+                    $fileinfo->filetime      = $file->getCTime();
+                    $fileinfo->fileextension = $file->extension();
+                    $fileinfo->username      = $this->getSysUser()->username;
+                    $fileinfo->hash_md5      = $file->md5();
+
+                    if (empty($activepath)) {
+                        $savename = \think\facade\Filesystem::disk('public')->putFile('/', $file);
+                        
+                        $fileinfo->filepath = $url . '/' . $savename;
+                        $fileinfo->filename = basename($savename);  
+                    } else {
+                        $savename = $activepath . '/' . $file->hashName();
+                        $savepath = $this->app->getRootPath() . $this->storage_path . $savename;
+                        
+                        $file = $file->move($this->app->getRootPath() . $this->storage_path . $activepath, $savepath);
+
+                        $fileinfo->filepath = $url . $savename;
+                        $fileinfo->filename = $file->hashName();
+                    }
+
+                    $fileinfo->save();
+
+                    $savenames[] = $fileinfo->filepath;
+                }
+
+                return json(['code' => 0, 'msg'=>'上传成功', 'filename'=>$savenames]);
+            } catch (ValidateException $e) {
+                $this->error($e->getMessage());
+            }
+        } else {
+            $this->error('图片不能为空');
+        }
+    }
+
+    /**
+     * 修改文件title
+     */
+    public function updateFileTitle($id = 0, $filetitle = '')
+    {
+        $fileInfo = FileManagerModel::find($id);
+        if ($fileInfo == null) {
+            return json(['code'=>1, 'fileid='.$id.'不存在']);
+        }
+
+        $fileInfo->title = $filetitle;
+
+        if ($fileInfo->save()) {
+            return json(['code'=>0, 'msg'=>'success']);
+        } else {
+            return json(['code'=>1, 'msg'=>'failed']);
+        }
+    }
+
+    /**
+     * 删除
+     * @param int|array $id  info id
+     * @return array
+     */
+    public function delete($id)
+    {
+        if ($this->request->isPost()) {
+            $whereOp = '=';
+
+            if (is_array($id)) {
+                $whereOp = 'IN';
+            }
+
+            $list = FileManagerModel::where('fileid', $whereOp, $id)->select();
+
+            foreach ($list as $value) {
+                $file = $this->app->getRootPath() . 'public' . $value->filepath;
+                if (file_exists($file)) {
+                    unlink($file);
+                }
+            }
+  
+            if (FileManagerModel::destroy($id)) {
+                return ['code' => 0,'msg'=>'删除成功'];
+            } else {
+                return ['code' => 1,'msg'=>'删除失败'];
+            }
+        }
+    }
+
+    /**
+     * 删除空目录
+     */
+    public function deldir()
+    {
+        if ($this->request->isPost()) {
+            $dir = str_replace('/', DIRECTORY_SEPARATOR, $this->request->param('dir'));
+
+            $dir_name = $this->app->getRootPath() . $this->storage_path . DIRECTORY_SEPARATOR . $dir;
+
+            try {
+                rmdir($dir_name);
+                return ['code' => 0, 'msg' => 'success'];
+            } catch (Exception $e) {
+                return ['code' => 1, 'msg' => 'failed, 目录不为空'];
+            }
+        }
+    }
+
+    /**
+     * 删除文件
+     */
+    public function delfile()
+    {
+        if ($this->request->isPost()) {
+            $filename = str_replace('/', DIRECTORY_SEPARATOR, $this->request->param('filename'));
+
+            $filepath = $this->app->getRootPath() . $this->storage_path . DIRECTORY_SEPARATOR . $filename;
+
+            if (unlink($filepath)) {
+                return ['code' => 0, 'msg' => 'success'];
+            } else {
+                return ['code' => 1, 'msg' => 'failed'];
+            }
+        }
+    }
+
+    /**
+     * 图片上传(iframe 页面)
+     */
+    public function uploadimg(string $img_id = 'picture', $thumb = false, $width = 400, $height = 300,
+        $original = false, $infoid = 0, $cjid = 0)
+    {
+        View::assign([
+            'img_id'    => $img_id,
+            'thumb'     => $thumb,
+            'width'     => $width,
+            'height'    => $height,
+            'original'  => $original,
+            'infoid'    => $infoid,
+            'cjid'      => $cjid
+        ]);
+
+        return View::fetch();
+    }
+
+    /**
+     * 本地图片上传
+     * @file upload_file   上传的文件
+     * @param string  $img_id   图片ipnut text id 默认值 picture
+     * @param boolean $thumb    是否制作缩略图
+     * @param int $width        缩略图最大宽
+     * @param int $height       缩略图最大高
+     * @param int $id           信息ID
+     * @param int $cjid         信息临时ID
+     * @param bool $saveoriginal   生成缩略图后是否保存原图 默认保存 saveoriginal
+     */
+    public function uploadLocalImg(string $img_id = 'picture', $thumb = false, $width = 400, $height = 300,
+        $original = false, $id = 0, $cjid = 0)
+    {
+        if ($this->request->isPost()) {
+            $file = $this->request->file('upload_file');
+
+            if ($file) {
+                try {
+                    validate(
+                        [
+                            'file' => [
+                                // 限制文件大小(单位b),这里限制为4M
+                                'fileSize' => 4 * 1024 * 1024,
+                                // 限制文件后缀,多个后缀以英文逗号分割
+                                'fileExt'  => 'jpg,png,gif,jpeg,webp,jfif'
+                            ]
+                        ],
+                        [
+                            'file.fileSize' => '文件太大',
+                            'file.fileExt' => '不支持的文件后缀',
+                        ]
+                    )->check(['file' => $file]);
+
+                    $result = $this->dealUploadImg($file, $thumb, $width, $height, $original, $id, $cjid);
+
+                    return json([
+                        'code'    => 0,
+                        'img_id'  => $img_id,
+                        'picname' => $result['picname'],
+                        'thumb'   => $result['thumbname']
+                    ]);
+                } catch (ValidateException $e) {
+                    $this->error($e->getMessage());
+                } catch (Exception $e) {
+                    $this->error($e->getMessage());
+                }
+            } else {
+                $this->error('图片不能为空');
+            }
+        }
+    }
+
+    /**
+     * 网络图片上传
+     * @paran string url_file   网络图片地址
+     * @param string  $img_id   图片ipnut text id 默认值 picture
+     * @param boolean $water    是否添加水印
+     * @param boolean $thumb    是否制作缩略图
+     * @param int $width        缩略图最大宽
+     * @param int $height       缩略图最大高
+     * @param bool $overwrite   生成缩略图后是否保存原图
+     */
+    public function uploadUrlImg(string $img_id = 'picture', $thumb = false, $width = 400, $height = 300,
+        $original = false, $id = 0, $cjid = 0)
+    {
+        if ($this->request->isPost()) {
+            $urlImg = $this->request->param('url_file');
+
+            if ($urlImg) {
+                try {
+                    $file = FileUtils::downloadUrlImg($urlImg);
+                    
+                    $result = $this->dealUploadImg($file, $thumb, $width, $height, $original, $id, $cjid);
+
+                    // 删除临时文件
+                    @unlink($file->getRealPath());
+
+                    return json([
+                        'code'    => 0,
+                        'img_id'  => $img_id,
+                        'picname' => $result['picname'],
+                        'thumb'   => $result['thumbname']
+                    ]);
+                } catch (\think\exception\ValidateException $e) {
+                    $this->error($e->getMessage());
+                }
+            } else {
+                $this->error('图片地址不能为空');
+            }
+        }
+    }
+
+    /**
+     * 选择服务器图片
+     * @paran string online_file  服务器图片地址
+     * @param string  $img_id   图片ipnut text id 默认值 picture
+     */
+    public function uploadOnlineImg(string $img_id = 'picture')
+    {
+        if ($this->request->isPost()) {
+            $pathImg = $this->request->param('online_file');
+
+            if ($pathImg && file_exists($this->app->getRootPath() . "public" . $pathImg)) {
+                return json([
+                    'code'    => 0,
+                    'img_id'  => $img_id,
+                    'picname' => $pathImg,
+                    'thumb'   => ''
+                ]);
+            } else {
+                $this->error('图片地址不存在');
+            }
+        }
+    }
+
+    /**
+     * 判断(远程)文件是否为图片
+     */
+    // public function isImg()
+    // {
+    //     if ($this->request->isAjax()) {
+    //         $filename = $this->request->param('filename');
+
+    //         $res = \mylib\GetImageByurl::isImg($filename);
+    //         if (!$res) {
+    //             $this->error('该图片不合法');
+    //         } else {
+    //             return ['code'=>2,'msg'=>'图片地址可用'];
+    //         }
+    //     }
+    // }
+
+    /**
+     * ckeditor 富文本编辑器上传图片
+     */
+    public function ckeditorUploadImage()
+    {
+        if ($this->request->isPost()) {
+            $file = $this->request->file('upload');
+
+            if ($file) {
+                try {
+                    validate(
+                        [
+                            'file' => [
+                                // 限制文件大小(单位b),这里限制为4M
+                                'fileSize' => 4 * 1024 * 1024,
+                                // 限制文件后缀,多个后缀以英文逗号分割
+                                'fileExt'  => 'jpg,png,gif,jpeg,webp,jfif'
+                            ]
+                        ],
+                        [
+                            'file.fileSize' => '文件太大',
+                            'file.fileExt' => '不支持的文件后缀',
+                        ]
+                    )->check(['file' => $file]);
+
+                    $savename = \think\facade\Filesystem::disk('public')->putFile('/', $file);
+
+                    $savename = str_replace('\\', '/', $savename);
+                    $infoid   = (int) $this->request->param('infoid');
+                    $cjid     = (int) $this->request->param('cjid');
+                    $username = $this->getSysUser()->username;
+                    
+                    FileManagerModel::saveFileInfo($file, $savename, $file->getOriginalName(), $infoid, $cjid, $username);
+
+                    return json([
+                        'uploaded' => 1,
+                        'fileName' => basename($savename),
+                        'url' => Config::get('filesystem.disks.public.url') . '/' . $savename
+                    ]);
+                } catch (\think\exception\ValidateException $e) {
+                    $this->error($e->getMessage());
+                    return json([
+                        'uploaded' => 1,
+                        'error' =>  ['message' => $e->getMessage()]
+                    ]);
+                }
+            } else {
+                return json([
+                    'uploaded' => 1,
+                    'error' =>  ['message' => '图片不能为空']
+                ]);
+            }
+        }
+    }
+
+    /**
+     * 处理上传的图片
+     */
+    protected function dealUploadImg(UploadedFile $file, $thumb, $width, $height, $original, $id, $cjid): array
+    {
+        $urlpath = Config::get('filesystem.disks.public.url');
+
+        $username = $this->getSysUser()->username;
+
+        $savename =  str_replace('\\', '/', $file->hashName());
+
+        $originalName = $file->getOriginalName();
+
+        $thumbname = "";
+
+        if ($thumb == true) {
+            $image = Image::open($file);
+            
+            $image->thumb($width, $height, 1);
+
+            $ext = $file->extension();
+            
+            if ($original == true) {
+                \think\facade\Filesystem::disk('public')->putFileAs('/', $file, $savename);
+                
+                $thumbname = str_replace('.' . $ext, '',  $savename) . $this->t_suffix . '.' . $ext;
+
+                $savepath = str_replace('\\', '/', Config::get('filesystem.disks.public.root') . '/' . $thumbname);
+
+                $image->save($savepath);
+                
+                FileManagerModel::saveFileInfo($savepath, $thumbname, $originalName, $id, $cjid, $username);
+
+                $thumbname = $urlpath . '/' . $thumbname;
+            } else {
+                $image->save(Config::get('filesystem.disks.public.root') . '/' . $savename);
+            }
+        } else {
+            \think\facade\Filesystem::disk('public')->putFileAs('/', $file, $savename);
+        }
+
+        $fileinfo = FileManagerModel::saveFileInfo($file, $savename, $originalName, $id, $cjid, $username);
+
+        return [
+            'picname'   => $fileinfo->filepath,
+            'thumbname' => $thumbname,
+        ];
+    }
+}
+>>>>>>> 78b76253c8ce5873016cf837373af5e30ac80c86

+ 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'    => '页面错误!请稍后再试~',
     // 显示错误信息

BIN
public/static/images/success.gif


BIN
public/static/images/success.png


+ 228 - 0
public/static/index/css/index.css

@@ -1,3 +1,4 @@
+<<<<<<< HEAD
 @charset "utf-8";
 /* css */
 * { margin: 0; padding: 0 }
@@ -223,3 +224,230 @@ li.disabled {
 .pagination li:hover {
     background: #f5f5f5;
 }
+=======
+@charset "utf-8";
+/* css */
+* { margin: 0; padding: 0 }
+body { font: 15px "Microsoft YaHei", Arial, Helvetica, sans-serif; color: #555; background: #efefef; line-height: 1.5; }
+img { border: 0; display: block }
+ul, li { list-style: none; }
+a { text-decoration: none; color: #555 }
+a:hover { text-decoration: none; color: #000; }
+.clear { clear: both; }
+.blank { height: 20px; overflow: hidden; width: 100%; margin: auto; clear: both }
+.f_l { float: left }
+.f_r { float: right }
+.ml-20 { margin-left: 20px }
+.ml-10 { margin-left: 10px }
+.box { width: 80%; margin: auto; overflow: hidden; clear: both; }
+@media(max-width:1400px) {
+    .box {width: 1000px; }
+}
+.nobox { width: 100% }
+.c_white { background: #fff }
+article { width: 1000px; margin: auto; overflow: hidden; padding: 20px 0 }
+.container { width: 1000px; margin: auto }
+/*header*/
+header { width: 100%; background: #fff; overflow: hidden; box-shadow: 0 1px 1px rgba(0,0,0,.04); }
+.logo { text-align: center; font-size: 22px; padding: 20px 0 }
+nav { width: 1000px; margin: 0 auto 20px; text-align: center; border-bottom: #000 1px solid; border-top: #000 1px solid; overflow: hidden }
+nav li { display: inline; line-height: 40px; padding: 0 20px }
+.newsbox { width: 50%; background: #fff; margin-top: 20px }
+.newsbox ul { margin: 20px; }
+.newstitle { margin: 20px; line-height: 30px; border-bottom: #000 1px solid; }
+.newstitle span { float: right; font-size: 18px }
+.newstitle span a { color: #000; }
+.newstitle b { background: #333; width: 118px; display: block; font-size: 14px; font-weight: normal; color: #FFF; text-align: center }
+.newsli li { padding-left: 10px; line-height: 30px; text-overflow: ellipsis; white-space: nowrap; overflow: hidden; }
+.sbox { width: 32%; background: #FFF; padding-bottom: 20px; position: relative; z-index: 2; }
+.sbox h2 { font-size: 16px; padding: 50px 0 20px; border-bottom: #CCC 1px solid; margin: 0 20px; text-overflow: ellipsis; white-space: nowrap; overflow: hidden; }
+.sbox p { overflow: hidden; text-overflow: ellipsis; -webkit-box-orient: vertical; display: -webkit-box; -webkit-line-clamp: 3; line-height: 24px; height: 72px; padding: 20px 20px 0 20px }
+.sbox.ml { margin-left: 2%; }
+.sbox span { width: 80px; height: 30px; line-height: 30px; text-align: center; margin: auto; display: block; background: #333; color: #FFF; position: absolute }
+.read { display: block; text-align: center; margin: 20px auto 0; width: 100px; border: #333 1px solid; line-height: 26px; position: relative; }
+.read:before { content: ''; position: absolute; top: 0; left: 0; width: 0; height: 26px; background: #333; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; -webkit-transition: 0.5s; transition: 0.5s; z-index: -1; }
+.read:hover { color: #fff; }
+.read:hover:before { width: 100px; }
+.blogs { width: 66%; float: left }
+.bloglist { background: #FFF; overflow: hidden; padding: 20px; margin-bottom: 20px; }
+.bloglist h2 { font-size: 18px; position: relative }
+.bloglist h2:before { content: ""; width: 3px; height: 26px; position: absolute; left: -20px; top: 0; background: #333 }
+.bloglist p { overflow: hidden; text-overflow: ellipsis; -webkit-box-orient: vertical; display: -webkit-box; -webkit-line-clamp: 3; line-height: 24px; height: 72px; margin: 10px 0 0 }
+.blogs div.more { text-align: center; color: #666; width: 100%; clear: both; margin: 25px 0 10px 0; }
+.blogs div.more a { border: 1px solid #333; padding: 5px 10px; background: #333; color: #FFF }
+aside { width: 32%; float: right }
+.ztbox { border: #000 1px solid; background: #fff; overflow: hidden; }
+.ztbox li { border-bottom: #888 1px solid; line-height: 40px; height: 40px; padding-left: 70px; position: relative; }
+.ztbox li:last-child { border-bottom: 0 }
+.ztbox li:after { content: "》"; position: absolute; right: 10px; color: #000; -moz-transition: all .5s ease; -webkit-transition: all .5s ease; transition: all .5s ease; }
+.ztbox li:hover:after { right: 0px }
+.ztbox li:before { background: #000; position: absolute; left: 0; width: 50px; text-align: center; color: #FFF }
+.ztbox li:nth-child(1):before { content: "1"; }
+.ztbox li:nth-child(2):before { content: "2"; }
+.ztbox li:nth-child(3):before { content: "3"; }
+.ztbox li:nth-child(4):before { content: "4"; }
+.ztbox li:nth-child(5):before { content: "5"; }
+.ztbox li:nth-child(6):before { content: "6"; }
+.ztbox li:nth-child(7):before { content: "7"; }
+.ztbox li:nth-child(8):before { content: "8"; }
+.paihang { background: #FFF; overflow: hidden; margin-top: 20px }
+.paihang h2 { font-size: 16px; padding: 8px 20px; position: relative }
+.paihang h2:after { content: ""; background-color: #282828; left: 20px; width: 60px; height: 2px; bottom: 0; position: absolute; -webkit-transition: 0.5s; -moz-transition: 0.5s; -ms-transition: 0.5s; -o-transition: 0.5s; transition: 0.5s; }
+.paihang ul { padding: 10px 20px }
+.paihang:hover ::after { width: 90px; }
+.paihang ul li { text-overflow: ellipsis; white-space: nowrap; overflow: hidden; line-height: 26px }
+footer { width: 100%; text-align: center; background: #FFF; padding: 10px 0; line-height: 26px; border-top: #333 1px solid; }
+/*list*/
+.place { margin: 10px 0; width: 100%; overflow: hidden; background: #fff; }
+.place a { display: block; float: left; padding: 5px 0; background: #fff; margin: 0 10px; width: 100px; text-align: center }
+.pagelist { text-align: center; color: #666; width: 100%; clear: both; margin: 25px 0 10px 0; padding-top: 20px }
+.pagelist a { color: #666; margin: 0 2px 10px; border: 1px solid #fff; padding: 5px 10px; background: #FFF; display: inline-block; }
+.pagelist a:hover { color: #333; }
+.pagelist > b { border: 1px solid #333; padding: 5px 10px; background: #333; color: #FFF }
+.pagelist  input{ color: #666; margin: 0 2px 10px; border: 1px solid #fff; padding: 5px 5px; height: 22px; display: inline-block;}
+a.curPage { color: #333; font-weight: bold; }
+/*about*/
+.newsview { padding: 20px; overflow: hidden; background: rgba(255,255,255,1); margin: 20px 0 }
+.newsview h2 { font-size: 16px; width: 120px; height: 30px; line-height: 30px; text-align: center; background: #333; color: #fff; margin: 10px 0; font-weight: normal; }
+.news_infos { padding-bottom: 20px }
+/*infosbox*/
+.infosbox { float: left; width: 66%; overflow: hidden; background: #FFF; }
+.newsview { padding: 0 30px }
+.news_title { font-size: 24px; font-weight: normal; }
+.news_author { width: 100%; color: #999; line-height: 18px; }
+.news_author span { margin-right: 10px; padding-left: 20px }
+.news_about { color: #888888; border: 1px solid #F3F3F3; padding: 10px; margin: 20px auto 15px auto; line-height: 23px; background: none repeat 0 0 #F6F6F6; }
+.news_about strong { color: #38485A; font-weight: 400 !important; font-size: 13px; padding-right: 8px; }
+.news_content { line-height: 24px; font-size: 14px; }
+.news_content p { overflow: hidden; padding-bottom: 4px; padding-top: 6px; word-wrap: break-word; }
+.tags a { background: #333; padding: 3px 8px; margin: 0 5px 0 0; color: #fff; }
+.tags { margin: 30px 0; }
+.infosbox .news_con { line-height: 1.8; font-size: 16px; text-align: justify; }
+.infosbox .news_con p { margin-bottom: 25x }
+.infosbox .news_con img { max-width: 650px; height: auto; }
+.infosbox .news_con table { border-collapse: collapse; display: table; width: 100%; text-align: center; background-color: transparent; border-spacing: 0; }
+.infosbox .news_con table tbody{ border: 0; } 
+.infosbox .news_con table tr{ border: 0; border-top: 1px solid #ddd; background-color: #fff; }
+.infosbox .news_con table tr td{ font-size: 14px; color: #4f4f4f; line-height: 22px; border: 1px solid #ddd; padding: 8px; word-break: normal!important; vertical-align: middle; }
+.infosbox .news_con table tr th{ font-size: 14px; color: #4f4f4f; line-height: 22px; border: 1px solid #ddd; padding: 8px; word-break: normal!important; vertical-align: middle; }
+.infosbox .share { padding: 20px; }
+.nextinfo { line-height: 24px; width: 100%; background: #FFF; border-radius: 10px; overflow: hidden; margin: 20px 0 }
+.nextinfo p { padding: 4px 10px; border-radius: 5px; }
+.nextinfo a:hover { color: #000; text-decoration: underline }
+.diggit { width: 140px; margin: 20px auto; background: #E2523A; color: #fff; box-shadow: 1px 2px 6px 0px rgba(0,0,0,.2); border-radius: 3px; line-height: 40px; text-align: center; }
+.diggit a { color: #fff; }
+#diggnum { margin: 5px; }
+.otherlink, .xzsm, .ffsm { width: 100%; background: #FFF; overflow: hidden; margin: 20px 0 }
+.otherlink h2 { border-bottom: #000 2px solid; line-height: 40px; font-size: 14px; padding-left: 40px; color: #000 }
+.otherlink ul { margin: 10px 0 }
+.otherlink li { line-height: 24px; height: 24px; display: block; width: 290px; float: left; overflow: hidden; margin-right: 30px; padding-left: 10px; }
+.otherlink li a:hover { text-decoration: underline; color: #000 }
+.news_pl { margin: 10px 0; width: 100%; background: #FFF; overflow: hidden; margin: 20px 0 }
+.news_pl h2 { border-bottom: #000 2px solid; line-height: 40px; font-size: 14px; padding-left: 30px; color: #000 }
+.xzsm ul, .ffsm ul { padding: 20px; line-height: 24px; border-top: 6px solid #a6b5c5; }
+.bloginfo { overflow: hidden; margin-top: 20px }
+.bloginfo ul li { float: left; font-size: 12px; margin: 0 15px 0 0; color: #748594; line-height: 1.5; display: inline-block; }
+.bloginfo ul li a { color: #748594; }
+.bloginfo ul li a:hover { color: #000 }
+/*time*/
+.timebox { background: #FFF; padding: 30px }
+.timebox span { position: relative; line-height: 32px; padding-right: 40px; color: #999 }
+.timebox span:after { position: absolute; content: ""; width: 2px; height: 40px; background: #e0dfdf; right: 18px }
+.timebox li { text-overflow: ellipsis; white-space: nowrap; overflow: hidden; }
+.timebox li i { position: relative; font-style: normal }
+.timebox li i:before { content: " "; height: 10px; width: 10px; border: 2px solid #cccaca; background: #fff; position: absolute; top: 4px; left: -26px; border-radius: 50%; -webkit-transition: all .5s ease; -moz-transition: all .5s ease; -ms-transition: all .5s ease; -o-transition: all .5s ease; transition: all .5s ease; }
+.timebox li:hover i:before { background: #333 }
+/*phone*/
+ @media screen and (min-width: 768px) and (max-width: 1023px) {
+nav, article { width: 100% }
+.box { width: 100% }
+}
+ @media only screen and (max-width: 767px) {
+nav, article { width: 100% }
+.box { width: 94% }
+aside { display: none }
+.sbox { width: 100%; margin: 0 auto 10px }
+.sbox.ml { margin-left: 0; }
+.blogs { width: 100% }
+.newsbox { width: 100% }
+nav { border: none }
+#starlist { width: 90%; margin: auto; }
+nav li { width: 33%; padding: 0; display: block; float: left; border-top: 1px solid #333; border-bottom: 1px solid #333; }
+nav li:nth-child(n+4) { border-top: none }
+nav li:nth-child(2), nav li:nth-child(5), nav li:nth-child(8) { border-left: 1px solid #333; border-right: 1px solid #333; }
+.infosbox { width: 100% }
+}
+button.submit {
+    width: 100%;
+    font-family: "Roboto", "Open Sans", sans-serif;
+    font-weight: 400;
+    padding: 10px 12px;
+    max-width: 27.75em;
+    min-height: 26px;
+    background: #F7F7F7;
+    color: #333333;
+    border: solid 1px #D4D4D4;
+    border-radius: 0;
+    -webkit-appearance: none;
+    -webkit-transition: background 0.2s;
+    transition: background 0.2s;
+    cursor: pointer
+} 
+
+/*read*/
+.news_con h2 { font-size: 16px; width: auto; height: 30px; line-height: 30px; text-align: center; background: #333; color: #fff; margin: 10px 0; font-weight: normal;display:inline-block !important; display:inline;padding: 0px 20px;}
+
+a.current_category {
+    background: #dbd3d3
+}
+code:not(.language-plaintext,.language-php,.language-c,.language-js,.language-javascript,.language-java,.language-sql,.language-html) {
+    color: #c7254e;
+    background-color: #f9f2f4;
+}
+
+/* 分页 */
+.pagination {
+    display: inline-block;
+    padding-left: 0;
+    border-radius: 4px;
+    list-style: none;
+}
+
+.pagination li {
+    float: left;
+    border: 1px solid #DDD;
+    border-left: none;
+    min-width: 31px;
+    height: 28px;
+    line-height: 28px;
+    text-align: center;
+}
+
+.pagination li.active,
+li.disabled {
+    width: 31px;
+    text-align: center;
+    color: #737373;
+    cursor: default;
+    background: #f5f5f5;
+}
+
+.pagination li a {
+    color: #3399d5;
+}
+
+.pagination li:first-child {
+    border-left: 1px solid #DDD;
+    border-bottom-left-radius: 5px;
+    border-top-left-radius: 5px;
+}
+
+.pagination li:last-child {
+    border-bottom-right-radius: 5px;
+    border-top-right-radius: 5px;
+}
+
+.pagination li:hover {
+    background: #f5f5f5;
+}
+>>>>>>> 78b76253c8ce5873016cf837373af5e30ac80c86

+ 0 - 1
public/static/plugins/.gitignore

@@ -1,4 +1,3 @@
-/ace
 /ckeditor/ckeditor4
 /h-ui
 /h-ui.admin

File diff suppressed because it is too large
+ 5989 - 0
public/static/plugins/ace/ace.js


File diff suppressed because it is too large
+ 1455 - 0
public/static/plugins/ace/mode-markdown.js


+ 128 - 0
public/static/plugins/ace/theme-chrome.js

@@ -0,0 +1,128 @@
+define("ace/theme/chrome",["require","exports","module","ace/lib/dom"], function(require, exports, module) {
+
+exports.isDark = false;
+exports.cssClass = "ace-chrome";
+exports.cssText = ".ace-chrome .ace_gutter {\
+background: #ebebeb;\
+color: #333;\
+overflow : hidden;\
+}\
+.ace-chrome .ace_print-margin {\
+width: 1px;\
+background: #e8e8e8;\
+}\
+.ace-chrome {\
+background-color: #FFFFFF;\
+color: black;\
+}\
+.ace-chrome .ace_cursor {\
+color: black;\
+}\
+.ace-chrome .ace_invisible {\
+color: rgb(191, 191, 191);\
+}\
+.ace-chrome .ace_constant.ace_buildin {\
+color: rgb(88, 72, 246);\
+}\
+.ace-chrome .ace_constant.ace_language {\
+color: rgb(88, 92, 246);\
+}\
+.ace-chrome .ace_constant.ace_library {\
+color: rgb(6, 150, 14);\
+}\
+.ace-chrome .ace_invalid {\
+background-color: rgb(153, 0, 0);\
+color: white;\
+}\
+.ace-chrome .ace_fold {\
+}\
+.ace-chrome .ace_support.ace_function {\
+color: rgb(60, 76, 114);\
+}\
+.ace-chrome .ace_support.ace_constant {\
+color: rgb(6, 150, 14);\
+}\
+.ace-chrome .ace_support.ace_type,\
+.ace-chrome .ace_support.ace_class\
+.ace-chrome .ace_support.ace_other {\
+color: rgb(109, 121, 222);\
+}\
+.ace-chrome .ace_variable.ace_parameter {\
+font-style:italic;\
+color:#FD971F;\
+}\
+.ace-chrome .ace_keyword.ace_operator {\
+color: rgb(104, 118, 135);\
+}\
+.ace-chrome .ace_comment {\
+color: #236e24;\
+}\
+.ace-chrome .ace_comment.ace_doc {\
+color: #236e24;\
+}\
+.ace-chrome .ace_comment.ace_doc.ace_tag {\
+color: #236e24;\
+}\
+.ace-chrome .ace_constant.ace_numeric {\
+color: rgb(0, 0, 205);\
+}\
+.ace-chrome .ace_variable {\
+color: rgb(49, 132, 149);\
+}\
+.ace-chrome .ace_xml-pe {\
+color: rgb(104, 104, 91);\
+}\
+.ace-chrome .ace_entity.ace_name.ace_function {\
+color: #0000A2;\
+}\
+.ace-chrome .ace_heading {\
+color: rgb(12, 7, 255);\
+}\
+.ace-chrome .ace_list {\
+color:rgb(185, 6, 144);\
+}\
+.ace-chrome .ace_marker-layer .ace_selection {\
+background: rgb(181, 213, 255);\
+}\
+.ace-chrome .ace_marker-layer .ace_step {\
+background: rgb(252, 255, 0);\
+}\
+.ace-chrome .ace_marker-layer .ace_stack {\
+background: rgb(164, 229, 101);\
+}\
+.ace-chrome .ace_marker-layer .ace_bracket {\
+margin: -1px 0 0 -1px;\
+border: 1px solid rgb(192, 192, 192);\
+}\
+.ace-chrome .ace_marker-layer .ace_active-line {\
+background: rgba(0, 0, 0, 0.07);\
+}\
+.ace-chrome .ace_gutter-active-line {\
+background-color : #dcdcdc;\
+}\
+.ace-chrome .ace_marker-layer .ace_selected-word {\
+background: rgb(250, 250, 255);\
+border: 1px solid rgb(200, 200, 250);\
+}\
+.ace-chrome .ace_storage,\
+.ace-chrome .ace_keyword,\
+.ace-chrome .ace_meta.ace_tag {\
+color: rgb(147, 15, 128);\
+}\
+.ace-chrome .ace_string.ace_regex {\
+color: rgb(255, 0, 0)\
+}\
+.ace-chrome .ace_string {\
+color: #1A1AA6;\
+}\
+.ace-chrome .ace_entity.ace_other.ace_attribute-name {\
+color: #994409;\
+}\
+.ace-chrome .ace_indent-guide {\
+background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y;\
+}\
+";
+
+var dom = require("../lib/dom");
+dom.importCssString(exports.cssText, exports.cssClass);
+});

+ 0 - 2
public/storage/.gitignore

@@ -1,2 +0,0 @@
-*
-!.gitignore

+ 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>

+ 4 - 2
view/index/article/read.html

@@ -8,16 +8,18 @@
       <div class="bloginfo">
         <ul>
           <li class="author"><a href="{$data.category_url}"> {$data.category_name} </a></li>
-          <li class="timer">{$data.create_time}</li>
+          <li class="timer">{$data.create_time|date="Y-m-d"}</li>
           <li class="view">{$data.hits} 已阅读</li>
           <li class="like">{$data.likes} 点赞</li>
+          <li class="writer">作者: {$data.writer?:"huwhois"}</li>
+          <li class="source">来源: {$data.source} </li>
         </ul>
       </div>
       <div class="tags">
         {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


+ 4 - 10
view/sys/article/save.html

@@ -7,6 +7,7 @@
 <article class="cl pd-20">
     <form action="{:url('save')}" method="post" class="form form-horizontal" id="form-save">
         <input type="hidden" name="id" value="{$data['id']}">
+        <input type="hidden" name="cjid" value="{$data['cjid']}">
         <input type="hidden" name="content_type" value="{$data['content_type']}">
         <div class="row cl">
             <label class="form-label col-xs-4 col-sm-2">
@@ -160,7 +161,7 @@
             //图片上传
             simpleUpload: {
                 // The URL the images are uploaded to.
-                uploadUrl: '/sys/file_manager/ckeditorUploadImage'
+                uploadUrl: '/sys/file_manager/ckeditorUploadImage?infoid={$data.id}&cjid={$data.cjid}'
             },
             //自定义字体
             fontFamily: {
@@ -235,14 +236,7 @@
 
     //添加标题图
     function addTitlePic() {
-        layer.open({
-            type: 2,
-            area: ['700px', '500px'],
-            fix: false, //不固定
-            maxmin: true,
-            shade: 0.4,
-            title: '添加标题图',
-            content: '{:url("file_manager/uploadimg", ["_layer"=>true,"img_id"=>"titlepic"])}'
-        });
+        let url = '{:url("file_manager/uploadimg", ["_layer"=>true,"img_id"=>"titlepic","infoid"=>$data.id,"cjid"=>$data.cjid])}'
+        layer_show('添加标题图', url, 800, 500);
     }
 </script>

+ 31 - 237
view/sys/article/savemd.html

@@ -22,8 +22,8 @@
 
     #dialog {
         position: fixed;
-        height: 400px;
-        width: 800px;
+        height: 300px;
+        width: 600px;
         background: #FFFFFF;
         z-index: 5;
         left: 30%;
@@ -32,15 +32,6 @@
         display: none;
     }
 
-    #showImg {
-        height: 160px;
-        width: 160px;
-        position: absolute;
-        border: 0.5px solid gainsboro;
-        bottom: 80px;
-        left: 35%;
-    }
-
     #cancel {
         border: 0px none #FFECEC;
         background: #999999;
@@ -68,85 +59,12 @@
     #insert:hover {
         background: #CB474D;
     }
-
-    #online {
-        width: 100%;
-        height: 224px;
-        padding: 10px 0 0 0;
-    }
-
-    #online #imageList {
-        width: 100%;
-        height: 100%;
-        overflow-x: hidden;
-        overflow-y: auto;
-        position: relative;
-        margin-left: 20px;
-    }
-
-    #online ul {
-        display: block;
-        list-style: none;
-        margin: 0;
-        padding: 0;
-    }
-
-    #online li {
-        float: left;
-        display: block;
-        list-style: none;
-        padding: 0;
-        width: 113px;
-        height: 113px;
-        margin: 0 0 9px 9px;
-        background-color: #eee;
-        overflow: hidden;
-        cursor: pointer;
-        position: relative;
-    }
-
-    #online li img {
-        cursor: pointer;
-    }
-
-    #online li .icon {
-        cursor: pointer;
-        width: 113px;
-        height: 113px;
-        position: absolute;
-        top: 0;
-        left: 0;
-        z-index: 2;
-        border: 0;
-        background-repeat: no-repeat;
-    }
-
-    #online li .icon:hover {
-        width: 107px;
-        height: 107px;
-        border: 3px solid #1094fa;
-    }
-
-    #online li.selected .icon {
-        background-image: url(/static/images/success.png);
-        background-image: url(images/success.gif)\9;
-        background-position: 75px 75px;
-    }
-
-    #online li.clearFloat {
-        float: none;
-        clear: both;
-        display: block;
-        width: 0;
-        height: 0;
-        margin: 0;
-        padding: 0;
-    }
 </style>
 
 <article class="cl pd-20">
     <form action="{:url('save')}" method="post" class="form form-horizontal" id="form-save">
         <input type="hidden" name="id" value="{$data['id']}">
+        <input type="hidden" name="cjid" value="{$data['cjid']}">
         <input type="hidden" name="content_type" value="{$data['content_type']}">
         <div class="row cl">
             <label class="form-label col-xs-4 col-sm-2">
@@ -288,6 +206,7 @@
         <img src="/static/images/X.png" style="height: 25px;width: 25px;position: absolute;right: 10px;top: 10px;cursor: pointer;"
             onclick="f_cancel()" />
     </div>
+<<<<<<< HEAD
 
     <div id="tab-img" class="HuiTab" style="margin-top: 40px;">
         <div class="tabBar clearfix">
@@ -378,7 +297,14 @@
                     <div class="col-3"> </div>
                 </div>
             </form>
+=======
+    <div class="row cl" style="margin-top:40px;">
+        <div style="width: 160px;height: 160px;margin: 0 auto;display: table-cell;vertical-align: middle;text-align: center;">
+            <img id="view-picture" src="/static/images/upload_picture.png" alt="图片"
+                title="图片" style="max-width: 120px;max-height: 120px;" onclick="addPicture()">
+>>>>>>> 78b76253c8ce5873016cf837373af5e30ac80c86
         </div>
+        <input type="text" class="input-text" name="picture" id="picture" value="">
     </div>
     <div style="position: absolute;bottom: 1px;width: 100%;height: 40px;border-top: 1px solid gray;">
         <button id="cancel" onclick="f_cancel()">取消</button>
@@ -395,40 +321,27 @@
 <script type="text/javascript" src="/static/plugins/jquery.validation/1.14.0/validate-methods.js"></script>
 
 <script type="text/javascript">
-    jQuery.Huitab = function (tabBar, tabCon, class_name, tabEvent, i) {
-        var $tab_menu = $(tabBar);
-        // 初始化操作
-        $tab_menu.removeClass(class_name);
-        $(tabBar).eq(i).addClass(class_name);
-        $(tabCon).hide();
-        $(tabCon).eq(i).show();
-
-        $tab_menu.bind(tabEvent, function () {
-            $tab_menu.removeClass(class_name);
-            $(this).addClass(class_name);
-            var index = $tab_menu.index(this);
-            $(tabCon).hide();
-            $(tabCon).eq(index).show()
-        })
-    }
-
     var editor = ace.edit('mdeditor');//编辑框
 
     editor.setTheme('ace/theme/chrome');
     editor.getSession().setMode('ace/mode/markdown');
     editor.renderer.setShowPrintMargin(false);
 
+    //左侧插入,用户插入一些特定方法
+    function insertText(val) {
+        editor.insert(val); //光标位置插入
+    }
+
     //添加标题图
     function addTitlePic() {
-        layer.open({
-            type: 2,
-            area: ['700px', '500px'],
-            fix: false, //不固定
-            maxmin: true,
-            shade: 0.4,
-            title: '添加标题图',
-            content: '{:url("file_manager/uploadimg", ["_layer"=>true,"img_id"=>"titlepic"])}'
-        });
+        let url = '{:url("file_manager/uploadimg", ["_layer"=>true,"img_id"=>"titlepic","infoid"=>$data.id,"cjid"=>$data.cjid])}'
+        layer_show('添加标题图', url, 800, 500);
+    }
+
+    // 上传图片
+    function addPicture() {
+        let url = '{:url("file_manager/uploadimg", ["_layer"=>true,"img_id"=>"picture","infoid"=>$data.id,"cjid"=>$data.cjid])}'
+        layer_show('插入图片', url, 800, 500);
     }
 
     //插入图片弹窗取消
@@ -439,139 +352,20 @@
     function showDialog() {
         $('#dialog').show();
     }
-
-    //左侧插入,用户插入一些特定方法
-    function insertText(val) {
-        editor.insert(val); //光标位置插入
-    }
-
-    // 文档图片插入地址
-    var imgUrl = "";
-
+    
     //插入图片
     function insert() {
         $('#dialog').hide();
-        insertText('![这里写图片描述](' + imgUrl + ')')
-    }
-
-    //上传图片到服务器,返回图片地址
-    function uploadFile() {
-        imgUrl = 'https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/logo_white.png';
-        $('#showImg').attr('src', 'https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/logo_white.png');
-    }
 
-    //本地上传图片
-    function uploadImg() {
-        if ($("#upload_file").val() == '') {
-            layer.msg("请选择要上传的文件", {
-                icon: 6,
-                time: 1000
-            });
-            return false;
-        } else {
-            var formData = new FormData($("#form-uploadimg")[0]);
-            $.ajax({
-                url: '{:url("file_manager/uploadimg")}',
-                type: 'POST',
-                async: true,
-                cache: false,
-                data: formData,
-                processData: false,
-                contentType: false,
-                dataType: "json",
-                success: function (res) {
-                    if (res.code == 0) {
-                        console.log(res);
-                        imgUrl = res.picture_url + res.picname;
-                        $("#view-picture").attr('src', imgUrl);
-                    } else {
-                        layer.msg(res.msg, {
-                            icon: 5,
-                            time: 1000
-                        });
-                        return false;
-                    }
-                }
-            });
-        }
-    }
-
-    // 网络图片
-    function uploadUrlImg() {
-        if ($("#url_file").val() == '') {
-            layer.msg("请选择要上传的地址", {
-                icon: 6,
-                time: 1000
-            });
-            return false;
-        } else {
-            var formData = new FormData($("#form-uploadurlimg")[0]);
-            $.ajax({
-                url: '{:url("file_manager/uploadurlimg")}',
-                type: 'POST',
-                async: true,
-                cache: false,
-                data: formData,
-                processData: false,
-                contentType: false,
-                dataType: "json",
-                success: function (res) {
-                    if (res.code == 0) {
-                        console.log(res);
-                        imgUrl = res.picture_url + res.picname;
-                        $("#view-picture-url").attr('src', imgUrl);
-                    } else {
-                        layer.msg(res.msg, {
-                            icon: 5,
-                            time: 1000
-                        });
-                        return false;
-                    }
-                }
-            });
-        }
-    }
+        // 文档图片插入地址
+        var imgUrl = $("#picture").val();
+        
+        insertText('![这里写图片描述](' + imgUrl + ')')
 
-    // 获取服务器图片
-    function onlinepicture(page) {
-        var data = { "page": page };
-        $.ajax({
-            url: '{:url("file_manager/onlineimg")}',
-            type: 'GET',
-            async: true,
-            cache: false,
-            data: 'page=' + page,
-            processData: false,
-            contentType: false,
-            dataType: "json",
-            success: function (res) {
-                if (res.code == 0) {
-                    html_str = "";
-                    res.list.forEach(element => {
-                        html_str += '<li><img width="170" height="113" src="' + element.url + '?noCache=' + element.mtime + '"';
-                        html_str += '_src="' + element.url + '">';
-                        html_str += '<span class="icon"></span></li>';
-                    });
-                    $('ul.list').prepend(html_str);
-                }
-            }
-        });
+        $("#picture").val('');
+        $("#view-picture").attr('src', '/static/images/upload_picture.png');
     }
 
-    $(function () {
-        $.Huitab("#tab-img .tabBar span", "#tab-img .tabCon", "current", "click", "0");
-        $(document).on("click", "#online li", function () {
-            $("#online li").removeClass('selected');
-
-            $(this).addClass('selected');
-
-            imgUrl = $(this).children('img').attr('_src');
-
-            $("#online_file").val(imgUrl);
-        })
-    });
-
-
     function validator(params) {
         return $("#form-save").validate({
             debug: true,

+ 136 - 0
view/sys/file_manager/database_picture.html

@@ -0,0 +1,136 @@
+<style>
+    #online {
+        width: 100%;
+        height: 224px;
+        padding: 10px 0 0 0;
+    }
+
+    #online #imageList {
+        width: 100%;
+        height: 100%;
+        overflow-x: hidden;
+        overflow-y: auto;
+        position: relative;
+        margin-left: 20px;
+    }
+
+    #online ul {
+        display: block;
+        list-style: none;
+        margin: 0;
+        padding: 0;
+    }
+
+    #online li {
+        float: left;
+        display: block;
+        list-style: none;
+        padding: 0;
+        width: 113px;
+        height: 113px;
+        margin: 0 0 9px 9px;
+        background-color: #eee;
+        overflow: hidden;
+        cursor: pointer;
+        position: relative;
+    }
+
+    #online li img {
+        cursor: pointer;
+    }
+
+    #online li .icon {
+        cursor: pointer;
+        width: 113px;
+        height: 113px;
+        position: absolute;
+        top: 0;
+        left: 0;
+        z-index: 2;
+        border: 0;
+        background-repeat: no-repeat;
+    }
+
+    #online li .icon:hover {
+        width: 107px;
+        height: 107px;
+        border: 3px solid #1094fa;
+    }
+
+    #online li.selected .icon {
+        background-image: url(/static/images/success.png);
+        background-image: url(images/success.gif)\9;
+        background-position: 75px 75px;
+    }
+
+    #online li.clearFloat {
+        float: left;
+        clear: both;
+        display: block;
+        width: 113px;
+        height: 113px;
+        margin: 0 0 9px 9px;
+        padding: 0;
+    }
+</style>
+
+<div class="cl mt-20" id="online">
+    <div id="imageList">
+        <ul class="list">
+            <!-- <li>
+                <img width="170" height="113" src="/storage/20220223/d5cc488e71c58bb072debe45ed06c6ad.jpg?noCache=1634567323"
+                 _src="/storage/20220223/d5cc488e71c58bb072debe45ed06c6ad.jpg">
+                <span class="icon"></span>
+            </li>
+             -->
+            <li class="clearFloat"></li>
+        </ul>
+    </div>
+</div>
+
+<script type="text/javascript">
+    $(function () {
+        $.Huitab("#tab-img .tabBar span", "#tab-img .tabCon", "current", "click", "0");
+        $(document).on("click", "#online li", function () {
+            $("#online li").removeClass('selected');
+            
+            $(this).addClass('selected');
+            
+            img = $(this).children('img').attr('_src');
+            
+            $("#online_file").val(img);
+        });
+    });
+    
+    function onlinepicture() {
+        let infoid = $("input[name='infoid']").val();
+        let cjid = $("input[name='cjid']").val();
+
+        $.ajax({
+            url: '{:url("file_manager/queryList")}',
+            type: 'POST',
+            async: true,
+            cache: false,
+            data: JSON.stringify({
+                infoid: infoid,
+                cjid: cjid
+            }),
+            processData: false,
+            contentType: 'application/json',
+            dataType: "json",
+            success: function (res) {
+                if (res.code == 0) {
+                    html_str = "";
+                    res.list.forEach(element => {
+                        html_str += '<li><img width="170" height="113" src="' + element.filepath + '?noCache=' + element.filetime + '"';
+                        html_str += '_src="' + element.filepath + '" title="'+element.title+'">';
+                        html_str += '<span class="icon"></span></li>';
+                    });
+                    $('ul.list').prepend(html_str);
+                }
+            }
+        });
+    }
+
+    onlinepicture();
+</script>

+ 81 - 0
view/sys/file_manager/directory_picture.html

@@ -0,0 +1,81 @@
+<div class="row cl">
+    <table class="table table-border table-bordered table-bg">
+        <thead>
+            <tr class="text-c">
+                <th>
+                    <strong>文件名</strong>
+                </th>
+                <th>
+                    <strong>文件大小</strong>
+                </th>
+                <th>
+                    <strong>最后修改时间</strong>
+                </th>
+            </tr>
+        </thead>
+        <tbody>
+        </tbody>
+    </table>
+</div>
+
+<script type="text/javascript">
+    var data = {
+        dirs: [],
+        files: [],
+        activeurl: '',
+        activepath: ''
+    }
+
+    function maketbody() {
+        let tbhtml = '';
+        tbhtml += '<tr class="text-c" bgcolor="#FFFFFF" height="26" onMouseMove="javascript:this.bgColor=\'#FCFDEE\';" onMouseOut="javascript:this.bgColor=\'#FFFFFF\';">'
+        tbhtml += '<td>'+(data.activeurl ? '<i class="Hui-iconfont Hui-iconfont-arrow1-top"></i>' : '') +'<a onclick="onlinepicture(\''+data.activeurl+'\')">上级目录</a></td>'
+        tbhtml += '<td>当前目录:<span style="color:#f00;"> ./storage'+data.activepath+'</span></td><td></td></tr>'
+
+        data.dirs.forEach((dir) => {
+            tbhtml += '<tr class="text-c" style="height:26px; " onMouseMove="javascript:this.bgColor=\'#FCFDEE\';" onMouseOut="javascript:this.bgColor=\'#FFFFFF\';">'
+            tbhtml += '<td style="text-align:left;"><img src="/static/images/icon/dir.png">'
+            tbhtml += '<a onclick="onlinepicture(\''+data.activepath+'/'+dir+'\')">'+dir+'</a></td><td></td><td></td></tr>'
+        });
+
+        data.files.forEach((file) => {
+            tbhtml += '<tr class="text-c" style="height:26px; " onMouseMove="javascript:this.bgColor=\'#FCFDEE\';" onMouseOut="javascript:this.bgColor=\'#FFFFFF\';">'
+            tbhtml += '<td style="text-align:left;"><img src="/static/images/icon/'+file.extension+'.png">'
+            tbhtml += '<a onclick="selcetimg(\'/storage'+data.activepath+'/'+file.filename+'\')">'+file.filename+'</a></td>'
+            tbhtml += '<td>'+file.size+'</td><td></td></tr>'
+        });
+
+        document.querySelector('table tbody').innerHTML = tbhtml;
+    }
+
+    function onlinepicture(activepath) {        
+        $.ajax({
+            url: '{:url("file_manager/explorer")}',
+            type: 'GET',
+            async: true,
+            cache: false,
+            data: 'activepath='+activepath,
+            processData: false,
+            contentType: 'application/x-www-form-urlencoded',
+            dataType: "json",
+            success: function (res) {
+                if (res.code == 0) {
+                    // console.log(res);
+                    data.dirs       = res.dirs
+                    data.files      = res.files
+                    data.activeurl  = res.activeurl
+                    data.activepath = res.activepath
+
+                    maketbody();
+                }
+            }
+        });
+    }
+
+    function selcetimg(img) {
+        $("#online_file").val(img);
+    }
+
+    onlinepicture(data.activepath);
+</script>
+

+ 232 - 0
view/sys/file_manager/explorer.html

@@ -1,3 +1,4 @@
+<<<<<<< HEAD
 <style>
     .progress {
         width: 600px;
@@ -227,4 +228,235 @@
         });
     }
 </script>
+=======
+<style>
+    .progress {
+        width: 600px;
+        height: 10px;
+        border: 1px solid #ccc;
+        border-radius: 10px;
+        margin: 10px 0px;
+        overflow: hidden;
+        display: -webkit-inline-box;
+    }
+
+    /* 初始状态设置进度条宽度为0px */
+    .progress>div {
+        width: 0px;
+        height: 100%;
+        background-color: yellowgreen;
+        transition: all .3s ease;
+    }
+</style>
+
+<article class="cl pd-20">
+    <div class="cl pd-5 bg-1 bk-gray">
+        <span class="l">
+            <a class="btn radius btn-default" href="{:url('index')}"><i
+                    class="Hui-iconfont Hui-iconfont-pages"></i>数据库模式</a>
+            <a class="btn radius btn-secondary"><i class="Hui-iconfont Hui-iconfont-jifen"></i> 目录模式 </a>
+            <a class="btn btn-primary radius" onclick="uploadFile();"><i
+                    class="Hui-iconfont Hui-iconfont-add"></i>上传附件</a>
+            <input type="file" id="upload_file" hidden multiple onchange="fileChange()">
+            <input type="hidden" id="activepath" name="activepath" value="{$activepath}">
+            <div class="progress">
+                <div></div>
+            </div>
+        </span>
+        <span class="r">共有:
+            <strong>{$counts}</strong> 个对象</span>
+    </div>
+    <div class="cl mt-20">
+        <table class="table table-border table-bordered table-bg">
+            <thead>
+                <tr class="text-c">
+                    <th width="25%">
+                        <strong>文件名</strong>
+                    </th>
+                    <th width="16%">
+                        <strong>文件大小</strong>
+                    </th>
+                    <th width="22%">
+                        <strong>最后修改时间</strong>
+                    </th>
+                    <th width="34%">
+                        <strong>操作</strong>
+                    </th>
+                </tr>
+            </thead>
+            <tbody>
+                <tr class="text-c" bgcolor='#FFFFFF' height='26' onMouseMove="javascript:this.bgColor='#FCFDEE';"
+                    onMouseOut="javascript:this.bgColor='#FFFFFF';">
+                    <td>
+                        {notempty name="activepath"}<i class="Hui-iconfont Hui-iconfont-arrow1-top"></i>{/notempty}
+                        <a href="/sys/file_manager/explorer?activepath={$activeurl}">上级目录</a>
+                    </td>
+                    <td>当前目录:
+                        <span style="color:#f00;"> ./storage{$activepath} </span>  
+                    </td>
+                    <td></td>
+                    <td></td>
+                </tr>
+                {foreach $dirs as $dir}
+                <tr class="text-c" style="height:26px; " onMouseMove="javascript:this.bgColor='#FCFDEE';"
+                    onMouseOut="javascript:this.bgColor='#FFFFFF';">
+                    <td style="text-align:left;">
+                        <img src="/static/images/icon/dir.png">
+                        <a href="/sys/file_manager/explorer?activepath={$activepath.'/'.$dir}">
+                            {$dir}
+                        </a>
+                    </td>
+                    <td></td>
+                    <td></td>
+                    <td>
+                        <a class="btn" onclick="del_dir(this, '{$activepath}/{$dir}')">删除</a>
+                    </td>
+                </tr>
+                {/foreach}
+                {foreach $files as $file}
+                <tr class="text-c" bgcolor='#FFFFFF' height='26' onMouseMove="javascript:this.bgColor='#FCFDEE';"
+                    onMouseOut="javascript:this.bgColor='#FFFFFF';">
+                    <td style="text-align:left;">
+                        <img src="/static/images/icon/{$file['extension']}.png">
+                        <a href="/storage{$activepath}/{$file['filename']}" target="_blank">
+                            {$file['filename']}
+                        </a>
+                    </td>
+                    <td align='center'> {$file['size']} </td>
+                    <td align='center'> {$file['time']|date="Y-m-d H:i:s"} </td>
+                    <td>
+                        <a href="/storage{$activepath.'/'.$file['filename']}" class="btn radius btn-primary"
+                            target="_blank">查看/下载</a>&nbsp;
+                        <a class="btn radius btn-danger"
+                            onclick="del_file(this,'{$activepath}/{$file.filename}')">删除</a>&nbsp;
+                        <!-- <a href='' class="btn" >移动</a> -->
+                    </td>
+                </tr>
+                {/foreach}
+            </tbody>
+        </table>
+    </div>
+</article>
+
+<!--请在下方写此页面业务相关的脚本-->
+<script type="text/javascript">
+    /*删除图片*/
+    function del_dir(obj, dir) {
+        layer.confirm('确认要删除吗?', function (index) {
+            $.post('deldir', {
+                'dir': dir
+            }, function (res) {
+                if (res.code == 0) {
+                    $(obj).parents('tr').remove();
+                    topalert({
+                        type: 0,
+                        content: res.msg,
+                        speed: 1000
+                    });
+                } else {
+                    topalert({
+                        type: 2,
+                        content: res.msg,
+                        speed: 2000
+                    });
+                }
+                layer.close(layer.index);
+            }, 'json');
+        });
+    }
+
+    /*删除图片*/
+    function del_file(obj, filename) {
+        layer.confirm('确认要删除吗?', function (index) {
+            $.post('delfile', {
+                'filename': filename
+            }, function (res) {
+                if (res.code == 0) {
+                    $(obj).parents('tr').remove();
+                    topalert({
+                        type: 0,
+                        content: res.msg,
+                        speed: 1000
+                    });
+                } else {
+                    topalert({
+                        type: 2,
+                        content: res.msg,
+                        speed: 2000
+                    });
+                }
+                layer.close(layer.index);
+            }, 'json');
+        });
+    }
+
+    //通过点击图片来触发文件上传按钮
+    function uploadFile(params) {
+        $("#upload_file").click();
+    }
+
+    // 自动上传处理
+    function fileChange() {
+        let uploadFile = $("#upload_file").get(0).files;
+        // console.log(uploadFile);
+        if (uploadFile == undefined || uploadFile == null) {
+            layer.msg("请选择文件", { icon: 5, time: 1000 });
+            return false;
+        }
+
+        if (uploadFile.length > 20) {
+            layer.msg("最多20个文件", { icon: 5, time: 1000 });
+            return false;
+        }
+
+        let formData = new FormData();
+
+        formData.append('activepath', $('#activepath').val());
+
+        for (let i = 0; i < uploadFile.length; i++) {
+            formData.append('upload_file[]', uploadFile[i]);
+        }
+
+        $.ajax({
+            url: '{:url("file_manager/uploadFile")}',
+            type: 'post',
+            dataType: 'json',
+            data: formData,
+            processData: false,
+            contentType: false,
+            xhr: function () {
+                var xhr = new XMLHttpRequest();
+                //使用XMLHttpRequest.upload监听上传过程,注册progress事件,打印回调函数中的event事件
+                xhr.upload.addEventListener('progress', function (e) {
+                    // console.log(e);
+                    //loaded代表上传了多少
+                    //total代表总数为多少
+                    var progressRate = (e.loaded / e.total) * 100 + '%';
+
+                    //通过设置进度条的宽度达到效果
+                    $('.progress > div').css('width', progressRate);
+                })
+
+                return xhr;
+            },
+            success: function (res) {
+                console.log(res);
+                if (res.code == 0) {
+                    layer.msg(res.msg, {
+                        icon: 1,
+                        time: 1000
+                    });
+                    window.location.reload();
+                } else {
+                    layer.msg(res.msg, {
+                        icon: 5,
+                        time: 1000
+                    });
+                    return false;
+                }
+            }
+        });
+    }
+</script>
+>>>>>>> 78b76253c8ce5873016cf837373af5e30ac80c86
 <!--请在上方写此页面业务相关的脚本-->

+ 210 - 0
view/sys/file_manager/index.html

@@ -1,3 +1,4 @@
+<<<<<<< HEAD
 <style>
     .progress {
         width: 600px;
@@ -202,4 +203,213 @@
         //     content: 'test'
         // });
     }
+=======
+<style>
+    .progress {
+        width: 600px;
+        height: 10px;
+        border: 1px solid #ccc;
+        border-radius: 10px;
+        margin: 10px 0px;
+        overflow: hidden;
+        display: -webkit-inline-box;
+    }
+
+    /* 初始状态设置进度条宽度为0px */
+    .progress>div {
+        width: 0px;
+        height: 100%;
+        background-color: yellowgreen;
+        transition: all .3s ease;
+    }
+</style>
+
+<article class="cl pd-10">
+    <div class="cl pd-5 bg-1 bk-gray mt-20">
+        <span class="l">
+            <a class="btn radius btn-secondary"><i class="Hui-iconfont Hui-iconfont-jifen"></i>数据库模式</a>
+            <a class="btn radius btn-default" href="{:url('explorer')}"><i class="Hui-iconfont Hui-iconfont-pages"></i> 目录模式 </a>
+            <a class="btn btn-danger radius" onclick="del_all();"><i class="Hui-iconfont Hui-iconfont-del2"></i>批量删除</a>
+            <a class="btn btn-primary radius" onclick="uploadFile();"><i class="Hui-iconfont Hui-iconfont-add"></i>上传附件</a>
+            <input type="file" id="upload_file" hidden multiple onchange="fileChange()">
+            <div class="progress">
+                <div></div>
+            </div>
+        </span>
+        <span class="r">共有数据:<strong id="total">{$list->total()}</strong>条</span>
+    </div>
+
+    <div class="cl mt-20">
+        <table class="table table-border table-bordered table-bg">
+            <thead>
+                <tr class="text-c">
+                    <th width="25px;">
+                        <input type="checkbox" name="allcheck" value="">
+                    </th>
+                    <th width="60px;">ID</th>
+                    <th>文件title</th>
+                    <th style="min-width: 260px;">文件路径</th>
+                    <th>文件类型</th>
+                    <th>文件大小</th>
+                    <th>增加者</th>
+                    <th>增加时间</th>
+                    <th width="100px;">操作</th>
+                </tr>
+            </thead>
+            <tbody>
+                {foreach $list as $val}
+                <tr class="text-c">
+                    <td>
+                        <input type="checkbox" value="{$val.fileid}" name="checkbox[]">
+                    </td>
+                    <td>{$val.fileid}</td>
+                    <td class="text-l">{$val.title}</td>
+                    <td class="text-l">
+                        <a href="{$val.filepath}" title="{$val.filepath}" target="_blank">{$val.filepath}</a>
+                    </td>
+                    <td>{$val.fileextension}</td>
+                    <td>{$val.filesize|format_bytes}</td>
+                    <td>{$val.username}</td>
+                    <td>{$val.filetime|date="Y-m-d H:i:s"}</td>
+                    <td class="td-manager">
+                        <a class="btn btn-secondary radius" title="编辑title" onClick="editTitle('{$val.fileid}','{$val.title}')"><i
+                            class="Hui-iconfont Hui-iconfont-edit"></i></a>
+                        <a class="btn btn-danger radius" title="删除" onClick="del(this,'{$val.fileid}')"><i
+                            class="Hui-iconfont Hui-iconfont-del2"></i></a></td>
+                </tr>
+                {/foreach}
+            </tbody>
+        </table>
+    </div>
+    <div class="cl pd-5 bg-1 bk-gray mt-20 ">
+        <span class="r">{$list->render()|raw}</span>
+    </div>
+</article>
+
+<script>
+    //通过点击图片来触发文件上传按钮
+    function uploadFile(params) {
+        $("#upload_file").click();
+    }
+
+    // 上传处理
+    function fileChange() {
+        let uploadFile = $("#upload_file").get(0).files;
+        // console.log(uploadFile);
+        if (uploadFile == undefined || uploadFile == null) {
+            layer.msg("请选择文件", { icon: 5, time: 1000 });
+            return false;
+        }
+
+        if (uploadFile.length > 20) {
+            layer.msg("最多20个文件", { icon: 5, time: 1000 });
+            return false;
+        }
+
+        let formData = new FormData();
+
+        for (let i = 0; i < uploadFile.length; i++) {
+            formData.append('upload_file[]', uploadFile[i]);
+        }
+
+        $.ajax({
+            url: '{:url("file_manager/uploadFile")}',
+            type: 'post',
+            dataType: 'json',
+            data: formData,
+            processData: false,
+            contentType: false,
+            xhr: function () {
+                var xhr = new XMLHttpRequest();
+                //使用XMLHttpRequest.upload监听上传过程,注册progress事件,打印回调函数中的event事件
+                xhr.upload.addEventListener('progress', function (e) {
+                    // console.log(e);
+                    //loaded代表上传了多少
+                    //total代表总数为多少
+                    var progressRate = (e.loaded / e.total) * 100 + '%';
+
+                    //通过设置进度条的宽度达到效果
+                    $('.progress > div').css('width', progressRate);
+                })
+
+                return xhr;
+            },
+            success: function (res) {
+                console.log(res);
+                if (res.code == 0) {
+                    layer.msg(res.msg, {
+                        icon: 1,
+                        time: 1000
+                    });
+                    window.location.reload();
+                } else {
+                    layer.msg(res.msg, {
+                        icon: 5,
+                        time: 1000
+                    });
+                    return false;
+                }
+            }
+        });
+    }
+
+    function editTitle(id, title) {
+        if (id==0) {
+            layer.msg('id不可为空', {icon: 5,time: 1000});
+        }
+
+        var content  = '<div  class="cl" style="padding:20px;">';
+            content += '<label class="form-label col-sm-4">';
+            content += '<span class="c-red">*</span>文件title:</label>';
+            content += '<div class="formControls col-sm-6">';
+            content += '<input type="text" class="input-text" name="filetile" id="filetile">';
+            content += '</div><div class="col-3"></div></div></div>';
+
+        layer.open({
+            type: 1,
+            area: ['500px', '200px'],
+            title: '修改文件title',
+            content: '\<\div style="padding:20px;">\<\span class="c-red">*\<\/span>文件title:\<\input type="text" class="input-text" name="filetitle" value="'+title+'" id="filetitle">\<\/div>',
+            btn: ['确定', '取消'],
+            yes: function(index, layero){
+                let filetitle = document.querySelector('input[name="filetitle"]').value;
+                $.ajax({
+                    url: '{:url("file_manager/updateFileTitle")}',
+                    type: 'post',
+                    dataType: 'json',
+                    contentType: 'application/json',
+                    data: JSON.stringify({
+                        id: id,
+                        filetitle: filetitle
+                    }),
+                    success: function (res) {
+                        if (res.code == 0) {
+                            layer.msg(res.msg, {
+                                icon: 1,
+                                time: 1000
+                            });
+                            window.location.reload();
+                        } else {
+                            layer.msg(res.msg, {
+                                icon: 5,
+                                time: 1000
+                            });
+                        }
+                        layer.close(index);
+                    }
+                });
+            }
+        });
+        
+        // layer.open({
+        //     type: 2,
+        //     area: ['700px', '500px'],
+        //     fix: false, //不固定
+        //     maxmin: true,
+        //     shade: 0.4,
+        //     title: '添加标题图',
+        //     content: 'test'
+        // });
+    }
+>>>>>>> 78b76253c8ce5873016cf837373af5e30ac80c86
 </script>

+ 0 - 450
view/sys/file_manager/uploadimg copy.html

@@ -1,450 +0,0 @@
-<!-- <div class="cl pd-5 bg-1 bk-gray">
-        <a href="{:url('/file_manager/selectpicture')}" class="btn btn-default radius sethumb">
-            <i class="Hui-iconfont">&#xe600;</i> 站内选择 </a>&nbsp;&nbsp;
-        <a href="javascript:void(0);" class="btn btn-primary radius sethumb">
-            <i class="Hui-iconfont">&#xe600;</i> 本地上传 </a>&nbsp;&nbsp;
-        <a href="{:url('/file_manager/onlinepicture')}" class="btn btn-default radius sethumb">
-            <i class="Hui-iconfont">&#xe600;</i> 网络图片 </a>&nbsp;&nbsp;
-    </div> -->
-<!-- 本地上传 -->
-<style>
-    #online {
-        width: 100%;
-        height: 224px;
-        padding: 10px 0 0 0;
-    }
-
-    #online #imageList {
-        width: 100%;
-        height: 100%;
-        overflow-x: hidden;
-        overflow-y: auto;
-        position: relative;
-        margin-left: 20px;
-    }
-
-    #online ul {
-        display: block;
-        list-style: none;
-        margin: 0;
-        padding: 0;
-    }
-
-    #online li {
-        float: left;
-        display: block;
-        list-style: none;
-        padding: 0;
-        width: 113px;
-        height: 113px;
-        margin: 0 0 9px 9px;
-        background-color: #eee;
-        overflow: hidden;
-        cursor: pointer;
-        position: relative;
-    }
-
-    #online li img {
-        cursor: pointer;
-    }
-
-    #online li .icon {
-        cursor: pointer;
-        width: 113px;
-        height: 113px;
-        position: absolute;
-        top: 0;
-        left: 0;
-        z-index: 2;
-        border: 0;
-        background-repeat: no-repeat;
-    }
-
-    #online li .icon:hover {
-        width: 107px;
-        height: 107px;
-        border: 3px solid #1094fa;
-    }
-
-    #online li.selected .icon {
-        background-image: url(/static/images/success.png);
-        background-image: url(images/success.gif)\9;
-        background-position: 75px 75px;
-    }
-
-    #online li.clearFloat {
-        float: none;
-        clear: both;
-        display: block;
-        width: 0;
-        height: 0;
-        margin: 0;
-        padding: 0;
-    }
-</style>
-
-<div id="tab-img" class="HuiTab">
-    <div class="tabBar clearfix">
-        <span>本地上传</span>
-        <span>网络文件上传</span>
-        <a onclick="onlinepicture(1)"><span>服务器图片选择</span></a>
-    </div>
-    <div class="tabCon">
-        <div class="step1 active" style="margin-left:30px;">
-            <form id="form-uploadimg" method="post" action="" enctype="multipart/form-data">
-                <div class="row cl" style="margin-top:20px;">
-                    <label class="form-label col-xs-2 col-sm-2"><span class="c-red">*</span>图片要求: </label>
-                    <div class="formControls col-xs-8 col-sm-8">
-                        格式 jpg,png,gif,jpeg,webp; 大小不超过4M.
-                    </div>
-                    <div class="col-3"> </div>
-                </div>
-                <div class="row cl" style="margin-top:20px;">
-                    <label class="form-label col-xs-2 col-sm-2">
-                        <span class="c-red">*</span>本地上传:</label>
-                    <div class="formControls col-xs-4 col-sm-4">
-                        <input type="file" class="input-text" name="upload_file" id="upload_file">
-                    </div>
-                    <div class="col-3"> </div>
-                </div>
-                <div class="row cl" style="margin-top:20px;">
-                    <input type="hidden" name="img_id" value={$img_id}>
-                    <div class="formControls col-xs-12 col-sm-8">
-                        <div class="skin-minimal">
-                            <div class="check-box">
-                                <input type="checkbox" name="overwrite" value="{$overwrite}" {$overwrite ? 'checked'
-                                    : "" }>
-                                <label for="overwrite">覆盖原图</label>
-                            </div>
-                            <div class="check-box">
-                                <input type="checkbox" name="water" value="{$water}" {$water ? 'checked' : "" }>
-                                <label for="water">水印</label>
-                            </div>
-                            <div class="check-box">
-                                <input type="checkbox" name="thumb" value="{$thumb}" {$thumb ? 'checked' : "" }>
-                                <label for="thumb-1">缩略图</label>
-                                <input type="text" class="input-text" name="width" value={$width}
-                                    style="width: 80px;">缩略图宽度
-                                <input type="text" class="input-text" name="height" value={$height}
-                                    style="width: 80px;">缩略图高度
-                            </div>
-                        </div>
-                    </div>
-                </div>
-                <div class="row cl" style="margin-top:30px;margin-left:30px;">
-                    <div class="col-xs-6 col-sm-5 col-xs-offset-2 col-sm-offset-2">
-                        <input class="btn btn-primary radius" type="button" value="&nbsp;确&nbsp;定&nbsp;"
-                            onCLick="uploadImg()">
-                        <input class="btn btn-default radius" type="button" value="&nbsp;取&nbsp;消&nbsp;"
-                            onClick="layer_close();">
-                    </div>
-                </div>
-            </form>
-        </div>
-        <!-- 本地上传end -->
-    </div>
-    <div class="tabCon">
-        <form id="form-uploadurlimg" method="post" action="" enctype="multipart/form-data">
-            <div class="row cl" style="margin-top:20px;">
-                <label class="form-label col-xs-2 col-sm-2"><span class="c-red">*</span>图片要求: </label>
-                <div class="formControls col-xs-8 col-sm-8">
-                    格式 jpg,png,gif,jpeg,webp; 大小不超过4M.
-                </div>
-                <div class="col-3"> </div>
-            </div>
-            <div class="row cl" style="margin-top:20px;">
-                <label class="form-label col-xs-2 col-sm-2">
-                    <span class="c-red">*</span>图片地址:</label>
-                <div class="formControls col-xs-4 col-sm-4">
-                    <input type="text" class="input-text" name="url_file" id="url_file">
-                </div>
-                <div class="col-3"> </div>
-            </div>
-            <div class="row cl" style="margin-top:20px;">
-                <input type="hidden" name="img_id" value={$img_id}>
-                <div class="formControls col-xs-12 col-sm-8">
-                    <div class="skin-minimal">
-                        <div class="check-box">
-                            <input type="checkbox" name="overwrite" value="{$overwrite}" {$overwrite ? 'checked' : "" }>
-                            <label for="overwrite">覆盖原图</label>
-                        </div>
-                        <div class="check-box">
-                            <input type="checkbox" name="water" value="{$water}" {$water ? 'checked' : "" }>
-                            <label for="water">水印</label>
-                        </div>
-                        <div class="check-box">
-                            <input type="checkbox" name="thumb" value="{$thumb}" {$thumb ? 'checked' : "" }>
-                            <label for="thumb-1">缩略图</label>
-                            <input type="text" class="input-text" name="width" value={$width} style="width: 80px;">缩略图宽度
-                            <input type="text" class="input-text" name="height" value={$height}
-                                style="width: 80px;">缩略图高度
-                        </div>
-                    </div>
-                </div>
-            </div>
-            <div class="row cl" style="margin-top:30px;margin-left:30px;">
-                <div class="col-xs-6 col-sm-5 col-xs-offset-2 col-sm-offset-2">
-                    <input class="btn btn-primary radius" type="button" value="&nbsp;确&nbsp;定&nbsp;"
-                        onCLick="uploadUrlImg()">
-                    <input class="btn btn-default radius" type="button" value="&nbsp;取&nbsp;消&nbsp;"
-                        onClick="layer_close();">
-                </div>
-            </div>
-        </form>
-    </div>
-    <!-- 在线图片 -->
-    <div class="tabCon">
-        <form id="form-uploadonlineimg" method="post" action="" enctype="multipart/form-data">
-            <div class="row cl" style="margin-top:20px;" id="online">
-                <div id="imageList">
-                    <ul class="list">
-                        <!-- <li>
-                            <img width="170" height="113" src="/storage/20220223/d5cc488e71c58bb072debe45ed06c6ad.jpg?noCache=1634567323"
-                             _src="/storage/20220223/d5cc488e71c58bb072debe45ed06c6ad.jpg">
-                            <span class="icon"></span>
-                        </li>
-                         -->
-                        <li class="clearFloat"></li>
-                    </ul>
-                </div>
-            </div>
-            <div class="row cl" style="margin-top:20px;">
-                <label class="form-label col-xs-2 col-sm-2">
-                    <span class="c-red">*</span>图片地址:</label>
-                <div class="formControls col-xs-8 col-sm-8">
-                    <input type="text" class="input-text" name="online_file" id="online_file">
-                </div>
-                <div class="col-3"> </div>
-            </div>
-            <div class="row cl" style="margin-top:20px;">
-                <input type="hidden" name="img_id" value={$img_id}>
-                <div class="formControls col-xs-12 col-sm-8">
-                    <div class="skin-minimal">
-                        <div class="check-box">
-                            <input type="checkbox" name="thumb" value="{$thumb}" {$thumb ? 'checked' : "" }>
-                            <label for="thumb-1">缩略图</label>
-                            <input type="text" class="input-text" name="width" value={$width} style="width: 80px;">缩略图宽度
-                            <input type="text" class="input-text" name="height" value={$height}
-                                style="width: 80px;">缩略图高度
-                            <input type="checkbox" name="overwrite" value="{$overwrite}" {$overwrite ? 'checked' : "" }>
-                            <label for="overwrite">覆盖原图</label>
-                        </div>
-                    </div>
-                </div>
-            </div>
-            <div class="row cl" style="margin-top:30px;margin-left:30px;">
-                <div class="col-xs-6 col-sm-5 col-xs-offset-2 col-sm-offset-2">
-                    <input class="btn btn-primary radius" type="button" value="&nbsp;确&nbsp;定&nbsp;"
-                        onCLick="uploadOnlineImg()">
-                    <input class="btn btn-default radius" type="button" value="&nbsp;取&nbsp;消&nbsp;"
-                        onClick="layer_close();">
-                </div>
-            </div>
-        </form>
-    </div>
-</div>
-
-<!--请在下方写此页面业务相关的脚本-->
-<script type="text/javascript">
-    jQuery.Huitab = function (tabBar, tabCon, class_name, tabEvent, i) {
-        var $tab_menu = $(tabBar);
-        // 初始化操作
-        $tab_menu.removeClass(class_name);
-        $(tabBar).eq(i).addClass(class_name);
-        $(tabCon).hide();
-        $(tabCon).eq(i).show();
-
-        $tab_menu.bind(tabEvent, function () {
-            $tab_menu.removeClass(class_name);
-            $(this).addClass(class_name);
-            var index = $tab_menu.index(this);
-            $(tabCon).hide();
-            $(tabCon).eq(index).show()
-        })
-    }
-
-    $(function () {
-        $.Huitab("#tab-img .tabBar span", "#tab-img .tabCon", "current", "click", "0");
-        $(document).on("click", "#online li", function(){
-            $("#online li").removeClass('selected');
-
-            $(this).addClass('selected');
-
-            img = $(this).children('img').attr('_src');
-
-            $("#online_file").val(img);
-        })
-    });
-
-    function onlinepicture(page) {
-        var data = { "page": page };
-        $.ajax({
-            url: '{:url("file_manager/onlineimg")}',
-            type: 'GET',
-            async: true,
-            cache: false,
-            data: 'page=' + page,
-            processData: false,
-            contentType: false,
-            dataType: "json",
-            success: function (res) {
-                if (res.code == 0) {
-                    html_str = "";
-                    res.list.forEach(element => {
-                        html_str += '<li><img width="170" height="113" src="' + element.url + '?noCache=' + element.mtime + '"';
-                        html_str += '_src="' + element.url + '">';
-                        html_str += '<span class="icon"></span></li>';
-                    });
-                    $('ul.list').prepend(html_str);
-                }
-            }
-        });
-    }
-
-    //step1本地上传图片
-    function uploadImg() {
-        if ($("#upload_file").val() == '') {
-            layer.msg("请选择要上传的文件", {
-                icon: 6,
-                time: 1000
-            });
-            return false;
-        } else {
-            var formData = new FormData($("#form-uploadimg")[0]);
-            $.ajax({
-                url: '{:url("file_manager/uploadimg")}',
-                type: 'POST',
-                async: true,
-                cache: false,
-                data: formData,
-                processData: false,
-                contentType: false,
-                dataType: "json",
-                beforeSend: function () {
-                    // loadIndex = layer.load();
-                },
-                success: function (res) {
-                    if (res.code == 0) {
-                        // layer.close(loadIndex);
-                        console.log(res);
-                        var img = res.picture_url + res.picname;
-                        window.parent.$("#" + res.img_id).val(img);
-
-                        if (res.thumbname) {
-                            img = res.picture_url + res.thumbname;
-                            window.parent.$("#thumb").val(img);
-                        }
-
-                        window.parent.$("#view-" + res.img_id).attr('src', img);
-                        layer_close();
-                    } else {
-                        // layer.close(loadIndex);
-                        layer.msg(res.msg, {
-                            icon: 5,
-                            time: 1000
-                        });
-                        return false;
-                    }
-                }
-            });
-        }
-    }
-
-    // 网络图片
-    function uploadUrlImg() {
-        if ($("#url_file").val() == '') {
-            layer.msg("文件地址不可以为空", {
-                icon: 6,
-                time: 1000
-            });
-            return false;
-        } else {
-            var formData = new FormData($("#form-uploadurlimg")[0]);
-            $.ajax({
-                url: '{:url("file_manager/uploadurlimg")}',
-                type: 'POST',
-                async: true,
-                cache: false,
-                data: formData,
-                processData: false,
-                contentType: false,
-                dataType: "json",
-                beforeSend: function () {
-                    // loadIndex = layer.load();
-                },
-                success: function (res) {
-                    if (res.code == 0) {
-                        console.log(res);
-                        // layer.close(loadIndex);
-                        var img = res.picture_url + res.picname;
-                        window.parent.$("#" + res.img_id).val(img);
-
-                        if (res.thumbname) {
-                            img = res.picture_url + res.thumbname;
-                            window.parent.$("#thumb").val(img);
-                        }
-
-                        window.parent.$("#view-" + res.img_id).attr('src', img);
-                        layer_close();
-                    } else {
-                        // layer.close(loadIndex);
-                        layer.msg(res.msg, {
-                            icon: 5,
-                            time: 1000
-                        });
-                        return false;
-                    }
-                }
-            });
-        }
-    }
-
-    function uploadOnlineImg() {
-        if ($("#online_file").val() == '') {
-            layer.msg("文件地址不可以为空", {
-                icon: 6,
-                time: 1000
-            });
-            return false;
-        } else {
-            var formData = new FormData($("#form-uploadonlineimg")[0]);
-            $.ajax({
-                url: '{:url("file_manager/uploadonlineimg")}',
-                type: 'POST',
-                async: true,
-                cache: false,
-                data: formData,
-                processData: false,
-                contentType: false,
-                dataType: "json",
-                beforeSend: function () {
-                    // loadIndex = layer.load();
-                },
-                success: function (res) {
-                    if (res.code == 0) {
-                        // console.log(res);
-                        // layer.close(loadIndex);
-                        var img = res.picname;
-                        window.parent.$("#" + res.img_id).val(img);
-
-                        if (res.thumbname) {
-                            img = res.thumbname;
-                            window.parent.$("#thumb").val(img);
-                        }
-
-                        window.parent.$("#view-" + res.img_id).attr('src', img);
-                        layer_close();
-                    } else {
-                        // layer.close(loadIndex);
-                        layer.msg(res.msg, {
-                            icon: 5,
-                            time: 1000
-                        });
-                        return false;
-                    }
-                }
-            });
-        }
-    }
-</script>
-<!--请在上方写此页面业务相关的脚本-->

+ 348 - 0
view/sys/file_manager/uploadimg.html

@@ -1,3 +1,4 @@
+<<<<<<< HEAD
 <!-- <div class="cl pd-5 bg-1 bk-gray">
         <a href="{:url('/file_manager/selectpicture')}" class="btn btn-default radius sethumb">
             <i class="Hui-iconfont">&#xe600;</i> 站内选择 </a>&nbsp;&nbsp;
@@ -356,3 +357,350 @@
     }
 </script>
 <!--请在上方写此页面业务相关的脚本-->
+=======
+<div id="tab-img" class="HuiTab">
+    <div class="tabBar clearfix">
+        <span>本地上传</span>
+        <span>网络文件上传</span>
+        <span>服务器图片选择</span>
+        <input type="hidden" name="layer" id="layer" value="{$layer}">
+        <input type="hidden" name="infoid" value={$infoid}>
+        <input type="hidden" name="cjid" value={$cjid}>
+    </div>
+    <!-- 本地上传 -->
+    <div class="tabCon">
+        <div class="step1 active" style="margin-left:30px;">
+            <form id="form-uploadimg" method="post" action="" enctype="multipart/form-data">
+                <div class="row cl" style="margin-top:20px;">
+                    <label class="form-label col-xs-2 col-sm-2"><span class="c-red">*</span>图片要求: </label>
+                    <div class="formControls col-xs-8 col-sm-8">
+                        格式 jpg,png,gif,jpeg,webp; 大小不超过4M.
+                    </div>
+                    <div class="col-3"> </div>
+                </div>
+                <div class="row cl" style="margin-top:20px;">
+                    <label class="form-label col-xs-2 col-sm-2">
+                        <span class="c-red">*</span>本地上传:</label>
+                    <div class="formControls  col-xs-8 col-sm-8">
+                        <input type="file" class="input-text" name="upload_file" id="upload_file">
+                    </div>
+                    <div class="col-3"> </div>
+                </div>
+                <div class="row cl" style="margin-top:20px;">
+                    <input type="hidden" name="img_id" value={$img_id}>
+                    <input type="hidden" name="infoid" value={$infoid}>
+                    <input type="hidden" name="cjid" value={$cjid}>
+                    <div class="formControls col-sm-12">
+                        <div class="skin-minimal">
+                            <div class="check-box">
+                                <input type="checkbox" name="thumb" value="true" {$thumb ? 'checked' : "" }>
+                                <label for="thumb-1">缩略图</label>
+                                <input type="text" class="input-text" name="width" value={$width}
+                                    style="width: 80px;">缩略图宽度
+                                <input type="text" class="input-text" name="height" value={$height}
+                                    style="width: 80px;">缩略图高度
+                                <input type="checkbox" name="original" value="true" {$original ? 'checked' : "" } style="margin-left: 20px;">
+                                <label for="overwrite">保留原图</label>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div class="row cl" style="margin-top:30px;margin-left:30px;">
+                    <div class="col-xs-6 col-sm-5 col-xs-offset-2 col-sm-offset-2">
+                        <input class="btn btn-primary radius" type="button" value="&nbsp;确&nbsp;定&nbsp;"
+                            onCLick="uploadLocalImg();">
+                        <input class="btn btn-default radius" type="button" value="&nbsp;取&nbsp;消&nbsp;"
+                            onClick="layer_close();">
+                    </div>
+                </div>
+            </form>
+        </div>
+        <!-- 本地上传end -->
+    </div>
+    <!-- 网络图片 -->
+    <div class="tabCon">
+        <form id="form-uploadurlimg" method="post" action="" enctype="multipart/form-data">
+            <div class="row cl" style="margin-top:20px;">
+                <label class="form-label col-xs-2 col-sm-2"><span class="c-red">*</span>图片要求: </label>
+                <div class="formControls col-xs-8 col-sm-8">
+                    格式 jpg,png,gif,jpeg,webp; 大小不超过4M.
+                </div>
+                <div class="col-3"> </div>
+            </div>
+            <div class="row cl" style="margin-top:20px;">
+                <label class="form-label col-xs-2 col-sm-2">
+                    <span class="c-red">*</span>图片地址:</label>
+                <div class="formControls col-xs-8 col-sm-8">
+                    <input type="text" class="input-text" name="url_file" id="url_file">
+                </div>
+                <div class="col-3"> </div>
+            </div>
+            <div class="row cl" style="margin-top:20px;">
+                <input type="hidden" name="img_id" value={$img_id}>
+                <div class="formControls col-xs-12 col-sm-12">
+                    <div class="skin-minimal">
+                        <div class="check-box">
+                            <input type="checkbox" name="thumb" value="{$thumb}" {$thumb ? 'checked' : "" }>
+                            <label for="thumb-1">缩略图</label>
+                            <input type="text" class="input-text" name="width" value={$width} style="width: 80px;">缩略图宽度
+                            <input type="text" class="input-text" name="height" value={$height}
+                                style="width: 80px;">缩略图高度
+                            <input type="checkbox" name="original" value="{$original}" {$original ? 'checked' : "" } style="margin-left: 20px;">
+                            <label for="overwrite">保留原图</label>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <div class="row cl" style="margin-top:30px;margin-left:30px;">
+                <div class="col-xs-6 col-sm-5 col-xs-offset-2 col-sm-offset-2">
+                    <input class="btn btn-primary radius" type="button" value="&nbsp;确&nbsp;定&nbsp;"
+                        onCLick="uploadUrlImg()">
+                    <input class="btn btn-default radius" type="button" value="&nbsp;取&nbsp;消&nbsp;"
+                        onClick="layer_close();">
+                </div>
+            </div>
+        </form>
+    </div>
+    <!-- 在线图片 -->
+    <style>
+        a.active-btn {
+            color: #fff;
+            background-color: #3bb4f2;
+            border-color: #3bb4f2;
+        }
+    </style>
+    <div class="tabCon">
+        <a class="btn radius active-btn" id="database_picture"><i class="Hui-iconfont Hui-iconfont-jifen"></i>数据库模式</a>
+        <a class="btn radius" id="directory_picture"><i class="Hui-iconfont Hui-iconfont-pages"></i> 目录模式</a>
+        <div class="database online-picture">
+            {include file="file_manager/database_picture" /}
+        </div>
+        <div class="directory online-picture" style="display: none;">
+            {include file="file_manager/directory_picture" /}
+        </div>
+        <form id="form-uploadonlineimg" method="post" action="" enctype="multipart/form-data">
+            <div class="row cl" style="margin-top:20px;">
+                <label class="form-label col-xs-2 col-sm-2">
+                    <span class="c-red">*</span>图片地址:</label>
+                <div class="formControls col-xs-8 col-sm-8">
+                    <input type="hidden" name="img_id" value={$img_id}>
+                    <input type="text" class="input-text" name="online_file" id="online_file">
+                </div>
+                <div class="col-3"> </div>
+            </div>
+            <div class="row cl" style="margin-top:30px;margin-left:30px;">
+                <div class="col-xs-6 col-sm-5 col-xs-offset-2 col-sm-offset-2">
+                    <input class="btn btn-primary radius" type="button" value="&nbsp;确&nbsp;定&nbsp;"
+                        onCLick="uploadOnlineImg()">
+                    <input class="btn btn-default radius" type="button" value="&nbsp;取&nbsp;消&nbsp;"
+                        onClick="layer_close();">
+                </div>
+            </div>
+        </form>
+    </div>
+</div>
+
+<!--请在下方写此页面业务相关的脚本-->
+<script type="text/javascript">
+    jQuery.Huitab = function (tabBar, tabCon, class_name, tabEvent, i) {
+        var $tab_menu = $(tabBar);
+        // 初始化操作
+        $tab_menu.removeClass(class_name);
+        $(tabBar).eq(i).addClass(class_name);
+        $(tabCon).hide();
+        $(tabCon).eq(i).show();
+
+        $tab_menu.bind(tabEvent, function () {
+            $tab_menu.removeClass(class_name);
+            $(this).addClass(class_name);
+            var index = $tab_menu.index(this);
+            $(tabCon).hide();
+            $(tabCon).eq(index).show()
+        })
+    }
+
+    $(function () {
+        $.Huitab("#tab-img .tabBar span", "#tab-img .tabCon", "current", "click", "0");
+
+        $("#database_picture").click(function () {
+            $(".online-picture").css('display', 'none');
+            $(".database").css('display', 'block');
+
+            $(this).addClass('active-btn');
+            $('#directory_picture').removeClass('active-btn');
+        });
+
+        $("#directory_picture").click(function () {
+            $(".online-picture").css('display', 'none');
+            $(".directory").css('display', 'block');
+
+            $(this).addClass('active-btn');
+            $('#database_picture').removeClass('active-btn');
+        });
+    });
+
+    // 本地上传图片
+    function uploadLocalImg() {
+        var layer = $("#layer").val();
+        if ($("#upload_file").val() == '') {
+            layer.msg("请选择要上传的文件", {
+                icon: 6,
+                time: 1000
+            });
+            return false;
+        } else {
+            var formData = new FormData($("#form-uploadimg")[0]);
+            $.ajax({
+                url: '{:url("file_manager/uploadLocalImg")}',
+                type: 'POST',
+                async: true,
+                cache: false,
+                data: formData,
+                processData: false,
+                contentType: false,
+                dataType: "json",
+                beforeSend: function () {
+                    // loadIndex = layer.load();
+                },
+                success: function (res) {
+                    if (res.code == 0) {
+                        // layer.close(loadIndex);
+                        if (layer == true) {
+                            var img = res.thumb ? res.thumb : res.picname;
+
+                            window.parent.$("#" + res.img_id).val(img);
+
+                            window.parent.$("#view-" + res.img_id).attr('src', img);
+
+                            layer_close();
+                        } else {
+                            layer.msg('上传成功', {
+                                icon: 1,
+                                time: 1000
+                            }, () => {
+                                window.location.reload();
+                            });
+                        }
+                    } else {
+                        // layer.close(loadIndex);
+                        layer.msg(res.msg, {
+                            icon: 5,
+                            time: 1000
+                        });
+                        return false;
+                    }
+                }
+            });
+        }
+    }
+
+    // 网络图片
+    function uploadUrlImg() {
+        var layer = $("#layer").val();
+        if ($("#url_file").val() == '') {
+            layer.msg("文件地址不可以为空", {
+                icon: 6,
+                time: 1000
+            });
+            return false;
+        } else {
+            var formData = new FormData($("#form-uploadurlimg")[0]);
+            $.ajax({
+                url: '{:url("file_manager/uploadUrlImg")}',
+                type: 'POST',
+                async: true,
+                cache: false,
+                data: formData,
+                processData: false,
+                contentType: false,
+                dataType: "json",
+                beforeSend: function () {
+                    // loadIndex = layer.load();
+                },
+                success: function (res) {
+                    if (res.code == 0) {
+                        console.log(layer);
+                        // layer.close(loadIndex);
+                        if (layer == true) {
+                            var img = res.picname;
+                            window.parent.$("#" + res.img_id).val(img);
+
+                            if (res.thumbname) {
+                                img = res.thumbname;
+                                window.parent.$("#thumb").val(img);
+                            }
+
+                            window.parent.$("#view-" + res.img_id).attr('src', img);
+                            layer_close();
+                        } else {
+                            window.location.reload();
+                        }
+                    } else {
+                        // layer.close(loadIndex);
+                        layer.msg(res.msg, {
+                            icon: 5,
+                            time: 1000
+                        });
+                        return false;
+                    }
+                }
+            });
+        }
+    }
+
+    function uploadOnlineImg() {
+        var layer = $("#layer").val();
+        if ($("#online_file").val() == '') {
+            layer.msg("文件地址不可以为空", {
+                icon: 6,
+                time: 1000
+            });
+            return false;
+        } else {
+            var formData = new FormData($("#form-uploadonlineimg")[0]);
+            $.ajax({
+                url: '{:url("file_manager/uploadOnlineImg")}',
+                type: 'POST',
+                async: true,
+                cache: false,
+                data: formData,
+                processData: false,
+                contentType: false,
+                dataType: "json",
+                beforeSend: function () {
+                    // loadIndex = layer.load();
+                },
+                success: function (res) {
+                    // layer.close(loadIndex);
+                    if (res.code == 0) {
+                        if (layer == true) {
+                            var img = res.picname;
+                            window.parent.$("#" + res.img_id).val(img);
+                            if (res.thumbname) {
+                                img = res.thumbname;
+                                window.parent.$("#thumb").val(img);
+                            }
+                            window.parent.$("#view-" + res.img_id).attr('src', img);
+                            layer_close();
+                        } else {
+                            layer.msg('上传成功', {
+                                icon: 1,
+                                time: 1000
+                            }, () => {
+                                window.location.reload();
+                            });
+                        }
+                    } else {
+                        layer.msg(res.msg, {
+                            icon: 5,
+                            time: 1000
+                        });
+                        return false;
+                    }
+                }
+            });
+        }
+    }
+</script>
+<!--请在上方写此页面业务相关的脚本-->
+>>>>>>> 78b76253c8ce5873016cf837373af5e30ac80c86

Some files were not shown because too many files changed in this diff