<!--
|
苏州金庭单用
|
左侧【选择框-列表树】或【列表树】,右边表格内容
|
只针对左侧树含泵站的情况
|
右侧内容,需要 defineExpose 的方法:getTableData
|
|
V2版本说明:
|
(1)泵站上层增加了 area 结构
|
(2)LogicalType 改为 LogicType
|
-->
|
<template>
|
<AMContainer>
|
<template #aside>
|
<el-card shadow="hover" class="h100 left-tree-card" v-loading="treeLoading">
|
<LeftTreeByMgr
|
ref="leftTreeRef"
|
:treedata="listTreeData"
|
:title-name="`${list.label}列表`"
|
:current-node-key="currentListID"
|
:defaultProps="list.treeProps"
|
:selectIsShow="type === 'select-list'"
|
:selectData="selectTreeData"
|
:defaultSelectValue="currentSelectID"
|
:selectProps="select?.treeProps"
|
:folderIcon="(_, data) => folderIconFun(_, data)"
|
:showNodeIcon="showNodeIcon"
|
:expandOnClickNode="expandOnClickNode"
|
:showMoreOperate="showMoreOperate"
|
:showAdd="showAdd"
|
:customDropdown="customDropdown"
|
:defaultExpandAll="defaultExpandAll"
|
:showSelectNodeIcon="showSelectNodeIcon"
|
:selectNodeIcon="selectNodeIcon"
|
:selectFolderIcon="selectFolderIcon"
|
@click="handleClickNode"
|
@selectchange="selectNodeChange"
|
@treeEdit="treeEdit"
|
@treeDelete="treeDelete"
|
@treeAdd="treeAdd"
|
>
|
<template #customDropdown="{ data, node }">
|
<slot name="customDropdown" :data="data" :node="node" v-if="customDropdown"> </slot>
|
</template>
|
</LeftTreeByMgr>
|
</el-card>
|
</template>
|
<template #main>
|
<slot name="main" :listNode="currentListNode" :selectNode="currentSelectNode"> </slot>
|
</template>
|
</AMContainer>
|
</template>
|
|
<script setup lang="ts">
|
import { ElMessage } from 'element-plus';
|
import { ref, computed, PropType, onMounted, nextTick, provide } from 'vue';
|
import AMContainer from '/@/components/layout/AMContainer.vue';
|
import LeftTreeByMgr from '/@/components/tree/leftTreeByMgr.vue';
|
import { getDefaultLogicPolicyStd } from '/@/api/szjt/logicPolicyStd';
|
import { convertListToTree } from '/@/utils/util';
|
import { getSite } from '/@/projectCom/components/manage/utils';
|
|
const props = defineProps({
|
type: {
|
type: String as PropType<'list' | 'select-list'>,
|
required: true,
|
},
|
/** @description 默认选择的泵站ID */
|
defaultSelectID: {
|
type: String,
|
},
|
|
list: {
|
type: Object as PropType<{
|
requestApi: Function;
|
label: string;
|
treeProps?: {
|
id: string;
|
label: string;
|
children: string;
|
};
|
isFlatTree?: Boolean;
|
code?: string;
|
}>,
|
|
required: true,
|
},
|
folderIcon: {
|
type: Function as PropType<(node, data) => Boolean>,
|
default: null,
|
},
|
/**
|
* 节点是否带 icon
|
*/
|
showNodeIcon: {
|
type: Boolean,
|
default: true,
|
},
|
select: {
|
type: Object as PropType<{
|
requestApi: Function;
|
label: string;
|
treeProps?: {
|
id: string;
|
label: string;
|
children: string;
|
};
|
code?: string;
|
}>,
|
},
|
req: {
|
type: Function,
|
required: true,
|
},
|
contentRef: {
|
type: Object,
|
},
|
expandOnClickNode: {
|
type: Boolean,
|
default: true,
|
},
|
/**是否显示右侧更多操作图标,默认为编辑和删除 */
|
showMoreOperate: {
|
type: [Boolean, Function],
|
default: false,
|
},
|
/**需要先开启 showMoreOperate,自定义一个在更多操作中的dropwDownMenu,自己加入操作 */
|
customDropdown: {
|
type: Boolean,
|
default: false,
|
},
|
/**树是否存在添加数据操作 */
|
showAdd: {
|
type: Boolean,
|
default: false,
|
},
|
/**是否默认展开全部 */
|
defaultExpandAll: {
|
type: Boolean,
|
default: false,
|
},
|
/**
|
* 是否展示选择节点图标
|
*/
|
showSelectNodeIcon: {
|
type: Boolean,
|
default: true,
|
},
|
/**
|
* 选择自定义节点 icon
|
*/
|
selectNodeIcon: {
|
type: Function as PropType<(node, data) => String>,
|
default: null,
|
},
|
/**
|
* 选择节点文件夹图标显示自定义
|
*/
|
selectFolderIcon: {
|
type: Function as PropType<(node, data) => Boolean>,
|
default: null,
|
},
|
});
|
|
const emits = defineEmits<{
|
(event: 'selectChange', data): void;
|
(event: 'listClick', data): void;
|
(event: 'treeEdit', node, data): void;
|
(event: 'treeDelete', node, data): void;
|
(event: 'treeAdd'): void;
|
}>();
|
|
const treeAdd = () => {
|
emits('treeAdd');
|
};
|
const treeEdit = (data, node) => {
|
emits('treeEdit', data, node);
|
};
|
const treeDelete = (data, node) => {
|
emits('treeDelete', data, node);
|
};
|
|
const folderIconFun = (_, data) => {
|
if (props.folderIcon) {
|
return props.folderIcon(_, data);
|
} else {
|
if (props.type === 'list') {
|
return data.LogicType !== siteLogicType.value;
|
}
|
}
|
};
|
|
/**
|
* 根据层级清空对应内容
|
* @param type
|
*/
|
const resetContent = (type: 'top' | 'select' | 'list' | 'table') => {
|
props.contentRef?.clearTableData();
|
if (type !== 'table') {
|
listTreeData.value = [];
|
currentListNode.value = null;
|
if (type !== 'list') {
|
currentSelectNode.value = null;
|
if (type !== 'select') {
|
selectTreeData.value = [];
|
}
|
}
|
}
|
};
|
|
//#region ====================== 左侧树数据,tree init ======================
|
const treeLoading = ref(false);
|
const leftTreeRef = ref<InstanceType<typeof LeftTreeByMgr>>(null);
|
|
const selectTreeData = ref([]);
|
const currentSelectNode = ref(null);
|
const currentSelectID = computed(() => {
|
return currentSelectNode.value?.[selectIDKey.value];
|
});
|
|
const selectNodeChange = (data) => {
|
currentSelectNode.value = data;
|
// 未选中泵站
|
if (data?.LogicType !== props.select.code) {
|
resetContent('list');
|
return;
|
}
|
getListTreeData();
|
emits('selectChange', data);
|
};
|
|
const getSelectTreeData = async (...extraParams) => {
|
treeLoading.value = true;
|
const params = [...extraParams, props.req];
|
const res = await props.select.requestApi(...params).finally(() => {
|
treeLoading.value = false;
|
});
|
if (res?.Code === 0) {
|
const resData = (res.Data || []) as [];
|
selectTreeData.value = resData;
|
let firstSelectTreeNode = null;
|
if (props.type === 'select-list') {
|
firstSelectTreeNode = getSite(
|
resData,
|
{
|
key: 'LogicType',
|
value: siteLogicType.value,
|
},
|
{
|
key: 'LogicID',
|
value: props.defaultSelectID,
|
}
|
);
|
} else {
|
firstSelectTreeNode = selectTreeData.value[0];
|
}
|
if (firstSelectTreeNode) {
|
selectNodeChange(firstSelectTreeNode);
|
} else {
|
resetContent('select');
|
}
|
} else {
|
ElMessage.error(`获取${props.select.label}列表失败` + (res?.Message ? `,${JSON.stringify(res.Message)}` : ''));
|
}
|
};
|
|
const listTreeData = ref([]);
|
const currentListNode = ref(null);
|
const listIDKey = computed(() => {
|
return props.list?.treeProps?.id || 'ID';
|
});
|
const selectIDKey = computed(() => {
|
return props.select?.treeProps?.id || 'ID';
|
});
|
const currentListID = computed(() => {
|
return currentListNode.value?.[listIDKey.value];
|
});
|
const siteLogicType = computed(() => {
|
if (props.type === 'select-list') {
|
return props.select?.code;
|
} else {
|
return props.list?.code;
|
}
|
});
|
const handleClickNode = (data) => {
|
currentListNode.value = data;
|
if (props.type === 'list') {
|
// 未选中泵站
|
if (data?.LogicType !== siteLogicType.value) {
|
resetContent('table');
|
return;
|
}
|
}
|
nextTick(() => {
|
leftTreeRef.value?.treeRef.setCurrentKey(data[listIDKey.value]);
|
});
|
emits('listClick', data);
|
};
|
const getListTreeData = async (...extraParams) => {
|
treeLoading.value = true;
|
const params =
|
props.type === 'select-list'
|
? [
|
{
|
BelongType: props.select.code,
|
BelongID: currentSelectID.value,
|
},
|
props.req,
|
]
|
: [...extraParams, props.req];
|
const res = await props.list.requestApi(...params).finally(() => {
|
treeLoading.value = false;
|
});
|
if (res?.Code === 0) {
|
const resData = (res.Data || []) as [];
|
if (props.list.isFlatTree) {
|
listTreeData.value = convertListToTree(resData, {
|
ID: props.list?.treeProps?.id || 'ID',
|
Children: props.list?.treeProps?.children || 'Children',
|
ParentID: 'ParentID',
|
});
|
} else {
|
listTreeData.value = resData;
|
}
|
let firstListTreeNode = null;
|
if (props.type === 'list') {
|
firstListTreeNode = getSite(
|
resData,
|
{
|
key: 'LogicType',
|
value: siteLogicType.value,
|
},
|
{
|
key: 'LogicID',
|
value: props.defaultSelectID,
|
}
|
);
|
} else {
|
firstListTreeNode = listTreeData.value[0];
|
}
|
|
if (firstListTreeNode) {
|
handleClickNode(firstListTreeNode);
|
} else {
|
resetContent('list');
|
}
|
} else {
|
ElMessage.error(`获取${props.list.label}列表失败` + (res?.Message ? `,${JSON.stringify(res.Message)}` : ''));
|
}
|
};
|
//#endregion
|
//#region ====================== 往下层组件注入 ======================
|
provide('treeListData', listTreeData);
|
provide('treeSelectData', selectTreeData);
|
//#endregion
|
|
onMounted(() => {
|
getDefaultLogicPolicyStd(props.req).then((data) => {
|
if (typeof data !== 'undefined') {
|
if (props.type === 'list') {
|
getListTreeData({
|
PolicyID: data.ID,
|
});
|
} else if (props.type === 'select-list') {
|
getSelectTreeData({
|
PolicyID: data.ID,
|
});
|
}
|
} else {
|
resetContent('top');
|
}
|
});
|
});
|
</script>
|
<style scoped lang="scss"></style>
|