feat : login first

This commit is contained in:
2025-09-26 17:59:26 +08:00
parent 5890122a37
commit 7d09a6028a
7 changed files with 236 additions and 0 deletions

View File

@@ -0,0 +1,16 @@
<?php
/**
* This service file is part of item.
*
* @author ctexthuang
* @contact ctexthuang@qq.com
*/
declare(strict_types=1);
namespace App\Service\Api;
abstract class BaseApiService
{
abstract public function handle();
}

View File

@@ -0,0 +1,47 @@
<?php
/**
* This service file is part of item.
*
* @author ctexthuang
* @contact ctexthuang@qq.com
*/
declare(strict_types=1);
namespace App\Service\Api\Login;
use App\Common\Interface\LoginInterface;
use App\Lib\Log\Logger;
use Hyperf\Di\Annotation\Inject;
abstract class AbstractLoginService implements LoginInterface
{
/**
* @var Logger
*/
#[Inject]
protected Logger $logger;
/**
* @param string $identifier
* @return void
*/
protected function logAttempt(string $identifier): void
{
$this->logger->request()->info(
sprintf('[%s] Login Attempt by %s',
static::class,
$identifier
)
);
}
/**
* @param array $data
* @return bool
*/
protected function validateCredentials(array $data): bool
{
return !empty($data);
}
}

View File

@@ -0,0 +1,50 @@
<?php
/**
* This service file is part of item.
*
* @author ctexthuang
* @contact ctexthuang@qq.com
*/
declare(strict_types=1);
namespace App\Service\Api\Login;
use App\Exception\ErrException;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface;
use Psr\Container\NotFoundExceptionInterface;
class LoginFactory
{
/**
* 策略映射 对应 request type
*/
private const array HANDLER_MAP = [
'password' => PasswordLoginService::class
];
/**
* @param ContainerInterface $container
*/
public function __construct(
private readonly ContainerInterface $container
) {}
/**
* @param string $type
* @return PasswordLoginService
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function get(string $type):
PasswordLoginService
{
$handlerClass = self::HANDLER_MAP[$type] ?? null;
return match (true) {
$handlerClass !== null => $this->container->get($handlerClass),
default => throw new ErrException('类不存在')
};
}
}

View File

@@ -0,0 +1,43 @@
<?php
/**
* This service file is part of item.
*
* @author ctexthuang
* @contact ctexthuang@qq.com
*/
declare(strict_types=1);
namespace App\Service\Api\Login;
use App\Service\Api\BaseApiService;
use Hyperf\Di\Annotation\Inject;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class LoginService extends BaseApiService
{
/**
* @var LoginFactory
*/
#[Inject]
protected LoginFactory $loginFactory;
/**
* @return string[]
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function handle(): array
{
try {
$type = '1';
$username= '1';
$password = '1';
$res = $this->loginFactory->get($type)->authenticate($username, $password);
return ['success'];
} catch (\Exception $e) {
return ['error'];
}
}
}

View File

@@ -0,0 +1,46 @@
<?php
/**
* This service file is part of item.
*
* @author ctexthuang
* @contact ctexthuang@qq.com
*/
declare(strict_types=1);
namespace App\Service\Api\Login;
use App\Common\Interface\LoginInterface;
use App\Exception\ErrException;
class PasswordLoginService extends AbstractLoginService implements LoginInterface
{
/**
* @param string $username
* @param string $password
* @return string[]
*/
public function authenticate(string $username, string $password): array
{
if (!$this->validateCredentials([
'username' => $username,
'password' => $password,
])) throw new ErrException('error');
$this->logAttempt($username);
//
return [
'code' => 'success'
];
}
/**
* @param string $type
* @return bool
*/
public function supports(string $type): bool
{
return $type === 'password';
}
}