init commit

master
叶志超 2023-10-13 16:43:53 +08:00
parent c1fc36b44c
commit d184776cb3
275 changed files with 8305 additions and 0 deletions

View File

@ -0,0 +1,5 @@
import { bootstrap } from './base'
import { App } from '@/app/BD&time'
import { setupStore } from '@/stores'
bootstrap(App, [ setupStore ])

View File

@ -0,0 +1,5 @@
import { bootstrap } from './base'
import { App } from '@/app/BDCommunicationAssistant'
import { setupStore } from '@/stores'
bootstrap(App, [ setupStore ])

View File

@ -0,0 +1,6 @@
import { bootstrap } from './base'
import { App } from '@/app/BDComprehensiveExperimentalPlatform'
import { setupMap } from '@/components/Map'
import { setupStore } from '@/stores'
bootstrap(App, [ setupMap, setupStore ])

View File

@ -0,0 +1,6 @@
import { bootstrap } from './base'
import { App } from '@/app/BDDataAnalysisPlatform'
import { setupMap } from '@/components/Map'
import { setupStore } from '@/stores'
bootstrap(App, [ setupMap, setupStore ])

View File

@ -0,0 +1,6 @@
import { bootstrap } from './base'
import { App } from '@/app/BDMeteorologicalDataDisplayPlatform'
import { setupMap } from '@/components/Map'
import { setupStore } from '@/stores'
bootstrap(App, [ setupMap, setupStore ])

View File

@ -0,0 +1,4 @@
import { bootstrap } from './base'
import { App } from '@/app/BDMeteorologicalDataProtocol'
bootstrap(App)

View File

@ -0,0 +1,6 @@
import { bootstrap } from './base'
import { App } from '@/app/BDPositionTrackRetracing'
import { setupMap } from '@/components/Map'
import { setupStore } from '@/stores'
bootstrap(App, [ setupMap, setupStore ])

View File

@ -0,0 +1,5 @@
import { bootstrap } from './base'
import { App } from '@/app/BDSatellite3DPostureControl'
import { setupStore } from '@/stores'
bootstrap(App, [ setupStore ])

View File

@ -0,0 +1,5 @@
import { bootstrap } from './base'
import { App } from '@/app/BDSatelliteAttitudeControl'
import { setupStore } from '@/stores'
bootstrap(App, [ setupStore ])

View File

@ -0,0 +1,5 @@
import { bootstrap } from './base'
import { App } from '@/app/BDSatelliteParameterMonitoringPlatform'
import { setupStore } from '@/stores'
bootstrap(App, [ setupStore ])

View File

@ -0,0 +1,5 @@
import { bootstrap } from './base'
import { App } from '@/app/BDSatelliteTimeConfiguration'
import { setupStore } from '@/stores'
bootstrap(App, [ setupStore ])

View File

@ -0,0 +1,5 @@
import { bootstrap } from './base'
import { App } from '@/app/ClockConfig'
import { setupStore } from '@/stores'
bootstrap(App, [ setupStore ])

View File

@ -0,0 +1,5 @@
import { bootstrap } from './base'
import { App } from '@/app/ElectronicScreenDesign'
import { setupStore } from '@/stores'
bootstrap(App, [ setupStore ])

View File

@ -0,0 +1,5 @@
import { bootstrap } from './base'
import { App } from '@/app/FontDesign'
import { setupStore } from '@/stores'
bootstrap(App, [ setupStore ])

View File

@ -0,0 +1,5 @@
import { bootstrap } from './base'
import { App } from '@/app/GeneratingConstellationChart'
import { setupStore } from '@/stores'
bootstrap(App, [ setupStore ])

View File

@ -0,0 +1,5 @@
import { bootstrap } from './base'
import { App } from '@/app/GestureRecognition'
import { setupStore } from '@/stores'
bootstrap(App, [ setupStore ])

View File

@ -0,0 +1,5 @@
import { bootstrap } from './base'
import { App } from '@/app/NixieTubeConfiguration'
import { setupStore } from '@/stores'
bootstrap(App, [ setupStore ])

View File

@ -0,0 +1,5 @@
import { bootstrap } from './base'
import { App } from '@/app/VoltageMonitoring'
import { setupStore } from '@/stores'
bootstrap(App, [ setupStore ])

View File

@ -0,0 +1,5 @@
import { bootstrap } from './base'
import { App } from '@/app/WirelessCommunicationModuleConfiguration'
import { setupStore } from '@/stores'
bootstrap(App, [ setupStore ])

View File

@ -0,0 +1,10 @@
import { createApp } from 'vue'
import '@/common.less'
export const bootstrap = (App, setupFuncs: Function[] = []) => {
const app = createApp(App)
setupFuncs.forEach((setupFunc) => setupFunc.call(this, app))
app.mount('#app')
}

View File

@ -0,0 +1,6 @@
import { bootstrap } from './base'
import { App } from '@/app/distanceCalculationTool'
import { setupMap } from '@/components/Map'
import { setupStore } from '@/stores'
bootstrap(App, [ setupMap, setupStore ])

View File

