fix: 物模型开发
This commit is contained in:
parent
519042d019
commit
b46b71812d
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<template v-if="isPermission">
|
||||
<template v-if="popConfirm">
|
||||
<a-popconfirm v-bind="popConfirm" :disabled="!isPermission || props.disabled">
|
||||
<a-popconfirm v-bind="popConfirm" @confirm="conform" :disabled="!isPermission || props.disabled">
|
||||
<a-tooltip v-if="tooltip" v-bind="tooltip">
|
||||
<slot v-if="noButton"></slot>
|
||||
<a-button v-else v-bind="_buttonProps" :disabled="_isPermission" @click="handleClick">
|
||||
|
@ -108,6 +108,10 @@ const _isPermission = computed(() =>
|
|||
const handleClick = (e: MouseEvent) => {
|
||||
emits('click', e)
|
||||
}
|
||||
|
||||
const conform = (e: MouseEvent) => {
|
||||
props.popConfirm?.onConfirm?.(e)
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
|
||||
|
|
|
@ -5,12 +5,12 @@ import { detail } from '@/api/device/instance'
|
|||
export const useInstanceStore = defineStore({
|
||||
id: 'device',
|
||||
state: () => ({
|
||||
current: {} as Partial<DeviceInstance>,
|
||||
detail: {} as Partial<DeviceInstance>,
|
||||
current: {} as DeviceInstance,
|
||||
detail: {} as DeviceInstance,
|
||||
tabActiveKey: 'Info'
|
||||
}),
|
||||
actions: {
|
||||
setCurrent(current: Partial<DeviceInstance>) {
|
||||
setCurrent(current: DeviceInstance) {
|
||||
this.current = current
|
||||
this.detail = current
|
||||
},
|
||||
|
|
|
@ -5,8 +5,8 @@ import { detail} from '@/api/device/product'
|
|||
export const useProductStore = defineStore({
|
||||
id: 'product',
|
||||
state: () => ({
|
||||
current: {} as ProductItem | undefined,
|
||||
detail: {} as ProductItem | undefined,
|
||||
current: {} as ProductItem,
|
||||
detail: {} as ProductItem,
|
||||
tabActiveKey: 'Info'
|
||||
}),
|
||||
actions: {
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
<template #extra>
|
||||
<img @click="handleRefresh" :src="getImage('/device/button.png')" style="margin-right: 20px; cursor: pointer;" />
|
||||
</template>
|
||||
<component :is="tabs[instanceStore.tabActiveKey]" />
|
||||
<component :is="tabs[instanceStore.tabActiveKey]" v-bind="{ type: 'device' }" />
|
||||
</page-container>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ import { updateMetadata, asyncUpdateMetadata } from '../../metadata'
|
|||
import { Store } from 'jetlinks-store';
|
||||
import { SystemConst } from '@/utils/consts';
|
||||
import { detail } from '@/api/device/instance';
|
||||
import { DeviceInstance } from '@/views/device/Instance/typings';
|
||||
|
||||
interface Props {
|
||||
type: 'product' | 'device';
|
||||
|
@ -50,7 +51,8 @@ const save = reactive({
|
|||
save.loading = true
|
||||
addFormRef.value?.validateFields().then(async (formValue) => {
|
||||
const type = metadataStore.model.type
|
||||
const _metadata = JSON.parse((props.type === 'device' ? instanceStore.detail.metadata : productStore.current?.metadata) || '{}')
|
||||
const _detail: ProductItem | DeviceInstance = props.type === 'device' ? instanceStore.detail : productStore.current
|
||||
const _metadata = JSON.parse(_detail?.metadata || '{}')
|
||||
const list = _metadata[type] as any[]
|
||||
if (formValue.id) {
|
||||
if (metadataStore.model.action === 'add' && list.some(item => item.id === formValue.id)) {
|
||||
|
@ -70,7 +72,7 @@ const save = reactive({
|
|||
productStore.setCurrent(detail)
|
||||
}
|
||||
}
|
||||
const _data = updateMetadata(type, [formValue], _metadata, updateStore)
|
||||
const _data = updateMetadata(type, [formValue], _detail, updateStore)
|
||||
const result = await asyncUpdateMetadata(props.type, _data)
|
||||
if (result.status === 200) {
|
||||
if ((window as any).onTabSaveSuccess) {
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
<JTable :loading="loading" :data-source="data" size="small" :columns="columns" row-key="id" model="TABLE">
|
||||
<template #headerTitle>
|
||||
<a-input-search v-model:value="searchValue" placeholder="请输入名称" @search="handleSearch"></a-input-search>
|
||||
<PermissionButton :has-permission="permission" key="add" @click="handleAddClick"
|
||||
:disabled="operateLimits('add', type)" type="primary" :tooltip="{
|
||||
<PermissionButton type="primary" :uhas-permission="`${permission}:update`" key="add" @click="handleAddClick"
|
||||
:udisabled="operateLimits('add', type)" :tooltip="{
|
||||
title: operateLimits('add', type) ? '当前的存储方式不支持新增' : '新增',
|
||||
}">
|
||||
<template #icon>
|
||||
|
@ -30,6 +30,24 @@
|
|||
{{ expandsType[item] }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template #action="slotProps">
|
||||
<PermissionButton :has-permission="`${permission}:update`" type="link" key="edit" style="padding: 0"
|
||||
:disabled="operateLimits('updata', type)" @click="handleEditClick(slotProps)" :tooltip="{
|
||||
title: operateLimits('updata', type) ? '当前的存储方式不支持编辑' : '编辑',
|
||||
}">
|
||||
<EditOutlined />
|
||||
</PermissionButton>,
|
||||
<PermissionButton :has-permission="`${permission}:delete`" type="link" key="delete" style="padding: 0"
|
||||
:pop-confirm="{
|
||||
title: '确认删除?', onConfirm: async () => {
|
||||
await removeItem(slotProps);
|
||||
},
|
||||
}" :tooltip="{
|
||||
title: '删除',
|
||||
}">
|
||||
<DeleteOutlined />
|
||||
</PermissionButton>
|
||||
</template>
|
||||
</JTable>
|
||||
</template>
|
||||
<script setup lang="ts" name="BaseMetadata">
|
||||
|
@ -40,6 +58,12 @@ import { useInstanceStore } from '@/store/instance'
|
|||
import { useProductStore } from '@/store/product'
|
||||
import { useMetadataStore } from '@/store/metadata'
|
||||
import PermissionButton from '@/components/PermissionButton/index.vue'
|
||||
import { PlusOutlined } from '@ant-design/icons-vue'
|
||||
import { message } from 'ant-design-vue/es'
|
||||
import { SystemConst } from '@/utils/consts'
|
||||
import { Store } from 'jetlinks-store'
|
||||
import { asyncUpdateMetadata, removeMetadata } from '../metadata'
|
||||
import { detail } from '@/api/device/instance'
|
||||
// import { detail } from '@/api/device/instance'
|
||||
// import { detail as productDetail } from '@/api/device/product'
|
||||
interface Props {
|
||||
|
@ -75,6 +99,7 @@ const actions: JColumnProps[] = [
|
|||
title: '操作',
|
||||
align: 'left',
|
||||
width: 200,
|
||||
dataIndex: 'action',
|
||||
scopedSlots: true,
|
||||
},
|
||||
];
|
||||
|
@ -123,6 +148,41 @@ const operateLimits = (action: 'add' | 'updata', types: MetadataType) => {
|
|||
(instanceStore.detail.features || []).find((item: { id: string; name: string }) => item.id === limitsMap.get(`${types}-${action}`))
|
||||
);
|
||||
};
|
||||
|
||||
const handleEditClick = (record: MetadataItem) => {
|
||||
metadataStore.model.edit = true;
|
||||
metadataStore.model.item = record;
|
||||
metadataStore.model.type = type;
|
||||
metadataStore.model.action = 'edit';
|
||||
if (!instanceStore.detail?.independentMetadata && props.target === 'device') {
|
||||
message.warning('修改物模型后会脱离产品物模型');
|
||||
}
|
||||
}
|
||||
|
||||
const resetMetadata = async () => {
|
||||
const { id } = route.params
|
||||
const resp = await detail(id as string);
|
||||
if (resp.status === 200) {
|
||||
instanceStore.setCurrent(resp?.result || []);
|
||||
}
|
||||
};
|
||||
|
||||
const removeItem = async (record: MetadataItem) => {
|
||||
// const removeDB = () => {
|
||||
// return DB.getDB().table(`${type}`).delete(record.id!);
|
||||
// };
|
||||
const _currentData = removeMetadata(type, [record], target === 'device' ? instanceStore.current : productStore.detail);
|
||||
const result = await asyncUpdateMetadata(target, _currentData);
|
||||
if (result.status === 200) {
|
||||
message.success('操作成功!');
|
||||
Store.set(SystemConst.REFRESH_METADATA_TABLE, true);
|
||||
metadataStore.model.edit = false;
|
||||
metadataStore.model.item = {};
|
||||
resetMetadata();
|
||||
} else {
|
||||
message.error('操作失败!');
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
|
||||
|
|
|
@ -1,52 +1,50 @@
|
|||
<template>
|
||||
<div class='device-detail-metadata' style="position: relative;">
|
||||
<div class="tips">
|
||||
<a-tooltip :title="instanceStore.detail?.independentMetadata && type === 'device'
|
||||
? '该设备已脱离产品物模型,修改产品物模型对该设备无影响'
|
||||
: '设备会默认继承产品的物模型,修改设备物模型后将脱离产品物模型'">
|
||||
<div class="ellipsis">
|
||||
<info-circle-outlined style="margin-right: 3px" />
|
||||
{{
|
||||
instanceStore.detail?.independentMetadata && type === 'device'
|
||||
? '该设备已脱离产品物模型,修改产品物模型对该设备无影响'
|
||||
: '设备会默认继承产品的物模型,修改设备物模型后将脱离产品物模型'
|
||||
}}
|
||||
</div>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<a-tabs class="metadataNav" destroyInactiveTabPane type="card">
|
||||
<template #rightExtra>
|
||||
<a-space>
|
||||
<PermissionButton v-if="type === 'device' && instanceStore.detail?.independentMetadata"
|
||||
:hasPermission="`${permission}:update`" :popConfirm="{ title: '确认重置?', onConfirm: resetMetadata, }"
|
||||
:tooltip="{ title: '重置后将使用产品的物模型配置' }" key="reload">
|
||||
重置操作
|
||||
</PermissionButton>
|
||||
<PermissionButton
|
||||
:uhasPermission="`${permission}:update`"
|
||||
@click="visible = true">快速导入</PermissionButton>
|
||||
<PermissionButton
|
||||
:uhasPermission="`${permission}:update`"
|
||||
@click="cat = true">物模型TSL</PermissionButton>
|
||||
</a-space>
|
||||
</template>
|
||||
<a-card>
|
||||
<div class='device-detail-metadata' style="position: relative;">
|
||||
<div class="tips">
|
||||
<a-tooltip :title="instanceStore.detail?.independentMetadata && type === 'device'
|
||||
? '该设备已脱离产品物模型,修改产品物模型对该设备无影响'
|
||||
: '设备会默认继承产品的物模型,修改设备物模型后将脱离产品物模型'">
|
||||
<div class="ellipsis">
|
||||
<info-circle-outlined style="margin-right: 3px" />
|
||||
{{
|
||||
instanceStore.detail?.independentMetadata && type === 'device'
|
||||
? '该设备已脱离产品物模型,修改产品物模型对该设备无影响'
|
||||
: '设备会默认继承产品的物模型,修改设备物模型后将脱离产品物模型'
|
||||
}}
|
||||
</div>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<a-tabs class="metadataNav" destroyInactiveTabPane type="card">
|
||||
<template #rightExtra>
|
||||
<a-space>
|
||||
<PermissionButton v-if="type === 'device' && instanceStore.detail?.independentMetadata"
|
||||
:hasPermission="`${permission}:update`" :popConfirm="{ title: '确认重置?', onConfirm: resetMetadata, }"
|
||||
:tooltip="{ title: '重置后将使用产品的物模型配置' }" key="reload">
|
||||
重置操作
|
||||
</PermissionButton>
|
||||
<PermissionButton :uhasPermission="`${permission}:update`" @click="visible = true">快速导入</PermissionButton>
|
||||
<PermissionButton :uhasPermission="`${permission}:update`" @click="cat = true">物模型TSL</PermissionButton>
|
||||
</a-space>
|
||||
</template>
|
||||
|
||||
<a-tab-pane tab="属性定义" key="properties">
|
||||
<BaseMetadata :target="type" type="properties" :permission="permission" />
|
||||
</a-tab-pane>
|
||||
<a-tab-pane tab="功能定义" key="functions">
|
||||
<BaseMetadata :target="type" type="functions" :permission="permission" />
|
||||
</a-tab-pane>
|
||||
<a-tab-pane tab="事件定义" key="events">
|
||||
<BaseMetadata :target="type" type="events" :permission="permission" />
|
||||
</a-tab-pane>
|
||||
<a-tab-pane tab="标签定义" key="tags">
|
||||
<BaseMetadata :target="type" type="tags" :permission="permission" />
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
<Import v-model:visible="visible" :type="type" @close="visible = false" />
|
||||
<Cat v-model:visible="cat" @close="cat = false" :type="type" />
|
||||
</div>
|
||||
<a-tab-pane tab="属性定义" key="properties">
|
||||
<BaseMetadata :target="type" type="properties" :permission="permission" />
|
||||
</a-tab-pane>
|
||||
<a-tab-pane tab="功能定义" key="functions">
|
||||
<BaseMetadata :target="type" type="functions" :permission="permission" />
|
||||
</a-tab-pane>
|
||||
<a-tab-pane tab="事件定义" key="events">
|
||||
<BaseMetadata :target="type" type="events" :permission="permission" />
|
||||
</a-tab-pane>
|
||||
<a-tab-pane tab="标签定义" key="tags">
|
||||
<BaseMetadata :target="type" type="tags" :permission="permission" />
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
<Import v-model:visible="visible" :type="type" @close="visible = false" />
|
||||
<Cat v-model:visible="cat" @close="cat = false" :type="type" />
|
||||
</div>
|
||||
</a-card>
|
||||
</template>
|
||||
<script setup lang="ts" name="Metadata">
|
||||
import { InfoCircleOutlined } from '@ant-design/icons-vue';
|
||||
|
|
|
@ -58,4 +58,26 @@ export const asyncUpdateMetadata = (
|
|||
case 'device':
|
||||
return saveMetadata(data.id, JSON.parse(data.metadata || '{}'));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除物模型数据
|
||||
* @param type 物模型类型
|
||||
* @param item 删除的数据
|
||||
* @param data 设备/产品数据
|
||||
* @param onEvent 回调
|
||||
*/
|
||||
export const removeMetadata = (
|
||||
type: MetadataType,
|
||||
item: MetadataItem[],
|
||||
data: ProductItem | DeviceInstance,
|
||||
onEvent?: (type: 'remove', item: MetadataItem) => void,
|
||||
): ProductItem | DeviceInstance => {
|
||||
const metadata = JSON.parse(data.metadata || '{}') as DeviceMetadata;
|
||||
const config = (metadata[type] || []) as MetadataItem[];
|
||||
// @ts-ignore
|
||||
metadata[type] = config.filter((i) => !item.map((r) => r.id).includes(i.id));
|
||||
onEvent?.('remove', item);
|
||||
data.metadata = JSON.stringify(metadata);
|
||||
return data;
|
||||
};
|
Loading…
Reference in New Issue