Index.php 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982
  1. <?php
  2. namespace app\admin\controller;
  3. use think\Hook;
  4. use think\Db;
  5. use Exception;
  6. use ip_limit\IpLocationQuery;
  7. class Index extends Base
  8. {
  9. public function __construct()
  10. {
  11. parent::__construct();
  12. }
  13. public function login()
  14. {
  15. if (Request()->isPost()) {
  16. $data = input('post.');
  17. $res = model('Admin')->login($data);
  18. if ($res['code'] > 1) {
  19. return $this->error($res['msg']);
  20. }
  21. return $this->success($res['msg']);
  22. }
  23. Hook::listen("admin_login_init", $this->request);
  24. return $this->fetch('admin@index/login');
  25. }
  26. public function logout()
  27. {
  28. $res = model('Admin')->logout();
  29. $this->redirect('index/login');
  30. }
  31. public function index()
  32. {
  33. $menus = @include MAC_ADMIN_COMM . 'auth.php';
  34. $version = config('version');
  35. foreach ($menus as $k1 => $v1) {
  36. foreach ($v1['sub'] as $k2 => $v2) {
  37. if ($v2['show'] == 1) {
  38. if (strpos($v2['action'], 'javascript') !== false) {
  39. $url = $v2['action'];
  40. } else {
  41. $url = url('admin/' . $v2['controller'] . '/' . $v2['action']);
  42. }
  43. if (!empty($v2['param'])) {
  44. $url .= '?' . $v2['param'];
  45. }
  46. if ($this->check_auth($v2['controller'], $v2['action'])) {
  47. $menus[$k1]['sub'][$k2]['url'] = $url;
  48. } else {
  49. unset($menus[$k1]['sub'][$k2]);
  50. }
  51. } else {
  52. unset($menus[$k1]['sub'][$k2]);
  53. }
  54. }
  55. if (empty($menus[$k1]['sub'])) {
  56. unset($menus[$k1]);
  57. }
  58. }
  59. $quickmenu = config('quickmenu');
  60. if (empty($quickmenu)) {
  61. $quickmenu = mac_read_file(APP_PATH . 'data/config/quickmenu.txt');
  62. $quickmenu = explode(chr(13), $quickmenu);
  63. }
  64. if (!empty($quickmenu)) {
  65. $menus[1]['sub'][13] = ['name' => lang('admin/index/quick_tit'), 'url' => 'javascript:void(0);return false;', 'controller' => '', 'action' => ''];
  66. foreach ($quickmenu as $k => $v) {
  67. if (empty($v)) {
  68. continue;
  69. }
  70. $one = explode(',', trim($v));
  71. if (substr($one[1], 0, 4) == 'http' || substr($one[1], 0, 2) == '//') {
  72. } elseif (substr($one[1], 0, 1) == '/') {
  73. } elseif (strpos($one[1], '###') !== false || strpos($one[1], 'javascript:') !== false) {
  74. } else {
  75. $one[1] = url($one[1]);
  76. }
  77. $menus[1]['sub'][14 + $k] = ['name' => $one[0], 'url' => $one[1], 'controller' => '', 'action' => ''];
  78. }
  79. }
  80. $langs = glob('./application/lang/*.php');
  81. foreach ($langs as $k => &$v) {
  82. $v = str_replace(['./application/lang/','.php'],['',''],$v);
  83. }
  84. $config = config('maccms');
  85. $this->assign('config', $config);
  86. $this->assign('langs', $langs);
  87. $this->assign('version', $version);
  88. $this->assign('menus', $menus);
  89. $this->assign('title', lang('admin/index/title'));
  90. $ipQuery = new IpLocationQuery();
  91. $country_code = $ipQuery->queryProvince(mac_get_client_ip());
  92. if($country_code == ""){
  93. $country_code = "其它";
  94. }
  95. $this->assign('ip_location', $country_code);
  96. return $this->fetch('admin@index/index');
  97. }
  98. public function welcome()
  99. {
  100. $version = config('version');
  101. $update_sql = file_exists('./application/data/update/database.php');
  102. $this->assign('spider_data', $this->botlist());
  103. $os_data = $this->get_system_status();
  104. $show_os_guide = false;
  105. if (empty($os_data['cpu_usage']) || empty($os_data['mem_total'])) {
  106. $show_os_guide = true;
  107. }
  108. if (empty($os_data['disk_datas'])) {
  109. $show_os_guide = true;
  110. } else {
  111. $disk_total = 0;
  112. foreach($os_data['disk_datas'] as $disk) {
  113. $disk_total += $disk[1];
  114. }
  115. if ($disk_total == 0) {
  116. $show_os_guide = true;
  117. }
  118. }
  119. $this->assign('show_os_guide', $show_os_guide);
  120. $this->assign('os_data', $os_data);
  121. $this->assign('version', $version);
  122. $this->assign('update_sql', $update_sql);
  123. $this->assign('mac_lang', config('default_lang'));
  124. $this->assign('dashboard_data', $this->getAdminDashboardData());
  125. $this->assign('admin', $this->_admin);
  126. $this->assign('title', lang('admin/index/welcome/title'));
  127. return $this->fetch('admin@index/welcome');
  128. }
  129. public function quickmenu()
  130. {
  131. if (Request()->isPost()) {
  132. $param = input();
  133. $validate = \think\Loader::validate('Token');
  134. if (!$validate->check($param)) {
  135. return $this->error($validate->getError());
  136. }
  137. $quickmenu = input('post.quickmenu');
  138. $quickmenu = str_replace(chr(10), '', $quickmenu);
  139. $menu_arr = explode(chr(13), $quickmenu);
  140. $res = mac_arr2file(APP_PATH . 'extra/quickmenu.php', $menu_arr);
  141. if ($res === false) {
  142. return $this->error(lang('save_err'));
  143. }
  144. return $this->success(lang('save_ok'));
  145. } else {
  146. $config_menu = config('quickmenu');
  147. if (empty($config_menu)) {
  148. $quickmenu = mac_read_file(APP_PATH . 'data/config/quickmenu.txt');
  149. } else {
  150. $quickmenu = array_values($config_menu);
  151. $quickmenu = join(chr(13), $quickmenu);
  152. }
  153. $this->assign('quickmenu', $quickmenu);
  154. $this->assign('title', lang('admin/index/quickmenu/title'));
  155. return $this->fetch('admin@index/quickmenu');
  156. }
  157. }
  158. public function checkcache()
  159. {
  160. $res = 'no';
  161. $r = cache('cache_data');
  162. if ($r == '1') {
  163. $res = 'haved';
  164. }
  165. echo $res;
  166. }
  167. public function clear()
  168. {
  169. $res = $this->_cache_clear();
  170. //运行缓存
  171. if (!$res) {
  172. $this->error(lang('admin/index/clear_err'));
  173. }
  174. // 搜索缓存结果清理
  175. model('VodSearch')->clearOldResult(true);
  176. return $this->success(lang('admin/index/clear_ok'));
  177. }
  178. public function iframe()
  179. {
  180. $val = input('post.val', 0);
  181. if ($val != 0 && $val != 1) {
  182. return $this->error(lang('admin/index/clear_ok'));
  183. }
  184. if ($val == 1) {
  185. cookie('is_iframe', 'yes');
  186. } else {
  187. cookie('is_iframe', null);
  188. }
  189. return $this->success(lang('admin/index/iframe'));
  190. }
  191. public function unlocked()
  192. {
  193. $param = input();
  194. $password = $param['password'];
  195. if ($this->_admin['admin_pwd'] != md5($password)) {
  196. return $this->error(lang('admin/index/pass_err'));
  197. }
  198. return $this->success(lang('admin/index/unlock_ok'));
  199. }
  200. public function check_back_link()
  201. {
  202. $param = input();
  203. $res = mac_check_back_link($param['url']);
  204. return json($res);
  205. }
  206. public function select()
  207. {
  208. $param = input();
  209. $tpl = $param['tpl'];
  210. $tab = $param['tab'];
  211. $col = $param['col'];
  212. $ids = $param['ids'];
  213. $url = $param['url'];
  214. $val = $param['val'];
  215. $refresh = $param['refresh'];
  216. if (empty($tpl) || empty($tab) || empty($col) || empty($ids) || empty($url)) {
  217. return $this->error(lang('param_err'));
  218. }
  219. if (is_array($ids)) {
  220. $ids = join(',', $ids);
  221. }
  222. if (empty($refresh)) {
  223. $refresh = 'yes';
  224. }
  225. $url = url($url);
  226. $mid = 1;
  227. if ($tab == 'art') {
  228. $mid = 2;
  229. } elseif ($tab == 'actor') {
  230. $mid = 8;
  231. } elseif ($tab == 'website') {
  232. $mid = 11;
  233. } elseif ($tab == 'manga') {
  234. $mid = 12;
  235. }
  236. $this->assign('mid', $mid);
  237. if ($tpl == 'select_type') {
  238. $type_tree = model('Type')->getCache('type_tree');
  239. $this->assign('type_tree', $type_tree);
  240. } elseif ($tpl == 'select_level') {
  241. $level_list = [1, 2, 3, 4, 5, 6, 7, 8, 9];
  242. $this->assign('level_list', $level_list);
  243. }
  244. $this->assign('refresh', $refresh);
  245. $this->assign('url', $url);
  246. $this->assign('tab', $tab);
  247. $this->assign('col', $col);
  248. $this->assign('ids', $ids);
  249. $this->assign('val', $val);
  250. return $this->fetch('admin@public/' . $tpl);
  251. }
  252. public function get_system_status()
  253. {
  254. //判斷系統
  255. $os_name = PHP_OS;
  256. $os_data = [];
  257. $os_data['os_name'] = $os_name;
  258. if (strtoupper(substr($os_name, 0, 3)) === 'WIN') {
  259. // Windows系统
  260. $os_data['os_name'] = 'WINDOWS';
  261. $os_data['disk_datas'] = $this->get_spec_disk('all');
  262. $os_data['cpu_usage'] = $this->getCpuUsage();
  263. $mem_arr = $this->getMemoryUsage();
  264. $os_data['mem_usage'] = $mem_arr['usage'];
  265. $os_data['mem_total'] = round($mem_arr['TotalVisibleMemorySize'] / 1024, 2);
  266. $os_data['mem_used'] = $os_data['mem_total'] - round($mem_arr['FreePhysicalMemory'] / 1024, 2);
  267. } else {
  268. // Linux和FreeBSD的处理逻辑
  269. $os_data['os_name'] = strtoupper($os_name);
  270. // 获取磁盘信息
  271. $totalSpace = 0;
  272. $freeSpace = 0;
  273. if (function_exists('disk_total_space') && function_exists('disk_free_space')) {
  274. $totalSpace = @disk_total_space(ROOT_PATH);
  275. $freeSpace = @disk_free_space(ROOT_PATH);
  276. }
  277. if ($totalSpace > 0) {
  278. $totalSpaceGB = round($totalSpace / (1024 * 1024 * 1024), 2);
  279. $freeSpaceGB = round($freeSpace / (1024 * 1024 * 1024), 2);
  280. $usedSpaceGB = round($totalSpaceGB - $freeSpaceGB, 2);
  281. $tmp_disk_data = [];
  282. $tmp_disk_data[0] = $usedSpaceGB;
  283. $tmp_disk_data[1] = $totalSpaceGB;
  284. $tmp_disk_data[2] = round(100 - ($freeSpaceGB / $totalSpaceGB * 100), 2);
  285. $os_data['disk_datas']['/'] = $tmp_disk_data;
  286. } else {
  287. $os_data['disk_datas']['/'] = [0, 0, 0];
  288. }
  289. // 获取内存和CPU信息
  290. $mem_arr = $this->get_unix_server_memory_usage();
  291. $os_data['cpu_usage'] = $this->get_unix_server_cpu_usage();
  292. $os_data['mem_usage'] = $mem_arr['usage'];
  293. $os_data['mem_used'] = $mem_arr['used'];
  294. $os_data['mem_total'] = $mem_arr['total'];
  295. }
  296. return $os_data;
  297. }
  298. private function byte_format($size, $dec = 2)
  299. {
  300. if ($size == 0) {
  301. return "0 B";
  302. }
  303. $a = array("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB");
  304. $pos = 0;
  305. while ($size >= 1024) {
  306. $size /= 1024;
  307. $pos++;
  308. }
  309. return round($size, $dec);
  310. }
  311. private function get_disk_space($letter)
  312. {
  313. // 添加函数存在性检查
  314. if (!function_exists('disk_total_space') || !function_exists('disk_free_space')) {
  315. return [];
  316. }
  317. // 获取磁盘信息
  318. $diskct = 0;
  319. $disk = array();
  320. $diskz = 0; //磁盘总容量
  321. $diskk = 0; //磁盘剩余容量
  322. $is_disk = $letter . ':';
  323. if (@\disk_total_space($is_disk) != NULL) {
  324. $diskct++;
  325. $total_space = @\disk_total_space($is_disk);
  326. $free_space = @\disk_free_space($is_disk);
  327. // 转换为GB并保留两位小数
  328. $total_space_gb = round($total_space / (1024 * 1024 * 1024), 2);
  329. $free_space_gb = round($free_space / (1024 * 1024 * 1024), 2);
  330. $disk[$letter][0] = round($this->byte_format($free_space), 2);
  331. $disk[$letter][1] = round($this->byte_format($total_space), 2);
  332. if ($total_space > 0) {
  333. $disk[$letter][2] = round(100 - ($free_space_gb / $total_space_gb * 100), 2);
  334. } else {
  335. $disk[$letter][2] = 0;
  336. }
  337. $diskk += round($this->byte_format($free_space), 2);
  338. $diskz += round($this->byte_format($total_space), 2);
  339. }
  340. return $disk;
  341. }
  342. private function get_spec_disk($type = 'system')
  343. {
  344. $disk = array();
  345. switch ($type) {
  346. case 'system':
  347. //strrev(array_pop(explode(':',strrev(getenv_info('SystemRoot')))));//取得系统盘符
  348. $disk = $this->get_disk_space(strrev(array_pop(explode(':', strrev(getenv('SystemRoot'))))));
  349. break;
  350. case 'all':
  351. foreach (range('b', 'z') as $letter) {
  352. $disk = array_merge($disk, $this->get_disk_space(strtoupper($letter)));
  353. }
  354. break;
  355. default:
  356. $disk = $this->get_disk_space($type);
  357. break;
  358. }
  359. return $disk;
  360. }
  361. private function isComAvailable()
  362. {
  363. return extension_loaded('com_dotnet');
  364. }
  365. private function getCpuUsage()
  366. {
  367. if (!$this->isComAvailable()) {
  368. if (!function_exists('shell_exec')) {
  369. return 0;
  370. }
  371. try {
  372. $cmd = "wmic cpu get loadpercentage";
  373. $output = shell_exec($cmd);
  374. if ($output) {
  375. preg_match('/\d+/', $output, $matches);
  376. if (isset($matches[0])) {
  377. return (float)$matches[0];
  378. }
  379. }
  380. } catch (Exception $e) {
  381. return 0;
  382. }
  383. return 0;
  384. }
  385. try {
  386. if(class_exists('COM')){
  387. $wmi = new \COM('WinMgmts:\\\\.');
  388. $cpus = $wmi->ExecQuery('SELECT LoadPercentage FROM Win32_Processor');
  389. } else {
  390. return 0;
  391. }
  392. $cpu_load = 0;
  393. $cpu_count = 0;
  394. foreach ($cpus as $cpu) {
  395. $cpu_load += $cpu->LoadPercentage;
  396. $cpu_count++;
  397. }
  398. return $cpu_count > 0 ? round($cpu_load / $cpu_count, 2) : 0;
  399. } catch (Exception $e) {
  400. if (!function_exists('shell_exec')) {
  401. return 0;
  402. }
  403. try {
  404. $cmd = "wmic cpu get loadpercentage";
  405. $output = shell_exec($cmd);
  406. if ($output) {
  407. preg_match('/\d+/', $output, $matches);
  408. if (isset($matches[0])) {
  409. return (float)$matches[0];
  410. }
  411. }
  412. } catch (Exception $e) {
  413. return 0;
  414. }
  415. return 0;
  416. }
  417. }
  418. private function getMemoryUsage()
  419. {
  420. if (!$this->isComAvailable()) {
  421. if (!function_exists('shell_exec')) {
  422. return [
  423. 'TotalVisibleMemorySize' => 0,
  424. 'FreePhysicalMemory' => 0,
  425. 'usage' => 0
  426. ];
  427. }
  428. try {
  429. $cmd = "wmic OS get FreePhysicalMemory,TotalVisibleMemorySize /Value";
  430. $output = shell_exec($cmd);
  431. if ($output) {
  432. preg_match('/TotalVisibleMemorySize=(\d+)/i', $output, $total);
  433. preg_match('/FreePhysicalMemory=(\d+)/i', $output, $free);
  434. if (isset($total[1]) && isset($free[1])) {
  435. $total_mem = (float)$total[1];
  436. $free_mem = (float)$free[1];
  437. $used_mem = $total_mem - $free_mem;
  438. return [
  439. 'TotalVisibleMemorySize' => $total_mem,
  440. 'FreePhysicalMemory' => $free_mem,
  441. 'usage' => $total_mem > 0 ? round(($used_mem / $total_mem) * 100, 2) : 0
  442. ];
  443. }
  444. }
  445. } catch (Exception $e) {
  446. return [
  447. 'TotalVisibleMemorySize' => 0,
  448. 'FreePhysicalMemory' => 0,
  449. 'usage' => 0
  450. ];
  451. }
  452. }
  453. try {
  454. if(class_exists('COM')){
  455. $wmi = new \COM('WinMgmts:\\\\.');
  456. $os = $wmi->ExecQuery('SELECT TotalVisibleMemorySize,FreePhysicalMemory FROM Win32_OperatingSystem');
  457. } else {
  458. return [
  459. 'TotalVisibleMemorySize' => 0,
  460. 'FreePhysicalMemory' => 0,
  461. 'usage' => 0
  462. ];
  463. }
  464. foreach ($os as $item) {
  465. $total = $item->TotalVisibleMemorySize;
  466. $free = $item->FreePhysicalMemory;
  467. $used = $total - $free;
  468. return [
  469. 'TotalVisibleMemorySize' => $total,
  470. 'FreePhysicalMemory' => $free,
  471. 'usage' => $total > 0 ? round(($used / $total) * 100, 2) : 0
  472. ];
  473. }
  474. } catch (Exception $e) {
  475. if (!function_exists('shell_exec')) {
  476. return [
  477. 'TotalVisibleMemorySize' => 0,
  478. 'FreePhysicalMemory' => 0,
  479. 'usage' => 0
  480. ];
  481. }
  482. try {
  483. $cmd = "wmic OS get FreePhysicalMemory,TotalVisibleMemorySize /Value";
  484. $output = shell_exec($cmd);
  485. if ($output) {
  486. preg_match('/TotalVisibleMemorySize=(\d+)/i', $output, $total);
  487. preg_match('/FreePhysicalMemory=(\d+)/i', $output, $free);
  488. if (isset($total[1]) && isset($free[1])) {
  489. $total_mem = (float)$total[1];
  490. $free_mem = (float)$free[1];
  491. $used_mem = $total_mem - $free_mem;
  492. return [
  493. 'TotalVisibleMemorySize' => $total_mem,
  494. 'FreePhysicalMemory' => $free_mem,
  495. 'usage' => $total_mem > 0 ? round(($used_mem / $total_mem) * 100, 2) : 0
  496. ];
  497. }
  498. }
  499. } catch (Exception $e) {
  500. return [
  501. 'TotalVisibleMemorySize' => 0,
  502. 'FreePhysicalMemory' => 0,
  503. 'usage' => 0
  504. ];
  505. }
  506. }
  507. }
  508. private function get_unix_server_memory_usage()
  509. {
  510. // 首先尝试使用通用的 sysinfo 方法
  511. if (function_exists('sysinfo')) {
  512. $si = sysinfo();
  513. if ($si) {
  514. $total_mem = $si['totalram'] * $si['mem_unit'] / 1024 / 1024;
  515. $free_mem = $si['freeram'] * $si['mem_unit'] / 1024 / 1024;
  516. $used_mem = $total_mem - $free_mem;
  517. $usage = ($total_mem > 0) ? ($used_mem / $total_mem) * 100 : 0;
  518. return [
  519. 'total' => round($total_mem, 2),
  520. 'used' => round($used_mem, 2),
  521. 'usage' => round($usage, 2)
  522. ];
  523. }
  524. }
  525. // 尝试不同的内存信息获取方法
  526. $methods = [
  527. // Linux free 命令
  528. 'free' => function() {
  529. if (!function_exists('shell_exec')) {
  530. return null;
  531. }
  532. $free = shell_exec('free');
  533. if ($free) {
  534. $free = (string)trim($free);
  535. $free_arr = explode("\n", $free);
  536. $mem = explode(" ", $free_arr[1]);
  537. $mem = array_filter($mem);
  538. $mem = array_merge($mem);
  539. if (count($mem) >= 3 && !empty($mem[1])) {
  540. return [
  541. 'total' => round($mem[1] / 1024, 2),
  542. 'used' => round($mem[2] / 1024, 2),
  543. 'usage' => round($mem[2] / $mem[1] * 100, 2)
  544. ];
  545. }
  546. }
  547. return null;
  548. },
  549. // FreeBSD/Unix sysctl 命令
  550. 'sysctl' => function() {
  551. if (!function_exists('shell_exec')) {
  552. return null;
  553. }
  554. $sysctl = shell_exec('/sbin/sysctl -n hw.physmem hw.pagesize vm.stats.vm.v_free_count 2>/dev/null');
  555. if ($sysctl) {
  556. $lines = explode("\n", trim($sysctl));
  557. if (count($lines) >= 3 && !empty($lines[0])) {
  558. $total_mem = $lines[0] / 1024 / 1024;
  559. $page_size = $lines[1];
  560. $free_pages = $lines[2];
  561. $free_mem = ($free_pages * $page_size) / 1024 / 1024;
  562. $used_mem = $total_mem - $free_mem;
  563. $usage = $total_mem > 0 ? ($used_mem / $total_mem) * 100 : 0;
  564. return [
  565. 'total' => round($total_mem, 2),
  566. 'used' => round($used_mem, 2),
  567. 'usage' => round($usage, 2)
  568. ];
  569. }
  570. }
  571. return null;
  572. },
  573. // /proc/meminfo 文件读取
  574. 'proc' => function() {
  575. if (!is_readable('/proc/meminfo')) {
  576. return null;
  577. }
  578. $meminfo = file_get_contents('/proc/meminfo');
  579. if ($meminfo) {
  580. preg_match('/MemTotal:\s+(\d+)/i', $meminfo, $total);
  581. preg_match('/MemFree:\s+(\d+)/i', $meminfo, $free);
  582. preg_match('/Cached:\s+(\d+)/i', $meminfo, $cached);
  583. preg_match('/Buffers:\s+(\d+)/i', $meminfo, $buffers);
  584. if (isset($total[1]) && isset($free[1])) {
  585. $total_mem = $total[1] / 1024;
  586. $free_mem = ($free[1] + (isset($cached[1]) ? $cached[1] : 0) + (isset($buffers[1]) ? $buffers[1] : 0)) / 1024;
  587. $used_mem = $total_mem - $free_mem;
  588. $usage = ($total_mem > 0) ? ($used_mem / $total_mem) * 100 : 0;
  589. return [
  590. 'total' => round($total_mem, 2),
  591. 'used' => round($used_mem, 2),
  592. 'usage' => round($usage, 2)
  593. ];
  594. }
  595. }
  596. return null;
  597. }
  598. ];
  599. // 依次尝试各种方法
  600. foreach ($methods as $method) {
  601. $result = $method();
  602. if ($result !== null) {
  603. return $result;
  604. }
  605. }
  606. // 如果所有方法都失败,返回默认值
  607. return [
  608. 'total' => 0,
  609. 'used' => 0,
  610. 'usage' => 0
  611. ];
  612. }
  613. private function get_unix_server_cpu_usage()
  614. {
  615. // 首先尝试使用通用的方法
  616. $methods = [
  617. // top 命令 (Linux)
  618. 'top_linux' => function() {
  619. if (!function_exists('shell_exec')) {
  620. return null;
  621. }
  622. $cpu_load = shell_exec("top -bn1 | grep 'Cpu(s)' 2>/dev/null");
  623. if (!empty($cpu_load)) {
  624. if (preg_match('/(\d+[.,]\d+).*?us/', $cpu_load, $matches)) {
  625. return round((float)str_replace(',', '.', $matches[1]), 2);
  626. }
  627. }
  628. return null;
  629. },
  630. // top 命令 (FreeBSD)
  631. 'top_bsd' => function() {
  632. if (!function_exists('shell_exec')) {
  633. return null;
  634. }
  635. $cpu_load = shell_exec("top -d2 -n1 | grep 'CPU:' 2>/dev/null");
  636. if (!empty($cpu_load)) {
  637. if (preg_match('/(\d+\.\d+)%\s+user/', $cpu_load, $matches)) {
  638. return round((float)$matches[1], 2);
  639. }
  640. }
  641. return null;
  642. },
  643. // sysctl (FreeBSD/Unix)
  644. 'sysctl' => function() {
  645. if (!function_exists('shell_exec')) {
  646. return null;
  647. }
  648. $cpu_load = shell_exec('/sbin/sysctl -n kern.cp_time 2>/dev/null');
  649. if (!empty($cpu_load)) {
  650. $times = explode(" ", trim($cpu_load));
  651. if (count($times) >= 5) {
  652. $total = array_sum($times);
  653. $idle = $times[4];
  654. return $total > 0 ? round(100 - ($idle * 100 / $total), 2) : 0;
  655. }
  656. }
  657. return null;
  658. },
  659. // /proc/stat 文件读取
  660. 'proc' => function() {
  661. if (is_readable('/proc/stat')) {
  662. $stats1 = file_get_contents('/proc/stat');
  663. usleep(100000); // 等待100ms
  664. $stats2 = file_get_contents('/proc/stat');
  665. if ($stats1 && $stats2) {
  666. $stats_arr1 = explode(' ', trim(explode("\n", $stats1)[0]));
  667. $stats_arr2 = explode(' ', trim(explode("\n", $stats2)[0]));
  668. if (count($stats_arr1) >= 5 && count($stats_arr2) >= 5) {
  669. $cpu1 = array_sum(array_slice($stats_arr1, 1));
  670. $cpu2 = array_sum(array_slice($stats_arr2, 1));
  671. $idle1 = $stats_arr1[4];
  672. $idle2 = $stats_arr2[4];
  673. $diff_cpu = $cpu2 - $cpu1;
  674. $diff_idle = $idle2 - $idle1;
  675. if ($diff_cpu > 0) {
  676. return round(100 * (1 - $diff_idle / $diff_cpu), 2);
  677. }
  678. }
  679. }
  680. }
  681. return null;
  682. }
  683. ];
  684. // 依次尝试各种方法
  685. foreach ($methods as $method) {
  686. $result = $method();
  687. if ($result !== null) {
  688. return $result;
  689. }
  690. }
  691. return 0;
  692. }
  693. private function _getServerLoadLinuxData()
  694. {
  695. if (is_readable("/proc/stat")) {
  696. $stats = @file_get_contents("/proc/stat");
  697. if ($stats !== false) {
  698. // Remove double spaces to make it easier to extract values with explode()
  699. $stats = preg_replace("/[[:blank:]]+/", " ", $stats);
  700. // Separate lines
  701. $stats = str_replace(array("\r\n", "\n\r", "\r"), "\n", $stats);
  702. $stats = explode("\n", $stats);
  703. // Separate values and find line for main CPU load
  704. foreach ($stats as $statLine) {
  705. $statLineData = explode(" ", trim($statLine));
  706. // Found!
  707. if (
  708. (count($statLineData) >= 5) &&
  709. ($statLineData[0] == "cpu")
  710. ) {
  711. return array(
  712. $statLineData[1],
  713. $statLineData[2],
  714. $statLineData[3],
  715. $statLineData[4],
  716. );
  717. }
  718. }
  719. }
  720. }
  721. return null;
  722. }
  723. private function getAdminDashboardData()
  724. {
  725. $result = [];
  726. //已注册总用户数量
  727. $result['user_count'] = model('User')->count();
  728. $result['user_count'] = number_format($result['user_count'], 0, '.', ',');
  729. //已审核用户数量
  730. $result['user_active_count'] = model('User')->where('user_status', 1)->count();
  731. $result['user_active_count'] = number_format($result['user_active_count'], 0, '.', ',');
  732. $today_start = strtotime(date('Y-m-d 00:00:00'));
  733. $today_end = $today_start + 86399;
  734. //本日来客量
  735. $result['today_visit_count'] = model('Visit')->where('visit_time', 'between', $today_start . ',' . $today_end)->count();
  736. $result['today_visit_count'] = number_format($result['today_visit_count'], 0, '.', ',');
  737. //本日总入金
  738. $result['today_money_get'] = model('Order')->where('order_time', 'between', $today_start . ',' . $today_end)->where('order_status', 1)->sum('order_price');
  739. $result['today_money_get'] = number_format($result['today_money_get'], 2, '.', ',');
  740. //前七天 每日用户访问数
  741. $tmp_arr = Db::query("select FROM_UNIXTIME(visit_time, '%Y-%c-%d' ) days,count(*) count from (SELECT * from ".config('database.prefix')."visit where visit_time >= (unix_timestamp(CURDATE())-604800)) as temp group by days");
  742. $result['seven_day_visit_day'] = [];
  743. $result['seven_day_visit_count'] = [];
  744. $result['raise_visit_user_today'] = 0;
  745. if (is_array($tmp_arr) && count($tmp_arr) > 1 && (strtotime(end($tmp_arr)['days']) == strtotime(date('Y-m-d')))) {
  746. $yesterday_visit_count = $tmp_arr[count($tmp_arr) - 2]['count'];
  747. $lastday_visit_count = end($tmp_arr)['count'];
  748. if ($yesterday_visit_count != 0) {
  749. $result['raise_visit_user_today'] = number_format((($lastday_visit_count - $yesterday_visit_count) / $yesterday_visit_count) * 100, 2, '.', ',');
  750. } else {
  751. $result['raise_visit_user_today'] = 0;
  752. }
  753. }
  754. foreach ($tmp_arr as $data) {
  755. array_push($result['seven_day_visit_day'], $data['days']);
  756. array_push($result['seven_day_visit_count'], $data['count']);
  757. }
  758. //近七日用户访问总量
  759. $result['seven_day_visit_total_count'] = 0;
  760. foreach ($result['seven_day_visit_data'] as $k => $value) {
  761. $result['seven_day_visit_total_count'] = $result['seven_day_visit_total_count'] + $value['count'];
  762. }
  763. $result['seven_day_visit_total_count'] = number_format($result['seven_day_visit_total_count'], 0, '.', ',');
  764. //前七天 每日用户注册数
  765. $result['seven_day_reg_data'] = Db::query("select FROM_UNIXTIME(user_reg_time, '%Y-%c-%d' ) days,count(*) count from (SELECT * from ".config('database.prefix')."user where user_reg_time >= (unix_timestamp(CURDATE())-604800)) as tmp group by days");
  766. //近七日用户注册总量
  767. $result['seven_day_reg_total_count'] = 0;
  768. $result['seven_day_reg_day'] = [];
  769. $result['seven_day_reg_count'] = [];
  770. foreach ($result['seven_day_reg_data'] as $k => $value) {
  771. array_push($result['seven_day_reg_day'], $value['days']);
  772. array_push($result['seven_day_reg_count'], $value['count']);
  773. $result['seven_day_reg_total_count'] = $result['seven_day_reg_total_count'] + $value['count'];
  774. }
  775. //比較前一天的註冊量漲幅
  776. $result['raise_reg_user_today'] = 0;
  777. if (is_array($result['seven_day_reg_data']) && count($result['seven_day_reg_data']) > 1 && (strtotime(end($result['seven_day_reg_data'])['days']) == strtotime(date('Y-m-d')))) {
  778. $yesterday_reg_count = $result['seven_day_reg_data'][count($result['seven_day_reg_data']) - 2]['count'];
  779. $lastday_reg_count = end($result['seven_day_reg_data'])['count'];
  780. if ($yesterday_reg_count != 0) {
  781. $result['raise_reg_user_today'] = number_format((($lastday_reg_count - $yesterday_reg_count) / $yesterday_reg_count) * 100, 2, '.', ',');
  782. } else {
  783. $result['raise_reg_user_today'] = 0;
  784. }
  785. }
  786. $result['seven_day_reg_total_count'] = number_format($result['seven_day_reg_total_count'], 0, '.', ',');
  787. return $result;
  788. }
  789. public function rangeDateDailyVisit()
  790. {
  791. $range_daily_visit_data = Db::query("select FROM_UNIXTIME(visit_time, '%Y-%c-%d' ) days,count(*) count from (SELECT * from ".config('database.prefix')."visit where visit_time >= " . strtotime($_POST['startDate']) . "&& visit_time <= " . strtotime($_POST['endDate']) . " ) as temp group by days");
  792. $result = [];
  793. $range_visit_day = [];
  794. $range_visit_count = [];
  795. $range_visit_sum = 0;
  796. foreach ($range_daily_visit_data as $data) {
  797. $range_visit_sum = $range_visit_sum + $data['count'];
  798. array_push($range_visit_day, $data['days']);
  799. array_push($range_visit_count, $data['count']);
  800. }
  801. $result['days'] = $range_visit_day;
  802. $result['count'] = $range_visit_count;
  803. $result['sum'] = $range_visit_sum;
  804. return json_encode($result);
  805. }
  806. public function botlist()
  807. {
  808. $day_arr = [];
  809. //列出最近10天的日期
  810. for ($i = 0; $i < 7; $i++) {
  811. $day_arr[$i] = date('Y-m-d', time() - $i * 60 * 60 * 24);
  812. }
  813. $google_arr = [];
  814. $baidu_arr = [];
  815. $sogou_arr = [];
  816. $soso_arr = [];
  817. $yahoo_arr = [];
  818. $msn_arr = [];
  819. $msn_bot_arr = [];
  820. $sohu_arr = [];
  821. $yodao_arr = [];
  822. $twiceler_arr = [];
  823. $alexa_arr = [];
  824. $bot_list = [];
  825. foreach ($day_arr as $day_vo) {
  826. if (file_exists(ROOT_PATH . 'runtime/log/bot/' . $day_vo . '.txt')) {
  827. $bot_content = file_get_contents(ROOT_PATH . 'runtime/log/bot/' . $day_vo . '.txt');
  828. } else {
  829. $bot_content = '';
  830. }
  831. $google_arr[$day_vo] = substr_count($bot_content, 'Google');
  832. $baidu_arr[$day_vo] = substr_count($bot_content, 'Baidu');
  833. $sogou_arr[$day_vo] = substr_count($bot_content, 'Sogou');
  834. $soso_arr[$day_vo] = substr_count($bot_content, 'SOSO');
  835. $yahoo_arr[$day_vo] = substr_count($bot_content, 'Yahoo');
  836. $msn_arr[$day_vo] = substr_count($bot_content, 'MSN');
  837. $msn_bot_arr[$day_vo] = substr_count($bot_content, 'msnbot');
  838. $sohu_arr[$day_vo] = substr_count($bot_content, 'Sohu');
  839. $yodao_arr[$day_vo] = substr_count($bot_content, 'Yodao');
  840. $twiceler_arr[$day_vo] = substr_count($bot_content, 'Twiceler');
  841. $alexa_arr[$day_vo] = substr_count($bot_content, 'Alexa');
  842. }
  843. $bot_list['Google']['key'] = array_keys($google_arr);
  844. $bot_list['Google']['values'] = array_values($google_arr);
  845. $bot_list['Baidu']['keys'] = array_keys($baidu_arr);
  846. $bot_list['Baidu']['values'] = array_values($baidu_arr);
  847. $bot_list['Sogou']['keys'] = array_keys($sogou_arr);
  848. $bot_list['Sogou']['values'] = array_values($sogou_arr);
  849. $bot_list['SOSO']['keys'] = array_keys($soso_arr);
  850. $bot_list['SOSO']['values'] = array_values($soso_arr);
  851. $bot_list['Yahoo']['keys'] = array_keys($yahoo_arr);
  852. $bot_list['Yahoo']['values'] = array_values($yahoo_arr);
  853. $bot_list['MSN']['keys'] = array_keys($msn_arr);
  854. $bot_list['MSN']['values'] = array_values($msn_arr);
  855. $bot_list['msnbot']['keys'] = array_keys($msn_bot_arr);
  856. $bot_list['msnbot']['values'] = array_values($msn_bot_arr);
  857. $bot_list['Sohu']['keys'] = array_keys($sohu_arr);
  858. $bot_list['Sohu']['values'] = array_values($sohu_arr);
  859. $bot_list['Yodao']['keys'] = array_keys($yodao_arr);
  860. $bot_list['Yodao']['values'] = array_values($yodao_arr);
  861. $bot_list['Twiceler']['keys'] = array_keys($twiceler_arr);
  862. $bot_list['Twiceler']['values'] = array_values($twiceler_arr);
  863. $bot_list['Alexa']['keys'] = array_keys($alexa_arr);
  864. $bot_list['Alexa']['values'] = array_values($alexa_arr);
  865. if (!empty($_POST['category'])) {
  866. return $bot_list[$_POST['category']];
  867. } else {
  868. return $bot_list;
  869. }
  870. }
  871. public function botlog()
  872. {
  873. $parm = input();
  874. $data = $parm['data'];
  875. $bot_content = file_get_contents(ROOT_PATH . 'runtime/log/bot/' . $data . '.txt');
  876. $bot_list = array_slice(array_reverse(explode("\r\n", trim($bot_content))), 0, 20);
  877. $this->assign('bot_list', $bot_list);
  878. return $this->fetch('admin@others/botlog');
  879. }
  880. }