Index.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. <?php
  2. namespace app\controller\admin;
  3. use app\BaseController;
  4. use app\model\CardModel;
  5. use app\model\LinkStoreModel;
  6. use app\model\SettingModel;
  7. use app\model\UserModel;
  8. use DateInterval;
  9. use DatePeriod;
  10. use DateTime;
  11. use think\facade\Cache;
  12. use think\facade\Db;
  13. //use Upgrade;
  14. class Index extends BaseController
  15. {
  16. public $authService = "https://auth.mtab.cc";
  17. public $authCode = '';
  18. function setSubscription(): \think\response\Json
  19. {
  20. $this->getAdmin();
  21. $code = $this->request->post("code", "");
  22. if (trim($code)) {
  23. Db::table('setting')->replace()->insert(['keys' => 'authCode', 'value' => $code]);
  24. SettingModel::refreshSetting();
  25. }
  26. return $this->success("ok");
  27. }
  28. private function initAuth()
  29. {
  30. $authCode = $this->Setting('authCode', '', true);
  31. if (strlen($authCode) == 0) {
  32. $authCode = env('authCode', '');
  33. }
  34. $this->authCode = $authCode;
  35. $this->authService = $this->Setting('authServer', 'https://auth.mtab.cc', true);
  36. }
  37. function updateApp(): \think\response\Json
  38. {
  39. $this->getAdmin();
  40. $this->initAuth();
  41. $result = \Axios::http()->post($this->authService . '/getUpGrade', [
  42. 'timeout' => 10,
  43. 'form_params' => [
  44. 'authorization_code' => $this->authCode,
  45. 'version_code' => app_version_code,
  46. ]
  47. ]);
  48. if ($result->getStatusCode() == 200) {
  49. $json = json_decode($result->getBody()->getContents(), true);
  50. if ($json['code'] === 1) {
  51. $upgradePhp = runtime_path() . 'update.php';
  52. $f = "";
  53. $upGrade = null;
  54. if (!empty($json['info']['update_php'])) {
  55. try {//用远程脚本更新,一般用不到,除非上一个版本发生一些问题需要额外脚本处理
  56. $f = file_get_contents($json['info']['update_php']);
  57. file_put_contents(runtime_path() . 'update.php', $f);
  58. require_once $upgradePhp;
  59. $upGrade = new \Upgrade();
  60. } catch (\Exception $e) {
  61. }
  62. }
  63. if ($upGrade === null) {
  64. $upGrade = new \Upgrade2();
  65. }
  66. if (!empty($json['info']['update_zip'])) {
  67. $upGrade->update_download_url = $json['info']['update_zip'];
  68. }
  69. if (!empty($json['info']['update_sql'])) {
  70. $upGrade->update_sql_url = $json['info']['update_sql'];
  71. }
  72. $status = $upGrade->run();//启动任务
  73. try {
  74. unlink($upgradePhp);
  75. } catch (\Exception $e) {
  76. }
  77. if ($status === true) {
  78. return $this->success('更新完毕');
  79. } else {
  80. return $this->error($status);
  81. }
  82. } else {
  83. return $this->error($json['msg']);
  84. }
  85. }
  86. return $this->error("没有更新的版本");
  87. }
  88. function authorization(): \think\response\Json
  89. {
  90. $this->getAdmin();
  91. $this->initAuth();
  92. $result = \Axios::http()->post($this->authService . '/checkAuth', [
  93. 'timeout' => 5,
  94. 'form_params' => [
  95. 'authorization_code' => $this->authCode,
  96. 'version_code' => app_version_code,
  97. ]
  98. ]);
  99. $info = [];
  100. $info['version'] = app_version;
  101. $info['version_code'] = app_version_code;
  102. $info['php_version'] = phpversion();
  103. if ($result->getStatusCode() == 200) {
  104. $jsonStr = $result->getBody()->getContents();
  105. $json = json_decode($jsonStr, true);
  106. $info['remote'] = $json;
  107. return $this->success($info);
  108. } else {
  109. return $this->error('授权服务器连接失败', $info);
  110. }
  111. }
  112. private function countFilesInDirectory($directory): int
  113. {
  114. $fileCount = 0;
  115. // 获取目录中的文件和子目录
  116. $files = scandir($directory);
  117. foreach ($files as $file) {
  118. // 排除"."和".."
  119. if ($file != '.' && $file != '..') {
  120. $filePath = $directory . '/' . $file;
  121. // 如果是目录,则递归调用函数
  122. if (is_dir($filePath)) {
  123. $fileCount += $this->countFilesInDirectory($filePath);
  124. } else {
  125. // 如果是文件,则增加文件数量
  126. $fileCount++;
  127. }
  128. }
  129. }
  130. return $fileCount;
  131. }
  132. function getServicesStatus(): \think\response\Json
  133. {
  134. $this->getAdmin();
  135. $userNum = UserModel::count("id");
  136. $linkNum = LinkStoreModel::count("id");
  137. $redisNum = 0;
  138. $fileNum = Cache::get("fileNum");
  139. if (!$fileNum) {
  140. if (is_dir(public_path() . 'images')) {
  141. $fileNum = $this->countFilesInDirectory(public_path() . 'images');
  142. Cache::set('fileNum', $fileNum, 300);
  143. }
  144. }
  145. return $this->success("ok", ["userNum" => $userNum, "linkNum" => $linkNum, "redisNum" => $redisNum, "fileNum" => $fileNum]);
  146. }
  147. function getUserLine(): \think\response\Json
  148. {
  149. $this->getAdmin();
  150. $result = UserModel::whereMonth('create_time');
  151. $result = $result->field('DATE_FORMAT(create_time, "%Y-%m-%d") as time, count(id) as total');
  152. $result = $result->group('time')->select();
  153. return $this->success('ok', $this->render($result));
  154. }
  155. function getHotTab(): \think\response\Json
  156. {
  157. $this->getAdmin();
  158. $list = LinkStoreModel::order('install_num', 'desc')->limit(30)->cache('hotTab', 60)->select()->toArray();
  159. return $this->success('ok', $list);
  160. }
  161. private function render($arr): array
  162. {
  163. $info = [];
  164. foreach ($arr as $key => $value) {
  165. $info[$value['time']] = $value['total'];
  166. }
  167. $time = [];
  168. $total = [];
  169. //当月的第一天
  170. $start = date('Y-m-01', strtotime(date('Y-m-d')));
  171. //当月的最后一天
  172. $end = date('Y-m-d', strtotime(date('Y-m-01') . ' +1 month -1 day'));
  173. $start_date = new DateTime($start);
  174. $end_date = new DateTime($end);
  175. $interval = new DateInterval('P1D');
  176. $dateRange = new DatePeriod($start_date, $interval, $end_date);
  177. $ts = null;
  178. foreach ($dateRange as $date) {
  179. $ts = $date->format('Y-m-d');
  180. $time[] = $ts;
  181. if (isset($info[$ts])) {
  182. $total[] = $info[$ts];
  183. } else {
  184. $total[] = 0;
  185. }
  186. }
  187. // 判断是否需要添加最后一天的数据
  188. if ($end_date->format('Y-m-d') != $ts) {
  189. $time[] = $end_date->format('Y-m-d');
  190. $total[] = isset($info[$end_date->format('Y-m-d')]) ? $info[$end_date->format('Y-m-d')] : 0;
  191. }
  192. return ['time' => $time, 'total' => $total, 'sum' => array_sum($total)];
  193. }
  194. function cardList(): \think\response\Json
  195. {
  196. $this->getAdmin();
  197. $this->initAuth();
  198. $result = \Axios::http()->post($this->authService . '/card', [
  199. 'timeout' => 15,
  200. 'form_params' => [
  201. 'authorization_code' => $this->authCode
  202. ]
  203. ]);
  204. try {
  205. $json = $result->getBody()->getContents();
  206. $json = json_decode($json, true);
  207. if ($json['code'] === 1) {
  208. return $this->success('ok', $json['data']);
  209. }
  210. } catch (\Exception $e) {
  211. }
  212. return $this->error('远程卡片获取失败');
  213. }
  214. //获取本地应用
  215. function localCard(): \think\response\Json
  216. {
  217. $this->getAdmin();
  218. $apps = CardModel::select();
  219. return $this->success('ok', $apps);
  220. }
  221. function stopCard(): \think\response\Json
  222. {
  223. $this->getAdmin();
  224. $name_en = $this->request->post('name_en', '');
  225. CardModel::where('name_en', $name_en)->update(['status' => 0]);
  226. Cache::delete('cardList');
  227. return $this->success('设置成功');
  228. }
  229. function startCard(): \think\response\Json
  230. {
  231. $this->getAdmin();
  232. $name_en = $this->request->post('name_en', '');
  233. CardModel::where('name_en', $name_en)->update(['status' => 1]);
  234. Cache::delete('cardList');
  235. return $this->success('设置成功');
  236. }
  237. function installCard(): \think\response\Json
  238. {
  239. $this->getAdmin();
  240. $this->initAuth();
  241. $name_en = $this->request->post("name_en", '');
  242. $version = 0;
  243. $type = $this->request->post('type', 'install');
  244. if (mb_strlen($name_en) > 0) {
  245. $card = CardModel::where('name_en', $name_en)->find();
  246. if ($card) {
  247. if ($type == 'install') {
  248. return $this->error('您已安装当前卡片组件');
  249. }
  250. if ($type == 'update') {
  251. $version = $card['version'];
  252. }
  253. }
  254. $result = \Axios::http()->post($this->authService . '/installCard', [
  255. 'timeout' => 15,
  256. 'form_params' => [
  257. 'authorization_code' => $this->authCode,
  258. 'name_en' => $name_en,
  259. 'version' => $version
  260. ]
  261. ]);
  262. try {
  263. $json = $result->getBody()->getContents();
  264. $json = json_decode($json, true, JSON_UNESCAPED_UNICODE);
  265. if ($json['code'] == 0) {
  266. return $this->error($json['msg']);
  267. }
  268. return $this->installCardTask($json['data']);
  269. } catch (\Exception $e) {
  270. }
  271. }
  272. return $this->error("没有需要安装的卡片插件!");
  273. }
  274. function uninstallCard(): \think\response\Json
  275. {
  276. $this->getAdmin();
  277. $name_en = $this->request->post("name_en");
  278. if ($name_en) {
  279. $this->deleteDirectory(root_path() . 'plugins/' . $name_en);
  280. CardModel::where('name_en', $name_en)->delete();
  281. Cache::delete('cardList');
  282. }
  283. return $this->success('卸载完毕!');
  284. }
  285. private function deleteDirectory($dir)
  286. {
  287. if (!is_dir($dir)) {
  288. return;
  289. }
  290. $files = scandir($dir);
  291. foreach ($files as $file) {
  292. if ($file != '.' && $file != '..') {
  293. if (is_dir("$dir/$file")) {
  294. $this->deleteDirectory("$dir/$file");
  295. } else {
  296. unlink("$dir/$file");
  297. }
  298. }
  299. }
  300. rmdir($dir);
  301. }
  302. private function readCardInfo($name_en)
  303. {
  304. $file = root_path() . 'plugins/' . $name_en . '/info.json';
  305. $info = file_get_contents($file);
  306. try {
  307. return json_decode($info, true);
  308. } catch (\Exception $e) {
  309. }
  310. return false;
  311. }
  312. private function installCardTask($info): \think\response\Json
  313. {
  314. if ($info['download']) {
  315. $task = new \PluginsInstall($info);
  316. $state = $task->run();
  317. if ($state === true) {
  318. $config = $this->readCardInfo($info['name_en']);
  319. $data = [
  320. 'name' => $config['name'],
  321. 'name_en' => $config['name_en'],
  322. 'version' => $config['version'],
  323. 'tips' => $config['tips'],
  324. 'src' => $config['src'],
  325. 'url' => $config['url'],
  326. 'window' => $config['window'],
  327. ];
  328. $find = CardModel::where('name_en', $info['name_en'])->find();
  329. if ($find) {
  330. $find->force()->save($data);
  331. } else {
  332. CardModel::create($data);
  333. }
  334. Cache::delete('cardList');
  335. return $this->success("安装成功");
  336. }
  337. return $this->error($state);
  338. }
  339. return $this->error('新版本没有提供下载地址!');
  340. }
  341. }