1043 lines
44 KiB
PHP
1043 lines
44 KiB
PHP
<?php namespace Phpcmf\Model\Member;
|
||
|
||
class Member extends \Phpcmf\Model\Member
|
||
{
|
||
|
||
/**
|
||
* 内容发布之后(已迁移至 Cms Models/Content::module_content_after)
|
||
*/
|
||
public function module_content_after($module, $data, $member) {
|
||
}
|
||
|
||
/**
|
||
* 登录记录
|
||
*
|
||
* @param intval $data 会员
|
||
* @param string $OAuth 登录方式
|
||
*/
|
||
protected function _login_log($data, $type = '') {
|
||
|
||
if (IS_ADMIN && APP_DIR == 'member') {
|
||
return;// 后台创建的用户不记录登录日志
|
||
}
|
||
|
||
$ip = \Phpcmf\Service::L('input')->ip_address();
|
||
if (!$ip || !$data['id']) {
|
||
return;
|
||
}
|
||
|
||
// 防止多次记录
|
||
if (\Phpcmf\Service::L('cache')->get_auth_data("member_login_after_".$data['id'], SITE_ID, 60)) {
|
||
return;
|
||
}
|
||
|
||
$agent = \Phpcmf\Service::L('input')->get_user_agent();
|
||
if (strlen($agent) <= 5) {
|
||
return;
|
||
}
|
||
|
||
$log = [
|
||
'uid' => $data['id'],
|
||
'type' => $type,
|
||
'loginip' => $ip,
|
||
'logintime' => SYS_TIME,
|
||
'useragent' => substr($agent, 0, 255),
|
||
];
|
||
|
||
// 只保留20条登录记录
|
||
$row = $this->table('member_login')->where('uid', $data['id'])
|
||
->order_by('logintime desc')->getAll(21);
|
||
if (dr_count($row) > 20) {
|
||
$ids = '';
|
||
foreach ($row as $t) {
|
||
$ids.= (int)$t['id'].',';
|
||
}
|
||
// 删除多余的记录
|
||
$ids && $this->db->table('member_login')->where('uid', $data['id'])->where('id not in ('.trim($ids, ',').')')->delete();
|
||
}
|
||
|
||
// 登录后的通知
|
||
\Phpcmf\Service::L('Notice')->send_notice('member_login', $data);
|
||
|
||
// 登录后的钩子
|
||
$data['log'] = [
|
||
'now' => $log,
|
||
'before' => $row,
|
||
];
|
||
\Phpcmf\Hooks::trigger('member_login_after', $data);
|
||
|
||
\Phpcmf\Service::L('cache')->set_auth_data("member_login_after_".$data['id'], 1, SITE_ID);
|
||
|
||
// 同一天Ip一致时只更新一次更新时间
|
||
if ($row = $this->db
|
||
->table('member_login')
|
||
->where('uid', $data['id'])
|
||
->where('loginip', $ip)
|
||
->where('DATEDIFF(from_unixtime(logintime),now())=0')
|
||
->get()
|
||
->getRowArray()) {
|
||
$this->db->table('member_login')->where('id', $row['id'])->update($log);
|
||
} else {
|
||
$this->db->table('member_login')->insert($log);
|
||
}
|
||
|
||
}
|
||
|
||
/**
|
||
* 初始化处理
|
||
*/
|
||
public function init_member($member) {
|
||
|
||
// 明天凌晨时间戳
|
||
$time = strtotime(date('Y-m-d', strtotime('+1 day')));
|
||
|
||
// 每日登录积分处理
|
||
if (dr_is_app('explog')) {
|
||
$value = \Phpcmf\Service::L('member_auth', 'member')->member_auth('login_exp', $member);
|
||
if ($value && !\Phpcmf\Service::L('input')->get_cookie('login_experience_'.$member['id'])) {
|
||
$this->add_experience($member['id'], $value, dr_lang('每日登陆'), '', 'login_exp_'.date('Ymd', SYS_TIME), 1);
|
||
\Phpcmf\Service::L('input')->set_cookie('login_experience_'.$member['id'], 1, $time - SYS_TIME);
|
||
}
|
||
}
|
||
|
||
// 每日登录金币处理
|
||
if (dr_is_app('scorelog')) {
|
||
$value = \Phpcmf\Service::L('member_auth', 'member')->member_auth('login_score', $member);
|
||
if ($value && !\Phpcmf\Service::L('input')->get_cookie('login_score_'.$member['id'])) {
|
||
$this->add_score($member['id'], $value, dr_lang('每日登陆'), '', 'login_score_'.date('Ymd', SYS_TIME), 1);
|
||
\Phpcmf\Service::L('input')->set_cookie('login_score_'.$member['id'], 1, $time - SYS_TIME);
|
||
}
|
||
}
|
||
|
||
// 没有注册ip时,短时间内按获取的地址作为ip填充
|
||
if (!$member['regip'] && $member['regtime']) {
|
||
$ctime = SYS_TIME - $member['regtime'];
|
||
if ($ctime < 80000 && $ctime > 100) {
|
||
$this->table('member')->update($member['id'], [
|
||
'regip' => (string)\Phpcmf\Service::L('input')->ip_address()
|
||
]);
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 用户组信息
|
||
*/
|
||
public function get_member_group($data) {
|
||
|
||
if (IS_ADMIN && !\Phpcmf\Service::M()->is_table_exists('member_group_index')) {
|
||
return $data;
|
||
}
|
||
|
||
$data2 = $this->update_group($data, $this->db->table('member_group_index')->where('uid', (int)$data['id'])->get()->getResultArray());
|
||
if ($data2) {
|
||
foreach ($data2 as $t) {
|
||
$data['group_name'][$t['gid']] = $t['group_name'] = \Phpcmf\Service::C()->member_cache['group'][$t['gid']]['name'];
|
||
$t['group_icon'] = \Phpcmf\Service::C()->member_cache['group'][$t['gid']]['level'][$t['lid']]['icon'];
|
||
$t['group_level'] = \Phpcmf\Service::C()->member_cache['group'][$t['gid']]['level'][$t['lid']]['name'];
|
||
$data['group'][$t['gid']] = $t;
|
||
$data['groupid'][$t['gid']] = $t['gid'];
|
||
$data['levelid'][$t['gid']] = $t['lid'];
|
||
$data['authid'][] = $t['lid'] ? $t['gid'].'-'.$t['lid'] : $t['gid'];
|
||
if ($t['timeout']) {
|
||
$data['group_timeout'] = $t['gid'];
|
||
$data['group_timeout_time'] = $t['etime'];
|
||
}
|
||
}
|
||
}
|
||
|
||
return $data;
|
||
}
|
||
|
||
/**
|
||
* 授权登录信息
|
||
*/
|
||
public function oauth($uid) {
|
||
|
||
$data = $this->db->table('member_oauth')->where('uid', $uid)->get()->getResultArray();
|
||
if (!$data) {
|
||
return [];
|
||
}
|
||
|
||
$rt = [];
|
||
foreach ($data as $t) {
|
||
$rt[$t['oauth']] = $t;
|
||
}
|
||
|
||
return $rt;
|
||
}
|
||
|
||
// 获取authid
|
||
public function authid($uid) {
|
||
|
||
if (!$uid) {
|
||
return [0];
|
||
} elseif ($uid == $this->uid) {
|
||
return \Phpcmf\Service::C()->member['authid'];
|
||
}
|
||
|
||
$rt = [];
|
||
$data2 = $this->db->table('member_group_index')->where('uid', $uid)->get()->getResultArray();
|
||
if ($data2) {
|
||
foreach ($data2 as $t) {
|
||
$rt[] = $t['lid'] ? $t['gid'].'-'.$t['lid'] : $t['gid'];
|
||
}
|
||
}
|
||
|
||
return $rt;
|
||
}
|
||
|
||
// 更新用户组
|
||
// member 用户信息
|
||
// groups 拥有的用户组
|
||
public function update_group($member, $groups) {
|
||
|
||
$g = [];
|
||
if (!$member || !$groups) {
|
||
return $g;
|
||
}
|
||
|
||
$uid = (int)$member['id'];
|
||
foreach ($groups as $group) {
|
||
// 判断是否可用
|
||
if (!\Phpcmf\Service::C()->member_cache['group'][$group['gid']]) {
|
||
continue;
|
||
}
|
||
$group['gid'] = (int)$group['gid'];
|
||
$group['timeout'] = 0;
|
||
// 判断等级是否有效
|
||
$levels = isset(\Phpcmf\Service::C()->member_cache['group'][$group['gid']]['level']) ? \Phpcmf\Service::C()->member_cache['group'][$group['gid']]['level'] : [];
|
||
if ($levels) {
|
||
// 当已知等级不存在时
|
||
if ($group['lid'] && (!isset($levels[$group['lid']]) || !$levels[$group['lid']])) {
|
||
$this->db->table('member_group_index')->where('uid', $uid)->where('gid', $group['gid'])->update(['lid' => 0]);
|
||
$group['lid'] = 0;
|
||
}
|
||
// 没有等级时自动选取免费等级
|
||
if (!$group['lid']) {
|
||
foreach ($levels as $ls) {
|
||
if (!$ls['value']) {
|
||
$group['lid'] = $ls['id'];
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
} elseif ($group['lid']) {
|
||
// 还原升级
|
||
$this->db->table('member_group_index')->where('uid', $uid)->where('gid', $group['gid'])->update(['lid' => 0]);
|
||
$group['lid'] = 0;
|
||
}
|
||
$group_info = \Phpcmf\Service::C()->member_cache['group'][$group['gid']];
|
||
// 判断过期
|
||
$price = floatval($group_info['price']);
|
||
if ($group['etime'] && $group['etime'] - SYS_TIME < 0) {
|
||
// 过期了
|
||
if ($group_info['setting']['timeout']) {
|
||
// 过期自动续费price
|
||
$name = $group_info['unit'] ? 'score' : 'money';
|
||
if ($name == 'money') {
|
||
// 余额
|
||
if ($price > 0) {
|
||
// 收费组情况下
|
||
if ($member[$name] - $price < 0) {
|
||
// 余额不足 删除
|
||
if (!$group_info['setting']['outtype'] && $this->delete_group($uid, $group['gid'], 0)) {
|
||
$this->notice($uid, 2, dr_lang('您的用户组(%s)已过期,自动续费失败,账户%s不足', $group_info['name'], dr_lang('余额')));
|
||
} else {
|
||
// // 不主动删除用户组 情况下保留
|
||
$group['timeout'] = 1;
|
||
$g[$group['gid']] = $group;
|
||
}
|
||
continue;
|
||
}
|
||
$group['etime'] = dr_member_group_etime($group_info['days'], $group_info['setting']['dtype']);
|
||
if (!dr_is_app('pay')) {
|
||
log_message('error', '用户组自动续费失败:没有安装「支付系统」插件');
|
||
continue;
|
||
} else {
|
||
// 自动续费
|
||
$rt = $this->add_money($uid, -$price);
|
||
if (!$rt['code']) {
|
||
continue;
|
||
}
|
||
// 增加到交易流水
|
||
$rt = \Phpcmf\Service::M('Pay')->add_paylog([
|
||
'uid' => $member['id'],
|
||
'username' => $member['username'],
|
||
'touid' => 0,
|
||
'tousername' => '',
|
||
'mid' => 'system',
|
||
'title' => dr_lang('用户组(%s)续费', $group_info['name']),
|
||
'value' => -$price,
|
||
'type' => 'finecms',
|
||
'status' => 1,
|
||
'result' => dr_lang('有效期至%s', $group['etime'] ? dr_date($group['etime']) : dr_lang('永久')),
|
||
'paytime' => SYS_TIME,
|
||
'inputtime' => SYS_TIME,
|
||
]);
|
||
// 提醒通知
|
||
$this->notice(
|
||
$uid,
|
||
2,
|
||
dr_lang('您的用户组(%s)已过期,自动续费成功', $group_info['name']),
|
||
\Phpcmf\Service::L('router')->member_url('paylog/show', ['id'=>$rt['code']])
|
||
);
|
||
}
|
||
} else {
|
||
// 免费组自己续费
|
||
$group['etime'] = dr_member_group_etime($group_info['days'], $group_info['setting']['dtype']);
|
||
// 提醒通知
|
||
$this->notice(
|
||
$uid,
|
||
2,
|
||
dr_lang('您的用户组(%s)已过期,自动免费续期成功,有效期至%s', $group_info['name'], $group['etime'] ? dr_date($group['etime']) : dr_lang('永久'))
|
||
);
|
||
}
|
||
// 更新时间
|
||
$this->db->table('member_group_index')->where('uid', $uid)->where('gid', $group['gid'])->update(['etime' => $group['etime']]);
|
||
} else {
|
||
// 金币
|
||
$price = (int)$price;
|
||
if ($price > 0) {
|
||
// 收费组情况下
|
||
if ($member[$name] - $price < 0) {
|
||
// 金币不足 删除
|
||
if (!$group_info['setting']['outtype'] && $this->delete_group($uid, $group['gid'], 0)) {
|
||
// 提醒通知
|
||
$this->notice($uid, 2, dr_lang('您的用户组(%s)已过期,自动续费失败,账户%s不足', $group_info['name'], SITE_SCORE));
|
||
} else {
|
||
// false 情况下保留
|
||
$group['timeout'] = 1;
|
||
$g[$group['gid']] = $group;
|
||
}
|
||
continue;
|
||
}
|
||
// 自动续费
|
||
$group['etime'] = dr_member_group_etime($group_info['days'], $group_info['setting']['dtype']);
|
||
// 自动续费
|
||
$rt = $this->add_score($uid, -$price, dr_lang('您的用户组(%s)自动续费', $group_info['name']));
|
||
if (!$rt['code']) {
|
||
continue;
|
||
}
|
||
// 提醒通知
|
||
$this->notice(
|
||
$uid,
|
||
2,
|
||
dr_lang('您的用户组(%s)已过期,自动续费成功', $group_info['name'])
|
||
);
|
||
} else {
|
||
// 免费组自己续费
|
||
// 提醒通知
|
||
$group['etime'] = dr_member_group_etime($group_info['days'], $group_info['setting']['dtype']);
|
||
// 提醒通知
|
||
$this->notice(
|
||
$uid,
|
||
2,
|
||
dr_lang('您的用户组(%s)已过期,自动免费续期成功,有效期至%s', $group_info['name'], $group['etime'] ? dr_date($group['etime']) : dr_lang('永久'))
|
||
);
|
||
}
|
||
// 更新时间
|
||
$this->db->table('member_group_index')->where('uid', $uid)->where('gid', $group['gid'])->update(['etime' => $group['etime']]);
|
||
}
|
||
} else {
|
||
// 未开通自动续费直接删除
|
||
if (!$group_info['setting']['outtype'] && $this->delete_group($uid, $group['gid'], 0)) {
|
||
// 提醒通知
|
||
$this->notice($uid, 2, dr_lang('您的用户组(%s)已过期,系统权限已关闭', $group_info['name']));
|
||
} else {
|
||
// false 情况下保留
|
||
$group['timeout'] = 1;
|
||
$g[$group['gid']] = $group;
|
||
}
|
||
continue;
|
||
}
|
||
}
|
||
// 开启自动升级时需要判断等级
|
||
if ($levels
|
||
&& \Phpcmf\Service::C()->member_cache['group'][$group['gid']]['setting']['level']['auto']) {
|
||
$value = \Phpcmf\Service::C()->member_cache['group'][$group['gid']]['setting']['level']['unit'] ? $member['spend'] : $member['experience'];
|
||
$level = array_reverse($levels); // 倒序判断
|
||
foreach ($level as $t) {
|
||
if ($value >= $t['value']) {
|
||
if ($group['lid'] != $t['id']) {
|
||
// 开始变更等级
|
||
// 更新数据
|
||
$update = [
|
||
'lid' => $t['id']
|
||
];
|
||
if (\Phpcmf\Service::C()->member_cache['group'][$group['gid']]['setting']['timetype']) {
|
||
// 按等级计算时间
|
||
$update['etime'] = dr_member_group_etime(
|
||
\Phpcmf\Service::C()->member_cache['group'][$group['gid']]['level'][$t['id']]['setting']['days'],
|
||
\Phpcmf\Service::C()->member_cache['group'][$group['gid']]['level'][$t['id']]['setting']['dtype'],
|
||
0
|
||
);
|
||
}
|
||
$this->db->table('member_group_index')->where('uid', $uid)->where('gid', $group['gid'])->update($update);
|
||
/* 等级升级 */
|
||
$this->notice($uid, 2, dr_lang('您的用户组(%s)等级自动升级为(%s)', \Phpcmf\Service::C()->member_cache['group'][$group['gid']]['name'], $t['name']));
|
||
$group['lid'] = $t['id'];
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
$g[$group['gid']] = $group;
|
||
}
|
||
|
||
return $g;
|
||
}
|
||
|
||
// 删除用户组 is_admin 是否是管理员删除,否则就是过期删除
|
||
public function delete_group($uid, $gid, $is_admin = 1) {
|
||
|
||
// 回调信息
|
||
$call = $this->member_info($uid);
|
||
$call['group'] = $this->table('member_group_index')->where('gid', $gid)->where('uid', $uid)->getRow();
|
||
|
||
$this->db->table('member_group_index')->where('gid', $gid)->where('uid', $uid)->delete();
|
||
|
||
// 管理员删除时提醒
|
||
if ($is_admin) {
|
||
$this->notice($uid, 2, dr_lang('您的用户组(%s)被取消', \Phpcmf\Service::C()->member_cache['group'][$gid]['name']));
|
||
}
|
||
|
||
// 判断微信标记组
|
||
if (dr_is_app('weixin')) {
|
||
\Phpcmf\Service::C()->init_file('weixin');
|
||
\Phpcmf\Service::M('user', 'weixin')->delete_member_group($uid, $gid);
|
||
}
|
||
|
||
// 过期后变更
|
||
if (!$is_admin && \Phpcmf\Service::C()->member_cache['group'][$gid]['setting']['out_gid']
|
||
&& \Phpcmf\Service::C()->member_cache['group'][$gid]['setting']['out_gid'] != $gid) {
|
||
$this->insert_group($uid, \Phpcmf\Service::C()->member_cache['group'][$gid]['setting']['out_gid']);
|
||
}
|
||
|
||
\Phpcmf\Service::M('member')->clear_cache($uid);
|
||
|
||
\Phpcmf\Hooks::trigger('member_del_group_after', $call);
|
||
|
||
return true;
|
||
}
|
||
|
||
// 新增用户组
|
||
public function insert_group($uid, $gid, $is_notice = 1) {
|
||
|
||
$data = [
|
||
'uid' => $uid,
|
||
'gid' => $gid,
|
||
'lid' => 0,
|
||
'stime' => SYS_TIME,
|
||
'etime' => \Phpcmf\Service::C()->member_cache['group'][$gid]['setting']['timetype'] ? 0 : dr_member_group_etime(\Phpcmf\Service::C()->member_cache['group'][$gid]['days'], \Phpcmf\Service::C()->member_cache['group'][$gid]['setting']['dtype']),
|
||
];
|
||
$rt = $this->table('member_group_index')->insert($data);
|
||
if (!$rt['code']) {
|
||
return;
|
||
}
|
||
|
||
$data['id'] = $rt['code'];
|
||
|
||
// 挂钩点 用户组变更之后
|
||
$call = $this->member_info($uid);
|
||
$call['group'] = $data;
|
||
$call['group_gid'] = $call['gid'] = $gid;
|
||
$call['group_name'] = \Phpcmf\Service::C()->member_cache['group'][$gid]['name'];
|
||
$is_notice && \Phpcmf\Service::L('Notice')->send_notice('member_edit_group', $call);
|
||
\Phpcmf\Hooks::trigger('member_edit_group_after', $call);
|
||
|
||
// 判断微信标记组
|
||
if (dr_is_app('weixin')) {
|
||
\Phpcmf\Service::C()->init_file('weixin');
|
||
\Phpcmf\Service::M('user', 'weixin')->add_member_group($uid, $gid);
|
||
}
|
||
|
||
if (!\Phpcmf\Service::C()->member_cache['config']['groups']) {
|
||
// 没开启多个组时,关闭之前的用户组
|
||
$data2 = $this->db->table('member_group_index')->where('uid', $uid)->where('gid<>' . $gid)->get()->getResultArray();
|
||
if ($data2) {
|
||
foreach ($data2 as $t) {
|
||
$this->delete_group($uid, $t['gid'], 1);
|
||
}
|
||
}
|
||
}
|
||
\Phpcmf\Service::M('member')->clear_cache($uid);
|
||
}
|
||
|
||
// 手动变更等级
|
||
public function update_level($uid, $gid, $lid) {
|
||
|
||
$old = $data = $this->db->table('member_group_index')->where('uid', $uid)->where('gid', $gid)->get()->getRowArray();
|
||
$data['gid'] = $gid;
|
||
$data['lid'] = $lid;
|
||
|
||
// 更新数据
|
||
$update = [
|
||
'lid' => $lid
|
||
];
|
||
if (\Phpcmf\Service::C()->member_cache['group'][$gid]['setting']['timetype']) {
|
||
// 按等级计算时间
|
||
$update['etime'] = dr_member_group_etime(
|
||
\Phpcmf\Service::C()->member_cache['group'][$gid]['level'][$lid]['setting']['days'],
|
||
\Phpcmf\Service::C()->member_cache['group'][$gid]['level'][$lid]['setting']['dtype'],
|
||
\Phpcmf\Service::C()->member_cache['group'][$gid]['setting']['timect'] ? $old['etime'] : 0
|
||
);
|
||
}
|
||
$this->db->table('member_group_index')->where('uid', $uid)->where('gid', $gid)->update($update);
|
||
// 挂钩点 用户组变更之后
|
||
$call = $this->member_info($uid);
|
||
$call['group_name'] = \Phpcmf\Service::C()->member_cache['group'][$gid]['name'];
|
||
$call['group_level'] = \Phpcmf\Service::C()->member_cache['group'][$gid]['level'][$lid]['name'];
|
||
\Phpcmf\Service::L('Notice')->send_notice('member_edit_level', $call);
|
||
\Phpcmf\Hooks::trigger('member_edit_level_after', $data, $old);
|
||
\Phpcmf\Service::M('member')->clear_cache($uid);
|
||
}
|
||
|
||
// 申请用户组
|
||
public function apply_group($verify_id, $member, $gid, $lid, $price, $my_verify) {
|
||
|
||
$group = \Phpcmf\Service::C()->member_cache['group'][$gid];
|
||
|
||
if ($group['setting']['verify']) {
|
||
$my_verify['uid'] = (int)$member['id'];
|
||
$my_verify['username'] = (string)$member['username'];
|
||
$my_verify['gid'] = $gid;
|
||
$my_verify['price'] = $group['price'];
|
||
$my_verify['lid'] = $lid;
|
||
$my_verify['status'] = 0;
|
||
$my_verify['content'] = dr_array2string($my_verify['content']);
|
||
$my_verify['inputtime'] = SYS_TIME;
|
||
if ($verify_id) {
|
||
$rt = \Phpcmf\Service::M()->table('member_group_verify')->update($verify_id, $my_verify);
|
||
} else {
|
||
// 被拒再次提交不重复扣款
|
||
$my_verify['price'] = (float)$price;
|
||
$rt = \Phpcmf\Service::M()->table('member_group_verify')->insert($my_verify);
|
||
}
|
||
if (!$rt['code']) {
|
||
return dr_return_data(0, $rt['msg']);
|
||
}
|
||
// 提醒
|
||
$this->admin_notice(0, 'member', $member, dr_lang('用户组[%s]申请审核', $group['name']), 'member/apply/edit:id/'.$rt['code']);
|
||
// 审核
|
||
return dr_return_data(1, dr_lang('等待管理员审核'));
|
||
} else {
|
||
// 直接开通
|
||
$this->insert_group($member['id'], $gid);
|
||
$lid && $this->update_level($member['id'], $gid, $lid);
|
||
if ($my_verify['content']) {
|
||
\Phpcmf\Service::M()->table('member_data')->update($member['id'], $my_verify['content']);
|
||
}
|
||
|
||
return dr_return_data(1, dr_lang('开通成功'));
|
||
}
|
||
}
|
||
|
||
// 审核用户
|
||
public function verify_member($uid) {
|
||
|
||
$this->db->table('member_data')->where('id', $uid)->update(['is_verify' => 1]);
|
||
// 后台提醒
|
||
$this->todo_admin_notice('member/verify/index:field/id/keyword/'.$uid, 0);
|
||
// 审核提醒
|
||
// 注册审核后的通知
|
||
\Phpcmf\Service::L('Notice')->send_notice('member_register_verify', $this->get_member($uid));
|
||
}
|
||
|
||
/**
|
||
* 验证登录
|
||
*
|
||
* @param string $username 用户名
|
||
* @param string $password 明文密码
|
||
* @param intval $remember 是否记住密码
|
||
*/
|
||
public function login($username, $password, $remember = 0) {
|
||
|
||
if (!$username) {
|
||
return dr_return_data(0, dr_lang('账号不能为空'));
|
||
} elseif (!$password) {
|
||
return dr_return_data(0, dr_lang('密码不能为空'));
|
||
}
|
||
// 登录
|
||
$data = $this->_find_member_info($username);
|
||
if (!$data) {
|
||
return dr_return_data(0, dr_lang('用户不存在'));
|
||
}
|
||
// 密码验证
|
||
$password2 = dr_safe_password($password);
|
||
if (md5(md5($password2).$data['salt'].md5($password2)) != $data['password']) {
|
||
if (strlen($password2) == 32 && md5($password2.$data['salt'].$password2) == $data['password']) {
|
||
// 加密验证成功
|
||
} else {
|
||
\Phpcmf\Hooks::trigger('member_login_password_error', [
|
||
'member' => $data,
|
||
'password' => $password,
|
||
'ip' => (string)\Phpcmf\Service::L('input')->ip_address(),
|
||
'time' => SYS_TIME,
|
||
]);
|
||
return dr_return_data(0, dr_lang('密码不正确'));
|
||
}
|
||
}
|
||
|
||
// 验证管理员登录
|
||
/*
|
||
$rt = $this->_is_admin_login_member($data['id']);
|
||
if (!$rt['code']) {
|
||
return $rt;
|
||
}*/
|
||
|
||
// 保存本地会话
|
||
$this->save_cookie($data, $remember);
|
||
|
||
// 记录日志
|
||
$this->_login_log($data);
|
||
|
||
return dr_return_data(1, 'ok', [
|
||
'auth'=> md5($data['password'].$data['salt']), // API认证字符串,
|
||
'member' => $this->get_member($data['id']),
|
||
'sso' => $this->sso($data, $remember)]
|
||
);
|
||
}
|
||
|
||
// 短信登录
|
||
public function login_sms($phone, $remember) {
|
||
|
||
$data = $this->db->table('member')->where('phone', $phone)->get()->getRowArray();
|
||
if (!$data) {
|
||
// 未注册
|
||
if (\Phpcmf\Service::C()->member_cache['login']['auto_reg']) {
|
||
// 自动注册
|
||
$groupid = (int)\Phpcmf\Service::C()->member_cache['register']['groupid'];
|
||
if (!$groupid) {
|
||
return dr_return_data(0, dr_lang('无效的用户组'));
|
||
} elseif (!\Phpcmf\Service::C()->member_cache['group'][$groupid]['register']) {
|
||
return dr_return_data(0, dr_lang('用户组[%s]不允许注册', \Phpcmf\Service::C()->member_cache['group'][$groupid]['name']));
|
||
}
|
||
$rt = $this->register($groupid, [
|
||
'username' => '',
|
||
'phone' => $phone,
|
||
'email' => '',
|
||
'password' => SYS_KEY.'_login_sms',
|
||
'name' => '',
|
||
]);
|
||
if ($rt['code']) {
|
||
$data = $rt['data'];
|
||
$data['uid'] = $data['id'];
|
||
$this->table('member')->update($rt['code'], [
|
||
'salt' => 'login_sms'
|
||
]);
|
||
} else {
|
||
return dr_return_data(0, $rt['msg'], ['field' => $rt['data']['field']]);
|
||
}
|
||
} else {
|
||
return dr_return_data(0, dr_lang('手机号码未注册'));
|
||
}
|
||
} else {
|
||
// 记录日志
|
||
$data['uid'] = $data['id'];
|
||
$this->_login_log($data);
|
||
}
|
||
|
||
// 保存本地会话
|
||
$this->save_cookie($data, $remember);
|
||
|
||
return dr_return_data($data['id'], 'ok', [
|
||
'auth'=> md5($data['password'].$data['salt']), // API认证字符串,
|
||
'member' => $this->get_member($data['id']),
|
||
'sso' => $this->sso($data, $remember)]
|
||
);
|
||
}
|
||
|
||
// 绑定注册模式 授权注册绑定
|
||
public function register_oauth_bang($oauth, $groupid, $member, $data = []) {
|
||
|
||
if (!$oauth) {
|
||
return dr_return_data(0, dr_lang('OAuth数据不存在,请重试'));
|
||
}
|
||
|
||
$rt = $this->register($groupid, $member, $data, $oauth);
|
||
if (!$rt['code']) {
|
||
return dr_return_data(0, $rt['msg']);
|
||
}
|
||
|
||
$member = $rt['data'];
|
||
|
||
// 保存本地会话
|
||
$this->save_cookie($member);
|
||
|
||
// 记录日志
|
||
$this->_login_log($member, $oauth['oauth']);
|
||
|
||
// 更改状态
|
||
$this->db->table('member_oauth')->where('id', $oauth['id'])->update(['uid' => $member['id']]);
|
||
|
||
// 更新微信插件粉丝表
|
||
if (dr_is_app('weixin') && $oauth['oauth'] == 'wechat') {
|
||
$this->db->table('weixin_user')->where('openid', $oauth['oid'])->update([
|
||
'uid' => $member['id'],
|
||
'username' => $member['username'],
|
||
]);
|
||
}
|
||
|
||
// 同步登录
|
||
$sso = $this->sso($member);
|
||
|
||
// 下载头像
|
||
\Phpcmf\Service::L('thread')->cron(['action' => 'oauth_down_avatar', 'id' => $oauth['id'] ]);
|
||
|
||
return dr_return_data($member['id'], 'ok', [
|
||
'auth'=> md5($member['password'].$member['salt']), // API认证字符串,
|
||
'member' => $member,
|
||
'sso' => $sso
|
||
]);
|
||
}
|
||
|
||
// 直接登录模式 授权注册
|
||
public function register_oauth($groupid, $oauth) {
|
||
|
||
$rt = $this->register($groupid, [
|
||
'username' => '',
|
||
'name' => dr_clear_emoji($oauth['nickname']),
|
||
'email' => '',
|
||
'phone' => '',
|
||
], null, $oauth);
|
||
if (!$rt['code']) {
|
||
return dr_return_data(0, $rt['msg']);
|
||
}
|
||
|
||
$data = $rt['data'];
|
||
|
||
// 保存本地会话
|
||
$this->save_cookie($data);
|
||
|
||
// 记录日志
|
||
$this->_login_log($data, $oauth['oauth']);
|
||
|
||
// 更改状态
|
||
$this->db->table('member_oauth')->where('id', $oauth['id'])->update(['uid' => $data['id']]);
|
||
if (dr_is_app('weixin') && $oauth['oauth'] == 'wechat') {
|
||
$this->db->table('weixin_user')->where('openid', $oauth['oid'])->update([
|
||
'uid' => $data['id'],
|
||
'username' => $data['username'],
|
||
]);
|
||
}
|
||
|
||
// 下载头像和同步登录
|
||
$sso = $this->sso($data);
|
||
$sso[] = \Phpcmf\Service::L('router')->member_url('api/avatar', ['id'=>$oauth['id']]);
|
||
|
||
return dr_return_data($data['id'], 'ok', [
|
||
'auth'=> md5($data['password'].$data['salt']), // API认证字符串,
|
||
'member' => $data,
|
||
'sso' => $sso
|
||
]);
|
||
}
|
||
|
||
/**
|
||
* 存储授权信息
|
||
*/
|
||
public function insert_oauth($uid, $type, $data, $state = '', $back = '') {
|
||
|
||
$row = $this->db->table('member_oauth')->where('oid', $data['oid'])->where('oauth', $data['oauth'])->get()->getRowArray();
|
||
if (!$row && $data['unionid']) {
|
||
// 没找到尝试 unionid
|
||
$row = $this->db->table('member_oauth')->where('unionid', $data['unionid'])->get()->getRowArray();
|
||
if (!$uid && $row['uid']) {
|
||
$uid = $row['uid'];
|
||
}
|
||
$ins = 1; // 新插入授权
|
||
} else {
|
||
$ins = 0;
|
||
}
|
||
|
||
// 授权更新
|
||
if (!$row || $ins) {
|
||
// 插入授权信息
|
||
$data['uid'] = (int)$uid;
|
||
$rt = $this->table('member_oauth')->insert($data);
|
||
if (!$rt['code']) {
|
||
return dr_return_data(0, $rt['msg']);
|
||
}
|
||
$id = $rt['code'];
|
||
} else {
|
||
// 更新授权信息
|
||
$uid && $data['uid'] = $uid;
|
||
$this->db->table('member_oauth')->where('id', $row['id'])->update($data);
|
||
$id = $row['id'];
|
||
}
|
||
|
||
// 绑定成功更新头像
|
||
if ($uid && $data['avatar']) {
|
||
list($cache_path) = dr_avatar_path();
|
||
if (!is_file($cache_path.$uid.'.jpg')) {
|
||
// 没有头像下载头像
|
||
$img = dr_catcher_data($data['avatar']);
|
||
if (strlen($img) > 20 && file_put_contents($cache_path.$uid.'.jpg', $img)) {
|
||
// 头像状态认证
|
||
$this->db->table('member_data')->where('id', $uid)->update(['is_avatar' => 1]);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 存储
|
||
\Phpcmf\Service::L('cache')->set_auth_data('member_auth_'.$type.'_'.$data['oauth'].'_'.$id, $id);
|
||
|
||
return dr_return_data($id, $type == 'login' ? \Phpcmf\Service::L('router')->member_url('login/oauth', ['id' => $id, 'name' => $data['oauth'], 'state' => $state, 'back' => $back]) : \Phpcmf\Service::L('router')->member_url('account/oauth', ['id' => $id, 'name' => $data['oauth']]));
|
||
}
|
||
|
||
// 删除会员后执行 sync是否删除相关数据表
|
||
public function member_delete($id, $sync = 0) {
|
||
|
||
$this->clear_cache($id);
|
||
|
||
// 删除会员的相关表
|
||
$this->db->table('member')->where('id', $id)->delete();
|
||
$this->db->table('member_data')->where('id', $id)->delete();
|
||
$this->db->table('member_group_index')->where('uid', $id)->delete();
|
||
$this->db->table('member_login')->where('uid', $id)->delete();
|
||
$this->db->table('member_oauth')->where('uid', $id)->delete();
|
||
$this->db->table('admin')->where('uid', $id)->delete();
|
||
$this->db->table('admin_login')->where('uid', $id)->delete();
|
||
$this->db->table('admin_role_index')->where('uid', $id)->delete();
|
||
$this->db->table('member_group_verify')->where('uid', $id)->delete();
|
||
$this->is_table_exists('member_paylog') && $this->db->table('member_paylog')->where('uid', $id)->delete();
|
||
$this->is_table_exists('member_scorelog') && $this->db->table('member_scorelog')->where('uid', $id)->delete();
|
||
$this->is_table_exists('member_explog') && $this->db->table('member_explog')->where('uid', $id)->delete();
|
||
$this->is_table_exists('member_cashlog') && $this->db->table('member_cashlog')->where('uid', $id)->delete();
|
||
$this->is_table_exists('member_notice') && $this->db->table('member_notice')->where('uid', $id)->delete();
|
||
$this->delete_admin_notice('member/verify/index:field/id/keyword/'.$id, 0);
|
||
|
||
// 删除头像
|
||
list($cache_path, $cache_url) = dr_avatar_path();
|
||
if (is_file($cache_path.$id.'.jpg')) {
|
||
unlink($cache_url.$id.'.jpg');
|
||
}
|
||
|
||
// 删除微信uid
|
||
if (dr_is_app('weixin') && $this->is_table_exists('weixin_user')) {
|
||
$this->db->table('weixin_user')->where('uid', $id)->update([
|
||
'uid' => 0,
|
||
'username' => '',
|
||
]);
|
||
}
|
||
|
||
if (!$sync) {
|
||
return ;
|
||
}
|
||
|
||
// 同步删除动作
|
||
\Phpcmf\Service::M('Sync')->delete_member($id);
|
||
|
||
// 按站点数据删除
|
||
SYS_ATTACHMENT_DB && \Phpcmf\Service::M('Attachment')->uid_delete($id);
|
||
foreach ($this->site as $siteid) {
|
||
// 表单
|
||
if ($this->db->query("SHOW TABLES LIKE '".$this->dbprefix($siteid . '_form')."'")->getRowArray()) {
|
||
$form = $this->is_table_exists($siteid . '_form') ? $this->init(['table' => $siteid . '_form'])->getAll() : [];
|
||
if ($form) {
|
||
foreach ($form as $t) {
|
||
$table = $siteid . '_form_' . $t['table'];
|
||
\Phpcmf\Service::M()->db->tableExists(\Phpcmf\Service::M()->dbprefix($table)) && $this->db->table($table)->where('uid', $id)->delete();
|
||
for ($i = 0; $i < 200; $i++) {
|
||
if (!$this->db->query("SHOW TABLES LIKE '" . $this->dbprefix($table) . '_data_' . $i . "'")->getRowArray()) {
|
||
break;
|
||
}
|
||
$this->db->table($table . '_data_' . $i)->where('uid', $id)->delete();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
// 模块
|
||
if ($this->db->query("SHOW TABLES LIKE '".$this->dbprefix('module')."'")->getRowArray()) {
|
||
$module = $this->table('module')->getAll();
|
||
if ($module) {
|
||
foreach ($module as $m) {
|
||
$mdir = $m['dirname'];
|
||
$table = $siteid.'_'.$mdir;
|
||
// 模块内容
|
||
if (!$this->db->query("SHOW TABLES LIKE '".$this->dbprefix($table)."'")->getRowArray()) {
|
||
break;
|
||
}
|
||
$mdb = \Phpcmf\Service::M('Content', $mdir);
|
||
$mdb->_init($mdir, $siteid);
|
||
// 查询删除内容
|
||
$index = $this->table($table.'_index')->where('uid', $id)->getAll();
|
||
if ($index) {
|
||
foreach ($index as $t) {
|
||
$mdb->delete_content($t['id']);
|
||
}
|
||
}
|
||
$form = $this->is_table_exists('module_form') ? $this->db->table('module_form')->where('module', $mdir)->get()->getResultArray() : [];
|
||
if ($form) {
|
||
foreach ($form as $t) {
|
||
$mytable = $table.'_form_'.$t['table'];
|
||
if (!$this->db->query("SHOW TABLES LIKE '".$this->dbprefix($mytable)."'")->getRowArray()) {
|
||
break;
|
||
}
|
||
$this->db->table($mytable)->where('uid', $id)->delete();
|
||
for ($i = 0; $i < 200; $i ++) {
|
||
if (!$this->db->query("SHOW TABLES LIKE '".$this->dbprefix($mytable).'_data_'.$i."'")->getRowArray()) {
|
||
break;
|
||
}
|
||
$this->db->table($mytable.'_data_'.$i)->where('uid', $id)->delete();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 缓存动作
|
||
public function member_cache() {
|
||
|
||
// 获取会员全部配置信息
|
||
$cache = [];
|
||
$resultQuery = $this->db->table('member_setting')->get();
|
||
$result = $resultQuery ? $resultQuery->getResultArray() : [];
|
||
if ($result) {
|
||
foreach ($result as $t) {
|
||
// auth_type 存的是 0/1/2,不能走 dr_string2array(会把 "0" 变成 [])
|
||
if ($t['name'] === 'auth_type') {
|
||
$cache[$t['name']] = intval($t['value']);
|
||
} else {
|
||
$cache[$t['name']] = dr_string2array($t['value']);
|
||
}
|
||
}
|
||
}
|
||
|
||
if (!isset($cache['list_field']) || !$cache['list_field']) {
|
||
$cache['list_field'] = array (
|
||
'username' =>
|
||
array (
|
||
'use' => '1',
|
||
'name' => '账号',
|
||
'width' => '110',
|
||
'func' => 'author',
|
||
),
|
||
'group' =>
|
||
array (
|
||
'func' => 'group',
|
||
'center' => '1',
|
||
),
|
||
'name' =>
|
||
array (
|
||
'use' => '1',
|
||
'name' => '姓名',
|
||
'width' => '120',
|
||
'func' => '',
|
||
),
|
||
'money' =>
|
||
array (
|
||
'use' => '1',
|
||
'name' => '余额',
|
||
'width' => '120',
|
||
'func' => 'money',
|
||
),
|
||
'score' =>
|
||
array (
|
||
'use' => '1',
|
||
'name' => '积分',
|
||
'width' => '120',
|
||
'func' => 'score',
|
||
),
|
||
'regip' =>
|
||
array (
|
||
'use' => '1',
|
||
'name' => '注册IP',
|
||
'width' => '140',
|
||
'func' => 'ip',
|
||
),
|
||
'regtime' =>
|
||
array (
|
||
'use' => '1',
|
||
'name' => '注册时间',
|
||
'width' => '170',
|
||
'func' => 'datetime',
|
||
),
|
||
'is_lock' =>
|
||
array (
|
||
'func' => 'save_select_value',
|
||
'center' => '1',
|
||
),
|
||
);
|
||
}
|
||
|
||
// 字段归属
|
||
$cache['myfield'] = $cache['field'];
|
||
|
||
// 自定义字段
|
||
$register_field = $group_field = $cache['field'] = [];
|
||
$fieldQuery = $this->db->table('field')->where('disabled', 0)->where('relatedname', 'member')->orderBy('displayorder ASC,id ASC')->get();
|
||
$field = $fieldQuery ? $fieldQuery->getResultArray() : [];
|
||
if ($field) {
|
||
foreach ($field as $f) {
|
||
$f['setting'] = dr_string2array($f['setting']);
|
||
$cache['field'][$f['fieldname']] = $f;
|
||
// 归类用户组字段
|
||
if ($cache['myfield'][$f['id']]) {
|
||
foreach ($cache['myfield'][$f['id']] as $gid) {
|
||
$group_field[$gid][] = $f['fieldname'];
|
||
}
|
||
}
|
||
// 归类可用注册的字段
|
||
if ($cache['register_field'][$f['id']]) {
|
||
$register_field[] = $f['fieldname'];
|
||
}
|
||
}
|
||
}
|
||
|
||
// 支付接口
|
||
if ($cache['payapi']) {
|
||
foreach ($cache['payapi'] as $i => $t) {
|
||
if (!$t['use']) {
|
||
unset($cache['payapi'][$i]);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 注册配置
|
||
$cache['register']['notallow'] = explode(',', trim((string)$cache['register']['notallow']));
|
||
|
||
// 用户组
|
||
$cache['register']['group'] = [];
|
||
$groupQuery = $this->db->table('member_group')->orderBy('displayorder ASC,id ASC')->get();
|
||
$group = $groupQuery ? $groupQuery->getResultArray() : [];
|
||
if ($group) {
|
||
$has_level = $this->is_table_exists('member_level');
|
||
$level_order = ($has_level && $this->is_field_exists('member_level', 'displayorder'))
|
||
? 'displayorder ASC,id ASC'
|
||
: 'id ASC';
|
||
foreach ($group as $t) {
|
||
$level = [];
|
||
if ($has_level) {
|
||
$levelQuery = $this->db->table('member_level')->where('gid', $t['id'])->orderBy($level_order)->get();
|
||
$level = $levelQuery ? $levelQuery->getResultArray() : [];
|
||
}
|
||
if ($level) {
|
||
foreach ($level as $lv) {
|
||
$lv['icon'] = dr_get_file($lv['stars']);
|
||
$lv['setting'] = dr_string2array($lv['setting']);
|
||
$cache['authid'][] = $t['id'].'-'.$lv['id'];
|
||
$t['level'][$lv['id']] = $lv;
|
||
}
|
||
} else {
|
||
$cache['authid'][] = $t['id'];
|
||
}
|
||
$t['setting'] = dr_string2array($t['setting']);
|
||
// 用户组的可用字段
|
||
$t['field'] = $group_field[$t['id']];
|
||
// 当前用户组开启了注册时, 查询它可注册的字段
|
||
$t['register'] && $t['field'] && $t['register_field'] = $register_field ? dr_array_intersect($t['field'], $register_field) : [];
|
||
// 是否允许注册
|
||
$t['register'] && $cache['register']['group'][] = $t['id'];
|
||
$cache['group'][$t['id']] = $t;
|
||
}
|
||
}
|
||
|
||
\Phpcmf\Service::L('cache')->set_file('member', $cache);
|
||
|
||
return $cache;
|
||
}
|
||
} |