刘妍 2025-04-07 16:31:04 +08:00
commit a3cbfe665b
7 changed files with 416 additions and 15 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

View File

@ -3,6 +3,11 @@ import { mapFun } from '@/hooks/ceshiFun.hook';
import { router } from '@/router';
import { previewUrl } from '@/utils';
import { EventBus } from '@/utils/eventBus';
import axiosInstance from '@/api/axios';
import { translateStr } from '@/api/http';
import {
RequestParamsObjType,
} from '@/enums/httpEnum';
const chartEditStore = useChartEditStore();
const ceshiFunction = mapFun();
@ -162,6 +167,40 @@ export const eventCommonHandler = (
obj.option = elementList[j].option;
// chartEditStore.updateComponentList(arr[0], obj);
}
} else if (elementList[j].movement == 'callBackRequest') {
const {
requestUrl,
requestApi,
requestContentType,
requestDataType,
requestHttpType,
requestParams
} = elementList[j].callBackRequest;
// 处理头部
let headers: RequestParamsObjType = Object.fromEntries(requestParams.Header.map(item => [item.key, item.value]));
// headers['X-Token'] = localStorage.getItem('X-Token');
// params 参数
let params: RequestParamsObjType = Object.fromEntries(requestParams.Params.map(item => [item.key, item.value]));
try {
const url = new Function(
'return `' +
`${requestApi.includes('https://') || requestApi.includes('http://') ? requestApi : requestUrl + requestApi}`.trim() +
'`',
)();
return axiosInstance({
url,
method: requestHttpType,
data: {},
params: translateStr(params),
headers: translateStr(headers),
});
} catch (error) {
console.log(error);
window['$message'].error('URL地址格式有误');
}
}
}
}

View File

