This commit is contained in:
zh
2025-11-10 15:29:14 +08:00
14 changed files with 1172 additions and 259 deletions

View File

@ -33,6 +33,13 @@ export const TsApi = {
data data
}) })
}, },
// /tsSource/delete
deleteTsModelSource: async (data: any) => {
return await request.post({
url: '/tsSource/delete',
data
})
},
queryTsSource: async (data: any) => { queryTsSource: async (data: any) => {
return await request.post({ return await request.post({
url: '/tsSource/query', url: '/tsSource/query',

View File

@ -2,21 +2,21 @@ import { createRouter, createWebHashHistory } from 'vue-router'
import homeIndex from '@/views/home/index.vue' import homeIndex from '@/views/home/index.vue'
const routes = [ const routes = [
// {
// path: '/',
// component: () => import('@/views/login/index.vue'),
// hidden: true
// },
{ {
path: '/', path: '/',
component: () => import('@/views/author/index.vue'),
hidden: true
},
{
path: '/login',
component: () => import('@/views/login/index.vue'), component: () => import('@/views/login/index.vue'),
hidden: true hidden: true
}, },
// {
// path: '/',
// component: () => import('@/views/author/index.vue'),
// hidden: true
// },
// {
// path: '/login',
// component: () => import('@/views/login/index.vue'),
// hidden: true
// },
{ path: '/ts', component: () => import('@/views/TS/list.vue'), hidden: true }, { path: '/ts', component: () => import('@/views/TS/list.vue'), hidden: true },
{ path: '/tsEdit', name: 'tsEdit', component: () => import('@/views/TS/edit.vue'), hidden: true }, { path: '/tsEdit', name: 'tsEdit', component: () => import('@/views/TS/edit.vue'), hidden: true },
{ path: '/404', component: () => import('@/views/404.vue'), hidden: true }, { path: '/404', component: () => import('@/views/404.vue'), hidden: true },

View File

@ -50,9 +50,15 @@ const initTreeCallBack = () => {
if (res.code == 200) { if (res.code == 200) {
for (let i = res.data.length - 1; i >= 0; i--) { for (let i = res.data.length - 1; i >= 0; i--) {
res.data[i].svg = await cusNodeIcon(res.data[i]); res.data[i].svg = await cusNodeIcon(res.data[i]);
} }
zNodes.value = res.data zNodes.value = res.data
console.log("data", zNodes.value) /*zNodes.value.forEach(item => {
if (typeof item.detail == 'string') {
item.detail = JSON.parse(item.detail)
}
})*/
console.log("zNodes.value", zNodes.value)
treeObj.value = $.fn.zTree.init($(`#treeDemos`), setting, zNodes.value) treeObj.value = $.fn.zTree.init($(`#treeDemos`), setting, zNodes.value)
window.treeObj = treeObj.value window.treeObj = treeObj.value
} }
@ -73,8 +79,8 @@ const initTreeCallBack = () => {
if (arr[i].sourceType === 'directory') { if (arr[i].sourceType === 'directory') {
continue continue
} }
let detail = JSON.parse(arr[i].detail || '{}') let detail = typeof arr[i].detail == 'string' ? JSON.parse(arr[i].detail || '{}') : arr[i].detail
let params = JSON.parse(arr[i].params || '{}') let params = typeof arr[i].params == 'string' ? JSON.parse(arr[i].params || '{}') : arr[i].params
if (!detail.name) { if (!detail.name) {
detail.name = arr[i].sourceName detail.name = arr[i].sourceName
} }
@ -89,10 +95,29 @@ const initTreeCallBack = () => {
} }
) )
} else { } else {
console.log({...detail, ...params})
initMapData(arr[i].sourceType, {...detail, ...params}) initMapData(arr[i].sourceType, {...detail, ...params})
} }
} }
//gis实例渲染后查找是否有相关的轨迹运动对象有则渲染
let guijiEvents = window['tsObj']._Store.getTaskByProperty("move", "callback")
guijiEvents.forEach(event => {
let detail = typeof event.detail == 'string' ? JSON.parse(event.detail) : JSON.parse(JSON.stringify(event.detail))
let duration_S = (event.endTime - event.startTime) / 1000
let distance = new YJ.Tools().computeDistance2(detail.line.positions);
let speed = (distance / duration_S) * window['tsObj']._Store._multiplier
detail.speed = speed
console.log("event的detail", detail)
initMapData("guiji", detail, (TrajectoryMotionObject) => {
TrajectoryMotionObject.state = false
TrajectoryMotionObject.oldSpeed = (distance / duration_S) * window['tsObj']._Store._multiplier
(window as any)._entityMap.set(event.id + event.callback + event.sourceId, TrajectoryMotionObject)
let tsEntitys = (window as any)._entityMap.get(event.sourceId);
TrajectoryMotionObject.moveCallBack(tsEntitys)
})
})
layers.sort((obj1, obj2) => { layers.sort((obj1, obj2) => {
return obj1.detail.layerIndex - obj2.detail.layerIndex; return obj1.detail.layerIndex - obj2.detail.layerIndex;
}); });

View File

@ -42,12 +42,15 @@ const numbers = ref(0)
const detail:any = ref({}) const detail:any = ref({})
const eventBus: any = inject('bus') const eventBus: any = inject('bus')
let eventObj:any = ref(null) let eventObj: any = ref(null)
eventBus.on('click-event-show-plane', (params) => { eventBus.on('click-event-show-plane', (params) => {
console.log('兄弟 B 的方法被触发了!', params) console.log('兄弟 B 的方法被触发了!', params)
eventObj.value = (params ? params : null) eventObj.value = (params ? params : null)
if (eventObj.value) { if (eventObj.value) {
let details = JSON.parse(eventObj.value.detail) let details = eventObj.value.detail
if (typeof details == 'string') {
details = JSON.parse(eventObj.value.detail)
}
switch (params.callback) { switch (params.callback) {
case 'flicker': case 'flicker':
// times.value = detail.times // times.value = detail.times

View File

@ -58,24 +58,35 @@ const props = defineProps(['eventList',])
const menus = ref([ const menus = ref([
{ {
name: "删除", name: "删除",
fun: () => { fun:
let param = new FormData () => {
param.append("id", rightClickEvent.value.id) delEvent([rightClickEvent.value.id], () => {
TsApi.delEvent(param).then(res => {
if (res.code == 200) {
eventBus.emit('delete-event', rightClickEvent.value.id)
ElMessage({message: "操作成功", type: "success"}) ElMessage({message: "操作成功", type: "success"})
rightClickEvent.value = null rightClickEvent.value = null
}
}) })
}
}
}, { }, {
name: '定位', fun: () => { name: '定位', fun: () => {
let entity = window['earth_ts'].entityMap.get(rightClickEvent.value.sourceId) let entity = window['earth_ts'].entityMap.get(rightClickEvent.value.sourceId)
entity && entity.flyTo() entity && entity.flyTo()
} }
},]) },]
)
const clicked = ref(false) const clicked = ref(false)
const delEvent = (ids, cb) => {
TsApi.delEvent(ids).then(res => {
if (res.code == 200) {
eventBus.emit('delete-event', ids)
cb()
}
})
}
eventBus.on("del-event-by-source", ids => {
delEvent(ids, () => {
})
})
function onCancel() { function onCancel() {
clicked.value = true clicked.value = true

View File

@ -2,10 +2,10 @@ import {$changeComponentPop} from "../../../utils/communication";
import {ipcRenderer} from "electron"; import {ipcRenderer} from "electron";
import {addMapSource, initMapData} from "../entity"; import {addMapSource, initMapData} from "../entity";
import {TsApi} from "../../../api/ts"; import {TsApi} from "../../../api/ts";
import {ElMessage} from "element-plus"; import {ElMessage, ElMessageBox} from "element-plus";
import {useTreeNode} from "../../components/tree/hooks/treeNode"; import {useTreeNode} from "../../components/tree/hooks/treeNode";
const {cusAddNodes} = useTreeNode() const {cusAddNodes, getSelectedNodes, cusRemoveNode} = useTreeNode()
function getLastPathComponent(path, extensionsToRemove = []) { function getLastPathComponent(path, extensionsToRemove = []) {
// 处理路径分隔符 // 处理路径分隔符
@ -139,8 +139,46 @@ export const useRightOperate = () => {
} }
}) })
} }
const delNode = () => { const delNode = (node, eventBus) => {
console.log("删除节点") console.log("删除节点", eventBus)
ElMessageBox.confirm('此操作将永久删除节点及所有子节点, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(async () => {
let selectNodes = getSelectedNodes(window.treeObj)
let source_ids = cusRemoveNode(window.treeObj, selectNodes)
console.log(source_ids)
TsApi.deleteTsModelSource(source_ids).then(res => {
if (res.code == 0 || res.code == 200) {
ElMessage({
message: '删除成功',
type: 'success'
})
let eventIds = []
source_ids.forEach(item => {
let entity = (window as any).earth_ts.entityMap.get(item)
if (entity) {
entity.remove();
(window as any)._entityMap.delete(entity.options.id)
}
//关闭资源的编辑框,删除相关的事件
// eventBus.emit("destroyComponent", item);
let arr = window['tsObj']._Store.getTaskByProperty(item, "sourceId", "id")
eventIds = eventIds.concat(arr)
});
eventBus.emit("del-event-by-source", eventIds)
}
})
}).catch(() => {
// 用户点击取消,不执行任何操作
})
/*let formData = new FormData()
formData.append("id", "")
TsApi.deleteTsModelSource(formData).then(res => {
})*/
} }
const editNode = () => { const editNode = () => {
console.log("编辑节点") console.log("编辑节点")

View File

@ -5,20 +5,20 @@
<div class="control"> <div class="control">
<span>{{ formatTime(currentStamp) }}</span> <span>{{ formatTime(currentStamp) }}</span>
<el-icon :size="20" @click="play"> <el-icon :size="20" @click="play">
<ZoomOut /> <ZoomOut/>
</el-icon> </el-icon>
<el-icon :size="20" @click="stop"> <el-icon :size="20" @click="stop">
<ZoomIn /> <ZoomIn/>
</el-icon> </el-icon>
<span class="title">{{ TSOBJ.name }}</span> <span class="title">{{ TSOBJ.name }}</span>
<span class="zoom"> <span class="zoom">
<el-icon :size="20" @click="add(-1)"> <el-icon :size="20" @click="add(-1)">
<ZoomOut /> <ZoomOut/>
</el-icon> </el-icon>
<el-slider :disabled="true" :max="maxLevel" :min="minLevel" v-model="level" :show-tooltip="false" <el-slider :disabled="true" :max="maxLevel" :min="minLevel" v-model="level" :show-tooltip="false"
style="width:80%;padding-right: 8px;" /> style="width:80%;padding-right: 8px;"/>
<el-icon :size="20" @click="add(1)"> <el-icon :size="20" @click="add(1)">
<ZoomIn /> <ZoomIn/>
</el-icon> </el-icon>
</span> </span>
</div> </div>
@ -36,7 +36,8 @@
</div> </div>
<!-- 时间轴刻度线 --> <!-- 时间轴刻度线 -->
<timeScale :ticTiny="ticTiny" :ticMain="ticMain" :distanceOfTicTiny="distanceOfTicTiny" <timeScale :ticTiny="ticTiny" :ticMain="ticMain" :distanceOfTicTiny="distanceOfTicTiny"
:distanceOfTicMain="distanceOfTicMain" :originOffset="originOffset" :originMainOffset="originMainOffset"> :distanceOfTicMain="distanceOfTicMain" :originOffset="originOffset"
:originMainOffset="originMainOffset">
</timeScale> </timeScale>
<!-- 事件色块 --> <!-- 事件色块 -->
<chart :eventList="TSOBJ._Store._tasks" :hr="hr" :originHrOffset="originHrOffset" :scrollLeft="scrollLeft"> <chart :eventList="TSOBJ._Store._tasks" :hr="hr" :originHrOffset="originHrOffset" :scrollLeft="scrollLeft">
@ -51,13 +52,13 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ZoomIn, ZoomOut } from '@element-plus/icons-vue' import {ZoomIn, ZoomOut} from '@element-plus/icons-vue'
import EventParams from "./components/eventParams.vue" import EventParams from "./components/eventParams.vue"
import Grid from "./components/grid.vue" import Grid from "./components/grid.vue"
import TimeScale from "./components/timeScale.vue" import TimeScale from "./components/timeScale.vue"
import Chart from "./components/chart.vue" import Chart from "./components/chart.vue"
import { ref, onBeforeUnmount } from "vue" import {ref, onBeforeUnmount} from "vue"
let currentStamp = ref(window['tsObj']._Store._startTimestamp) let currentStamp = ref(window['tsObj']._Store._startTimestamp)
let maxLevel = ref(24) let maxLevel = ref(24)
@ -120,6 +121,8 @@ function todoEvent(timeId: number, res: any, isEnd: boolean) {
let tsEntity = window['earth_ts'].entityMap.get(res.sourceId); let tsEntity = window['earth_ts'].entityMap.get(res.sourceId);
tsEntity.flicker(Number(res.detail.times) * 1000, Number(res.detail.numbers)) tsEntity.flicker(Number(res.detail.times) * 1000, Number(res.detail.numbers))
break; break;
case 'move':
break
} }
} }
@ -130,7 +133,7 @@ let eventCallback = () => {
let timeId = Math.round(props.TSOBJ._Store._currentTimestamp / 1000); let timeId = Math.round(props.TSOBJ._Store._currentTimestamp / 1000);
timeId *= 1000; timeId *= 1000;
// console.log(timeId) // console.log(timeId)
let taskIds:any = []; let taskIds: any = [];
let dataMap = props.TSOBJ._Store.dealData("startTime"); let dataMap = props.TSOBJ._Store.dealData("startTime");
console.log(dataMap) console.log(dataMap)

View File

@ -66,9 +66,9 @@ let getEventList = () => {
}) })
newTS(params, events) newTS(params, events)
} }
eventBus.on('delete-event', (id) => { eventBus.on('delete-event', (ids) => {
console.log(id) console.log(ids)
tsOBJ.value._Store._tasks = tsOBJ.value._Store._tasks.filter(item => item.id != id) tsOBJ.value._Store._tasks = tsOBJ.value._Store._tasks.filter(item => !ids.includes(item.id))
}) })
// 新建态势推演对象 // 新建态势推演对象
let newTS = (params, events) => { let newTS = (params, events) => {

View File

@ -13,6 +13,8 @@ export function initMapData(type, data, cb: any = null) {
entityObject = new YJ.Obj.BillboardObject(window['earth_ts'], data) entityObject = new YJ.Obj.BillboardObject(window['earth_ts'], data)
break break
case 'model': case 'model':
data.url = baseURL + data.modelDataUrl
entityObject = new YJ.Obj.Model(window['earth_ts'], data) entityObject = new YJ.Obj.Model(window['earth_ts'], data)
break break
case 'line': case 'line':
@ -38,6 +40,14 @@ export function initMapData(type, data, cb: any = null) {
}) })
break break
case "guiji":
entityObject = new YJ.Obj.TrajectoryMotionObject(
window['earth_ts'],
data
);
if (cb)
cb(entityObject)
break
} }
if (entityObject) { if (entityObject) {
function getOptions() { function getOptions() {
@ -48,7 +58,14 @@ export function initMapData(type, data, cb: any = null) {
options = getOptions() options = getOptions()
if (entityObject.options.id) { if (entityObject.options.id) {
(window as any)._entityMap.set(entityObject.options.id, entityObject) if (type !== 'guiji')
(window as any)._entityMap.set(entityObject.options.id, entityObject)
/*else (window as any)._entityMap.set(res.ID + res.callback + res.source_id, entityObject)
let tsEntitys = ts_Map.get(Number(res.source_id));
TrajectoryMotionObject.moveCallBack(tsEntitys);*/
} }
return options return options

View File

@ -1,94 +1,177 @@
<template> <template>
<div class="newEvent"> <div class="newEvent" v-if="isShowPup">
<el-dialog v-model="isShowPup" :modal="true" draggable :close-on-click-modal="false"> <!-- <el-dialog v-model="isShowPup" :modal="true" draggable :close-on-click-modal="false">
<template #header> <template #header>
<div class="set_pup_header"> <div class="set_pup_header">
<div class="system_title"> <div class="system_title">
<!--{{ t('model.title') }}--> 态势事件
态势事件 </div>
</div> </div>
</div>
</template>
<div class="set_detail">
<div class="sort">
<el-tree
ref="treeRef"
style="max-width: 600px"
:data="eventTree"
:props="defaultProps"
node-key="id"
:check-on-click-node="true"
@node-click="handleNodeClick"
:default-expanded-keys="['normal']"
:current-node-key="currentKey"
:class="{'custom-tree': true}"
/>
</div>
<div class="eventDetail">
<template v-if="currentKey&&currentKey!='normal'">
<el-form label-width="auto" :model="form" style="max-width: 600px">
<el-form-item label="事件名称">
<el-input v-model="form.name"/>
</el-form-item>
<el-form-item label="开始时间">
<el-date-picker
v-model="form.datetime"
type="datetime"
placeholder="选择触发时间"
/>
</el-form-item>
<el-form-item label="持续时间">
<div class="duration">
<span>
<el-input v-model="hour"/>
</span>
<span>
<el-input v-model="minute"/>
</span><span>
<el-input v-model="second"/>
</span>
</div>
</el-form-item>
<template v-if="currentKey=='flicker'">
<el-form-item label="闪烁间隔">
<div class="duration">
<span>
<el-input v-model="times"/>
</span>
</div>
</el-form-item>
<el-form-item label="闪烁次数">
<div class="duration">
<span>
<el-input v-model="numbers"/>
</span>
</div>
</el-form-item>
</template>
<template v-if="currentKey=='move'">
<el-form-item label="路径是否包含元素点位" label-width="160">
<el-switch v-model="isContainModelPosition"/>
</el-form-item>
<el-button>绘制路径</el-button>
</template>
<el-form-item>
<div class="optionbtn">
<el-button @click="addEvent">确定</el-button>
<el-button>取消</el-button>
</div>
</el-form-item>
</el-form>
</template> </template>
<div class="set_detail">
<div class="sort">
<el-tree
ref="treeRef"
style="max-width: 600px"
:data="eventTree"
:props="defaultProps"
node-key="id"
:check-on-click-node="true"
@node-click="handleNodeClick"
:default-expanded-keys="['normal']"
:current-node-key="currentKey"
:class="{'custom-tree': true}"
/>
</div>
<div class="eventDetail">
<template v-if="currentKey&&currentKey!='normal'">
<el-form label-width="auto" :model="form" style="max-width: 600px">
<el-form-item label="事件名称">
<el-input v-model="form.name"/>
</el-form-item>
<el-form-item label="开始时间">
<el-date-picker
v-model="form.datetime"
type="datetime"
placeholder="选择触发时间"
/>
</el-form-item>
<el-form-item label="持续时间">
<div class="duration">
<span>
<el-input v-model="hour"/>
</span>
<span>
<el-input v-model="minute"/>
</span><span>
<el-input v-model="second"/>
</span>
</div>
<div class="placeholder"></div> </div>
</el-form-item>
<template v-if="currentKey=='flicker'">
<el-form-item label="闪烁间隔">
<div class="duration">
<span>
<el-input v-model="times"/>
</span>
</div>
</el-form-item>
<el-form-item label="闪烁次数">
<div class="duration">
<span>
<el-input v-model="numbers"/>
</span>
</div>
</el-form-item>
</template>
<template v-if="currentKey=='move'">
<el-form-item label="路径是否包含元素点位" label-width="160">
<el-switch v-model="isContainModelPosition"/>
</el-form-item>
<el-button @click="drawLine">绘制路径</el-button>
</template>
<el-form-item>
<div class="optionbtn">
<el-button @click="addEvent">确定</el-button>
<el-button>取消</el-button>
</div>
</el-form-item>
</el-form>
</template>
</div>
<div class="placeholder"></div>
</div>
</el-dialog>-->
<div class="set_pup_header">
<div class="system_title">
态势事件
</div> </div>
</el-dialog> </div>
<div class="set_detail">
<div class="sort">
<el-tree
ref="treeRef"
style="max-width: 600px"
:data="eventTree"
:props="defaultProps"
node-key="id"
:check-on-click-node="true"
@node-click="handleNodeClick"
:default-expanded-keys="['normal']"
:current-node-key="currentKey"
:class="{'custom-tree': true}"
/>
</div>
<div class="eventDetail">
<template v-if="currentKey&&currentKey!='normal'">
<el-form label-width="auto" :model="form" style="max-width: 600px">
<el-form-item label="事件名称">
<el-input v-model="form.name"/>
</el-form-item>
<el-form-item label="开始时间">
<el-date-picker
v-model="form.datetime"
type="datetime"
placeholder="选择触发时间"
/>
</el-form-item>
<el-form-item label="持续时间">
<div class="duration">
<span>
<el-input v-model="hour"/>
</span>
<span>
<el-input v-model="minute"/>
</span><span>
<el-input v-model="second"/>
</span>
</div>
</el-form-item>
<template v-if="currentKey=='flicker'">
<el-form-item label="闪烁间隔">
<div class="duration">
<span>
<el-input v-model="times"/>
</span>
</div>
</el-form-item>
<el-form-item label="闪烁次数">
<div class="duration">
<span>
<el-input v-model="numbers"/>
</span>
</div>
</el-form-item>
</template>
<template v-if="currentKey=='move'">
<el-form-item label="路径是否包含元素点位" label-width="160">
<el-switch v-model="isContainModelPosition"/>
</el-form-item>
<el-button @click="drawLine">绘制路径</el-button>
</template>
<el-form-item>
<div class="optionbtn">
<el-button @click="addEvent">确定</el-button>
<el-button @click="isShowPup=false">取消</el-button>
</div>
</el-form-item>
</el-form>
</template>
</div>
<div class="placeholder"></div>
</div>
</div> </div>
</template> </template>
@ -98,6 +181,7 @@ import {ref, reactive} from "vue";
import type {RenderContentContext, TreeInstance} from 'element-plus' import type {RenderContentContext, TreeInstance} from 'element-plus'
import {TsApi} from "../../api/ts"; import {TsApi} from "../../api/ts";
import {ElMessage} from "element-plus"; import {ElMessage} from "element-plus";
import {initMapData} from "./entity";
const treeRef = ref<TreeInstance>() const treeRef = ref<TreeInstance>()
// 存储当前需要高亮的节点 key初始为空 // 存储当前需要高亮的节点 key初始为空
@ -108,6 +192,7 @@ interface Tree {
children?: Tree[] children?: Tree[]
} }
const eventBus: any = inject('bus')
let form = reactive({ let form = reactive({
name: '闪烁-', name: '闪烁-',
// datetime: '', // datetime: '',
@ -118,8 +203,10 @@ const minute = ref(0)
const second = ref(0) const second = ref(0)
const times = ref(0)//闪烁间隔 const times = ref(0)//闪烁间隔
const numbers = ref(0)//闪烁次数 const numbers = ref(0)//闪烁次数
const isContainModelPosition = ref(true) const isContainModelPosition = ref(true)
const eventBus: any = inject('bus') const positions = ref([])//机动事件的轨迹点
form['datetime'] = new Date(window['tsObj']._Store._currentTimestamp) form['datetime'] = new Date(window['tsObj']._Store._currentTimestamp)
const isShowPup = ref(false) const isShowPup = ref(false)
@ -150,7 +237,14 @@ const handleNodeClick = (data: Tree, node, TreeNode, event) => {
currentKey.value = data.id; // data.id 为节点的唯一 key需与 tree 的 node-key 对应) currentKey.value = data.id; // data.id 为节点的唯一 key需与 tree 的 node-key 对应)
form.name = data.name + '-' + zNode.value.sourceName form.name = data.name + '-' + zNode.value.sourceName
} }
const drawLine = () => {
let draw = new YJ.Draw.DrawPolyline(window['earth_ts'])
draw.start((error, p) => {
positions.value = p
})
}
const addEvent = () => { const addEvent = () => {
console.log(zNode.value)
let startTime = form.datetime.getTime() let startTime = form.datetime.getTime()
let obj = {} let obj = {}
switch (currentKey.value) { switch (currentKey.value) {
@ -160,7 +254,33 @@ const addEvent = () => {
numbers: numbers.value numbers: numbers.value
} }
break break
case 'move':
let detail = typeof zNode.value.detail == 'string' ? JSON.parse(zNode.value.detail) : JSON.parse(JSON.stringify(zNode.value.detail))
let position = [...positions.value]
if (isContainModelPosition.value) {
position.unshift(detail.positions || detail.position)
}
positions.value = position;
obj = {
ground: false,
show: true,
// speed: 0,
loop: false,
line: {
smooth: false,
show: false,
positions: positions.value,
},
isContainModelPosition: isContainModelPosition.value
}
break
} }
// 当事件为机动事件且轨迹点的长度为0时终止
if (obj['positions'] && obj['positions'].length == 0) {
ElMessage({message: "机动事件的路径不合法", type: "warning"})
return
}
let duration_S = hour.value * 3600 + minute.value * 60 + second.value
let dbParams = { let dbParams = {
id: new YJ.Tools().randomString(), id: new YJ.Tools().randomString(),
planId: window.planId, planId: window.planId,
@ -168,9 +288,11 @@ const addEvent = () => {
name: form.name, name: form.name,
callback: currentKey.value, callback: currentKey.value,
startTime, startTime,
endTime: startTime + (hour.value * 3600 + minute.value * 60 + second.value) * 1000, endTime: startTime + duration_S * 1000,
"detail": JSON.stringify(obj) "detail": JSON.stringify(obj)
} }
console.log(obj)
TsApi.addTsEvent(dbParams).then(res => { TsApi.addTsEvent(dbParams).then(res => {
if (res.code == 200) { if (res.code == 200) {
ElMessage({ ElMessage({
@ -179,6 +301,19 @@ const addEvent = () => {
}) })
} }
if (currentKey.value == 'move') {
let params = JSON.parse(JSON.stringify(obj))
let distance = new YJ.Tools().computeDistance2(params.line.positions);
let speeds = (distance / duration_S) * window['tsObj']._Store._multiplier
params.speed = speeds
initMapData("guiji", params, (entityObject) => {
entityObject.state = false
entityObject.oldSpeed = (distance / duration_S) * window['tsObj']._Store._multiplier
(window as any)._entityMap.set(dbParams.id + dbParams.callback + dbParams.sourceId, entityObject)
let tsEntitys = (window as any)._entityMap.get(dbParams.sourceId);
entityObject.moveCallBack(tsEntitys)
})
}
isShowPup.value = false isShowPup.value = false
reset() reset()
@ -195,6 +330,7 @@ const reset = () => {
name: '闪烁-', name: '闪烁-',
// datetime: '', // datetime: '',
} }
form['datetime'] = new Date(window['tsObj']._Store._currentTimestamp)
currentKey.value = "flicker" currentKey.value = "flicker"
} }
@ -218,10 +354,38 @@ eventBus.on('openAddEvent', (data, cb, type) => {
.newEvent { .newEvent {
position: absolute; position: absolute;
z-index: 99; z-index: 99;
//bottom: 200px; top: 40%;
//left: 50%; left: 50%;
//width: 40vw; transform: translate(-50%, -50%);
//height: 50vh; width: 570px;
height: 320px;
border: 1px solid #0ff;
border-radius: 3px;
background: rgba(0, 0, 0, 0.5);
.set_pup_header {
display: flex;
justify-content: center;
align-items: center;
padding-top: 10px;
padding-bottom: 20px;
.system_title {
background: url('@/assets/images/titlebg.png') no-repeat;
background-size: 100% 100%;
width: 229px;
height: 34px;
line-height: 34px;
text-align: center;
font-family: 'alimamashuheiti';
font-size: 18px;
color: #fff;
//margin-bottom: 25px;
//font-weight: 700;
}
}
.set_detail { .set_detail {
display: flex; display: flex;
@ -294,82 +458,9 @@ eventBus.on('openAddEvent', (data, cb, type) => {
} }
} }
:deep(.el-overlay) {
position: absolute;
}
:deep(.el-overlay-dialog) {
/*position: absolute;
right: auto;*/
bottom: auto;
}
:deep(.el-dialog) {
background: linear-gradient(180deg, rgba(0, 255, 255, 0.2) 0%, rgba(0, 255, 255, 0) 100%),
rgba(0, 0, 0, 0.6);
border: 1px solid #00c9ff;
padding: 0 !important;
//position: absolute;
width: 570px;
height: 323px;
}
:deep(.el-dialog__body) {
padding: 0 !important;
height: calc(100% - 50px);
}
:deep(.el-dialog__headerbtn) {
height: 30px;
width: 30px;
border-bottom-left-radius: 80%;
background-color: #008989;
&:hover {
background-color: #00ffff;
.el-dialog__close {
color: rgba(0, 66, 66, 1); // 悬停时改变关闭图标为红色
}
}
}
:deep(.el-dialog__headerbtn .el-dialog__close) {
color: #fff;
}
.set_pup_header {
width: 100%;
height: 100%;
// background-color: #00ffff;
display: flex;
justify-content: center;
align-items: center;
//padding-bottom: 20px;
.system_title {
background: url('@/assets/images/titlebg.png') no-repeat;
background-size: 100% 100%;
width: 229px;
height: 34px;
line-height: 34px;
text-align: center;
font-family: 'alimamashuheiti';
font-size: 18px;
color: #fff;
//font-weight: 700;
}
}
} }
:deep(.el-input__wrapper), :deep(.el-input__inner ) {
background: transparent;
--el-input-placeholder-color: #fff;
color: #fff;
//border: 1px solid #0ff;
}
/* /*
:deep(.el-tree-node__children .is-checked) { :deep(.el-tree-node__children .is-checked) {

View File

@ -36,7 +36,7 @@
<el-form-item> <el-form-item>
<div class="optionbtn"> <div class="optionbtn">
<el-button @click="addPlan(ruleFormRef)">确定</el-button> <el-button @click="addPlan(ruleFormRef)">确定</el-button>
<el-button>取消</el-button> <el-button @click="isShowPup= false">取消</el-button>
</div> </div>
</el-form-item> </el-form-item>
</el-form> </el-form>

View File

@ -30,9 +30,11 @@ export class Store {
_startTimestamp _startTimestamp
_currentTimestamp _currentTimestamp
_tasks _tasks
_multiplier
private _panelWidth //面板宽度 private _panelWidth //面板宽度
constructor(option) { constructor(option) {
this._multiplier = option.multiplier || 1
this._panelWidth = option.panelWidth this._panelWidth = option.panelWidth
this._tasks = option.tasks this._tasks = option.tasks
this._startTimestamp = option.startTimestamp this._startTimestamp = option.startTimestamp
@ -153,4 +155,13 @@ export class Store {
return map return map
} }
// 通过特定的字段名和值来获取事件
getTaskByProperty(value, property = "ID", isReturnPropertyValue = null) {
// console.log("getTaskById", id)
if (isReturnPropertyValue) {
return this._tasks.map(task => task[isReturnPropertyValue])
} else {
return this._tasks.filter(task => (task[property] == value))
}
}
} }

View File

@ -13,8 +13,18 @@
</div> </div>
</div> </div>
</div> --> </div> -->
<el-tooltip v-for="(item, i) of setList" :key="item.id" :content="t('iconTitle.' + item.name)" effect="customized" :hide-after="0"> <el-tooltip
<div class="set_item" :class="{ 'last-item': i === setList.length - 1 }" @click="item.callback"> v-for="(item, i) of setList"
:key="item.id"
:content="t('iconTitle.' + item.name)"
effect="customized"
:hide-after="0"
>
<div
class="set_item"
:class="{ 'last-item': i === setList.length - 1 }"
@click="item.callback"
>
<svg-icon :name="item.icon" :size="20"></svg-icon> <svg-icon :name="item.icon" :size="20"></svg-icon>
</div> </div>
</el-tooltip> </el-tooltip>
@ -48,7 +58,12 @@ const logout = async (e) => {
window.earth = null window.earth = null
} }
if (res.code === 200) { if (res.code === 200) {
router.push({ path: '/login' }) router.push({
path: '/',
query: {
type: 'logout'
}
})
// localStorage.clear() // localStorage.clear()
} }
} }
@ -69,8 +84,8 @@ const setList = ref([
icon: 'beidou', icon: 'beidou',
name: 'locate', name: 'locate',
className: 'header_public', className: 'header_public',
dbcallback: (e) => { }, dbcallback: (e) => {},
callback: (e) => { } callback: (e) => {}
// dbcallback: this.flyTo, // dbcallback: this.flyTo,
// callback: this.locate, // callback: this.locate,
}, },
@ -152,10 +167,12 @@ ipcRenderer.on('fullscreen-status-changed', (event, isFullscreen) => {
top: 0; top: 0;
bottom: 0; bottom: 0;
width: 1px; width: 1px;
background: linear-gradient(180deg, background: linear-gradient(
rgba(var(--color-base1), 0), 180deg,
rgba(var(--color-base1), 1), rgba(var(--color-base1), 0),
rgba(204, 204, 204, 0)); rgba(var(--color-base1), 1),
rgba(204, 204, 204, 0)
);
} }
.set_item.last-item::after { .set_item.last-item::after {

View File

@ -1,20 +1,35 @@
<template> <template>
<div class="login-container" style="position: fixed; width: 100vw; height: 100vh; left: 0; top: 0"> <div
<transition name="video-fade" mode="out-in" class="login-container"
style="position: fixed; width: 100vw; height: 100vh; left: 0; top: 0; object-fit: cover"> style="position: fixed; width: 100vw; height: 100vh; left: 0; top: 0"
>
<transition
name="video-fade"
mode="out-in"
style="position: fixed; width: 100vw; height: 100vh; left: 0; top: 0; object-fit: cover"
>
<!-- 第一个视频播放一次 --> <!-- 第一个视频播放一次 -->
<video v-if="!isFirstVideoPlayed" ref="firstVideoRef" key="first-video" muted @ended="onFirstVideoEnded" <!-- <video v-if="!isFirstVideoPlayed" ref="firstVideoRef" key="first-video" muted @ended="onFirstVideoEnded"
src="../../assets/video/login_front.mp4" src="../../assets/video/login_front.mp4"
style="position: fixed; width: 100vw; height: 100vh; left: 0; top: 0; object-fit: cover"></video> style="position: fixed; width: 100vw; height: 100vh; left: 0; top: 0; object-fit: cover"></video> -->
<!-- 第二个视频循环播放 --> <!-- 第二个视频循环播放 -->
<video v-else key="second-video" autoplay loop muted src="../../assets/video/login_feature.mp4" <!-- <video v-else key="second-video" autoplay loop muted src="../../assets/video/login_feature.mp4"
style="position: fixed; width: 100vw; height: 100vh; left: 0; top: 0; object-fit: cover"></video> style="position: fixed; width: 100vw; height: 100vh; left: 0; top: 0; object-fit: cover"></video> -->
<video
key="second-video"
autoplay
loop
muted
src="../../assets/video/author_video.mp4"
style="position: fixed; width: 100vw; height: 100vh; left: 0; top: 0; object-fit: cover"
></video>
</transition> </transition>
<div class="rightBox" v-if="isDesktop"> <!-- 登录页面 -->
<div class="rightBox" v-if="isDesktop && !isAuth">
<el-button size="small" :icon="Setting" @click="serviceDialog = true"> </el-button> <el-button size="small" :icon="Setting" @click="serviceDialog = true"> </el-button>
<el-button size="small" :icon="SwitchButton" @click="goExit"> </el-button> <el-button size="small" :icon="SwitchButton" @click="goExit"> </el-button>
</div> </div>
<transition name="fade"> <transition name="fade" v-if="!isAuth">
<div v-show="true" class="content"> <div v-show="true" class="content">
<div class="titleBox"> <div class="titleBox">
<div class="titleItem"> <div class="titleItem">
@ -24,45 +39,95 @@
</div> </div>
</div> </div>
</div> </div>
<el-form class="login-form" autoComplete="on" :model="loginForm" :rules="loginRules" ref="loginFormRef" <el-form
label-position="left"> class="login-form"
autoComplete="on"
:model="loginForm"
:rules="loginRules"
ref="loginFormRef"
label-position="left"
>
<el-form-item prop="username"> <el-form-item prop="username">
<el-input name="username" type="text" v-model="loginForm.username" autoComplete="on" placeholder="请输入用户名" <el-input
:prefix-icon="User" /> name="username"
type="text"
v-model="loginForm.username"
autoComplete="on"
placeholder="请输入用户名"
:prefix-icon="User"
/>
</el-form-item> </el-form-item>
<el-form-item prop="password"> <el-form-item prop="password">
<el-input type="password" @keyup.enter.native="handleLogin(loginFormRef)" v-model="loginForm.password" <el-input
autoComplete="on" placeholder="请输入密码" :prefix-icon="Unlock" show-password></el-input> type="password"
@keyup.enter.native="handleLogin(loginFormRef)"
v-model="loginForm.password"
autoComplete="on"
placeholder="请输入密码"
:prefix-icon="Unlock"
show-password
></el-input>
</el-form-item> </el-form-item>
<el-form-item class="rememberForget"> <el-form-item class="rememberForget">
<!-- justify-content: space-around;align-items: center; --> <!-- justify-content: space-around;align-items: center; -->
<div style="display: flex"> <div style="display: flex">
<svg class="checkbox-svg" v-show="checkboxVModel" style="pointer-events: none;" <svg
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14" height="14" class="checkbox-svg"
viewBox="0 0 14 14" fill="none"> v-show="checkboxVModel"
<path fill="rgba(var(--color-base1), 1)" style="pointer-events: none"
d="M7.34788e-16 2L-2.20436e-15 12C-2.40727e-15 13.1046 0.895431 14 2 14L12 14C13.1046 14 14 13.1046 14 12L14 2C14 0.895431 13.1046 -1.46958e-15 12 -1.46958e-15L2 -1.46958e-15C0.895431 -1.60485e-15 8.02424e-16 0.895431 7.34788e-16 2Z"> xmlns="http://www.w3.org/2000/svg"
</path> xmlns:xlink="http://www.w3.org/1999/xlink"
width="14"
height="14"
viewBox="0 0 14 14"
fill="none"
>
<path
fill="rgba(var(--color-base1), 1)"
d="M7.34788e-16 2L-2.20436e-15 12C-2.40727e-15 13.1046 0.895431 14 2 14L12 14C13.1046 14 14 13.1046 14 12L14 2C14 0.895431 13.1046 -1.46958e-15 12 -1.46958e-15L2 -1.46958e-15C0.895431 -1.60485e-15 8.02424e-16 0.895431 7.34788e-16 2Z"
></path>
<path <path
d="M5.47283 8.3039L3.10764 6.12807C3.06194 6.08647 2.99525 6.08647 2.94955 6.12946L2.04424 6.98093C1.98989 7.03224 1.98495 7.12376 2.03312 7.18201L6.03602 11.9566C6.09778 12.0301 6.20647 12.0065 6.24105 11.9136C7.03644 9.69343 9.25835 5.63439 11.9619 2.69585C11.999 2.65564 12.0101 2.59601 11.9904 2.54331L11.8211 2.08568C11.7915 2.00525 11.7038 1.97474 11.6396 2.02328C8.63587 4.21019 6.45966 6.92546 5.47283 8.3039Z" d="M5.47283 8.3039L3.10764 6.12807C3.06194 6.08647 2.99525 6.08647 2.94955 6.12946L2.04424 6.98093C1.98989 7.03224 1.98495 7.12376 2.03312 7.18201L6.03602 11.9566C6.09778 12.0301 6.20647 12.0065 6.24105 11.9136C7.03644 9.69343 9.25835 5.63439 11.9619 2.69585C11.999 2.65564 12.0101 2.59601 11.9904 2.54331L11.8211 2.08568C11.7915 2.00525 11.7038 1.97474 11.6396 2.02328C8.63587 4.21019 6.45966 6.92546 5.47283 8.3039Z"
fill="#004242"></path> fill="#004242"
></path>
</svg> </svg>
<svg class="checkbox-svg" v-show="!checkboxVModel" style="pointer-events: none;" <svg
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14" height="14" class="checkbox-svg"
viewBox="0 0 14 14" fill="none"> v-show="!checkboxVModel"
<path fill-rule="evenodd" fill="url(#linear_border_2442_533_0)" style="pointer-events: none"
d="M0 12L0 2C0 0.895431 0.895431 0 2 0L12 0C13.1046 0 14 0.895431 14 2L14 12C14 13.1046 13.1046 14 12 14L2 14C0.895431 14 0 13.1046 0 12ZM2 12.5C1.72386 12.5 1.5 12.2761 1.5 12L1.5 2C1.5 1.72386 1.72386 1.5 2 1.5L12 1.5C12.2761 1.5 12.5 1.72386 12.5 2L12.5 12C12.5 12.2761 12.2761 12.5 12 12.5L2 12.5Z"> xmlns="http://www.w3.org/2000/svg"
</path> xmlns:xlink="http://www.w3.org/1999/xlink"
width="14"
height="14"
viewBox="0 0 14 14"
fill="none"
>
<path
fill-rule="evenodd"
fill="url(#linear_border_2442_533_0)"
d="M0 12L0 2C0 0.895431 0.895431 0 2 0L12 0C13.1046 0 14 0.895431 14 2L14 12C14 13.1046 13.1046 14 12 14L2 14C0.895431 14 0 13.1046 0 12ZM2 12.5C1.72386 12.5 1.5 12.2761 1.5 12L1.5 2C1.5 1.72386 1.72386 1.5 2 1.5L12 1.5C12.2761 1.5 12.5 1.72386 12.5 2L12.5 12C12.5 12.2761 12.2761 12.5 12 12.5L2 12.5Z"
></path>
<defs> <defs>
<linearGradient id="linear_border_2442_533_0" x1="0" y1="-0.5574798583984375" x2="12.1173095703125" <linearGradient
y2="12.878036499023438" gradientUnits="userSpaceOnUse"> id="linear_border_2442_533_0"
x1="0"
y1="-0.5574798583984375"
x2="12.1173095703125"
y2="12.878036499023438"
gradientUnits="userSpaceOnUse"
>
<stop offset="0.0625" stop-color="rgba(var(--color-base1), 1)" /> <stop offset="0.0625" stop-color="rgba(var(--color-base1), 1)" />
<stop offset="1" stop-color="var(--color-border1)" /> <stop offset="1" stop-color="var(--color-border1)" />
</linearGradient> </linearGradient>
</defs> </defs>
</svg> </svg>
<el-checkbox :disabled="loading" v-model="checkboxVModel" @change="rememberpwd" <el-checkbox
label="string">记住密码</el-checkbox> :disabled="loading"
v-model="checkboxVModel"
@change="rememberpwd"
label="string"
>记住密码</el-checkbox
>
<!-- <div style="cursor: pointer;">忘记密码</div> --> <!-- <div style="cursor: pointer;">忘记密码</div> -->
</div> </div>
</el-form-item> </el-form-item>
@ -85,15 +150,24 @@
<h2 class="greet"><span>欢迎您使用</span>实景三维电子沙盘系统</h2> <h2 class="greet"><span>欢迎您使用</span>实景三维电子沙盘系统</h2>
<div class="serviceContent"> <div class="serviceContent">
<el-tabs v-model="selectedService" class="demo-tabs" @tab-click="handleSelect"> <el-tabs v-model="selectedService" class="demo-tabs" @tab-click="handleSelect">
<el-tab-pane v-for="item in serviceOptions" :label="item.name" :name="item.name"></el-tab-pane> <el-tab-pane
v-for="item in serviceOptions"
:label="item.name"
:name="item.name"
></el-tab-pane>
</el-tabs> </el-tabs>
<div class="tabPanel"> <div class="tabPanel">
<template v-if="selectedService == '接口服务'"> <template v-if="selectedService == '接口服务'">
<div class="item"> <div class="item">
<span class="itemLabel">服务选择</span> <span class="itemLabel">服务选择</span>
<el-select class="select" popper-class="login-select-popper" v-model="servVal"> <el-select class="select" popper-class="login-select-popper" v-model="servVal">
<el-option size="mini" v-for="item in servOptions" :key="item.value" :label="item.name" <el-option
:value="item.name"> size="mini"
v-for="item in servOptions"
:key="item.value"
:label="item.name"
:value="item.name"
>
</el-option> </el-option>
</el-select> </el-select>
</div> </div>
@ -125,8 +199,13 @@
<div class="item"> <div class="item">
<span class="itemLabel">串口选择</span> <span class="itemLabel">串口选择</span>
<el-select class="select" popper-class="login-select-popper" v-model="gpsVal"> <el-select class="select" popper-class="login-select-popper" v-model="gpsVal">
<el-option size="mini" v-for="item in gpsOptions" :key="item.value" :label="item.Product" <el-option
:value="item.Name"> size="mini"
v-for="item in gpsOptions"
:key="item.value"
:label="item.Product"
:value="item.Name"
>
</el-option> </el-option>
</el-select> </el-select>
</div> </div>
@ -140,6 +219,77 @@
</div> </div>
</div> </div>
</div> </div>
<!-- 授权页面 -->
<Dialog
ref="baseDialog"
class="graffiti"
title="系统授权"
:closeCallback="closeCallBack"
left="calc(50vw - 188px)"
top="calc(50vh - 191px)"
>
<template #content>
<div class="auth_info custom_scroll_bar content_h">
<div class="auth_info_box">
<div>
<span class="fankuai"></span>
{{ t('auths.authCode') }}
</div>
<div
class="auth_info_text"
@click="copy(authInfo.license_code)"
style="cursor: pointer"
title="点击可复制"
>
{{ authInfo.license_code || '' }}
<svg-icon name="copy" :size="20" style="margin-left: 30px"></svg-icon>
</div>
</div>
<div class="auth_info_box">
<div>
<span class="fankuai"></span>
{{ t('auths.authTime') }}
</div>
<div class="auth_info_text" v-if="authInfo.status != null">
<template v-if="authInfo.generateTime != ''">
{{ authInfo.generateTime || '2023-01-01' }}-
</template>
{{ authInfo.expireTime || '2023-01-01' }}
</div>
<div v-else class="auth_info_text">暂无</div>
</div>
<div class="auth_info_box">
<div>
<span class="fankuai"></span>
{{ t('auths.authType') }}
</div>
<div
v-if="authInfo.status != null"
class="auth_info_text"
style="font-size: 16px"
:style="{
color: authInfo.status ? 'rgba(27, 248, 195, 1)' : 'rgba(255, 161, 69, 1)'
}"
>
{{ authInfo.status ? t('auths.authTempExpire') : t('auths.authexpire') }}
</div>
<!-- <div v-else class="auth_info_text">{{ authInfo.message || '无' }}</div> -->
<div
v-else
class="auth_info_text"
style="font-size: 16px; color: rgba(241, 108, 85, 1)"
>
{{ t('auths.noAuthexpire') }}
</div>
</div>
<!-- <uploadFiles accept=".lic" :maxSize="1"></uploadFiles> -->
</div>
</template>
<template #footer>
<uploadFiles accept=".lic" :maxSize="1"></uploadFiles>
<button @click="close">退出系统</button>
</template>
</Dialog>
</div> </div>
</template> </template>
@ -191,6 +341,164 @@ onMounted(() => {
loginInit() loginInit()
initialize() initialize()
}) })
//授权判断
import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router'
import useClipboard from 'vue-clipboard3'
import { AuthApi } from '@/api/setting/auth'
import Dialog from '@/components/dialog/baseDialog.vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { $sendElectronChanel } from '@/utils/communication'
let isAuth = ref(true)
const { ipcRenderer } = require('electron')
const router = useRouter()
const getAuthInfo = async () => {
try {
const res = await AuthApi.showAuth()
if (typeof res.data === 'object') {
authInfo.value.generateTime = res.data.generateTime
authInfo.value.expireTime = res.data.expireTime
getStatus2()
getStatus(res.data.expireTime)
}
} catch (error) {
// 统一处理错误
ElMessageBox.confirm('您没有进行系统授权哦,系统功能将无法使用?', '提示', {
confirmButtonText: '去授权',
cancelButtonText: '退出系统',
type: 'warning',
closeOnClickModal: false
})
.then(async () => {
try {
baseDialog.value?.open()
} catch (error) {
console.error('打开授权对话框失败:', error)
}
})
.catch(() => {
// 用户点击取消,不执行任何操作
ipcRenderer.send('quit-app')
})
}
}
const baseDialog = ref(null)
const getStatus = (date) => {
const timestamp = new Date(date).getTime()
const currentTimestamp = Date.now()
if (timestamp > currentTimestamp) {
// router.push({ path: '/login' })
isAuth.value = false
} else {
ElMessageBox.confirm('您没有进行系统授权哦,系统功能将无法使用?', '提示', {
confirmButtonText: '去授权',
cancelButtonText: '退出系统',
type: 'warning',
closeOnClickModal: false
})
.then(async () => {
try {
baseDialog.value?.open()
} catch (error) {
console.error('打开授权对话框失败:', error)
}
})
.catch(() => {
// 用户点击取消,不执行任何操作
ipcRenderer.send('quit-app')
})
}
}
//授权页面
// const closeCallBack = (e) => {
// baseDialog.value?.close()
// }
const close = (e) => {
ElMessageBox.confirm('确定要退出系统吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(async () => {
ipcRenderer.send('quit-app')
})
.catch(() => {
// 用户点击取消,不执行任何操作
})
}
const eventBus = inject('bus')
const { t } = useI18n()
const authInfo = ref({
license_code: '',
//授权信息
generateTime: '', //开始时间
expireTime: '', //结束时间
authDays: null, //授权时间
status: null
})
//上传授权文件成功
eventBus.on('upload', (data) => {
if (data) {
isAuth.value = false
baseDialog.value?.close()
}
})
const { toClipboard } = useClipboard()
const getAuthInfo2 = async () => {
const res = await AuthApi.showAuth()
if (typeof res.data === 'object') {
authInfo.value.generateTime = res.data.generateTime
authInfo.value.expireTime = res.data.expireTime
getStatus2()
}
}
const getStatus2 = () => {
const timestamp = new Date(authInfo.value.expireTime).getTime()
const currentTimestamp = Date.now()
if (timestamp > currentTimestamp) {
authInfo.value.status = true
} else {
authInfo.value.status = false
}
window.checkAuthIsValid = authInfo.value.status
}
const getAuthCode = async () => {
const res = await AuthApi.authInfo()
authInfo.value.license_code = res.data
}
setTimeout(() => {
getAuthCode()
}, 5000)
//复制
const copy = async (text) => {
try {
await toClipboard(text)
ElMessage.success('复制成功')
} catch (e) {
ElMessage.error('复制失败')
}
}
if (!router.currentRoute.value.query.type) {
setTimeout(() => {
getAuthCode()
getAuthInfo()
}, 5000)
} else {
isAuth.value = false
}
</script> </script>
<style lang="scss"> <style lang="scss">
// 添加过渡样式 // 添加过渡样式
@ -286,7 +594,6 @@ onMounted(() => {
.el-select__tags-text { .el-select__tags-text {
color: rgba(0, 66, 66, 1) !important; color: rgba(0, 66, 66, 1) !important;
} }
} }
</style> </style>
<style scoped lang="scss"> <style scoped lang="scss">
@ -390,7 +697,6 @@ onMounted(() => {
color: #fff; color: #fff;
} }
} }
} }
} }
} }
@ -472,7 +778,7 @@ onMounted(() => {
border-radius: 0 0 0 90%; border-radius: 0 0 0 90%;
background: rgba(var(--color-base1), 1); background: rgba(var(--color-base1), 1);
&>span { & > span {
font-size: 1rem; font-size: 1rem;
position: absolute; position: absolute;
right: 0px; right: 0px;
@ -569,7 +875,8 @@ onMounted(() => {
align-items: center; align-items: center;
margin: 15px 0; margin: 15px 0;
.select {} .select {
}
} }
} }
} }
@ -606,4 +913,387 @@ onMounted(() => {
} }
} }
} }
//授权
.auth_info {
width: 100%;
display: flex;
flex-direction: column;
height: 100%;
overflow-y: auto;
color: rgba(var(--color-text2), 0.8);
.auth_info_text {
color: #fff;
font-size: 14px;
font-weight: 700;
margin: 7px 0 15px 15px;
display: flex;
align-items: center;
}
.auth_info_box {
margin-bottom: 15px;
border-bottom: 1px solid rgba(204, 204, 204, 0.2);
}
.el-button--primary {
color: #fff !important;
font-size: 16px;
background: rgba(var(--color-base1), 0.2) !important;
font-weight: bolder;
border-color: transparent;
border-radius: 4px;
}
}
.fankuai {
width: 10px;
height: 10px;
// 旋转角度
transform: rotate(45deg);
border: 2px solid rgba(var(--color-base1), 1);
display: inline-block;
margin-right: 5px;
margin-left: 5px;
}
.YJ-custom-base-dialog {
position: absolute;
color: #ffffff;
font-size: 14px;
z-index: 99;
background: linear-gradient(0deg, #00ffff33 0%, #00ffff00 100%), rgba(0, 0, 0, 0.6);
border: 1.5px solid;
border-image: linear-gradient(to bottom, rgba(var(--color-base1), 1) 6.25%, rgb(0, 200, 255) 100%)
1;
text-align: left;
font-family: 'sy-boldface';
}
.YJ-custom-base-dialog * {
box-sizing: border-box;
}
.YJ-custom-base-dialog:after {
display: block;
position: absolute;
content: '';
left: -1.5px;
top: -6px;
width: 70.5px;
height: 6px;
opacity: 1;
background: rgba(var(--color-base1), 1);
clip-path: polygon(0 0, calc(100% - 3px) 0, 100% 6px, 0 6px);
}
.YJ-custom-base-dialog svg {
fill: #ffffff;
width: 12px;
height: 12px;
margin-right: 5px;
}
.YJ-custom-base-dialog .custom-divider {
width: 100%;
display: block;
border-top: 1px solid rgba(204, 204, 204, 0.2);
}
.YJ-custom-base-dialog .text-number {
font-family: 'D-Din-Bold';
margin-left: 5px;
}
::v-deep .title-box {
line-height: 46px;
padding: 5px 16px 5px 16px !important;
position: relative;
}
::v-deep .title-box > .close-box {
display: none;
}
::v-deep .title-box > .title {
font-family: 'Ali-mother-counts-bold';
font-size: 18px;
font-weight: 400;
letter-spacing: 0px;
line-height: 0px;
color: rgba(255, 255, 255, 1);
text-align: left;
text-shadow: 0px 0px 9px rgba(20, 118, 255, 1);
-webkit-pointer-events: none;
-moz-pointer-events: none;
-ms-pointer-events: none;
-o-pointer-events: none;
pointer-events: none;
}
::v-deep .foot {
position: relative;
padding: 20px 24px;
display: flex;
justify-content: center;
}
::v-deep .foot > button {
margin-left: 10px;
border-radius: 4px;
background: rgba(var(--color-base1), 0.2);
border: 1px solid rgba(var(--color-base1), 0.5);
font-size: 14px;
font-weight: 400;
color: rgba(255, 255, 255, 1);
padding: 5px 20px;
cursor: pointer;
}
::v-deep .foot > button:hover {
border: 1px solid rgba(var(--color-base1), 1);
color: rgba(var(--color-base1), 1);
}
::v-deep .foot > .show > .label {
margin: 0px 10px;
}
::v-deep .el-message-box {
--el-messagebox-title-color: #fff !important;
--el-messagebox-content-color: #fff !important;
background:
linear-gradient(180deg, rgba(var(--color-base1), 0) 0%, rgba(var(--color-base1), 0.2) 100%),
rgba(0, 0, 0, 0.6) !important;
}
#app {
.service {
z-index: 9999;
width: 100vw;
height: 100vh;
position: absolute;
.contentBox {
padding: 0 40px 40px 40px;
background-color: #ffffff;
backdrop-filter: blur(2px);
width: 450px;
position: absolute;
color: rgba(51, 51, 51, 1);
left: 50%;
top: 29%;
transform: translate(-50%, 0%);
display: flex;
flex-direction: column;
justify-content: space-between;
.hello {
color: rgba(0, 66, 66, 1);
font-family: 'ddin';
font-size: 30px;
font-weight: 700;
line-height: 30px;
margin-bottom: 16px;
}
.greet {
color: rgba(0, 66, 66, 1);
font-family: 'SourceHanSans';
font-size: 18px;
line-height: 18px;
font-weight: 500;
span {
color: rgba(153, 153, 153, 1);
font-weight: 500;
margin-right: 5px;
}
}
.titleBox {
height: 40px;
.title {
line-height: 50px;
padding-left: 15px;
font-size: 1rem;
text-shadow: 0px 0px 9px rgba(20, 118, 255, 1);
}
.closeBox {
right: 0;
position: absolute;
display: inline-block;
width: 30px;
height: 30px;
border-radius: 0 0 0 90%;
background: rgba(var(--color-base1), 1);
& > span {
font-size: 1rem;
position: absolute;
right: 0px;
cursor: pointer;
color: rgba(0, 66, 66, 1);
font-weight: 700;
width: 25px;
height: 25px;
display: flex;
align-items: center;
justify-content: center;
}
}
}
.serviceContent {
margin-top: 30px;
flex: auto;
::v-deep .el-tabs {
.el-tabs__header {
margin-bottom: 5px;
.el-tabs__nav-wrap {
.el-tabs__nav-scroll {
.el-tabs__nav {
.el-tabs__active-bar {
background: rgba(0, 66, 66, 1);
height: 3px;
}
.el-tabs__item {
color: rgba(153, 153, 153, 1);
font-size: 16px;
font-weight: 500;
}
.el-tabs__item:focus-visible {
box-shadow: none;
}
.el-tabs__item.is-active {
font-size: 18px;
color: rgba(0, 66, 66, 1);
}
}
}
}
.el-tabs__nav-wrap::after {
height: 1px;
}
}
}
.tab {
border-radius: 5px;
//width: 50%;
width: 300px;
margin: 0 auto;
overflow: hidden;
background: rgba(var(--color-base1), 0.2);
display: flex;
.tab-item {
display: inline-block;
flex: 1;
height: 32px;
line-height: 32px;
text-align: center;
cursor: pointer;
}
.activeService {
border: 1px solid rgba(var(--color-base1), 1);
border-radius: 5px;
}
}
.itemLabel {
width: 64px;
flex: 0 0 64px;
white-space: nowrap;
text-align: right;
display: inline-block;
margin-right: 10px;
}
.tabPanel {
margin: 0;
.item {
display: flex;
align-items: center;
margin: 15px 0;
.select {
}
}
}
}
}
.btn {
text-align: center;
button {
width: 166px;
height: 40px;
border-radius: 0;
::v-deep span {
font-weight: 500;
}
&:hover {
border: 1px solid rgba(var(--color-base1), 1) !important;
}
}
button:nth-child(1) {
background: rgba(0, 255, 255, 1) !important;
border-color: #ff000000 !important;
color: rgba(0, 66, 66, 1) !important;
}
button:nth-child(2) {
background: rgba(255, 255, 255, 1) !important;
border-color: rgba(204, 204, 204, 0.4) !important;
color: rgba(102, 102, 102, 1) !important;
}
}
}
}
::v-deep .el-popper {
z-index: 9999 !important;
}
</style>
<style lang="scss">
.el-message-box {
--el-messagebox-title-color: #fff !important;
--el-messagebox-content-color: #fff !important;
background:
linear-gradient(180deg, rgba(var(--color-base1), 0) 0%, rgba(var(--color-base1), 0.2) 100%),
rgba(0, 0, 0, 0.6) !important;
.el-message-box__btns {
.el-button {
--el-button-text-color: #fff;
--el-button-bg-color: rgba(var(--color-base1), 0.2) !important;
--el-button-hover-bg-color: rgba(var(--color-base1), 0.2) !important;
--el-button-border-color: rgba(var(--color-base1), 0.5) !important;
--el-button-hover-border-color: rgba(var(--color-base1), 1) !important;
--el-button-hover-text-color: rgba(var(--color-base1), 1) !important;
}
.el-button--primary {
--el-button-bg-color: rgba(var(--color-base1), 0.2) !important;
--el-button-hover-bg-color: rgba(var(--color-base1), 0.2) !important;
}
.el-button:focus-visible {
outline: none !important;
}
}
}
</style> </style>