find(); } /** * 根据用户ID查找用户 * @param int $userid * @return Member|null */ public static function findByUserid(int $userid): ?Member { return self::where('userid', $userid)->find(); } /** * 验证密码 * 支持两种密码格式: * 1. 新格式: bcrypt hash (60字符, 以 $2y$ 开头) * 2. 旧格式: 双重MD5 (32字符) * * @param string $password 明文密码 * @return bool */ public function verifyPassword(string $password): bool { $hash = $this->password; // 新格式: bcrypt if (strlen($hash) === 60 && strpos($hash, '$2y$') === 0) { return password_verify($password, $hash); } // 旧格式: 双重MD5 (兼容原系统) $legacyHash = md5(md5($password)); return $legacyHash === $hash; } /** * 升级密码为 bcrypt 格式 * @param string $password 明文密码 * @return bool */ public function upgradePassword(string $password): bool { $this->password = password_hash($password, PASSWORD_DEFAULT); return $this->save(); } /** * 检查用户是否被禁用 * @return bool */ public function isDisabled(): bool { return $this->disabled == 1; } /** * 检查账号是否过期 * @return bool */ public function isExpired(): bool { if (empty($this->endtime)) { return false; } return $this->endtime < time(); } /** * 获取用户套餐信息 * @return array|null */ public function getProductInfo(): ?array { // 从主库获取套餐信息 $product = \think\facade\Db::connect('dbbiz') ->name('product_list') ->where('v_type', $this->v_type) ->find(); return $product; } /** * 获取代理商信息 * @return array|null */ public function getAgentInfo(): ?array { if (empty($this->formtypeid)) { return null; } return self::where('userid', $this->formtypeid)->find(); } /** * 记录登录日志 * @param bool $success * @param string $loginType * @return void */ public function logLogin(bool $success, string $loginType = 'password'): void { try { \think\facade\Db::connect('dbmember') ->name('member_login_log') ->insert([ 'userid' => $this->userid, 'ip' => request()->ip(), 'time' => time(), 'succeed' => $success ? 1 : 0, 'diqu' => '', 'login_type' => $loginType, 'adminid' => 0, 'v_type' => $this->v_type ?? 0, ]); } catch (\Exception $e) { // 日志记录失败不影响登录 } } }