|
@@ -1,116 +1,129 @@
|
|
|
<template>
|
|
|
- <RightFillPano>
|
|
|
+ <RightFillPano>
|
|
|
<template #header>
|
|
|
<div class="tabs" v-if="positionList.length > 0">
|
|
|
<span class="tabs-left">行动录制</span>
|
|
|
<div class="tabs-right">
|
|
|
- <span v-if="!isRecord"></span>
|
|
|
- <span v-else class="timer-display">{{ formatTime(recordingTime) }}</span>
|
|
|
- <span class="tabs-right-img">
|
|
|
- <img v-show="!isRecord" src="@/assets/record_n.svg" alt="" @click="startRecord('start')">
|
|
|
- <img v-show="isRecord" src="@/assets/record_s.svg" alt="" @click="startRecord('stop')">
|
|
|
- </span>
|
|
|
+ <span v-if="!isRecord"></span>
|
|
|
+ <span v-else class="timer-display">{{ formatTime(recordingTime) }}</span>
|
|
|
+ <span class="tabs-right-img">
|
|
|
+ <img
|
|
|
+ v-show="!isRecord"
|
|
|
+ src="@/assets/record_n.svg"
|
|
|
+ alt=""
|
|
|
+ @click="startRecord('start')"
|
|
|
+ />
|
|
|
+ <img
|
|
|
+ v-show="isRecord"
|
|
|
+ src="@/assets/record_s.svg"
|
|
|
+ alt=""
|
|
|
+ @click="startRecord('stop')"
|
|
|
+ />
|
|
|
+ </span>
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
|
<mediaList v-if="positionList.length > 0" />
|
|
|
- <div v-else class="positioning-content">
|
|
|
- 暂无定位信息或已结束定位
|
|
|
- </div>
|
|
|
+ <div v-else class="positioning-content">暂无定位信息或已结束定位</div>
|
|
|
</RightFillPano>
|
|
|
</template>
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
import { RightFillPano } from "@/layout";
|
|
|
-import { postAddPathInPosition, postInsertAnimationModelInPosition } from '@/api'
|
|
|
+import { postAddPathInPosition, postInsertAnimationModelInPosition } from "@/api";
|
|
|
import mediaList from "./components/mediaList.vue";
|
|
|
import { nextTick, ref, onUnmounted } from "vue";
|
|
|
import { positionList, paths, initialPaths } from "@/store";
|
|
|
import { initialAnimationModels } from "@/store/animation";
|
|
|
import { sdk } from "@/sdk";
|
|
|
+import { showLeftCtrlPanoStack, showLeftPanoStack } from "@/env";
|
|
|
+import { mergeFuns } from "@/components/drawing/hook";
|
|
|
|
|
|
const isRecord = ref(false);
|
|
|
const startTime = ref<number>(0);
|
|
|
const endTime = ref<number>(0);
|
|
|
const recordingTime = ref<number>(0);
|
|
|
-let timer: NodeJS.Timeout | null = null;
|
|
|
|
|
|
nextTick(() => {
|
|
|
-// enterEdit();
|
|
|
+ // enterEdit();
|
|
|
});
|
|
|
|
|
|
// 格式化时间为 HH:MM:SS 格式
|
|
|
const formatTime = (seconds: number): string => {
|
|
|
- const hours = Math.floor(seconds / 3600);
|
|
|
- const minutes = Math.floor((seconds % 3600) / 60);
|
|
|
- const secs = seconds % 60;
|
|
|
-
|
|
|
- return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
|
|
|
+ const hours = Math.floor(seconds / 3600);
|
|
|
+ const minutes = Math.floor((seconds % 3600) / 60);
|
|
|
+ const secs = seconds % 60;
|
|
|
+
|
|
|
+ return `${hours.toString().padStart(2, "0")}:${minutes
|
|
|
+ .toString()
|
|
|
+ .padStart(2, "0")}:${secs.toString().padStart(2, "0")}`;
|
|
|
};
|
|
|
|
|
|
+let cleanup: () => void;
|
|
|
const startRecord = (type: string) => {
|
|
|
- if (type === 'start') {
|
|
|
- // 开始录制
|
|
|
- isRecord.value = true;
|
|
|
- startTime.value = Date.now(); // 记录开始时间戳
|
|
|
- recordingTime.value = 0;
|
|
|
-
|
|
|
- // 启动计时器,每秒更新一次
|
|
|
- timer = setInterval(() => {
|
|
|
- recordingTime.value = Math.floor((Date.now() - startTime.value) / 1000);
|
|
|
- }, 1000);
|
|
|
- sdk.startRecordPath()
|
|
|
- } else {
|
|
|
- // 停止录制
|
|
|
- isRecord.value = false;
|
|
|
- endTime.value = Date.now(); // 记录结束时间戳
|
|
|
-
|
|
|
- // 清除计时器
|
|
|
- if (timer) {
|
|
|
- clearInterval(timer);
|
|
|
- timer = null;
|
|
|
- }
|
|
|
-
|
|
|
- // 重置录制时间
|
|
|
- recordingTime.value = 0;
|
|
|
-
|
|
|
- console.log('录制时间段:', {
|
|
|
- startTime: startTime.value,
|
|
|
- endTime: endTime.value,
|
|
|
- duration: endTime.value - startTime.value
|
|
|
- });
|
|
|
- // 这里调path接口传路线数据过去,有几个设备就生成几个path
|
|
|
- let positionPaths = sdk.generateAniPathData() || []
|
|
|
- positionPaths.forEach(async(positionPath: any) => {
|
|
|
- await postAddPathInPosition(positionPath, startTime.value, endTime.value)
|
|
|
- })
|
|
|
-
|
|
|
- // 生成动画模型数据接口(等钟文返回动画数据am)
|
|
|
- // await postInsertAnimationModelInPosition(am)
|
|
|
- //获取一次列表
|
|
|
- setTimeout(async () => {
|
|
|
- await initialPaths()
|
|
|
- // 刷新动画列表
|
|
|
- // await initialAnimationModels()
|
|
|
- }, 500)
|
|
|
- }
|
|
|
+ if (type === "start") {
|
|
|
+ // 开始录制
|
|
|
+ isRecord.value = true;
|
|
|
+ startTime.value = Date.now(); // 记录开始时间戳
|
|
|
+ recordingTime.value = 0;
|
|
|
+
|
|
|
+ // 启动计时器,每秒更新一次
|
|
|
+ const timer = setInterval(() => {
|
|
|
+ recordingTime.value = Math.floor((Date.now() - startTime.value) / 1000);
|
|
|
+ }, 1000);
|
|
|
+ sdk.startRecordPath();
|
|
|
+
|
|
|
+ cleanup = mergeFuns(() => {
|
|
|
+ clearInterval(timer);
|
|
|
+
|
|
|
+ isRecord.value = false;
|
|
|
+ endTime.value = Date.now(); // 记录结束时间戳
|
|
|
+ // 重置录制时间
|
|
|
+ recordingTime.value = 0;
|
|
|
+
|
|
|
+ console.log("录制时间段:", {
|
|
|
+ startTime: startTime.value,
|
|
|
+ endTime: endTime.value,
|
|
|
+ duration: endTime.value - startTime.value,
|
|
|
+ });
|
|
|
+ if (dispose) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 这里调path接口传路线数据过去,有几个设备就生成几个path
|
|
|
+ let positionPaths = sdk.generateAniPathData() || [];
|
|
|
+ positionPaths.forEach(async (positionPath: any) => {
|
|
|
+ await postAddPathInPosition(positionPath, startTime.value, endTime.value);
|
|
|
+ });
|
|
|
+
|
|
|
+ // 生成动画模型数据接口(等钟文返回动画数据am)
|
|
|
+ // await postInsertAnimationModelInPosition(am)
|
|
|
+ //获取一次列表
|
|
|
+ setTimeout(async () => {
|
|
|
+ await initialPaths();
|
|
|
+ // 刷新动画列表
|
|
|
+ // await initialAnimationModels()
|
|
|
+ }, 500);
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ cleanup();
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
+let dispose = false;
|
|
|
// 组件卸载时清理计时器
|
|
|
onUnmounted(() => {
|
|
|
- if (timer) {
|
|
|
- clearInterval(timer);
|
|
|
- timer = null;
|
|
|
- }
|
|
|
+ dispose = true;
|
|
|
+ cleanup && cleanup();
|
|
|
});
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
-.positioning-content{
|
|
|
+.positioning-content {
|
|
|
display: flex;
|
|
|
justify-content: center;
|
|
|
padding-top: 60px;
|
|
|
}
|
|
|
+
|
|
|
.tabs {
|
|
|
height: 60px;
|
|
|
border-bottom: 1px solid rgba(255, 255, 255, 0.16);
|
|
@@ -120,26 +133,31 @@ onUnmounted(() => {
|
|
|
margin: -20px;
|
|
|
padding: 0 20px;
|
|
|
margin-bottom: 20px;
|
|
|
+
|
|
|
.tabs-left {
|
|
|
font-size: 16px;
|
|
|
font-weight: blod;
|
|
|
color: #fff;
|
|
|
}
|
|
|
+
|
|
|
.tabs-right {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
gap: 10px;
|
|
|
+
|
|
|
.timer-display {
|
|
|
- font-family: 'Courier New', monospace;
|
|
|
+ font-family: "Courier New", monospace;
|
|
|
font-weight: bold;
|
|
|
- color: #FFFFFF;
|
|
|
+ color: #ffffff;
|
|
|
font-size: 14px;
|
|
|
min-width: 65px;
|
|
|
text-align: center;
|
|
|
}
|
|
|
+
|
|
|
.tabs-right-img {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
img {
|
|
|
width: 20px;
|
|
|
height: 20px;
|
|
@@ -148,4 +166,4 @@ onUnmounted(() => {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-</style>
|
|
|
+</style>
|