refactor(系统设置): 自定义函数
This commit is contained in:
parent
09b0693187
commit
fbd163cdd4
|
@ -0,0 +1,12 @@
|
||||||
|
package io.metersphere.base.mapper.ext;
|
||||||
|
|
||||||
|
import io.metersphere.base.domain.CustomFunction;
|
||||||
|
import io.metersphere.controller.request.CustomFunctionRequest;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface ExtCustomFunctionMapper {
|
||||||
|
|
||||||
|
List<CustomFunction> queryAll(@Param("request")CustomFunctionRequest request);
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
||||||
|
<mapper namespace="io.metersphere.base.mapper.ext.ExtCustomFunctionMapper">
|
||||||
|
|
||||||
|
<select id="queryAll" resultType="io.metersphere.base.domain.CustomFunction">
|
||||||
|
select id, name, tags, type, description, create_time, update_time, project_id from custom_function
|
||||||
|
<where>
|
||||||
|
<if test="request.name != null and request.name!=''">
|
||||||
|
and (custom_function.name like CONCAT('%', #{request.name},'%')
|
||||||
|
or custom_function.tags like CONCAT('%', #{request.name},'%'))
|
||||||
|
</if>
|
||||||
|
<if test="request.projectId != null">
|
||||||
|
and custom_function.project_id = #{request.projectId}
|
||||||
|
</if>
|
||||||
|
<if test="request.type != null">
|
||||||
|
and custom_function.type = #{request.type}
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
|
@ -8,6 +8,7 @@ import io.metersphere.base.domain.CustomFunction;
|
||||||
import io.metersphere.base.domain.CustomFunctionExample;
|
import io.metersphere.base.domain.CustomFunctionExample;
|
||||||
import io.metersphere.base.domain.CustomFunctionWithBLOBs;
|
import io.metersphere.base.domain.CustomFunctionWithBLOBs;
|
||||||
import io.metersphere.base.mapper.CustomFunctionMapper;
|
import io.metersphere.base.mapper.CustomFunctionMapper;
|
||||||
|
import io.metersphere.base.mapper.ext.ExtCustomFunctionMapper;
|
||||||
import io.metersphere.commons.constants.ApiRunMode;
|
import io.metersphere.commons.constants.ApiRunMode;
|
||||||
import io.metersphere.commons.exception.MSException;
|
import io.metersphere.commons.exception.MSException;
|
||||||
import io.metersphere.commons.utils.BeanUtils;
|
import io.metersphere.commons.utils.BeanUtils;
|
||||||
|
@ -34,6 +35,8 @@ public class CustomFunctionService {
|
||||||
@Resource
|
@Resource
|
||||||
private CustomFunctionMapper customFunctionMapper;
|
private CustomFunctionMapper customFunctionMapper;
|
||||||
@Resource
|
@Resource
|
||||||
|
private ExtCustomFunctionMapper extCustomFunctionMapper;
|
||||||
|
@Resource
|
||||||
private JMeterService jMeterService;
|
private JMeterService jMeterService;
|
||||||
|
|
||||||
public CustomFunctionWithBLOBs save(CustomFunctionRequest request) {
|
public CustomFunctionWithBLOBs save(CustomFunctionRequest request) {
|
||||||
|
@ -76,17 +79,9 @@ public class CustomFunctionService {
|
||||||
String projectId = request.getProjectId();
|
String projectId = request.getProjectId();
|
||||||
if (StringUtils.isBlank(projectId)) {
|
if (StringUtils.isBlank(projectId)) {
|
||||||
projectId = SessionUtils.getCurrentProjectId();
|
projectId = SessionUtils.getCurrentProjectId();
|
||||||
|
request.setProjectId(projectId);
|
||||||
}
|
}
|
||||||
CustomFunctionExample example = new CustomFunctionExample();
|
return extCustomFunctionMapper.queryAll(request);
|
||||||
CustomFunctionExample.Criteria criteria = example.createCriteria();
|
|
||||||
criteria.andProjectIdEqualTo(projectId);
|
|
||||||
if (StringUtils.isNotBlank(request.getType())) {
|
|
||||||
criteria.andTypeEqualTo(request.getType());
|
|
||||||
}
|
|
||||||
if (StringUtils.isNotBlank(request.getName())) {
|
|
||||||
criteria.andNameEqualTo(request.getName());
|
|
||||||
}
|
|
||||||
return customFunctionMapper.selectByExample(example);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update(CustomFunctionRequest request) {
|
public void update(CustomFunctionRequest request) {
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
</el-link>
|
</el-link>
|
||||||
|
|
||||||
<custom-function-relate ref="customFunctionRelate" @addCustomFuncScript="addCustomFuncScript"/>
|
<custom-function-relate ref="customFunctionRelate" @addCustomFuncScript="addCustomFuncScript"/>
|
||||||
|
<!--接口列表-->
|
||||||
|
<api-func-relevance @save="apiSave" @close="apiClose" ref="apiFuncRelevance"/>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
|
@ -32,9 +34,11 @@
|
||||||
import MsCodeEdit from "../../../definition/components/MsCodeEdit";
|
import MsCodeEdit from "../../../definition/components/MsCodeEdit";
|
||||||
import MsDropdown from "../../../../common/components/MsDropdown";
|
import MsDropdown from "../../../../common/components/MsDropdown";
|
||||||
import CustomFunctionRelate from "@/business/components/settings/project/function/CustomFunctionRelate";
|
import CustomFunctionRelate from "@/business/components/settings/project/function/CustomFunctionRelate";
|
||||||
|
import {getCodeTemplate} from "@/business/components/settings/project/function/custom-function";
|
||||||
|
import ApiFuncRelevance from "@/business/components/settings/project/function/ApiFuncRelevance";
|
||||||
export default {
|
export default {
|
||||||
name: "Jsr233ProcessorContent",
|
name: "Jsr233ProcessorContent",
|
||||||
components: {MsDropdown, MsCodeEdit, CustomFunctionRelate},
|
components: {MsDropdown, MsCodeEdit, CustomFunctionRelate, ApiFuncRelevance},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
jsr223ProcessorData: {},
|
jsr223ProcessorData: {},
|
||||||
|
@ -100,8 +104,17 @@
|
||||||
title: "插入自定义函数",
|
title: "插入自定义函数",
|
||||||
command: "custom_function",
|
command: "custom_function",
|
||||||
index: "custom_function"
|
index: "custom_function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "从API定义导入",
|
||||||
|
command: "api_definition",
|
||||||
|
index: "api_definition"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "新API测试[JSON]",
|
||||||
|
command: "new_api_request",
|
||||||
|
index: "new_api_request"
|
||||||
}
|
}
|
||||||
|
|
||||||
],
|
],
|
||||||
isCodeEditAlive: true,
|
isCodeEditAlive: true,
|
||||||
languages: [
|
languages: [
|
||||||
|
@ -168,8 +181,74 @@
|
||||||
doFuncLink(funcLink) {
|
doFuncLink(funcLink) {
|
||||||
if (funcLink.command === 'custom_function') {
|
if (funcLink.command === 'custom_function') {
|
||||||
this.$refs.customFunctionRelate.open(this.jsr223ProcessorData.scriptLanguage);
|
this.$refs.customFunctionRelate.open(this.jsr223ProcessorData.scriptLanguage);
|
||||||
|
} else if (funcLink.command === 'api_definition') {
|
||||||
|
this.$refs.apiFuncRelevance.open();
|
||||||
|
} else if (funcLink.command === 'new_api_request') {
|
||||||
|
// requestObj为空则生产默认模版
|
||||||
|
let headers = new Map();
|
||||||
|
headers.set('Content-type', 'application/json');
|
||||||
|
let code = getCodeTemplate(this.jsr223ProcessorData.scriptLanguage, {requestHeaders: headers});
|
||||||
|
let codeStr = this.jsr223ProcessorData.script + "\n\n" + code;
|
||||||
|
this.jsr223ProcessorData.script = this.jsr223ProcessorData.script ? codeStr : code;
|
||||||
|
this.reload();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
apiSave(data, env) {
|
||||||
|
// data:选中的多个接口定义或多个接口用例; env: 关联页面选中的环境
|
||||||
|
let condition = env.config.httpConfig.conditions || [];
|
||||||
|
let requestUrl = "";
|
||||||
|
if (condition && condition.length > 0) {
|
||||||
|
// 如果有多个环境,取第一个
|
||||||
|
let protocol = condition[0].protocol ? condition[0].protocol : "http";
|
||||||
|
requestUrl = protocol + "://" + condition[0].socket;
|
||||||
|
}
|
||||||
|
// todo
|
||||||
|
if (data.length > 5) {
|
||||||
|
this.$warning("最多可以选择5个接口!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let code = "";
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.forEach(dt => {
|
||||||
|
let param = this.parseRequestObj(dt, requestUrl);
|
||||||
|
code += '\n' + getCodeTemplate(this.jsr223ProcessorData.scriptLanguage, param);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (code) {
|
||||||
|
let codeStr = this.jsr223ProcessorData.script + code;
|
||||||
|
this.jsr223ProcessorData.script = this.jsr223ProcessorData.script ? codeStr : code;
|
||||||
|
this.reload();
|
||||||
|
} else {
|
||||||
|
//todo
|
||||||
|
this.$warning("无对应语言模版");
|
||||||
|
}
|
||||||
|
this.$refs.apiFuncRelevance.close();
|
||||||
|
},
|
||||||
|
parseRequestObj(data, requestUrl) {
|
||||||
|
let requestHeaders = new Map();
|
||||||
|
let requestMethod = "";
|
||||||
|
let requestBody = "";
|
||||||
|
let request = JSON.parse(data.request);
|
||||||
|
// 拼接发送请求需要的参数
|
||||||
|
requestUrl = requestUrl + request.path;
|
||||||
|
requestMethod = request.method;
|
||||||
|
let headers = request.headers;
|
||||||
|
if (headers && headers.length > 0) {
|
||||||
|
headers.forEach(header => {
|
||||||
|
if (header.name) {
|
||||||
|
requestHeaders.set(header.name, header.value);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
let body = request.body;
|
||||||
|
if (body.json) {
|
||||||
|
requestBody = body.raw;
|
||||||
|
}
|
||||||
|
return {requestUrl, requestHeaders, requestMethod, requestBody}
|
||||||
|
},
|
||||||
|
apiClose() {
|
||||||
|
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -22,11 +22,12 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ApiEnvironmentConfig from "../../../test/components/ApiEnvironmentConfig";
|
|
||||||
import {parseEnvironment} from "../../../test/model/EnvironmentModel";
|
import {parseEnvironment} from "../../../test/model/EnvironmentModel";
|
||||||
export default {
|
export default {
|
||||||
name: "MsEnvironmentSelect",
|
name: "MsEnvironmentSelect",
|
||||||
components: {ApiEnvironmentConfig},
|
components: {
|
||||||
|
ApiEnvironmentConfig: () => import('@/business/components/api/test/components/ApiEnvironmentConfig')
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
environments: [],
|
environments: [],
|
||||||
|
|
|
@ -161,7 +161,7 @@ export default {
|
||||||
this.$get('/api/environment/get/' + environmentId, response => {
|
this.$get('/api/environment/get/' + environmentId, response => {
|
||||||
let environment = response.data;
|
let environment = response.data;
|
||||||
parseEnvironment(environment);
|
parseEnvironment(environment);
|
||||||
this.$emit("save", apis, environment, "API");
|
this.$emit("save", apis, environment);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -177,7 +177,7 @@ export default {
|
||||||
this.$get('/api/environment/get/' + environmentId, response => {
|
this.$get('/api/environment/get/' + environmentId, response => {
|
||||||
let environment = response.data;
|
let environment = response.data;
|
||||||
parseEnvironment(environment);
|
parseEnvironment(environment);
|
||||||
this.$emit("save", apiCases, environment, "CASE");
|
this.$emit("save", apiCases, environment);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<el-card class="table-card">
|
<el-card class="table-card">
|
||||||
<template v-slot:header>
|
<template v-slot:header>
|
||||||
<ms-table-header :show-create="false" :condition.sync="condition"
|
<ms-table-header :show-create="false" :condition.sync="condition"
|
||||||
:title="'自定义函数'" @search="init">
|
:title="'自定义函数'" @search="init" :tip="'根据 名称/标签 搜索'">
|
||||||
<template v-slot:button>
|
<template v-slot:button>
|
||||||
<ms-table-button icon="el-icon-circle-plus-outline" :content="'创建函数'" @click="handleCreate"/>
|
<ms-table-button icon="el-icon-circle-plus-outline" :content="'创建函数'" @click="handleCreate"/>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
style="width: 350px;float: left;"
|
style="width: 350px;float: left;"
|
||||||
:closable="false" show-icon>
|
:closable="false" show-icon>
|
||||||
</el-alert>
|
</el-alert>
|
||||||
<ms-table-search-bar :condition.sync="condition" @change="init" class="search-bar" :tip="'根据名称搜索'"/>
|
<ms-table-search-bar :condition.sync="condition" @change="init" class="search-bar" :tip="'根据 名称/标签 搜索'"/>
|
||||||
<el-table border class="adjust-table" :data="data" style="width: 100%" ref="table"
|
<el-table border class="adjust-table" :data="data" style="width: 100%" ref="table"
|
||||||
highlight-current-row @current-change="handleCurrentChange">
|
highlight-current-row @current-change="handleCurrentChange">
|
||||||
<el-table-column prop="name" :label="$t('commons.name')" show-overflow-tooltip/>
|
<el-table-column prop="name" :label="$t('commons.name')" show-overflow-tooltip/>
|
||||||
|
|
|
@ -231,10 +231,9 @@ export default {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "新API测试[JSON]",
|
title: "新API测试[JSON]",
|
||||||
command: "new_api",
|
command: "new_api_request",
|
||||||
index: "new_api"
|
index: "new_api_request"
|
||||||
}
|
}
|
||||||
|
|
||||||
],
|
],
|
||||||
response: {},
|
response: {},
|
||||||
request: {},
|
request: {},
|
||||||
|
@ -300,6 +299,14 @@ export default {
|
||||||
this.$refs.customFunctionRelate.open(this.form.type);
|
this.$refs.customFunctionRelate.open(this.form.type);
|
||||||
} else if (funcLink.command === 'api_definition') {
|
} else if (funcLink.command === 'api_definition') {
|
||||||
this.$refs.apiFuncRelevance.open();
|
this.$refs.apiFuncRelevance.open();
|
||||||
|
} else if (funcLink.command === 'new_api_request') {
|
||||||
|
// requestObj为空则生产默认模版
|
||||||
|
let headers = new Map();
|
||||||
|
headers.set('Content-type', 'application/json');
|
||||||
|
let code = getCodeTemplate(this.form.type, {requestHeaders: headers});
|
||||||
|
let codeStr = this.form.script + "\n\n" + code;
|
||||||
|
this.form.script = this.form.script ? codeStr : code;
|
||||||
|
this.reloadCodeEdit();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
reload() {
|
reload() {
|
||||||
|
@ -377,21 +384,43 @@ export default {
|
||||||
this.form.script = this.form.script + '\n\n' + script;
|
this.form.script = this.form.script + '\n\n' + script;
|
||||||
this.reloadCodeEdit();
|
this.reloadCodeEdit();
|
||||||
},
|
},
|
||||||
apiSave(data, env, type) {
|
apiSave(data, env) {
|
||||||
// data:选中的多个接口定义或多个接口用例。env: 关联页面选中的环境
|
// data:选中的多个接口定义或多个接口用例; env: 关联页面选中的环境
|
||||||
let condition = env.config.httpConfig.conditions || [];
|
let condition = env.config.httpConfig.conditions || [];
|
||||||
let requestUrl = "";
|
let requestUrl = "";
|
||||||
let requestHeaders = new Map;
|
|
||||||
let requestMethod = "";
|
|
||||||
let requestBody = "";
|
|
||||||
if (condition && condition.length > 0) {
|
if (condition && condition.length > 0) {
|
||||||
// 如果有多个环境,取第一个
|
// 如果有多个环境,取第一个
|
||||||
let protocol = condition[0].protocol ? condition[0].protocol : "http";
|
let protocol = condition[0].protocol ? condition[0].protocol : "http";
|
||||||
requestUrl = protocol + "://" + condition[0].socket;
|
requestUrl = protocol + "://" + condition[0].socket;
|
||||||
}
|
}
|
||||||
// todo
|
// todo
|
||||||
|
if (data.length > 5) {
|
||||||
|
this.$warning("最多可以选择5个接口!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let code = "";
|
||||||
if (data.length > 0) {
|
if (data.length > 0) {
|
||||||
let request = JSON.parse(data[0].request);
|
data.forEach(dt => {
|
||||||
|
let param = this.parseRequestObj(dt, requestUrl);
|
||||||
|
code += '\n' + getCodeTemplate(this.form.type, param);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (code) {
|
||||||
|
let codeStr = this.form.script + code;
|
||||||
|
this.form.script = this.form.script ? codeStr : code;
|
||||||
|
this.reloadCodeEdit();
|
||||||
|
} else {
|
||||||
|
//todo
|
||||||
|
this.$warning("无对应语言模版");
|
||||||
|
}
|
||||||
|
this.$refs.apiFuncRelevance.close();
|
||||||
|
},
|
||||||
|
parseRequestObj(data, requestUrl) {
|
||||||
|
let requestHeaders = new Map();
|
||||||
|
let requestMethod = "";
|
||||||
|
let requestBody = "";
|
||||||
|
let request = JSON.parse(data.request);
|
||||||
|
// 拼接发送请求需要的参数
|
||||||
requestUrl = requestUrl + request.path;
|
requestUrl = requestUrl + request.path;
|
||||||
requestMethod = request.method;
|
requestMethod = request.method;
|
||||||
let headers = request.headers;
|
let headers = request.headers;
|
||||||
|
@ -406,18 +435,7 @@ export default {
|
||||||
if (body.json) {
|
if (body.json) {
|
||||||
requestBody = body.raw;
|
requestBody = body.raw;
|
||||||
}
|
}
|
||||||
}
|
return {requestUrl, requestHeaders, requestMethod, requestBody}
|
||||||
let param = {requestUrl, requestHeaders, requestMethod, requestBody};
|
|
||||||
let code = getCodeTemplate(this.form.type, param);
|
|
||||||
if (code) {
|
|
||||||
let codeStr = this.form.script + "\n\n" + code;
|
|
||||||
this.form.script = this.form.script ? codeStr : code;
|
|
||||||
this.reloadCodeEdit();
|
|
||||||
} else {
|
|
||||||
//todo
|
|
||||||
this.$warning("无对应语言模版");
|
|
||||||
}
|
|
||||||
this.$refs.apiFuncRelevance.close();
|
|
||||||
},
|
},
|
||||||
apiClose() {
|
apiClose() {
|
||||||
|
|
||||||
|
|
|
@ -16,21 +16,31 @@ export function getCodeTemplate(language, requestObj) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function groovyCode(obj) {
|
function groovyCode(obj) {
|
||||||
let {requestHeaders, requestBody, requestUrl, requestMethod} = obj;
|
let {requestHeaders = new Map(), requestBody = "", requestUrl = "", requestMethod = ""} = obj;
|
||||||
let headers = "", body = JSON.stringify(requestBody);
|
let headers = "", body = JSON.stringify(requestBody);
|
||||||
for (let [k, v] of requestHeaders) {
|
for (let [k, v] of requestHeaders) {
|
||||||
|
// 拼装映射
|
||||||
headers += `['${k}':'${v}']`;
|
headers += `['${k}':'${v}']`;
|
||||||
}
|
}
|
||||||
return `
|
headers = headers === "" ? "[]" : headers;
|
||||||
import groovy.json.JsonOutput
|
let params = "";
|
||||||
|
params += `[
|
||||||
|
'url': '${requestUrl}',
|
||||||
|
'method': '${requestMethod}',
|
||||||
|
'headers': ${headers}, // 请求headers 例:['Content-type':'application/json']
|
||||||
|
'data': ${body} // 参数
|
||||||
|
]`
|
||||||
|
return `import groovy.json.JsonOutput
|
||||||
import groovy.json.JsonSlurper
|
import groovy.json.JsonSlurper
|
||||||
|
|
||||||
def http_post() {
|
def http_post() {
|
||||||
def headers = ${headers} // 请求headers 例:['Content-type':'application/json']
|
def params = ${params}
|
||||||
|
|
||||||
|
def headers = params['headers']
|
||||||
// json数据
|
// json数据
|
||||||
def data = ${body}
|
def data = params['data']
|
||||||
def conn = new URL("${requestUrl}").openConnection()
|
def conn = new URL(params['url']).openConnection()
|
||||||
conn.setRequestMethod("${requestMethod}")
|
conn.setRequestMethod(params['method'])
|
||||||
if (data) {
|
if (data) {
|
||||||
headers.each {
|
headers.each {
|
||||||
k,v -> conn.setRequestProperty(k, v);
|
k,v -> conn.setRequestProperty(k, v);
|
||||||
|
@ -46,6 +56,5 @@ def http_post() {
|
||||||
log.info(conn.content.text)
|
log.info(conn.content.text)
|
||||||
}
|
}
|
||||||
http_post()
|
http_post()
|
||||||
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue