cxgj/models/User.php
2023-11-27 09:45:13 +08:00

549 lines
18 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace app\models;
use app\models\Model;
use app\modules\api\components\ApiHelper;
use function PHPSTORM_META\type;
use Yii;
use yii\web\IdentityInterface;
use app\components\FlashStorage;
use app\components\EncryptHelper;
use app\components\SysConst;
use app\models\auth\RoleUser;
use app\models\auth\RolePermission;
use app\models\integral\Integral;
use Gumlet\ImageResize;
use Gumlet\ImageResizeException;
/**
* This is the model class for table "{{%user}}".
*
* @property int $id ID
* @property int $cx_mch_id 平台商户ID
* @property string $username 用户名
* @property string $password 密码
* @property string $auth_key AUTH_KEY
* @property string $access_token ACCESS_TOKEN
* @property string $nickname 昵称
* @property string $avatar_url 头像
* @property string|null $mobile_phone 手机号
* @property string|null $mobile_prefix 手机号国家代码
* @property string|null $email 邮箱
* @property string|null $real_name 真实姓名
* @property string|null $desc 个性签名
* @property int $gender 性别0=女1=男2=保密
* @property string|null $birthday 生日
* @property int $status 状态0=正常1=封禁2=挂起3=注销
* @property int $parent_id PARENT_ID
* @property int $is_modify_un 用户名是否可以修改0=否1=是
* @property int $is_delete 是否删除0=否1=是
* @property int $country_id 国家ID
* @property int $city_id 城市ID
* @property int $created_at 添加时间
* @property int $updated_at 更新时间
* @property int $type 0=用户1=管理员
* @property int $is_view 是否有观看视频
* @property int|null $level_id 用户等级
* @property float|null $level_exp 升级经验
*/
class User extends \yii\db\ActiveRecord implements IdentityInterface
{
const STATUS_NORMAL = 0;
const STATUS_FORBIDDEN = 1;
const STATUS_HANGUP = 2;
const STATUS_ACCOUNT_LOGOUT = 3;
const IS_YES = 1;
const IS_NO = 0;
const GENDER_UNKNOWN = 0;
const GENDER_MAN = 1;
const GENDER_WOMEN = 2;
const GENDER_SECRET = 3;
const TYPE_USER = 0;
const TYPE_ADMIN = 1;
const TYPE_STORE = 2;
const TYPE_COACH = 3;
const TYPE_STAFF = 6; //员工
const TYPE_BOSS_STAFF = 7; //boss员工
const TYPE_ADMIN_STAFF = 8; //总部管理员
const DEFAULT_AVATAR_URL = '/statics/images/avatar.jpg';
/**
* {@inheritdoc}
*/
public static function tableName()
{
return '{{%user}}';
}
/**
* {@inheritdoc}
*/
public function rules()
{
return [
[['username', 'password', 'auth_key', 'access_token', 'nickname', 'email', 'real_name', 'avatar_url', 'mobile_phone', 'mobile_prefix'], 'trim'],
[['cx_mch_id', 'gender', 'status', 'parent_id', 'is_modify_un', 'is_delete', 'country_id', 'city_id', 'created_at', 'updated_at', 'type', 'is_view','level_id'], 'integer'],
[['username', 'password', 'auth_key', 'access_token', 'nickname', 'avatar_url'], 'required'],
[['birthday'], 'safe'],
[['level_exp'], 'number'],
[['username', 'desc'], 'string', 'max' => 64],
[['password', 'auth_key', 'access_token', 'nickname', 'email', 'real_name'], 'string', 'max' => 256],
[['avatar_url'], 'string', 'max' => 2048],
[['mobile_phone'], 'string', 'max' => 128],
[['mobile_prefix'], 'string', 'max' => 16],
[['username'], 'unique'],
];
}
/**
* {@inheritdoc}
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'cx_mch_id' => '平台商户ID',
'username' => '用户名',
'password' => '密码',
'auth_key' => 'AUTH_KEY',
'access_token' => 'ACCESS_TOKEN',
'nickname' => '昵称',
'avatar_url' => '头像',
'mobile_phone' => '手机号',
'mobile_prefix' => '手机号国家代码',
'email' => '邮箱',
'real_name' => '真实姓名',
'desc' => '个性签名',
'gender' => '性别0=女1=男2=保密',
'birthday' => '生日',
'status' => '状态0=正常1=封禁2=挂起3=注销',
'parent_id' => 'PARENT_ID',
'is_modify_un' => '用户名是否可以修改0=否1=是',
'is_delete' => '是否删除0=否1=是',
'country_id' => '国家ID',
'city_id' => '城市ID',
'created_at' => '添加时间',
'updated_at' => '更新时间',
'type' => '0=普通用户1=管理员',
'is_view' => '是否有观看视频',
'level_id' => '会员等级',
'level_exp' => '升级经验',
];
}
public function beforeSave($insert)
{
if (parent::beforeSave($insert)) {
if ($this->isNewRecord) {
$this->created_at = time();
}
$this->updated_at = time();
$this->htmlTagFilter();
return true;
} else {
return false;
}
}
public function htmlTagFilter()
{
$this->nickname = Model::htmlTagFilter($this->nickname);
$this->username = Model::htmlTagFilter($this->username);
$this->desc = Model::htmlTagFilter($this->desc);
$this->real_name = Model::htmlTagFilter($this->real_name);
$this->email = Model::htmlTagFilter($this->email);
}
/**
* Validates password
*
* @param string $password password to validate
* @return boolean if password provided is valid for current user
*/
public function validatePassword($password)
{
return Yii::$app->security->validatePassword($password, $this->password);
}
/**
* Generates password hash from password and sets it to the model
*
* @param string $password
*/
public function setPassword($password)
{
$this->password = Yii::$app->security->generatePasswordHash($password);
}
/**
* Finds an identity by the given ID.
* @param string|int $id the ID to be looked for
* @return IdentityInterface the identity object that matches the given ID.
* Null should be returned if such an identity cannot be found
* or the identity is not in an active state (disabled, deleted, etc.)
*/
public static function findIdentity($id)
{
return static::findOne([
'id' => $id,
'is_delete' => 0,
'status' => self::STATUS_NORMAL,
]);
}
/**
* Finds an identity by the given token.
* @param mixed $token the token to be looked for
* @param mixed $type the type of the token. The value of this parameter depends on the implementation.
* For example, [[\yii\filters\auth\HttpBearerAuth]] will set this parameter to be `yii\filters\auth\HttpBearerAuth`.
* @return IdentityInterface the identity object that matches the given token.
* Null should be returned if such an identity cannot be found
* or the identity is not in an active state (disabled, deleted, etc.)
*/
public static function findIdentityByAccessToken($token, $type = null)
{
$user_token = UserToken::find()
->where([
'is_delete' => 0,
'token' => $token,
'cx_mch_id' => Model::getCxMchId()
])
->andFilterWhere([
'type' => $type,
])->one();
if ($user_token && $user_token->expire_time > time()) {
return static::findOne([
'id' => $user_token->user_id,
'is_delete' => 0,
'status' => self::STATUS_NORMAL,
]);
}
return static::findOne([
'id' => 0,
'is_delete' => 0,
'status' => self::STATUS_NORMAL,
]);
}
/**
* Returns an ID that can uniquely identify a user identity.
* @return string|int an ID that uniquely identifies a user identity.
*/
public function getId()
{
return $this->id;
}
/**
* Returns a key that can be used to check the validity of a given identity ID.
*
* The key should be unique for each individual user, and should be persistent
* so that it can be used to check the validity of the user identity.
*
* The space of such keys should be big enough to defeat potential identity attacks.
*
* This is required if [[User::enableAutoLogin]] is enabled.
* @return string a key that is used to check the validity of a given identity ID.
* @see validateAuthKey()
*/
public function getAuthKey()
{
return $this->auth_key;
}
/**
* Validates the given auth key.
*
* This is required if [[User::enableAutoLogin]] is enabled.
* @param string $authKey the given auth key
* @return bool whether the given auth key is valid.
* @see getAuthKey()
*/
public function validateAuthKey($authKey)
{
return $this->getAuthKey() === $authKey;
}
//是否已经绑定手机号
public function getIsBindPhone()
{
return true;
$mobile = empty($this->mobile_phone) ? null : EncryptHelper::decryptMobilePhone($this->mobile_phone);
return $mobile ? true : false;
}
//是否绑定微信小程序登录
public function getBindWxmp()
{
return $this->hasOne(UserOauth::className(), ['user_id' => 'id'])->where(['type' => SysConst::$cxOauthProviderWxmp, 'is_delete' => 0, 'cx_mch_id' => 0]);
}
//账户余额
public function getBalance()
{
// $cx_mch_id = Model::getCxMchId();
return $this->hasOne(Balance::className(), ['user_id' => 'id'])->where(['is_delete' => 0, 'scene' => Balance::$cxBalanceSceneUserWallet, 'cx_mch_id' => 0]);
}
//账户积分
public function getIntegral()
{
// $cx_mch_id = Model::getCxMchId();
return $this->hasOne(Integral::className(), ['user_id' => 'id'])->where(['is_delete' => 0, 'scene' => Integral::$cxIntegralSceneUserIntegralWallet, 'cx_mch_id' => 0]);
}
public static function getGender($gender)
{
$labels = self::genderLabels();
return isset($labels[$gender]) ? $labels[$gender] : "未知";
}
public static function genderLabels()
{
return [
'0' => '未知',
'1' => '男',
'2' => '女',
'3' => '保密'
];
}
public static function getStatus($status)
{
$labels = self::statusLabels();
return isset($labels[$status]) ? $labels[$status] : "未知";
}
public static function statusLabels()
{
return [
'0' => '正常',
'1' => '封禁',
'2' => '挂起',
'3' => '注销',
];
}
public static function lastLogin($user_id, $is_pass = 1, $err_msg = null, $cx_mch_id = 0)
{
return log\UserLoginLog::logger($user_id, $is_pass, $err_msg, $cx_mch_id);
}
public static function typeLabels()
{
return [
'0' => '普通用户',
'1' => '管理员',
'2' => '员工',
];
}
public static function getType($type)
{
$labels = self::typeLabels();
return isset($labels[$type]) ? $labels[$type] : "未知";
}
//生成一个用户名
public static function generateUsername($retry = 3, $prefix = "U", $len = 6)
{
$cache_key = "u_g_u";
$cache_val = FlashStorage::getCache($cache_key);
if ($cache_val !== false) {
sleep(1);
$retry -= 1;
return $retry > 0 ? self::generateUsername($retry, $prefix) : null;
}
FlashStorage::setCache($cache_key, $cache_key);
$username = null;
while (true) {
$username = self::_generate($prefix, $len);
$exists = User::find()->where(['username' => $username])->exists();
if (!$exists) {
FlashStorage::deleteCache($cache_key);
break;
}
}
return $username;
}
//生成一个昵称
public static function generateNickname($retry = 3, $prefix = "HY_", $len = 8)
{
$cache_key = "u_g_ns";
$cache_val = FlashStorage::getCache($cache_key);
if ($cache_val !== false) {
sleep(1);
$retry -= 1;
return $retry > 0 ? self::generateNickname($retry, $prefix) : null;
}
FlashStorage::setCache($cache_key, $cache_key);
$nickname = null;
while (true) {
$nickname = self::_generate($prefix, $len);
$exists = User::find()->where(['nickname' => $nickname])->exists();
if (!$exists) {
FlashStorage::deleteCache($cache_key);
break;
}
}
return $nickname;
}
public static function _generate($prefix, $len)
{
$username = $prefix;
$chars = "qwertyuiopasdfghjklzxcvbnm1234567890MNBVCXZASDFGHJKLPIUIYTREWQ";
$max = strlen($chars) - 1;
for ($i = strlen($username); $i < $len; $i++) {
$start = mt_rand(0, $max);
$username .= $chars[$start];
}
//并发情况生成唯一username
$cache_key = "u_g_un_{$username}";
$cache_val = FlashStorage::getCache($cache_key);
if ($cache_val !== false) {
usleep(500);
return self::_generate($prefix, $len);
}
FlashStorage::setCache($cache_key, $cache_key, 60);
return $username;
}
/**
* 绑定状态
* @param object $user 用户
* @param array $data $data['data]
*/
public static function bindQuery($user, $data)
{
$data['data'] = isset($data['data']) ? $data['data'] : [];
//手机是否需要绑定
$data['data']['required_bind_phone'] = \Yii::$app->params['requiredBindMobilePhone'];
$data['data']['is_bind_phone'] = $user->isBindPhone;
//是否绑定第三方登录
$data['data']['required_bind_oauth_login'] = \Yii::$app->params['requiredOauthLogin'];
//微信小程序
$data['data']['is_bind_wxmp'] = $user->bindWxmp ? true : false;
$data['data']['user_id'] = $user->id;
// $data['data']['user_store_id'] = $user->store_id ? $user->store_id : 0;
$data['data']['user_store_id'] = $user->store_id ? $user->store_id : 1;
$data['data']['user_type'] = $user->type;
if(!in_array($user->type,[2,7,8])){
$data['data']['user_type'] = 0;
}
//门店人员身份 1-门店管理员 2-门店服务员 3-门店财务人员
if ($user->type == 2) {
$storeData = ApiHelper::findOneUserStoreId($user->id);
if(empty($storeData)){
$data['data']['store_type'] = 0;
$data['data']['store_id'] = 0;
$data['data']['user_type'] = 0;
}else{
$data['data']['store_type'] = $storeData['user_type'];
$data['data']['store_id'] = $storeData['store_id'];
}
}
return $data;
}
public function getPermissions()
{
$cx_mch_id = Model::getCxMchId();
$role_ids = $this->hasMany(RoleUser::className(), ['user_id' => 'id'])->where(['is_delete' => 0, 'cx_mch_id' => $cx_mch_id])->select('role_id')->column();
$list = RolePermission::find()
->where([
'cx_mch_id' => $cx_mch_id,
'role_id' => $role_ids,
'is_delete' => 0
])
->select('permissions')->column();
$permissions = [];
foreach ($list as $index => $item) {
$item = json_decode($item, true);
$permissions = array_merge($permissions, $item);
}
$permissions = array_unique($permissions);
return $permissions;
}
//头像处理
public static function resizeAvatar($filename, $max_width = 512, $max_height = 512)
{
$filename = trim($filename);
$filename = trim($filename, '/');
if (!file_exists($filename)) {
return Model::asReturnError("文件{$filename}不存在");
}
try {
$gumletImagic = new ImageResize($filename);
$gumletImagic->resizeToBestFit($max_width, $max_height);
$gumletImagic->save($filename);
} catch (ImageResizeException $ex) {
return Model::asReturnError($ex->getMessage());
}
return Model::asReturnSuccess('ok', ['dst_url' => "/{$filename}"]);
}
//门店
public function getStore()
{
// return $this->hasOne(Store::className(), ['user_id' => 'id'])->where(['is_delete' => 0]);
}
public function getStoreUser()
{
return $this->hasOne(StoreUser::className(), ['user_id' => 'id'])->where(['is_delete' => 0]);
}
/**
* 分销团队详情
* @param $id 当前用户id
* @return array
*/
public static function getDistrbutionTeam($id)
{
//直属下级
$down = User::find()
->select('id,username,nickname,avatar_url,mobile_phone,email,real_name,created_at')
->where(['is_delete' => 0])->andWhere(['parent_id' => $id])->asArray()->all();
$down_count = count($down);
foreach ($down as $index => &$item){
$item['down_count'] = User::find()->where(['is_delete' => 0])->andWhere(['parent_id' => $item['id']])->count();
}
return ['down' => $down,'down_count' => $down_count];
}
/**
* 分销-用户名、真实姓名、手机号搜索上级
* @param $mobile 关键字
*/
public static function getParentUser($content)
{
$mobile = EncryptHelper::encryptMobilePhone(trim($content));
$data = User::find()->select('id,nickname,avatar_url,mobile_phone')
->where(['is_delete' => 0])
->andWhere(['status' => 0])
->andWhere([
'OR',
['like','nickname',$content],
['like','mobile_phone',$mobile],
])
->asArray()->all();
return $data;
}
}