vr-shopxo-source/app/service/UserService.php

2777 lines
92 KiB
PHP
Executable File
Raw Blame History

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
// +----------------------------------------------------------------------
// | ShopXO 国内领先企业级B2C免费开源电商系统
// +----------------------------------------------------------------------
// | Copyright (c) 2011~2099 http://shopxo.net All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( https://opensource.org/licenses/mit-license.php )
// +----------------------------------------------------------------------
// | Author: Devil
// +----------------------------------------------------------------------
namespace app\service;
use think\facade\Db;
use app\service\SystemService;
use app\service\RegionService;
use app\service\SafetyService;
use app\service\ResourcesService;
use app\service\SystemBaseService;
/**
* 用户服务层
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-01T21:51:08+0800
*/
class UserService
{
// user登录session key
public static $user_login_key = 'user_login_info';
public static $user_token_key = 'user_token_data';
/**
* 获取用户登录信息
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2021-12-06
* @desc description
* @param [boolean] $is_cache [是否缓存读取]
*/
public static function LoginUserInfo($is_cache = true)
{
// 静态数据避免重复读取
static $user_login_info = null;
if($user_login_info === null)
{
// 参数
$params = input();
// 用户数据处理
if(APPLICATION == 'web')
{
// web用户session
$user_login_info = MyCookie(self::$user_login_key);
// 用户信息为空指定了token则设置登录信息
if(empty($user_login_info))
{
$token = empty($params['token']) ? MyCookie(self::$user_token_key) : $params['token'];
if(!empty($token))
{
$user_login_info = self::UserTokenData($token);
if(!empty($user_login_info) && isset($user_login_info['id']))
{
self::UserLoginRecord($user_login_info['id']);
}
}
}
} else {
if(!empty($params['token']))
{
$user_login_info = self::UserTokenData($params['token']);
}
}
}
// 是否缓存读取
if(!empty($user_login_info) && !$is_cache)
{
// 根据用户id从数据库获取信息并处理
$user_login_info = self::UserHandle(self::UserInfo('id', $user_login_info['id']));
if(!empty($user_login_info))
{
// 重新更新用户缓存
self::UserLoginRecord($user_login_info['id']);
if(!empty($user_login_info['token']))
{
MyCache(SystemService::CacheKey('shopxo.cache_user_info').$user_login_info['token'], $user_login_info);
}
}
}
return $user_login_info;
}
/**
* 获取用户token用户数据
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @datetime 2019-08-18T19:01:59+0800
* @desc description
* @param [string] $token [用户token]
*/
public static function UserTokenData($token)
{
$user = MyCache(SystemService::CacheKey('shopxo.cache_user_info').$token);
if(!empty($user) && isset($user['id']))
{
return $user;
}
// 数据库校验
return self::AppUserInfoHandle(null, 'token', $token);
}
/**
* 用户状态校验
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2019-02-27
* @desc description
* @param [string] $field [条件字段]
* @param [string] $value [条件值]
*/
public static function UserStatusCheck($field, $value)
{
// 查询用户状态是否正常
$user = self::UserInfo($field, $value);
if(empty($user))
{
return DataReturn('用户不存在或已删除', -110);
}
if(!in_array($user['status'], [0,1]))
{
$common_user_status_list = MyConst('common_user_status_list');
if(isset($common_user_status_list[$user['status']]))
{
return DataReturn($common_user_status_list[$user['status']]['tips'], -110);
} else {
return DataReturn('用户状态有误', -110);
}
}
return DataReturn('正常', 0);
}
/**
* 用户列表
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-06T21:31:53+0800
* @param [array] $params [输入参数]
*/
public static function UserList($params = [])
{
$where = empty($params['where']) ? [] : $params['where'];
$field = empty($params['field']) ? '*' : $params['field'];
$order_by = empty($params['order_by']) ? 'id desc' : trim($params['order_by']);
$m = isset($params['m']) ? intval($params['m']) : 0;
$n = isset($params['n']) ? intval($params['n']) : 10;
// 获取用户列表
$data = Db::name('User')->where($where)->order($order_by)->field($field)->limit($m, $n)->select()->toArray();
return DataReturn(MyLang('common.handle_success'), 0, self::UserListHandle($data, $params));
}
/**
* 列表数据处理
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2022-08-01
* @desc description
* @param [array] $data [数据列表]
* @param [array] $params [输入参数]
*/
public static function UserListHandle($data, $params = [])
{
if(!empty($data))
{
// 用户列表钩子-前面
$hook_name = 'plugins_service_user_list_handle_begin';
MyEventTrigger($hook_name, [
'hook_name' => $hook_name,
'is_backend' => true,
'params' => &$params,
'data' => &$data,
]);
// 字段列表
$keys = ArrayKeys($data);
// 邀请用户列表
if(in_array('referrer', $keys))
{
$referrer_list = self::GetUserViewInfo(array_column($data, 'referrer'));
}
// 开始处理数据
$common_gender_list = MyConst('common_gender_list');
$common_user_status_list = MyConst('common_user_status_list');
foreach($data as &$v)
{
// 生日
if(array_key_exists('birthday', $v))
{
$v['birthday_text'] = empty($v['birthday']) ? '' : date('Y-m-d', $v['birthday']);
}
// 头像
if(array_key_exists('avatar', $v))
{
if(!empty($v['avatar']))
{
$v['avatar'] = ResourcesService::AttachmentPathViewHandle($v['avatar']);
} else {
$v['avatar'] = SystemBaseService::AttachmentHost().'/static/index/'.strtolower(MyC('common_default_theme', 'default', true)).'/images/default-user-avatar.jpg';
}
}
// 邀请用户信息
if(array_key_exists('referrer', $v))
{
$v['referrer_info'] = (!empty($referrer_list) && is_array($referrer_list) && array_key_exists($v['referrer'], $referrer_list)) ? $referrer_list[$v['referrer']] : [];
}
// 时间
if(array_key_exists('add_time', $v))
{
$v['add_time'] = date('Y-m-d H:i:s', $v['add_time']);
}
if(array_key_exists('upd_time', $v))
{
$v['upd_time'] = date('Y-m-d H:i:s', $v['upd_time']);
}
// 性别
if(array_key_exists('gender', $v))
{
$v['gender_text'] = isset($common_gender_list[$v['gender']]) ? $common_gender_list[$v['gender']]['name'] : '未知';
}
// 状态
if(array_key_exists('status', $v))
{
$v['status_text'] = $common_user_status_list[$v['status']]['name'];
}
}
// 用户列表钩子-后面
$hook_name = 'plugins_service_user_list_handle_end';
MyEventTrigger($hook_name, [
'hook_name' => $hook_name,
'is_backend' => true,
'params' => &$params,
'data' => &$data,
]);
}
return $data;
}
/**
* 用户总数
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-10T22:16:29+0800
* @param [array] $where [条件]
*/
public static function UserTotal($where)
{
return (int) Db::name('User')->where($where)->count();
}
/**
* 用户信息保存
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-10T22:16:29+0800
* @param [array] $params [输入参数]
*/
public static function UserSave($params = [])
{
// 请求参数
$p = [
[
'checked_type' => 'empty',
'key_name' => 'admin',
'error_msg' => '管理员信息有误',
],
[
'checked_type' => 'length',
'key_name' => 'username',
'checked_data' => '30',
'is_checked' => 1,
'error_msg' => '用户名格式最多 30 个字符之间',
],
[
'checked_type' => 'unique',
'key_name' => 'username',
'checked_data' => 'User',
'checked_key' => 'id',
'is_checked' => 1,
'error_msg' => '用户已存在[{$var}]',
],
[
'checked_type' => 'length',
'key_name' => 'nickname',
'checked_data' => '30',
'is_checked' => 1,
'error_msg' => '用户昵称格式最多 30 个字符之间',
],
[
'checked_type' => 'fun',
'key_name' => 'mobile',
'checked_data' => 'CheckMobile',
'is_checked' => 1,
'error_msg' => '手机号码格式错误',
],
[
'checked_type' => 'fun',
'key_name' => 'email',
'checked_data' => 'CheckEmail',
'is_checked' => 1,
'error_msg' => '邮箱格式错误',
],
[
'checked_type' => 'in',
'key_name' => 'gender',
'checked_data' => array_column(MyConst('common_gender_list'), 'id'),
'error_msg' => '性别值范围不正确',
],
[
'checked_type' => 'in',
'key_name' => 'status',
'checked_data' => array_column(MyConst('common_user_status_list'), 'id'),
'error_msg' => '状态值范围不正确',
],
[
'checked_type' => 'length',
'key_name' => 'address',
'checked_data' => '80',
'is_checked' => 1,
'error_msg' => '地址格式最多 80 个字符之间',
],
[
'checked_type' => 'fun',
'key_name' => 'pwd',
'checked_data' => 'CheckLoginPwd',
'is_checked' => 1,
'error_msg' => '密码格式 6~18 个字符之间',
],
];
$ret = ParamsChecked($params, $p);
if($ret !== true)
{
return DataReturn($ret, -1);
}
// 更新数据
$data = [
'system_type' => empty($params['system_type_name']) ? 'default' : $params['system_type_name'],
'username' => isset($params['username']) ? $params['username'] : '',
'nickname' => isset($params['nickname']) ? $params['nickname'] : '',
'mobile' => isset($params['mobile']) ? $params['mobile'] : '',
'email' => isset($params['email']) ? $params['email'] : '',
'address' => isset($params['address']) ? $params['address'] : '',
'gender' => intval($params['gender']),
'integral' => intval($params['integral']),
'locking_integral' => intval($params['locking_integral']),
'status' => intval($params['status']),
'alipay_openid' => isset($params['alipay_openid']) ? $params['alipay_openid'] : '',
'baidu_openid' => isset($params['baidu_openid']) ? $params['baidu_openid'] : '',
'toutiao_openid' => isset($params['toutiao_openid']) ? $params['toutiao_openid'] : '',
'toutiao_unionid' => isset($params['toutiao_unionid']) ? $params['toutiao_unionid'] : '',
'qq_openid' => isset($params['qq_openid']) ? $params['qq_openid'] : '',
'qq_unionid' => isset($params['qq_unionid']) ? $params['qq_unionid'] : '',
'weixin_openid' => isset($params['weixin_openid']) ? $params['weixin_openid'] : '',
'weixin_unionid' => isset($params['weixin_unionid']) ? $params['weixin_unionid'] : '',
'weixin_web_openid' => isset($params['weixin_web_openid']) ? $params['weixin_web_openid'] : '',
'kuaishou_openid' => isset($params['kuaishou_openid']) ? $params['kuaishou_openid'] : '',
'birthday' => empty($params['birthday']) ? 0 : strtotime($params['birthday']),
'referrer' => empty($params['referrer']) ? 0 : intval($params['referrer']),
];
// 用户保存处理钩子
$hook_name = 'plugins_service_user_save_handle';
$ret = EventReturnHandle(MyEventTrigger($hook_name, [
'hook_name' => $hook_name,
'is_backend' => true,
'params' => &$params,
'data' => &$data,
'user_id' => isset($params['id']) ? intval($params['id']) : 0,
]));
if(isset($ret['code']) && $ret['code'] != 0)
{
return $ret;
}
// 密码
if(!empty($params['pwd']))
{
$data['salt'] = GetNumberCode(6);
$data['pwd'] = LoginPwdEncryption(trim($params['pwd']), $data['salt']);
}
// 更新/添加
if(!empty($params['id']))
{
// 获取用户信息
$user = Db::name('User')->where(['id'=>intval($params['id'])])->field('id,integral')->find();
if(empty($user))
{
return DataReturn('用户信息不存在', -10);
}
$ret = self::UserUpdateHandle($data, $params['id']);
if($ret['code'] == 0)
{
$user_id = $params['id'];
}
} else {
$data['add_time'] = time();
$ret = self::UserInsert($data);
if($ret['code'] != 0)
{
return $ret;
}
$user_id = $ret['data']['user_id'];
}
// 添加用户后处理钩子
$hook_name = 'plugins_service_user_save_success_handle';
$ret = EventReturnHandle(MyEventTrigger($hook_name, [
'hook_name' => $hook_name,
'is_backend' => true,
'params' => &$params,
'data' => &$data,
'user_id' => &$user_id,
]));
if(isset($ret['code']) && $ret['code'] != 0)
{
return $ret;
}
// 状态
if(isset($user_id))
{
if(($data['integral'] > 0 && empty($user)) || (isset($user['integral']) && $user['integral'] != $data['integral']))
{
$integral_type = 1;
$old_integral = 0;
$opt_integral = 0;
if(!empty($params['id']))
{
$old_integral = $user['integral'];
$integral_type = ($user['integral'] > $data['integral']) ? 0 : 1;
$opt_integral = ($integral_type == 1) ? $data['integral']-$user['integral'] : $user['integral']-$data['integral'];
}
IntegralService::UserIntegralLogAdd($user_id, $old_integral, $opt_integral, '管理员操作', $integral_type, $params['admin']['id']);
}
return DataReturn(MyLang('common.operate_success'), 0);
}
return DataReturn(MyLang('common.operate_fail'), -100);
}
/**
* 用户信息更新
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2022-02-13
* @desc description
* @param [array] $data [用户更新信息]
* @param [int] $user_id [用户id]
*/
public static function UserUpdateHandle($data, $user_id)
{
$data['upd_time'] = time();
if(Db::name('User')->where(['id'=>intval($user_id)])->update($data))
{
// 更新成功后钩子
$hook_name = 'plugins_service_user_update_success';
$ret = EventReturnHandle(MyEventTrigger($hook_name, [
'hook_name' => $hook_name,
'is_backend' => true,
'user_id' => $user_id,
'data' => $data,
]));
if(isset($ret['code']) && $ret['code'] != 0)
{
return $ret;
}
return DataReturn(MyLang('common.update_success'), 0);
}
return DataReturn(MyLang('common.update_fail'), -100);
}
/**
* 用户删除
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-10T22:16:29+0800
* @param [array] $params [输入参数]
*/
public static function UserDelete($params = [])
{
// 参数是否有误
if(empty($params['ids']))
{
return DataReturn('商品id有误', -1);
}
// 是否数组
if(!is_array($params['ids']))
{
$params['ids'] = explode(',', $params['ids']);
}
// 删除操作
if(Db::name('User')->where(['id'=>$params['ids']])->delete())
{
return DataReturn(MyLang('common.delete_success'), 0);
}
return DataReturn(MyLang('common.delete_fail'), -100);
}
/**
* 用户登录记录
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2017-03-09T11:37:43+0800
* @param [int] $user_id [用户id]
* @return [boolean] [记录成功true, 失败false]
*/
public static function UserLoginRecord($user_id = 0)
{
if(!empty($user_id))
{
$user = self::UserInfo('id', $user_id);
if(!empty($user))
{
// 用户数据处理
$user = self::UserHandle($user);
// 用户登录成功信息纪录钩子
$hook_name = 'plugins_service_user_login_success_record';
MyEventTrigger($hook_name, [
'hook_name' => $hook_name,
'is_backend' => true,
'user' => &$user,
'user_id' => $user_id
]);
// web端设置session
if(APPLICATION == 'web')
{
// 存储session