api接口开发
This commit is contained in:
@@ -39,7 +39,7 @@ public class ApiCustomRequestController {
|
||||
@ResponseBody
|
||||
@PostMapping(value = "/add")
|
||||
public ResponseJson<Object> add(ApiCustomRequest apiCustomRequest) {
|
||||
apiCustomRequestService.addRequest(apiCustomRequest);
|
||||
return DocResponseJson.ok();
|
||||
ApiCustomRequest requestSaved = apiCustomRequestService.addRequest(apiCustomRequest);
|
||||
return DocResponseJson.ok(requestSaved);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,16 @@ public class ApiCustomDocVo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 接口ID
|
||||
*/
|
||||
private Long requestId;
|
||||
|
||||
/**
|
||||
* 文件夹ID
|
||||
*/
|
||||
private Long folderId;
|
||||
|
||||
/**
|
||||
* 接口名称
|
||||
*/
|
||||
@@ -102,4 +112,20 @@ public class ApiCustomDocVo implements Serializable {
|
||||
public void setMethod(String method) {
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
public Long getRequestId() {
|
||||
return requestId;
|
||||
}
|
||||
|
||||
public void setRequestId(Long requestId) {
|
||||
this.requestId = requestId;
|
||||
}
|
||||
|
||||
public Long getFolderId() {
|
||||
return folderId;
|
||||
}
|
||||
|
||||
public void setFolderId(Long folderId) {
|
||||
this.folderId = folderId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,11 @@ public class ApiCustomVo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 文件夹ID
|
||||
*/
|
||||
private Long folderId;
|
||||
|
||||
/**
|
||||
* 文件夹名称
|
||||
*/
|
||||
@@ -64,4 +69,12 @@ public class ApiCustomVo implements Serializable {
|
||||
public void setApis(List<ApiCustomDocVo> apis) {
|
||||
this.apis = apis;
|
||||
}
|
||||
|
||||
public Long getFolderId() {
|
||||
return folderId;
|
||||
}
|
||||
|
||||
public void setFolderId(Long folderId) {
|
||||
this.folderId = folderId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,5 +32,5 @@ public interface ApiCustomRequestService extends IService<ApiCustomRequest> {
|
||||
* @author 暮光:城中城
|
||||
* @since 2021-12-22
|
||||
*/
|
||||
void addRequest(ApiCustomRequest apiCustomRequest);
|
||||
ApiCustomRequest addRequest(ApiCustomRequest apiCustomRequest);
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ public class ApiCustomRequestServiceImpl extends ServiceImpl<ApiCustomRequestMap
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRequest(ApiCustomRequest apiCustomRequest) {
|
||||
public ApiCustomRequest addRequest(ApiCustomRequest apiCustomRequest) {
|
||||
apiDocAuthJudgeService.judgeDevelopAndThrow(apiCustomRequest.getDocId());
|
||||
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
|
||||
if (apiCustomRequest.getId() == null) {
|
||||
@@ -84,6 +84,7 @@ public class ApiCustomRequestServiceImpl extends ServiceImpl<ApiCustomRequestMap
|
||||
apiCustomRequest.setCreateUserName(null);
|
||||
}
|
||||
this.saveOrUpdate(apiCustomRequest);
|
||||
return apiCustomRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -103,6 +104,7 @@ public class ApiCustomRequestServiceImpl extends ServiceImpl<ApiCustomRequestMap
|
||||
List<ApiCustomVo> customGroupChildren = this.getCustomGroupChildren(children, apiGroupMap, apiMap);
|
||||
List<ApiCustomDocVo> apis = this.buildApiCustomDocVo(apiCustomList);
|
||||
ApiCustomVo apiCustomVo = new ApiCustomVo();
|
||||
apiCustomVo.setFolderId(customGroup.getId());
|
||||
apiCustomVo.setName(customGroup.getFolderName());
|
||||
apiCustomVo.setDesc(customGroup.getFolderDesc());
|
||||
apiCustomVo.setChildren(customGroupChildren);
|
||||
@@ -117,6 +119,8 @@ public class ApiCustomRequestServiceImpl extends ServiceImpl<ApiCustomRequestMap
|
||||
if (CollectionUtils.isNotEmpty(apiCustomList)) {
|
||||
for (ApiCustomRequest apiCustom : apiCustomList) {
|
||||
ApiCustomDocVo apiCustomDocVo = new ApiCustomDocVo();
|
||||
apiCustomDocVo.setRequestId(apiCustom.getId());
|
||||
apiCustomDocVo.setFolderId(apiCustom.getFolderId());
|
||||
apiCustomDocVo.setApiUrl(apiCustom.getApiUrl());
|
||||
apiCustomDocVo.setMethod(apiCustom.getMethod());
|
||||
apiCustomDocVo.setApiName(apiCustom.getApiName());
|
||||
|
||||
@@ -1,17 +1,11 @@
|
||||
package com.zyplayer.doc.db.framework.db.mapper.base;
|
||||
|
||||
import com.alibaba.druid.pool.DruidPooledConnection;
|
||||
import com.baomidou.mybatisplus.core.MybatisConfiguration;
|
||||
import com.zyplayer.doc.data.service.manage.DbHistoryService;
|
||||
import com.zyplayer.doc.db.framework.db.bean.DatabaseFactoryBean;
|
||||
import com.zyplayer.doc.db.framework.db.bean.DatabaseRegistrationBean;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.ibatis.builder.SqlSourceBuilder;
|
||||
import org.apache.ibatis.builder.StaticSqlSource;
|
||||
import org.apache.ibatis.mapping.BoundSql;
|
||||
import org.apache.ibatis.mapping.ParameterMapping;
|
||||
import org.apache.ibatis.parsing.GenericTokenParser;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Repository;
|
||||
@@ -20,7 +14,10 @@ import javax.annotation.Resource;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.util.*;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
@@ -35,14 +32,13 @@ public class SqlExecutor {
|
||||
|
||||
@Resource
|
||||
DatabaseRegistrationBean databaseRegistrationBean;
|
||||
@Resource
|
||||
DbHistoryService dbHistoryService;
|
||||
|
||||
// 执行中的PreparedStatement信息,用于强制取消执行
|
||||
private static final Map<String, PreparedStatement> statementMap = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 取消执行
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2019年8月18日
|
||||
*/
|
||||
@@ -62,6 +58,7 @@ public class SqlExecutor {
|
||||
|
||||
/**
|
||||
* 执行sql,返回结果
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2019年8月18日
|
||||
*/
|
||||
@@ -72,6 +69,7 @@ public class SqlExecutor {
|
||||
|
||||
/**
|
||||
* 执行sql,返回结果
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2019年8月18日
|
||||
*/
|
||||
@@ -82,6 +80,7 @@ public class SqlExecutor {
|
||||
|
||||
/**
|
||||
* 执行sql,可通过handler回调每一行的结果
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2019年8月18日
|
||||
*/
|
||||
@@ -89,9 +88,6 @@ public class SqlExecutor {
|
||||
if (factoryBean == null) {
|
||||
return ExecuteResult.error("未找到数据库连接", executeParam.getSql());
|
||||
}
|
||||
// BoundSql boundSql = getBoundSql(sql, paramMap);
|
||||
// sql = boundSql.getSql();
|
||||
// String sqlStr = SqlLogUtil.getSqlString(paramMap, boundSql);
|
||||
// 有参数的时候不输出日志,暂时只有导数据才有参数
|
||||
if (CollectionUtils.isEmpty(executeParam.getParamList())) {
|
||||
if (StringUtils.isNotBlank(executeParam.getPrefixSql())) {
|
||||
@@ -99,7 +95,6 @@ public class SqlExecutor {
|
||||
}
|
||||
logger.info("sql ==> {}", executeParam.getSql());
|
||||
}
|
||||
// List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
|
||||
PreparedStatement preparedStatement = null;
|
||||
PreparedStatement prefixStatement = null;
|
||||
DruidPooledConnection connection = null;
|
||||
@@ -181,16 +176,4 @@ public class SqlExecutor {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private BoundSql getBoundSql(String sql, Map<String, Object> paramMap){
|
||||
// 组装参数
|
||||
GenericTokenParser parser = new GenericTokenParser("${", "}", content -> {
|
||||
Object o = paramMap.get(content);
|
||||
return (o == null) ? null : String.valueOf(o);
|
||||
});
|
||||
sql = parser.parse(sql);
|
||||
SqlSourceBuilder sqlSourceBuilder = new SqlSourceBuilder(new MybatisConfiguration());
|
||||
StaticSqlSource parse = (StaticSqlSource) sqlSourceBuilder.parse(sql, Object.class, paramMap);
|
||||
return parse.getBoundSql(new Object());
|
||||
}
|
||||
}
|
||||
|
||||
4
zyplayer-doc-ui/api-ui/package-lock.json
generated
4
zyplayer-doc-ui/api-ui/package-lock.json
generated
@@ -214,7 +214,7 @@
|
||||
"dependencies": {
|
||||
"@ant-design/colors": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://r.cnpmjs.org/@ant-design/colors/download/@ant-design/colors-6.0.0.tgz",
|
||||
"resolved": "https://registry.npm.taobao.org/@ant-design/colors/download/@ant-design/colors-6.0.0.tgz",
|
||||
"integrity": "sha1-m5NmJXz/zEfbQrnQIDu1ksE8Apg=",
|
||||
"requires": {
|
||||
"@ctrl/tinycolor": "^3.4.0"
|
||||
@@ -1029,7 +1029,7 @@
|
||||
"dependencies": {
|
||||
"assert-plus": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://r.cnpmjs.org/assert-plus/download/assert-plus-1.0.0.tgz",
|
||||
"resolved": "https://registry.nlark.com/assert-plus/download/assert-plus-1.0.0.tgz",
|
||||
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
|
||||
"optional": true
|
||||
}
|
||||
|
||||
@@ -22,5 +22,8 @@ export const zyplayerApi = {
|
||||
docAuthList: data => apiClient({url: '/doc-api/doc/auth/list', method: 'post', data: data}),
|
||||
docAuthAssign: data => apiClient({url: '/doc-api/doc/auth/assign', method: 'post', data: data}),
|
||||
docAuthDelete: data => apiClient({url: '/doc-api/doc/auth/delete', method: 'post', data: data}),
|
||||
|
||||
apiCustomFolderAdd: data => apiClient({url: '/api-custom-folder/add', method: 'post', data: data}),
|
||||
apiCustomRequestAdd: data => apiClient({url: '/api-custom-request/add', method: 'post', data: data}),
|
||||
};
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ function getTreeDataChildren(customRequest, keywords, metaInfo, treeIndex) {
|
||||
customRequest.children.forEach(item => {
|
||||
let tempTreeId = treeIndex + "_" + indexFolder + "_" + indexApi;
|
||||
let treeChildren = getTreeDataChildren(item, keywords, metaInfo, tempTreeId);
|
||||
treeData.push({title: item.name, key: tempTreeId, children: treeChildren});
|
||||
treeData.push({title: item.name, key: tempTreeId, folderId: item.folderId, isLeaf: false, children: treeChildren});
|
||||
indexApi++;
|
||||
});
|
||||
}
|
||||
@@ -43,10 +43,11 @@ function getTreeDataChildren(customRequest, keywords, metaInfo, treeIndex) {
|
||||
key: tempTreeId,
|
||||
isLeaf: true,
|
||||
method: item.method,
|
||||
folderId: item.folderId,
|
||||
query: {
|
||||
...metaInfo,
|
||||
path: item.apiUrl,
|
||||
method: item.method,
|
||||
requestId: item.requestId,
|
||||
folderId: item.folderId,
|
||||
}
|
||||
});
|
||||
indexApi++;
|
||||
|
||||
@@ -71,6 +71,8 @@
|
||||
docChoiceId.value = parseInt(route.query.id);
|
||||
} else if (route.path === '/openapi/view' && route.query.id){
|
||||
docChoiceId.value = parseInt(route.query.id);
|
||||
} else if (route.path === '/custom/request' && route.query.id){
|
||||
docChoiceId.value = parseInt(route.query.id);
|
||||
} else {
|
||||
docChoiceId.value = docResourceList.value[0].id;
|
||||
}
|
||||
|
||||
@@ -1,42 +1,38 @@
|
||||
<template>
|
||||
<a-directory-tree :showIcon="false" :tree-data="treeData" v-model:expandedKeys="expandedKeys" @select="docChecked">
|
||||
<template #title="{ title, isLeaf, method, children, key }">
|
||||
<template v-if="key === 'info'">
|
||||
<template #title="record">
|
||||
<template v-if="record.key === 'info'">
|
||||
<file-text-outlined style="margin-right: 3px;"/>
|
||||
</template>
|
||||
<template v-if="isLeaf">
|
||||
<a-tag color="pink" v-if="method === 'get'">get</a-tag>
|
||||
<a-tag color="red" v-else-if="method === 'post'">post</a-tag>
|
||||
<a-tag color="orange" v-else-if="method === 'put'">put</a-tag>
|
||||
<a-tag color="green" v-else-if="method === 'head'">head</a-tag>
|
||||
<a-tag color="cyan" v-else-if="method === 'patch'">patch</a-tag>
|
||||
<a-tag color="blue" v-else-if="method === 'delete'">delete</a-tag>
|
||||
<a-tag color="purple" v-else-if="method === 'options'">options</a-tag>
|
||||
<a-tag color="purple" v-else-if="method === 'trace'">trace</a-tag>
|
||||
<template v-if="record.isLeaf">
|
||||
<a-tag color="pink" v-if="record.method === 'get'">get</a-tag>
|
||||
<a-tag color="red" v-else-if="record.method === 'post'">post</a-tag>
|
||||
<a-tag color="orange" v-else-if="record.method === 'put'">put</a-tag>
|
||||
<a-tag color="green" v-else-if="record.method === 'head'">head</a-tag>
|
||||
<a-tag color="cyan" v-else-if="record.method === 'patch'">patch</a-tag>
|
||||
<a-tag color="blue" v-else-if="record.method === 'delete'">delete</a-tag>
|
||||
<a-tag color="purple" v-else-if="record.method === 'options'">options</a-tag>
|
||||
<a-tag color="purple" v-else-if="record.method === 'trace'">trace</a-tag>
|
||||
</template>
|
||||
<span style="margin: 0 6px 0 3px;">{{title}}</span>
|
||||
<template v-if="children">
|
||||
<a-badge :count="children.length" :number-style="{backgroundColor: '#fff', color: '#999', boxShadow: '0 0 0 1px #d9d9d9 inset'}"/>
|
||||
<span style="margin: 0 6px 0 3px;">{{record.title}}</span>
|
||||
<template v-if="record.children">
|
||||
<a-badge :count="record.children.length" showZero :number-style="{backgroundColor: '#fff', color: '#999', boxShadow: '0 0 0 1px #d9d9d9 inset'}"/>
|
||||
<a-dropdown :trigger="['click']">
|
||||
<span @click.stop="" style="padding: 3px 10px;"><ellipsis-outlined /></span>
|
||||
<template #overlay>
|
||||
<a-menu>
|
||||
<a-menu-item>
|
||||
<plus-outlined />
|
||||
<a href="javascript:;"> 新建接口</a>
|
||||
<a-menu @click="handleMenuClick($event, record)">
|
||||
<a-menu-item key="newRequest">
|
||||
<plus-outlined /> 新建接口
|
||||
</a-menu-item>
|
||||
<a-menu-item>
|
||||
<folder-add-outlined />
|
||||
<a href="javascript:;"> 新建文件夹</a>
|
||||
<a-menu-item key="newFolder">
|
||||
<folder-add-outlined /> 新建文件夹
|
||||
</a-menu-item>
|
||||
<a-menu-divider />
|
||||
<a-menu-item>
|
||||
<edit-outlined />
|
||||
<a href="javascript:;"> 编辑</a>
|
||||
<a-menu-item key="edit">
|
||||
<edit-outlined /> 编辑
|
||||
</a-menu-item>
|
||||
<a-menu-item>
|
||||
<delete-outlined />
|
||||
<a href="javascript:;"> 删除</a>
|
||||
<a-menu-item key="delete">
|
||||
<delete-outlined /> 删除
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
@@ -63,21 +59,20 @@
|
||||
const router = useRouter();
|
||||
|
||||
let tagPathMap = ref({});
|
||||
let customRequestDoc = ref({});
|
||||
let customRequestDoc = {};
|
||||
let treeData = ref([]);
|
||||
let expandedKeys = ref([]);
|
||||
let choiceDocId = ref('');
|
||||
let expandedKeys = ref(['main']);
|
||||
let choiceDocId = '';
|
||||
let searchKeyword = '';
|
||||
|
||||
const docChecked = (val, node) => {
|
||||
if (node.node.key === 'info') {
|
||||
router.push({path: '/custom/info'});
|
||||
} else if (node.node.isLeaf) {
|
||||
if (node.node.isLeaf) {
|
||||
let dataRef = node.node.dataRef;
|
||||
router.push({path: '/custom/view', query: dataRef.query});
|
||||
router.push({path: '/custom/request', query: dataRef.query});
|
||||
}
|
||||
};
|
||||
const loadDoc = (docId, keyword, callback) => {
|
||||
choiceDocId.value = docId;
|
||||
choiceDocId = docId;
|
||||
zyplayerApi.apiDocApisDetail({id: docId}).then(res => {
|
||||
let v2Doc = res.data;
|
||||
if (!v2Doc && v2Doc.length != 1) {
|
||||
@@ -85,7 +80,7 @@
|
||||
message.error('获取文档数据失败');
|
||||
return;
|
||||
}
|
||||
customRequestDoc.value = v2Doc;
|
||||
customRequestDoc = v2Doc;
|
||||
store.commit('setCustomRequestDoc', v2Doc);
|
||||
loadTreeData(keyword);
|
||||
callback(true);
|
||||
@@ -94,12 +89,48 @@
|
||||
});
|
||||
};
|
||||
const loadTreeData = async (keyword) => {
|
||||
let metaInfo = {id: choiceDocId.value};
|
||||
treeData.value = getTreeDataForTag(customRequestDoc.value, keyword, metaInfo);
|
||||
let metaInfo = {id: choiceDocId};
|
||||
searchKeyword = keyword;
|
||||
treeData.value = getTreeDataForTag(customRequestDoc, keyword, metaInfo);
|
||||
treeData.value.unshift({key: 'info', title: '文档说明信息', isLeaf: true});
|
||||
await nextTick();
|
||||
expandedKeys.value = ['main'];
|
||||
};
|
||||
const handleMenuClick = (event, record) => {
|
||||
if (event.key === 'newFolder') {
|
||||
let params = {
|
||||
// id: '',
|
||||
docId: choiceDocId,
|
||||
parentFolderId: record.folderId,
|
||||
folderName: '新建文件夹',
|
||||
folderDesc: '',
|
||||
};
|
||||
zyplayerApi.apiCustomFolderAdd(params).then(res => {
|
||||
loadDoc(choiceDocId, searchKeyword);
|
||||
});
|
||||
} else if (event.key === 'newRequest') {
|
||||
let params = {
|
||||
// id: '',
|
||||
docId: choiceDocId,
|
||||
folderId: record.folderId,
|
||||
apiName: '新建接口',
|
||||
method: 'get',
|
||||
apiUrl: '',
|
||||
// formData: '测试xxx',
|
||||
// bodyData: '测试xxx',
|
||||
// headerData: '测试xxx',
|
||||
// cookieData: '测试xxx',
|
||||
};
|
||||
zyplayerApi.apiCustomRequestAdd(params).then(res => {
|
||||
loadDoc(choiceDocId, searchKeyword);
|
||||
let requestSaved = res.data;
|
||||
let queryInfo = {
|
||||
id: choiceDocId,
|
||||
requestId: requestSaved.id,
|
||||
folderId: requestSaved.folderId,
|
||||
};
|
||||
router.push({path: '/custom/request', query: queryInfo});
|
||||
});
|
||||
}
|
||||
};
|
||||
const toJsonObj = (value) => {
|
||||
if (typeof value !== 'string') {
|
||||
return value;
|
||||
@@ -121,6 +152,7 @@
|
||||
loadDoc,
|
||||
loadTreeData,
|
||||
treeData,
|
||||
handleMenuClick,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user