@ -0,0 +1,6 @@
import { bootstrap } from './base'
import { App } from '@/app/index'
import { setupRouter } from '@/router/index'
import { setupStore } from '@/stores'
bootstrap(App, [ setupRouter, setupStore ])

58
src/render/common.less Normal file
View File

@ -0,0 +1,58 @@
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
a {
text-decoration: none;
}
li {
list-style: none;
}
div::-webkit-scrollbar {
width: 0;
}
.w-full {
width: 100%;
}
.h-full {
height: 100%;
}
.w-h-full {
width: 100%;
height: 100%;
}
.text-center {
text-align: center;
}
.flex {
display: flex;
}
.flex-col {
flex-direction: column;
}
.flex-1 {
flex: 1 1 0%;
}
.mx-auto {
margin-left: auto;
margin-right: auto;
}
.text-right {
text-align: right;
}

View File

@ -0,0 +1 @@
export { default as Application } from './index.vue'

View File

@ -0,0 +1,39 @@
<template>
<n-config-provider :locale="zhCN" :date-locale="dateZhCN" :theme-overrides="themeOverrides">
<n-loading-bar-provider>
<n-message-provider>
<n-notification-provider>
<n-dialog-provider>
<slot name="default"></slot>
</n-dialog-provider>
</n-notification-provider>
</n-message-provider>
</n-loading-bar-provider>
</n-config-provider>
</template>
<script setup lang="ts">
import {
zhCN,
dateZhCN,
NConfigProvider,
GlobalThemeOverrides,
NDialogProvider,
NMessageProvider,
NLoadingBarProvider,
NNotificationProvider,
} from 'naive-ui'
const themeOverrides: GlobalThemeOverrides = {
// common: {
// // fontSize: '24px',
// // fontWeight: 'bold',
// fontWeightStrong: 'bold'
// },
// Button: {
// fontSizeLarge: '18px',
// iconSizeLarge: '28px',
// heightLarge: '44px',
// }
}
</script>

View File

@ -0,0 +1,47 @@
import { reactive } from 'vue'
import { graphic } from 'echarts/core'
const active_color = new graphic.LinearGradient(
0, 1, 0, 0,
[
{offset: 0.3, color: '#83bff6'},
{offset: 1, color: '#188df0'}
]
)
const unactive_color = '#9ca3af'
export const option = reactive({
grid: {
containLabel: true
},
xAxis: {
type: 'category',
axisTick: { show: false },
axisLine: { show: false },
axisLabel: { color: 'black' }
},
yAxis: {
max: 60,
splitNumber: 3,
axisLabel: {
fontSize: 24
}
},
series: [{
type: 'bar',
barMaxWidth: '50%',
label: {
show: true,
position: 'top',
// formatter: function ({ value }) {
// return !value || value[1] === 0 ? '' : value[1]
// }
// formatter: '{a}-{b}-{c}'
},
itemStyle: {
// color: ({ value }) => {
// return value[1] ? active_color : unactive_color
// }
}
}]
})

View File

@ -0,0 +1 @@
export { default as CNR } from './index.vue';

View File

@ -0,0 +1,42 @@
<template>
<v-chart autoresize :option="option" />
</template>
<script lang="ts" setup>
import { use } from 'echarts/core'
import { BarChart } from 'echarts/charts'
import { GridComponent } from 'echarts/components'
import { CanvasRenderer } from 'echarts/renderers'
import VChart from 'vue-echarts'
import { option } from './data'
import { Satellite } from '@/api/satellite/type.d'
use([
CanvasRenderer,
BarChart,
GridComponent
])
const update = (satellites: Array<Satellite>) => {
const xAxisData = []
const seriesData = []
for (let i = 0; i < satellites.value.length; i++) {
const { svid, cn0, active } = satellites.value[i]
xAxisData.push(svid)
seriesData.push([i, cn0, active])
}
option.xAxis.data = xAxisData
option.series[0].data = seriesData
}
const clear = () => {
option.xAxis.data = null
option.series[0].data = null
}
defineExpose({ update, clear })
</script>

View File

@ -0,0 +1 @@
export { default as Clock } from './index.vue'

View File

