|
|
@@ -1,7 +1,343 @@
|
|
|
<template>
|
|
|
- <div>院区重点监控区域</div>
|
|
|
+ <div class="safety-platform-container">
|
|
|
+ <div class="safety-platform-container__header">
|
|
|
+ <div class="breadcrumb-title">院区重点监控区域</div>
|
|
|
+ </div>
|
|
|
+ <div class="safety-platform-container__main">
|
|
|
+ <div class="search-table-container">
|
|
|
+ <header class="disaster-precaution__header">
|
|
|
+ <el-button
|
|
|
+ v-if="surveillanceAreaManagePermission"
|
|
|
+ class="search-table-container--button"
|
|
|
+ type="primary"
|
|
|
+ :icon="Plus"
|
|
|
+ @click="handleAddSurveillanceArea"
|
|
|
+ >
|
|
|
+ 新建重点监控区域
|
|
|
+ </el-button>
|
|
|
+ <BasicSearch
|
|
|
+ :searchConfig="SURVEILLANCE_AREA_LIST_SEARCH_CONFIG"
|
|
|
+ :searchData="searchData"
|
|
|
+ :custom-reset="true"
|
|
|
+ @update:search-data="handleSearch"
|
|
|
+ @custom-reset="handleReset"
|
|
|
+ >
|
|
|
+ <template #surveillanceArea>
|
|
|
+ <el-input
|
|
|
+ v-model="searchKeyword"
|
|
|
+ :placeholder="`请输入${curSearchTypeLabel}进行搜索`"
|
|
|
+ clearable
|
|
|
+ @input="handleSearch"
|
|
|
+ @keyup.enter="handleSearch"
|
|
|
+ style="width: 380px"
|
|
|
+ >
|
|
|
+ <template #prefix>
|
|
|
+ <el-icon color="#1777ff"><Search /></el-icon>
|
|
|
+ </template>
|
|
|
+ <template #prepend>
|
|
|
+ <el-select
|
|
|
+ v-model="searchSelectedType"
|
|
|
+ placeholder="选择搜索项"
|
|
|
+ @change="handleSelectedTypeChange"
|
|
|
+ style="width: 100px"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in surveillanceAreaQueryOptions"
|
|
|
+ :key="item.value"
|
|
|
+ :label="item.label"
|
|
|
+ :value="item.value"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </template>
|
|
|
+ </el-input>
|
|
|
+ </template>
|
|
|
+ </BasicSearch>
|
|
|
+ </header>
|
|
|
+ <BasicTable ref="basicTableRef" :tableData="tableData" :tableConfig="tableConfig">
|
|
|
+ <template #cameraName="scope">
|
|
|
+ <div class="camera-name-container">
|
|
|
+ <div v-for="item in scope.row.children" :key="item.id">
|
|
|
+ <ThumbnailClick
|
|
|
+ :imageUrl="item.pushStreamDTO.imageUrl"
|
|
|
+ :code="item.code"
|
|
|
+ position="right"
|
|
|
+ @mouse-enter="handleMouseEnter"
|
|
|
+ @mouse-leave="handleMouseLeave"
|
|
|
+ >
|
|
|
+ <div
|
|
|
+ :class="{ active: activeCameraCode === item.code && activePositionId === scope.row.id }"
|
|
|
+ @click="handleCameraClick(scope.row.id, item.code)"
|
|
|
+ >{{ item.name }}</div
|
|
|
+ >
|
|
|
+ </ThumbnailClick>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <template #action="{ row, index }">
|
|
|
+ <div class="action-container--div">
|
|
|
+ <ActionButton text="上移" @click="handleUpOne(row, index)" v-if="index > 0" />
|
|
|
+ <ActionButton text="下移" @click="handleDownOne(row, index)" v-if="index < tableData.length - 1" />
|
|
|
+ <ActionButton text="编辑" @click="handleEditSurveillanceArea(row)" />
|
|
|
+ <ActionButton
|
|
|
+ text="删除"
|
|
|
+ :popconfirm="{
|
|
|
+ title: '是否删除该重点监控区域?',
|
|
|
+ }"
|
|
|
+ @confirm="handleDeleteSurveillanceArea(row.id)"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </BasicTable>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <UpdatePositionMonitorCamera
|
|
|
+ v-if="updatePositionMonitorCameraVisible"
|
|
|
+ @confirm="handleConfirmPositionMonitorCamera"
|
|
|
+ @close="handleClosePositionMonitorCamera"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
</template>
|
|
|
|
|
|
-<script setup lang="ts"></script>
|
|
|
+<script setup lang="ts">
|
|
|
+ import { ref, onMounted, reactive, computed } from 'vue';
|
|
|
+ import { ElMessage } from 'element-plus';
|
|
|
+ import { Plus, Search } from '@element-plus/icons-vue';
|
|
|
+ import { storeToRefs } from 'pinia';
|
|
|
+ import BasicSearch from '@/components/BasicSearch.vue';
|
|
|
+ import BasicTable from '@/components/BasicTable.vue';
|
|
|
+ import ActionButton from '@/components/ActionButton.vue';
|
|
|
+ import UpdatePositionMonitorCamera from '@/components/position-monitor-camera-edit/UpdatePositionMonitorCamera.vue';
|
|
|
+ import ThumbnailClick from '@/components/thumbnail/ThumbnailClick.vue';
|
|
|
+ import useTableConfig from '@/hooks/useTableConfigHook';
|
|
|
+ import { useUserInfoHook } from '@/hooks/useUserInfoHook';
|
|
|
+ import { usePositionMonitorCameraEdit } from '@/store/modules/usePositionMonitorCameraEdit';
|
|
|
+ import {
|
|
|
+ FIELDTYPE,
|
|
|
+ FIELD_CONTENT,
|
|
|
+ POSITION_TYPE,
|
|
|
+ surveillanceAreaQueryOptions,
|
|
|
+ SURVEILLANCE_MANAGEMENT_PERMISSIONS,
|
|
|
+ } from './constant';
|
|
|
+ import {
|
|
|
+ SURVEILLANCE_AREA_LIST_TABLE_MAX_HEIGHT_DEFAULT,
|
|
|
+ SURVEILLANCE_AREA_LIST_TABLE_MAX_HEIGHT_PERMISSION,
|
|
|
+ SURVEILLANCE_AREA_LIST_TABLE_OPTIONS,
|
|
|
+ SURVEILLANCE_AREA_LIST_TABLE_COLUMNS,
|
|
|
+ SURVEILLANCE_AREA_LIST_SEARCH_CONFIG,
|
|
|
+ } from './config';
|
|
|
+ import {
|
|
|
+ GetPositionListParams,
|
|
|
+ PositionMonitorCameraListRes,
|
|
|
+ getSurveillanceAreaList,
|
|
|
+ AddOrUpdatePositionInfoParams,
|
|
|
+ addOrUpdatePositionInfo,
|
|
|
+ updateCameraGroupOrder,
|
|
|
+ } from '@/api/security-confidentiality-position';
|
|
|
+ import { deleteCameraGroupApi } from '@/api/nine-square-grid';
|
|
|
|
|
|
-<style scoped></style>
|
|
|
+ const { tableConfig } = useTableConfig(SURVEILLANCE_AREA_LIST_TABLE_COLUMNS, SURVEILLANCE_AREA_LIST_TABLE_OPTIONS);
|
|
|
+
|
|
|
+ const { permissions } = useUserInfoHook();
|
|
|
+ const surveillanceAreaManagePermission = ref<boolean>(false);
|
|
|
+
|
|
|
+ const positionMonitorCameraEdit = usePositionMonitorCameraEdit();
|
|
|
+ const {
|
|
|
+ titleOfUpdatePositionMonitorCamera,
|
|
|
+ dataOfPosition,
|
|
|
+ idOfPosition,
|
|
|
+ nameOfPosition,
|
|
|
+ selectedCameraIdsOfPosition,
|
|
|
+ } = storeToRefs(positionMonitorCameraEdit);
|
|
|
+ const { initDataOfPosition, resetPositionMonitorCameraEdit } = positionMonitorCameraEdit;
|
|
|
+
|
|
|
+ const searchData = reactive<GetPositionListParams>({
|
|
|
+ groupName: '',
|
|
|
+ cameraName: '',
|
|
|
+ });
|
|
|
+
|
|
|
+ const searchSelectedType = ref(FIELDTYPE.POSITION_NAME);
|
|
|
+ const searchKeyword = ref('');
|
|
|
+ const curSearchTypeLabel = computed(() => {
|
|
|
+ const option = surveillanceAreaQueryOptions.find((item) => item.value === searchSelectedType.value);
|
|
|
+ return option ? option.label : FIELD_CONTENT[searchSelectedType.value];
|
|
|
+ });
|
|
|
+
|
|
|
+ const tableData = ref<PositionMonitorCameraListRes[]>([]);
|
|
|
+
|
|
|
+ const updatePositionMonitorCameraVisible = ref(false);
|
|
|
+
|
|
|
+ const handleAddSurveillanceArea = () => {
|
|
|
+ titleOfUpdatePositionMonitorCamera.value = '新建重点监控区域';
|
|
|
+ dataOfPosition.value = undefined;
|
|
|
+ initDataOfPosition();
|
|
|
+ updatePositionMonitorCameraVisible.value = true;
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleSearch = () => {
|
|
|
+ if (searchSelectedType.value === FIELDTYPE.POSITION_NAME) searchData.groupName = searchKeyword.value;
|
|
|
+ else searchData.cameraName = searchKeyword.value;
|
|
|
+ getTableData();
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleReset = () => {
|
|
|
+ searchKeyword.value = '';
|
|
|
+ searchSelectedType.value = FIELDTYPE.POSITION_NAME;
|
|
|
+ searchData.cameraName = '';
|
|
|
+ searchData.groupName = '';
|
|
|
+ getTableData();
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleSelectedTypeChange = () => {
|
|
|
+ searchKeyword.value = '';
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleUpOne = (currentRow: PositionMonitorCameraListRes, currentIndex: number) => {
|
|
|
+ // 获取上一行的数据
|
|
|
+ const prevRow = tableData.value[currentIndex - 1];
|
|
|
+ // 构造交换数据数组
|
|
|
+ const swapData = [
|
|
|
+ { id: prevRow.id, orderNum: currentRow.orderNum }, // 上一行使用当前行的orderNum
|
|
|
+ { id: currentRow.id, orderNum: prevRow.orderNum }, // 当前行使用上一行的orderNum
|
|
|
+ ];
|
|
|
+
|
|
|
+ updateCameraGroupOrder(swapData)
|
|
|
+ .then(() => {
|
|
|
+ ElMessage.success('上移成功');
|
|
|
+ getTableData();
|
|
|
+ })
|
|
|
+ .catch(() => {
|
|
|
+ ElMessage.error('上移失败');
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleDownOne = (currentRow: PositionMonitorCameraListRes, currentIndex: number) => {
|
|
|
+ // 获取下一行的数据
|
|
|
+ const nextRow = tableData.value[currentIndex + 1];
|
|
|
+ // 构造交换数据数组
|
|
|
+ const swapData = [
|
|
|
+ { id: nextRow.id, orderNum: currentRow.orderNum }, // 下一行使用当前行的orderNum
|
|
|
+ { id: currentRow.id, orderNum: nextRow.orderNum }, // 当前行使用下一行的orderNum
|
|
|
+ ];
|
|
|
+
|
|
|
+ updateCameraGroupOrder(swapData)
|
|
|
+ .then(() => {
|
|
|
+ ElMessage.success('下移成功');
|
|
|
+ getTableData();
|
|
|
+ })
|
|
|
+ .catch(() => {
|
|
|
+ ElMessage.error('下移失败');
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleEditSurveillanceArea = (row: PositionMonitorCameraListRes) => {
|
|
|
+ titleOfUpdatePositionMonitorCamera.value = '编辑重点监控区域';
|
|
|
+ dataOfPosition.value = row;
|
|
|
+ initDataOfPosition();
|
|
|
+ updatePositionMonitorCameraVisible.value = true;
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleDeleteSurveillanceArea = (id: number) => {
|
|
|
+ deleteCameraGroupApi(id).then(() => {
|
|
|
+ ElMessage.success('重点监控区域删除成功');
|
|
|
+ getTableData();
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleConfirmPositionMonitorCamera = () => {
|
|
|
+ const params: AddOrUpdatePositionInfoParams = {
|
|
|
+ id: idOfPosition.value ?? undefined,
|
|
|
+ groupName: nameOfPosition.value,
|
|
|
+ type: POSITION_TYPE.SURVEILLANCE_AREA,
|
|
|
+ cameraIdList: selectedCameraIdsOfPosition.value.map((item) => item.id),
|
|
|
+ };
|
|
|
+ addOrUpdatePositionInfo(params).then(() => {
|
|
|
+ ElMessage.success(idOfPosition.value ? '重点监控区域编辑成功' : '重点监控区域新建成功');
|
|
|
+ getTableData();
|
|
|
+ });
|
|
|
+ updatePositionMonitorCameraVisible.value = false;
|
|
|
+ resetPositionMonitorCameraEdit();
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleClosePositionMonitorCamera = () => {
|
|
|
+ ElMessage.info('取消操作');
|
|
|
+ updatePositionMonitorCameraVisible.value = false;
|
|
|
+ resetPositionMonitorCameraEdit();
|
|
|
+ };
|
|
|
+
|
|
|
+ const getTableData = () => {
|
|
|
+ tableConfig.loading = true;
|
|
|
+ getSurveillanceAreaList(searchData).then((res) => {
|
|
|
+ tableData.value = res;
|
|
|
+ });
|
|
|
+ tableConfig.loading = false;
|
|
|
+ };
|
|
|
+
|
|
|
+ // 当前选中的重点监控区域id和相机code
|
|
|
+ const activePositionId = ref(0);
|
|
|
+ const activeCameraCode = ref('');
|
|
|
+ const handleCameraClick = (id: number, code: string) => {
|
|
|
+ activePositionId.value = id;
|
|
|
+ activeCameraCode.value = code;
|
|
|
+ };
|
|
|
+ const handleMouseEnter = (code: string) => {
|
|
|
+ activeCameraCode.value = code;
|
|
|
+ };
|
|
|
+ const handleMouseLeave = () => {
|
|
|
+ activeCameraCode.value = '';
|
|
|
+ };
|
|
|
+
|
|
|
+ // 动态生成表格列配置
|
|
|
+ const getTableColumns = () => {
|
|
|
+ if (surveillanceAreaManagePermission.value) {
|
|
|
+ return SURVEILLANCE_AREA_LIST_TABLE_COLUMNS;
|
|
|
+ } else {
|
|
|
+ // 过滤掉操作列
|
|
|
+ return SURVEILLANCE_AREA_LIST_TABLE_COLUMNS.filter(
|
|
|
+ (column) => column.prop !== 'action' && column.type !== 'selection',
|
|
|
+ );
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ onMounted(() => {
|
|
|
+ getTableData();
|
|
|
+ surveillanceAreaManagePermission.value = Boolean(
|
|
|
+ permissions.find(
|
|
|
+ (item: { code: string }) => item.code === SURVEILLANCE_MANAGEMENT_PERMISSIONS.SURVEILLANCE_MANAGEMENT,
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ tableConfig.maxHeight = surveillanceAreaManagePermission.value
|
|
|
+ ? SURVEILLANCE_AREA_LIST_TABLE_MAX_HEIGHT_PERMISSION
|
|
|
+ : SURVEILLANCE_AREA_LIST_TABLE_MAX_HEIGHT_DEFAULT;
|
|
|
+ tableConfig.columns = getTableColumns();
|
|
|
+ });
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+ @use '@/styles/page-main-layout.scss' as *;
|
|
|
+ @use '@/styles/page-details-layout.scss' as *;
|
|
|
+ @use '@/styles/basic-table-action.scss' as *;
|
|
|
+
|
|
|
+ .action-container--div {
|
|
|
+ justify-content: flex-start;
|
|
|
+ }
|
|
|
+
|
|
|
+ .camera-name-container {
|
|
|
+ display: flex;
|
|
|
+ gap: 10px;
|
|
|
+ align-items: flex-start;
|
|
|
+ flex-direction: column;
|
|
|
+ }
|
|
|
+
|
|
|
+ .camera-name-container .thumb-nail {
|
|
|
+ color: #1777ff;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+
|
|
|
+ .camera-name-container .thumb-nail:hover {
|
|
|
+ color: #94c1ff;
|
|
|
+ }
|
|
|
+
|
|
|
+ .camera-name-container .active {
|
|
|
+ color: #003f97;
|
|
|
+ }
|
|
|
+</style>
|