Files
hyperf_rbac_framework_serve…/README.md
2025-09-17 17:18:18 +08:00

282 lines
8.5 KiB
Markdown
Raw 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.
## 仓库
- [hyperf_rbac_framework_server_ctexthuang](https://gitee.com/ctexthuang/hyperf_rbac_framework_server_ctexthuang.git) - git远程仓库地址
## 特性
- **最新技术栈**:使用 PHP8.3/hyperf3.1/swoole5.1.4/phpredis 6.0.2 等后端前沿技术开发
## 文档
[文档地址 Github](https://hyperf.wiki/3.1/)
## 前序准备
- [php8.3](https://www.php.net/) 和 [git](https://git-scm.com/) - 项目开发环境
- [swoole](https://www.swoole.com/) - 熟悉 swoole 特性
- [php8.3](https://www.php.net/) - 熟悉 php 基础语法
- [hyperf](https://hyperf.wiki/3.1/) - 熟悉 `hyperf` 基本语法
## 安装和使用
- 安装 swoole 和 phpredis 扩展
```
自行搜索安装教程
```
- 获取代码
```bash
git clone https://gitee.com/ctexthuang/hyperf_rbac_framework_server_ctexthuang.git
```
- vendor
```bash
composer install
```
- 运行
```bash
cp .env.example .env
vim .env
php bin/hyperf.php start
```
- command 函数
```bash
#框架自有 php bin/hyperf.php + 以下
gen:amqp-consumer Create a new amqp consumer class
gen:amqp-producer Create a new amqp producer class
gen:aspect Create a new aspect class
gen:class Create a new class
gen:command Create a new command class
gen:constant Create a new constant class
gen:controller Create a new controller class
gen:job Create a new job class
gen:kafka-consumer Create a new kafka consumer class
gen:listener Create a new listener class
gen:middleware Create a new middleware class
gen:migration Generate a new migration file
gen:model Create new model classes.
gen:nats-consumer Create a new nats consumer class
gen:nsq-consumer Create a new nsq consumer class
gen:process Create a new process class
gen:repository Create a new repository class
gen:request Create a new form request class
gen:resource create a new resource
gen:seeder Create a new seeder class
gen:service Create a new service class
#新增命令
php bin/hyperf.php gen:service LoginService
php bin/hyperf.php gen:repository OssRepository
```
## Git 贡献提交规范
- `feat` 新功能
- `fix` 修补 bug
- `docs` 文档
- `style` 格式、样式(不影响代码运行的变动)
- `refactor` 重构(即不是新增功能,也不是修改 BUG 的代码)
- `perf` 优化相关,比如提升性能、体验
- `test` 添加测试
- `build` 编译相关的修改,对项目构建或者依赖的改动
- `ci` 持续集成修改
- `chore` 构建过程或辅助工具的变动
- `revert` 回滚到上一个版本
- `workflow` 工作流改进
- `mod` 不确定分类的修改
- `wip` 开发中
- `types` 类型
## 日志(合理安排)
| 分组名称 | 用途 | 日志级别 | 保留天数 | 备注 |
|---------|---------|------------|------|----------|
| app | 应用业务日志 | DEBUG/INFO | 7 | 主要业务逻辑日志 |
| error | 错误日志 | ERROR | 30 | 只记录错误 |
| cache | CACHE日志 | DEBUG | 3 | 开发调试用 |
| request | 请求访问日志 | INFO | 15 | 记录所有请求 |
| cron | 定时任务日志 | INFO | 30 | 定时任务执行记录 |
| payment | 支付相关日志 | INFO | 90 | 重要财务数据 |
| audit | 审计日志 | INFO | 365 | 重要操作记录 |\
```php
//注入这个类
use App\Lib\Log\Logger;
$this->logger->cache()->error(...),
```
## 缓存
```php
//注入这个类
use App\Cache\Redis\RedisCache
$this->redis->with($poolName)->exists($key)
//$poolName 配置在 config/autoload/redis.php 在 default下面追加即可 看官网
//lua调用涉及多文件请看示例
$this->redis->with($poolName ?? 'default')->lua(RateLimit::class)->check($argument);
//lua()里面是App\Cache\Redis\Lua\*文件 后面跟的方法是 该文件的方法
//我做了返回类型补全 可以直接IDE跳转查看参数
```
## tips
1.AdminService类必须继承BaseAdminService
```php
//例子 app/Service/Admin/AdminUser/UserService
class UserService extends \App\Service\Admin\BaseAdminService {
}
//由于在 app/Controller/Admin/AdminUserController 中 service 是 注解注入的 所以 BaseAdminService只会实例化一次单例
class AdminUserController extends AbstractController
{
/**
* @var UserService
*/
#[Inject]
protected UserService $service;
/**
* @return array
*/
#[RequestMapping(path: "getInfo", methods: "GET")]
public function getInfo(): array
{
return $this->service->handle();
}
}
//所以在service中获取上下文的数据必须重置获取而不能存入BaseService属性中拿取
//假设在 Api目录中写 BaseApiService请务必注意
class UserService extends \App\Service\Admin\BaseAdminService {
/**
* @param string $name
* @return \current_admin_id|mixed
*/
public function __get(string $name)
{
if ($name === 'adminId') return Context::get('current_admin_id',0);
if (!property_exists($this, $name)) throw new ErrException('属性未定义');
return $this->$name;
}
}
class UserService extends BaseAdminService{
public function handle()
{
return $this->adminId;
}
}
// 或者在controller中实例化去调用
class AdminUserController extends AbstractController
{
/**
* @return array
*/
#[RequestMapping(path: "getInfo", methods: "GET")]
public function getInfo(): array
{
return (new UserService)->handle();
}
}
```
2.controller必须增加ResponseFormat注解
```php
//示例 : app/Controller/Admin/AdminUserController
#[Controller(prefix: "admin/adminUser")]
#[ResponseFormat('admin')]
#[Middleware(middleware: AdminTokenMiddleware::class, priority: 100)]
#[Middleware(middleware: PermissionMiddleware::class, priority: 99)]
class AdminUserController extends \App\Controller\AbstractController{
}
//因为在涉及到公有抛出 ErrException或者 验证器抛出 的时候 会根据不同的注解 返回不同的 Return
class BaseErrExceptionHandler extends ExceptionHandler{
public function handle()
{
// 从注解获取响应格式(优先于路径解析)
$format = $this->request->getAttribute('response_format') ?? $this->repairResponseFormatByPath();
// 动态选择策略
$returnClass = match ($format) {
'admin', 'common' => AdminReturn::class,
'api' => ApiReturn::class,
default => null,
};
}
}
// 通过切面存入
class ResponseFormatAspect extends AbstractAspect
{
// 获取注解定义的格式
$annotation = $proceedingJoinPoint->getAnnotationMetadata()->class[ResponseFormat::class]
?? $proceedingJoinPoint->getAnnotationMetadata()->method[ResponseFormat::class] ?? null;
if ($annotation) {
// 将注解格式存入请求属性(覆盖中间件的默认值)
$request = $proceedingJoinPoint->arguments['request'] ?? null;
if ($request instanceof Request) {
$request->withAttribute('response_format', $annotation->format);
}
}
}
```
3.token的使用要分模块
```php
//示例 app/Service/Admin/Login/LoginService
use App\Service\BaseTokenService $tokenService
class LoginService extends \App\Service\Admin\BaseAdminService{
public function handle()
{
$jwtHandle = $this->tokenService->setJwt('admin')->getJwt();
return $this->adminReturn->success('success',[
'access_token' => $jwtHandle->builderAccessToken((string) $adminInfo->id)->toString(),
'refresh_token' => $jwtHandle->builderRefreshToken((string) $adminInfo->id)->toString(),
'expire_at' => (int) $jwtHandle->getConfig('ttl', 0),
]);
}
}
//setJwt函数里面类似$poolName 设置在 config/autoload/jwt.php 未设置属性可复用 default 设置
```
4.引入 Repository层架构 解放 model层压力 model 只管理数据模型和关联
```php
//详细请看app/Common/Repository 文件下的文件 示例 app/Service/Admin/Login/LoginService
class LoginService extends \App\Service\Admin\BaseAdminService{
/**
* 需要提前注入
* @var AdminUserRepository
*/
#[Inject]
protected AdminUserRepository $userRepository;
public function handle()
{
$adminInfo = $this->userRepository->findByUserName((string)$this->request->input('username'));
}
}
```
5.公用类都在 app/Common 下面 包括 `Interface``Macros``Repository``Trait`
6.后台权限注解 #[Permission] 和 #[PermissionMiddleware]