@ -0,0 +1,250 @@
<template>
<v-chart autoresize :option="option" />
</template>
<script lang="ts" setup>
import { reactive } from "vue"
import VChart from "vue-echarts"
import { use } from "echarts/core"
import { GaugeChart } from "echarts/charts"
import { CanvasRenderer } from "echarts/renderers"
import { TitleComponent } from "echarts/components"
use([
GaugeChart,
CanvasRenderer,
TitleComponent,
])
// TODO:
const props = defineProps({
title: String
})
const option = reactive({
title: {
text: props.title,
left: 'center',
textStyle: {
fontSize: 28,
}
},
series: [
{
name: 'hour',
type: 'gauge',
animation: false,
startAngle: 90,
endAngle: -270,
min: 0,
max: 12,
splitNumber: 12,
clockwise: true,
axisLine: {
lineStyle: {
// width: 15,
// color: ['#00ca95'],
color: [[1, '#00ca95']]
// shadowColor: 'rgba(0, 0, 0, 0.5)',
// shadowBlur: 15
}
},
axisTick:{
lineStyle: {
color: '#00ca95',
width: 2
}
},
splitLine: {
length: 15,
lineStyle: {
color: '#00ca95',
shadowColor: 'rgba(0, 0, 0, 0.3)',
shadowBlur: 3,
shadowOffsetX: 1,
shadowOffsetY: 2
}
},
axisLabel: {
color: '#fff',
fontSize: 12,
distance: 15,
formatter: function (value) {
if (value === 0) {
return '';
}
return value + '';
}
},
pointer: {
icon: 'path://M2.9,0.7L2.9,0.7c1.4,0,2.6,1.2,2.6,2.6v115c0,1.4-1.2,2.6-2.6,2.6l0,0c-1.4,0-2.6-1.2-2.6-2.6V3.3C0.3,1.9,1.4,0.7,2.9,0.7z',
width: 12,
length: '55%',
offsetCenter: [0, '8%'],
itemStyle: {
color: '#2AB8FF',
shadowColor: 'rgba(0, 0, 0, 0.3)',
shadowBlur: 8,
shadowOffsetX: 2,
shadowOffsetY: 4
}
},
detail: {
show: false
},
data: [
{
value: 0
}
]
},
{
name: 'minute',
type: 'gauge',
animation: false,
startAngle: 90,
endAngle: -270,
min: 0,
max: 60,
clockwise: true,
axisLine: {
show: false
},
splitLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
show: false
},
pointer: {
icon: 'path://M2.9,0.7L2.9,0.7c1.4,0,2.6,1.2,2.6,2.6v115c0,1.4-1.2,2.6-2.6,2.6l0,0c-1.4,0-2.6-1.2-2.6-2.6V3.3C0.3,1.9,1.4,0.7,2.9,0.7z',
width: 8,
length: '70%',
offsetCenter: [0, '8%'],
itemStyle: {
color: '#2AB8FF',
shadowColor: 'rgba(0, 0, 0, 0.3)',
shadowBlur: 8,
shadowOffsetX: 2,
shadowOffsetY: 4
}
},
anchor: {
show: true,
size: 20,
showAbove: false,
itemStyle: {
borderWidth: 15,
borderColor: '#2AB8FF',
shadowColor: 'rgba(0, 0, 0, 0.3)',
shadowBlur: 8,
shadowOffsetX: 2,
shadowOffsetY: 4
}
},
detail: {
show: false
},
title: {
offsetCenter: ['0%', '-40%']
},
data: [
{
value: 0
}
]
},
{
name: 'second',
type: 'gauge',
startAngle: 90,
endAngle: -270,
min: 0,
max: 60,
animationEasingUpdate: 'bounceOut',
clockwise: true,
axisLine: {
show: false
},
splitLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
show: false
},
pointer: {
icon: 'path://M2.9,0.7L2.9,0.7c1.4,0,2.6,1.2,2.6,2.6v115c0,1.4-1.2,2.6-2.6,2.6l0,0c-1.4,0-2.6-1.2-2.6-2.6V3.3C0.3,1.9,1.4,0.7,2.9,0.7z',
width: 4,
length: '85%',
offsetCenter: [0, '8%'],
itemStyle: {
color: '#2AB8FF',
shadowColor: 'rgba(0, 0, 0, 0.3)',
shadowBlur: 8,
shadowOffsetX: 2,
shadowOffsetY: 4
}
},
anchor: {
show: true,
size: 15,
showAbove: true,
itemStyle: {
color: '#2AB8FF',
shadowColor: 'rgba(0, 0, 0, 0.3)',
shadowBlur: 8,
shadowOffsetX: 2,
shadowOffsetY: 4
}
},
detail: {
show: false
},
title: {
offsetCenter: ['0%', '-40%']
},
data: [
{
value: 0
}
]
}
]
})
let date
const update = (dateTime: Date) => {
if (!dateTime) return
const seconds = dateTime.getSeconds()
const minutes = dateTime.getMinutes()
const hours = dateTime.getHours()
const second_data = seconds
const minute_data = second_data / 60 + minutes
const hour_data = (minute_data / 60 + hours) % 12
const value = {
series: [
{ data: [{ value: hour_data }] },
{ data: [{ value: minute_data }] },
{
animation: second_data !== 0,
data: [{ value: second_data }]
}
]
}
Object.assign(option, value)
date = dateTime
}
const getDate = () => date
defineExpose({ update, getDate })
</script>

View File

@ -0,0 +1,65 @@
import { reactive } from "vue"
export const active_color = '#e5323e'
export const unactive_color = '#9ca3af'
export const option = reactive({
polar: {
radius: '85%'
},
angleAxis: {
min: 0,
max: 360,
interval: 45,
axisTick: {
show: false
},
axisLabel: {
fontSize: 24,
formatter: function (value: number) {
switch (value)
{
case 0 : return '北'
case 90 : return '东'
case 180 : return '南'
case 270 : return '西'
}
},
}
},
radiusAxis: {
min: -90,
max: 0,
interval: 30,
axisLabel: {
rotate: -25,
showMinLabel: false,
showMaxLabel: false,
verticalAlign: 'bottom',
// formatter: function(value: number){
// return Math.abs(value)
// },
formatter: function(value, index){
if(value === 0){
return '';
}
return -value;
},
}
},
series: [{
coordinateSystem: 'polar',
type: 'scatter',
symbolSize: 32,
label: {
show: true,
formatter: '{@[2]}'
},
itemStyle: {
color: ({ value }) => {
return value[3] ? active_color : unactive_color
}
},
}]
})

