添加导弹

This commit is contained in:
严争鸣 2025-05-09 18:09:03 +08:00
parent fce2eb5df3
commit 6af0bab0d6
11 changed files with 272 additions and 130 deletions

Binary file not shown.

View File

@ -7,3 +7,19 @@ export function getDaodanTree() {
method: 'get', method: 'get',
}) })
} }
export function updateDDManualConfigTrajInfo(data) {
return request({
url: `${baseUrl}/dd/gjInfo`,
method: 'PUT',
data,
})
}
export function uploadDDSTKFile(data) {
return request({
url: `${baseUrl}/dd/upload-stk`,
method: 'POST',
data,
})
}

View File

@ -8,29 +8,28 @@ import { useTestConfig } from './hooks/testHooks'
const panels = ['手动配置', 'STK轨迹文件配置'] const panels = ['手动配置', 'STK轨迹文件配置']
export default defineComponent({ export default defineComponent({
setup() { setup() {
const { daodanData, showOrHideDdConfig } = useDaodan() const { daodanData, showOrHideDdConfig, getDaodanTreeData } = useDaodan()
const { const {
trajData, trajData,
boosterList, boosterList,
interceptData, interceptData,
loadStoreData, loadStoreData,
loadData,
saveDataToStore, saveDataToStore,
addIntercept, saveDataToBackend,
initDaodan,
} = useTestConfig() } = useTestConfig()
watch(daodanData, newval => { watch(daodanData, newval => {
loadStoreData() // loadStoreData()
// console.log(newval, '-=----') loadData()
// console.log(daodanData.value, 'newval')
}) })
const name = ref('手动配置') const name = ref('手动配置')
// const handleClose = () => {}
const confirm = () => { const confirm = () => {
// initDaodan() // saveDataToStore()
saveDataToStore() saveDataToBackend()
showOrHideDdConfig({}) showOrHideDdConfig({})
getDaodanTreeData()
} }
const removeIntercept = id => { const removeIntercept = id => {
@ -96,11 +95,37 @@ export default defineComponent({
</> </>
) : ( ) : (
<> <>
<TrajUpload title="轨迹点" /> <TrajUpload
<TrajUpload title="一级助推器" /> title="轨迹点"
<TrajUpload title="二级助推器" /> ddData={daodanData.value}
<TrajUpload title="三级助推器" /> type={daodanData.value.id}
<TrajUpload title="拦截" /> tableData={
daodanData.value.stkInfo?.[daodanData.value.id] ||
[]
}
/>
{['一级助推器', '二级助推器', '三级助推器'].map(
(title, index) => (
<TrajUpload
title={title}
ddData={daodanData.value}
type={`booster-${index + 1}`}
tableData={
daodanData.value.stkInfo?.[
`booster-${index + 1}`
] || []
}
/>
)
)}
<TrajUpload
title="拦截"
ddData={daodanData.value}
type={'intercept-1'}
tableData={
daodanData.value.stkInfo?.['intercept-1'] || []
}
/>
</> </>
)} )}
</div> </div>

View File

@ -125,8 +125,10 @@ export default defineComponent({
title: getTitle('time'), title: getTitle('time'),
key: 'time', key: 'time',
render(row) { render(row) {
return ( return row.name !== '最高点' ? (
<NDatePicker v-model:value={row.time} type="datetime"></NDatePicker> <NDatePicker v-model:value={row.time} type="datetime"></NDatePicker>
) : (
'-'
) )
}, },
}, },
@ -146,18 +148,18 @@ export default defineComponent({
return dict[key] || key return dict[key] || key
} }
const dialog = useDialog() // const dialog = useDialog()
const remove = () => { // const remove = () => {
dialog.warning({ // dialog.warning({
title: '删除拦截', // title: '',
content: '确定删除该拦截吗?', // content: '',
positiveText: '确定', // positiveText: '',
negativeText: '取消', // negativeText: '',
onPositiveClick: () => { // onPositiveClick: () => {
emit('removeIntercept', dataId.value) // emit('removeIntercept', dataId.value)
}, // },
}) // })
} // }
const columnsFilter = computed(() => { const columnsFilter = computed(() => {
if (props.title === '轨迹点') { if (props.title === '轨迹点') {

View File

@ -1,4 +1,5 @@
import { NUpload, NButton } from 'naive-ui' import { NUpload, NButton, NDataTable } from 'naive-ui'
import { time2Format } from '@/utils/date'
export default defineComponent({ export default defineComponent({
name: 'TrajUpload', name: 'TrajUpload',
@ -7,17 +8,82 @@ export default defineComponent({
type: String, type: String,
required: true, required: true,
}, },
ddData: {
type: Object,
default: () => ({}),
},
type: {
type: String,
default: '',
},
tableData: {
type: Array,
default: () => [],
},
}, },
setup(props, { emit }) { setup(props, { emit }) {
const columns = [
{
title: '序号',
key: 'index',
width: 80,
render: (row, rowIndex) => {
return rowIndex + 1
},
},
{
title: '经度',
key: 'lon',
width: 120,
},
{
title: '纬度',
key: 'lat',
},
{
title: '高度',
key: 'alt',
},
{
title: '时间',
key: 'time',
render: row => {
return time2Format(row.time)
},
// width: 120,
},
]
const tableData = ref([])
function handleFinish({ file, event }) {
console.log(JSON.parse(event.target.response))
const { data } = JSON.parse(event.target.response)
tableData.value = data.stkInfo[props.ddData.id]
}
return () => ( return () => (
<> <>
<div class="detail-item-title">{props.title}</div> <div class="detail-item-title">{props.title}</div>
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<div class="w-[80px]">STK 文件</div> <div class="w-[80px]">STK 文件</div>
<NUpload action="https://www.mocky.io/v2/5e4bafc63100007100d8b70f"> <NUpload
action={`api/${window.settings.apis}/dd/upload-stk`}
data={{ fileId: props.type, daoDanId: props.ddData.id }}
onFinish={handleFinish}
>
<NButton>上传文件</NButton> <NButton>上传文件</NButton>
</NUpload> </NUpload>
</div> </div>
<div>
<NDataTable
max-height={250}
columns={columns}
data={
props.tableData.length > 0 ? props.tableData : tableData.value
}
></NDataTable>
</div>
</> </>
) )
}, },

View File

@ -246,7 +246,7 @@ function addDaodan(trajData, type = 0) {
let minTime = 0 let minTime = 0
function initDaodan() { function initDaodan() {
saveDataToStore() // saveDataToStore()
minTime = getMinTime([ minTime = getMinTime([
...toRaw(trajData.value.data), ...toRaw(trajData.value.data),
// ...toRaw(interceptData.value.map(item => toRaw(item.data))).flat(Infinity), // ...toRaw(interceptData.value.map(item => toRaw(item.data))).flat(Infinity),

View File

@ -60,8 +60,7 @@ export function useDDPlay({
function computePath(daodan, trajData, type) { function computePath(daodan, trajData, type) {
const { id, data: ddTrajData } = trajData const { id, data: ddTrajData } = trajData
ddTrajData[1].lon = (ddTrajData[0].lon + ddTrajData[2].lon) / 2
ddTrajData[1].lat = (ddTrajData[0].lat + ddTrajData[2].lat) / 2
const points = ddTrajData.map(item => { const points = ddTrajData.map(item => {
const { time, lon, lat, alt } = item const { time, lon, lat, alt } = item
@ -691,7 +690,7 @@ export function useDDPlay({
position: positionProperty, position: positionProperty,
polyline: { polyline: {
positions: positionList, positions: positionList,
width: 8, width: 16,
material: new Cesium.PolylineGlowMaterialProperty({ material: new Cesium.PolylineGlowMaterialProperty({
glowPower: 0.1, glowPower: 0.1,
color: type color: type
@ -726,6 +725,8 @@ export function useDDPlay({
return { return {
entities: [pathLine, ddMap, boosterMap, interceptMap], entities: [pathLine, ddMap, boosterMap, interceptMap],
addDaodan, addDaodan,
removeAllEntity,
} }
} }

View File

@ -3,8 +3,7 @@ import { useDaodan } from '../../ddHooks'
import { cartesian32LonLat } from '@/utils/pos' import { cartesian32LonLat } from '@/utils/pos'
import { generateId } from '@/utils/id' import { generateId } from '@/utils/id'
import store from 'store2' import store from 'store2'
import { useDDPlay } from './ddPlayHooks' import { updateDDManualConfigTrajInfo } from '@/api/daodan'
// import { useDaodan } from '../../ddHooks'
const trajData = ref({ const trajData = ref({
id: 'dd', id: 'dd',
@ -21,7 +20,7 @@ const trajData = ref({
lon: null, lon: null,
lat: null, lat: null,
alt: 2000000, alt: 2000000,
time: 1183135280000, time: null,
}, },
{ {
name: '落点', name: '落点',
@ -82,14 +81,29 @@ export function useTestConfig() {
boosterList, boosterList,
interceptData, interceptData,
loadStoreData, loadStoreData,
loadData,
addIntercept, addIntercept,
handleClickPoint, handleClickPoint,
saveDataToStore, saveDataToStore,
addCheckedDaodan, saveDataToBackend,
initDaodan,
} }
} }
async function saveDataToBackend() {
const { id, name, country } = toRaw(daodanData.value)
const { data, msg } = await updateDDManualConfigTrajInfo({
id,
gjInfo: {
id,
name,
country,
trajData: trajData.value,
boosterList: boosterList.value,
interceptData: interceptData.value,
},
})
}
function saveDataToStore() { function saveDataToStore() {
// test() // test()
const daodanDataRaw = toRaw(daodanData.value) const daodanDataRaw = toRaw(daodanData.value)
@ -118,6 +132,15 @@ function loadStoreData() {
} }
} }
function loadData() {
const daodanDataRaw = toRaw(daodanData.value)
const data = daodanDataRaw.gjInfo
if (data) {
trajData.value = data.trajData
interceptData.value = data.interceptData
}
}
function addIntercept() { function addIntercept() {
// d // d
interceptData.value.push({ interceptData.value.push({
@ -163,77 +186,3 @@ function handleClickPoint(rowData) {
rowData.lat = position[1] rowData.lat = position[1]
}, Cesium.ScreenSpaceEventType.LEFT_CLICK) }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
} }
// function initDaodan() {
// saveDataToStore()
// const minTime = getMinTime([
// ...toRaw(trajData.value.data),
// // ...toRaw(interceptData.value.map(item => toRaw(item.data))).flat(Infinity),
// ])
// // console.log(minTime)
// const { addDaodan } = useDDPlay({
// ddData: {
// ...toRaw(daodanData.value),
// trajData: trajData.value,
// boosterList: boosterList.value,
// interceptData: interceptData.value,
// },
// startTimeStampOfAnimation: Date.now(),
// isAniCalcBasedOnCurrentTime: true,
// minTime: minTime,
// })
// addDaodan()
// }
function addCheckedDaodan(ids) {
const storeDaodanData = store.get('daodanData')
if (ids.length > 0 && storeDaodanData) {
let daodanList = Object.values(storeDaodanData).filter(daodan => {
return ids.includes(daodan.id)
})
daodanList.forEach(item => {
initDaodan(item)
})
}
}
function initDaodan(daodanData, isAniCalcBasedOnCurrentTime = true) {
const { trajData } = daodanData
const minTime = getMinTime([...trajData.data])
const { entities, addDaodan } = useDDPlay({
ddData: {
...daodanData,
},
startTimeStampOfAnimation: Date.now(),
isAniCalcBasedOnCurrentTime,
minTime: minTime,
})
addDaodan()
setInterval(() => {
console.log('entities', entities)
}, 2000)
}
function getMinTime(data) {
let minTime = Infinity
data.forEach(item => {
minTime = Math.min(item.time, minTime)
})
return minTime
}
function dianhuo(ddPrimitive) {
modelAnimationController({
primitive: ddPrimitive,
type: 'BoosterFlames Size',
initVal: 0,
maxVal: 1,
step: 0.1,
fn: () => {
console.log('%c点火', 'color: red;font-size: 20px;border: 1px solid red')
},
})
}

View File

@ -1,6 +1,8 @@
import { onMounted, ref, watch } from 'vue' import { onMounted, ref, watch } from 'vue'
import { getDaodanTree } from '@/api/Daodan' import { getDaodanTree } from '@/api/Daodan'
import store from 'store2' import { useTree } from '@/utils/tree'
import { difference } from 'lodash'
import { useDDPlay } from './components/hooks/ddPlayHooks'
// import { useTestConfig } from './components/hooks/testHooks' // import { useTestConfig } from './components/hooks/testHooks'
const isLoading = ref(false) const isLoading = ref(false)
@ -19,12 +21,87 @@ async function getDaodanTreeData() {
const daodanRes = await getDaodanTree() const daodanRes = await getDaodanTree()
const { code, data } = daodanRes const { code, data } = daodanRes
if (code === '200') { if (code === '200') {
// console.log(data, 'baseRes')
treeData.value = [data] treeData.value = [data]
} }
isLoading.value = false isLoading.value = false
} }
const { filterTreeNodeByField } = useTree()
const daodanMap = new Map()
function addCheckedDaodan(ids) {
const addIds = difference(ids, [...daodanMap.keys()])
const removeIds = difference([...daodanMap.keys()], ids)
if (addIds.length > 0) {
const nodes = filterTreeNodeByField({
treeData: treeData.value,
params: addIds,
paramName: 'dataId',
})
nodes.forEach(node => {
console.log(node.data, '-----')
node?.data?.gjInfo && initDaodan(node.data.gjInfo)
})
// console.log(nodes, 'nodes------')
// nodes.forEach(node => {
// const {
// data: { stkInfo },
// } = node
// Object.keys(stkInfo).forEach(key => {
// const color = Cesium.Color.fromRandom().withAlpha(1)
// stkInfo[key].forEach(item => {
// viewer.entities.add({
// position: Cesium.Cartesian3.fromDegrees(
// item.lon,
// item.lat,
// item.alt
// ),
// point: {
// color: color,
// pixelSize: 5,
// },
// })
// })
// })
// })
}
if (removeIds.length > 0) {
// removeDaodan(removeIds)
removeIds.forEach(id => {
daodanMap.get(removeIds[0])?.removeAllEntity()
})
}
}
function initDaodan(daodanData, isAniCalcBasedOnCurrentTime = true) {
const { trajData } = daodanData
const { data } = trajData
data[1].lon = (data[0].lon + data[2].lon) / 2
data[1].lat = (data[0].lat + data[2].lat) / 2
data[1].time = (data[2].time - data[0].time) / 2 + data[0].time
const minTime = getMinTime(data)
console.log(minTime, data)
const daodanPlay = useDDPlay({
ddData: {
...daodanData,
},
startTimeStampOfAnimation: Date.now(),
isAniCalcBasedOnCurrentTime,
minTime: minTime,
})
daodanMap.set(daodanData.id, daodanPlay)
daodanPlay.addDaodan()
}
function getMinTime(data) {
let minTime = Infinity
data.forEach(item => {
minTime = Math.min(item.time, minTime)
})
return minTime
}
export function useDaodan() { export function useDaodan() {
return { return {
showDdConfigCom, showDdConfigCom,
@ -33,5 +110,6 @@ export function useDaodan() {
isLoading, isLoading,
daodanData, daodanData,
treeData, treeData,
addCheckedDaodan,
} }
} }

View File

@ -6,10 +6,15 @@ import { onMounted } from 'vue'
export default defineComponent({ export default defineComponent({
setup() { setup() {
const { treeData, isLoading, showOrHideDdConfig, getDaodanTreeData } = const {
useDaodan() treeData,
isLoading,
showOrHideDdConfig,
getDaodanTreeData,
addCheckedDaodan,
} = useDaodan()
const { addCheckedDaodan } = useTestConfig() // const { addCheckedDaodan } = useTestConfig()
onMounted(() => { onMounted(() => {
getDaodanTreeData() getDaodanTreeData()

View File

@ -52,18 +52,18 @@ onMounted(async () => {
viewer.scene.postProcessStages.fxaa.enabled = true viewer.scene.postProcessStages.fxaa.enabled = true
viewer.scene.skyBox = new Cesium.SkyBox({ viewer.scene.skyBox = new Cesium.SkyBox({
sources: { sources: {
positiveX: 'GV/resources/theme/skyBox/PositiveX.jpg', // positiveX: 'GV/resources/theme/skyBox/PositiveX.jpg',
negativeX: 'GV/resources/theme/skyBox/NegativeX.jpg', // negativeX: 'GV/resources/theme/skyBox/NegativeX.jpg',
positiveY: 'GV/resources/theme/skyBox/PositiveY.jpg', // positiveY: 'GV/resources/theme/skyBox/PositiveY.jpg',
negativeY: 'GV/resources/theme/skyBox/NegativeY.jpg', // negativeY: 'GV/resources/theme/skyBox/NegativeY.jpg',
positiveZ: 'GV/resources/theme/skyBox/PositiveZ.jpg', // positiveZ: 'GV/resources/theme/skyBox/PositiveZ.jpg',
negativeZ: 'GV/resources/theme/skyBox/NegativeZ.jpg', // negativeZ: 'GV/resources/theme/skyBox/NegativeZ.jpg',
// positiveX: './images/skybox/skyCube2k_px.jpg', positiveX: './images/skybox/skyCube2k_px.jpg',
// negativeX: './images/skybox/skyCube2k_mx.jpg', negativeX: './images/skybox/skyCube2k_mx.jpg',
// positiveY: './images/skybox/skyCube2k_py.jpg', positiveY: './images/skybox/skyCube2k_py.jpg',
// negativeY: './images/skybox/skyCube2k_my.jpg', negativeY: './images/skybox/skyCube2k_my.jpg',
// positiveZ: './images/skybox/skyCube2k_pz.jpg', positiveZ: './images/skybox/skyCube2k_pz.jpg',
// negativeZ: './images/skybox/skyCube2k_mz.jpg', negativeZ: './images/skybox/skyCube2k_mz.jpg',
}, },
}) })