|
|
<template>
|
|
|
<!-- <div class="app-container" :style="{ transform: `scale(${scaleRatio})`,transformOrigin: `left top` }">-->
|
|
|
<!-- <div :style="{ transform: `scale(${scaleRatio})`,transformOrigin: `left top` }">-->
|
|
|
<div class="app-container">
|
|
|
<TOP/>
|
|
|
<LEFT/>
|
|
|
<RIGHT/>
|
|
|
<el-button style="position: fixed;top: 10px;right: 10px" type="primary" @click="toAdmin">管理</el-button>
|
|
|
</div>
|
|
|
|
|
|
<!-- </div>-->
|
|
|
</template>
|
|
|
<script setup lang="jsx">
|
|
|
import Ruler from "@/components/ruler.vue";
|
|
|
import {defineComponent, nextTick, onMounted, ref} from "vue";
|
|
|
import {
|
|
|
getParasPos,
|
|
|
getParasSignalpro,
|
|
|
setParasPos,
|
|
|
setParasSignalpro,
|
|
|
getShildList,
|
|
|
addShildData,
|
|
|
delShildData,
|
|
|
StartWork,
|
|
|
StopWork,
|
|
|
RestartWork,
|
|
|
ShutDownWork,
|
|
|
getAllAirPort,
|
|
|
getArea,
|
|
|
GetAllCData,
|
|
|
InsertCListData,
|
|
|
UpdateCData
|
|
|
} from "@/api/api";
|
|
|
import {useRouter} from "vue-router";
|
|
|
import {ElMessage} from "element-plus";
|
|
|
|
|
|
const scaleRatio = ref(window.innerWidth / 1080)
|
|
|
const onSubmit = (e) => {
|
|
|
console.log(e)
|
|
|
}
|
|
|
const boxPos = ref({x: 100, y: 100, rotate: 0})
|
|
|
|
|
|
const TOP = defineComponent({
|
|
|
name: 'TOP',
|
|
|
setup() {
|
|
|
return () => (
|
|
|
<div class="top">
|
|
|
<div class="title">探测系统</div>
|
|
|
<div class="items">
|
|
|
<div
|
|
|
class={{item: true, click: itemsId.value === 1}}
|
|
|
onClick={() => setItemsId(1)}
|
|
|
>
|
|
|
<span>主界面</span>
|
|
|
</div>
|
|
|
|
|
|
<div
|
|
|
class={{item: true, click: itemsId.value === 2}}
|
|
|
onClick={() => setItemsId(2)}
|
|
|
>
|
|
|
<span>区域标定</span>
|
|
|
</div>
|
|
|
|
|
|
<div
|
|
|
class={{item: true, click: itemsId.value === 3}}
|
|
|
onClick={() => setItemsId(3)}
|
|
|
>
|
|
|
<span>软件设置</span>
|
|
|
</div>
|
|
|
|
|
|
<div
|
|
|
class={{item: true, click: itemsId.value === 4}}
|
|
|
onClick={() => setItemsId(4)}
|
|
|
>
|
|
|
<span>历史记录</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
)
|
|
|
}
|
|
|
})
|
|
|
const LEFT = defineComponent({
|
|
|
name: 'LEFT',
|
|
|
setup() {
|
|
|
return () => (
|
|
|
<div class="left">
|
|
|
<Ruler
|
|
|
ref={rulerRef}
|
|
|
index={dotIndex.value}
|
|
|
width={areaData.value.width}
|
|
|
height={areaData.value.height}
|
|
|
boxPos={boxPos.value}
|
|
|
dots={dots.value}
|
|
|
dotIndex={0}
|
|
|
/>
|
|
|
</div>
|
|
|
)
|
|
|
}
|
|
|
})
|
|
|
const RIGHT = defineComponent({
|
|
|
name: 'RIGHT',
|
|
|
setup() {
|
|
|
return () => (
|
|
|
<div class="right">
|
|
|
{itemsId.value === 1 && (
|
|
|
<div class="tabsItem">
|
|
|
<ElCard shadow="always">
|
|
|
<ElForm inline model={form1.value} class="demo-form-inline">
|
|
|
<ElFormItem>
|
|
|
<ElSelect
|
|
|
modelValue={form1.value.region}
|
|
|
placeholder="请选择机场名称"
|
|
|
style={{width: "200px"}}
|
|
|
clearable
|
|
|
onUpdate:modelValue={val => selectUpdate(val)}
|
|
|
>
|
|
|
{
|
|
|
options1.value.map(i => {
|
|
|
return <ElOption label={i.name} value={i.id}/>
|
|
|
})
|
|
|
}
|
|
|
|
|
|
|
|
|
</ElSelect>
|
|
|
</ElFormItem>
|
|
|
|
|
|
<ElFormItem>
|
|
|
<ElSelect
|
|
|
modelValue={form1.value.region1}
|
|
|
placeholder="请选择区域名称"
|
|
|
style={{width: "200px"}}
|
|
|
clearable
|
|
|
onUpdate:modelValue={val => (form1.value.region1 = val)}
|
|
|
>
|
|
|
|
|
|
{
|
|
|
options2.value.map(i => {
|
|
|
return <ElOption label={i.name} value={i.id}/>
|
|
|
})
|
|
|
}
|
|
|
</ElSelect>
|
|
|
</ElFormItem>
|
|
|
|
|
|
<ElFormItem>
|
|
|
<ElButton type="primary" onClick={onSubmit}>固定目标</ElButton>
|
|
|
</ElFormItem>
|
|
|
</ElForm>
|
|
|
</ElCard>
|
|
|
|
|
|
<ElCard shadow="always" style={{marginTop: "12px"}}>
|
|
|
<ElButton
|
|
|
type="primary"
|
|
|
disabled={radarWorkState.value === 1}
|
|
|
onClick={StartWorkBtn}
|
|
|
>
|
|
|
启动雷达
|
|
|
</ElButton>
|
|
|
<ElButton
|
|
|
type="danger"
|
|
|
disabled={radarWorkState.value === 0}
|
|
|
onClick={StopWorkBtn}
|
|
|
>
|
|
|
关闭雷达
|
|
|
</ElButton>
|
|
|
<ElButton type="warning" onClick={RestartWorkBtn}>重启雷达</ElButton>
|
|
|
<ElButton type="info" onClick={ShutDownWorkBtn}>急停雷达</ElButton>
|
|
|
</ElCard>
|
|
|
|
|
|
<ElCard shadow="always" style={{marginTop: "12px"}}>
|
|
|
{radarWorkState.value === 1 && (
|
|
|
<div style={{
|
|
|
width: 'calc(50% - 50px)',
|
|
|
position: 'relative',
|
|
|
borderRadius: '5px',
|
|
|
backgroundColor: '#01CE69',
|
|
|
height: '44px',
|
|
|
display: 'inline-block',
|
|
|
padding: '0 20px',
|
|
|
marginRight: '20px'
|
|
|
}}>
|
|
|
<span style={{
|
|
|
position: 'absolute',
|
|
|
top: '50%',
|
|
|
transform: 'translateY(-50%)',
|
|
|
left: '20%',
|
|
|
color: '#fff',
|
|
|
letterSpacing: '2px'
|
|
|
}}>雷达通讯状态</span>
|
|
|
<ElIcon size="20px" style={{
|
|
|
position: 'absolute',
|
|
|
top: '50%',
|
|
|
transform: 'translateY(-50%)',
|
|
|
right: '40px'
|
|
|
}}>
|
|
|
<SuccessFilled color="#fff"/>
|
|
|
</ElIcon>
|
|
|
</div>
|
|
|
)}
|
|
|
{radarWorkState.value === 0 && (
|
|
|
<div style={{
|
|
|
width: 'calc(50% - 50px)',
|
|
|
position: 'relative',
|
|
|
borderRadius: '5px',
|
|
|
backgroundColor: '#E8370D',
|
|
|
height: '44px',
|
|
|
display: 'inline-block',
|
|
|
padding: '0 20px'
|
|
|
}}>
|
|
|
<span style={{
|
|
|
position: 'absolute',
|
|
|
top: '50%',
|
|
|
transform: 'translateY(-50%)',
|
|
|
left: '20%',
|
|
|
color: '#fff',
|
|
|
letterSpacing: '2px'
|
|
|
}}>雷达通讯状态</span>
|
|
|
<ElIcon size="20px" style={{
|
|
|
position: 'absolute',
|
|
|
top: '50%',
|
|
|
transform: 'translateY(-50%)',
|
|
|
right: '40px'
|
|
|
}}>
|
|
|
<WarningFilled color="#fff"/>
|
|
|
</ElIcon>
|
|
|
</div>
|
|
|
)}
|
|
|
</ElCard>
|
|
|
|
|
|
<ElCard shadow="always" style={{marginTop: "12px"}}>
|
|
|
<ElForm inline model={form2.value} class="demo-form-inline">
|
|
|
<ElFormItem>
|
|
|
<ElDatePicker
|
|
|
modelValue={form2.value.date}
|
|
|
type="date"
|
|
|
placeholder="选择时间"
|
|
|
clearable
|
|
|
onUpdate:modelValue={val => (form2.value.date = val)}
|
|
|
/>
|
|
|
</ElFormItem>
|
|
|
|
|
|
<ElFormItem>
|
|
|
<ElButton onClick={onSubmit}>停止检测</ElButton>
|
|
|
<ElButton type="primary" onClick={onSubmit}>批量操作</ElButton>
|
|
|
</ElFormItem>
|
|
|
</ElForm>
|
|
|
|
|
|
<ElTable
|
|
|
highlightCurrentRow
|
|
|
onCurrentChange={table1Current}
|
|
|
data={tableData1.value}
|
|
|
style={{width: "100%"}}
|
|
|
>
|
|
|
<ElTableColumn type="selection" width={55}/>
|
|
|
<ElTableColumn label="序号" type="index" width={60}/>
|
|
|
<ElTableColumn prop="Lon" label="目标经度" width={120}/>
|
|
|
<ElTableColumn prop="Lat" label="目标纬度" width={120}/>
|
|
|
<ElTableColumn label="告警等级" width={160}>
|
|
|
{{
|
|
|
default: scope => <ElRate modelValue={scope.row.rate || 3} disabled/>
|
|
|
}}
|
|
|
</ElTableColumn>
|
|
|
<ElTableColumn label="处理状态" showOverflowTooltip>
|
|
|
{{
|
|
|
default: scope => (
|
|
|
<>
|
|
|
<ElButton type="primary" link>已处理</ElButton>
|
|
|
<ElButton type="primary" link onClick={() => addShildItem()}>不处理</ElButton>
|
|
|
<ElButton type="primary" link>未发现</ElButton>
|
|
|
</>
|
|
|
)
|
|
|
}}
|
|
|
</ElTableColumn>
|
|
|
</ElTable>
|
|
|
</ElCard>
|
|
|
|
|
|
<ElCard shadow="always" style={{marginTop: "12px"}}>
|
|
|
<ElTable data={tableData2.value} style={{width: "100%"}}>
|
|
|
<ElTableColumn label="序号" type="index" width={60}/>
|
|
|
<ElTableColumn prop="name" label="目标名称" width={120}/>
|
|
|
<ElTableColumn prop="lon" label="目标经度" width={120}/>
|
|
|
<ElTableColumn prop="lat" label="目标纬度" width={120}/>
|
|
|
<ElTableColumn prop="deviation" label="deviation" width={120}/>
|
|
|
<ElTableColumn prop="shielding" label="shielding" width={120}/>
|
|
|
<ElTableColumn label="操作" showOverflowTooltip>
|
|
|
{{
|
|
|
default: scope => (
|
|
|
<ElButton type="primary" link onClick={() => delShildItem(scope.row)}>删除</ElButton>
|
|
|
)
|
|
|
}}
|
|
|
</ElTableColumn>
|
|
|
</ElTable>
|
|
|
</ElCard>
|
|
|
</div>
|
|
|
)}
|
|
|
|
|
|
{itemsId.value === 2 && (
|
|
|
<div class="tabsItem">
|
|
|
<ElCard shadow="always">
|
|
|
<ElForm inline model={form5.value} class="demo-form-inline">
|
|
|
<ElFormItem>
|
|
|
<ElInput
|
|
|
modelValue={form5.value.region}
|
|
|
placeholder="请输入机场名称"
|
|
|
style={{width: "200px"}}
|
|
|
onUpdate:modelValue={val => (form5.value.region = val)}
|
|
|
/>
|
|
|
</ElFormItem>
|
|
|
|
|
|
<ElFormItem>
|
|
|
<ElInput
|
|
|
modelValue={form5.value.region1}
|
|
|
placeholder="请输入区域名称"
|
|
|
style={{width: "200px"}}
|
|
|
onUpdate:modelValue={val => (form5.value.region1 = val)}
|
|
|
/>
|
|
|
</ElFormItem>
|
|
|
|
|
|
<ElFormItem>
|
|
|
<ElButton type="primary" onClick={onSubmit}>添加</ElButton>
|
|
|
</ElFormItem>
|
|
|
</ElForm>
|
|
|
|
|
|
<ElForm inline model={form6.value} class="demo-form-inline" style={{marginTop: "12px"}}>
|
|
|
<ElFormItem>
|
|
|
<ElSelect
|
|
|
modelValue={form6.value.region}
|
|
|
placeholder="请选择机场名称"
|
|
|
style={{width: "200px"}}
|
|
|
clearable
|
|
|
onUpdate:modelValue={val => select2Update(val)}
|
|
|
>
|
|
|
{
|
|
|
options1.value.map(i => {
|
|
|
return <ElOption label={i.name} value={i.id}/>
|
|
|
})
|
|
|
}
|
|
|
</ElSelect>
|
|
|
</ElFormItem>
|
|
|
|
|
|
<ElFormItem>
|
|
|
<ElSelect
|
|
|
modelValue={form6.value.region1}
|
|
|
placeholder="请选择区域名称"
|
|
|
style={{width: "200px"}}
|
|
|
clearable
|
|
|
onUpdate:modelValue={val => select3Update(val)}
|
|
|
>
|
|
|
{
|
|
|
options2.value.map(i => {
|
|
|
return <ElOption label={i.name} value={i.id}/>
|
|
|
})
|
|
|
}
|
|
|
</ElSelect>
|
|
|
</ElFormItem>
|
|
|
|
|
|
<ElFormItem>
|
|
|
<ElButton type="primary" onClick={getArea2}>确定</ElButton>
|
|
|
</ElFormItem>
|
|
|
</ElForm>
|
|
|
</ElCard>
|
|
|
|
|
|
<ElCard shadow="always" style={{marginTop: "12px"}}>
|
|
|
{areaPoints.value.map((i, k) => (
|
|
|
<div style={{marginBottom: "12px"}} key={k}>
|
|
|
<ElInput onUpdate:modelValue={val => (areaPoints.value[k].name = val)} modelValue={i.name}
|
|
|
placeholder="点位名称" style={{width: "100px"}}/>
|
|
|
<ElInput
|
|
|
modelValue={i.lon} placeholder="经度"
|
|
|
style={{width: "150px", marginLeft: "20px"}}
|
|
|
onUpdate:modelValue={val => (areaPoints.value[k].lon = val)}
|
|
|
/>
|
|
|
<ElInput
|
|
|
modelValue={i.lat} placeholder="纬度"
|
|
|
style={{width: "150px", marginLeft: "20px"}}
|
|
|
onUpdate:modelValue={val => (areaPoints.value[k].lat = val)}
|
|
|
/>
|
|
|
<ElButton type="primary" onClick={() => getPoint(k)}
|
|
|
style={{marginLeft: "20px"}}>获取</ElButton>
|
|
|
</div>
|
|
|
))}
|
|
|
|
|
|
<ElButton type="primary" onClick={() => {
|
|
|
InsertCListData([{
|
|
|
name: '点位名称',
|
|
|
lon: '1',
|
|
|
lat: '1',
|
|
|
fodAreaId: form6.value.region1,
|
|
|
fodAirId: form6.value.region
|
|
|
}]).then(() => {
|
|
|
getArea2()
|
|
|
})
|
|
|
}}
|
|
|
style={{textAlign: "center"}}>添加</ElButton>
|
|
|
</ElCard>
|
|
|
|
|
|
<div style={{textAlign: "center", marginTop: "12px"}}>
|
|
|
<ElButton type="primary" onClick={saveAreaPoint} style={{marginLeft: "20px"}}>提交</ElButton>
|
|
|
</div>
|
|
|
</div>
|
|
|
)}
|
|
|
|
|
|
{itemsId.value === 3 && (
|
|
|
<div class="tabsItem">
|
|
|
<div>成像设置</div>
|
|
|
|
|
|
<ElForm model={parasSignalproForm.value} inline labelWidth="auto" labelPosition="top">
|
|
|
{["imaging_rangemin", "imaging_rangemax", "imaging_rangeres", "imaging_azimuthlength", "imaging_azimuthres"].map((key, idx) => (
|
|
|
<ElFormItem style={{width: "calc(33% - 32px)"}} label={key} key={idx}>
|
|
|
<ElInput
|
|
|
modelValue={(parasSignalproForm.value.imaging || {})[key]}
|
|
|
onUpdate:modelValue={val => ((parasSignalproForm.value.imaging ||= {})[key] = val)}
|
|
|
/>
|
|
|
</ElFormItem>
|
|
|
))}
|
|
|
</ElForm>
|
|
|
|
|
|
<div>检测设置</div>
|
|
|
<ElForm model={parasSignalproForm.value} inline labelWidth="auto" labelPosition="top">
|
|
|
{["alpha", "decstartr", "decwidth", "sk_r", "sk_a", "lk_r", "lk_a"].map((key, idx) => (
|
|
|
<ElFormItem style={{width: "calc(33% - 32px)"}} label={key} key={idx}>
|
|
|
<ElInput
|
|
|
modelValue={(parasSignalproForm.value.dectection || {})[key]}
|
|
|
onUpdate:modelValue={val => ((parasSignalproForm.value.dectection ||= {})[key] = val)}
|
|
|
/>
|
|
|
</ElFormItem>
|
|
|
))}
|
|
|
|
|
|
<ElFormItem style={{width: "100%"}}>
|
|
|
<div style={{textAlign: "center", width: "100%"}}>
|
|
|
<ElButton type="primary" onClick={saveParasSignalproForm}>保存</ElButton>
|
|
|
</div>
|
|
|
</ElFormItem>
|
|
|
</ElForm>
|
|
|
|
|
|
<div>路线设置</div>
|
|
|
<ElForm model={parasPosForm.value} inline labelWidth="auto" labelPosition="top">
|
|
|
<ElFormItem style={{width: "calc(33% - 32px)"}} label="路线数量">
|
|
|
<ElInputNumber
|
|
|
modelValue={(parasPosForm.value.runwaynum || {}).startpos_num}
|
|
|
precision={0}
|
|
|
step={1}
|
|
|
min={0}
|
|
|
onUpdate:modelValue={val => {
|
|
|
parasPosForm.value.runwaynum.startpos_num = val;
|
|
|
updateRunwayNum(val);
|
|
|
}}
|
|
|
/>
|
|
|
</ElFormItem>
|
|
|
|
|
|
{Array.from({length: (parasPosForm.value.runwaynum || {}).startpos_num || 0}).map((_, k) => (
|
|
|
<div key={k} style="width: 100%">
|
|
|
<div>路线{k + 1}设置</div>
|
|
|
{["startpos_lon_a", "startpos_lat_a", "startpos_alt_a", "startpos_lon_b", "startpos_lat_b", "startpos_alt_b", "startpos_ori"].map((field, idx) => (
|
|
|
<ElFormItem style={{width: "calc(33% - 32px)", display: "inline-block"}} label={field}
|
|
|
key={idx}>
|
|
|
<ElInput
|
|
|
modelValue={(parasPosForm.value.runwayedges[k] || {})[field]}
|
|
|
onUpdate:modelValue={val => (((parasPosForm.value.runwayedges[k] ||= {})[field] = val))}
|
|
|
/>
|
|
|
</ElFormItem>
|
|
|
))}
|
|
|
</div>
|
|
|
))}
|
|
|
|
|
|
<ElFormItem style={{width: "100%"}}>
|
|
|
<div style={{textAlign: "center", width: "100%"}}>
|
|
|
<ElButton type="primary" onClick={saveParasPosForm}>保存</ElButton>
|
|
|
</div>
|
|
|
</ElFormItem>
|
|
|
</ElForm>
|
|
|
</div>
|
|
|
)}
|
|
|
|
|
|
{itemsId.value === 4 && (
|
|
|
<div class="tabsItem">
|
|
|
<ElCard shadow="always">
|
|
|
<ElDatePicker
|
|
|
style={{width: "calc(100% - 20px)"}}
|
|
|
modelValue={date1.value}
|
|
|
type="datetimerange"
|
|
|
rangeSeparator="到"
|
|
|
startPlaceholder="选择开始时间"
|
|
|
endPlaceholder="选择结束时间"
|
|
|
onUpdate:modelValue={val => (date1.value = val)}
|
|
|
/>
|
|
|
</ElCard>
|
|
|
|
|
|
<ElCard shadow="always" style={{marginTop: "12px"}}>
|
|
|
<ElForm inline model={form3.value} class="demo-form-inline">
|
|
|
{["region", "region1", "region2"].map((key, idx) => (
|
|
|
<ElFormItem key={idx}>
|
|
|
{key === "region2" ? (
|
|
|
<ElSelect
|
|
|
modelValue={form3.value[key]}
|
|
|
placeholder="请选择固定目标"
|
|
|
style={{width: "170px"}}
|
|
|
clearable
|
|
|
onUpdate:modelValue={val => (form3.value[key] = val)}
|
|
|
>
|
|
|
<ElOption label="目标1" value="shanghai"/>
|
|
|
<ElOption label="目标2" value="beijing"/>
|
|
|
</ElSelect>
|
|
|
) : (
|
|
|
<ElSelect
|
|
|
modelValue={form3.value[key]}
|
|
|
placeholder={`请选择${key === "region" ? "机场" : "区域"}`}
|
|
|
style={{width: "170px"}}
|
|
|
clearable
|
|
|
onUpdate:modelValue={val => (form3.value[key] = val)}
|
|
|
>
|
|
|
<ElOption label="机场1" value="shanghai"/>
|
|
|
<ElOption label="机场2" value="beijing"/>
|
|
|
<ElOption label="区域1" value="shanghai"/>
|
|
|
<ElOption label="区域2" value="beijing"/>
|
|
|
</ElSelect>
|
|
|
)}
|
|
|
</ElFormItem>
|
|
|
))}
|
|
|
</ElForm>
|
|
|
</ElCard>
|
|
|
|
|
|
<ElCard shadow="always" style={{marginTop: "12px"}}>
|
|
|
<ElForm inline model={form4.value} class="demo-form-inline">
|
|
|
<ElFormItem>
|
|
|
<ElInput
|
|
|
modelValue={form4.value.input1}
|
|
|
placeholder="请输入检测序号"
|
|
|
style={{width: "170px"}}
|
|
|
onUpdate:modelValue={val => (form4.value.input1 = val)}
|
|
|
/>
|
|
|
</ElFormItem>
|
|
|
|
|
|
<ElFormItem>
|
|
|
<ElDatePicker
|
|
|
modelValue={form4.value.date1}
|
|
|
type="date"
|
|
|
placeholder="选择检测时间"
|
|
|
clearable
|
|
|
style={{width: "170px"}}
|
|
|
onUpdate:modelValue={val => (form4.value.date1 = val)}
|
|
|
/>
|
|
|
</ElFormItem>
|
|
|
|
|
|
<ElFormItem>
|
|
|
<ElInput
|
|
|
modelValue={form4.value.input2}
|
|
|
placeholder="请输入检测人员"
|
|
|
style={{width: "170px"}}
|
|
|
onUpdate:modelValue={val => (form4.value.input2 = val)}
|
|
|
/>
|
|
|
</ElFormItem>
|
|
|
</ElForm>
|
|
|
</ElCard>
|
|
|
|
|
|
<ElCard shadow="always" style={{marginTop: "12px"}}>
|
|
|
<ElTable data={tableData2.value} style={{width: "100%"}}>
|
|
|
<ElTableColumn label="序号" type="index" width={60}/>
|
|
|
<ElTableColumn prop="coordinate" label="目标坐标" width={120}/>
|
|
|
<ElTableColumn label="告警等级" width={160}>
|
|
|
{{default: scope => <ElRate modelValue={scope.row.rate} disabled/>}}
|
|
|
</ElTableColumn>
|
|
|
<ElTableColumn label="处理状态" showOverflowTooltip>
|
|
|
{{
|
|
|
default: scope => (
|
|
|
<>
|
|
|
<span>{scope.row.type === 1 ? "已处理" : ""}</span>
|
|
|
<span>{scope.row.type === 2 ? "不处理" : ""}</span>
|
|
|
<span>{scope.row.type === 3 ? "未发现" : ""}</span>
|
|
|
</>
|
|
|
)
|
|
|
}}
|
|
|
</ElTableColumn>
|
|
|
</ElTable>
|
|
|
</ElCard>
|
|
|
</div>
|
|
|
)}
|
|
|
</div>
|
|
|
)
|
|
|
}
|
|
|
})
|
|
|
|
|
|
const router = useRouter();
|
|
|
const toAdmin = () => {
|
|
|
router.push('/serve')
|
|
|
}
|
|
|
// setTimeout(() => {
|
|
|
// setZoom({lon: 120.0005, lat: 30.005}, 2)
|
|
|
// }, 30000)
|
|
|
|
|
|
const socketData = [
|
|
|
{
|
|
|
"TimeQuality": 19124,
|
|
|
"GpsWeek": 2378,
|
|
|
"GpsSeconds": 443388.33,
|
|
|
"Latitude": 28.24388795549,
|
|
|
"Longitude": 113.00382002762,
|
|
|
"EllipsoidHeight": 14.6323,
|
|
|
"VelocityNorth": -0.1931,
|
|
|
"VelocityEast": 3.2447,
|
|
|
"ActualSpeed": 11.701587,
|
|
|
"RollAngle": 1.047412,
|
|
|
"HeadingAngle": 92.054855,
|
|
|
"IncludedAngle": 0.0,
|
|
|
"SolutionStatus": "",
|
|
|
"Fps": 3.485E-42,
|
|
|
"FpsNum": 0.0,
|
|
|
"MotorPitchAngle": 0.0,
|
|
|
"MotorAzimuthAngle": 0.0,
|
|
|
"ty": 3
|
|
|
},
|
|
|
{
|
|
|
"radar_type": 0,
|
|
|
"radar_ver": "0.1.1",
|
|
|
"arm_ver": "0.0.0",
|
|
|
"al_ver": "0.0.0",
|
|
|
"pwc_ver": "0.0.0",
|
|
|
"cd_ver": "0.0.0",
|
|
|
"v1": 0,
|
|
|
"v2": 0,
|
|
|
"v3": 0,
|
|
|
"v4": 0,
|
|
|
"radar_total_vol": 23.5,
|
|
|
"radar_total_cur": 0.0,
|
|
|
"nx_vol": 0.0,
|
|
|
"nx_cur": 0.0,
|
|
|
"nx_temp": 25.0,
|
|
|
"arm_vol": 23.5,
|
|
|
"arm_cur": 0.0,
|
|
|
"arm_temp": 25.0,
|
|
|
"ant_vol": 23.5,
|
|
|
"ant_cur": 0.0,
|
|
|
"ant_temp": 0.0,
|
|
|
"at_work_area_status": 0,
|
|
|
"pwb_err_code": 0,
|
|
|
"pwa_err_code": 0,
|
|
|
"al_err_code": 0,
|
|
|
"arm_err_code": 0,
|
|
|
"radar_err_code": 0,
|
|
|
"radar_work_state": 0,
|
|
|
"ty": 1
|
|
|
},
|
|
|
{
|
|
|
"Seq": 3.0,
|
|
|
"MD5": null,
|
|
|
"TimeStamp": 5.644776E+24,
|
|
|
"MissionID": 5.644776E+24,
|
|
|
"RngRes": 0.075,
|
|
|
"RngNum": 0.0,
|
|
|
"RngMin": 15.0,
|
|
|
"AziRes": 0.1,
|
|
|
"AziNum": 0.0,
|
|
|
"AziMin": 600.0,
|
|
|
"DataType": 2.8E-44,
|
|
|
"LonMin": 112.99582,
|
|
|
"LatMin": 28.242912,
|
|
|
"TarNum": 6E-45,
|
|
|
"ty": 4
|
|
|
}
|
|
|
]
|
|
|
let area = {
|
|
|
"LatMin": 0,
|
|
|
"LatMax": 0,
|
|
|
"LonMin": 0,
|
|
|
"LonMax": 0,
|
|
|
}
|
|
|
const dots = ref([
|
|
|
// {
|
|
|
// x: 150,
|
|
|
// y: 98
|
|
|
// },
|
|
|
// {
|
|
|
// x: 50,
|
|
|
// y: 102
|
|
|
// },
|
|
|
// {
|
|
|
// x: 75,
|
|
|
// y: 75
|
|
|
// },
|
|
|
// {
|
|
|
// x: 125,
|
|
|
// y: 125
|
|
|
// }
|
|
|
])
|
|
|
|
|
|
const points = ref([
|
|
|
{
|
|
|
lon: 120.38532472236,
|
|
|
lat: 36.14505053622,
|
|
|
name: '点位1',
|
|
|
},
|
|
|
{
|
|
|
lon: 120.38532472236,
|
|
|
lat: 36.15302618219,
|
|
|
name: '点位2',
|
|
|
},
|
|
|
{
|
|
|
lon: 120.39109582218,
|
|
|
lat: 36.15302618219,
|
|
|
name: '点位3',
|
|
|
},
|
|
|
{
|
|
|
lon: 120.39109582218,
|
|
|
lat: 36.14505053622,
|
|
|
name: '点位4',
|
|
|
},
|
|
|
])
|
|
|
|
|
|
const a = ref(window)
|
|
|
|
|
|
const list = ref([
|
|
|
{
|
|
|
value1: '点位1',
|
|
|
value2: '经纬度:(528,11)'
|
|
|
},
|
|
|
{
|
|
|
value1: '点位1',
|
|
|
value2: '经纬度:(528,11)'
|
|
|
},
|
|
|
{
|
|
|
value1: '点位1',
|
|
|
value2: '经纬度:(528,11)'
|
|
|
},
|
|
|
])
|
|
|
const rulerRef = ref()
|
|
|
const itemsId = ref(1)
|
|
|
const form1 = ref({})
|
|
|
const form2 = ref({})
|
|
|
const form3 = ref({})
|
|
|
const form4 = ref({})
|
|
|
const form5 = ref({})
|
|
|
const form6 = ref({})
|
|
|
const radarWorkState = ref(0)
|
|
|
const dotIndex = ref(-1)
|
|
|
const tableData1 = ref([])
|
|
|
const tableData2 = ref([
|
|
|
{
|
|
|
"id": 2,
|
|
|
"name": "测试",
|
|
|
"lon": 12.2299995,
|
|
|
"lat": 323.329987,
|
|
|
"deviation": 12,
|
|
|
"shielding": 20
|
|
|
},
|
|
|
{
|
|
|
"id": 1,
|
|
|
"name": "测试",
|
|
|
"lon": 12.2299995,
|
|
|
"lat": 323.329987,
|
|
|
"deviation": 12,
|
|
|
"shielding": 20
|
|
|
}
|
|
|
])
|
|
|
const date1 = ref([])
|
|
|
const setItemsId = (e) => {
|
|
|
itemsId.value = e
|
|
|
}
|
|
|
const locationData = ref({})
|
|
|
const currentPosition = ref({})
|
|
|
|
|
|
const getDistanceInMeters = (lon1, lat1, lon2, lat2) => {
|
|
|
const R = 6371000; // 地球半径(米)
|
|
|
const toRad = deg => deg * Math.PI / 180;
|
|
|
|
|
|
const dLat = toRad(lat2 - lat1);
|
|
|
const dLon = toRad(lon2 - lon1);
|
|
|
|
|
|
const a =
|
|
|
Math.sin(dLat / 2) ** 2 +
|
|
|
Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) * Math.sin(dLon / 2) ** 2;
|
|
|
|
|
|
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
|
|
return R * c;
|
|
|
}
|
|
|
|
|
|
function getXYDistanceFromMin(current, minPoint) {
|
|
|
const R = 6371000; // 地球半径(米)
|
|
|
const toRad = deg => deg * Math.PI / 180;
|
|
|
|
|
|
// 计算两点之间某一维的距离
|
|
|
const haversineDistance = (lat1, lon1, lat2, lon2) => {
|
|
|
const dLat = toRad(lat2 - lat1);
|
|
|
const dLon = toRad(lon2 - lon1);
|
|
|
const a =
|
|
|
Math.sin(dLat / 2) ** 2 +
|
|
|
Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) * Math.sin(dLon / 2) ** 2;
|
|
|
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
|
|
return R * c;
|
|
|
};
|
|
|
|
|
|
// 横向距离(经度方向)
|
|
|
const xDistance = haversineDistance(minPoint.lat, minPoint.lon, minPoint.lat, current.lon);
|
|
|
// 纵向距离(纬度方向)
|
|
|
const yDistance = haversineDistance(minPoint.lat, minPoint.lon, current.lat, minPoint.lon);
|
|
|
|
|
|
return {xDistance, yDistance};
|
|
|
}
|
|
|
const processData = (data) => {
|
|
|
// console.log('data',data.ty)
|
|
|
// console.log('FodName', data.FodName)
|
|
|
if (data.FodName === '雷达信息') {
|
|
|
// console.log('雷达信息', data.radar_work_state)
|
|
|
radarWorkState.value = data.radar_work_state
|
|
|
}
|
|
|
if (data.FodName === '图像数据') {
|
|
|
}
|
|
|
if (data.FodName === 'fod信息') {
|
|
|
setDot(data)
|
|
|
}
|
|
|
if (data.ty === 3) {
|
|
|
}
|
|
|
if (data.FodName === '车辆信息') {
|
|
|
currentPosition.value = {
|
|
|
lon: data.Longitude,
|
|
|
lat: data.Latitude,
|
|
|
}
|
|
|
// console.log(data.Longitude > area.LonMin, data.Longitude < area.LonMax, data.Latitude > area.LatMin, data.Latitude < area.LatMax)
|
|
|
if (data.Longitude > area.LonMin && data.Longitude < area.LonMax && data.Latitude > area.LatMin && data.Latitude < area.LatMax) {
|
|
|
let xAndy = getXYDistanceFromMin({lon: data.Longitude, lat: data.Latitude}, {lon: area.LonMin, lat: area.LatMin})
|
|
|
let location = {
|
|
|
x: xAndy.xDistance,
|
|
|
y: xAndy.yDistance,
|
|
|
rotate: data.HeadingAngle
|
|
|
// rotate: 0
|
|
|
}
|
|
|
console.log('location', location)
|
|
|
boxPos.value = location
|
|
|
}
|
|
|
|
|
|
}
|
|
|
};
|
|
|
const parasSignalproForm = ref({
|
|
|
imaging: {},
|
|
|
dectection: {}
|
|
|
})
|
|
|
const parasPosForm = ref({
|
|
|
runwaynum: {
|
|
|
startpos_num: 1
|
|
|
},
|
|
|
runwayedges: [
|
|
|
{
|
|
|
startpos_lon_a: '',
|
|
|
startpos_lat_a: '',
|
|
|
startpos_alt_a: '',
|
|
|
startpos_lon_b: '',
|
|
|
startpos_lat_b: '',
|
|
|
startpos_alt_b: '',
|
|
|
startpos_ori: ''
|
|
|
}
|
|
|
]
|
|
|
})
|
|
|
|
|
|
onMounted(() => {
|
|
|
getTableData()
|
|
|
ad()
|
|
|
getOption()
|
|
|
getShildTableList()
|
|
|
points.value = localStorage.getItem('points') ? JSON.parse(localStorage.getItem('points')) : [
|
|
|
{
|
|
|
lon: 117.213524,
|
|
|
lat: 36.837967,
|
|
|
name: '点位1',
|
|
|
},
|
|
|
{
|
|
|
lon: 117.213524,
|
|
|
lat: 36.847967,
|
|
|
name: '点位2',
|
|
|
},
|
|
|
{
|
|
|
lon: 117.223524,
|
|
|
lat: 36.847967,
|
|
|
name: '点位3',
|
|
|
},
|
|
|
{
|
|
|
lon: 117.223524,
|
|
|
lat: 36.837967,
|
|
|
name: '点位4',
|
|
|
},
|
|
|
]
|
|
|
getArea1()
|
|
|
|
|
|
// setDot({
|
|
|
// "DarDatas": [{"Lon": 117.213524, "Lat": 36.837967}, {"Lon": 0.0, "Lat": 0.0}, {
|
|
|
// "Lon": 0.0,
|
|
|
// "Lat": 0.0
|
|
|
// }, {"Lon": 0.0, "Lat": 0.0}, {"Lon": 117.2134, "Lat": 36.837967}, {"Lon": 0.0, "Lat": 0.0}, {
|
|
|
// "Lon": 0.0,
|
|
|
// "Lat": 0.0
|
|
|
// }, {"Lon": 0.0, "Lat": 0.0}, {"Lon": 117.21341, "Lat": 36.837986}, {"Lon": 0.0, "Lat": 0.0}, {
|
|
|
// "Lon": 0.0,
|
|
|
// "Lat": 0.0
|
|
|
// }, {"Lon": 0.0, "Lat": 0.0}, {"Lon": 117.21337, "Lat": 36.838}, {"Lon": 0.0, "Lat": 0.0}],
|
|
|
// "Seq": 0,
|
|
|
// "MD5": "038fb0493c415f58c703ab205f9f2c94",
|
|
|
// "TimeStamp": 1757556826,
|
|
|
// "MissionID": 1757556826,
|
|
|
// "RngRes": 0.075,
|
|
|
// "RngNum": 0,
|
|
|
// "RngMin": 10.0,
|
|
|
// "AziRes": 0.1,
|
|
|
// "AziNum": 0,
|
|
|
// "AziMin": 0.03593219,
|
|
|
// "DataType": 20,
|
|
|
// "LonMin": 117.213844,
|
|
|
// "LatMin": 36.83799,
|
|
|
// "TarNum": 14,
|
|
|
// "ty": 0,
|
|
|
// "FodName": "fod信息"
|
|
|
// })
|
|
|
})
|
|
|
|
|
|
const getOption = () => {
|
|
|
getParasPos().then((e) => {
|
|
|
parasPosForm.value = {
|
|
|
runwaynum: e.runwaynum,
|
|
|
runwayedges: e.runwayedges,
|
|
|
}
|
|
|
})
|
|
|
getParasSignalpro().then((e) => {
|
|
|
parasSignalproForm.value = {
|
|
|
imaging: e.imaging,
|
|
|
dectection: e.dectection,
|
|
|
}
|
|
|
})
|
|
|
}
|
|
|
const saveParasSignalproForm = () => {
|
|
|
setParasSignalpro(parasSignalproForm.value).then(e => {
|
|
|
console.log(e)
|
|
|
})
|
|
|
}
|
|
|
const saveParasPosForm = () => {
|
|
|
setParasPos(parasPosForm.value).then(e => {
|
|
|
console.log(e)
|
|
|
})
|
|
|
}
|
|
|
const updateRunwayNum = (e) => {
|
|
|
let arr = new Array(e).fill(0)
|
|
|
.map((item, index) => {
|
|
|
if (index <= parasPosForm.value.runwayedges.length - 1) {
|
|
|
return JSON.parse(JSON.stringify(parasPosForm.value.runwayedges[index]))
|
|
|
} else {
|
|
|
return {
|
|
|
startpos_lon_a: '',
|
|
|
startpos_lat_a: '',
|
|
|
startpos_alt_a: '',
|
|
|
startpos_lon_b: '',
|
|
|
startpos_lat_b: '',
|
|
|
startpos_alt_b: '',
|
|
|
startpos_ori: ''
|
|
|
}
|
|
|
}
|
|
|
})
|
|
|
console.log(arr)
|
|
|
parasPosForm.value.runwayedges = JSON.parse(JSON.stringify(arr))
|
|
|
}
|
|
|
|
|
|
const addShildItem = () => {
|
|
|
addShildData({
|
|
|
name: 'string',
|
|
|
lon: 123,
|
|
|
lat: 12,
|
|
|
deviation: 12,
|
|
|
shielding: 23
|
|
|
}).then(e => {
|
|
|
getShildTableList()
|
|
|
})
|
|
|
}
|
|
|
const delShildItem = (e) => {
|
|
|
delShildData(e).then(e => {
|
|
|
getShildTableList()
|
|
|
})
|
|
|
}
|
|
|
const getShildTableList = () => {
|
|
|
getShildList({
|
|
|
pageIndex: 1,
|
|
|
pageSize: 10,
|
|
|
name: 'string'
|
|
|
}).then((e) => {
|
|
|
tableData2.value = e.data
|
|
|
|
|
|
})
|
|
|
}
|
|
|
|
|
|
const ad = () => {
|
|
|
|
|
|
// 1. 创建 WebSocket 连接(ws:// 或 wss://)
|
|
|
// const socket = new WebSocket("ws://192.168.1.123:7789/ws");
|
|
|
const socket = new WebSocket("ws://192.168.1.123:7789/ws");
|
|
|
|
|
|
// 2. 连接成功时触发
|
|
|
socket.addEventListener("open", () => {
|
|
|
console.log("✅ WebSocket 连接成功");
|
|
|
});
|
|
|
|
|
|
// 3. 接收消息
|
|
|
socket.addEventListener("message", (event) => {
|
|
|
console.log(JSON.parse(event.data))
|
|
|
processData(JSON.parse(event.data))
|
|
|
});
|
|
|
|
|
|
// 4. 连接关闭时触发
|
|
|
socket.addEventListener("close", () => {
|
|
|
console.log("❌ WebSocket 已关闭");
|
|
|
});
|
|
|
|
|
|
// 5. 出错时触发
|
|
|
socket.addEventListener("error", (error) => {
|
|
|
console.error("⚠️ WebSocket 出错:", error);
|
|
|
});
|
|
|
}
|
|
|
|
|
|
const StartWorkBtn = () => {
|
|
|
StartWork()
|
|
|
rulerRef.value.setDot([], true)
|
|
|
tableData1.value = []
|
|
|
}
|
|
|
const StopWorkBtn = () => {
|
|
|
StopWork()
|
|
|
}
|
|
|
const RestartWorkBtn = () => {
|
|
|
RestartWork()
|
|
|
}
|
|
|
const ShutDownWorkBtn = () => {
|
|
|
ShutDownWork()
|
|
|
}
|
|
|
const getPoint = (k) => {
|
|
|
areaPoints.value[k].lon = currentPosition.value.lon || 0
|
|
|
areaPoints.value[k].lat = currentPosition.value.lat || 0
|
|
|
}
|
|
|
const getArea1 = () => {
|
|
|
if (points.value.length < 4) return
|
|
|
let data = points.value
|
|
|
|
|
|
let latMin = data[0].lat;
|
|
|
let latMax = data[0].lat;
|
|
|
let lonMin = data[0].lon;
|
|
|
let lonMax = data[0].lon;
|
|
|
|
|
|
for (let i = 1; i < data.length; i++) {
|
|
|
const p = data[i];
|
|
|
if (p.lat < latMin) latMin = p.lat;
|
|
|
if (p.lat > latMax) latMax = p.lat;
|
|
|
if (p.lon < lonMin) lonMin = p.lon;
|
|
|
if (p.lon > lonMax) lonMax = p.lon;
|
|
|
}
|
|
|
// area = {
|
|
|
// LatMin: latMin,
|
|
|
// LatMax: latMax,
|
|
|
// LonMin: lonMin,
|
|
|
// LonMax: lonMax,
|
|
|
// }
|
|
|
}
|
|
|
const savePoint = () => {
|
|
|
localStorage.setItem('points', JSON.stringify(points.value))
|
|
|
getArea1()
|
|
|
}
|
|
|
const setDot = (e) => {
|
|
|
let dots = e.DarDatas.map((v, k) => {
|
|
|
if (v.Lon == 0 && v.Lat == 0) return null
|
|
|
return {
|
|
|
x: 300 - (area.LonMax - v.Lon) / ((area.LonMax - area.LonMin) / 300),
|
|
|
y: 1800 - (area.LatMax - v.Lat) / ((area.LatMax - area.LatMin) / 1800),
|
|
|
index: k
|
|
|
}
|
|
|
}).filter(v => v)
|
|
|
tableData1.value = [...tableData1.value, ...e.DarDatas.filter(v => v.Lon !== 0 && v.Lat !== 0).map((v, k) => {
|
|
|
return {...v, index: k}
|
|
|
})]
|
|
|
rulerRef.value.setDot(dots, false)
|
|
|
}
|
|
|
const table1Current = (e, v) => {
|
|
|
if (dotIndex.value === e.index) {
|
|
|
dotIndex.value = -1
|
|
|
} else {
|
|
|
dotIndex.value = e.index || 0
|
|
|
}
|
|
|
console.log(e)
|
|
|
}
|
|
|
|
|
|
|
|
|
const options1 = ref([])
|
|
|
const options2 = ref([])
|
|
|
const getTableData = async () => {
|
|
|
await getAllAirPort().then(e => {
|
|
|
options1.value = e.data
|
|
|
})
|
|
|
}
|
|
|
const selectUpdate = (val) => {
|
|
|
form1.value.region = val
|
|
|
getArea({airId: val}).then(e => {
|
|
|
options2.value = e.data
|
|
|
})
|
|
|
}
|
|
|
const select2Update = (val) => {
|
|
|
form6.value.region = val
|
|
|
getArea({airId: val}).then(e => {
|
|
|
options2.value = e.data
|
|
|
})
|
|
|
}
|
|
|
const select3Update = (val) => {
|
|
|
form6.value.region1 = val
|
|
|
}
|
|
|
const areaPoints = ref([])
|
|
|
const getArea2 = () => {
|
|
|
GetAllCData({areaId: form6.value.region1}).then((res) => {
|
|
|
areaPoints.value = res.data
|
|
|
})
|
|
|
}
|
|
|
|
|
|
function getBoundingBoxAndSize(pointsArr) {
|
|
|
if (!pointsArr || pointsArr.length === 0) {
|
|
|
}
|
|
|
|
|
|
let maxLon = Math.max(...pointsArr.map(p => p.lon));
|
|
|
let minLon = Math.min(...pointsArr.map(p => p.lon));
|
|
|
let maxLat = Math.max(...pointsArr.map(p => p.lat));
|
|
|
let minLat = Math.min(...pointsArr.map(p => p.lat));
|
|
|
|
|
|
const R = 6371000;
|
|
|
|
|
|
const toRad = deg => deg * Math.PI / 180;
|
|
|
|
|
|
// Haversine 距离计算
|
|
|
const haversineDistance = (lat1, lon1, lat2, lon2) => {
|
|
|
const dLat = toRad(lat2 - lat1);
|
|
|
const dLon = toRad(lon2 - lon1);
|
|
|
const a =
|
|
|
Math.sin(dLat / 2) ** 2 +
|
|
|
Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) * Math.sin(dLon / 2) ** 2;
|
|
|
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
|
|
return R * c;
|
|
|
};
|
|
|
|
|
|
const width = Math.round(haversineDistance(minLat, minLon, minLat, maxLon))
|
|
|
const height = Math.round(haversineDistance(minLat, minLon, maxLat, maxLon))
|
|
|
|
|
|
return {width, height, minLat, minLon, maxLat, maxLon};
|
|
|
}
|
|
|
|
|
|
const areaData = ref({
|
|
|
width: 500,
|
|
|
height: 1000
|
|
|
})
|
|
|
const saveAreaPoint = () => {
|
|
|
let arr = []
|
|
|
areaPoints.value.forEach((v, k) => {
|
|
|
arr.push(UpdateCData(v))
|
|
|
})
|
|
|
Promise.all(arr).then(() => {
|
|
|
ElMessage.success('保存成功')
|
|
|
let data = getBoundingBoxAndSize(areaPoints.value)
|
|
|
console.log(data)
|
|
|
areaData.value = data
|
|
|
area = {
|
|
|
"LatMin": data.minLat,
|
|
|
"LatMax": data.maxLat,
|
|
|
"LonMin": data.minLon,
|
|
|
"LonMax": data.maxLon
|
|
|
}
|
|
|
}).catch((err) => {
|
|
|
ElMessage.error(err)
|
|
|
})
|
|
|
}
|
|
|
</script>
|
|
|
<style>
|
|
|
.app-container {
|
|
|
width: 1080px;
|
|
|
min-width: 1080px;
|
|
|
height: 100vh;
|
|
|
margin: 0 auto;
|
|
|
}
|
|
|
|
|
|
.top {
|
|
|
width: 100%;
|
|
|
height: 80px;
|
|
|
font-size: 24px;
|
|
|
background-color: #202227;
|
|
|
position: relative;
|
|
|
}
|
|
|
|
|
|
.items {
|
|
|
position: absolute;
|
|
|
top: 15%;
|
|
|
left: 50%;
|
|
|
transform: translateX(-50%);
|
|
|
white-space: nowrap;
|
|
|
}
|
|
|
|
|
|
.item {
|
|
|
display: inline-block;
|
|
|
width: 120px;
|
|
|
height: 100%;
|
|
|
color: #8C9A9C;
|
|
|
line-height: 56px;
|
|
|
cursor: pointer;
|
|
|
font-size: 18px;
|
|
|
font-weight: 600;
|
|
|
letter-spacing: 2px;
|
|
|
}
|
|
|
|
|
|
.item span {
|
|
|
display: inline-block;
|
|
|
height: 100%;
|
|
|
}
|
|
|
|
|
|
.item.click span,
|
|
|
.item:hover span {
|
|
|
color: #0D52BF;
|
|
|
border-bottom: 2px solid #0D52BF;
|
|
|
}
|
|
|
|
|
|
.title {
|
|
|
line-height: 80px;
|
|
|
color: #fff;
|
|
|
margin-left: 20px;
|
|
|
display: inline-block;
|
|
|
text-align: left;
|
|
|
}
|
|
|
|
|
|
.left {
|
|
|
display: inline-block;
|
|
|
height: calc(100vh - 80px);
|
|
|
width: 34%;
|
|
|
vertical-align: top;
|
|
|
}
|
|
|
|
|
|
.right {
|
|
|
padding: 20px 20px 0 20px;
|
|
|
display: inline-block;
|
|
|
height: calc(100vh - 80px - 20px);
|
|
|
width: calc(66% - 40px);
|
|
|
background-color: #F6F7FB;
|
|
|
overflow: auto;
|
|
|
}
|
|
|
</style> |