You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

340 lines
13 KiB

3 years ago
  1. <?php
  2. namespace app\controller;
  3. use app\BaseController;
  4. use think\facade\Db;
  5. use think\facade\View;
  6. use think\facade\Request;
  7. use app\lib\Btapi;
  8. use app\lib\Plugins;
  9. class Admin extends BaseController
  10. {
  11. public function verifycode()
  12. {
  13. return captcha();
  14. }
  15. public function login(){
  16. if(request()->islogin){
  17. return redirect('/admin');
  18. }
  19. if(request()->isAjax()){
  20. $username = input('post.username',null,'trim');
  21. $password = input('post.password',null,'trim');
  22. $code = input('post.code',null,'trim');
  23. if(empty($username) || empty($password)){
  24. return json(['code'=>-1, 'msg'=>'用户名或密码不能为空']);
  25. }
  26. if(!captcha_check($code)){
  27. return json(['code'=>-1, 'msg'=>'验证码错误']);
  28. }
  29. if($username == config_get('admin_username') && $password == config_get('admin_password')){
  30. Db::name('log')->insert(['uid' => 0, 'action' => '登录后台', 'data' => 'IP:'.$this->clientip, 'addtime' => date("Y-m-d H:i:s")]);
  31. $session = md5($username.config_get('admin_password'));
  32. $expiretime = time()+2562000;
  33. $token = authcode("{$username}\t{$session}\t{$expiretime}", 'ENCODE', config_get('syskey'));
  34. cookie('admin_token', $token, ['expire' => $expiretime, 'httponly' => true]);
  35. config_set('admin_lastlogin', date('Y-m-d H:i:s'));
  36. return json(['code'=>0]);
  37. }else{
  38. return json(['code'=>-1, 'msg'=>'用户名或密码错误']);
  39. }
  40. }
  41. return view();
  42. }
  43. public function logout()
  44. {
  45. cookie('admin_token', null);
  46. return redirect('/admin/login');
  47. }
  48. public function index()
  49. {
  50. $stat = ['total'=>0, 'free'=>0, 'pro'=>0, 'ltd'=>0, 'third'=>0];
  51. $json_arr = Plugins::get_plugin_list();
  52. if($json_arr){
  53. foreach($json_arr['list'] as $plugin){
  54. $stat['total']++;
  55. if($plugin['type']==10) $stat['third']++;
  56. elseif($plugin['type']==12) $stat['ltd']++;
  57. elseif($plugin['type']==8) $stat['pro']++;
  58. elseif($plugin['type']==5 || $plugin['type']==6 || $plugin['type']==7) $stat['free']++;
  59. }
  60. }
  61. $stat['runtime'] = Db::name('config')->where('key','runtime')->value('value') ?? '<font color="red">未运行</font>';
  62. $stat['record_total'] = Db::name('record')->count();
  63. $stat['record_isuse'] = Db::name('record')->whereTime('usetime', '>=', strtotime('-7 days'))->count();
  64. View::assign('stat', $stat);
  65. $tmp = 'version()';
  66. $mysqlVersion = Db::query("select version()")[0][$tmp];
  67. $info = [
  68. 'framework_version' => app()::VERSION,
  69. 'php_version' => PHP_VERSION,
  70. 'mysql_version' => $mysqlVersion,
  71. 'software' => $_SERVER['SERVER_SOFTWARE'],
  72. 'os' => php_uname(),
  73. 'date' => date("Y-m-d H:i:s"),
  74. ];
  75. View::assign('info', $info);
  76. return view();
  77. }
  78. public function set(){
  79. if(request()->isAjax()){
  80. $params = Request::param();
  81. foreach ($params as $key => $value) {
  82. config_set($key, $value);
  83. }
  84. cache('configs', NULL);
  85. return json(['code'=>0]);
  86. }
  87. $mod = input('param.mod', 'sys');
  88. View::assign('mod', $mod);
  89. View::assign('conf', config('sys'));
  90. $runtime = Db::name('config')->where('key','runtime')->value('value') ?? '<font color="red">未运行</font>';
  91. View::assign('runtime', $runtime);
  92. return view();
  93. }
  94. public function setaccount(){
  95. $params = Request::param();
  96. if(isset($params['username']))$params['username']=trim($params['username']);
  97. if(isset($params['oldpwd']))$params['oldpwd']=trim($params['oldpwd']);
  98. if(isset($params['newpwd']))$params['newpwd']=trim($params['newpwd']);
  99. if(isset($params['newpwd2']))$params['newpwd2']=trim($params['newpwd2']);
  100. if(empty($params['username'])) return json(['code'=>-1, 'msg'=>'用户名不能为空']);
  101. config_set('admin_username', $params['username']);
  102. if(!empty($params['oldpwd']) && !empty($params['newpwd']) && !empty($params['newpwd2'])){
  103. if(config_get('admin_password') != $params['oldpwd']){
  104. return json(['code'=>-1, 'msg'=>'旧密码不正确']);
  105. }
  106. if($params['newpwd'] != $params['newpwd2']){
  107. return json(['code'=>-1, 'msg'=>'两次新密码输入不一致']);
  108. }
  109. config_set('admin_password', $params['newpwd']);
  110. }
  111. cache('configs', NULL);
  112. cookie('admin_token', null);
  113. return json(['code'=>0]);
  114. }
  115. public function testbturl(){
  116. $bt_url = input('post.bt_url');
  117. $bt_key = input('post.bt_key');
  118. if(!$bt_url || !$bt_key)return json(['code'=>-1, 'msg'=>'参数不能为空']);
  119. $btapi = new Btapi($bt_url, $bt_key);
  120. $result = $btapi->get_config();
  121. if($result && isset($result['status']) && $result['status']==1){
  122. $result = $btapi->get_user_info();
  123. if($result && isset($result['username'])){
  124. return json(['code'=>0, 'msg'=>'面板连接测试成功!']);
  125. }else{
  126. return json(['code'=>-1, 'msg'=>'面板连接测试成功,但未安装专用插件']);
  127. }
  128. }else{
  129. return json(['code'=>-1, 'msg'=>isset($result['msg'])?$result['msg']:'面板地址无法连接']);
  130. }
  131. }
  132. public function plugins(){
  133. $typelist = [];
  134. $json_arr = Plugins::get_plugin_list();
  135. if($json_arr){
  136. foreach($json_arr['type'] as $type){
  137. $typelist[$type['id']] = $type['title'];
  138. }
  139. }
  140. View::assign('typelist', $typelist);
  141. return view();
  142. }
  143. public function plugins_data(){
  144. $type = input('post.type/d');
  145. $keyword = input('post.keyword', null, 'trim');
  146. $json_arr = Plugins::get_plugin_list();
  147. if(!$json_arr) return json([]);
  148. $typelist = [];
  149. foreach($json_arr['type'] as $row){
  150. $typelist[$row['id']] = $row['title'];
  151. }
  152. $list = [];
  153. foreach($json_arr['list'] as $plugin){
  154. if($type > 0 && $plugin['type']!=$type) continue;
  155. if(!empty($keyword) && $keyword != $plugin['name'] && stripos($plugin['title'], $keyword)===false) continue;
  156. $versions = [];
  157. foreach($plugin['versions'] as $version){
  158. $ver = $version['m_version'].'.'.$version['version'];
  159. if(isset($version['download'])){
  160. $status = false;
  161. if(file_exists(get_data_dir().'plugins/other/'.$version['download'])){
  162. $status = true;
  163. }
  164. $versions[] = ['status'=>$status, 'type'=>1, 'version'=>$ver, 'download'=>$version['download'], 'md5'=>$version['md5']];
  165. }else{
  166. $status = false;
  167. if(file_exists(get_data_dir().'plugins/package/'.$plugin['name'].'-'.$ver.'.zip')){
  168. $status = true;
  169. }
  170. $versions[] = ['status'=>$status, 'type'=>0, 'version'=>$ver];
  171. }
  172. }
  173. $list[] = [
  174. 'id' => $plugin['id'],
  175. 'name' => $plugin['name'],
  176. 'title' => $plugin['title'],
  177. 'type' => $plugin['type'],
  178. 'typename' => $typelist[$plugin['type']],
  179. 'desc' => str_replace('target="_blank"','target="_blank" rel="noopener noreferrer"',$plugin['ps']),
  180. 'price' => $plugin['price'],
  181. 'author' => isset($plugin['author']) ? $plugin['author'] : '官方',
  182. 'versions' => $versions
  183. ];
  184. }
  185. return json($list);
  186. }
  187. public function download_plugin(){
  188. $name = input('post.name', null, 'trim');
  189. $version = input('post.version', null, 'trim');
  190. if(!$name || !$version) return json(['code'=>-1, 'msg'=>'参数不能为空']);
  191. try{
  192. Plugins::download_plugin($name, $version);
  193. Db::name('log')->insert(['uid' => 0, 'action' => '下载插件', 'data' => $name.'-'.$version, 'addtime' => date("Y-m-d H:i:s")]);
  194. return json(['code'=>0,'msg'=>'下载成功']);
  195. }catch(\Exception $e){
  196. return json(['code'=>-1, 'msg'=>$e->getMessage()]);
  197. }
  198. }
  199. public function refresh_plugins(){
  200. try{
  201. Plugins::refresh_plugin_list();
  202. Db::name('log')->insert(['uid' => 0, 'action' => '刷新插件列表', 'data' => '刷新插件列表成功', 'addtime' => date("Y-m-d H:i:s")]);
  203. return json(['code'=>0,'msg'=>'获取最新插件列表成功!']);
  204. }catch(\Exception $e){
  205. return json(['code'=>-1, 'msg'=>$e->getMessage()]);
  206. }
  207. }
  208. public function record(){
  209. return view();
  210. }
  211. public function record_data(){
  212. $ip = input('post.ip', null, 'trim');
  213. $offset = input('post.offset/d');
  214. $limit = input('post.limit/d');
  215. $select = Db::name('record');
  216. if(!empty($ip)){
  217. $select->where('ip', $ip);
  218. }
  219. $total = $select->count();
  220. $rows = $select->order('id','desc')->limit($offset, $limit)->select();
  221. return json(['total'=>$total, 'rows'=>$rows]);
  222. }
  223. public function log(){
  224. return view();
  225. }
  226. public function log_data(){
  227. $action = input('post.action', null, 'trim');
  228. $offset = input('post.offset/d');
  229. $limit = input('post.limit/d');
  230. $select = Db::name('log');
  231. if(!empty($action)){
  232. $select->where('action', $action);
  233. }
  234. $total = $select->count();
  235. $rows = $select->order('id','desc')->limit($offset, $limit)->select();
  236. return json(['total'=>$total, 'rows'=>$rows]);
  237. }
  238. public function list(){
  239. $type = input('param.type', 'black');
  240. View::assign('type', $type);
  241. View::assign('typename', $type=='white'?'白名单':'黑名单');
  242. return view();
  243. }
  244. public function list_data(){
  245. $type = input('param.type', 'black');
  246. $ip = input('post.ip', null, 'trim');
  247. $offset = input('post.offset/d');
  248. $limit = input('post.limit/d');
  249. $tablename = $type == 'black' ? 'black' : 'white';
  250. $select = Db::name($tablename);
  251. if(!empty($ip)){
  252. $select->where('ip', $ip);
  253. }
  254. $total = $select->count();
  255. $rows = $select->order('id','desc')->limit($offset, $limit)->select();
  256. return json(['total'=>$total, 'rows'=>$rows]);
  257. }
  258. public function list_op(){
  259. $type = input('param.type', 'black');
  260. $tablename = $type == 'black' ? 'black' : 'white';
  261. $act = input('post.act', null);
  262. if($act == 'get'){
  263. $id = input('post.id/d');
  264. if(!$id) return json(['code'=>-1, 'msg'=>'no id']);
  265. $data = Db::name($tablename)->where('id', $id)->find();
  266. return json(['code'=>0, 'data'=>$data]);
  267. }elseif($act == 'add'){
  268. $ip = input('post.ip', null, 'trim');
  269. if(!$ip) return json(['code'=>-1, 'msg'=>'IP不能为空']);
  270. if(Db::name($tablename)->where('ip', $ip)->find()){
  271. return json(['code'=>-1, 'msg'=>'该IP已存在']);
  272. }
  273. Db::name($tablename)->insert([
  274. 'ip' => $ip,
  275. 'enable' => 1,
  276. 'addtime' => date("Y-m-d H:i:s")
  277. ]);
  278. return json(['code'=>0, 'msg'=>'succ']);
  279. }elseif($act == 'edit'){
  280. $id = input('post.id/d');
  281. $ip = input('post.ip', null, 'trim');
  282. if(!$id || !$ip) return json(['code'=>-1, 'msg'=>'IP不能为空']);
  283. if(Db::name($tablename)->where('ip', $ip)->where('id', '<>', $id)->find()){
  284. return json(['code'=>-1, 'msg'=>'该IP已存在']);
  285. }
  286. Db::name($tablename)->where('id', $id)->update([
  287. 'ip' => $ip
  288. ]);
  289. return json(['code'=>0, 'msg'=>'succ']);
  290. }elseif($act == 'enable'){
  291. $id = input('post.id/d');
  292. $enable = input('post.enable/d');
  293. if(!$id) return json(['code'=>-1, 'msg'=>'no id']);
  294. Db::name($tablename)->where('id', $id)->update([
  295. 'enable' => $enable
  296. ]);
  297. return json(['code'=>0, 'msg'=>'succ']);
  298. }elseif($act == 'del'){
  299. $id = input('post.id/d');
  300. if(!$id) return json(['code'=>-1, 'msg'=>'no id']);
  301. Db::name($tablename)->where('id', $id)->delete();
  302. return json(['code'=>0, 'msg'=>'succ']);
  303. }
  304. return json(['code'=>-1, 'msg'=>'no act']);
  305. }
  306. }