Compare commits
2 Commits
1628d64e44
...
727084fc51
Author | SHA1 | Date |
---|---|---|
|
727084fc51 | |
|
bc171d0b0f |
|
@ -203,6 +203,7 @@
|
|||
cameraData.value.regionId = formData.regionId;
|
||||
cameraData.value.multitrans = formData.multitrans;
|
||||
cameraData.value.scale = formData.scale;
|
||||
cameraData.value.parentId = formData.parentId;
|
||||
})
|
||||
|
||||
</script>
|
||||
|
|
|
@ -14,9 +14,9 @@
|
|||
<span style="margin-left: 5px;">
|
||||
<a-button preIcon="ant-design:swap-outlined" @click="switchResolution">{{ resolution }}</a-button>
|
||||
</span>
|
||||
<span style="margin-left: 5px;">
|
||||
<!-- <span style="margin-left: 5px;">
|
||||
<a-button preIcon="ant-design:phone-outlined" @click="screenshot">巡航*</a-button>
|
||||
</span>
|
||||
</span>-->
|
||||
<span style="margin-left: 5px;" v-show="!izPhone">
|
||||
<a-button preIcon="ant-design:phone-outlined" @click="startPhone">电话</a-button>
|
||||
</span>
|
||||
|
|
|
@ -196,6 +196,7 @@ import {
|
|||
formData.regionId = props.data.regionId;
|
||||
formData.multitrans = props.data.multitrans;
|
||||
formData.scale = props.data.scale;
|
||||
formData.parentId = props.data.parentId;
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
);
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
<template>
|
||||
<a-row class="p-2">
|
||||
<a-col :span="9">
|
||||
<PlanAddTree ref="leftTree" :data="formData" @select="onTreeSelect"/>
|
||||
</a-col>
|
||||
<a-col :span="15">
|
||||
<PlanAddForm ref="addForm" :initData="formData" :data="nodeData" @success="submitCallback" />
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="iot-nuIotRegionInfo" setup>
|
||||
import {defineExpose, nextTick, reactive, ref} from 'vue';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
import PlanAddTree from './PlanAddTree.vue'
|
||||
import PlanAddForm from './PlanAddForm.vue';
|
||||
const emit = defineEmits(['register', 'ok']);
|
||||
|
||||
const formData = reactive<Record<string, any>>({
|
||||
projectId: '',
|
||||
regionId: ''
|
||||
});
|
||||
|
||||
// 给子组件定义一个ref变量
|
||||
const leftTree = ref();
|
||||
const addForm = ref();
|
||||
// 当前选中的区域信息
|
||||
const nodeData = ref({});
|
||||
|
||||
// 左侧树选择后触发
|
||||
function onTreeSelect(data) {
|
||||
nodeData.value = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 详情
|
||||
*/
|
||||
async function edit(record) {
|
||||
await nextTick(() => {
|
||||
const tmpData = {};
|
||||
Object.keys(formData).forEach((key) => {
|
||||
if(record.hasOwnProperty(key)){
|
||||
tmpData[key] = record[key]
|
||||
}
|
||||
})
|
||||
//赋值
|
||||
Object.assign(formData, tmpData);
|
||||
leftTree.value.clean();
|
||||
});
|
||||
}
|
||||
|
||||
async function submitForm(){
|
||||
addForm.value.submitForm();
|
||||
}
|
||||
|
||||
function submitCallback() {
|
||||
emit('ok');
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
edit,
|
||||
submitForm
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
.p-2{
|
||||
height: calc(100vh - 325px);
|
||||
}
|
||||
|
||||
.form-content{
|
||||
background-color: #ffffff;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
:deep(.ant-tabs-nav ){
|
||||
padding: 0 20px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,160 @@
|
|||
<template>
|
||||
<a-card :bordered="false" style="height: 100%">
|
||||
<div class="title">
|
||||
2.选择录像存储位置、码流、计划
|
||||
</div>
|
||||
<a-divider />
|
||||
<a-spin :spinning="loading">
|
||||
<BasicForm @register="registerForm" class="jeecg-basic-form">
|
||||
<template #storageDevInput="{ model, field }">
|
||||
<a-select v-model:value="model[field]">
|
||||
<template v-for="item in storageDevOptions" :key="`${item.storageDevId}`">
|
||||
<a-select-option :value="item.storageDevId" :label="item.storageDevName">
|
||||
{{item.storageDevName}}
|
||||
</a-select-option>
|
||||
</template>
|
||||
</a-select>
|
||||
</template>
|
||||
<template #planInput="{ model, field }">
|
||||
<a-select v-model:value="model[field]">
|
||||
<template v-for="item in planOptions" :key="`${item.recordPlanId}`">
|
||||
<a-select-option :value="item.recordPlanId" :label="item.planName">
|
||||
{{item.planName}}
|
||||
</a-select-option>
|
||||
</template>
|
||||
</a-select>
|
||||
</template>
|
||||
</BasicForm>
|
||||
</a-spin>
|
||||
</a-card>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { watch, computed, inject, ref, unref, onMounted } from 'vue';
|
||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||
import { addRecordCfgs, getAllRecordPlans, getStorageDevice } from '../plan.api';
|
||||
import { addFormSchema } from "../plan.data";
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import {propTypes} from "@/utils/propTypes";
|
||||
const { createMessage, createSuccessModal } = useMessage();
|
||||
const emit = defineEmits(['success']);
|
||||
const props = defineProps({
|
||||
initData: { type: Object, default: () => ({}) },
|
||||
data: { type: Array, default: () => ([]) }
|
||||
});
|
||||
const areaOptions = ref<any[]>([]);
|
||||
const loading = ref<boolean>(false);
|
||||
// 当前是否是更新模式
|
||||
const isUpdate = ref<boolean>(true);
|
||||
// 当前的弹窗数据
|
||||
const initModel = ref<object>({});
|
||||
// 当前的弹窗数据
|
||||
const treeModel = ref<object>([]);
|
||||
// 当前的弹窗数据
|
||||
const model = ref<object>({});
|
||||
|
||||
const planOptions = ref<any[]>([]);
|
||||
const storageDevOptions = ref<any[]>([]);
|
||||
|
||||
//注册表单
|
||||
const [registerForm, { resetFields, setFieldsValue, validate, updateSchema }] = useForm({
|
||||
schemas: addFormSchema,
|
||||
showActionButtonGroup: false
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
watch(
|
||||
() => props.initData,
|
||||
async () => {
|
||||
let record = unref(props.initData);
|
||||
if (typeof record !== 'object') {
|
||||
record = {};
|
||||
}
|
||||
initModel.value = record;
|
||||
if(record.projectId!=''&&record.regionId!=''){
|
||||
await fetchStorageDev(record.projectId,record.regionId);
|
||||
await fetchPlan();
|
||||
}
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
);
|
||||
// data 变化,重填表单
|
||||
watch(
|
||||
() => props.data,
|
||||
async () => {
|
||||
let record = unref(props.data);
|
||||
console.log(record);
|
||||
if (typeof record !== 'object') {
|
||||
record = [];
|
||||
}
|
||||
treeModel.value = record;
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
);
|
||||
});
|
||||
|
||||
// 提交事件
|
||||
async function submitForm() {
|
||||
if(treeModel.value!=null){
|
||||
if(treeModel.value.length == 0){
|
||||
createMessage.info('请选择监控点!');
|
||||
}else{
|
||||
try {
|
||||
loading.value = true;
|
||||
let values = await validate();
|
||||
values = Object.assign({}, model.value, values);
|
||||
console.log(values);
|
||||
values["ids"] = treeModel.value.join(',');
|
||||
//提交表单
|
||||
await addRecordCfgs(values);
|
||||
//刷新列表
|
||||
emit('success');
|
||||
Object.assign(model.value, {});
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const fetchStorageDev = async (projectId,regionId) => {
|
||||
storageDevOptions.value = [];
|
||||
const data = await getStorageDevice({ projectId : projectId, regionId: regionId });
|
||||
console.log(data);
|
||||
Object.assign(storageDevOptions.value, data);
|
||||
}
|
||||
|
||||
const fetchPlan = async () => {
|
||||
planOptions.value = [];
|
||||
const data = await getAllRecordPlans({});
|
||||
console.log(data);
|
||||
Object.assign(planOptions.value, data);
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
submitForm,
|
||||
});
|
||||
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
|
||||
:deep(.ant-card-body){
|
||||
padding: 0px 0px 0px 0px;
|
||||
}
|
||||
|
||||
.ant-divider-horizontal{
|
||||
margin: 0px 0px 20px 0px;
|
||||
}
|
||||
|
||||
.title{
|
||||
padding: 10px 0px 10px 10px;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.jeecg-basic-form {
|
||||
padding: 0px 20px;
|
||||
}
|
||||
|
||||
</style>
|
|
@ -0,0 +1,147 @@
|
|||
<template>
|
||||
<a-card :bordered="false" style="height: 100%" class="card">
|
||||
<div class="title">
|
||||
1.选择监控点
|
||||
</div>
|
||||
<a-divider />
|
||||
<a-alert type="info" show-icon class="alert" style="margin-bottom: 8px">
|
||||
<template #message>
|
||||
<template v-if="checkedKeys.length > 0">
|
||||
<span>已选中 {{ checkedKeys.length }} 条记录</span>
|
||||
<a-divider type="vertical" />
|
||||
<a @click="clean">清空</a>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span>未选中任何数据</span>
|
||||
</template>
|
||||
</template>
|
||||
</a-alert>
|
||||
<a-spin :spinning="loading">
|
||||
<!--区域树-->
|
||||
<template v-if="treeData.length > 0">
|
||||
<a-tree
|
||||
:clickRowToExpand="false"
|
||||
:treeData="treeData"
|
||||
:selectedKeys="selectedKeys"
|
||||
:checkStrictly="checkStrictly"
|
||||
:load-data="loadChildrenTreeData"
|
||||
:checkedKeys="checkedKeys"
|
||||
v-model:expandedKeys="expandedKeys"
|
||||
@check="onCheck"
|
||||
checkable
|
||||
>
|
||||
</a-tree>
|
||||
</template>
|
||||
<a-empty v-else description="暂无数据" />
|
||||
</a-spin>
|
||||
</a-card>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {defineExpose, nextTick, onMounted, ref, unref, watch} from 'vue';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { useMethods } from '/@/hooks/system/useMethods';
|
||||
const { createMessage } = useMessage();
|
||||
import { queryTreeList } from '../plan.api';
|
||||
const props = defineProps({
|
||||
data: { type: Object, default: () => ({}) },
|
||||
});
|
||||
// 当前的弹窗数据
|
||||
const model = ref<object>({});
|
||||
const emit = defineEmits(['select']);
|
||||
const syncoading = ref<boolean>(false);
|
||||
const loading = ref<boolean>(false);
|
||||
// 区域树列表数据
|
||||
const treeData = ref<any[]>([]);
|
||||
// 当前选中的项
|
||||
const checkedKeys = ref<any[]>([]);
|
||||
// 当前展开的项
|
||||
const expandedKeys = ref<any[]>([]);
|
||||
// 当前选中的项
|
||||
const selectedKeys = ref<any[]>([]);
|
||||
// 树父子是否关联
|
||||
const checkStrictly = ref<boolean>(true);
|
||||
|
||||
// 加载顶级区域信息
|
||||
async function loadRootTreeData() {
|
||||
if(model.value.projectId==''&&model.value.regionId==''){
|
||||
return ;
|
||||
}
|
||||
try {
|
||||
loading.value = true;
|
||||
treeData.value = [];
|
||||
model.value["recordPlanId"] = "-1";
|
||||
const result = await queryTreeList(model.value);
|
||||
if (Array.isArray(result)) {
|
||||
treeData.value = result;
|
||||
}
|
||||
} finally {
|
||||
loading.value = false;
|
||||
syncoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function clean(){
|
||||
checkedKeys.value = [];
|
||||
emit('select', checkedKeys.value);
|
||||
}
|
||||
|
||||
// 树复选框选择事件
|
||||
function onCheck(e) {
|
||||
if (Array.isArray(e)) {
|
||||
checkedKeys.value = e;
|
||||
} else {
|
||||
checkedKeys.value = e.checked;
|
||||
}
|
||||
emit('select', checkedKeys.value);
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// data 变化,重填表单
|
||||
watch(
|
||||
() => props.data,
|
||||
async () => {
|
||||
let record = unref(props.data);
|
||||
if (typeof record !== 'object') {
|
||||
record = {};
|
||||
}
|
||||
model.value = record;
|
||||
await loadRootTreeData();
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
);
|
||||
});
|
||||
|
||||
defineExpose({
|
||||
clean
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
:deep(.ant-card-body){
|
||||
padding: 0px 0px 0px 0px;
|
||||
background-color: aliceblue;
|
||||
}
|
||||
|
||||
.card{
|
||||
background-color: aliceblue;
|
||||
}
|
||||
|
||||
:deep(.ant-tree-list-holder){
|
||||
background-color: aliceblue !important;
|
||||
}
|
||||
|
||||
.ant-divider-horizontal{
|
||||
margin: 0px 0px 10px 0px;
|
||||
}
|
||||
|
||||
.title{
|
||||
padding: 10px 0px 10px 10px;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
</style>
|
|
@ -0,0 +1,181 @@
|
|||
<template>
|
||||
<a-card :bordered="false" style="height: 100%">
|
||||
<a-spin :spinning="syncoading">
|
||||
<!-- <div class="j-table-operator" style="width: 100%">
|
||||
<a-button preIcon="ant-design:sync-outlined" @click="loadRootTreeData">刷新</a-button>
|
||||
</div>-->
|
||||
<a-spin :spinning="loading">
|
||||
<!--区域树-->
|
||||
<template v-if="treeData.length > 0">
|
||||
<a-tree
|
||||
v-if="!treeReloading"
|
||||
:clickRowToExpand="false"
|
||||
:treeData="treeData"
|
||||
:selectedKeys="selectedKeys"
|
||||
:checkStrictly="checkStrictly"
|
||||
:load-data="loadChildrenTreeData"
|
||||
:checkedKeys="checkedKeys"
|
||||
v-model:expandedKeys="expandedKeys"
|
||||
@select="onSelect"
|
||||
>
|
||||
</a-tree>
|
||||
</template>
|
||||
<a-empty v-else description="暂无数据" />
|
||||
</a-spin>
|
||||
</a-spin>
|
||||
</a-card>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { nextTick, ref } from 'vue';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { useMethods } from '/@/hooks/system/useMethods';
|
||||
const { createMessage } = useMessage();
|
||||
import { queryProjectTreeSync, queryRegionTreeSync } from '../plan.api';
|
||||
|
||||
const emit = defineEmits(['select', 'rootTreeData']);
|
||||
const syncoading = ref<boolean>(false);
|
||||
const loading = ref<boolean>(false);
|
||||
// 区域树列表数据
|
||||
const treeData = ref<any[]>([]);
|
||||
// 当前选中的项
|
||||
const checkedKeys = ref<any[]>([]);
|
||||
// 当前展开的项
|
||||
const expandedKeys = ref<any[]>([]);
|
||||
// 当前选中的项
|
||||
const selectedKeys = ref<any[]>([]);
|
||||
// 树组件重新加载
|
||||
const treeReloading = ref<boolean>(false);
|
||||
// 树父子是否关联
|
||||
const checkStrictly = ref<boolean>(true);
|
||||
// 当前选中的区域
|
||||
const currentRegion = ref<any>(null);
|
||||
|
||||
// 加载顶级区域信息
|
||||
async function loadRootTreeData() {
|
||||
try {
|
||||
loading.value = true;
|
||||
treeData.value = [];
|
||||
const result = await queryProjectTreeSync();
|
||||
if (Array.isArray(result)) {
|
||||
treeData.value = result;
|
||||
}
|
||||
if (expandedKeys.value.length === 0) {
|
||||
autoExpandParentNode();
|
||||
} else {
|
||||
if (selectedKeys.value.length === 0) {
|
||||
let item = treeData.value[0];
|
||||
if (item) {
|
||||
// 默认选中第一个
|
||||
setSelectedKey(item.id, item);
|
||||
}
|
||||
} else {
|
||||
emit('select', currentRegion.value);
|
||||
}
|
||||
}
|
||||
emit('rootTreeData', treeData.value);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
syncoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
loadRootTreeData();
|
||||
|
||||
/**
|
||||
* 加载子级区域信息
|
||||
*/
|
||||
async function loadChildrenTreeData(treeNode) {
|
||||
try {
|
||||
const result = await queryRegionTreeSync({
|
||||
parentId: treeNode.dataRef.id,
|
||||
projectId: treeNode.dataRef.projectId,
|
||||
});
|
||||
if (result.length == 0) {
|
||||
treeNode.dataRef.isLeaf = true;
|
||||
} else {
|
||||
treeNode.dataRef.children = result;
|
||||
if (expandedKeys.value.length > 0) {
|
||||
// 判断获取的子级是否有当前展开的项
|
||||
let subKeys: any[] = [];
|
||||
for (let key of expandedKeys.value) {
|
||||
if (result.findIndex((item) => item.id === key) !== -1) {
|
||||
subKeys.push(key);
|
||||
}
|
||||
}
|
||||
if (subKeys.length > 0) {
|
||||
expandedKeys.value = [...expandedKeys.value];
|
||||
}
|
||||
}
|
||||
}
|
||||
treeData.value = [...treeData.value];
|
||||
emit('rootTreeData', treeData.value);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动展开父节点,只展开一级
|
||||
*/
|
||||
function autoExpandParentNode() {
|
||||
let item = treeData.value[0];
|
||||
if (item) {
|
||||
if (!item.isLeaf) {
|
||||
expandedKeys.value = [item.key];
|
||||
}
|
||||
// 默认选中第一个
|
||||
setSelectedKey(item.id, item);
|
||||
reloadTree();
|
||||
} else {
|
||||
emit('select', null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新加载树组件,防止无法默认展开数据
|
||||
*/
|
||||
async function reloadTree() {
|
||||
await nextTick();
|
||||
treeReloading.value = true;
|
||||
await nextTick();
|
||||
treeReloading.value = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前选中的行
|
||||
*/
|
||||
function setSelectedKey(key: string, data?: object) {
|
||||
selectedKeys.value = [key];
|
||||
if (data) {
|
||||
currentRegion.value = data;
|
||||
emit('select', data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 树选择事件
|
||||
*/
|
||||
function onSelect(selKeys, event) {
|
||||
if (selKeys.length > 0 && selectedKeys.value[0] !== selKeys[0]) {
|
||||
setSelectedKey(selKeys[0], event.selectedNodes[0]);
|
||||
} else {
|
||||
// 这样可以防止用户取消选择
|
||||
setSelectedKey(selectedKeys.value[0]);
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
loadRootTreeData,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
:deep(.ant-card-body){
|
||||
padding: 24px 0px 0px 24px;
|
||||
}
|
||||
|
||||
</style>
|
|
@ -0,0 +1,213 @@
|
|||
<template>
|
||||
<div>
|
||||
<!--引用表格-->
|
||||
<BasicTable @register="registerTable" :rowSelection="rowSelection">
|
||||
<!--插槽:table标题-->
|
||||
<template #tableTitle>
|
||||
<a-button v-if="queryParam.regionId" type="primary" preIcon="ant-design:plus-outlined" @click="handleAdd"> 新增</a-button>
|
||||
<a-button v-if="selectedRowKeys.length > 0" preIcon="ant-design:delete-outlined" @click="batchHandleDelete"> 删除</a-button>
|
||||
</template>
|
||||
<!--操作栏-->
|
||||
<template #action="{ record }"></template>
|
||||
<template v-slot:bodyCell="{ column, record, index, text }">
|
||||
<template v-if="column.dataIndex === 'recordSwitchBoolean'">
|
||||
<a-switch
|
||||
v-model:checked="record.recordSwitchBoolean"
|
||||
checked-children="开"
|
||||
un-checked-children="关"
|
||||
@change="(checked) => handleSwitchChange(checked, record)"
|
||||
/>
|
||||
</template>
|
||||
</template>
|
||||
<!-- <template #recordSlot="{ text, record }">
|
||||
<a-switch
|
||||
v-model:checked="record.recordSwitch"
|
||||
checked-children="启用"
|
||||
un-checked-children="停用"
|
||||
/>
|
||||
</template>-->
|
||||
</BasicTable>
|
||||
<!-- 表单区域 -->
|
||||
<PlanModal ref="registerModal"></PlanModal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="iot-nuIotCameraInfo" setup>
|
||||
import { ref, reactive, createVNode, h, onMounted, watch, unref } from 'vue';
|
||||
import { BasicTable, useTable, TableAction } from '/@/components/Table';
|
||||
import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import { columns } from '../plan.data';
|
||||
import {batchDeleteCfgs, editRecordCfgs, list} from '../plan.api';
|
||||
import { useUserStore } from '/@/store/modules/user';
|
||||
import { useDrawer } from "@/components/Drawer";
|
||||
import { useRouter } from 'vue-router';
|
||||
import PlanModal from './PlanModal.vue';
|
||||
|
||||
const props = defineProps({
|
||||
data: { type: Object, default: () => ({}) },
|
||||
});
|
||||
//注册drawer
|
||||
const [registerDrawer, { openDrawer }] = useDrawer();
|
||||
let router = useRouter();
|
||||
const queryParam = reactive<any>({});
|
||||
const registerModal = ref();
|
||||
const userStore = useUserStore();
|
||||
//注册table数据
|
||||
const { prefixCls, tableContext, onExportXls, onImportXls } = useListPage({
|
||||
tableProps: {
|
||||
title: '护理单元-物联管理-录像计划',
|
||||
api: list,
|
||||
columns,
|
||||
rowKey : "ids",
|
||||
canResize: false,
|
||||
showActionColumn: false,
|
||||
actionColumn: {
|
||||
width: 180,
|
||||
fixed: 'right',
|
||||
},
|
||||
beforeFetch: async (params) => {
|
||||
return Object.assign(params, queryParam);
|
||||
},
|
||||
},
|
||||
});
|
||||
const [registerTable, { reload, collapseAll, updateTableDataRecord, findTableDataRecord, getDataSource, getSelectRows }, { rowSelection, selectedRowKeys }] = tableContext;
|
||||
const labelCol = reactive({
|
||||
xs:24,
|
||||
sm:4,
|
||||
xl:6,
|
||||
xxl:4
|
||||
});
|
||||
const wrapperCol = reactive({
|
||||
xs: 24,
|
||||
sm: 20,
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
watch(
|
||||
() => props.data,
|
||||
async () => {
|
||||
queryParam.projectId = props.data.projectId;
|
||||
queryParam.regionId = props.data.regionId;
|
||||
let record = unref(props.data);
|
||||
if (typeof record !== 'object') {
|
||||
record = {};
|
||||
}
|
||||
reload();
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* 新增
|
||||
*/
|
||||
function handleAdd(record: Recordable) {
|
||||
record["projectId"] = queryParam.projectId;
|
||||
record["regionId"] = queryParam.regionId;
|
||||
registerModal.value.disableSubmit = false;
|
||||
registerModal.value.edit(record);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
*/
|
||||
function handleEdit(record: Recordable) {
|
||||
record["projectId"] = queryParam.projectId;
|
||||
record["regionId"] = queryParam.regionId;
|
||||
openDrawer(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
showFooter: true,
|
||||
tenantSaas: false,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除事件
|
||||
*/
|
||||
async function batchHandleDelete() {
|
||||
const selectRows = getSelectRows();
|
||||
let ids = [];
|
||||
let devIds = [];
|
||||
if(selectRows.length>0){
|
||||
selectRows.forEach(function(element) {
|
||||
ids.push(element.ids);
|
||||
devIds.push(element.deviceIndex);
|
||||
})
|
||||
let params = { ids: ids.join(","), deviceIndex: devIds.join(",")};
|
||||
console.log(params);
|
||||
await batchDeleteCfgs(params);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功回调
|
||||
*/
|
||||
function handleSuccess() {
|
||||
reload();
|
||||
}
|
||||
|
||||
/**
|
||||
* 操作栏
|
||||
*/
|
||||
function getTableAction(record) {
|
||||
return [
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
function handleSwitchChange(checked, record) {
|
||||
let recordSwitch = 0;
|
||||
if(checked){
|
||||
recordSwitch = 1;
|
||||
}
|
||||
editRecordCfgs({ ids: record.ids, recordSwitch: recordSwitch });
|
||||
}
|
||||
|
||||
/**
|
||||
* 左侧树选择后触发
|
||||
*/
|
||||
function onTreeSelect(data) {
|
||||
// departData.value = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 左侧树rootTreeData触发
|
||||
*/
|
||||
function onRootTreeData(data) {
|
||||
// rootTreeData.value = data;
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
.jeecg-basic-table-form-container {
|
||||
padding: 0;
|
||||
.table-page-search-submitButtons {
|
||||
display: block;
|
||||
margin-bottom: 24px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.query-group-cust{
|
||||
min-width: 100px !important;
|
||||
}
|
||||
.query-group-split-cust{
|
||||
width: 30px;
|
||||
display: inline-block;
|
||||
text-align: center
|
||||
}
|
||||
.ant-form-item:not(.ant-form-item-with-help){
|
||||
margin-bottom: 16px;
|
||||
height: 32px;
|
||||
}
|
||||
:deep(.ant-picker),:deep(.ant-input-number){
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.p-2{
|
||||
height: calc(100vh - 120px);
|
||||
}
|
||||
|
||||
</style>
|
|
@ -0,0 +1,67 @@
|
|||
<template>
|
||||
<j-modal :title="title" :width="width" :visible="visible" @ok="handleOk" :okButtonProps="{ class: { 'jee-hidden': disableSubmit } }" @cancel="handleCancel" cancelText="关闭">
|
||||
<PlanAdd ref="registerForm" @ok="submitCallback" :formDisabled="disableSubmit" :formBpm="false"></PlanAdd>
|
||||
</j-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, nextTick, defineExpose } from 'vue';
|
||||
|
||||
import JModal from '/@/components/Modal/src/JModal/JModal.vue';
|
||||
import PlanAdd from "./PlanAdd.vue";
|
||||
|
||||
const title = ref<string>('');
|
||||
const width = ref<number>(800);
|
||||
const visible = ref<boolean>(false);
|
||||
const disableSubmit = ref<boolean>(false);
|
||||
const registerForm = ref();
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
|
||||
// const player = ref();
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
* @param record
|
||||
*/
|
||||
function edit(record) {
|
||||
title.value = "添加录像设置";
|
||||
visible.value = true;
|
||||
nextTick(() => {
|
||||
registerForm.value.edit(record);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 确定按钮点击事件
|
||||
*/
|
||||
function handleOk() {
|
||||
registerForm.value.submitForm();
|
||||
}
|
||||
|
||||
/**
|
||||
* form保存回调事件
|
||||
*/
|
||||
function submitCallback() {
|
||||
handleCancel();
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消按钮回调事件
|
||||
*/
|
||||
function handleCancel() {
|
||||
visible.value = false;
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
edit,
|
||||
disableSubmit,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
/**隐藏样式-modal确定按钮 */
|
||||
.jee-hidden {
|
||||
display: none !important;
|
||||
}
|
||||
</style>
|
||||
<style lang="less" scoped></style>
|
|
@ -0,0 +1,46 @@
|
|||
<template>
|
||||
|
||||
<a-row class="p-2" type="flex" :gutter="10">
|
||||
<a-col :xl="4" :lg="24" :md="24" style="margin-bottom: 10px">
|
||||
<PlanLeftTree ref="leftTree" @select="onTreeSelect" @rootTreeData="onRootTreeData" />
|
||||
</a-col>
|
||||
<a-col :xl="20" :lg="24" :md="24" style="margin-bottom: 10px">
|
||||
<div v-show="planData != null">
|
||||
<PlanList :data="planData" />
|
||||
</div>
|
||||
<div v-show="planData == null" style="padding-top: 40px">
|
||||
<a-empty description="请选择区域" />
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="iot-nuIotCameraInfo" setup>
|
||||
import { ref } from 'vue';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
import PlanLeftTree from './components/PlanLeftTree.vue'
|
||||
import PlanList from './components/PlanList.vue';
|
||||
|
||||
// 给子组件定义一个ref变量
|
||||
const leftTree = ref();
|
||||
// 当前选中的区域信息
|
||||
const planData = ref({});
|
||||
const rootTreeData = ref<any[]>([]);
|
||||
// 左侧树选择后触发
|
||||
function onTreeSelect(data) {
|
||||
planData.value = data;
|
||||
}
|
||||
// 左侧树rootTreeData触发
|
||||
function onRootTreeData(data) {
|
||||
rootTreeData.value = data;
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
.p-2{
|
||||
height: calc(100vh - 120px);
|
||||
}
|
||||
|
||||
</style>
|
|
@ -0,0 +1,86 @@
|
|||
import { defHttp } from '/@/utils/http/axios';
|
||||
import {Modal} from "ant-design-vue";
|
||||
|
||||
enum Api {
|
||||
queryProjectTreeSync = '/iot/projectInfo/queryRegionTreeSync',
|
||||
queryRegionTreeSync = '/iot/regionInfo/queryRegionTreeSync',
|
||||
queryTreeList = '/iot/cameraInfo/queryTreeList',
|
||||
getStorageDevice = '/iot/cameraInfo/getStorageDevice',
|
||||
getAllRecordPlans = '/iot/cameraInfo/getAllRecordPlans',
|
||||
getRecordCfgs = '/iot/cameraInfo/getRecordCfgs',
|
||||
addRecordCfgs = '/iot/cameraInfo/addRecordCfgs',
|
||||
setRecordCfgs = '/iot/cameraInfo/setRecordCfgs',
|
||||
delRecordCfgs = '/iot/cameraInfo/delRecordCfgs',
|
||||
getBatchProgress = '/iot/cameraInfo/getBatchProgress',
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取项目树列表
|
||||
* @param params
|
||||
*/
|
||||
export const queryProjectTreeSync = (params?) => defHttp.get({ url: Api.queryProjectTreeSync, params });
|
||||
|
||||
/**
|
||||
* 获取区域树列表
|
||||
* @param params
|
||||
*/
|
||||
export const queryRegionTreeSync = (params?) => defHttp.get({ url: Api.queryRegionTreeSync, params });
|
||||
|
||||
/**
|
||||
* 获取树列表
|
||||
* @param params
|
||||
*/
|
||||
export const queryTreeList = (params?) => defHttp.get({ url: Api.queryTreeList, params });
|
||||
|
||||
/**
|
||||
* 列表接口
|
||||
* @param params
|
||||
*/
|
||||
export const getStorageDevice = (params) => defHttp.get({ url: Api.getStorageDevice, params });
|
||||
|
||||
/**
|
||||
* 获取存储设备列表
|
||||
* @param params
|
||||
*/
|
||||
export const getAllRecordPlans = (params) => defHttp.get({ url: Api.getAllRecordPlans, params });
|
||||
|
||||
/**
|
||||
* 获取录像配置
|
||||
* @param params
|
||||
*/
|
||||
export const list = (params) => defHttp.get({ url: Api.getRecordCfgs, params });
|
||||
|
||||
/**
|
||||
* 添加录像计划
|
||||
* @param params
|
||||
*/
|
||||
export const addRecordCfgs = (params) => defHttp.post({ url: Api.addRecordCfgs, params });
|
||||
|
||||
/**
|
||||
* 设置录像计划
|
||||
* @param params
|
||||
*/
|
||||
export const editRecordCfgs = (params) => defHttp.post({ url: Api.setRecordCfgs, params });
|
||||
|
||||
/**
|
||||
* 获取批量操作录像计划进度
|
||||
* @param params
|
||||
*/
|
||||
export const getBatchProgress = (params) => defHttp.get({ url: Api.getBatchProgress, params });
|
||||
|
||||
|
||||
/**
|
||||
* 批量删除数据源
|
||||
* @param params
|
||||
*/
|
||||
export const batchDeleteCfgs = (params) => {
|
||||
Modal.confirm({
|
||||
title: '确认删除',
|
||||
content: '是否删除选中数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
defHttp.get({ url: Api.delRecordCfgs, params });
|
||||
},
|
||||
});
|
||||
};
|
|
@ -0,0 +1,158 @@
|
|||
import {BasicColumn} from '/@/components/Table';
|
||||
import {FormSchema} from '/@/components/Table';
|
||||
|
||||
//列表数据
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
title: '设备序号',
|
||||
align: "center",
|
||||
dataIndex: 'deviceIndex'
|
||||
},
|
||||
{
|
||||
title: '设备名称',
|
||||
align: "center",
|
||||
dataIndex: 'deviceName'
|
||||
},
|
||||
{
|
||||
title: 'IP地址',
|
||||
align: "center",
|
||||
dataIndex: 'ip'
|
||||
},
|
||||
{
|
||||
title: '录像开关',
|
||||
align: "center",
|
||||
dataIndex: 'recordSwitchBoolean',
|
||||
},
|
||||
{
|
||||
title: '录像存储位置',
|
||||
align: "center",
|
||||
dataIndex: 'storageDevName'
|
||||
},
|
||||
{
|
||||
title: '录像码流',
|
||||
align: "center",
|
||||
dataIndex: 'streamType',
|
||||
customRender:({record})=>{
|
||||
if(record.streamType == 0){
|
||||
return '主码流';
|
||||
}else if(record.streamType == 1){
|
||||
return '子码流';
|
||||
}else{
|
||||
return '';
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '录像计划',
|
||||
align: "center",
|
||||
dataIndex: 'planName'
|
||||
},
|
||||
];
|
||||
|
||||
export const formSchema: FormSchema[] = [
|
||||
{
|
||||
label: '',
|
||||
field: 'ids',
|
||||
component: 'Input',
|
||||
show: false,
|
||||
},
|
||||
{
|
||||
label: '设备序号',
|
||||
field: 'deviceIndex',
|
||||
component: 'Input',
|
||||
dynamicDisabled: true
|
||||
},
|
||||
{
|
||||
label: '设备名称',
|
||||
field: 'deviceName',
|
||||
component: 'Input',
|
||||
dynamicDisabled: true
|
||||
},
|
||||
{
|
||||
label: '录像开关',
|
||||
field: 'recordSwitch',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
options: [
|
||||
{label:'开启' , value: '1'},
|
||||
{label:'关闭' , value: '0'},
|
||||
]
|
||||
},
|
||||
defaultValue: '1'
|
||||
},
|
||||
{
|
||||
label: '存储位置',
|
||||
field: 'storageDevName',
|
||||
component: 'Input',
|
||||
slot: 'storageDevInput',
|
||||
},
|
||||
{
|
||||
label: '录像码流',
|
||||
field: 'streamType',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
options: [
|
||||
{label:'主码流' , value: 0},
|
||||
{label:'子码流' , value: 1},
|
||||
]
|
||||
},
|
||||
dynamicDisabled: true
|
||||
},
|
||||
{
|
||||
label: '录像计划',
|
||||
field: 'planName',
|
||||
component: 'Input',
|
||||
}
|
||||
];
|
||||
|
||||
export const addFormSchema: FormSchema[] = [
|
||||
{
|
||||
label: '设备序号',
|
||||
field: 'deviceIndex',
|
||||
component: 'Input',
|
||||
show: false
|
||||
},
|
||||
{
|
||||
label: '录像开关',
|
||||
field: 'recordSwitch',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
options: [
|
||||
{label:'开启' , value: '1'},
|
||||
{label:'关闭' , value: '0'},
|
||||
]
|
||||
},
|
||||
defaultValue: '1',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: '存储位置',
|
||||
field: 'storageDevId',
|
||||
component: 'Input',
|
||||
slot: 'storageDevInput',
|
||||
defaultValue: '0',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: '录像码流',
|
||||
field: 'streamType',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
options: [
|
||||
{label:'主码流' , value: 0},
|
||||
{label:'子码流' , value: 1},
|
||||
]
|
||||
},
|
||||
defaultValue: 0,
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: '录像计划',
|
||||
field: 'recordPlanId',
|
||||
component: 'Input',
|
||||
slot: 'planInput',
|
||||
defaultValue: '1',
|
||||
required: true,
|
||||
}
|
||||
];
|
||||
|
Loading…
Reference in New Issue