NowExec.php 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. <?php
  2. declare (strict_types = 1);
  3. namespace app\command;
  4. use PHPUnit\Exception;
  5. use think\console\Command;
  6. use think\console\Input;
  7. use think\console\input\Argument;
  8. use think\console\input\Option;
  9. use think\console\Output;
  10. use think\facade\Db;
  11. use think\facade\Cache;
  12. class NowExec extends Command
  13. {
  14. public $redis=[];
  15. protected function configure()
  16. {
  17. ini_set("memory_limit","512M");
  18. // 指令配置
  19. $this->setName('NowExec')
  20. ->setDescription('the hello command');
  21. }
  22. protected function execute(Input $input, Output $output)
  23. {
  24. $this->redis=Cache::store("redis");
  25. $iscgd = $this->redis->get("nowexec");
  26. if($iscgd==0){
  27. $this->redis->set("nowexec",1);
  28. }else{
  29. return;
  30. }
  31. try {
  32. if ($this->redis->handler()->llen('nowreport') > 0) {
  33. $data = $this->redis->handler()->rpop('nowreport');
  34. $user_info = json_decode($data, true);
  35. try {
  36. $rel = $this->checkJob($user_info);
  37. if ($rel) {
  38. $this->doData($user_info);
  39. }
  40. }catch (\Exception $e){
  41. Db::name("exec")->where(["id"=>$data['id']])->save(["remark"=>$e->getMessage(),'status'=>3,
  42. "updatetime"=>date
  43. ("Y-m-d H:i:s")]);
  44. $this->redis->set("nowexec", 0);
  45. $output->writeln('queuecus');
  46. }
  47. }
  48. $this->redis->set("nowexec", 0);
  49. $output->writeln('queuecus');
  50. }catch (\Exception $e){
  51. $this->redis->set("nowexec", 0);
  52. $output->writeln('queuecus');
  53. }
  54. }
  55. protected function checkJob($data){
  56. if($data['id']!=''){
  57. $info = Db::name("exec")->where(["id"=>$data['id']])->find();
  58. if($info['status']!=1){
  59. return false;
  60. }
  61. }else{
  62. return false;
  63. }
  64. return true;
  65. }
  66. protected function doData($data){
  67. $zipfile=[];
  68. $dir = "/storage/report/".date("YmdHis")."/";
  69. $diff = $this->monthDiff($data['start'],$data['end']);
  70. foreach ($diff as $value){
  71. $start = $value." 00:00:00";
  72. $end = date("Y-m-t",strtotime($value))." 23:59:59";
  73. $sql =str_replace(["%s","%t"],[$start,$end],$data['exec_sql']);
  74. $list = Db::query($sql);
  75. if(empty($list)){
  76. continue;
  77. }
  78. $header = array_keys($list[0]);
  79. array_walk($list, function (&$v) {
  80. $v = array_values($v);
  81. });
  82. $zipfile []=$this->execfile(date("Y-m",strtotime($start)).'月份'.$data['name'],$header,$list,$dir);
  83. }
  84. if(empty($zipfile)){
  85. $info=[];
  86. $info['status']=2;
  87. $info['remark']='文件生成失败';
  88. $info['updatetime']=date("Y-m-d H:i:s");
  89. Db::name("exec")->where(["id"=>$data['id']])->save($info);
  90. return ;
  91. }
  92. $zip=$this->addzipfile($zipfile,$data['name']);
  93. if(is_file(root_path() . 'public'.$zip)){
  94. $info=[];
  95. $info['status']=2;
  96. $info['down_url']=$zip;
  97. $info['expiretime']=date("Y-m-d H:i:s",time()+7*24*3600);
  98. // $info['updatetime']=date("Y-m-d H:i:s");
  99. Db::name("exec")->where(["id"=>$data['id']])->save($info);
  100. return ;
  101. }else{
  102. $info=[];
  103. $info['status']=2;
  104. $info['remark']='文件生成失败';
  105. $info['updatetime']=date("Y-m-d H:i:s");
  106. Db::name("exec")->where(["id"=>$data['id']])->save($info);
  107. return ;
  108. }
  109. }
  110. protected function execfile($fileName,$headArr,$data,$root_dir){
  111. if(is_file(root_path() . 'public'.$root_dir.$fileName)){
  112. unlink(root_path() . 'public'.$root_dir.$fileName);
  113. }
  114. $objPHPExcel = new \PHPExcel();
  115. $objPHPExcel->getProperties();
  116. $keyA = 0; // 设置表头
  117. foreach ($headArr as $v) {
  118. $colum = \PHPExcel_Cell::stringFromColumnIndex($keyA);
  119. $objPHPExcel->setActiveSheetIndex(0)->setCellValue($colum . '1', $v);
  120. $keyA += 1;
  121. }
  122. $column = 2;
  123. $objActSheet = $objPHPExcel->getActiveSheet();
  124. foreach ($data as $key => $rows) { // 行写入
  125. $span = 0;
  126. foreach ($rows as $keyName => $value) { // 列写入
  127. //判断数据是否有数组,如果有数组,转换成字符串
  128. if(is_array($value)){
  129. $value = implode("、", $value);
  130. }
  131. $objActSheet->setCellValue(\PHPExcel_Cell::stringFromColumnIndex($span) . $column, $value);
  132. $span++;
  133. }
  134. $column++;
  135. }
  136. $file = $fileName. ".xls";
  137. $dir =root_path() . 'public'.$root_dir;
  138. if(!is_dir($dir)){
  139. mkdir($dir,0777,true);
  140. }
  141. $objPHPExcel->setActiveSheetIndex(0); // 设置活动单指数到第一个表,所以Excel打开这是第一个表
  142. $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
  143. $objWriter->save($dir . $file); // 文件通过浏览器下载
  144. return $dir.$file;
  145. }
  146. public function monthDiff($start,$end){
  147. $start = $start==""? "2000-01-01" :date("Y-m",strtotime($start))."-01";
  148. $end= $end==""?date("Y-m",time())."-01" : date("Y-m",strtotime($end))."-01";
  149. $data=[];
  150. while (strtotime($start)<=strtotime($end)){
  151. $data[]=$start;
  152. $start = date('Y-m-d', strtotime("$start +1 month"));
  153. }
  154. return $data;
  155. }
  156. public function addzipfile($filelist,$zipname){
  157. $datetime = date("YmdHis");
  158. $zip_dir="/storage/zip/".$datetime."/".$zipname.".zip";
  159. $file_dir =root_path()."public/storage/zip/".$datetime."/".$zipname.".zip";
  160. $saveDir = root_path()."public/storage/zip/".$datetime."/";
  161. if(!is_dir( $saveDir)){
  162. mkdir($saveDir,0777,true);
  163. }
  164. # 5.1 文件打包,提示:使用本类,linux需开启zlib,windows需取消php_zip.dll前的注释
  165. $zip = new \ZipArchive ();
  166. # 5.2 文件不存在则生成一个新的文件 用CREATE打开文件会追加内容至zip
  167. if ($zip->open($file_dir, \ZipArchive::OVERWRITE) !== true && $zip->open($file_dir, \ZipArchive::CREATE) !==
  168. true) echo '无法打开文件或者文件创建失败';
  169. # 5.3 批量写入压缩包
  170. foreach ($filelist as $value){
  171. $fileName=basename($value);
  172. $filedir=pathinfo($value);
  173. $zip->addEmptyDir($fileName);
  174. // @$zip->addFile($v['file_path'], 'resume'.DIRECTORY_SEPARATOR.basename($headername));
  175. @$zip->addFile($value,$fileName.DIRECTORY_SEPARATOR.basename($value));
  176. # 5.4 关闭压缩包写入
  177. $dir = $filedir['dirname'];
  178. //@unlink($value);
  179. // @$this->deldir($filedir['dirname']);
  180. }
  181. $zip->close();
  182. @$this->deldir($dir);
  183. return $zip_dir;
  184. }
  185. public function deldir($path){
  186. //如果是目录则继续
  187. if(is_dir($path)){
  188. //扫描一个文件夹内的所有文件夹和文件并返回数组
  189. $p = scandir($path);
  190. //如果 $p 中有两个以上的元素则说明当前 $path 不为空
  191. if(count($p)>2){
  192. foreach($p as $val){
  193. //排除目录中的.和..
  194. if($val !="." && $val !=".."){
  195. //如果是目录则递归子目录,继续操作
  196. if(is_dir($path.$val)){
  197. //子目录中操作删除文件夹和文件
  198. deldir($path.$val.'/');
  199. }else{
  200. //如果是文件直接删除
  201. unlink($path.'/'.$val);
  202. }
  203. }
  204. }
  205. }
  206. }
  207. //删除目录
  208. return rmdir($path);
  209. }
  210. }