812 lines
23 KiB
Vue
812 lines
23 KiB
Vue
<script setup lang="ts">
|
||
import type { VbenFormProps } from '#/adapter/form';
|
||
import type { VxeGridProps } from '#/adapter/vxe-table';
|
||
|
||
import { computed, h, ref, watch } from 'vue';
|
||
import { useRouter } from 'vue-router';
|
||
|
||
import { Page, useVbenModal } from '@vben/common-ui';
|
||
|
||
import {
|
||
Button,
|
||
message as Message,
|
||
Modal,
|
||
Popover,
|
||
Tag,
|
||
} from 'ant-design-vue';
|
||
|
||
import { useVbenForm } from '#/adapter/form';
|
||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||
import {
|
||
postAggregationDeviceBatchCreateAsync,
|
||
postAggregationDeviceCreateAsync,
|
||
postAggregationDeviceDeleteAsync,
|
||
postAggregationDeviceDeviceCommandForApiAsync,
|
||
postAggregationDeviceRepushDeviceInfoToIoTplatform,
|
||
postDeviceInfoCacheDeviceDataToRedis,
|
||
postDeviceInfoPage,
|
||
} from '#/api-client';
|
||
import { Icon } from '#/components/icon';
|
||
import { Loading } from '#/components/Loading';
|
||
import { TableAction } from '#/components/table-action';
|
||
import { $t } from '#/locales';
|
||
|
||
import {
|
||
addDeviceFormSchema,
|
||
batchAddDeviceFormSchema,
|
||
commandFormSchema,
|
||
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 loadingTip = ref('缓存刷新中...');
|
||
const commandRow: Record<string, any> = ref({});
|
||
const [UserModal, userModalApi] = useVbenModal({
|
||
draggable: true,
|
||
onConfirm: submit,
|
||
onBeforeClose: () => {
|
||
editRow.value = {};
|
||
return true;
|
||
},
|
||
});
|
||
|
||
const [CommandModal, commandModalApi] = useVbenModal({
|
||
draggable: true,
|
||
onConfirm: submitCommand,
|
||
onBeforeClose: () => {
|
||
commandRow.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',
|
||
});
|
||
|
||
const [CommandForm, commandFormApi] = useVbenForm({
|
||
// 默认展开
|
||
collapsed: false,
|
||
// 所有表单项共用,可单独在表单内覆盖
|
||
commonConfig: {
|
||
labelWidth: 110,
|
||
componentProps: {
|
||
class: 'w-full',
|
||
},
|
||
},
|
||
layout: 'horizontal',
|
||
schema: commandFormSchema.value,
|
||
showCollapseButton: false,
|
||
showDefaultActions: false,
|
||
});
|
||
|
||
const [BatchAddForm, batchAddFormApi] = useVbenForm({
|
||
// 默认展开
|
||
collapsed: false,
|
||
// 所有表单项共用,可单独在表单内覆盖
|
||
commonConfig: {
|
||
labelWidth: 110,
|
||
componentProps: {
|
||
class: 'w-4/5',
|
||
},
|
||
},
|
||
layout: 'horizontal',
|
||
schema: batchAddDeviceFormSchema.value,
|
||
showCollapseButton: false,
|
||
showDefaultActions: false,
|
||
wrapperClass: 'grid-cols-2',
|
||
// 添加响应式监听
|
||
autoSubmitOnEnter: false,
|
||
});
|
||
|
||
const [BatchAddModal, batchAddModalApi] = useVbenModal({
|
||
draggable: true,
|
||
onConfirm: submitBatchAdd,
|
||
onBeforeClose: () => {
|
||
batchAddFormApi.resetForm();
|
||
stopLineCheck();
|
||
return true;
|
||
},
|
||
onOpenChange: (isOpen) => {
|
||
if (isOpen) {
|
||
// 模态框打开时启动行数检查
|
||
setTimeout(() => {
|
||
startLineCheck();
|
||
}, 100);
|
||
} else {
|
||
// 模态框关闭时停止行数检查
|
||
stopLineCheck();
|
||
}
|
||
},
|
||
});
|
||
|
||
// 获取批量添加模态框的状态
|
||
const batchAddModalState = batchAddModalApi.useStore();
|
||
|
||
// 新增和编辑提交的逻辑
|
||
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 toDeviceInfoData = (row: Record<string, any>) => {
|
||
// 或者使用编程式导航
|
||
router.push({
|
||
path: '/iotdbdatamanagement/deviceData',
|
||
query: {
|
||
DeviceAddress: row.deviceAddress,
|
||
IoTDataType: 'Data',
|
||
},
|
||
});
|
||
};
|
||
|
||
const toDeviceLog = (row: Record<string, any>) => {
|
||
// 根据平台类型跳转到对应的日志页面
|
||
if (row.ioTPlatform === 1 || row.ioTPlatform === '1') {
|
||
// CTWing平台
|
||
router.push({
|
||
path: '/iotdbdatamanagement/ctwingLog',
|
||
query: {
|
||
DeviceAddress: row.deviceAddress,
|
||
},
|
||
});
|
||
} else if (row.ioTPlatform === 2 || row.ioTPlatform === '2') {
|
||
// OneNET平台
|
||
router.push({
|
||
path: '/iotdbdatamanagement/onenetLog',
|
||
query: {
|
||
DeviceAddress: row.deviceAddress,
|
||
},
|
||
});
|
||
}
|
||
};
|
||
|
||
const toTelemetryLog = (row: Record<string, any>) => {
|
||
// 跳转到遥测日志页面
|
||
router.push({
|
||
path: '/iotdbdatamanagement/telemetryLog',
|
||
query: {
|
||
DeviceAddress: row.deviceAddress,
|
||
},
|
||
});
|
||
};
|
||
|
||
// 重推设备信息到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 {
|
||
Message.error('重推设备信息失败');
|
||
} finally {
|
||
pageLoading.value = false;
|
||
loadingTip.value = '缓存刷新中...';
|
||
}
|
||
};
|
||
const openAddModal = async () => {
|
||
editRow.value = {};
|
||
userModalApi.open();
|
||
};
|
||
|
||
const openCommandModal = (row: Record<string, any>) => {
|
||
commandRow.value = row;
|
||
commandModalApi.open();
|
||
};
|
||
|
||
// 指令提交逻辑
|
||
async function submitCommand() {
|
||
const { valid } = await commandFormApi.validate();
|
||
if (!valid) return;
|
||
|
||
const formValues = await commandFormApi.getValues();
|
||
|
||
try {
|
||
commandModalApi.setState({ loading: true, confirmLoading: true });
|
||
|
||
// 调用指令接口
|
||
const result = await postAggregationDeviceDeviceCommandForApiAsync({
|
||
body: {
|
||
Id: commandRow.value.id,
|
||
CommandContent: formValues.CommandContent,
|
||
},
|
||
});
|
||
|
||
if (result.data) {
|
||
Message.success('指令下发成功');
|
||
commandModalApi.close();
|
||
commandRow.value = {};
|
||
} else {
|
||
Message.error('指令下发失败');
|
||
}
|
||
} catch (error) {
|
||
console.error('指令发送失败:', error);
|
||
Message.error('指令下发失败');
|
||
} finally {
|
||
commandModalApi.setState({ loading: false, confirmLoading: false });
|
||
}
|
||
}
|
||
|
||
// 批量添加设备提交逻辑
|
||
async function submitBatchAdd() {
|
||
const { valid } = await batchAddFormApi.validate();
|
||
if (!valid) return;
|
||
|
||
const formValues = await batchAddFormApi.getValues();
|
||
|
||
// 处理设备地址列表
|
||
const addressList = formValues.addressList
|
||
.split('\n')
|
||
.map((address: string) => address.trim())
|
||
.filter((address: string) => address.length > 0);
|
||
|
||
if (addressList.length === 0) {
|
||
Message.error('请输入至少一个设备地址');
|
||
return;
|
||
}
|
||
|
||
// 验证行数限制
|
||
if (addressList.length > 100) {
|
||
Message.error('设备地址不能超过100行');
|
||
return;
|
||
}
|
||
|
||
// 验证设备地址格式(简单验证)
|
||
const invalidAddresses = addressList.filter(
|
||
(address: string) => !address || address.length < 3,
|
||
);
|
||
if (invalidAddresses.length > 0) {
|
||
Message.error(`以下设备地址格式不正确: ${invalidAddresses.join(', ')}`);
|
||
return;
|
||
}
|
||
|
||
// 根据平台类型处理数据
|
||
let ioTPlatformProductId = '';
|
||
if (formValues.ioTPlatform === 2 || formValues.ioTPlatform === '2') {
|
||
// OneNET平台
|
||
ioTPlatformProductId = formValues.oneNETProductId;
|
||
} else if (formValues.ioTPlatform === 1 || formValues.ioTPlatform === '1') {
|
||
// CTWing平台
|
||
ioTPlatformProductId = formValues.ctWingProductId;
|
||
}
|
||
|
||
if (!ioTPlatformProductId) {
|
||
Message.error('请选择产品');
|
||
return;
|
||
}
|
||
|
||
const batchCreateParams = {
|
||
addressList,
|
||
ioTPlatform: formValues.ioTPlatform,
|
||
ioTPlatformProductId,
|
||
};
|
||
|
||
try {
|
||
batchAddModalApi.setState({ loading: true, confirmLoading: true });
|
||
const resp = await postAggregationDeviceBatchCreateAsync({
|
||
body: batchCreateParams,
|
||
});
|
||
if (resp.data) {
|
||
Message.success(`批量添加设备成功,共添加 ${addressList.length} 个设备`);
|
||
batchAddModalApi.close();
|
||
batchAddFormApi.resetForm();
|
||
gridApi.reload();
|
||
} else {
|
||
Message.error('批量添加设备失败');
|
||
}
|
||
} catch (error) {
|
||
console.error('批量添加设备失败:', error);
|
||
Message.error('批量添加设备失败');
|
||
} finally {
|
||
batchAddModalApi.setState({ loading: false, confirmLoading: false });
|
||
}
|
||
}
|
||
|
||
// 打开批量添加模态框
|
||
const openBatchAddModal = () => {
|
||
console.log('打开批量添加模态框');
|
||
batchAddFormApi.resetForm();
|
||
addressLines.value = 0; // 重置行数
|
||
batchAddModalApi.open();
|
||
};
|
||
|
||
// 批量添加地址行数
|
||
const addressLines = ref(0);
|
||
|
||
// 检查行数是否超过限制
|
||
const isOverLineLimit = computed(() => {
|
||
return addressLines.value > 100;
|
||
});
|
||
|
||
// 监听表单值变化,实时更新行数
|
||
watch(
|
||
() => batchAddFormApi.getValues()?.addressList,
|
||
(newValue) => {
|
||
try {
|
||
console.log('监听地址列表变化:', newValue);
|
||
if (!newValue || typeof newValue !== 'string') {
|
||
addressLines.value = 0;
|
||
return;
|
||
}
|
||
const lines = newValue.split('\n').filter((line: string) => line.trim());
|
||
addressLines.value = lines.length;
|
||
console.log('更新行数:', addressLines.value);
|
||
} catch {
|
||
addressLines.value = 0;
|
||
}
|
||
},
|
||
{ immediate: true },
|
||
);
|
||
|
||
// 监听表单值变化,实时更新行数(备用方案)
|
||
watch(
|
||
() => batchAddFormApi.getValues(),
|
||
(formValues) => {
|
||
try {
|
||
const addressList = formValues?.addressList;
|
||
console.log('监听表单值变化:', addressList);
|
||
if (!addressList || typeof addressList !== 'string') {
|
||
addressLines.value = 0;
|
||
return;
|
||
}
|
||
const lines = addressList
|
||
.split('\n')
|
||
.filter((line: string) => line.trim());
|
||
addressLines.value = lines.length;
|
||
console.log('备用方案更新行数:', addressLines.value);
|
||
} catch {
|
||
addressLines.value = 0;
|
||
}
|
||
},
|
||
{ deep: true, immediate: true },
|
||
);
|
||
|
||
// 使用定时器定期检查行数(第三种方案)
|
||
let lineCheckInterval: NodeJS.Timeout | null = null;
|
||
|
||
// 在模态框打开时启动定时器
|
||
const startLineCheck = () => {
|
||
if (lineCheckInterval) {
|
||
clearInterval(lineCheckInterval);
|
||
}
|
||
lineCheckInterval = setInterval(() => {
|
||
try {
|
||
// 尝试多种方式获取表单值
|
||
let addressList = '';
|
||
|
||
// 方式1:直接获取
|
||
const formValues = batchAddFormApi.getValues();
|
||
console.log('表单值:', formValues);
|
||
addressList = formValues?.addressList || '';
|
||
|
||
// 方式2:如果方式1失败,尝试其他方法
|
||
if (!addressList) {
|
||
try {
|
||
const rawValues = batchAddFormApi.getValues();
|
||
console.log('原始表单值:', rawValues);
|
||
addressList = rawValues?.addressList || '';
|
||
} catch (error) {
|
||
console.log('方式2失败:', error);
|
||
}
|
||
}
|
||
|
||
// 方式3:直接从DOM获取
|
||
if (!addressList) {
|
||
const textarea = document.querySelector(
|
||
'textarea[name="addressList"]',
|
||
) as HTMLTextAreaElement;
|
||
if (textarea) {
|
||
addressList = textarea.value;
|
||
console.log('从DOM获取的地址列表:', addressList);
|
||
}
|
||
}
|
||
|
||
console.log('获取到的地址列表:', addressList);
|
||
|
||
if (addressList && typeof addressList === 'string') {
|
||
const lines = addressList
|
||
.split('\n')
|
||
.filter((line: string) => line.trim());
|
||
const newLineCount = lines.length;
|
||
console.log(
|
||
'计算出的行数:',
|
||
newLineCount,
|
||
'当前行数:',
|
||
addressLines.value,
|
||
);
|
||
if (newLineCount !== addressLines.value) {
|
||
console.log('定时器更新行数:', newLineCount);
|
||
addressLines.value = newLineCount;
|
||
}
|
||
} else {
|
||
console.log('地址列表为空或不是字符串');
|
||
}
|
||
} catch (error) {
|
||
console.error('定时器检查行数失败:', error);
|
||
}
|
||
}, 300);
|
||
};
|
||
|
||
// 在模态框关闭时清除定时器
|
||
const stopLineCheck = () => {
|
||
if (lineCheckInterval) {
|
||
clearInterval(lineCheckInterval);
|
||
lineCheckInterval = null;
|
||
}
|
||
};
|
||
|
||
// 缓存刷新按钮处理函数
|
||
const handleCacheRefresh = async () => {
|
||
try {
|
||
cacheRefreshLoading.value = true;
|
||
pageLoading.value = true;
|
||
loadingTip.value = '缓存刷新中...';
|
||
const result = await postDeviceInfoCacheDeviceDataToRedis();
|
||
if (result.data) {
|
||
Message.success('缓存刷新成功');
|
||
gridApi.reload();
|
||
} else {
|
||
Message.error('缓存刷新失败');
|
||
}
|
||
} catch (error) {
|
||
console.error('缓存刷新失败:', error);
|
||
Message.error('缓存刷新失败');
|
||
} finally {
|
||
cacheRefreshLoading.value = false;
|
||
pageLoading.value = false;
|
||
loadingTip.value = '缓存刷新中...';
|
||
}
|
||
};
|
||
|
||
// 工具栏按钮配置
|
||
const toolbarActions = computed(() => [
|
||
{
|
||
label: $t('common.add'),
|
||
type: 'primary',
|
||
icon: 'ant-design:plus-outlined',
|
||
onClick: openAddModal.bind(null),
|
||
auth: ['AbpIdentity.Users.Create'],
|
||
},
|
||
{
|
||
label: '批量添加',
|
||
type: 'primary',
|
||
icon: 'ant-design:plus-outlined',
|
||
onClick: openBatchAddModal.bind(null),
|
||
auth: ['AbpIdentity.Users.Create'],
|
||
},
|
||
{
|
||
label: cacheRefreshLoading.value
|
||
? $t('common.loading')
|
||
: $t('abp.IoTDBBase.CacheRefresh'),
|
||
type: 'default',
|
||
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="loadingTip" />
|
||
<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 }">
|
||
<div style="display: flex; gap: 8px; align-items: center">
|
||
<!-- 编辑按钮已注释,因为后端没有更新接口 -->
|
||
<!-- <Button size="small" type="link" @click="onEdit.bind(null, row)()">
|
||
{{ $t('common.edit') }}
|
||
</Button> -->
|
||
<Button size="small" type="link" @click="toDeviceInfoData.bind(null, row)()">
|
||
{{ $t('abp.deviceInfos.viewData') }}
|
||
</Button>
|
||
<Button size="small" type="link" @click="openCommandModal.bind(null, row)()">
|
||
{{ $t('abp.IoTDBBase.Command') }}
|
||
</Button>
|
||
<Popover trigger="hover" placement="bottomRight" :overlay-style="{ minWidth: '120px' }">
|
||
<template #content>
|
||
<div style="display: flex; flex-direction: column; gap: 4px">
|
||
<Button type="text" size="small" @click="toDeviceLog.bind(null, row)()"
|
||
style="padding: 4px 8px; text-align: left">
|
||
{{ $t('abp.IoTDBBase.PlatformLog') }}
|
||
</Button>
|
||
<Button type="text" size="small" @click="toTelemetryLog.bind(null, row)()"
|
||
style="padding: 4px 8px; text-align: left">
|
||
{{ $t('abp.IoTDBBase.TelemetryLog') }}
|
||
</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)()"
|
||
style="padding: 4px 8px; color: #ff4d4f; text-align: left">
|
||
{{ $t('common.delete') }}
|
||
</Button>
|
||
</div>
|
||
</template>
|
||
<Button size="small" type="link">
|
||
<template #icon>
|
||
<Icon icon="ant-design:more-outlined" />
|
||
</template>
|
||
</Button>
|
||
</Popover>
|
||
</div>
|
||
</template>
|
||
</Grid>
|
||
<UserModal :title="editRow.id ? $t('common.edit') : $t('common.add')" class="w-[800px]">
|
||
<component :is="editRow.id ? EditForm : AddForm" />
|
||
</UserModal>
|
||
<CommandModal :title="$t('abp.IoTDBBase.Command')" class="w-[600px]">
|
||
<CommandForm />
|
||
</CommandModal>
|
||
<BatchAddModal title="批量添加设备" class="w-[800px]">
|
||
<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 v-if="isOverLineLimit" style="color: #ff4d4f">
|
||
(超过100行限制)
|
||
</span>
|
||
</span>
|
||
<span v-else> 当前行数: {{ addressLines }} (调试信息) </span>
|
||
</div>
|
||
<div class="flex gap-2">
|
||
<Button @click="batchAddModalApi.close()">
|
||
{{ $t('common.cancel') }}
|
||
</Button>
|
||
<Button type="primary" :loading="batchAddModalState?.confirmLoading" @click="submitBatchAdd"
|
||
:disabled="isOverLineLimit">
|
||
{{ $t('common.confirm') }}
|
||
</Button>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
</BatchAddModal>
|
||
</Page>
|
||
</template>
|