View File

@ -0,0 +1 @@
export { default as Planisphere } from './index.vue';

View File

@ -0,0 +1,34 @@
<template>
<VChart autoresize :option="option" />
</template>
<script lang="ts" setup>
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import { ScatterChart } from 'echarts/charts'
import { PolarComponent } from 'echarts/components'
import VChart from 'vue-echarts'
import { option } from './data'
import { Satellite } from '@/api/satellite/type.d'
// TODO: echart
use([
CanvasRenderer,
ScatterChart,
PolarComponent
])
const update = (satellites: Array<Satellite>) => {
const data = satellites.value.map(({ svid, ele, az, active }) => {
return [parseInt(ele) * -1, az, svid, active]
})
option.series[0].data = data
}
const clear = () => {
option.series[0].data = null
}
defineExpose({ update, clear })
</script>

View File

@ -0,0 +1,3 @@
import { Clock } from './Clock'
export { Clock }

View File

@ -0,0 +1 @@
export const zooms = [4, 20]

View File

@ -0,0 +1 @@
export { default as Map } from './index.vue'

View File

@ -0,0 +1,61 @@
<template>
<el-amap
ref="mapRef"
viewMode="3D"
:zooms="zooms"
:zoom="zoom"
:center="center"
v-bind="$attrs"
>
<el-amap-control-map-type :defaultType="1" />
<slot></slot>
</el-amap>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { zooms } from './data'
defineProps({
zoom: {
type: Number,
default: 4.5,
},
center: {
type: Array,
default: [105, 31],
},
})
// TODO:
// const mapStyle = ref('amap://styles/grey')
// TODO:
const mapRef = ref()
const setZoomAndCenter = (zoom, center) => mapRef.value.$$getInstance()?.setZoomAndCenter(zoom, center, true)
defineExpose({ setZoomAndCenter })
</script>
<style scoped lang="less">
.el-vue-amap-container {
width: 100%;
height: 100%;
:deep(.amap-container) {
.amap-ctrl-overlay-layer {
display: none!important;
}
.amap-logo {
display: none!important;
}
.amap-copyright {
display: none!important;
}
}
}
</style>

View File

@ -0,0 +1,18 @@
<template>
<el-amap-info-window
v-model:visible="visible"
:position="position"
>
<slot></slot>
</el-amap-info-window>
</template>
<script lang="ts" setup>
import { computed } from "vue"
const props = defineProps({
position: Array
})
const visible = computed(() => props.position.value !== null)
</script>

View File

@ -0,0 +1,11 @@
<template>
<el-amap-marker :icon="markIcon" anchor="bottom-center" v-if="!!position && position.length >= 2 && !isNaN(position[0]) && !isNaN(position[1]) " :position="position" />
</template>
<script lang="ts" setup>
import markIcon from '@/assets/mark.png'
defineProps({
position: Array<Number>
})
</script>

View File

@ -0,0 +1,13 @@
<template>
<el-amap-polyline v-if="!!path && path.length >= 2" :path="path" :strokeColor="strokeColor" :strokeOpacity="strokeOpacity" :strokeWeight="strokeWeight" />
</template>
<script lang="ts" setup>
defineProps({
path: Array<Array<Number>>
})
const strokeColor = '#fef301'
const strokeOpacity = 1
const strokeWeight = 6
</script>

View File

@ -0,0 +1,10 @@
<template>
<el-amap-text v-if="!!position && position.length >= 2 && !isNaN(position[0]) && !isNaN(position[1]) " :position="position" />
</template>
<script lang="ts" setup>
defineProps({
position: Array<Number>
})
</script>

View File

@ -0,0 +1,9 @@
<template>
<el-amap-marker v-for="(position, index) in positions" :key="index" :position="position" />
</template>
<script lang="ts" setup>
defineProps({
positions: Array
})
</script>

View File

@ -0,0 +1,12 @@
<template>
<el-amap-mouse-tool
type="rule"
:auto-clear="false"
/>
</template>
<script lang="ts" setup>
</script>
<style scoped lang="less">
</style>

View File

@ -0,0 +1 @@
export { default as PolylineView } from './index.vue';

View File

@ -0,0 +1,9 @@
<template>
<el-amap-polyline v-for="(path, index) in paths" :key="index" :path="path" />
</template>
<script lang="ts" setup>
defineProps({
paths: Array
})
</script>

View File

@ -0,0 +1,2 @@
export const timing = [[0, 0.3], [1, 0.7]]
export const rotationSpeed = 10

View File

@ -0,0 +1,2 @@
export { default as TrackLineView } from './index.vue';
export { Journey } from './type';

View File

