diff --git a/src/views/iot/tplink/camera/components/CameraCommonForm.vue b/src/views/iot/tplink/camera/components/CameraCommonForm.vue
index a5cf3fe..cba9d0d 100644
--- a/src/views/iot/tplink/camera/components/CameraCommonForm.vue
+++ b/src/views/iot/tplink/camera/components/CameraCommonForm.vue
@@ -17,7 +17,7 @@
- 画面镜像
+ 画面翻转
changeSwitch('flip_type', value)">
@@ -27,17 +27,6 @@
中心
-
- 画面翻转
-
-
- changeSwitch('rotate_type', value)">
- 关闭
- 上下翻转
- 左翻转90°
- 右翻转90°
-
-
@@ -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; //画面旋转 貌似不好使,需要找厂家
});
}
diff --git a/src/views/iot/tplink/camera/components/CameraMultitransForm.vue b/src/views/iot/tplink/camera/components/CameraMultitransForm.vue
index 2e8d5d7..2358bd4 100644
--- a/src/views/iot/tplink/camera/components/CameraMultitransForm.vue
+++ b/src/views/iot/tplink/camera/components/CameraMultitransForm.vue
@@ -52,6 +52,7 @@
const formData = reactive>({
//预览通道参数
videoDevId: '',//设备索引
+ storageDevId: '',//存储设备ID
multitrans: '',//IPC能力集中multitrans的能力
startTime: '',//回放开始时间
endTime: '',//回放结束时间
@@ -97,51 +98,32 @@
});
//获取录像回放地址
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 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,
- "type": "rtsp",
- "decoderType": "wasm", // 硬软解类型
- "queryAddress": item.queryAddress,
- "videoSessionId": "",
- "videoDevId": item.videoDevId, // 设备id
- "useMultitrans": true,
- "storageDevId": item.storageDevId,
- "startTime": startTime, // 回放开始时间 13位
- "endTime": endTime, // 回放结束时间 13位
- "eventType": [1, 2], // 事件类型
- "scale": item.scale // 回放倍速
- });
- setTimeout(()=>{stop(player)}, duration);
- })
- }
- });
+ let startTime = formData.startTime*1000;
+ let endTime = formData.endTime*1000;
+ let duration = endTime - startTime;
+ player.value = new TumsPlayer('video-container-multitrans', {
+ "autoplay": true,
+ "resolution": "HD",
+ "streamType": "sdvod", // 回放类型
+ "url": res.url, // 该url为一次性 需要通过接口实时获取
+ "socket": res.wssUrl,
+ "type": "rtsp",
+ "decoderType": "wasm", // 硬软解类型
+ "queryAddress": res.queryAddress,
+ "videoSessionId": "",
+ "videoDevId": res.videoDevId, // 设备id
+ "useMultitrans": true,
+ "storageDevId": formData.storageDevId,
+ "startTime": startTime, // 回放开始时间 13位
+ "endTime": endTime, // 回放结束时间 13位
+ "eventType": [1, 2], // 事件类型
+ "scale": 1 // 回放倍速
+ });
+ setTimeout(()=>{stop(player)}, duration);
+ })
}
/**
diff --git a/src/views/iot/tplink/camera/components/CameraPlaybackForm.vue b/src/views/iot/tplink/camera/components/CameraPlaybackForm.vue
index 31f8d4d..345599b 100644
--- a/src/views/iot/tplink/camera/components/CameraPlaybackForm.vue
+++ b/src/views/iot/tplink/camera/components/CameraPlaybackForm.vue
@@ -55,6 +55,7 @@
const formData = reactive>({
//预览通道参数
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});
diff --git a/src/views/iot/tplink/camera/components/CameraPreviewForm.vue b/src/views/iot/tplink/camera/components/CameraPreviewForm.vue
index 7b88c39..5e526b4 100644
--- a/src/views/iot/tplink/camera/components/CameraPreviewForm.vue
+++ b/src/views/iot/tplink/camera/components/CameraPreviewForm.vue
@@ -17,8 +17,11 @@
巡航*
-
- 电话*
+
+ 电话
+
+
+ 电话
分屏
录制
-
+
报警
@@ -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('超清');
const izPlaying = ref(true);
const izRecording = ref(false);
+ const izPhone = ref(false);
const fishEyeDisplayMode = ref('ORIGIN');
- const rotateType = ref('off');
+ const flipType = ref('off');
const useForm = Form.useForm;
const emit = defineEmits(['register', 'ok']);
const formData = reactive>({
@@ -103,6 +107,8 @@
wsUrl: '',//用于建立ws连接传输视频帧信息
wssUrl: '',//用于建立wss接传输视频帧信息
+ flip_type: '',//画面镜像旋转: "off"//关闭 "left_and_right"//左右 "up_and_down"//上下 "center"//中心
+
});
const { createMessage } = useMessage();
const labelCol = ref({ 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', // 当sdk资源不在根路径下时,需配置pluginPath
+ 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;
+ }
+
/**
* 销毁
*/
diff --git a/src/views/iot/tplink/project/ProjectInfo.api.ts b/src/views/iot/tplink/project/ProjectInfo.api.ts
index 1061dff..ba88b78 100644
--- a/src/views/iot/tplink/project/ProjectInfo.api.ts
+++ b/src/views/iot/tplink/project/ProjectInfo.api.ts
@@ -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();
+ });
+};
diff --git a/src/views/iot/tplink/project/ProjectInfo.data.ts b/src/views/iot/tplink/project/ProjectInfo.data.ts
index 9b1b2ea..835d534 100644
--- a/src/views/iot/tplink/project/ProjectInfo.data.ts
+++ b/src/views/iot/tplink/project/ProjectInfo.data.ts
@@ -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
},
];
diff --git a/src/views/iot/tplink/project/ProjectInfoList.vue b/src/views/iot/tplink/project/ProjectInfoList.vue
index 462fdd6..807c508 100644
--- a/src/views/iot/tplink/project/ProjectInfoList.vue
+++ b/src/views/iot/tplink/project/ProjectInfoList.vue
@@ -5,7 +5,8 @@
- 同步
+ 新增
+ 同步
@@ -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();
+ }
+
/**
* 查询
*/
diff --git a/src/views/iot/tplink/project/components/ProjectInfoDrawer.vue b/src/views/iot/tplink/project/components/ProjectInfoDrawer.vue
index 298342f..c9f0ea5 100644
--- a/src/views/iot/tplink/project/components/ProjectInfoDrawer.vue
+++ b/src/views/iot/tplink/project/components/ProjectInfoDrawer.vue
@@ -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();
//刷新列表