刘妍 2025-05-08 16:50:31 +08:00
commit 4ea4e53fa4
28 changed files with 975 additions and 131 deletions

View File

@ -65266,7 +65266,7 @@ function isnan (val) {
// | tag: vint | size: vint | data: Buffer(size) |
this._tag_stack.push(tagObj);
// <<<<<<<<
// ポインタを進める
// ポインタを進めるs
this._cursor += tag.length;
this._total += tag.length;
// 読み込み状態変更

View File

@ -13,6 +13,8 @@ enum Api {
TempeleteByTableName = '/api/Layer/TempeleteByTableName',
// 更新单条数据
UpdateTableData = '/api/Layer/UpdateTableData',
// 添加单条数据
AddTableData = '/api/Layer/AddTableData',
// 上传样式
UploadSldStyle = '/api/Layer/UploadSldStyle',
}
@ -23,6 +25,7 @@ export function tableDataByTableName(params: TableDataByTableNameParams) {
return defHttp.get({ url: Api.TableDataByTableName, params });
}
/**
* @description:
*/
@ -32,6 +35,17 @@ export function updateTableData(params: any) {
params,
});
}
/**
* @description:
*/
export function addTableData(params: any) {
return defHttp.post({
url: Api.AddTableData,
params,
});
}
/**
* @description:
*/

View File

