| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 |
- <template>
- <div>
- <div v-if="showSearch" class="search-container">
- <a-input-search
- v-model:value="searchValue"
- :placeholder="$t('system.views.dept.search.deptName')"
- />
- </div>
- <Spin :spinning="loading">
- <a-tree
- v-bind="getAttrs"
- :expanded-keys="expandedKeys"
- :auto-expand-parent="autoExpandParent"
- @expand="onExpand"
- :field-names="fieldNames"
- :tree-data="computedTreeData"
- >
- <template #title="{ deptName }">
- <span v-if="!showSearch">
- {{ deptName }}
- </span>
- <span v-else-if="deptName.indexOf(searchValue) > -1">
- {{ deptName.substr(0, deptName.indexOf(searchValue)) }}
- <span style="color: #f50">{{ searchValue }}</span>
- {{ deptName.substr(deptName.indexOf(searchValue) + searchValue.length) }}
- </span>
- <span v-else>{{ deptName }}</span>
- </template>
- </a-tree>
- </Spin>
- </div>
- </template>
- <script lang="ts">
- import { computed, defineComponent, onMounted, reactive, ref, toRefs, unref, watch } from 'vue';
- import { Spin } from 'ant-design-vue';
- import { errorMessage } from '@/utils/message/SystemNotice';
- import TreeUtils from '@/utils/TreeUtils';
- import { propTypes } from '@/utils/propTypes';
- import { ApiServiceEnum, defHttp } from '@/utils/http/axios';
- const getParentKey = (key: number, treeData: Array<any>): number => {
- let parentKey;
- for (let i = 0; i < treeData.length; i++) {
- const node = treeData[i];
- if (node.children) {
- if (node.children.some((item: any) => item.deptId === key)) {
- parentKey = node.deptId;
- } else {
- const secondParentKey = getParentKey(key, node.children);
- if (secondParentKey) {
- parentKey = secondParentKey;
- }
- }
- }
- }
- return parentKey;
- };
- export default defineComponent({
- name: 'SysDeptTree',
- components: { Spin },
- props: {
- // 是否支持搜索
- showSearch: propTypes.bool.def(true),
- // 是否异步加载
- async: propTypes.bool,
- },
- setup(props, { attrs }) {
- const { async: asyncRef } = toRefs(props);
- const searchValue = ref<string>('');
- const dataList = ref<Array<any>>([]);
- const autoExpandParent = ref(false);
- const expandedKeys = ref<Array<number>>([]);
- const loading = ref(false);
- const getAttrs = computed(() => {
- const result: any = {
- ...attrs,
- };
- if (unref(asyncRef)) {
- result.loadData = handleAsyncLoadData;
- }
- return result;
- });
- /**
- * 树形数据计算属性
- */
- const computedTreeData = computed(() => {
- const async = unref(asyncRef);
- if (async) {
- return unref(dataList);
- }
- return (
- TreeUtils.convertList2Tree(
- dataList.value,
- (item) => item.deptId,
- (item) => item.parentId,
- 0,
- ) || []
- );
- });
- const onExpand = (keys: Array<number>) => {
- expandedKeys.value = keys;
- autoExpandParent.value = false;
- };
- /**
- * 所有数据
- */
- const getAllDataList = computed(() => {
- const result: any[] = [];
- if (unref(asyncRef)) {
- recursionAddChildren(unref(dataList), result);
- } else {
- result.push(...unref(dataList));
- }
- return result;
- });
- const recursionAddChildren = (list: any[], allData: any[]) => {
- list.forEach((item) => {
- allData.push(item);
- if (item.children && item.children.length > 0) {
- recursionAddChildren(item.children, allData);
- }
- });
- };
- watch(searchValue, (value) => {
- const allData = unref(getAllDataList);
- expandedKeys.value = allData
- .map(({ deptName, deptId }: any) => {
- if (deptName.indexOf(value) > -1) {
- return getParentKey(deptId, computedTreeData.value);
- }
- return null;
- })
- .filter((item, i, self) => item && self.indexOf(item) === i) as Array<number>;
- autoExpandParent.value = true;
- });
- const handleAsyncLoadData = async (treeNode) => {
- const dataRef = treeNode.dataRef;
- dataRef.children = await loadData(dataRef.deptId);
- dataList.value = [...unref(dataList)];
- };
- const reload = () => loadData();
- /**
- * 加载数据函数
- */
- const loadData = async (parentId?: number | null) => {
- const parameter: Recordable = {
- sortName: 'seq',
- sortOrder: 'asc',
- };
- if (parentId !== undefined && parentId !== null) {
- parameter.parameter = {
- 'parentId@=': parentId,
- };
- }
- try {
- loading.value = true;
- const result = (await defHttp.post({
- service: ApiServiceEnum.SMART_SYSTEM,
- url: 'sys/dept/list',
- data: parameter,
- })) as any[];
- result.forEach((item) => {
- if (item.hasChild !== true) {
- item.isLeaf = true;
- }
- });
- if (unref(asyncRef)) {
- if (parentId === 0) {
- dataList.value = result;
- } else {
- return result;
- }
- } else {
- dataList.value = result;
- }
- } catch (e) {
- errorMessage(e);
- } finally {
- loading.value = false;
- }
- };
- /**
- * 加载数据
- */
- onMounted(() => {
- let parentId: number | undefined = undefined;
- if (unref(asyncRef)) {
- parentId = 0;
- }
- loadData(parentId);
- });
- return {
- computedTreeData,
- autoExpandParent,
- onExpand,
- loadData,
- loading,
- expandedKeys,
- fieldNames: reactive({
- children: 'children',
- title: 'deptName',
- key: 'deptId',
- }),
- getAttrs,
- handleAsyncLoadData,
- searchValue,
- reload,
- };
- },
- });
- </script>
- <style scoped lang="less">
- .search-container {
- margin-bottom: 10px;
- }
- </style>
|