Skip to content

Commit cda7b82

Browse files
committed
update5.3.0
- 增加 ignored_methods 配置参数,用于过滤不需要解析的方法。 - 增加请求响应状态码显示功能,用法请查看配置参数`responses_status`。 - 增加 apidoc-export 导出插件,目前支持导出 swagger.json
1 parent 45ba932 commit cda7b82

File tree

15 files changed

+193
-29
lines changed

15 files changed

+193
-29
lines changed

README.md

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,25 +39,24 @@ Apidoc是一个通过解析注解生成Api接口文档的PHP composer扩展,
3939
- Markdown文档:支持.md文件的文档展示。
4040
- Json/TypeScript生成:文档自动生成接口的Json及TypeScript。
4141
- 代码生成器:配置+模板即可快速生成代码及数据表的创建,大大提高工作效率。
42-
42+
- 接口分享:支持自由指定应用/接口生成分享链接、导出swagger.json文件。
4343

4444
## 📌兼容
4545

4646
以下框架已内置兼容,可开箱即用
4747

48-
|框架|版本|
49-
|-|-|-|
50-
|ThinkPHP|5.1、6.x、8.x|
51-
|Laravel|8.x、9.x、10.x|
52-
|Webman|1.x|
53-
|Hyperf|2.x、3.x|
48+
| 框架 | 版本 | 说明 |
49+
| -------- |--------| ------------------------------------ |
50+
| ThinkPHP | \>=5.1 | |
51+
| Webman | \>=1.x | |
52+
| Laravel | \>=8.x | 低于 Laravel8 版本未测试,可自行尝试 |
53+
| Hyperf | \>=2.x | |
5454

5555

5656
## 📖使用文档
5757

5858
[https://docs.apidoc.icu](https://docs.apidoc.icu/)
5959

60-
[https://hg-code.gitee.io/apidoc-php/](https://hg-code.gitee.io/apidoc-php/)
6160

6261
## 🏆支持我们
6362

src/Controller.php

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use hg\apidoc\utils\Lang;
1616
use hg\apidoc\utils\Request;
1717
use hg\apidoc\exception\ErrorException;
18+
use hg\apidoc\export\ExportSwagger;
1819

1920
class Controller
2021
{
@@ -448,4 +449,26 @@ public function handleApiShareAction()
448449
return Helper::showJson(0, "", $res);
449450
}
450451

451-
}
452+
/**
453+
* 导出swagger.json
454+
* @return array
455+
*/
456+
public function exportSwagger()
457+
{
458+
459+
$this->init(true);
460+
$config = $this->config;
461+
$params = $this->requestParams;
462+
if($config['export_config']['enable'] === false){
463+
throw new ErrorException('export config not enable');
464+
}
465+
if (empty($params['key'])) {
466+
throw new ErrorException('field not found', ['field' => 'key']);
467+
}
468+
$searchData = (new ApiShare())->getShareData($config,$params['key']);
469+
470+
$res = (new ExportSwagger($config['export_config']))->exportJson($config,$searchData);
471+
return Helper::showJson(0, "", $res);
472+
}
473+
474+
}

src/annotation/ResponseStatus.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
namespace hg\apidoc\annotation;
4+
5+
use Attribute;
6+
use Doctrine\Common\Annotations\Annotation;
7+
use hg\apidoc\utils\AbstractAnnotation;
8+
9+
/**
10+
* 成功响应体
11+
* @package hg\apidoc\annotation
12+
* @Annotation
13+
* @Target({"METHOD","ANNOTATION"})
14+
*/
15+
#[Attribute(Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
16+
class ResponseStatus extends AbstractAnnotation
17+
{
18+
19+
/**
20+
* 状态码
21+
* @var number
22+
*/
23+
public $name;
24+
25+
/**
26+
* 描述
27+
* @var string
28+
*/
29+
public $desc;
30+
31+
public $contentType;
32+
33+
/**
34+
* @param string $name 状态码
35+
* @param string $desc 描述
36+
* @param string $contentType 内容类型
37+
*/
38+
public function __construct(
39+
$name = '',
40+
string $desc = '',
41+
string $contentType = '',
42+
...$attrs
43+
)
44+
{
45+
parent::__construct(...func_get_args());
46+
}
47+
48+
}

src/config.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,18 @@
7474
['name'=>'message','desc'=>'业务信息','type'=>'string','require'=>1],
7575
]
7676
],
77+
// (选配)全局响应状态码
78+
'responses_status'=>[
79+
[
80+
'name'=>'200',
81+
'desc'=>'请求成功'
82+
],
83+
[
84+
'name'=>'401',
85+
'desc'=>'登录令牌无效',
86+
'contentType'=>''
87+
],
88+
],
7789
// (选配)apidoc路由前缀,默认apidoc
7890
'route_prefix'=>'/apidoc',
7991
//(选配)默认作者
@@ -88,6 +100,9 @@
88100
*/
89101
'ignored_annitation'=>[],
90102

