485 lines
13 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup lang="ts">
import type { VbenFormProps } from '#/adapter/form';
import type { VxeGridProps } from '#/adapter/vxe-table';
import { h, nextTick, onMounted, ref, watch } from 'vue';
import { useRoute } from 'vue-router';
import { Page, useVbenModal } from '@vben/common-ui';
import { message as Message, Tag } from 'ant-design-vue';
import { useVbenForm } from '#/adapter/form';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import {
postIoTplatformThingModelInfoCopyAnotherThingModelAsync,
postIoTplatformThingModelInfoCopyStandardThingModel,
postIoTplatformThingModelInfoCreateAsync,
postIoTplatformThingModelInfoDeleteAsync,
postIoTplatformThingModelInfoPageAsync,
postIoTplatformThingModelInfoUpdateAsync,
} from '#/api-client';
import { TableAction } from '#/components/table-action';
import { $t } from '#/locales';
import {
addThingModelFormSchema,
copyThingModelFormSchema,
editThingModelFormSchema,
querySchema,
tableSchema,
} from './schema';
defineOptions({
name: 'IoTPlatformThingModelInfo',
});
const route = useRoute();
// 从路由参数获取产品信息
const productId = ref<string>((route.query.productId as string) || '');
const productName = ref<string>((route.query.productName as string) || '');
const ioTPlatform = ref<string>((route.query.ioTPlatform as string) || '2');
const formOptions: VbenFormProps = {
schema: querySchema.value,
};
const gridOptions: VxeGridProps<any> = {
checkboxConfig: {
highlight: true,
labelField: 'thingModelName',
},
columns: tableSchema.value,
height: 'auto',
keepSource: true,
pagerConfig: {},
toolbarConfig: {
custom: true,
},
customConfig: {
storage: true,
},
proxyConfig: {
ajax: {
query: async ({ page }, formValues) => {
// 如果没有产品ID直接返回空数据让表格正常显示空白状态
if (!productId.value) {
hasData.value = false;
return {
items: [],
totalCount: 0,
};
}
try {
const { data } = await postIoTplatformThingModelInfoPageAsync({
query: {
input: {
pageIndex: page.currentPage,
pageSize: page.pageSize,
ioTPlatform: Number.parseInt(ioTPlatform.value) as 1 | 2,
ioTPlatformProductId: productId.value,
...(formValues?.SearchKeyWords && { searchKeyWords: formValues.SearchKeyWords }),
},
},
});
// 更新数据状态,检查是否有数据
hasData.value = data?.items && data.items.length > 0;
return data || { items: [], totalCount: 0 };
} catch (error) {
console.error('查询物模型信息失败:', error);
hasData.value = false;
return {
items: [],
totalCount: 0,
};
}
},
},
},
};
const [Grid, gridApi] = useVbenVxeGrid({ formOptions, gridOptions });
const editRow: Record<string, any> = ref({});
// 跟踪数据状态,用于控制按钮显示
const hasData = ref(true);
const [ThingModelModal, thingModelModalApi] = useVbenModal({
draggable: true,
footer: true,
showCancelButton: true,
showConfirmButton: true,
onConfirm: submit,
onBeforeClose: () => {
return true;
},
onOpenChange: (isOpen: boolean) => {
if (isOpen && editRow.value.id) {
// 编辑模式下,模态框打开后设置表单值
nextTick(() => {
editFormApi.setValues({ ...editRow.value });
});
}
},
onCancel: () => {
thingModelModalApi.close();
},
});
const [CopyModal, copyModalApi] = useVbenModal({
draggable: true,
footer: true,
showCancelButton: true,
showConfirmButton: true,
onConfirm: submitCopy,
onBeforeClose: () => {
return true;
},
onCancel: () => {
copyModalApi.close();
},
});
const [AddForm, addFormApi] = useVbenForm({
collapsed: false,
commonConfig: {
labelWidth: 110,
componentProps: {
class: 'w-4/5',
},
},
layout: 'horizontal',
schema: addThingModelFormSchema.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: editThingModelFormSchema.value,
showCollapseButton: false,
showDefaultActions: false,
wrapperClass: 'grid-cols-2',
});
const [CopyForm, copyFormApi] = useVbenForm({
collapsed: false,
commonConfig: {
labelWidth: 110,
componentProps: {
class: 'w-4/5',
},
},
layout: 'horizontal',
schema: copyThingModelFormSchema.value,
showCollapseButton: false,
showDefaultActions: false,
wrapperClass: 'grid-cols-2',
});
// 监听路由参数变化,自动加载数据
watch(
() => [route.query.productId, route.query.ioTPlatform],
async ([newProductId, newIoTPlatform]) => {
if (newProductId) {
productId.value = newProductId as string;
}
if (newIoTPlatform) {
ioTPlatform.value = newIoTPlatform as string;
}
if (route.query.productName) {
productName.value = route.query.productName as string;
}
// 延迟执行,确保组件完全初始化
if (gridApi) {
setTimeout(async () => {
try {
await gridApi.reload();
} catch (error) {
console.error('加载数据时出错:', error);
}
}, 100);
}
},
{ immediate: false },
);
// 页面初始化时加载数据
onMounted(async () => {
// 从路由参数初始化
if (route.query.productId) {
productId.value = route.query.productId as string;
}
if (route.query.productName) {
productName.value = route.query.productName as string;
}
if (route.query.ioTPlatform) {
ioTPlatform.value = route.query.ioTPlatform as string;
}
// 延迟加载数据,确保表格已初始化
// 即使没有 productId也要触发一次查询让表格显示空白状态
await nextTick();
setTimeout(async () => {
if (gridApi && gridApi.reload) {
try {
await gridApi.reload();
} catch (error) {
console.error('初始化加载数据时出错:', error);
}
}
}, 300);
});
// 新增和编辑提交的逻辑
async function submit() {
// 检查是否有产品ID
if (!productId.value) {
Message.error('产品ID不存在无法保存物模型信息');
return;
}
const isEdit = !!editRow.value.id;
const formApi = isEdit ? editFormApi : addFormApi;
const api = isEdit
? postIoTplatformThingModelInfoUpdateAsync
: postIoTplatformThingModelInfoCreateAsync;
const { valid } = await formApi.validate();
if (!valid) return;
const formValues = await formApi.getValues();
const fetchParams: any = {
...formValues,
// 自动添加平台和产品信息
ioTPlatform: Number.parseInt(ioTPlatform.value) as 1 | 2,
ioTPlatformProductId: productId.value,
// 编辑时需要添加ID
...(isEdit && { id: editRow.value.id }),
};
try {
const resp = await api({ query: { input: fetchParams } });
if (resp.data) {
Message.success(
editRow.value.id ? $t('common.editSuccess') : $t('common.addSuccess'),
);
thingModelModalApi.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'),
);
}
}
async function onEdit(record: any) {
editRow.value = record;
thingModelModalApi.open();
}
const openAddModal = async () => {
editRow.value = {};
thingModelModalApi.open();
};
// 打开复制已有模型模态框
const openCopyAnotherThingModelModal = async () => {
console.log('打开复制模态框,当前参数:', {
productId: productId.value,
productName: productName.value,
ioTPlatform: ioTPlatform.value,
});
copyModalApi.open();
};
// 复制提交逻辑
async function submitCopy() {
// 检查是否有产品ID
if (!productId.value) {
Message.error('产品ID不存在无法复制物模型信息');
return;
}
const { valid } = await copyFormApi.validate();
if (!valid) return;
const formValues = await copyFormApi.getValues();
console.log('复制提交参数:', {
formValues,
params: {
productId: productId.value,
productName: productName.value,
ioTPlatform: ioTPlatform.value,
},
});
try {
const resp = await postIoTplatformThingModelInfoCopyAnotherThingModelAsync({
query: {
input: {
ioTPlatform: Number.parseInt(ioTPlatform.value) as 1 | 2,
ioTPlatformProductId: productId.value,
sourceProductId: formValues.ioTPlatformProductId,
},
},
});
if (resp.data) {
Message.success('复制模型成功');
copyModalApi.close();
gridApi.reload();
} else {
Message.error('复制模型失败');
}
} catch (error) {
console.error('复制模型失败:', error);
Message.error('复制模型失败');
}
}
// 删除函数
async function onDel(record: any) {
try {
const resp = await postIoTplatformThingModelInfoDeleteAsync({
query: {
input: { id: record.id },
},
});
if (resp.data) {
Message.success($t('common.deleteSuccess'));
gridApi.reload();
} else {
Message.error($t('common.deleteFail'));
}
} catch (error) {
console.error('删除失败:', error);
Message.error($t('common.deleteFail'));
}
}
// 复制标准模型函数
async function copyStandardThingModel() {
// 检查是否有产品ID
if (!productId.value) {
Message.error('产品ID不存在无法复制标准模型');
return;
}
try {
const resp = await postIoTplatformThingModelInfoCopyStandardThingModel({
query: {
input: {
ioTPlatform: Number.parseInt(ioTPlatform.value) as 1 | 2,
ioTPlatformProductId: productId.value,
},
},
});
if (resp.data) {
Message.success('复制标准模型成功');
gridApi.reload();
} else {
Message.error('复制标准模型失败');
}
} catch (error) {
console.error('复制标准模型失败:', error);
Message.error('复制标准模型失败');
}
}
</script>
<template>
<Page auto-content-height>
<Grid>
<template #toolbar-actions>
<TableAction :actions="[
{
label: $t('common.add'),
type: 'primary',
icon: 'ant-design:plus-outlined',
onClick: openAddModal.bind(null),
auth: ['AbpIdentity.Users.Create'],
disabled: !productId,
},
{
label: $t('abp.thingModelInfos.copyStandardThingModel'),
type: 'default',
icon: 'ant-design:copy-outlined',
onClick: copyStandardThingModel,
auth: ['AbpIdentity.Users.Create'],
disabled: !productId,
},
{
label: $t('abp.thingModelInfos.copyAnotherThingModelModal'),
type: 'default',
icon: 'ant-design:copy-outlined',
onClick: openCopyAnotherThingModelModal,
auth: ['AbpIdentity.Users.Create'],
ifShow: !hasData,
disabled: !productId,
},
]" />
</template>
<template #isValueNeedConvert="{ row }">
<component :is="h(
Tag,
{ color: row.isValueNeedConvert ? 'blue' : 'default' },
() => (row.isValueNeedConvert ? '是' : '否'),
)
" />
</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('common.delete'),
icon: 'ant-design:delete-outlined',
type: 'link',
size: 'small',
auth: ['AbpIdentity.Users.Delete'],
popConfirm: {
title: $t('common.askConfirmDelete'),
confirm: onDel.bind(null, row),
},
},
]" />
</template>
</Grid>
<ThingModelModal :title="editRow.id ? $t('common.edit') : $t('common.add')" class="w-[800px]">
<component :is="editRow.id ? EditForm : AddForm" />
</ThingModelModal>
<!-- 复制已有模型模态框 -->
<CopyModal title="复制已有模型" class="w-[600px]">
<CopyForm />
</CopyModal>
</Page>
</template>