@ -0,0 +1,66 @@
<template>
<PolylineView :paths="journey.paths" />
<Marker :positions="positions" />
<el-amap-loca @init="initLoca" />
</template>
<script lang="ts" setup>
import { reactive, watch } from 'vue'
import Marker from '../Marker.vue'
import { PolylineView } from '../PolylineView'
import { Journey } from './type'
import { timing, rotationSpeed } from './data'
const props = defineProps({
journey: Journey
})
const positions = reactive([])
let mapInstance = null
let locaInstance = null
let finished = true
const initLoca = loca => {
locaInstance = loca
mapInstance = loca.map
loca.animate.start();
}
watch(
() => props.journey,
(value) => {
const { paths } = value
clear()
if (paths.length > 0) load()
},
{ deep: true },
)
const load = () => {
finished = false
locaInstance?.viewControl.addTrackAnimate({
path : props.journey.paths[0], //
duration: props.journey.duration, //
timing, //
rotationSpeed, //
}, () => finished = true)
}
const clear = () => {
finished = true
positions.length = 0
locaInstance?.viewControl.clearAnimates()
}
const run = () => {
if (!finished) positions[0] = mapInstance?.getCenter().toArray()
requestAnimationFrame(run)
}
run()
</script>

View File

@ -0,0 +1,6 @@
export class Journey {
constructor(paths, durationData) {
this.paths = paths
this.durationData = durationData
}
}

View File

@ -0,0 +1,28 @@
import type { App } from 'vue'
import VueAMap, { initAMapApiLoader, lazyAMapApiLoaderInstance } from '@vuemap/vue-amap'
import '@vuemap/vue-amap/dist/style.css'
import { wgs84togcj02 } from 'coordtransform'
initAMapApiLoader({
key: '763566888253f0a902f73609cf45a021',
})
export const setupMap = (app: App) => {
app.use(VueAMap)
// 引入高德原生 SDK
lazyAMapApiLoaderInstance.then()
}
export const lonlat2Position = (longitude, latitude) => {
return wgs84togcj02(longitude, latitude)
}
export * from './Map'
export * from './PolylineView'
export * from './TrackLineView'
export { default as Marker } from './Marker.vue'
export { default as MapText } from './MapText.vue'
export { default as MapMarker } from './MapMarker.vue'
export { default as MapPolyline } from './MapPolyline.vue'
export { default as MapInfoWindow } from './MapInfoWindow.vue'
export { default as MouseTool } from './MouseTool.vue'

View File

@ -0,0 +1 @@
export * from './amap'

View File

@ -0,0 +1,26 @@
export const BAUDRATE_OPTIONS = [
{ label: 9600 , value: 9600 },
{ label: 38400 , value: 38400 },
{ label: 115200, value: 115200 },
]
export const DATA_BITS_OPTIONS = [
{ label: 8 , value: 8 },
{ label: 7 , value: 7 },
]
export const STOPBITS_OPTIONS = [
{ label: 1 , value: 1 },
{ label: 2 , value: 2 },
]
export const PARITY_OPTIONS = [
{ label: '无' , value: 'none' },
{ label: '奇' , value: 'odd' },
{ label: '偶' , value: 'even' },
]
export const FLOW_CONTROL_OPTIONS = [
{ label: '无' , value: 'none' },
{ label: '硬件', value: 'hardware' },
]

View File

@ -0,0 +1 @@
export { default as SerialPortManagementView } from './index.vue'

View File

@ -0,0 +1,74 @@
<template>
<!-- TODO: 使用form grid替换 -->
<n-descriptions :column="1">
<n-descriptions-item>
<n-button :disabled="serialPort.isOpen" type="primary" @click="onSelectBtnClick"></n-button>
</n-descriptions-item>
<n-descriptions-item label="波特率">
<n-select :disabled="serialPort.instance === null || serialPort.isOpen" v-model:value="serialPortOptions.baudRate" :options="BAUDRATE_OPTIONS" />
</n-descriptions-item>
<n-descriptions-item label="数据位">
<n-select :disabled="serialPort.instance === null || serialPort.isOpen" v-model:value="serialPortOptions.dataBits" :options="DATA_BITS_OPTIONS" />
</n-descriptions-item>
<n-descriptions-item label="停止位">
<n-select :disabled="serialPort.instance === null || serialPort.isOpen" v-model:value="serialPortOptions.stopBits" :options="STOPBITS_OPTIONS" />
</n-descriptions-item>
<n-descriptions-item label="奇偶校验">
<n-select :disabled="serialPort.instance === null || serialPort.isOpen" v-model:value="serialPortOptions.parity" :options="PARITY_OPTIONS" />
</n-descriptions-item>
<n-descriptions-item>
<n-button :disabled="serialPort.instance === null" type="primary" @click="onTriggerBtnClick">{{ serialPort.isOpen ? '' : '' }}</n-button>
</n-descriptions-item>
</n-descriptions>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { NDescriptions, NDescriptionsItem, NSelect, NButton, useMessage } from 'naive-ui'
import { BAUDRATE_OPTIONS, DATA_BITS_OPTIONS, STOPBITS_OPTIONS, PARITY_OPTIONS } from './data'
import { useSerialPortStore } from '@/stores/serialPort'
const message = useMessage()
const serialPort = useSerialPortStore()
const serialPortOptions = ref({
baudRate: BAUDRATE_OPTIONS[BAUDRATE_OPTIONS.length - 1].value,
dataBits: DATA_BITS_OPTIONS[0].value,
stopBits: STOPBITS_OPTIONS[0].value,
parity : PARITY_OPTIONS[0].value,
})
let closedPromise
const openSerialPort = () => {
closedPromise = serialPort.open(serialPortOptions.value).catch((error) => {
console.error(error)
message.error('打开串口失败,' + error.message)
})
}
const closeSerialPort = async () => {
try {
await serialPort.close()
await closedPromise
} catch (error) {
console.error(error)
message.error('关闭串口失败,' + error.message)
}
}
const onSelectBtnClick = serialPort.select
const onTriggerBtnClick = async () => {
if (serialPort.isOpen) {
closeSerialPort()
} else {
openSerialPort()
}
}
</script>
<style scoped lang="less">
.n-button {
width: 100%;
}
</style>