103+
// (选配)解析时忽略的方法
104+
'ignored_methods'=>[],
105+
91106
// (选配)数据库配置
92107
'database'=>[],
93108
// (选配)Markdown文档

src/config/plugin/hg/apidoc/app.php

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,18 @@
7575
['name'=>'message','desc'=>'业务信息','type'=>'string','require'=>1],
7676
]
7777
],
78+
// (选配)全局响应状态码
79+
'responses_status'=>[
80+
[
81+
'name'=>'200',
82+
'desc'=>'请求成功'
83+
],
84+
[
85+
'name'=>'401',
86+
'desc'=>'登录令牌无效',
87+
'contentType'=>''
88+
],
89+
],
7890
//(选配)默认作者
7991
'default_author'=>'',
8092
//(选配)默认请求类型
@@ -87,11 +99,14 @@
8799
*/
88100
'ignored_annitation'=>[],
89101

102+
// (选配)解析时忽略的方法
103+
'ignored_methods'=>[],
104+
90105
// (选配)数据库配置
91106
'database'=>[],
92107
// (选配)Markdown文档
93108
'docs' => [],
94109
// (选配)接口生成器配置 注意:是一个二维数组
95110
'generator' =>[]
96111
]
97-
];
112+
];

src/exception/ErrorException.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class ErrorException extends HttpException
3737
'datatable create error' => ['status'=>412,'code' => 5006, 'msg' => '数据表[${table}]创建失败,error:${message},sql:${sql}'],
3838
'field not found' => ['status'=>412,'code' => 5006, 'msg' => '${field}字段不能为空'],
3939
'share not exists' => ['status'=>404,'code' => 4004, 'msg' => '该分享不存在'],
40+
'export config not enable' => ['status'=>404,'code' => 4004, 'msg' => '导出配置未启用'],
4041
];
4142

4243
public function __construct(string $exceptionCode, array $data = [])
@@ -61,4 +62,4 @@ public function getException($exceptionCode)
6162
return null;
6263
}
6364

64-
}
65+
}

src/middleware/HyperfMiddleware.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,14 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface
3434
static function getApidocConfig()
3535
{
3636
$config = config("apidoc");
37+
$exportConfig = config("apidoc-export");
3738
if (!(!empty($config['auto_url']) && !empty($config['auto_url']['filter_keys']))){
3839
$config['auto_url']['filter_keys'] = ['App','Controller'];
3940
}
4041
$config['app_frame'] = "hyperf";
42+
if (!empty($exportConfig)){
43+
$config['export_config'] = $exportConfig;
44+
}
4145
return $config;
4246
}
4347

src/middleware/WebmanMiddleware.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,14 @@ public function process(Request $request, callable $handler) : Response
3838
static function getApidocConfig()
3939
{
4040
$config = config('plugin.hg.apidoc.app.apidoc');
41+
$exportConfig = config('plugin.hg.apidoc-export.app');
4142
if (!(!empty($config['auto_url']) && !empty($config['auto_url']['filter_keys']))){
4243
$config['auto_url']['filter_keys'] = ['app','controller'];
4344
}
4445
$config['app_frame'] = "webman";
46+
if (!empty($exportConfig)){
47+
$config['export_config'] = $exportConfig;
48+
}
4549
return $config;
4650
}
4751

src/parses/ParseApiDetail.php

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -61,17 +61,25 @@ public function parseApiMethod($refClass,$refMethod,$currentAppData = null){
6161

6262
}
6363
if (empty($refMethod->name)) {
64-
return [];
64+
return false;
65+
}
66+
if(!empty($config['ignored_methods']) && in_array($refMethod->name, $config['ignored_methods'])){
67+
return false;
6568
}
6669
$classTextAnnotations = ParseAnnotation::parseTextAnnotation($refClass);
6770
$classAnnotations = (new ParseAnnotation($config))->getClassAnnotation($refClass);
6871

