TestRefillClear.php 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921
  1. <?php
  2. use PHPUnit\Framework\TestCase;
  3. define('APP_ID', 'test');
  4. define('BASE_ROOT_PATH', str_replace('/test', '', dirname(__FILE__)));
  5. require_once(BASE_ROOT_PATH . '/global.php');
  6. require_once(BASE_CORE_PATH . '/lrlz.php');
  7. require_once(BASE_ROOT_PATH . '/fooder.php');
  8. class TestRefillClear extends TestCase
  9. {
  10. public static function setUpBeforeClass(): void
  11. {
  12. Base::run_util();
  13. }
  14. //docker-compose run phpcli php /var/www/html/phpunit-9.2.5.phar --filter "/(TestRefillClear::testClearFirstDay)( .*)?$/" --test-suffix TestRefillClear.php /var/www/html/test
  15. public function testClearFirstDay()
  16. {
  17. $start_date = strtotime($this->earlist_orderday());
  18. $end_date = $start_date + 86400;
  19. $this->clear($start_date,$end_date);
  20. }
  21. //2021年,8、9、10、11
  22. //docker-compose run -d phpcli php /var/www/html/phpunit-9.2.5.phar --filter "/(TestRefillClear::testDecember1)( .*)?$/" --test-suffix TestRefillClear.php /var/www/html/test
  23. public function testDecember1()
  24. {
  25. $start_date = strtotime('2021-12-01');
  26. $end_date = strtotime('2021-12-02');
  27. $this->clear($start_date,$end_date,1833109);//FL732551744393963
  28. }
  29. //docker-compose run -d phpcli php /var/www/html/phpunit-9.2.5.phar --filter "/(TestRefillClear::testDecember12)( .*)?$/" --test-suffix TestRefillClear.php /var/www/html/test
  30. public function testDecember2()
  31. {
  32. $start_date = strtotime('2021-12-02');
  33. $end_date = strtotime('2021-12-03');
  34. $this->clear($start_date,$end_date);
  35. }
  36. //docker-compose run -d phpcli php /var/www/html/phpunit-9.2.5.phar --filter "/(TestRefillClear::testDecember23)( .*)?$/" --test-suffix TestRefillClear.php /var/www/html/test
  37. public function testDecember3()
  38. {
  39. $start_date = strtotime('2021-12-03');
  40. $end_date = strtotime('2021-12-04');
  41. $this->clear($start_date,$end_date,1932237);
  42. }
  43. //docker-compose run -d phpcli php /var/www/html/phpunit-9.2.5.phar --filter "/(TestRefillClear::testDecember24)( .*)?$/" --test-suffix TestRefillClear.php /var/www/html/test
  44. public function testDecember4()
  45. {
  46. $start_date = strtotime('2021-12-04');
  47. $end_date = strtotime('2021-12-05');
  48. $this->clear($start_date,$end_date,145358);
  49. }
  50. //docker-compose run -d phpcli php /var/www/html/phpunit-9.2.5.phar --filter "/(TestRefillClear::testDecember3)( .*)?$/" --test-suffix TestRefillClear.php /var/www/html/test
  51. public function testDecember6()
  52. {
  53. $start_date = strtotime('2021-12-06');
  54. $end_date = strtotime('2021-12-07');
  55. $this->clear($start_date,$end_date,1051542);
  56. }
  57. //docker-compose run -d phpcli php /var/www/html/phpunit-9.2.5.phar --filter "/(TestRefillClear::testDecember7)( .*)?$/" --test-suffix TestRefillClear.php /var/www/html/test
  58. public function testDecember7()
  59. {
  60. $start_date = strtotime('2021-12-07');
  61. $end_date = strtotime('2021-12-08');
  62. $this->clear($start_date,$end_date);
  63. }
  64. //docker-compose run -d phpcli php /var/www/html/phpunit-9.2.5.phar --filter "/(TestRefillClear::testDecember8)( .*)?$/" --test-suffix TestRefillClear.php /var/www/html/test
  65. public function testDecember8()
  66. {
  67. $start_date = strtotime('2021-12-08');
  68. $end_date = strtotime('2021-12-09');
  69. $this->clear($start_date,$end_date);
  70. }
  71. //docker-compose run -d phpcli php /var/www/html/phpunit-9.2.5.phar --filter "/(TestRefillClear::testDecember9)( .*)?$/" --test-suffix TestRefillClear.php /var/www/html/test
  72. public function testDecember9()
  73. {
  74. $start_date = strtotime('2021-12-09');
  75. $end_date = strtotime('2021-12-10');
  76. $this->clear($start_date,$end_date);
  77. }
  78. //docker-compose run -d phpcli php /var/www/html/phpunit-9.2.5.phar --filter "/(TestRefillClear::testDecember10)( .*)?$/" --test-suffix TestRefillClear.php /var/www/html/test
  79. public function testDecember10()
  80. {
  81. $start_date = strtotime('2021-12-10');
  82. $end_date = strtotime('2021-12-11');
  83. $this->clear($start_date,$end_date);
  84. }
  85. //docker-compose run -d phpcli php /var/www/html/phpunit-9.2.5.phar --filter "/(TestRefillClear::testDecember11)( .*)?$/" --test-suffix TestRefillClear.php /var/www/html/test
  86. public function testDecember11()
  87. {
  88. $start_date = strtotime('2021-12-11');
  89. $end_date = strtotime('2021-12-12');
  90. $this->clear($start_date,$end_date);
  91. }
  92. //docker-compose run -d phpcli php /var/www/html/phpunit-9.2.5.phar --filter "/(TestRefillClear::testDecember12)( .*)?$/" --test-suffix TestRefillClear.php /var/www/html/test
  93. public function testDecember12()
  94. {
  95. $start_date = strtotime('2021-12-12');
  96. $end_date = strtotime('2021-12-14');
  97. $this->clear($start_date,$end_date);
  98. }
  99. //docker-compose run -d phpcli php /var/www/html/phpunit-9.2.5.phar --filter "/(TestRefillClear::testDecember14)( .*)?$/" --test-suffix TestRefillClear.php /var/www/html/test
  100. public function testDecember14()
  101. {
  102. $start_date = strtotime('2021-12-14');
  103. $end_date = strtotime('2021-12-15');
  104. $this->clear($start_date,$end_date);
  105. }
  106. //docker-compose run -d phpcli php /var/www/html/phpunit-9.2.5.phar --filter "/(TestRefillClear::testDecember15)( .*)?$/" --test-suffix TestRefillClear.php /var/www/html/test
  107. public function testDecember15()
  108. {
  109. $start_date = strtotime('2021-12-15');
  110. $end_date = strtotime('2021-12-16');
  111. $this->clear($start_date,$end_date);
  112. }
  113. //docker-compose run -d phpcli php /var/www/html/phpunit-9.2.5.phar --filter "/(TestRefillClear::testDecember16)( .*)?$/" --test-suffix TestRefillClear.php /var/www/html/test
  114. public function testDecember16()
  115. {
  116. $start_date = strtotime('2021-12-16');
  117. $end_date = strtotime('2021-12-20');
  118. $this->clear($start_date,$end_date);
  119. }
  120. //docker-compose run -d phpcli php /var/www/html/phpunit-9.2.5.phar --filter "/(TestRefillClear::testDecember20)( .*)?$/" --test-suffix TestRefillClear.php /var/www/html/test
  121. public function testDecember20()
  122. {
  123. $start_date = strtotime('2021-12-20');
  124. $end_date = strtotime('2022-12-28');
  125. $this->clear($start_date,$end_date);
  126. }
  127. public function testAllRecords()
  128. {
  129. $rorder_getter = function ($mchid,$mch_order,$mod_refill)
  130. {
  131. $result = [];
  132. $i = 0;
  133. while(true)
  134. {
  135. $start = $i * 1000;
  136. $ritems = $mod_refill->table('refill_order')->field('*')
  137. ->where(['mchid' => $mchid, 'mch_order' => $mch_order])
  138. ->order('order_id desc')
  139. ->limit("{$start},1000")->master(true)->select();
  140. $i++;
  141. $result = array_merge($ritems,$result);
  142. if(count($ritems) < 1000) {
  143. break;
  144. }
  145. }
  146. return $result;
  147. };
  148. $vorder_getter = function ($order_ids,$mod_vr)
  149. {
  150. $result = [];
  151. $i = 0;
  152. while(true)
  153. {
  154. $start = $i * 1000;
  155. $vitems = $mod_vr->table('vr_order')->field('*')
  156. ->where(['order_id' => ['in', $order_ids]])
  157. ->order('order_id asc')
  158. ->limit("{$start},1000")->master(true)->select();
  159. $i++;
  160. $result = array_merge($vitems,$result);
  161. if(count($vitems) < 1000) {
  162. break;
  163. }
  164. }
  165. return $result;
  166. };
  167. $mod_refill = Model('refill_order');
  168. $ritems = $rorder_getter(10234,'2021120700113026892979',$mod_refill);
  169. $oids = [];
  170. foreach ($ritems as $item) {
  171. $oids[] = $item['order_id'];
  172. }
  173. $mod_vr = Model('vr_order');
  174. $vitems = $vorder_getter($oids,$mod_vr);
  175. $ret = count($vitems) == count($ritems);
  176. }
  177. private function clear($start_date, $end_date,$line = 0)
  178. {
  179. $order_finder = function ($start,$fp)
  180. {
  181. $end = $start + 3600;
  182. $cond = ['order_time&order_time' => ['_multi' => true, ['egt', $start], ['lt', $end]],
  183. 'inner_status' => 0];
  184. $i = 0;
  185. while (true)
  186. {
  187. $start = $i * 1000;
  188. $items = Model()->table('refill_order')
  189. ->field('mchid,mch_order,order_time')
  190. ->where($cond)
  191. ->order('order_time desc')->limit("{$start},1000")->select();
  192. $i++;
  193. if(empty($items)) break;
  194. foreach ($items as $item) {
  195. fputcsv($fp,$item);
  196. }
  197. }
  198. };
  199. $order_saver = function ($start,$file) use ($order_finder)
  200. {
  201. if(file_exists($file)) {
  202. return $file;
  203. }
  204. $fp = fopen($file,'w+');
  205. if($fp === false) {
  206. Log::record("Cannot open file {$file}.",Log::ERR);
  207. return false;
  208. }
  209. $end = $start + 86400;
  210. for ($hour = $start; $hour < $end; $hour += 3600) {
  211. $order_finder($hour,$fp);
  212. }
  213. fclose($fp);
  214. return $file;
  215. };
  216. $handle_days = function ($start_date, $end_date,$line = 0) use ($order_saver)
  217. {
  218. for ($date = $start_date; $date < $end_date; $date += 86400)
  219. {
  220. $sdate = date('Y-m-d',$date);
  221. $morder_file = BASE_DATA_PATH . "/log/order/{$sdate}-morder.csv";
  222. $check_file = BASE_DATA_PATH . "/log/order/{$sdate}-check.csv";
  223. $refill_file = BASE_DATA_PATH . "/log/order/{$sdate}-refill.csv";
  224. $vr_file = BASE_DATA_PATH . "/log/order/{$sdate}-vr.csv";
  225. $file = $order_saver($date,$morder_file);
  226. if($file === false) {
  227. Log::record("order_saver cannot open morder file.",Log::ERR);
  228. break;
  229. }
  230. $this->order_delete($file,$check_file,$refill_file,$vr_file,$line);
  231. }
  232. };
  233. $handle_days($start_date, $end_date,$line);
  234. }
  235. private function order_delete($file,$check_file,$refill_file,$vr_file,$line)
  236. {
  237. $rorder_getter = function ($mchid,$mch_order,$mod_refill)
  238. {
  239. $result = [];
  240. $i = 0;
  241. while(true)
  242. {
  243. $start = $i * 1000;
  244. $ritems = $mod_refill->table('refill_order')->field('*')
  245. ->where(['mchid' => $mchid, 'mch_order' => $mch_order])
  246. ->order('order_id desc')
  247. ->limit("{$start},1000")->master(true)->select();
  248. $i++;
  249. $result = array_merge($ritems,$result);
  250. if(count($ritems) < 1000) {
  251. break;
  252. }
  253. }
  254. return $result;
  255. };
  256. $vorder_getter = function ($order_ids,$mod_vr)
  257. {
  258. $result = [];
  259. $i = 0;
  260. while(true)
  261. {
  262. $start = $i * 1000;
  263. $vitems = $mod_vr->table('vr_order')->field('*')
  264. ->where(['order_id' => ['in', $order_ids]])
  265. ->order('order_id asc')
  266. ->limit("{$start},1000")->master(true)->select();
  267. $i++;
  268. $result = array_merge($vitems,$result);
  269. if(count($vitems) < 1000) {
  270. break;
  271. }
  272. }
  273. return $result;
  274. };
  275. $order_checker = function ($mchid,$mch_order,$frefill,$fvr) use($rorder_getter,$vorder_getter)
  276. {
  277. $mod_refill = Model('refill_order');
  278. $ritems = $rorder_getter($mchid,$mch_order,$mod_refill);
  279. if(empty($ritems)) {
  280. return [false,'没查到记录.'];
  281. }
  282. elseif(count($ritems) === 1) {
  283. return [true,[]];
  284. }
  285. $oids = [];
  286. $inner_state = [0 => 0 ,1 => 1];
  287. foreach ($ritems as $item) {
  288. $oids[] = $item['order_id'];
  289. $state = intval($item['inner_status']);
  290. $inner_state[$state] += 1;
  291. }
  292. //检查inner_status=0唯一。
  293. if($inner_state[0] != 1) {
  294. return [false,"inner_status=0 counts = {$inner_state[0]}"];
  295. }
  296. $mod_vr = Model('vr_order');
  297. $vitems = $vorder_getter($oids,$mod_vr);
  298. //检查refill 表记录和vr_order表记录是否一致
  299. if(count($ritems) !== count($vitems)) {
  300. return [false,'refill_orders != vr_orders'];
  301. }
  302. $order_state = [];
  303. foreach ($vitems as $item)
  304. {
  305. $state = intval($item['order_state']);
  306. if(!array_key_exists($state,$order_state)) {
  307. $order_state[$state] = 0;
  308. }
  309. $order_state[$state] += 1;
  310. }
  311. //检查一种订单只能有,成功或者失败状态.
  312. $vcount = count($vitems);
  313. if($vcount != $order_state[ORDER_STATE_SUCCESS] + $order_state[ORDER_STATE_CANCEL]) {
  314. return [false,'ORDER_STATE_SUCCESS + ORDER_STATE_CANCEL != order count.'];
  315. }
  316. elseif($order_state[ORDER_STATE_SUCCESS] > 1) {
  317. //成功订单只能小于等于1,否则为错误
  318. return [false,'ORDER_STATE_SUCCESS count > 1'];
  319. }
  320. else {
  321. foreach ($ritems as $item) {
  322. fputcsv($frefill,$item);
  323. }
  324. foreach ($vitems as $item) {
  325. fputcsv($fvr,$item);
  326. }
  327. }
  328. $inner_orders = [];
  329. foreach ($ritems as $item)
  330. {
  331. $status = intval($item['inner_status']);
  332. if($status === 1) {
  333. $inner_orders[] = $item['order_id'];
  334. }
  335. }
  336. return [true,$inner_orders];
  337. };
  338. $delter = function ($order_ids,$order_time)
  339. {
  340. $mod_refill = Model('refill_order');
  341. $mod_refill->table('refill_order')->where(['order_id' => ['in',$order_ids],'order_time' => $order_time])->delete();
  342. $mod_vr = Model('vr_order');
  343. $mod_vr->table('vr_order')->where(['order_id' => ['in',$order_ids]])->delete();
  344. };
  345. $position = function ($fp,$line)
  346. {
  347. $index = 0;
  348. while(!feof($fp) && $index < $line) {
  349. $items = fgetcsv($fp);
  350. $index += 1;
  351. }
  352. };
  353. $fp = fopen($file,'r');
  354. if($fp === false) {
  355. return false;
  356. }
  357. $fcheck = fopen($check_file,'a+');
  358. if($fcheck === false) {
  359. fclose($fp);
  360. return false;
  361. }
  362. $frefill = fopen($refill_file,'a+');
  363. $fvr = fopen($vr_file,'a+');
  364. $position($fp,$line);
  365. while(!feof($fp))
  366. {
  367. [$mchid, $mch_order, $order_time] = fgetcsv($fp);
  368. if(empty($mchid) || empty($mch_order)) continue;
  369. [$succ,$err] = $order_checker($mchid,$mch_order,$frefill,$fvr);
  370. if($succ === false) {
  371. fputcsv($fcheck,[$mchid,$mch_order,$err]);
  372. }
  373. else
  374. {
  375. $order_ids = $err;
  376. if(!empty($order_ids)) {
  377. $delter($order_ids,$order_time);
  378. }
  379. }
  380. }
  381. fclose($fp);
  382. fclose($fcheck);
  383. fclose($frefill);
  384. fclose($fvr);
  385. }
  386. private function earlist_orderday()
  387. {
  388. $mod_refill = Model('refill_order');
  389. $item = $mod_refill->table('refill_order')->field('order_time')->order('order_id asc')->find();
  390. if(empty($item)) {
  391. return false;
  392. } else {
  393. $order_time = intval($item['order_time']);
  394. $day_stamp = date('Y-m-d',$order_time);
  395. return $day_stamp;
  396. }
  397. }
  398. public function testEarlist()
  399. {
  400. $time = $this->earlist_orderday();
  401. }
  402. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  403. /// 以下代码为清除pdlog
  404. const pdlog_table_name = 'pd_log_bak';
  405. //docker-compose run -d phpcli php /var/www/html/phpunit-9.2.5.phar --filter "/(TestRefillClear::testLogSeventh)( .*)?$/" --test-suffix TestRefillClear.php /var/www/html/test
  406. public function testLogSeventh()
  407. {
  408. $this->delete_log(74224997,strtotime('2021-09-01'));
  409. }
  410. //docker-compose run -d phpcli php /var/www/html/phpunit-9.2.5.phar --filter "/(TestRefillClear::testLogNine)( .*)?$/" --test-suffix TestRefillClear.php /var/www/html/test
  411. public function testLogNine()
  412. {
  413. $this->delete_log(127113184,strtotime('2021-10-01'));
  414. }
  415. //docker-compose run -d phpcli php /var/www/html/phpunit-9.2.5.phar --filter "/(TestRefillClear::testLogTen)( .*)?$/" --test-suffix TestRefillClear.php /var/www/html/test
  416. public function testLogTen()
  417. {
  418. $this->delete_log(306132968,strtotime('2021-11-01'));
  419. }
  420. //docker-compose run -d phpcli php /var/www/html/phpunit-9.2.5.phar --filter "/(TestRefillClear::testLogEleven)( .*)?$/" --test-suffix TestRefillClear.php /var/www/html/test
  421. public function testLogEleven()
  422. {
  423. $this->delete_log(619026072,strtotime('2021-12-01'));
  424. }
  425. //docker-compose run -d phpcli php /var/www/html/phpunit-9.2.5.phar --filter "/(TestRefillClear::testLogDec20)( .*)?$/" --test-suffix TestRefillClear.php /var/www/html/test
  426. public function testLogDec20()
  427. {
  428. $this->delete_log(1079138574,strtotime('2021-12-20'));
  429. }
  430. private function delete_log($start_id,$endtime)
  431. {
  432. //需要的函数
  433. $lgid_getter = function ()
  434. {
  435. $lgid = rkcache('lastest_lgid');
  436. $lgid = intval($lgid);
  437. return $lgid;
  438. };
  439. $lgid_writter = function ($lgid)
  440. {
  441. wkcache('lastest_lgid',$lgid);
  442. };
  443. $maxid_getter = function () {
  444. $items = Model()->table(self::pdlog_table_name)->field('max(lg_id) as maxid')->select();
  445. return intval($items['0']['maxid']);
  446. };
  447. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  448. $mod_refill = Model('refill_order');
  449. $pd_log = Model();
  450. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  451. /// 一条一条的删除日志
  452. $finder = function ($start_id, $endtime, $maxid)
  453. {
  454. $start = $start_id;
  455. $quit = false;
  456. while (!$quit)
  457. {
  458. if($start >= $maxid) break;
  459. $end = $start + 1000;
  460. $cond = ['lg_id' => [['egt', $start], ['lt',$end], 'and']];
  461. $items = Model()->table(self::pdlog_table_name)
  462. ->field('*')
  463. ->where($cond)
  464. ->order('lg_id asc')->select();
  465. foreach ($items as $item)
  466. {
  467. $add_time = intval($item['lg_add_time']);
  468. if($add_time >= $endtime){
  469. $quit = true;
  470. break;
  471. }
  472. yield $item;
  473. }
  474. $start = $end;
  475. }
  476. };
  477. $checker = function ($log) use ($mod_refill)
  478. {
  479. $sdate = date('Y-m-d H:i:s',$log['lg_add_time']);
  480. Log::record("{$sdate} lgid={$log['lg_id']},type={$log['lg_type']},sn={$log['lg_order_sn']}",Log::DEBUG);
  481. $logid = intval($log['lg_id']);
  482. $lgtype = $log['lg_type'];
  483. if (in_array($lgtype, ['bonus_add_money','hand_out_bonus', 'bonus_refund', 'bonus_expire'])) {
  484. return [$logid,false];
  485. }
  486. $order_sn = $log['lg_order_sn'];
  487. if(empty($order_sn) && strlen($order_sn) < 16) {
  488. return [false,false];
  489. }
  490. if (!in_array($lgtype, ['order_pay', 'order_freeze', 'order_cancel'])) {
  491. return [false,false];
  492. }
  493. $order = $mod_refill->table('refill_order')->field('*')->where(['order_sn' => $order_sn])->master(true)->find();
  494. if(empty($order)) {
  495. return [$logid,true];
  496. } else {
  497. return [false,false];
  498. }
  499. };
  500. $delter = function ($logid) use ($pd_log)
  501. {
  502. if ($logid > 0) {
  503. $result = $pd_log->table(self::pdlog_table_name)->where(['lg_id' => $logid])->delete();
  504. return $result;
  505. } else {
  506. return false;
  507. }
  508. };
  509. $onebyone_handler = function ($start_id,$endtime,$maxid,$fLog) use($finder,$checker,$delter)
  510. {
  511. $logs = $finder($start_id,$endtime,$maxid);
  512. foreach ($logs as $item)
  513. {
  514. [$logid,$save] = $checker($item);
  515. if($logid !== false) {
  516. $delter($logid);
  517. }
  518. if($save) {
  519. fputcsv($fLog,$item);
  520. }
  521. }
  522. };
  523. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  524. /// 一批一批的删除日志
  525. $batch_finder = function ($start_id, $endtime, $maxid)
  526. {
  527. $start = $start_id;
  528. $quit = false;
  529. while (!$quit)
  530. {
  531. if($start >= $maxid) break;
  532. $end = $start + 200;
  533. $cond = ['lg_id' => [['egt', $start], ['lt',$end], 'and']];
  534. $items = Model()->table(self::pdlog_table_name)
  535. ->field('*')
  536. ->where($cond)
  537. ->order('lg_id asc')->select();
  538. $logs = [];
  539. foreach ($items as $item)
  540. {
  541. $add_time = intval($item['lg_add_time']);
  542. if($add_time >= $endtime){
  543. $quit = true;
  544. break;
  545. }
  546. else {
  547. $logs[] = $item;
  548. }
  549. }
  550. if(!empty($logs)) {
  551. yield $logs;
  552. }
  553. $start = $end;
  554. }
  555. };
  556. //return:1,可以直接删除,不需要存储; 2,不可以删除,3,检查后可以删除
  557. $batch_check_log = function ($log)
  558. {
  559. $sdate = date('Y-m-d H:i:s',$log['lg_add_time']);
  560. Log::record("{$sdate} lgid={$log['lg_id']},type={$log['lg_type']},sn={$log['lg_order_sn']}",Log::DEBUG);
  561. $logid = intval($log['lg_id']);
  562. $order_sn = $log['lg_order_sn'];
  563. $lgtype = $log['lg_type'];
  564. if (in_array($lgtype, ['bonus_add_money','hand_out_bonus', 'bonus_refund', 'bonus_expire'])) {
  565. return [1,$logid,$order_sn];
  566. }
  567. if(empty($order_sn) && strlen($order_sn) < 16) {
  568. return [2,false,false];
  569. }
  570. if (!in_array($lgtype, ['order_pay', 'order_freeze', 'order_cancel'])) {
  571. return [2,false,false];
  572. }
  573. return [3,$logid,$order_sn];
  574. };
  575. $batch_checker = function ($logs) use ($mod_refill,$batch_check_log)
  576. {
  577. $del_ids = [];
  578. $savers = [];
  579. $exist_logs = [];
  580. $sns = [];
  581. foreach ($logs as $log)
  582. {
  583. [$type,$logid,$order_sn] = $batch_check_log($log);
  584. if($type === 1) {
  585. $del_ids[] = $logid;
  586. }
  587. elseif($type === 3) {
  588. $exist_logs[$logid] = $log;
  589. $sns[] = $order_sn;
  590. }
  591. else {
  592. }
  593. }
  594. if(!empty($sns))
  595. {
  596. $sns = array_unique($sns);
  597. $orders = $mod_refill->table('refill_order')->field('order_sn')->where(['order_sn' => ['in', $sns]])->master(true)->select();
  598. $sn_sns = [];
  599. foreach ($orders as $item) {
  600. $sn = $item['order_sn'];
  601. $sn_sns[$sn] = $sn;
  602. }
  603. foreach ($exist_logs as $logid => $log)
  604. {
  605. $sn = $log['lg_order_sn'];
  606. if(!array_key_exists($sn,$sn_sns)) {
  607. $del_ids[] = $logid;
  608. $savers[] = $log;
  609. }
  610. }
  611. }
  612. return [$del_ids,$savers];
  613. };
  614. $batch_delter = function ($logids) use ($pd_log)
  615. {
  616. if (!empty($logids)) {
  617. $result = $pd_log->table(self::pdlog_table_name)->where(['lg_id' => ['in',$logids]])->delete();
  618. return $result;
  619. } else {
  620. return false;
  621. }
  622. };
  623. $batch_handler = function ($start_id,$endtime,$maxid,$fLog) use($batch_finder,$batch_checker,$batch_delter)
  624. {
  625. $logs = $batch_finder($start_id,$endtime,$maxid);
  626. foreach ($logs as $batch)
  627. {
  628. [$logids,$savers] = $batch_checker($batch);
  629. $batch_delter($logids);
  630. foreach ($savers as $item) {
  631. fputcsv($fLog,$item);
  632. }
  633. }
  634. };
  635. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  636. if($start_id === 0) {
  637. $start_id = $lgid_getter();
  638. }
  639. $cur_time = time();
  640. $sdate = date('Y-m-d',time());
  641. $filename = BASE_DATA_PATH . "/log/pdlog/{$sdate}-{$cur_time}.csv";
  642. $fLog = fopen($filename,'w+');
  643. $logid = $start_id;
  644. $maxid = $maxid_getter();
  645. // $onebyone_handler($start_id,$endtime,$maxid,$fLog);
  646. $batch_handler($start_id,$endtime,$maxid,$fLog);
  647. $lgid_writter($logid);
  648. }
  649. public function testImport()
  650. {
  651. $filename = BASE_DATA_PATH . "/log/pdlog/2022-01-02-1641055749.csv";
  652. $this->import_pdlog($filename);
  653. }
  654. //docker-compose run -d phpcli php /var/www/html/phpunit-9.2.5.phar --filter "/(TestRefillClear::testImportNine)( .*)?$/" --test-suffix TestRefillClear.php /var/www/html/test
  655. public function testImportNine()
  656. {
  657. $filename = BASE_DATA_PATH . "/log/pdlog/2021-09-01.csv";
  658. $this->import_pdlog($filename);
  659. }
  660. //docker-compose run -d phpcli php /var/www/html/phpunit-9.2.5.phar --filter "/(TestRefillClear::testImportTen)( .*)?$/" --test-suffix TestRefillClear.php /var/www/html/test
  661. public function testImportTen()
  662. {
  663. $filename = BASE_DATA_PATH . "/log/pdlog/2022-01-03-1641141137.csv";
  664. $this->import_pdlog($filename);
  665. }
  666. private function import_pdlog($filename,$start_line = 0)
  667. {
  668. $position = function ($fp,$line)
  669. {
  670. $index = 0;
  671. while(!feof($fp) && $index < $line) {
  672. $items = fgetcsv($fp);
  673. $index += 1;
  674. }
  675. };
  676. $reader = function ($fp)
  677. {
  678. while(!feof($fp))
  679. {
  680. $logs = [];
  681. for ($index = 0; $index < 200 && !feof($fp); $index++) {
  682. $log = fgetcsv($fp);
  683. $logs[] = $log;
  684. }
  685. yield $logs;
  686. }
  687. };
  688. $converter = function ($logs)
  689. {
  690. $result = [];
  691. $sns = [];
  692. foreach ($logs as $log) {
  693. $item = [];
  694. $logid = $log[0];
  695. $item['lg_id'] = $log[0];
  696. $item['lg_member_id'] = $log[1];
  697. $item['lg_member_name'] = $log[2];
  698. $item['lg_admin_name'] = $log[3];
  699. $item['lg_type'] = $log[4];
  700. $item['lg_av_amount'] = $log[5];
  701. $item['lg_freeze_amount'] = $log[6];
  702. $item['lg_add_time'] = $log[7];
  703. $item['lg_desc'] = $log[8];
  704. $item['lg_order_sn'] = $log[9];
  705. $item['lg_available'] = $log[10];
  706. $sns[] = $log[9];
  707. $result[$logid] = $item;
  708. }
  709. return [$result,$sns];
  710. };
  711. $mod_refill = Model('refill_order');
  712. $filter = function ($logs,$sns) use($mod_refill)
  713. {
  714. $sns = array_unique($sns);
  715. $sn2sn = [];
  716. $orders = $mod_refill->table('refill_order')->field('order_sn')->where(['order_sn' => ['in', $sns]])->master(true)->select();
  717. foreach ($orders as $order) {
  718. $sn = $order['order_sn'];
  719. $sn2sn[$sn] = $sn;
  720. }
  721. $inserts = [];
  722. $dels = [];
  723. foreach ($logs as $lgid => $log)
  724. {
  725. $sn = $log['lg_order_sn'];
  726. if(array_key_exists($sn,$sn2sn)) {
  727. $inserts[] = $log;
  728. } else {
  729. $dels[] = $log;
  730. }
  731. }
  732. return [$inserts,$dels];
  733. };
  734. $inserter = function ($records)
  735. {
  736. if(empty($records)) return false;
  737. try {
  738. $ret = Model()->table(self::pdlog_table_name)->insertAll($records);
  739. return $ret;
  740. }
  741. catch (Exception $ex) {
  742. Log::record($ex->getMessage(),Log::ERR);
  743. return false;
  744. }
  745. };
  746. $delname = BASE_DATA_PATH . "/log/pdlog/del.csv";
  747. $fDel = fopen($delname,'a+');
  748. $delter = function ($records) use ($fDel)
  749. {
  750. foreach ($records as $item) {
  751. $log = [];
  752. $log[] = $item['lg_id'];
  753. $log[] = $item['lg_member_id'];
  754. $log[] = $item['lg_member_name'];
  755. $log[] = $item['lg_admin_name'];
  756. $log[] = $item['lg_type'];
  757. $log[] = $item['lg_av_amount'];
  758. $log[] = $item['lg_freeze_amount'];
  759. $log[] = $item['lg_add_time'];
  760. $log[] = $item['lg_desc'];
  761. $log[] = $item['lg_order_sn'];
  762. $log[] = $item['lg_available'];
  763. fputcsv($fDel,$log);
  764. }
  765. };
  766. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  767. $fLog = fopen($filename,'r');
  768. $position($fLog,$start_line);
  769. $logger = $reader($fLog);
  770. foreach ($logger as $items) {
  771. [$logs, $sns] = $converter($items);
  772. [$inserts, $dels] = $filter($logs, $sns);
  773. $inserter($inserts);
  774. $delter($dels);
  775. }
  776. fclose($fLog);
  777. fclose($fDel);
  778. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  779. }
  780. }