commit
120cd494c6
@ -14,8 +14,9 @@ apimanager 模块是一个用于API管理、测试的模块。
|
||||
6. 基于catchadmin开发,模块安装简单,使用便捷,支持模块数据导入导出。
|
||||
7. 开源开放易于二次开发,测试用例可共享,形成产品API知识库。
|
||||
8. 支持私有化部署、云原生部署。
|
||||
9. 可视化管理系统路由列表,并可与API测试工具结合可视化测试系统接口。
|
||||
|
||||
演示地址:www.uctoo.com 控制台使用demo帐号登录
|
||||
演示地址:demo.uctoo.com 控制台使用demo帐号登录
|
||||
模块使用界面截图:
|
||||
<table>
|
||||
<tr>
|
||||
@ -39,6 +40,9 @@ apimanager 模块是一个用于API管理、测试的模块。
|
||||
<tr>
|
||||
<td><img src="https://gitee.com/UCT_admin/materials/raw/master/uctoo_apitester/images/apirun.png"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://gitee.com/UCT_admin/materials/raw/master/uctoo_apitester/images/routelist.png"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## 产品架构
|
||||
@ -70,8 +74,10 @@ apimanager 模块是一个用于API管理、测试的模块。
|
||||
## 使用手册
|
||||
1. 可以通过API管理->API分类功能增删改查API分类。
|
||||
2. 可以通过API环境变量功能增删改查用户环境变量。环境变量的key值以{{key}}方式定义,在API测试用例中对应的{{key}}值将替换为环境变量的value值。每个用户可以创建多组环境变量,可以切换当前选中的环境变量组。
|
||||
3. 可以通过API列表功能增删改查API测试用例。api_url、header、body、query、auth字段支持环境变量。
|
||||
3. 可以通过API列表功能增删改查API测试用例。api_url、header、body、query、auth字段支持环境变量。新增API测试用例时,标识字段请与路由列表name字段保持一致,以便API测试用例与路由一一对应快速检索。
|
||||
4. 可以对已添加的API测试用例执行测试操作,在API测试界面,可以对api_url、header、body、query、auth等字段进行自定义编辑。发送按钮可以实际执行API测试用例,获得接口返回值。
|
||||
5. 可以使用路由列表->同步至数据库功能,将系统内所有路由信息保存至数据库,以便可视化管理和测试。与 php think route:list -m 命令相同效果。
|
||||
6. 可以使用路由列表->API测试功能,以路由name字段为请求参数跳转至API测试列表页面,以便快速查询出对应的API测试用例进行API测试。(需更新前端vue项目layout/mixin/formOperate.js文件修复了页面初始化传参bug)
|
||||
|
||||
具体请参考 https://www.kancloud.cn/doc_uctoo/manual
|
||||
|
||||
|
@ -1,128 +1,71 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="filter-container">
|
||||
<el-input
|
||||
v-model="queryParam.env_name"
|
||||
placeholder="环境名称"
|
||||
clearable
|
||||
class="filter-item form-search-input"
|
||||
/>
|
||||
<el-button
|
||||
class="filter-item search"
|
||||
icon="el-icon-search"
|
||||
@click="handleSearch"
|
||||
>
|
||||
<el-input v-model="queryParam.env_name" placeholder="环境名称" clearable class="filter-item form-search-input" />
|
||||
<el-button class="filter-item search" icon="el-icon-search" @click="handleSearch">
|
||||
搜索
|
||||
</el-button>
|
||||
<el-button
|
||||
class="filter-item"
|
||||
icon="el-icon-refresh"
|
||||
@click="handleRefresh"
|
||||
>
|
||||
<el-button class="filter-item" icon="el-icon-refresh" @click="handleRefresh">
|
||||
重置
|
||||
</el-button>
|
||||
<el-button
|
||||
class="filter-item fr"
|
||||
type="primary"
|
||||
icon="el-icon-plus"
|
||||
@click="handleCreateEnv"
|
||||
>
|
||||
<el-button class="filter-item fr" type="primary" icon="el-icon-plus" @click="handleCreateEnv">
|
||||
新增
|
||||
</el-button>
|
||||
</div>
|
||||
<el-table
|
||||
ref="multipleTable"
|
||||
:data="data"
|
||||
tooltip-effect="dark"
|
||||
style="width: 100%"
|
||||
border
|
||||
fit
|
||||
@selection-change="handleSelectMulti"
|
||||
>
|
||||
<el-table ref="multipleTable" :data="data" tooltip-effect="dark" style="width: 100%" border fit @selection-change="handleSelectMulti">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column prop="env_name" label="环境名称" />
|
||||
<el-table-column prop="selected" label="当前环境" />
|
||||
<el-table-column prop="env_name" label="环境名称" />
|
||||
<el-table-column prop="selected" label="当前环境" />
|
||||
<el-table-column prop="creator" label="创建人" />
|
||||
<el-table-column prop="created_at" label="创建时间" />
|
||||
<el-table-column prop="updated_at" label="更新时间" />
|
||||
<el-table-column label="操作" fixed="right" width="300">
|
||||
<template slot-scope="module">
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="el-icon-refresh"
|
||||
@click="selectAPIenv(module.row.id)"
|
||||
>切换</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="el-icon-edit"
|
||||
@click="handleUpdate(module.row)"
|
||||
/>
|
||||
<el-button
|
||||
type="danger"
|
||||
icon="el-icon-delete"
|
||||
@click="handleDelete(module.row.id)"
|
||||
/>
|
||||
<el-button type="primary" icon="el-icon-refresh" @click="selectAPIenv(module.row.id)" >切换</el-button>
|
||||
<el-button type="primary" icon="el-icon-edit" @click="handleUpdate(module.row)" />
|
||||
<el-button type="danger" icon="el-icon-delete" @click="handleDelete(module.row.id)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination
|
||||
background
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
:current-page="paginate.current"
|
||||
hide-on-single-page
|
||||
:page-sizes="paginate.sizes"
|
||||
:page-size="paginate.limit"
|
||||
:layout="paginate.layout"
|
||||
:total="paginate.total"
|
||||
/>
|
||||
background
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
:current-page="paginate.current"
|
||||
hide-on-single-page
|
||||
:page-sizes="paginate.sizes"
|
||||
:page-size="paginate.limit"
|
||||
:layout="paginate.layout"
|
||||
:total="paginate.total"/>
|
||||
<!----------------------------------- 编辑 ---------------------------------------------->
|
||||
<el-dialog
|
||||
:close-on-click-modal="false"
|
||||
:title="title"
|
||||
:visible.sync="formVisible"
|
||||
@close="handleCancel"
|
||||
>
|
||||
<el-form
|
||||
label-position="top"
|
||||
:ref="formName"
|
||||
:model="formFieldsData"
|
||||
:rules="rules"
|
||||
>
|
||||
<el-form-item
|
||||
label="env_name"
|
||||
:label-width="formLabelWidth"
|
||||
prop="env_name"
|
||||
>
|
||||
<el-input
|
||||
v-model="formFieldsData.env_name"
|
||||
placeholder="请输入环境名称"
|
||||
autocomplete="off"
|
||||
clearable
|
||||
/>
|
||||
<el-dialog :close-on-click-modal="false" :title="title" :visible.sync="formVisible" @close="handleCancel">
|
||||
<el-form label-position="top" :ref="formName" :model="formFieldsData" :rules="rules">
|
||||
<el-form-item label="env_name" :label-width="formLabelWidth" prop="env_name">
|
||||
<el-input v-model="formFieldsData.env_name" placeholder="请输入环境名称" autocomplete="off" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
label="env_json"
|
||||
:label-width="formLabelWidth"
|
||||
prop="env_json"
|
||||
>
|
||||
<!-- <el-form-item label="appid" :label-width="formLabelWidth" prop="appid">
|
||||
<el-input v-model="formFieldsData.appid" placeholder="请输入appid" autocomplete="off" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="project_id" :label-width="formLabelWidth" prop="project_id">
|
||||
<el-input v-model="formFieldsData.project_id" placeholder="请输入project_id" autocomplete="off" clearable />
|
||||
</el-form-item> -->
|
||||
<el-form-item label="env_json" :label-width="formLabelWidth" prop="env_json">
|
||||
<avue-crud
|
||||
ref="crudJSON"
|
||||
:option="tableOption"
|
||||
:data="jsonTableData"
|
||||
@row-update="addUpdateJSON"
|
||||
@row-del="rowDelJSON"
|
||||
@row-save="rowSaveJSON"
|
||||
>
|
||||
<template slot-scope="{ row, index }" slot="menu">
|
||||
<el-button
|
||||
type="text"
|
||||
size="small"
|
||||
@click="rowCellJSON(row, index)"
|
||||
>{{ row.$cellEdit ? "自定义保存" : "自定义修改" }}</el-button
|
||||
>
|
||||
</template>
|
||||
ref="crudJSON"
|
||||
:option="tableOption"
|
||||
:data="jsonTableData"
|
||||
@row-update="addUpdateJSON"
|
||||
@row-del="rowDelJSON"
|
||||
@row-save="rowSaveJSON"
|
||||
>
|
||||
<template slot-scope="{ row, index }" slot="menu">
|
||||
<el-button
|
||||
type="text"
|
||||
size="small"
|
||||
@click="rowCellJSON(row, index)"
|
||||
>{{ row.$cellEdit ? "自定义保存" : "自定义修改" }}</el-button
|
||||
>
|
||||
</template>
|
||||
</avue-crud>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
@ -134,137 +77,141 @@
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import formOperate from "@/layout/mixin/formOperate";
|
||||
export default {
|
||||
name: "apimanager_apienv",
|
||||
mixins: [formOperate],
|
||||
data() {
|
||||
return {
|
||||
formName: "apiEnv",
|
||||
formLabelWidth: "120px",
|
||||
// 刷新路由
|
||||
refreshRoute: true,
|
||||
// 用户搜索
|
||||
queryParam: {
|
||||
env_name: ""
|
||||
},
|
||||
formVisible: false,
|
||||
formFieldsData: {
|
||||
env_name: "",
|
||||
env_json: ""
|
||||
},
|
||||
url: "apiTesterUserenv",
|
||||
// 表单验证
|
||||
rules: {
|
||||
env_name: [{ required: true, message: "请输入环境名称" }],
|
||||
env_json: [{ required: true, message: "请输入环境变量" }]
|
||||
},
|
||||
jsonTableData: [],
|
||||
tableOption: {
|
||||
refreshBtn: false,
|
||||
addBtn: false,
|
||||
editBtn: false,
|
||||
addRowBtn: true,
|
||||
cancelBtn: false,
|
||||
border: true,
|
||||
columnBtn: false,
|
||||
column: [
|
||||
{
|
||||
label: "Key",
|
||||
prop: "key",
|
||||
cell: true,
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: "Key值示例:{{KeyName}}",
|
||||
trigger: "blur"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: "Value",
|
||||
prop: "value",
|
||||
cell: true,
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入Value值",
|
||||
trigger: "blur"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
import formOperate from '@/layout/mixin/formOperate'
|
||||
import { parseTime } from '@/utils'
|
||||
export default {
|
||||
name:'apimanager_apienv',
|
||||
mixins: [formOperate],
|
||||
data() {
|
||||
return {
|
||||
formName: 'apiEnv',
|
||||
formLabelWidth: '120px',
|
||||
// 刷新路由
|
||||
refreshRoute: true,
|
||||
// 用户搜索
|
||||
queryParam: {
|
||||
env_name: '',
|
||||
},
|
||||
formVisible: false,
|
||||
formFieldsData: {
|
||||
env_name: '',
|
||||
env_json: ''
|
||||
},
|
||||
url: 'apiTesterUserenv',
|
||||
// 表单验证
|
||||
rules: {
|
||||
env_name: [
|
||||
{ required: true, message: '请输入环境名称' }
|
||||
],
|
||||
env_json: [
|
||||
{ required: true, message: '请输入环境变量' }
|
||||
]
|
||||
},
|
||||
jsonTableData:[],
|
||||
tableOption: {
|
||||
refreshBtn:false,
|
||||
addBtn: false,
|
||||
editBtn: false,
|
||||
addRowBtn: true,
|
||||
cancelBtn: false,
|
||||
border: true,
|
||||
column: [
|
||||
{
|
||||
label: "Key",
|
||||
prop: "key",
|
||||
cell: true,
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: "Key值示例:{{KeyName}}",
|
||||
trigger: "blur"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: "Value",
|
||||
prop: "value",
|
||||
cell: true,
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入Value值",
|
||||
trigger: "blur"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
}
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
formFieldsData: {
|
||||
deep: true,
|
||||
handler(data) {
|
||||
if (data.env_json) {
|
||||
let obj = this.JsonToObject(data.env_json);
|
||||
let arr = Object.entries(obj).map(item => {
|
||||
},
|
||||
watch:{
|
||||
formFieldsData:{
|
||||
deep:true,
|
||||
handler(data){
|
||||
if(data.env_json){
|
||||
let obj = this.JsonToObject(data.env_json)
|
||||
let arr = Object.entries(obj).map(item => {
|
||||
return { key: item[0], value: item[1], $cellEdit: false };
|
||||
});
|
||||
this.jsonTableData = arr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleCreateEnv() {
|
||||
this.jsonTableData = [];
|
||||
this.handleCreate();
|
||||
},
|
||||
selectAPIenv(id) {
|
||||
this.$http.get("apiTesterUserenv/selectAPIenv/" + id).then(response => {
|
||||
this.$message.success(response.message);
|
||||
this.handleRefresh();
|
||||
});
|
||||
},
|
||||
// ↓ 处理 ApiBaseInfo Json数据格式 返回 Object 格式 ↓
|
||||
JsonToObject(json) {
|
||||
if (json) {
|
||||
let flag = /\'/.test(json);
|
||||
if (flag) {
|
||||
return JSON.parse(json.replace(/\'/gi, '"'));
|
||||
methods: {
|
||||
handleCreateEnv(){
|
||||
this.jsonTableData = []
|
||||
this.handleCreate()
|
||||
},
|
||||
selectAPIenv(id) {
|
||||
this.$http.get( 'apiTesterUserenv/selectAPIenv/' + id).then(response => {
|
||||
this.$message.success(response.message)
|
||||
this.handleRefresh()
|
||||
})
|
||||
},
|
||||
// ↓ 处理 ApiBaseInfo Json数据格式 返回 Object 格式 ↓
|
||||
JsonToObject(json) {
|
||||
if (json) {
|
||||
let flag = /\'/.test(json);
|
||||
if (flag) {
|
||||
return JSON.parse(json.replace(/\'/gi, '"'));
|
||||
} else {
|
||||
return JSON.parse(json);
|
||||
}
|
||||
} else {
|
||||
return JSON.parse(json);
|
||||
return null;
|
||||
}
|
||||
},
|
||||
// ↓ JSON 表格 行编辑 ↓
|
||||
rowCellJSON(row, index) {
|
||||
this.$refs.crudJSON.rowCell(row, index);
|
||||
},
|
||||
// ↓ JSON 表格 编辑行数据 ↓
|
||||
addUpdateJSON(form, index, done, loading) {
|
||||
loading();
|
||||
done();
|
||||
},
|
||||
// ↓ JSON 表格 保存行数据 ↓
|
||||
rowSaveJSON(form, done) {
|
||||
done();
|
||||
this.formFieldsData.env_json = this.handlerJson(this.jsonTableData);
|
||||
},
|
||||
// ↓ JSON 表格 删除行数据 ↓
|
||||
rowDelJSON(form, index, done) {
|
||||
this.jsonTableData.splice(index, 1);
|
||||
this.formFieldsData.env_json = this.handlerJson(this.jsonTableData);
|
||||
},
|
||||
handlerJson(arrData){
|
||||
let cache = {};
|
||||
arrData.forEach(item => {
|
||||
cache[item.key] = item.value;
|
||||
});
|
||||
if(Object.keys(cache).length){
|
||||
return JSON.stringify(cache);
|
||||
}else{
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
// ↓ JSON 表格 行编辑 ↓
|
||||
rowCellJSON(row, index) {
|
||||
this.$refs.crudJSON.rowCell(row, index);
|
||||
},
|
||||
// ↓ JSON 表格 编辑行数据 ↓
|
||||
addUpdateJSON(form, index, done, loading) {
|
||||
loading();
|
||||
done();
|
||||
},
|
||||
// ↓ JSON 表格 保存行数据 ↓
|
||||
rowSaveJSON(form, done) {
|
||||
done();
|
||||
this.formFieldsData.env_json = this.handlerJson(this.jsonTableData);
|
||||
},
|
||||
// ↓ JSON 表格 删除行数据 ↓
|
||||
rowDelJSON(form, index, done) {
|
||||
this.jsonTableData.splice(index, 1);
|
||||
this.formFieldsData.env_json = this.handlerJson(this.jsonTableData);
|
||||
},
|
||||
handlerJson(arrData) {
|
||||
let cache = {};
|
||||
arrData.forEach(item => {
|
||||
cache[item.key] = item.value;
|
||||
});
|
||||
if (Object.keys(cache).length) {
|
||||
return JSON.stringify(cache);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -329,11 +329,11 @@ export default {
|
||||
this.apiBaseInfo = response.data;
|
||||
this.apiBaseInfo.body = this.apiBaseInfo.body.replace(/'/g, '"');
|
||||
if (this.apiBaseInfo.body) {
|
||||
let resstr = this.apiBaseInfo.body
|
||||
.replace(/\\/g, "")
|
||||
.replace(/"{/g, "{")
|
||||
.replace(/}"/g, "}");
|
||||
this.rawJson = JSON.parse(resstr);
|
||||
// let resstr = this.apiBaseInfo.body
|
||||
// .replace(/\\/g, "")
|
||||
// .replace(/"{/g, "{")
|
||||
// .replace(/}"/g, "}");
|
||||
this.rawJson = JSON.parse(this.apiBaseInfo.body);
|
||||
} else {
|
||||
this.rawJson = {};
|
||||
}
|
||||
|
@ -239,13 +239,13 @@
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
label="标识"
|
||||
label="标识(路由name)"
|
||||
:label-width="formLabelWidth"
|
||||
prop="api_name"
|
||||
>
|
||||
<el-input
|
||||
v-model="formFieldsData.api_name"
|
||||
placeholder="请输入英文唯一标识"
|
||||
placeholder="请输入英文唯一标识(请与路由name字段一致)"
|
||||
autocomplete="off"
|
||||
clearable
|
||||
/>
|
||||
|
@ -0,0 +1,159 @@
|
||||
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-form ref="form" :model="queryParam" :inline="true">
|
||||
<el-form-item prop="rule" label="rule" :label-width="formLabelWidth">
|
||||
<el-input v-model="queryParam.rule" placeholder="rule" type="input"></el-input>
|
||||
</el-form-item><el-form-item prop="route" label="route" :label-width="formLabelWidth">
|
||||
<el-input v-model="queryParam.route" placeholder="route" type="input"></el-input>
|
||||
</el-form-item><el-form-item prop="method" label="method" :label-width="formLabelWidth">
|
||||
<el-input v-model="queryParam.method" placeholder="method" type="input"></el-input>
|
||||
</el-form-item><el-form-item prop="name" label="name" :label-width="formLabelWidth">
|
||||
<el-input v-model="queryParam.name" placeholder="name" type="input"></el-input>
|
||||
</el-form-item><el-form-item prop="domain" label="domain" :label-width="formLabelWidth">
|
||||
<el-input v-model="queryParam.domain" placeholder="domain" type="input"></el-input>
|
||||
</el-form-item><el-form-item prop="option" label="option" :label-width="formLabelWidth">
|
||||
<el-input v-model="queryParam.option" placeholder="option" type="input"></el-input>
|
||||
</el-form-item><el-form-item prop="pattern" label="pattern" :label-width="formLabelWidth">
|
||||
<el-input v-model="queryParam.pattern" placeholder="pattern" type="input"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button icon="el-icon-search" type="primary" @click="handleSearch">
|
||||
查询
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-divider content-position="center"></el-divider>
|
||||
<div class="filter-container">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<div class="grid-content">
|
||||
<el-button class="filter-item" icon="el-icon-refresh" @click="handleRefresh">刷新</el-button>
|
||||
<!-- <el-button class="filter-item" type="primary" icon="el-icon-plus" @click="handleCreate()">添加</el-button> -->
|
||||
<el-button type="primary" class="filter-item" icon="el-icon-refresh" @click="sync">
|
||||
同步至数据库
|
||||
</el-button>
|
||||
<el-button v-if="this.selectedIds.length" size="small" class="filter-item mb-5" type="danger" icon="el-icon-delete" @click="handleMultiDelete">批量删除</el-button>
|
||||
<el-button @click="clearFilter">清除所有过滤器</el-button>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-button icon="el-icon-info" circle @click="templateVersion" style="float: right; padding: 3px 0"></el-button>
|
||||
<el-dropdown @command="handleTableCommand" style="float: right; padding: 3px 0">
|
||||
<span class="el-dropdown-link">
|
||||
<i class="el-icon-more el-icon--right"></i>
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="a">配置表格</el-dropdown-item>
|
||||
<el-dropdown-item command="b" divided>移除</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
<div class="grid-content">
|
||||
<el-dropdown @command="handleDropdownCommand" style="float: right; padding: 3px 0">
|
||||
<span class="el-dropdown-link">
|
||||
<i class="el-icon-menu el-icon--right"></i>
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-checkbox-group v-model="checkList">
|
||||
<el-dropdown-item command="a"><el-checkbox label="rule"></el-checkbox></el-dropdown-item><el-dropdown-item command="a"><el-checkbox label="route"></el-checkbox></el-dropdown-item><el-dropdown-item command="a"><el-checkbox label="method"></el-checkbox></el-dropdown-item><el-dropdown-item command="a"><el-checkbox label="name"></el-checkbox></el-dropdown-item><el-dropdown-item command="a"><el-checkbox label="domain"></el-checkbox></el-dropdown-item><el-dropdown-item command="a"><el-checkbox label="option"></el-checkbox></el-dropdown-item><el-dropdown-item command="a"><el-checkbox label="pattern"></el-checkbox></el-dropdown-item>
|
||||
</el-checkbox-group>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
<el-table ref="multipleTable" :data="data" tooltip-effect="dark" style="width: 100%" fit @selection-change="handleSelectMulti">
|
||||
<el-table-column type="selection" width="55" v-if="true"></el-table-column>
|
||||
<el-table-column prop="rule" label="rule" sortable="true" v-if="true"></el-table-column>
|
||||
<el-table-column prop="route" label="route" sortable="true" v-if="true"></el-table-column>
|
||||
<el-table-column prop="method" label="method" sortable="true" v-if="true"></el-table-column>
|
||||
<el-table-column prop="name" label="name" sortable="true" v-if="true"></el-table-column>
|
||||
<el-table-column prop="domain" label="domain" sortable="true" v-if="true"></el-table-column>
|
||||
<el-table-column prop="option" label="option" sortable="true" v-if="true"></el-table-column>
|
||||
<el-table-column prop="pattern" label="pattern" sortable="true" v-if="true"></el-table-column>
|
||||
<el-table-column prop="creator" label="创建人" v-if="true"></el-table-column>
|
||||
<el-table-column prop="created_at" label="创建时间" v-if="true"></el-table-column>
|
||||
<el-table-column prop="updated_at" label="更新时间" v-if="true"></el-table-column>
|
||||
<el-table-column label="操作" v-if="true" fixed="right">
|
||||
<template slot-scope="module">
|
||||
<el-button type="primary" icon="el-icon-stopwatch" @click="testApi(module.row.name)">API测试</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="paginate.current" hide-on-single-page :page-sizes="paginate.sizes" :page-size="paginate.limit" :layout="paginate.layout" :total="paginate.total"></el-pagination>
|
||||
<!----------------------------------- 新增/编辑 ---------------------------------------------->
|
||||
<el-drawer ref="drawer" size="60%" :title="drawerTitle" :visible.sync="formVisible" :before-close="handleClose" direction="rtl" @close="handleCancel">
|
||||
<div class="demo-drawer__content">
|
||||
<el-form :ref="formName" :model="formFieldsData" :rules="rules">
|
||||
<el-form-item prop="rule" label="rule" :label-width="formLabelWidth">
|
||||
<el-input v-model="formFieldsData.rule" placeholder="rule" autocomplete="off" clearable type="input"></el-input>
|
||||
</el-form-item><el-form-item prop="route" label="route" :label-width="formLabelWidth">
|
||||
<el-input v-model="formFieldsData.route" placeholder="route" autocomplete="off" clearable type="input"></el-input>
|
||||
</el-form-item><el-form-item prop="method" label="method" :label-width="formLabelWidth">
|
||||
<el-input v-model="formFieldsData.method" placeholder="method" autocomplete="off" clearable type="input"></el-input>
|
||||
</el-form-item><el-form-item prop="name" label="name" :label-width="formLabelWidth">
|
||||
<el-input v-model="formFieldsData.name" placeholder="name" autocomplete="off" clearable type="input"></el-input>
|
||||
</el-form-item><el-form-item prop="domain" label="domain" :label-width="formLabelWidth">
|
||||
<el-input v-model="formFieldsData.domain" placeholder="domain" autocomplete="off" clearable type="input"></el-input>
|
||||
</el-form-item><el-form-item prop="option" label="option" :label-width="formLabelWidth">
|
||||
<el-input v-model="formFieldsData.option" placeholder="option" autocomplete="off" clearable type="input"></el-input>
|
||||
</el-form-item><el-form-item prop="pattern" label="pattern" :label-width="formLabelWidth">
|
||||
<el-input v-model="formFieldsData.pattern" placeholder="pattern" autocomplete="off" clearable type="input"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="drawer__footer">
|
||||
<el-button @click="handleCancel">取 消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" :loading="loading">{{ loading ? '提交中 ...' : '确 定' }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import formOperate from '@/layout/mixin/formOperate'
|
||||
|
||||
export default {
|
||||
name:'apimanager_routeList',
|
||||
mixins: [formOperate],
|
||||
data() {
|
||||
return {
|
||||
url: 'routeList',
|
||||
formName: 'route_list',
|
||||
formLabelWidth: '120px',
|
||||
// 用户搜索
|
||||
queryParam: {
|
||||
rule:'',route:'',method:'',name:'',domain:'',option:'',pattern:'',
|
||||
},
|
||||
formVisible: false,
|
||||
formFieldsData: {
|
||||
rule:'',route:'',method:'',name:'',domain:'',option:'',pattern:'',
|
||||
},
|
||||
loading: false,
|
||||
checkList: [],
|
||||
search: '',
|
||||
drawerTitle: 'route_list',
|
||||
form: {rule:'',route:'',method:'',name:'',domain:'',option:'',pattern:'', },
|
||||
timer: null,
|
||||
// 表单验证
|
||||
rules: {
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {},
|
||||
methods: {
|
||||
testApi(name) {
|
||||
let api_name = name.replace(/\\/g,"\\\\") //数据库存了含反斜杠的字段查询时转义成四个反斜杠
|
||||
this.$router.push({ path: "/apitester", query: { api_name} });
|
||||
},
|
||||
sync() {
|
||||
this.$http.post('apimanager/routelist/sync').then(res => {
|
||||
this.$message.success(res.message)
|
||||
this.handleRefresh()
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
@ -4,5 +4,6 @@ export default {
|
||||
// api测试
|
||||
apitester: () => import('@/views/apimanager/apitester'),
|
||||
apirun: () => import('@/views/apimanager/apirun'),
|
||||
apienv: () => import('@/views/apimanager/apienv')
|
||||
apienv: () => import('@/views/apimanager/apienv'),
|
||||
apimanager_routeList: () => import('@/views/apimanager/route_list/route_list'),
|
||||
}
|
||||
|
93
catch/apimanager/controller/RouteList.php
Normal file
93
catch/apimanager/controller/RouteList.php
Normal file
@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
namespace catchAdmin\apimanager\controller;
|
||||
|
||||
use catcher\base\CatchRequest as Request;
|
||||
use catcher\CatchResponse;
|
||||
use catcher\base\CatchController;
|
||||
use catchAdmin\apimanager\repository\RouteListRepository as RouteListModel;
|
||||
use think\Response;
|
||||
|
||||
class RouteList extends CatchController
|
||||
{
|
||||
|
||||
protected $routeListModel;
|
||||
|
||||
/**
|
||||
*
|
||||
* @time 2021/11/11 17:47
|
||||
* @param RouteListModel $routeListModel
|
||||
* @return mixed
|
||||
*/
|
||||
public function __construct(RouteListModel $routeListModel)
|
||||
{
|
||||
$this->routeListModel = $routeListModel;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @time 2021/11/11 17:47
|
||||
* @return Response
|
||||
*/
|
||||
public function index() : Response
|
||||
{
|
||||
return CatchResponse::paginate($this->routeListModel->getList());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @time 2021/11/11 17:47
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public function save(Request $request) : Response
|
||||
{
|
||||
return CatchResponse::success($this->routeListModel->storeBy($request->post()));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @time 2021/11/11 17:47
|
||||
* @param $id
|
||||
* @return Response
|
||||
*/
|
||||
public function read($id) : Response
|
||||
{
|
||||
return CatchResponse::success($this->routeListModel->findBy($id));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @time 2021/11/11 17:47
|
||||
* @param $id
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public function update($id, Request $request) : Response
|
||||
{
|
||||
return CatchResponse::success($this->routeListModel->updateBy($id, $request->post()));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @time 2021/11/11 17:47
|
||||
* @param $id
|
||||
* @return Response
|
||||
*/
|
||||
public function delete($id) : Response
|
||||
{
|
||||
return CatchResponse::success($this->routeListModel->deleteBy($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步
|
||||
*
|
||||
* @time 2021/11/11 17:47
|
||||
* @return \think\response\Json
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function sync()
|
||||
{
|
||||
return CatchResponse::success($this->routeListModel->sync());
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
use think\migration\Migrator;
|
||||
use think\migration\db\Column;
|
||||
use Phinx\Db\Adapter\MysqlAdapter;
|
||||
|
||||
class RouteList extends Migrator
|
||||
{
|
||||
/**
|
||||
* Change Method.
|
||||
*
|
||||
* Write your reversible migrations using this method.
|
||||
*
|
||||
* More information on writing migrations is available here:
|
||||
* http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
|
||||
*
|
||||
* The following commands can be used in this method and Phinx will
|
||||
* automatically reverse them when rolling back:
|
||||
*
|
||||
* createTable
|
||||
* renameTable
|
||||
* addColumn
|
||||
* renameColumn
|
||||
* addIndex
|
||||
* addForeignKey
|
||||
*
|
||||
* Remember to call "create()" or "update()" and NOT "save()" when working
|
||||
* with the Table class.
|
||||
*/
|
||||
public function change()
|
||||
{
|
||||
$table = $this->table('route_list', ['engine' => 'InnoDB', 'collation' => 'utf8mb4_general_ci', 'comment' => '路由表' ,'id' => 'id' ,'primary_key' => ['id']]);
|
||||
$table->addColumn('rule', 'string', ['limit' => 128,'null' => true,'signed' => true,'comment' => 'rule',])
|
||||
->addColumn('route', 'string', ['limit' => 256,'null' => true,'signed' => true,'comment' => 'route',])
|
||||
->addColumn('method', 'string', ['limit' => 16,'null' => true,'signed' => true,'comment' => 'method',])
|
||||
->addColumn('name', 'string', ['limit' => 256,'null' => true,'signed' => true,'comment' => 'name',])
|
||||
->addColumn('domain', 'string', ['limit' => 128,'null' => true,'signed' => true,'comment' => 'domain',])
|
||||
->addColumn('option', 'string', ['limit' => 256,'null' => true,'signed' => true,'comment' => 'option',])
|
||||
->addColumn('pattern', 'string', ['limit' => 128,'null' => true,'signed' => true,'comment' => 'pattern',])
|
||||
->addColumn('title', 'string', ['limit' => 128,'null' => true,'signed' => true,'comment' => 'title',])
|
||||
->addColumn('created_at', 'integer', ['limit' => MysqlAdapter::INT_REGULAR,'null' => false,'default' => 0,'signed' => false,'comment' => '创建时间',])
|
||||
->addColumn('updated_at', 'integer', ['limit' => MysqlAdapter::INT_REGULAR,'null' => false,'default' => 0,'signed' => false,'comment' => '更新时间',])
|
||||
->addColumn('deleted_at', 'integer', ['limit' => MysqlAdapter::INT_REGULAR,'null' => false,'default' => 0,'signed' => false,'comment' => '软删除字段',])
|
||||
->addColumn('creator_id', 'integer', ['limit' => MysqlAdapter::INT_REGULAR,'null' => false,'default' => 0,'signed' => false,'comment' => '创建人ID',])
|
||||
->addIndex(['name'], ['unique' => true,'name' => 'route_list_name'])
|
||||
->create();
|
||||
}
|
||||
}
|
@ -9,7 +9,6 @@
|
||||
// | Author: UCToo <contact@uctoo.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
use think\facade\Log;
|
||||
use think\migration\Seeder;
|
||||
|
||||
class ApimanagerMenusSeed extends Seeder
|
||||
@ -24,7 +23,6 @@ class ApimanagerMenusSeed extends Seeder
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
Log::write("ApimanagerMenusSeed",'debug');
|
||||
\catcher\Utils::importTreeData($this->getPermissions(), 'permissions', 'parent_id');
|
||||
}
|
||||
|
||||
@ -33,7 +31,7 @@ class ApimanagerMenusSeed extends Seeder
|
||||
return array (
|
||||
0 =>
|
||||
array (
|
||||
'id' => 136,
|
||||
'id' => 143,
|
||||
'permission_name' => 'API管理',
|
||||
'parent_id' => 0,
|
||||
'level' => '',
|
||||
@ -47,97 +45,430 @@ class ApimanagerMenusSeed extends Seeder
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'hidden' => 1,
|
||||
'sort' => 10,
|
||||
'created_at' => 1622926698,
|
||||
'updated_at' => 1622959419,
|
||||
'sort' => 1,
|
||||
'created_at' => 1621425807,
|
||||
'updated_at' => 1621427128,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
'id' => 144,
|
||||
'permission_name' => 'API分类',
|
||||
'parent_id' => 143,
|
||||
'level' => '',
|
||||
'route' => '/apicategory',
|
||||
'icon' => 'el-icon-s-grid',
|
||||
'module' => 'apimanager',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'apicategory',
|
||||
'component' => 'apicategory',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'hidden' => 1,
|
||||
'sort' => 10,
|
||||
'created_at' => 1621413029,
|
||||
'updated_at' => 1624010103,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
'id' => 145,
|
||||
'permission_name' => 'API测试列表',
|
||||
'parent_id' => 143,
|
||||
'level' => '',
|
||||
'route' => '/apitester',
|
||||
'icon' => 'el-icon-stopwatch',
|
||||
'module' => 'apimanager',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'apitester',
|
||||
'component' => 'apitester',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1621479275,
|
||||
'updated_at' => 1624010086,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
'id' => 146,
|
||||
'permission_name' => '列表',
|
||||
'parent_id' => 145,
|
||||
'level' => '',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'apimanager',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'apitester@index',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1621778966,
|
||||
'updated_at' => 1624010086,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
'id' => 147,
|
||||
'permission_name' => '创建',
|
||||
'parent_id' => 145,
|
||||
'level' => '',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'apimanager',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'apitester@save',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1621779011,
|
||||
'updated_at' => 1624010086,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
5 =>
|
||||
array (
|
||||
'id' => 148,
|
||||
'permission_name' => '更新',
|
||||
'parent_id' => 145,
|
||||
'level' => '',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'apimanager',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'apitester@update',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1621779033,
|
||||
'updated_at' => 1624010086,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
6 =>
|
||||
array (
|
||||
'id' => 149,
|
||||
'permission_name' => '读取',
|
||||
'parent_id' => 145,
|
||||
'level' => '',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'apimanager',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'apitester@read',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1621779051,
|
||||
'updated_at' => 1624010086,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
7 =>
|
||||
array (
|
||||
'id' => 150,
|
||||
'permission_name' => '删除',
|
||||
'parent_id' => 145,
|
||||
'level' => '',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'apimanager',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'apitester@delete',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1621779083,
|
||||
'updated_at' => 1624010086,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
8 =>
|
||||
array (
|
||||
'id' => 151,
|
||||
'permission_name' => '列表',
|
||||
'parent_id' => 144,
|
||||
'level' => '',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'apimanager',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'apicategory@index',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1621779121,
|
||||
'updated_at' => 1624010103,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
9 =>
|
||||
array (
|
||||
'id' => 152,
|
||||
'permission_name' => '创建',
|
||||
'parent_id' => 144,
|
||||
'level' => '',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'apimanager',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'apicategory@save',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1621779137,
|
||||
'updated_at' => 1624010103,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
10 =>
|
||||
array (
|
||||
'id' => 153,
|
||||
'permission_name' => '更新',
|
||||
'parent_id' => 144,
|
||||
'level' => '',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'apimanager',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'apicategory@update',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1621779154,
|
||||
'updated_at' => 1624010103,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
11 =>
|
||||
array (
|
||||
'id' => 154,
|
||||
'permission_name' => '读取',
|
||||
'parent_id' => 144,
|
||||
'level' => '',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'apimanager',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'apicategory@read',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1621779171,
|
||||
'updated_at' => 1624010103,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
12 =>
|
||||
array (
|
||||
'id' => 155,
|
||||
'permission_name' => '删除',
|
||||
'parent_id' => 144,
|
||||
'level' => '',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'apimanager',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'apicategory@delete',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1621779186,
|
||||
'updated_at' => 1624010103,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
13 =>
|
||||
array (
|
||||
'id' => 156,
|
||||
'permission_name' => 'API运行',
|
||||
'parent_id' => 143,
|
||||
'level' => '',
|
||||
'route' => '/apimanager/apirun',
|
||||
'icon' => 'el-icon-position',
|
||||
'module' => 'apimanager',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'apirun',
|
||||
'component' => 'apirun',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'hidden' => 2,
|
||||
'sort' => 1,
|
||||
'created_at' => 1621798022,
|
||||
'updated_at' => 1621831249,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
14 =>
|
||||
array (
|
||||
'id' => 161,
|
||||
'permission_name' => 'API环境变量',
|
||||
'parent_id' => 143,
|
||||
'level' => '',
|
||||
'route' => '/apienv',
|
||||
'icon' => 'el-icon-setting',
|
||||
'module' => 'apimanager',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'apienv',
|
||||
'component' => 'apienv',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1622176953,
|
||||
'updated_at' => 1622177106,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
15 =>
|
||||
array (
|
||||
'id' => 281,
|
||||
'permission_name' => '路由列表',
|
||||
'parent_id' => 143,
|
||||
'level' => '143',
|
||||
'route' => '/apimanager/routeList/curd',
|
||||
'icon' => 'el-icon-link',
|
||||
'module' => 'apimanager',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'routeList',
|
||||
'component' => 'apimanager_routeList',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'hidden' => 1,
|
||||
'sort' => 0,
|
||||
'created_at' => 1636624116,
|
||||
'updated_at' => 1636689266,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
16 =>
|
||||
array (
|
||||
'id' => 282,
|
||||
'permission_name' => '列表',
|
||||
'parent_id' => 281,
|
||||
'level' => '143-281',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'apimanager',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'routeList@index',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1636624117,
|
||||
'updated_at' => 1636689266,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
17 =>
|
||||
array (
|
||||
'id' => 283,
|
||||
'permission_name' => '保存',
|
||||
'parent_id' => 281,
|
||||
'level' => '143-281',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'apimanager',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'routeList@save',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1636624117,
|
||||
'updated_at' => 1636689266,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
18 =>
|
||||
array (
|
||||
'id' => 284,
|
||||
'permission_name' => '读取',
|
||||
'parent_id' => 281,
|
||||
'level' => '143-281',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'apimanager',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'routeList@read',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1636624118,
|
||||
'updated_at' => 1636689266,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
19 =>
|
||||
array (
|
||||
'id' => 285,
|
||||
'permission_name' => '更新',
|
||||
'parent_id' => 281,
|
||||
'level' => '143-281',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'apimanager',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'routeList@update',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1636624118,
|
||||
'updated_at' => 1636689266,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
20 =>
|
||||
array (
|
||||
'id' => 286,
|
||||
'permission_name' => '删除',
|
||||
'parent_id' => 281,
|
||||
'level' => '143-281',
|
||||
'route' => '',
|
||||
'icon' => '',
|
||||
'module' => 'apimanager',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'routeList@delete',
|
||||
'component' => '',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 2,
|
||||
'hidden' => 1,
|
||||
'sort' => 1,
|
||||
'created_at' => 1636624119,
|
||||
'updated_at' => 1636689266,
|
||||
'deleted_at' => 0,
|
||||
'children' =>
|
||||
array (
|
||||
0 =>
|
||||
array (
|
||||
'id' => 137,
|
||||
'permission_name' => 'API分类',
|
||||
'parent_id' => 136,
|
||||
'level' => '',
|
||||
'route' => '/apicategory',
|
||||
'icon' => 'el-icon-s-grid',
|
||||
'module' => 'apimanager',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'apicategory',
|
||||
'component' => 'apicategory',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'hidden' => 1,
|
||||
'sort' => 10,
|
||||
'created_at' => 1622928640,
|
||||
'updated_at' => 1622959419,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
1 =>
|
||||
array (
|
||||
'id' => 138,
|
||||
'permission_name' => 'API环境变量',
|
||||
'parent_id' => 136,
|
||||
'level' => '',
|
||||
'route' => '/apienv',
|
||||
'icon' => 'el-icon-setting',
|
||||
'module' => 'apimanager',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'apienv',
|
||||
'component' => 'apienv',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'hidden' => 1,
|
||||
'sort' => 9,
|
||||
'created_at' => 1622930243,
|
||||
'updated_at' => 1622959419,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
'id' => 140,
|
||||
'permission_name' => 'API测试列表',
|
||||
'parent_id' => 136,
|
||||
'level' => '',
|
||||
'route' => '/apitester',
|
||||
'icon' => 'el-icon-stopwatch',
|
||||
'module' => 'apimanager',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'apitester',
|
||||
'component' => 'apitester',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'hidden' => 1,
|
||||
'sort' => 8,
|
||||
'created_at' => 1622951640,
|
||||
'updated_at' => 1622959419,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
'id' => 141,
|
||||
'permission_name' => 'API运行',
|
||||
'parent_id' => 136,
|
||||
'level' => '',
|
||||
'route' => '/apimanager/apirun',
|
||||
'icon' => 'el-icon-position',
|
||||
'module' => 'apimanager',
|
||||
'creator_id' => 1,
|
||||
'permission_mark' => 'apirun',
|
||||
'component' => 'apirun',
|
||||
'redirect' => '',
|
||||
'keepalive' => 1,
|
||||
'type' => 1,
|
||||
'hidden' => 2,
|
||||
'sort' => 1,
|
||||
'created_at' => 1622951894,
|
||||
'updated_at' => 1622959419,
|
||||
'deleted_at' => 0,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
66
catch/apimanager/model/RouteList.php
Normal file
66
catch/apimanager/model/RouteList.php
Normal file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | UCToo [ Universal Convergence Technology ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2014-2021 https://www.uctoo.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: UCToo <contact@uctoo.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace catchAdmin\apimanager\model;
|
||||
|
||||
use catchAdmin\apimanager\model\search\RouteListSearch;
|
||||
use catcher\base\CatchModel as Model;
|
||||
/**
|
||||
*
|
||||
* @property int $id
|
||||
* @property string $rule
|
||||
* @property string $route
|
||||
* @property string $method
|
||||
* @property string $name
|
||||
* @property string $domain
|
||||
* @property string $option
|
||||
* @property string $pattern
|
||||
* @property string $title
|
||||
* @property int $created_at
|
||||
* @property int $updated_at
|
||||
* @property int $deleted_at
|
||||
* @property int $creator_id
|
||||
*/
|
||||
class RouteList extends Model
|
||||
{
|
||||
use RouteListSearch;
|
||||
public $field = [
|
||||
//
|
||||
'id',
|
||||
//
|
||||
'rule',
|
||||
//
|
||||
'route',
|
||||
//
|
||||
'method',
|
||||
//
|
||||
'name',
|
||||
//
|
||||
'domain',
|
||||
//
|
||||
'option',
|
||||
//
|
||||
'pattern',
|
||||
//
|
||||
'title',
|
||||
// 创建时间
|
||||
'created_at',
|
||||
// 更新时间
|
||||
'updated_at',
|
||||
// 软删除字段
|
||||
'deleted_at',
|
||||
// 创建人ID
|
||||
'creator_id',
|
||||
];
|
||||
|
||||
public $name = 'route_list';
|
||||
|
||||
}
|
50
catch/apimanager/model/search/RouteListSearch.php
Normal file
50
catch/apimanager/model/search/RouteListSearch.php
Normal file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | UCToo [ Universal Convergence Technology ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2014-2021 https://www.uctoo.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: UCToo <contact@uctoo.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace catchAdmin\apimanager\model\search;
|
||||
|
||||
use catchAdmin\apimanager\model\ApiCategory;
|
||||
|
||||
trait RouteListSearch
|
||||
{
|
||||
public function searchRuleAttr($query, $value, $data)
|
||||
{
|
||||
return $query->whereLike('rule', $value);
|
||||
}
|
||||
|
||||
public function searchRouteAttr($query, $value, $data)
|
||||
{
|
||||
return $query->whereLike('route', $value);
|
||||
}
|
||||
|
||||
public function searchMethodAttr($query, $value, $data)
|
||||
{
|
||||
return $query->whereLike('method', $value);
|
||||
}
|
||||
|
||||
public function searchNameAttr($query, $value, $data)
|
||||
{
|
||||
return $query->whereLike('name', $value);
|
||||
}
|
||||
public function searchDomainAttr($query, $value, $data)
|
||||
{
|
||||
return $query->whereLike('domain', $value);
|
||||
}
|
||||
public function searchOptionAttr($query, $value, $data)
|
||||
{
|
||||
return $query->whereLike('option', $value);
|
||||
}
|
||||
public function searchPatternAttr($query, $value, $data)
|
||||
{
|
||||
return $query->whereLike('pattern', $value);
|
||||
}
|
||||
|
||||
}
|
66
catch/apimanager/repository/RouteListRepository.php
Normal file
66
catch/apimanager/repository/RouteListRepository.php
Normal file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | UCToo [ Universal Convergence Technology ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2014-2021 https://www.uctoo.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: UCToo <contact@uctoo.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace catchAdmin\apimanager\repository;
|
||||
|
||||
use catchAdmin\permissions\middleware\PermissionsMiddleware;
|
||||
use catchAdmin\apimanager\model\RouteList;
|
||||
use catcher\base\CatchRepository;
|
||||
use catcher\exceptions\FailedException;
|
||||
use think\facade\Console;
|
||||
use think\facade\Log;
|
||||
use think\facade\Db;
|
||||
|
||||
class RouteListRepository extends CatchRepository
|
||||
{
|
||||
protected $routeList;
|
||||
|
||||
public function __construct(RouteList $routeList)
|
||||
{
|
||||
$this->routeList = $routeList;
|
||||
}
|
||||
|
||||
protected function model()
|
||||
{
|
||||
return $this->routeList;
|
||||
}
|
||||
|
||||
public function all()
|
||||
{
|
||||
$routeList = $this->routeList->select();
|
||||
|
||||
return $routeList->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步
|
||||
*
|
||||
* @time 2020年06月26日
|
||||
* @throws \Exception
|
||||
* @return bool
|
||||
*/
|
||||
public function sync()
|
||||
{
|
||||
DB::table('route_list')->delete(true);
|
||||
Console::call('route:list', ['-m']); //没用,也不是从命令生成的route_list文件读的数据,就是想执行一下命令
|
||||
$routeList = app()->route->getRuleList();
|
||||
$rows = [];
|
||||
foreach ($routeList as $item) {
|
||||
$item['route'] = $item['route'] instanceof \Closure ? '<Closure>' : $item['route'];
|
||||
$item['option'] = json_encode($item['option']);
|
||||
$item['pattern'] = json_encode($item['pattern']);
|
||||
$rows[] = $item;
|
||||
}
|
||||
$res = $this->routeList->saveAll($rows);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -23,4 +23,7 @@ $router->group(function () use ($router){
|
||||
$router->get('apiTesterUserenv/selectAPIenv/<id>', '\catchAdmin\apimanager\controller\ApiTesterUserenv@selectAPIenv');
|
||||
// apiTesterLog路由
|
||||
$router->resource('apiTesterLog', '\catchAdmin\apimanager\controller\ApiTesterLog');
|
||||
// routeList 路由
|
||||
$router->resource('routeList', catchAdmin\apimanager\controller\RouteList::class);
|
||||
$router->post('apimanager/routelist/sync', 'catchAdmin\apimanager\controller\RouteList@sync');
|
||||
})->middleware('auth');
|
10
public/index.html
Normal file
10
public/index.html
Normal file
@ -0,0 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>catchadmin app server</title>
|
||||
</head>
|
||||
<body>
|
||||
catchadmin app server V2.0.0
|
||||
</body>
|
||||
</html>
|
Loading…
x
Reference in New Issue
Block a user