物联设备设备维度添加设备

This commit is contained in:
曹磊 2026-03-18 09:05:00 +08:00
parent eaf360daae
commit 03f8fd101b
11 changed files with 661 additions and 35 deletions

View File

@ -6,15 +6,6 @@
<a-form ref="formRef" :model="queryParam" :label-col="labelCol"
:wrapper-col="wrapperCol">
<a-row :gutter="24">
<a-col :lg="6">
<a-form-item name="dimension">
<template #label><span title="设备维度">设备维度</span></template>
<a-select v-model:value="queryParam.dimension" placeholder="请选择设备维度" allow-clear>
<a-select-option value="区域维度">区域维度</a-select-option>
<a-select-option value="机构维度">机构维度</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :lg="6">
<a-form-item name="deviceType">
<template #label><span title="设备类型">设备类型</span></template>
@ -112,6 +103,7 @@ const { prefixCls, tableContext, onExportXls, onImportXls } = useListPage({
fixed: 'right',
},
beforeFetch: async (params) => {
queryParam.dimension = '区域维度';
return Object.assign(params, queryParam);
},
},

View File

@ -0,0 +1,83 @@
<template>
<a-drawer :title="title" :width="width" :visible="visible" :closable="true" :footer-style="{ textAlign: 'right' }"
:bodyStyle="{ padding: '14px' }" @close="handleCancel">
<template #footer>
<a-button type="primary" style="margin-right: 8px" @click="handleCancel">关闭</a-button>
<a-button type="primary" @click="handleOk" v-if="!disableSubmit">确认</a-button>
</template>
<AreaDeviceAddList v-if="visible" ref="registerForm" @ok="submitCallback" :formDisabled="disableSubmit"
:formBpm="false">
</AreaDeviceAddList>
</a-drawer>
</template>
<script lang="ts" setup>
import { ref, nextTick, defineExpose } from 'vue';
import AreaDeviceAddList from './AreaDeviceAddList.vue'
const title = ref<string>('');
const width = ref<number>(1500);
const visible = ref<boolean>(false);
const disableSubmit = ref<boolean>(false);
const registerForm = ref();
const emit = defineEmits(['register', 'success']);
/**
* 新增
*/
function add() {
title.value = '新增';
visible.value = true;
nextTick(() => {
registerForm.value.add();
});
}
/**
* 编辑
* @param record
*/
function edit(record) {
title.value = disableSubmit.value ? '添加设备' : '编辑';
visible.value = true;
nextTick(() => {
registerForm.value.init(record);
});
}
/**
* 确定按钮点击事件
*/
function handleOk() {
registerForm.value.submitForm();
}
/**
* form保存回调事件
*/
function submitCallback() {
handleCancel();
emit('success');
}
/**
* 取消按钮回调事件
*/
function handleCancel() {
visible.value = false;
emit('success');
}
defineExpose({
add,
edit,
disableSubmit,
});
</script>
<style lang="less">
/**隐藏样式-modal确定按钮 */
.jee-hidden {
display: none !important;
}
</style>
<style lang="less" scoped></style>

View File

