233 lines
8.2 KiB
Vue
233 lines
8.2 KiB
Vue
<template>
|
|
<div class="table-header">
|
|
<div>
|
|
<j-input-search v-model:value="searchValue" placeholder="请输入名称" @search="handleSearch" allowClear></j-input-search>
|
|
</div>
|
|
<div>
|
|
<PermissionButton type="primary" :hasPermission="`${permission}:update`" key="add" @click="handleAddClick"
|
|
:disabled="operateLimits('add', type)" :tooltip="{
|
|
title: operateLimits('add', type) ? '当前的存储方式不支持新增' : '新增',
|
|
}">
|
|
<template #icon>
|
|
<AIcon type="PlusOutlined" />
|
|
</template>
|
|
新增
|
|
</PermissionButton>
|
|
<Edit v-if="metadataStore.model.edit" :type="target" :tabs="type" @refresh="refreshMetadata"></Edit>
|
|
</div>
|
|
</div>
|
|
<j-table :loading="loading" :data-source="data" :columns="columns" row-key="id" model="TABLE" size="small"
|
|
:pagination="pagination">
|
|
<template #bodyCell="{ column, record }">
|
|
<template v-if="column.dataIndex === 'id'">
|
|
<div style="width: 100px"><Ellipsis>{{ record.id || '-' }}</Ellipsis></div>
|
|
</template>
|
|
<template v-if="column.dataIndex === 'name'">
|
|
<div style="width: 200px"><Ellipsis>{{ record.name || '-' }}</Ellipsis></div>
|
|
</template>
|
|
<template v-if="column.dataIndex === 'description'">
|
|
<div style="width: 200px"><Ellipsis>{{ record.description || '-' }}</Ellipsis></div>
|
|
</template>
|
|
<template v-if="column.dataIndex === 'level'">
|
|
{{ levelMap[record.expands?.level] || '-' }}
|
|
</template>
|
|
<template v-if="column.dataIndex === 'async'">
|
|
{{ record.async ? '是' : '否' }}
|
|
</template>
|
|
<template v-if="column.dataIndex === 'valueType'">
|
|
{{ record.valueType?.type }}
|
|
</template>
|
|
<template v-if="column.dataIndex === 'source'">
|
|
{{ sourceMap[record.expands?.source] }}
|
|
</template>
|
|
<template v-if="column.dataIndex === 'type'">
|
|
<j-tag v-for="item in (record.expands?.type || [])" :key="item">
|
|
{{ expandsType[item] }}
|
|
</j-tag>
|
|
</template>
|
|
<template v-if="column.dataIndex === 'action'">
|
|
<j-space>
|
|
<PermissionButton :has-permission="`${permission}:update`" type="link" key="edit" style="padding: 0"
|
|
:disabled="operateLimits('updata', type)" @click="handleEditClick(record)" :tooltip="{
|
|
title: operateLimits('updata', type) ? '当前的存储方式不支持编辑' : '编辑',
|
|
}">
|
|
<AIcon type="EditOutlined" />
|
|
</PermissionButton>
|
|
<PermissionButton :has-permission="`${permission}:delete`" type="link" key="delete" style="padding: 0" danger
|
|
:pop-confirm="{
|
|
title: '确认删除?', onConfirm: async () => {
|
|
await removeItem(record);
|
|
},
|
|
}" :tooltip="{
|
|
title: '删除',
|
|
}">
|
|
<AIcon type="DeleteOutlined" />
|
|
</PermissionButton>
|
|
</j-space>
|
|
</template>
|
|
</template>
|
|
</j-table>
|
|
</template>
|
|
<script setup lang="ts" name="BaseMetadata">
|
|
import type { MetadataItem, MetadataType } from '@/views/device/Product/typings'
|
|
import { useColumns } from './columns';
|
|
import { useInstanceStore } from '@/store/instance'
|
|
import { useProductStore } from '@/store/product'
|
|
import { useMetadataStore } from '@/store/metadata'
|
|
import PermissionButton from '@/components/PermissionButton/index.vue'
|
|
import { TablePaginationConfig } from 'ant-design-vue/es'
|
|
import { asyncUpdateMetadata, removeMetadata } from '../metadata'
|
|
import Edit from './Edit/index.vue'
|
|
import { ColumnProps } from 'ant-design-vue/es/table'
|
|
import { onlyMessage } from '@/utils/comm';
|
|
interface Props {
|
|
type: MetadataType;
|
|
target: 'product' | 'device';
|
|
permission: string | string[];
|
|
}
|
|
const props = defineProps<Props>()
|
|
const route = useRoute()
|
|
const instanceStore = useInstanceStore()
|
|
const productStore = useProductStore()
|
|
|
|
const loading = ref(false)
|
|
const data = ref<MetadataItem[]>([])
|
|
const { type, target = 'product' } = props
|
|
const levelMap = ref({
|
|
ordinary: '普通',
|
|
warn: '警告',
|
|
urgent: '紧急',
|
|
})
|
|
const sourceMap = ref({
|
|
device: '设备',
|
|
manual: '手动',
|
|
rule: '规则',
|
|
});
|
|
const expandsType = ref({
|
|
read: '读',
|
|
write: '写',
|
|
report: '上报',
|
|
});
|
|
const actions: ColumnProps[] = [
|
|
{
|
|
title: '操作',
|
|
align: 'left',
|
|
width: 80,
|
|
dataIndex: 'action',
|
|
},
|
|
];
|
|
const pagination = {
|
|
showTotal: (num: number, range: number[]) => {
|
|
return `第 ${range[0]} - ${range[1]} 条/总共 ${num} 条`;
|
|
},
|
|
showSizeChanger: true,
|
|
showQuickJumper: false,
|
|
defaultPageSize: 10,
|
|
size: 'small',
|
|
} as TablePaginationConfig
|
|
// const columns = computed(() => MetadataMapping.get(type)!.concat(actions))
|
|
const { columns } = useColumns(type)
|
|
const items = computed(() => JSON.parse((target === 'product' ? productStore.current?.metadata : instanceStore.current.metadata) || '{}'))
|
|
const searchValue = ref<string>()
|
|
const handleSearch = (searchValue: string) => {
|
|
if (searchValue) {
|
|
const arr = items.value[type].filter((item: MetadataItem) => item.name!.indexOf(searchValue) > -1).sort((a: MetadataItem, b: MetadataItem) => b?.sortsIndex - a?.sortsIndex)
|
|
data.value = arr
|
|
} else {
|
|
data.value = items.value[type]
|
|
}
|
|
}
|
|
|
|
const refreshMetadata = () => {
|
|
loading.value = true
|
|
// const res = target === 'product'
|
|
// ? await productDetail(route.params.id as string)
|
|
// : await detail(route.params.id as string);
|
|
const result = target === 'product' ? productStore.current?.metadata : instanceStore.current.metadata
|
|
const item = JSON.parse(result || '{}') as MetadataItem[]
|
|
console.log(item)
|
|
data.value = item[type]?.sort((a: any, b: any) => b?.sortsIndex - a?.sortsIndex)
|
|
loading.value = false
|
|
}
|
|
watch([route.params.id, type], refreshMetadata, { immediate: true })
|
|
|
|
const metadataStore = useMetadataStore()
|
|
watch(() => metadataStore.model.importMetadata,
|
|
(val: boolean) => {
|
|
if (!!val) {
|
|
refreshMetadata()
|
|
metadataStore.set('importMetadata', false)
|
|
}
|
|
})
|
|
const handleAddClick = () => {
|
|
metadataStore.set('edit', true)
|
|
metadataStore.set('item', undefined)
|
|
metadataStore.set('type', type)
|
|
metadataStore.set('action', 'add')
|
|
if (props.target === 'device' && !instanceStore.detail?.independentMetadata) {
|
|
onlyMessage('修改物模型后会脱离产品物模型', 'warning')
|
|
}
|
|
}
|
|
|
|
const limitsMap = new Map<string, any>();
|
|
limitsMap.set('events-add', 'eventNotInsertable');
|
|
limitsMap.set('events-updata', 'eventNotModifiable');
|
|
limitsMap.set('properties-add', 'propertyNotInsertable');
|
|
limitsMap.set('properties-updata', 'propertyNotModifiable');
|
|
const operateLimits = (action: 'add' | 'updata', types: MetadataType) => {
|
|
return (
|
|
target === 'device' &&
|
|
(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 (props.target === 'device' && !instanceStore.detail?.independentMetadata) {
|
|
onlyMessage('修改物模型后会脱离产品物模型', 'warning');
|
|
}
|
|
}
|
|
|
|
const resetMetadata = async () => {
|
|
// const { id } = route.params
|
|
// const resp = await detail(id as string);
|
|
// if (resp.status === 200) {
|
|
// instanceStore.setCurrent(resp?.result || []);
|
|
// }
|
|
const { id } = route.params
|
|
if (target === 'device') {
|
|
await instanceStore.refresh(id as string)
|
|
} else {
|
|
await productStore.getDetail(id as string)
|
|
}
|
|
metadataStore.set('importMetadata', true)
|
|
|
|
};
|
|
|
|
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) {
|
|
onlyMessage('操作成功!');
|
|
// Store.set(SystemConst.REFRESH_METADATA_TABLE, true);
|
|
metadataStore.model.edit = false;
|
|
metadataStore.model.item = {};
|
|
resetMetadata();
|
|
} else {
|
|
onlyMessage('操作失败!', 'error');
|
|
}
|
|
};
|
|
</script>
|
|
<style scoped lang="less">
|
|
.table-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
padding: 16px;
|
|
}
|
|
</style> |