文章目录
- <?phpdeclare(strict_types=1); /** * This file is part of hyperf-tt. * * @link https://github.com/zhaohao19941221/hyperf-tt * @document https://github.com/zhaohao19941221/hyperf-tt.git */ namespace AppCommand;use HyperfCommandAnnotationCommand; use HyperfCommandCommand as HyperfCommand; use HyperfDbConnectionDb; use PsrContainerContainerInterface; use SymfonyComponentConsoleInputInputArgument; use SymfonyComponentConsoleInputInputOption;/** * @Command */ class SwaggerCommand extends HyperfCommand { /** * @var ContainerInterface */ protected container;// 表注释对应 protectedswaggerTable;// 请求方式 protected swaggerMethod;// url路径 protectedswaggerPath;// 标签 protected swaggerTag;// 概要 protectedswaggerSummary;// 描述 protected swaggerDescription;// query格式数据 protectedswaggerQuery;// 请求 json 数据类型 protected swaggerRequestBody;// 响应 json 数据类型 protectedswaggerResponse;/** * 执行的命令行. * * @var string */ protected name = 'swagger:format';public function __construct(ContainerInterfacecontainer) { this->container =container; parent::__construct(); }public function configure() { parent::configure(); this->setHelp('示例:php bin/hyperf.php swagger:format Post '{"errcode":0,"errmsg":"success","data":{"token":"666"}}'');this->setDescription('swagger mode生成'); this->addArgument('method', InputArgument::OPTIONAL, '请求方式', 'Get');this->addArgument('response', InputArgument::OPTIONAL, '响应 json 数据类型'); this->addArgument('table', InputArgument::OPTIONAL, '自动填充数据表');this->addOption('path', 'P', InputOption::VALUE_OPTIONAL, 'url路径'); this->addOption('tag', 'T', InputOption::VALUE_OPTIONAL, '标签');this->addOption('summary', 'S', InputOption::VALUE_OPTIONAL, '概要'); this->addOption('description', 'D', InputOption::VALUE_OPTIONAL, '描述');this->addOption('query', 'Q', InputOption::VALUE_OPTIONAL, 'query格式数据'); this->addOption('request', 'R', InputOption::VALUE_OPTIONAL, '请求 json 数据类型'); }public function handle() {this->swaggerTable = this->input->getArgument('table');this->swaggerMethod = ucfirst(strtolower(this->input->getArgument('method')));this->swaggerPath = this->getSwaggerPath(this->input->getOption('path')); this->swaggerTag =this->getSwaggerTag(this->input->getOption('tag'));this->swaggerSummary = this->getSwaggerSummary(this->input->getOption('summary')); this->swaggerDescription =this->getSwaggerDescription(this->input->getOption('description'));this->swaggerQuery = this->getSwaggerParameter(this->input->getOption('query')); this->swaggerRequestBody =this->getSwaggerRequestBody(this->input->getOption('request'));this->swaggerResponse = this->getSwaggerResponse(this->input->getArgument('response')); echo this->getSwaggerModel(); }/** * 获取 swagger 结构. */ public function getSwaggerModel() {doc = PHP_EOL . PHP_EOL; header =this->swaggerPath . this->swaggerTag .this->swaggerSummary . this->swaggerDescription;header = trim(header, PHP_EOL);body = this->swaggerQuery .this->swaggerRequestBody . this->swaggerResponse;body = trim(body, PHP_EOL);doc .= <<<eof /** * @OA{this->swaggerMethod}( {header} * operationId="", * @OAParameter(name="Authorization", in="header", description="jwt签名", required=true, * @OASchema(type="string", default="Bearer {{Authorization}}") * ), {body} * ) */ eof;doc .= PHP_EOL . PHP_EOL; return doc; }/** * 获取路径数据. * @param null|stringpath 路径 */ public function getSwaggerPath(?string path): string {doc = <<<eof * path="{path}", eof;doc .= PHP_EOL; return doc; }/** * 获取标签数据. * @param null|stringtag 标签 */ public function getSwaggerTag(?string tag): string {doc = <<<eof * tags={"{tag}"}, eof;doc .= PHP_EOL; return doc; }/** * 获取概要数据. * @param null|stringsummary 概要 * @return string 概要格式数据 */ public function getSwaggerSummary(?string summary): string {doc = <<<eof * summary="{summary}", eof;doc .= PHP_EOL; return doc; }/** * 获取描述数据. * @param null|stringdescription 描述 * @return string 描述格式数据 */ public function getSwaggerDescription(?string description): string {doc = <<<eof * description="{description}", eof;doc .= PHP_EOL; return doc; }/** * query 参数拼接. */ public function getSwaggerParameter(?stringparameter): string { if (! parameter) { return <<<'eof' eof; } parse_str(parameter, output); if (!parameter) { return <<<'eof' eof; } doc = ''; foreach (output as k =>v) { type =this->gettype(v);doc .= <<<eof * @OAParameter(name="{k}", in="query", description="", * @OASchema(type="{type}", default="{v}") * ), eof;doc .= PHP_EOL; } return doc; }/** * 获取请求 JsonContent 数据. */ public function getSwaggerRequestBody(?stringrequestBody): string { if (! requestBody) { return <<<'eof' eof; }requestBody = this->constructSwaggerDoc(requestBody); doc = <<<eof * @OARequestBody(description="请求body", * @OAJsonContent(type="object", {requestBody} * ) * ), eof; doc .= PHP_EOL; returndoc; }/** * 获取响应 JsonContent 数据. * @param null|string response 响应json */ public function getSwaggerResponse(?stringresponse): string { comment =this->getColumnComment(this->swaggerTable);comment['errcode'] = '错误码'; comment['errmsg'] = '错误信息';comment['data'] = '返回数据'; if (! response) { return <<<eof * @OAResponse(response="200", description="响应信息返回", * @OAJsonContent(type="object", * @OAProperty(property="errcode", type="integer", description="{comment['errcode']}"), * @OAProperty(property="errmsg", type="string", description="{comment['errmsg']}"), * @OAProperty(property="data", type="object", description="{comment['data']}", * @OAProperty(property="example", type="string", description="例子", * ) * ) * ) eof; } response =this->constructSwaggerDoc(response,comment); return <<<eof * @OAResponse(response="200", description="响应信息返回", * @OAJsonContent(type="object", {response} * ) * ) eof; }/** * 检测是否为有序数据. * @param mixedarray * @return string array 有序数据 object 无序数组 */ public function checkIsArray(array): string { if (! is_array(array)) { return 'string'; } num = count(array); for (i = 0;i < num; ++i) { if (isset(array[i])) { continue; } return 'object'; } return 'array'; }/** * 构造 JsonContent 数据. * @param array|string data json格式字符串数据|数组数据 * @param arraycomment 注释 * @param string placeholder 占位空格数量 * @param stringpropertyType 数据格式 * @return string JsonContent格式数据 */ private function constructSwaggerDoc(data, arraycomment = [], string placeholder = '', stringpropertyType = 'Property'): string { if (! data) { return <<<'eof' eof; }data = is_array(data) ?data : json_decode(data, true);required = this->arrayToJsonObject(data); doc = ''; if (propertyType == 'Items') { doc .= <<<eof * {placeholder}@OAItems( eof; doc .= PHP_EOL;placeholder .= ' '; } doc .= <<<eof * {placeholder}required={required}, eof;doc .= PHP_EOL; foreach (data ask => v) {description = comment[k] ?? null; type =this->gettype(v); if (in_array(type, ['object', 'array'])) { if (isset(v[0]) || empty(v)) { if (isset(v[0]) && is_array(v[0])) { doc .= <<<eof * {placeholder}@OAProperty(property="{k}", type="array", description="{description}", eof; doc .= PHP_EOL;newPlaceholder = placeholder . ' ';doc .= this->constructSwaggerDoc(v[0], comment,newPlaceholder, 'Items'); } else { doc .= <<<eof * {placeholder}@OAProperty(property="{k}", type="array", description="{description}", * {placeholder}@OAItems() eof;doc .= PHP_EOL; } } else { doc .= <<<eof * {placeholder}@OAProperty(property="{k}", type="object", description="{description}", eof; doc .= PHP_EOL;newPlaceholder = placeholder . ' ';doc .= this->constructSwaggerDoc(v, comment,newPlaceholder); } if (isset(v[0]) || empty(v)) { doc .= <<<eof * {placeholder}), eof; } else { doc .= <<<eof * {placeholder}), eof; } doc .= PHP_EOL; } else {doc .= <<<eof * {placeholder}@OAProperty(property="{k}", type="{type}", description="{description}"), eof; doc .= PHP_EOL; } } if (propertyType == 'Items') { placeholder = substr(placeholder, 0, -4); doc .= <<<eof * {placeholder}), eof; doc .= PHP_EOL; } if (!placeholder) { doc = trim(doc, PHP_EOL); } return doc; }/** * 获取数据类型. * @paramvalue */ private function gettype(value): string {type = (string) gettype(value); switch (type) { case 'array': result =this->checkIsArray(value); break; case 'integer': case 'boolean': case 'string':result = type; break; default:result = 'string'; break; } return result; }/** * json数组格式转化为对象格式. * @param arrayarray 有序数组 */ private function arrayToJsonObject(array array): string {jsonObject = trim(json_encode(array_keys(array)), '['); return '{' . trim(jsonObject, ']') . '}'; }/** * 获取数据表字段描述. */ private function getColumnComment(?string tables): array { if (empty(tables)) { return []; }tablesList = explode(',',tables); if (! tablesList) { return []; }haveKey = []; list = []; foreach (tablesList as v) {sql = "SELECT COLUMN_NAME,column_comment FROM INFORMATION_SCHEMA.Columns WHERE table_name = '{v}'";comment = Db::select(sql); // 需要保持字段名唯一,唯一字段才会保留 foreach (comment as v) { // 判断 字段名 是否出现过 if (in_array(v['COLUMN_NAME'], haveKey)) { continue; } // 判断 字段名 是否存在,存在的情况需要移除,并加入到 haveKey 数组 if (isset(list[v['COLUMN_NAME']])) { unset(list[v['COLUMN_NAME']]); array_push(haveKey, v['COLUMN_NAME']); }list[v['COLUMN_NAME']] =v['column_comment']; } } return $list; } }
- php bin/hyperf.php swagger:format Post '{"errcode":0,"errmsg":"success","data":{"token":"666"}}'
<?php
declare(strict_types=1);
/**
* This file is part of hyperf-tt.
*
* @link https://github.com/zhaohao19941221/hyperf-tt
* @document https://github.com/zhaohao19941221/hyperf-tt.git
*/
namespace AppCommand;
use HyperfCommandAnnotationCommand;
use HyperfCommandCommand as HyperfCommand;
use HyperfDbConnectionDb;
use PsrContainerContainerInterface;
use SymfonyComponentConsoleInputInputArgument;
use SymfonyComponentConsoleInputInputOption;
/**
* @Command
*/
class SwaggerCommand extends HyperfCommand
{
/**
* @var ContainerInterface
*/
protected container;
// 表注释对应
protectedswaggerTable;
// 请求方式
protected swaggerMethod;
// url路径
protectedswaggerPath;
// 标签
protected swaggerTag;
// 概要
protectedswaggerSummary;
// 描述
protected swaggerDescription;
// query格式数据
protectedswaggerQuery;
// 请求 json 数据类型
protected swaggerRequestBody;
// 响应 json 数据类型
protectedswaggerResponse;
/**
* 执行的命令行.
*
* @var string
*/
protected name = 'swagger:format';
public function __construct(ContainerInterfacecontainer)
{
this->container =container;
parent::__construct();
}
public function configure()
{
parent::configure();
this->setHelp('示例:php bin/hyperf.php swagger:format Post '{"errcode":0,"errmsg":"success","data":{"token":"666"}}'');this->setDescription('swagger mode生成');
this->addArgument('method', InputArgument::OPTIONAL, '请求方式', 'Get');this->addArgument('response', InputArgument::OPTIONAL, '响应 json 数据类型');
this->addArgument('table', InputArgument::OPTIONAL, '自动填充数据表');this->addOption('path', 'P', InputOption::VALUE_OPTIONAL, 'url路径');
this->addOption('tag', 'T', InputOption::VALUE_OPTIONAL, '标签');this->addOption('summary', 'S', InputOption::VALUE_OPTIONAL, '概要');
this->addOption('description', 'D', InputOption::VALUE_OPTIONAL, '描述');this->addOption('query', 'Q', InputOption::VALUE_OPTIONAL, 'query格式数据');
this->addOption('request', 'R', InputOption::VALUE_OPTIONAL, '请求 json 数据类型');
}
public function handle()
{this->swaggerTable = this->input->getArgument('table');this->swaggerMethod = ucfirst(strtolower(this->input->getArgument('method')));this->swaggerPath = this->getSwaggerPath(this->input->getOption('path'));
this->swaggerTag =this->getSwaggerTag(this->input->getOption('tag'));this->swaggerSummary = this->getSwaggerSummary(this->input->getOption('summary'));
this->swaggerDescription =this->getSwaggerDescription(this->input->getOption('description'));this->swaggerQuery = this->getSwaggerParameter(this->input->getOption('query'));
this->swaggerRequestBody =this->getSwaggerRequestBody(this->input->getOption('request'));this->swaggerResponse = this->getSwaggerResponse(this->input->getArgument('response'));
echo this->getSwaggerModel();
}
/**
* 获取 swagger 结构.
*/
public function getSwaggerModel()
{doc = PHP_EOL . PHP_EOL;
header =this->swaggerPath . this->swaggerTag .this->swaggerSummary . this->swaggerDescription;header = trim(header, PHP_EOL);body = this->swaggerQuery .this->swaggerRequestBody . this->swaggerResponse;body = trim(body, PHP_EOL);doc .= <<<eof
/**
* @OA{this->swaggerMethod}(
{header}
* operationId="",
* @OAParameter(name="Authorization", in="header", description="jwt签名", required=true,
* @OASchema(type="string", default="Bearer {{Authorization}}")
* ),
{body}
* )
*/
eof;doc .= PHP_EOL . PHP_EOL;
return doc;
}
/**
* 获取路径数据.
* @param null|stringpath 路径
*/
public function getSwaggerPath(?string path): string
{doc = <<<eof
* path="{path}",
eof;doc .= PHP_EOL;
return doc;
}
/**
* 获取标签数据.
* @param null|stringtag 标签
*/
public function getSwaggerTag(?string tag): string
{doc = <<<eof
* tags={"{tag}"},
eof;doc .= PHP_EOL;
return doc;
}
/**
* 获取概要数据.
* @param null|stringsummary 概要
* @return string 概要格式数据
*/
public function getSwaggerSummary(?string summary): string
{doc = <<<eof
* summary="{summary}",
eof;doc .= PHP_EOL;
return doc;
}
/**
* 获取描述数据.
* @param null|stringdescription 描述
* @return string 描述格式数据
*/
public function getSwaggerDescription(?string description): string
{doc = <<<eof
* description="{description}",
eof;doc .= PHP_EOL;
return doc;
}
/**
* query 参数拼接.
*/
public function getSwaggerParameter(?stringparameter): string
{
if (! parameter) {
return <<<'eof'
eof;
}
parse_str(parameter, output);
if (!parameter) {
return <<<'eof'
eof;
}
doc = '';
foreach (output as k =>v) {
type =this->gettype(v);doc .= <<<eof
* @OAParameter(name="{k}", in="query", description="",
* @OASchema(type="{type}", default="{v}")
* ),
eof;doc .= PHP_EOL;
}
return doc;
}
/**
* 获取请求 JsonContent 数据.
*/
public function getSwaggerRequestBody(?stringrequestBody): string
{
if (! requestBody) {
return <<<'eof'
eof;
}requestBody = this->constructSwaggerDoc(requestBody);
doc = <<<eof
* @OARequestBody(description="请求body",
* @OAJsonContent(type="object",
{requestBody}
* )
* ),
eof;
doc .= PHP_EOL;
returndoc;
}
/**
* 获取响应 JsonContent 数据.
* @param null|string response 响应json
*/
public function getSwaggerResponse(?stringresponse): string
{
comment =this->getColumnComment(this->swaggerTable);comment['errcode'] = '错误码';
comment['errmsg'] = '错误信息';comment['data'] = '返回数据';
if (! response) {
return <<<eof
* @OAResponse(response="200", description="响应信息返回",
* @OAJsonContent(type="object",
* @OAProperty(property="errcode", type="integer", description="{comment['errcode']}"),
* @OAProperty(property="errmsg", type="string", description="{comment['errmsg']}"),
* @OAProperty(property="data", type="object", description="{comment['data']}",
* @OAProperty(property="example", type="string", description="例子",
* )
* )
* )
eof;
}
response =this->constructSwaggerDoc(response,comment);
return <<<eof
* @OAResponse(response="200", description="响应信息返回",
* @OAJsonContent(type="object",
{response}
* )
* )
eof;
}
/**
* 检测是否为有序数据.
* @param mixedarray
* @return string array 有序数据 object 无序数组
*/
public function checkIsArray(array): string
{
if (! is_array(array)) {
return 'string';
}
num = count(array);
for (i = 0;i < num; ++i) {
if (isset(array[i])) {
continue;
}
return 'object';
}
return 'array';
}
/**
* 构造 JsonContent 数据.
* @param array|string data json格式字符串数据|数组数据
* @param arraycomment 注释
* @param string placeholder 占位空格数量
* @param stringpropertyType 数据格式
* @return string JsonContent格式数据
*/
private function constructSwaggerDoc(data, arraycomment = [], string placeholder = '', stringpropertyType = 'Property'): string
{
if (! data) {
return <<<'eof'
eof;
}data = is_array(data) ?data : json_decode(data, true);required = this->arrayToJsonObject(data);
doc = '';
if (propertyType == 'Items') {
doc .= <<<eof
* {placeholder}@OAItems(
eof;
doc .= PHP_EOL;placeholder .= ' ';
}
doc .= <<<eof
* {placeholder}required={required},
eof;doc .= PHP_EOL;
foreach (data ask => v) {description = comment[k] ?? null;
type =this->gettype(v);
if (in_array(type, ['object', 'array'])) {
if (isset(v[0]) || empty(v)) {
if (isset(v[0]) && is_array(v[0])) {
doc .= <<<eof
* {placeholder}@OAProperty(property="{k}", type="array", description="{description}",
eof;
doc .= PHP_EOL;newPlaceholder = placeholder . ' ';doc .= this->constructSwaggerDoc(v[0], comment,newPlaceholder, 'Items');
} else {
doc .= <<<eof
* {placeholder}@OAProperty(property="{k}", type="array", description="{description}",
* {placeholder}@OAItems()
eof;doc .= PHP_EOL;
}
} else {
doc .= <<<eof
* {placeholder}@OAProperty(property="{k}", type="object", description="{description}",
eof;
doc .= PHP_EOL;newPlaceholder = placeholder . ' ';doc .= this->constructSwaggerDoc(v, comment,newPlaceholder);
}
if (isset(v[0]) || empty(v)) {
doc .= <<<eof
* {placeholder}),
eof;
} else {
doc .= <<<eof
* {placeholder}),
eof;
}
doc .= PHP_EOL;
} else {doc .= <<<eof
* {placeholder}@OAProperty(property="{k}", type="{type}", description="{description}"),
eof;
doc .= PHP_EOL;
}
}
if (propertyType == 'Items') {
placeholder = substr(placeholder, 0, -4);
doc .= <<<eof
* {placeholder}),
eof;
doc .= PHP_EOL;
}
if (!placeholder) {
doc = trim(doc, PHP_EOL);
}
return doc;
}
/**
* 获取数据类型.
* @paramvalue
*/
private function gettype(value): string
{type = (string) gettype(value);
switch (type) {
case 'array':
result =this->checkIsArray(value);
break;
case 'integer':
case 'boolean':
case 'string':result = type;
break;
default:result = 'string';
break;
}
return result;
}
/**
* json数组格式转化为对象格式.
* @param arrayarray 有序数组
*/
private function arrayToJsonObject(array array): string
{jsonObject = trim(json_encode(array_keys(array)), '[');
return '{' . trim(jsonObject, ']') . '}';
}
/**
* 获取数据表字段描述.
*/
private function getColumnComment(?string tables): array
{
if (empty(tables)) {
return [];
}
tablesList = explode(',',tables);
if (! tablesList) {
return [];
}haveKey = [];
list = [];
foreach (tablesList as v) {sql = "SELECT COLUMN_NAME,column_comment FROM INFORMATION_SCHEMA.Columns WHERE table_name = '{v}'";comment = Db::select(sql);
// 需要保持字段名唯一,唯一字段才会保留
foreach (comment as v) {
// 判断 字段名 是否出现过
if (in_array(v['COLUMN_NAME'], haveKey)) {
continue;
}
// 判断 字段名 是否存在,存在的情况需要移除,并加入到 haveKey 数组
if (isset(list[v['COLUMN_NAME']])) {
unset(list[v['COLUMN_NAME']]);
array_push(haveKey, v['COLUMN_NAME']);
}list[v['COLUMN_NAME']] =v['column_comment'];
}
}
return $list;
}
}
<?php
declare(strict_types=1);
/**
* This file is part of hyperf-tt.
*
* @link https://github.com/zhaohao19941221/hyperf-tt
* @document https://github.com/zhaohao19941221/hyperf-tt.git
*/
namespace AppCommand;
use HyperfCommandAnnotationCommand;
use HyperfCommandCommand as HyperfCommand;
use HyperfDbConnectionDb;
use PsrContainerContainerInterface;
use SymfonyComponentConsoleInputInputArgument;
use SymfonyComponentConsoleInputInputOption;
/**
* @Command
*/
class SwaggerCommand extends HyperfCommand
{
/**
* @var ContainerInterface
*/
protected container;
// 表注释对应
protectedswaggerTable;
// 请求方式
protected swaggerMethod;
// url路径
protectedswaggerPath;
// 标签
protected swaggerTag;
// 概要
protectedswaggerSummary;
// 描述
protected swaggerDescription;
// query格式数据
protectedswaggerQuery;
// 请求 json 数据类型
protected swaggerRequestBody;
// 响应 json 数据类型
protectedswaggerResponse;
/**
* 执行的命令行.
*
* @var string
*/
protected name = 'swagger:format';
public function __construct(ContainerInterfacecontainer)
{
this->container =container;
parent::__construct();
}
public function configure()
{
parent::configure();
this->setHelp('示例:php bin/hyperf.php swagger:format Post '{"errcode":0,"errmsg":"success","data":{"token":"666"}}'');this->setDescription('swagger mode生成');
this->addArgument('method', InputArgument::OPTIONAL, '请求方式', 'Get');this->addArgument('response', InputArgument::OPTIONAL, '响应 json 数据类型');
this->addArgument('table', InputArgument::OPTIONAL, '自动填充数据表');this->addOption('path', 'P', InputOption::VALUE_OPTIONAL, 'url路径');
this->addOption('tag', 'T', InputOption::VALUE_OPTIONAL, '标签');this->addOption('summary', 'S', InputOption::VALUE_OPTIONAL, '概要');
this->addOption('description', 'D', InputOption::VALUE_OPTIONAL, '描述');this->addOption('query', 'Q', InputOption::VALUE_OPTIONAL, 'query格式数据');
this->addOption('request', 'R', InputOption::VALUE_OPTIONAL, '请求 json 数据类型');
}
public function handle()
{this->swaggerTable = this->input->getArgument('table');this->swaggerMethod = ucfirst(strtolower(this->input->getArgument('method')));this->swaggerPath = this->getSwaggerPath(this->input->getOption('path'));
this->swaggerTag =this->getSwaggerTag(this->input->getOption('tag'));this->swaggerSummary = this->getSwaggerSummary(this->input->getOption('summary'));
this->swaggerDescription =this->getSwaggerDescription(this->input->getOption('description'));this->swaggerQuery = this->getSwaggerParameter(this->input->getOption('query'));
this->swaggerRequestBody =this->getSwaggerRequestBody(this->input->getOption('request'));this->swaggerResponse = this->getSwaggerResponse(this->input->getArgument('response'));
echo this->getSwaggerModel();
}
/**
* 获取 swagger 结构.
*/
public function getSwaggerModel()
{doc = PHP_EOL . PHP_EOL;
header =this->swaggerPath . this->swaggerTag .this->swaggerSummary . this->swaggerDescription;header = trim(header, PHP_EOL);body = this->swaggerQuery .this->swaggerRequestBody . this->swaggerResponse;body = trim(body, PHP_EOL);doc .= <<<eof
/**
* @OA{this->swaggerMethod}(
{header}
* operationId="",
* @OAParameter(name="Authorization", in="header", description="jwt签名", required=true,
* @OASchema(type="string", default="Bearer {{Authorization}}")
* ),
{body}
* )
*/
eof;doc .= PHP_EOL . PHP_EOL;
return doc;
}
/**
* 获取路径数据.
* @param null|stringpath 路径
*/
public function getSwaggerPath(?string path): string
{doc = <<<eof
* path="{path}",
eof;doc .= PHP_EOL;
return doc;
}
/**
* 获取标签数据.
* @param null|stringtag 标签
*/
public function getSwaggerTag(?string tag): string
{doc = <<<eof
* tags={"{tag}"},
eof;doc .= PHP_EOL;
return doc;
}
/**
* 获取概要数据.
* @param null|stringsummary 概要
* @return string 概要格式数据
*/
public function getSwaggerSummary(?string summary): string
{doc = <<<eof
* summary="{summary}",
eof;doc .= PHP_EOL;
return doc;
}
/**
* 获取描述数据.
* @param null|stringdescription 描述
* @return string 描述格式数据
*/
public function getSwaggerDescription(?string description): string
{doc = <<<eof
* description="{description}",
eof;doc .= PHP_EOL;
return doc;
}
/**
* query 参数拼接.
*/
public function getSwaggerParameter(?stringparameter): string
{
if (! parameter) {
return <<<'eof'
eof;
}
parse_str(parameter, output);
if (!parameter) {
return <<<'eof'
eof;
}
doc = '';
foreach (output as k =>v) {
type =this->gettype(v);doc .= <<<eof
* @OAParameter(name="{k}", in="query", description="",
* @OASchema(type="{type}", default="{v}")
* ),
eof;doc .= PHP_EOL;
}
return doc;
}
/**
* 获取请求 JsonContent 数据.
*/
public function getSwaggerRequestBody(?stringrequestBody): string
{
if (! requestBody) {
return <<<'eof'
eof;
}requestBody = this->constructSwaggerDoc(requestBody);
doc = <<<eof
* @OARequestBody(description="请求body",
* @OAJsonContent(type="object",
{requestBody}
* )
* ),
eof;
doc .= PHP_EOL;
returndoc;
}
/**
* 获取响应 JsonContent 数据.
* @param null|string response 响应json
*/
public function getSwaggerResponse(?stringresponse): string
{
comment =this->getColumnComment(this->swaggerTable);comment['errcode'] = '错误码';
comment['errmsg'] = '错误信息';comment['data'] = '返回数据';
if (! response) {
return <<<eof
* @OAResponse(response="200", description="响应信息返回",
* @OAJsonContent(type="object",
* @OAProperty(property="errcode", type="integer", description="{comment['errcode']}"),
* @OAProperty(property="errmsg", type="string", description="{comment['errmsg']}"),
* @OAProperty(property="data", type="object", description="{comment['data']}",
* @OAProperty(property="example", type="string", description="例子",
* )
* )
* )
eof;
}
response =this->constructSwaggerDoc(response,comment);
return <<<eof
* @OAResponse(response="200", description="响应信息返回",
* @OAJsonContent(type="object",
{response}
* )
* )
eof;
}
/**
* 检测是否为有序数据.
* @param mixedarray
* @return string array 有序数据 object 无序数组
*/
public function checkIsArray(array): string
{
if (! is_array(array)) {
return 'string';
}
num = count(array);
for (i = 0;i < num; ++i) {
if (isset(array[i])) {
continue;
}
return 'object';
}
return 'array';
}
/**
* 构造 JsonContent 数据.
* @param array|string data json格式字符串数据|数组数据
* @param arraycomment 注释
* @param string placeholder 占位空格数量
* @param stringpropertyType 数据格式
* @return string JsonContent格式数据
*/
private function constructSwaggerDoc(data, arraycomment = [], string placeholder = '', stringpropertyType = 'Property'): string
{
if (! data) {
return <<<'eof'
eof;
}data = is_array(data) ?data : json_decode(data, true);required = this->arrayToJsonObject(data);
doc = '';
if (propertyType == 'Items') {
doc .= <<<eof
* {placeholder}@OAItems(
eof;
doc .= PHP_EOL;placeholder .= ' ';
}
doc .= <<<eof
* {placeholder}required={required},
eof;doc .= PHP_EOL;
foreach (data ask => v) {description = comment[k] ?? null;
type =this->gettype(v);
if (in_array(type, ['object', 'array'])) {
if (isset(v[0]) || empty(v)) {
if (isset(v[0]) && is_array(v[0])) {
doc .= <<<eof
* {placeholder}@OAProperty(property="{k}", type="array", description="{description}",
eof;
doc .= PHP_EOL;newPlaceholder = placeholder . ' ';doc .= this->constructSwaggerDoc(v[0], comment,newPlaceholder, 'Items');
} else {
doc .= <<<eof
* {placeholder}@OAProperty(property="{k}", type="array", description="{description}",
* {placeholder}@OAItems()
eof;doc .= PHP_EOL;
}
} else {
doc .= <<<eof
* {placeholder}@OAProperty(property="{k}", type="object", description="{description}",
eof;
doc .= PHP_EOL;newPlaceholder = placeholder . ' ';doc .= this->constructSwaggerDoc(v, comment,newPlaceholder);
}
if (isset(v[0]) || empty(v)) {
doc .= <<<eof
* {placeholder}),
eof;
} else {
doc .= <<<eof
* {placeholder}),
eof;
}
doc .= PHP_EOL;
} else {doc .= <<<eof
* {placeholder}@OAProperty(property="{k}", type="{type}", description="{description}"),
eof;
doc .= PHP_EOL;
}
}
if (propertyType == 'Items') {
placeholder = substr(placeholder, 0, -4);
doc .= <<<eof
* {placeholder}),
eof;
doc .= PHP_EOL;
}
if (!placeholder) {
doc = trim(doc, PHP_EOL);
}
return doc;
}
/**
* 获取数据类型.
* @paramvalue
*/
private function gettype(value): string
{type = (string) gettype(value);
switch (type) {
case 'array':
result =this->checkIsArray(value);
break;
case 'integer':
case 'boolean':
case 'string':result = type;
break;
default:result = 'string';
break;
}
return result;
}
/**
* json数组格式转化为对象格式.
* @param arrayarray 有序数组
*/
private function arrayToJsonObject(array array): string
{jsonObject = trim(json_encode(array_keys(array)), '[');
return '{' . trim(jsonObject, ']') . '}';
}
/**
* 获取数据表字段描述.
*/
private function getColumnComment(?string tables): array
{
if (empty(tables)) {
return [];
}
tablesList = explode(',',tables);
if (! tablesList) {
return [];
}haveKey = [];
list = [];
foreach (tablesList as v) {sql = "SELECT COLUMN_NAME,column_comment FROM INFORMATION_SCHEMA.Columns WHERE table_name = '{v}'";comment = Db::select(sql);
// 需要保持字段名唯一,唯一字段才会保留
foreach (comment as v) {
// 判断 字段名 是否出现过
if (in_array(v['COLUMN_NAME'], haveKey)) {
continue;
}
// 判断 字段名 是否存在,存在的情况需要移除,并加入到 haveKey 数组
if (isset(list[v['COLUMN_NAME']])) {
unset(list[v['COLUMN_NAME']]);
array_push(haveKey, v['COLUMN_NAME']);
}list[v['COLUMN_NAME']] =v['column_comment'];
}
}
return $list;
}
}
php bin/hyperf.php swagger:format Post '{"errcode":0,"errmsg":"success","data":{"token":"666"}}'
php bin/hyperf.php swagger:format Post '{"errcode":0,"errmsg":"success","data":{"token":"666"}}'



