|
@@ -0,0 +1,275 @@
|
|
|
|
+<template>
|
|
|
|
+ <t-dialog
|
|
|
|
+ v-model:visible="props.visible"
|
|
|
|
+ header="关联图元属性"
|
|
|
|
+ :width="580"
|
|
|
|
+ @close="close"
|
|
|
|
+ @confirm="confirm"
|
|
|
|
+ >
|
|
|
|
+ <div class="flex">
|
|
|
|
+ <div style="width: 200px">
|
|
|
|
+ <div class="input-search mt-8">
|
|
|
|
+ <div class="btn">
|
|
|
|
+ <search-icon class="hover" />
|
|
|
|
+ </div>
|
|
|
|
+ <t-input
|
|
|
|
+ v-model="search"
|
|
|
|
+ @change="onSearch"
|
|
|
|
+ @enter="onSearch"
|
|
|
|
+ placeholder="搜索图元"
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+ <div class="props-tree mt-8">
|
|
|
|
+ <t-tree
|
|
|
|
+ v-model:actived="activedId"
|
|
|
|
+ activable
|
|
|
|
+ hover
|
|
|
|
+ :data="penTree"
|
|
|
|
+ :expand-level="1"
|
|
|
|
+ :filter="bindFilter"
|
|
|
|
+ @click="onClick"
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <t-divider
|
|
|
|
+ class="mt-8"
|
|
|
|
+ style="
|
|
|
|
+ height: 360px;
|
|
|
|
+ border-left: 2px solid var(--color-background-input);
|
|
|
|
+ "
|
|
|
|
+ layout="vertical"
|
|
|
|
+ />
|
|
|
|
+ <div style="width: 300px">
|
|
|
|
+ <div class="input-search mt-8">
|
|
|
|
+ <div class="btn">
|
|
|
|
+ <search-icon class="hover" />
|
|
|
|
+ </div>
|
|
|
|
+ <t-input
|
|
|
|
+ v-model="propSearch"
|
|
|
|
+ @change="onPropSearch"
|
|
|
|
+ @enter="onPropSearch"
|
|
|
|
+ placeholder="搜索属性"
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+ <div class="props mt-8">
|
|
|
|
+ <t-table
|
|
|
|
+ class="data-list"
|
|
|
|
+ ref="tableRef"
|
|
|
|
+ row-key="value"
|
|
|
|
+ :columns="columns"
|
|
|
|
+ :data="propData"
|
|
|
|
+ :height="300"
|
|
|
|
+ :bordered="false"
|
|
|
|
+ :selected-row-keys="selectedIds"
|
|
|
|
+ @select-change="onselect"
|
|
|
|
+ >
|
|
|
|
+ </t-table>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </t-dialog>
|
|
|
|
+</template>
|
|
|
|
+
|
|
|
|
+<script lang="ts" setup>
|
|
|
|
+import { SearchIcon } from 'tdesign-icons-vue-next';
|
|
|
|
+import { onBeforeMount, ref, watch } from 'vue';
|
|
|
|
+import { getPenTree } from '@/services/common';
|
|
|
|
+import { penProps } from '@/services/defaults';
|
|
|
|
+import { MessagePlugin } from 'tdesign-vue-next';
|
|
|
|
+
|
|
|
|
+const props = defineProps<{
|
|
|
|
+ visible: boolean;
|
|
|
|
+ data: {
|
|
|
|
+ id: string;
|
|
|
|
+ idLabel: string;
|
|
|
|
+ keyLabel: string;
|
|
|
|
+ key: string;
|
|
|
|
+ value: any;
|
|
|
|
+ };
|
|
|
|
+}>();
|
|
|
|
+const emit = defineEmits(['update:visible', 'change']);
|
|
|
|
+const penTree = ref([]);
|
|
|
|
+const selectedData = ref({
|
|
|
|
+ id: '',
|
|
|
|
+ idLabel: '',
|
|
|
|
+ keyLabel: '',
|
|
|
|
+ key: '',
|
|
|
|
+ value: '',
|
|
|
|
+});
|
|
|
|
+
|
|
|
|
+watch(
|
|
|
|
+ () => props.visible,
|
|
|
|
+ () => {
|
|
|
|
+ if (props.visible) {
|
|
|
|
+ activedId.value = [props.data.id];
|
|
|
|
+ selectedIds.value = [props.data.key];
|
|
|
|
+ selectedData.value.id = props.data.id;
|
|
|
|
+ selectedData.value.idLabel = props.data.idLabel;
|
|
|
|
+ selectedData.value.keyLabel = props.data.keyLabel;
|
|
|
|
+ selectedData.value.key = props.data.key;
|
|
|
|
+ if (selectedData.value.id) {
|
|
|
|
+ getPropData();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+);
|
|
|
|
+
|
|
|
|
+onBeforeMount(() => {
|
|
|
|
+ penTree.value = getPenTree();
|
|
|
|
+});
|
|
|
|
+
|
|
|
|
+const search = ref('');
|
|
|
|
+const bindFilter = ref<any>(null);
|
|
|
|
+const onSearch = () => {
|
|
|
|
+ bindFilter.value = search.value
|
|
|
|
+ ? (node) => {
|
|
|
|
+ return (
|
|
|
|
+ node.value?.indexOf(search.value) >= 0 ||
|
|
|
|
+ node.data?.label.indexOf(search.value) >= 0
|
|
|
|
+ );
|
|
|
|
+ }
|
|
|
|
+ : null;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+const propSearch = ref('');
|
|
|
|
+const onPropSearch = () => {
|
|
|
|
+ propData.value = mergedArray.filter((item) => {
|
|
|
|
+ return (
|
|
|
|
+ item.label.indexOf(propSearch.value) >= 0 ||
|
|
|
|
+ item.value.indexOf(propSearch.value) >= 0
|
|
|
|
+ );
|
|
|
|
+ });
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+let mergedArray = [];
|
|
|
|
+
|
|
|
|
+const onClick = (e) => {
|
|
|
|
+ selectedData.value.id = activedId.value[0];
|
|
|
|
+ selectedData.value.idLabel = e.node.data.label;
|
|
|
|
+ getPropData();
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+const getPropData = () => {
|
|
|
|
+ let penP = [
|
|
|
|
+ {
|
|
|
|
+ value: 'text',
|
|
|
|
+ label: '文字',
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ value: 'visible',
|
|
|
|
+ label: '显示',
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ value: 'progress',
|
|
|
|
+ label: '进度',
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ value: 'showChild',
|
|
|
|
+ label: '状态',
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ value: 'checked',
|
|
|
|
+ label: '选中',
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ value: 'selectedKey',
|
|
|
|
+ label: '单选选中值',
|
|
|
|
+ },
|
|
|
|
+ ];
|
|
|
|
+ let target: any;
|
|
|
|
+ if (selectedData.value.id && selectedData.value.id !== '固定值') {
|
|
|
|
+ target = meta2d.findOne(selectedData.value.id);
|
|
|
|
+ } else {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ if (target?.realTimes) {
|
|
|
|
+ for (const item of target.realTimes) {
|
|
|
|
+ const found = penP.findIndex((elem: any) => elem.value === item.key);
|
|
|
|
+ if (found < 0) {
|
|
|
|
+ penP.push({
|
|
|
|
+ value: item.key,
|
|
|
|
+ label: item.label,
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ mergedArray = penP
|
|
|
|
+ .concat(penProps)
|
|
|
|
+ .filter(
|
|
|
|
+ (item, index, self) =>
|
|
|
|
+ index === self.findIndex((t) => t.value === item.value)
|
|
|
|
+ );
|
|
|
|
+ propData.value = mergedArray;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+const onselect = (value: string[], options: any) => {
|
|
|
|
+ selectedData.value.keyLabel = options.selectedRowData[0].label;
|
|
|
|
+ selectedData.value.key = options.selectedRowData[0].value;
|
|
|
|
+ selectedIds.value = value;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+function close() {
|
|
|
|
+ emit('update:visible', false);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+const confirm = () => {
|
|
|
|
+ props.data.id = selectedData.value.id;
|
|
|
|
+ props.data.idLabel = selectedData.value.idLabel;
|
|
|
|
+ props.data.keyLabel = selectedData.value.keyLabel;
|
|
|
|
+ props.data.key = selectedData.value.key;
|
|
|
|
+ close();
|
|
|
|
+ // emit('change', selectedData.value);
|
|
|
|
+};
|
|
|
|
+const propData = ref([]);
|
|
|
|
+
|
|
|
|
+const activedId = ref([]);
|
|
|
|
+
|
|
|
|
+const selectedIds = ref([]);
|
|
|
|
+
|
|
|
|
+const activedProp = ref([]);
|
|
|
|
+
|
|
|
|
+const columns = [
|
|
|
|
+ { colKey: 'row-select', type: 'single', width: 50 },
|
|
|
|
+ { colKey: 'label', title: '名称' },
|
|
|
|
+ { colKey: 'value', title: 'key名', width: 150 },
|
|
|
|
+ // { colKey: 'type', title: '类型' ,width:80},
|
|
|
|
+];
|
|
|
|
+</script>
|
|
|
|
+
|
|
|
|
+<style lang="postcss" scoped>
|
|
|
|
+.props-tree {
|
|
|
|
+ height: 300px;
|
|
|
|
+ overflow-y: auto;
|
|
|
|
+}
|
|
|
|
+.props {
|
|
|
|
+ height: 320px;
|
|
|
|
+ overflow-y: auto;
|
|
|
|
+ /* padding-bottom: 16px; */
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.input-search {
|
|
|
|
+ width: 100%;
|
|
|
|
+ padding: 4px 0px;
|
|
|
|
+
|
|
|
|
+ .btn {
|
|
|
|
+ left: 14px;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+:deep(.t-table) {
|
|
|
|
+ .t-table__header--fixed:not(.t-table__header--multiple) > tr > th {
|
|
|
|
+ background-color: #262d3a !important;
|
|
|
|
+ }
|
|
|
|
+ th {
|
|
|
|
+ border-bottom: 1px solid var(--color-background-input);
|
|
|
|
+ }
|
|
|
|
+ td {
|
|
|
|
+ border-bottom: 1px solid var(--color-background-input);
|
|
|
|
+ }
|
|
|
|
+ .t-table__empty-row {
|
|
|
|
+ td {
|
|
|
|
+ border-bottom: 0px;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+</style>
|