View File

@ -0,0 +1 @@
export { default as SerialPortReceivingMessageView } from './index.vue';

View File

@ -0,0 +1,64 @@
<template>
<n-card embedded title="数据接收" class="h-full">
<div
ref="terminalRef"
class="h-full">
</div>
<template #header-extra>
<n-space align="center" :wrap="false">
<n-button
type="primary"
size="large"
class="primary-button"
@click="clearBtnClick">
 
</n-button>
<n-switch size="large" v-model:value="appending">
<template #checked>
 
</template>
<template #unchecked>
 
</template>
</n-switch>
</n-space>
</template>
</n-card>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { Terminal } from 'xterm'
import { FitAddon } from 'xterm-addon-fit'
import 'xterm/css/xterm.css'
import { NCard, NSpace, NButton, NSwitch } from 'naive-ui'
import { useSerialPortStore, SerialPortEventType } from '@/stores/serialPort'
const terminalRef = ref()
let term: Terminal
const clearBtnClick = () => term?.clear()
onMounted(() => {
term = new Terminal({
rows: Math.floor(terminalRef.value.clientHeight / 17)
})
const fitAddon = new FitAddon();
term.loadAddon(fitAddon)
if (terminalRef.value) {
term.open(terminalRef.value)
fitAddon.fit()
}
})
const appending = ref(true)
const onSerialPortData = (data: Uint8Array) => {
if (!data) return
if (appending.value) term?.write(data)
}
const serialPort = useSerialPortStore()
serialPort.addEventListener(SerialPortEventType.data, onSerialPortData)
</script>

View File

@ -0,0 +1 @@
export { default as SerialPortSendingMessageView } from './index.vue'

View File

@ -0,0 +1,51 @@
<template>
<n-card embedded title="数据发送" class="h-full">
<n-input
v-model:value="message"
type="textarea"
size="large"
placeholder="输入要发送的信息"
class="h-full"
:autosize="{ maxRows: 8}"
:clearable="true"
/>
<template #header-extra>
<n-space align="center" :wrap="false">
<n-button type="primary"
size="large"
:disabled="!serialPort.isOpen || message.length === 0"
@click="sendBtnClick">
 
</n-button>
<slot name="extra"></slot>
</n-space>
</template>
</n-card>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { NCard, NInput, NSpace, NButton } from 'naive-ui'
import { useSerialPortStore } from '@/stores/serialPort'
const message = ref('')
const NEWLINE_REGEXP = /\n/g
const serialPort = useSerialPortStore()
const sendBtnClick = async () => {
if (!message.value) return
const text = message.value.replace(NEWLINE_REGEXP, '\r\n') + '\r\n'
await serialPort.write(text)
message.value = ''
}
const update = (text: string) => {
if ( text.length <= 0 ) return
message.value = text
}
defineExpose({ update })
</script>

View File

@ -0,0 +1,3 @@
export * from './ManagementView'
export * from './SendingMessageView'
export * from './ReceivingMessageView'

View File

@ -0,0 +1 @@
export { default as SerialPortManagementDrawer } from './index.vue'

View File

@ -0,0 +1,33 @@
<template>
<n-button circle type="primary" size="large" class="drawer-control-button" @click="show = true">
<template #icon>
<n-icon>
<Cable />
</n-icon>
</template>
</n-button>
<n-drawer v-model:show="show">
<n-drawer-content>
<SerialPortManagementView></SerialPortManagementView>
</n-drawer-content>
</n-drawer>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { NButton, NIcon, NDrawer, NDrawerContent } from 'naive-ui'
import { CableFilled as Cable } from '@vicons/material'
import { SerialPortManagementView } from '@/components/SerialPort'
const show = ref(false)
</script>
<style scoped lang="less">
.drawer-control-button {
position: fixed;
right: 60px;
top: 120px;
}
</style>

View File

@ -0,0 +1 @@
export { default as TabPane } from './index.vue'

View File

