main
徐景良 1 week ago
parent 8b6d626f11
commit 44a5902ce5

@ -8,7 +8,7 @@ VITE_PUBLIC_PATH = /
#基础框架
VITE_GLOB_API_URL = http://192.168.10.163:9620
VITE_GLOB_API_URL_SITUATION = http://192.168.10.163:9024
VITE_GLOB_API_URL_SITUATION = http://192.168.10.163:9024/
# File upload address optional
# It can be forwarded by nginx or write the actual address directly
VITE_GLOB_UPLOAD_URL= http://60.213.14.14:6070

@ -38,4 +38,4 @@ VITE_GLOB_YINGXIANG_SERVER = http://192.168.31.205:8080/geoserver/ne/wms?service
VITE_GLOB_FILE_PREVIEW = http://120.222.154.7:6081
VITE_GLOB_API_URL_SITUATION = http://123.132.248.154:6033
VITE_GLOB_API_URL_SITUATION = http://123.132.248.154:6033/

Binary file not shown.

After

Width:  |  Height:  |  Size: 359 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 381 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 911 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 394 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

File diff suppressed because it is too large Load Diff

@ -445,7 +445,6 @@ export function mapFun() {
// 加载图层
const handlerAddLayer = (params)=>{
let data = null;
layerOptions?.forEach((item,index)=>{
item?.children?.forEach((it,idx)=>{

@ -3,11 +3,11 @@
<div class="flex ai-c jc-sb max-w navsbox">
<div
class="flex navsli ai-c jc-c"
v-for="(item, index) in navsArr"
:class="index == navsIndex ? 'navsliactive' : ''"
@click="navsClick(item, index)"
>
{{ item.label }}
v-for="(item, index) in navsArr"
:class="index == navsIndex ? 'navsliactive' : ''"
@click="navsClick(item, index)"
>
{{ item.label }}
<span class="navsNum" v-if="item.value != 0">{{ item.value }}</span>
</div>
</div>
@ -25,9 +25,12 @@
<img class="mr-1" src="@/assets/images/chart/equipment/address.png" />
<div class="numStyle" :title="item.address">{{ item.address }}</div>
</div>
<div class="flex mt-1 ai-c">
<img class="mr-1 timeicon" src="@/assets/images/chart/equipment/time.png" />
<div class="numStyle">{{ item.reportTime }}</div>
<div class="flex mt-1 ai-c spaceBetween">
<div class="flex">
<img class="mr-1 timeicon" src="@/assets/images/chart/equipment/time.png" />
<div class="numStyle">{{ item.reportTime }}</div>
</div>
<div class="numStyle typeStyle">{{item.sourceType}}</div>
</div>
</div>
</div>
@ -41,6 +44,7 @@
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore';
import * as mars3d from 'mars3d';
import { EventBus } from '@/utils/eventBus';
import axios from 'axios'
import { eventHandlerHook } from '@/hooks/eventHandler.hook';
const chartEditStore = useChartEditStore();
@ -71,19 +75,35 @@
datasSize,
} = toRefs(props.chartConfig.option);
console.log("navsArr",navsArr.value)
const navsClick = function (item, index) {
navsIndex.value = index;
props.chartConfig.request.requestSQLContent.sql = item.sql;
console.log("props.chartConfig",props.chartConfig);
useChartDataFetch(props.chartConfig, useChartEditStore, (resData: any) => {
props.chartConfig.option.sectionDatas = resData;
});
};
// 线
const getStateCount = function(){
}
// callback
useChartDataFetch(props.chartConfig, useChartEditStore, (resData: any[]) => {
props.chartConfig.option.sectionDatas = resData;
});
onMounted(() => {
// 线
getStateCount();
//
setTimeout(function () {
handlerLoadFirePoint(sectionDatas.value);
@ -171,7 +191,7 @@
style: {
image: '/map/fire.png',
clampToGround: true,
scale: 0.8,
scale: 0.6,
label: {
text: item.title,
font_size: 12,
@ -239,7 +259,7 @@
//
const handlerFireDetail = (item) => {
//
//
eventHandlerHook(
chartEditStore.getComponentList,
props.chartConfig.events.interactConfigEvents,
@ -349,8 +369,7 @@
}
}
.sectionLi {
padding: 9px 12px;
height: 104px;
padding: 10px 12px 20px 12px;
background: url('@/assets/images/chart/equipment/sectionbg.png');
background-size: 100% 100%;
}
@ -369,6 +388,14 @@
overflow: hidden; /* 隐藏溢出内容 :ml-search[overflow] */
text-overflow: ellipsis;
}
.typeStyle{
float:right;
background: url('@/assets/images/chart/equipment/source-type-bg.png');
padding:2px 12px;
background-size:100% 100%;
background-repeat: no-repeat;
}
.desStyle {
color: v-bind('desColor');
font-size: v-bind('desSize+"px"');
@ -385,5 +412,11 @@
.mt-1 {
margin-top: 8px;
}
}
.spaceBetween{
justify-content: space-between;
}
</style>

@ -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>

@ -1,5 +1,6 @@
<template>
<div class="go-title-03">
<!-- 图片信息 -->
<div class="bannerbox" >
<a-carousel autoplay dots-class="slick-dots slick-thumb" preview-disabled v-if="imageLoading">
<div v-for="item in dataset.imgArr">
@ -8,6 +9,7 @@
</div>
</a-carousel>
</div>
<!-- 字段信息 -->
<div class="flex column sectionsbox">
<div class="flex mt-1" v-for="item in dataset.data">
<div class="flex ai-c jc-c tasktitlesbox">
@ -56,15 +58,16 @@ const imageLoading = ref(false);
onMounted(()=>{
const sql = props.chartConfig.request?.requestSQLContent?.sql;
//
EventBus.on(props.chartConfig.id+'dataupdate', (data) => {
// sql
props.chartConfig.request.requestSQLContent.sql = replaceSqlParams(sql,{Id:data.id})
// callback
useChartDataFetch(props.chartConfig, useChartEditStore, (resData: any) => {
// props.chartConfig.option.dataset = resData;
let data = [];
props.chartConfig.option.showColumns?.forEach((item,index)=>{
let info = {
title:item.zh_name,
@ -72,11 +75,8 @@ onMounted(()=>{
}
data.push(info);
})
//
props.chartConfig.option.dataset.imgArr = [];
let tempImages = resData[0].image.split(",");
if(tempImages.length>0){
@ -86,12 +86,12 @@ onMounted(()=>{
}else{
props.chartConfig.option.dataset.imgArr = [VITE_GLOB_API_URL+"/"+resData[0].image]
}
console.log("props.chartConfig.option.dataset.imgArr",props.chartConfig.option.dataset.imgArr);
imageLoading.value = true;
props.chartConfig.option.dataset.data = data;
});
});
})
function firstLetterToLowerCase(str) {

@ -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',
};

@ -0,0 +1,219 @@
<template>
<div class="go-title-03">
<div class="clue-information-container">
<div class="left-container">
</div>
<div class="right-container">
</div>
</div>
<!-- 图片信息 -->
<div class="bannerbox" >
<a-carousel autoplay dots-class="slick-dots slick-thumb" preview-disabled v-if="imageLoading">
<div v-for="item in dataset.imgArr">
<a-image :src="item" />
</div>
</a-carousel>
</div>
<!-- 字段信息 -->
<div class="flex column sectionsbox">
<div class="flex mt-1" v-for="item in dataset.data">
<div class="flex ai-c jc-c tasktitlesbox">
<div class="dots"></div>
<div class="titleText">{{ item.title }}</div>
</div>
<div class="desStyle">{{ item.desc }}</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { PropType, toRefs, ref, onMounted } from 'vue';
import { CreateComponentType } from '@/packages/index.d';
import { useChartDataFetch } from '@/hooks';
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore';
import { EventBus } from '@/utils/eventBus';
import { getAppEnvConfig } from '@/utils/env'
import { getAssetsImg } from '@/utils/index';
import { replaceSqlParams } from '@/utils/sqlHandler';
var { VITE_GLOB_API_URL } = getAppEnvConfig();
const props = defineProps({
chartConfig: {
type: Object as PropType<CreateComponentType>,
required: true
}
})
const { w, h } = toRefs(props.chartConfig.attr)
const {
colors,
titleSize,
titleColor,
desColor,
desSize,
dataset
} = toRefs(props.chartConfig.option)
const imageLoading = ref(false);
onMounted(()=>{
const sql = props.chartConfig.request?.requestSQLContent?.sql;
//
EventBus.on(props.chartConfig.id+'dataupdate', (data) => {
// sql
props.chartConfig.request.requestSQLContent.sql = replaceSqlParams(sql,{Id:data.id})
// callback
useChartDataFetch(props.chartConfig, useChartEditStore, (resData: any) => {
let data = [];
props.chartConfig.option.showColumns?.forEach((item,index)=>{
let info = {
title:item.zh_name,
desc:resData[0][firstLetterToLowerCase(item.en_name)]
}
data.push(info);
})
//
props.chartConfig.option.dataset.imgArr = [];
let tempImages = resData[0].image.split(",");
if(tempImages.length>0){
tempImages?.forEach((img,idx)=>{
props.chartConfig.option.dataset.imgArr.push(VITE_GLOB_API_URL+"/"+img)
})
}else{
props.chartConfig.option.dataset.imgArr = [VITE_GLOB_API_URL+"/"+resData[0].image]
}
imageLoading.value = true;
props.chartConfig.option.dataset.data = data;
});
});
})
function firstLetterToLowerCase(str) {
return str.charAt(0).toLowerCase() + str.slice(1);
}
//
const handlerShowColumns = ()=> {
}
</script>
<style lang="scss" scoped>
@include go('title-03') {
position: relative;
width: v-bind('w'+"px");
height: v-bind('h'+"px");
padding: 18px 20px;
.max-w{
width: 100%;
}
.column{
flex-direction: column;
}
.flex{
display: flex;
}
.jc-sb{
justify-content: space-between;
}
.jc-sa{
justify-content: space-around;
}
.ai-c{
align-items: center;
}
.mt-1{
margin-top: 5px;
}
.bannerbox{
width: 100%;
height: 44%;
border: 1px solid v-bind('colors[0]');
padding: 6px;
margin-bottom: 40px;
}
.sectionsbox{
width: 96%;
margin: 0 auto;
}
.tasktitlesbox{
width: 120px;
height: 30px;
}
.dots{
width: 3px;
height: 3px;
border-radius: 3px;
background: v-bind('colors[3]');
margin-right: 8px;
}
.titleText{
color: v-bind('titleColor');
font-size: v-bind('titleSize+"px"');
}
.desStyle{
width: calc(100% - 120px);
color: v-bind('desColor');
font-size: v-bind('desSize+"px"');
line-height: 30px;
}
:deep(.ant-carousel){
height: 100%;
}
:deep(.ant-image){
width: 100%;
height: 100%;
}
:deep(.slick-slider){
height: 100%;
}
:deep(.slick-list){
height: 100%;
}
:deep(.slick-track){
height: 100%;
}
:deep(.slick-slide) {
text-align: center;
height: 100%;
line-height: 100%;
overflow: hidden;
}
:deep(.slick-slide img) {
width: 100%;
height: 100%;
}
:deep(.slick-dots) {
position: relative;
bottom: -20px;
}
:deep(.slick-dots li.slick-active button) {
background: v-bind('colors[2]');
}
:deep(.slick-dots li button) {
background: v-bind('colors[1]');
}
}
</style>

@ -15,6 +15,7 @@ import { TaskIcons02Config } from './TaskIcons02/index';
import { TaskIcons03Config } from './TaskIcons03/index';
import { TaskAddRouteConfig } from './TaskAddRoute/index';
import { TaskRoutePlanConfig } from './TaskRoutePlan/index';
import {TaskAssignConfig} from './TaskAssign';
export default [
@ -34,5 +35,6 @@ export default [
TaskIcons02Config,
TaskIcons03Config,
TaskAddRouteConfig,
TaskRoutePlanConfig
TaskRoutePlanConfig,
TaskAssignConfig,
];

Loading…
Cancel
Save