ChannelSettleMonth.php 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. <?php
  2. /**
  3. * 公会未结算数据统计定时器脚本
  4. *
  5. */
  6. namespace app\crontab;
  7. set_time_limit(0);
  8. use think\console\Command;
  9. use think\console\Input;
  10. use think\console\Output;
  11. use think\console\Input\Argument;
  12. use think\Db;
  13. use think\Env;
  14. class ChannelSettleMonth extends Command {
  15. protected $_output;
  16. protected function configure() {
  17. $this->addArgument('execMonth', Argument::OPTIONAL); //指定统计的日期时,格式Y-m
  18. $this->setName('ChannelSettleMonth')->setDescription('公会未结算数据统计脚本');
  19. }
  20. protected function execute(Input $input, Output $output) {
  21. ini_set('memory_limit', '1024M');
  22. set_time_limit(3600);
  23. $month = $input->getArgument('execMonth'); //指定的执行月份
  24. $this->_output = $output;
  25. //指定统计的月份时
  26. if(!empty($month)){
  27. $start_time = mktime(0,0,0,date('m',strtotime($month)),01);
  28. $end_time = mktime(0,0,0,date('m',strtotime($month))+1,01)-1;
  29. }
  30. //未指定统计的月份时
  31. else{
  32. $start_time = mktime(0,0,0,date('m')-1,01); //上一个自然月的第一天
  33. $end_time = mktime(0,0,0,date('m'),01)-1; //上一个自然月的最后一天
  34. }
  35. $output->writeln(date('Y-m-d H:i:s')." ChannelSettleMonth start\r\n");
  36. //有流水的公会账号
  37. $guild_channel_list = Db::table('cy_pay')->alias('p')
  38. ->join('nw_channel c1', 'p.channel_id = c1.id')
  39. ->join('nw_channel c2', 'c1.parent_id = c2.id')
  40. ->join('nw_channel c3', 'c2.parent_id = c3.id')
  41. ->field('DISTINCT (case when c2.`level`=1 then c2.id else c3.id end) as guild_channel_id')
  42. ->where(['p.status'=>1,'p.create_time'=>['<=',$end_time]])
  43. // ->where(['p.status'=>1])
  44. ->select();
  45. $output->writeln("guild_channel_list sql: ".Db::table('cy_pay')->getLastSql()."\r\n");
  46. if(!empty($guild_channel_list)){
  47. $arr = [];
  48. foreach($guild_channel_list as $key=>$value){
  49. $where = [];
  50. $where['p.status'] = 1;
  51. $channel_id = $value['guild_channel_id'];
  52. $channelIds = get_child_channel_arr($channel_id);
  53. array_push($channelIds,$channel_id);
  54. $where['p.channel_id'] = ['in',$channelIds];
  55. $where['p.settle_id'] = 0;
  56. $where['p.create_time'] = ['<=',$end_time];
  57. $GameChannelData = Db::table('cy_pay')->alias('p')
  58. ->join('cy_game g', 'p.gameid = g.id','inner')
  59. ->join('nw_game_channel_divide d','p.gameid = d.game_id and d.channel_id='.$channel_id,'left')
  60. ->field("p.gameid AS game_id,g.name as game_name,g.channel_split_ratio,count(*) as pay_cnt,SUM(p.amount) AS pay_amt,d.id as ratio_id,d.ratio,SUM(p.real_amount) AS pay_real_amt,SUM(p.real_ptb) AS pay_real_ptb")
  61. ->where($where)
  62. ->group('p.gameid')
  63. ->select();
  64. $total_amt = $divide_amt = $total_cnt = 0;
  65. foreach ( $GameChannelData as &$det ) {
  66. if(intval($det['ratio_id'])){
  67. $ratio_id = $det['ratio_id'];
  68. $ratio = floatval($det['ratio']);
  69. }
  70. else{
  71. $ratio_id = 0;
  72. $ratio = floatval($det['channel_split_ratio']);
  73. }
  74. if(!$ratio){
  75. $template = '您尚有游戏未配置分成比例,游戏名:'.$det['game_name'].',请先设置分成比例 。时间:'.date('Y-m-d H:i:s');
  76. $ddurl = Env::get('operat_url');
  77. curlDD($template, $ddurl,true);
  78. }
  79. else{
  80. $total_cnt += floatval($det['pay_cnt']);
  81. $total_amt += floatval($det['pay_amt']);
  82. $divide_amt += floatval(intval($det['pay_amt'] * $ratio) / 100);
  83. }
  84. }
  85. //总流水
  86. $settle_apply_amt = $unwithdraw_amt = $withdraw_apply_amt = 0;
  87. $settle_apply_amt = floatval(Db::table('nw_game_channel_divide_settle')->where(['channel_id'=>$channel_id,'first_audit_status'=>1,'second_audit_status'=>0])->sum('total_divide_amt'));
  88. $channelInfo = Db::table('nw_channel')->field('id,name,amount,js_amount')->where(['id'=>$channel_id])->find();
  89. if($channelInfo){
  90. $unwithdraw_amt = $channelInfo['js_amount'];
  91. }
  92. $withdraw_apply_amt = floatval(Db::table('nw_channel_withdraw')->where(['channel_id'=>$channel_id,'status'=>0])->sum('withdraw_amt'));
  93. $arr[$key][0] = $channel_id;
  94. $arr[$key][1] = date('Y-m',$end_time);
  95. $arr[$key][2] = $total_amt;
  96. $arr[$key][3] = $total_cnt;
  97. $arr[$key][4] = $divide_amt;
  98. $arr[$key][5] = $settle_apply_amt;
  99. $arr[$key][6] = $unwithdraw_amt;
  100. $arr[$key][7] = $withdraw_apply_amt;
  101. $arr[$key][8] = time();
  102. $arr[$key][9] = time();
  103. }
  104. $arr_key = array('channel_id','month','unsettle_total_amt','unsettle_cnt','unsettle_amt','settle_apply_amt','unwithdraw_amt','withdraw_apply_amt','create_time','update_time');
  105. $arr_update = array('unsettle_total_amt','unsettle_cnt','unsettle_amt','settle_apply_amt','unwithdraw_amt','withdraw_apply_amt','update_time');
  106. $execInfo = $this->multArray2InsertExec('nw_channel_month_data',$arr_key,$arr,$arr_update);
  107. if ($execInfo['code'] == 0) {
  108. $output->writeln("insert error:".json_encode($execInfo)." time:".date('Y-m-d H:i:s')."\r\n");
  109. }
  110. }
  111. $output->writeln(date('Y-m-d H:i:s')." ChannelSettleMonth end\r\n");
  112. exit;
  113. }
  114. /**
  115. * 多条数据同时转化成插入SQL语句,并执行SQL语句,支持批量更新和新增
  116. *
  117. * @param string $table 表名
  118. * @param array $arr_key 是表字段名的key:$arr_key=array('field1','field2','field3')
  119. * @param array $arr 是字段值 数组示例 arrat(('a','b','c'), ('bbc','bbb','caaa'),('add','bppp','cggg'))
  120. * @param array $arr_list 是需要更新的表字段名的key $arr_list=array('field1','field2','field3')
  121. * @param string $split
  122. *
  123. * @return array
  124. */
  125. private function multArray2InsertExec($table,$arr_key,$arr,$arr_list,$split='`')
  126. {
  127. $arrValues=array();
  128. $arrListValues = array();
  129. if ( empty($table) || !is_array($arr_key) || !is_array($arr) || !is_array($arr_list)) {
  130. return ['code'=> 0, 'msg' => 'multArray2Insert param ERROR '];
  131. }
  132. $sql = "INSERT INTO %s( %s ) values %s on duplicate key update %s";
  133. foreach ($arr as $k => $v) {
  134. $arrValues[$k] = "'".implode("','", array_values($v))."'";
  135. }
  136. foreach ($arr_list as $k => $v) {
  137. $arrListValues[$k] = $v . "=values(".$v.')';
  138. }
  139. $sql = sprintf($sql,$table,"{$split}" .implode("{$split} ,{$split}",$arr_key) . "{$split}", "(". implode("),(",array_values($arrValues)) . ")",implode(',',$arrListValues));
  140. $this->_output->writeln(" insert sql: {$sql} \r\n");
  141. if($sql){
  142. try {
  143. $result = Db::execute($sql);
  144. } catch (\think\exception\PDOException $e) {
  145. return ['code'=> 0, 'msg' => 'InsertSql ERROR '.$e->getMessage()];
  146. }
  147. return ['code'=> 1, 'msg' => 'SUCCESS'];
  148. }else{
  149. return ['code'=> 0, 'msg' => 'InsertSql Null'];
  150. }
  151. }
  152. }