@ -11,15 +11,6 @@
<a-input v-model:value="queryParam.nuName" placeholder="请输入区域名称" allow-clear/>
</a-form-item>
</a-col>
<a-col :lg="5">
<a-form-item name="dimension">
<template #label><span title="设备维度">设备维度</span></template>
<a-select v-model:value="queryParam.dimension" placeholder="请选择设备维度" allow-clear>
<a-select-option value="区域维度">区域维度</a-select-option>
<a-select-option value="机构维度">机构维度</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :lg="5">
<a-form-item name="deviceType">
<template #label><span title="设备类型">设备类型</span></template>
@ -60,7 +51,7 @@
<BasicTable @register="registerTable">
<!--插槽:table标题-->
<template #tableTitle>
<a-button type="primary" preIcon="ant-design:plus-outlined" @click="handleAdd"> 添加设备</a-button>
<a-button type="primary" preIcon="ant-design:plus-outlined" @click="handleAdd"> 添加区域设备</a-button>
</template>
<!--操作栏-->
<template #action="{ record }">
@ -70,7 +61,7 @@
</template>
</BasicTable>
<!-- 表单区域 -->
<DeviceAddModal ref="registerDrawer" @success="handleSuccess" />
<AreaDeviceAddModal ref="registerDrawer" @success="handleSuccess" />
<LogModal ref="logDrawer" @success="handleSuccess" />
</div>
</template>
@ -79,10 +70,10 @@
import {ref, reactive, defineExpose, nextTick} from 'vue';
import { BasicTable, useTable, TableAction } from '/@/components/Table';
import { useListPage } from '/@/hooks/system/useListPage';
import { deviceColumns } from '../manager.data';
import { areaDeviceColumns } from '../manager.data';
import { deviceList } from '../manager.api';
import { useUserStore } from '/@/store/modules/user';
import DeviceAddModal from './DeviceAddModal.vue';
import AreaDeviceAddModal from './AreaDeviceAddModal.vue';
import LogModal from './LogModal.vue';
const formRef = ref();
@ -98,7 +89,7 @@ const { prefixCls, tableContext, onExportXls, onImportXls } = useListPage({
tableProps: {
title: '设备管理',
api: deviceList,
columns: deviceColumns,
columns: areaDeviceColumns,
canResize: false,
useSearchForm: false,
showIndexColumn: true,
@ -107,6 +98,7 @@ const { prefixCls, tableContext, onExportXls, onImportXls } = useListPage({
fixed: 'right',
},
beforeFetch: async (params) => {
queryParam.dimension = '区域维度';
return Object.assign(params, queryParam);
},
},

View File

@ -0,0 +1,82 @@
<template>
<a-drawer :title="title" :width="width" :visible="visible" :closable="true" :footer-style="{ textAlign: 'right' }"
:bodyStyle="{ padding: '14px' }" @close="handleCancel">
<template #footer>
<a-button type="primary" style="margin-right: 8px" @click="handleCancel">关闭</a-button>
<a-button type="primary" @click="handleOk" v-if="!disableSubmit">确认</a-button>
</template>
<AreaDeviceList v-if="visible" ref="registerForm" @ok="submitCallback" :formDisabled="disableSubmit"
:formBpm="false">
</AreaDeviceList>
</a-drawer>
</template>
<script lang="ts" setup>
import { ref, nextTick, defineExpose } from 'vue';
import AreaDeviceList from './AreaDeviceList.vue'
const title = ref<string>('');
const width = ref<number>(1800);
const visible = ref<boolean>(false);
const disableSubmit = ref<boolean>(false);
const registerForm = ref();
const emit = defineEmits(['register', 'success']);
/**
* 新增
*/
function add() {
title.value = '新增';
visible.value = true;
nextTick(() => {
registerForm.value.add();
});
}
/**
* 编辑
* @param record
*/
function edit(record) {
title.value = disableSubmit.value ? '设备管理' : '编辑';
visible.value = true;
nextTick(() => {
registerForm.value.init(record);
});
}
/**
* 确定按钮点击事件
*/
function handleOk() {
registerForm.value.submitForm();
}
/**
* form保存回调事件
*/
function submitCallback() {
handleCancel();
emit('success');
}
/**
* 取消按钮回调事件
*/
function handleCancel() {
visible.value = false;
}
defineExpose({
add,
edit,
disableSubmit,
});
</script>
<style lang="less">
/**隐藏样式-modal确定按钮 */
.jee-hidden {
display: none !important;
}
</style>
<style lang="less" scoped></style>

View File

@ -34,6 +34,7 @@
<BasicTable @register="registerTable">
<!--插槽:table标题-->
<template #tableTitle>
<a-button type="primary" preIcon="ant-design:plus-outlined" @click="handleAdd"> 添加机构设备</a-button>
<a-button type="primary" preIcon="ant-design:unlock-outlined" @click="handleOrgUnbind"> 机构解绑</a-button>
</template>
<!--操作栏-->
@ -44,7 +45,8 @@
</template>
</BasicTable>
<!-- 表单区域 -->
<DeviceModal ref="registerDrawer" @success="handleSuccess" />
<OrgDeviceModal ref="orgDrawer" @success="handleSuccess" />
<AreaDeviceModal ref="areaDrawer" @success="handleSuccess" />
</div>
</template>
@ -55,14 +57,16 @@ import { useListPage } from '/@/hooks/system/useListPage';
import { nuColumns } from '../manager.data';
import { areaList,unbindOrg } from '../manager.api';
import { useUserStore } from '/@/store/modules/user';
import DeviceModal from './DeviceModal.vue';
import AreaDeviceModal from './AreaDeviceModal.vue';
import OrgDeviceModal from './OrgDeviceModal.vue';
import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue';
import {Modal} from "ant-design-vue";
import {ExclamationCircleOutlined} from "@ant-design/icons-vue";
const formRef = ref();
const queryParam = reactive<any>({});
const registerDrawer = ref();
const orgDrawer = ref();
const areaDrawer = ref();
const orgCode = ref<any>('');
const departId = ref<any>('');
const userStore = useUserStore();
@ -132,12 +136,21 @@ function getTableAction(record) {
];
}
/**
* 设备管理
*/
function handleAdd(){
let record = { "departId" : departId.value,"orgCode":orgCode.value };
orgDrawer.value.disableSubmit = true;
orgDrawer.value.edit(record);
}
/**
* 设备管理
*/
function deviceManager(record: Recordable){
registerDrawer.value.disableSubmit = true;
registerDrawer.value.edit(record);
areaDrawer.value.disableSubmit = true;
areaDrawer.value.edit(record);
}
/**
@ -160,6 +173,7 @@ function searchReset() {
//
function init(record) {
orgCode.value = record.orgCode;
departId.value = record.id;
searchQuery();
}

View File

@ -0,0 +1,224 @@
<template>
<a-spin :spinning="confirmLoading">
<div class="p-2">
<!--查询区域-->
<div class="jeecg-basic-table-form-container">
<a-form ref="formRef" :model="queryParam" :label-col="labelCol"
:wrapper-col="wrapperCol">
<a-row :gutter="24">
<a-col :lg="6">
<a-form-item name="deviceType">
<template #label><span title="设备类型">设备类型</span></template>
<a-select v-model:value="queryParam.deviceType" placeholder="请选择设备类型" allow-clear>
<a-select-option value="摄像头">摄像头</a-select-option>
<a-select-option value="录像机">录像机</a-select-option>
<a-select-option value="交换机">交换机</a-select-option>
<a-select-option value="路由器">路由器</a-select-option>
<a-select-option value="无线AP">无线AP</a-select-option>
<a-select-option value="智能电表">智能电表</a-select-option>
<a-select-option value="智能水表">智能水表</a-select-option>
<a-select-option value="温湿度计">温湿度计</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :lg="6">
<a-form-item name="izAllocate">
<template #label><span title="分配状态">在线状态</span></template>
<a-select v-model:value="queryParam.izAllocate" placeholder="请选择在线状态" allow-clear>
<a-select-option value="未分配">未分配</a-select-option>
<a-select-option value="释放">释放</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :lg="6">
<span style="float: left; overflow: hidden" class="table-page-search-submitButtons">
<a-col :lg="6">
<a-button type="primary" preIcon="ant-design:search-outlined" @click="searchQuery">查询</a-button>
<a-button type="primary" preIcon="ant-design:reload-outlined" @click="searchReset"
style="margin-left: 8px">重置</a-button>
</a-col>
</span>
</a-col>
</a-row>
</a-form>
</div>
<!--引用表格-->
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<!--插槽:table标题-->
<template #tableTitle>
<a-button v-if="selectedRowKeys.length > 0" type="primary" preIcon="ant-design:plus-outlined" @click="handleCreate"> 绑定设备</a-button>
</template>
<!--操作栏-->
<template #action="{ record }">
<TableAction :actions="getTableAction(record)"/>
</template>
<template v-slot:bodyCell="{ column, record, index, text }">
</template>
</BasicTable>
<a-modal
ref="modalRef"
v-model:visible="visible"
:wrap-style="{ overflow: 'hidden', background:'transparent'}"
:bodyStyle="{ padding:'12px' }"
@ok="handleOk"
>
<a-textarea v-model:value="remarks" placeholder="请输入备注" :rows="4" />
<template #title>
<div ref="modalTitleRef" style="width: 100%; cursor: move">备注</div>
</template>
</a-modal>
</div>
</a-spin>
</template>
<script lang="ts" name="iotManager-deviceAddList" setup>
import {ref, reactive, defineExpose, nextTick} from 'vue';
import { BasicTable, useTable, TableAction } from '/@/components/Table';
import { useListPage } from '/@/hooks/system/useListPage';
import { deviceAddColumns } from '../manager.data';
import { canAddList,addOrgBatch } from '../manager.api';
import { useUserStore } from '/@/store/modules/user';
const formRef = ref();
const confirmLoading = ref<boolean>(false);
const queryParam = reactive<any>({});
const departId = ref<any>('');
const orgCode = ref<any>('');
const remarks = ref<any>('');
const visible = ref<any>();
const userStore = useUserStore();
//table
const { prefixCls, tableContext, onExportXls, onImportXls } = useListPage({
tableProps: {
title: '添加设备',
api: canAddList,
columns: deviceAddColumns,
canResize: false,
useSearchForm: false,
showIndexColumn: true,
showActionColumn: false,
actionColumn: {
width: 180,
fixed: 'right',
},
beforeFetch: async (params) => {
queryParam.dimension = '机构维度';
queryParam.departId = departId.value;
return Object.assign(params, queryParam);
},
},
});
const [registerTable, { reload, collapseAll, updateTableDataRecord, findTableDataRecord, getDataSource }, { rowSelection, selectedRowKeys, selectedRows }] = tableContext;
const labelCol = reactive({
xs:24,
sm:8,
xl:8,
xxl:8
});
const wrapperCol = reactive({
xs: 24,
sm: 16,
});
/**
* 成功回调
*/
function handleSuccess() {
reload();
}
/**
* 操作栏
*/
function getTableAction(record) {
return [
{
},
];
}
/**
* 查询
*/
function searchQuery() {
queryParam.departId = departId.value;
reload();
}
/**
* 重置
*/
function searchReset() {
formRef.value.resetFields();
selectedRowKeys.value = [];
//
searchQuery();
}
function handleCreate(){
visible.value = true;
}
function handleOk(){
confirmLoading.value = true;
let record = {
"deviceList": selectedRows.value,
"remarks": remarks.value,
"departId": departId.value,
"orgCode": orgCode.value,
}
addOrgBatch(record)
.then((res) => {
searchQuery();
}).catch(() =>{})
.finally(() => {
confirmLoading.value = false;
visible.value = false;
});
}
//
function init(record) {
departId.value = record.departId;
orgCode.value = record.orgCode;
searchQuery();
}
defineExpose({
init
});
</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>

View File

@ -5,15 +5,15 @@
<a-button type="primary" style="margin-right: 8px" @click="handleCancel">关闭</a-button>
<a-button type="primary" @click="handleOk" v-if="!disableSubmit">确认</a-button>
</template>
<DeviceAddList v-if="visible" ref="registerForm" @ok="submitCallback" :formDisabled="disableSubmit"
<OrgDeviceAddList v-if="visible" ref="registerForm" @ok="submitCallback" :formDisabled="disableSubmit"
:formBpm="false">
</DeviceAddList>
</OrgDeviceAddList>
</a-drawer>
</template>
<script lang="ts" setup>
import { ref, nextTick, defineExpose } from 'vue';
import DeviceAddList from './DeviceAddList.vue'
import OrgDeviceAddList from './OrgDeviceAddList.vue'
const title = ref<string>('');
const width = ref<number>(1500);

View File

@ -0,0 +1,207 @@
<template>
<div class="p-2">
<!--查询区域-->
<div class="jeecg-basic-table-form-container">
<a-form ref="formRef" :model="queryParam" :label-col="labelCol"
:wrapper-col="wrapperCol">
<a-row :gutter="24">
<a-col :lg="5">
<a-form-item name="deviceType">
<template #label><span title="设备类型">设备类型</span></template>
<a-select v-model:value="queryParam.deviceType" placeholder="请选择设备类型" allow-clear>
<a-select-option value="摄像头">摄像头</a-select-option>
<a-select-option value="录像机">录像机</a-select-option>
<a-select-option value="交换机">交换机</a-select-option>
<a-select-option value="路由器">路由器</a-select-option>
<a-select-option value="无线AP">无线AP</a-select-option>
<a-select-option value="智能电表">智能电表</a-select-option>
<a-select-option value="智能水表">智能水表</a-select-option>
<a-select-option value="温湿度计">温湿度计</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :lg="5">
<a-form-item name="deviceStatus">
<template #label><span title="在线状态">在线状态</span></template>
<a-select v-model:value="queryParam.deviceStatus" placeholder="请选择在线状态" allow-clear>
<a-select-option value="在线">在线</a-select-option>
<a-select-option value="离线">离线</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :lg="4">
<span style="float: left; overflow: hidden" class="table-page-search-submitButtons">
<a-col :lg="6">
<a-button type="primary" preIcon="ant-design:search-outlined" @click="searchQuery">查询</a-button>
<a-button type="primary" preIcon="ant-design:reload-outlined" @click="searchReset"
style="margin-left: 8px">重置</a-button>
</a-col>
</span>
</a-col>
</a-row>
</a-form>
</div>
<!--引用表格-->
<BasicTable @register="registerTable">
<!--插槽:table标题-->
<template #tableTitle>
<a-button type="primary" preIcon="ant-design:plus-outlined" @click="handleAdd"> 添加区域设备</a-button>
</template>
<!--操作栏-->
<template #action="{ record }">
<TableAction :actions="getTableAction(record)"/>
</template>
<template v-slot:bodyCell="{ column, record, index, text }">
</template>
</BasicTable>
<!-- 表单区域 -->
<OrgDeviceAddModal ref="registerDrawer" @success="handleSuccess" />
<LogModal ref="logDrawer" @success="handleSuccess" />
</div>
</template>
<script lang="ts" name="iotManager-deviceList" setup>
import {ref, reactive, defineExpose, nextTick} from 'vue';
import { BasicTable, useTable, TableAction } from '/@/components/Table';
import { useListPage } from '/@/hooks/system/useListPage';
import { orgDeviceColumns } from '../manager.data';
import { deviceList } from '../manager.api';
import { useUserStore } from '/@/store/modules/user';
import OrgDeviceAddModal from './OrgDeviceAddModal.vue';
import LogModal from './LogModal.vue';
const formRef = ref();
const queryParam = reactive<any>({});
const registerDrawer = ref();
const logDrawer = ref();
const departId = ref<any>('');
const orgCode = ref<any>('');
const userStore = useUserStore();
//table
const { prefixCls, tableContext, onExportXls, onImportXls } = useListPage({
tableProps: {
title: '设备管理',
api: deviceList,
columns: orgDeviceColumns,
canResize: false,
useSearchForm: false,
showIndexColumn: true,
actionColumn: {
width: 180,
fixed: 'right',
},
beforeFetch: async (params) => {
queryParam.dimension = '机构维度';
queryParam.departId = departId.value;
return Object.assign(params, queryParam);
},
},
});
const [registerTable, { reload, collapseAll, updateTableDataRecord, findTableDataRecord, getDataSource }, { rowSelection, selectedRowKeys }] = tableContext;
const labelCol = reactive({
xs:24,
sm:8,
xl:8,
xxl:8
});
const wrapperCol = reactive({
xs: 24,
sm: 16,
});
/**
* 成功回调
*/
function handleSuccess() {
reload();
}
/**
* 操作栏
*/
function getTableAction(record) {
return [
{
label: '设备日志',
onClick: deviceLog.bind(null, record),
},
];
}
/**
* 设备管理
*/
function handleAdd(){
let record = { "departId" : departId.value,"orgCode":orgCode.value };
registerDrawer.value.disableSubmit = true;
registerDrawer.value.edit(record);
}
/**
* 设备日志
*/
function deviceLog(record: Recordable){
logDrawer.value.disableSubmit = true;
logDrawer.value.edit(record);
}
/**
* 查询
*/
function searchQuery() {
reload();
}
/**
* 重置
*/
function searchReset() {
formRef.value.resetFields();
//
searchQuery();
}
//
function init(record) {
departId.value = record.departId;
orgCode.value = record.sysOrgCode;
searchQuery();
}
defineExpose({
init
});
</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>

View File

@ -5,15 +5,15 @@
<a-button type="primary" style="margin-right: 8px" @click="handleCancel">关闭</a-button>
<a-button type="primary" @click="handleOk" v-if="!disableSubmit">确认</a-button>
</template>
<DeviceList v-if="visible" ref="registerForm" @ok="submitCallback" :formDisabled="disableSubmit"
<OrgDeviceList v-if="visible" ref="registerForm" @ok="submitCallback" :formDisabled="disableSubmit"
:formBpm="false">
</DeviceList>
</OrgDeviceList>
</a-drawer>
</template>
<script lang="ts" setup>
import { ref, nextTick, defineExpose } from 'vue';
import DeviceList from './DeviceList.vue'
import OrgDeviceList from './OrgDeviceList.vue'
const title = ref<string>('');
const width = ref<number>(1800);

View File

@ -6,6 +6,7 @@ enum Api {
deviceList = '/iot/manager/device/list',
canAddList = '/iot/manager/device/canAddList',
addBatch = '/iot/manager/device/addBatch',
addOrgBatch = '/iot/manager/device/addOrgBatch',
unbindOrg = '/iot/manager/device/unbindOrg',
logList = '/iot/manager/log/list',
}
@ -35,6 +36,7 @@ export const canAddList = (params) => defHttp.get({ url: Api.canAddList, params
* @param params
*/
export const addBatch = (params) => defHttp.post({ url: Api.addBatch, params }, { joinParamsToUrl: true });
export const addOrgBatch = (params) => defHttp.post({ url: Api.addOrgBatch, params }, { joinParamsToUrl: true });
/**
*
*/

View File

@ -53,7 +53,37 @@ export const nuColumns: BasicColumn[] = [
];
//列表数据
export const deviceColumns: BasicColumn[] = [
export const orgDeviceColumns: BasicColumn[] = [
{
title: '设备标识',
align: "center",
dataIndex: 'sn',
},
{
title: '设备维度',
align: "center",
dataIndex: 'dimension',
},
{
title: '设备类型',
align: "center",
dataIndex: 'deviceType',
},
{
title: '在线状态',
align: "center",
dataIndex: 'deviceStatus',
},
{
title: '分配状态',
align: "center",
dataIndex: 'izAllocate',
},
];
//列表数据
export const areaDeviceColumns: BasicColumn[] = [
{
title: '区域名称',
align: "center",