'cameraadd'

This commit is contained in:
yangqiao
2025-02-17 16:43:12 +08:00
parent 45d8686d2f
commit 52845e5133
8 changed files with 281 additions and 119 deletions

View File

@@ -1,14 +1,10 @@
<template>
<div>
<SwitchLanguage />
<!-- <CameraView /> -->
<router-view></router-view>
</div>
</template>
<script setup lang="ts">
import SwitchLanguage from "./components/SwitchLanguage.vue";
// import CameraView from "./components/CameraView/index.vue";
import SwitchLanguage from './components/SwitchLanguage.vue'
</script>
<style scoped>
</style>
<style scoped></style>

View File

@@ -4,6 +4,42 @@
left: 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 99;
background: rgba(0,0,0,0.4);
background: rgba(0, 0, 0, 0.4);
.header_box {
width: 50%;
display: flex;
justify-content: flex-end;
padding: 10px 0;
box-sizing: border-box;
}
.img_box {
width: 50vh;
height: 50vh;
display: flex;
align-items: center;
justify-content: center;
padding: 0;
margin: 0;
.icon_box {
animation: spin 2s linear infinite;
}
}
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}

View File

@@ -1,43 +1,86 @@
<template>
<div class="camera_box">
<img :src="imgOneVal" alt="" style="width: 50vw; height: 50vh">
<img :src="imgTwoVal" alt="" style="width: 50vw; height: 50vh">
<div class="header_box">
<el-icon color="#fff" size="20" @click="closeCamera"
><CircleClose
/></el-icon>
</div>
<div class="img_box">
<!-- <el-icon class="icon_box" color="#fff" size="36" v-show="!loading"
><Loading
/></el-icon> -->
<img
:src="imgOneVal"
style="width: 50vw; height: 50vh"
alt=""
v-show="cameraNumber === 1"
/>
<img
:src="imgTwoVal"
style="width: 50vw; height: 50vh"
alt=""
v-show="cameraNumber === 2"
/>
</div>
<!-- <canvas ref="cameraOne" style="width: 50vw; height: 50vh"></canvas> -->
<!-- <canvas ref="cameraTwo" style="width: 50vw; height: 50vh"></canvas> -->
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from "vue";
import useWebSocket from "../../utils/websocket";
const videoElement = ref<HTMLVideoElement | null>(null);
<script setup lang="ts">
import { ref, onMounted, onUnmounted, defineExpose, defineEmits } from 'vue'
import useWebSocket from '../../utils/websocket'
import { Loading } from '@element-plus/icons-vue'
const videoElement = ref<HTMLVideoElement | null>(null)
// const cameraOne = ref("")
// const cameraTwo = ref("");
const imgOneVal = ref("");
const imgTwoVal = ref("");
// const videoUrl = ref('');
const imgOneVal = ref('')
const imgTwoVal = ref('')
const loading = ref<boolean>(false)
const handleMessage = (e: any) => {
imgOneVal.value = "data:image/jpeg;base64," + e.data
};
const handleTwoMessage = (e: any) => {
imgTwoVal.value = "data:image/jpeg;base64," + e.data
};
const ws = useWebSocket(handleMessage, import.meta.env.VITE_WB_CAMERA_ONE_URL);
const wsTwo = useWebSocket(handleTwoMessage, import.meta.env.VITE_WB_CAMERA_TWO_URL);
// const ws = new WebSocket(import.meta.env.VITE_WB_CAMERA_ONE_URL)
onMounted(() => {
});
onUnmounted(() => {
if (ws) {
ws.close();
ws = null;
wsTwo.close();
wsTwo = null;
imgOneVal.value = 'data:image/jpeg;base64,' + e.data
if (!loading.value && imgOneVal.value) {
loading.value = true
}
});
}
const handleTwoMessage = (e: any) => {
imgTwoVal.value = 'data:image/jpeg;base64,' + e.data
if (!loading.value && imgTwoVal.value) {
loading.value = true
}
}
const cameraNumber = ref<Number>(0)
const ws = useWebSocket(handleMessage, import.meta.env.VITE_WB_CAMERA_ONE_URL)
const wsTwo = useWebSocket(
handleTwoMessage,
import.meta.env.VITE_WB_CAMERA_TWO_URL
)
const emit = defineEmits(['closeCamera'])
// const ws = new WebSocket(import.meta.env.VITE_WB_CAMERA_ONE_URL)
onMounted(() => {})
const closeCamera = () => {
cameraNumber.value = 0
emit('closeCamera')
}
const closeWs = () => {
if (ws) {
ws.handleClose()
ws = null
}
}
const closeWsTwo = () => {
if (wsTwo) {
wsTwo.handleClose()
wsTwo = null
}
}
defineExpose({ cameraNumber })
onUnmounted(() => {
closeWs()
closeWsTwo()
})
</script>
<style scoped>
@import "./index.less";
<style scoped>
@import './index.less';
</style>

View File

@@ -0,0 +1,4 @@
.process_box {
width: 100%;
height: 100%;
}

View File

