fixed:态势图首页bug修复,甘特图部分功能

This commit is contained in:
aq 2025-04-07 11:10:49 +08:00
parent 42841de47d
commit 2283317c85
19 changed files with 284 additions and 39 deletions

View File

@ -34,8 +34,44 @@ window['settings'] = {
: {
icon: './images/icons/10-7600-0-侦察机.svg',
color: '#d00',
model: './models/IDF.glb',
payload: 'airplaneConic',
model: './models/甲.glb',
payload: 'radar',
},
预警机: {
icon: './images/icons/10-7600-0-侦察机.svg',
color: '#d00',
model: './models/预警机.glb',
payload: 'radar',
},
战斗机: {
icon: './images/icons/10-7600-0-侦察机.svg',
color: '#d00',
model: './models/战斗机.glb',
payload: 'radar',
},
运输机: {
icon: './images/icons/10-7600-0-侦察机.svg',
color: '#d00',
model: './models/运输机.glb',
payload: 'radar',
},
轰炸机: {
icon: './images/icons/10-7600-0-侦察机.svg',
color: '#d00',
model: './models/轰炸机.glb',
payload: 'radar',
},
武装直升机: {
icon: './images/icons/10-7600-0-侦察机.svg',
color: '#d00',
model: './models/武装直升机.glb',
payload: 'radar',
},
加油机: {
icon: './images/icons/10-7600-0-侦察机.svg',
color: '#ff0',
model: './models/加油机.glb',
payload: 'radar',
},
: {
icon: './images/icons/10-5900-0-航空母舰.svg',
@ -46,7 +82,7 @@ window['settings'] = {
: {
icon: './images/icons/10-6100-0-驱逐舰.svg',
color: '#dd0',
model: './models/驱逐舰2.glb',
model: './models/驱逐舰1.glb',
payload: 'radar',
},
},

BIN
public/models/F-2A.glb Executable file

Binary file not shown.

BIN
public/models/IDF.glb Executable file

Binary file not shown.

BIN
public/models/加油机.glb Executable file

Binary file not shown.

BIN
public/models/战斗机.glb Executable file

Binary file not shown.

BIN
public/models/武装直升机.glb Executable file

Binary file not shown.

BIN
public/models/甲.glb Executable file

Binary file not shown.

BIN
public/models/轰炸机.glb Executable file

Binary file not shown.

BIN
public/models/运输机.glb Executable file

Binary file not shown.

BIN
public/models/预警机.glb Executable file

Binary file not shown.

View File

@ -93,8 +93,43 @@ async function getMBEntityOpt({
const mubiaoDict = window.settings.mbDict[targetType]
const countryColor = window.settings.mbCountryDict[country]
// const headingPitchRoll = new Cesium.HeadingPitchRoll(
// heading,
// pitch,
// roll
// )
// const newOrientation = Cesium.Transforms.headingPitchRollQuaternion(
// obj.position,
// headingPitchRo11
// )
const staticOrientation = {
position: Cesium.Cartesian3.fromDegrees(116.0, 39.9, 10000), // 初始位置北京附近高度10km
orientation: Cesium.Transforms.headingPitchRollQuaternion(
Cesium.Cartesian3.fromDegrees(116.0, 39.9, 10000),
new Cesium.HeadingPitchRoll(
Cesium.Math.toRadians(90), // 航向正东方向0=正北90=正东)
Cesium.Math.toRadians(-90), // 俯仰:轻微下倾(模拟地球曲率)
Cesium.Math.toRadians(0) // 滚转:保持水平
)
),
properties: {
velocity: 800, // 飞行速度km/h
heading: 90.0, // 当前航向(度)
pitch: -90, // 当前俯仰(度)
roll: 0.0, // 当前滚转(度)
altitude: 10000 // 当前高度(米)
}
};
// console.log(country, countryColor)
let ellipsoid
let ellipsoid;
console.log(extendInfo,targetType,id,'----exteninfo')
let flag = false ;
if(id == 'xx19' || id == 'xx42' || id == 'xx42' || id == 'xxx1' || id == 'xx14' || id == 'xx30' || id == 'xx48' || id == 'xx24' || id == 'xx'){
flag = true
}
if (extendInfo) {
const {
angle,
@ -150,6 +185,19 @@ async function getMBEntityOpt({
0.4
),
scaleByDistance: new Cesium.NearFarScalar(7000000, 1.0, 18000000, 0.4),
},
// 新增 name 标签(例如显示在 id 下方)
nameLabel: {
text: '99999999999', // 假设 name 是传入的变量
font: '12pt sans-serif',
fillColor: Cesium.Color.WHITE, // 白色文字
outlineColor: Cesium.Color.BLACK,
outlineWidth: 2,
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
pixelOffset: new Cesium.Cartesian2(20, -40), // 调整位置(在 id 下方)
pixelOffsetScaleByDistance: new Cesium.NearFarScalar(7000000, 1.0, 18000000, 0.4),
scaleByDistance: new Cesium.NearFarScalar(7000000, 1.0, 18000000, 0.4),
show: true // 默认显示
},
billboard: {
show: !iconOrModel.value,
@ -161,11 +209,15 @@ async function getMBEntityOpt({
color: Cesium.Color.fromCssColorString(countryColor),
scaleByDistance: new Cesium.NearFarScalar(7000000, 1.0, 18000000, 0.4),
},
...(flag ? {
orientation: staticOrientation.orientation,
properties: staticOrientation.properties
} : {}),
model: {
show: iconOrModel.value,
uri: mubiaoDict.model,
scale: 1000,
minimumPixelSize: 50,
scale: 50,
minimumPixelSize: 25,
},
...ellipsoid,
}

View File

@ -239,7 +239,10 @@ class SatelliteEntity {
}
// this.createSensor(satelliteEntity)
// return satelliteEntity
this.createPointUnderTheSatellite(color)
const color1 = Cesium.Color.fromCssColorString(
chroma.random().brighten().hex()
).withAlpha(0.8)
this.createPointUnderTheSatellite(color1)
this.entity = viewer.entities.add(satelliteEntity)
return this.entity
}

View File

@ -4,7 +4,7 @@ import { useRoute } from 'vue-router'
import { time2FormatWithTimezone } from '@/utils/date'
import WidgetNav from '../WidgetNav'
const timeZoneList = [
const timeZoneList1 = [
{ label: '中国/北京', value: 'Asia/Shanghai' },
{ label: '日本/东京', value: 'Asia/Tokyo' },
{ label: '韩国/首尔', value: 'Asia/Seoul' },
@ -20,18 +20,87 @@ const timeZoneList = [
{ label: '俄罗斯/莫斯科', value: 'Europe/Moscow' },
{ label: '澳大利亚/悉尼', value: 'Australia/Sydney' },
]
const timezone = ref('Asia/Shanghai')
const worldTime = ref('')
const timeZoneList = [
//
{ label: '中时区', value: 'UTC' },
{ label: '东一区', value: 'UTC+1' },
{ label: '东二区', value: 'UTC+2' },
{ label: '东三区', value: 'UTC+3' },
{ label: '东四区', value: 'UTC+4' },
{ label: '东五区', value: 'UTC+5' },
{ label: '东六区', value: 'UTC+6' },
{ label: '东七区', value: 'UTC+7' },
{ label: '东八区', value: 'UTC+8' },
{ label: '东九区', value: 'UTC+9' },
{ label: '东十区', value: 'UTC+10' },
{ label: '东十一区', value: 'UTC+11' },
{ label: '东十二区', value: 'UTC+12' },
// 西
{ label: '西十二区', value: 'UTC-12' },
{ label: '西十一区', value: 'UTC-11' },
{ label: '西十区', value: 'UTC-10' },
{ label: '西九区', value: 'UTC-9' },
{ label: '西八区', value: 'UTC-8' },
{ label: '西七区', value: 'UTC-7' },
{ label: '西六区', value: 'UTC-6' },
{ label: '西五区', value: 'UTC-5' },
{ label: '西四区', value: 'UTC-4' },
{ label: '西三区', value: 'UTC-3' },
{ label: '西二区', value: 'UTC-2' },
{ label: '西一区', value: 'UTC-1' }
];
const timezone = ref('UTC+8')
const worldTime = ref()
function adjustTime(targetValue) {
//
const match = targetValue.match(/UTC([+-])(\d+)/);
if (!match) throw new Error('Invalid timezone format');
const sign = match[1] === '+' ? 1 : -1;
const targetOffset = sign * parseInt(match[2], 10);
//
const now = new Date();
// -
const diffHours = targetOffset - 8;
//
return new Date(
now.getTime() + diffHours * 60 * 60 * 1000
);
}
function getAdjustedTime(targetValue) {
const date = adjustTime(targetValue);
//
return date.toLocaleString('zh-CN', {
timeZone: 'Asia/Shanghai', // 使
hour12: false
});
}
// 使
console.log('调整后时间:', getAdjustedTime('UTC+9'));
// 2023/10/15 13:30:00
const getTime = () => {
// const date = moment(new Date()).tz(timezone.value)
// console.log(date)
worldTime.value = time2FormatWithTimezone(new Date(), timezone.value)
worldTime.value = getAdjustedTime(timezone.value)
// console.log(timezone.value,'---timezone.value')
// worldTime.value = time2FormatWithTimezone(new Date(), timezone.value)
requestAnimationFrame(getTime)
}
const localeTime = ref('')
const getLocalTime = () => {
localeTime.value = time2FormatWithTimezone(new Date(), 'Asia/Shanghai')
// localeTime.value = time2FormatWithTimezone(new Date(), 'Asia/Shanghai')
localeTime.value = getAdjustedTime(timezone.value)
requestAnimationFrame(getLocalTime)
}
onMounted(() => {
@ -59,7 +128,7 @@ const route = useRoute()
<div class="time-title cursor-pointer">
{{
timeZoneList.find(item => item.value === timezone).label ||
'中国/北京'
'东八区'
}}
</div>
</n-popselect>

View File

@ -40,7 +40,7 @@ export default defineComponent({
label-field="nodeName"
// v-model:checked="checkedKeys"
// defaultCheckedKeys="allKeys"
checkable={false}
// checkable={false}
showSearch
renderSuffix={renderSuffix}
// nodeProps={nodeProps}

View File

@ -5,6 +5,7 @@ import {
NButton,
NDatePicker,
NUpload,
NSwitch,
} from 'naive-ui'
import ModalCom from '@/components/Modal/index.vue'
import { useEvent } from '../hooks'
@ -76,7 +77,15 @@ export default defineComponent({
formRef.value?.validate(erros => {})
}
}
watch(
() => mainEventData.value.eventType,
val => {
console.log(val, '------eventType')
},
{
immediate: true,
}
)
watch(
[
() => mainEventData.value.fileUrl,
@ -123,7 +132,7 @@ export default defineComponent({
<NFormItem label="事件时间" path="timeRange">
<NDatePicker
v-model:value={mainEventData.value.timeRange}
type="datetimerange"
type="daterange"
clearable
/>
</NFormItem>
@ -133,6 +142,27 @@ export default defineComponent({
type="textarea"
/>
</NFormItem>
<NFormItem label="事件类型" path="eventType">
<NSwitch
v-model:value={mainEventData.value.eventType}
checked-value={true}
unchecked-value={false}
default-value={true}
v-slots={{
checked: () => '已发生',
unchecked: () => '未发生',
}}
></NSwitch>
</NFormItem>
{!mainEventData.value.eventType ? (
<NFormItem label="导弹种类" path="category">
<NInput
v-model:value={mainEventData.value.category}
type="text"
/>
</NFormItem>
) : null}
<NFormItem label="上传图片" path="fileUrl">
<NUpload
default-file-list={uploadImg.value}

View File

@ -13,13 +13,27 @@ const subEventRules = {
trigger: ['blur', 'change'],
},
}
// const mainEventRules = {
// name: { required: true, message: '', trigger: ['blur', 'input'] },
// timeRange: {
// required: true,
// message: '',
// trigger: ['blur', 'input'],
// },
// }
const mainEventRules = {
name: { required: true, message: '请输入名称', trigger: ['blur', 'input'] },
timeRange: {
required: true,
message: '请选择时间',
trigger: ['blur', 'input'],
validator(rule, value) {
if (!value) {
return new Error('请选择时间范围')
}
return true
},
trigger: ['change'],
},
}
const showMainEvent = ref(false)
@ -37,14 +51,16 @@ const mainEventData = ref({
// type: 'mainEvent',
describe: '',
fileUrl: '',
eventType: true,
category: '123333',
})
function resetMainEventData() {
mainEventData.value = {
name: '',
timeRange: null,
describe: '',
eventType: true,
fileUrl: '',
}
}
@ -66,6 +82,7 @@ const eventData = ref({
timeRange: null,
fileUrl: '',
describe: '',
eventType: true,
equipModel: '',
reportSite: '',
twoType: '',
@ -78,6 +95,7 @@ function resetEventData() {
timeRange: null,
fileUrl: '',
describe: '',
eventType: true,
equipModel: '',
reportSite: '',
twoType: '',
@ -90,12 +108,11 @@ const oneClassData = ref(null)
async function searchTreeList() {
tableData.value = []
// const res = await getSimpTreeList({
// targetId: targetId.value,
// startTime: range.value ? range.value[0] : null,
// endTime: range.value ? range.value[1] : null,
// })
const res = await getSimpTreeList()
const res = await getSimpTreeList({
targetId: targetId.value,
startTime: range.value ? range.value[0] : null,
endTime: range.value ? range.value[1] : null,
})
tableData.value = res.data.list
// console.log('searchTreeList', tableData)
}

View File

@ -1,4 +1,11 @@
import { Group, Image, Text, CheckBox, Rect } from '@visactor/vtable/es/vrender'
import {
Group,
Image,
Text,
CheckBox,
Rect,
Circle,
} from '@visactor/vtable/es/vrender'
import { useDialog } from 'naive-ui'
import { Gantt, tools, TYPES } from '@visactor/vtable-gantt'
import { getMainGantt, getSubGantt } from '@/api/Gantt/gantt'
@ -116,7 +123,7 @@ const useGantt = ({ router, route }: GanttParams) => {
dom: HTMLElement,
params: Record<string, string>
) {
// console.log(subId, 'renderMainTask')
console.log(subId, 'renderMainTask')
await getGanttData(params)
const option = getOption()
@ -179,6 +186,7 @@ const useGantt = ({ router, route }: GanttParams) => {
},
headerRowHeight: 59,
rowHeight: subId ? 200 : 100,
taskBar: renderTaskBar(subId),
timelineHeader: {
backgroundColor: headerBgColor,
@ -567,6 +575,18 @@ const useGantt = ({ router, route }: GanttParams) => {
container.add(rect)
}
if (!subId) {
// 添加状态圆点直径8px
const dot = new Circle({
radius: 4, // 半径4px
fill: textColor, // 填充色
stroke: textColor, // 边框色
strokeWidth: 1, // 边框粗细
zIndex: 10, // 确保显示在最上层
})
container.add(dot)
}
return {
rootContainer: container,
}

View File

@ -56,22 +56,24 @@ export default defineComponent({
refresh.value = false
}
})
function getRefresh() {
console.log(props.happen, '------------heppen')
renderMainTask(document.querySelector('#tableContainer'), {
ids: props.types,
startTime: props.dateRange ? props.dateRange[0] : null,
endTime: props.dateRange ? props.dateRange[1] : null,
status: props.happen, //12
})
stopRefresh()
intervalTimer = new Interval(startRefresh, 5000, { immediate: true })
intervalTimer.startInterval()
refresh.value = false
}
onMounted(() => {
nextTick(() => {
// console.log(props);
renderMainTask(document.querySelector('#tableContainer'), {
ids: props.types,
startTime: props.dateRange ? props.dateRange[0] : null,
endTime: props.dateRange ? props.dateRange[1] : null,
status: props.happen, //12
})
stopRefresh()
intervalTimer = new Interval(startRefresh, 5000, { immediate: true })
intervalTimer.startInterval()
refresh.value = false
getRefresh()
})
})
watch(
@ -83,6 +85,9 @@ export default defineComponent({
watch(
() => props.happen,
val => {
console.log('------------------------happenChange')
// getRefresh()
requestAnimationFrame(getRefresh)
changeTimeScales(props.scale, val)
}
)

View File

@ -103,6 +103,19 @@ export default defineComponent({
},
],
conic: [
{
title: '名称',
key: 'name',
render(row) {
return (
<NInput
v-model:value={row.name}
max={120}
min={0}
></NInput>
)
},
},
{
title: '开合角',
key: 'angle',