// +---------------------------------------------------------------------- namespace Admin\Model; use Think\Model; use Org\RedisSDK\Redis; /** * 文档基础模型 */ class UserModel extends Model{ /* 自动验证规则 */ protected $_validate = array( array('account', '', -3, self::EXISTS_VALIDATE, 'unique'), //用户名被占用 array('idcard', '', -42, self::EXISTS_VALIDATE, 'unique',EXISTS_VALIDATE), //用户名被占用 ); /* 自动完成规则 */ protected $_auto = array( array('password', 'think_ucenter_md5', self::MODEL_BOTH, 'function', UC_AUTH_KEY), array('anti_addiction', 0, self::MODEL_INSERT), array('lock_status', 1, self::MODEL_INSERT), array('balance', 0, self::MODEL_INSERT), array('cumulative', 0, self::MODEL_INSERT), array('vip_level', 0, self::MODEL_INSERT), array('register_time', NOW_TIME,self::MODEL_INSERT), ); /** * 构造函数 * @param string $name 模型名称 * @param string $tablePrefix 表前缀 * @param mixed $connection 数据库连接信息 */ public function __construct($name = '', $tablePrefix = '', $connection = '') { /* 设置默认的表前缀 */ $this->tablePrefix ='tab_'; /* 执行构造方法 */ parent::__construct($name, $tablePrefix, $connection); } public function login($account,$password,$type,$game_id,$game_name){ $map['account'] = $account; /* 获取用户数据 */ $user = $this->where($map)->find(); if($user==''){ return -1000; } if(is_array($user) && $user['lock_status'] && $user['check_status']){ /* 验证用户密码 */ if(think_ucenter_md5($password, UC_AUTH_KEY) === $user['password'] || $type == 3){ //动态密码 if($user['otp_status'] == 1 && $type == 4){ if (empty(I('post.code'))) { return -1004; } elseif (!R('Sdk/OTP/verifyKey', array($user['id'], I('post.code')))) { return -10041; } } $this->updateLogin($user['id']); //更新用户登录信息 $this->autoLogin($user); if($game_id==0 || empty($game_id)){ $this->user_login_record($user,$type); } return $user['id']; //登录成功,返回用户ID } else { return -10021; //密码错误 } } else { if($user['lock_status'] == 0 || $user['check_status'] == 0){ return -1001;//被禁用 } } } /** * wap 登录 * @param string $account 用户帐号 * @param string $password 密码 * @param integer $type 注册方式 * @param integer $game_id 游戏编号 * @param string $game_name 游戏名称 * @return integer 大于0 登录成功,返回用户ID * @author 鹿文学 */ public function wap_login($account,$password,$type,$game_id,$game_name){ $map['account'] = $account; /* 获取用户数据 */ $user = $this->where($map)->find(); if($user==''){ return -1000; } if(is_array($user) && $user['lock_status'] && $user['check_status']){ /* 验证用户密码 */ if(think_ucenter_md5($password, UC_AUTH_KEY) === $user['password'] || $type == 3){ //动态密码 if($user['otp_status'] == 1 && $type == 4){ if (empty(I('post.code'))) { return -1004; } elseif (!R('Sdk/OTP/verifyKey', array($user['id'], I('post.code')))) { return -10041; } } $this->updateLogin($user['id']); //更新用户登录信息 $this->autoLogin($user,'suser_auth'); if($game_id==0 || empty($game_id)){ $this->user_login_record($user,$type); } return $user['id']; //登录成功,返回用户ID } else { return -10021; //密码错误 } } else { if($user['lock_status'] == 0 || $user['check_status']==0){ return -1001;//被禁用 } } } /** * wap 登录验证 * @return boolean true 已登录,false 已退出 * @author 鹿文学 */ public function wap_is_login() { $user = session('suser_auth'); if($user) {return true;}else{return false;} } /** * wap 退出登录 * @return integer 1 已登录退出,0 未登录 * @author 鹿文学 */ public function wap_logout() { if($this->wap_is_login()) { session('suser_auth',null); session('suser_auth_sign',null); return 1; } else { return 0; } } /** * wap 登录用户信息 * @param string $key 键[可选] * @return array * @author 鹿文学 */ public function wap_login_info($key='') { if(!empty($key)) { return session('suser_auth.' . $key); } else { return session('suser_auth'); } } /** * wap 更改登录用户信息 * @param string $key 键 * @param string $value 值 * @return array * @author 鹿文学 */ public function wap_set_login_info($key='',$value='') { if(!empty($key) && !empty($value)) { session('suser_auth.'.$key,$value); session('suser_auth_sign',null); session('suser_auth_sign', data_auth_sign(session('suser_auth'))); } } /** * wap 更改登录用户全部信息 * @param array $data 要存在session中的数据 * @return array * @author 鹿文学 */ public function wap_set_login_info_array($data) { if(is_array($data)) { session('suser_auth',null); session('suser_auth_sign',null); session('suser_auth',$data); session('suser_auth_sign', data_auth_sign($data)); } } public function third_login($login_data){ $map['openid'] = $login_data['openid']; /* 获取用户数据 */ $user = $this->where($map)->find(); if(is_array($user)){ if($user['lock_status'] == 0 || $user['check_status']==0){ return -1001;//被禁用 } if($user['fgame_id']==0&&$login_data['fgame_id']!=0&&$login_data['fgame_name']!=''){ $this->update_third_Login_($user['id'],$login_data['nickname'],$login_data['fgame_id'],$login_data['fgame_name']); //更新用户登录信息 }else{ $this->update_third_Login($user['id'],$login_data['nickname']); //更新用户登录信息 } $this->autoLogin($user); return $user['id']; //登录成功,返回用户ID } else { if(empty($user)){ $data['account'] = $login_data['account']; $data['password'] = $login_data['account']; $data['nickname'] = $login_data['nickname']; $data['phone'] = ""; $data['openid'] = $login_data['openid']; $data['promote_id'] = $login_data['promote_id']; $data['parent_id'] = $login_data['parent_id']; $data['promote_account'] = $login_data['promote_account']; $data['third_login_type'] = $login_data['third_login_type']; $data['register_way'] = $login_data['register_way']; $data['register_type']=$login_data['register_type']; $data['fgame_id'] = $login_data['fgame_id']; $data['fgame_name'] = $login_data['fgame_name']; $data['is_union'] = $login_data['is_union']; $data['head_img']=$login_data['head_img']; $data['check_time'] = time(); return $this->register($data); } } } //用户登录记录 public function user_login_record($data,$type){ $data=array( 'user_id'=>$data['id'], 'user_account'=>$data['account'], 'user_nickname'=>$data['nickname'], 'server_id'=>null, 'type'=>$type, 'server_name'=>null, 'login_time'=>NOW_TIME, 'login_ip'=>get_client_ip(), 'promote_id'=>$data['promote_id'], ); $uid =M('user_login_record','tab_')->add($data); return $uid ? $uid : 0; //0-未知错误,大于0登录记录成功 } //用户登录记录 public function user_login_record1($data,$type,$game_id,$game_name,$sdk_version){ $data=array( 'user_id'=>$data['id'], 'user_account'=>$data['account'], 'user_nickname'=>$data['nickname'], 'game_id'=>$game_id, 'promote_id'=>$data['promote_id'], 'game_name'=>$game_name, 'sdk_version'=>$sdk_version, 'server_id'=>null, 'type'=>$type, 'server_name'=>null, 'login_time'=>NOW_TIME, 'login_ip'=>get_client_ip(), ); return 1; //0-未知错误,大于0登录记录成功 } //用户登录记录 public function user_login_record2($user,$type,$game_id,$game_name,$sdk_version){ $data=array( 'user_id'=>$user['id'], 'user_account'=>$user['account'], 'user_nickname'=>$user['nickname'], 'game_id'=>$game_id, 'promote_id'=>$user['promote_id'], 'game_name'=>$game_name, 'sdk_version'=>$sdk_version, 'server_id'=>null, 'type'=>$type, 'server_name'=>null, 'login_time'=>NOW_TIME, 'login_ip'=>get_client_ip(), 'lpuid'=>$user['puid'], ); $uid =M('user_login_record','tab_')->add($data); //记录游戏登录信息 M('user_game_login_record','tab_')->add($data); return $uid ? $uid : 0; //0-未知错误,大于0登录记录成功 } /** *游戏用户注册 *user表加game_id */ public function register_($account,$password,$register_way,$register_type,$promote_id=0,$promote_account="",$phone="",$game_id="",$game_name="",$sdk_version=""){ $data = array( 'account' => $account, 'password' => $password, 'nickname' => $account, 'phone' => $phone, 'head_img' =>"http://".$_SERVER['HTTP_HOST'].'/Public/Sdk/logoo.png', 'promote_id' => $promote_id, 'promote_account' => $promote_account, 'register_way' => $register_way, 'register_type' => $register_type, 'register_ip' => get_client_ip(), 'parent_id'=>get_fu_id($promote_id), 'parent_name'=>get_parent_name($promote_id), 'fgame_id' =>$game_id, 'fgame_name'=>$game_name, 'sdk_version'=>$sdk_version, 'check_time' => time() ); if($register_type==2){ $map['phone']=$phone; $find=M('user','tab_')->field('phone')->where($map)->find(); if(null!==$find){ return -3;exit; } } if($register_type==7){ $map['email']=$account; $find=M('user','tab_')->field('email')->where($map)->find(); if(null!==$find){ return -3;exit; } $data['email']=$account; } /* 添加用户 */ if($this->create($data)){ $uid = $this->add(); $u_user['uid']=$uid; $u_user['account']=$account; $u_user['password']=think_encrypt($password); M('user_pwd')->add($u_user); return $uid ? $uid : 0; //0-未知错误,大于0-注册成功 } else { return $this->getError(); //错误详情见自动验证注释 } } /** *游戏用户注册 *user表加game_id */ public function sdk_register_($account,$password,$register_way,$register_type,$promote_id=0,$promote_account="",$phone="",$game_id="",$game_name="",$sdk_version="",$device_type="",$unique_code=""){ $data = array( 'account' => $account, 'password' => $password, 'nickname' => getChinaChar(rand(2,4)), 'phone' => $phone, 'head_img' =>'', 'promote_id' => $promote_id, 'promote_account' => $promote_account, 'register_way' => $register_way, 'register_type' => $register_type, 'register_ip' => get_client_ip(), 'parent_id'=>get_fu_id($promote_id), 'parent_name'=>get_parent_name($promote_id), 'fgame_id' =>$game_id, 'fgame_name'=>$game_name, 'sdk_version'=>$sdk_version, 'check_time' => time(), 'device_type'=>$device_type, 'device_number' =>$unique_code ); if($register_type==2){ $map['phone']=$phone; $find=M('user','tab_')->field('phone')->where($map)->find(); if(null!==$find){ return -3;exit; } } if($register_type==7){ $map['email']=$account; $find=M('user','tab_')->field('email')->where($map)->find(); if(null!==$find){ return -3;exit; } $data['email']=$account; } /* 添加用户 */ if($this->create($data)){ $uid = $this->add(); $u_user['uid']=$uid; $u_user['account']=$account; $u_user['password']=think_encrypt($password); M('user_pwd')->add($u_user); return $uid ? $uid : 0; //0-未知错误,大于0-注册成功 } else { return $this->getError(); //错误详情见自动验证注释 } } /* * 小号注册 */ public function register_small($puid,$account,$register_way=1,$register_type=1,$promote_id=0,$promote_account="",$game_id="",$game_name="",$sdk_version=""){ $data = array( 'account' => $account, 'nickname' => $account, 'head_img' =>"http://".$_SERVER['HTTP_HOST'].'/Public/Sdk/logoo.png', 'promote_id' => $promote_id, 'promote_account' => $promote_account, 'register_way' => $register_way, 'register_type' => $register_type, 'register_ip' => get_client_ip(), 'parent_id'=>get_fu_id($promote_id), 'parent_name'=>get_parent_name($promote_id), 'fgame_id' =>$game_id, 'fgame_name'=>$game_name, 'sdk_version'=>$sdk_version, 'puid' => $puid, ); /* 添加用户 */ if($this->create($data)){ $uid = $this->add(); $u_user['uid']=$uid; $u_user['account']=$account; $u_user['password']=think_encrypt($password); M('user_pwd')->add($u_user); return $uid ? $uid : 0; //0-未知错误,大于0-注册成功 } else { return $this->getError(); //错误详情见自动验证注释 } } /** *游戏用户注册 */ public function register($data){ $data = array( 'account' => $data['account'], 'password' => $data['password'], 'nickname' => $data['nickname'], 'phone' => $data['phone'], 'openid' => $data['openid'], 'promote_id' => empty($data['promote_id'])?0:$data['promote_id'], 'head_img' =>empty($data['head_img'])?"http://".$_SERVER['HTTP_HOST'].'/Public/Sdk/logoo.png':$data['head_img'], 'promote_account' =>empty($data['promote_account'])?"自然注册":$data['promote_account'], 'third_login_type' => $data['third_login_type'], 'register_way' => $data['register_way'], 'register_type' => $data['register_type'], 'register_ip' => get_client_ip(), 'parent_id'=>empty($data['parent_id'])?0:$data['parent_id'], 'parent_name'=>$data['parent_name'], 'fgame_id'=>$data['fgame_id'], 'fgame_name'=>$data['fgame_name'], 'is_union'=>$data['is_union'], 'register_time'=>$data['register_time'], 'real_name'=>$data['real_name'], 'idcard'=>$data['idcard'], 'age_status'=>$data['age_status'], 'sex' => $data['sex'], 'check_time' => time() ); /* 添加用户 */ if($this->create($data)){ $uid = $this->add(); $data['id'] = $uid; $this->autoLogin($data); if(!empty($data['openid'])){ $this->update_third_Login($data['id'],$data['nickname']); } $u_user['uid']=$uid; $u_user['account']=$data['account']; $u_user['password']=think_encrypt($data['password']); M('user_pwd')->add($u_user); return $uid ? $uid : 0; //0-未知错误,大于0-注册成功 } else { return $this->getError(); //错误详情见自动验证注释 } } /** * wap 注册 * @author 鹿文学 */ public function wap_register($data){ $data = array( 'account' => $data['account'], 'password' => $data['password'], 'nickname' => $data['nickname'], 'phone' => $data['phone'], 'openid' => $data['openid'], 'promote_id' => empty($data['promote_id'])?0:$data['promote_id'], 'head_img' =>empty($data['head_img'])?"http://".$_SERVER['HTTP_HOST'].'/Public/Sdk/logoo.png':$data['head_img'], 'promote_account' =>empty($data['promote_account'])?"自然注册":$data['promote_account'], 'third_login_type' => $data['third_login_type'], 'register_way' => $data['register_way'], 'register_type' => $data['register_type'], 'register_ip' => get_client_ip(), 'parent_id'=>empty($data['parent_id'])?0:$data['parent_id'], 'parent_name'=>$data['parent_name'], 'fgame_id'=>$data['fgame_id'], 'fgame_name'=>$data['fgame_name'], 'is_union'=>$data['is_union'], 'register_time'=>$data['register_time'], 'real_name'=>$data['real_name'], 'idcard'=>$data['idcard'], 'age_status'=>$data['age_status'], 'sex' => $data['sex'], 'check_time' => time() ); /* 添加用户 */ if($this->create($data)){ $uid = $this->add(); $data['id'] = $uid; $this->autoLogin($data,'suser_auth'); if(!empty($data['openid'])){ $this->update_third_Login($data['id'],$data['nickname']); } $u_user['uid']=$uid; $u_user['account']=$data['account']; $u_user['password']=think_encrypt($data['password']); M('user_pwd')->add($u_user); return $uid ? $uid : 0; //0-未知错误,大于0-注册成功 } else { return $this->getError(); //错误详情见自动验证注释 } } /** *游戏用户注册 */ public function sdk_register($data){ $data = array( 'account' => $data['account'], 'password' => $data['password'], 'nickname' => $data['nickname'], 'phone' => $data['phone'], 'openid' => $data['openid'], 'promote_id' => empty($data['promote_id'])?0:$data['promote_id'], 'head_img' =>empty($data['head_img'])?'':$data['head_img'], 'promote_account' =>empty($data['promote_account'])?"自然注册":$data['promote_account'], 'third_login_type' => $data['third_login_type'], 'register_way' => $data['register_way'], 'register_type' => $data['register_type'], 'register_ip' => get_client_ip(), 'parent_id'=>empty($data['parent_id'])?0:$data['parent_id'], 'parent_name'=>$data['parent_name'], 'fgame_id'=>$data['fgame_id'], 'fgame_name'=>$data['fgame_name'], 'is_union'=>$data['is_union'], 'register_time'=>$data['register_time'], 'real_name'=>$data['real_name'], 'idcard'=>$data['idcard'], 'age_status'=>$data['age_status'], 'sex' => $data['sex'], 'check_time' => time() ); /* 添加用户 */ if($this->create($data)){ $uid = $this->add(); $data['id'] = $uid; $this->autoLogin($data); if(!empty($data['openid'])){ $this->update_third_Login($data['id'],$data['nickname']); } $u_user['uid']=$uid; $u_user['account']=$data['account']; $u_user['password']=think_encrypt($data['password']); M('user_pwd')->add($u_user); return $uid ? $uid : 0; //0-未知错误,大于0-注册成功 } else { return $this->getError(); //错误详情见自动验证注释 } } /** *app用户注册 */ public function app_register($account,$password,$register_way,$register_type,$nickname,$sex,$promote_id){ $data = array( 'account' => $account, 'password' => $password, 'register_way' => $register_way, 'register_type' => $register_type, 'nickname' => $nickname, 'sex' => $sex, 'login_time'=>time(), 'head_img' =>'', 'phone' => $account, 'register_ip' => get_client_ip(), 'promote_id' => $promote_id, 'promote_account' => get_promote_account($promote_id), 'check_time' => time() ); if($register_type==1){ unset($data['phone']); }else{ $map['phone']=$account; $find=M('user','tab_')->field('phone')->where($map)->find(); if(null!==$find){ return -3;exit; } } /* 添加用户 */ if($this->create($data)){ $uid = $this->add(); $u_user['uid']=$uid; $u_user['account']=$account; $u_user['password']=think_encrypt($password); M('user_pwd')->add($u_user); return $uid ? $uid : 0; //0-未知错误,大于0-注册成功 } else { return $this->getError(); //错误详情见自动验证注释 } } public function app_third_register($reg_data){ $data = array( 'account' => $reg_data['account'], 'password' => $reg_data['password'], 'nickname' => $reg_data['nickname'], 'phone' => $reg_data['phone'], 'openid' => $reg_data['openid'], 'promote_id' => empty($reg_data['promote_id'])?0:$reg_data['promote_id'], 'head_img' =>empty($reg_data['head_img'])?'':$reg_data['head_img'], 'promote_account' =>empty($reg_data['promote_account'])?"自然注册":$reg_data['promote_account'], 'third_login_type' => $reg_data['third_login_type'], 'register_way' => $reg_data['register_way'], 'register_type' => $reg_data['register_type'], 'register_ip' => get_client_ip(), 'login_ip' => get_client_ip(), 'login_time'=>time(), 'register_time'=>time(), 'sex' => $reg_data['sex'], 'check_time' => time() ); if($this->create($data)){ $uid = $this->add(); return $uid ? $uid : 0; } else { return $this->getError(); } } /** *修改用户信息 */ public function updateUser($data){ $c_data = $this->create($data); if(empty($data['password'])){ unset($c_data['password']); } elseif(isset($data['register_type'])){ } else { if(!$this->verifyUser($data['id'],$data['old_password'])){ return -2; }else{ $u_map['uid']=$data['id']; M('user_pwd')->where($u_map)->setField('password',think_encrypt($c_data['password'])); } } return $this->where("id=".$data['id'])->save($c_data); } /** * 获取详情页数据 * @param integer $id 文档ID * @return array 详细数据 */ public function detail($id){ /* 获取基础数据 */ $info = $this->field(true)->find($id); if(!(is_array($info) || 1 !== $info['status'])){ $this->error = '文档被禁用或已删除!'; return false; } /* 获取模型数据 */ $logic = $this->logic($info['model_id']); $detail = $logic->detail($id); //获取指定ID的数据 if(!$detail){ $this->error = $logic->getError(); return false; } $info = array_merge($info, $detail); return $info; } /** *检查账号是否存在 */ public function checkAccount($account){ $map['account'] = $account; $map['phone'] = $account; $map['_logic'] = "OR"; $data = $this->where($map)->find(); if(empty($data)){return true;} return false; } // 检查用户 lwx public function checkUsername($account){ $map['account'] = $account; $data = $this->where($map)->find(); if(empty($data)){return true;} return false; } // 检查身份证 yyh public function checkIdcard($account){ $map['idcard'] = $account; $data = $this->where($map)->find(); if(empty($data)){return true;} return false; } // 更改密码 lwx 2015-05-20 public function updatePassword($id,$password) { $map['id']=$id; $data['password']=think_ucenter_md5($password, UC_AUTH_KEY); $return = $this->where($map)->save($data); if ($return !== false){ $u_map['uid']=$id; M('user_pwd')->where($u_map)->setField('password',think_encrypt($password)); return true; } else{ return false; } } public function checkPassword($account,$password) { $map['account'] = $account; $map['password'] = think_ucenter_md5($password, UC_AUTH_KEY); $user = $this->where($map)->find(); if(is_array($user) && $user['lock_status']){ return true; } else { return false; } } protected function updateLogin($uid){ $model = M('User','tab_'); $data["id"] = $uid; $data["login_time"] = NOW_TIME; $data["login_ip"] = get_client_ip(); $model->save($data); } protected function update_third_Login($uid,$nickname){ $model = M('User','tab_'); $data["id"] = $uid; $data['nickname'] = $nickname; $data["login_time"] = NOW_TIME; $data["login_ip"] = get_client_ip(); $model->save($data); } protected function update_third_Login_($uid,$nickname,$fgame_id,$fgame_name){ $model = M('User','tab_'); $data["id"] = $uid; $data['nickname'] = $nickname; $data["login_time"] = NOW_TIME; $data["fgame_id"] = $fgame_id; $data["fgame_name"] = $fgame_name; $data["login_ip"] = get_client_ip(); $model->save($data); } /** * 自动登录用户 * @param integer $user 用户信息数组 */ private function autoLogin($user,$session_name='user_auth'){ /* 记录登录SESSION和COOKIES */ $auth = array( 'user_id' => $user['id'], 'account' => $user['account'], 'nickname' => $user['nickname'], ); session($session_name, $auth); session($session_name.'_sign', data_auth_sign($auth)); } /** *更新玩家信息 */ public function updateInfo($data){ $new_data = $this->create($data); if(empty($data['password'])){ unset($new_data['password']); }else{ $user = $this->where(['id'=>$data['id']])->find(); if( C('UC_OPEN')==1 ){ $res = uc_user_edit($user['account'],'',$data['password'],'',1); if($res != 1) {return false;} /** * 同步修改其他站点用户密码 */ $domain = C('UC_OTHER_WEB_URL'); $username = get_user_account($data['id']); if(!empty($domain)){ $url = "http://{$domain}/Api/user/editPassword?account={$username}&type=1&newpsw={$data['password']}"; $aa = json_decode(file_get_contents($url),true); } } $u_map['uid']=$data['id']; M('user_pwd')->where($u_map)->setField('password',think_encrypt($new_data['password'])); } $return = $this->save($new_data); return $return; } public function save_alipay($id,$data) { if (!empty($data['password'])) { $password = $data['password']; unset($data['password']); $user = $this->where(['id'=>$id])->find(); if(think_ucenter_md5($password, UC_AUTH_KEY) != $user['password']) { $this->error='游戏平台密码错误'; return 0; } } else {unset($data['password']);} $res = $this->where(['id'=>$id])->save($data); if($res) { $this->error='添加成功'; } else { $this->error='添加失败'; } return $res; } public function updateUserInfo($data) { if(!empty($data['id'])) { if (empty($data['password'])) { unset($data['password']); } if(count($data)==1 && $data['id']) {$this->error='修改成功';return true;} $result = $this->updateInfo($data); if($result) $this->error='修改成功'; else $this->error='修改失败'; return $result; } else { if(empty($data['account'])) {$this->error = '请输入账户';return false;} if(!preg_match('/^[a-zA-Z0-9]{6,20}$/',$data['account'])) { $this->error = '账户由6-20位数字字母组合';return false; } if(empty($data['password'])) {$this->error = '请输入密码';return false;} if(!preg_match('/^.{6,15}$/u',$data['password'])) { $this->error = '密码由6-15位字符';return false; } if(empty($data['real_name'])) {$this->error = '请输入真实姓名';return false;} if(!preg_match('/^[\x{4e00}-\x{9fa5}]{2,8}$/u',$data['real_name'])) { $this->error = '真实姓名由2-8位汉字';return false; } if(empty($data['idcard'])) {$this->error = '请输入身份证号';return false;} if(!empty($data['account'])) { $data['account'] = 'pa_'.str_replace('pa_','',$data['account']); } $new_data = $this->create($data); if($new_data) { $return = $this->add($new_data); if($return>0) { $u_user['uid']=$return; $u_user['account']=$new_data['account']; $u_user['password']=think_encrypt($new_data['password']); M('user_pwd')->add($u_user); $this->error = '添加成功'; return $return; } else{ $this->error = '添加失败'; return $return; } } else { return $this->getError(); } } } /** * 验证用户密码 * @param int $uid 用户id * @param string $password_in 密码 * @return true 验证成功,false 验证失败 * @author huajie */ protected function verifyUser($uid, $password_in){ $password = $this->getFieldById($uid, 'password'); if(think_ucenter_md5($password_in, UC_AUTH_KEY) === $password){ return true; } return false; } /** * 创建时间不写则取当前时间 * @return int 时间戳 * @author huajie */ protected function getCreateTime(){ $create_time = I('post.create_time'); return $create_time?strtotime($create_time):NOW_TIME; } /** * 生成不重复的name标识 * @author huajie */ private function generateName(){ $str = 'abcdefghijklmnopqrstuvwxyz0123456789'; //源字符串 $min = 10; $max = 39; $name = false; while (true){ $length = rand($min, $max); //生成的标识长度 $name = substr(str_shuffle(substr($str,0,26)), 0, 1); //第一个字母 $name .= substr(str_shuffle($str), 0, $length); //检查是否已存在 $res = $this->getFieldByName($name, 'id'); if(!$res){ break; } } return $name; } /** *第三方用户登录/注册 */ public function tr_register($userinfo){ $data = array( 'account' => $userinfo['account'], 'password' => $userinfo['account'], 'nickname' => $userinfo['nickname'], 'promote_id' => $userinfo['promote_id'], 'promote_account' => $userinfo['promote_account'], 'register_way' => $userinfo['register_way'], 'register_type' => $userinfo['register_type'], 'register_ip' => get_client_ip(), 'parent_id'=>get_fu_id($userinfo['promote_id']), 'parent_name'=>get_parent_name($userinfo['$promote_id']), 'fgame_id' =>$userinfo['game_id'], 'fgame_name'=>get_game_name($userinfo['game_id']), 'sdk_version'=>$userinfo['sdk_version'], 'openid' =>$userinfo['openid'], 'check_time' => time(), 'device_type' => $userinfo['device_type'], 'device_number' => $userinfo['unique_code'] ); /* 添加用户 */ if($this->create($data)){ $uid = $this->add(); $u_user['uid']=$uid; $u_user['account']=$userinfo['account']; $u_user['password']=think_encrypt($userinfo['password']); M('user_pwd')->add($u_user); $this->autoLogin($uid); return $uid ? $uid : 0; //0-未知错误,大于0-注册成功 } else { return $this->getError(); //错误详情见自动验证注释 } } public function login_($account,$password,$type=1,$game_id,$game_name,$sdk_version){ $map['account'] = $account; /* 获取用户数据 */ $user = $this->where($map)->find(); if(is_array($user) && $user['lock_status'] && $user['check_status']){ /* 验证用户密码 */ if(think_ucenter_md5($password, UC_AUTH_KEY) === $user['password']||$type==2){ $token = $this->updateLogin_($user['id'],$account,$password,$user['fgame_id'],$game_id,$game_name); //更新用户登录信息 $this->user_login_record($user,$type,$game_id,$game_name,$sdk_version); return array("user_id"=>$user['id'],"token"=>$token); //登录成功,返回用户ID } else { return -2; //密码错误 } } else { return -1; //用户不存在或被禁用 } } public function login_1($account,$password,$type=1,$game_id,$game_name,$sdk_version){ $map['account'] = $account; /* 获取用户数据 */ $user = $this->where($map)->find(); if(is_array($user) && $user['lock_status'] && $user['check_status']){ /* 验证用户密码 */ if(think_ucenter_md5($password, UC_AUTH_KEY) === $user['password']||$type==2){ $token = $this->updateLogin_($user['id'],$account,$password,$user['fgame_id'],$game_id,$game_name); //更新用户登录信息 $this->user_login_record1($user,$type,$game_id,$game_name,$sdk_version); return array("user_id"=>$user['id'],"token"=>$token); //登录成功,返回用户ID } else { return -2; //密码错误 } } else { return -1; //用户不存在或被禁用 } } public function login_sdk($account,$password,$type=1,$game_id,$game_name,$sdk_version,$unique_code){ $map['account'] = $account; /* 获取用户数据 */ $user = $this->where($map)->find(); if(is_array($user) && $user['lock_status'] && $user['check_status']){ /* 验证用户密码 */ if(think_ucenter_md5($password, UC_AUTH_KEY) === $user['password']||$type==2){ $test_resource = M('test_resource','tab_')->where("user_id=%s and apply_status=2",$user['id'])->find();//测试资源(扶持号) if($test_resource){ //扶持号 if($user['device_number'] && $unique_code && $user['device_number'] !=$unique_code){ //#当前登录设备信息与历史登录设备信息不一致,触发账户冻结 $this->sdklogin_device_error($user,$test_resource,$unique_code); $this->sdklogin_ip_error($user,$test_resource,get_client_ip()); return -1;//扶持号被禁用 }else{ $token = $this->sdklogin_update($user,$account,$password,$user['fgame_id'],$game_id,$game_name,$unique_code); //更新用户登录信息 $this->user_login_record2($user,$type,$game_id,$game_name,$sdk_version); $this->sdklogin_ip_error($user,$test_resource,get_client_ip()); return array("user_id"=>$user['id'],"token"=>$token); //登录成功,返回用户ID } }else{ $token = $this->sdklogin_update($user,$account,$password,$user['fgame_id'],$game_id,$game_name,$unique_code); //更新用户登录信息 $this->user_login_record2($user,$type,$game_id,$game_name,$sdk_version); return array("user_id"=>$user['id'],"token"=>$token); //登录成功,返回用户ID } } else { return -2; //密码错误 } } else { return -1; //用户不存在或被禁用 } } //更新用户登录信息 protected function sdklogin_update($user,$account,$password,$user_fgame_id,$game_id,$game_name,$unique_code=''){ $model = M('User','tab_'); $uid = $user['id']; $data["id"] = $uid; $data["login_time"] = NOW_TIME; $data["login_ip"] = get_client_ip(); $data["device_number"] = $unique_code; $data["last_login_ip"] = $user['login_ip']; $data["last_device_number"] = $user['device_number']; $data["token"] = $this->generateToken($uid,$account,$password); if($user_fgame_id){ $model->save($data); }else{ $data['fgame_id']=$game_id; $data['fgame_name']=$game_name; $model->save($data); $device_type = M('User','tab_')->where(['id' => $user['id']])->getField('device_type'); if(empty($device_type)){ $gameServer = substr($game_name, -10, 9); if($gameServer == '安卓版'){ $arr['device_type'] = 'Android'; } elseif($gameServer == '苹果版') { $arr['device_type'] = 'IOS'; } $arr['time'] = time(); $arr['account'] = $account; ksort($arr); reset($arr); $sign = md5(http_build_query($arr) . C('GET_INFO_KEY')); $arr['sign'] = $sign; $reData = curl_post('http://oa.76ba.com/api/wanmeng/deviceTypeUpdate',$arr); } } return $data["token"]; } // 扶持号登录设备异常 protected function sdklogin_device_error($user,$resource,$unique_code){ $model = M('User','tab_'); $uid = $user['id']; $data["id"] = $uid; $data["device_number"] = $unique_code; $data["last_device_number"] = $user['device_number']; $data["lock_status"] = 0 ; $model->save($data); $protect_data['user_id']= $uid; $protect_data['user_account']= $resource['user_account']; $protect_data['server_id'] = $resource['server_id']; $protect_data['server_name']= $resource['server_name']; $protect_data['game_id']=$resource['game_id']; $protect_data['game_name']=$resource['game_name']; $protect_data['nickname']=$resource['role_name']; $protect_data['promote_id']=$resource['promote_id']; $protect_data['promote_account']=$resource['promote_account']; $protect_data['type']=2; $protect_data['detail']="登录设备号异常,本次异常设备号:".$unique_code.",历史登录设备号:".$user['device_number']; $protect_data['create_time'] = NOW_TIME; M('protect_log','tab_')->add($protect_data); } // 扶持号登录IP异常 protected function sdklogin_ip_error($user,$resource,$ip){ $newloginip_source = file_get_contents("http://ip.taobao.com/service/getIpInfo.php?ip=".$ip); $aldloginip_source = file_get_contents("http://ip.taobao.com/service/getIpInfo.php?ip=".$user['login_ip']); $newloginip_source = json_decode($newloginip_source,true); $aldloginip_source = json_decode($aldloginip_source,true); if($newloginip_source['data']['city']!=$aldloginip_source['data']['city']){ //登录城市不一致时触发IP异常 $uid = $user['id']; $protect_data['user_id']= $uid; $protect_data['user_account']= $resource['user_account']; $protect_data['server_id'] = $resource['server_id']; $protect_data['server_name']= $resource['server_name']; $protect_data['game_id']=$resource['game_id']; $protect_data['game_name']=$resource['game_name']; $protect_data['nickname']=$resource['role_name']; $protect_data['promote_id']=$resource['promote_id']; $protect_data['promote_account']=$resource['promote_account']; $protect_data['type']=1; $protect_data['detail']="登录IP异常,本次异常IP:".$ip.",历史登录IP:".$user['login_ip']; $protect_data['create_time'] = NOW_TIME; M('protect_log','tab_')->add($protect_data); } } //判断game_id是否有值 protected function updateLogin_($uid,$account,$password,$user_fgame_id,$game_id,$game_name){ $model = M('User','tab_'); $data["id"] = $uid; $data["login_time"] = NOW_TIME; $data["login_ip"] = get_client_ip(); $data["token"] = $this->generateToken($uid,$account,$password); if($user_fgame_id){ $model->save($data); }else{ $data['fgame_id']=$game_id; $data['fgame_name']=$game_name; $model->save($data); } return $data["token"]; } /** *随机生成token */ protected function generateToken($user_id,$account,$password){ $str = $user_id.$account.$password.NOW_TIME.sp_random_string(7); $token = MD5($str); return $token; } /** * 更新游戏角色数据 * @param $id */ public function update_user_player($ids){ $ids = is_array($ids) ? $ids : [$ids]; $success_num = 0; foreach ($ids as $id){ $data = M('user_play_info','tab_')->find($id); $account = $data['user_account']; $game_id = $data['game_id']; $server_id = $data['server_id']; $game = M('game','tab_')->find($game_id); $url = $game['game_role_url']; if(empty($url)){ continue; } $param['account'] = $account; $param['game_id'] = $game_id; $param['server_id'] = $server_id; $res = $this->post_data($url,$param); if($res){ $data['role_name'] = $res['role_name']; $data['role_level'] = $res['role_level']; $result = M('user_play_info','tab_')->save($data); if($result !== false){ $success_num++; } }else{ } } $result['suc'] = $success_num; $result['ero'] = count($ids) - $success_num; return $result; } /** * 用户平台币修改 * @param $promote_account 渠道帐号 * @param $num 平台币数量 * @param $type 1:增加 2:收回 */ public function edit_user_balance_coin($user_id,$num){ //开启事务 $this->startTrans(); $map['id'] = $user_id; $data = $this->field('puid,balance')->where($map)->find(); if(!empty($data) && $data['puid']>0) { $map['id'] = $data['puid']; $data = $this->field('balance')->where($map)->find(); } $data['balance'] -= (int)$num; if($data['balance'] < 0){ $this->error = "该用户平台币小于所要扣除的平台币!"; $this->rollback(); return false; } $res = $this->where($map)->save($data); $rec = D('UserCoin')->record($user_id,$num); if($res && $rec){ //事务提交 $this->commit(); \Think\Log::actionLog('PromoteCoin/deduct/type/1','PromoteCoin',0); return true; }else{ //事务回滚 $this->rollback(); return false; } } /** * 请求链接 * @param $url 请求地址 * @param $data 请求参数 * @return mixed */ function post_data($url, $param = array()) { if (empty($url) || empty($param)) { return false; } $ch = curl_init();//初始化curl curl_setopt($ch, CURLOPT_URL, $url);//抓取指定网页 curl_setopt($ch, CURLOPT_HEADER, 0);//设置header curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//要求结果为字符串且输出到屏幕上 curl_setopt($ch, CURLOPT_POST, 1);//post提交方式 curl_setopt($ch, CURLOPT_POSTFIELDS, $param); $data = curl_exec($ch);//运行curl curl_close($ch); return $data; } /** * 获取登录游戏信息并记录登录信息 * @param array $map 条件数组 * @param integer $game_id 游戏编号 * @param string $game_name 游戏名称 * @param $sdk_version $sdk_version 游戏类型(1安卓2苹果) * @param integer $type 用户名类型(1-用户名,2-邮箱,3-手机,4-UID) * @return array/integer * @author 鹿文学 */ public function get_enter_game_info($map=array(),$account,$game_id,$game_name,$sdk_version,$type=4) { switch($type) { case 1:{$map['account'] = $account;};break; case 2:{$map['email'] = $account;};break; case 3:{$map['phone'] = $account;};break; case 4:{$map['id'] = $account;};break; } /* 获取用户数据 */ $user = $this->where($map)->find(); if(is_array($user) && $user['lock_status']){ $token = $this->updateLogin_($user['id'],$account,'',$user['fgame_id'],$game_id,$game_name); //更新用户登录信息 $this->user_login_record2($user,$type,$game_id,$game_name,$sdk_version); return array('user_id'=>$user['id'],'account'=>$user['account'],'token'=>$token); //登录成功,返回用户ID } else { return -1; //用户不存在或被禁用 } } /** * 用户分析 * @param integer $promote_id 推广员编号 * @param integer $game_id 游戏编号 * @return array 用户分析结果集 * @author 鹿文学 */ public function user($promote_id='',$game_id='') { $redis = new Redis(['host'=>'127.0.0.1','port'=>6379],[]); //所有键值 $keys = $redis->keys('analysis_*'); $all = M('analysis','tab_')->field('id')->count(); if(!$keys || (($all - count($keys)) > 100)){ //redis不存在,写入redis数据 get_redis_data(); $keys = $redis->keys('analysis_*'); } //所有value数组 $analysis = $redis->mget($keys); //组合数组为键值对 $analysis = array_combine($keys,$analysis); $data = []; if(!empty($_GET['start']) && !empty($_GET['end'])) { $start = strtotime($_GET['start']); $end = strtotime($_GET['end']); } elseif (!empty($_GET['start']) && empty($_GET['end'])) { $start = strtotime($_GET['start']); $end = strtotime(date('Y-m-d',time())); } elseif (empty($_GET['start']) && !empty($_GET['end'])) { $result = $this->field('register_time')->find(); $start = $result['register_time']; $end = strtotime($_GET['end']); } else { $result = $this->field('register_time')->find(); $start = $result['register_time']; $end = strtotime(date('Y-m-d',time())); } $map2=[]; $map = array(); $map2['tab_user_login_record.login_time']=$map['register_time'] = ['between',[$start,$end+86399]]; $datelist = get_date_list($start,$end); foreach ($datelist as $key => $value) { $data[$key] = array( 'time'=>$value, 'news'=>0, 'old'=>0, 'dau'=>0, 'wau'=>0, 'mau'=>0, ); if($promote_id && $game_id){ $shuju = json_decode($analysis['analysis_'.$value.'_promote_'.$promote_id.'_game_'.$game_id],true); }elseif($promote_id){ $shuju = json_decode($analysis['analysis_'.$value.'_promote_'.$promote_id],true); }elseif ($game_id){ $shuju = json_decode($analysis['analysis_'.$value.'_game_'.$game_id],true); }else{ $shuju = json_decode($analysis['analysis_'.$value],true); } $data[$key]['news'] = $shuju['new_count'] ? $shuju['new_count'] : 0; $data[$key]['old'] = $shuju['active_count'] ? ($shuju['active_count'] - $shuju['new_count']) : 0; $data[$key]['dau'] = $shuju['active_count'] ? $shuju['active_count'] : 0; $t = strtotime($value); $datewau = get_date_list(strtotime('-6 day',$t),$t+86399); $datemau = get_date_list(strtotime('-30 day',$t),$t+86399); $active_wau = array(); $active_mau = array(); foreach ($datewau as $kk=>$vv){ if($promote_id && $game_id){ $zishuju = json_decode($analysis['analysis_'.$vv.'_promote_'.$promote_id.'_game_'.$game_id],true); }elseif($promote_id){ $zishuju = json_decode($analysis['analysis_'.$vv.'_promote_'.$promote_id],true); }elseif ($game_id){ $zishuju = json_decode($analysis['analysis_'.$vv.'_game_'.$game_id],true); }else{ $zishuju = json_decode($analysis['analysis_'.$vv],true); } if($analysis['analysis_'.$vv]){ $active_wau[] = array_filter(explode(',',$zishuju['active_id'])); } } $data[$key]['wau'] = count(array_unique(array_reduce($active_wau, 'array_merge', array()))); foreach ($datemau as $kk=>$vv){ if($promote_id && $game_id){ $zishuju = json_decode($analysis['analysis_'.$vv.'_promote_'.$promote_id.'_game_'.$game_id],true); }elseif($promote_id){ $zishuju = json_decode($analysis['analysis_'.$vv.'_promote_'.$promote_id],true); }elseif ($game_id){ $zishuju = json_decode($analysis['analysis_'.$vv.'_game_'.$game_id],true); }else{ $zishuju = json_decode($analysis['analysis_'.$vv],true); } if($analysis['analysis_'.$vv] && $zishuju['active_id']){ $active_mau = array_merge($active_mau, explode(',',$zishuju['active_id'])); } } $data[$key]['mau'] = count(array_unique($active_mau)); } krsort($data); return $data; } /** * 用户分析 * @param integer $start 开始时间(时间戳) * @param integer $end 结束时间(时间戳) * @param integer $promote_id 推广员编号 * @param integer $game_id 游戏编号 * @return array 用户分析结果集 * @author 鹿文学 */ public function user1($start,$end,$promote_id='',$game_id='') { $data = ''; $datelist = get_date_list($start,$end); $map2=[]; $map = array(); if ($promote_id) { $map2['tab_user.promote_id']=$map['promote_id'] = $promote_id; } if ($game_id) { $map2['tab_user_login_record.game_id']=$map['fgame_id'] = $game_id; } // 老用户 $old = $this->totalPlayerByGroup($datelist,array_merge($map2,array('tab_user_login_record.login_time'=>['between',[$start,$end+86399]])),'old','time',1,'time',true); $week = $this->getActiveBeforeSetDate(6,$start,$end,$map2,'week','time',true); $month = $this->getActiveBeforeSetDate(30,$start,$end,$map2,'month','time',true); foreach ($datelist as $key => $value) { $data[$key]['time'] = $value; $data[$key]['news'] = 0 ; $data[$key]['old'] = 0; $data[$key]['dau'] = 0; foreach ($old as $v) { if ($v['time'] == $value) { $data[$key]['old'] = $v['old']; $data[$key]['dau'] = $v['old']; break; } } $data[$key]['wau'] = 0; foreach ($week as $k => $v) { if ($v['time']==$value) { $data[$key]['wau'] += $v['week'];break; } } $data[$key]['mau'] = 0; foreach ($month as $k => $v) { if ($v['time']==$value) { $data[$key]['mau'] += $v['month'];break; } } } // 新增用户 $user = $this->newsAdd(array_merge($map,array('register_time'=>['between',[$start,$end+86399]]))); if ($user) { foreach($data as $key => $value) { foreach($user as $k => $v) { if ($v['time']==$value['time']) { $data[$key]['news'] = $v['news']; $data[$key]['dau'] += $v['news']; break; } } } } krsort($data); return $data; } /** * 分组统计玩家 * @param string $type 减去天数 * @param integer $start 开始时间戳 * @param integer $end 结束时间戳 * @param array $map 条件数组 * @param string $fieldname 字段别名 * @param string $group 分组字段名 * @return array 详细数据 * @author 鹿文学 */ public function getActiveBeforeSetDate($type,$start,$end,$map,$fieldname='count',$group='time') { $datelist = get_date_list($start,$end); foreach ($datelist as $k => $v) { $t = strtotime($v); $count = $this->active(array('tab_user_login_record.login_time'=>['between',[strtotime('-'.$type.' day',$t),$t+86399]])); $data[$k] = [$group=>$v,$fieldname => $count]; } return $data; } /** * 分组统计玩家 * @param array $map 条件数组 * @param string $fieldname 字段别名 * @param string $group 分组字段名 * @param integer $flag 时间类别(1:天,2:月,3:周) * @param string $order 排序 * @param boolean $cut false 不去除新用户 * @return array 详细数据 * @author 鹿文学 */ public function totalPlayerByGroup($datelist,$map,$fieldname='count',$group='time',$flag=1,$order='time',$cut=false) { switch($flag) { case 2:{$dateform = '%Y-%m';};break; case 3:{$dateform = '%Y-%u';};break; case 4:{$dateform = '%Y';};break; case 5:{$dateform = '%Y-%m-%d %H';};break; default:$dateform = '%Y-%m-%d'; } if (strpos($order,'desc') !== false) {rsort($datelist);} foreach($datelist as $k => $v) { $data[$k]=[$group=>$v,$fieldname=>0]; } if ($flag == 5) { $start = $map['tab_user_login_record.login_time']; $map['tab_user.register_time'] = array('lt',$start[1][0]); $sql = $this->field('FROM_UNIXTIME(tab_user_login_record.login_time,"'.$dateform.'") as '.$group.',tab_user_login_record.user_id,FROM_UNIXTIME(register_time,"'.$dateform.'") as rtime') ->join('tab_user_login_record on tab_user_login_record.user_id=tab_user.id and tab_user_login_record.login_time>register_time','inner') ->where($map)->group('tab_user_login_record.user_id')->order('tab_user_login_record.login_time')->select(false); $list = $this->table('('.$sql.') as a ')->field('a.time,GROUP_CONCAT(a.user_id) as list,count(distinct a.user_id) as '.$fieldname)->where('UNIX_TIMESTAMP(a.rtime)group('a.'.$group)->order($order)->select(); } elseif ($flag == 2) { $sql = $this->field('FROM_UNIXTIME(tab_user_login_record.login_time,"'.$dateform.'") as '.$group.',tab_user_login_record.user_id,FROM_UNIXTIME(register_time,"'.$dateform.'") as rtime') ->join('tab_user_login_record on tab_user_login_record.user_id=tab_user.id and tab_user_login_record.login_time>register_time','inner') ->where($map)->order('tab_user_login_record.login_time')->select(false); $mid = $this->table('('.$sql.') as a ') ->where('a.time <> a.rtime')->group('a.user_id,a.'.$group)->select(false); $list = $this->table('('.$mid.') as b ')->field('b.rtime,b.'.$group.',count(distinct b.user_id) as '.$fieldname) ->group('b.rtime,b.'.$group)->order($order)->select(); } else { $sql = $this->field('FROM_UNIXTIME(tab_user_login_record.login_time,"'.$dateform.'") as '.$group.',tab_user_login_record.user_id,FROM_UNIXTIME(register_time,"'.$dateform.'") as rtime') ->join('tab_user_login_record on tab_user_login_record.user_id=tab_user.id and tab_user_login_record.login_time>register_time','inner') ->where($map)->order('tab_user_login_record.login_time')->select(false); $mid = $this->table('('.$sql.') as a ')->field('a.time,GROUP_CONCAT(user_id) as list')->where('UNIX_TIMESTAMP(a.rtime)group('a.user_id,a.'.$group)->select(false); $list = $this->table('('.$mid.') as b ')->field('b.'.$group.',count(distinct b.list) as '.$fieldname) ->group('b.'.$group)->order($order)->select(); } if ($cut) { // 去除新用户 if ($list[0]) { if ($flag == 5) { foreach ($data as $k => $v) { foreach($list as $lv) { $time = explode(' ',$lv[$group]); if ($time[1] == $v[$group]){ $data[$k][$fieldname] += (integer)$lv[$fieldname]; break; } } } } else { foreach ($data as $k => $v) { foreach($list as $lv) { if ($v[$group] == $lv[$group]){ $data[$k][$fieldname] += (integer)$lv[$fieldname]; break; } } } } } } else { $map1['register_time'] = $map['tab_user_login_record.login_time']; $news = $this->newsAdd($map1,$fieldname,$group,$flag,$order); if ($list[0]) { if ($flag == 5) { foreach ($data as $k => $v) { foreach($list as $lv) { $time = explode(' ',$lv[$group]); if ($time[1] == $v[$group]){ $data[$k][$fieldname] += (integer)$lv[$fieldname]; break; } } foreach ($news as $nv) { $nvtime = explode(' ',$nv[$group]); if ($nvtime[1] == $v[$group]) { $data[$k][$fieldname] += (integer)$nv[$fieldname];break; } } } }elseif($flag==2){ foreach ($data as $k => $v) { foreach($list as $lv) { if ($v[$group] == $lv[$group]){ $data[$k][$fieldname] += (integer)$lv[$fieldname]; continue; } } foreach ($news as $nv) { if ($nv[$group] == $v[$group]) { // dump($data[$k][$fieldname]); $data[$k][$fieldname] += (integer)$nv[$fieldname];break; } } } }else{ foreach ($data as $k => $v) { foreach($list as $lv) { if ($v[$group] == $lv[$group]){ $data[$k][$fieldname] += (integer)$lv[$fieldname]; break; } } foreach ($news as $nv) { if ($nv[$group] == $v[$group]) { $data[$k][$fieldname] += (integer)$nv[$fieldname];break; } } } } } else { if ($flag == 5) { foreach ($data as $k => $v) { foreach ($news as $nv) { $nvtime = explode(' ',$nv[$group]); if ($nvtime[1] == $v[$group]) { $data[$k][$fieldname] += (integer)$nv[$fieldname];break; } } } } else { $data = $news; } } } return $data; } /* * 用户总数 * @param array $map 条件数组 * @author 鹿文学 */ public function old($map=array()) { return $this->where($map)->count(); } /* * 活跃用户总数 * @param array $map 条件数组 * @author 鹿文学 */ public function active($map=array()) { $start = $map['tab_user_login_record.login_time']; $map['register_time'] = array('lt',$start[1][0]); $data = $this->field('FROM_UNIXTIME(tab_user_login_record.login_time,"%Y-%m-%d") as time,group_concat(tab_user.id) as list,count(distinct tab_user.id)as count,FROM_UNIXTIME(register_time,"%Y-%m-%d") as rtime') ->join('tab_user_login_record on tab_user_login_record.user_id=tab_user.id','inner') ->where($map)->order('tab_user_login_record.login_time')->select(); $map1['register_time'] = $start; $news = $this->old($map1); return $data[0]?$data[0]['count']+$news:0+$news; } /* * 新用户 按时间分组 * @param array $map 条件数组 * @param string $field 字段别名 * @param string $group 分组字段名 * @author 鹿文学 */ public function newsAdd($map=array(),$field='news',$group='time',$flag=1,$order='time') { switch($flag) { case 2:{$dateform = '%Y-%m';};break; case 3:{$dateform = '%Y-%u';};break; case 4:{$dateform = '%Y';};break; case 5:{$dateform = '%Y-%m-%d %H';};break; default:$dateform = '%Y-%m-%d'; } $map['puid'] = 0; $user = $this->field('FROM_UNIXTIME(register_time, "'.$dateform.'") as '.$group.',group_concat(id) as id ,COUNT(id) AS '.$field) ->where($map) ->group($group) ->order($order) ->select(); return $user; } /** * LTV统计 * @param integer $start 开始时间(时间戳) * @param integer $end 结束时间(时间戳) * @return array 用户分析结果集 * @author 鹿文学 */ public function ltv($start,$end) { $map['time'] = array('between',array(date('Y-m-d',strtotime('-29 day',$start)),date('Y-m-d',strtotime('+30 day',$end)))); $record = M('ltv','tab_')->field('money as amount,active_count as active,active_id,new_count,new_id,time')->where($map)->order('time asc')->select(); $day = floor(($start-strtotime($record[0]['time']))/86400); $data = array(); $datelist = get_date_list($start,$end); foreach ($record as $key=>$v){ if($v['time']< date('Y-m-d',$start)){ $data[$key]['time'] = $v['time']; $data[$key]['amount'] = $v['amount']; $data[$key]['active'] = 0; } if($v['time']>= date('Y-m-d',$start) && $v['time']<= date('Y-m-d',$end)){ $data[$key]['time'] = $v['time']; $data[$key]['amount'] = $v['amount']; $data[$key]['active'] = $v['active']; $ltvactive = array(); for ($i=1;$i<31;$i++){ $active = array(); for($j=0;$j<$i;$j++){ $active = array_merge($active, explode(',',$record[$key-$j]['active_id'])); } $ltvactive[$i] = count(array_unique($active)); } $data[$key]['ltvactive'] = $ltvactive; } } //dump($data); foreach ($datelist as $key=>$v){ $subscript = 0; foreach ($record as $k=>$vo) { if($vo['time'] == $v) { $subscript = $k; } } for($i=1;$i<31;$i++){ if($record[$subscript+$i]){ $new = explode(',',$record[$subscript]['new_id']); $active = explode(',',$record[$subscript+$i]['active_id']); $count = count(array_intersect($new,$active)); $rate['rate'.$i]= $record[$subscript]['new_count'] == 0 ? 0 : $count/$record[$subscript]['new_count'] * 100; } $ratention[$v] = $rate; } } foreach ($data as $k => $v) { if ($k<$day) {continue;} foreach($ratention as $i => $j) { if($i == $v['time']) { $am = 0;$ac = 0;$rate = 1; for($m=1;$m<31;$m++) { if (strtotime($i)+$m*86400>mktime(0,0,0,date('m'),date('d'),date('Y'))){continue;} $am += $data[$k-$m+1]['amount']; //$ac += $data[$k-$m+1]['active']; $ac = $data[$k]['ltvactive'][$m]; $rate += $j['rate'.$m]/100; if ($m<8 || $m == 14 || $m == 30) { if($am && $ac){ $data[$k]['ltv'.$m] = round($am/$ac*$rate,2); }else{ $data[$k]['ltv'.$m] = 0; } } } } } } $data = array_slice($data,$day); //dump($data); krsort($data); return $data; } public function ltvActive($datelist) { foreach($datelist as $v) { for($i=1;$i<31;$i++) { $end = strtotime($v); $data[$v][$i] = $this->active(['tab_user_login_record.login_time'=>['between',[strtotime('-'.($i-1).' day',$end),$end+86399]]]); } } return $data; } /** * 玩家1-7,14,30天留存率 * @param array $news 新增用户数据(按天分组) * @param array $rate 留存率初始化数组(按天分组) * @return array 详细数据 * @author 鹿文学 */ public function ratentionRateData($news,$rate) { $ratention = []; for($i=1;$i<31;$i++) { $ratention = array_merge($ratention,$this->ratentionRate($news,[],$i,'rate'.$i)); } foreach($rate as $k => $v) { foreach($ratention as $i) {if($k==$i['login_time']){$rate[$k][$i['key']] = $i[$i['key']];continue;}} } return $rate; } /* * 统计总活跃用户 * @param array $map 条件数组 * @author 鹿文学 */ public function tatalActivePlayer($map=array()) { $count = $this->join('tab_user_login_record on tab_user_login_record.user_id=tab_user.id','inner') ->where($map)->count('user_id'); return $count?$count:0; } /** * 玩家留存率 * @param array $news 新增用户数据(按天分组) * @param array $map 条件数组 * @param integer $flag 留存类型(1:1天,3:3天,7:7天) * @param string $fieldname 字段别名 * @param string $group 分组字段名 * @return array 详细数据 * @author 鹿文学 */ public function ratentionRate($news,$map,$flag=1,$fieldname='retentionrate',$group='login_time') { $map['lock_status']=1; $data = array(); foreach ($news as $value) { $ct1 = strtotime("+$flag day",strtotime($value['time'])); $ct2 = strtotime("+1 day",$ct1)-1; $map['tab_user_login_record.login_time'] = array(array('egt',$ct1),array('elt',$ct2)); $map['user_id']=array('in',$value['id']); $count = count(explode(',',$value['id'])); $d=$this ->field('count(distinct user_id) as '.$fieldname.' ,FROM_UNIXTIME(tab_user_login_record.login_time,"%Y-%m-%d") as '.$group) ->join('tab_user_login_record on tab_user.id=tab_user_login_record.user_id','right') ->where($map) ->group($group) ->select(); if ($d) $data[]=array( $group=>$value['time'],'key'=>$fieldname, $fieldname=>($d[0][$fieldname]==0)?0:sprintf("%.2f",($d[0][$fieldname]/$count)*100) ); } return $data; } /* * 活跃排行(推广员) * @param string $timestr 时间条件 (between 开始时间戳 and 结束时间戳) * @param string $fieldname 名称 * @param array $promoteid 推广员编号数组 * @param integer $row 限制条数(0:不限) * @param string $ordermark 排序(asc:升序,desc:降序) * @author 鹿文学 */ public function activeRankOnPromote($timestr,$fieldname='count',$promoteid='',$row=0,$ordermark='desc') { $map['tab_user.promote_id']=array('gt',0); if ($promoteid[0]) {$map['tab_user.promote_id']=array('in',$promoteid);} $sql = $this->field('tab_user.promote_id,tab_promote.account as promote_account,tab_user.id') ->join('tab_promote on (tab_promote.id = tab_user.promote_id) ') ->where(['register_time'.$timestr,$map]) ->select(false); $mid = $this->field('tab_user.promote_id,tab_promote.account as promote_account,tab_user.id') ->join('tab_user_login_record as uu on tab_user.id = uu.user_id') ->join('tab_promote on(tab_user.promote_id = tab_promote.id)') ->union($sql) ->group('tab_user.promote_id,tab_user.id') ->where(['uu.login_time '.$timestr,$map]) ->select(false); $last = $this->table('('.$mid.') as a')->field('a.promote_id,a.promote_account,GROUP_CONCAT(a.id),count(a.id) as '.$fieldname) ->group('a.promote_id')->select(false); if($row>0) { $data = $this->table('('.$last.') as b')->limit($row)->order('b.'.$fieldname.' '.$ordermark)->select(); } else { $data = $this->table('('.$last.') as b')->order('b.'.$fieldname.' '.$ordermark)->select(); } return $data; } /* * 活跃排行(游戏) * @param string $timestr 时间条件 (between 开始时间戳 and 结束时间戳) * @param string $fieldname 名称 * @param array $promoteid 游戏编号数组 * @param integer $row 限制条数(0:不限) * @param string $ordermark 排序(asc:升序,desc:降序) * @author 鹿文学 */ public function activeRankOnGame($timestr,$fieldname='count',$gameid='',$row=0,$ordermark='desc') { $map2['fgame_id']=$map['uu.game_id']=array('gt',0); if ($gameid[0]) {$map2['fgame_id']=$map['uu.game_id']=array('in',$gameid);} $sql = $this->field('fgame_id as game_id,fgame_name as game_name,tab_user.id') ->where(['register_time'.$timestr,$map2]) ->select(false); $mid = $this->field('uu.game_id,game_name,tab_user.id') ->join('tab_user_login_record as uu on tab_user.id = uu.user_id') ->union($sql) ->group('uu.game_id,tab_user.id') ->where(['uu.login_time '.$timestr,$map]) ->select(false); $last = $this->table('('.$mid.') as a')->field('a.game_id,a.game_name,GROUP_CONCAT(a.id),count(a.id) as '.$fieldname) ->group('a.game_id')->select(false); if($row>0) { $data = $this->table('('.$last.') as b')->limit($row)->order('b.'.$fieldname.' '.$ordermark)->select(); } else { $data = $this->table('('.$last.') as b')->order('b.'.$fieldname.' '.$ordermark)->select(); } return $data; } /** * 获取所有玩家(新增用户+老用户) */ public function getPlayers($map=array()) { $map1 = $map; unset($map1['r.register_time']); $map1['login_time'] = $map['r.register_time']; $map1['lpuid']=0; $map1['promote_id'] = $map1['r.promote_id']; unset($map1['r.promote_id']); $result = M('user_login_record','tab_')->field('user_id as id,user_account as account,login_time as register_time,promote_id') ->group('id')->where($map1)->select(false); $map['puid']=0; $sql = $this->alias("r")->field("r.id,r.account,r.register_time,r.promote_id") ->where($map) ->union('(' .$result. ')') ->select(false); $data = $this->table('('.$sql.') as a')->group('a.id')->select(); return $data; } /** * 查找玩家(登录记录表) */ public function findPlayer($map=""){ $map['lpuid']=0; $data = M('user_login_record','tab_')->alias("r")->field("r.*") ->group("r.user_id") ->where($map) ->find(); return $data; } /** * 获取用户列表 */ public function getUserList($param, $field = "*", $group = "") { $result = $this->where($param) ->field($field) ->group($group) ->select(); return $result; } /** * 获取未流失的玩家 * @param $day int 几天算玩家流失 */ public function getKeepPlayers($map = '', $day, $falseIndex = false) { $join = "right join tab_user as u on r.user_id = u.id"; if ($falseIndex) {//日期范围大于5天使用强制索引 $join = "FORCE INDEX (PRIMARY) " . $join; } $data = $this->table("tab_user_login_record") ->alias("r") ->field("GROUP_CONCAT(DISTINCT u.id) as user_ids,FROM_UNIXTIME(u.register_time+{$day}*86400, '%Y-%m-%d') as register_date") ->join($join) ->group("register_date") ->where($map) ->select(); return $data; } }