Compare commits

...

3 Commits

Author SHA1 Message Date
ChenYi
789a16e958 新增重推设备信息 2025-08-05 11:30:06 +08:00
ChenYi
ee10c142a6 修改设备批量添加 2025-08-05 11:16:38 +08:00
ChenYi
22b6895eed 调整设备添加 2025-08-05 10:57:01 +08:00
3 changed files with 143 additions and 34 deletions

View File

@ -2,7 +2,7 @@
import type { VbenFormProps } from '#/adapter/form'; import type { VbenFormProps } from '#/adapter/form';
import type { VxeGridProps } from '#/adapter/vxe-table'; import type { VxeGridProps } from '#/adapter/vxe-table';
import { computed, h, ref } from 'vue'; import { computed, h, ref, watch } from 'vue';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { Page, useVbenModal } from '@vben/common-ui'; import { Page, useVbenModal } from '@vben/common-ui';
@ -18,9 +18,10 @@ import {
import { useVbenForm } from '#/adapter/form'; import { useVbenForm } from '#/adapter/form';
import { useVbenVxeGrid } from '#/adapter/vxe-table'; import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { import {
postAggregationDeviceBatchCreateAsync,
postAggregationDeviceCreateAsync, postAggregationDeviceCreateAsync,
postAggregationDeviceDeleteAsync, postAggregationDeviceDeleteAsync,
postAggregationDeviceBatchCreateAsync, postAggregationDeviceRepushDeviceInfoToIoTplatform,
postDeviceInfoCacheDeviceDataToRedis, postDeviceInfoCacheDeviceDataToRedis,
postDeviceInfoPage, postDeviceInfoPage,
} from '#/api-client'; } from '#/api-client';
@ -82,6 +83,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ formOptions, gridOptions });
const editRow: Record<string, any> = ref({}); const editRow: Record<string, any> = ref({});
const cacheRefreshLoading = ref(false); const cacheRefreshLoading = ref(false);
const pageLoading = ref(false); const pageLoading = ref(false);
const loadingTip = ref('缓存刷新中...');
const commandRow: Record<string, any> = ref({}); const commandRow: Record<string, any> = ref({});
const [UserModal, userModalApi] = useVbenModal({ const [UserModal, userModalApi] = useVbenModal({
draggable: true, draggable: true,
@ -167,16 +169,22 @@ const [BatchAddForm, batchAddFormApi] = useVbenForm({
showCollapseButton: false, showCollapseButton: false,
showDefaultActions: false, showDefaultActions: false,
wrapperClass: 'grid-cols-2', wrapperClass: 'grid-cols-2',
//
autoSubmitOnEnter: false,
}); });
const [BatchAddModal, batchAddModalApi] = useVbenModal({ const [BatchAddModal, batchAddModalApi] = useVbenModal({
draggable: true, draggable: true,
onConfirm: submitBatchAdd, onConfirm: submitBatchAdd,
onBeforeClose: () => { onBeforeClose: () => {
batchAddFormApi.resetForm();
return true; return true;
}, },
}); });
//
const batchAddModalState = batchAddModalApi.useStore();
// //
async function submit() { async function submit() {
const isEdit = !!editRow.value.id; const isEdit = !!editRow.value.id;
@ -331,6 +339,28 @@ const toTelemetryLog = (row: Record<string, any>) => {
}, },
}); });
}; };
// IoT
const repushDeviceInfo = async (row: Record<string, any>) => {
try {
pageLoading.value = true;
loadingTip.value = '重推设备信息中...';
const result = await postAggregationDeviceRepushDeviceInfoToIoTplatform({
body: { id: row.id },
});
if (result.data) {
Message.success('重推设备信息成功');
gridApi.reload();
} else {
Message.error('重推设备信息失败');
}
} catch (error) {
Message.error('重推设备信息失败');
} finally {
pageLoading.value = false;
loadingTip.value = '缓存刷新中...';
}
};
const openAddModal = async () => { const openAddModal = async () => {
editRow.value = {}; editRow.value = {};
userModalApi.open(); userModalApi.open();
@ -385,7 +415,9 @@ async function submitBatchAdd() {
} }
// //
const invalidAddresses = addressList.filter((address: string) => !address || address.length < 3); const invalidAddresses = addressList.filter(
(address: string) => !address || address.length < 3,
);
if (invalidAddresses.length > 0) { if (invalidAddresses.length > 0) {
Message.error(`以下设备地址格式不正确: ${invalidAddresses.join(', ')}`); Message.error(`以下设备地址格式不正确: ${invalidAddresses.join(', ')}`);
return; return;
@ -435,15 +467,58 @@ async function submitBatchAdd() {
// //
const openBatchAddModal = () => { const openBatchAddModal = () => {
console.log('打开批量添加模态框');
batchAddFormApi.resetForm(); batchAddFormApi.resetForm();
batchAddModalApi.open(); batchAddModalApi.open();
}; };
//
const addressLines = ref(0);
//
const getAddressLines = () => {
try {
const formValues = batchAddFormApi.getValues();
const addressList = formValues?.addressList;
if (!addressList || typeof addressList !== 'string') {
addressLines.value = 0;
return 0;
}
const lines = addressList.split('\n').filter((line: string) => line.trim());
addressLines.value = lines.length;
return lines.length;
} catch {
addressLines.value = 0;
return 0;
}
};
// 使
const computedAddressLines = computed(() => {
try {
const formValues = batchAddFormApi.getValues();
const addressList = formValues?.addressList;
if (!addressList || typeof addressList !== 'string') {
return 0;
}
const lines = addressList.split('\n').filter((line: string) => line.trim());
return lines.length;
} catch {
return 0;
}
});
// addressLines
watch(computedAddressLines, (newValue) => {
addressLines.value = newValue;
}, { immediate: true });
// //
const handleCacheRefresh = async () => { const handleCacheRefresh = async () => {
try { try {
cacheRefreshLoading.value = true; cacheRefreshLoading.value = true;
pageLoading.value = true; pageLoading.value = true;
loadingTip.value = '缓存刷新中...';
const result = await postDeviceInfoCacheDeviceDataToRedis(); const result = await postDeviceInfoCacheDeviceDataToRedis();
if (result.data) { if (result.data) {
Message.success('缓存刷新成功'); Message.success('缓存刷新成功');
@ -457,6 +532,7 @@ const handleCacheRefresh = async () => {
} finally { } finally {
cacheRefreshLoading.value = false; cacheRefreshLoading.value = false;
pageLoading.value = false; pageLoading.value = false;
loadingTip.value = '缓存刷新中...';
} }
}; };
@ -496,7 +572,7 @@ const toolbarActions = computed(() => [
<template> <template>
<Page auto-content-height> <Page auto-content-height>
<Loading :loading="pageLoading" tip="缓存刷新中..." /> <Loading :loading="pageLoading" :tip="loadingTip" />
<Grid> <Grid>
<template #toolbar-actions> <template #toolbar-actions>
<TableAction :actions="toolbarActions" /> <TableAction :actions="toolbarActions" />
@ -561,15 +637,19 @@ const toolbarActions = computed(() => [
<template #content> <template #content>
<div style="display: flex; flex-direction: column; gap: 4px"> <div style="display: flex; flex-direction: column; gap: 4px">
<Button type="text" size="small" @click="toDeviceLog.bind(null, row)()" <Button type="text" size="small" @click="toDeviceLog.bind(null, row)()"
style=" padding: 4px 8px;text-align: left"> style="padding: 4px 8px; text-align: left">
{{ $t('abp.IoTDBBase.PlatformLog') }} {{ $t('abp.IoTDBBase.PlatformLog') }}
</Button> </Button>
<Button type="text" size="small" @click="toTelemetryLog.bind(null, row)()" <Button type="text" size="small" @click="toTelemetryLog.bind(null, row)()"
style=" padding: 4px 8px;text-align: left"> style="padding: 4px 8px; text-align: left">
{{ $t('abp.IoTDBBase.TelemetryLog') }} {{ $t('abp.IoTDBBase.TelemetryLog') }}
</Button> </Button>
<Button type="text" size="small" @click="repushDeviceInfo.bind(null, row)()"
style="padding: 4px 8px; text-align: left">
重推设备信息
</Button>
<Button type="text" size="small" @click="onDel.bind(null, row)()" <Button type="text" size="small" @click="onDel.bind(null, row)()"
style=" padding: 4px 8px; color: #ff4d4f;text-align: left"> style="padding: 4px 8px; color: #ff4d4f; text-align: left">
{{ $t('common.delete') }} {{ $t('common.delete') }}
</Button> </Button>
</div> </div>
@ -591,6 +671,23 @@ const toolbarActions = computed(() => [
</CommandModal> </CommandModal>
<BatchAddModal title="批量添加设备" class="w-[800px]"> <BatchAddModal title="批量添加设备" class="w-[800px]">
<BatchAddForm /> <BatchAddForm />
<template #footer>
<div class="flex w-full items-center justify-between">
<div class="text-sm text-gray-500">
<span v-if="addressLines > 0">
{{ addressLines }} 行设备地址
</span>
</div>
<div class="flex gap-2">
<Button @click="batchAddModalApi.close()">
{{ $t('common.cancel') }}
</Button>
<Button type="primary" :loading="batchAddModalState?.confirmLoading" @click="submitBatchAdd">
{{ $t('common.confirm') }}
</Button>
</div>
</div>
</template>
</BatchAddModal> </BatchAddModal>
</Page> </Page>
</template> </template>

View File

@ -89,6 +89,14 @@ export const tableSchema: any = computed((): VxeGridProps['columns'] => [
]); ]);
export const addDeviceFormSchema: any = computed(() => [ export const addDeviceFormSchema: any = computed(() => [
{
component: 'Input',
fieldName: 'deviceAddress',
label: $t('abp.deviceInfos.deviceAddress'),
rules: z.string().min(1, {
message: `${$t('common.pleaseInput')}${$t('abp.deviceInfos.deviceAddress')}`,
}),
},
{ {
component: 'ApiSelect', component: 'ApiSelect',
fieldName: 'ioTPlatform', fieldName: 'ioTPlatform',
@ -361,14 +369,6 @@ export const addDeviceFormSchema: any = computed(() => [
}, },
rules: z.string().optional(), rules: z.string().optional(),
}, },
{
component: 'Input',
fieldName: 'deviceAddress',
label: $t('abp.deviceInfos.deviceAddress'),
rules: z.string().min(1, {
message: `${$t('common.pleaseInput')}${$t('abp.deviceInfos.deviceAddress')}`,
}),
},
]); ]);
export const editDeviceFormSchemaEdit: any = computed(() => [ export const editDeviceFormSchemaEdit: any = computed(() => [
@ -667,6 +667,25 @@ export const commandFormSchema: any = computed(() => [
]); ]);
export const batchAddDeviceFormSchema: any = computed(() => [ export const batchAddDeviceFormSchema: any = computed(() => [
{
component: 'Textarea',
fieldName: 'addressList',
label: $t('abp.deviceInfos.deviceAddress'),
componentProps: {
rows: 4,
placeholder: $t('common.pleaseInput') + $t('abp.deviceInfos.deviceAddress') + ',每行一个设备地址',
showCount: true,
maxLength: 2000,
style: {
resize: 'vertical',
minHeight: '32px',
maxHeight: '200px',
},
},
rules: z.string().min(1, {
message: `${$t('common.pleaseInput')}${$t('abp.deviceInfos.deviceAddress')}`,
}),
},
{ {
component: 'ApiSelect', component: 'ApiSelect',
fieldName: 'ioTPlatform', fieldName: 'ioTPlatform',
@ -939,18 +958,4 @@ export const batchAddDeviceFormSchema: any = computed(() => [
}, },
rules: z.string().optional(), rules: z.string().optional(),
}, },
{
component: 'Textarea',
fieldName: 'addressList',
label: $t('abp.deviceInfos.deviceAddress'),
componentProps: {
rows: 8,
placeholder: $t('common.pleaseInput') + $t('abp.deviceInfos.deviceAddress') + ',每行一个设备地址',
showCount: true,
maxLength: 2000,
},
rules: z.string().min(1, {
message: `${$t('common.pleaseInput')}${$t('abp.deviceInfos.deviceAddress')}`,
}),
},
]); ]);

View File

@ -8,8 +8,7 @@ import { useRoute } from 'vue-router';
import { Page } from '@vben/common-ui'; import { Page } from '@vben/common-ui';
import { useVbenVxeGrid } from '#/adapter/vxe-table'; import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { postDeviceInfoPage } from '#/api-client'; import { postDeviceInfoPage, postTableModelCtWingLogInfo } from '#/api-client';
import { postTableModelCtWingLogInfo } from '#/api-client';
import DeviceSelect from '../deviceData/DeviceSelect.vue'; import DeviceSelect from '../deviceData/DeviceSelect.vue';
import { querySchema, tableSchema } from './schema'; import { querySchema, tableSchema } from './schema';
@ -53,11 +52,17 @@ const fetchDeviceOptions = async () => {
// //
const getDeviceInfoByAddress = (deviceAddress: string) => { const getDeviceInfoByAddress = (deviceAddress: string) => {
if (!deviceAddress || !deviceOptions.value || deviceOptions.value.length === 0) { if (
!deviceAddress ||
!deviceOptions.value ||
deviceOptions.value.length === 0
) {
return null; return null;
} }
const device = deviceOptions.value.find((device) => device.deviceAddress === deviceAddress); const device = deviceOptions.value.find(
(device) => device.deviceAddress === deviceAddress,
);
return device; return device;
}; };
@ -189,7 +194,9 @@ const gridOptions: VxeGridProps<any> = {
ajax: { ajax: {
query: async ({ page }, formValues) => { query: async ({ page }, formValues) => {
// API // API
const currentFormValues = gridApi?.formApi ? await gridApi.formApi.getValues() : {}; const currentFormValues = gridApi?.formApi
? await gridApi.formApi.getValues()
: {};
// DeviceAddress使 // DeviceAddress使
if (!currentFormValues.DeviceAddress && DeviceAddress) { if (!currentFormValues.DeviceAddress && DeviceAddress) {