@ -24,7 +24,7 @@
<img class="img" src="/src/assets/images/chart/xunchaguiji/locationicon.png" />
<span>位置</span>
</div>
<div class="rotatebox flex ai-c jc-c">
<div class="rotatebox flex ai-c jc-c" @click="rotateLine(item)">
<img class="img" src="/src/assets/images/chart/xunchaguiji/rotateicon.png" />
<span>轨迹</span>
</div>
@ -84,6 +84,21 @@ const handlerAddEntity = (data) => {
window.graphicLayer.addGraphic(graphic);
window.globalMap.flyToGraphic(graphic,{radius:300});
}
const rotateLine = (data)=>{
axios({
method: "post",
url: VITE_GLOB_API_URL + '/api/FirePatrol/GetPatrolPointByTime',
data: {
page: 1,
limit: 9999
},
headers: {
'X-Token': localStorage.getItem("X-Token")
}
}).then(res => {
})
}
const getListData=()=>{
axios({
method: "post",
@ -101,7 +116,7 @@ const getListData=()=>{
})
}
onMounted(() => {
// getListData()
getListData()
})
</script>

View File

@ -0,0 +1,319 @@
<template>
<n-space vertical>
<div style="width: 500px">
URL 地址 &请求方式 & API接口
<n-input v-model:value.trim="data.requestUrl" :min="1" placeholder="请输入URL地址"> </n-input>
<n-input-group style="margin-top: 10px">
<n-select
style="width: 120px"
v-model:value="data.requestHttpType"
:options="selectTypeOptions"
default-value="get"
/>
<n-input v-model:value.trim="data.requestApi" :min="1" placeholder="请输入API"> </n-input>
</n-input-group>
<!-- <div style="margin-top: 10px">
选择方式
<n-tabs v-model:value="data.requestContentType" type="segment" size="small">
<n-tab :name="RequestContentTypeEnum.DEFAULT" tab="普通请求"> </n-tab>
<n-tab :name="RequestContentTypeEnum.SQL" tab="SQL 请求"> </n-tab>
</n-tabs>
</div> -->
<div
style="margin-top: 10px"
v-if="data.requestContentType == RequestContentTypeEnum.DEFAULT"
>
<n-tabs type="line" animated v-model:value="tabValue">
<n-tab v-for="item in RequestParamsTypeEnum" :key="item" :name="item" :tab="item">
{{ item }}
</n-tab>
</n-tabs>
</div>
<div class="go-mt-3">
<div v-if="tabValue !== RequestParamsTypeEnum.BODY">
<n-table class="go-request-header-table-box" :single-line="false" size="small">
<thead>
<tr>
<th></th>
<th>Key</th>
<th>Value</th>
<th>操作</th>
<th>结果</th>
</tr>
</thead>
<tbody>
<tr
v-for="(item, index) in RequestParamsTypeEnum.PARAMS == tabValue
? data.requestParams.Params
: data.requestParams.Header"
:key="index"
>
<td>
{{ index + 1 }}
</td>
<td>
<n-input v-model:value="item.key" type="text" size="small" @blur="blur" />
</td>
<td>
<n-input v-model:value="item.value" type="text" size="small" @blur="blur" />
</td>
<td>
<div style="width: 80px">
<n-button class="go-ml-2" type="primary" size="small" ghost @click="add(index)"
>+</n-button
>
<n-button
class="go-ml-2"
type="warning"
size="small"
ghost
:disabled="index === 0"
@click="remove(index)"
>
-
</n-button>
</div>
</td>
<td>
<n-button v-if="item.error" class="go-ml-2" text type="error">
格式错误
</n-button>
<n-button v-else class="go-ml-2" text type="primary"> 格式通过 </n-button>
</td>
</tr>
</tbody>
</n-table>
</div>
<div v-else>
<n-radio-group v-model:value="data.requestParamsBodyType" name="radiogroup">
<n-space>
<n-radio v-for="bodyEnum in RequestBodyEnumList" :key="bodyEnum" :value="bodyEnum">
{{ bodyEnum }}
</n-radio>
</n-space>
</n-radio-group>
<!-- none -->
<n-card
class="go-mt-3 go-pb-3"
v-if="data.requestParamsBodyType === RequestBodyEnum['NONE']"
>
<n-text depth="3">该接口没有 Body </n-text>
</n-card>
<!-- 具有对象属性时 -->
<template
v-else-if="
data.requestParamsBodyType === RequestBodyEnum['FORM_DATA'] ||
data.requestParamsBodyType === RequestBodyEnum['X_WWW_FORM_URLENCODED']
"
>
<request-header-table
class="go-mt-3"
:target="data.requestParams[RequestParamsTypeEnum.BODY][data.requestParamsBodyType]"
@update="updateRequestBodyTable"
></request-header-table>
</template>
<!-- json -->
<template v-else-if="data.requestParamsBodyType === RequestBodyEnum['JSON']">
<monaco-editor
v-model:modelValue="
data.requestParams[RequestParamsTypeEnum.BODY][data.requestParamsBodyType]
"
width="600px"
height="200px"
language="json"
/>
</template>
<!-- xml -->
<template v-else-if="data.requestParamsBodyType === RequestBodyEnum['XML']">
<monaco-editor
v-model:modelValue="
data.requestParams[RequestParamsTypeEnum.BODY][data.requestParamsBodyType]
"
width="600px"
height="200px"
language="html"
/>
</template>
</div>
</div>
</div>
</n-space>
</template>
<script setup lang="ts">
import { ref, toRefs, reactive, PropType, withDefaults, onMounted, watch } from 'vue';
import { MonacoEditor } from '@/components/Pages/MonacoEditor';
import { RequestHeaderTable } from '@/views/chart/ContentConfigurations/components/ChartData/components/ChartDataRequest/components/RequestHeaderTable/index';
import { SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting';
import {
selectTypeOptions,
selectTimeOptions,
} from '@/views/chart/ContentConfigurations/components/ChartData/index.d';
import { useTargetData } from '@/views/chart/ContentConfigurations/components/hooks/useTargetData.hook';
import {
RequestParamsTypeEnum,
RequestContentTypeEnum,
RequestParamsObjType,
RequestBodyEnumList,
RequestBodyEnum,
RequestHttpEnum,
} from '@/enums/httpEnum';
const tabValue = ref(RequestParamsTypeEnum.PARAMS);
const emits = defineEmits(['changeCallBackEnd']);
const props = defineProps({
panel: {
type: Object,
},
index: {
type: Number,
},
});
console.log(props.panel);
const data: any = ref({
requestUrl: '',
requestApi: '',
requestContentType: '',
requestDataType: 0,
requestHttpType: '',
requestParams: {
Body: {
'form-data': {},
'x-www-form-urlencoded': {},
json: '',
xml: '',
},
Header: [
{
key: '',
value: '',
error: false,
},
],
Params: [
{
key: '',
value: '',
error: false,
},
],
},
});
watch(
() => data.value,
(newValue) => {
emits('changeCallBackEnd', props.index, newValue);
},
{
deep: true,
},
);
//
const add = (index: number) => {
if (RequestParamsTypeEnum.PARAMS == tabValue.value) {
data.value.requestParams.Params.splice(index + 1, 0, {
key: '',
value: '',
error: false,
});
} else {
data.value.requestParams.Header.splice(index + 1, 0, {
key: '',
value: '',
error: false,
});
}
};
//
const remove = (index: number) => {
if (RequestParamsTypeEnum.PARAMS == tabValue.value) {
data.value.requestParams.Params.splice(index, 1);
} else {
data.value.requestParams.Header.splice(index, 1);
}
blur();
};
//
const blur = () => {
let successNum = 0;
let tableArray: any = [];
if (RequestParamsTypeEnum.PARAMS == tabValue.value) {
tableArray = data.value.requestParams.Params;
} else {
tableArray = data.value.requestParams.Header;
}
tableArray.forEach((item) => {
if ((item.key !== '' && item.value == '') || (item.key === '' && item.value !== '')) {
//
item.error = true;
} else {
//
successNum++;
item.error = false;
}
});
//
if (successNum == tableArray.length) {
//
const updateObj: any = {};
tableArray.forEach((e) => {
if (e.key) updateObj[e.key] = e.value;
});
}
};
onMounted(() => {
if (!props.panel?.callBackRequest) {
data.value = {
requestUrl: '',
requestApi: '',
requestContentType: '',
requestDataType: 0,
requestHttpType: '',
requestParams: {
Body: {
'form-data': {},
'x-www-form-urlencoded': {},
json: '',
xml: '',
},
Header: [
{
key: '',
value: '',
error: false,
},
],
Params: [
{
key: '',
value: '',
error: false,
},
],
},
};
} else {
data.value = props.panel.callBackRequest;
}
});
</script>
<style lang="scss" scoped>
.select-type {
width: 300px;
}
</style>

View File

@ -55,7 +55,6 @@
<div class="movement-type">
<template v-if="panel.movement != 'newaddress'">
<div class="movement-type__element" v-if="panel.movement == 'style'">
关联组件可选择分组里的单组件
<n-select
@ -66,6 +65,14 @@
/>
</div>
<div class="movement-type__element" v-if="panel.movement == 'callBackRequest'">
<CallBackEndApi
:panel="panel"
:index="panelIndex"
@changeCallBackEnd="changeCallBackEnd"
/>
</div>
<div class="movement-type__element" v-else>
关联组件可多选
<n-select
@ -75,7 +82,6 @@
multiple
/>
</div>
</template>
<div class="movement-type__element" v-if="panel.movement == 'map'">
@ -180,6 +186,7 @@
import { projectListApi } from '@/api/path/project.api';
import { funSelectOptions, layerOptions } from '@/hooks/ceshiFun.hook';
import { getLoad } from '@/api/sys/sysDataItemDetail';
import CallBackEndApi from './CallBackRequest.vue';
const EventComponent = loadAsyncComponent(() => import('./EventComponent.vue'));
const { targetData, chartEditStore } = useTargetData();
@ -401,6 +408,10 @@
props.eventData.movementList[index].option = data;
props.eventData.movementList[index].chartConfig = chartConfig.value[index];
};
const changeCallBackEnd = (index, data) => {
props.eventData.movementList[index].callBackRequest = data;
};
watch(
() => targetDataOption.value,
(newData) => {

View File

@ -1,7 +1,13 @@
<template>
<n-collapse-item title="组件交互事件配置" name="2">
<template #header-extra>
<n-button v-if="!targetData.isChildEvent" type="primary" tertiary size="small" @click.stop="addEvent">
<n-button
v-if="!targetData.isChildEvent"
type="primary"
tertiary
size="small"
@click.stop="addEvent"
>
<template #icon>
<n-icon>
<pencil-icon />
@ -11,7 +17,10 @@
</n-button>
</template>
<!-- 无数据 -->
<div v-if="interactConfigItem.length == 0 && !targetData.isChildEvent" class="no-data go-flex-center">
<div
v-if="interactConfigItem.length == 0 && !targetData.isChildEvent"
class="no-data go-flex-center"
>
<img :src="noData" alt="暂无数据" />
<n-text :depth="3">暂无内容</n-text>
</div>
@ -117,24 +126,27 @@
const { targetData, chartEditStore } = useTargetData();
const { DocumentTextIcon, CloseIcon, PencilIcon } = icon.ionicons5;
const interactConfigItem: any = ref([]);
const childEventChange = ref()
const childEventChange = ref();
const eventTab = ref();
const getEventName = (type: string) => {
return eventTypeOptions.find((item) => item.value === type)?.label;
};
onMounted(() => {
if(!targetData.value.isChildEvent){
if (!targetData.value.isChildEvent) {
if (Object.keys(targetData.value.events.interactConfigEvents).length > 0) {
interactConfigItem.value = targetData.value.events.interactConfigEvents;
}
}else{
} else {
}
})
});
// tab
const changeTab = (type: string) => {
const index = eventTab.value.match(/交互(\S*)-/)[1];
eventTab.value =
'交互' + index + '-' + eventTypeOptions.find((item) => item.value === type)?.label;
console.log(type);
console.log(eventTab.value);
};
//
const showModal = ref(false);
@ -151,10 +163,11 @@
//
const saveEvents = async () => {
if(!targetData.value.isChildEvent){
if (!targetData.value.isChildEvent) {
targetData.value.events.interactConfigEvents = interactConfigItem.value;
}else{
targetData.value.events.interactConfigEvents[childEventChange.value] = interactConfigItem.value
} else {
targetData.value.events.interactConfigEvents[childEventChange.value] =
interactConfigItem.value;
}
closeEvents();
};
@ -192,7 +205,7 @@
eventTypeOptions.find((item) => item.value === interactConfigItem.value[0].type)?.label;
};
const addChildEvent = (type) => {
childEventChange.value = type
childEventChange.value = type;
interactConfigItem.value = targetData.value.events.interactConfigEvents[type] || [];
if (interactConfigItem.value?.length == 0) {
interactConfigItem.value = [
@ -212,7 +225,7 @@
'交互1-' +
eventTypeOptions.find((item) => item.value === interactConfigItem.value[0].type)?.label;
showModal.value = true;
}
};
const showEvent = (item: any, index: number) => {
showModal.value = true;
changIndex.value = index;

View File

@ -61,4 +61,8 @@ export const movementTypeOptions: EventOptionsItemType[] = [
label: '修改组件样式',
value: 'style',
},
{
label: '调用后台API',
value: 'callBackRequest',
},
];