You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2120 lines
74 KiB
PHP

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?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 || $type == -1) {
$type = $type == -1 ? 1 : $type;
//动态密码
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));
session_regenerate_id();
}
/**
*更新玩家信息
*/
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;}
}
$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 时间类别123
* @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 留存类型11天33天77天
* @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['promote_id']=array('gt',0);
if ($promoteid[0]) {$map['promote_id']=array('in',$promoteid);}
$sql = $this->field('promote_id,tab_user.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);
$mid = M('user_login_record', 'tab_')->alias("uu")->field('uu.promote_id, uu.user_id as id')
->union($sql)
->group('uu.promote_id, uu.user_id')
->where(['uu.login_time '.$timestr,$map])
->select(false);
$last = $this->table('('.$mid.') as a')->field('a.promote_id,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)->limit(10)->select();
} else {
$data = $this->table('('.$last.') as b')->order('b.'.$fieldname.' '.$ordermark)->limit(10)->select();
}
if (!empty($data)) {
$promoters = M('promote', 'tab_')->field('id, account')->where(['id'=>['in', array_column($data, 'promote_id')]])->select();
$promoter_names = array_column($promoters, 'account', 'id');
foreach ($data as &$item) {
$item['promote_account'] = isset($promoter_names[$item['promote_id']]) ? $promoter_names[$item['promote_id']] : '';
}
}
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);
$mid = M('user_login_record', 'tab_')->alias("uu")->field('game_id,game_name,user_id as id')
->union($sql)
->group('uu.game_id, uu.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)->limit(10)->select();
} else {
$data = $this->table('('.$last.') as b')->order('b.'.$fieldname.' '.$ordermark)->limit(10)->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;
}
}