<template>
    <div class="m-menuManagement">
        <DragLayout>
            <template v-slot:left>
                <div class="g-treeBox">
                    <div class="tree-top">
                        <span class="u-title">{{ $t(config.topTitle) }}</span>
                        <i class="el-icon-plus" v-show="!leftTreeConfig.filterText && config.showTopAdd" @click="addClickDirectory"></i>
                    </div>
                    <el-input
                        v-if="config.showSearch"
                        prefix-icon="el-icon-search"
                        :placeholder="$t('cs.common.verification.verifyRequired', { verifyName: $t('cs.common.text.keyword') })"
                        size="small"
                        v-model="leftTreeConfig.filterText"
                        style="margin: auto; margin-bottom: 12px; width: calc(100% - 32px)"
                    ></el-input>
                    <!-- 默认左侧树 -->
                    <el-tree
                        :ref="leftTreeConfig.treeRef"
                        :default-expanded-keys="leftTreeConfig.defaultExpandedKeys"
                        :empty-text="leftTreeConfig.emptyText"
                        node-key="directoryId"
                        :default-expand-all="leftTreeConfig.defaultExpandAll"
                        :highlight-current="true"
                        :expand-on-click-node="false"
                        :data="leftTreeConfig.treeData"
                        :load="loadNode"
                        :lazy="leftTreeConfig.lazy"
                        v-if="!leftTreeConfig.searchTreeShow"
                        :props="config.props"
                        @node-click="treeClick"
                        :draggable="true"
                        @node-drop="nodeDrop"
                        :allow-drop="allowDrop"
                        :allow-drag="allowDrag"
                        @node-drag-over="nodeDragOver"
                        style="overflow-y: auto; flex: 1"
                        :class="[oneHaveChildren ? 'g-oneHaveChildren' : 'g-oneNoHaveChildren']"
                    >
                        <div class="g-treeSlot tree-slot" slot-scope="{ data }" :title="data.directoryName">
                            <div class="g-treeSlot-content">
                                <div class="g-left">
                                    <i v-if="data.directoryType == 1" :class="[config.iconList[0]]"></i>
                                    <!-- <img v-if="data.directoryType == 1" :src="config.iconList[0]" alt=""> -->
                                    <i v-else class="el-icon-folder"></i>
                                    <span>{{ data.directoryName }}</span>
                                </div>
                                <i
                                    v-if="
                                        !leftTreeConfig.searchTreeShow &&
                                        config.dropdown.length == 1 &&
                                        data.directoryId &&
                                        data.directoryId != 'null'
                                    "
                                    :class="[config.dropdown[0].icon, 'g-right']"
                                    @click="deleteSystemFn($event, data)"
                                    @click.stop
                                ></i>
                                <div class="g-dropdown" v-if="!leftTreeConfig.searchTreeShow && config.dropdown.length > 1" @click.stop>
                                    <el-dropdown
                                        trigger="click"
                                        @command="menuClick"
                                        placement="bottom"
                                        class="el-dropdown"
                                        v-if="data.directoryId && data.directoryId != 'null'"
                                        v-show="!leftTreeConfig.filterText"
                                    >
                                        <span class="el-dropdown-link">
                                            <i class="el-icon-more"></i>
                                        </span>
                                        <el-dropdown-menu slot="dropdown">
                                            <el-dropdown-item
                                                v-for="(item, index) in treeMenuList(data,config.dropdown)"
                                                :key="index"
                                                :command="{ data: data, type: item.type }"
                                            >
                                                {{ $t(item.label) }}
                                            </el-dropdown-item>
                                        </el-dropdown-menu>
                                    </el-dropdown>
                                </div>
                            </div>
                        </div>
                    </el-tree>
                </div>
            </template>
            <template v-slot:right>
                <div class="g-container" v-if="leftTreeConfig.current && rightFormConfig.showRight">
                    <slot name="form" :slotProps="leftTreeConfig.current"></slot>
                </div>
                <EmptyPage v-if="rightFormConfig.isShowEmptyPage" />
            </template>
        </DragLayout>
    </div>
</template>

<script scoped>
import EmptyPage from "../../BusinessCommon/Components/EmptyPage.vue";
import CoreAPI from "../../Common/JS/CoreAPI.js";

