merge
|
After Width: | Height: | Size: 359 B |
|
After Width: | Height: | Size: 381 B |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 46 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 8.5 KiB |
|
After Width: | Height: | Size: 7.9 KiB |
|
After Width: | Height: | Size: 911 B |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 8.9 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 278 B |
|
After Width: | Height: | Size: 394 B |
|
After Width: | Height: | Size: 5.5 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 4.9 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 8.9 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 46 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 6.8 KiB |
@ -0,0 +1,18 @@
|
||||
import { PublicConfigClass } from '@/packages/public'
|
||||
import { chartInitConfig } from '@/settings/designSetting'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { TaskAssignConfig } from './index'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
|
||||
export const option = {
|
||||
textSize: 14,
|
||||
colors: ['#0C2411','#00611A','#FFFFFF'],
|
||||
text: '添加途经点'
|
||||
}
|
||||
|
||||
export default class Config extends PublicConfigClass implements CreateComponentType {
|
||||
public key = TaskAssignConfig.key
|
||||
public attr = { ...chartInitConfig, w: 1139, h: 249, zIndex: 1 }
|
||||
public chartConfig = cloneDeep(TaskAssignConfig)
|
||||
public option = cloneDeep(option)
|
||||
}
|
||||
@ -0,0 +1,64 @@
|
||||
<template>
|
||||
<CollapseItem name="样式" :expanded="true">
|
||||
<SettingItemBox name="样式">
|
||||
<SettingItem name="文字">
|
||||
<n-input-number
|
||||
size="small"
|
||||
v-model:value="optionData.text"
|
||||
:min="10"
|
||||
/>
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
</CollapseItem>
|
||||
<CollapseItem name="样式" :expanded="true">
|
||||
<SettingItemBox name="样式">
|
||||
<SettingItem name="文字大小">
|
||||
<n-input-number
|
||||
size="small"
|
||||
v-model:value="optionData.textSize"
|
||||
:min="10"
|
||||
/>
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
</CollapseItem>
|
||||
<CollapseItem name="样式" :expanded="true">
|
||||
<SettingItemBox
|
||||
:name="`颜色-${index + 1}`"
|
||||
v-for="(item, index) in optionData.colors"
|
||||
:key="index"
|
||||
>
|
||||
<SettingItem name="颜色">
|
||||
<n-color-picker
|
||||
size="small"
|
||||
:modes="['hex']"
|
||||
v-model:value="optionData.colors[index]"
|
||||
></n-color-picker>
|
||||
</SettingItem>
|
||||
<SettingItem>
|
||||
<n-button
|
||||
size="small"
|
||||
@click="optionData.colors[index] = option.colors[index]"
|
||||
>
|
||||
恢复默认
|
||||
</n-button>
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
</CollapseItem>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType } from 'vue'
|
||||
import {
|
||||
CollapseItem,
|
||||
SettingItemBox,
|
||||
SettingItem
|
||||
} from '@/components/Pages/ChartItemSetting'
|
||||
import { option } from './config'
|
||||
|
||||
const props = defineProps({
|
||||
optionData: {
|
||||
type: Object as PropType<typeof option>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@ -0,0 +1,14 @@
|
||||
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d';
|
||||
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d';
|
||||
|
||||
export const TaskAssignConfig: ConfigType = {
|
||||
key: 'TaskAssign',
|
||||
chartKey: 'VTaskAssign',
|
||||
conKey: 'VCTaskAssign',
|
||||
title: '线索信息',
|
||||
category: ChatCategoryEnum.TITLE,
|
||||
categoryName: ChatCategoryEnumName.TITLE,
|
||||
package: PackagesCategoryEnum.TASKS,
|
||||
chartFrame: ChartFrameEnum.STATIC,
|
||||
image: 'task-assign.png',
|
||||
};
|
||||
@ -0,0 +1,806 @@
|
||||
<template>
|
||||
<div
|
||||
class="patrol-container"
|
||||
@click="clickBtn"
|
||||
@dblclick="dblclickBtn"
|
||||
@contextmenu="rightclickBtn"
|
||||
@mouseenter="mouseenterBtn"
|
||||
@mouseleave="mouseleaveBtn"
|
||||
>
|
||||
|
||||
<div class="clue-information-containers">
|
||||
|
||||
<!-- 左侧列表 -->
|
||||
<div class="left-container">
|
||||
|
||||
<!-- item 1 -->
|
||||
<div class="clue-item" v-for="(item,index) in listItem" :key="index">
|
||||
|
||||
<!-- 内容 -->
|
||||
<div class="clue-item-information" @click="handlerGetInfo(item)">
|
||||
<div class="icon">
|
||||
<img v-if="item.state == 1" :src="'/public/components/Task/taskassign/'+item.icon+'-active.png'" alt="">
|
||||
<img v-else :src="'/public/components/Task/taskassign/'+item.icon+'.png'" alt="">
|
||||
</div>
|
||||
<div class="label" :style="{'background-image': item.state == 1 ? 'url(/public/components/Task/taskassign/item-bg-active.png)' : 'url(/public/components/Task/taskassign/item-bg.png)'}">
|
||||
{{item.name}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 时间线 -->
|
||||
<div class="item-liner">
|
||||
<div class="left-line" v-if="index > 0"></div>
|
||||
<div class="point"></div>
|
||||
<div class="right-line" v-if="index < listItem.length-1"></div>
|
||||
</div>
|
||||
|
||||
<!-- 时间 -->
|
||||
<div class="clue-item-title" >
|
||||
<span class="time">
|
||||
{{item.time}}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- 点击弹窗 -->
|
||||
<div class="verify-container" v-if="item.checked"
|
||||
:style="{'background-image': item.state == 1 ? 'url(/public/components/Task/taskassign/detail-bg-active.png)' : 'url(/public/components/Task/taskassign/detail-bg.png)'}"
|
||||
>
|
||||
<div class="title"
|
||||
:style="{
|
||||
'background': item.state == 1 ? 'linear-gradient( 270deg, #271410 0%, #740B09 47%, #CC0101 100%)' : 'linear-gradient( 270deg, #0A261E 0%, #15AF3F 47%, #17B241 100%)',
|
||||
'border-left':item.state == 1 ? '3px solid #F02626' : '3px solid #20C24D'
|
||||
}"
|
||||
>
|
||||
{{item.name}}
|
||||
<div class="close-button" @click="handlerCloseInfo(item)">
|
||||
<img v-if="item.state == 1" src="/public/components/Task/taskassign/close-active.png" alt="">
|
||||
<img v-else src="/public/components/Task/taskassign/close.png" alt="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 图片 -->
|
||||
<div class="image-container"
|
||||
:style="{'border': item.state == 1 ? '2px solid rgba(240, 38, 38, 1)' : '2px solid #20C24D'}"
|
||||
>
|
||||
|
||||
</div>
|
||||
<!-- 内容 -->
|
||||
<div class="description-container">
|
||||
<div class="description-item" v-for="(item,index) in detailInfo" :key="index">
|
||||
<div class="label">{{item.label}}</div>
|
||||
<div class="value">{{item.value}}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<!-- 右侧添加项目 -->
|
||||
<div class="right-container">
|
||||
<div class="add-item-container" @click="methodsShow = true;"></div>
|
||||
<div class="methods-container" v-if="methodsShow">
|
||||
<div class="methods-item" v-for="(item,index) in methods" :key="index" @click="selectMethods(item);">
|
||||
<div class="icon">
|
||||
<img :src="'/public/components/Task/taskassign/methods-'+item.icon+'.png'" alt="">
|
||||
</div>
|
||||
<div class="label">{{item.label}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- <img src="@/assets/images/chart/tasks/assign-task.png" alt="" />
|
||||
<span>任务下发</span> -->
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import {
|
||||
computed,
|
||||
PropType,
|
||||
toRefs,
|
||||
watch,
|
||||
reactive,
|
||||
ref,
|
||||
onMounted,
|
||||
onUnmounted,
|
||||
createVNode,
|
||||
} from 'vue';
|
||||
import * as mars3d from 'mars3d';
|
||||
import * as Cesium from 'mars3d-cesium';
|
||||
import { CreateComponentType } from '@/packages/index.d';
|
||||
import { eventHandlerHook } from '@/hooks/eventHandler.hook';
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore';
|
||||
import { EventBus } from '@/utils/eventBus';
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { uuid, buildGUID } from '@/utils/uuid';
|
||||
import { servicesTopic, services_replyTopic, errorName } from '@/utils/debugging/remote';
|
||||
import {
|
||||
getClient,
|
||||
createConnection,
|
||||
clientSubscribe,
|
||||
destroyConnection,
|
||||
createSeizeConnection,
|
||||
} from '@/utils/mqtt';
|
||||
import { listDronePort, saveHandFlyTask } from '@/api/situation';
|
||||
import { airPortStore } from '@/store/modules/airport';
|
||||
import { useMessage } from '@/hooks/web/useMessage';
|
||||
import { applyDroneControl } from '@/api/demo/airportMaintenance';
|
||||
import axios from 'axios'
|
||||
import { getAppEnvConfig } from '@/utils/env'
|
||||
var { VITE_GLOB_API_URL } = getAppEnvConfig();
|
||||
|
||||
const methodsShow = ref(false)
|
||||
|
||||
const { createMessage, createConfirm } = useMessage();
|
||||
const bid = buildGUID();
|
||||
const airPortStoreVal = airPortStore();
|
||||
const props = defineProps({
|
||||
chartConfig: {
|
||||
type: Object as PropType<CreateComponentType>,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
const { w, h, x, y } = toRefs(props.chartConfig.attr);
|
||||
const chartEditStore = useChartEditStore();
|
||||
// 传递过来的线索信息
|
||||
const deliveryData = ref();
|
||||
// 无人机调用信息
|
||||
const droneData = ref();
|
||||
|
||||
const clickBtn = (val) => {
|
||||
|
||||
// assignTask();
|
||||
|
||||
eventHandlerHook(
|
||||
chartEditStore.getComponentList,
|
||||
props.chartConfig.events.interactConfigEvents,
|
||||
'click',
|
||||
deliveryData.value,
|
||||
);
|
||||
};
|
||||
const dblclickBtn = (val) => {
|
||||
eventHandlerHook(
|
||||
chartEditStore.getComponentList,
|
||||
props.chartConfig.events.interactConfigEvents,
|
||||
'dblclick',
|
||||
val,
|
||||
);
|
||||
};
|
||||
const rightclickBtn = (event) => {
|
||||
event.preventDefault(); // 阻止默认的右键菜单
|
||||
eventHandlerHook(
|
||||
chartEditStore.getComponentList,
|
||||
props.chartConfig.events.interactConfigEvents,
|
||||
'rightclick',
|
||||
);
|
||||
};
|
||||
const mouseenterBtn = (val) => {
|
||||
eventHandlerHook(
|
||||
chartEditStore.getComponentList,
|
||||
props.chartConfig.events.interactConfigEvents,
|
||||
'mousein',
|
||||
val,
|
||||
);
|
||||
};
|
||||
const mouseleaveBtn = (val) => {
|
||||
eventHandlerHook(
|
||||
chartEditStore.getComponentList,
|
||||
props.chartConfig.events.interactConfigEvents,
|
||||
'mouseout',
|
||||
val,
|
||||
);
|
||||
};
|
||||
|
||||
// 下发任务
|
||||
const taskInfo = ref({});
|
||||
|
||||
const assignTask = () => {
|
||||
let querys = taskInfo.value
|
||||
|
||||
axios({
|
||||
method: "post",
|
||||
url: VITE_GLOB_API_URL + '/api/FireManagement/IssuedFireClueTask',
|
||||
data: querys,
|
||||
headers: {
|
||||
'X-Token': localStorage.getItem("X-Token")
|
||||
}
|
||||
}).then(res => {
|
||||
if (res.data.code == 200) {
|
||||
ElMessage({
|
||||
message: res.data.message,
|
||||
type: 'success',
|
||||
})
|
||||
} else {
|
||||
ElMessage({
|
||||
message: res.data.message,
|
||||
type: 'error',
|
||||
})
|
||||
}
|
||||
if(!res){
|
||||
ElMessage({
|
||||
message: res,
|
||||
type: 'error',
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// 组件通信
|
||||
EventBus.on(props.chartConfig.id + 'dataupdate', (data) => {
|
||||
taskInfo.value = data;
|
||||
});
|
||||
});
|
||||
|
||||
const listItem = ref([
|
||||
{
|
||||
name:"初始线索",
|
||||
icon:"monitor",
|
||||
checked:false,
|
||||
time:"2025/11/09 14:45:19",
|
||||
state:1,
|
||||
},
|
||||
// {
|
||||
// name:"无人机核查",
|
||||
// icon:"uav",
|
||||
// checked:false,
|
||||
// time:"2025/11/09 14:45:19",
|
||||
// state:1,
|
||||
// },
|
||||
// {
|
||||
// name:"人员核查",
|
||||
// checked:false,
|
||||
// icon:"verify",
|
||||
// time:"2025/11/09 14:45:19",
|
||||
// state:2,
|
||||
// }
|
||||
])
|
||||
|
||||
|
||||
// 方式列表
|
||||
const methods = ref([
|
||||
{
|
||||
label:"视频监控",
|
||||
icon:"monitor",
|
||||
value:"monitor",
|
||||
},{
|
||||
label:"无人机核查",
|
||||
icon:"uav",
|
||||
value:"uav",
|
||||
},{
|
||||
label:"直升机核查",
|
||||
icon:"helicopter",
|
||||
value:"",
|
||||
},{
|
||||
label:"人员核查",
|
||||
icon:"verify",
|
||||
value:"",
|
||||
},{
|
||||
label:"关闭线索",
|
||||
icon:"close",
|
||||
value:"",
|
||||
},{
|
||||
label:"应急响应",
|
||||
icon:"response",
|
||||
value:"",
|
||||
}
|
||||
])
|
||||
|
||||
const selectMethods = (item) => {
|
||||
|
||||
switch(item.icon){
|
||||
case "monitor":
|
||||
handlerGetNearByMonitor(item);
|
||||
break;
|
||||
|
||||
case "uav":
|
||||
handlerUavVerify(item);
|
||||
break;
|
||||
|
||||
case "verify":
|
||||
handlerUserVerify(item);
|
||||
break;
|
||||
|
||||
case "close":
|
||||
handlerCloseClue(item);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
methodsShow.value = false;
|
||||
}
|
||||
|
||||
// 点击时间线节点获取详情
|
||||
const handlerGetInfo = (item) => {
|
||||
|
||||
listItem.value.forEach((item,index)=>{
|
||||
item.checked = false;
|
||||
})
|
||||
|
||||
switch(item.icon){
|
||||
case 'monitor':
|
||||
handlerDetail(item);
|
||||
break;
|
||||
case 'verify':
|
||||
handlerVerify(item);
|
||||
break;
|
||||
}
|
||||
|
||||
item.checked = true;
|
||||
}
|
||||
|
||||
// 关闭
|
||||
const handlerCloseInfo = (item) => {
|
||||
item.checked = false;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
const detailInfo = ref([{}]);
|
||||
|
||||
// 获取初始线索详情
|
||||
const handlerDetail = (item) => {
|
||||
|
||||
let sql = `
|
||||
SELECT "ReportPerson","ReportTime","Describe" ,"Address", CASE
|
||||
WHEN "SourceType"='6' THEN '遥感监测线索'
|
||||
WHEN "SourceType"='2' THEN '高空瞭望线索'
|
||||
WHEN "SourceType"='3' THEN '无人机线索'
|
||||
WHEN "SourceType"='1' THEN '地面巡查线索'
|
||||
WHEN "SourceType"='5' THEN '公众反馈线索'
|
||||
WHEN "SourceType"='4' THEN '人工合并'
|
||||
ELSE '其他'
|
||||
END AS "SourceType" ,"Image" from fm_fireclueinfo where "Id" = '5292760'
|
||||
`
|
||||
|
||||
axios.post(VITE_GLOB_API_URL+'/api/FireResources/GetDataBySql',{
|
||||
sql:sql
|
||||
}).then((res) => {
|
||||
console.log("res",res);
|
||||
|
||||
let data = res.data.result[0];
|
||||
|
||||
detailInfo.value = [
|
||||
{
|
||||
label:"线索描述",
|
||||
key:"describe",
|
||||
value:data.describe,
|
||||
},{
|
||||
label:"线索位置",
|
||||
key:"address",
|
||||
value:data.address,
|
||||
},{
|
||||
label:"线索来源",
|
||||
key:"sourceType",
|
||||
value:data.sourceType,
|
||||
},{
|
||||
label:"上报时间",
|
||||
key:"reportTime",
|
||||
value:data.reportTime,
|
||||
}
|
||||
]
|
||||
|
||||
let imageList = JSON.parse(data.image);
|
||||
|
||||
console.log("imageList",imageList);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
// 获取人员核查详情
|
||||
const handlerVerify = (item) => {
|
||||
|
||||
}
|
||||
|
||||
// 附近视频监控
|
||||
function handlerGetNearByMonitor(item){
|
||||
|
||||
let monitorGraphic = new mars3d.graphic.BillboardEntity({
|
||||
position: [118.034537,35.389578],
|
||||
attr: item,
|
||||
style: {
|
||||
pixelSize: 100,
|
||||
scale: 0.7,
|
||||
image: '/public/components/task/taskassign/map-monitor.png',
|
||||
offset:[0,100],
|
||||
clampToGround: true,
|
||||
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, // 贴地
|
||||
horizontalOrigin: Cesium.HorizontalOrigin.CENTER, // 水平居中
|
||||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // 垂直底部贴地
|
||||
pixelOffset: new Cesium.Cartesian2(0, 0) // 不偏移
|
||||
},
|
||||
});
|
||||
|
||||
monitorGraphic.on(mars3d.EventType.click, function (event: any) {
|
||||
var data = event.graphic.options.attr;
|
||||
console.log('点击了点位', data);
|
||||
});
|
||||
|
||||
window.globalMap.graphicLayer.addGraphic(monitorGraphic);
|
||||
}
|
||||
|
||||
// 无人机飞行控制
|
||||
function handlerUavVerify(item){
|
||||
|
||||
axios({
|
||||
method: "post",
|
||||
url: VITE_GLOB_API_URL + '/api/FireManagement/IssuedFireClueTask',
|
||||
data: {},
|
||||
headers: {
|
||||
'X-Token': localStorage.getItem("X-Token")
|
||||
}
|
||||
}).then(res => {
|
||||
if (res.data.code == 200) {
|
||||
ElMessage({
|
||||
message: res.data.message,
|
||||
type: 'success',
|
||||
})
|
||||
} else {
|
||||
ElMessage({
|
||||
message: res.data.message,
|
||||
type: 'error',
|
||||
})
|
||||
}
|
||||
if(!res){
|
||||
ElMessage({
|
||||
message: res,
|
||||
type: 'error',
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
let obj = {
|
||||
name:item.label,
|
||||
icon:item.icon,
|
||||
checked:false,
|
||||
time:"2025/11/09 14:45:19"
|
||||
}
|
||||
listItem.value.push(obj);
|
||||
|
||||
let graphic = new mars3d.graphic.BillboardEntity({
|
||||
position: [118.020379,35.415164],
|
||||
attr: item,
|
||||
style: {
|
||||
pixelSize: 100,
|
||||
scale: 0.7,
|
||||
image: '/public/components/task/taskassign/map-uav.png',
|
||||
offset:[0,100],
|
||||
clampToGround: true,
|
||||
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
|
||||
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
||||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||
pixelOffset: new Cesium.Cartesian2(0, 0)
|
||||
},
|
||||
});
|
||||
|
||||
window.globalMap.graphicLayer.addGraphic(graphic);
|
||||
|
||||
}
|
||||
|
||||
// 人员核查
|
||||
function handlerUserVerify(item){
|
||||
|
||||
axios({
|
||||
method: "post",
|
||||
url: VITE_GLOB_API_URL + '/api/FireManagement/IssuedFireClueTask',
|
||||
data: {},
|
||||
headers: {
|
||||
'X-Token': localStorage.getItem("X-Token")
|
||||
}
|
||||
}).then(res => {
|
||||
if (res.data.code == 200) {
|
||||
ElMessage({
|
||||
message: res.data.message,
|
||||
type: 'success',
|
||||
})
|
||||
} else {
|
||||
ElMessage({
|
||||
message: res.data.message,
|
||||
type: 'error',
|
||||
})
|
||||
}
|
||||
if(!res){
|
||||
ElMessage({
|
||||
message: res,
|
||||
type: 'error',
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
let obj = {
|
||||
name:item.label,
|
||||
icon:item.icon,
|
||||
checked:false,
|
||||
time:"2025/11/09 14:45:19"
|
||||
}
|
||||
listItem.value.push(obj);
|
||||
|
||||
let graphic = new mars3d.graphic.BillboardEntity({
|
||||
position: [118.034137,35.424721],
|
||||
attr: item,
|
||||
style: {
|
||||
pixelSize: 100,
|
||||
scale: 0.8,
|
||||
image: '/public/components/task/taskassign/map-user.png',
|
||||
offset:[0,100],
|
||||
clampToGround: true,
|
||||
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
|
||||
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
||||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||
pixelOffset: new Cesium.Cartesian2(0, 0)
|
||||
},
|
||||
});
|
||||
|
||||
window.globalMap.graphicLayer.addGraphic(graphic);
|
||||
}
|
||||
|
||||
// 关闭线索
|
||||
function handlerCloseClue(item){
|
||||
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.patrol-container {
|
||||
width: v-bind('`${w}px`');
|
||||
height: v-bind('`${h}px`');
|
||||
background: linear-gradient(180deg, #182b20 0%, #136c3d 100%);
|
||||
border-radius: 2px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
img {
|
||||
width: 16px;
|
||||
}
|
||||
span {
|
||||
margin-left: 6px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.clue-information-containers{
|
||||
width:100%;
|
||||
height: 100%;
|
||||
display:flex;
|
||||
background:#07261E;
|
||||
background-image:url(@/assets/images/chart/tasks/taskassign/container-bg.png);
|
||||
background-size:100% 100%;
|
||||
.left-container{
|
||||
flex:auto;
|
||||
display:flex;
|
||||
justify-content: center; /* 水平居中 */
|
||||
padding:20px;
|
||||
.clue-item{
|
||||
flex:1;
|
||||
flex: 0 0 calc(30% - 40px);
|
||||
position:relative;
|
||||
.clue-item-information{
|
||||
width:135px;
|
||||
margin:0px auto;
|
||||
height: calc( 100% - 60px);
|
||||
.icon{
|
||||
width:100%;
|
||||
height: calc( 100% - 50px);
|
||||
text-align:center;
|
||||
img{
|
||||
width:135px;
|
||||
}
|
||||
}
|
||||
.label{
|
||||
width: 100px;
|
||||
margin:0px auto;
|
||||
height:28px;
|
||||
font-family: PingFangSC, PingFang SC;
|
||||
font-weight: 400;
|
||||
font-size: 16px;
|
||||
color: #FFFFFF;
|
||||
line-height:28px;
|
||||
text-shadow: 0px 2px 4px #46311C;
|
||||
text-align: center;
|
||||
font-style: normal;
|
||||
margin-top:12px;
|
||||
background-size:100% 100%;
|
||||
}
|
||||
}
|
||||
.item-liner{
|
||||
width:100%;
|
||||
height:10px;
|
||||
margin:8px 0px 10px 0px;
|
||||
position:relative;
|
||||
.left-line{
|
||||
position:absolute;
|
||||
top:0px;
|
||||
left:0px;
|
||||
width:50%;
|
||||
height:3px;
|
||||
background:#00611a;
|
||||
z-index:1;
|
||||
}
|
||||
.point{
|
||||
width:12px;
|
||||
height:12px;
|
||||
border-radius:50%;
|
||||
position:absolute;
|
||||
top:-5px;
|
||||
left:50%;
|
||||
transform: translate(-50%,0);
|
||||
z-index:2;
|
||||
&::before{
|
||||
content:"";
|
||||
width:16px;
|
||||
height:16px;
|
||||
background:#00f5355b;
|
||||
position:absolute;
|
||||
top:-2px;
|
||||
left:-2px;
|
||||
border-radius:50%;
|
||||
}
|
||||
&::after{
|
||||
content:"";
|
||||
width:8px;
|
||||
height:8px;
|
||||
background:#00f535;
|
||||
position:absolute;
|
||||
top:2px;
|
||||
left:2px;
|
||||
border:1px solid rgba(255,255,255,0.5);
|
||||
border-radius:50%;
|
||||
}
|
||||
}
|
||||
|
||||
.right-line{
|
||||
position:absolute;
|
||||
top:0px;
|
||||
right:0px;
|
||||
width:50%;
|
||||
height:3px;
|
||||
background:#00611a;
|
||||
z-index:1;
|
||||
}
|
||||
}
|
||||
.clue-item-title{
|
||||
width:100%;
|
||||
height:27px;
|
||||
text-align: center;
|
||||
.time{
|
||||
padding:3px 6px;
|
||||
background:rgba(0,0,0,0.8);
|
||||
color:rgba(203, 230, 205, 1);
|
||||
border:1px solid rgba(61, 73, 77, 1);
|
||||
border-radius:5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.right-container{
|
||||
width:160px;
|
||||
height:100%;
|
||||
padding:20px;
|
||||
.add-item-container{
|
||||
width:40px;
|
||||
height:40px;
|
||||
margin:80px auto;
|
||||
background-image:url(/public/components/task/taskassign/methods-add.png);
|
||||
background-size:100% 100%;
|
||||
}
|
||||
.methods-container{
|
||||
position:absolute;
|
||||
padding:30px 4px 10px 10px;
|
||||
bottom:88px;
|
||||
right:-136px;
|
||||
width:160px;
|
||||
height:300px;
|
||||
background-image:url(@/assets/images/chart/tasks/taskassign/methods-container-bg.png);
|
||||
background-size: 100% 100%;
|
||||
.methods-item{
|
||||
width:100%;
|
||||
display:flex;
|
||||
height:40px;
|
||||
color:#fff;
|
||||
padding:0px 0px;
|
||||
gap:10px;
|
||||
&:hover{
|
||||
background:#0a4533;
|
||||
}
|
||||
.icon{
|
||||
width:30px;
|
||||
height:30px;
|
||||
padding:5px;
|
||||
img{
|
||||
width:30px;
|
||||
height:30px;
|
||||
}
|
||||
}
|
||||
.label{
|
||||
flex:1;
|
||||
line-height:40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.verify-container{
|
||||
width:356px;
|
||||
height:497px;
|
||||
position:absolute;
|
||||
top:-540px;
|
||||
left:-74px;
|
||||
background-image:url(/public/components/task/taskassign/detail-bg.png);
|
||||
background-size: 100% 100%;
|
||||
z-index:9999;
|
||||
.title{
|
||||
font-size:16px;
|
||||
width: calc( 100% - 46px);
|
||||
height:30px;
|
||||
color:#fff;
|
||||
border-left:3px solid #20C24D;
|
||||
margin:30px;
|
||||
line-height:30px;
|
||||
text-indent:10px;
|
||||
background: linear-gradient( 270deg, #0A261E 0%, #15AF3F 47%, #17B241 100%);
|
||||
}
|
||||
.close-button{
|
||||
width:30px;
|
||||
height:30px;
|
||||
position:absolute;
|
||||
top:28px;
|
||||
right:20px;
|
||||
|
||||
}
|
||||
.image-container{
|
||||
width: calc( 100% - 60px);
|
||||
margin:0px auto;
|
||||
height:200px;
|
||||
}
|
||||
.description-container{
|
||||
width: calc( 100% - 60px);
|
||||
margin:0px auto;
|
||||
height:200px;
|
||||
color:#fff;
|
||||
.description-item{
|
||||
width:100%;
|
||||
min-height:30px;
|
||||
line-height:18px;
|
||||
margin:8px 0px;
|
||||
display:flex;
|
||||
font-size:14px;
|
||||
.label{
|
||||
width:100px;
|
||||
position:relative;
|
||||
text-indent:20px;
|
||||
color:#cfcfcf;
|
||||
&::before{
|
||||
content:"";
|
||||
width:4px;
|
||||
height:4px;
|
||||
border-radius: 50%;
|
||||
position:absolute;
|
||||
top:8px;
|
||||
left:0px;
|
||||
background: #C9FFC7;
|
||||
box-shadow: 0px 0px 5px 1px #1FBF4B;
|
||||
}
|
||||
}
|
||||
.value{
|
||||
flex:1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.operation-container{
|
||||
width:100%;
|
||||
height:80px;
|
||||
background:orange;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,84 @@
|
||||
import { PublicConfigClass } from '@/packages/public';
|
||||
import { chartInitConfig, requestSqlConfig } from '@/settings/designSetting';
|
||||
import { CreateComponentType } from '@/packages/index.d';
|
||||
import { TaskClueInformationConfig } from './index';
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
import { getAssetsImg } from '@/utils/index';
|
||||
|
||||
export const option = {
|
||||
colors: ['#457453', '#00611A', '#00CC13', '#C9FFC7'],
|
||||
titleColor: '#CBE6CD',
|
||||
titleSize: 15,
|
||||
desColor: '#FFFFFF',
|
||||
desSize: 15,
|
||||
dataset: {
|
||||
data: [
|
||||
{
|
||||
title: '预警描述',
|
||||
desc: '费县马庄镇牛田村村委东北方向375.75° 1.197公里处发现火情',
|
||||
},
|
||||
{
|
||||
title: '水平角',
|
||||
desc: '375.75°',
|
||||
},
|
||||
{
|
||||
title: '俯视角',
|
||||
desc: '98.5°',
|
||||
},
|
||||
{
|
||||
title: '经纬度',
|
||||
desc: '117.90911,3012349',
|
||||
},
|
||||
{
|
||||
title: '预警时间',
|
||||
desc: '2024.12.24 13:08:07',
|
||||
},
|
||||
{
|
||||
title: '线索来源',
|
||||
desc: '无人机上报',
|
||||
},
|
||||
],
|
||||
imgArr: [
|
||||
getAssetsImg('@/assets/images/chart/tasks/bannerimg1.png'),
|
||||
getAssetsImg('@/assets/images/chart/tasks/bannerimg1.png'),
|
||||
getAssetsImg('@/assets/images/chart/tasks/bannerimg1.png'),
|
||||
],
|
||||
},
|
||||
primaryKey: 'id',
|
||||
showColumns: [
|
||||
{
|
||||
type: 'text',
|
||||
en_name: 'ReportPerson',
|
||||
zh_name: '人员名称',
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
en_name: 'ReportTime',
|
||||
zh_name: '上报时间',
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
en_name: 'Describe',
|
||||
zh_name: '火情描述',
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
en_name: 'Address',
|
||||
zh_name: '位置地点',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default class Config extends PublicConfigClass implements CreateComponentType {
|
||||
public key = TaskBannerConfig.key;
|
||||
public attr = { ...chartInitConfig, w: 400, h: 527, zIndex: 1 };
|
||||
public chartConfig = cloneDeep(TaskBannerConfig);
|
||||
public option = cloneDeep(option);
|
||||
public request = {
|
||||
...requestSqlConfig,
|
||||
requestSQLContent: {
|
||||
sql: 'update fm_fireclueinfo set "status" = #{Status} where "Id" = #{Id}',
|
||||
},
|
||||
};
|
||||
public filter = 'return res.result;';
|
||||
}
|
||||
@ -0,0 +1,158 @@
|
||||
<template>
|
||||
<CollapseItem name="样式" :expanded="true">
|
||||
<SettingItemBox
|
||||
:name="`颜色-${index + 1}`"
|
||||
v-for="(item, index) in optionData.colors"
|
||||
:key="index"
|
||||
>
|
||||
<SettingItem name="颜色">
|
||||
<n-color-picker
|
||||
size="small"
|
||||
:modes="['hex']"
|
||||
v-model:value="optionData.colors[index]"
|
||||
></n-color-picker>
|
||||
</SettingItem>
|
||||
<SettingItem>
|
||||
<n-button
|
||||
size="small"
|
||||
@click="optionData.colors[index] = option.colors[index]"
|
||||
>
|
||||
恢复默认
|
||||
</n-button>
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
</CollapseItem>
|
||||
<CollapseItem name="样式" :expanded="true">
|
||||
<SettingItemBox name="样式">
|
||||
<SettingItem name="文字颜色">
|
||||
<n-color-picker
|
||||
size="small"
|
||||
:modes="['hex']"
|
||||
v-model:value="optionData.desColor"
|
||||
></n-color-picker>
|
||||
</SettingItem>
|
||||
<SettingItem name="文字大小">
|
||||
<n-input-number
|
||||
size="small"
|
||||
v-model:value="optionData.desSize"
|
||||
:min="12"
|
||||
/>
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
</CollapseItem>
|
||||
<CollapseItem name="样式" :expanded="true">
|
||||
<SettingItemBox name="样式">
|
||||
<SettingItem name="文字颜色">
|
||||
<n-color-picker
|
||||
size="small"
|
||||
:modes="['hex']"
|
||||
v-model:value="optionData.titleColor"
|
||||
></n-color-picker>
|
||||
</SettingItem>
|
||||
<SettingItem name="文字大小">
|
||||
<n-input-number
|
||||
size="small"
|
||||
v-model:value="optionData.titleSize"
|
||||
:min="12"
|
||||
/>
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
</CollapseItem>
|
||||
|
||||
|
||||
<CollapseItem name="展示信息" :expanded="true">
|
||||
|
||||
<SettingItem name="主键字段">
|
||||
<a-input size="small" v-model:value="optionData.primaryKey" placeholder="主键字段" />
|
||||
</SettingItem>
|
||||
|
||||
|
||||
<a-table size="small" :dataSource="optionData.showColumns" :columns="columns"
|
||||
:pagination="false"
|
||||
>
|
||||
|
||||
<template #bodyCell="{ column,record}">
|
||||
|
||||
<template v-if="column.key === 'type'">
|
||||
<a-select v-model:value="record.type" size="small">
|
||||
<a-select-option value="text">文本</a-select-option>
|
||||
<a-select-option value="image">图片</a-select-option>
|
||||
<a-select-option value="video">视频</a-select-option>
|
||||
</a-select>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'en_name'">
|
||||
<a-input size="small" v-model:value="record.en_name" placeholder="英文字段" />
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'zh_name'">
|
||||
<a-input size="small" v-model:value="record.zh_name" placeholder="中文名称" />
|
||||
</template>
|
||||
|
||||
</template>
|
||||
|
||||
|
||||
<template #footer>
|
||||
<a-button type="default" size="small" @click="addShowColumns">
|
||||
<template #icon>
|
||||
<PlusOutlined />
|
||||
</template>
|
||||
添加显示字段
|
||||
</a-button>
|
||||
</template>
|
||||
|
||||
</a-table>
|
||||
|
||||
</CollapseItem>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType,ref } from 'vue'
|
||||
import { PlusOutlined } from '@ant-design/icons-vue';
|
||||
|
||||
import {
|
||||
CollapseItem,
|
||||
SettingItemBox,
|
||||
SettingItem
|
||||
} from '@/components/Pages/ChartItemSetting'
|
||||
import { option } from './config'
|
||||
|
||||
const props = defineProps({
|
||||
optionData: {
|
||||
type: Object as PropType<typeof option>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
const columns = ref(
|
||||
[
|
||||
{
|
||||
title: '字段类型',
|
||||
dataIndex: 'type',
|
||||
key: 'type',
|
||||
},
|
||||
{
|
||||
title: '英文字段',
|
||||
dataIndex: 'en_name',
|
||||
key: 'en_name',
|
||||
},
|
||||
{
|
||||
title: '中文名称',
|
||||
dataIndex: 'zh_name',
|
||||
key: 'zh_name',
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
const addShowColumns = ()=>{
|
||||
props.optionData.showColumns.push({
|
||||
type:"text",
|
||||
en_name: '',
|
||||
zh_name: '',
|
||||
})
|
||||
}
|
||||
</script>
|
||||
@ -0,0 +1,14 @@
|
||||
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d';
|
||||
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d';
|
||||
|
||||
export const TaskClueInformationConfig: ConfigType = {
|
||||
key: 'TaskClueInformation',
|
||||
chartKey: 'VTaskClueInformation',
|
||||
conKey: 'VCTaskClueInformation',
|
||||
title: '线索信息',
|
||||
category: ChatCategoryEnum.TITLE,
|
||||
categoryName: ChatCategoryEnumName.TITLE,
|
||||
package: PackagesCategoryEnum.TASKS,
|
||||
chartFrame: ChartFrameEnum.COMMON,
|
||||
image: 'banner.png',
|
||||
};
|
||||