review:【antd】【iot】物模型的管理
This commit is contained in:
@@ -23,16 +23,65 @@ const props = defineProps<{
|
|||||||
productId: number;
|
productId: number;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
// 产品信息
|
const product = ref<IotProductApi.Product>({} as IotProductApi.Product); // 产品信息
|
||||||
const product = ref<IotProductApi.Product>({} as IotProductApi.Product);
|
|
||||||
|
|
||||||
// 提供产品信息给子组件
|
provide(IOT_PROVIDE_KEY.PRODUCT, product); // 提供产品信息给子组件
|
||||||
provide(IOT_PROVIDE_KEY.PRODUCT, product);
|
|
||||||
|
|
||||||
// 组件引用
|
// TODO @haohao:form 是不是用 web-antd/src/views/system/user/index.vue 里 open 的风格;
|
||||||
const thingModelFormRef = ref();
|
const thingModelFormRef = ref();
|
||||||
|
// TODO @haohao:thingModelTSLRef 应该是个 modal,也可以调整下风格;
|
||||||
const thingModelTSLRef = ref();
|
const thingModelTSLRef = ref();
|
||||||
|
|
||||||
|
// TODO @haohao:方法的顺序、注释、调整的和别的模块一致。
|
||||||
|
|
||||||
|
// 新增功能
|
||||||
|
function handleCreate() {
|
||||||
|
thingModelFormRef.value?.open('create');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 编辑功能
|
||||||
|
function handleEdit(row: any) {
|
||||||
|
thingModelFormRef.value?.open('update', row.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除功能
|
||||||
|
async function handleDelete(row: any) {
|
||||||
|
// TODO @haohao:应该有个 loading,类似别的模块写法;
|
||||||
|
try {
|
||||||
|
await deleteThingModel(row.id);
|
||||||
|
message.success('删除成功');
|
||||||
|
gridApi.reload();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('删除失败:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打开 TSL
|
||||||
|
function handleOpenTSL() {
|
||||||
|
thingModelTSLRef.value?.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取数据类型标签
|
||||||
|
// TODO @haohao:可以直接在 data.ts 就写掉这个逻辑;
|
||||||
|
function getDataTypeLabel(row: any) {
|
||||||
|
return getDataTypeOptionsLabel(row.property?.dataType) || '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 刷新表格
|
||||||
|
function handleRefresh() {
|
||||||
|
gridApi.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取产品信息
|
||||||
|
async function getProductData() {
|
||||||
|
try {
|
||||||
|
product.value = await getProduct(props.productId);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取产品信息失败:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO @haohao:字段的顺序,调整成别的模块一直;
|
||||||
const [Grid, gridApi] = useVbenVxeGrid({
|
const [Grid, gridApi] = useVbenVxeGrid({
|
||||||
gridOptions: {
|
gridOptions: {
|
||||||
columns: useGridColumns(),
|
columns: useGridColumns(),
|
||||||
@@ -64,51 +113,6 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// 新增功能
|
|
||||||
function handleCreate() {
|
|
||||||
thingModelFormRef.value?.open('create');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 编辑功能
|
|
||||||
function handleEdit(row: any) {
|
|
||||||
thingModelFormRef.value?.open('update', row.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除功能
|
|
||||||
async function handleDelete(row: any) {
|
|
||||||
try {
|
|
||||||
await deleteThingModel(row.id);
|
|
||||||
message.success('删除成功');
|
|
||||||
gridApi.reload();
|
|
||||||
} catch (error) {
|
|
||||||
console.error('删除失败:', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 打开 TSL
|
|
||||||
function handleOpenTSL() {
|
|
||||||
thingModelTSLRef.value?.open();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取数据类型标签
|
|
||||||
function getDataTypeLabel(row: any) {
|
|
||||||
return getDataTypeOptionsLabel(row.property?.dataType) || '-';
|
|
||||||
}
|
|
||||||
|
|
||||||
// 刷新表格
|
|
||||||
function handleRefresh() {
|
|
||||||
gridApi.reload();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取产品信息
|
|
||||||
async function getProductData() {
|
|
||||||
try {
|
|
||||||
product.value = await getProduct(props.productId);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('获取产品信息失败:', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 初始化
|
// 初始化
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await getProductData();
|
await getProductData();
|
||||||
@@ -116,11 +120,7 @@ onMounted(async () => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Page
|
<Page auto-content-height>
|
||||||
auto-content-height
|
|
||||||
description="管理产品的物模型定义,包括属性、服务和事件"
|
|
||||||
title="物模型管理"
|
|
||||||
>
|
|
||||||
<Grid>
|
<Grid>
|
||||||
<template #toolbar-tools>
|
<template #toolbar-tools>
|
||||||
<TableAction
|
<TableAction
|
||||||
@@ -134,23 +134,21 @@ onMounted(async () => {
|
|||||||
{
|
{
|
||||||
label: 'TSL',
|
label: 'TSL',
|
||||||
type: 'default',
|
type: 'default',
|
||||||
color: 'success',
|
color: 'success', // TODO @haohao:貌似 color 可以去掉?应该是不生效的哈。ps:另外,也给搞个 icon?
|
||||||
onClick: handleOpenTSL,
|
onClick: handleOpenTSL,
|
||||||
},
|
},
|
||||||
]"
|
]"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 数据类型列 -->
|
<!-- 数据类型列 -->
|
||||||
<template #dataType="{ row }">
|
<template #dataType="{ row }">
|
||||||
<span>{{ getDataTypeLabel(row) }}</span>
|
<span>{{ getDataTypeLabel(row) }}</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 数据定义列 -->
|
<!-- 数据定义列 -->
|
||||||
|
<!-- TODO @haohao:可以在 data.ts 就写掉这个逻辑; -->
|
||||||
<template #dataDefinition="{ row }">
|
<template #dataDefinition="{ row }">
|
||||||
<DataDefinition :data="row" />
|
<DataDefinition :data="row" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 操作列 -->
|
<!-- 操作列 -->
|
||||||
<template #actions="{ row }">
|
<template #actions="{ row }">
|
||||||
<TableAction
|
<TableAction
|
||||||
@@ -178,8 +176,7 @@ onMounted(async () => {
|
|||||||
|
|
||||||
<!-- 物模型表单 -->
|
<!-- 物模型表单 -->
|
||||||
<ThingModelForm ref="thingModelFormRef" @success="handleRefresh" />
|
<ThingModelForm ref="thingModelFormRef" @success="handleRefresh" />
|
||||||
|
|
||||||
<!-- TSL 弹窗 -->
|
<!-- TSL 弹窗 -->
|
||||||
<ThingModelTsl ref="thingModelTSLRef"/>
|
<ThingModelTsl ref="thingModelTSLRef" />
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
<!-- TODO @haohao:如果是模块内用的,就用 modules 里。(等后面点在看,优先级:低) -->
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { ThingModelData } from '#/api/iot/thingmodel';
|
import type { ThingModelData } from '#/api/iot/thingmodel';
|
||||||
|
|
||||||
@@ -17,7 +18,6 @@ defineOptions({ name: 'DataDefinition' });
|
|||||||
|
|
||||||
const props = defineProps<{ data: ThingModelData }>();
|
const props = defineProps<{ data: ThingModelData }>();
|
||||||
|
|
||||||
// 格式化布尔值和枚举值列表为字符串
|
|
||||||
const formattedDataSpecsList = computed(() => {
|
const formattedDataSpecsList = computed(() => {
|
||||||
if (
|
if (
|
||||||
!props.data.property?.dataSpecsList ||
|
!props.data.property?.dataSpecsList ||
|
||||||
@@ -28,9 +28,8 @@ const formattedDataSpecsList = computed(() => {
|
|||||||
return props.data.property.dataSpecsList
|
return props.data.property.dataSpecsList
|
||||||
.map((item) => `${item.value}-${item.name}`)
|
.map((item) => `${item.value}-${item.name}`)
|
||||||
.join('、');
|
.join('、');
|
||||||
});
|
}); // 格式化布尔值和枚举值列表为字符串
|
||||||
|
|
||||||
// 显示的简短文本(第一个值)
|
|
||||||
const shortText = computed(() => {
|
const shortText = computed(() => {
|
||||||
if (
|
if (
|
||||||
!props.data.property?.dataSpecsList ||
|
!props.data.property?.dataSpecsList ||
|
||||||
@@ -43,7 +42,7 @@ const shortText = computed(() => {
|
|||||||
return count > 1
|
return count > 1
|
||||||
? `${first.value}-${first.name} 等${count}项`
|
? `${first.value}-${first.name} 等${count}项`
|
||||||
: `${first.value}-${first.name}`;
|
: `${first.value}-${first.name}`;
|
||||||
});
|
}); // 显示的简短文本(第一个值)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -100,9 +99,8 @@ const shortText = computed(() => {
|
|||||||
</template>
|
</template>
|
||||||
<!-- 服务 -->
|
<!-- 服务 -->
|
||||||
<div v-if="Number(data.type) === IoTThingModelTypeEnum.SERVICE">
|
<div v-if="Number(data.type) === IoTThingModelTypeEnum.SERVICE">
|
||||||
调用方式:{{
|
调用方式:
|
||||||
getThingModelServiceCallTypeLabel(data.service?.callType as any)
|
{{ getThingModelServiceCallTypeLabel(data.service?.callType as any) }}
|
||||||
}}
|
|
||||||
</div>
|
</div>
|
||||||
<!-- 事件 -->
|
<!-- 事件 -->
|
||||||
<div v-if="Number(data.type) === IoTThingModelTypeEnum.EVENT">
|
<div v-if="Number(data.type) === IoTThingModelTypeEnum.EVENT">
|
||||||
@@ -111,6 +109,7 @@ const shortText = computed(() => {
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
/** TODO @haohao:tindwind */
|
||||||
.data-specs-text {
|
.data-specs-text {
|
||||||
cursor: help;
|
cursor: help;
|
||||||
border-bottom: 1px dashed #d9d9d9;
|
border-bottom: 1px dashed #d9d9d9;
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
export {default as DataDefinition} from './data-definition.vue';
|
export { default as DataDefinition } from './data-definition.vue';
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ const props = defineProps<{ isStructDataSpecs?: boolean; modelValue: any }>();
|
|||||||
const emits = defineEmits(['update:modelValue']);
|
const emits = defineEmits(['update:modelValue']);
|
||||||
const thingModelEvent = useVModel(props, 'modelValue', emits) as Ref<any>;
|
const thingModelEvent = useVModel(props, 'modelValue', emits) as Ref<any>;
|
||||||
|
|
||||||
// 默认选中,INFO 信息
|
/** 默认选中,INFO 信息 */
|
||||||
watch(
|
watch(
|
||||||
() => thingModelEvent.value.type,
|
() => thingModelEvent.value.type,
|
||||||
(val: string | undefined) =>
|
(val: string | undefined) =>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { Ref } from 'vue';
|
import type { Ref } from 'vue';
|
||||||
|
|
||||||
|
// TODO @haohao:使用 form.vue;
|
||||||
import type { IotProductApi } from '#/api/iot/product/product';
|
import type { IotProductApi } from '#/api/iot/product/product';
|
||||||
import type { ThingModelData } from '#/api/iot/thingmodel';
|
import type { ThingModelData } from '#/api/iot/thingmodel';
|
||||||
|
|
||||||
@@ -61,6 +62,7 @@ const formData = ref<any>({
|
|||||||
const formRef = ref(); // 表单 Ref
|
const formRef = ref(); // 表单 Ref
|
||||||
|
|
||||||
/** 打开弹窗 */
|
/** 打开弹窗 */
|
||||||
|
// TODO @haohao:Modal 的写法。
|
||||||
async function open(type: string, id?: number) {
|
async function open(type: string, id?: number) {
|
||||||
dialogVisible.value = true;
|
dialogVisible.value = true;
|
||||||
// 设置标题:create -> 新增,update -> 编辑
|
// 设置标题:create -> 新增,update -> 编辑
|
||||||
@@ -244,6 +246,7 @@ function resetForm() {
|
|||||||
:confirm-loading="formLoading"
|
:confirm-loading="formLoading"
|
||||||
@ok="submitForm"
|
@ok="submitForm"
|
||||||
>
|
>
|
||||||
|
<!-- TODO @haohao:这个可以改造成 data.ts schema 形式么?可能是有一定成本,后续迁移 ele 版本,会容易很多。 -->
|
||||||
<Form
|
<Form
|
||||||
ref="formRef"
|
ref="formRef"
|
||||||
:model="formData"
|
:model="formData"
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { Modal, Radio, Textarea } from 'ant-design-vue';
|
|||||||
import { getThingModelTSL } from '#/api/iot/thingmodel';
|
import { getThingModelTSL } from '#/api/iot/thingmodel';
|
||||||
import { IOT_PROVIDE_KEY } from '#/views/iot/utils/constants';
|
import { IOT_PROVIDE_KEY } from '#/views/iot/utils/constants';
|
||||||
|
|
||||||
defineOptions({name: 'ThingModelTsl'});
|
defineOptions({ name: 'ThingModelTsl' });
|
||||||
|
|
||||||
const dialogVisible = ref(false); // 弹窗的是否展示
|
const dialogVisible = ref(false); // 弹窗的是否展示
|
||||||
const dialogTitle = ref('物模型 TSL'); // 弹窗的标题
|
const dialogTitle = ref('物模型 TSL'); // 弹窗的标题
|
||||||
|
|||||||
Reference in New Issue
Block a user