AutoController.class.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. <?php
  2. namespace Admin\Controller;
  3. use Think\Page;
  4. use Think\Cache\Driver\Redis;
  5. /**
  6. * 后台默认控制器
  7. *
  8. */
  9. class AutoController extends AdminController
  10. {
  11. protected $active_batch;
  12. /**
  13. * @return int
  14. * @ flag 1清空 Code_Active_list 清空二维码激活缓存队列
  15. * @ flag 2清空 Code_Add_list 清空二维码新增缓存队列
  16. * @ flag 3清空 fenbiao_page清空分页缓存变量
  17. * @ flag 4清空 $table_name.'_count' 分表操作缓存列表 无需清空
  18. *
  19. */
  20. /*参数的配置 start*/
  21. protected $tasks_id;
  22. protected $bach_id;
  23. protected $product_id;
  24. protected $printer_id;
  25. protected $task_name;
  26. /*参数的配置 stop*/
  27. public function clearS()
  28. {
  29. if(empty(I('flag'))){
  30. echo '请输入操作动作';
  31. }
  32. $redis=new Redis();
  33. $flag=I('flag');
  34. $status=0;
  35. switch ($flag){
  36. case 1:
  37. $num = $redis->lSize("Code_Active_list");
  38. for($i=0;$i< $num;$i++){
  39. $redis->rPop("Code_Active_list");
  40. }
  41. $status=1;
  42. break;
  43. case 2:
  44. $num = $redis->lSize("Code_Add_list");
  45. for($i=0;$i< $num;$i++){
  46. $redis->rPop("Code_Add_list");
  47. }
  48. $status=1;
  49. break;
  50. case 3:
  51. S('fenbiao_page',Null);
  52. $status=1;
  53. break;
  54. default:
  55. $status=2;
  56. }
  57. if($status==1){
  58. echo '清空成功';
  59. }
  60. else{
  61. echo '清空失败';
  62. }
  63. }
  64. /*查款redis里面的数据*/
  65. public function getS()
  66. {
  67. if(empty(I('flag'))){
  68. echo '请输入操作动作';
  69. }
  70. $redis=new Redis();
  71. $flag=I('flag');
  72. switch ($flag){
  73. case 1:
  74. echo '待更新二维码:'. $redis->lSize("Code_Active_list");
  75. break;
  76. case 2:
  77. echo '待新增二维码:'. $redis->lSize("Code_Add_list");
  78. break;
  79. case 3:
  80. echo '待分表二维码:'. $redis->lSize("fenbiao_page");
  81. break;
  82. default:
  83. $status=2;
  84. }
  85. }
  86. public function togetTxtActivefile(){
  87. /* $redis=new Redis();
  88. $redis->rm('Code_Active_list');
  89. echo '待更新二维码:'. $redis->lSize("Code_Active_list");die;*/
  90. $result = array();
  91. if(empty(I('active_batch'))){
  92. $result['status'] = 0;
  93. $result['cont'] = '激活批次号缺少';
  94. $this->ajaxReturn($result);
  95. }
  96. /*修改激活批次表*/
  97. $return1 = M('activate_list')-> where('active_batch ='.I('active_batch'))->setField('status',1);
  98. $return2 = $this->getTxtActivefile(I('active_batch'));
  99. /*修改激活批次表*/
  100. if($return1 && $return2){
  101. $result['status'] = 1;
  102. $result['cont'] = '任务已提交';
  103. $this->ajaxReturn($result);
  104. }
  105. }
  106. /*
  107. * 获取需要激活的二维码
  108. * 并插入到redis 缓存中去
  109. * 默认 需要插入的目录Data/active/
  110. * 激活批次号:active_batch
  111. */
  112. public function getTxtActivefile($active_batch){
  113. /*$redis=new Redis();
  114. echo '待更新二维码:'. $redis->lSize("Code_Active_list"); die;
  115. $active_batch = 991156;*/
  116. set_time_limit(0);
  117. $this->active_batch = $active_batch;
  118. $dir="Data/Code_Active_list/".$active_batch.'/0/';
  119. $files=scandir($dir);
  120. $txt_file_array=array();
  121. $redis=new Redis();
  122. foreach($files as $key ){
  123. if(get_extension($key)=='txt'){
  124. //更新缓存
  125. $this->CodeStatusUpdateCache($key,'Code_Active_list','http://hn.6in7.cn/');
  126. }
  127. }
  128. /*修改表数据*/
  129. $return = M('activate_list')-> where('active_batch ='.$this->active_batch)->setField('status',0);
  130. return true;
  131. //echo '待更新二维码:'. $redis->lSize("Code_Active_list");
  132. }
  133. public function togetTxtAddfile(){
  134. $result = array();
  135. if( empty(I('bach_id')) || empty(I('tasks_id')) || empty(I('product_id')) || empty(I('printer_id')) || empty(I('task_name'))){
  136. $result['status'] = 0;
  137. $result['cont'] = '批次参数缺少';
  138. $this->ajaxReturn($result);
  139. }else{
  140. $this->tasks_id = I('tasks_id');
  141. $this->bach_id = I('bach_id');
  142. $this->product_id = I('product_id');
  143. $this->printer_id = I('printer_id');
  144. $this->task_name = I('task_name');
  145. }
  146. /*修改任务表*/
  147. $return1 = M('task')-> where('id ='.I('tasks_id'))->setField('lock',1);
  148. $return2 = $this->getTxtAddfile();
  149. /*修改激活批次表*/
  150. if($return1 && $return2){
  151. $result['status'] = 1;
  152. $result['cont'] = '任务已提交';
  153. $this->ajaxReturn($result);
  154. }
  155. }
  156. /*
  157. * 该函数需要后期后端操作,一个文件要对应 任务id,产品id,批次号等绑定
  158. * 获取需要新增的二维码
  159. * 并插入到redis 缓存中去
  160. * 默认 需要插入的目录Data/add/
  161. *
  162. */
  163. public function getTxtAddfile(){
  164. $dir="Data/Code_Add_list/".$this->task_name.'/'.get_current_admin_name() . '/'.$this->task_name.'_'.$this->tasks_id.'/0/';
  165. $files=scandir($dir);
  166. $txt_file_array=array();
  167. $redis=new Redis();
  168. foreach($files as $key ){
  169. if(get_extension($key)=='txt'){
  170. //更新缓存
  171. $this->CodeStatusUpdateCache($key,'Code_Add_list','http://hn.6in7.cn/');
  172. }
  173. }
  174. $return = M('task')-> where('id ='.I('tasks_id'))->setField('lock',0);
  175. return true;
  176. }
  177. /*
  178. * 二维码插入
  179. * redis主键 Code_Add_list
  180. * Code_Add_list每一条数据为serialize 数据,
  181. * 平均单条插别人耗时间:0.0045s,单次插入数量:5000;预计耗时:22.5s~30s
  182. * 一分钟访问两次 执行时间在30s~60s
  183. * 一分钟处理1w条数据,100w 平均耗时 100分钟=1 h 40 m
  184. */
  185. public function addCode(){
  186. $redis=new Redis();
  187. if(!$redis->lSize("Code_Add_list")){
  188. echo '没有需要插入的二维码数据';
  189. }
  190. $i=0;$j=0;
  191. // $CodeMode->startTrans();
  192. w_log('Data/Add_log.txt',time()." : 插入开始");
  193. $t1 = microtime(true);
  194. //echo $redis->lSize("Code_Add_list").'<br/>';
  195. //die;
  196. for($kk=5000;$kk>0 && $redis->lSize("Code_Add_list")>0;$kk--){
  197. $where=array();
  198. $where=unserialize($redis->rPop("Code_Add_list")) ;
  199. $where['add_time']=time();
  200. $where['update_time']=time();
  201. $where['varify_code']='';
  202. if(strpos($where['code'], ',')){
  203. $temp_code=explode(',', $where['code']);
  204. $where['code']=current($temp_code);
  205. $where['varify_code']=end($temp_code);
  206. }
  207. $task_name = $where['task_name'];
  208. $tasks_id = $where['tasks_id'];
  209. $file = $where['file'];
  210. unset($where['file']);
  211. unset($where['task_name']);
  212. $where_str='';
  213. $field_str='';
  214. foreach ( $where as $key=>$value){
  215. if($key=='varify_code'){
  216. $field_str.="`".$key."`";
  217. $where_str.="'".$value."'";
  218. }else{
  219. $field_str.="`".$key."`,";
  220. $where_str.="'".$value."',";
  221. }
  222. }
  223. $table_name= getSubTable('codes',$where['code']);
  224. $table_name = "INSERT ignore INTO `$table_name` ($field_str) VALUES ($where_str)";
  225. $Model = M();
  226. $status = $Model->execute($table_name);
  227. if($status)
  228. {
  229. $i++;
  230. M('task')->where('id = '.$tasks_id)->setInc('checked_num',1);
  231. }
  232. else{
  233. //插入错误日志
  234. $j++;
  235. $dir = "Data/Code_Add_list/".$task_name.'/admin/'.$task_name.'_'.$tasks_id.'/2/';
  236. if(!file_exists($dir)){
  237. //判断文件是否存在
  238. mkdir($dir, 0777, true);
  239. }
  240. w_log($dir.$file,time().':'.$where['code'].$where['varify_code'].'添加失败');
  241. /*错误记录表 +1*/
  242. M('task')->where('id = '.$tasks_id)->setInc('wrong_num',1);
  243. }
  244. }
  245. $t2 = microtime(true);
  246. echo '耗时'.round($t2-$t1,3).'秒<br>';
  247. echo '成功插入:'.$i.'条数据,失败:'.$j.'条数据<br>';
  248. }
  249. /*
  250. * 二维码更新状态变更
  251. * redis主键 Code_Active_list
  252. * 平均单条插别人耗时间:0.0045s,单次插入数量:5000;预计耗时:22.5s~30s
  253. * 一分钟访问两次 执行时间在30s~60s
  254. * 一分钟处理1w条数据,100w 平均耗时 100分钟=1 h 40 m
  255. */
  256. public function activeCode(){
  257. $redis=new Redis();
  258. if(!$redis->lSize("Code_Active_list")){
  259. echo '没有需要更新的二维码数据';
  260. return 'ok';
  261. }
  262. w_log('Data/Active_log.txt',time()."更新开始");
  263. $t1 = microtime(true);
  264. $i=0;$j=0;
  265. $time = time();
  266. for($kk=5000;$kk>0;$kk--){
  267. $where=array();
  268. $Active_data=unserialize($redis->rPop("Code_Active_list"));
  269. $where['code']=$Active_data['code'];
  270. if(strpos($where['code'], ',')){
  271. $where['code']=current(explode(',', $where['code']));
  272. }
  273. $where['Status']=0;
  274. $data=array();
  275. $data['Status']=1;
  276. $data['active_batch']=$Active_data['active_batch'];
  277. $data['update_time']= $time;
  278. $data['active_time']= $time;
  279. if($data['active_batch']){
  280. $table_name= getSubTable('codes',$where['code'],1);
  281. $CodeMode= M($table_name);
  282. $status=$CodeMode->where($where)->save($data);
  283. if($status)
  284. {
  285. $i++;
  286. //修改激活批次表
  287. M('activate_list')->where('active_batch = '.$data['active_batch'])->setInc('succ',1);
  288. }
  289. else{
  290. //0代表码错误,1代表重复激活,2代表系统错误
  291. $j++;
  292. //写日志
  293. $insert_data = array();
  294. $insert_data['code'] = $where['code'];
  295. $insert_data['active_batch'] = $data['active_batch'];
  296. $insert_data['time'] = $time;
  297. $return1 = $CodeMode->field('id')->where('code = '.'"'.$where['code'].'"')->select();
  298. if(count($return1)>0){
  299. $return2 = $CodeMode->field('id')->where($where)->find();
  300. if(count($return2)>0){
  301. $insert_data['error'] = 2;
  302. }else{
  303. $insert_data['error'] = 1;
  304. }
  305. }else{
  306. $insert_data['error'] = 0;
  307. }
  308. if( M('activate_list_log')->add($insert_data)){
  309. M('activate_list')->where('active_batch = '.$data['active_batch'])->setInc('fail',1);
  310. }
  311. //判断开始
  312. //w_log('Data/Active_wrong_'.$data['active_batch'].'_log.txt',time().':'.$where['code'].'更新失败');
  313. }
  314. }else{
  315. $j++;
  316. w_log('Data/Active_wrong_log.txt',time().':'.$where['code'].'更新失败,激活批次为空');
  317. }
  318. }
  319. $t2 = microtime(true);
  320. echo '耗时'.round($t2-$t1,3).'秒<br>';
  321. echo '更新成功:'.$i.'条数据,失败:'.$j.'条数据<br>';
  322. echo '还剩'.$redis->lSize("Code_Active_list").'条数据待更新<br/>';
  323. w_log('Data/Active_log.txt',time().'更新结束 共插入 条数据');
  324. }
  325. /*
  326. * redis 操作
  327. * 把需要更新的二维码
  328. * push 到 Code_Active_list主键
  329. * & redis_key redis主键
  330. * 二维码中包含的主域名
  331. */
  332. protected function CodeStatusUpdateCache($file,$redis_key='Code_Active_list',$host='http://hn.6in7.cn/'){
  333. if($redis_key=='Code_Active_list'){
  334. $dir = 'Data/'.$redis_key.'/'.$this->active_batch.'/0/'.$file;
  335. $path = 'Data/'.$redis_key.'/'.$this->active_batch.'/1/'.$file;
  336. }else{
  337. $dir = "Data/Code_Add_list/".$this->task_name.'/'.get_current_admin_name() . '/'.$this->task_name.'_'.$this->tasks_id.'/0/'.$file;
  338. $path = "Data/Code_Add_list/".$this->task_name.'/'.get_current_admin_name() . '/'.$this->task_name.'_'.$this->tasks_id.'/1/'.$file;
  339. }
  340. $cont= file_get_contents(iconv("utf-8","gbk",$dir));
  341. $cont = preg_replace('/\n|\r\n/','*',$cont);
  342. $cont =str_replace($host,"",$cont);
  343. $data = explode("*",$cont);
  344. $data = array_filter($data);
  345. $total = count($data);
  346. //写入日志
  347. w_log('Data/redis_log.txt',time().":".$file."文件插入Code_Active_list 队列中");
  348. $redis=new Redis();
  349. $i=0;
  350. foreach($data as $k=>$v){
  351. /*
  352. * 如果是插入需要对数据重组
  353. */
  354. if($redis_key=='Code_Add_list'){
  355. /*相关的参数 start*/
  356. $Insert_data['code']=$v;
  357. $Insert_data['bach_id']=$this->bach_id;
  358. $Insert_data['tasks_id']=$this->tasks_id;
  359. $Insert_data['product_id']=$this->product_id;
  360. $Insert_data['printer_id']=$this->printer_id;
  361. $Insert_data['file'] = $file;
  362. $Insert_data['task_name'] = $this->task_name;
  363. $Insert_data['Status']=0;
  364. /*相关的参数 stop*/
  365. $redis->lpush($redis_key,serialize($Insert_data));
  366. }else if($redis_key=='Code_Active_list'){
  367. $Active_data['code']=$v;
  368. $Active_data['active_batch']=$this->active_batch;
  369. $redis->lpush($redis_key,serialize($Active_data));
  370. }
  371. else{
  372. $redis->lpush($redis_key,$v);
  373. }
  374. $i++;
  375. }
  376. copy($dir, $path);
  377. unlink($dir);
  378. w_log('Data/redis_log.txt',time().":".$file."共有数据:".$total.',已插入数据:'.$i.',{$redis_key} 目前共有数据:'.$redis->lSize($redis_key));
  379. }
  380. /*
  381. * 获取分表表名
  382. */
  383. }