444 lines
11 KiB
Vue
Raw Normal View History

2025-10-22 15:09:56 +08:00
<script setup lang="ts">
import type { VbenFormProps } from '#/adapter/form';
import type { VxeGridProps } from '#/adapter/vxe-table';
2025-10-23 09:37:23 +08:00
import { h, nextTick, ref, watch } from 'vue';
2025-10-22 15:09:56 +08:00
import { useVbenModal } from '@vben/common-ui';
2025-10-23 09:37:23 +08:00
import { message as Message, Modal, Tag } from 'ant-design-vue';
2025-10-22 15:09:56 +08:00
import { useVbenForm } from '#/adapter/form';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import {
2025-10-23 11:48:10 +08:00
postThingModelInfoCopyAnotherThingModelAsync,
2025-10-23 09:37:23 +08:00
postThingModelInfoCopyStandardThingModel,
2025-10-22 15:09:56 +08:00
postThingModelInfoCreateAsync,
2025-10-23 09:37:23 +08:00
postThingModelInfoDeleteAsync,
postThingModelInfoPageAsync,
2025-10-22 15:09:56 +08:00
postThingModelInfoUpdateAsync,
} from '#/api-client';
import { TableAction } from '#/components/table-action';
import { $t } from '#/locales';
import {
addThingModelFormSchema,
2025-10-23 11:48:10 +08:00
copyThingModelFormSchema,
2025-10-22 15:09:56 +08:00
editThingModelFormSchema,
querySchema,
tableSchema,
} from './schema';
defineOptions({
name: 'ThingModelInfoModal',
});
const props = withDefaults(defineProps<Props>(), {
visible: false,
productId: '',
productName: '',
ioTPlatform: '2',
});
// 定义emits
const emit = defineEmits<{
2025-10-23 09:37:23 +08:00
close: [];
2025-10-22 15:09:56 +08:00
'update:visible': [value: boolean];
}>();
2025-10-23 09:37:23 +08:00
// 定义props
interface Props {
visible?: boolean;
productId?: string;
productName?: string;
ioTPlatform?: string;
}
2025-10-22 15:09:56 +08:00
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) => {
const { data } = await postThingModelInfoPageAsync({
2025-10-23 11:20:10 +08:00
query: {
2025-10-22 15:09:56 +08:00
pageIndex: page.currentPage,
pageSize: page.pageSize,
2025-10-23 11:20:10 +08:00
ioTPlatform: Number.parseInt(props.ioTPlatform) as 1 | 2,
ioTPlatformProductId: props.productId,
2025-10-22 15:09:56 +08:00
...formValues,
},
});
2025-10-23 11:48:10 +08:00
// 更新数据状态,检查是否有数据
hasData.value = data?.items && data.items.length > 0;
2025-10-22 15:09:56 +08:00
return data;
},
},
},
};
const [Grid, gridApi] = useVbenVxeGrid({ formOptions, gridOptions });
const editRow: Record<string, any> = ref({});
2025-10-23 11:48:10 +08:00
// 跟踪数据状态,用于控制按钮显示
const hasData = ref(true);
2025-10-22 15:09:56 +08:00
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();
},
});
2025-10-23 11:48:10 +08:00
const [CopyModal, copyModalApi] = useVbenModal({
draggable: true,
footer: true,
showCancelButton: true,
showConfirmButton: true,
onConfirm: submitCopy,
onBeforeClose: () => {
return true;
},
onCancel: () => {
copyModalApi.close();
},
});
2025-10-22 15:09:56 +08:00
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',
});
2025-10-23 11:48:10 +08:00
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',
});
2025-10-22 15:09:56 +08:00
// 监听props变化自动设置筛选条件
watch(
() => [props.visible, props.productId, props.ioTPlatform],
async ([visible, productId, ioTPlatform]) => {
console.log('物模型模态框props变化:', { visible, productId, ioTPlatform });
2025-10-23 13:54:19 +08:00
console.log('所有props:', props);
2025-10-22 15:09:56 +08:00
if (visible && productId) {
// 延迟执行,确保组件完全初始化
setTimeout(async () => {
try {
// 设置表单筛选条件
const filterValues: any = {};
2025-10-23 09:37:23 +08:00
2025-10-22 15:09:56 +08:00
if (ioTPlatform) {
filterValues.ioTPlatform = ioTPlatform;
}
2025-10-23 09:37:23 +08:00
2025-10-22 15:09:56 +08:00
if (productId) {
filterValues.oneNETProductId = productId;
}
console.log('设置筛选条件:', filterValues);
// 设置筛选表单的值
if (Object.keys(filterValues).length > 0) {
await gridApi.formApi.setValues(filterValues);
// 重新加载数据
await gridApi.reload();
}
} catch (error) {
console.error('设置筛选条件时出错:', error);
}
}, 100);
}
},
2025-10-23 09:37:23 +08:00
{ immediate: true },
2025-10-22 15:09:56 +08:00
);
// 新增和编辑提交的逻辑
async function submit() {
const isEdit = !!editRow.value.id;
const formApi = isEdit ? editFormApi : addFormApi;
const api = isEdit
? postThingModelInfoUpdateAsync
: postThingModelInfoCreateAsync;
const { valid } = await formApi.validate();
if (!valid) return;
2025-10-28 13:59:55 +08:00
const formValues = await formApi.getValues();
2025-10-22 15:09:56 +08:00
const fetchParams: any = {
2025-10-23 09:37:23 +08:00
...formValues,
// 自动添加平台和产品信息
ioTPlatform: Number.parseInt(props.ioTPlatform) as 1 | 2,
ioTPlatformProductId: props.productId,
// 编辑时需要添加ID
...(isEdit && { id: editRow.value.id }),
2025-10-22 15:09:56 +08:00
};
try {
const resp = await api({ body: 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();
};
2025-10-23 11:48:10 +08:00
// 打开复制已有模型模态框
const openCopyAnotherThingModelModal = async () => {
2025-10-23 13:54:19 +08:00
console.log('打开复制模态框当前props:', {
productId: props.productId,
productName: props.productName,
2025-10-23 14:31:42 +08:00
ioTPlatform: props.ioTPlatform,
2025-10-23 13:54:19 +08:00
});
2025-10-23 11:48:10 +08:00
copyModalApi.open();
};
// 复制提交逻辑
async function submitCopy() {
const { valid } = await copyFormApi.validate();
if (!valid) return;
const formValues = await copyFormApi.getValues();
2025-10-23 14:31:42 +08:00
2025-10-23 13:54:19 +08:00
console.log('复制提交参数:', {
formValues,
props: {
productId: props.productId,
productName: props.productName,
2025-10-23 14:31:42 +08:00
ioTPlatform: props.ioTPlatform,
},
2025-10-23 13:54:19 +08:00
});
2025-10-23 11:48:10 +08:00
try {
const resp = await postThingModelInfoCopyAnotherThingModelAsync({
body: {
ioTPlatform: Number.parseInt(props.ioTPlatform) as 1 | 2,
ioTPlatformProductId: props.productId,
2025-10-23 13:54:19 +08:00
sourceProductId: formValues.ioTPlatformProductId,
2025-10-23 11:48:10 +08:00
},
});
if (resp.data) {
Message.success('复制模型成功');
copyModalApi.close();
gridApi.reload();
} else {
Message.error('复制模型失败');
}
} catch (error) {
console.error('复制模型失败:', error);
Message.error('复制模型失败');
}
}
2025-10-22 15:09:56 +08:00
// 删除函数
async function onDel(record: any) {
try {
const resp = await postThingModelInfoDeleteAsync({
body: { 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() {
try {
const resp = await postThingModelInfoCopyStandardThingModel({
body: {
ioTPlatform: props.ioTPlatform,
ioTPlatformProductId: props.productId,
},
});
if (resp.data) {
Message.success('复制标准模型成功');
gridApi.reload();
} else {
Message.error('复制标准模型失败');
}
} catch (error) {
console.error('复制标准模型失败:', error);
Message.error('复制标准模型失败');
}
}
// 关闭模态框
function closeModal() {
emit('update:visible', false);
emit('close');
}
</script>
<template>
2025-10-23 09:37:23 +08:00
<Modal :open="visible" :title="`${props.ioTPlatform === 1 ? 'CTWing' : 'OneNET'}物模型管理 - ${productName || '产品'}`"
width="90%" :footer="null" @cancel="closeModal" @ok="closeModal"
:body-style="{ height: '70vh', overflow: 'hidden' }">
<div style="display: flex; flex-direction: column; height: 100%">
<Grid style="flex: 1; overflow: hidden">
2025-10-22 15:09:56 +08:00
<template #toolbar-actions>
<TableAction :actions="[
{
label: $t('common.add'),
type: 'primary',
icon: 'ant-design:plus-outlined',
onClick: openAddModal.bind(null),
auth: ['AbpIdentity.Users.Create'],
},
{
2025-10-23 13:54:19 +08:00
label: $t('abp.thingModelInfos.copyStandardThingModel'),
2025-10-22 15:09:56 +08:00
type: 'default',
icon: 'ant-design:copy-outlined',
onClick: copyStandardThingModel,
auth: ['AbpIdentity.Users.Create'],
},
2025-10-23 11:48:10 +08:00
{
2025-10-23 13:54:19 +08:00
label: $t('abp.thingModelInfos.copyAnotherThingModelModal'),
2025-10-23 11:48:10 +08:00
type: 'default',
icon: 'ant-design:copy-outlined',
onClick: openCopyAnotherThingModelModal,
auth: ['AbpIdentity.Users.Create'],
ifShow: !hasData,
},
2025-10-22 15:09:56 +08:00
]" />
</template>
<template #isValueNeedConvert="{ row }">
2025-10-23 09:37:23 +08:00
<component :is="h(
Tag,
{ color: row.isValueNeedConvert ? 'blue' : 'default' },
() => (row.isValueNeedConvert ? '是' : '否'),
2025-10-22 15:09:56 +08:00
)
" />
</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',
2025-10-23 09:37:23 +08:00
type: 'link',
size: 'small',
auth: ['AbpIdentity.Users.Delete'],
2025-10-22 15:09:56 +08:00
popConfirm: {
title: $t('common.askConfirmDelete'),
confirm: onDel.bind(null, row),
},
},
]" />
</template>
</Grid>
</div>
<ThingModelModal :title="editRow.id ? $t('common.edit') : $t('common.add')" class="w-[800px]">
<component :is="editRow.id ? EditForm : AddForm" />
</ThingModelModal>
2025-10-23 14:31:42 +08:00
2025-10-23 13:54:19 +08:00
<!-- 复制已有模型模态框 -->
<CopyModal title="复制已有模型" class="w-[600px]">
<CopyForm />
</CopyModal>
2025-10-22 15:09:56 +08:00
</Modal>
</template>