6972
$textAnnotations = ParseAnnotation::parseTextAnnotation($refMethod);
7073
// 标注不解析的方法
7174
if (in_array("NotParse", $textAnnotations)) {
72-
return [];
75+
return false;
7376
}
7477
$methodAnnotations = $this->getMethodAnnotation($refMethod);
78+
79+
// 标注不解析的方法
80+
if (isset($methodAnnotations['notParse']) || empty($methodAnnotations)) {
81+
return false;
82+
}
7583
$methodAnnotations = self::handleApiBaseInfo($methodAnnotations,$refClass->name,$refMethod->name,$textAnnotations,$config);
7684
// 是否开启debug
7785
if (
@@ -137,6 +145,25 @@ public function parseApiMethod($refClass,$refMethod,$currentAppData = null){
137145
$methodAnnotations['param'] = $this->mergeGlobalOrAppParams($params,'body');
138146
}
139147

148+
// 合并全局响应状态码
149+
if (
150+
!in_array("NotResponsesStatus", $textAnnotations) &&
151+
!isset($methodAnnotations['notResponsesStatus'])
152+
)
153+
{
154+
$globalResponseStatus = [];
155+
if (!empty($config['responses_status'])){
156+
$globalResponseStatus = $config['responses_status'];
157+
}else if(!empty($this->currentApp['responses_status'])){
158+
$globalResponseStatus = $this->currentApp['responses_status'];
159+
}
160+
if (count($globalResponseStatus)>0){
161+
$responseStatus = !empty($methodAnnotations['responseStatus'])?$methodAnnotations['responseStatus']:[];
162+
$methodAnnotations['responseStatus'] = Helper::arrayMergeAndUnique("name", $globalResponseStatus,$responseStatus);
163+
}
164+
165+
}
166+
140167
//添加成功响应体
141168
$methodAnnotations['responseSuccess'] = $this->handleApiResponseSuccess($methodAnnotations,$textAnnotations);
142169
//添加异常响应体
@@ -195,7 +222,7 @@ protected function getMethodAnnotation($refMethod,$refField=""){
195222
if (!empty($refField)){
196223
$handleFields = [$refField];
197224
}else{
198-
$handleFields = ["header","query","param","routeParam","returned","before","after","responseSuccess","responseError"];
225+
$handleFields = ["header","query","param","routeParam","returned","before","after","responseSuccess","responseError","responseStatus"];
199226
}
200227
foreach ($handleFields as $field) {
201228
if (!empty($annotations[$field])){
@@ -262,8 +289,8 @@ protected function handleApiResponseSuccess($methodAnnotations,$textAnnotations)
262289
$paramType='success';
263290
if (
264291
in_array("NotResponses", $textAnnotations) ||
265-
in_array("NotResponseSuccess", $textAnnotations) ||
266-
isset($methodAnnotations['notResponses']) ||
292+
in_array("NotResponseSuccess", $textAnnotations) ||
293+
isset($methodAnnotations['notResponses']) ||
267294
isset($methodAnnotations['notResponseSuccess'])
268295
) {
269296
// 注解了不使用全局响应
@@ -325,8 +352,8 @@ protected function handleApiResponseError($methodAnnotations,$textAnnotations){
325352
$mergeParams = [];
326353
if (
327354
in_array("NotResponses", $textAnnotations) ||
328-
in_array("NotResponseError", $textAnnotations) ||
329-
isset($methodAnnotations['notResponses']) ||
355+
in_array("NotResponseError", $textAnnotations) ||
356+
isset($methodAnnotations['notResponses']) ||
330357
isset($methodAnnotations['notResponseError'])
331358
) {
332359
// 注解了不使用全局响应
@@ -363,6 +390,10 @@ protected function handleApiResponseError($methodAnnotations,$textAnnotations){
363390

364391

365392
public static function handleApiBaseInfo($methodInfo,$className,$methodName,$textAnnotations,$config){
393+
// 是否存在apidoc的注解
394+
if (empty($methodInfo)) {
395+
return false;
396+
}
366397
// 无标题,且有文本注释
367398
if (empty($methodInfo['title']) && !empty($textAnnotations) && count($textAnnotations) > 0) {
368399
$methodInfo['title'] = Lang::getLang($textAnnotations[0]);
@@ -380,8 +411,8 @@ public static function handleApiBaseInfo($methodInfo,$className,$methodName,$tex
380411

381412
// 默认default_author
382413
if (
383-
empty($methodInfo['author']) &&
384-
!empty($config['default_author']) &&
414+
empty($methodInfo['author']) &&
415+
!empty($config['default_author']) &&
385416
!in_array("NotDefaultAuthor", $textAnnotations) &&
386417
!isset($methodInfo['notDefaultAuthor'])
387418
) {
@@ -668,8 +699,8 @@ public function handleRefData($annotation,$refParams, string $field): array
668699
// }
669700
return $refParams;
670701
}
671-
672-
702+
703+
673704

674705

675706

@@ -754,4 +785,4 @@ public static function filterParamsField(array $data, $fields, string $type = "f
754785

755786

756787

757-
}
788+
}

0 commit comments

Comments
 (0)