Merge branch 'main' of http://123.132.248.154:10000/gitY/DiKongGanZhiPingTai
commit
9f3bdd049d
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { defHttp } from '@/utils/http/axios';
|
||||||
|
enum Api {
|
||||||
|
GetDataList = '/api/Manage/GetDataList',
|
||||||
|
}
|
||||||
|
|
||||||
|
export function GetDataList(params) {
|
||||||
|
return defHttp.get({
|
||||||
|
url: Api.GetDataList,
|
||||||
|
params
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,15 @@
|
||||||
import { clientReizePublish, clientReizeSubscribe } from '@/utils/mqtt';
|
import { clientReizePublish, clientReizeSubscribe } from '@/utils/mqtt';
|
||||||
|
|
||||||
|
export const return_home_status = {
|
||||||
|
canceled: '取消或终止',
|
||||||
|
failed: '失败',
|
||||||
|
in_progress: '执行中',
|
||||||
|
ok: '执行成功',
|
||||||
|
paused: '暂停',
|
||||||
|
rejected: '拒绝',
|
||||||
|
sent: '已下发',
|
||||||
|
timeout: '超时',
|
||||||
|
};
|
||||||
export const eventsTopic = (data) => {
|
export const eventsTopic = (data) => {
|
||||||
// 发送消息
|
// 发送消息
|
||||||
clientReizePublish('thing/product/8UUXN5400A079H/events', data);
|
clientReizePublish('thing/product/8UUXN5400A079H/events', data);
|
||||||
|
|
|
||||||
|
|
@ -29,3 +29,12 @@ export const services_replyTopic = () => {
|
||||||
// 订阅消息
|
// 订阅消息
|
||||||
clientSubscribe('thing/product/8UUXN5400A079H/services_reply');
|
clientSubscribe('thing/product/8UUXN5400A079H/services_reply');
|
||||||
};
|
};
|
||||||
|
// 无人机
|
||||||
|
export const servicesUAVTopic = (data) => {
|
||||||
|
// 发送消息
|
||||||
|
clientPublish('thing/product/1581F8HGX254V00A0BUY/services', data);
|
||||||
|
};
|
||||||
|
export const services_replyUAVTopic = () => {
|
||||||
|
// 订阅消息
|
||||||
|
clientSubscribe('thing/product/1581F8HGX254V00A0BUY/services_reply');
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ const connection = {
|
||||||
connectTimeout: 30 * 1000, // ms
|
connectTimeout: 30 * 1000, // ms
|
||||||
reconnectPeriod: 4000, // ms
|
reconnectPeriod: 4000, // ms
|
||||||
// clientId: 'mqttx_' + Math.random().toString(16).substring(2, 8),
|
// clientId: 'mqttx_' + Math.random().toString(16).substring(2, 8),
|
||||||
clientId: 'mqtt_client_1581F8HGX254V00A0BUY',
|
clientId: `mqtt_${Math.random().toString(16).slice(2)}`,
|
||||||
// auth
|
// auth
|
||||||
username: 'sdhc',
|
username: 'sdhc',
|
||||||
password: '',
|
password: '',
|
||||||
|
|
@ -43,11 +43,23 @@ const handleOnReConnect = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// 创建连接函数
|
// 创建连接函数
|
||||||
const createConnection = () => {
|
const createConnection = (callback?) => {
|
||||||
try {
|
try {
|
||||||
const { protocol, host, port, endpoint, ...options } = connection;
|
const { protocol, host, port, endpoint, ...options } = connection;
|
||||||
const connectUrl = `${protocol}://${host}:${port}${endpoint}`;
|
const connectUrl = `${protocol}://${host}:${port}${endpoint}`;
|
||||||
client = mqtt.connect(connectUrl, options);
|
client = mqtt.connect(connectUrl, options);
|
||||||
|
client.on('connect', () => {
|
||||||
|
console.log('✅ 已连接');
|
||||||
|
if(callback){
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
client.on('close', () => {
|
||||||
|
console.log('❌ 连接已关闭');
|
||||||
|
});
|
||||||
|
client.on('error', (err) => {
|
||||||
|
console.error('❌ 出错了:', err);
|
||||||
|
});
|
||||||
if (client.on) {
|
if (client.on) {
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
@ -95,6 +107,14 @@ const clientPublish = (topic: string, querys: any) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
// 获取连接状态
|
||||||
|
const getConnectStatus = () => {
|
||||||
|
console.log('client',client)
|
||||||
|
if (!client.connected) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
// on 事件
|
// on 事件
|
||||||
// connect 连接
|
// connect 连接
|
||||||
// reconnect 重新连接
|
// reconnect 重新连接
|
||||||
|
|
@ -162,4 +182,5 @@ export {
|
||||||
getReizeClient,
|
getReizeClient,
|
||||||
clientReizeSubscribe,
|
clientReizeSubscribe,
|
||||||
clientReizePublish,
|
clientReizePublish,
|
||||||
|
getConnectStatus,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -40,3 +40,32 @@ export function buildShortUUID(prefix = ''): string {
|
||||||
unique++;
|
unique++;
|
||||||
return prefix + '_' + random + unique + String(time);
|
return prefix + '_' + random + unique + String(time);
|
||||||
}
|
}
|
||||||
|
export function uuid(len, radix) {
|
||||||
|
const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
|
||||||
|
let uuid = [],
|
||||||
|
i;
|
||||||
|
radix = radix || chars.length;
|
||||||
|
|
||||||
|
if (len) {
|
||||||
|
// Compact form
|
||||||
|
for (i = 0; i < len; i++) uuid[i] = chars[0 | (Math.random() * radix)];
|
||||||
|
} else {
|
||||||
|
// rfc4122, version 4 form
|
||||||
|
let r;
|
||||||
|
|
||||||
|
// rfc4122 requires these characters
|
||||||
|
uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
|
||||||
|
uuid[14] = '4';
|
||||||
|
|
||||||
|
// Fill in random data. At i==19 set the high bits of clock sequence as
|
||||||
|
// per rfc4122, sec. 4.1.5
|
||||||
|
for (i = 0; i < 36; i++) {
|
||||||
|
if (!uuid[i]) {
|
||||||
|
r = 0 | (Math.random() * 16);
|
||||||
|
uuid[i] = chars[i == 19 ? (r & 0x3) | 0x8 : r];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return uuid.join('');
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,29 @@
|
||||||
<template>
|
<template>
|
||||||
<BasicTable class="w-4/4 xl:w-5/5" @register="registerTable">
|
<BasicTable @register="registerTable">
|
||||||
<template #toolbar>
|
<template #toolbar>
|
||||||
<a-button type="primary" @click="openFeedbackDrawer">设备定损与反馈</a-button>
|
<a-button type="primary" @click="openFeedbackDrawer">设备定损与反馈</a-button>
|
||||||
<a-button type="primary" @click="openDeviceBindingModal">设备绑定码</a-button>
|
<a-button type="primary" @click="openDeviceBindingModal">设备绑定码</a-button>
|
||||||
</template>
|
</template>
|
||||||
<template #bodyCell="{ column, record }">
|
<template #bodyCell="{ column, record }">
|
||||||
|
<template v-if="column.key == 'workSpaceId'">
|
||||||
|
{{ props.projectList.find(item => item.value == record.workSpaceId)?.label }}
|
||||||
|
</template>
|
||||||
|
<template v-if="column.key == 'first_power_on'">
|
||||||
|
{{ record.first_power_on? dayjs(record.first_power_on).format('YYYY-MM-DD HH:mm:ss'): '' }}
|
||||||
|
</template>
|
||||||
|
<template v-if="column.key == 'compatible_status'">
|
||||||
|
{{ record.compatible_status? record.compatible_status == 0? "不需要一致性升级": "需要一致性升级": "" }}
|
||||||
|
</template>
|
||||||
|
<template v-if="column.key == 'flighttask_step_code'">
|
||||||
|
{{ workStatus(record)}}
|
||||||
|
</template>
|
||||||
<template v-if="column.key === 'action'">
|
<template v-if="column.key === 'action'">
|
||||||
<TableAction
|
<TableAction
|
||||||
:actions="[
|
:actions="[
|
||||||
{
|
{
|
||||||
icon: 'ant-design:file-search-outlined',
|
icon: 'ant-design:file-search-outlined',
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
|
console.log('deviceInfoList',deviceInfoList)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -26,24 +39,70 @@
|
||||||
<a-drawer class="feedback-drawer" v-model:open="feedbackDrawer" width="80%" :closable="false">
|
<a-drawer class="feedback-drawer" v-model:open="feedbackDrawer" width="80%" :closable="false">
|
||||||
<FeedbackDrawer />
|
<FeedbackDrawer />
|
||||||
</a-drawer>
|
</a-drawer>
|
||||||
|
<a-drawer class="feedback-drawer" v-model:open="feedbackDrawer" width="45%" :closable="false">
|
||||||
|
<FeedbackDrawer />
|
||||||
|
</a-drawer>
|
||||||
<a-modal v-model:open="deviceBindingModal" title="设备绑定码" @ok="handleOk">
|
<a-modal v-model:open="deviceBindingModal" title="设备绑定码" @ok="handleOk">
|
||||||
<DeviceBindModal />
|
<DeviceBindModal />
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from "vue"
|
import { ref, defineProps, onMounted, watch, nextTick } from "vue"
|
||||||
import { BasicTable, useTable, TableAction } from '@/components/Table';
|
import { BasicTable, useTable, TableAction } from '@/components/Table';
|
||||||
import { columns, dataSource, searchFormSchema } from './utils'
|
import { columns, searchFormSchema } from './utils'
|
||||||
import FeedbackDrawer from './FeedbackDrawer/index.vue'
|
import FeedbackDrawer from './FeedbackDrawer/index.vue'
|
||||||
import DeviceBindModal from './DeviceBindModal/index.vue'
|
import DeviceBindModal from './DeviceBindModal/index.vue'
|
||||||
|
import { GetDataList } from '@/api/demo/device'
|
||||||
|
import { getClient, clientSubscribe } from '@/utils/mqtt'
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
|
const props = defineProps(['projectList','connected'])
|
||||||
|
watch(() => props.projectList, () => {
|
||||||
|
const targetField = searchFormSchema.find(item => item.field === 'project');
|
||||||
|
if (targetField) {
|
||||||
|
targetField.componentProps = {
|
||||||
|
...(targetField.componentProps || {}),
|
||||||
|
options: props.projectList,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
})
|
||||||
|
watch(() => props.connected, () => {
|
||||||
|
getClient().on('message', (topic, message) => {
|
||||||
|
const rs = JSON.parse(message)
|
||||||
|
console.log('rs',rs)
|
||||||
|
console.log('getDataSource',getDataSource())
|
||||||
|
let list = getDataSource()
|
||||||
|
let sn = rs.gateway
|
||||||
|
for(let i = 0; i < list.length; i++){
|
||||||
|
if(list[i].sn == sn){
|
||||||
|
list[i] = {...list[i],...rs.data}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setTableData(list)
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
const feedbackDrawer = ref(false)
|
const feedbackDrawer = ref(false)
|
||||||
const deviceBindingModal = ref(false)
|
const deviceBindingModal = ref(false)
|
||||||
const [registerTable, { reload, expandAll, getForm}] = useTable({
|
const afterFetch = ref(false)
|
||||||
|
const deviceControl = ref(false)
|
||||||
|
watch(() => [afterFetch.value, props.connected], ([newAfterFetch, newConnected], [oldAfterFetch, oldConnected]) => {
|
||||||
|
console.log(newAfterFetch,newConnected)
|
||||||
|
console.log(getDataSource())
|
||||||
|
if(newConnected && newAfterFetch){
|
||||||
|
nextTick(() => {
|
||||||
|
console.log(getDataSource())
|
||||||
|
getDataSource().forEach(item => {
|
||||||
|
let topicUrl = `thing/product/${item.sn}/osd`;
|
||||||
|
clientSubscribe(topicUrl);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const [registerTable, { reload, expandAll, getForm,getDataSource,setTableData }] = useTable({
|
||||||
title: '机场',
|
title: '机场',
|
||||||
// api: (params) => LoadCaseInfoLists(type,params),
|
api: GetDataList,
|
||||||
dataSource,
|
|
||||||
columns,
|
columns,
|
||||||
rowKey: 'id',
|
rowKey: 'id',
|
||||||
formConfig: {
|
formConfig: {
|
||||||
|
|
@ -57,16 +116,15 @@ const [registerTable, { reload, expandAll, getForm}] = useTable({
|
||||||
useSearchForm: true,
|
useSearchForm: true,
|
||||||
// 显示表格设置工具
|
// 显示表格设置工具
|
||||||
showTableSetting: true,
|
showTableSetting: true,
|
||||||
bordered: true,
|
bordered: false,
|
||||||
beforeFetch(data) {
|
beforeFetch(data) {
|
||||||
let params = {...data}
|
return data
|
||||||
if(!params.nowStatus){
|
|
||||||
params.nowStatus = '复提待审核'
|
|
||||||
}
|
|
||||||
return params
|
|
||||||
},
|
},
|
||||||
afterFetch(data) {
|
afterFetch(data) {
|
||||||
console.log('afterFetch', data);
|
afterFetch.value = true
|
||||||
|
return data.map(item => {
|
||||||
|
return {...item, children: item.uavList}
|
||||||
|
})
|
||||||
},
|
},
|
||||||
actionColumn: {
|
actionColumn: {
|
||||||
width: 100,
|
width: 100,
|
||||||
|
|
@ -83,6 +141,30 @@ const openFeedbackDrawer = () => {
|
||||||
const openDeviceBindingModal = () => {
|
const openDeviceBindingModal = () => {
|
||||||
deviceBindingModal.value = true
|
deviceBindingModal.value = true
|
||||||
}
|
}
|
||||||
|
const workStatus = (record) => {
|
||||||
|
if(record.flighttask_step_code){
|
||||||
|
switch(record.flighttask_step_code){
|
||||||
|
case 0:
|
||||||
|
return '作业准备中'
|
||||||
|
case 1:
|
||||||
|
return '飞行作业中'
|
||||||
|
case 2:
|
||||||
|
return '作业后状态恢复'
|
||||||
|
case 3:
|
||||||
|
return '自定义飞行区更新中'
|
||||||
|
case 4:
|
||||||
|
return '地形障碍物更新中'
|
||||||
|
case 5:
|
||||||
|
return '任务空闲'
|
||||||
|
case 255:
|
||||||
|
return '飞行器异常'
|
||||||
|
case 256:
|
||||||
|
return '未知状态'
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import { BasicColumn, FormSchema } from '@/components/Table';
|
||||||
export const columns = [
|
export const columns = [
|
||||||
{
|
{
|
||||||
title: '设备型号',
|
title: '设备型号',
|
||||||
dataIndex: 'model',
|
dataIndex: 'typeId',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '设备SN',
|
title: '设备SN',
|
||||||
|
|
@ -18,7 +18,7 @@ export const columns = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '固件升级',
|
title: '固件升级',
|
||||||
dataIndex: 'upgrade',
|
dataIndex: 'compatible_status',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '飞行安全数据库',
|
title: '飞行安全数据库',
|
||||||
|
|
@ -26,11 +26,11 @@ export const columns = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '工作状态',
|
title: '工作状态',
|
||||||
dataIndex: 'status',
|
dataIndex: 'flighttask_step_code',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '所属项目',
|
title: '所属项目',
|
||||||
dataIndex: 'project',
|
dataIndex: 'workSpaceId',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '加入组织时间',
|
title: '加入组织时间',
|
||||||
|
|
@ -38,26 +38,10 @@ export const columns = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '在线时间',
|
title: '在线时间',
|
||||||
dataIndex: 'online_time',
|
dataIndex: 'first_power_on',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
export const dataSource = [
|
|
||||||
{ model: 111, sn:222, name: 333, version: 444, upgrade:'1.0.0', database:'test', status: 555, project: 666, join_time: 777, online_time: 888 },
|
|
||||||
{ model: 111, sn:222, name: 333, version: 444, upgrade:'1.0.0', database:'test', status: 555, project: 666, join_time: 777, online_time: 888 },
|
|
||||||
{ model: 111, sn:222, name: 333, version: 444, upgrade:'1.0.0', database:'test', status: 555, project: 666, join_time: 777, online_time: 888 },
|
|
||||||
{ model: 111, sn:222, name: 333, version: 444, upgrade:'1.0.0', database:'test', status: 555, project: 666, join_time: 777, online_time: 888 },
|
|
||||||
{ model: 111, sn:222, name: 333, version: 444, upgrade:'1.0.0', database:'test', status: 555, project: 666, join_time: 777, online_time: 888 },
|
|
||||||
{ model: 111, sn:222, name: 333, version: 444, upgrade:'1.0.0', database:'test', status: 555, project: 666, join_time: 777, online_time: 888 },
|
|
||||||
{ model: 111, sn:222, name: 333, version: 444, upgrade:'1.0.0', database:'test', status: 555, project: 666, join_time: 777, online_time: 888 },
|
|
||||||
{ model: 111, sn:222, name: 333, version: 444, upgrade:'1.0.0', database:'test', status: 555, project: 666, join_time: 777, online_time: 888 },
|
|
||||||
{ model: 111, sn:222, name: 333, version: 444, upgrade:'1.0.0', database:'test', status: 555, project: 666, join_time: 777, online_time: 888 },
|
|
||||||
{ model: 111, sn:222, name: 333, version: 444, upgrade:'1.0.0', database:'test', status: 555, project: 666, join_time: 777, online_time: 888 },
|
|
||||||
{ model: 111, sn:222, name: 333, version: 444, upgrade:'1.0.0', database:'test', status: 555, project: 666, join_time: 777, online_time: 888 },
|
|
||||||
{ model: 111, sn:222, name: 333, version: 444, upgrade:'1.0.0', database:'test', status: 555, project: 666, join_time: 777, online_time: 888 },
|
|
||||||
{ model: 111, sn:222, name: 333, version: 444, upgrade:'1.0.0', database:'test', status: 555, project: 666, join_time: 777, online_time: 888 },
|
|
||||||
{ model: 111, sn:222, name: 333, version: 444, upgrade:'1.0.0', database:'test', status: 555, project: 666, join_time: 777, online_time: 888 },
|
|
||||||
{ model: 111, sn:222, name: 333, version: 444, upgrade:'1.0.0', database:'test', status: 555, project: 666, join_time: 777, online_time: 888 },
|
|
||||||
]
|
|
||||||
export const searchFormSchema: FormSchema[] = [
|
export const searchFormSchema: FormSchema[] = [
|
||||||
{
|
{
|
||||||
field: 'upgrade_status',
|
field: 'upgrade_status',
|
||||||
|
|
|
||||||
|
|
@ -2,20 +2,51 @@
|
||||||
<div class="device-page">
|
<div class="device-page">
|
||||||
<a-tabs v-model:activeKey="activeKey" class="device-tabs">
|
<a-tabs v-model:activeKey="activeKey" class="device-tabs">
|
||||||
<a-tab-pane key="airport" tab="机场">
|
<a-tab-pane key="airport" tab="机场">
|
||||||
<Airport />
|
<Airport :connected="connected" :projectList="projectList"/>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
<a-tab-pane key="aerocraft" tab="飞行器">
|
<a-tab-pane key="aerocraft" tab="飞行器">
|
||||||
<Aerocraft />
|
<Aerocraft :projectList="projectList"/>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
</a-tabs>
|
</a-tabs>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from "vue"
|
import { ref, onMounted, onBeforeUnmount } from "vue"
|
||||||
import Airport from './Airport/index.vue'
|
import Airport from './Airport/index.vue'
|
||||||
import Aerocraft from './Aerocraft/index.vue'
|
import Aerocraft from './Aerocraft/index.vue'
|
||||||
|
import { GetWorkspaceList } from '@/api/demo/projecthome'
|
||||||
|
import { getConnectStatus,createConnection,destroyConnection } from '@/utils/mqtt'
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if(!getConnectStatus()){
|
||||||
|
console.log("需要重连")
|
||||||
|
createConnection(changeConnect)
|
||||||
|
connectMQTT.value = true
|
||||||
|
}else{
|
||||||
|
changeConnect()
|
||||||
|
}
|
||||||
|
GetWorkspaceList().then(res => {
|
||||||
|
projectList.value = res.map(item => {
|
||||||
|
return {
|
||||||
|
label: item.WorkspaceName,
|
||||||
|
value: item.Id,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
if(connectMQTT.value){
|
||||||
|
destroyConnection()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const changeConnect = () => {
|
||||||
|
connected.value = true
|
||||||
|
}
|
||||||
const activeKey = ref('airport')
|
const activeKey = ref('airport')
|
||||||
|
const projectList = ref([])
|
||||||
|
const connectMQTT = ref(false)
|
||||||
|
const connected = ref(false)
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,4 +6,5 @@ export { default as LivePreview } from './src/LivePreview.vue';
|
||||||
export { default as RemoteDebugging } from './src/RemoteDebugging.vue';
|
export { default as RemoteDebugging } from './src/RemoteDebugging.vue';
|
||||||
export { default as LoadControl } from './src/LoadControl.vue';
|
export { default as LoadControl } from './src/LoadControl.vue';
|
||||||
export { default as FlightControl } from './src/FlightControl.vue';
|
export { default as FlightControl } from './src/FlightControl.vue';
|
||||||
|
export { default as TakeOffForm } from './src/TakeOffForm.vue';
|
||||||
export { default as Map } from '../workplan/components/map.vue';
|
export { default as Map } from '../workplan/components/map.vue';
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,14 @@
|
||||||
</div>
|
</div>
|
||||||
<!-- 飞行控制 -->
|
<!-- 飞行控制 -->
|
||||||
<div v-if="flightControlVisible">
|
<div v-if="flightControlVisible">
|
||||||
<FlightControl @changeFlightControl="changeFlightControl" />
|
<FlightControl @changeFlightControl="changeFlightControl" @clickTakeOff="clickTakeOff" />
|
||||||
|
</div>
|
||||||
|
<!-- 一键起飞表单 -->
|
||||||
|
<div v-if="takeOffFormVisible">
|
||||||
|
<TakeOffForm @changeTakeOffForm="changeTakeOffForm" />
|
||||||
</div>
|
</div>
|
||||||
<div class="AirportLive" v-if="airportLiveVisible" v-drag>
|
<div class="AirportLive" v-if="airportLiveVisible" v-drag>
|
||||||
<AirportLive />
|
<AirportLive :msgData="msgData" />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="LivePreview"
|
class="LivePreview"
|
||||||
|
|
@ -35,7 +39,7 @@
|
||||||
:style="{ bottom: airportLiveVisible ? '300px' : '20px' }"
|
:style="{ bottom: airportLiveVisible ? '300px' : '20px' }"
|
||||||
v-drag
|
v-drag
|
||||||
>
|
>
|
||||||
<LivePreview />
|
<LivePreview :msgData="msgData" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -51,6 +55,7 @@
|
||||||
RemoteDebugging,
|
RemoteDebugging,
|
||||||
LoadControl,
|
LoadControl,
|
||||||
FlightControl,
|
FlightControl,
|
||||||
|
TakeOffForm,
|
||||||
} from './index';
|
} from './index';
|
||||||
import { useMessage } from '@/hooks/web/useMessage';
|
import { useMessage } from '@/hooks/web/useMessage';
|
||||||
import { getClient, createConnection, clientSubscribe } from '@/utils/mqtt';
|
import { getClient, createConnection, clientSubscribe } from '@/utils/mqtt';
|
||||||
|
|
@ -81,6 +86,8 @@
|
||||||
const loadControlVisible = ref(false);
|
const loadControlVisible = ref(false);
|
||||||
// 飞行控制
|
// 飞行控制
|
||||||
const flightControlVisible = ref(false);
|
const flightControlVisible = ref(false);
|
||||||
|
// 一键起飞表单
|
||||||
|
const takeOffFormVisible = ref(false);
|
||||||
const changeAirportLive = () => {
|
const changeAirportLive = () => {
|
||||||
airportLiveVisible.value = !airportLiveVisible.value;
|
airportLiveVisible.value = !airportLiveVisible.value;
|
||||||
};
|
};
|
||||||
|
|
@ -93,6 +100,13 @@
|
||||||
const changeFlightControl = () => {
|
const changeFlightControl = () => {
|
||||||
flightControlVisible.value = !flightControlVisible.value;
|
flightControlVisible.value = !flightControlVisible.value;
|
||||||
};
|
};
|
||||||
|
const clickTakeOff = () => {
|
||||||
|
console.log('clickTakeOff');
|
||||||
|
takeOffFormVisible.value = true;
|
||||||
|
};
|
||||||
|
const changeTakeOffForm = () => {
|
||||||
|
takeOffFormVisible.value = false;
|
||||||
|
};
|
||||||
const msgData = ref();
|
const msgData = ref();
|
||||||
const changeSelect = async (value?: any) => {
|
const changeSelect = async (value?: any) => {
|
||||||
console.log(value);
|
console.log(value);
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@
|
||||||
<div class="title">机场直播</div>
|
<div class="title">机场直播</div>
|
||||||
<div class="title-icon">
|
<div class="title-icon">
|
||||||
<RedoOutlined @click="startLiveFun" />
|
<RedoOutlined @click="startLiveFun" />
|
||||||
<a-divider type="vertical" style="border-color: #4e5778" />
|
<!-- <a-divider type="vertical" style="border-color: #4e5778" /> -->
|
||||||
<ExpandOutlined />
|
<!-- <ExpandOutlined /> -->
|
||||||
<a-divider type="vertical" style="border-color: #4e5778" />
|
<a-divider type="vertical" style="border-color: #4e5778" />
|
||||||
<PoweroffOutlined @click="closeLive" />
|
<PoweroffOutlined @click="closeLive" />
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -25,44 +25,116 @@
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { RedoOutlined, ExpandOutlined, PoweroffOutlined } from '@ant-design/icons-vue';
|
import { RedoOutlined, ExpandOutlined, PoweroffOutlined } from '@ant-design/icons-vue';
|
||||||
import { onMounted, onBeforeUnmount } from 'vue';
|
import { onMounted, onBeforeUnmount, watch } from 'vue';
|
||||||
import { startLive, endLive } from '@/api/workmanagement/airportMaintenance';
|
import { startLive, endLive } from '@/api/workmanagement/airportMaintenance';
|
||||||
import TCPlayer from 'tcplayer.js';
|
import TCPlayer from 'tcplayer.js';
|
||||||
import 'tcplayer.js/dist/tcplayer.min.css'; //引入插件和样式文件
|
import 'tcplayer.js/dist/tcplayer.min.css'; //引入插件和样式文件
|
||||||
|
import { servicesTopic, services_replyTopic } from '@/utils/debugging/remote';
|
||||||
|
import { useMessage } from '@/hooks/web/useMessage';
|
||||||
|
import { buildGUID } from '@/utils/uuid';
|
||||||
|
|
||||||
|
const { createMessage } = useMessage();
|
||||||
|
const props = defineProps({
|
||||||
|
msgData: Object,
|
||||||
|
});
|
||||||
let player;
|
let player;
|
||||||
|
watch(
|
||||||
|
() => props.msgData,
|
||||||
|
(val) => {
|
||||||
|
if (val.topic == 'thing/product/8UUXN5400A079H/services_reply') {
|
||||||
|
if (val.message.method == 'live_start_push') {
|
||||||
|
console.log(val);
|
||||||
|
if (val.message.data.result == 0) {
|
||||||
|
createMessage.success('开始直播成功');
|
||||||
|
player.src('http://175.27.168.120:6012/live/2.m3u8');
|
||||||
|
} else if (val.message.data.result == 513003) {
|
||||||
|
createMessage.success('直播已开启');
|
||||||
|
player.src('http://175.27.168.120:6012/live/2.m3u8');
|
||||||
|
} else {
|
||||||
|
createMessage.error('开始直播失败');
|
||||||
|
}
|
||||||
|
} else if (val.message.method == 'live_stop_push') {
|
||||||
|
if (val.message.data.result == 0) {
|
||||||
|
createMessage.success('停止直播成功');
|
||||||
|
if (player) {
|
||||||
|
// player.dispose();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
createMessage.error('停止直播失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
const startLiveFun = () => {
|
const startLiveFun = () => {
|
||||||
const querys = {
|
const querys = {
|
||||||
urlType: 1, // 0 = 自适应;如需 RTMP 改为 1;GB28181 为 3;WebRTC 为 4
|
bid: buildGUID(),
|
||||||
url: 'rtmp://221.2.83.254:1935/live/2',
|
method: 'live_start_push',
|
||||||
|
tid: buildGUID(),
|
||||||
|
timestamp: new Date().getTime(),
|
||||||
|
data: {
|
||||||
|
url_type: 1, // 0 = 自适应;如需 RTMP 改为 1;GB28181 为 3;WebRTC 为 4
|
||||||
|
url: 'rtmp://175.27.168.120:6019/live/2',
|
||||||
//video_id = "1581F8HGX254V00A0BUY/0-100-1/normal-0",
|
//video_id = "1581F8HGX254V00A0BUY/0-100-1/normal-0",
|
||||||
videoId: '8UUXN5400A079H/165-0-7/normal-0',
|
video_id: '8UUXN5400A079H/165-0-7/normal-0',
|
||||||
quality: 1, // 0=自适应,1=流畅,2=标清,3=高清,4=超清
|
video_quality: 1, // 0=自适应,1=流畅,2=标清,3=高清,4=超清
|
||||||
|
},
|
||||||
};
|
};
|
||||||
startLive(querys).then((res) => {
|
servicesTopic(querys);
|
||||||
console.log(res);
|
services_replyTopic();
|
||||||
|
// const querys = {
|
||||||
|
// urlType: 1, // 0 = 自适应;如需 RTMP 改为 1;GB28181 为 3;WebRTC 为 4
|
||||||
|
// url: 'rtmp://175.27.168.120:6019/live/2',
|
||||||
|
// //video_id = "1581F8HGX254V00A0BUY/0-100-1/normal-0",
|
||||||
|
// videoId: '8UUXN5400A079H/165-0-7/normal-0',
|
||||||
|
// quality: 1, // 0=自适应,1=流畅,2=标清,3=高清,4=超清
|
||||||
|
// };
|
||||||
|
// startLive(querys).then((res) => {
|
||||||
|
// console.log(res);
|
||||||
|
// player = TCPlayer('player-container-id', {
|
||||||
|
// width: 360,
|
||||||
|
// height: 200,
|
||||||
|
// sources: [
|
||||||
|
// {
|
||||||
|
// src: 'http://175.27.168.120:6012/live/2.m3u8', // 播放地址
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// licenseUrl: 'http://175.27.168.120:6012/live/2.m3u8', // license 地址,必传。参考准备工作部分,在视立方控制台申请 license 后可获得 licenseUrl
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
};
|
||||||
|
const closeLive = () => {
|
||||||
|
const querys = {
|
||||||
|
bid: buildGUID(),
|
||||||
|
method: 'live_stop_push',
|
||||||
|
tid: buildGUID(),
|
||||||
|
timestamp: new Date().getTime(),
|
||||||
|
data: {
|
||||||
|
video_id: '8UUXN5400A079H/165-0-7/normal-0',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
servicesTopic(querys);
|
||||||
|
// endLive({
|
||||||
|
// videoId: '8UUXN5400A079H/165-0-7/normal-0',
|
||||||
|
// }).then((res) => {
|
||||||
|
// console.log(res);
|
||||||
|
// player.dispose();
|
||||||
|
// });
|
||||||
|
};
|
||||||
|
onMounted(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
startLiveFun();
|
||||||
player = TCPlayer('player-container-id', {
|
player = TCPlayer('player-container-id', {
|
||||||
width: 360,
|
width: 360,
|
||||||
height: 200,
|
height: 200,
|
||||||
sources: [
|
sources: [
|
||||||
{
|
{
|
||||||
src: 'http://221.2.83.254:7005/live/2.m3u8', // 播放地址
|
src: 'http://175.27.168.120:6012/live/2.m3u8', // 播放地址
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
licenseUrl: 'http://221.2.83.254:7005/live/2.m3u8', // license 地址,必传。参考准备工作部分,在视立方控制台申请 license 后可获得 licenseUrl
|
licenseUrl: 'http://175.27.168.120:6012/live/2.m3u8', // license 地址,必传。参考准备工作部分,在视立方控制台申请 license 后可获得 licenseUrl
|
||||||
});
|
});
|
||||||
});
|
}, 1000);
|
||||||
};
|
|
||||||
const closeLive = () => {
|
|
||||||
endLive({
|
|
||||||
videoId: '8UUXN5400A079H/165-0-7/normal-0',
|
|
||||||
}).then((res) => {
|
|
||||||
console.log(res);
|
|
||||||
player.dispose();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
onMounted(() => {
|
|
||||||
// startLiveFun();
|
|
||||||
});
|
});
|
||||||
// 销毁视频控件
|
// 销毁视频控件
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
|
|
@ -107,5 +179,11 @@
|
||||||
border: 1px solid #3a57e8;
|
border: 1px solid #3a57e8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.player {
|
||||||
|
height: 200px;
|
||||||
|
#player-container-id-live {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -8,38 +8,49 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="content-button">
|
<div class="content-button">
|
||||||
<a-button>获取飞行器控制器</a-button>
|
<a-button @click="obtain">获取飞行器控制权</a-button>
|
||||||
<a-button>一键起飞</a-button>
|
<a-button @click="emits('clickTakeOff')">一键起飞</a-button>
|
||||||
<a-button>指点飞行</a-button>
|
<a-button>指点飞行</a-button>
|
||||||
<a-button>智能环绕</a-button>
|
<!-- <a-button>智能环绕</a-button> -->
|
||||||
<a-button>一键返航</a-button>
|
<a-button @click="returnVoyage">一键返航</a-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="content-info">
|
<div class="content-info">
|
||||||
<div class="info-item">
|
<div class="info-item">
|
||||||
<img src="@/assets/images/flightoperation/flight_control.png" alt="" />
|
<img src="@/assets/images/flightoperation/flight_control.png" alt="" />
|
||||||
<div class="info-item-top"></div>
|
<div class="info-item-top" title="上升" @click="changeDRC('throttle', 'up')"></div>
|
||||||
<div class="info-item-right"></div>
|
<div class="info-item-right" title="右旋转" @click="changeDRC('yaw', 'up')"></div>
|
||||||
<div class="info-item-bottom"></div>
|
<div class="info-item-bottom" title="下降" @click="changeDRC('throttle', 'down')"></div>
|
||||||
<div class="info-item-left"></div>
|
<div class="info-item-left" title="左旋转" @click="changeDRC('yaw', 'down')"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="info-item">
|
<div class="info-item">
|
||||||
<img src="@/assets/images/flightoperation/flight_control.png" alt="" />
|
<img src="@/assets/images/flightoperation/flight_control.png" alt="" />
|
||||||
<div class="info-item-top"></div>
|
<div class="info-item-top" title="前进" @click="changeDRC('pitch', 'up')"></div>
|
||||||
<div class="info-item-right"></div>
|
<div class="info-item-right" title="右移" @click="changeDRC('roll', 'up')"></div>
|
||||||
<div class="info-item-bottom"></div>
|
<div class="info-item-bottom" title="后退" @click="changeDRC('pitch', 'down')"></div>
|
||||||
<div class="info-item-left"></div>
|
<div class="info-item-left" title="左移" @click="changeDRC('roll', 'down')"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, ref, watch } from 'vue';
|
import { onMounted, ref, watch, reactive } from 'vue';
|
||||||
import { getClient, createConnection } from '@/utils/mqtt';
|
import { getClient, createConnection } from '@/utils/mqtt';
|
||||||
import { CloseOutlined } from '@ant-design/icons-vue';
|
import { CloseOutlined } from '@ant-design/icons-vue';
|
||||||
import { vDrag } from '@/utils/drag';
|
import { vDrag } from '@/utils/drag';
|
||||||
|
import { getReizeClient, createSeizeConnection, clientReizePublish } from '@/utils/mqtt';
|
||||||
|
import {
|
||||||
|
eventsTopic,
|
||||||
|
events_replyTopic,
|
||||||
|
drcDownTopic,
|
||||||
|
servicesTopic,
|
||||||
|
return_home_status,
|
||||||
|
} from '@/utils/debugging/events';
|
||||||
|
import { buildGUID } from '@/utils/uuid';
|
||||||
|
import { useMessage } from '@/hooks/web/useMessage';
|
||||||
|
|
||||||
const emits = defineEmits(['changeFlightControl']);
|
const { createMessage } = useMessage();
|
||||||
|
const emits = defineEmits(['changeFlightControl', 'clickTakeOff']);
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
airportAllVal: Object,
|
airportAllVal: Object,
|
||||||
});
|
});
|
||||||
|
|
@ -58,6 +69,13 @@
|
||||||
capacity_percent: 0,
|
capacity_percent: 0,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
const data = reactive({
|
||||||
|
roll: 1024,
|
||||||
|
pitch: 1024,
|
||||||
|
throttle: 1024,
|
||||||
|
yaw: 1024,
|
||||||
|
gimbal_pitch: 1024,
|
||||||
|
});
|
||||||
watch(
|
watch(
|
||||||
() => props.airportAllVal,
|
() => props.airportAllVal,
|
||||||
(val) => {
|
(val) => {
|
||||||
|
|
@ -65,6 +83,65 @@
|
||||||
airportVal.value = val.data;
|
airportVal.value = val.data;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
// 获取
|
||||||
|
const obtain = () => {
|
||||||
|
if (!getReizeClient()) {
|
||||||
|
createSeizeConnection();
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
// 飞行控制权抢夺
|
||||||
|
eventsTopic({
|
||||||
|
bid: buildGUID(),
|
||||||
|
method: 'flight_authority_grab',
|
||||||
|
tid: buildGUID(),
|
||||||
|
timestamp: new Date().getTime(),
|
||||||
|
data: {},
|
||||||
|
});
|
||||||
|
// 负载控制权抢夺
|
||||||
|
eventsTopic({
|
||||||
|
bid: buildGUID(),
|
||||||
|
method: 'payload_authority_grab',
|
||||||
|
tid: buildGUID(),
|
||||||
|
timestamp: new Date().getTime(),
|
||||||
|
data: {
|
||||||
|
payload_index: '99-0-0',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
events_replyTopic();
|
||||||
|
// // 接收消息
|
||||||
|
getReizeClient().on('message', (topic, message) => {
|
||||||
|
const rs = JSON.parse(message);
|
||||||
|
console.log(rs);
|
||||||
|
// 一键返航
|
||||||
|
if (rs.method === 'return_home') {
|
||||||
|
createMessage.info(return_home_status[rs.data.output.status]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 1000);
|
||||||
|
};
|
||||||
|
// 一键返航
|
||||||
|
const returnVoyage = () => {
|
||||||
|
servicesTopic({
|
||||||
|
bid: buildGUID(),
|
||||||
|
method: 'return_home',
|
||||||
|
tid: buildGUID(),
|
||||||
|
timestamp: new Date().getTime(),
|
||||||
|
data: {},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const changeDRC = (type, value) => {
|
||||||
|
if (value == 'up') {
|
||||||
|
data[type] = data[type] + 20;
|
||||||
|
} else {
|
||||||
|
data[type] = data[type] - 20;
|
||||||
|
}
|
||||||
|
const querys = {
|
||||||
|
seq: 1,
|
||||||
|
method: 'stick_control',
|
||||||
|
data: data,
|
||||||
|
};
|
||||||
|
drcDownTopic(querys);
|
||||||
|
};
|
||||||
onMounted(() => {});
|
onMounted(() => {});
|
||||||
</script>
|
</script>
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
<div class="preview-title">
|
<div class="preview-title">
|
||||||
<div class="title-select">
|
<div class="title-select">
|
||||||
<div class="title-select-item">
|
<div class="title-select-item">
|
||||||
|
<span>镜头:</span>
|
||||||
<a-select
|
<a-select
|
||||||
ref="select"
|
ref="select"
|
||||||
v-model:value="selectVal.camera"
|
v-model:value="selectVal.camera"
|
||||||
|
|
@ -23,9 +24,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="title-icon">
|
<div class="title-icon">
|
||||||
<RedoOutlined />
|
<RedoOutlined @click="startLiveFun" />
|
||||||
<a-divider type="vertical" style="border-color: #4e5778" />
|
<!-- <a-divider type="vertical" style="border-color: #4e5778" /> -->
|
||||||
<ExpandOutlined />
|
<!-- <ExpandOutlined /> -->
|
||||||
<a-divider type="vertical" style="border-color: #4e5778" />
|
<a-divider type="vertical" style="border-color: #4e5778" />
|
||||||
<PoweroffOutlined @click="closeLive" />
|
<PoweroffOutlined @click="closeLive" />
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -46,7 +47,7 @@
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { RedoOutlined, ExpandOutlined, PoweroffOutlined } from '@ant-design/icons-vue';
|
import { RedoOutlined, ExpandOutlined, PoweroffOutlined } from '@ant-design/icons-vue';
|
||||||
import { reactive, onMounted, ref } from 'vue';
|
import { reactive, onMounted, ref, watch } from 'vue';
|
||||||
import { buildGUID } from '@/utils/uuid';
|
import { buildGUID } from '@/utils/uuid';
|
||||||
import { getClient, createConnection } from '@/utils/mqtt';
|
import { getClient, createConnection } from '@/utils/mqtt';
|
||||||
import {
|
import {
|
||||||
|
|
@ -57,21 +58,79 @@
|
||||||
} from '@/api/workmanagement/airportMaintenance';
|
} from '@/api/workmanagement/airportMaintenance';
|
||||||
import TCPlayer from 'tcplayer.js';
|
import TCPlayer from 'tcplayer.js';
|
||||||
import 'tcplayer.js/dist/tcplayer.min.css'; //引入插件和样式文件
|
import 'tcplayer.js/dist/tcplayer.min.css'; //引入插件和样式文件
|
||||||
|
import { servicesUAVTopic, services_replyUAVTopic } from '@/utils/debugging/remote';
|
||||||
|
import { useMessage } from '@/hooks/web/useMessage';
|
||||||
|
|
||||||
|
const { createMessage } = useMessage();
|
||||||
|
const props = defineProps({
|
||||||
|
msgData: Object,
|
||||||
|
});
|
||||||
let player;
|
let player;
|
||||||
|
watch(
|
||||||
|
() => props.msgData,
|
||||||
|
(val) => {
|
||||||
|
if (val.topic == 'thing/product/1581F8HGX254V00A0BUY/services_reply') {
|
||||||
|
if (val.message.method == 'live_start_push') {
|
||||||
|
console.log(val);
|
||||||
|
if (val.message.data.result == 0) {
|
||||||
|
createMessage.success('开始直播成功');
|
||||||
|
player.src('http://175.27.168.120:6012/live/3.m3u8');
|
||||||
|
} else if (val.message.data.result == 513003) {
|
||||||
|
createMessage.success('直播已开启');
|
||||||
|
player.src('http://175.27.168.120:6012/live/3.m3u8');
|
||||||
|
} else {
|
||||||
|
createMessage.error('开始直播失败');
|
||||||
|
}
|
||||||
|
} else if (val.message.method == 'live_stop_push') {
|
||||||
|
if (val.message.data.result == 0) {
|
||||||
|
createMessage.success('停止直播成功');
|
||||||
|
if (player) {
|
||||||
|
// player.dispose();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
createMessage.error('停止直播失败');
|
||||||
|
}
|
||||||
|
} else if (val.message.method == 'live_set_quality') {
|
||||||
|
if (val.message.data.result == 0) {
|
||||||
|
createMessage.success('设置清晰度成功');
|
||||||
|
player.src('http://175.27.168.120:6012/live/3.m3u8');
|
||||||
|
} else {
|
||||||
|
createMessage.error('设置清晰度失败');
|
||||||
|
}
|
||||||
|
} else if (val.message.method == 'live_lens_change') {
|
||||||
|
console.log(val);
|
||||||
|
|
||||||
|
if (val.message.data.result == 0) {
|
||||||
|
createMessage.success('设置直播镜头成功');
|
||||||
|
player.src('http://175.27.168.120:6012/live/3.m3u8');
|
||||||
|
} else {
|
||||||
|
createMessage.error('设置直播镜头失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
const selectVal = reactive({
|
const selectVal = reactive({
|
||||||
camera: 1,
|
camera: 'normal',
|
||||||
resolution: 1,
|
resolution: 1,
|
||||||
});
|
});
|
||||||
const optionsArr = reactive({
|
const optionsArr = reactive({
|
||||||
cameraOptions: [
|
cameraOptions: [
|
||||||
{
|
{
|
||||||
label: '相机',
|
label: '红外',
|
||||||
value: 0,
|
value: 'ir',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '直播',
|
label: '默认',
|
||||||
value: 1,
|
value: 'normal',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '广角',
|
||||||
|
value: 'wide',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '变焦',
|
||||||
|
value: 'zoom',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
resolutionOptions: [
|
resolutionOptions: [
|
||||||
|
|
@ -99,38 +158,77 @@
|
||||||
});
|
});
|
||||||
const startLiveFun = () => {
|
const startLiveFun = () => {
|
||||||
const querys = {
|
const querys = {
|
||||||
urlType: 1, // 0 = 自适应;如需 RTMP 改为 1;GB28181 为 3;WebRTC 为 4
|
bid: buildGUID(),
|
||||||
url: 'rtmp://221.2.83.254:1935/live/3',
|
method: 'live_start_push',
|
||||||
|
tid: buildGUID(),
|
||||||
|
timestamp: new Date().getTime(),
|
||||||
|
data: {
|
||||||
|
url_type: 1, // 0 = 自适应;如需 RTMP 改为 1;GB28181 为 3;WebRTC 为 4
|
||||||
|
url: 'rtmp://175.27.168.120:6019/live/3',
|
||||||
//video_id = "1581F8HGX254V00A0BUY/0-100-1/normal-0",
|
//video_id = "1581F8HGX254V00A0BUY/0-100-1/normal-0",
|
||||||
videoId: '1581F8HGX254V00A0BUY/165-0-7/normal-0',
|
video_id: '1581F8HGX254V00A0BUY/165-0-7/normal-0',
|
||||||
quality: 1, // 0=自适应,1=流畅,2=标清,3=高清,4=超清
|
video_quality: 1, // 0=自适应,1=流畅,2=标清,3=高清,4=超清
|
||||||
|
},
|
||||||
};
|
};
|
||||||
startLive(querys).then((res) => {
|
servicesUAVTopic(querys);
|
||||||
console.log(res);
|
services_replyUAVTopic();
|
||||||
playVideo();
|
// const querys = {
|
||||||
});
|
// urlType: 1, // 0 = 自适应;如需 RTMP 改为 1;GB28181 为 3;WebRTC 为 4
|
||||||
|
// // url: 'rtmp://221.2.83.254:1935/live/3',
|
||||||
|
// url: 'rtmp://175.27.168.120:6019/live/3',
|
||||||
|
// //video_id = "1581F8HGX254V00A0BUY/0-100-1/normal-0",
|
||||||
|
// videoId: '1581F8HGX254V00A0BUY/165-0-7/normal-0',
|
||||||
|
// quality: 1, // 0=自适应,1=流畅,2=标清,3=高清,4=超清
|
||||||
|
// };
|
||||||
|
// startLive(querys).then((res) => {
|
||||||
|
// console.log(res);
|
||||||
|
// playVideo();
|
||||||
|
// });
|
||||||
};
|
};
|
||||||
const resolutionChange = (val: any) => {
|
const resolutionChange = (val: any) => {
|
||||||
const querys = {
|
const querys = {
|
||||||
videoId: '1581F8HGX254V00A0BUY/165-0-7/normal-0',
|
bid: buildGUID(),
|
||||||
videoQuality: val, // 0=自适应,1=流畅,2=标清,3=高清,4=超清
|
method: 'live_set_quality',
|
||||||
|
tid: buildGUID(),
|
||||||
|
timestamp: new Date().getTime(),
|
||||||
|
data: {
|
||||||
|
video_id: '1581F8HGX254V00A0BUY/165-0-7/normal-0',
|
||||||
|
video_quality: val, // 0=自适应,1=流畅,2=标清,3=高清,4=超清
|
||||||
|
},
|
||||||
};
|
};
|
||||||
setCameraVideo(querys).then((res) => {
|
servicesUAVTopic(querys);
|
||||||
console.log(res);
|
// const querys = {
|
||||||
playVideo();
|
// videoId: '1581F8HGX254V00A0BUY/165-0-7/normal-0',
|
||||||
});
|
// videoQuality: val, // 0=自适应,1=流畅,2=标清,3=高清,4=超清
|
||||||
|
// };
|
||||||
|
// setCameraVideo(querys).then((res) => {
|
||||||
|
// console.log(res);
|
||||||
|
// playVideo();
|
||||||
|
// });
|
||||||
};
|
};
|
||||||
const cameraChange = (val: any) => {
|
const cameraChange = (val: any) => {
|
||||||
console.log(val);
|
console.log(val);
|
||||||
const requestData = {
|
const querys = {
|
||||||
videoId: '1581F8HGX254V00A0BUY/165-0-7/normal-0',
|
bid: buildGUID(),
|
||||||
position: val, // 0=自适应,1=流畅,2=标清,3=高清,4=超清
|
method: 'live_lens_change',
|
||||||
camera: '99-0-0',
|
tid: buildGUID(),
|
||||||
|
timestamp: new Date().getTime(),
|
||||||
|
data: {
|
||||||
|
video_id: '1581F8HGX254V00A0BUY/165-0-7/normal-0',
|
||||||
|
video_type: val, // 0=自适应,1=流畅,2=标清,3=高清,4=超清
|
||||||
|
},
|
||||||
};
|
};
|
||||||
exchangeCamera(requestData).then((res) => {
|
console.log(querys);
|
||||||
console.log(res);
|
servicesUAVTopic(querys);
|
||||||
playVideo();
|
// const requestData = {
|
||||||
});
|
// videoId: '1581F8HGX254V00A0BUY/165-0-7/normal-0',
|
||||||
|
// position: val, // 0=自适应,1=流畅,2=标清,3=高清,4=超清
|
||||||
|
// camera: '99-0-0',
|
||||||
|
// };
|
||||||
|
// exchangeCamera(requestData).then((res) => {
|
||||||
|
// console.log(res);
|
||||||
|
// playVideo();
|
||||||
|
// });
|
||||||
};
|
};
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
playedTime: 0,
|
playedTime: 0,
|
||||||
|
|
@ -143,21 +241,34 @@
|
||||||
height: 180,
|
height: 180,
|
||||||
sources: [
|
sources: [
|
||||||
{
|
{
|
||||||
src: 'http://221.2.83.254:7005/live/3.m3u8', // 播放地址
|
src: 'http://175.27.168.120:6012/live/3.m3u8', // 播放地址
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
licenseUrl: 'http://221.2.83.254:7005/live/3.m3u8', // license 地址,必传。参考准备工作部分,在视立方控制台申请 license 后可获得 licenseUrl
|
licenseUrl: 'http://175.27.168.120:6012/live/3.m3u8', // license 地址,必传。参考准备工作部分,在视立方控制台申请 license 后可获得 licenseUrl
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
const closeLive = () => {
|
const closeLive = () => {
|
||||||
endLive({
|
const querys = {
|
||||||
videoId: '1581F8HGX254V00A0BUY/165-0-7/normal-0',
|
bid: buildGUID(),
|
||||||
}).then((res) => {
|
method: 'live_stop_push',
|
||||||
console.log(res);
|
tid: buildGUID(),
|
||||||
});
|
timestamp: new Date().getTime(),
|
||||||
|
data: {
|
||||||
|
video_id: '1581F8HGX254V00A0BUY/165-0-7/normal-0',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
servicesUAVTopic(querys);
|
||||||
|
// endLive({
|
||||||
|
// videoId: '1581F8HGX254V00A0BUY/165-0-7/normal-0',
|
||||||
|
// }).then((res) => {
|
||||||
|
// console.log(res);
|
||||||
|
// });
|
||||||
};
|
};
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// startLiveFun();
|
setTimeout(() => {
|
||||||
|
startLiveFun();
|
||||||
|
playVideo();
|
||||||
|
}, 1000);
|
||||||
// resolutionChange(1);
|
// resolutionChange(1);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -241,5 +352,11 @@
|
||||||
top: 100px;
|
top: 100px;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
}
|
}
|
||||||
|
.player {
|
||||||
|
height: 180px;
|
||||||
|
#player-container-id-live {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,22 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="direction-controller">
|
<div class="direction-controller">
|
||||||
<img src="@/assets/images/flightoperation/direction_controller.png" alt="" />
|
<img src="@/assets/images/flightoperation/direction_controller.png" alt="" />
|
||||||
<div class="direction-controller-top" @click="changeDrc('top')"></div>
|
<div class="direction-controller-top" title="前进" @click="changeDrc('pitch', 'top')"></div>
|
||||||
<div class="direction-controller-right" @click="changeDrc('right')"></div>
|
<div
|
||||||
<div class="direction-controller-bottom" @click="changeDrc('bottom')"></div>
|
class="direction-controller-right"
|
||||||
<div class="direction-controller-left" @click="changeDrc('left')"></div>
|
title="右移"
|
||||||
|
@click="changeDrc('roll', 'right')"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
class="direction-controller-bottom"
|
||||||
|
title="后退"
|
||||||
|
@click="changeDrc('pitch', 'bottom')"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
class="direction-controller-left"
|
||||||
|
title="左移"
|
||||||
|
@click="changeDrc('roll', 'left')"
|
||||||
|
></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -73,6 +85,10 @@
|
||||||
);
|
);
|
||||||
|
|
||||||
const obtain = () => {
|
const obtain = () => {
|
||||||
|
if (!getReizeClient()) {
|
||||||
|
createSeizeConnection();
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
// 飞行控制权抢夺
|
// 飞行控制权抢夺
|
||||||
eventsTopic({
|
eventsTopic({
|
||||||
bid: buildGUID(),
|
bid: buildGUID(),
|
||||||
|
|
@ -92,6 +108,7 @@
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
events_replyTopic();
|
events_replyTopic();
|
||||||
|
}, 1000);
|
||||||
};
|
};
|
||||||
// 单拍
|
// 单拍
|
||||||
const singleShot = () => {
|
const singleShot = () => {
|
||||||
|
|
@ -107,15 +124,11 @@
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
// 控制方向
|
// 控制方向
|
||||||
const changeDrc = (val) => {
|
const changeDrc = (type, val) => {
|
||||||
if (val == 'top') {
|
if (val == 'up') {
|
||||||
drcVal.pitch = drcVal.pitch + 20;
|
drcVal[type] = drcVal[type] + 20;
|
||||||
} else if (val == 'bottom') {
|
} else {
|
||||||
drcVal.pitch = drcVal.pitch - 20;
|
drcVal[type] = drcVal[type] - 20;
|
||||||
} else if (val == 'left') {
|
|
||||||
drcVal.roll = drcVal.roll - 20;
|
|
||||||
} else if (val == 'right') {
|
|
||||||
drcVal.roll = drcVal.roll + 20;
|
|
||||||
}
|
}
|
||||||
const querys = {
|
const querys = {
|
||||||
seq: 1,
|
seq: 1,
|
||||||
|
|
@ -125,7 +138,6 @@
|
||||||
drcDownTopic(querys);
|
drcDownTopic(querys);
|
||||||
};
|
};
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// createSeizeConnection();
|
|
||||||
// // 接收消息
|
// // 接收消息
|
||||||
// getReizeClient().on('message', (topic, message) => {
|
// getReizeClient().on('message', (topic, message) => {
|
||||||
// const rs = JSON.parse(message);
|
// const rs = JSON.parse(message);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,289 @@
|
||||||
|
<template>
|
||||||
|
<div class="takeoff-information">
|
||||||
|
<div class="title"
|
||||||
|
>一键起飞
|
||||||
|
<div @click="emits('changeTakeOffForm')">
|
||||||
|
<CloseOutlined />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
<div class="content-edit">
|
||||||
|
目标点纬度
|
||||||
|
<div>
|
||||||
|
<a-input v-model:value="data.target_latitude" readonly />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="content-edit">
|
||||||
|
目标点经度
|
||||||
|
<div>
|
||||||
|
<a-input v-model:value="data.target_longitude" readonly />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="content-edit">
|
||||||
|
目标点高度
|
||||||
|
<div>
|
||||||
|
<a-input v-model:value="data.target_height" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="content-edit">
|
||||||
|
安全起飞高度
|
||||||
|
<div>
|
||||||
|
<a-input v-model:value="data.security_takeoff_height" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="content-edit">
|
||||||
|
返航模式
|
||||||
|
<div>
|
||||||
|
<a-select v-model:value="data.rth_mode" :options="rth_modeOptions" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="content-edit">
|
||||||
|
返航高度
|
||||||
|
<div>
|
||||||
|
<a-input v-model:value="data.rth_altitude" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="content-edit">
|
||||||
|
遥控器失控动作
|
||||||
|
<div>
|
||||||
|
<a-select v-model:value="data.rc_lost_action" :options="rc_lost_actionOptions" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="content-edit">
|
||||||
|
指点飞行失控动作
|
||||||
|
<div>
|
||||||
|
<a-select
|
||||||
|
v-model:value="data.commander_mode_lost_action"
|
||||||
|
:options="commander_mode_lost_actionOptions"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="content-edit">
|
||||||
|
指点飞行模式
|
||||||
|
<div>
|
||||||
|
<a-select
|
||||||
|
v-model:value="data.commander_flight_mode"
|
||||||
|
:options="commander_flight_modeOptions"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="content-edit">
|
||||||
|
指点飞行高度
|
||||||
|
<div>
|
||||||
|
<a-input v-model:value="data.commander_flight_height" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content-button">
|
||||||
|
<a-button
|
||||||
|
type="primary"
|
||||||
|
style="background: #0a99eb; width: 40%"
|
||||||
|
@click="emits('changeTakeOffForm')"
|
||||||
|
>关闭</a-button
|
||||||
|
>
|
||||||
|
<a-button type="primary" style="background: #3a57e8; width: 40%" @click="takeOff"
|
||||||
|
>起飞</a-button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { reactive, ref, watch } from 'vue';
|
||||||
|
import { CopyOutlined, EditOutlined } from '@ant-design/icons-vue';
|
||||||
|
import { timestampToFormattedDate } from '@/utils/index';
|
||||||
|
import { buildGUID, uuid } from '@/utils/uuid';
|
||||||
|
import { servicesTopic, services_replyTopic } from '@/utils/debugging/events';
|
||||||
|
import { vDrag } from '@/utils/drag';
|
||||||
|
import { CloseOutlined } from '@ant-design/icons-vue';
|
||||||
|
|
||||||
|
const emits = defineEmits(['changeTakeOffForm']);
|
||||||
|
const props = defineProps({
|
||||||
|
msgData: Object,
|
||||||
|
});
|
||||||
|
const data = reactive({
|
||||||
|
flight_id: uuid(14, 14),
|
||||||
|
target_latitude: 35.134615,
|
||||||
|
target_longitude: 118.296676,
|
||||||
|
target_height: 115,
|
||||||
|
security_takeoff_height: 100,
|
||||||
|
rth_altitude: 115,
|
||||||
|
rth_mode: 1,
|
||||||
|
max_speed: 10,
|
||||||
|
commander_flight_mode: 1,
|
||||||
|
rc_lost_action: 2,
|
||||||
|
commander_mode_lost_action: 1,
|
||||||
|
commander_flight_height: 115.0,
|
||||||
|
flight_safety_advance_check: 1,
|
||||||
|
simulate_mission: {
|
||||||
|
is_enable: 1, // 是否开启模拟任务{"0":"不开启","1":"开启"}
|
||||||
|
latitude: 35.143567, // 模拟器纬度
|
||||||
|
longitude: 118.305623, // 模拟器经度
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const uavInformation = ref({
|
||||||
|
sub_device: {
|
||||||
|
// 飞行器状态
|
||||||
|
device_online_status: 0,
|
||||||
|
},
|
||||||
|
drone_battery_maintenance_info: {
|
||||||
|
// 电池剩余电量
|
||||||
|
capacity_percent: 0,
|
||||||
|
},
|
||||||
|
wireless_link: {
|
||||||
|
// 飞行器上 Dongle 数量
|
||||||
|
dongle_number: 0,
|
||||||
|
sdr_quality: 0,
|
||||||
|
'4g_quality': 0,
|
||||||
|
'4g_uav_quality': 0,
|
||||||
|
'4g_gnd_quality': 0,
|
||||||
|
remain_upload: 0,
|
||||||
|
sdr_link_state: 0,
|
||||||
|
sdr_freq_band: 0,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const time = ref(timestampToFormattedDate(new Date().getTime()));
|
||||||
|
const rth_modeOptions = ref([
|
||||||
|
{ label: '智能高度', value: 0 },
|
||||||
|
{ label: '设定高度', value: 1 },
|
||||||
|
]);
|
||||||
|
const rc_lost_actionOptions = ref([
|
||||||
|
{ label: '悬停', value: 0 },
|
||||||
|
{ label: '着陆(降落)', value: 1 },
|
||||||
|
{ label: '返航', value: 2 },
|
||||||
|
]);
|
||||||
|
const commander_mode_lost_actionOptions = ref([
|
||||||
|
{ label: '继续执行指点飞行任务', value: 0 },
|
||||||
|
{ label: '退出指点飞行任务,执行普通失控行为', value: 1 },
|
||||||
|
]);
|
||||||
|
const commander_flight_modeOptions = ref([
|
||||||
|
{ label: '智能高度飞行', value: 0 },
|
||||||
|
{ label: '设定高度飞行', value: 1 },
|
||||||
|
]);
|
||||||
|
watch(
|
||||||
|
() => props.msgData,
|
||||||
|
(val) => {
|
||||||
|
if (val.topic == 'thing/product/8UUXN5400A079H/osd') {
|
||||||
|
if (
|
||||||
|
val.message.data.sub_device ||
|
||||||
|
val.message.data.drone_battery_maintenance_info ||
|
||||||
|
val.message.data.wireless_link
|
||||||
|
) {
|
||||||
|
// console.log(val);
|
||||||
|
uavInformation.value = val.message.data;
|
||||||
|
time.value = timestampToFormattedDate(val.message.timestamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
const takeOff = () => {
|
||||||
|
const querys = {
|
||||||
|
bid: buildGUID(),
|
||||||
|
data: data,
|
||||||
|
tid: buildGUID(),
|
||||||
|
timestamp: new Date().getTime(),
|
||||||
|
method: 'takeoff_to_point',
|
||||||
|
};
|
||||||
|
console.log(querys);
|
||||||
|
// servicesTopic(querys);
|
||||||
|
setTimeout(() => {
|
||||||
|
emits('changeTakeOffForm');
|
||||||
|
}, 1000);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.takeoff-information {
|
||||||
|
position: absolute;
|
||||||
|
top: 120px;
|
||||||
|
left: 300px;
|
||||||
|
z-index: 999;
|
||||||
|
width: 460px;
|
||||||
|
padding: 10px;
|
||||||
|
background: #0d0e15;
|
||||||
|
margin: 10px 0 0 10px;
|
||||||
|
box-shadow:
|
||||||
|
0px 10px 30px 0px rgba(0, 0, 6, 0.15),
|
||||||
|
inset 0px 0px 36px 0px rgba(58, 87, 232, 0.73);
|
||||||
|
border-radius: 6px;
|
||||||
|
backdrop-filter: blur(3px);
|
||||||
|
color: #fff;
|
||||||
|
.title {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px 0;
|
||||||
|
box-shadow: 0px 10px 30px 0px rgba(0, 0, 6, 0.15);
|
||||||
|
border-bottom: 1px solid #4e5778;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
span {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.content-title {
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 10px 0;
|
||||||
|
span {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.content-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border-bottom: 1px solid #4e5778;
|
||||||
|
padding: 10px 0;
|
||||||
|
.item-div {
|
||||||
|
width: 49%;
|
||||||
|
img {
|
||||||
|
width: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.content-button {
|
||||||
|
margin-top: 10px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.content-edit {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
// border: 1px solid #4e5778;
|
||||||
|
margin-top: 10px;
|
||||||
|
padding: 2px 10px;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 12px;
|
||||||
|
input {
|
||||||
|
background: none;
|
||||||
|
width: 260px;
|
||||||
|
text-align: right;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
::v-deep .ant-input-number,
|
||||||
|
.ant-input-number-group-wrapper {
|
||||||
|
background: none;
|
||||||
|
width: 260px !important;
|
||||||
|
text-align: right;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
::v-deep .ant-input-number-group-wrapper {
|
||||||
|
input {
|
||||||
|
background: none;
|
||||||
|
width: 260px !important;
|
||||||
|
text-align: right;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
::v-deep .ant-select-selector {
|
||||||
|
background: none;
|
||||||
|
width: 260px;
|
||||||
|
text-align: right;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Loading…
Reference in New Issue