export default {
    name: "Menu",
    props: {
        config: {
            type: Object,
            default() {
                return {
                    activeName: "",
                    treeData: [],
                    showSearch: true,
                    topTitle: "--",
                    showTopAdd: true
                };
            }
        },
        mode: {
            type: String,
            default: "dev"
        }
    },
    components: { EmptyPage },
    data() {
        return {
            oneHaveChildren: false,
            leftTreeConfig: {
                //首页左侧树相关配置属性
                treeData: [],
                filterText: "", // 左侧树输入框值
                lazy: true,
                searchTreeShow: false,
                defaultExpandAll: false,
                defaultExpandedKeys: [""],
                treeRef: "tree",
                searchTreeKey: [],
                searchInitTree: [],
                searchInitPid: "",
                emptyText: this.$t("cs.common.text.noData"),
                current: null,
                node: null,
                searchFnc: null,
                isTreeClick: false
            },
            rightFormConfig: {
                showRight: false,
                isShowEmptyPage: true
            }
        };
    },
    methods: {
        /*----------  树相关  ----------*/

        // 拖拽
        nodeDrop(node, dropNode, location, event) {
            CloudServiceCommon.Log.debug(event);
            // node  拖拽的节点
            // dropNode  目标节点
            // location 位置
            const _this = this;
            if (location == "inner") _this.leftTreeConfig.node = _this.$refs[_this.leftTreeConfig.treeRef].getNode(dropNode.data.directoryId);
            else _this.leftTreeConfig.node = _this.$refs[_this.leftTreeConfig.treeRef].getNode(dropNode.data.parentDirectoryId || "null");
            let postData = CloudServiceCommon.Methods.getTreeDragPostData(node, dropNode, location);
            if (_this.leftTreeConfig.node) _this.leftTreeConfig.node.data.children = null;
            _this.config.dragDirectory(postData).then(
                res => {
                    CloudServiceCommon.Log.debug(res);
                    if (_this.leftTreeConfig.node) {
                        _this.leftTreeConfig.node.loaded = false;
                        _this.leftTreeConfig.node.expand();
                    } else {
                        _this.leftTreeConfig.treeData = [];
                        _this.RefreshTree(_this.leftTreeConfig.current, true);
                    }
                },
                rej => {
                    _this.$message({
                        type: "error",
                        message: rej.msg
                    });
                    _this.RefreshTree(_this.leftTreeConfig.current, true);
                }
            );
        },
        allowDrop(draggingNode, dropNode, type) {
            // 如果目标节点是根目录 不允许
            if (this.config.isSys) {
                if (dropNode.data.directoryId == "null") return false;
                if (!dropNode.data.parentDirectoryId && type == "inner") return false;
            }
            if(this.mode && this.mode == "runTime"){
                if (type == "inner") return false;
                if(dropNode.data.parentDirectoryId != draggingNode.data.parentDirectoryId) return false;
            }
            return true;
        },
        allowDrag(node) {
            return true;
        },
        nodeDragOver() {
            CloudServiceCommon.Log.debug("--");
        },
        //获取菜单树
        getMenuTreeData(filterText) {
            let _this = this;
            _this.leftTreeConfig.searchFnc = setTimeout(function () {
                _this.config.getMenuTreeData(filterText).then(res => {
                    let treeData = [];
                    _this.leftTreeConfig.emptyText = _this.$t("cs.common.text.noResult");
                    _this.oneHaveChildrenFn(res);
                    if (res.length == 0) {
                        treeData = [];
                    } else {
                        treeData = [];
                        res.forEach(ele => {
                            treeData.push(ele);
                        });
                    }
                    if (treeData.length == 0) {
                        _this.leftTreeConfig.treeData = [];
                    } else {
                        _this.leftTreeConfig.treeData = CloudServiceCommon.Methods.deepCopy(treeData);
                    }

                    setTimeout(() => {
                        _this.resultTreeSearchTreeShow(false);
                    });
                });
            }, 500);
        },
        // 外面添加目录加号点击
        addClickDirectory() {
            this.$emit("addClickDirectory");
        },

        treeClick(data) {
            if (data.directoryType == 0) {
                this.$refs[this.leftTreeConfig.treeRef].setCurrentKey(this.leftTreeConfig.current ? this.leftTreeConfig.current.directoryId : null);
                return;
            }
            if (this.leftTreeConfig.current && data.directoryId == this.leftTreeConfig.current.directoryId) return;
            this.$emit("treeClick", data);
            this.leftTreeConfig.isTreeClick = true;
            this.redirectMenu(data);
        },

        //重新定位到某个菜单
        redirectMenu(current) {
            if (!current) return;
            let itmer = setTimeout(() => {
                this.$refs[this.leftTreeConfig.treeRef].setCurrentKey(current.directoryId);
                this.rightFormConfig.showRight = false;
                if (!this.leftTreeConfig.current || this.leftTreeConfig.current.directoryId != current.directoryId) {
                    this.leftTreeConfig.current = current;
                }
                this.$nextTick(() => {
                    this.rightFormConfig.showRight = true;
                    this.rightFormConfig.isShowEmptyPage = false;
                    clearTimeout(itmer);
                });
            }, 0);
        },
        // 重置树的状态配置,一般用于懒加载与全加载状态切换
        resultTreeSearchTreeShow(lazy) {
            let _this = this;
            let treeConfig = _this.leftTreeConfig;
            treeConfig.searchTreeShow = true;
            _this.leftTreeConfig.isTreeClick = !lazy;
            _this.$nextTick(() => {
                treeConfig.lazy = lazy;
                treeConfig.defaultExpandAll = !lazy;
                treeConfig.searchTreeShow = false;
                if (!lazy && treeConfig.current) {
                    setTimeout(() => {
                        // 保持选中
                        _this.$refs[_this.leftTreeConfig.treeRef].setCurrentKey(
                            _this.leftTreeConfig.current.directoryId ? _this.leftTreeConfig.current.directoryId : null
                        );
                    });
                }
            });
        },
        //懒加载
        loadNode(node, resolve) {
            const _this = this;
            this.config.loadNode(node).then(res => {
                _this.leftTreeConfig.emptyText = _this.$t("cs.common.text.noData");
                if (
                    (_this.leftTreeConfig.current && _this.leftTreeConfig.current.parentId == node.data.directoryId) ||
                    !_this.leftTreeConfig.isTreeClick
                ) {
                    _this.redirectMenu(_this.leftTreeConfig.current);
                }
                if (node.level == 0) {
                    this.oneHaveChildrenFn(res);
                }
                if (node.level == 1 && (!res || res.length == 0)) {
                    resolve([]);
                }
                resolve(res);
            });
            resolve([]);
        },

        //重置到无表单状态
        resetRightStatus() {
            this.$refs[this.leftTreeConfig.treeRef].setCurrentKey(null);
            this.leftTreeConfig.current = null;
            this.rightFormConfig.showRight = false;
            this.rightFormConfig.isShowEmptyPage = true;
        },

        //递归获取当前节点下的子节点是否包含
        getNodeHaveCurr(childNodes, curDirectoryId) {
            let have = false;
            function nodeHaveCurr(child) {
                for (let i = 0; i < child.length; i++) {
                    const element = child[i];
                    if (element.data.directoryId === curDirectoryId) {
                        have = true;
                    }
                    if (element.childNodes && element.childNodes.length > 0) {
                        nodeHaveCurr(element.childNodes, curDirectoryId);
                    }
                }
            }
            nodeHaveCurr(childNodes);
            return have;
        },
        //删除菜单
        delTree(data) {
            if (this.leftTreeConfig.current){
                if (this.leftTreeConfig.current.directoryId == data.directoryId) {
                    this.resetRightStatus();
                } else {
                    let node = this.$refs[this.leftTreeConfig.treeRef].getNode(data.directoryId);
                    if (node && node.childNodes && node.childNodes.length > 0) {
                        if (this.getNodeHaveCurr(node.childNodes, this.leftTreeConfig.current.directoryId)) {
                            this.resetRightStatus();
                        }
                    }
                }
            }
            this.$refs[this.leftTreeConfig.treeRef].remove(data.directoryId);
            this.$message.success(this.$t("cs.common.message.deleteSuccessConfirmation"));
        },
        // 右键菜单点击
        menuClick(item) {
            this.$emit("menuClick", item);
        },
        deleteSystemFn(e, data) {
            this.$emit("menuClick", { type: "deleteDirectory", data });
        },
        //遍历树
        forTree(list, parentId) {
            for (let i = 0; i < list.length; i++) {
                let item = list[i];
                if (parentId == item.id) {
                    this.leftTreeConfig.searchInitPid = item.parentId;
                    return;
                }
                if (item.children?.length > 0) {
                    this.forTree(item.children, parentId);
                }
            }
        },
        // 搜索树展开节点
        getSerachTreeKey(parentId) {
            const _this = this;
            if (!parentId) return;

            _this.leftTreeConfig.searchTreeKey.unshift(parentId);
            _this.leftTreeConfig.searchInitPid = "";
            _this.forTree(_this.leftTreeConfig.searchInitTree, parentId);
            if (_this.leftTreeConfig.searchInitPid) {
                _this.getSerachTreeKey(_this.leftTreeConfig.searchInitPid);
            }
        },
        //获取最新的展开父级集合
        getNewExtendList() {
            return new Promise((resolve, reject) => {
                this.config
                    .getMenuTreeData("")
                    .then(res => {
                        this.leftTreeConfig.searchInitTree = res;
                        this.getSerachTreeKey(this.leftTreeConfig.current.parentId);
                        resolve();
                    })
                    .catch(err => {
                        CloudServiceCommon.Log.debug(err);
                        reject();
                    });
            });
        },
        //重新刷新树
        //默认根据当前节点对应的内容刷新父级的目录
        RefreshTree(res, type) {
            this.leftTreeConfig.current = res;
            this.leftTreeConfig.isTreeClick = false;
            //如果没有父目录则刷新全部树
            if (type) {
                this.resultTreeSearchTreeShow(true);
                return;
            }
            this.leftTreeConfig.node = this.$refs[this.leftTreeConfig.treeRef].getNode(res.parentId ? res.parentId : "");
            if (this.leftTreeConfig.node && this.leftTreeConfig.node.expand) {
                this.leftTreeConfig.node.loaded = false;
                this.leftTreeConfig.node.expand();
            } else {
                this.resultTreeSearchTreeShow(true);
            }
        },
        //判断第一层是否有包含子集的节点
        oneHaveChildrenFn(treeData) {
            let result = treeData.some(item => {
                if (item.isChildren) {
                    return true;
                }
            });
            this.oneHaveChildren = result;
        }
    },
    computed: {
        // wsl 2023-01-13 add 树节点的右键菜单根据条件过滤
        treeMenuList(){
            var _this=this;
            return function(treeNode,originalMenu){
                if (_this.mode=="runTime"&&treeNode.isDefault==1) {
                   return originalMenu.filter(item=>item.type == "addDirectory")
                }
               return originalMenu;
            }
        }
    },
    watch: {
        //input 快捷查询树结构
        "leftTreeConfig.filterText": function (val) {
            const _this = this;
            clearTimeout(_this.leftTreeConfig.searchFnc);
            if (!val) {
                _this
                    .getNewExtendList()
                    .then(() => {
                        _this.leftTreeConfig.defaultExpandedKeys = _this.leftTreeConfig.defaultExpandedKeys.concat(
                            _this.leftTreeConfig.searchTreeKey
                        );
                        _this.resultTreeSearchTreeShow(true);
                    })
                    .catch(() => {
                        _this.leftTreeConfig.defaultExpandedKeys = _this.leftTreeConfig.defaultExpandedKeys.concat(
                            _this.leftTreeConfig.searchTreeKey
                        );
                        _this.resultTreeSearchTreeShow(true);
                    });

                return;
            }
            _this.leftTreeConfig.defaultExpandedKeys = [""];
            _this.getMenuTreeData(val);
        }
    }
};
</script>
<style lang="less" scoped>
.m-menuManagement {
    height: 100%;
    i {
        cursor: pointer;
        font-size: 16px;
    }
    .g-menuManagement-main {
        height: 100%;
    }
    .g-treeBox {
        display: flex;
        flex-direction: column;
        height: 100%;
        width: 100%;
        box-sizing: border-box;
        overflow: hidden;
        .tree-top {
            display: flex;
            align-items: center;
            height: 36px;
            justify-content: space-between;
            padding: 0 16px;
            padding-right: 7px;
            margin-bottom: 8px;
            .u-title {
                font-weight: bold;
                font-stretch: normal;
                letter-spacing: 0px;
                color: #303133;
            }
            i {
                font-size: 16px;
                cursor: pointer;
                margin: 0 8px;
                color: #303133;
            }
        }
        .el-tree {
            overflow-y: auto;
        }
        .g-treeSlot {
            align-items: center;
            display: flex;
            height: 100%;
            width: calc(100% - 24px);
            .g-treeSlot-content {
                position: relative;
                display: flex;
                justify-content: space-between;
                align-items: center;
                white-space: nowrap;
                width: 100%;
                &:hover {
                    .g-right {
                        display: block;
                    }
                }
                .g-left {
                    display: flex;
                    align-items: center;
                    width: calc(100% - 30px);
                    i {
                        margin-right: 8px;
                    }
                    span {
                        max-width: calc(100% - 24px);
                        display: inline-block;
                        overflow: hidden;
                        text-overflow: ellipsis;
                    }
                }
                .g-dropdown {
                    margin-right: 12px;
                }
                .g-right {
                    position: absolute;
                    right: 5px;
                    display: none;
                }
            }
        }
    }
    .g-oneHaveChildren {
        // padding-left: 7px;
    }
    .g-container {
        width: 100%;
    }
}
</style>
<style lang="less">
.m-menuManagement .g-oneNoHaveChildren .el-tree-node__expand-icon.is-leaf {
    padding-left: 0px !important;
    padding-right: 3px;
}
.m-menuManagement .g-oneNoHaveChildren .g-dropdown {
    margin-right: 3px !important;
}
</style>