@@ -0,0 +1,12 @@
<template>
<div class="process_box" v-show="isCollapse"></div>
</template>
<script setup lang="ts">
import { ref, defineExpose, defineEmits } from 'vue'
const isCollapse = ref<boolean>(false)
</script>
<style scoped>
@import './index.less';
</style>

View File

@@ -7,7 +7,7 @@
:id="`${num}title`"
>
<div class="title-box">
<p>{{generateTitle('问题设定')}}:</p>
<p>{{ generateTitle('问题设定') }}:</p>
<span>{{ key.title }}</span>
</div>
<div
@@ -18,29 +18,44 @@
>
<div class="title">
<img src="../../assets/logo.png" alt="" />
<span v-if="item.source === 'Planner'">{{generateTitle('角色')}}{{ item.source }}</span>
<span v-else>{{generateTitle('模型名称')}}{{ `${item.source}` }}</span>
<span v-if="item.source === 'Planner'"
>{{ generateTitle('角色') }}{{ item.source }}</span
>
<span v-else
>{{ generateTitle('模型名称') }}{{ `${item.source}` }}</span
>
<!-- <span v-else>{{generateTitle('模型名称')}}{{ `${item.source}: ${item.agent_name}` }}</span> -->
<p
class="active_item"
v-if="reasonStatus.index === index && reasonStatus.show"
v-if="key.children.length - 1 === index && reasonStatus.show"
>
<img src="../../assets/layout/vector.png" alt="" />
{{generateTitle('推理中')}}...
{{ generateTitle('推理中') }}...
</p>
</div>
<div class="reasoning-content">
<div
class="reasoning-text"
:class="{
active: reasonStatus.index === index && reasonStatus.show
active: key.children.length - 1 === index && reasonStatus.show
}"
>
<div
style="font-size: 14px"
:class="{ 'show-box': current[index] }"
>
<MdPreview style="background: linear-gradient(to bottom,#d5e6f4 0%,#afceea 50%,#c2d9ef 100%);" :editorId="id" :modelValue="item.content" />
<MdPreview
style="
background: linear-gradient(
to bottom,
#d5e6f4 0%,
#afceea 50%,
#c2d9ef 100%
);
"
:editorId="id"
:modelValue="item.content"
/>
</div>
</div>
<div class="icon-box">
@@ -54,7 +69,11 @@
class="complete-box"
v-if="completeList[num].show && num === completeList[num].index"
>
{{ generateTitle('推理完成,如果希望了解更多可继续在下面框中提问或新建对话。')}}
{{
generateTitle(
'推理完成,如果希望了解更多可继续在下面框中提问或新建对话。'
)
}}
</div>
</div>
</div>
@@ -63,7 +82,7 @@
import { ref, defineExpose, defineEmits, defineProps } from 'vue'
import { Plus, Minus } from '@element-plus/icons-vue'
import { MdPreview } from 'md-editor-v3'
import {generateTitle} from '../../utils/i18n'
import { generateTitle } from '../../utils/i18n'
import 'md-editor-v3/lib/style.css'
const props: any = defineProps({
reasoningList: {

View File

@@ -71,4 +71,25 @@
}
}
.camera_dialog {
position: fixed;
top: 0;
left: 66px;
z-index: 99;
display: flex;
align-items: center;
column-gap: 12px;
.camera_item {
display: flex;
align-items: center;
flex-direction: column;
cursor: pointer;
span {
font-size: 12px;
color: #fff;
}
}
}
}

View File