@ -0,0 +1,18 @@
<template>
<n-tab-pane :name="(name as string)" :tab="tab">
<slot></slot>
</n-tab-pane>
</template>
<script setup lang="ts">
import { NTabPane } from 'naive-ui'
defineProps({
name: String,
tab: String
})
</script>
<style scoped lang="less">
</style>

View File

@ -0,0 +1,3 @@
export { default as Tabs } from './index.vue'
// export * from './TabPane'
export { TabPane } from './TabPane'

View File

@ -0,0 +1,44 @@
<template>
<n-tabs type="segment" size="large" v-bind="$attrs">
<slot></slot>
</n-tabs>
</template>
<script setup lang="ts">
import { NTabs } from 'naive-ui'
</script>
<style scoped lang="less">
.n-tabs {
--n-tab-height: 50px;
--n-tab-text-color-active: #18a058 !important;
--n-tab-text-color-hover: #18a058 !important;
position: relative;
// height: 100%;
min-height: var(--n-tab-height);
:deep(.n-tabs-nav) {
position: absolute;
height: var(--n-tab-height);
left: 0;
right: 0;
bottom: 0;
.n-tabs-tab--active {
background-color: inherit !important;
box-shadow: inherit !important;
}
}
:deep(.n-tab-pane) {
position: absolute;
padding: 0;
top: 0;
bottom: var(--n-tab-height);
overflow: auto;
}
}
</style>

View File

@ -0,0 +1,12 @@
<template>
<RootLayout>
<n-layout-content position="absolute" v-bind="$attrs.contentAttrs">
<slot name="default"></slot>
</n-layout-content>
</RootLayout>
</template>
<script setup lang="ts">
import { NLayoutContent } from 'naive-ui'
import { default as RootLayout } from '@/layout/absolute/Root.vue'
</script>

View File

@ -0,0 +1,16 @@
<template>
<RootLayout>
<n-layout-header position="absolute" v-bind="$attrs.headerAttrs">
<slot name="header"></slot>
</n-layout-header>
<n-layout-content position="absolute" v-bind="$attrs.contentAttrs">
<slot name="default"></slot>
</n-layout-content>
</RootLayout>
</template>
<script setup lang="ts">
import { NLayoutHeader, NLayoutContent } from 'naive-ui'
import { default as RootLayout } from '@/layout/absolute/Root.vue'
</script>

View File

@ -0,0 +1,16 @@
<template>
<RootLayout has-sider>
<n-layout-sider v-bind="$attrs.siderAttrs">
<slot name="sider"></slot>
</n-layout-sider>
<n-layout-content v-bind="$attrs.contentAttrs">
<slot name="default"></slot>
</n-layout-content>
</RootLayout>
</template>
<script setup lang="ts">
import { NLayoutSider, NLayoutContent } from 'naive-ui'
import { default as RootLayout } from './Root.vue'
</script>

View File

@ -0,0 +1,25 @@
<template>
<RootLayout has-sider sider-placement="right" class="root-layout">
<n-layout-sider v-bind="$attrs.siderAttrs" position="absolute">
<slot name="sider"></slot>
</n-layout-sider>
<n-layout-content v-bind="$attrs.contentAttrs">
<slot name="default"></slot>
</n-layout-content>
</RootLayout>
</template>
<script setup lang="ts">
import { NLayoutSider, NLayoutContent } from 'naive-ui'
import { default as RootLayout } from './Root.vue'
</script>
<style scoped lang="less">
.root-layout {
.n-layout-sider {
left: auto;
right: 0;
}
}
</style>

View File

@ -0,0 +1,9 @@
<template>
<n-layout position="absolute">
<slot name="default"></slot>
</n-layout>
</template>
<script setup lang="ts">
import { NLayout } from 'naive-ui'
</script>

View File

@ -0,0 +1 @@
export { default as Layout } from './index.vue'

View File

@ -0,0 +1,12 @@
<template>
<!-- TODO: 重构所有的布局解决layout-sider和layout-content同时存在时可能存在的冲突 -->
<n-layout position="absolute" v-bind="$attrs">
<!-- <n-layout-content position="absolute"> -->
<slot name="default"></slot>
<!-- </n-layout-content> -->
</n-layout>
</template>
<script setup lang="ts">
import { NLayout } from 'naive-ui'
</script>

View File

@ -0,0 +1 @@
export { default as FixFooterLayout } from './index.vue'

View File

@ -0,0 +1,30 @@
<template>
<ParentLayout>
<n-layout-content position="absolute">
<slot name="default"></slot>
</n-layout-content>
<n-layout-footer position="absolute" bordered>
<slot name="footer"></slot>
</n-layout-footer>
</ParentLayout>
</template>
<script setup lang="ts">
import { NLayoutFooter, NLayoutContent } from 'naive-ui'
import { Layout as ParentLayout } from '@/layout/default'
</script>
<style lang="less" scoped>
.n-layout {
--footer-height: 100px;
.n-layout-footer {
height: var(--footer-height)
}
.n-layout-content {
bottom: var(--footer-height)
}
}
</style>

View File

@ -0,0 +1 @@
export { default as FixHeaderLayout } from './index.vue'

View File

