Develop.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. <?php
  2. /**
  3. * ----------------------------------------------------------------------------
  4. * 行到水穷处,坐看云起时
  5. * 开发软件,找贵阳云起信息科技,官网地址:https://www.56q7.com/
  6. * ----------------------------------------------------------------------------
  7. * Author: 老成
  8. * email:85556713@qq.com
  9. */
  10. declare (strict_types = 1);
  11. namespace app\admin\controller;
  12. use app\admin\service\curd\CurdService;
  13. use app\common\controller\Backend;
  14. use app\common\model\AuthRule;
  15. use app\common\model\Queue;
  16. use app\admin\command\Queue as QueueCommand;
  17. use think\annotation\route\Group;
  18. use think\annotation\route\Route;
  19. use think\facade\Db;
  20. #[Group("develop")]
  21. class Develop extends Backend
  22. {
  23. protected $noNeedRight = ['*'];
  24. protected function _initialize()
  25. {
  26. parent::_initialize();
  27. if(!$this->auth->isSuperAdmin()){
  28. $this->error(__('超级管理员才能访问'));
  29. }
  30. }
  31. //一键crud
  32. #[Route("GET,JSON","crud")]
  33. public function crud()
  34. {
  35. if($this->request->isJson()){
  36. if(!config('app.app_debug')) {
  37. $this->error(__('只允许在开启调试模式下执行'));
  38. }
  39. $data=$this->request->post();
  40. try{
  41. $service=CurdService::newInstance($data);
  42. $service->volidate();
  43. $content=$service->build();
  44. if($data['type']=='file'){
  45. $url=$service->getIndexUrl();
  46. $this->success(__('创建成功'),$url);
  47. }
  48. if($data['type']=='code'){
  49. $this->success('',$content);
  50. }
  51. }catch (\Exception $e){
  52. $this->error($e->getMessage());
  53. }
  54. }else{
  55. $tree=AuthRule::getMenuListTree('*');
  56. $ruledata=[0 => __('无')];
  57. foreach ($tree as $value){
  58. $ruledata[$value['id']]=$value['title'];
  59. }
  60. $config = Db::getConfig();
  61. $default=$config['default'];
  62. $prefix=$config['connections'][$default]['prefix'];
  63. $this->assign('ruledata',$ruledata);
  64. $this->assign('app',['admin']);
  65. $this->assign('tablePrefix',$prefix);
  66. return $this->fetch();
  67. }
  68. }
  69. //清除创建
  70. #[Route("JSON","clear")]
  71. public function clear()
  72. {
  73. if(!config('app.app_debug')) {
  74. $this->error(__('只允许在开启调试模式下执行'));
  75. }
  76. $data=$this->request->post();
  77. try{
  78. CurdService::newInstance($data)->clear();
  79. }catch (\Exception $e){
  80. $this->error($e->getMessage());
  81. }
  82. $this->success(__('清除成功'));
  83. }
  84. //构造表格
  85. #[Route("GET,POST","queue")]
  86. public function queue()
  87. {
  88. if($this->request->isAjax()){
  89. $list=Queue::alias('queue')->whereRaw("queue.limit=0 or queue.limit>queue.times")->select();
  90. $this->success('',$list);
  91. }
  92. return $this->fetch();
  93. }
  94. #[Route("GET","queueLog")]
  95. public function queueLog()
  96. {
  97. $type=$this->request->get('type');
  98. //每次读取1kb
  99. $readSize=1024*2;
  100. $log=root_path().'queue.log';
  101. if($type=='total'){
  102. if (!file_exists($log)) {
  103. $this->success('',1);
  104. }
  105. //获取文件大小
  106. $size=filesize($log);
  107. //获取总页数
  108. $total=ceil($size/$readSize);
  109. $this->success('',$total);
  110. }
  111. if($type=='content'){
  112. $page=$this->request->get('page/d');
  113. if (!file_exists($log)) {
  114. $this->success('');
  115. }
  116. $fp=fopen($log,'r');
  117. //定位到读取的页数的行首
  118. $start=($page-1)*$readSize;
  119. fseek($fp,$start);
  120. while ($start>0){
  121. $char=fgetc($fp);
  122. if($char=="\n"){
  123. break;
  124. }
  125. $start--;
  126. $readSize++;
  127. fseek($fp,$start);
  128. }
  129. $content='';
  130. while(!feof($fp)) {
  131. $content.=fgets($fp);
  132. if(strlen($content)>$readSize){
  133. break;
  134. }
  135. }
  136. fclose($fp);
  137. $this->success('',$content);
  138. }
  139. }
  140. #[Route("POST","delQueue")]
  141. public function delQueue()
  142. {
  143. $this->queueReload(function(){
  144. $id=$this->request->post('id');
  145. Queue::find($id)->delete();
  146. });
  147. $list=Queue::alias('queue')->whereRaw("queue.limit=0 or queue.limit>queue.times")->select();
  148. $this->success(__('删除成功'),$list);
  149. }
  150. private function queueReload($callback)
  151. {
  152. try{
  153. $callback();
  154. }catch (\Exception $e){
  155. $this->error($e->getMessage());
  156. }
  157. $refreshTime=QueueCommand::refreshTime;
  158. $time=QueueCommand::$timetxt;
  159. $locktime=intval(file_get_contents($time));
  160. $locktime=$locktime+($refreshTime-$locktime%$refreshTime);
  161. file_put_contents(QueueCommand::$locktxt,$locktime);
  162. }
  163. #[Route("GET,POST","addQueue")]
  164. public function addQueue()
  165. {
  166. if($this->request->isPost()){
  167. $data=$this->request->post('row/a');
  168. if(!class_exists("\\app\\admin\\command\\queueEvent\\".$data['function'])){
  169. $this->error(__('处理类不存在'));
  170. }
  171. $filter=[];
  172. if($data['filter']){
  173. foreach ($data['filter'] as $key=>$value){
  174. $value=trim($value);
  175. if($value==''){
  176. continue;
  177. }
  178. $year=intval(date('Y'));
  179. if($key=='年'){
  180. $value=intval($value);
  181. if($value<$year){
  182. $this->error(__('年份不能小于当前年份'));
  183. }
  184. $value=(string)$value;
  185. }
  186. if($key=='月'){
  187. $value=intval($value);
  188. if($value<1 || $value>12){
  189. $this->error(__('月份必须在1-12之间'));
  190. }
  191. if($value<10){
  192. $value='0'.$value;
  193. }
  194. $value=(string)$value;
  195. }
  196. if($key=='日'){
  197. $value=intval($value);
  198. if($value<1 || $value>31){
  199. $this->error(__('日必须在1-31之间'));
  200. }
  201. if($value<10){
  202. $value='0'.$value;
  203. }
  204. $value=(string)$value;
  205. }
  206. if($key=='时'){
  207. $value=intval($value);
  208. if($value<0 || $value>23){
  209. $this->error(__('时必须在0-23之间'));
  210. }
  211. if($value<10){
  212. $value='0'.$value;
  213. }
  214. $value=(string)$value;
  215. }
  216. if($key=='分'){
  217. $value=intval($value);
  218. if($value<0 || $value>59){
  219. $this->error(__('分必须在0-59之间'));
  220. }
  221. if($value<10){
  222. $value='0'.$value;
  223. }
  224. $value=(string)$value;
  225. }
  226. if($key=='秒'){
  227. $value=intval($value);
  228. if($value<0 || $value>59){
  229. $this->error(__('秒必须在0-59之间'));
  230. }
  231. if($value<10){
  232. $value='0'.$value;
  233. }
  234. $value=(string)$value;
  235. }
  236. switch ($key){
  237. case '年':
  238. $filter['Y']=$value;
  239. break;
  240. case '月':
  241. $filter['m']=$value;
  242. break;
  243. case '日':
  244. $filter['d']=$value;
  245. break;
  246. case '时':
  247. $filter['H']=$value;
  248. break;
  249. case '分':
  250. $filter['i']=$value;
  251. break;
  252. case '秒':
  253. $filter['s']=$value;
  254. break;
  255. }
  256. }
  257. $data['filter']=json_encode($filter,JSON_UNESCAPED_UNICODE);
  258. }
  259. $this->queueReload(function () use ($data){
  260. (new Queue())->save($data);
  261. });
  262. $this->success(__('添加成功'));
  263. }
  264. return $this->fetch();
  265. }
  266. #[Route("GET,POST","queueStatus")]
  267. public function queueStatus()
  268. {
  269. $timetxt=QueueCommand::$timetxt;
  270. if($this->request->isPost()){
  271. $status=$this->request->post('status');
  272. $timetxt1=intval(file_get_contents($timetxt));
  273. sleep(2);
  274. $timetxt2=intval(file_get_contents($timetxt));
  275. if($status){
  276. if($timetxt1!=$timetxt2) {
  277. $this->error(__('队列正在执行中'));
  278. }
  279. $str=php_ini_loaded_file();
  280. $str=substr($str,0,strrpos($str,'/'));
  281. $phppath='';
  282. $callback='';
  283. if (substr(php_uname(), 0, 7) == "Windows"){
  284. if(!function_exists('popen') || !function_exists('pclose')){
  285. $this->error(__('popen或pclose函数被禁用了'));
  286. }
  287. $phppath=substr($str,0,strrpos($str,'/')).DS.'bin'.DS.'php.exe';
  288. $callback=function ($cmd){
  289. pclose(popen($cmd,'r'));
  290. };
  291. }
  292. if (substr(php_uname(), 0, 5) == "Linux"){
  293. if(!function_exists('exec')){
  294. $this->error(__('exec函数被禁用了'));
  295. }
  296. $phppath=substr($str,0,strrpos($str,'/')).DS.'bin'.DS.'php';
  297. $callback=function ($cmd){
  298. $logpath=root_path()."queue.log";
  299. if(file_exists($logpath)){
  300. unlink($logpath);
  301. }
  302. exec("{$cmd} > {$logpath} &");
  303. };
  304. }
  305. if($phppath==''){
  306. $this->error(__('当前操作仅支持windows或linux系统'));
  307. }
  308. $command=root_path().'think Queue';
  309. $cmd=$phppath." ".$command;
  310. file_put_contents($timetxt,1);
  311. $callback($cmd);
  312. $this->success();
  313. }else{
  314. if($timetxt1==$timetxt2) {
  315. $this->error(__('队列服务已经停止了'));
  316. }
  317. file_put_contents($timetxt,0);
  318. $this->success();
  319. }
  320. }
  321. $timetxt1=intval(file_get_contents($timetxt));
  322. sleep(2);
  323. $timetxt2=intval(file_get_contents($timetxt));
  324. $status='normal';
  325. $keeptime=$timetxt2;
  326. $stoptime='';
  327. if($timetxt1==$timetxt2) {
  328. $status='hidden';
  329. $stoptime=date('Y-m-d H:i:s',filemtime($timetxt));
  330. }
  331. $this->success('',compact('status','keeptime','stoptime'));
  332. }
  333. //获取表格
  334. #[Route("JSON","getTable")]
  335. public function getTable()
  336. {
  337. $limit=$this->request->post('limit/d',7);
  338. $page=$this->request->post('page/d',7);
  339. $labelValue=$this->request->post('labelValue');
  340. $where="";
  341. if($labelValue) {
  342. $where="and `TABLE_NAME` like '%{$labelValue}%'";
  343. }
  344. $offect=($page-1)*$limit;
  345. $config = Db::getConfig();
  346. $default=$config['default'];
  347. $dbname=$config['connections'][$default]['database'];
  348. $count=Db::query("SELECT COUNT(*) AS `count` FROM `information_schema`.`TABLES` where `TABLE_SCHEMA` = '{$dbname}' {$where};");
  349. $tableList = Db::query("SELECT `TABLE_NAME` AS `name`,`TABLE_COMMENT` AS `title` FROM `information_schema`.`TABLES` where `TABLE_SCHEMA` = '{$dbname}' {$where} limit {$offect},{$limit};");
  350. foreach ($tableList as $key=>$value){
  351. $tableList[$key]['title']=$tableList[$key]['name'].($tableList[$key]['title']?' - '.$tableList[$key]['title']:'');
  352. }
  353. return json(['total'=>$count[0]['count'],'rows'=>$tableList]);
  354. }
  355. //获取字段
  356. #[Route("GET","getFields")]
  357. public function getFields()
  358. {
  359. $table = $this->request->get('table');
  360. $config = Db::getConfig();
  361. $default=$config['default'];
  362. $dbname=$config['connections'][$default]['database'];
  363. //从数据库中获取表字段信息
  364. $sql = "SELECT `COLUMN_NAME` AS `name`,`COLUMN_COMMENT` AS `title`,`DATA_TYPE` AS `type` FROM `information_schema`.`columns` WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ? ORDER BY ORDINAL_POSITION";
  365. //加载主表的列
  366. $fieldList = Db::query($sql, [$dbname, $table]);
  367. $this->success("",$fieldList);
  368. }
  369. }