This commit is contained in:
1378012178@qq.com 2025-03-19 09:47:36 +08:00
commit 4a2e668204
8 changed files with 196 additions and 95 deletions

View File

@ -17,7 +17,7 @@
</a-row>
<a-row style="margin-top: 14px">
<a-col :span="4" class="labelText">
画面镜像
画面翻转
</a-col>
<a-col :span="8">
<a-select v-model:value="formData.flip_type" @change="(value) => changeSwitch('flip_type', value)">
@ -27,17 +27,6 @@
<a-select-option value="center">中心</a-select-option>
</a-select>
</a-col>
<a-col :span="4" class="labelText">
画面翻转
</a-col>
<a-col :span="8">
<a-select v-model:value="formData.rotate_type" @change="(value) => changeSwitch('rotate_type', value)">
<a-select-option value="off">关闭</a-select-option>
<a-select-option value="anticlockwise_180">上下翻转</a-select-option>
<a-select-option value="anticlockwise_90">左翻转90°</a-select-option>
<a-select-option value="clockwise_90">右翻转90°</a-select-option>
</a-select>
</a-col>
</a-row>
<a-row style="margin-top: 14px">
<a-col :span="1"></a-col>
@ -255,9 +244,8 @@ import {
smartwtl: "auto_wtl",//"auto_wtl_ae" //- "auto_wtl" //- "manual" //
smartwtl_digital_level: "0",//
flip_type: "center",// "off"// "left_and_right"// "up_and_down"// "center"//
flip_type: "center",// "off"// "left_and_right"// "up_and_down"// "center"//
night_vision_mode: "md_night_vision",//"wtl_night_vision"// "inf_night_vision"// "md_night_vision"//
rotate_type: "off",// "off"// "anticlockwise_180"//180 "clockwise_90"//90 "anticlockwise_90"//90
});
const player = ref();
@ -268,6 +256,7 @@ import {
/**
* 恢复默认
*/
function restoreDefault(){
if(formData.deviceIndex==''){
return
@ -362,9 +351,8 @@ import {
"type": "switch"
}).then(res=>{
// console.log(res);
formData.flip_type = res.flip_type; //
formData.flip_type = res.flip_type; //
formData.night_vision_mode = res.night_vision_mode; //
formData.rotate_type = res.rotate_type; // 使
});
}

View File

@ -52,6 +52,7 @@
const formData = reactive<Record<string, any>>({
//
videoDevId: '',//
storageDevId: '',//ID
multitrans: '',//IPCmultitrans
startTime: '',//
endTime: '',//
@ -97,52 +98,33 @@
});
//
await getMultitransUrl({
"deviceIndex":formData.videoDevId,
"startTime":formData.startTime,
"endTime":formData.endTime,
"scale":formData.scale
"videoDevId":formData.videoDevId
}).then(res=>{
confirmLoading.value=false;
if(res.success == false){
createMessage.error(res.message)
}else{
const list = res;
list.forEach(item => {
let startTime = item.startTime*1000;
let endTime = item.endTime*1000;
let startTime = formData.startTime*1000;
let endTime = formData.endTime*1000;
let duration = endTime - startTime;
// console.log(duration);
// console.log("url:"+item.url);
// console.log("socket:"+item.wssUrl);
// console.log("queryAddress:"+item.queryAddress);
// console.log("videoDevId:"+item.videoDevId);
// console.log("storageDevId:"+item.storageDevId);
// console.log("startTime:"+startTime);
// console.log("endTime:"+endTime);
// console.log("scale:"+item.scale);
player.value = new TumsPlayer('video-container-multitrans', {
"autoplay": true,
"resolution": "HD",
"streamType": "sdvod", //
"url": item.url, // url
"socket": item.wssUrl,
"url": res.url, // url
"socket": res.wssUrl,
"type": "rtsp",
"decoderType": "wasm", //
"queryAddress": item.queryAddress,
"queryAddress": res.queryAddress,
"videoSessionId": "",
"videoDevId": item.videoDevId, // id
"videoDevId": res.videoDevId, // id
"useMultitrans": true,
"storageDevId": item.storageDevId,
"storageDevId": formData.storageDevId,
"startTime": startTime, // 13
"endTime": endTime, // 13
"eventType": [1, 2], //
"scale": item.scale //
"scale": 1 //
});
setTimeout(()=>{stop(player)}, duration);
})
}
});
}
/**
* 切换回放倍

View File

@ -55,6 +55,7 @@
const formData = reactive<Record<string, any>>({
//
videoDevId: '',//
storageDevId: '',//ID
startTime: '',//
endTime: '',//
videoType: '',//
@ -101,11 +102,12 @@
});
//
await getPlaybackUrlList({
"deviceIndex":formData.videoDevId,
"videoDevId":formData.videoDevId,
"storageDevId":formData.storageDevId,
"videoType":formData.videoType,
"scale":formData.scale,
"startTime":formData.startTime,
"endTime":formData.endTime,
"videoType":formData.videoType,
"scale":formData.scale
}).then(res=>{
confirmLoading.value=false;
// console.log(res);
@ -153,6 +155,7 @@
* 切换回放倍
*/
function changeScale(){
//
createMessage.info('切换回放倍速至'+formData.scale+'倍');
let scale = parseInt(formData.scale) ;
player.value.setPlaybackConfig({"scale":scale});

View File

@ -17,8 +17,11 @@
<span style="margin-left: 5px;">
<a-button preIcon="ant-design:phone-outlined" @click="screenshot">巡航*</a-button>
</span>
<span style="margin-left: 5px;">
<a-button preIcon="ant-design:phone-outlined" @click="screenshot">电话*</a-button>
<span style="margin-left: 5px;" v-show="!izPhone">
<a-button preIcon="ant-design:phone-outlined" @click="startPhone">电话</a-button>
</span>
<span style="margin-left: 5px;" v-show="izPhone">
<a-button type="primary" danger ghost preIcon="ant-design:phone-outlined" @click="stopPhone">电话</a-button>
</span>
<span style="margin-left: 15px;">分屏
<a-select
@ -46,20 +49,14 @@
<span style="margin-left: 5px;" v-show="izRecording">
<a-button type="primary" danger ghost preIcon="ant-design:video-camera-outlined" @click="recordingEnd">录制</a-button>
</span>
<!-- <span style="margin-left: 15px;">画面翻转
<a-select
ref="select"
v-model:value="rotateType"
style="width: 120px"
@focus="focus"
@change="saveImageSwitch"
>
<a-select-option value="off">不翻转</a-select-option>
<a-select-option value="anticlockwise_180">上下翻转</a-select-option>
<a-select-option value="clockwise_90">右翻转90°</a-select-option>
<a-select-option value="anticlockwise_90">左翻转90°</a-select-option>
<span style="margin-left: 15px;">画面翻转
<a-select v-model:value="formData.flip_type" @change="(value) => changeSwitch('flip_type', value)">
<a-select-option value="off">关闭</a-select-option>
<a-select-option value="left_and_right">左右</a-select-option>
<a-select-option value="up_and_down">上下</a-select-option>
<a-select-option value="center">中心</a-select-option>
</a-select>
</span>-->
</span>
<span style="margin-left: 5px;">
<a-button preIcon="ant-design:alert-outlined" @click="manualAlarm">报警</a-button>
</span>
@ -74,7 +71,13 @@
import { useMessage } from '/@/hooks/web/useMessage';
import { getValueType } from '/@/utils';
import { Form } from 'ant-design-vue';
import { getPreviewUrl, testAudio } from "@/views/iot/tplink/camera/camera.api";
import {
getImageCommon,
getMultitransUrl,
getPreviewUrl,
setImageCommon,
testAudio
} from "@/views/iot/tplink/camera/camera.api";
const props = defineProps({
formDisabled: { type: Boolean, default: false },
@ -87,8 +90,9 @@
const resolution = ref<string>('超清');
const izPlaying = ref<boolean>(true);
const izRecording = ref<boolean>(false);
const izPhone = ref<boolean>(false);
const fishEyeDisplayMode = ref<string>('ORIGIN');
const rotateType = ref<string>('off');
const flipType = ref<string>('off');
const useForm = Form.useForm;
const emit = defineEmits(['register', 'ok']);
const formData = reactive<Record<string, any>>({
@ -103,6 +107,8 @@
wsUrl: '',//ws
wssUrl: '',//wss
flip_type: '',// "off"// "left_and_right"// "up_and_down"// "center"//
});
const { createMessage } = useMessage();
const labelCol = ref<any>({ xs: { span: 24 }, sm: { span: 5 } });
@ -144,6 +150,7 @@
});
createPreview();
getSwitch();
/* await getIpcCapability({"deviceIndex":formData.deviceIndex}).then(res=>{
console.log(res);
@ -172,6 +179,8 @@
// url: formData.backupUrl, // , getPreviewUrl
socket: formData.wssUrl, // websocket, getPreviewUrl
pluginPath: '/static', // sdkpluginPath
talkEnable: true,
useMultitrans: true,
});
let isPlaying = player.value.isPlaying();
@ -230,19 +239,32 @@
player.value.setFishEyeDisplayMode(fishEyeDisplayMode.value);
}
/**
* 获取画面翻转
*/
function getSwitch(){
if(formData.deviceIndex==null){
return
}
getImageCommon({
"deviceIndex": formData.deviceIndex,
"type": "switch"
}).then(res=>{
formData.flip_type = res.flip_type; //
});
}
/**
* 画面翻转
*/
function saveImageSwitch(){
player.value.saveImageSwitch({rotate_type:1}).then(() => {
// 0.5-2s
createMessage.success('设置成功实际画面需要0.5-2s进行响应');
}).catch((errData) => {
//
// errData.error_code
console.log(errData);
createMessage.error('设置错误,'+errData.msg);
});
function changeSwitch(attr,value){
let param = {};
param[attr] = value;
setImageCommon({
"deviceIndex": formData.deviceIndex,
"type": "switch",
"param": param
}).then(res=>{ });
}
/**
@ -288,6 +310,31 @@
});
}
/**
* 开始电话
*/
function startPhone(){
getMultitransUrl({
"videoDevId":formData.deviceIndex
}).then(res=>{
console.log(res);
player.value.startVoiceIntercom({
"url": res.url, // url
"wssUrl": res.wssUrl,
"mode": "half_duplex"
});
izPhone.value = true;
});
}
/**
* 结束电话
*/
function stopPhone(){
player.value.stopVoiceIntercom();
izPhone.value = false;
}
/**
* 销毁
*/

View File

@ -3,6 +3,9 @@ import { defHttp } from '/@/utils/http/axios';
enum Api {
list = '/iot/projectInfo/list',
sync = '/iot/projectInfo/sync',
add = '/iot/projectInfo/add',
edit = '/iot/projectInfo/edit',
delete = '/iot/projectInfo/delete',
}
/**
@ -16,3 +19,21 @@ export const list = (params) => defHttp.get({ url: Api.list, params });
* @param params
*/
export const sync = (params) => defHttp.get({ url: Api.sync, params });
/**
*
* @param params
*/
export const saveOrUpdatePrject = (params, isUpdate) => {
let url = isUpdate ? Api.edit : Api.add;
return defHttp.post({ url: url, params });
};
/**
*
*/
export const deletePrject = (params,handleSuccess) => {
return defHttp.post({ url: Api.delete, params }, { joinParamsToUrl: true }).then(() => {
handleSuccess();
});
};

View File

@ -81,6 +81,7 @@ export const formSchema: FormSchema[] = [
label: '项目序号',
field: 'projectId',
component: 'Input',
dynamicDisabled: true
},
{
label: '项目名称',
@ -91,26 +92,31 @@ export const formSchema: FormSchema[] = [
label: '创建时间',
field: 'createTimeStr',
component: 'Input',
dynamicDisabled: true
},
{
label: '设备数量',
field: 'deviceNum',
component: 'Input',
dynamicDisabled: true
},
{
label: '离线设备数',
field: 'offlineNum',
component: 'Input',
dynamicDisabled: true
},
{
label: '异常设备数',
field: 'abnormalNum',
component: 'Input',
dynamicDisabled: true
},
{
label: '运行天数',
field: 'runningTimeStr',
component: 'Input',
dynamicDisabled: true
},
{
label: '状态',
@ -125,6 +131,7 @@ export const formSchema: FormSchema[] = [
]
};
},
dynamicDisabled: true
},
];