@@ -3,7 +3,7 @@
<div
class="content-left"
:style="{
width: isCollapse ? 'calc(100% - 200px)' : 'calc(100% - 7px)',
width: isCollapse ? 'calc(100% - 200px)' : 'calc(100% - 7px)'
}"
>
<div class="body-box" ref="container">
@@ -17,10 +17,10 @@
<div class="tip-box">
<p class="active_item">
<el-icon size="6" color="#fff"><Plus /></el-icon>
{{ generateTitle("新建对话") }}
{{ generateTitle('新建对话') }}
</p>
<div class="tip-text" v-show="disableStatus">
{{ generateTitle("回答输出中暂不能再次提问") }}
{{ generateTitle('回答输出中暂不能再次提问') }}
</div>
</div>
<TextareaView ref="textareaRef" :minRows="1" @submitFun="submitFun" />
@@ -31,28 +31,53 @@
:reasoningList="reasoningList"
@changeStatusFun="changeStatusFun"
/>
<div class="camera_dialog">
<div class="camera_item" @click="cameraFun(1)">
<el-icon color="#fff" size="16"><VideoCameraFilled /></el-icon>
<span>监控1</span>
</div>
<div class="camera_item" @click="cameraFun(2)">
<el-icon color="#fff" size="16"><VideoCameraFilled /></el-icon>
<span>监控2</span>
</div>
</div>
<CameraView
ref="cameraViewRef"
v-show="cameraShow"
@closeCamera="closeCamera"
/>
</div>
</template>
<script setup lang="ts">
import ReasoningView from "../../components/ReasoningView/index.vue";
import TextareaView from "../../components/TextareaView.vue";
import collapseView from "../../components/collapseView/index.vue";
import { Plus } from "@element-plus/icons-vue";
import { ref, onMounted, nextTick } from "vue";
import ReasoningView from '../../components/ReasoningView/index.vue'
import TextareaView from '../../components/TextareaView.vue'
import collapseView from '../../components/collapseView/index.vue'
import CameraView from '../../components/CameraView/index.vue'
import { Plus, VideoCameraFilled } from '@element-plus/icons-vue'
import { ref, onMounted, nextTick } from 'vue'
// import { getModelList } from '../../api/user'
import { useRoute } from "vue-router";
import useWebSocket from "../../utils/websocket";
import { useRoute } from 'vue-router'
import useWebSocket from '../../utils/websocket'
// import { getAgent } from '../../utils/agent'
import { generateTitle } from "../../utils/i18n";
const route: any = useRoute();
const reasoningRef = ref<any>(null);
const textareaRef = ref<any>(null);
const collapseRef = ref<any>(null);
const isCollapse = ref<boolean>(true);
import { generateTitle } from '../../utils/i18n'
const route: any = useRoute()
const reasoningRef = ref<any>(null)
const textareaRef = ref<any>(null)
const collapseRef = ref<any>(null)
const isCollapse = ref<boolean>(true)
const cameraShow = ref<boolean>(false)
const cameraViewRef = ref<any>(null)
const changeStatusFun = (val: boolean) => {
isCollapse.value = val;
};
const reasoningList = ref<Array<any>>([]);
isCollapse.value = val
}
const cameraFun = (val: number) => {
cameraShow.value = true
cameraViewRef.value.cameraNumber = val
}
const closeCamera = () => {
cameraShow.value = false
}
const reasoningList = ref<Array<any>>([])
// const getModelListFun = async () => {
// try {
// const { data, code } = await getModelList()
@@ -64,76 +89,82 @@ const reasoningList = ref<Array<any>>([]);
// }
// }
const submitFun = (val: any) => {
completeFun();
addMode(JSON.parse(val).content);
ws.send(val);
};
completeFun()
addMode(JSON.parse(val).content)
ws.send(val)
}
const addMode = (val: any) => {
endStatus.value = false;
endStatus.value = false
reasoningList.value.push({
title: val,
children: [],
});
children: []
})
reasoningRef.value.completeList.push({
show: false,
index: reasoningRef.value.completeList.length,
});
};
const disableStatus = ref(false);
index: reasoningRef.value.completeList.length
})
}
const disableStatus = ref(false)
const completeFun = () => {
disableStatus.value = true;
textareaRef.value.disableStatus = true;
};
disableStatus.value = true
textareaRef.value.disableStatus = true
}
const handleMessage = (e: any) => {
getMessage(e.data);
getHeight();
};
const endStatus = ref(false);
getMessage(e.data)
getHeight()
}
const endStatus = ref(false)
const getMessage = async (e: any) => {
reasoningRef.value.reasonStatus.show = true;
let data = JSON.parse(e);
if (data.content) {
let list = reasoningList.value[reasoningList.value.length - 1].children;
let status = list.filter(
(key: any) =>
key.group_name === data.group_name && key.agent_name === data.agent_name
)[0];
if (list.length && status && status.agent_name) {
for (let i = 0; i < list.length; i++) {
const item = list[i];
if (
item.group_name === data.group_name &&
item.agent_name === data.agent_name
) {
item.content += data.content;
}
}
} else {
list.push(JSON.parse(e));
}
reasoningRef.value.reasonStatus.show = true
let data = JSON.parse(e)
if (data.type === 'UserInputRequestedEvent') {
disableStatus.value = false
textareaRef.value.disableStatus = false
reasoningRef.value.reasonStatus.show = false
}
};
const ws = useWebSocket(handleMessage,'');
if (data.content) {
let list = reasoningList.value[reasoningList.value.length - 1].children
list.push(data)
// let status = list.filter(
// (key: any) =>
// key.group_name === data.group_name && key.agent_name === data.agent_name
// )[0]
// if (list.length && status && status.agent_name) {
// for (let i = 0; i < list.length; i++) {
// const item = list[i]
// if (
// item.group_name === data.group_name &&
// item.agent_name === data.agent_name
// ) {
// item.content += data.content
// }
// }
// } else {
// list.push(JSON.parse(e))
// }
}
}
const ws = useWebSocket(handleMessage, '')
const sendFun = () => {
setTimeout(() => {
addMode(JSON.parse(route.query.content).content);
completeFun();
ws.send(route.query.content);
}, 300);
};
const container = ref<any>(null);
addMode(JSON.parse(route.query.content).content)
completeFun()
ws.send(route.query.content)
}, 300)
}
const container = ref<any>(null)
const getHeight = () => {
container.value.scrollTop = container.value.scrollHeight + 150;
collapseRef.value.scrollTop = collapseRef.value.scrollHeight + 50;
};
container.value.scrollTop = container.value.scrollHeight + 150
collapseRef.value.scrollTop = collapseRef.value.scrollHeight + 50
}
onMounted(() => {
// getModelListFun();
nextTick(() => {
getHeight();
sendFun();
});
});
getHeight()
sendFun()
})
})
</script>
<style scoped>
@import "./index.less";
@import './index.less';
</style>