<?php
// +----------------------------------------------------------------------
// | OneThink [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013 http://www.onethink.cn All rights reserved.
// +----------------------------------------------------------------------
// | Author: huajie < banhuajie @ 163 . com >
// +----------------------------------------------------------------------
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 < banhuajie @ 163 . com >
*/
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 < banhuajie @ 163 . com >
*/
protected function getCreateTime(){
$create_time = I('post.create_time');
return $create_time?strtotime($create_time):NOW_TIME;
}
/**
* 生成不重复的name标识
* @author huajie < banhuajie @ 163 . com >
*/
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)< UNIX_TIMESTAMP ( a . ' . $ group . ' ) ' ) - > 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)< UNIX_TIMESTAMP ( a . ' . $ group . ' ) ' ) - > 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;
}
}