2 Commits
prod ... master

Author SHA1 Message Date
fyy
f230decc38 style: 格式化代码、修改弹窗样式 2025-08-28 14:29:58 +08:00
lxj
d2102ac20a 视频流适配内外网 2025-08-28 09:10:56 +08:00
5 changed files with 55 additions and 86 deletions

View File

@@ -1,5 +1,7 @@
export interface AddStreamProxyResult { export interface AddStreamProxyResult {
key:string; key:string;
app:string;
streamId:string;
rtsp:string; rtsp:string;
rtmp:string; rtmp:string;
flv:string; flv:string;

View File

@@ -1,8 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue'; import { ref } from 'vue';
import { Page, useVbenModal, type VbenFormProps } from '@vben/common-ui'; import { Page, useVbenModal, type VbenFormProps } from '@vben/common-ui';
import { Space } from 'ant-design-vue'; import { Space } from 'ant-design-vue';
import { useVbenVxeGrid, type VxeGridProps } from '#/adapter/vxe-table'; import { useVbenVxeGrid, type VxeGridProps } from '#/adapter/vxe-table';
@@ -57,10 +57,6 @@ async function externalLoginOnLoad() {
if (!response.ok) { if (!response.ok) {
throw new Error(`Request failed: ${response.status}`); throw new Error(`Request failed: ${response.status}`);
} }
const result2 = await response.json();
console.log(result2);
// }
} }
} catch (error) { } catch (error) {
console.error('External login error:', error); console.error('External login error:', error);
@@ -94,12 +90,8 @@ const gridOptions: VxeGridProps = {
proxyConfig: { proxyConfig: {
ajax: { ajax: {
query: async ({ page }, formValues = {}) => { query: async ({ page }, formValues = {}) => {
// 修改添加对token的使用如果token存在则请求外部接口否则使用原接口
console.log(1243);
sessionStorage.removeItem('token'); sessionStorage.removeItem('token');
await externalLoginOnLoad(); await externalLoginOnLoad();
console.log(23423310248);
if (token.value) { if (token.value) {
try { try {
const response = await fetch( const response = await fetch(
@@ -113,17 +105,6 @@ const gridOptions: VxeGridProps = {
Accept: 'application/json, text/plain, */*', Accept: 'application/json, text/plain, */*',
}, },
body: JSON.stringify({ body: JSON.stringify({
// pageReq: {
// pageNum: page.currentPage,
// pageSize: page.pageSize,
// },
// parkStates: parkStates.value,
// parkOrderTypes: [100, 200, 201, 300, 500],
// plNos: ['PFN000000022', 'PFN000000012', 'PFN000000025'],
// terminalSource: 50,
// orderStates: [],
// orgId: 10012,
// ...formValues,
pageReq: { pageReq: {
pageNum: page.currentPage, pageNum: page.currentPage,
pageSize: page.pageSize, pageSize: page.pageSize,
@@ -135,19 +116,12 @@ const gridOptions: VxeGridProps = {
orderStates: [], orderStates: [],
parkOrderTypes: [100, 200, 201, 300, 500], parkOrderTypes: [100, 200, 201, 300, 500],
terminalSource: 50, terminalSource: 50,
// plNos、carNumber、orgId、orderStates、parkOrderTypes、terminalSource为接口参数固定需求
// parkStates10-在场、20-离场
}), }),
}, },
); );
// if (!response.ok) {
// throw new Error(
// `External API request failed: ${response.status}`,
// );
// }
const result = await response.json(); const result = await response.json();
console.log(result);
// 根据返回数据结构调整 // 根据返回数据结构调整
return { return {
rows: result.data.dataList || [], rows: result.data.dataList || [],

View File

@@ -76,7 +76,6 @@ const [BasicModal, modalApi] = useVbenModal({
for (const item of result.data) { for (const item of result.data) {
if (item.fileName.includes('进场图片')) { if (item.fileName.includes('进场图片')) {
data.parkInImgPath = item.filePath; data.parkInImgPath = item.filePath;
console.log('图片路径:', data.parkInImgPath);
} else { } else {
data.parkOutImgPath = item.filePath; data.parkOutImgPath = item.filePath;
} }

View File

@@ -5,13 +5,9 @@ import { useVbenModal } from '@vben/common-ui';
const emit = defineEmits<{ reload: [] }>(); const emit = defineEmits<{ reload: [] }>();
const picture1 = ref('') const pictureUrl = ref('');
// const { onBeforeClose, markInitialized, resetInitialized } = useBeforeCloseDiff( const monitorPictureUrl = ref('');
// { const voucherUrl = ref('');
// initializedGetter: defaultFormValueGetter(formApi),
// currentGetter: defaultFormValueGetter(formApi),
// },
// );
const [BasicModal, modalApi] = useVbenModal({ const [BasicModal, modalApi] = useVbenModal({
// 在这里更改宽度 // 在这里更改宽度
@@ -23,22 +19,11 @@ const [BasicModal, modalApi] = useVbenModal({
if (!isOpen) { if (!isOpen) {
return null; return null;
} }
const {data} = modalApi.getData() as { data:any };
console.log(data)
picture1.value = data.pictureUrl;
// detail.value = await meetInfo(id);
// if (detail.value?.picture) {
// const res = await ossInfo([conferenceSettingsDetail.value?.picture]);
// if (res) {
// let imgArr = [] as string[];
// res.forEach(item => {
// imgArr.push(item.url)
// })
// conferenceSettingsDetail.value.pictureArr = imgArr;
// }
// }
modalApi.modalLoading(true); modalApi.modalLoading(true);
const { data } = modalApi.getData() as { data: any };
pictureUrl.value = data.pictureUrl;
monitorPictureUrl.value = data.monitorPictureUrl;
voucherUrl.value = data.voucherUrl;
modalApi.modalLoading(false); modalApi.modalLoading(false);
}, },
}); });
@@ -54,28 +39,38 @@ async function handleConfirm() {
modalApi.lock(false); modalApi.lock(false);
} }
} }
async function handleClosed() {} async function handleClosed() {
pictureUrl.value = '';
monitorPictureUrl.value = '';
voucherUrl.value = '';
}
</script> </script>
<template> <template>
<BasicModal title="抓拍图片"> <BasicModal title="抓拍图片">
<div class="detail-wrapper"> <div class="detail-wrapper">
<div class="detail-grid"> <div class="detail-grid">
<div class="detail-card"> <div class="detail-card">
<img class="detail-thumb" :src="picture1"></img> <div class="detail-thumb">
<div class="detail-caption">人脸凭证照片</div> <img v-if="voucherUrl" :src="voucherUrl" />
</div>
<div class="detail-caption">人脸凭证照片</div>
</div>
<div class="detail-card">
<div class="detail-thumb">
<img v-if="monitorPictureUrl" :src="monitorPictureUrl" />
</div>
<div class="detail-caption">监控设备抓拍</div>
</div>
<div class="detail-card">
<div class="detail-thumb">
<img v-if="pictureUrl" :src="pictureUrl" />
</div>
<div class="detail-caption">人脸门禁抓拍</div>
</div>
</div>
</div> </div>
<div class="detail-card"> </BasicModal>
<img class="detail-thumb" :src="picture1"></img>
<div class="detail-caption">监控设备抓拍</div>
</div>
<div class="detail-card">
<img class="detail-thumb" :src="picture1"></img>
<div class="detail-caption">人脸门禁抓拍</div>
</div>
</div>
</div>
</BasicModal>
</template> </template>
<style scoped> <style scoped>
@@ -93,10 +88,6 @@ async function handleClosed() {}
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
background-color: #fff;
border-radius: 8px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.08);
padding: 16px;
} }
.detail-thumb { .detail-thumb {

View File

@@ -2,11 +2,8 @@
<Page class="h-full w-full"> <Page class="h-full w-full">
<!-- 设备分组区域 --> <!-- 设备分组区域 -->
<div class="flex h-full gap-[8px]"> <div class="flex h-full gap-[8px]">
<div class="h-full pb-[5px] c-tree bg-background"> <div class="c-tree bg-background h-full pb-[5px]">
<ChannelTree <ChannelTree class="w-[300px]" @check="onNodeChecked" />
class="w-[300px]"
@check="onNodeChecked"
/>
</div> </div>
<!-- 设备分组区域 --> <!-- 设备分组区域 -->
@@ -52,7 +49,7 @@ import { Page } from '@vben/common-ui';
import ChannelTree from './channel-tree.vue'; import ChannelTree from './channel-tree.vue';
import mpegts from 'mpegts.js'; import mpegts from 'mpegts.js';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import { addFFmpegStreamProxy, addStreamProxy } from '#/api/sis/stream'; import { addStreamProxy } from '#/api/sis/stream';
import { import {
Svg16FrameIcon, Svg16FrameIcon,
Svg1FrameIcon, Svg1FrameIcon,
@@ -296,8 +293,8 @@ function streamProxy(nodeData: any, cb: Function) {
if (isSupportH265) { if (isSupportH265) {
addStreamProxy(params).then((res) => cb(res)); addStreamProxy(params).then((res) => cb(res));
} else { } else {
addFFmpegStreamProxy(params).then((res) => cb(res)); // addFFmpegStreamProxy(params).then((res) => cb(res));
// addStreamProxy(params).then((res) => cb(res)); addStreamProxy(params).then((res) => cb(res));
} }
} }
@@ -310,7 +307,8 @@ function doPlayer(nodeData: any, index: number = 0) {
console.log('index=', index); console.log('index=', index);
if (mpegts.isSupported()) { if (mpegts.isSupported()) {
streamProxy(nodeData, (res: AddStreamProxyResult) => { streamProxy(nodeData, (res: AddStreamProxyResult) => {
const url = res.wsFlv; const host = window.location.host;
const url = `http://${host}/${res.app}/${res.streamId}.live.flv`;
// 将url 绑定到 nodeData // 将url 绑定到 nodeData
nodeData.url = url; nodeData.url = url;
closePlayer(index); closePlayer(index);
@@ -337,7 +335,9 @@ function doPlayer(nodeData: any, index: number = 0) {
player.play(); player.play();
playerList[index] = { playerList[index] = {
player, player,
key: nodeData.id,
data: nodeData, data: nodeData,
el: videoElement,
}; };
} else { } else {
console.log('视频播放元素获取异常'); console.log('视频播放元素获取异常');
@@ -381,10 +381,13 @@ function catchUp() {
if (playerData) { if (playerData) {
const { player, el } = playerData; const { player, el } = playerData;
const end = player.buffered.end(player.buffered.length - 1); const end = player.buffered.end(player.buffered.length - 1);
const diff = end - el.currentTime; const { currentTime } = el;
if (diff > 2) { if (end && currentTime) {
// 如果延迟超过2秒 const diff = end - el.currentTime;
el.currentTime = end - 0.5; // 跳转到接近直播点 if (diff > 2) {
// 如果延迟超过2秒
el.currentTime = end - 0.5; // 跳转到接近直播点
}
} }
} }
}); });