View File

@ -5,7 +5,8 @@
<BasicTable @register="registerTable">
<!--插槽:table标题-->
<template #tableTitle>
<a-button type="primary" preIcon="ant-design:sync-outlined" @click="handleSync"> 同步</a-button>
<a-button type="primary" preIcon="ant-design:plus-outlined" @click="handleCreate"> 新增</a-button>
<a-button preIcon="ant-design:sync-outlined" @click="handleSync"> 同步</a-button>
</template>
<!--操作栏-->
<template #action="{ record }">
@ -30,6 +31,10 @@
import { useRouter } from 'vue-router';
import { useDrawer } from "@/components/Drawer";
import ProjectInfoDrawer from './components/ProjectInfoDrawer.vue';
import { deletePrject } from "@/views/iot/tplink/project/ProjectInfo.api";
import {Modal} from "ant-design-vue";
import {ExclamationCircleOutlined} from "@ant-design/icons-vue";
import {rebootDevice} from "@/views/iot/tplink/camera/camera.api";
//drawer
const [registerDrawer, { openDrawer }] = useDrawer();
let router = useRouter();
@ -70,29 +75,71 @@
});
/**
* 详情
* 新增
*/
function handleDetail(record: Recordable) {
function handleCreate() {
openDrawer(true, {
isUpdate: false,
showFooter: true,
tenantSaas: false,
});
}
/**
* 编辑
*/
function handleEdit(record: Recordable) {
openDrawer(true, {
record,
isUpdate: true,
showFooter: false,
showFooter: true,
tenantSaas: false,
});
}
/**
* 删除
*/
function handleDelete(record: Recordable) {
Modal.confirm({
title: '删除项目',
width: '500px',
icon: createVNode(ExclamationCircleOutlined),
content: createVNode('div', { style: 'color:red;' }, '项目删除后,与之相关信息将失效,确定要删除该项目吗?'),
okText: '确定',
onOk() {
deletePrject(record, reload);
},
onCancel() {
// console.log('Cancel');
},
class: 'test',
});
}
/**
* 操作栏
*/
function getTableAction(record) {
return [
{
label: '详情',
onClick: handleDetail.bind(null, record),
label: '编辑',
onClick: handleEdit.bind(null, record),
},
{
label: '删除',
onClick: handleDelete.bind(null, record),
},
];
}
/**
* 成功回调
*/
function handleSuccess() {
reload();
}
/**
* 查询
*/

View File

@ -19,6 +19,7 @@ import { formSchema } from "@/views/iot/tplink/project/ProjectInfo.data";
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
import { useDrawerAdaptiveWidth } from '/@/hooks/jeecg/useAdaptiveWidth';
import { getTenantId } from "/@/utils/auth";
import { saveOrUpdatePrject } from "@/views/iot/tplink/project/ProjectInfo.api";
// Emits
const emit = defineEmits(['success', 'register']);
@ -62,6 +63,11 @@ const { adaptiveWidth } = useDrawerAdaptiveWidth();
//
async function handleSubmit() {
try {
let values = await validate();
setDrawerProps({ confirmLoading: true });
let params = values;
let isUpdateVal = unref(isUpdate);
await saveOrUpdatePrject(params,isUpdateVal);
//
closeDrawer();
//