+
@@ -258,4 +269,86 @@ onMounted(() => {
transform: translateX(-120%) scale(0.8);
filter: blur(4px);
}
+
+.btn-class {
+ @apply h-[28px] w-[110px];
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 1rem;
+ letter-spacing: 4px;
+ color: #a7cae0;
+ cursor: pointer;
+ background: linear-gradient(
+ 90deg,
+ rgba(47, 255, 255, 0.4) 0%,
+ rgba(8, 77, 126, 0.4) 25%,
+ rgba(8, 77, 126, 0.4) 70%,
+ rgba(47, 255, 255, 0.4) 100%
+ );
+ filter: drop-shadow(inset 0 0 0 2px red);
+ clip-path: polygon(
+ 0% 0%,
+ 71.67% 0%,
+ 79.33% 6%,
+ 84% 15.33%,
+ 88% 28%,
+ 91% 41.67%,
+ 94.33% 59.33%,
+ 97% 74%,
+ 99% 88%,
+ 100% 100%,
+ 0% 100%
+ );
+ border-radius: 5px;
+ &:hover {
+ background: linear-gradient(
+ 180deg,
+ rgba(8, 77, 126, 0.2) 0%,
+ rgba(8, 77, 126, 0.42) 100%
+ ),
+ rgba(47, 255, 255, 0.4);
+ box-shadow: inset 0 0 12px rgba(151, 200, 255, 0.44);
+ }
+
+ &::after {
+ content: '显示天气';
+ width: 100%;
+ height: 100%;
+ display: block;
+ position: absolute;
+ left: 0;
+ top: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ // color: '#a7cae0';
+ // background: var(--gradient-bg);
+ // background-clip: text;
+ }
+}
+
+.checked {
+ color: #f2f7fb;
+ background: linear-gradient(
+ 180deg,
+ rgba(8, 77, 126, 0.2) 0%,
+ rgba(8, 77, 126, 0.42) 100%
+ ),
+ rgba(47, 255, 255, 0.4);
+ box-shadow: inset 0 0 12px rgba(151, 200, 255, 0.44);
+}
+
+.left {
+ &::after {
+ content: '热力图';
+ }
+}
+.right {
+ transform: rotateY(180deg);
+ &::after {
+ transform: rotateY(-180deg);
+ }
+}
diff --git a/src/views/Earth/index.vue b/src/views/Earth/index.vue
index 2d617f2c2..fcc0ae067 100644
--- a/src/views/Earth/index.vue
+++ b/src/views/Earth/index.vue
@@ -16,7 +16,9 @@ onMounted(() => {
fullscreenButton: false,
homeButton: false,
imageryProvider: new Cesium.UrlTemplateImageryProvider({
- url: 'GV/resources/theme/earthTheme/{z}/{x}/{y}.jpg',
+ url: 'http://192.168.10.201:2022/api/maptilecache/service/tms/1.0.0/img_globle1to9-PNG-4326@EPSG:4326@png/{z}/{x}/{reverseY}.png',
+ // url: 'js/Cesium/Assets/Textures/NaturalEarthII/{z}/{x}/{reverseY}.jpg',
+ // url: 'GV/resources/theme/earthTheme/{z}/{x}/{y}.jpg',
tilingScheme: new Cesium.GeographicTilingScheme(),
}),
@@ -36,7 +38,16 @@ onMounted(() => {
// 开启抗锯齿
viewer.scene.postProcessStages.fxaa.enabled = true
- // viewer.scene.skyBox = GV.SkyboxTheme.getSkyBox('GV/resources/theme/skyBox/{z}/{x}/{y}.jpg',false,'jpg')
+ viewer.scene.skyBox = new Cesium.SkyBox({
+ sources: {
+ positiveX: 'GV/resources/theme/skyBox/PositiveX.jpg',
+ negativeX: 'GV/resources/theme/skyBox/NegativeX.jpg',
+ positiveY: 'GV/resources/theme/skyBox/PositiveY.jpg',
+ negativeY: 'GV/resources/theme/skyBox/NegativeY.jpg',
+ positiveZ: 'GV/resources/theme/skyBox/PositiveZ.jpg',
+ negativeZ: 'GV/resources/theme/skyBox/NegativeZ.jpg',
+ },
+ })
// viewer.scene.globe.depthTestAgainstTerrain = true
// addBaseFacilities()
diff --git a/src/views/Gantt/components/Gantt/hooks/gantt.ts b/src/views/Gantt/components/Gantt/hooks/gantt.ts
new file mode 100644
index 000000000..23258ea78
--- /dev/null
+++ b/src/views/Gantt/components/Gantt/hooks/gantt.ts
@@ -0,0 +1,334 @@
+import { Group, Image, Text, CheckBox, Rect } from '@visactor/vtable/es/vrender'
+
+import { Gantt, tools, TYPES } from '@visactor/vtable-gantt'
+import { getMainGantt, getSubGantt } from '@/api/Gantt'
+
+type GanttParams = {
+ route?: any
+ router?: any
+}
+let ganttInstance: null | Gantt = null
+const bgColor = '#1c202c'
+const headerBgColor = '#33566f22'
+const textColor = '#65c5e7'
+const textColorWithOp = '#75fbfd22'
+
+const useGantt = ({ router, route }: GanttParams) => {
+ const { subId } = route.params
+ const records = ref([])
+ onMounted(() => {
+ getGanttData(subId)
+ })
+ async function getGanttData(subId: string) {
+ if (subId) {
+ const res = await getSubGantt(subId)
+ records.value = res
+ ganttInstance?.setRecords(records.value)
+ } else {
+ const res = await getMainGantt()
+ // console.log(res, '----')
+ records.value = res
+ ganttInstance?.setRecords(records.value)
+ }
+ }
+ function renderMainTask(dom: HTMLElement) {
+ const option = getOption()
+ ganttInstance = new Gantt(dom, option)
+ // window['ganttInstance'] = ganttInstance
+ console.log(ganttInstance)
+ }
+ function getOption(): TYPES.GanttConstructorOptions {
+ const option = {
+ records: records.value,
+ taskListTable: renderTaskListTable(),
+ tasksShowMode: TYPES.TasksShowMode.Sub_Tasks_Arrange,
+
+ frame: {
+ outerFrameStyle: {
+ borderLineWidth: 2,
+ borderColor: textColor,
+ cornerRadius: 3,
+ },
+ // verticalSplitLineHighlight: {
+ // lineColor: 'green',
+ // lineWidth: 3
+ // }
+ },
+ grid: {
+ // backgroundColor: bgColor,
+ horizontalLine: {
+ lineWidth: 1,
+ lineColor: textColorWithOp,
+ },
+ verticalLine: {
+ lineWidth: 1,
+ lineColor: textColorWithOp,
+ lineDash: [4, 8],
+ },
+ },
+ taskList: {
+ // backgroundColor: bgColor,
+ headerStyle: {
+ borderColor: '#e1e4e8',
+ borderLineWidth: 0,
+ fontSize: 18,
+ fontWeight: 'bold',
+ color: 'red',
+ },
+ },
+ headerRowHeight: 59,
+ rowHeight: subId ? 200 : 100,
+ taskBar: renderTaskBar(subId),
+ timelineHeader: {
+ backgroundColor: headerBgColor,
+ colWidth: 100,
+ verticalLine: {
+ lineColor: textColorWithOp,
+ lineWidth: 1,
+ lineDash: [4, 2],
+ },
+ horizontalLine: {
+ lineColor: textColorWithOp,
+ lineWidth: 1,
+ lineDash: [4, 2],
+ },
+ scales: getTimeScales('day'),
+ },
+ minDate: '2024-11-14',
+ maxDate: '2024-12-30',
+
+ scrollStyle: {
+ scrollRailColor: 'RGBA(246,246,246,0)',
+ visible: 'focus',
+ width: 6,
+ scrollSliderCornerRadius: 2,
+ scrollSliderColor: 'rgba(255,255,255,0.25)',
+ },
+ underlayBackgroundColor: bgColor,
+ }
+ return option as TYPES.GanttConstructorOptions
+ }
+ function renderColumn() {
+ const columns = [
+ {
+ field: 'name',
+ title: '类型',
+ width: '120',
+ mergeCell: true,
+ },
+ ]
+ if (subId) {
+ columns.unshift({
+ field: 'isCheck',
+ title: '',
+ width: '60',
+ headerType: 'checkbox',
+ cellType: 'checkbox',
+ })
+ }
+ return columns
+ }
+
+ function renderTaskListTable() {
+ const taskListTable = {
+ columns: renderColumn(),
+ // tableWidth: 'auto',
+ theme: {
+ underlayBackgroundColor: bgColor,
+ headerStyle: {
+ borderColor: textColorWithOp,
+ borderLineWidth: 1,
+ fontWeight: 'bold',
+ color: textColor,
+ bgColor: headerBgColor,
+ textAlign: 'center',
+ fontSize: 20,
+ hover: {
+ cellBgColor: 'transparent',
+ },
+ },
+
+ bodyStyle: {
+ borderColor: textColorWithOp,
+ textAlign: 'center',
+ borderLineWidth: 1,
+ autoWrapText: true,
+ fontSize: 16,
+ color: textColor,
+ bgColor: bgColor,
+ hover: {
+ cellBgColor: textColorWithOp,
+ },
+ },
+ },
+ }
+ return taskListTable
+ }
+
+ function renderTaskBar(subId: string) {
+ const taskBar = {
+ resizable: false,
+ moveable: false,
+ startDateField: 'start',
+ endDateField: 'end',
+ // progressField: 'progress',
+ barStyle: { width: subId ? 180 : 60 },
+ customLayout: args => {
+ const { width, height, startDate, endDate, taskRecord } = args
+ const container = new Group({
+ width,
+ height,
+ fill: 'transparent',
+ // stroke:true,
+ // stroke: textColor,
+ display: 'flex',
+ flexDirection: 'column',
+ justifyContent: 'center',
+ })
+ if (!subId) {
+ container.addEventListener('click', event => {
+ router.push({
+ path: `/gantt/sub/${taskRecord.id}`,
+ })
+ })
+ }
+
+ if (subId) {
+ const image = new Image({
+ image: taskRecord.avatar,
+ width: 100,
+ height: 100,
+ x: 10,
+ y: 10,
+ boundsPadding: [0, 0, 10, 0],
+ })
+ container.add(image)
+ }
+ // const checkbox = new CheckBox({
+ // width: 20,
+ // height: 20,
+ // checked: false,
+ // })
+ // container.add(checkbox)
+
+ // checkbox.addEventListener('click', event => {
+ // console.log(event, 'event')
+ // })
+ const name = new Text({
+ text: taskRecord.name,
+ fontSize: 16,
+ fontFamily: 'sans-serif',
+ fill: textColor,
+ fontWeight: 'bold',
+ maxLineWidth: width,
+ textAlign: 'center',
+ // boundsPadding: [10, 0, 0, 0],
+ })
+ container.add(name)
+
+ const days = new Text({
+ text: `${startDate.toLocaleDateString()} ~ ${endDate.toLocaleDateString()}`,
+ fontSize: 13,
+ fontFamily: 'sans-serif',
+ fill: textColor,
+ boundsPadding: [10, 0, 0, 0],
+ })
+ container.add(days)
+ const rect = new Rect({
+ width: width,
+ height: 7,
+ fill: {
+ gradient: 'linear',
+ x0: 0,
+ y0: 0,
+ x1: 1,
+ y1: 0,
+ stops: [
+ {
+ offset: 0,
+ color: textColor,
+ },
+ {
+ offset: 1,
+ color: textColorWithOp,
+ },
+ ],
+ },
+ boundsPadding: [10, 0, 0, 0],
+ })
+ container.add(rect)
+ return {
+ rootContainer: container,
+ }
+ },
+ hoverBarStyle: {
+ cornerRadius: 2,
+ barOverlayColor: textColorWithOp,
+ },
+ selectedBarStyle: {
+ // cornerRadius: 2,
+ borderColor: textColorWithOp,
+ borderLineWidth: 2,
+ },
+ }
+ return taskBar
+ }
+ function renderGroup(opt: IGroupGraphicAttribute) {
+ return new Group(opt)
+ }
+
+ function renderText(opt: ITextGraphicAttribute) {
+ return new Text(opt)
+ }
+
+ function renderImage(opt: IImageGraphicAttribute) {
+ return new Image(opt)
+ }
+
+ function changeTimeScales(scale: TYPES.ITimelineScale['unit']) {
+ const scales = getTimeScales(scale)
+ ganttInstance && ganttInstance.updateScales(scales)
+ }
+
+ function getTimeScales(
+ scale: TYPES.ITimelineScale['unit']
+ ): TYPES.ITimelineScale[] {
+ return [
+ {
+ unit: scale,
+ step: 1,
+ customLayout: args => {
+ const { width, height, startDate } = args
+ const container = new Group({
+ width,
+ height,
+ display: 'flex',
+ flexDirection: 'row',
+ flexWrap: 'nowrap',
+ })
+
+ const day = new Text({
+ text:
+ scale === 'day'
+ ? startDate.toLocaleDateString()
+ : startDate.toLocaleTimeString(),
+ fontSize: 14,
+ fontWeight: 'bold',
+ fontFamily: 'sans-serif',
+ fill: textColor,
+ textAlign: 'right',
+ maxLineWidth: width,
+ boundsPadding: [25, 12, 10, 12],
+ })
+ container.add(day)
+ return {
+ rootContainer: container,
+ }
+ },
+ },
+ ]
+ }
+ return { renderMainTask, changeTimeScales }
+}
+
+export default useGantt
diff --git a/src/views/Gantt/components/Gantt/index.jsx b/src/views/Gantt/components/Gantt/index.jsx
new file mode 100644
index 000000000..6331deb18
--- /dev/null
+++ b/src/views/Gantt/components/Gantt/index.jsx
@@ -0,0 +1,29 @@
+import useGantt from './hooks/gantt'
+import { useRouter, useRoute } from 'vue-router'
+
+export default defineComponent({
+ props: {
+ scale: {
+ type: String,
+ default: 'day',
+ },
+ },
+ setup(props) {
+ const router = useRouter()
+ const route = useRoute()
+ const { renderMainTask, changeTimeScales } = useGantt({ route, router })
+
+ onMounted(() => {
+ nextTick(() => {
+ renderMainTask(document.querySelector('#tableContainer'))
+ })
+ })
+ watch(
+ () => props.scale,
+ val => {
+ changeTimeScales(val)
+ }
+ )
+ return () =>
+ },
+})
diff --git a/src/views/Gantt/components/MainGantt/index.jsx b/src/views/Gantt/components/MainGantt/index.jsx
new file mode 100644
index 000000000..da637e79c
--- /dev/null
+++ b/src/views/Gantt/components/MainGantt/index.jsx
@@ -0,0 +1,21 @@
+import { NDatePicker, NRadioButton, NRadioGroup } from 'naive-ui'
+import GanttCom from '../Gantt'
+
+export default defineComponent({
+ setup() {
+ const range = ref()
+ const value = ref('day')
+ return () => (
+ <>
+
+
+
+
+
+
+
+
+ >
+ )
+ },
+})
diff --git a/src/views/Gantt/components/SubGantt/index.jsx b/src/views/Gantt/components/SubGantt/index.jsx
new file mode 100644
index 000000000..6ed3a1a06
--- /dev/null
+++ b/src/views/Gantt/components/SubGantt/index.jsx
@@ -0,0 +1,17 @@
+import { NButton } from 'naive-ui'
+import GanttCom from '../Gantt'
+
+export default defineComponent({
+ setup() {
+ const value = ref('day')
+ return () => (
+ <>
+
+ 态势展示
+ 返回
+
+
+ >
+ )
+ },
+})
diff --git a/src/views/Gantt/index copy.vue b/src/views/Gantt/index copy.vue
new file mode 100644
index 000000000..6574e9297
--- /dev/null
+++ b/src/views/Gantt/index copy.vue
@@ -0,0 +1,531 @@
+
+
+
+
+
diff --git a/src/views/Gantt/index.jsx b/src/views/Gantt/index.jsx
new file mode 100644
index 000000000..56a354280
--- /dev/null
+++ b/src/views/Gantt/index.jsx
@@ -0,0 +1,17 @@
+import { RouterView } from 'vue-router'
+import HeaderCom from '../Content/components/Header/index.vue'
+
+export default defineComponent({
+ setup() {
+ return () => (
+
+ )
+ },
+})
diff --git a/src/views/Gantt/index.vue b/src/views/Gantt/index.vue
new file mode 100644
index 000000000..bc0b7565a
--- /dev/null
+++ b/src/views/Gantt/index.vue
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/src/views/Satellite/hooks/satellite.ts b/src/views/Satellite/hooks/satellite.ts
index e354ef4a3..4167c68ca 100644
--- a/src/views/Satellite/hooks/satellite.ts
+++ b/src/views/Satellite/hooks/satellite.ts
@@ -47,7 +47,7 @@ export function useSatellite() {
// setTimeout(() => {
// satellite.sensor = true
- // }, 10000)
+ // }, 2000)
// viewer.clock.multiplier = 100
return cesiumSateEntity
diff --git a/src/views/Weather/hooks/weather.ts b/src/views/Weather/hooks/weather.ts
new file mode 100644
index 000000000..aceb6f2c4
--- /dev/null
+++ b/src/views/Weather/hooks/weather.ts
@@ -0,0 +1,98 @@
+import { ref, nextTick } from 'vue'
+import { parseWKT } from '@/utils/parseWKT'
+import Subscriber from '@cesium-extends/subscriber'
+import { useWeatherPopup } from './weatherPopup'
+const { popupMap, createPopup } = useWeatherPopup()
+
+let subscriber: Subscriber | null = null
+const weatherMap = new Map()
+const weatherList = [
+ {
+ id: '10',
+ createTime: null,
+ updateTime: null,
+ geom: 'POINT (121.9 29.02)',
+ type: 'weather',
+ name: '晴天',
+ description: null,
+ },
+]
+const useWeather = () => {
+ const showWeather = ref(true)
+
+ nextTick(() => {
+ watch(
+ showWeather,
+ newVal => {
+ newVal ? showWeatherPoints() : hideWeatherPoints()
+ },
+ {
+ immediate: true,
+ }
+ )
+ })
+
+ return {
+ showWeather,
+ }
+}
+
+function showWeatherPoints() {
+ subscriber = new Subscriber(viewer, {
+ pickResult: {
+ enable: true,
+ },
+ })
+ weatherList.forEach(data => {
+ const entity = createWeatherPoint(data)
+ addEventSub(data.id, entity, data)
+ weatherMap.set(data.id, entity)
+ })
+}
+
+function hideWeatherPoints() {
+ subscriber && subscriber.destroy()
+ weatherMap.keys().forEach(key => {
+ viewer.entities.remove(weatherMap.get(key))
+ weatherMap.delete(key)
+ if (popupMap.has(key)) {
+ popupMap.get(key).windowClose()
+ popupMap.delete(key)
+ }
+ })
+}
+
+function createWeatherPoint(data) {
+ const { name, geom } = data
+ const pos = parseWKT(geom).coordinates
+ const entity = viewer.entities.add({
+ name,
+ position: Cesium.Cartesian3.fromDegrees(...pos),
+ billboard: {
+ image: '/images/icons/base/weather.png',
+ width: 30,
+ height: 30,
+ verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
+ },
+ })
+ return entity
+}
+
+function addEventSub(
+ id: string | number,
+ entity: Cesium.Entity,
+ data: Record
+) {
+ subscriber &&
+ subscriber.add(
+ entity,
+ (movement, entity) => {
+ console.log(movement, entity, 'move')
+ createPopup(id, entity.position, data)
+ },
+ 'LEFT_CLICK'
+ )
+ // console.log(subscriber, '-------')
+}
+
+export { useWeather }
diff --git a/src/views/Weather/hooks/weatherPopup.ts b/src/views/Weather/hooks/weatherPopup.ts
new file mode 100644
index 000000000..23a4c74c8
--- /dev/null
+++ b/src/views/Weather/hooks/weatherPopup.ts
@@ -0,0 +1,39 @@
+import Popup from '@/views/Earth/components/Popup'
+
+const popupMap: Map = new Map()
+
+export const useWeatherPopup = () => {
+ return {
+ popupMap,
+ createPopup,
+ }
+}
+
+function createPopup(id: string | number, position: Cesium.Cartesian3, data) {
+ if (popupMap.has(id)) {
+ return
+ }
+ const opts = {
+ viewer,
+ position,
+ title: '天气信息',
+ slotContent: generateContent(data),
+ // slotFooter: generateFooter(data),
+ closeEvent: function () {
+ if (popupMap.has(id)) {
+ popupMap.get(id).windowClose()
+ popupMap.delete(id)
+ }
+ },
+ }
+ const popup = new Popup(opts)
+ popupMap.set(id, popup)
+}
+
+function generateContent(data: TBaseNode) {
+ return h(
+ 'div',
+ {},
+ Object.keys(data).map(key => h('div', {}, `${key}:${data[key]}`))
+ )
+}
diff --git a/vite.config.ts b/vite.config.ts
index c2cee9d43..8b1ca24bf 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -4,6 +4,7 @@ import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import WindiCSS from 'vite-plugin-windicss'
+import vueJsx from '@vitejs/plugin-vue-jsx'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
@@ -11,17 +12,18 @@ import { NaiveUiResolver } from 'unplugin-vue-components/resolvers'
// https://vitejs.dev/config/
export default defineConfig({
- define: {
- // enable hydration mismatch details in production build
- __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: 'true',
- },
-
+ // define: {
+ // // enable hydration mismatch details in production build
+ // __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: 'true',
+ // },
+ base: '/',
plugins: [
vue({
script: {
defineModel: true,
},
}),
+ vueJsx(),
WindiCSS(),
AutoImport({
imports: [