feat: API数据源支持Token认证 #9189

This commit is contained in:
taojinlong 2024-06-25 15:53:15 +08:00
parent fd79203282
commit 4c2db14934
11 changed files with 183 additions and 72 deletions

View File

@ -41,6 +41,9 @@ public class ApiUtils {
}; };
List<ApiDefinition> apiDefinitionList = JsonUtil.parseList(datasourceRequest.getDatasource().getConfiguration(), listTypeReference); List<ApiDefinition> apiDefinitionList = JsonUtil.parseList(datasourceRequest.getDatasource().getConfiguration(), listTypeReference);
for (ApiDefinition apiDefinition : apiDefinitionList) { for (ApiDefinition apiDefinition : apiDefinitionList) {
if (StringUtils.isNotEmpty(apiDefinition.getType()) && apiDefinition.getType().equalsIgnoreCase("params")) {
continue;
}
DatasetTableDTO datasetTableDTO = new DatasetTableDTO(); DatasetTableDTO datasetTableDTO = new DatasetTableDTO();
datasetTableDTO.setTableName(apiDefinition.getDeTableName()); datasetTableDTO.setTableName(apiDefinition.getDeTableName());
datasetTableDTO.setName(apiDefinition.getName()); datasetTableDTO.setName(apiDefinition.getName());
@ -59,7 +62,7 @@ public class ApiUtils {
if (apiDefinition == null) { if (apiDefinition == null) {
DEException.throwException("未找到"); DEException.throwException("未找到");
} }
String response = execHttpRequest(apiDefinition, apiDefinition.getApiQueryTimeout() == null || apiDefinition.getApiQueryTimeout() <= 0 ? 10 : apiDefinition.getApiQueryTimeout()); String response = execHttpRequest(apiDefinition, apiDefinition.getApiQueryTimeout() == null || apiDefinition.getApiQueryTimeout() <= 0 ? 10 : apiDefinition.getApiQueryTimeout(), params(datasourceRequest));
fieldList = getTableFields(apiDefinition); fieldList = getTableFields(apiDefinition);
result.put("fieldList", fieldList); result.put("fieldList", fieldList);
dataList = fetchResult(response, apiDefinition); dataList = fetchResult(response, apiDefinition);
@ -116,19 +119,38 @@ public class ApiUtils {
if (apiDefinition == null) { if (apiDefinition == null) {
DEException.throwException("未找到"); DEException.throwException("未找到");
} }
String response = execHttpRequest(apiDefinition, apiDefinition.getApiQueryTimeout() == null || apiDefinition.getApiQueryTimeout() <= 0 ? 10 : apiDefinition.getApiQueryTimeout()); String response = execHttpRequest(apiDefinition, apiDefinition.getApiQueryTimeout() == null || apiDefinition.getApiQueryTimeout() <= 0 ? 10 : apiDefinition.getApiQueryTimeout(), params(datasourceRequest));
return fetchResult(response, apiDefinition); return fetchResult(response, apiDefinition);
} }
public static String execHttpRequest(ApiDefinition apiDefinition, int socketTimeout) { public static String execHttpRequest(ApiDefinition apiDefinition, int socketTimeout, List<ApiDefinition> paramsList) {
String response = ""; String response = "";
HttpClientConfig httpClientConfig = new HttpClientConfig(); HttpClientConfig httpClientConfig = new HttpClientConfig();
httpClientConfig.setSocketTimeout(socketTimeout * 1000); httpClientConfig.setSocketTimeout(socketTimeout * 1000);
ApiDefinitionRequest apiDefinitionRequest = apiDefinition.getRequest(); ApiDefinitionRequest apiDefinitionRequest = apiDefinition.getRequest();
for (Map header : apiDefinitionRequest.getHeaders()) { for (Map header : apiDefinitionRequest.getHeaders()) {
if (header.get("name") != null && StringUtils.isNotEmpty(header.get("name").toString()) && header.get("value") != null && StringUtils.isNotEmpty(header.get("value").toString())) { if (header.get("name") != null && StringUtils.isNotEmpty(header.get("name").toString()) && header.get("value") != null && StringUtils.isNotEmpty(header.get("value").toString())) {
httpClientConfig.addHeader(header.get("name").toString(), header.get("value").toString()); if (header.get("nameType") != null && header.get("nameType").toString().equalsIgnoreCase("params")) {
String param = header.get("value").toString();
for (ApiDefinition definition : paramsList) {
for (int i = 0; i < definition.getFields().size(); i++) {
TableField field = definition.getFields().get(i);
if (field.getOriginName().equalsIgnoreCase(param)) {
String resultStr = execHttpRequest(definition, definition.getApiQueryTimeout() == null || apiDefinition.getApiQueryTimeout() <= 0 ? 10 : apiDefinition.getApiQueryTimeout(), null);
List<String[]> dataList = fetchResult(resultStr, definition);
System.out.println(dataList.get(0)[i]);
if (dataList.size() > 0) {
httpClientConfig.addHeader(header.get("name").toString(), dataList.get(0)[i]);
}
}
}
}
} else {
httpClientConfig.addHeader(header.get("name").toString(), header.get("value").toString());
}
} }
} }
if (apiDefinitionRequest.getAuthManager() != null if (apiDefinitionRequest.getAuthManager() != null
@ -194,7 +216,7 @@ public class ApiUtils {
return response; return response;
} }
private static void previewNum(List<Map<String, Object>> field){ private static void previewNum(List<Map<String, Object>> field) {
for (Map<String, Object> stringObjectMap : field) { for (Map<String, Object> stringObjectMap : field) {
JSONArray newArray = new JSONArray(); JSONArray newArray = new JSONArray();
if (stringObjectMap.get("value") != null) { if (stringObjectMap.get("value") != null) {
@ -202,7 +224,7 @@ public class ApiUtils {
TypeReference<JSONArray> listTypeReference = new TypeReference<JSONArray>() { TypeReference<JSONArray> listTypeReference = new TypeReference<JSONArray>() {
}; };
JSONArray array = objectMapper.readValue(stringObjectMap.get("value").toString(), listTypeReference); JSONArray array = objectMapper.readValue(stringObjectMap.get("value").toString(), listTypeReference);
if(array.size() > 100){ if (array.size() > 100) {
for (int i = 0; i < Math.min(100, array.size()); i++) { for (int i = 0; i < Math.min(100, array.size()); i++) {
newArray.add(array.get(i)); newArray.add(array.get(i));
} }
@ -254,8 +276,8 @@ public class ApiUtils {
} }
int i = 0; int i = 0;
try { try {
LinkedHashMap data = currentData.get(0); LinkedHashMap data = currentData.get(0);
}catch (Exception e){ } catch (Exception e) {
DEException.throwException("数据不符合规范, " + e.getMessage()); DEException.throwException("数据不符合规范, " + e.getMessage());
} }
for (LinkedHashMap data : currentData) { for (LinkedHashMap data : currentData) {
@ -540,6 +562,18 @@ public class ApiUtils {
} }
private static List<ApiDefinition> params(DatasourceRequest datasourceRequest) {
TypeReference<List<ApiDefinition>> listTypeReference = new TypeReference<List<ApiDefinition>>() {
};
List<ApiDefinition> apiDefinitionListTemp = null;
try {
apiDefinitionListTemp = objectMapper.readValue(datasourceRequest.getDatasource().getConfiguration(), listTypeReference);
} catch (Exception e) {
DEException.throwException(e);
}
return apiDefinitionListTemp.stream().filter(apiDefinition -> apiDefinition.getType() != null && apiDefinition.getType().equalsIgnoreCase("params")).collect(Collectors.toList());
}
private static ApiDefinition checkApiDefinition(DatasourceRequest datasourceRequest) throws DEException { private static ApiDefinition checkApiDefinition(DatasourceRequest datasourceRequest) throws DEException {
List<ApiDefinition> apiDefinitionList = new ArrayList<>(); List<ApiDefinition> apiDefinitionList = new ArrayList<>();
TypeReference<List<ApiDefinition>> listTypeReference = new TypeReference<List<ApiDefinition>>() { TypeReference<List<ApiDefinition>> listTypeReference = new TypeReference<List<ApiDefinition>>() {

View File

@ -107,6 +107,8 @@ public class DatasourceServer implements DatasourceApi {
all_scope, add_scope all_scope, add_scope
} }
private TypeReference<List<ApiDefinition>> listTypeReference = new TypeReference<List<ApiDefinition>>() {
};
@Resource @Resource
private CommonThreadPool commonThreadPool; private CommonThreadPool commonThreadPool;
@ -505,11 +507,11 @@ public class DatasourceServer implements DatasourceApi {
DEException.throwException("不存在的数据源!"); DEException.throwException("不存在的数据源!");
} }
BeanUtils.copyBean(datasourceDTO, datasource); BeanUtils.copyBean(datasourceDTO, datasource);
TypeReference<List<ApiDefinition>> listTypeReference = new TypeReference<List<ApiDefinition>>() {
};
if (datasourceDTO.getType().equalsIgnoreCase(DatasourceConfiguration.DatasourceType.API.toString())) { if (datasourceDTO.getType().equalsIgnoreCase(DatasourceConfiguration.DatasourceType.API.toString())) {
List<ApiDefinition> apiDefinitionList = JsonUtil.parseList(datasourceDTO.getConfiguration(), listTypeReference); List<ApiDefinition> apiDefinitionList = JsonUtil.parseList(datasourceDTO.getConfiguration(), listTypeReference);
List<ApiDefinition> apiDefinitionListWithStatus = new ArrayList<>(); List<ApiDefinition> apiDefinitionListWithStatus = new ArrayList<>();
List<ApiDefinition> params = new ArrayList<>();
int success = 0; int success = 0;
for (ApiDefinition apiDefinition : apiDefinitionList) { for (ApiDefinition apiDefinition : apiDefinitionList) {
String status = null; String status = null;
@ -534,9 +536,16 @@ public class DatasourceServer implements DatasourceApi {
if (log != null) { if (log != null) {
apiDefinition.setUpdateTime(log.getStartTime()); apiDefinition.setUpdateTime(log.getStartTime());
} }
apiDefinitionListWithStatus.add(apiDefinition);
if (StringUtils.isEmpty(apiDefinition.getType()) || apiDefinition.getType().equalsIgnoreCase("table")) {
apiDefinitionListWithStatus.add(apiDefinition);
} else {
params.add(apiDefinition);
}
} }
datasourceDTO.setApiConfigurationStr(new String(Base64.getEncoder().encode(Objects.requireNonNull(JsonUtil.toJSONString(apiDefinitionListWithStatus)).toString().getBytes()))); datasourceDTO.setApiConfigurationStr(new String(Base64.getEncoder().encode(Objects.requireNonNull(JsonUtil.toJSONString(apiDefinitionListWithStatus)).toString().getBytes())));
datasourceDTO.setParamsStr(new String(Base64.getEncoder().encode(Objects.requireNonNull(JsonUtil.toJSONString(params)).toString().getBytes())));
if (success == apiDefinitionList.size()) { if (success == apiDefinitionList.size()) {
datasourceDTO.setStatus("Success"); datasourceDTO.setStatus("Success");
} else { } else {
@ -847,12 +856,13 @@ public class DatasourceServer implements DatasourceApi {
} }
public ApiDefinition checkApiDatasource(Map<String, String> request) throws DEException { public ApiDefinition checkApiDatasource(Map<String, String> request) throws DEException {
ApiDefinition apiDefinition = JsonUtil.parseObject(new String(java.util.Base64.getDecoder().decode(request.get("data"))), ApiDefinition.class); ApiDefinition apiDefinition = JsonUtil.parseObject(new String(java.util.Base64.getDecoder().decode(request.get("data"))), ApiDefinition.class);
String response = ApiUtils.execHttpRequest(apiDefinition, apiDefinition.getApiQueryTimeout() == null || apiDefinition.getApiQueryTimeout() <= 0 ? 10 : apiDefinition.getApiQueryTimeout()); List<ApiDefinition> paramsList = JsonUtil.parseList(new String(java.util.Base64.getDecoder().decode(request.get("paramsList"))), listTypeReference);
String response = ApiUtils.execHttpRequest(apiDefinition, apiDefinition.getApiQueryTimeout() == null || apiDefinition.getApiQueryTimeout() <= 0 ? 10 : apiDefinition.getApiQueryTimeout(), paramsList);
if (request.keySet().contains("type") && request.get("type").equals("apiStructure")) { if (request.keySet().contains("type") && request.get("type").equals("apiStructure")) {
apiDefinition.setShowApiStructure(true); apiDefinition.setShowApiStructure(true);
} }
ApiUtils.checkApiDefinition(apiDefinition, response); ApiUtils.checkApiDefinition(apiDefinition, response);
if (apiDefinition.getRequest().getAuthManager() != null && StringUtils.isNotBlank(apiDefinition.getRequest().getAuthManager().getUsername()) && StringUtils.isNotBlank(apiDefinition.getRequest().getAuthManager().getPassword()) && apiDefinition.getRequest().getAuthManager().getVerification().equals("Basic Auth")) { if (apiDefinition.getRequest().getAuthManager() != null && StringUtils.isNotBlank(apiDefinition.getRequest().getAuthManager().getUsername()) && StringUtils.isNotBlank(apiDefinition.getRequest().getAuthManager().getPassword()) && apiDefinition.getRequest().getAuthManager().getVerification().equals("Basic Auth")) {
apiDefinition.getRequest().getAuthManager().setUsername(new String(Base64.getEncoder().encode(apiDefinition.getRequest().getAuthManager().getUsername().getBytes()))); apiDefinition.getRequest().getAuthManager().setUsername(new String(Base64.getEncoder().encode(apiDefinition.getRequest().getAuthManager().getUsername().getBytes())));

View File

@ -24,6 +24,7 @@ export interface Field {
export interface ApiItem { export interface ApiItem {
status: string status: string
name: string name: string
type: string
deTableName?: string deTableName?: string
url: string url: string
method: string method: string
@ -57,10 +58,12 @@ const originFieldItem = reactive({
}) })
let apiItemList = reactive<ApiConfiguration[]>([]) let apiItemList = reactive<ApiConfiguration[]>([])
let paramsList = reactive<ApiConfiguration[]>([])
let apiItem = reactive<ApiItem>({ let apiItem = reactive<ApiItem>({
status: '', status: '',
name: '', name: '',
type: 'table',
url: '', url: '',
method: 'GET', method: 'GET',
request: { request: {
@ -95,6 +98,7 @@ const edit_api_item = ref(false)
const active = ref(1) const active = ref(1)
const loading = ref(false) const loading = ref(false)
const columns = shallowRef([]) const columns = shallowRef([])
const valueList = shallowRef([])
const tableData = shallowRef([]) const tableData = shallowRef([])
const apiItemBasicInfo = ref<FormInstance>() const apiItemBasicInfo = ref<FormInstance>()
const isNumber = (rule, value, callback) => { const isNumber = (rule, value, callback) => {
@ -152,9 +156,16 @@ const rule = reactive<FormRules>({
}) })
const activeName = ref('third') const activeName = ref('third')
provide('api-active-name', activeName) provide('api-active-name', activeName)
const initApiItem = (val: ApiItem, apiList, name) => { const initApiItem = (val: ApiItem, from, name) => {
activeName.value = name activeName.value = name
apiItemList = apiList apiItemList = from.apiConfiguration
paramsList = from.paramsConfiguration
if (val.type !== 'params') {
valueList.value = []
for (let i = 0; i < paramsList.length; i++) {
valueList.value = valueList.value.concat(paramsList[i].fields)
}
}
Object.assign(apiItem, val) Object.assign(apiItem, val)
edit_api_item.value = true edit_api_item.value = true
active.value = 0 active.value = 0
@ -167,9 +178,10 @@ const showApiData = () => {
apiItemBasicInfo.value.validate(valid => { apiItemBasicInfo.value.validate(valid => {
if (valid) { if (valid) {
const data = Base64.encode(JSON.stringify(apiItem)) const data = Base64.encode(JSON.stringify(apiItem))
const params = Base64.encode(JSON.stringify(paramsList))
loading.value = true loading.value = true
cancelMap['/datasource/checkApiDatasource']?.() cancelMap['/datasource/checkApiDatasource']?.()
checkApiItem({ data: data, type: 'apiStructure' }) checkApiItem({ data: data, type: 'apiStructure', paramsList: params })
.then(response => { .then(response => {
originFieldItem.jsonFields = response.data.jsonFields originFieldItem.jsonFields = response.data.jsonFields
}) })
@ -203,7 +215,7 @@ const fieldOptions = [
] ]
const disabledNext = ref(false) const disabledNext = ref(false)
const saveItem = () => { const saveItem = () => {
if (apiItem.fields.length === 0) { if (apiItem.type !== 'params' && apiItem.fields.length === 0) {
ElMessage.error(t('datasource.api_field_not_empty')) ElMessage.error(t('datasource.api_field_not_empty'))
return return
} }
@ -239,7 +251,8 @@ const next = () => {
} }
cancelMap['/datasource/checkApiDatasource']?.() cancelMap['/datasource/checkApiDatasource']?.()
checkApiItem({ data: Base64.encode(JSON.stringify(apiItem)) }) const params = Base64.encode(JSON.stringify(paramsList))
checkApiItem({ data: Base64.encode(JSON.stringify(apiItem)), paramsList: params })
.then(response => { .then(response => {
apiItem.jsonFields = response.data.jsonFields apiItem.jsonFields = response.data.jsonFields
apiItem.fields = [] apiItem.fields = []
@ -465,6 +478,7 @@ defineExpose({
<api-http-request-form <api-http-request-form
v-if="edit_api_item" v-if="edit_api_item"
:request="apiItem.request" :request="apiItem.request"
:value-list="valueList"
@changeId="changeId" @changeId="changeId"
/> />
</el-form-item> </el-form-item>
@ -572,7 +586,11 @@ defineExpose({
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="deExtractType" :label="t('datasource.field_type')"> <el-table-column
prop="deExtractType"
:label="t('datasource.field_type')"
:disabled="apiItem.type == 'params'"
>
<template #default="scope"> <template #default="scope">
<el-select <el-select
v-model="scope.row.deExtractType" v-model="scope.row.deExtractType"

View File

@ -22,6 +22,10 @@ const props = defineProps({
type: Boolean, type: Boolean,
default: true default: true
}, },
valueList: {
type: Array as PropType<Item[]>,
default: () => []
},
request: { request: {
type: Object as PropType<ApiRequest>, type: Object as PropType<ApiRequest>,
default: () => ({ default: () => ({
@ -143,6 +147,7 @@ const emits = defineEmits(['changeId'])
:show-desc="true" :show-desc="true"
:suggestions="headerSuggestions" :suggestions="headerSuggestions"
:items="apiRequest.headers" :items="apiRequest.headers"
:value-list="valueList"
/> />
</el-tab-pane> </el-tab-pane>

View File

@ -22,6 +22,10 @@ const props = defineProps({
type: Array as PropType<Item[]>, type: Array as PropType<Item[]>,
default: () => [] default: () => []
}, },
valueList: {
type: Array as PropType<Item[]>,
default: () => []
},
suggestions: { suggestions: {
type: Array, type: Array,
default: () => [] default: () => []
@ -78,7 +82,6 @@ const options = [
value: 'fixed' value: 'fixed'
} }
] ]
const value = ref('') const value = ref('')
</script> </script>
@ -91,7 +94,7 @@ const value = ref('')
<el-icon class="drag handle"> <el-icon class="drag handle">
<Icon name="icon_drag_outlined"></Icon> <Icon name="icon_drag_outlined"></Icon>
</el-icon> </el-icon>
<el-col :span="activeName === 'third' ? 8 : 6" v-if="!unShowSelect"> <el-col :span="activeName === 'params' ? 8 : 6" v-if="!unShowSelect">
<el-input <el-input
v-if="!suggestions" v-if="!suggestions"
v-model="element.name" v-model="element.name"
@ -110,8 +113,8 @@ const value = ref('')
show-word-limit show-word-limit
/> />
</el-col> </el-col>
<el-col :span="3" v-if="activeName === 'fourth'"> <el-col :span="3" v-if="activeName === 'table'">
<el-select v-model="value"> <el-select v-model="element.nameType">
<el-option <el-option
v-for="item in options" v-for="item in options"
:key="item.value" :key="item.value"
@ -131,19 +134,31 @@ const value = ref('')
/> />
</el-col> </el-col>
<el-col :span="activeName === 'third' ? 7 : 6"> <el-col :span="activeName === 'params' ? 7 : 6">
<el-input <el-input
v-if="!needMock && activeName === 'third'" v-if="!needMock && activeName === 'params'"
v-model="element.value" v-model="element.value"
:disabled="isReadOnly" :disabled="isReadOnly"
:placeholder="unShowSelect ? t('common.description') : valueText" :placeholder="unShowSelect ? t('common.description') : valueText"
show-word-limit show-word-limit
/> />
<el-select
v-model="element.value"
v-if="!needMock && activeName === 'table' && element.nameType === 'params'"
>
<el-option
v-for="item in valueList"
:key="item.originName"
:label="item.name"
:value="item.originName"
/>
</el-select>
<el-input <el-input
v-if="!needMock && activeName === 'fourth'" v-if="!needMock && activeName === 'table' && element.nameType !== 'params'"
v-model="element.value" v-model="element.value"
:disabled="isReadOnly" :disabled="isReadOnly"
:placeholder="value === 'params' ? '参数名称' : '值'" :placeholder="'值'"
show-word-limit show-word-limit
/> />
</el-col> </el-col>

View File

@ -27,6 +27,7 @@ const prop = defineProps({
syncSetting?: SyncSetting syncSetting?: SyncSetting
configuration?: Configuration configuration?: Configuration
apiConfiguration?: ApiConfiguration[] apiConfiguration?: ApiConfiguration[]
paramsConfiguration?: ApiConfiguration[]
}>({ }>({
id: 0, id: 0,
name: '', name: '',
@ -80,6 +81,7 @@ const defaultApiItem = {
name: '', name: '',
deTableName: '', deTableName: '',
url: '', url: '',
type: '',
serialNumber: 0, serialNumber: 0,
method: 'GET', method: 'GET',
request: { request: {
@ -319,17 +321,24 @@ const addApiItem = item => {
apiItem = cloneDeep(item) apiItem = cloneDeep(item)
} else { } else {
apiItem = cloneDeep(defaultApiItem) apiItem = cloneDeep(defaultApiItem)
apiItem.serialNumber = apiItem.type = activeName.value
let serialNumber1 =
form.value.apiConfiguration.length > 0 form.value.apiConfiguration.length > 0
? form.value.apiConfiguration[form.value.apiConfiguration.length - 1].serialNumber + 1 ? form.value.apiConfiguration[form.value.apiConfiguration.length - 1].serialNumber + 1
: 0 : 0
let serialNumber2 =
form.value.paramsConfiguration.length > 0
? form.value.paramsConfiguration[form.value.paramsConfiguration.length - 1].serialNumber + 1
: 0
apiItem.serialNumber = serialNumber1 + serialNumber2
} }
nextTick(() => { nextTick(() => {
editApiItem.value.initApiItem(apiItem, form.value.apiConfiguration, activeName.value) editApiItem.value.initApiItem(apiItem, form.value, activeName.value)
}) })
} }
const activeName = ref('third') const activeName = ref('table')
const showPriority = ref(false) const showPriority = ref(false)
const deleteItem = (item, idx) => { const deleteItem = (item, idx) => {
@ -354,15 +363,28 @@ const resetForm = () => {
const returnItem = apiItem => { const returnItem = apiItem => {
var find = false var find = false
for (let i = 0; i < form.value.apiConfiguration.length; i++) { if (apiItem.type !== 'params') {
if (form.value.apiConfiguration[i].serialNumber === apiItem.serialNumber) { for (let i = 0; i < form.value.apiConfiguration.length; i++) {
find = true if (form.value.apiConfiguration[i].serialNumber === apiItem.serialNumber) {
form.value.apiConfiguration[i] = apiItem find = true
form.value.apiConfiguration[i] = apiItem
}
}
if (!find) {
state.itemRef = []
form.value.apiConfiguration.push(apiItem)
}
} else {
for (let i = 0; i < form.value.paramsConfiguration.length; i++) {
if (form.value.paramsConfiguration[i].serialNumber === apiItem.serialNumber) {
find = true
form.value.paramsConfiguration[i] = apiItem
}
}
if (!find) {
state.itemRef = []
form.value.paramsConfiguration.push(apiItem)
} }
}
if (!find) {
state.itemRef = []
form.value.apiConfiguration.push(apiItem)
} }
} }
@ -476,12 +498,6 @@ const apiRule = {
const dialogEditParams = ref(false) const dialogEditParams = ref(false)
const dialogRenameApi = ref(false) const dialogRenameApi = ref(false)
const activeParamsName = ref('') const activeParamsName = ref('')
const apiParams = ref([
{
id: 1,
name: '接口1'
}
])
const paramsObj = ref({ const paramsObj = ref({
name: '', name: '',
id: 1, id: 1,
@ -490,7 +506,7 @@ const paramsObj = ref({
const apiObj = ref({ const apiObj = ref({
name: '', name: '',
id: 1 serialNumber: 1
}) })
const paramsObjRules = { const paramsObjRules = {
name: [ name: [
@ -524,6 +540,7 @@ const apiObjRules = {
] ]
} }
const setActiveName = val => { const setActiveName = val => {
gridData.value = val.fields
activeParamsName.value = val.name activeParamsName.value = val.name
} }
@ -545,12 +562,13 @@ const saveParamsObj = () => {
const saveApiObj = () => { const saveApiObj = () => {
apiObjRef.value.validate(result => { apiObjRef.value.validate(result => {
if (result) { if (result) {
apiParams.value.forEach(ele => { form.value.paramsConfiguration.forEach(ele => {
if (ele.id === apiObj.value.id) { if (ele.serialNumber === apiObj.value.serialNumber) {
ele.name = apiObj.value.name ele.name = apiObj.value.name
} }
}) })
} }
dialogRenameApi.value = false
}) })
} }
@ -562,17 +580,12 @@ const apiResetForm = () => {
dialogRenameApi.value = false dialogRenameApi.value = false
} }
const gridData = ref([ const gridData = ref([])
{
name: 'name',
deType: 0,
id: 0
}
])
const handleApiParams = (cmd: string, data) => { const handleApiParams = (cmd: string, data) => {
if (cmd === 'rename') { if (cmd === 'rename') {
dialogRenameApi.value = true dialogRenameApi.value = true
paramsObj.value.name = data.name apiObj.value.name = data.name
apiObj.value.serialNumber = data.serialNumber
} }
if (cmd === 'delete') { if (cmd === 'delete') {
ElMessageBox.confirm('确定删除吗?', { ElMessageBox.confirm('确定删除吗?', {
@ -581,7 +594,10 @@ const handleApiParams = (cmd: string, data) => {
autofocus: false, autofocus: false,
showClose: false showClose: false
}).then(() => { }).then(() => {
apiParams.value.splice(0, 1) form.value.paramsConfiguration.splice(0, 1)
if (activeParamsName.value === data.name) {
gridData.value = []
}
}) })
} }
@ -601,7 +617,7 @@ const delParams = data => {
autofocus: false, autofocus: false,
showClose: false showClose: false
}).then(() => { }).then(() => {
apiParams.value.splice(0, 1) gridData.value.splice(0, 1)
}) })
} }
const datasetTypeList = [ const datasetTypeList = [
@ -668,8 +684,8 @@ defineExpose({
<template v-if="form.type === 'API'"> <template v-if="form.type === 'API'">
<div class="title-form_primary flex-space table-info-mr" v-show="activeStep !== 2"> <div class="title-form_primary flex-space table-info-mr" v-show="activeStep !== 2">
<el-tabs v-model="activeName" class="api-tabs"> <el-tabs v-model="activeName" class="api-tabs">
<el-tab-pane :label="t('datasource.data_table')" name="third"></el-tab-pane> <el-tab-pane :label="t('datasource.data_table')" name="table"></el-tab-pane>
<el-tab-pane label="接口参数" name="fourth"></el-tab-pane> <el-tab-pane label="接口参数" name="params"></el-tab-pane>
</el-tabs> </el-tabs>
<el-button type="primary" style="margin-left: auto" @click="() => addApiItem(null)"> <el-button type="primary" style="margin-left: auto" @click="() => addApiItem(null)">
<template #icon> <template #icon>
@ -680,11 +696,11 @@ defineExpose({
</div> </div>
<empty-background <empty-background
v-show="activeStep !== 2" v-show="activeStep !== 2"
v-if="!form.apiConfiguration.length" v-if="!form.apiConfiguration.length && activeName === 'table'"
:description="t('datasource.no_data_table')" :description="t('datasource.no_data_table')"
img-type="noneWhite" img-type="noneWhite"
/> />
<template v-if="form.type === 'API' && activeStep === 1 && activeName === 'third'"> <template v-if="form.type === 'API' && activeStep === 1 && activeName === 'table'">
<div class="api-card-content"> <div class="api-card-content">
<div <div
v-for="(api, idx) in form.apiConfiguration" v-for="(api, idx) in form.apiConfiguration"
@ -759,11 +775,11 @@ defineExpose({
</template> </template>
<div <div
style="display: flex" style="display: flex"
v-if="form.type === 'API' && activeStep === 1 && activeName === 'fourth'" v-if="form.type === 'API' && activeStep === 1 && activeName === 'params'"
> >
<div class="left-api_params"> <div class="left-api_params">
<div <div
v-for="ele in apiParams" v-for="ele in form.paramsConfiguration"
:class="[{ active: activeParamsName === ele.name }]" :class="[{ active: activeParamsName === ele.name }]"
class="list-item_primary" class="list-item_primary"
:title="ele.name" :title="ele.name"
@ -812,12 +828,6 @@ defineExpose({
<el-table-column :label="t('common.operate')"> <el-table-column :label="t('common.operate')">
<template #default="scope"> <template #default="scope">
<el-button text @click.stop="editParams(scope.row)">
<template #icon>
<Icon name="icon_edit_outlined"></Icon>
</template>
</el-button>
<el-button text @click.stop="delParams(scope.row)"> <el-button text @click.stop="delParams(scope.row)">
<template #icon> <template #icon>
<Icon name="icon_delete-trash_outlined"></Icon> <Icon name="icon_delete-trash_outlined"></Icon>
@ -1217,7 +1227,7 @@ defineExpose({
<el-form <el-form
label-position="top" label-position="top"
require-asterisk-position="right" require-asterisk-position="right"
ref="paramsObjRef" ref="apiObjRef"
@keydown.stop.prevent.enter @keydown.stop.prevent.enter
:model="apiObj" :model="apiObj"
:rules="apiObjRules" :rules="apiObjRules"

View File

@ -36,6 +36,7 @@ interface Form {
type: string type: string
configuration?: Configuration configuration?: Configuration
apiConfiguration?: ApiConfiguration[] apiConfiguration?: ApiConfiguration[]
paramsConfiguration?: ApiConfiguration[]
syncSetting?: SyncSetting syncSetting?: SyncSetting
} }
@ -353,7 +354,10 @@ const saveDS = () => {
request.apiConfiguration[i].fields[j].value = [] request.apiConfiguration[i].fields[j].value = []
} }
} }
request.configuration = Base64.encode(JSON.stringify(request.apiConfiguration)) let apiItems = []
apiItems = apiItems.concat(request.apiConfiguration)
apiItems = apiItems.concat(request.paramsConfiguration)
request.configuration = Base64.encode(JSON.stringify(apiItems))
request.syncSetting.startTime = new Date(request.syncSetting.startTime).getTime() request.syncSetting.startTime = new Date(request.syncSetting.startTime).getTime()
request.syncSetting.endTime = new Date(request.syncSetting.endTime).getTime() request.syncSetting.endTime = new Date(request.syncSetting.endTime).getTime()
} else { } else {
@ -421,7 +425,8 @@ const defaultForm = {
name: '', name: '',
description: '', description: '',
type: 'API', type: 'API',
apiConfiguration: [] apiConfiguration: [],
paramsConfiguration: []
} }
const form = reactive<Form>(cloneDeep(defaultForm)) const form = reactive<Form>(cloneDeep(defaultForm))
const defaultForm2 = { const defaultForm2 = {

View File

@ -141,6 +141,7 @@ export interface Configuration {
export interface ApiConfiguration { export interface ApiConfiguration {
id: string id: string
name: string name: string
type: string
deTableName: string deTableName: string
method: string method: string
url: string url: string
@ -176,6 +177,7 @@ export interface Node {
editType?: number editType?: number
configuration?: Configuration configuration?: Configuration
apiConfiguration?: ApiConfiguration[] apiConfiguration?: ApiConfiguration[]
paramsConfiguration?: ApiConfiguration[]
weight?: number weight?: number
lastSyncTime?: number | string lastSyncTime?: number | string
} }

View File

@ -471,6 +471,7 @@ const handleNodeClick = data => {
configuration, configuration,
syncSetting, syncSetting,
apiConfigurationStr, apiConfigurationStr,
paramsStr,
fileName, fileName,
size, size,
description, description,
@ -482,6 +483,9 @@ const handleNodeClick = data => {
if (apiConfigurationStr) { if (apiConfigurationStr) {
apiConfigurationStr = JSON.parse(Base64.decode(apiConfigurationStr)) apiConfigurationStr = JSON.parse(Base64.decode(apiConfigurationStr))
} }
if (paramsStr) {
paramsStr = JSON.parse(Base64.decode(paramsStr))
}
Object.assign(nodeInfo, { Object.assign(nodeInfo, {
name, name,
pid, pid,
@ -496,6 +500,7 @@ const handleNodeClick = data => {
configuration, configuration,
syncSetting, syncSetting,
apiConfiguration: apiConfigurationStr, apiConfiguration: apiConfigurationStr,
paramsConfiguration: paramsStr,
weight: data.weight, weight: data.weight,
lastSyncTime lastSyncTime
}) })
@ -587,6 +592,7 @@ const editDatasource = (editType?: number) => {
configuration, configuration,
syncSetting, syncSetting,
apiConfigurationStr, apiConfigurationStr,
paramsStr,
fileName, fileName,
size, size,
description, description,
@ -595,6 +601,9 @@ const editDatasource = (editType?: number) => {
if (configuration) { if (configuration) {
configuration = JSON.parse(Base64.decode(configuration)) configuration = JSON.parse(Base64.decode(configuration))
} }
if (paramsStr) {
paramsStr = JSON.parse(Base64.decode(paramsStr))
}
if (apiConfigurationStr) { if (apiConfigurationStr) {
apiConfigurationStr = JSON.parse(Base64.decode(apiConfigurationStr)) apiConfigurationStr = JSON.parse(Base64.decode(apiConfigurationStr))
} }
@ -613,6 +622,7 @@ const editDatasource = (editType?: number) => {
configuration, configuration,
syncSetting, syncSetting,
apiConfiguration: apiConfigurationStr, apiConfiguration: apiConfigurationStr,
paramsConfiguration: paramsStr,
lastSyncTime lastSyncTime
}) })
datasourceEditor.value.init(datasource) datasourceEditor.value.init(datasource)

View File

@ -28,4 +28,5 @@ public class ApiDefinition {
private String orgName; private String orgName;
private boolean showApiStructure; private boolean showApiStructure;
private Long updateTime; private Long updateTime;
private String type = "table";
} }

View File

@ -46,6 +46,7 @@ public class DatasourceDTO implements Serializable {
private String configuration; private String configuration;
private String apiConfigurationStr; private String apiConfigurationStr;
private String paramsStr;
/** /**
* Create timestamp * Create timestamp