@ -231,6 +231,32 @@ export const eventCommonHandler = (
console.log(error);
window['$message'].error('URL地址格式有误');
}
} else if (elementList[j].movement == 'revealInGroup') {
// 分组内组件显示
for (let k = 0; k < elementList[j].elementId.length; k++) {
componentList.forEach((list)=>{
if(list.isGroup && list.groupList.some((li) => li.id == elementList[j].elementId[k])){
list.groupList.forEach((l) => {
if(l.id == elementList[j].elementId[k]){
l.status.hide = false;
}
});
}
})
}
} else if (elementList[j].movement == 'hiddenInGroup') {
// 分组内组件隐藏
for (let k = 0; k < elementList[j].elementId.length; k++) {
componentList.forEach((list)=>{
if(list.isGroup && list.groupList.some((li) => li.id == elementList[j].elementId[k])){
list.groupList.forEach((l) => {
if(l.id == elementList[j].elementId[k]){
l.status.hide = true;
}
});
}
})
}
}
}
}
@ -242,22 +268,26 @@ export const eventHandlerHook = (
type: string,
params: any = null,
) => {
const elementList: any = [];
for (let i = 0; i < interactConfigEvents.length; i++) {
if (interactConfigEvents[i].type == type) {
if (!interactConfigEvents[i].movementList) {
return false;
}
for (let j = 0; j < interactConfigEvents[i].movementList.length; j++) {
elementList.push(interactConfigEvents[i].movementList[j]);
if(interactConfigEvents) {
const elementList: any = [];
for (let i = 0; i < interactConfigEvents.length; i++) {
if (interactConfigEvents[i].type == type) {
if (!interactConfigEvents[i].movementList) {
return false;
}
for (let j = 0; j < interactConfigEvents[i].movementList.length; j++) {
elementList.push(interactConfigEvents[i].movementList[j]);
}
}
}
}
if (componentList.length == 0 || elementList.length == 0) {
if (componentList.length == 0 || elementList.length == 0) {
return false;
}
eventCommonHandler(componentList, elementList, type, params);
} else {
return false;
}
eventCommonHandler(componentList, elementList, type, params);
};
// websocket事件
export const websocketEvent = (interactConfigEvents: any, params: any = null) => {

View File

@ -1,5 +1,5 @@
<template>
<div class="go-title-xuncha">
<div class="go-title-xuncha" @click="clickBtn">
<img class="img" src="@/assets/images/chart/xunchaguiji/back.png" />
<span class="span">返回</span>
</div>
@ -8,7 +8,10 @@
<script setup lang="ts">
import { PropType, toRefs } from 'vue'
import { CreateComponentType } from '@/packages/index.d'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore';
import { eventHandlerHook } from '@/hooks/eventHandler.hook';
const chartEditStore = useChartEditStore();
const props = defineProps({
chartConfig: {
type: Object as PropType<CreateComponentType>,
@ -21,6 +24,14 @@ const {
textColor,
textSize,
} = toRefs(props.chartConfig.option)
//
const clickBtn = () => {
eventHandlerHook(
chartEditStore.getComponentList,
props.chartConfig.events.interactConfigEvents,
'click'
);
};
</script>
<style lang="scss" scoped>

View File

@ -1,16 +1,6 @@
<template>
<div class="go-title-xuncha">
<div class="selbox">
<!-- <n-tree-select
v-model:value="areaValue"
:options="areaOptions"
label-field="name"
key-field="id"
children-field="children"
placeholder="请选择行政区划"
clearable
style="width: 240px"
/> -->
<el-tree-select
v-model="areaValue"
:data="areaOptions"
@ -78,8 +68,12 @@ import { EventBus } from '@/utils/eventBus'
import axios from 'axios'
import * as mars3d from "mars3d";
import { getAppEnvConfig } from '@/utils/env'
var { VITE_GLOB_API_URL } = getAppEnvConfig();
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore';
import { eventHandlerHook } from '@/hooks/eventHandler.hook';
const chartEditStore = useChartEditStore();
var { VITE_GLOB_API_URL } = getAppEnvConfig();
const props = defineProps({
chartConfig: {
type: Object as PropType<CreateComponentType>,
@ -150,6 +144,11 @@ const getAreaListData=(id)=>{
})
}
const lisClick=(e)=>{
eventHandlerHook(
chartEditStore.getComponentList,
props.chartConfig.events.interactConfigEvents,
'click'
);
EventBus.emit('clockinlistsenddata' , e);
if(entityArr.value.length>0){
entityArr.value.forEach(item =>{

View File

@ -63,8 +63,6 @@
);
function getDatasetValue(values) {
console.log(values);
let result = '';
values.forEach((val) => {
result = result + ' ' + option.dataset[0][val];
@ -72,11 +70,11 @@
return result;
}
onMounted(()=>{
onMounted(() => {
//
const sql = props.chartConfig.request?.requestSQLContent?.sql;
EventBus.on(props.chartConfig.id + 'dataupdate', (data) => {
props.chartConfig.request.requestSQLContent.sql = replaceSqlParams(sql,{Id:data.id});
props.chartConfig.request.requestSQLContent.sql = replaceSqlParams(sql, { Id: data.id });
// callback
useChartDataFetch(props.chartConfig, useChartEditStore, (resData: any[]) => {
option.dataset = resData;

View File

@ -105,6 +105,7 @@
preview-disabled
/>
<MonitorHK
:ref="(el) => setMonitorRef(el, videoIndex)"
v-if="!isEdit && videoItem.videourl && videoItem.manufacturer == '海康'"
:index="videoIndex"
:serialNumberValue="videoItem.videourl"
@ -128,6 +129,8 @@
:dataStyle="option.dataStyle"
@changeThisVideo="changeThisVideo"
@closeThisVideo="closeThisVideo"
@hideHKVideo="hideHKVideo"
@showHKVideo="showHKVideo"
/>
<MonitorTX
v-if="!isEdit && videoItem.videourl && videoItem.manufacturer == '腾讯'"
@ -140,6 +143,8 @@
:dataStyle="option.dataStyle"
@changeThisVideo="changeThisVideo"
@closeThisVideo="closeThisVideo"
@hideHKVideo="hideHKVideo"
@showHKVideo="showHKVideo"
/>
<MonitorQX
v-if="!isEdit && videoItem.videourl && videoItem.manufacturer == '青犀'"
@ -151,6 +156,8 @@
:dataStyle="option.dataStyle"
@changeThisVideo="changeThisVideo"
@closeThisVideo="closeThisVideo"
@hideHKVideo="hideHKVideo"
@showHKVideo="showHKVideo"
/>
</div>
</div>
@ -345,8 +352,18 @@
//
function hideModal() {
option.videoList = [{}];
option.status.hide = true;
switch (option.dataStyle.nowType) {
case '1':
option.videoList = [{}];
break;
case '4':
option.videoList = [{}, {}, {}, {}];
break;
case '9':
option.videoList = [{}, {}, {}, {}, {}, {}, {}, {}, {}];
break;
}
}
//
@ -393,6 +410,31 @@
}
}
//
const monitorRefs: any = ref([]);
let monitorHKList: any = [];
function setMonitorRef(el, index) {
monitorHKList.push(index);
monitorHKList = [...new Set(monitorHKList)];
monitorRefs.value[index] = el;
}
//
function hideHKVideo() {
monitorHKList.forEach((index) => {
if (monitorRefs.value[index]?.hideHkVideo) {
monitorRefs.value[index].hideHkVideo();
}
});
}
//
function showHKVideo() {
monitorHKList.forEach((index) => {
if (monitorRefs.value[index]?.hideHkVideo) {
monitorRefs.value[index].showHkVideo();
}
});
}
//
onMounted(() => {
// id

View File

@ -183,6 +183,20 @@
}
}
//
function showHkVideo() {
if (oWebControl != null) {
oWebControl.JS_ShowWnd();
}
}
//
function hideHkVideo() {
if (oWebControl != null) {
oWebControl.JS_HideWnd();
}
}
//
function reSizeVideo() {
//
@ -278,6 +292,8 @@
initPlugin,
init,
closeHkVideo,
showHkVideo,
hideHkVideo,
});
</script>

View File

@ -32,7 +32,11 @@
</div>
<!-- 视频 -->
<div class="box-container">
<div :id="'root' + props.index + props.timestamp" @click="clickThisVideo" />
<div
:id="'root' + props.index + props.timestamp"
class="LCPlayer-video-contaiiner"
@click="clickThisVideo"
/>
</div>
<!-- 控制栏 -->
<div class="box-controls">
@ -118,7 +122,7 @@
'timestamp',
'dataStyle',
]);
const emit = defineEmits(['changeThisVideo', 'closeThisVideo']);
const emit = defineEmits(['changeThisVideo', 'closeThisVideo', 'hideHKVideo', 'showHKVideo']);
let clPlayer: any = null;
@ -161,6 +165,22 @@
//
function fullScreenClick() {
clPlayer.fullScreen();
//
emit('hideHKVideo');
//
setTimeout(checkSize, 1000);
}
//
function checkSize() {
const element = document.querySelector('.LCPlayer-video-contaiiner');
const currentWidth = element.offsetWidth;
//
if (currentWidth > props.width) {
setTimeout(checkSize, 1000);
} else {
emit('showHKVideo');
}
}
// kitToken

View File

@ -48,9 +48,10 @@
<script setup lang="ts">
import { Close } from '@vicons/ionicons5';
import { onMounted } from 'vue';
const props = defineProps(['title', 'videourl', 'index', 'width', 'height', 'dataStyle']);
const emit = defineEmits(['changeThisVideo', 'closeThisVideo']);
const emit = defineEmits(['changeThisVideo', 'closeThisVideo', 'hideHKVideo', 'showHKVideo']);
function getUrl(value) {
return 'http://221.2.83.254:7012/live/' + value + '.m3u8';
@ -65,6 +66,24 @@
function closeVideo() {
emit('closeThisVideo', props.index);
}
//
function checkSize() {
//
if (document.querySelector('.vjs-default-skin').offsetWidth > props.width) {
setTimeout(checkSize, 1000);
//
emit('hideHKVideo');
} else {
setTimeout(checkSize, 1000);
//
emit('showHKVideo');
}
}
onMounted(() => {
setTimeout(checkSize, 1000);
});
</script>
<style lang="scss" scoped>

View File

@ -121,7 +121,7 @@
'timestamp',
'dataStyle',
]);
const emit = defineEmits(['changeThisVideo', 'closeThisVideo']);
const emit = defineEmits(['changeThisVideo', 'closeThisVideo', 'hideHKVideo', 'showHKVideo']);
// ;
function closeVideo() {
@ -157,6 +157,22 @@
//
function fullScreenClick() {
txPlayer.requestFullscreen();
//
emit('hideHKVideo');
//
setTimeout(checkSize, 1000);
}
//
function checkSize() {
const element = document.querySelector('.TCPlayer-video-contaiiner');
const currentWidth = element.offsetWidth;
//
if (currentWidth > props.width) {
setTimeout(checkSize, 1000);
} else {
emit('showHKVideo');
}
}
watch(
@ -206,7 +222,7 @@
onMounted(() => {
handlerPlayVideo();
control_volume.value = props.videoMuted;
control_volume.value = props.dataStyle.videoMuted;
});
onUnmounted(() => {

View File

@ -58,6 +58,7 @@
src="@/assets/images/chart/zhichu/component/SheXiangTouModal_Image.png"
/>
<MonitorHK
:ref="(el) => setMonitorRef(el, index)"
v-if="!isEdit && !option.status.hide && item.manufacturer == '海康'"
:index="index"
:serialNumberValue="item.videourl"
@ -74,6 +75,8 @@
:height="`${option.dataStyle.videoheight - 2 * option.dataStyle.borderWidth - 2 * option.dataStyle.padding}`"
:timestamp="option.dataStyle.timestamp"
:videoMuted="option.dataStyle.videoMuted"
@hideHKVideo="hideHKVideo"
@showHKVideo="showHKVideo"
/>
<MonitorTX
v-if="!isEdit && !option.status.hide && item.manufacturer == '腾讯'"
@ -85,6 +88,8 @@
:videoLoop="option.dataStyle.videoLoop"
:videoMuted="option.dataStyle.videoMuted"
:videoFit="option.dataStyle.videoFit"
@hideHKVideo="hideHKVideo"
@showHKVideo="showHKVideo"
/>
<MonitorQX
v-if="!isEdit && !option.status.hide && item.manufacturer == '青犀'"
@ -94,6 +99,8 @@
:videoLoop="option.dataStyle.videoLoop"
:videoMuted="option.dataStyle.videoMuted"
:videoFit="option.dataStyle.videoFit"
@hideHKVideo="hideHKVideo"
@showHKVideo="showHKVideo"
/>
</div>
<Title
@ -168,6 +175,31 @@
}
}
//
const monitorRefs: any = ref([]);
let monitorHKList: any = [];
function setMonitorRef(el, index) {
monitorHKList.push(index);
monitorHKList = [...new Set(monitorHKList)];
monitorRefs.value[index] = el;
}
//
function hideHKVideo() {
monitorHKList.forEach((index) => {
if (monitorRefs.value[index]?.hideHkVideo) {
monitorRefs.value[index].hideHkVideo();
}
});
}
//
function showHKVideo() {
monitorHKList.forEach((index) => {
if (monitorRefs.value[index]?.hideHkVideo) {
monitorRefs.value[index].showHkVideo();
}
});
}
//
onMounted(() => {
// id

View File

@ -171,6 +171,20 @@
}
}
//
function showHkVideo() {
if (oWebControl != null) {
oWebControl.JS_ShowWnd();
}
}
//
function hideHkVideo() {
if (oWebControl != null) {
oWebControl.JS_HideWnd();
}
}
//
function getPubKey(callback) {
oWebControl
@ -265,6 +279,8 @@
initPlugin,
init,
closeHkVideo,
showHkVideo,
hideHkVideo,
});
</script>

View File

@ -1,7 +1,7 @@
<template>
<div class="box">
<div class="box-container">
<div :id="'root' + props.index + props.timestamp"></div>
<div :id="'root' + props.index + props.timestamp" class="LCPlayer-video-contaiiner"></div>
</div>
<div class="box-controls">
<div class="left-controls">
@ -85,6 +85,8 @@
'timestamp',
'videoMuted',
]);
const emit = defineEmits(['hideHKVideo', 'showHKVideo']);
let clPlayer: any = null;
// /
@ -117,6 +119,22 @@
//
function fullScreenClick() {
clPlayer.fullScreen();
//
emit('hideHKVideo');
//
setTimeout(checkSize, 1000);
}
//
function checkSize() {
const element = document.querySelector('.LCPlayer-video-contaiiner');
const currentWidth = element.offsetWidth;
//
if (currentWidth > props.width) {
setTimeout(checkSize, 1000);
} else {
emit('showHKVideo');
}
}
// kitToken

View File

@ -14,11 +14,31 @@
</template>
<script setup lang="ts">
import { onMounted } from 'vue';
const props = defineProps(['videourl', 'width', 'height', 'videoMuted', 'videoLoop', 'videoFit']);
const emit = defineEmits(['hideHKVideo', 'showHKVideo']);
function getUrl(value) {
return 'http://221.2.83.254:7012/live/' + value + '.m3u8';
}
//
function checkSize() {
//
if (document.querySelector('.vjs-default-skin').offsetWidth > props.width) {
setTimeout(checkSize, 1000);
//
emit('hideHKVideo');
} else {
setTimeout(checkSize, 1000);
//
emit('showHKVideo');
}
}
onMounted(() => {
setTimeout(checkSize, 10 * 1000);
});
</script>
<style lang="scss" scoped>

View File

@ -27,9 +27,10 @@
'videoMuted',
'videoFit',
]);
const emit = defineEmits(['hideHKVideo', 'showHKVideo']);
//
let player: any = null;
let txPlayer: any = null;
watch(
() => props.videourl,
@ -40,22 +41,40 @@
function handlerPlayVideo() {
nextTick(function () {
if (player) {
player.src(props.videourl);
if (txPlayer) {
txPlayer.src(props.videourl);
} else {
player = TCPlayer('ZhiGan_WuRenJiShiShiHuaMian' + props.index + props.timestamp, {});
player.src(props.videourl);
txPlayer = TCPlayer('ZhiGan_WuRenJiShiShiHuaMian' + props.index + props.timestamp, {});
txPlayer.src(props.videourl);
}
});
}
function closePlayerVideo() {
if (player) {
player.dispose();
player = null;
if (txPlayer) {
txPlayer.dispose();
txPlayer = null;
}
}
//
function checkSize() {
//
if (document.querySelector('.TCPlayer-video-contaiiner').offsetWidth > props.width) {
setTimeout(checkSize, 1000);
//
emit('hideHKVideo');
} else {
setTimeout(checkSize, 1000);
//
emit('showHKVideo');
}
}
onMounted(() => {
setTimeout(checkSize, 1000);
});
onMounted(() => {
handlerPlayVideo();
});

View File

@ -5,9 +5,10 @@ import { chartInitConfig } from '@/settings/designSetting'
import { HuoQingDetailInfoConfig } from './index'
import dataJson from './data.json'
const { source } = dataJson;
const { source, header } = dataJson;
export const option = {
header: header,
dataset: source,
dataStyle:{
backgroud: '#FFFFFF00',

View File

@ -1,4 +1,61 @@
<template>
<CollapseItem name="数据设置" :expanded="true">
<div style="overflow-x: auto">
<n-table
class="go-request-header-table-box"
style="margin-top: 12px"
:single-line="false"
size="small"
>
<thead>
<tr>
<th>标题名称</th>
<th>标题内容</th>
<th>
<n-button
class="go-ml-2"
type="primary"
size="small"
ghost
@click="add(props.optionData.header.length - 1)"
>
+
</n-button></th
>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in props.optionData.header" :key="index">
<td>
<n-input v-model:value="item.label" type="text" size="small" />
</td>
<td>
<n-select
v-model:value="item.value"
multiple
:options="datasetOptions"
size="small"
/>
</td>
<td>
<div style="width: 40px">
<n-button
class="go-ml-2"
type="warning"
size="small"
ghost
:disabled="props.optionData.header.length === 1"
@click="remove(index)"
>
-
</n-button>
</div>
</td>
</tr>
</tbody>
</n-table>
</div>
</CollapseItem>
<CollapseItem name="设置" :expanded="true">
<SettingItemBox name="整体设置">
<SettingItem name="背景颜色">
@ -122,7 +179,7 @@
</template>
<script setup lang="ts">
import { PropType, watch, ref } from 'vue';
import { PropType, watch, ref, computed } from 'vue';
import { option } from './config';
import { cloneDeep } from 'lodash-es';
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting';
@ -133,4 +190,27 @@
required: true,
},
});
const datasetOptions = computed(() => {
const result = Object.entries(option.dataset[0]).map(([key, value]) => ({
label: key,
value: key,
}));
return result;
});
//
const add = (index: number) => {
props.optionData.header.splice(index + 1, 0, {
label: '',
value: [],
});
};
//
const remove = (index: number) => {
if (props.optionData.header.length !== 1) {
props.optionData.header.splice(index, 1);
}
};
</script>

View File

@ -1,32 +1,43 @@
{
"header": [
{
"label": "风向",
"value": ["windDirection"]
},
{
"label": "风速",
"value": ["windSpeed"]
},
{
"label": "温度",
"value": ["temperature"]
},
{
"label": "湿度",
"value": ["humidity"]
},
{
"label": "持续时间",
"value": ["duration"]
},
{
"label": "可燃物类型",
"value": ["fuelType"]
},
{
"label": "隔离带宽度",
"value": ["width"]
}
],
"source": [
{
"title": "风向",
"content": "西风"
},
{
"title": "风速",
"content": "34m/s"
},
{
"title": "温度",
"content": "98°C"
},
{
"title": "湿度",
"content": "34%RH"
},
{
"title": "持续时间",
"content": "54分钟"
},
{
"title": "可燃物类型",
"content": "枯叶落枝 草本植物"
},
{
"title": "隔离带宽度",
"content": "10米"
"windDirection": "西风",
"windSpeed": "34m/s",
"temperature": "98°C",
"humidity": "34%RH",
"duration": "54分钟",
"fuelType": "枯叶落枝 草本植物",
"width": "10米"
}
]
}

View File

@ -1,13 +1,13 @@
<template>
<div class="HuoQingDetailInfo">
<div class="list">
<div v-for="item in option.dataset" :key="item.key">
<div v-for="item in option.header" :key="item.key">
<div class="item">
<Dot :dotSize="option.dataStyle.dotSize" :dotColor="option.dataStyle.dotColor" />
<div class="title">
<span :class="checkLength(item.title) ? 'dot1' : 'dot2'">{{ item.title }}</span>
<span :class="checkLength(item.label) ? 'dot1' : 'dot2'">{{ item.label }}</span>
</div>
<div class="content"> {{ item.content }} </div>
<div class="content"> {{ getDatasetValue(item.value) }} </div>
</div>
</div>
</div>
@ -34,6 +34,7 @@
const { w, h } = toRefs(props.chartConfig.attr);
const option = reactive({
header: props.chartConfig.option.header,
dataset: props.chartConfig.option.dataset,
dataStyle: props.chartConfig.option.dataStyle,
});
@ -76,6 +77,14 @@
}
}
function getDatasetValue(values) {
let result = '';
values.forEach((val) => {
result = result + ' ' + option.dataset[0][val];
});
return result;
}
onMounted(() => {
//
const sql = props.chartConfig.request?.requestSQLContent?.sql;

View File

@ -143,7 +143,7 @@
//
function clickLi(item) {
item.visible = !item.visible;
// item.visible = !item.visible;
// option.value.series.data = option.value.dataset.source
// .filter((item) => item.visible)
// .map((item) => ({

View File

@ -65,7 +65,7 @@
/>
</div>
<div class="movement-type__element" v-if="panel.movement == 'callBackRequest'">
<div class="movement-type__element" v-else-if="panel.movement == 'callBackRequest'">
<CallBackEndApi
:panel="panel"
:index="panelIndex"
@ -73,6 +73,18 @@
/>
</div>
<div
class="movement-type__element"
v-else-if="['revealInGroup', 'hiddenInGroup'].includes(panel.movement)"
>
分组内关联组件可多选
<n-select
v-model:value="panel.elementId"
placeholder="请选择"
:options="elementSelectOptionsInGroup"
multiple
/>
</div>
<div class="movement-type__element" v-else>
关联组件可多选
<n-select
@ -177,7 +189,7 @@
</div>
</template>
<script setup lang="ts">
import { ref, defineEmits, onMounted, watch, defineAsyncComponent } from 'vue';
import { ref, defineEmits, onMounted, watch, defineAsyncComponent, computed } from 'vue';
import { eventTypeOptions, movementTypeOptions } from '../../../../hooks/eventData.hook';
import { goDialog, acquiesceAsyncComponent, previewPath, loadAsyncComponent } from '@/utils';
import { DesktopOutline } from '@vicons/ionicons5';
@ -186,9 +198,9 @@
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 CallBackEndApi = loadAsyncComponent(() => import('./CallBackRequest.vue'));
const { targetData, chartEditStore } = useTargetData();
const targetDataOption = ref([]);
const chartConfig = ref([]);
@ -314,6 +326,27 @@
};
}),
);
// -
const elementSelectOptionsInGroup = computed(() => {
let optionsInGroup = [];
chartEditStore.getComponentList.forEach((element) => {
if (
element.isGroup &&
element?.groupList.some(
(li) => li.key == targetData.value.key && li.id == targetData.value.id,
)
) {
optionsInGroup = element.groupList.map((item) => {
return {
label: '本分组内组件-' + item.chartConfig.title,
value: item.id,
};
});
}
});
return optionsInGroup;
});
//
const elementSelectSingleOptions: any = ref([]);
const treeIterator = (tree) => {

View File

@ -37,6 +37,14 @@ export const movementTypeOptions: EventOptionsItemType[] = [
label: '隐藏',
value: 'hidden',
},
{
label: '分组内显示',
value: 'revealInGroup',
},
{
label: '分组内隐藏',
value: 'hiddenInGroup',
},
{
label: '跳转新地址',
value: 'newaddress',

View File

@ -15,6 +15,7 @@
:clickRowToExpand="false"
:checkable="true"
@check="handleCheck"
@change="handleChange"
:treeData="treeData"
:fieldNames="{ key: 'id', title: 'applicationName', children: 'child' }"
:defaultExpandAll="true"
@ -33,7 +34,7 @@
import { deleteLayer } from '@/api/sys/layerManagement';
const { createMessage, createConfirm } = useMessage();
const emit = defineEmits(['select', 'edit', 'add', 'remove']);
const emit = defineEmits(['select', 'edit', 'add', 'remove','checked']);
defineOptions({ name: 'DeptTree' });
const treeData = ref<TreeItem[]>([]);
@ -48,6 +49,8 @@
});
});
}, 500);
//
nextTick(() => {
unref(asyncExpandTreeRef)?.expandAll(true);
@ -60,7 +63,15 @@
selectItem.value = item;
}
function handleCheck(checkedKeys, e) {
console.log('onChecked', checkedKeys, e);
emit("checked",checkedKeys);
}
function handleChange(key,e){
console.log(key,e);
}
/**
* 根据id值或某个属性的值从树结构中查询数据

View File

@ -64,7 +64,7 @@ export const formSchema: FormSchema[] = [
},
},
{
field: 'tableName',
field: 'tablename',
component: 'ApiSelect',
label: '空间数据表',
required: true,

View File

@ -106,6 +106,179 @@ const EditDrawingGeometry = (map,geometry) => {
flyTo: true
})
map.addLayer(drawingGraphicLayer)
// 绑定菜单
geometryBindMenu();
}
// 添加图斑
const AddDrawingGeometry = (map,type) => {
// 加载图层
if(drawingGraphicLayer){
drawingGraphicLayer.clear();
map.removeLayer(drawingGraphicLayer);
drawingGraphicLayer = null;
}
let geojson = {
"type": "FeatureCollection",
"features": []
}
drawingGraphicLayer = new mars3d.layer.GeoJsonLayer({
name: "编辑图层",
data:geojson,
isAutoEditing:true,
symbol: {
styleOptions: {
color: "#0d3685",
outlineColor: "#0d3685",
opacity: 0.8,
clampToGround:true,
"color": "#2f00b0",
"pixelSize": 10,
"opacity": 1,
"outline": true,
"outlineColor": "#ffffff",
"outlineOpacity": 0.6,
"outlineWidth": 2,
"scaleByDistance_far": 1000000,
"scaleByDistance_farValue": 0.1,
"scaleByDistance_near": 1000,
"scaleByDistance_nearValue": 1,
"distanceDisplayCondition_far": 10000,
"visibleDepth": true
}
},
popup: [],
popupOptions: {
showNull: true
},
flyTo: true
})
map.addLayer(drawingGraphicLayer);
// 开始绘制
switch(type){
case "point":
drawingGraphicLayer.startDraw({
type: "pointP",
style: {
pixelSize: 12,
color: "#3388ff",
label: {
// 不需要文字时去掉label配置即可
text: "",
font_size: 20,
color: "#ffffff",
outline: true,
outlineColor: "#000000",
pixelOffsetY: -20
}
}
})
break;
case "polygon":
// 贴地面
drawingGraphicLayer.startDraw({
type: "polygonP",
style: {
color: "#3388ff",
opacity: 0.5,
outline: true,
outlineColor: "#ffffff",
outlineWidth: 2.0,
clampToGround:true
}
})
break;
case "polyline":
drawingGraphicLayer.startDraw({
type: "polylineP",
style: {
color:"#3388ff",
width: 3,
clampToGround:true
}
})
break;
}
geometryBindMenu();
}
// 查看图斑
const PreviewDrawingGeometry = (map,geometry) => {
// 获取geojson
let geojson = null;
if(typeof geometry == 'string'){
let jsonData = WktToGeojson(geometry)
geojson = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": jsonData
}
]
}
}
if(drawingGraphicLayer){
drawingGraphicLayer.clear();
map.removeLayer(drawingGraphicLayer);
drawingGraphicLayer = null;
}
// 加载图层
drawingGraphicLayer = new mars3d.layer.GeoJsonLayer({
name: "编辑图层",
data:geojson,
isAutoEditing:true,
symbol: {
styleOptions: {
color: "#0d3685",
outlineColor: "#0d3685",
opacity: 0.8,
clampToGround:true,
"color": "#2f00b0",
"pixelSize": 10,
"opacity": 1,
"outline": true,
"outlineColor": "#ffffff",
"outlineOpacity": 0.6,
"outlineWidth": 2,
"scaleByDistance_far": 1000000,
"scaleByDistance_farValue": 0.1,
"scaleByDistance_near": 1000,
"scaleByDistance_nearValue": 1,
"distanceDisplayCondition_far": 10000,
"visibleDepth": true
}
},
popup: [],
popupOptions: {
showNull: true
},
flyTo: true
})
map.addLayer(drawingGraphicLayer)
}
// 图斑菜单
const geometryBindMenu = () => {
// 绑定菜单
drawingGraphicLayer.bindContextMenu([
{
text: "开始编辑对象",
@ -206,8 +379,7 @@ const EditDrawingGeometry = (map,geometry) => {
}
}
])
map.addLayer(drawingGraphicLayer)
// 获取编辑结果
drawingGraphicLayer.on(mars3d.EventType.editStop, function (e) {
let resultGeojson = e.graphic.toGeoJSON({standard:true,noAlt:true})
@ -216,34 +388,21 @@ const EditDrawingGeometry = (map,geometry) => {
EventBus.emit("editLayerEnd",resultWkt)
})
//
}
// 绘制完成
drawingGraphicLayer.on(mars3d.EventType.drawCreated, function (e) {
// 添加图斑
const AddDrawingGeometry = (map) => {
}
// 查看图斑
const DetailDrawingGeometryy = (map,geometry) => {
// 获取geojson
let geojson = null;
if(typeof geometry == 'string'){
let jsonData = WktToGeojson(geometry)
geojson = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": jsonData
}
]
let resultGeojson = e.graphic.toGeoJSON({standard:true,noAlt:true})
if(resultGeojson.geometry.type == "Polygon"){
resultGeojson.geometry.coordinates [0].push(resultGeojson.geometry.coordinates [0][0])
}
}
console.log("resultGeoJson",resultGeojson);
let resultWkt = GeojsonToWkt(resultGeojson.geometry)
EventBus.emit("editLayerEnd",resultWkt)
})
}
// 结束停止编辑
@ -252,4 +411,4 @@ const DrawingEnd = () => {
}
export {WktToGeojson,GeojsonToWkt,GetGeometryCenter,EditDrawingGeometry,AddDrawingGeometry,DrawingEnd}
export {WktToGeojson,GeojsonToWkt,GetGeometryCenter,EditDrawingGeometry,AddDrawingGeometry,PreviewDrawingGeometry,DrawingEnd}

View File

@ -6,6 +6,7 @@
@select="handleSelect"
@edit="editLayer"
@add="addLayer"
@checked="checkedLayer"
@remove="tableVisible = false"
/>
<div class="map-container w-3/4 xl:w-4/5">
@ -24,6 +25,30 @@
style="width: 200px; margin-right: 10px"
/>
<a-button type="primary" @click="getList"> </a-button>
<a-dropdown>
<template #overlay>
<a-menu >
<a-menu-item key="1" @click="addData('point')" >
<UserOutlined />
点数据
</a-menu-item>
<a-menu-item key="2" @click="addData('polyline')">
<UserOutlined />
线数据
</a-menu-item>
<a-menu-item key="3" @click="addData('polygon')">
<UserOutlined />
面数据
</a-menu-item>
</a-menu>
</template>
<a-button>
添加
<DownOutlined />
</a-button>
</a-dropdown>
<a-button type="primary" @click="exportTemplate"> </a-button>
<a-upload
:accept="'.xlsx,.csv,.xls,.zip'"
@ -87,7 +112,7 @@
</div>
</div>
<!-- 编辑 -->
<div class="data-edit" v-if="showTable == 'edit'">
<div class="data-edit" v-if="showTable == 'edit' || showTable == 'add'">
<a-form
ref="formRef"
:model="formState"
@ -172,7 +197,7 @@
import { CloseOutlined, InboxOutlined } from '@ant-design/icons-vue';
import { BasicTable, useTable, TableAction } from '@/components/Table';
import { columns } from './data';
import { tableDataByTableName, updateTableData, uploadSldStyle } from '@/api/application/layer';
import { tableDataByTableName, updateTableData, addTableData, uploadSldStyle } from '@/api/application/layer';
import { ValidateErrorEntity } from 'ant-design-vue/es/form/interface';
import { useMessage } from '@/hooks/web/useMessage';
import { uploadFile, fun_Delete } from '@/api/demo/files';
@ -182,25 +207,217 @@
import { message } from 'ant-design-vue';
import { EventBus } from '@/utils/eventBus';
import {
GetGeometryCenter,
EditDrawingGeometry,
AddDrawingGeometry,
DrawingEnd,
} from './geometryHandler.ts';
import {GetGeometryCenter,EditDrawingGeometry,AddDrawingGeometry,PreviewDrawingGeometry,DrawingEnd} from "./geometryHandler.ts"
import * as mars3d from 'mars3d';
let globalMap: mars3d.Map;
const onMapLoad = (map) => {
globalMap = map;
};
EventBus.on('editLayerEnd', function (e) {
}
EventBus.on("editLayerEnd",function(e){
formState.value.geom = e;
})
console.log('formState', formState.value);
});
//
const handlerLoadLayer = (record) => {
//
let layer = globalMap.getLayerById(record.id);
if(layer){
layer.show = !layer.show
}else{
let tileLayer = new mars3d.layer.WmsLayer({
name: "合肥WMS",
url: "http://192.168.10.163:8080/geoserver/my_workspace/wms",
layers: "my_workspace:fm_waterresourcetest",
parameters: {
transparent: true,
format: "image/png"
},
getFeatureInfoParameters: {
feature_count: 10
},
//
highlight: {
type: "wallP",
diffHeight: 100,
materialType: mars3d.MaterialType.LineFlow,
materialOptions: {
image: "https://data.mars3d.cn/img/textures/fence.png",
color: "#ffff00",
speed: 10, // 1-100
axisY: true
}
},
popup: "all",
flyTo: true
})
globalMap.addLayer(tileLayer);
let drawingGraphicLayer = new mars3d.layer.GeoJsonLayer({
id:record.id,
name: "编辑图层",
data:{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"id": "fm_fireproofbarracks.4",
"geometry": {
"type": "Point",
"coordinates": [118.037111, 35.402398]
},
"geometry_name": "geom",
"properties": {
"Name": "4号防火驿站",
"Info": null,
"Lng": null,
"Lat": null,
"State": "1",
"UpdateTime": null
}
},
{
"type": "Feature",
"id": "fm_fireproofbarracks.5",
"geometry": {
"type": "Point",
"coordinates": [118.032671, 35.406068]
},
"geometry_name": "geom",
"properties": {
"Name": "5号防火驿站",
"Info": null,
"Lng": null,
"Lat": null,
"State": "1",
"UpdateTime": null
}
},
{
"type": "Feature",
"id": "fm_fireproofbarracks.2",
"geometry": {
"type": "Point",
"coordinates": [118.044773, 35.398101]
},
"geometry_name": "geom",
"properties": {
"Name": "2号防火驿站",
"Info": null,
"Lng": null,
"Lat": null,
"State": "1",
"UpdateTime": null
}
},
{
"type": "Feature",
"id": "fm_fireproofbarracks.1",
"geometry": {
"type": "Point",
"coordinates": [118.046801, 35.397552]
},
"geometry_name": "geom",
"properties": {
"Name": "1号防火驿站",
"Info": null,
"Lng": null,
"Lat": null,
"State": "1",
"UpdateTime": null
}
},
{
"type": "Feature",
"id": "fm_fireproofbarracks.3",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[118.196381, 35.356013],
[118.196421, 35.356022],
[118.196433, 35.355985],
[118.196331, 35.35596],
[118.196339, 35.355921],
[118.19644, 35.355946],
[118.196449, 35.355921],
[118.196347, 35.355897],
[118.196355, 35.355847],
[118.196409, 35.355859],
[118.19646, 35.355871],
[118.196468, 35.355842],
[118.196365, 35.355819],
[118.196316, 35.355808],
[118.196307, 35.355846],
[118.196294, 35.355908],
[118.196277, 35.355979],
[118.196381, 35.356013]
]
]
},
"geometry_name": "geom",
"properties": {
"Name": "3号防火驿站",
"Info": null,
"Lng": null,
"Lat": null,
"State": "1",
"UpdateTime": null
}
}
],
"totalFeatures": 5,
"numberMatched": 5,
"numberReturned": 5,
"timeStamp": "2025-04-29T03:03:26.650Z",
"crs": {
"type": "name",
"properties": {
"name": "urn:ogc:def:crs:EPSG::404000"
}
}
},
isAutoEditing:true,
symbol: {
styleOptions: {
color: "#0d3685",
outlineColor: "#0d3685",
opacity: 0.8,
clampToGround:true,
"color": "#2f00b0",
"pixelSize": 10,
"opacity": 1,
"outline": true,
"outlineColor": "#ffffff",
"outlineOpacity": 0.6,
"outlineWidth": 2,
"scaleByDistance_far": 1000000,
"scaleByDistance_farValue": 0.1,
"scaleByDistance_near": 1000,
"scaleByDistance_nearValue": 1,
"distanceDisplayCondition_far": 10000,
"visibleDepth": true
}
},
popup: [],
popupOptions: {
showNull: true
},
flyTo: true
})
// globalMap.addLayer(drawingGraphicLayer);
}
}
const { VITE_GLOB_API_URL } = getAppEnvConfig();
const { createConfirm, createMessage } = useMessage();
@ -283,22 +500,51 @@
tableName: tableName.value,
list: [],
};
for (const key in formState.value) {
params.list.push({
name: key,
value: formState.value[key],
});
}
updateTableData(params).then((res) => {
console.log('res', res);
if (res) {
createMessage.success('编辑成功!');
DrawingEnd();
showTable.value = '';
} else {
createMessage.error('编辑失败!');
}
});
if(showTable.value == 'edit'){
updateTableData(params).then((res) => {
console.log('res', res);
if (res) {
createMessage.success('编辑成功!');
DrawingEnd();
showTable.value = '';
} else {
createMessage.error('编辑失败!');
}
});
}else if(showTable.value == 'add'){
params.list = [];
headData.value?.forEach((item,index)=>{
params.list.push({
name: item,
value: formState.value[item] ? formState.value[item] : null,
});
})
console.log("params",params.list);
addTableData(params).then((res) => {
console.log('res', res);
if (res) {
createMessage.success('添加成功!');
DrawingEnd();
showTable.value = '';
} else {
createMessage.error('添加失败!');
}
});
}
})
.catch((error: ValidateErrorEntity<FormState>) => {
console.log('error', error);
@ -310,6 +556,7 @@
};
const handleSelect = (record) => {
tableName.value = record.tableName;
applicationName.value = record.applicationName;
tableVisible.value = true;
@ -330,9 +577,21 @@
isUpdate: false,
});
};
const checkedLayer = (e) => {
console.log("e",e);
handlerLoadLayer(e);
}
const hanlerLoadLayer = () => {
}
const handleSuccess = () => {
treeRef.value.fetch();
};
const addData = (type) => {
AddDrawingGeometry(globalMap,type);
showTable.value = 'add';
}
const detailData = ref([]);
const editData = (record) => {
selectVal.value = record;
@ -342,6 +601,8 @@
EditDrawingGeometry(globalMap, record.geom);
};
const viewData = (record) => {
console.log('record', record);
PreviewDrawingGeometry(globalMap,record.geom);
selectVal.value = record;
formState.value = record;
showTable.value = 'detail';

View File

@ -329,6 +329,7 @@ function reload() {
sandbox.contentWindow?.location.reload()
}
defineExpose({ reload })
</script>