diff --git a/application/api/controller/Ueditor.php b/application/api/controller/Ueditor.php index 13d89f108..225438b54 100755 --- a/application/api/controller/Ueditor.php +++ b/application/api/controller/Ueditor.php @@ -123,53 +123,15 @@ class Ueditor extends Common */ private function DeleteFile() { - $path = input('path'); - if(!empty($path)) + $ret = ResourcesService::AttachmentDelete(input()); + if($ret['code'] == 0) { - // 附件删除前处理钩子 - $hook_name = 'plugins_controller_attachment_delete_handle_begin'; - Hook::listen($hook_name, [ - 'hook_name' => $hook_name, - 'is_backend' => true, - 'path' => &$path, - ]); - - $path = (__MY_ROOT_PUBLIC__ == '/') ? substr(ROOT_PATH, 0, -1).$path : str_replace(__MY_ROOT_PUBLIC__, ROOT_PATH, $path); - if(file_exists($path)) - { - if(is_writable($path)) - { - if(unlink($path)) - { - // 附件删除成功后处理钩子 - $hook_name = 'plugins_controller_attachment_delete_handle_end'; - Hook::listen($hook_name, [ - 'hook_name' => $hook_name, - 'is_backend' => true, - 'path' => $path, - ]); - - $this->current_result = json_encode(array( - 'state'=> 'SUCCESS' - )); - } else { - $this->current_result = json_encode(array( - 'state'=> '删除成功' - )); - } - } else { - $this->current_result = json_encode(array( - 'state'=> '没有删除权限' - )); - } - } else { - $this->current_result = json_encode(array( - 'state'=> '文件不存在' - )); - } + $this->current_result = json_encode(array( + 'state'=> 'SUCCESS' + )); } else { $this->current_result = json_encode(array( - 'state'=> '删除文件路径不能为空' + 'state'=> $ret['msg'] )); } } @@ -204,7 +166,7 @@ class Ueditor extends Common "oriName" => "scrawl.png" ); $field_name = $this->current_config['scrawlFieldName']; - $attachment_type = "base64"; + $attachment_type = "scrawl"; break; case 'uploadvideo': @@ -247,6 +209,7 @@ class Ueditor extends Common $data = $up->getFileInfo(); if(isset($data['state']) && $data['state'] == 'SUCCESS') { + $data['type'] = $attachment_type; $ret = ResourcesService::AttachmentAdd($data); if($ret['code'] == 0) { @@ -298,154 +261,35 @@ class Ueditor extends Common $start = isset($_GET['start']) ? htmlspecialchars($_GET['start']) : 0; $end = $start + $size; - /* 获取文件列表 */ + // 参数 + $params = [ + 'm' => $start, + 'n' => $size, + 'where' => [ + 'type' => substr($this->current_action, 4), + 'path_type' => input('path_type', 'other'), + ], + ]; + + // 数据初始化 $data = array( - "state" => "no match file", - "list" => array(), - "start" => $start, - "total" => 0, + 'state' => "没有相关数据", + 'list' => [], + 'start' => $start, + 'total' => ResourcesService::AttachmentTotal($params['where']), ); - // 是否从磁盘获取数据 0否, 1是 - $is_disk_get = 1; - - // 附件列表获取处理钩子 - $hook_name = 'plugins_controller_attachment_get_list_handle'; - Hook::listen($hook_name, [ - 'hook_name' => $hook_name, - 'is_backend' => true, - 'is_disk_get' => &$is_disk_get, - 'data' => &$data, - ]); - - // 是否从磁盘获取数据 - if($is_disk_get == 1) - { - $path = GetDocumentRoot() . (substr($path, 0, 1) == "/" ? "":"/") . $path; - $this->GetFilesList($path, $allow_files, $size, $start, $end, $data); - } + // 获取数据 + $ret = ResourcesService::AttachmentList($params); + if(!empty($ret['data'])) + { + $data['state'] = 'SUCCESS'; + $data['list'] = $ret['data']; + } - /* 返回数据 */ $this->current_result = json_encode($data); } - /** - * [GetFilesList 获取目录下的指定类型的文件] - * @author Devil - * @blog http://gong.gg/ - * @version 0.0.1 - * @datetime 2017-01-17T23:24:59+0800 - * @param [string] $path [路径地址] - * @param [string] $allow_files [允许的文件] - * @param [int] $size [条数] - * @param [int] $start [起始] - * @param [int] $end [结束标记] - * @param [array] $data [返回数据] - * @return [array] [数据] - */ - private function GetFilesList($path, $allow_files, $size, $start, $end, &$data) - { - // 从磁盘获取文件 - $files = $this->GetDirFilesList($path, $allow_files, $files); - - // 倒序 - //$files = $this->ArrayQuickSort($files); - - if(is_array($files) && count($files) > 0) - { - /* 获取指定范围的列表 */ - $len = count($files); - $list = []; - for ($i = min($end, $len) - 1; $i < $len && $i >= 0 && $i >= $start; $i--) - { - $list[] = $files[$i]; - } - - /* 返回数据 */ - $data = array( - "state" => "SUCCESS", - "list" => $list, - "start" => $start, - "total" => count($files) - ); - } - } - - /** - * 遍历获取目录下的指定类型的文件 - * @author Devil - * @blog http://gong.gg/ - * @version 0.0.1 - * @datetime 2017-01-17T23:24:59+0800 - * @param [string] $path [路径地址] - * @param [string] $allow_files [允许的文件] - * @param [array] &$files [数据] - * @return [array] [数据] - */ - private function GetDirFilesList($path, $allow_files, &$files = array()) - { - if(!is_dir($path)) return null; - if(substr($path, strlen($path) - 1) != '/') $path .= '/'; - $handle = opendir($path); - $document_root = GetDocumentRoot(); - while(false !== ($file = readdir($handle))) - { - if($file != '.' && $file != '..') - { - $path2 = $path . $file; - if(is_dir($path2)) - { - $this->GetDirFilesList($path2, $allow_files, $files); - } else { - if(preg_match("/\.(".$allow_files.")$/i", $file)) - { - $files[] = array( - 'url'=> substr($path2, strlen($document_root)), - 'mtime'=> filemtime($path2) - ); - } - } - } - } - return $files; - } - - /** - * 文件快速排序 - * @author Devil - * @blog http://gong.gg/ - * @version 1.0.0 - * @date 2018-12-25 - * @desc description - * @param [array] $data [需要排序的数据(选择一个基准元素,将待排序分成小和打两罐部分,以此类推递归的排序划分两罐部分)] - * @return [array] [排序好的数据] - */ - private function ArrayQuickSort($data) - { - if(!empty($data) && is_array($data)) - { - $len = count($data); - if($len <= 1) return $data; - - $base = $data[0]; - $left_array = array(); - $right_array = array(); - for($i=1; $i<$len; $i++) - { - if($base['mtime'] < $data[$i]['mtime']) - { - $left_array[] = $data[$i]; - } else { - $right_array[] = $data[$i]; - } - } - if(!empty($left_array)) $left_array = $this->ArrayQuickSort($left_array); - if(!empty($right_array)) $right_array = $this->ArrayQuickSort($right_array); - - return array_merge($left_array, array($base), $right_array); - } - } - /** * [ActionCrawler 抓取远程文件] * @author Devil @@ -469,30 +313,44 @@ class Ueditor extends Common foreach($source as $imgUrl) { $item = new \base\Uploader($imgUrl, $temp_config, "remote"); - $info = $item->getFileInfo(); + /** + * 得到上传文件所对应的各个参数,数组结构 + * array( + * "state" => "", //上传状态,上传成功时必须返回"SUCCESS" + * "url" => "", //返回的地址 + * "path" => "", //绝对地址 + * "title" => "", //新文件名 + * "original" => "", //原始文件名 + * "type" => "" //文件类型 + * "size" => "", //文件大小 + * "hash" => "", //sha256值 + * ) + */ + $data = $up->getFileInfo(); + if(isset($data['state']) && $data['state'] == 'SUCCESS') + { + $data['type'] = 'remote'; + $ret = ResourcesService::AttachmentAdd($data); + if($ret['code'] != 0) + { + $data['state'] = $ret['msg']; + } + } array_push($list, array( - "state" => $info["state"], - "url" => $info["url"], - "size" => $info["size"], - "title" => htmlspecialchars($info["title"]), - "original" => htmlspecialchars($info["original"]), + "state" => $data["state"], + "url" => $data["url"], + "size" => $data["size"], + "title" => htmlspecialchars($data["title"]), + "original" => htmlspecialchars($data["original"]), "source" => htmlspecialchars($imgUrl) )); } - // 附件抓取远程文件取结束处理钩子 - $hook_name = 'plugins_controller_attachment_crawler_handle_end'; - Hook::listen($hook_name, [ - 'hook_name' => $hook_name, - 'is_backend' => true, - 'list' => &$list, - ]); - /* 返回抓取数据 */ $this->current_result = json_encode(array( - 'state'=> count($list) ? 'SUCCESS':'ERROR', - 'list'=> $list - )); + 'state'=> count($list) ? 'SUCCESS':'ERROR', + 'list'=> $list + )); } } ?> \ No newline at end of file diff --git a/application/service/GoodsService.php b/application/service/GoodsService.php index 5c29428e9..6f7f019d8 100755 --- a/application/service/GoodsService.php +++ b/application/service/GoodsService.php @@ -401,7 +401,7 @@ class GoodsService $v['show_field_original_price_text'] = '原价'; $v['show_field_price_text'] = '销售价'; - // 商品处理前钩子 + // 商品处理后钩子 $hook_name = 'plugins_service_goods_handle_end'; $ret = Hook::listen($hook_name, [ 'hook_name' => $hook_name, diff --git a/application/service/ResourcesService.php b/application/service/ResourcesService.php index 9e99aed12..306e166a0 100755 --- a/application/service/ResourcesService.php +++ b/application/service/ResourcesService.php @@ -117,48 +117,214 @@ class ResourcesService */ public static function AttachmentAdd($params = []) { - if(!empty($params['title'])) + // 请求参数 + $p = [ + [ + 'checked_type' => 'empty', + 'key_name' => 'title', + 'error_msg' => '名称有误', + ], + [ + 'checked_type' => 'empty', + 'key_name' => 'original', + 'error_msg' => '原名有误', + ], + [ + 'checked_type' => 'empty', + 'key_name' => 'url', + 'error_msg' => '地址有误', + ], + [ + 'checked_type' => 'isset', + 'key_name' => 'size', + 'error_msg' => '文件大小有误', + ], + [ + 'checked_type' => 'isset', + 'key_name' => 'ext', + 'error_msg' => '扩展名有误', + ], + [ + 'checked_type' => 'empty', + 'key_name' => 'hash', + 'error_msg' => 'hash值有误', + ], + ]; + $ret = ParamsChecked($params, $p); + if($ret !== true) { - // 数据组装 - $data = [ - 'path_type' => input('path_type', 'other'), - 'original' => empty($params['original']) ? '' : mb_substr($params['original'], -160, null, 'utf-8'), - 'title' => $params['title'], - 'size' => $params['size'], - 'type' => $params['type'], - 'hash' => $params['hash'], - 'path' => self::AttachmentPathHandle($params['url']), - 'add_time' => time(), - ]; + return DataReturn($ret, -1); + } - // 附件上传前处理钩子 - $hook_name = 'plugins_service_attachment_handle_begin'; - Hook::listen($hook_name, [ + // 数据组装 + $data = [ + 'path_type' => input('path_type', 'other'), + 'original' => empty($params['original']) ? '' : mb_substr($params['original'], -160, null, 'utf-8'), + 'title' => $params['title'], + 'size' => $params['size'], + 'ext' => $params['ext'], + 'type' => isset($params['type']) ? $params['type'] : 'file', + 'hash' => $params['hash'], + 'url' => self::AttachmentPathHandle($params['url']), + 'add_time' => time(), + ]; + + // 附件上传前处理钩子 + $hook_name = 'plugins_service_attachment_handle_begin'; + Hook::listen($hook_name, [ + 'hook_name' => $hook_name, + 'is_backend' => true, + 'params' => $params, + 'data' => &$data, + ]); + + // 添加到数据库 + $attachment_id = Db::name('Attachment')->insertGetId($data); + if($attachment_id > 0) + { + // 附件上传后处理钩子 + $hook_name = 'plugins_service_attachment_handle_end'; + $ret = Hook::listen($hook_name, [ 'hook_name' => $hook_name, 'is_backend' => true, - 'params' => $params, + 'params' => &$params, 'data' => &$data, + 'attachment_id' => $attachment_id, ]); - // 添加到数据库 - $attachment_id = Db::name('Attachment')->insertGetId($data); - if($attachment_id > 0) + return DataReturn('添加成功', 0, $params); + } + + // 删除本地图片 + if(!empty($params['path'])) + { + \base\FileUtil::UnlinkFile($params['path']); + } + return DataReturn('添加失败', -100); + } + + /** + * 获取附件总数 + * @author Devil + * @blog http://gong.gg/ + * @version 1.0.0 + * @datetime 2019-06-25T22:44:52+0800 + * @param [array] $where [条件] + */ + public static function AttachmentTotal($where) + { + return (int) Db::name('Attachment')->where($where)->count(); + } + + /** + * 获取附件列表 + * @author Devil + * @blog http://gong.gg/ + * @version 1.0.0 + * @datetime 2019-06-25T22:44:52+0800 + * @param [array] $params [参数] + */ + public static function AttachmentList($params = []) + { + $m = max(0, isset($params['m']) ? intval($params['m']) : 0); + $n = max(1, isset($params['n']) ? intval($params['n']) : 20); + $data = Db::name('Attachment')->where($params['where'])->order('id desc')->limit($m, $n)->select(); + if(!empty($data)) + { + foreach($data as &$v) { - // 附件上传后处理钩子 - $hook_name = 'plugins_service_attachment_handle_end'; + // 附件列表处理前钩子 + $hook_name = 'plugins_service_attachment_list_handle_begin'; $ret = Hook::listen($hook_name, [ 'hook_name' => $hook_name, 'is_backend' => true, - 'params' => &$params, - 'data' => &$data, - 'attachment_id' => $attachment_id, + 'data' => &$v, ]); + if(isset($ret['code']) && $ret['code'] != 0) + { + return $ret; + } - return DataReturn('添加成功', 0, $params); + // 数据处理 + $v['url'] = self::AttachmentPathViewHandle($v['url']); + $v['add_time'] = date('Y-m-d H:i:s'); + + // 附件列表处理后钩子 + $hook_name = 'plugins_service_attachment_list_handle_end'; + $ret = Hook::listen($hook_name, [ + 'hook_name' => $hook_name, + 'is_backend' => true, + 'data' => &$v, + ]); + if(isset($ret['code']) && $ret['code'] != 0) + { + return $ret; + } } - return DataReturn('添加失败', 0); } - return DataReturn('附件不能为空', -1); + return DataReturn('操作成功', 0, $data); + } + + /** + * 附件删除 + * @author Devil + * @blog http://gong.gg/ + * @version 1.0.0 + * @datetime 2019-06-25T23:35:27+0800 + * @param [array] $params [输入参数] + */ + public static function AttachmentDelete($params = []) + { + // 请求参数 + $p = [ + [ + 'checked_type' => 'empty', + 'key_name' => 'id', + 'error_msg' => '操作id有误', + ] + ]; + $ret = ParamsChecked($params, $p); + if($ret !== true) + { + return DataReturn($ret, -1); + } + + // 获取数据 + $data = Db::name('Attachment')->find(intval($params['id'])); + if(empty($data)) + { + return DataReturn('数据不存在或已删除', -1); + } + + // 删除文件 + $path = substr(ROOT_PATH, 0, -1).$data['url']; + if(file_exists($path)) + { + if(is_writable($path)) + { + if(DB::name('Attachment')->where(['id'=>$data['id']])->delete()) + { + // 删除附件 + \base\FileUtil::UnlinkFile($path); + + // 附件删除成功后处理钩子 + $hook_name = 'plugins_service_attachment_delete_success'; + Hook::listen($hook_name, [ + 'hook_name' => $hook_name, + 'is_backend' => true, + 'data' => $data, + ]); + + return DataReturn('删除成功', 0); + } else { + return DataReturn('删除失败', -1); + } + } else { + return DataReturn('没有删除权限', -1); + } + } else { + return DataReturn('文件不存在', -1); + } } } ?> \ No newline at end of file diff --git a/extend/base/Uploader.php b/extend/base/Uploader.php index 4805bf746..5ecf0f788 100755 --- a/extend/base/Uploader.php +++ b/extend/base/Uploader.php @@ -62,7 +62,7 @@ class Uploader * @param array $config 配置项 * @param bool $base64 是否解析base64编码,可省略。若开启,则$fileField代表的是base64编码的字符串表单名 */ - public function __construct($fileField, $config, $type = "upload") + public function __construct($fileField, $config, $type = "file") { $this->fileField = $fileField; $this->config = $config; @@ -76,6 +76,7 @@ class Uploader // base64文件 case 'base64' : + case 'scrawl' : $this->uploadBase64(); break; @@ -492,9 +493,9 @@ class Uploader "path" => $this->filePath, "title" => $this->fileName, "original" => $this->oriName, - "type" => $this->fileType, + "ext" => $this->fileType, "size" => $this->fileSize, - "hash" => hash_file('sha256', $this->filePath, false), + "hash" => file_exists($this->filePath) ? hash_file('sha256', $this->filePath, false) : '', ); } } diff --git a/public/static/common/lib/ueditor/dialogs/attachment/attachment.css b/public/static/common/lib/ueditor/dialogs/attachment/attachment.css index cb43e4195..93112ab7b 100755 --- a/public/static/common/lib/ueditor/dialogs/attachment/attachment.css +++ b/public/static/common/lib/ueditor/dialogs/attachment/attachment.css @@ -716,4 +716,23 @@ i.file-preview.file-type-psd{ #online { height: 330px; } +} + +/** + * 原标题 + */ +#fileList .attachment-title { + position: absolute; + top: 0; + left: 0; + width: calc(100% - 23px); + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + text-indent: 5px; + text-align: left; + z-index: 3; + background: rgba(0, 0, 0, 0.3); + color: #fff; + padding: 2px 0; } \ No newline at end of file diff --git a/public/static/common/lib/ueditor/dialogs/attachment/attachment.js b/public/static/common/lib/ueditor/dialogs/attachment/attachment.js index 508e70263..e21a20f47 100755 --- a/public/static/common/lib/ueditor/dialogs/attachment/attachment.js +++ b/public/static/common/lib/ueditor/dialogs/attachment/attachment.js @@ -704,8 +704,15 @@ item.appendChild(preview); item.appendChild(icon); + // 原名功能 start + var original = document.createElement('p'); + original.setAttribute('class', 'attachment-title'); + original.innerHTML = list[i].original; + item.appendChild(original); + // 原名功能 end + // 文件添加删除功能 start - item.appendChild($("x").click(function() { + item.appendChild($("x").click(function() { var del = $(this); try{ window.event.cancelBubble = true; //停止冒泡 @@ -714,7 +721,7 @@ window.event.stopPropagation(); //阻止事件的传播 } finally { if(!confirm("确定要删除吗?")) return; - $.post(editor.getOpt("serverUrl") + "?action=deletefile", { "path": del.attr("url") }, function(responseText) { + $.post(editor.getOpt("serverUrl") + "?action=deletefile", { "id": del.attr("data-id") }, function(responseText) { json = utils.str2json(responseText); if (json.state == 'SUCCESS') del.parent().remove(); else alert(json.state); diff --git a/public/static/common/lib/ueditor/dialogs/image/image.css b/public/static/common/lib/ueditor/dialogs/image/image.css index 094b1ef44..7eb1ecba6 100755 --- a/public/static/common/lib/ueditor/dialogs/image/image.css +++ b/public/static/common/lib/ueditor/dialogs/image/image.css @@ -343,7 +343,7 @@ text-indent: 5px; text-align: left; z-index: 3; - background: rgba(0, 0, 0, 0.6); + background: rgba(0, 0, 0, 0.3); color: #fff; padding: 6px 0; } @@ -957,4 +957,23 @@ .tabbody .panel.focus { height: 315px; } +} + +/** + * 原标题 + */ +#imageList .attachment-title { + position: absolute; + top: 0; + left: 0; + width: calc(100% - 23px); + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + text-indent: 5px; + text-align: left; + z-index: 3; + background: rgba(0, 0, 0, 0.3); + color: #fff; + padding: 2px 0; } \ No newline at end of file diff --git a/public/static/common/lib/ueditor/dialogs/image/image.js b/public/static/common/lib/ueditor/dialogs/image/image.js index 8b18d8c7f..e018c874c 100755 --- a/public/static/common/lib/ueditor/dialogs/image/image.js +++ b/public/static/common/lib/ueditor/dialogs/image/image.js @@ -913,12 +913,19 @@ img.setAttribute('src', urlPrefix + list[i].url + (list[i].url.indexOf('?') == -1 ? '?noCache=':'&noCache=') + (+new Date()).toString(36) ); img.setAttribute('_src', urlPrefix + list[i].url); domUtils.addClass(icon, 'icon'); - + item.appendChild(img); item.appendChild(icon); + // 原名功能 start + var original = document.createElement('p'); + original.setAttribute('class', 'attachment-title'); + original.innerHTML = list[i].original; + item.appendChild(original); + // 原名功能 end + // 图片添加删除功能 start - item.appendChild($("x").click(function() { + item.appendChild($("x").click(function() { var del = $(this); try{ window.event.cancelBubble = true; //停止冒泡 @@ -927,7 +934,7 @@ window.event.stopPropagation(); //阻止事件的传播 } finally { if(!confirm("确定要删除吗?")) return; - $.post(editor.getOpt("serverUrl") + "?action=deletefile", { "path": del.attr("url") }, function(responseText) { + $.post(editor.getOpt("serverUrl") + "?action=deletefile", { "id": del.attr("data-id") }, function(responseText) { json = utils.str2json(responseText); if (json.state == 'SUCCESS') del.parent().remove(); else alert(json.state); diff --git a/public/static/common/lib/ueditor/dialogs/video/video.css b/public/static/common/lib/ueditor/dialogs/video/video.css index 8cd425f2a..c193129e8 100755 --- a/public/static/common/lib/ueditor/dialogs/video/video.css +++ b/public/static/common/lib/ueditor/dialogs/video/video.css @@ -778,4 +778,23 @@ i.file-preview.file-type-psd{ .tabbody .panel.focus { height: 300px; } +} + +/** + * 原标题 + */ +#videoList .attachment-title { + position: absolute; + top: 0; + left: 0; + width: calc(100% - 23px); + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + text-indent: 5px; + text-align: left; + z-index: 3; + background: rgba(0, 0, 0, 0.3); + color: #fff; + padding: 2px 0; } \ No newline at end of file diff --git a/public/static/common/lib/ueditor/dialogs/video/video.js b/public/static/common/lib/ueditor/dialogs/video/video.js index b230523a7..07e895359 100755 --- a/public/static/common/lib/ueditor/dialogs/video/video.js +++ b/public/static/common/lib/ueditor/dialogs/video/video.js @@ -252,8 +252,15 @@ item.appendChild(video); item.appendChild(icon); + // 原名功能 start + var original = document.createElement('p'); + original.setAttribute('class', 'attachment-title'); + original.innerHTML = list[i].original; + item.appendChild(original); + // 原名功能 end + // 视频添加删除功能 start - item.appendChild($("x").click(function() { + item.appendChild($("x").click(function() { var del = $(this); try{ window.event.cancelBubble = true; //停止冒泡 @@ -262,7 +269,7 @@ window.event.stopPropagation(); //阻止事件的传播 } finally { if(!confirm("确定要删除吗?")) return; - $.post(editor.getOpt("serverUrl") + "?action=deletefile", { "path": del.attr("url") }, function(responseText) { + $.post(editor.getOpt("serverUrl") + "?action=deletefile", { "id": del.attr("data-id") }, function(responseText) { json = utils.str2json(responseText); if (json.state == 'SUCCESS') del.parent().remove(); else alert(json.state);