TimestampBehavior::class ], 'treePath' => [ 'class' => ClosureTableBehavior::class, 'treePathModelClass' => UserTreePath::class, 'ownerParentIdAttribute' => 'parent_id', ], 'oldTreePath' => [ 'class' => OldClosureTableBehavior::class, 'treePathModelClass' => OldUserTreePath::class, 'ownerParentIdAttribute' => 'old_parent_id', ] ]; } //会员到期时间格式 //user_level_expires_ext:[['level' => 1, 'expires_in' => 到期时间戳], ['level' => 2, 'expires_in' => 到期时间戳]] public function rules() { return [ [['id', 'platform', 'type', 'is_delete', 'store_id', 'is_distributor', 'parent_id', 'old_parent_id', 'time', 'is_clerk', 'we7_uid', 'shop_id', 'level', 'is_delivery', 'delivery_office', 'is_saas_clerk','is_admin', 'is_holder'], 'integer'], [['total_price', 'price', 'money', 'integral', 'total_integral','free_money','total_free_money', 'user_level_expires','global_money_total','global_money'], 'number'], [['avatar_url', 'binding', 'alipay_open_id', 'bytedance_open_id', 'user_level_expires_ext'], 'string'], [['username', 'password', 'auth_key', 'access_token', 'wechat_open_id', 'wechat_union_id', 'nickname', 'contact_way', 'comments', 'wechat_app_open_id', 'remark_name', 'ali_openId'], 'string', 'max' => 255], [['access_token', 'binding', 'user_remark'], 'string', 'max' => 60], [['username', 'access_token'], 'required'], [['access_token', 'create_at', 'updated_at', 'adapay_user_huifu_id'], 'safe'], [['money_month', 'money_month_used'], 'safe'], ]; } public function attributeLabels() { return [ 'id' => 'ID', 'type' => '用户类型:0=管理员,1=普通用户', 'username' => 'Username', 'password' => 'Password', 'auth_key' => 'Auth Key', 'access_token' => 'Access Token', 'is_delete' => 'Is Delete', 'wechat_open_id' => '微信openid', 'wechat_union_id' => '微信用户union id', 'nickname' => '昵称', 'avatar_url' => '头像url', 'store_id' => '商城id', 'mch_id' => '配送员绑定商户id', 'is_distributor' => '是否是分销商 0--不是 1--是 2--申请中', 'parent_id' => '父级ID', 'time' => '成为分销商的时间', 'total_price' => '累计佣金', 'price' => '可提现佣金', 'is_clerk' => '是否是核销员 0--不是 1--是', 'we7_uid' => '微擎账户id', 'shop_id' => 'Shop ID', 'level' => '会员等级', 'integral' => '用户当前积分', 'total_integral' => '用户总积分', 'coin' => '用户当前贡献积分', 'total_coin' => '用户总贡献积分', 'money' => '余额', 'contact_way' => '联系方式', 'comments' => '备注', 'binding' => '授权手机号', 'wechat_platform_open_id' => '微信公众号openid', 'platform' => '小程序平台 微信:wx,支付宝:my(0、微信小程序,1、微信公众号2、APP端)', 'blacklist' => '黑名单 0.否 | 1.是', 'parent_user_id' => '可能成为上级的ID', 'appcid' => 'app唯一标识', 'is_admin' => '是否为手机端管理员', 'is_delivery'=>'是否是配送员 0--不是 1--是', 'delivery_office'=>'骑手是否在线(0、在线,1离线)', 'alipay_open_id' => '支付宝user_id', 'is_saas_clerk' => '是否为saas版核销员', 'created_at' => '创建时间', 'updated_at' => '更新时间', 'wechat_app_open_id' => '微信app端openid', 'old_parent_id' => '旧父级ID', 'user_remark' => '用户备注', 'remark_name' => '备注名', 'is_student' => '是否通过学生认证:0=否;1=是;', 'ali_openId' => '支付宝新openid', 'user_level_expires_ext' => '用户等级到期时间备注', 'user_level_expires' => '用户等级到期时间' ]; } public function beforeSave($insert) { // 创建用户自动赋值access_token if (parent::beforeSave($insert)) { if ($this->isNewRecord) { $this->access_token = \Yii::$app->security->generateRandomString(); } return true; } return false; } public function afterSave($insert, $changedAttributes) { parent::afterSave($insert, $changedAttributes); if ($insert && ($this->type == 1) && ($this->yinbaoSync == 0)) { (new PospalForm(['store_id' => $this->store_id]))->afterUserSave($this); } if($insert && $this->alipay_open_id){ UserCoupon::updateAll(['user_id' => $this->id], ['alipay_open_id' => $this->alipay_open_id]); } $changeIntegral = isset($changedAttributes['integral']) && ($this->integral != $changedAttributes['integral']); $changeMoney = isset($changedAttributes['money']) && ($this->money != $changedAttributes['money']); if(!$insert && ($changeIntegral || $changeMoney)){ \Yii::error([__METHOD__, $insert, $changedAttributes]); (new \app\modules\admin\models\alipay\Card(['store_id' => $this->store_id]))->cardUpdateByOpenid($this->alipay_open_id); } if($insert){ (new \app\utils\OrderUtil())->userAutoBecomeShare($this->id); // 赠送优惠券 \app\utils\AutoSendCoupon::send($this->id, CouponAutoSend::EVENT_NEWUSER, $this->store_id, 0, CouponAutoSend::EXT_REG); // 自动注册成为股东 $share_level_list = ShareHolderLevel::find()->where([ 'store_id' => $this->store_id, 'is_delete' => 0])->all(); // 查找是否有设置消费金额为0的等级条件 $currentLevel = null; foreach ($share_level_list as $k => $v) { $share_level_list_condition = json_decode($v->condition, true); if (!isset($share_level_list_condition['self'])) { continue; } $shareholder = $share_level_list_condition['self']; if ($shareholder['is_open'] && $shareholder['value']['price'] === '0') { $currentLevel = $v; break; } } if ($currentLevel) { $saas_user = SaasUser::findOne(['mobile' => $this->binding]); $shareHolderModel = new ShareHolder(); $shareHolderModel->level_id = $currentLevel->id; $shareHolderModel->store_id = $this->store_id; $shareHolderModel->user_id = $this->id; $shareHolderModel->name = $saas_user->name; $shareHolderModel->address = ''; $shareHolderModel->mobile = $saas_user->mobile; $shareHolderModel->province = 0; $shareHolderModel->city = 0; $shareHolderModel->district = 0; $shareHolderModel->province_name = ''; $shareHolderModel->city_name = ''; $shareHolderModel->district_name = ''; $shareHolderModel->status = 1; $shareHolderModel->audit_time = time(); if ($shareHolderModel->save()) { // BonusPool::checkChildHolderUpdateLevel($this->id, $currentLevel->id); BonusPool::ShareHolderLevelJob($shareHolderModel->store_id, 0, $shareHolderModel->user_id); if ((int)$currentLevel->member_level > (int)$this->level) { $this->level = $currentLevel->member_level; } $this->is_holder = 1; $this->save(); } } } if ($this->parent_id > 0 && !cache_lock(['ShareLevelJob', $this->store_id, $this->parent_id], 30)) { \queue_push(new \app\jobs\ShareLevelJob(['store_id' => $this->store_id, 'user_id' => $this->parent_id]), 30, 1); } if (isset($changedAttributes['level'])) { $user = User::findOne($this->id); $level = Level::findOne(['level' => $this->level, 'store_id' => $this->store_id, 'is_delete' => 0]); $result = self::handleUserLevelExpires($level, $user); $user->user_level_expires_ext = json_encode($result['user_level_expires_ext'], JSON_UNESCAPED_UNICODE); $user->user_level_expires = $result['expires_in']; $user->save(); } } public static function find(): UserQuery { return new UserQuery(get_called_class()); } public static function findOld(): OldUserQuery { return new OldUserQuery(get_called_class()); } /** * @return ActiveQuery */ public function getTreePathOwner(): ActiveQuery { return $this->hasOne(UserTreePath::class, ['parent_id' => 'id', 'child_id' => 'id']); } /** * @return ActiveQuery */ public function getOldTreePathOwner(): ActiveQuery { return $this->hasOne(OldUserTreePath::class, ['parent_id' => 'id', 'child_id' => 'id']); } /** * @return ActiveQuery */ public function getTreePathsChild(): ActiveQuery { return $this->hasMany(UserTreePath::class, ['child_id' => 'id']); } /** * @return ActiveQuery */ public function getOldTreePathsChild(): ActiveQuery { return $this->hasMany(OldUserTreePath::class, ['child_id' => 'id']); } /** * @return ActiveQuery */ public function getTreePathsNearestParent(): ActiveQuery { return $this->hasMany(UserTreePath::class, ['nearest_parent_id' => 'id']); } /** * @return ActiveQuery */ public function getOldTreePathsNearestParent(): ActiveQuery { return $this->hasMany(OldUserTreePath::class, ['nearest_parent_id' => 'id']); } /** * @return ActiveQuery */ public function getTreePathsParent(): ActiveQuery { return $this->hasMany(UserTreePath::class, ['parent_id' => 'id']); } /** * @return ActiveQuery */ public function getOldTreePathsParent(): ActiveQuery { return $this->hasMany(OldUserTreePath::class, ['parent_id' => 'id']); } /** * {@inheritdoc} */ public static function findIdentity($id) { return static::findOne($id); } /** * {@inheritdoc} */ public static function findIdentityByAccessToken($token, $type = null) { return static::findOne(['access_token' => $token]); } /** * {@inheritdoc} */ public function getId() { return $this->id; } /** * {@inheritdoc} */ public function getAuthKey() { } /** * {@inheritdoc} */ public function validateAuthKey($authKey) { } /** * 刷新token * @return bool */ public function refreshToken() { $this->access_token = \Yii::$app->security->generateRandomString(); return $this->save(); } public static function handleUserLevelExpires($level, $user) { if (!$level || !$user) { return ['user_level_expires_ext' => [], 'expires_in' => 0]; } // 会员等级新增有效期时间 $expires_in = 0; //购买会员有限期 0为永久 if ($level->expires_in > 0) { $expires_in = strtotime('+' . $level->expires_in . ' day'); if ($level->expires_type) { $expires_in = strtotime('+' . $level->expires_in . ' year'); } } $user_level_expires_ext = [['level' => $user->level, 'expires_in' => $expires_in]]; if ($user->user_level_expires_ext) { $user_level_expires_ext = json_decode($user->user_level_expires_ext, true); //给新的加上 排序(按等级) 并且 去除已经过期的 作为新的一个json array_push($user_level_expires_ext, ['level' => $user->level, 'expires_in' => $expires_in]); //排序 $last_names = array_column($user_level_expires_ext, 'level'); array_multisort($last_names, SORT_DESC, $user_level_expires_ext); //去除已经过期的 foreach ($user_level_expires_ext as $user_level_index => $user_level_item) { // 去除已经过期的 if ($user_level_item['expires_in'] > 0 && $user_level_item['expires_in'] <= time()) { unset($user_level_expires_ext[$user_level_index]); } } $user_level_expires_ext = array_values($user_level_expires_ext); } return ['user_level_expires_ext' => $user_level_expires_ext, 'expires_in' => $expires_in]; } public static function findUserByStore($store_id,$mobile,$nick_name,$avatar){ $user = User::find()->where(['store_id'=>$store_id,'binding'=>$mobile])->one(); if (!empty($user)){ return $user->id; } $user = new User(); $user->type = User::USER_TYPE_NORMAL; $user->binding = $mobile; $user->nickname = $nick_name; $user->avatar_url = $avatar; $user->username = \Yii::$app->security->generateRandomString(); $user->password = \Yii::$app->security->generatePasswordHash(\Yii::$app->security->generateRandomString(), 5); $user->auth_key = \Yii::$app->security->generateRandomString(); $user->access_token = \Yii::$app->security->generateRandomString(); $user->is_delete = User::USER_NOT_DELETE; $user->store_id = $store_id; $user->parent_id = 0; $user->old_parent_id = 0; $user->platform = User::USER_FROM_OPERATOR_BACK; if (!$user->save()) { return 0; } return $user->id; } }