@ -0,0 +1,30 @@
<template>
<ParentLayout>
<n-layout-header position="absolute" v-bind="$attrs.headerAttrs">
<slot name="header"></slot>
</n-layout-header>
<n-layout-content position="absolute" v-bind="$attrs.contentAttrs">
<slot name="default"></slot>
</n-layout-content>
</ParentLayout>
</template>
<script setup lang="ts">
import { NLayoutHeader, NLayoutContent } from 'naive-ui'
import { Layout as ParentLayout } from '@/layout/default'
</script>
<style lang="less" scoped>
.n-layout {
.n-layout-header {
height: var(--header-height);
box-shadow: 0px 5px 3px 0px rgb(0 0 0 / 12%);
z-index: 11;
}
.n-layout-content {
padding-top: var(--header-height);
}
}
</style>

View File

@ -0,0 +1 @@
export { default as LeftSiderLayout } from './index.vue'

View File

@ -0,0 +1,16 @@
<template>
<ParentLayout :has-sider="true" sider-placement="left">
<n-layout-sider v-bind="$attrs.siderAttrs">
<slot name="sider"></slot>
</n-layout-sider>
<n-layout-content v-bind="$attrs.contentAttrs">
<slot name="default"></slot>
</n-layout-content>
</ParentLayout>
</template>
<script setup lang="ts">
import { NLayoutSider, NLayoutContent } from 'naive-ui'
import { Layout as ParentLayout } from '@/layout/default'
</script>

View File

@ -0,0 +1 @@
export { default as RightSiderLayout } from './index.vue'

View File

@ -0,0 +1,23 @@
<template>
<ParentLayout :has-sider="true" sider-placement="right">
<n-layout-content>
<slot name="default"></slot>
</n-layout-content>
<n-layout-sider
bordered
:collapsed="collapsed"
:collapsed-width="0"
>
<slot name="sider"></slot>
</n-layout-sider>
</ParentLayout>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { NLayoutSider, NLayoutContent } from 'naive-ui'
import { Layout as ParentLayout } from '@/layout/default'
const collapsed = ref(true)
</script>

View File

@ -0,0 +1,16 @@
<template>
<RootLayout has-sider>
<n-layout-sider v-bind="$attrs.siderAttrs">
<slot name="sider"></slot>
</n-layout-sider>
<n-layout-content v-bind="$attrs.contentAttrs">
<slot name="default"></slot>
</n-layout-content>
</RootLayout>
</template>
<script setup lang="ts">
import { NLayoutSider, NLayoutContent } from 'naive-ui'
import { default as RootLayout } from '@/layout/static/Root.vue'
</script>

View File

@ -0,0 +1,9 @@
<template>
<n-layout v-bind="$attrs">
<slot name="default"></slot>
</n-layout>
</template>
<script setup lang="ts">
import { NLayout } from 'naive-ui'
</script>

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>北斗与时间的关系学习软件</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="../bootstrapScript/BD&time.ts"></script>
</body>
</html>

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>北斗通信助手教学软件</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="../bootstrapScript/BDCommunicationAssistant.ts"></script>
</body>
</html>

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>北斗综合实验平台</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="../bootstrapScript/BDComprehensiveExperimentalPlatform.ts"></script>
</body>
</html>

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>北斗数据分析平台</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="../bootstrapScript/BDDataAnalysisPlatform.ts"></script>
</body>
</html>

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>北斗气象数据展示平台</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="../bootstrapScript/BDMeteorologicalDataDisplayPlatform.ts"></script>
</body>
</html>

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>北斗气象数据协议</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="../bootstrapScript/BDMeteorologicalDataProtocol.ts"></script>
</body>
</html>

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>北斗位置轨迹回溯软件</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="../bootstrapScript/BDPositionTrackRetracing.ts"></script>
</body>
</html>

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>北斗卫星3D姿态展示软件</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="../bootstrapScript/BDSatellite3DPostureControl.ts"></script>
</body>
</html>

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>北斗卫星姿态控制软件</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="../bootstrapScript/BDSatelliteAttitudeControl.ts"></script>
</body>
</html>

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>北斗卫星参数监测平台</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="../bootstrapScript/BDSatelliteParameterMonitoringPlatform.ts"></script>
</body>
</html>

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>北斗卫星时间配置软件</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="../bootstrapScript/BDSatelliteTimeConfiguration.ts"></script>
</body>
</html>

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>时钟配置软件</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="../bootstrapScript/ClockConfig.ts"></script>
</body>
</html>

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>距离计算工具软件</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="../bootstrapScript/distanceCalculationTool.ts"></script>
</body>
</html>

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>电子屏幕设计软件</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="../bootstrapScript/ElectronicScreenDesign.ts"></script>
</body>
</html>

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>字体设计软件</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="../bootstrapScript/FontDesign.ts"></script>
</body>
</html>

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>生成星座图工具软件</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="../bootstrapScript/GeneratingConstellationChart.ts"></script>
</body>
</html>

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>手势识别软件</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="../bootstrapScript/GestureRecognition.ts"></script>
</body>
</html>

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>北斗启航实验平台软件</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="../bootstrapScript/index.ts"></script>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show More