Files
SaaS-lib/lib/component/tree/tree-api.vue

198 lines
5.2 KiB
Vue
Raw Normal View History

2024-05-15 17:29:42 +08:00
<template>
2024-07-01 15:03:45 +08:00
<a-spin :spinning="treeState.loading">
2024-07-19 10:36:05 +08:00
<div class="ns-tree-container">
<div class="ns-tree-form">
<div v-if="header" class="ns-tree-title">
2024-07-22 18:11:03 +08:00
<!-- <ns-icon :name="header.icon" size="14" /> -->
<span class="ns-title-extra-box">{{ header.title }}</span>
2024-07-19 10:36:05 +08:00
</div>
<div v-if="!formConfig?.schema">
<ns-form ref="formElRef" v-bind="formConfig" :model="formModel" @finish="formFinish" />
</div>
2024-07-04 11:19:38 +08:00
</div>
2024-07-19 10:36:05 +08:00
<div style="min-height: 150px">
<ns-tree v-if="treeData?.length" v-bind="getBindValue" :selectedKeys="selectedKeys">
2024-07-19 10:36:05 +08:00
<template #[item]="data" v-for="(item, index) in Object.keys($slots)" :key="index">
<slot :name="item" v-bind="{ ...data, formModel } || {}"></slot>
</template>
</ns-tree>
<!-- <a-empty v-if="!treeData?.length" /> -->
</div>
2024-06-25 14:52:13 +08:00
</div>
2024-05-30 14:16:42 +08:00
</a-spin>
2024-05-15 17:29:42 +08:00
</template>
2024-05-28 10:51:13 +08:00
<script lang="ts" setup>
2024-07-05 17:26:31 +08:00
import { computed, nextTick, reactive, ref, unref, useAttrs, watch } from 'vue';
2024-05-15 17:29:42 +08:00
import { TreeDataItem } from 'ant-design-vue/es/tree/Tree';
2024-05-28 10:51:13 +08:00
import { useApi } from '/nerv-lib/use/use-api';
import { AxiosRequestConfig } from 'axios';
import { get, isEmpty } from 'lodash-es';
2024-05-28 10:51:13 +08:00
import { useRoute } from 'vue-router';
2024-06-25 14:52:13 +08:00
import { debounce } from 'lodash-es';
2024-05-30 14:16:42 +08:00
import { treeProps, treeFormProps } from '/nerv-lib/component/tree/props';
2024-07-01 15:03:45 +08:00
2024-05-28 10:51:13 +08:00
defineOptions({
2024-05-15 17:29:42 +08:00
name: 'NsTreeApi',
2024-05-28 10:51:13 +08:00
});
2024-08-23 15:53:13 +08:00
const emit = defineEmits(['update:treeData', 'select', 'reload']);
2024-07-05 17:26:31 +08:00
// const model = defineModel('treeData');
2024-06-27 15:21:14 +08:00
2024-07-01 15:03:45 +08:00
const formElRef = ref();
const props = defineProps(treeProps);
2024-07-05 17:26:31 +08:00
const treeData = ref(props.treeData);
2024-06-26 16:57:42 +08:00
const selectedKeys = ref(props.selectedKeys || []);
2024-05-28 10:51:13 +08:00
const { httpRequest } = useApi();
const requestConfig: AxiosRequestConfig = { method: 'get' };
const route = useRoute();
const attrs = useAttrs();
2024-05-30 14:16:42 +08:00
const formModel = reactive({});
2024-07-05 17:26:31 +08:00
watch(
() => props.treeData,
(val) => {
treeData.value = val;
},
{
deep: true,
},
);
2024-05-30 14:16:42 +08:00
const treeState = reactive({
2024-06-25 14:52:13 +08:00
loading: false,
2024-05-30 14:16:42 +08:00
});
const formConfig = computed(() => {
return {
...treeFormProps,
...props.formConfig,
};
});
2024-06-28 16:46:07 +08:00
const isSticky: any = computed(() => {
return props.isSticky ? 'sticky' : 'static';
});
2024-06-25 14:52:13 +08:00
const formFinish = debounce((data: object) => {
2024-07-26 13:56:39 +08:00
// selectedKeys.value = [];
2024-06-25 14:52:13 +08:00
getData(data);
2024-08-23 15:53:13 +08:00
// formConfig.value.schemas.forEach((item: any) => {
// if (item.callList) {
// emit('reload');
// }
// });
//只刷新列表
if (formConfig.value.callList && !formConfig.value.defaultSelection) {
emit('reload');
}
2024-06-25 14:52:13 +08:00
}, 200);
const handleSelect = (keys: any, selectedRows: any) => {
if (props.cancelable || !isEmpty(keys)) {
selectedKeys.value = keys;
// props.onSelect && props.onSelect(keys, selectedRows);
emit('select', keys, selectedRows);
}
};
2024-05-28 10:51:13 +08:00
const getBindValue = computed(() => ({
...attrs,
...props,
treeData: treeData.value,
onSelect: handleSelect,
2024-05-28 10:51:13 +08:00
}));
2024-05-30 14:16:42 +08:00
const setLoading = (loading: boolean) => {
treeState.loading = loading;
};
const httpPrams = computed(() => {
2024-07-09 18:04:09 +08:00
return { ...route.params, ...route.query, ...props.params, ...formModel };
2024-05-30 14:16:42 +08:00
});
2024-05-15 17:29:42 +08:00
2024-06-25 14:52:13 +08:00
const getData = (params = {}) => {
2024-05-30 14:16:42 +08:00
const { api, transform, resultField } = props;
2024-05-28 10:51:13 +08:00
treeData.value = [];
if (!api) return;
2024-05-30 14:16:42 +08:00
setLoading(true);
2024-05-28 10:51:13 +08:00
httpRequest({
api,
2024-06-25 14:52:13 +08:00
params: { ...httpPrams.value, ...params },
pathParams: { ...route.params, ...route.query, ...params },
requestConfig: { ...requestConfig, data: { ...httpPrams.value, ...params } },
2024-05-30 14:16:42 +08:00
})
.then((res) => {
treeData.value = transform(get(res, resultField));
2024-08-23 15:53:13 +08:00
//默认选择第一个 并刷新列表
selectedKeys.value = [];
if (formConfig.value.callList && formConfig.value.defaultSelection) {
handleSelect([treeData.value[0].id], {
selected: true,
event: 'select',
selectedNodes: treeData.value,
node: {
...treeData.value[0],
dataRef: { ...treeData.value[0] },
},
});
// 默认选择第一个
}
2024-07-05 17:26:31 +08:00
emit('update:treeData', treeData.value);
// model.value = treeData.value;
2024-05-30 14:16:42 +08:00
})
.finally(() => {
setLoading(false);
});
2024-05-28 10:51:13 +08:00
};
getData();
2024-07-09 16:27:21 +08:00
const treeReload = (params) => {
getData(params);
};
2024-07-09 18:04:09 +08:00
const clearSelectedKeys = () => {
selectedKeys.value = [];
};
defineExpose({ treeReload, clearSelectedKeys });
2024-05-15 17:29:42 +08:00
</script>
2024-06-25 14:52:13 +08:00
<style lang="less" scoped>
2024-06-28 16:46:07 +08:00
@gap: 16px;
2024-06-25 14:52:13 +08:00
:deep(.ant-form-item) {
2024-06-28 16:46:07 +08:00
margin-bottom: @gap;
2024-06-25 14:52:13 +08:00
}
:deep(.ns-form::after) {
display: none;
}
2024-06-28 16:46:07 +08:00
.ns-tree-form {
position: v-bind(isSticky);
top: 0;
background-color: @white;
z-index: 2;
& ~ div {
padding: 0 @gap !important;
}
}
2024-06-25 14:52:13 +08:00
.ns-tree-title {
font-weight: bold;
user-select: text;
2024-06-28 16:46:07 +08:00
padding: @gap;
2024-07-17 15:07:23 +08:00
// margin-bottom: @gap;
// padding-bottom: 10px;
// border-bottom: 1px solid #e9e9e9;
2024-06-28 16:46:07 +08:00
2024-07-22 18:11:03 +08:00
// > span {
// padding-left: 6px;
// }
2024-06-25 14:52:13 +08:00
& ~ div {
2024-06-28 16:46:07 +08:00
padding: 0 @gap !important;
2024-07-01 15:03:45 +08:00
width: 100%;
2024-06-25 14:52:13 +08:00
}
}
2024-07-19 10:36:05 +08:00
.ns-tree-container {
display: flex;
flex-direction: column;
&:last-child {
flex: 1;
}
}
2024-06-25 14:52:13 +08:00
</style>