membersModel = new MembersModel; $this->where = []; $this->gameList = $gameList = model('Common/Game')->getAllByCondition('id,name'); $tmpSelfGameList = model('Common/Game')->getAllByCondition('id,name', [], '', 'self'); $selfGameList = array(); foreach ($tmpSelfGameList as $game) { $selfGameList[$game['id']] = $game; } $this->selfGameList = $selfGameList; } public function getWhere() { $where = []; // 推广四联查询 $business_type = input('tg_business', ''); // 商务 $president_type = input('tg_president', ''); // 会长 $president_type_son = input('tg_president_son', ''); // 子会长 $promoter_type = input('tg_promoter', ''); // 推广员 if ($business_type <> '') { $where['s.channel_id'] = ['in', get_child_channel_arr($business_type)]; } if ($president_type <> '') { $where['s.channel_id'] = ['in', get_child_channel_arr($president_type)]; } if ($president_type_son <> '') { $where['s.channel_id'] = ['in', get_child_channel_arr($president_type_son)]; } if ($promoter_type <> '') { $where['s.channel_id'] = $promoter_type; } !empty($flag = input('sub_flag')) && $where['s.flag'] = $flag; !empty($sub_gameid = input('sub_gameid')) && $where['s.game_id'] = $sub_gameid; !empty($sub_id = input('sub_id')) && $where['s.id'] = $sub_id; !empty($sub_username = input('sub_username')) && $where['s.sub_username'] = ['like', '%' . $sub_username . '%']; !empty($m_nickname = input('m_nickname')) && $where['m.nickname'] = ['like', '%' . $m_nickname . '%']; $m_username = input('m_username'); if(!empty($m_username)) { $mid = Db::table('cy_members')->where(['username' => $m_username])->value('id'); $where['s.member_id'] = $mid; } // 获取查询日期 $start_time = input('start_time'); $end_time = input('end_time'); // 如果没有传入日期,设置默认值(最近7天) // if (empty($start_time)) { // $start_time = date('Y-m-d', strtotime('-7 days')); // } // if (empty($end_time)) { // $end_time = date('Y-m-d'); // } // 赋值给类属性,供模板使用 $this->start_time = $start_time; $this->end_time = $end_time; // if ($username=='' && $id == '' && $nickname == ''){ // if(strtotime($this->end_time.' 23:59:59')-strtotime($this->start_time)>31*24*3600) // { // $this->error('单次查询日期的最长跨度为31天'); // } // } if (!empty(input('gh_status'))) { // 是否聚合用户:0=否、1=是 $where['channel.gh_status'] = 1; } $this->where = $where; } /** * 注册用户列表 */ public function index() { $this->getWhere(); $param = input('get.'); $page_size = input('page_size', 15); // 设置查询条件 if ($this->start_time && $this->end_time) { $this->where['s.create_time'] = ['between time', [strtotime($this->start_time), strtotime($this->end_time . ' 23:59:59')]]; } elseif($this->start_time){ $this->where['s.create_time'] = ['>=', strtotime($this->start_time)]; } elseif($this->end_time){ $this->where['s.create_time'] = ['<=', strtotime($this->end_time. ' 23:59:59')]; } // 游戏上线状态 $cooperation_status = $this->request->param('cooperation_status', 0, 'intval'); // 游戏上线状态 if(!empty($cooperation_status)){ $game_cooperation_status = $cooperation_status==1?1:2; $gameIds = Model('Game')->getNormalByIds($game_cooperation_status); $this->where['s.game_id'] = ['in', $gameIds]; } $list = Db::table('nw_subaccount')->alias('s') ->join('cy_members m', 's.member_id=m.id', 'left') ->join('nw_channel channel', 'channel.id=s.channel_id', 'left') ->join('nw_channel bchild', 'bchild.id=channel.parent_id AND bchild.level = 2', 'left') ->field('s.id,s.sub_username,s.real_name,m.id as mid,m.username,m.nickname,m.imeil,m.ip,s.channel_id,s.game_id as gameid,s.create_time,m.total_pay_amount,s.update_time as login_time,bchild.name as bchild_name,bchild.parent_id as bcparent_id, s.flag') ->where($this->where) // ->order('reg_time desc') ->order('s.id desc') ->paginate($page_size, false, array('query' => $param)) ->each(function ($item, $key) { $channel_list = get_channel_top_by_aggregate($item['channel_id']); $item['channel_zero_name'] = !empty($channel_list['0']['name']) ? $channel_list['0']['name'] : ''; $item['channel_one_name'] = !empty($channel_list['1']['name']) ? $channel_list['1']['name'] : ''; $item['channel_two_name'] = !empty($channel_list['2']['name']) ? $channel_list['2']['name'] : ''; $item['channel_three_name'] = !empty($channel_list['3']['name']) ? $channel_list['3']['name'] : ''; return $item; }); $gameList = $this->selfGameList; $gList = $gameList; $gameList = array_column($gameList, 'name', 'id'); $data = $list->toArray()['data']; $memberIdArr = []; foreach ($data as &$v) { $memberIdArr[] = $v['id']; // $v['top_channel_name'] = get_top_channel($v['channel_id'])['name']; // $v['dep_name'] = get_channel_name($v['channel_id']); // $v['union_name'] = get_union_channel($v['channel_id'])['name']; $condition = []; $condition['userid'] = $v['id']; $condition['gameid'] = $v['gameid']; $roleinfo = (new MemberService())->queryUserRole($condition); // 账号查询 $v['rolename'] = $roleinfo['rolename']; $v['servername'] = $roleinfo['servername']; $v['rolelevel'] = $roleinfo['rolelevel']; $userPayInfo = Db::table('cy_pay')->where(['status' => 1, 'userid' => $v['mid'], 'gameid' => $v['gameid']])->field('userid, sum(amount) as money, count(id) as paycount')->find(); $v['total_pay_amount'] = isset($userPayInfo['money']) ? $userPayInfo['money'] : 0; $v['total_pay_cnt'] = isset($userPayInfo['paycount']) ? $userPayInfo['paycount'] : 0; // $v['avatar'] = $v['avatar'] ? STATIC_DOMAIN . $v['avatar'] : ''; // 账号加密 // $v['username'] = stringObfuscation($v['username'],3); } $channel = []; $channelId = input('request.channel_id'); if ($channelId) { $channel = model('Common/Channel')->field(['id', 'name'])->find($channelId); } //$channel_list = model('Common/Channel')->getAllByCondition('id,name',['status' => 1,'flag'=>['in','3,4']]); $this->assign('list', $data); $this->assign('total', $list->total()); //总条数 $this->assign('start_time', $this->start_time); $this->assign('end_time', $this->end_time); $this->assign('page', $list->render()); $this->assign('game_list', $gameList); $this->assign('glist', $gList); $this->assign('channel', $channel); $this->assign('channel_list', []); $this->assign('start_time', $this->start_time); $this->assign('end_time', $this->end_time); $uniom = model('Channel')->where(['level' => 0])->field('id,name')->select(); $this->assign('uniom', $uniom); //顶级渠道列表 $this->assign('jh_url', url('Member/index', ['gh_status' => 1, 'page_size' => '100'], 'html')); return $this->fetch(); } public function index1(){ $this->getWhere(); $param = input('get.'); $page_size = input('page_size', 15); $list = Db::table('nw_subaccount')->alias('s') ->join('cy_members m', 's.member_id=m.id', 'left') ->join('nw_channel channel', 'channel.id=s.channel_id', 'left') ->join('nw_channel bchild', 'bchild.id=channel.parent_id AND bchild.level = 2', 'left') ->field('s.id,s.sub_username,s.real_name,m.id as mid,m.username,m.nickname,m.avatar,s.channel_id,s.game_id as gameid,m.reg_time,m.ip,m.imeil,m.total_pay_amount,m.login_time,bchild.name as bchild_name,bchild.parent_id as bcparent_id, s.flag') ->where($this->where) ->order('s.id desc') ->paginate($page_size, false, array('query' => $param)); $gameList = $this->selfGameList; $gList = $gameList; $gameList = array_column($gameList, 'name', 'id'); $data = $list->toArray()['data']; if(!empty($data)){ $roleInfo = Db::table('cy_role_info') ->field(['servername', 'rolename', 'rolelevel','userid','gameid']) ->order('id', 'asc') ->select()->toArray(); foreach ($data as &$v){ foreach ($roleInfo as $val){ if($v['id']==$val['userid'] && $v['gameid']==$val['gameid']){ $v['rolename'] = $val['rolename']; $v['servername'] = $val['servername']; $v['rolelevel'] = $val['rolelevel']; } } $userPayInfo = model('Pay')->where(['status' => 1, 'userid' => $v['id']])->group('userid')->field(['userid', 'sum(amount) as money', 'count(id) as paycount'])->find(); $v['total_pay_amount'] = isset($userPayInfo->money) ? $userPayInfo->money : 0; $v['total_pay_cnt'] = isset($userPayInfo->paycount) ? $userPayInfo->paycount : 0; $v['avatar'] = $v['avatar'] ? STATIC_DOMAIN . $v['avatar'] : ''; $channel_list = get_channel_top_by_aggregate($v['channel_id']); $v['channel_zero_name'] = !empty($channel_list['0']['name']) ? $channel_list['0']['name'] : ''; $v['channel_one_name'] = !empty($channel_list['1']['name']) ? $channel_list['1']['name'] : ''; $v['channel_two_name'] = !empty($channel_list['2']['name']) ? $channel_list['2']['name'] : ''; $v['channel_three_name'] = !empty($channel_list['3']['name']) ? $channel_list['3']['name'] : ''; } } $channel = []; $channelId = input('request.channel_id'); if ($channelId) { $channel = model('Common/Channel')->field(['id', 'name'])->find($channelId); } $this->assign('list', $data); $this->assign('total', $list->total()); //总条数 $this->assign('start_time', $this->start_time); $this->assign('end_time', $this->end_time); $this->assign('page', $list->render()); $this->assign('game_list', $gameList); $this->assign('glist', $gList); $this->assign('channel', $channel); $this->assign('channel_list', []); $this->assign('start_time', $this->start_time); $this->assign('end_time', $this->end_time); $uniom = model('Channel')->where(['level' => 0])->field('id,name')->select(); $this->assign('uniom', $uniom); //顶级渠道列表 $this->assign('jh_url', url('Member/index', ['gh_status' => 1, 'page_size' => '100'], 'html')); return $this->fetch(); } /** * 报表下载 * */ public function download($is_show = ['is_show'=>false]) { if (request()->isAjax()) { $this->getWhere(false); // 设置查询条件 if ($this->start_time && $this->end_time) { $where['reg_time'] = ['between time', [strtotime($this->start_time), strtotime($this->end_time . ' 23:59:59')]]; } elseif($this->start_time){ $where['reg_time'] = ['>=', strtotime($this->start_time)]; } elseif($this->end_time){ $where['reg_time'] = ['<=', strtotime($this->end_time. ' 23:59:59')]; } // 游戏上线状态 $cooperation_status = $this->request->param('cooperation_status', 0, 'intval'); // 游戏上线状态 if(!empty($cooperation_status)){ $game_cooperation_status = $cooperation_status==1?1:2; $gameIds = Model('Game')->getNormalByIds($game_cooperation_status); $this->where['gameid'] = ['in', $gameIds]; } if ($is_show['is_show']) { $start_time = input('request.start_time', '', 'trim'); $end_time = input('request.end_time', '', 'trim'); $username = input('request.username', '', 'trim'); $gameid = input('request.gameid', '', 'intval'); if (!$start_time) { $start_time = date("Y-m-d"); } if (!$end_time) { $end_time = date("Y-m-d"); } $LogStr = "时间:" . $start_time . "~" . $end_time; if ($gameid) { $game_name = get_game_nickname($gameid); } else { $game_name = "全部游戏"; } $LogStr .= ",游戏:" . $game_name; $LogStr .= ",玩家账号:" . $username; $this->insertLog($this->current_node, $LogStr, 122); } $sql = $this->membersModel ->field('id,username,nickname,channel_id,flag,gameid,reg_time,total_pay_amount,login_time,imeil') ->where($this->where) ->order('reg_time desc')->fetchSql(true)->select(); if ((new MakeReportGo())->addTask('memberList', $sql, session_id(), $is_show)) { $this->success('报表生成的任务已经提交, 报表生成完成后,会及时通知您,请耐心稍等'); } $this->error('报表生成任务不可重复提交,如遇到无法导出情况,建议修改查询条件解除当前状态,提交重新生成报表任务!'); } else{ $this->error('非法请求'); } } public function downloadSub() { if (request()->isAjax()) { $this->getWhere(false); // 设置查询条件 if ($this->start_time && $this->end_time) { $this->where['s.create_time'] = ['between time', [strtotime($this->start_time), strtotime($this->end_time . ' 23:59:59')]]; } elseif($this->start_time){ $this->where['s.create_time'] = ['>=', strtotime($this->start_time)]; } elseif($this->end_time){ $this->where['s.create_time'] = ['<=', strtotime($this->end_time. ' 23:59:59')]; } // 游戏上线状态 $cooperation_status = $this->request->param('cooperation_status', 0, 'intval'); // 游戏上线状态 if(!empty($cooperation_status)){ $game_cooperation_status = $cooperation_status==1?1:2; $gameIds = Model('Game')->getNormalByIds($game_cooperation_status); $this->where['s.game_id'] = ['in', $gameIds]; } $sql = Db::table('nw_subaccount')->alias('s') ->join('cy_members m', 's.member_id=m.id', 'left') ->join('nw_channel channel', 'channel.id=s.channel_id', 'left') ->join('nw_channel bchild', 'bchild.id=channel.parent_id AND bchild.level = 2', 'left') ->field('s.id,s.sub_username,s.real_name,m.id as mid,m.username,m.nickname,m.imeil,m.ip,s.channel_id,s.game_id as gameid,s.create_time,m.total_pay_amount,s.update_time as login_time,bchild.name as bchild_name,bchild.parent_id as bcparent_id, s.flag') ->where($this->where) ->order('s.id desc') ->fetchSql(true)->select(); // dump($sql); if ((new MakeReportGo())->addTask('memberSubList', $sql, session_id(), [])) { $this->success('报表生成的任务已经提交, 报表生成完成后,会及时通知您,请耐心稍等'); } $this->error('报表生成任务不可重复提交,如遇到无法导出情况,建议修改查询条件解除当前状态,提交重新生成报表任务!'); } else{ $this->error('非法请求'); } } /** * 冻结账户 */ public function frozen() { $id = input('id', 0, 'intval'); $flag = input('flag', 0, 'abs'); if (empty($id)) { $this->error('用户ID不能为空'); } $members = new MembersModel(); if (!$info = $members->get(['id' => $id])) { $this->error('非法参数'); } if ($flag == 1) $msg = '冻结'; else $msg = '解冻'; if ($members->update(['flag' => $flag, 'update_time' => time(),], ['id' => $id])) { // 插入冻结记录 model('FrozenHistory')->addData($id, $flag); $info = $msg . "玩家:{$info['username']}"; $this->insertLog($this->current_node, $info, 22); $this->success($msg . '账户成功'); } else { $this->error($msg . '账户失败'); } } /** * 子账户 - 冻结/解冻 */ public function frozenSubaccount() { $id = input('id', 0, 'intval'); $flag = input('flag', 0, 'abs'); if (empty($id)) { $this->error('用户ID不能为空'); } $nw_subaccount = new Subaccount(); if (!$info = $nw_subaccount->get(['id' => $id])) { $this->error('非法参数'); } if ($flag == 1) $msg = '冻结'; else $msg = '解冻'; if ($nw_subaccount->update(['flag' => $flag, 'update_time' => time(),], ['id' => $id])) { // 插入冻结记录 model('FrozenHistory')->addData($id, $flag); $info = $msg . "玩家:{$info['sub_username']}"; $this->insertLog($this->current_node, $info, 22); $this->success($msg . '账户成功'); } else { $this->error($msg . '账户失败'); } } /** * 登录用户列表 */ private function getLoginListQuery($where) { return Db::table('cy_logininfo')->alias('l') ->join('nw_subaccount s', 's.id = l.sub_id', 'left') ->join('cy_members m', 'm.id = l.userid', 'left') ->field( 'l.id,l.ip,l.channel_id,l.userid,l.gameid,l.imeil,l.login_time,' . 's.id AS sub_id,s.sub_username,m.username,m.total_pay_amount,m.flag,' . 'COALESCE(s.create_time,l.reg_time) AS reg_time' ) ->where($where) ->order('l.login_time desc,l.id desc'); } public function loginList() { $where = $this->_getLoginListCondition(true); // 剔除聚合渠道数据 // $where['c.flag'] = ['<>',4]; $list = $this->getLoginListQuery($where) ->paginate(25, false, ['query' => input('get.')]); $data = $list->toArray()['data']; foreach ($data as $key => $value) { // 与 playerActive 保持一致:按 id_path 中的实际 level 映射推广层级。 $channelInfo = get_top_second_channel_name_v2($value['channel_id']); $data[$key]['name'] = $channelInfo['channel_name']; $data[$key]['bchild_name'] = $channelInfo['second_name']; $data[$key]['top_channel_name'] = $channelInfo['top_name']; $data[$key]['union_name'] = $channelInfo['union_name']; // 账号加密 if($value['username']){ $data[$key]['username'] = stringObfuscation($value['username'], 3); } } $gameList = $this->selfGameList; $gList = array_column($gameList, 'name', 'id'); $this->assign('list', $data); $this->assign('total', $list->total()); //总条数 $this->assign('page', $list->render()); $this->assign('game_list', $gList); $this->assign('gList', $gameList); $this->assign('start_time', $this->start_time); $this->assign('end_time', $this->end_time); $uniom = model('Channel')->where(['level' => 0])->field('id,name')->select(); $this->assign('uniom', $uniom); //顶级渠道列表 return $this->fetch('login_list'); } /** * 登录用户 报表下载 */ public function loginListDownload($is_show = ['is_show'=>false]) { if (request()->isAjax()) { $where = $this->_getLoginListCondition(true); if ($is_show['is_show']) { $start_time = input('request.start_time', '', 'trim'); $end_time = input('request.end_time', '', 'trim'); $username = input('request.username', '', 'trim'); $gameid = input('request.gameid', '', 'intval'); if (!$start_time) { $start_time = date("Y-m-d"); } if (!$end_time) { $end_time = date("Y-m-d"); } $LogStr = "时间:" . $start_time . "~" . $end_time; if ($gameid) { $game_name = get_game_nickname($gameid); } else { $game_name = "全部游戏"; } $LogStr .= ",游戏:" . $game_name; $LogStr .= ",玩家账号:" . $username; $this->insertLog($this->current_node, $LogStr, 121); } // 剔除聚合渠道数据 // $where['c.flag'] = ['<>',4]; $sql = $this->getLoginListQuery($where) ->fetchSql(true) ->select(); if((new MakeReportGo())->addTask('memberLoginList', $sql, session_id(), $is_show)){ $this->success('报表生成的任务已经提交, 报表生成完成后,会及时通知您,请耐心稍等'); } $this->error('报表生成任务不可重复提交,如遇到无法导出情况,建议修改查询条件解除当前状态,提交重新生成报表任务!'); } else { $this->error('非法请求'); } } /** * 登录用户 条件查询 * @return array */ protected function _getLoginListCondition($isdefault) { // $where['m.is_local'] = 1; $start_time = input('request.start_time', '', 'trim'); $end_time = input('request.end_time', '', 'trim'); $username = input('request.username', '', 'trim'); $sub_username = input('request.sub_username', '', 'trim'); $imeil = input('request.imeil', '', 'trim'); $gameid = input('request.gameid', '', 'intval'); $channel_id = input('channel_id', 0, 'intval'); $top_channel_id = input('parent_channel_id', 0, 'intval'); $bplus_channel_id = $this->request->param('bplus_channel_id', 0, 'intval'); // 获取查询日期 $where['l.login_time'] =$this->getTimeCondition($start_time,$end_time,$isdefault); /* if ($username==''){ if(strtotime($this->end_time.' 23:59:59')-strtotime($this->start_time)>31*24*3600) { $this->error('单次查询日期的最长跨度为31天'); } } */ //用户名 if ($username != '') { $userid = $this->membersModel->where(['username' => $username])->value('id'); $where['l.userid'] = intval($userid) ?: 0; } //游戏名称 if (!empty($gameid)) { $where['l.gameid'] = ['=', $gameid]; } // 推广四联查询 $business_type = input('business_type', input('tg_business', '')); // 商务 $president_type = input('president_type', input('tg_president', '')); // 会长 $president_type_son = input('president_type_son', input('tg_president_son', '')); // 子会长 $promoter_type = input('promoter_type', input('tg_promoter', '')); // 推广员 if ($business_type <> '') { $where['l.channel_id'] = ['in', get_child_channel_arr($business_type)]; } if ($president_type <> '') { $where['l.channel_id'] = ['in', get_child_channel_arr($president_type)]; } if ($president_type_son <> '') { $where['l.channel_id'] = ['in', get_child_channel_arr($president_type_son)]; } if ($promoter_type <> '') { $where['l.channel_id'] = $promoter_type; } //渠道名称 if ( !empty($channel_id) || !empty($top_channel_id) || !empty($bplus_channel_id)) { $where['l.channel_id'] = $this->getChannelCondition($channel_id,$top_channel_id,$bplus_channel_id); } // 游戏上线状态 $cooperation_status = $this->request->param('cooperation_status', 0, 'intval'); // 游戏上线状态 if(!empty($cooperation_status)){ $game_cooperation_status = $cooperation_status==1?1:2; $gameIds = Model('Game')->getNormalByIds($game_cooperation_status); $where['l.gameid'] = ['in', $gameIds]; } return $where; } /** * 冻结用户列表 */ public function frozenList() { $where = []; $memberIdArr = []; $where['m.flag'] = 1; //查询参数 $start_time = input('request.start_time'); $end_time = input('request.end_time'); $username = input('request.username'); $gameid = input('request.gameid'); $imeil = input('request.imeil'); //开始时间和结束时间不为空时 if ($start_time != '' && $end_time != '') { $where['m.reg_time'] = [ ['>=', strtotime($start_time)], ['<=', strtotime($end_time . ' 23:59:59')], ]; } //开始时间不为空时 elseif ($start_time != '') { $where['m.reg_time'] = ['>=', strtotime($start_time)]; } //结束时间不为空时 elseif ($end_time != '') { $where['m.reg_time'] = ['<=', strtotime($end_time . ' 23:59:59')]; } else { /* $start_time = $end_time = date('Y-m-d', time()); $where['m.reg_time'] = ['>=', strtotime($start_time)]; */ } //用户名 if ($username != '') { $where['m.username'] = ['like', '%' . $username . '%']; } //imeil if ($imeil != '') { $where['m.imeil'] = ['=', $imeil]; } //游戏名称 if ($gameid != '') { $where['m.gameid'] = ['=', $gameid]; } $list = Db::table('cy_members')->alias('m') ->join('nw_channel c', 'm.channel_id = c.id') ->field("m.id,m.imeil,m.reg_time,m.login_time,m.gameid,m.username,m.total_pay_amount,m.flag,m.channel_id,c.name, '' as remark") ->order('m.id desc') ->where($where)->paginate(10, false, ['query' => input('get.')]); $data = $list->toArray()['data']; // 处理冻结备注 $subIds = array_column($data, 'id'); $frozenMaxList = Db::table('cy_frozen_history') ->field('user_id, MAX(id) as max_id') ->where(['user_id' => ['IN', $subIds], 'status' => 1]) ->group('user_id') ->select(); $maxIds = array_column($frozenMaxList, 'max_id'); $frozenList = model('FrozenHistory')->where(['id' => ['IN', $maxIds], 'status' => 1])->order('id desc')->group('user_id')->column('user_id,remark'); foreach ($data as $key => $value) { $memberIdArr[] = $value['id']; $data[ $key ]['top_channel_name'] = get_top_channel($value['channel_id'])['name']; $data[ $key ]['bchild_name'] = get_top_second_channel_name($value['channel_id'])['second_name']; $data[$key]['remark'] = $frozenList[$value['id']] ?? ''; } $payArr = model('pay')->where(['status' => 1, 'userid' => ['IN', $memberIdArr]])->group('userid') ->column('userid,sum(amount) as money,count(id) as paycount'); $gameList = $this->selfGameList; $gList = array_column($gameList, 'name', 'id'); $this->assign('list', $data); $this->assign('total', $list->total()); //总条数 $this->assign('payArr', $payArr); $this->assign('start_time', $start_time); $this->assign('end_time', $end_time); $this->assign('page', $list->render()); $this->assign('game_list', $gameList); $this->assign('gList', $gList); return $this->fetch('frozen_list'); } /** * 冻结子用户列表 */ public function frozenSubaccountList() { $where = []; $memberIdArr = []; $where['s.flag'] = 1; //查询参数 $start_time = input('request.start_time'); $end_time = input('request.end_time'); $username = input('request.username'); $sub_username = input('request.sub_username'); $gameid = input('request.gameid'); $imeil = input('request.imeil'); //开始时间和结束时间不为空时 if ($start_time != '' && $end_time != '') { $where['s.create_time'] = [ ['>=', strtotime($start_time)], ['<=', strtotime($end_time . ' 23:59:59')], ]; } //开始时间不为空时 elseif ($start_time != '') { $where['s.create_time'] = ['>=', strtotime($start_time)]; } //结束时间不为空时 elseif ($end_time != '') { $where['s.create_time'] = ['<=', strtotime($end_time . ' 23:59:59')]; } else { /* $start_time = $end_time = date('Y-m-d', time()); $where['m.create_time'] = ['>=', strtotime($start_time)]; */ } // 子账号用户名 if ($username != '') { $where['s.sub_username'] = ['like', '%' . $sub_username . '%']; } // 用户名 if ($username != '') { $where['m.username'] = ['like', '%' . $username . '%']; } //imeil if ($imeil != '') { $where['m.imeil'] = ['=', $imeil]; } //游戏名称 if ($gameid != '') { $where['s.game_id'] = ['=', $gameid]; } $list = Db::table('nw_subaccount')->alias('s') ->join('cy_members m', 's.member_id = m.id','left') ->join('nw_channel c', 'm.channel_id = c.id','left') ->field("s.id,s.sub_username,m.id as mid,m.imeil,m.reg_time,m.login_time,s.game_id as gameid,m.username,m.total_pay_amount,s.flag,s.channel_id,c.name, '' as remark") ->order('s.id desc') ->group('s.id') ->where($where)->paginate(20, false, ['query' => input('get.')]); $data = $list->toArray()['data']; // 处理冻结备注 $subIds = array_column($data, 'id'); $frozenMaxList = Db::table('cy_frozen_history') ->field('sub_user_id, MAX(id) as max_id') ->where(['sub_user_id' => ['IN', $subIds], 'status' => 1]) ->group('sub_user_id') ->select(); $maxIds = array_column($frozenMaxList, 'max_id'); $frozenList = model('FrozenHistory')->where(['id' => ['IN', $maxIds], 'status' => 1])->order('id desc')->group('sub_user_id')->column('sub_user_id,remark'); foreach ($data as $key => $value) { $memberIdArr[] = $value['id']; $data[$key]['top_channel_name'] = get_top_channel($value['channel_id'])['name']; $data[$key]['bchild_name'] = get_top_second_channel_name($value['channel_id'])['second_name']; $data[$key]['remark'] = $frozenList[$value['id']] ?? ''; } $payArr = model('pay')->where(['status' => 1, 'userid' => ['IN', $memberIdArr]])->group('userid') ->column('userid,sum(amount) as money,count(id) as paycount'); $gameList = $this->selfGameList; $gList = array_column($gameList, 'name', 'id'); $this->assign('list', $data); $this->assign('total', $list->total()); //总条数 $this->assign('payArr', $payArr); $this->assign('start_time', $start_time); $this->assign('end_time', $end_time); $this->assign('page', $list->render()); $this->assign('game_list', $gameList); $this->assign('gList', $gList); return $this->fetch('frozen_subaccount_list'); } /** * 实名认证列表 */ public function identityList() { $MembersTwoModel = new MembersTwo; $where = []; //用户名 if (trim(input('request.username')) != '') { // $where['m.username'] = ['like', '%' . input('request.username') . '%']; $where['m2.username'] = trim(input('request.username')); } //渠道名称 if (trim(input('request.realname')) != '') { /// $where['m2.realname'] = ['like', '%' . input('request.realname') . '%']; $where['m2.realname'] = trim(input('request.realname')); } //游戏名称 if (trim(input('request.idcard')) != '') { // $where['m2.idcard'] = ['like', '%' . input('request.idcard') . '%']; $where['m2.idcard'] = trim(input('request.idcard')); } //查询参数 $param = input('get.'); $list = $MembersTwoModel->table('cy_memberstwo m2')->field('m2.username,m2.realname,m2.idcard,m2.userid as uid, cg.name as cg_name') // ->where('m2.userid = m.id and (realname != "") AND (realname != -1) AND (realname IS NOT NULL) AND (idcard != "") AND (idcard != -1) AND (idcard IS NOT NULL)') // ->where('m2.userid = m.id and (m2.realname>"-1" AND m2.idcard>"-1")') ->join('cy_members cm', 'm2.userid = cm.id','left') ->join('cy_game cg', 'cm.gameid = cg.id','left') ->where('m2.realname>"-1" AND m2.idcard>"-1"') ->where($where)->order('m2.id desc') ->paginate(20, false, array('query' => $param)); $this->assign('list', $list); $this->assign('page', $list->render()); return $this->fetch('identity_list'); } /** * 绑定信息管理 */ public function bindList() { $where = $this->_getBindCondition(); if(!empty($where)){ //查询参数 $param = input('get.'); /* $list = $this->membersModel->field('SQL_CALC_FOUND_ROWS id,username,mobile,email,total_pay_amount,gameid') ->where('(mobile != "" AND mobile IS NOT NULL) OR (email != "" AND email IS NOT NULL)') ->where($where) ->order('id desc')->paginate(10, true, array('query' => $param));*/ $curpage = input('page') ? input('page') : 1; //当前页码 $list_data = $this->membersModel->field('SQL_CALC_FOUND_ROWS id,username,mobile,email,total_pay_amount,gameid') // ->where('(mobile != "" AND mobile IS NOT NULL) OR (email != "" AND email IS NOT NULL)') // ->where('(mobile>"" OR email>"")') ->where($where) ->order('id desc')->page($curpage,10)->select(); //总记录数 $total = Db::query("SELECT FOUND_ROWS() as total;"); $list = \think\paginator\driver\Bootstrap::make($list_data,10,$curpage,$total[0]['total'],false,[ 'var_page' => 'page', 'path' => url('bindList'),//这里根据需要修改url 'query' => $param, 'fragment' => '', ]); $data = $list->toArray(); $gameid = array_column($data['data'], 'gameid'); $gameid = array_unique($gameid); $gameList = model('game')->whereIn('id', $gameid)->column('id,name'); $this->assign('list', $list); $this->assign('gameList', $gameList); $this->assign('page', $list->render()); } $game_list = $this->selfGameList; $this->assign('game_list', $game_list); return $this->fetch('bind_list'); } private function _getParams() { $where = []; //开始时间和结束时间不为空时 if (input('request.start_time') != '' && input('request.end_time') != '') { $where['m.reg_time'] = [ ['>=', strtotime(input('request.start_time'))], ['<=', strtotime(input('request.end_time') . ' 23:59:59')], ]; } //开始时间不为空时 elseif (input('request.start_time') != '') { $where['m.reg_time'] = ['>=', strtotime(input('request.start_time'))]; } //结束时间不为空时 elseif (input('request.end_time') != '') { $where['m.reg_time'] = ['<=', strtotime(input('request.end_time') . ' 23:59:59')]; } //渠道名称 if (input('request.channel_name') != '') { $where['d.name'] = ['like', '%' . input('request.channel_name') . '%']; } //用户名 if (input('request.username') != '') { $where['m.username'] = ['like', '%' . input('request.username') . '%']; } //imeil if (input('request.imeil') != '') { $where['m.imeil'] = ['=', input('request.imeil')]; } //游戏名称 if (input('request.gameid') != '') { $where['g.id'] = ['=', input('request.gameid')]; } //手机号 if (input('request.mobile') != '') { $where['mobile'] = ['like', '%' . input('request.mobile') . '%']; } //邮箱 if (input('request.email') != '') { $where['email'] = ['like', '%' . input('request.email') . '%']; } return $where; } /** * 绑定信息 查询条件 * @return array */ protected function _getBindCondition() { $where = []; $mobile = input('request.mobile'); $email = input('request.email'); $username = input('request.username'); $gameid = input('request.gameid'); $type = input('request.type'); $total_pay_amount = input('request.total_pay_amount'); if ($username != '') { $where['username'] = $username; } if ($email != '') { $where['email'] = $email; } if ($mobile != '') { $where['mobile'] = $mobile; } //游戏名称 if ($gameid != '') { $where['gameid'] = ['=', $gameid]; } //游戏名称 if ($total_pay_amount != '') { $where['total_pay_amount'] = [$type, $total_pay_amount]; } return $where; } /** * 绑定信息 报表下载 */ public function bindListDownload($is_show = ['is_show'=>false]) { if (request()->isAjax()) { $where = $this->_getBindCondition(); if($is_show['is_show']){ $type = input('request.type'); $total_pay_amount = input('request.total_pay_amount'); $username = input('request.username', '', 'trim'); $gameid = input('request.gameid', '', 'intval'); if($total_pay_amount){ $LogStr = "充值金额:".$type.$total_pay_amount; } else{ $LogStr = "充值金额:"; } if($gameid){ $game_name = get_game_nickname($gameid); } else{ $game_name = "全部游戏"; } $LogStr .= ",游戏:".$game_name; $LogStr .= ",玩家账号:".$username; $this->insertLog($this->current_node,$LogStr,123); } $sql = $this->membersModel->field('id,username,mobile,email,total_pay_amount,gameid') // ->where('(mobile != "" AND mobile IS NOT NULL) OR (email != "" AND email IS NOT NULL)') ->where('(mobile>"" OR email>"" )') ->where($where) ->order('id desc') ->fetchSql(true) ->select(); if ((new MakeReportGo())->addTask('memberBindList', $sql, session_id(),$is_show)){ $this->success('报表生成的任务已经提交, 报表生成完成后,会及时通知您,请耐心稍等'); } $this->error('报表生成任务不可重复提交,如遇到无法导出情况,建议修改查询条件解除当前状态,提交重新生成报表任务!'); } else { $this->error('非法请求'); } } /** * 修改绑定信息 */ public function updateBind($id) { $id = (int)$id; if (empty($id)) { $this->error('用户ID不能为空'); } $memberInfo = $this->membersModel->where(['id' => $id])->find(); if (empty($memberInfo)) $this->error('用户不存在'); if (request()->isPost()) { $data = [ 'mobile' => input('post.mobile'), 'email' => input('post.email'), ]; $result = $this->validate($data, [ ['mobile', 'mobile', '手机号码格式不正确'], ['email', 'email', '邮箱格式不正确'], ]); if (true !== $result) { $this->error($result); } else { $now_time = time(); $data['update_time'] = $now_time; if ($this->membersModel->update($data, ['id' => $id])) { if ( $data['mobile'] != $memberInfo['mobile']) { // 插入玩家历史记录 Db::table('cy_member_history')->insert([ 'userid' => $id, 'mobile' => $data['mobile'], 'ip' => request()->ip(), 'create_time' => $now_time, 'admin_id' => session('ADMIN_ID') ]); } if ( $data['email'] != $memberInfo['email']) { // 插入玩家历史记录 Db::table('cy_member_history')->insert([ 'userid' => $id, 'email' => $data['email'], 'ip' => request()->ip(), 'create_time' => $now_time, 'admin_id' => session('ADMIN_ID') ]); } $msg = "修改玩家:{$memberInfo['username']}的手机号:{$data['mobile']},邮箱:{$data['email']}"; $this->insertLog($this->current_node, $msg, 23); $this->success('绑定信息修改成功', 'Member/bindList'); } else $this->error('绑定信息修改失败'); } } $this->assign('memberInfo', $memberInfo); return $this->fetch('update_bind'); } /** * 修改密码 */ public function updatePassword($id,$type = 1) { $id = (int)$id; $type = (int)$type; if (empty($id)) { $this->error('用户ID不能为空'); } $memberInfo = $this->membersModel->where(['id' => $id])->find(); if (empty($memberInfo)) $this->error('用户不存在'); if (request()->isPost()) { $password = input('post.password'); $confirm_password = input('post.confirm_password'); $data = [ 'password' => $password, 'confirm_password' => $confirm_password, ]; $result = $this->validate($data, [ ['password', 'require|length:6,15', '请输入密码|密码长度为 6 - 15'], ['confirm_password', 'require|length:6,15', '请输入确认密码|密码长度为 6 - 15'], ]); if (true !== $result) { $this->error($result); } elseif ($password != $confirm_password) { $this->error('密码不一致'); } else { $now_time = time(); unset($data['confirm_password']); $data['password'] = auth_code($password, "ENCODE", Env::get('auth_key')); $data['update_time'] = $now_time; if ($this->membersModel->update($data, ['id' => $id])) { // 插入玩家历史记录 Db::table('cy_member_history')->insert([ 'userid' => $id, 'password' => $data['password'], 'ip' => request()->ip(), 'create_time' => $now_time, 'admin_id' => session('ADMIN_ID') ]); $msg = "修改玩家:{$memberInfo['username']}的密码"; $this->insertLog($this->current_node, $msg, 21); // $memberLogic = new MemberLogic; // // $memberLogic->syncMember($memberInfo['username'], $password, $memberInfo['mobile'], $now_time); if ($type == 1) { $this->success('密码修改成功', 'Member/index'); }else{ $this->success('密码修改成功', 'Member/information'); } } else $this->error('密码修改失败'); } } $this->assign('memberInfo', $memberInfo); return $this->fetch('update_password'); } /** * 游戏-账号-角色 查询 */ public function query() { $condition = []; if (!empty(input('gh_status'))) { // 是否聚合用户:0=否、1=是 $condition['channel.gh_status'] = 1; // TODO: 设置抓取频率为一分钟10次。 $redis = Cache::init()->handler(); $cache_keys = 'member_query:' . getUserIp(); $num = $redis->get($cache_keys); if (!$num) { $num = 1; $redis->setex($cache_keys, 60, 1); } else { $num = $num + 1; $redis->Incrby($cache_keys, 1); } if ($num > 10) { return "访问次数受限,一分钟内请求为十次:" . $num; } } $gameId = input('game_id', 0, 'intval'); $username = input('username', '', 'trim'); $rolename = input('rolename', '', 'trim'); $start_time = input('start_time', '', 'trim'); $end_time = input('end_time', '', 'trim'); $page_size = input('page_size', 15); !empty($gameId) && $condition['info.gameid'] = $gameId; // !empty($username) && $condition['user.username'] = ['LIKE', '%' . $username . '%']; if (!empty($username)) { $userIds = Db::table('cy_members')->where('username', $username)->column('id'); $condition['info.userid'] = ['in', $userIds]; } !empty($rolename) && $condition['rolename'] = $rolename; // 推广数据 $business_type = input('business_type', ''); $president_type = input('president_type', ''); $president_type_son = input('president_type_son', ''); $promoter_type = input('promoter_type', ''); if ($business_type <> '') { $condition['info.channel_id'] = ['in', get_child_channel_arr($business_type)]; } if ($president_type <> '') { $condition['info.channel_id'] = ['in', get_child_channel_arr($president_type)]; } if ($president_type_son <> '') { $condition['info.channel_id'] = ['in', get_child_channel_arr($president_type_son)]; } if ($promoter_type <> '') { $condition['info.channel_id'] = $promoter_type; } // 获取查询日期 if ($start_time && $end_time) { $condition['info.create_time'] = ['between time', [strtotime($start_time), strtotime($end_time . ' 23:59:59')]]; } $infoList = Db::table('cy_role_info')->alias('info') ->join('nw_channel channel', 'channel.id = info.channel_id') ->join('cy_members user', 'user.id = info.userid') ->join('cy_game game', 'game.id = info.gameid') ->join('nw_subaccount sub', 'info.userid = sub.member_id AND info.gameid = sub.game_id') ->field(['info.id', 'game.name as game_name', 'user.username', 'info.serverid', 'info.servername', 'info.roleid', 'info.rolename', 'info.create_time', 'info.update_time', 'sub.channel_id', 'info.userid', 'info.rolelevel']) ->where($condition) ->order('update_time desc') ->group('info.roleid') ->paginate($page_size, 5000, ['query' => input('get.')]) ->each(function ($item, $key) { $channel_list = get_channel_top_by_aggregate($item['channel_id']); $item['channel_zero_name'] = !empty($channel_list['0']['name']) ? $channel_list['0']['name'] : ''; $item['channel_one_name'] = !empty($channel_list['1']['name']) ? $channel_list['1']['name'] : ''; $item['channel_two_name'] = !empty($channel_list['2']['name']) ? $channel_list['2']['name'] : ''; $item['channel_three_name'] = !empty($channel_list['3']['name']) ? $channel_list['3']['name'] : ''; return $item; }); $this->assign('list', $infoList); $this->assign('page', $infoList ? $infoList->render() : ''); $this->assign('game_list', $this->selfGameList); $this->assign('list_count', count($infoList)); $this->assign('jh_url', url('Member/query', ['gh_status' => 1, 'page_size' => '100'], 'html')); return $this->fetch(); } /** * 游戏-账号-角色 列表 */ public function roleList() { $infoList = []; $action = $this->request->param('action'); // 获取开始时间和结束时间 $start_time = $this->request->param('start_time', ''); $end_time = $this->request->param('end_time', ''); // 验证日期格式 if (!empty($start_time) && !preg_match('/^\d{4}-\d{2}-\d{2}$/', $start_time)) { $start_time = ''; } if (!empty($end_time) && !preg_match('/^\d{4}-\d{2}-\d{2}$/', $end_time)) { $end_time = ''; } // 日期最多选择到今天(包含今天) if (!empty($start_time) && $start_time > date('Y-m-d')) { $start_time = date('Y-m-d'); } if (!empty($end_time) && $end_time > date('Y-m-d')) { $end_time = date('Y-m-d'); } // 开始时间不能大于结束时间 if (!empty($start_time) && !empty($end_time) && $start_time > $end_time) { $start_time = $end_time; } // 未传时间(首次进入页面或查询时未选时间)时,默认查最近一个月的数据 if (empty($start_time) && empty($end_time)) { $start_time = date('Y-m-d', strtotime('-30 days')); $end_time = date('Y-m-d'); } if (0 == strnatcasecmp($action, 'search')) { $gameId = $this->request->param('game_id', 0, 'intval'); $username = $this->request->param('username', '', 'trim'); $rolename = $this->request->param('rolename', '', 'trim'); $condition = []; if (!empty($gameId)) { $condition['game.id'] = $gameId; } if(!empty($username)){ $userid = Db::table('cy_members')->where('username', $username)->value('id'); $condition['info.userid'] = $userid; } if(!empty($rolename)){ $condition['info.rolename'] = ['LIKE', "%{$rolename}%"]; } } else { $condition = []; } // 统一处理日期条件 if ($start_time && $end_time) { $condition['info.create_time'] = ['between time', [strtotime($start_time), strtotime($end_time . ' 23:59:59')]]; } elseif ($start_time) { $condition['info.create_time'] = ['>=', strtotime($start_time)]; } elseif ($end_time) { $condition['info.create_time'] = ['<=', strtotime($end_time . ' 23:59:59')]; } $infoList = (new MemberService())->accountQuery($condition); // 账号查询 // 格式化日期字段 if ($infoList) { $infoList->each(function (&$item) { $item['create_time'] = !empty($item['create_time']) ? date('Y-m-d H:i:s', $item['create_time']) : '-'; return $item; }); } $this->assign('list', $infoList); $this->assign('page', $infoList ? $infoList->render() : ''); $this->assign('game_list', $this->selfGameList); $this->assign('list_count', count($infoList)); $this->assign('start_time', $start_time); $this->assign('end_time', $end_time); return $this->fetch(); } // 账户-批量冻结/解冻 public function memberFrozenHandle() { $ids = $this->request->param('ids', '', 'trim'); $flag = $this->request->param('flag', ''); // 类型:1=冻结, 2=解冻 $remark = $this->request->param('remark', ''); if (empty($ids)) { $this->error('请先选择账号'); } if (empty($flag)) { $this->error('请选择操作类型'); } $flagMsg = '冻结'; if($flag == 2){ $flag = 0; $flagMsg = '解冻'; } $idArr = explode(',', $ids); $forzenList = $this->membersModel->where(['id' => ['IN', $idArr], 'flag' => $flag])->count(); if($forzenList){ $this->error('操作有误,存在"已'.$flagMsg.'"账号'); } Db::startTrans(); try { $result = Model('FrozenHistory')->addNewData(1, $idArr, $flag, $remark); if(!$result){ throw new \Exception('更新数据状态失败'); } $result = $this->membersModel->save(['flag' => $flag, 'update_time' => time()], ['id' => ['IN', $idArr]]); if ($result <= 0) { throw new \Exception('新增记录失败'); } $forzenList = $this->membersModel->where(['id' => ['IN', $idArr]])->column('username'); if($forzenList){ $memberNameList = implode(',', $forzenList); $info = $flagMsg . "玩家:{$memberNameList}"; $this->insertLog($this->current_node, $info, 415); } Db::commit(); } catch (\Exception $e) { Db::rollback(); $this->error($flagMsg.'失败:'. $e->getMessage()); } $this->success($flagMsg.'成功'); } // 子账户-批量冻结/解冻 public function subaccountFrozenHandle() { $ids = $this->request->param('ids', '', 'trim'); $flag = $this->request->param('flag', ''); // 类型:1=冻结, 2=解冻 $remark = $this->request->param('remark', ''); if (empty($ids)) { $this->error('请先选择账号'); } if (empty($flag)) { $this->error('请选择操作类型'); } $flagMsg = '冻结'; if($flag == 2){ $flag = 0; $flagMsg = '解冻'; } $idArr = explode(',', $ids); $forzenList = Model('Subaccount')->where(['id' => ['IN', $idArr], 'flag' => $flag])->count(); if($forzenList){ $this->error('操作有误,存在"已'.$flagMsg.'"账号'); } Db::startTrans(); try { $result = Model('FrozenHistory')->addNewData(2, $idArr, $flag, $remark); if(!$result){ throw new \Exception('更新数据状态失败'); } $result = Model('Subaccount')->save(['flag' => $flag, 'update_time' => time()], ['id' => ['IN', $idArr]]); if ($result <= 0) { throw new \Exception('新增记录失败'); } $forzenList = Model('Subaccount')->where(['id' => ['IN', $idArr]])->column('sub_username'); if($forzenList){ $memberNameList = implode(',', $forzenList); $info = $flagMsg . "子账户:{$memberNameList}"; $this->insertLog($this->current_node, $info, 39); } Db::commit(); } catch (\Exception $e) { Db::rollback(); $this->error($flagMsg.'失败:'. $e->getMessage()); } $this->success($flagMsg.'成功'); } // 注册单用户 public function register() { if ($this->request->isPost()) { $username = strtolower($this->request->param('username', '', 'trim')); $password = $this->request->param('password', '', 'trim'); $channelId = $this->request->param('channel_id', 0, 'intval'); $gameId = $this->request->param('game_id', 0, 'intval'); $data = [ 'username' => $username, 'password' => $password, 'channel_id' => $channelId, 'gameid' => $gameId, ]; $validResult = $this->validate($data, 'admin/Member'); if (true !== $validResult) { $this->error($validResult); } $channelInfo = model('Channel')->where(["id"=>$channelId])->find(); if($channelInfo['level'] <> 3){ $this->error('非推广员渠道,不能进行绑定'); } if($gameId && $channelId){ //是否禁止注册 if (isFrozenOption($channelId,$gameId,'register') || isFrozenOption($channelId,$gameId)) { $this->error('您所在渠道已被禁止注册此游戏'); } } if(!$gameId){ // 没有选择绑定游戏 $this->error('请选择绑定游戏'); } if(!$channelId){ // 没有选择绑定渠道 $this->error('请选择绑定渠道'); } // 判断该游戏是否处于白名单状态,若是,则判断是否有分包记录,没有的话,禁止注册关联 if(!empty($gameId)) { $game_info = model('game')->where(['id' => $gameId])->find(); // 处于白名单状态 if(2 == $game_info['cooperation_status']) { $conditions = array(); $conditions['gameid'] = $gameId; $conditions['channel_id'] = $channelId; $subPackageCnt = model('SdkGameList')->where($conditions)->count(); if(!$subPackageCnt){ $this->error('该游戏处于白名单状态,无法新增'); } } } $result = (new MemberService())->registerUser($data); if (true === $result) { $this->success('注册成功'); } else { $this->error($result); } } $channelList = (new Channel)->getAllByCondition('id,name', ['status' => 1, 'flag' => 3, 'level' => 3]); // 只能筛选上架和白名单的游戏 // , 'cooperation_status' =>['in','1,2'] $gameList = (new Game())->getAllByCondition('id,name', ['isdelete' => 0],'','self'); $selfGameList = array(); foreach ($gameList as $game) { $selfGameList[ $game['id']] = $game; } $this->assign('game_list', $selfGameList); $this->assign('channel_list', $channelList); return $this->fetch(); } // 批量注册 public function multiRegister() { $channelId = $this->request->param('channel_id', 0, 'intval'); $gameId = $this->request->param('game_id', 0, 'intval'); $file = request()->file('file'); if (empty($file)) { $this->error('请上传txt文件'); } if (empty($channelId)) { $this->error('请选择绑定渠道'); } if (empty($gameId)) { $this->error('请选择绑定游戏'); } $fileInfo = $file->getInfo(); if (!empty($file->getError())) { $this->error('文件上传失败,' . $file->getError()); } if (empty($fileInfo['name']) || strtolower(pathinfo($fileInfo['name'], PATHINFO_EXTENSION)) !== 'txt') { $this->error('请上传txt文件'); } if (!empty($fileInfo['size']) && $fileInfo['size'] > 10240000) { $this->error('上传文件大小不能超过10M'); } try { if (empty($fileInfo['tmp_name']) || !is_file($fileInfo['tmp_name'])) { throw new \Exception('上传临时文件不存在'); } $users = file($fileInfo['tmp_name']); if (false === $users) { throw new \Exception('读取上传文件失败'); } } catch (\Exception $e) { $this->error('批量注册失败,'.$e->getMessage()); } $channelInfo = model('Channel')->where(["id"=>$channelId])->find(); if($channelInfo['level'] <> 3){ $this->error('非推广员渠道,不能进行绑定'); } if($gameId && $channelId){ //是否禁止注册 if (isFrozenOption($channelId,$gameId,'register') || isFrozenOption($channelId,$gameId)) { $this->error('您所在渠道已被禁止注册此游戏'); } } // 判断该游戏是否处于白名单状态,若是,则判断是否有分包记录,没有的话,禁止注册关联 if(!empty($gameId)) { $game_info = model('game')->where(['id' => $gameId])->find(); // 处于白名单状态 if(2 == $game_info['cooperation_status']) { $conditions = array(); $conditions['gameid'] = $gameId; $conditions['channel_id'] = $channelId; $subPackageCnt = model('SdkGameList')->where($conditions)->count(); if(!$subPackageCnt){ $this->error('该游戏处于白名单状态,无法新增'); } } } $memberService = new MemberService(); $checkResult = $memberService->checkContent($users); // 重新检测内容 if (true !== $checkResult) { $this->error($checkResult); } $result = []; foreach ($users as $user) { list($username, $password) = explode(':', trim($user)); $data = [ 'username' => strtolower(trim($username)), 'password' => trim($password), 'channel_id' => $channelId, 'gameid' => $gameId ]; $validResult = $this->validate($data, 'admin/Member'); // 注册失败的 if (true !== $validResult) { $result[] = ['username' => $username, 'reason' => $validResult, 'status' => 0]; } else { // 注册用户 $flag = $memberService->registerUser($data); if (true === $flag) { $result[] = ['username' => $username, 'reason' => '', 'status' => 1]; } else { $result[] = ['username' => $username, 'reason' => $flag, 'status' => 0]; } } } $this->success('批量注册提交成功,具体注册结果可查看返回信息', null, $result); } // 首页 ajax加载渠道,避免渠道太多,页面渲染太慢 public function ajaxGetChannel() { $channel_list = model('Common/Channel')->getAllByCondition('id,name',['status' => 1,'flag'=>['in','3,4']]); $this->success('', '', $channel_list); } /** * 注册用户管理--账号明文查看操作 */ public function indexPassword(){ $channelId = $this->request->param('id', 0, 'intval'); if (empty($channelId)){ $this->result('',0,'参数错误!'); } $userName = $this->membersModel->where(['id'=>$channelId])->value('username'); // 记录操作日志 $this->insertLog($this->current_node,'查看账号:'.$userName,25); $this->result($userName,1,$userName); } /** * 登录用户列表--账号明文查看操作 */ public function loginPassword(){ $logininfoId = $this->request->param('id', 0, 'intval'); if (empty($logininfoId)){ $this->result('',0,'参数错误!'); } $info = Db::table('cy_logininfo')->alias('l') ->join('cy_members m', 'l.userid = m.id') ->join('cy_game c', 'l.gameid = c.id','left') ->field("m.username,c.name") ->where(['l.id'=>$logininfoId]) ->find(); // 记录操作日志 $this->insertLog($this->current_node,'查看账号:'.$info['username'].',关联游戏:'.$info['name'],26); $this->result($info['username'],1,$info['username']); } /** * 绑定信息管理--明文查看操作 */ public function bindPassword(){ $Id = $this->request->param('id' , 0 , 'intval'); $file = $this->request->param('file' , '' , 'trim'); if (empty($Id) || empty($file)){ $this->result('',0,'参数错误!'); } $file = trim($file); if ($file == 'username'){ $action = '账号'; }elseif ($file == 'mobile'){ $action = '手机号'; }elseif($file == 'email'){ $action = '邮箱'; }else{ $action = '密文'; } if ( $file == 'username') { $field = ["a.$file","c.name"]; }else{ $field = ["a.$file","c.name","a.username"]; } /*dump($file);*/ $info = $this->membersModel->alias('a')->join('cy_game c', 'a.gameid = c.id','left')->where(['a.id'=>$Id])->field($field)->find(); $logStr = ''; if (empty($info['name'])){ $logStr = '查看'.$action.':'.$info[$file]; }else{ $logStr = '查看'.$action.':'.$info[$file].',关联游戏:'.$info['name']; } if( $file != 'username') $logStr .= ',关联账号:' .$info['username']; // 记录操作日志 $this->insertLog($this->current_node,$logStr,27); $this->result($info[$file],1,$info[$file]); } /** * 实名认证--账号明文查看操作 */ public function identityPassword(){ $Id = $this->request->param('id', 0, 'intval'); $file = $this->request->param('file' , '' , 'trim'); if (empty($Id) || empty($file)){ $this->result('',0,'参数错误!'); } $file = trim($file); if ($file == 'username'){ $action = '账号'; $info = $this->membersModel->where(['id'=>$Id])->value('username'); }elseif ($file == 'idcard'){ $action = '身份证'; $info = model('MembersTwo')->where(['userid'=>$Id])->value('idcard'); }else{ $this->result('',0,'参数错误!'); } // 记录操作日志 $this->insertLog($this->current_node,'查看'.$action.':'.$info,28); $this->result($info,1,$info); } /** * 冻结用户列表--账号明文查看操作 */ public function frozenUsername(){ $id = $this->request->param('userid', 0, 'intval'); if (empty($id)){ $this->result('',0,'玩家ID参数错误!'); } $userName = $this->membersModel->where(['id'=>$id])->value('username'); // 记录操作日志 $this->insertLog($this->current_node,'查看账号:'.$userName,29); $this->result($userName,1); } /** * 用户汇总信息--明文查看操作 */ public function infomationPassword(){ $Id = $this->request->param('id' , 0 , 'intval'); $file = $this->request->param('file' , '' , 'trim'); if (empty($Id) || empty($file)){ $this->result('',0,'参数错误!'); } $file = trim($file); if ($file == 'username'){ $action = '账号'; $info = $this->membersModel->where(['id'=>$Id])->value('username'); }elseif ($file == 'idcard'){ $action = '身份证'; $info = model('MembersTwo')->where(['userid'=>$Id])->value('idcard'); }elseif ($file == 'email'){ $action = '邮箱'; $info = $this->membersModel->where(['id'=>$Id])->value('email'); }elseif ($file == 'mobile'){ $action = '手机号'; $info = $this->membersModel->where(['id'=>$Id])->value('mobile'); }else{ $this->result('',0,'参数错误!'); } // 记录操作日志 $this->insertLog($this->current_node,'查看'.$action.':'.$info,124); $this->result($info,1,$info); } /** * 登录列表下载--无加密 */ public function loginDowmExcel(){ $this->loginlistdownload(['is_show'=>true]); } /** * 注册管理页下载--无加密 */ public function registDowmExcel(){ $this->download(['is_show'=>true]); } /** * 绑定信息页下载--无加密 */ public function bindDowmExcel(){ $this->bindListDownload(['is_show'=>true]); } /** * 用户信息汇总 */ public function information() { $this->informationWhere(2); $param = input('get.'); $list = Db::table('cy_members')->alias('m') ->join('nw_channel channel', 'channel.id=m.channel_id', 'left') ->join('nw_channel bchild', 'bchild.id=channel.parent_id AND bchild.level = 2', 'left') ->field('m.id,m.username,m.nickname,m.channel_id,m.flag,m.gameid,m.reg_time,m.ip,m.imeil,m.total_pay_amount,m.login_time,bchild.name as bchild_name,bchild.parent_id as bcparent_id, m.test_status') ->where($this->where)->order('reg_time desc') ->paginate(10, false, array('query' => $param)); /* $list = $this->membersModel ->field('id,username,nickname,channel_id,flag,gameid,reg_time,ip,imeil,total_pay_amount,login_time') ->where($this->where)->order('reg_time desc') ->paginate(10, false, array('query' => $param));*/ $gameList = $this->selfGameList; $gList = $gameList; $gameList = array_column($gameList, 'name', 'id'); $data = $list->toArray()['data']; $memberIdArr = array(); foreach ($data as &$v) { $memberIdArr[] = $v['id']; $v['top_channel_name'] = get_top_channel($v['channel_id'])['name']; $v['dep_name'] = get_channel_name($v['channel_id']); $v['union_name'] = get_union_channel($v['channel_id'])['name']; // 账号加密 $v['mdusername'] = stringObfuscation($v['username'],3); } // 批量查询最近登录IP(查询后绑定方式,性能更好) // 这种方式比JOIN子查询更优:1.逻辑清晰 2.只查询当前页用户 3.易于维护和优化 4.避免复杂子查询 if (!empty($memberIdArr)) { // 使用子查询一次性获取当前页每个用户最新登录记录(取最大id) $latestLoginSubSql = Db::table('cy_logininfo') ->field('userid, MAX(id) as max_id') ->where('userid', 'in', $memberIdArr) ->group('userid') ->buildSql(); $latestLoginRows = Db::table('cy_logininfo')->alias('l1') ->join([$latestLoginSubSql => 'l2'], 'l1.id = l2.max_id') ->field('l1.userid, l1.ip') ->select(); // ->toArray(); $lastLoginIpList = []; foreach ($latestLoginRows as $row) { $lastLoginIpList[$row['userid']] = $row['ip']; } // 将最近登录IP绑定到用户数据中 foreach ($data as &$v) { $v['last_login_ip'] = isset($lastLoginIpList[$v['id']]) ? $lastLoginIpList[$v['id']] : '--'; } } else { // 如果没有数据,为每个用户设置默认值 foreach ($data as &$v) { $v['last_login_ip'] = '--'; } } $this->assign('list', $data); $this->assign('total', $list->total()); //总条数 $this->assign('start_time', $this->start_time); $this->assign('end_time', $this->end_time); $this->assign('page', $list->render()); $this->assign('game_list', $gameList); $this->assign('glist', $gList); $uniom = model('Channel')->where(['level'=>0])->field('id,name')->select(); $this->assign('uniom', $uniom); //顶级渠道列表 return $this->fetch(); } /** * 更新用户测试状态 */ public function updateTestStatus() { $id = $this->request->param('id', 0, 'intval'); $test_status = $this->request->param('test_status', 0, 'intval'); if (empty($id)) { $this->error('用户ID不能为空'); } $memberInfo = $this->membersModel->where(['id' => $id])->find(); if (empty($memberInfo)) { $this->error('用户不存在'); } $result = $this->membersModel->where(['id' => $id])->update([ 'test_status' => $test_status, 'update_time' => time(), ]); if ($result !== false) { $statusMsg = $test_status == 1 ? '测试' : '正常'; $info = "修改玩家:{$memberInfo['username']} 的测试状态为:{$statusMsg}"; $this->insertLog($this->current_node, $info, 415); $this->success('已设置为' . $statusMsg . '状态'); } else { $this->error('操作失败'); } } // 用户信息汇总查询条件 public function informationWhere($isdefault) { $where = []; $id = input('request.id'); $mobile = input('request.mobile'); $email = input('request.email'); $nickname = input('request.nickname'); $ip = input('request.ip'); $last_login_ip = input('request.last_login_ip', '', 'trim'); // 最近登录IP $idcard = input('request.idcard', '', 'trim'); // 身份证 $flag = input('request.flag'); $start_time = input('request.start_time'); $end_time = input('request.end_time'); $channel_id = input('request.channel_id'); $username = input('request.username'); $gameid = input('request.gameid'); $top_channel_id = input('request.parent_channel_id'); $bplus_channel_id = input('bplus_channel_id', 0, 'intval'); // 获取查询日期 $where['reg_time'] =$this->getTimeCondition($start_time,$end_time,$isdefault); /* if ($username == '' && $nickname == '' && $id == ''){ if(strtotime($this->end_time.' 23:59:59')-strtotime($this->start_time)>31*24*3600) { $this->error('单次查询日期的最长跨度为31天'); } } */ // 推广四联查询 $business_type = input('business_type', input('tg_business', '')); // 商务 $president_type = input('president_type', input('tg_president', '')); // 会长 $president_type_son = input('president_type_son', input('tg_president_son', '')); // 子会长 $promoter_type = input('promoter_type', input('tg_promoter', '')); // 推广员 if ($business_type <> '') { $where['m.channel_id'] = ['in', get_child_channel_arr($business_type)]; } if ($president_type <> '') { $where['m.channel_id'] = ['in', get_child_channel_arr($president_type)]; } if ($president_type_son <> '') { $where['m.channel_id'] = ['in', get_child_channel_arr($president_type_son)]; } if ($promoter_type <> '') { $where['m.channel_id'] = $promoter_type; } //渠道名称 if ( !empty($channel_id) || !empty($top_channel_id) || !empty($bplus_channel_id)) { $where['channel_id'] = $this->getChannelCondition($channel_id,$top_channel_id,$bplus_channel_id); } //最近登录IP(优先处理,因为可能影响用户ID条件) if ($last_login_ip != '') { $latestLoginSubSql = Db::table('cy_logininfo') ->field('userid, MAX(id) as max_id') ->group('userid') ->buildSql(); $matchedUserIds = Db::table('cy_logininfo')->alias('l1') ->join([$latestLoginSubSql => 'l2'], 'l1.id = l2.max_id') ->where('l1.ip', $last_login_ip) ->column('l1.userid'); if (!empty($matchedUserIds)) { $where['m.id'] = ['in', $matchedUserIds]; } else { $where['m.id'] = -1; } } // 身份证查询(支持 cy_memberstwo 与 nw_subaccount) if ($idcard != '') { $memberIdsFromMembersTwo = Db::table('cy_memberstwo') ->where('idcard', $idcard) ->column('userid'); $memberIdsFromSubaccount = Db::table('nw_subaccount') ->where('idcard_num', $idcard) ->column('member_id'); $matchedUserIds = array_values(array_unique(array_filter(array_merge( $memberIdsFromMembersTwo ?: [], $memberIdsFromSubaccount ?: [] )))); if (!empty($matchedUserIds)) { if (isset($where['m.id'])) { if (is_array($where['m.id']) && isset($where['m.id'][0]) && 'in' === strtolower($where['m.id'][0])) { $existingIds = $where['m.id'][1]; $intersectIds = array_values(array_intersect($existingIds, $matchedUserIds)); $where['m.id'] = !empty($intersectIds) ? ['in', $intersectIds] : -1; } else { if (!in_array($where['m.id'], $matchedUserIds)) { $where['m.id'] = -1; } } } else { $where['m.id'] = ['in', $matchedUserIds]; } } else { $where['m.id'] = -1; } } //用户ID(注意:如果同时有最近登录IP搜索,需要合并条件) if ($id != '') { if (isset($where['m.id']) && is_array($where['m.id']) && $where['m.id'][0] == 'in') { // 如果已经有IN条件(来自最近登录IP搜索),需要取交集 $existingIds = $where['m.id'][1]; if (in_array($id, $existingIds)) { $where['m.id'] = $id; } else { $where['m.id'] = -1; // 不存在,设置不可能的值 } } else { $where['m.id'] = $id; } } //用户昵称 if ($nickname != '') { $where['nickname'] = $nickname; } //用户名 if ($username != '') { $where['username'] = $username; } //游戏名称 if ($gameid != '') { $where['gameid'] = ['=', $gameid]; } //手机号 if ($mobile != '') { $where['mobile'] = $mobile; } //邮箱 if ($email != '') { $where['email'] = $email; } //注册IP if ($ip != '') { $where['ip'] = $ip; } //账号状态 if ($flag != '') { $where['m.flag'] = $flag; } //是否测试 $test_status = input('request.test_status', '', 'trim'); if ($test_status !== '') { $where['m.test_status'] = $test_status; } $this->where = $where; } /** * 获取渠道查询条件 * @param int $channel_id 渠道ID * @param int $top_channel_id 顶级渠道ID * @return */ private function getChannelCondition($channel_id,$top_channel_id,$bplus_channel_id=0) { //联盟/公会/渠道有选择时判断 if(!empty($channel_id) || !empty($top_channel_id) || !empty($bplus_channel_id)){ if(!empty($channel_id) && !empty($top_channel_id) && !empty($bplus_channel_id)){ unset($condition['p.channel_id']); $bChannelIds = get_child_channel_arr($top_channel_id); array_push($bChannelIds,$top_channel_id); $bplusChannelIds = get_child_channel_arr($bplus_channel_id); array_push($bplusChannelIds,$bplus_channel_id); $channelIds = array_intersect($bChannelIds,$bplusChannelIds,array($channel_id)); if($channelIds){ $channel = ['in',$channelIds]; } else{ $channel = -1; } } else if(!empty($top_channel_id) && !empty($bplus_channel_id)){ $bChannelIds = get_child_channel_arr($top_channel_id); array_push($bChannelIds,$top_channel_id); $bplusChannelIds = get_child_channel_arr($bplus_channel_id); array_push($bplusChannelIds,$bplus_channel_id); $channelIds = array_intersect($bChannelIds,$bplusChannelIds); if($channelIds){ $channel = ['in',$channelIds]; } else{ $channel = -1; } } elseif (!empty($channel_id) && !empty($bplus_channel_id)) { $bplusChannelIds = get_child_channel_arr($bplus_channel_id); array_push($bplusChannelIds,$bplus_channel_id); $channelIds = array_intersect($bplusChannelIds,array($channel_id)); if($channelIds){ $channel = ['in',$channelIds]; } else{ $channel = -1; } } elseif (!empty($channel_id) && !empty($top_channel_id)) { $bChannelIds = get_child_channel_arr($top_channel_id); array_push($bChannelIds,$top_channel_id); $channelIds = array_intersect($bChannelIds,array($channel_id)); if($channelIds){ $channel = ['in',$channelIds]; } else{ $channel = -1; } } elseif (!empty($top_channel_id)) { $channelIds = get_child_channel_arr($top_channel_id); array_push($channelIds,$top_channel_id); $channel = ['in',$channelIds]; } elseif (!empty($bplus_channel_id)) { $channelIds = get_child_channel_arr($bplus_channel_id); array_push($channelIds,$bplus_channel_id); $channel = ['in',$channelIds]; } elseif (!empty($channel_id)) { $channel = (int)$channel_id; } } /* if(!empty($channel_id) && !empty($top_channel_id)){ $channelIds = get_child_channel_arr($top_channel_id); array_push($channelIds,$top_channel_id); $channel = [ ['=', (int)$channel_id], ['in', $channelIds], ]; } elseif (!empty($channel_id)) { $top_channel_id = 0; // 如果同时输入渠道名称和顶级渠道,出于性能考虑,只查询渠道名称这个条件 $channel = (int)$channel_id; } //顶级渠道存到pay表中 存在渠道改变时候 需要定期刷表的情况后续开发 elseif (!empty($top_channel_id)) { unset($this->where['channel_id']); // 如果同时输入渠道名称和顶级渠道,出于性能考虑,只查询渠道名称这个条件 $channelIds = get_child_channel_arr($top_channel_id); array_push($channelIds,$top_channel_id); $channel = ['in',$channelIds]; } */ return $channel; } /** * 获取日期查询条件 * @param int $start_time 开始时间 * @param int $end_time 结束时间 * @param bool $isdefault 是否默认今天日期 * @return */ private function getTimeCondition($start_time,$end_time,$isdefault = true) { $this->start_time = $start_time; $this->end_time = $end_time; $time = []; //开始时间和结束时间不为空时 if ($start_time != '' && $end_time != '') { $time = [ ['>=', strtotime($start_time)], ['<=', strtotime($end_time . ' 23:59:59')], ]; } //开始时间不为空时 elseif ($start_time != '') { $time = ['>=', strtotime($start_time)]; } //结束时间不为空时 elseif ($end_time != '') { $time = ['<=', strtotime($end_time . ' 23:59:59')]; } else { if($isdefault === 2){ $this->start_time = $this->end_time = ''; $time = [ ['>=', strtotime($this->start_time)], ['<=', strtotime($this->end_time . ' 23:59:59')], ]; }else if($isdefault){ $this->start_time = $this->end_time = date('Y-m-d', time()); $time = [ ['>=', strtotime($this->start_time)], ['<=', strtotime($this->end_time . ' 23:59:59')], ]; } } return $time; } // 获取用户账号详情 public function userInfo() { $id = $this->request->param('id', '', 'intval'); $code = 1; // 获取用户信息 $info = $this->membersModel->where('id',$id) ->field('id,username,avatar,mobile,email,nickname,channel_id,flag,gameid,reg_time,ip,imeil,total_pay_amount,login_time') ->find(); if (empty($info)) { $code = 0; }else{ $info['username'] = stringObfuscation($info['username'],3); $info['top_channel_name'] = get_top_channel($info['channel_id'])['name'] ?: ''; $info['dep_name'] = get_channel_name($info['channel_id']) ?: ''; $userPayInfo = model('Pay')->where(['status' => 1, 'userid' => $id])->group('userid')->field(['userid', 'sum(amount) as money','count(id) as paycount'])->find(); $info['total_pay_amount'] = isset($userPayInfo->money) ? $userPayInfo->money : ''; $info['flag'] = $info['flag'] ? '冻结':'正常'; $info['reg_time'] = $info['reg_time'] ? date('Y-m-d H:i:s',$info['reg_time']) : ''; $info['imeil'] = $info['imeil'] ?: ''; $info['nickname'] = $info['nickname'] ?: ''; $info['gamename'] = $info['gameid'] ? model('Game')->getName($info['gameid']) : ''; $info['mobile'] = $info['mobile'] ? mobileObfuscation($info['mobile']) : ''; $info['email'] = $info['email'] ? mailObfuscation($info['email']) : ''; // 获取用户实名认证信息 $userInfo = (new MembersTwo())->where('userid',$id)->field('realname,idcard,sex,qq,birthday,address,zipcode')->find(); $info['realname'] = $userInfo['realname'] ?: ''; $info['idcard'] = $userInfo['idcard'] ? idcardObfuscation($userInfo['idcard']) : ''; $info['sex'] = $userInfo['sex'] == 1 ? '女': $userInfo['sex'] == 2 ? '男' : '保密'; $info['birthday'] = $userInfo['birthday'] ?: ''; $info['address'] = $userInfo['address'] ?: ''; $info['zipcode'] = $userInfo['zipcode'] ?: ''; $info['qq'] = $userInfo['qq'] ?: ''; $info['avatar'] = $info['avatar'] ? STATIC_DOMAIN . $info['avatar'] : ''; // 获取最后一次登录信息 $loginInfo = model('Logininfo')->where('userid',$id)->field('imeil,login_time,ip')->order('login_time desc')->find(); $info['last_imeil'] = $loginInfo['imeil'] ? : ''; $info['last_ip'] = $loginInfo['ip'] ? : ''; $info['last_login_time'] = $loginInfo['login_time'] ? date('Y-m-d H:i:s',$loginInfo['login_time']) : ''; } echo json_encode(['code'=>$code,'data'=>$info]); } /** * 用户冻结详情 */ public function frozenInfo($ids) { $param = input('get.'); $where['user_id'] = (int)$ids; $admin_id = input('request.admin_id'); $flag = input('request.flag'); $start_time = input('request.start_time'); $end_time = input('request.end_time'); // 获取查询日期 if (!empty($start_time) || !empty($end_time)){ $where['create_time'] =$this->getTimeCondition($start_time,$end_time,false); } //操作人 if ($admin_id != '') { $where['admin_id'] = $admin_id; } //冻结状态 if ($flag != '') { $where['status'] = $flag; } $list = model('FrozenHistory') ->where($where)->order('id desc') ->paginate(10, false, array('query' => $param))->each(function($item, $key){ if ( !$item['admin_id']) { $item['admin_name'] = '申诉冻结'; }else{ $item['admin_name'] =model('admin')->where('id',$item['admin_id'])->value('username'); } return $item; }); $data = $list->toArray()['data']; // 处理冻结备注 $subIds = array_column($data, 'id'); $frozenMaxList = Db::table('cy_frozen_history') ->field('user_id, MAX(id) as max_id') ->where(['user_id' => ['IN', $subIds], 'status' => 1]) ->group('user_id') ->select(); $maxIds = array_column($frozenMaxList, 'max_id'); $frozenList = model('FrozenHistory')->where(['id' => ['IN', $maxIds], 'status' => 1])->order('id desc')->group('user_id')->column('user_id,remark'); foreach ($data as $key => $value) { $data[$key]['remark'] = $frozenList[$value['id']] ?? ''; } $list->toArray()['data'] = $data; $aList = model('Common/Admin')->field('id,username as name')->where(['type'=> 1 ,'status'=> 1])->order('id')->select(); $adminList = array_merge([['id'=>0,'name'=>'申诉冻结']] ,$aList); $this->assign('list', $list); $this->assign('total', $list->total()); //总条数 $this->assign('start_time', $this->start_time); $this->assign('end_time', $this->end_time); $this->assign('page', $list->render()); $this->assign('adminList',$adminList); return $this->fetch(); } public function membersHistory($ids) { $param = input('get.'); $where['userid'] = (int)$ids; $type = input('request.type'); $start_time = input('request.start_time'); $end_time = input('request.end_time'); // 获取查询日期 $resWhere = $this->getTimeCondition($start_time,$end_time,false); if (!empty($resWhere)){ $where['h.create_time'] = $resWhere; } //冻结状态 if ($type != '') { if ( $type == 0 ) $where['h.channel'] = ['neq','']; if ( $type == 1 ) $where['h.mobile'] = ['neq','']; if ( $type == 2 ) $where['h.email'] = ['neq','']; if ( $type == 3 ) $where['h.password'] = ['neq','']; } $list = model('MemberHistory')->alias('h') ->join('cy_members m','m.id = h.userid') ->field('h.*,m.username') ->where($where)->order('id desc') ->paginate(10, false, array('query' => $param))->each(function($item, $key){ if ( !$item['admin_id']) { $item['admin_name'] = $item['username']; }else{ $item['admin_name'] =model('admin')->where('id',$item['admin_id'])->value('username'); } if ( $item['password']) { $item['type'] = '密码'; $item['text'] = passwordObfuscation($item['password']); }elseif( $item['email']){ $item['type'] = '邮箱'; $item['text'] = $item['email']; }elseif( $item['mobile']){ $item['type'] = '手机'; $item['text'] = $item['mobile']; }else{ $item['type'] = '渠道'; $item['text'] = $item['channel']; } return $item; }); $this->assign('list', $list); $this->assign('total', $list->total()); //总条数 $this->assign('start_time', $this->start_time); $this->assign('end_time', $this->end_time); $this->assign('page', $list->render()); return $this->fetch(); } /** * 用户信息汇总修改密码 */ public function updateInformationPassword($id) { $id = (int)$id; if (empty($id)) { $this->error('用户ID不能为空'); } $memberInfo = $this->membersModel->where(['id' => $id])->find(); if (empty($memberInfo)) $this->error('用户不存在'); if (request()->isPost()) { $password = input('post.password'); $confirm_password = input('post.confirm_password'); $data = [ 'password' => $password, 'confirm_password' => $confirm_password, ]; $result = $this->validate($data, [ ['password', 'require|length:6,15', '请输入密码|密码长度为 6 - 15'], ['confirm_password', 'require|length:6,15', '请输入确认密码|密码长度为 6 - 15'], ]); if (true !== $result) { $this->error($result); } elseif ($password != $confirm_password) { $this->error('密码不一致'); } else { $now_time = time(); unset($data['confirm_password']); $data['password'] = auth_code($password, "ENCODE", Env::get('auth_key')); $data['update_time'] = $now_time; if ($this->membersModel->update($data, ['id' => $id])) { // 插入玩家历史记录 Db::table('cy_member_history')->insert([ 'userid' => $id, 'password' => $data['password'], 'ip' => request()->ip(), 'create_time' => $now_time, 'admin_id' => session('ADMIN_ID') ]); $msg = "修改玩家:{$memberInfo['username']}的密码"; $this->insertLog($this->current_node, $msg, 125); // $memberLogic = new MemberLogic; // // $memberLogic->syncMember($memberInfo['username'], $password, $memberInfo['mobile'], $now_time); $this->success('密码修改成功', 'Member/information'); } else $this->error('密码修改失败'); } } $this->assign('memberInfo', $memberInfo); return $this->fetch('update_password'); } /** * 用户信息汇总冻结账户 */ public function informationFrozen() { $id = input('id', 0, 'intval'); $flag = input('flag', 0, 'abs'); if (empty($id)) { $this->error('用户ID不能为空'); } if (!$info = $this->membersModel->field('id,username')->find($id)) { $this->error('非法参数'); } if ($flag == 1) $msg = '冻结'; else $msg = '解冻'; if ($this->membersModel->update([ 'flag' => $flag, 'update_time' => time(), ], ['id' => $id])) { // 插入冻结记录 $res = model('FrozenHistory')->addData($id,$flag); $info = $msg . "玩家:{$info['username']}"; $this->insertLog($this->current_node, $info, 126); $this->success($msg . '账户成功'); } else { $this->error($msg . '账户失败'); } } /** * 删除用户头像 */ public function delAvatar() { $id = input('id', 0, 'intval'); if (empty($id)) { $this->error('用户ID不能为空'); } if (!$info = $this->membersModel->field('id,username')->find($id)) { $this->error('非法参数'); } if ($this->membersModel->update([ 'avatar' => '', 'update_time' => time(), ], ['id' => $id])) { $info = "删除玩家:{$info['username']}头像"; $this->insertLog($this->current_node, $info, 127); $this->success('删除成功'); } else { $this->error('删除失败'); } } // 清空实名 public function clearRealName(){ $id = input('id', 0, 'intval'); if (empty($id)) { $this->error('用户ID不能为空'); } $memberInfo = $this->membersModel->where(['id' => $id])->find(); if (empty($memberInfo)) $this->error('用户不存在'); if (model('common/MembersTwo')->where(['userid' => $id])->update(['realname' => '', 'idcard' => ''])) { $msg = "清空玩家:{$memberInfo['username']}的实名认证"; $this->insertLog($this->current_node, $msg, 21); $this->success('清空成功', 'Member/index'); } else { $this->error('清空失败'); } } // 角色管理 public function getRole() { $param = input('get.'); $filters = $this->getRoleFilters(); $where = $this->getRoleCondition($filters); $pageSize = input('page_size', 20, 'intval'); $pageSize = $pageSize > 0 ? $pageSize : 20; $list = $this->getRoleQuery($where) ->order('mgs.update_time desc') ->paginate($pageSize, false, array('query' => $param)) ->each(function ($item, $key) { $channel_list = get_channel_top_by_aggregate($item['channel_id']); $item['channel_zero_name'] = !empty($channel_list['0']['name']) ? $channel_list['0']['name'] : ''; $item['channel_one_name'] = !empty($channel_list['1']['name']) ? $channel_list['1']['name'] : ''; $item['channel_two_name'] = !empty($channel_list['2']['name']) ? $channel_list['2']['name'] : ''; $item['channel_three_name'] = !empty($channel_list['3']['name']) ? $channel_list['3']['name'] : ''; return $item; }); $this->assign('list', $list); $this->assign('total', $list->total()); //总条数 $this->assign('page', $list->render()); // 所属游戏 $gameList = $this->selfGameList; $gList = json_encode($gameList); $gameList = array_column($gameList, 'name', 'id'); $this->assign('game_list', $gameList); $this->assign('g_list', $gList); // 获取区服列表(根据游戏ID筛选,如果选择了游戏) $serverList = []; if (!empty($filters['game_id'])) { $serverList = Db::table('nw_game_server') ->where(['game_id' => $filters['game_id'], 'status' => 1]) ->field('serverid,servername') ->order('id desc') ->select(); } else { // 如果没有选择游戏,获取所有区服 $serverList = Db::table('nw_game_server') ->where(['status' => 1]) ->field('serverid,servername') ->order('id desc') ->select(); } $this->assign('server_list', $serverList); $this->assign('selected_serverid', $filters['server_id']); $this->assign('startTime', $filters['start_time']); $this->assign('endTime', $filters['end_time']); // 推广信息 $uniom = model('Channel')->where(['level' => 0])->field('id,name')->select(); $this->assign('uniom', $uniom); return $this->fetch(); } /** * 角色管理导出。 */ public function getRoleDownload() { if (!request()->isAjax()) { $this->error('非法请求'); } $filters = $this->getRoleFilters(); $where = $this->getRoleCondition($filters); $sql = $this->getRoleQuery($where, true) ->order('mgs.update_time desc') ->fetchSql(true) ->select(); if ((new MakeReportGo())->addTask('memberRoleList', $sql, session_id())) { $this->success('报表生成的任务已经提交, 报表生成完成后,会及时通知您,请耐心稍等'); } $this->error('报表生成任务提交失败,请稍后重试'); } /** * 获取角色管理查询参数。 */ private function getRoleFilters() { $startTime = input('request.start_time', '', 'trim'); $endTime = input('request.end_time', '', 'trim'); // 角色表数据量较大,无时间条件时沿用原逻辑默认查询当天。 if ($startTime === '' && $endTime === '') { $startTime = $endTime = date('Y-m-d'); } return [ 'cooperation_status' => input('request.cooperation_status', 0, 'intval'), 'business_type' => input('request.business_type', '', 'trim'), 'president_type' => input('request.president_type', '', 'trim'), 'president_type_son' => input('request.president_type_son', '', 'trim'), 'promoter_type' => input('request.promoter_type', '', 'trim'), 'start_time' => $startTime, 'end_time' => $endTime, 'username' => input('request.username', '', 'trim'), 'role_name' => input('request.role_name', '', 'trim'), 'role_id' => input('request.roleid', '', 'trim'), 'game_id' => input('request.gameid', 0, 'intval'), 'server_id' => input('request.serverid', '', 'trim'), ]; } /** * 组装角色管理查询条件。 */ private function getRoleCondition(array $filters) { $where = []; if ($filters['game_id'] > 0) { $where['mgs.game_id'] = $filters['game_id']; } if ($filters['username'] !== '') { $userIds = Db::table('cy_members') ->where('username', $filters['username']) ->column('id'); $where['mgs.member_id'] = ['in', empty($userIds) ? [0] : $userIds]; } if ($filters['role_name'] !== '') { $where['mgs.rolename'] = ['like', '%' . $filters['role_name'] . '%']; } if ($filters['role_id'] !== '') { $where['mgs.roleid'] = $filters['role_id']; } if ($filters['server_id'] !== '') { $where['mgs.serverid'] = $filters['server_id']; } // 渠道筛选层级越具体,优先级越高。 if ($filters['business_type'] !== '') { $where['mgs.channel_id'] = ['in', get_child_channel_arr($filters['business_type'])]; } if ($filters['president_type'] !== '') { $where['mgs.channel_id'] = ['in', get_child_channel_arr($filters['president_type'])]; } if ($filters['president_type_son'] !== '') { $where['mgs.channel_id'] = ['in', get_child_channel_arr($filters['president_type_son'])]; } if ($filters['promoter_type'] !== '') { $where['mgs.channel_id'] = $filters['promoter_type']; } if ($filters['start_time'] !== '' && $filters['end_time'] !== '') { $where['mgs.create_time'] = ['between time', [ strtotime($filters['start_time']), strtotime($filters['end_time'] . ' 23:59:59'), ]]; } elseif ($filters['start_time'] !== '') { $where['mgs.create_time'] = ['>=', strtotime($filters['start_time'])]; } elseif ($filters['end_time'] !== '') { $where['mgs.create_time'] = ['<=', strtotime($filters['end_time'] . ' 23:59:59')]; } if ($filters['cooperation_status'] > 0) { $gameCooperationStatus = $filters['cooperation_status'] == 1 ? 1 : 2; $gameIds = Model('Game')->getNormalByIds($gameCooperationStatus); $where['mgs.game_id'] = ['in', $gameIds]; } return $where; } /** * 创建角色管理列表与导出共用查询。 */ private function getRoleQuery(array $where, $forExport = false) { $field = 'mgs.*,m.username'; if ($forExport) { $field = 'mgs.mgs_id,m.username,mgs.game_id,mgs.roleid AS role_id,' . 'mgs.rolename AS role_name,mgs.rolelevel AS role_level,' . 'mgs.serverid AS server_id,mgs.servername AS server_name,' . 'mgs.channel_id,mgs.create_time,mgs.update_time'; } return Db::table('nw_member_game_server') ->alias('mgs') ->field($field) ->join('cy_members m', 'mgs.member_id=m.id', 'left') ->where($where) ->group('mgs.game_id,mgs.serverid,mgs.member_id,mgs.roleid'); } /** * 根据游戏ID获取区服列表(AJAX接口) */ public function getServerListByGame() { $gameId = input('game_id', 0, 'intval'); $serverList = []; if (!empty($gameId)) { $serverList = Db::table('nw_game_server') ->where(['game_id' => $gameId, 'status' => 1]) ->field('id,serverid,servername') ->order('id desc') ->select(); } $this->success('', '', $serverList); } /** * 玩家活跃记录 */ public function playerActive() { $filters = $this->getPlayerActiveFilters(); $where = $this->getPlayerActiveCondition($filters); $pageSize = input('page_size', 20, 'intval'); $pageSize = $pageSize > 0 ? $pageSize : 20; $list = $this->getPlayerActiveQuery($where, $filters) ->order('a.active_hour desc,a.id desc') ->paginate($pageSize, false, ['query' => input('get.')]); $this->hydratePlayerActiveList($list); $gameList = $this->selfGameList; $serverList = []; if (!empty($filters['game_id'])) { $serverList = Db::table('nw_game_server') ->where(['game_id' => $filters['game_id'], 'status' => 1]) ->field('id,servername') ->order('id desc') ->select(); } $this->assign('list', $list); $this->assign('total', $list->total()); $this->assign('page', $list->render()); $this->assign('filters', $filters); $this->assign('game_list', $gameList); $this->assign('server_list', $serverList); // 推广信息,与 getRole 页面保持一致。 $uniom = model('Channel')->where(['level' => 0])->field('id,name')->select(); $this->assign('uniom', $uniom); return $this->fetch('player_active'); } /** * 玩家活跃记录导出 */ public function playerActiveDownload() { if (!request()->isAjax()) { $this->error('非法请求'); } $filters = $this->getPlayerActiveFilters(); $where = $this->getPlayerActiveCondition($filters); $sql = $this->getPlayerActiveQuery($where, $filters, true) ->order('a.active_hour desc,a.id desc') ->fetchSql(true) ->select(); if ((new MakeReportGo())->addTask('playerActiveList', $sql, session_id())) { $this->success('报表生成的任务已经提交, 报表生成完成后,会及时通知您,请耐心稍等'); } $this->error('报表生成任务提交失败,请稍后重试'); } /** * 获取玩家活跃查询参数 */ private function getPlayerActiveFilters() { $activeStartTime = input('request.active_start_time', '', 'trim'); $activeEndTime = input('request.active_end_time', '', 'trim'); // 活跃表数据量会持续增长,无时间条件时默认查询当天。 if ($activeStartTime === '' && $activeEndTime === '') { $activeStartTime = $activeEndTime = date('Y-m-d'); } $filters = [ 'username' => input('request.username', '', 'trim'), 'game_id' => input('request.game_id', 0, 'intval'), 'server_id' => input('request.server_id', '', 'trim'), 'role_name' => input('request.role_name', '', 'trim'), 'role_id' => input('request.role_id', '', 'trim'), 'business_type' => input('request.business_type', 0, 'intval'), 'president_type' => input('request.president_type', 0, 'intval'), 'president_type_son' => input('request.president_type_son', 0, 'intval'), 'promoter_type' => input('request.promoter_type', 0, 'intval'), 'create_start_time' => input('request.create_start_time', '', 'trim'), 'create_end_time' => input('request.create_end_time', '', 'trim'), 'active_start_time' => $activeStartTime, 'active_end_time' => $activeEndTime, 'register_start_time' => input('request.register_start_time', '', 'trim'), 'register_end_time' => input('request.register_end_time', '', 'trim'), ]; $this->validatePlayerActiveTimeRanges($filters); return $filters; } /** * 校验玩家活跃查询中的时间范围。 */ private function validatePlayerActiveTimeRanges(array $filters) { $ranges = [ '角色创建时间' => ['create_start_time', 'create_end_time'], '账号注册时间' => ['register_start_time', 'register_end_time'], '活跃时间' => ['active_start_time', 'active_end_time'], ]; foreach ($ranges as $label => $fields) { $startTime = $filters[$fields[0]]; $endTime = $filters[$fields[1]]; if ($startTime !== '' && $endTime !== '' && strtotime($startTime) > strtotime($endTime)) { $this->error($label . ':开始时间 不能大于 结束时间'); } } } /** * 组装玩家活跃查询条件 */ private function getPlayerActiveCondition(array $filters) { $where = []; if ($filters['game_id'] > 0) { $where['a.game_id'] = $filters['game_id']; } if ($filters['server_id'] !== '') { $where['a.server_id'] = $filters['server_id']; } if ($filters['role_name'] !== '') { $where['a.role_name'] = ['like', $filters['role_name'] . '%']; } if ($filters['role_id'] !== '') { $where['a.role_id'] = $filters['role_id']; } $this->appendPlayerActiveTimeCondition( $where, 'a.active_hour', $filters['active_start_time'], $filters['active_end_time'], false ); $channelCondition = $this->getPlayerActiveChannelCondition($filters); if ($channelCondition !== null) { $where['a.channel_id'] = $channelCondition; } return $where; } /** * 添加时间范围条件。角色和账号时间为时间戳,活跃时间为 DATETIME。 */ private function appendPlayerActiveTimeCondition(array &$where, $field, $startTime, $endTime, $unixTime = true) { if ($startTime !== '' && $endTime !== '') { $start = $unixTime ? strtotime($startTime) : $startTime . ' 00:00:00'; $end = $unixTime ? strtotime($endTime . ' 23:59:59') : $endTime . ' 23:59:59'; $where[$field] = [['>=', $start], ['<=', $end]]; } elseif ($startTime !== '') { $where[$field] = ['>=', $unixTime ? strtotime($startTime) : $startTime . ' 00:00:00']; } elseif ($endTime !== '') { $where[$field] = ['<=', $unixTime ? strtotime($endTime . ' 23:59:59') : $endTime . ' 23:59:59']; } } /** * 获取渠道筛选条件,并继承充值列表对商务账号的数据权限限制。 */ private function getPlayerActiveChannelCondition(array $filters) { $selectedChannelIds = null; if ($filters['promoter_type'] > 0) { $selectedChannelIds = [$filters['promoter_type']]; } elseif ($filters['president_type_son'] > 0) { $selectedChannelIds = get_child_channel_arr($filters['president_type_son']); } elseif ($filters['president_type'] > 0) { $selectedChannelIds = get_child_channel_arr($filters['president_type']); } elseif ($filters['business_type'] > 0) { $selectedChannelIds = get_child_channel_arr($filters['business_type']); } $allowedChannelIds = null; $businessChannelIds = model('common/Business')->getChannelIds(session('ADMIN_ID')); if ($businessChannelIds != -1) { $allowedChannelIds = []; if (is_array($businessChannelIds) && !empty($businessChannelIds) && $businessChannelIds[0] !== '') { foreach (array_unique(array_map('intval', $businessChannelIds)) as $businessChannelId) { if ($businessChannelId > 0) { $allowedChannelIds = array_merge($allowedChannelIds, get_child_channel_arr($businessChannelId)); } } } $allowedChannelIds = array_values(array_unique(array_map('intval', $allowedChannelIds))); } if ($selectedChannelIds !== null && $allowedChannelIds !== null) { $selectedChannelIds = array_values(array_intersect($selectedChannelIds, $allowedChannelIds)); } elseif ($selectedChannelIds === null && $allowedChannelIds !== null) { $selectedChannelIds = $allowedChannelIds; } if ($selectedChannelIds === null) { return null; } $selectedChannelIds = array_values(array_unique(array_filter(array_map('intval', $selectedChannelIds)))); if (empty($selectedChannelIds)) { return -1; } return count($selectedChannelIds) === 1 ? $selectedChannelIds[0] : ['in', $selectedChannelIds]; } /** * 玩家活跃查询。普通列表先查活跃表,区服/角色创建时间等在分页后批量补全。 * 导出通过区服表把 a.server_id 转成 serverid,再关联角色表 create_time。 */ private function getPlayerActiveQuery(array $where, array $filters, $forExport = false) { $query = Db::table('cy_player_active_log')->alias('a') ->where($where); if ($forExport) { $latestRoleSql = Db::table('nw_member_game_server') ->field('member_id,game_id,serverid,roleid,MAX(create_time) as role_reg_time') ->group('member_id,game_id,serverid,roleid') ->buildSql(); $query ->join('cy_members m', 'm.id=a.member_id', 'left') ->join('cy_game game', 'game.id=a.game_id', 'left') ->join( 'nw_game_server game_server', 'game_server.id=a.server_id AND game_server.game_id=a.game_id', 'left' ) ->join( [$latestRoleSql => 'role_latest'], 'role_latest.member_id=a.member_id' . ' AND role_latest.game_id=a.game_id' . ' AND role_latest.serverid=game_server.serverid' . ' AND role_latest.roleid=CONVERT(a.role_id USING utf8)', 'left' ) // 区服名称和渠道层级名称由 Go 根据 server_id、game_id、channel_id 补全。 ->field('a.id,m.username,game.name as game_name,game_server.servername as server_name,a.role_name,a.role_id,a.active_hour,role_latest.role_reg_time,m.reg_time,a.member_id,a.subaccount_id,a.game_id,a.channel_id,a.server_id'); } else { $query->field('a.*'); } $query = $this->appendPlayerActiveMemberCondition($query, $filters); return $this->appendPlayerActiveRoleTimeCondition( $query, $filters['create_start_time'], $filters['create_end_time'] ); } /** * 账号或注册时间有筛选时才访问会员表,避免普通列表每次 JOIN。 */ private function appendPlayerActiveMemberCondition($query, array $filters) { if ( $filters['username'] === '' && $filters['register_start_time'] === '' && $filters['register_end_time'] === '' ) { return $query; } return $query->whereExists(function ($memberQuery) use ($filters) { $memberQuery->table('cy_members') ->alias('member_filter') ->field('1') ->whereExp('member_filter.id', '= a.member_id'); if ($filters['username'] !== '') { $memberQuery->where('member_filter.username', $filters['username']); } if ($filters['register_start_time'] !== '') { $memberQuery->where( 'member_filter.reg_time', '>=', intval(strtotime($filters['register_start_time'])) ); } if ($filters['register_end_time'] !== '') { $memberQuery->where( 'member_filter.reg_time', '<=', intval(strtotime($filters['register_end_time'] . ' 23:59:59')) ); } }); } /** * 角色创建时间筛选:经区服表对齐后,按角色表 create_time 过滤。 */ private function appendPlayerActiveRoleTimeCondition($query, $startTime, $endTime) { if ($startTime === '' && $endTime === '') { return $query; } $startTs = $startTime !== '' ? intval(strtotime($startTime)) : null; $endTs = $endTime !== '' ? intval(strtotime($endTime . ' 23:59:59')) : null; return $query->whereExists(function ($roleQuery) use ($startTs, $endTs) { $roleQuery->table('nw_member_game_server') ->alias('role_filter') ->join( 'nw_game_server role_server', 'role_server.serverid=role_filter.serverid AND role_server.game_id=role_filter.game_id' ) ->field('role_filter.mgs_id') ->whereExp('role_filter.member_id', '= a.member_id') ->whereExp('role_filter.game_id', '= a.game_id') ->whereExp('role_server.id', '= a.server_id') ->whereRaw('role_filter.roleid = CONVERT(a.role_id USING utf8)'); if ($startTs !== null) { $roleQuery->where('role_filter.create_time', '>=', $startTs); } if ($endTs !== null) { $roleQuery->where('role_filter.create_time', '<=', $endTs); } }); } /** * 分页完成后批量补全:账号、游戏、区服,再按四元组查角色 create_time。 */ private function hydratePlayerActiveList($list) { $items = $list->getCollection(); if ($items->isEmpty()) { return; } $memberIds = []; $gameIds = []; foreach ($items as $item) { $memberIds[] = intval($item['member_id']); $gameIds[] = intval($item['game_id']); } $memberIds = array_values(array_unique(array_filter($memberIds))); $gameIds = array_values(array_unique(array_filter($gameIds))); $memberById = []; if (!empty($memberIds)) { foreach (Db::table('cy_members')->where('id', 'in', $memberIds)->field('id,username,reg_time')->select() as $member) { $memberById[intval($member['id'])] = $member; } } $gameById = []; if (!empty($gameIds)) { foreach (Db::table('cy_game')->where('id', 'in', $gameIds)->field('id,name')->select() as $game) { $gameById[intval($game['id'])] = $game['name']; } } foreach ($items as $key => $item) { $row = is_array($item) ? $item : $item->toArray(); $memberId = intval($row['member_id']); $gameId = intval($row['game_id']); $serverRef = (string)$row['server_id']; $roleId = (string)$row['role_id']; $member = $memberById[$memberId] ?? []; $server = $this->resolvePlayerActiveServer($gameId, $serverRef); $channelList = get_top_second_channel_name_v2($row['channel_id']); $row['username'] = $member['username'] ?? ''; $row['reg_time'] = intval($member['reg_time'] ?? 0); $row['game_name'] = $gameById[$gameId] ?? ''; $row['game_server_id'] = $server['serverid'] ?? ''; $row['server_name'] = $server['servername'] ?? ''; $row['role_reg_time'] = $this->getPlayerActiveRoleCreateTime( $memberId, $row['channel_id'], $gameId, $server['serverid'] ?? '', $roleId ); $row['channel_name'] = $channelList['channel_name']; $row['second_channel'] = $channelList['second_name']; $row['top_channel'] = $channelList['top_name']; $row['union_name'] = $channelList['union_name']; $items->offsetSet($key, $row); } } /** * 活跃表 server_id 优先按区服主键查;兼容历史数据直接存游戏侧 serverid 的情况。 */ private function resolvePlayerActiveServer($gameId, $serverRef) { $gameId = intval($gameId); $serverRef = trim((string)$serverRef); if ($gameId <= 0 || $serverRef === '') { return []; } $server = Db::table('nw_game_server') ->where('id', intval($serverRef)) ->where('game_id', $gameId) ->field('id,serverid,servername') ->find(); if (!empty($server)) { return $server; } return Db::table('nw_game_server') ->where(['game_id' => $gameId, 'serverid' => $serverRef]) ->field('id,serverid,servername') ->find() ?: []; } /** * 按 member_id + channel_id + game_id + serverid + role_id 查询角色创建时间。 */ private function getPlayerActiveRoleCreateTime($memberId, $channelId, $gameId, $serverid, $roleId) { $memberId = intval($memberId); $channelId = intval($channelId); $gameId = intval($gameId); $serverid = trim((string)$serverid); $roleId = trim((string)$roleId); if ($memberId <= 0 || $gameId <= 0 || $serverid === '' || $roleId === '') { return 0; } $createTime = Db::table('nw_member_game_server') ->where([ 'member_id' => $memberId, 'channel_id' => $channelId, 'game_id' => $gameId, 'serverid' => $serverid, 'roleid' => $roleId, ]) ->max('create_time'); return intval($createTime); } }