SystemFile.php 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. <?php
  2. namespace app\adminapi\controller\v1\system;
  3. use app\adminapi\controller\AuthController;
  4. use app\models\system\SystemFile as SystemFileModel;
  5. use crmeb\services\FileService as FileClass;
  6. /**
  7. * 文件校验控制器
  8. * Class SystemFile
  9. * @package app\admin\controller\system
  10. *
  11. */
  12. class SystemFile extends AuthController
  13. {
  14. /**
  15. * 文件校验记录
  16. * @return mixed
  17. */
  18. public function index()
  19. {
  20. $rootPath = app()->getRootPath();
  21. $app = $this->getDir($rootPath . 'app');
  22. $extend = $this->getDir($rootPath . 'crmeb');
  23. $public = $this->getDir($rootPath . 'public');
  24. $arr = array();
  25. $arr = array_merge($app, $extend);
  26. $arr = array_merge($arr, $public);
  27. $fileAll = array();//本地文件
  28. $cha = array();//不同的文件
  29. foreach ($arr as $k => $v) {
  30. $fp = fopen($v, 'r');
  31. if (filesize($v)) $ct = fread($fp, filesize($v));
  32. else $ct = null;
  33. fclose($fp);
  34. $cthash = md5($ct);
  35. $update_time = stat($v);
  36. $fileAll[$k]['cthash'] = $cthash;
  37. $fileAll[$k]['filename'] = substr($v, strlen($rootPath));
  38. $fileAll[$k]['atime'] = $update_time['atime'];
  39. $fileAll[$k]['mtime'] = $update_time['mtime'];
  40. $fileAll[$k]['ctime'] = $update_time['ctime'];
  41. }
  42. $file = SystemFileModel::all(function ($query) {
  43. $query->order('atime', 'desc');
  44. })->toArray();//数据库中的文件
  45. if (empty($file)) {
  46. $data_num = array_chunk($fileAll, 10);
  47. SystemFileModel::beginTrans();
  48. $res = true;
  49. foreach ($data_num as $k => $v) {
  50. $res = $res && SystemFileModel::insertAll($v);
  51. }
  52. SystemFileModel::checkTrans($res);
  53. if ($res) {
  54. $cha = array();//不同的文件
  55. } else {
  56. $cha = $fileAll;
  57. }
  58. } else {
  59. $cha = array();//差异文件
  60. foreach ($file as $k => $v) {
  61. foreach ($fileAll as $ko => $vo) {
  62. if ($v['filename'] == $vo['filename']) {
  63. if ($v['cthash'] != $vo['cthash']) {
  64. // $cha[$k]['filename'] = $v['filename'];
  65. // $cha[$k]['cthash'] = $v['cthash'];
  66. // $cha[$k]['atime'] = $v['atime'];
  67. // $cha[$k]['mtime'] = $v['mtime'];
  68. // $cha[$k]['ctime'] = $v['ctime'];
  69. // $cha[$k]['type'] = '已修改';
  70. $cha[] = [
  71. 'filename' => $v['filename'],
  72. 'cthash' => $v['cthash'],
  73. 'atime' => date('Y-m-d H:i:s', $v['atime']),
  74. 'mtime' => date('Y-m-d H:i:s', $v['mtime']),
  75. 'ctime' => date('Y-m-d H:i:s', $v['ctime']),
  76. 'type' => '已修改',
  77. ];
  78. }
  79. unset($fileAll[$ko]);
  80. unset($file[$k]);
  81. }
  82. }
  83. }
  84. foreach ($file as $k => $v) {
  85. // $cha[$k]['filename'] = $v['filename'];
  86. // $cha[$k]['cthash'] = $v['cthash'];
  87. // $cha[$k]['atime'] = $v['atime'];
  88. // $cha[$k]['mtime'] = $v['mtime'];
  89. // $cha[$k]['ctime'] = $v['ctime'];
  90. // $cha[$k]['type'] = '已删除';
  91. $cha[] = [
  92. 'filename' => $v['filename'],
  93. 'cthash' => $v['cthash'],
  94. 'atime' => date('Y-m-d H:i:s', $v['atime']),
  95. 'mtime' => date('Y-m-d H:i:s', $v['mtime']),
  96. 'ctime' => date('Y-m-d H:i:s', $v['ctime']),
  97. 'type' => '已删除',
  98. ];
  99. }
  100. foreach ($fileAll as $k => $v) {
  101. // $cha[$k]['filename'] = $v['filename'];
  102. // $cha[$k]['cthash'] = $v['cthash'];
  103. // $cha[$k]['atime'] = $v['atime'];
  104. // $cha[$k]['mtime'] = $v['mtime'];
  105. // $cha[$k]['ctime'] = $v['ctime'];
  106. // $cha[$k]['type'] = '新增的';
  107. $cha[] = [
  108. 'filename' => $v['filename'],
  109. 'cthash' => $v['cthash'],
  110. 'atime' => date('Y-m-d H:i:s', $v['atime']),
  111. 'mtime' => date('Y-m-d H:i:s', $v['mtime']),
  112. 'ctime' => date('Y-m-d H:i:s', $v['ctime']),
  113. 'type' => '新增的',
  114. ];
  115. }
  116. }
  117. array_multisort(array_column($cha, 'ctime'), SORT_DESC, $cha);
  118. return $this->success(['list' => $cha]);
  119. }
  120. /**
  121. * 获取文件夹中的文件 包括子文件 不能直接用 直接使用 $this->getDir()方法 P156
  122. * @param $path
  123. * @param $data
  124. */
  125. public function searchDir($path, &$data)
  126. {
  127. if (is_dir($path) && !strpos($path, 'uploads')) {
  128. $dp = dir($path);
  129. while ($file = $dp->read()) {
  130. if ($file != '.' && $file != '..') {
  131. $this->searchDir($path . '/' . $file, $data);
  132. }
  133. }
  134. $dp->close();
  135. }
  136. if (is_file($path)) {
  137. $data[] = $path;
  138. }
  139. }
  140. /**
  141. * 获取文件夹中的文件 包括子文件
  142. * @param $dir
  143. * @return array
  144. */
  145. public function getDir($dir)
  146. {
  147. $data = array();
  148. $this->searchDir($dir, $data);
  149. return $data;
  150. }
  151. //打开目录
  152. public function opendir()
  153. {
  154. $fileAll = array('dir' => [], 'file' => []);
  155. //根目录
  156. $rootdir = app()->getRootPath();
  157. // return $rootdir;
  158. //当前目录
  159. $request_dir = app('request')->param('dir');
  160. //防止查看站点以外的目录
  161. if (strpos($request_dir, $rootdir) === false) {
  162. $request_dir = $rootdir;
  163. }
  164. //判断是否是返回上级
  165. if (app('request')->param('superior') && !empty($request_dir)) {
  166. if (strpos(dirname($request_dir), $rootdir) !== false) {
  167. $dir = dirname($request_dir);
  168. } else {
  169. $dir = $rootdir;
  170. }
  171. } else {
  172. $dir = !empty($request_dir) ? $request_dir : $rootdir;
  173. $dir = rtrim($dir, DS) . DS . app('request')->param('filedir');
  174. }
  175. $list = scandir($dir);
  176. foreach ($list as $key => $v) {
  177. if ($v != '.' && $v != '..') {
  178. if (is_dir($dir . DS . $v)) {
  179. $fileAll['dir'][] = FileClass::listInfo($dir . DS . $v);
  180. }
  181. if (is_file($dir . DS . $v)) {
  182. $fileAll['file'][] = FileClass::listInfo($dir . DS . $v);
  183. }
  184. }
  185. }
  186. //兼容windows
  187. $uname = php_uname('s');
  188. if (strstr($uname, 'Windows') !== false) {
  189. $dir = ltrim($dir, '\\');
  190. $rootdir = str_replace('\\', '\\\\', $rootdir);
  191. }
  192. $list = array_merge($fileAll['dir'], $fileAll['file']);
  193. foreach ($list as $key => $value) {
  194. $list[$key]['real_path'] = str_replace($rootdir, '', $value['pathname']);
  195. $list[$key]['mtime'] = date('Y-m-d H:i:s',$value['mtime']);
  196. }
  197. return $this->success(compact('dir', 'list'));
  198. }
  199. //读取文件
  200. public function openfile()
  201. {
  202. $file = $this->request->param('filepath');
  203. if (empty($file)) return $this->fail('出现错误');
  204. $filepath = $file;
  205. $content = FileClass::readFile($filepath);//防止页面内嵌textarea标签
  206. $ext = FileClass::getExt($filepath);
  207. $extarray = [
  208. 'js' => 'text/javascript'
  209. , 'php' => 'text/x-php'
  210. , 'html' => 'text/html'
  211. , 'sql' => 'text/x-mysql'
  212. , 'css' => 'text/x-scss'];
  213. $mode = empty($extarray[$ext]) ? '' : $extarray[$ext];
  214. return $this->success(compact('content', 'mode', 'filepath'));
  215. }
  216. //保存文件
  217. public function savefile()
  218. {
  219. $comment = $this->request->param('comment');
  220. $filepath = $this->request->param('filepath');
  221. if (!empty($comment) && !empty($filepath)) {
  222. //兼容windows
  223. $uname = php_uname('s');
  224. if (strstr($uname, 'Windows') !== false)
  225. $filepath = ltrim(str_replace('/', DS, $filepath), '.');
  226. if (FileClass::isWritable($filepath)) {
  227. $res = FileClass::writeFile($filepath, $comment);
  228. if ($res) {
  229. return $this->success('保存成功!');
  230. } else {
  231. return $this->fail('保存失败');
  232. }
  233. } else {
  234. return $this->fail('没有权限!');
  235. }
  236. } else {
  237. return $this->fail('出现错误');
  238. }
  239. }
  240. }