383 lines
11 KiB
Vue
383 lines
11 KiB
Vue
<script setup lang="ts">
|
||
import type { VbenFormProps } from '#/adapter/form';
|
||
import type { VxeGridProps } from '#/adapter/vxe-table';
|
||
|
||
import { computed, h, ref } from 'vue';
|
||
import { useRouter } from 'vue-router';
|
||
|
||
import { Page, useVbenModal } from '@vben/common-ui';
|
||
|
||
import { message as Message, Modal, Tag } from 'ant-design-vue';
|
||
import { Loading } from '#/components/Loading';
|
||
|
||
import { useVbenForm } from '#/adapter/form';
|
||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||
import {
|
||
postAggregationDeviceCreateAsync,
|
||
postAggregationDeviceDeleteAsync,
|
||
postDeviceInfoCacheDeviceDataToRedis,
|
||
postDeviceInfoPage,
|
||
} from '#/api-client';
|
||
import { TableAction } from '#/components/table-action';
|
||
import { $t } from '#/locales';
|
||
|
||
import {
|
||
addDeviceFormSchema,
|
||
editDeviceFormSchemaEdit,
|
||
querySchema,
|
||
tableSchema,
|
||
} from './schema';
|
||
|
||
defineOptions({
|
||
name: 'DeviceInfo',
|
||
});
|
||
|
||
const router = useRouter();
|
||
const formOptions: VbenFormProps = {
|
||
schema: querySchema.value,
|
||
};
|
||
const gridOptions: VxeGridProps<any> = {
|
||
checkboxConfig: {
|
||
highlight: true,
|
||
labelField: 'name',
|
||
},
|
||
columns: tableSchema.value,
|
||
height: 'auto',
|
||
keepSource: true,
|
||
pagerConfig: {},
|
||
toolbarConfig: {
|
||
custom: true,
|
||
},
|
||
customConfig: {
|
||
storage: true,
|
||
},
|
||
proxyConfig: {
|
||
ajax: {
|
||
query: async ({ page }, formValues) => {
|
||
const { data } = await postDeviceInfoPage({
|
||
body: {
|
||
pageIndex: page.currentPage,
|
||
pageSize: page.pageSize,
|
||
...formValues,
|
||
},
|
||
});
|
||
return data;
|
||
},
|
||
},
|
||
},
|
||
};
|
||
|
||
const [Grid, gridApi] = useVbenVxeGrid({ formOptions, gridOptions });
|
||
|
||
const editRow: Record<string, any> = ref({});
|
||
const cacheRefreshLoading = ref(false);
|
||
const pageLoading = ref(false);
|
||
const [UserModal, userModalApi] = useVbenModal({
|
||
draggable: true,
|
||
onConfirm: submit,
|
||
onBeforeClose: () => {
|
||
editRow.value = {};
|
||
return true;
|
||
},
|
||
});
|
||
|
||
const [AddForm, addFormApi] = useVbenForm({
|
||
// 默认展开
|
||
collapsed: false,
|
||
// 所有表单项共用,可单独在表单内覆盖
|
||
commonConfig: {
|
||
labelWidth: 110,
|
||
componentProps: {
|
||
class: 'w-4/5',
|
||
},
|
||
},
|
||
layout: 'horizontal',
|
||
schema: addDeviceFormSchema.value,
|
||
showCollapseButton: false,
|
||
showDefaultActions: false,
|
||
wrapperClass: 'grid-cols-2',
|
||
});
|
||
|
||
const [EditForm, editFormApi] = useVbenForm({
|
||
// 默认展开
|
||
collapsed: false,
|
||
// 所有表单项共用,可单独在表单内覆盖
|
||
commonConfig: {
|
||
labelWidth: 110,
|
||
componentProps: {
|
||
class: 'w-4/5',
|
||
},
|
||
},
|
||
// 提交函数
|
||
layout: 'horizontal',
|
||
schema: editDeviceFormSchemaEdit.value,
|
||
showCollapseButton: false,
|
||
showDefaultActions: false,
|
||
wrapperClass: 'grid-cols-2',
|
||
});
|
||
|
||
// 新增和编辑提交的逻辑
|
||
async function submit() {
|
||
const isEdit = !!editRow.value.id;
|
||
const formApi = isEdit ? editFormApi : addFormApi;
|
||
const api = postAggregationDeviceCreateAsync; // 目前只有创建接口,编辑也使用创建接口
|
||
const { valid } = await formApi.validate();
|
||
if (!valid) return;
|
||
|
||
const formValues = await formApi.getValues();
|
||
|
||
// 根据平台类型处理数据
|
||
const processedFormValues = { ...formValues };
|
||
|
||
if (formValues.ioTPlatform === 2 || formValues.ioTPlatform === '2') {
|
||
// OneNET平台
|
||
processedFormValues.ioTPlatformAccountId = formValues.oneNETAccountId;
|
||
processedFormValues.ioTPlatformProductId = formValues.oneNETProductId;
|
||
// 清理不需要的字段
|
||
delete processedFormValues.oneNETAccountId;
|
||
delete processedFormValues.oneNETProductId;
|
||
delete processedFormValues.ctWingAccountId;
|
||
delete processedFormValues.ctWingProductId;
|
||
} else if (formValues.ioTPlatform === 1 || formValues.ioTPlatform === '1') {
|
||
// CTWing平台
|
||
processedFormValues.ioTPlatformAccountId = formValues.ctWingAccountId;
|
||
processedFormValues.ioTPlatformProductId = formValues.ctWingProductId;
|
||
// 清理不需要的字段
|
||
delete processedFormValues.ctWingAccountId;
|
||
delete processedFormValues.ctWingProductId;
|
||
delete processedFormValues.oneNETAccountId;
|
||
delete processedFormValues.oneNETProductId;
|
||
}
|
||
|
||
const fetchParams: any = isEdit
|
||
? {
|
||
id: editRow.value.id,
|
||
...processedFormValues,
|
||
}
|
||
: {
|
||
...processedFormValues,
|
||
};
|
||
|
||
try {
|
||
userModalApi.setState({ loading: true, confirmLoading: true });
|
||
const resp = await api({ body: fetchParams });
|
||
if (resp.data) {
|
||
Message.success(
|
||
editRow.value.id ? $t('common.editSuccess') : $t('common.addSuccess'),
|
||
);
|
||
userModalApi.close();
|
||
editRow.value = {};
|
||
gridApi.reload();
|
||
} else {
|
||
Message.error(
|
||
editRow.value.id ? $t('common.editFail') : $t('common.addFail'),
|
||
);
|
||
}
|
||
} catch (error) {
|
||
console.error('设备操作失败:', error);
|
||
Message.error(
|
||
editRow.value.id ? $t('common.editFail') : $t('common.addFail'),
|
||
);
|
||
} finally {
|
||
userModalApi.setState({ loading: false, confirmLoading: false });
|
||
}
|
||
}
|
||
|
||
async function onEdit(record: any) {
|
||
editRow.value = record;
|
||
userModalApi.open();
|
||
|
||
// 根据平台类型设置表单值
|
||
const formValues = { ...record };
|
||
|
||
// 确保ioTPlatform是字符串格式,因为ApiSelect组件的valueField是'key'
|
||
if (formValues.ioTPlatform !== undefined && formValues.ioTPlatform !== null) {
|
||
formValues.ioTPlatform = String(formValues.ioTPlatform);
|
||
}
|
||
|
||
if (record.ioTPlatform === 2 || record.ioTPlatform === '2') {
|
||
// OneNET平台
|
||
formValues.oneNETAccountId = record.ioTPlatformAccountId;
|
||
formValues.oneNETProductId = record.ioTPlatformProductId;
|
||
} else if (record.ioTPlatform === 1 || record.ioTPlatform === '1') {
|
||
// CTWing平台
|
||
formValues.ctWingAccountId = record.ioTPlatformAccountId;
|
||
formValues.ctWingProductId = record.ioTPlatformProductId;
|
||
}
|
||
|
||
editFormApi.setValues(formValues);
|
||
}
|
||
|
||
function onDel(row: any) {
|
||
Modal.confirm({
|
||
title: `${$t('common.confirmDelete')}${row.deviceName || row.deviceAddress} ?`,
|
||
onOk: async () => {
|
||
try {
|
||
const result = await postAggregationDeviceDeleteAsync({
|
||
body: { id: row.id },
|
||
});
|
||
if (result.data) {
|
||
gridApi.reload();
|
||
Message.success($t('common.deleteSuccess'));
|
||
} else {
|
||
Message.error($t('common.deleteFail'));
|
||
}
|
||
} catch (error) {
|
||
console.error('删除设备失败:', error);
|
||
Message.error($t('common.deleteFail'));
|
||
}
|
||
},
|
||
});
|
||
}
|
||
const toStatusData = (row: Record<string, any>) => {
|
||
// 或者使用编程式导航
|
||
router.push({
|
||
path: '/iotdb/deviceData',
|
||
query: {
|
||
DeviceType: row.ioTPlatform,
|
||
DeviceId: row.deviceAddress,
|
||
FocusAddress: row.ioTPlatformDeviceOpenInfo,
|
||
DataBaseName: row.deviceName,
|
||
},
|
||
});
|
||
};
|
||
const openAddModal = async () => {
|
||
editRow.value = {};
|
||
userModalApi.open();
|
||
};
|
||
|
||
// 缓存刷新按钮处理函数
|
||
const handleCacheRefresh = async () => {
|
||
if (cacheRefreshLoading.value) return; // 防止重复点击
|
||
|
||
cacheRefreshLoading.value = true;
|
||
pageLoading.value = true;
|
||
try {
|
||
await postDeviceInfoCacheDeviceDataToRedis({
|
||
body: {},
|
||
});
|
||
Message.success($t('common.operationSuccess'));
|
||
} catch (error) {
|
||
console.error('缓存刷新失败:', error);
|
||
Message.error($t('common.operationFailed'));
|
||
} finally {
|
||
cacheRefreshLoading.value = false;
|
||
pageLoading.value = false;
|
||
}
|
||
};
|
||
|
||
// 工具栏按钮配置
|
||
const toolbarActions = computed(() => [
|
||
{
|
||
label: $t('common.add'),
|
||
type: 'primary',
|
||
icon: 'ant-design:plus-outlined',
|
||
onClick: openAddModal.bind(null),
|
||
auth: ['AbpIdentity.Users.Create'],
|
||
},
|
||
{
|
||
label: cacheRefreshLoading.value
|
||
? $t('common.loading')
|
||
: $t('abp.IoTDBBase.CacheRefresh'),
|
||
type: 'primary',
|
||
icon: cacheRefreshLoading.value
|
||
? 'ant-design:loading-outlined'
|
||
: 'ant-design:reload-outlined',
|
||
onClick: handleCacheRefresh,
|
||
disabled: cacheRefreshLoading.value,
|
||
style: {
|
||
backgroundColor: '#52c41a',
|
||
borderColor: '#52c41a',
|
||
},
|
||
},
|
||
]);
|
||
</script>
|
||
|
||
<template>
|
||
<Page auto-content-height>
|
||
<Loading :loading="pageLoading" tip="缓存刷新中..." />
|
||
<Grid>
|
||
<template #toolbar-actions>
|
||
<TableAction :actions="toolbarActions" />
|
||
</template>
|
||
|
||
<template #isArchiveStatus="{ row }">
|
||
{{
|
||
row.archiveStatus ? $t('common.Issued') : $t('common.Undistributed')
|
||
}}
|
||
</template>
|
||
<template #isTripState="{ row }">
|
||
{{ row.tripState ? $t('common.SwitchOff') : $t('common.Closing') }}
|
||
</template>
|
||
<template #isHaveValve="{ row }">
|
||
<component :is="h(Tag, { color: row.haveValve ? 'green' : 'red' }, () =>
|
||
row.haveValve ? $t('common.yes') : $t('common.no'),
|
||
)
|
||
" />
|
||
</template>
|
||
<template #isSelfDevelop="{ row }">
|
||
<component :is="h(Tag, { color: row.selfDevelop ? 'green' : 'red' }, () =>
|
||
row.selfDevelop ? $t('common.yes') : $t('common.no'),
|
||
)
|
||
" />
|
||
</template>
|
||
<template #isDynamicPassword="{ row }">
|
||
<component :is="h(Tag, { color: row.dynamicPassword ? 'green' : 'red' }, () =>
|
||
row.dynamicPassword ? $t('common.yes') : $t('common.no'),
|
||
)
|
||
" />
|
||
</template>
|
||
<template #isEnable="{ row }">
|
||
<component :is="h(Tag, { color: row.enabled ? 'green' : 'red' }, () =>
|
||
row.enabled ? $t('common.yes') : $t('common.no'),
|
||
)
|
||
" />
|
||
</template>
|
||
<template #ioTPlatformName="{ row }">
|
||
<span :style="{
|
||
color:
|
||
row.ioTPlatform === 2 || row.ioTPlatform === '2'
|
||
? '#0B34BE'
|
||
: '#048CD1',
|
||
fontWeight: 'bold',
|
||
}">
|
||
{{ row.ioTPlatformName }}
|
||
</span>
|
||
</template>
|
||
|
||
<template #action="{ row }">
|
||
<TableAction :actions="[
|
||
{
|
||
label: $t('common.edit'),
|
||
type: 'link',
|
||
size: 'small',
|
||
auth: ['AbpIdentity.Users.Update'],
|
||
onClick: onEdit.bind(null, row),
|
||
},
|
||
{
|
||
label: $t('abp.deviceInfos.viewData'),
|
||
type: 'link',
|
||
size: 'small',
|
||
auth: ['AbpIdentity.Users.Update'],
|
||
onClick: toStatusData.bind(null, row),
|
||
},
|
||
]" :drop-down-actions="[
|
||
{
|
||
label: $t('common.delete'),
|
||
icon: 'ant-design:delete-outlined',
|
||
type: 'primary',
|
||
auth: ['AbpIdentity.Users.Delete'],
|
||
popConfirm: {
|
||
title: $t('common.askConfirmDelete'),
|
||
confirm: onDel.bind(null, row),
|
||
},
|
||
},
|
||
]" />
|
||
</template>
|
||
</Grid>
|
||
<UserModal :title="editRow.id ? $t('common.edit') : $t('common.add')" class="w-[800px]">
|
||
<component :is="editRow.id ? EditForm : AddForm" />
|
||
</UserModal>
|
||
</Page>
|
||
</template>
|