Api文档
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

141 lines
6.9 KiB

<?php
use App\Common\Util\TP;
use Plugins\ApiDoc\Admin\Controller\DocumentController;
use Sc\Util\HtmlElement\El;
use Sc\Util\HtmlStructure\Html\Js\Axios;
use Sc\Util\HtmlStructure\Html\Js\JsCode;
use Sc\Util\HtmlStructure\Html\Js\JsFunc;
use Sc\Util\HtmlStructure\Html\Js\JsIf;
use Sc\Util\HtmlStructure\Html\Js\JsVar;
/** @var \Sc\Util\HtmlStructure\Html\Js\Vue $vue */
$apiInfo = El::double('el-card')->setAttr('v-if', 'currentApiInfo')->append(
El::double('template')->setAttr('#header')->append(
El::double('div')->append(
El::double('el-icon')
->addClass('icon cur')
->setAttr('@click.stop', 'toggleStar(currentApiInfo.url)')
->append('<component :is="Stars.includes(currentApiInfo.url) ? \'StarFilled\' : \'Star\'">'),
El::fromCode("<b v-if='currentApiInfo.method == GET' style='color: #F56C6C'>GET</b><b v-else style='color: #67C23A'>POST</b>"),
El::fromCode("{{ ApiInfo.host }}{{ currentApiInfo.url }}"),
El::fromCode("<el-icon class='cur send' @click='sendRequest' title='发送测试请求'><Promotion /></el-icon>"),
),
El::double('div')->setAttr('style', 'position: relative;top:10px')->append(
El::double('el-text')->setAttr('style', 'margin-right: 10px;')
->append("token:")
->append(El::double('el-text')->setAttr('style', 'color: #409EFF')->append("{{ currentApiInfo.auth == 'strength' ? '必须' : (currentApiInfo.auth == 'weak' ? '可选' : '无须') }}")),
El::double('el-text')->append("版本:"),
El::double('el-tag')->setAttr('v-for', '(version, index) in currentApiInfo.version')
->setAttr('size', 'small')
->setAttr('style', 'margin-left: 5px;')
->append('{{ version }}')
)
),
El::double('el-tabs')->setAttr('v-model', 'showApiInfo')
->setAttr('@tab-change', 'apiShowType')->append(
El::double('el-tab-pane')->setAttr('label', '请求参数')->setAttr('name', 'Form')->append(
El::double('el-scrollbar')->setAttr('style', 'height: calc(100vh - 250px);')->append(
El::double('el-form')->setAttrs([
'ref' => 'form',
'label-position' => 'top',
])->append(
El::double('el-form-item')
->setAttr('v-for', 'param in currentApiInfo.requestParams')
->append(
El::double('template')->setAttr('#label')->append('{{ param.describe }}'),
El::double('el-input')->setAttr('v-if', "param.type === 'Integer' || param.type === 'Float'")
->setAttr('v-model.number', 'apiFormData[param.name]'),
El::double('el-input')->setAttr('v-else-if', "param.type === 'String'")
->setAttr('v-model.number', 'apiFormData[param.name]'),
El::double('el-input')
->setAttr("v-else")
->setAttr(':readonly', "true")
->setAttr(':placeholder', "'请使用json组件模拟数据'")
)
)
)
),
El::double('el-tab-pane')->setAttr('label', 'Json')->setAttr('name', 'Json')->append(
El::fromCode('<div id="paramShowJson" style="width: 100%; height: calc(100vh - 250px);"></div>'),
),
El::double('el-tab-pane')->setAttr('label', '请求脚本')->setAttr('name', 'Scripts')->append(
El::double('iframe')->setAttr("src", TP::route()->to([DocumentController::class, 'requestCode'])),
),
El::double('el-tab-pane')->setAttr('label', '响应')->setAttr('name', 'Response')->append(
El::fromCode('<div id="ResponseJson" v-if="typeof response !== \'string\'" style="width: 100%; height: calc(100vh - 250px);"></div>'),
El::fromCode('<div v-else v-html="response" style="width: 100%; height: calc(100vh - 250px);"></div>'),
),
)
);
$vue->addMethod('getApiInfo', JsFunc::anonymous(['api'])->code(
Axios::get(TP::route()->to([DocumentController::class, 'doc']))
->success(JsCode::make(
JsVar::set("this.ApiInfo", '@data.data'),
JsVar::set("this.ApiInfo.versionSelect", '@this.ApiInfo.version.map(v => {return {label: "版本:" + v, value: v}})'),
JsCode::raw('this.$message.success("已获取最新文档信息,当前最新版本:" + Math.max(...data.data.version))')
))
));
$vue->addMethod('apiShowType', JsFunc::anonymous(['name'])->code(
JsCode::raw('console.log(name)'),
JsIf::when("name === 'Json' && this.apiFormEditor === null")->then(
JsCode::raw("this.apiFormEditor = new JSONEditor(document.getElementById('paramShowJson'), this.jsonEditorInitOptions('code', (value) => {
this.apiFormData = JSON.parse(value);
}))"),
),
JsIf::when("name === 'Response' && this.responseEditor === null")->then(
JsCode::raw("this.\$nextTick(() => this.responseEditor = new JSONEditor(document.getElementById('ResponseJson'), this.jsonEditorInitOptions('code', (value) => {})))"),
),
JsCode::raw('this.$nextTick(() => {
this.apiFormEditor && this.apiFormEditor.set(this.apiFormData);
});'),
));
$vue->addMethod('jsonEditorInitOptions', JsFunc::anonymous(['type', 'onChange'])->code(
JsCode::raw("return {
mode: type,
modes: ['code', 'form', 'text', 'tree', 'view', 'preview'], // allowed modes
onChangeText: onChange,
}")
));
$vue->addMethod('sendRequest', JsFunc::anonymous()->code(
JsCode::raw('let code = localStorage.getItem("requestCode");'),
JsIf::when('code.length > 0')->then(<<<JS
let request = {
setResponse(response){
VueApp.response = response;
if (typeof response === 'object'){
VueApp.responseEditor && VueApp.responseEditor.set(VueApp.response);
}
},
call(url, method, data){
let request = {
url: url,
method: method,
data: JSON.parse(JSON.stringify(data))
};
let VueApp = null;
try{
eval(code);
}catch (e) {
alert(e.message)
}
}
};
this.showApiInfo = "Response";
this.apiShowType(this.showApiInfo);
request.call(this.currentApiInfo.url, this.currentApiInfo.method, this.apiFormData);
JS)
));
return $apiInfo;