<template>
    <ap-container>
        <ap-aside margin="1111" width="400px">
            <div class="layout-aside-header">
                <div class="layout-aside-header-title">数据类别</div>
                <div class="layout-aside-header-icon">
                    <i class="el-icon-plus" @click="addDictionaryType"/>
                    <i class="el-icon-edit-outline" @click="editDictionaryType"/>
                    <i class="el-icon-delete" @click="deleteDictionaryType"/>
                    <el-popover ref="popoverRef" placement="bottom" trigger="click">
                        <el-button-group>
                            <el-button type="primary" icon="el-icon-top" @click="doSortChange('prev')">上移
                            </el-button>
                            <el-button type="primary" icon="el-icon-bottom" @click="doSortChange('next')">下移
                            </el-button>
                            <el-button type="primary" icon="el-icon-s-operation" @click="sortByIndex">一键排序
                            </el-button>
                        </el-button-group>
                        <i class="el-icon-sort" slot="reference"/>
                    </el-popover>
                </div>
            </div>
            <div class="layout-aside-content" v-loading="loadingTreeFlag">
                <el-tree
                    ref="tSysDictionaryTypeTree"
                    node-key="fdId"
                    :data="typeTreeList"
                    :props="defaultProps"
                    :highlight-current="true"
                    :expand-on-click-node="false"
                    :indent="10"
                    @node-click="nodeClickEvent">
                    <div slot-scope="{ node, data }" style="width: 100%">
                        <div class="dev-tree-node-left ap-ellipse">
                            {{data.fdName }}
                        </div>
                        <div style="font-size: 12px;" class=" ap-ellipse">{{ data.fdCode}}</div>
                    </div>
                </el-tree>
            </div>
        </ap-aside>
        <ap-split-panel></ap-split-panel>
        <ap-main margin="1110">
            <ap-table ref="tSysDictionaryTableRef" :options.sync="tableOpt"></ap-table>
        </ap-main>

        <el-dialog title="数据类别" :visible.sync="dialogVisible" width="350px">
            <el-form ref="dialogForm"
                     :inline="true"
                     :model="dialogForm" :rules="dialogFormRules" label-width="80px">
                <el-form-item label="父节点">
                    <el-select v-model="dialogForm.fdParentId" filterable placeholder="请选择父节点">
                        <el-option label="无" value=""></el-option>
                        <el-option
                            v-for="item in typeList"
                            :key="item.fdId"
                            :label="item.fdName"
                            :value="item.fdId">
                        </el-option>
                    </el-select>
                </el-form-item>
                <el-form-item label="名称" prop="fdName">
                    <el-input v-model="dialogForm.fdName"></el-input>
                </el-form-item>
                <el-form-item label="编码" prop="fdCode">
                    <el-input v-model="dialogForm.fdCode"></el-input>
                </el-form-item>
                <el-form-item label="分组">
                    <el-radio v-model="dialogForm.fdIsGroup" :label="1">是</el-radio>
                    <el-radio v-model="dialogForm.fdIsGroup" :label="0">否</el-radio>
                </el-form-item>
                <el-form-item label="类型" v-if="dialogForm.fdIsGroup == 0">
                    <el-select v-model="dialogForm.fdType" filterable placeholder="请选择类型">
                        <el-option label="单项" :value="0"></el-option>
                        <el-option label="数组" :value="1"></el-option>
                        <el-option label="键值对" :value="2"></el-option>
                    </el-select>
                </el-form-item>
                <el-form-item label="排序" prop="fdSort">
                    <el-input-number v-model="dialogForm.fdSort" controls-position="right"></el-input-number>
                </el-form-item>
            </el-form>
            <span slot="footer" class="dialog-footer">
                <el-button @click="dialogVisible = false">取 消</el-button>
                <el-button type="primary" @click="saveDialog" :loading="saveDialogLoadingFlag">确 定</el-button>
            </span>
        </el-dialog>
    </ap-container>
</template>

<script>
import {convertToTreeData} from 'ap-util/util/DataUtil'
import {getNodeByCurrent, getSortListByIndex} from 'ap-util/util/TreeUtil'

export default {
    name: 'SysDictionary',
    data() {
        let columns = [
            {
                prop: 'fdKey',
                label: '键(key)',
                type: 'input',
                align: "left",
                width: "200px",
                rules: [{min: 1, max: 30, message: "长度在 1 到 30 个字符", trigger: "blur"}]
            }, {
                prop: 'fdValue',
                label: '值(value)',
                type: 'input',
                align: "left",
                width: "200px",
                rules: [{required: true, message: "必填项", trigger: "blur"},
                    {min: 1, max: 500, message: "长度在 1 到 500 个字符", trigger: "blur"}]
            }, {
                prop: 'fdSort',
                label: '排序',
                type: 'inputNumber',
                align: "center",
                width: "80px"
            }, {
                prop: 'fdDisabled',
                label: '是否有效',
                type: 'select',
                align: "center",
                width: "80px",
                addDefaultValue: 0,
                selectOptions: [
                    {label: "有效", value: 0},
                    {label: "无效", value: 1}
                ],
                html: function (value, row) {
                    if (value == 0) {
                        return '<div class="ap-tag-success">有效</div>'
                    } else if (value == 1) {
                        return '<div class="ap-tag-danger">无效</el-tag>';
                    }
                }
            },
        ];

        let tableOpt = {
            title: "数据字典",
            columns: columns,
            dataUrl: "/apm/sys/dictionary/getTSysDictionaryGridList",
            saveUrl: "/apm/sys/dictionary/saveTSysDictionaryGridData",
            editPk: "fdId", //默认fdId
            deletePk: "fdId", // 默认fdId
            deleteUrl: "/apm/sys/dictionary/updateTSysDictionaryForDelete",
            toolbarBtn: [
                {
                    btnType: "primary",
                    text: "刷新缓存",
                    icon: "el-icon-magic-stick",
                    onClick: this.refreshCache
                },
                "separator", "add", "edit", "del", "cancel", "refresh", "save"],
            addDefaultObj: () => {
                return {
                    fdTypeId: this.selectedType.fdTypeId,
                    fdTypeName: this.selectedType.fdTypeName,
                    fdDeleted: 0
                }
            },
            params: () => {
                return {
                    typeId: this.selectedType.fdTypeId,
                    typeCode: this.selectedType.fdCode,
                }
            },
            beforeAdd: (opts) => {
                if (this.selectedType.fdType == 0 && this.$refs.tSysDictionaryTableRef.getAllData().length > 0) {
                    this.$message.error('当前类别，只允许一个字典项！');
                    return false;
                }
                return true;
            }
        };

        return {
            // ----- 左侧树 -----
            loadingTreeFlag: false,
            saveDialogLoadingFlag: false,
            dialogVisible: false,
            dialogTitle: '',
            isAddDialog: true,
            typeList: [],
            typeTreeList: [],
            defaultProps: {
                children: 'children',
                label: 'fdName'
            },

            dialogForm: {
                fdId: '',
                fdName: '',
                fdCode: '',
                fdIsGroup: 0,
                fdType: 0,
                fdParentId: '',
                fdSort: 0
            },

            dialogFormRules: {
                fdType: [
                    {required: true, message: '请选择类别', trigger: 'blur'}
                ],
                fdName: [
                    {required: true, message: '请输类别名称', trigger: 'blur'},
                    {min: 1, max: 20, message: '长度在 1 到 20 个字符', trigger: 'blur'}
                ],
                fdCode: [
                    {required: true, message: '请输数据字典编码', trigger: 'blur'},
                    {min: 1, max: 30, message: '长度在 1 到 30 个字符', trigger: 'blur'}
                ],
            },

            // 选择的类型
            selectedType: {
                fdTypeId: '',
                fdTypeName: '',
                fdCode: '',
            },
            // ----- 右侧 -----
            tableOpt: tableOpt,
        }
    },

    created() {
        this.loadTreeData();
    },

    methods: {
        // 左侧树：加载数据
        loadTreeData() {
            this.loadingTreeFlag = true;
            // 加载数据
            this.$request({
                url: '/apm/sys/dictionaryType/getTSysDictionaryTypeList',
                method: 'post'
            }).then(response => {
                // 数据格式转换：数组 -> tree
                this.typeTreeList = convertToTreeData(response.data, {
                    idKey: "fdId",
                    parentKey: "fdParentId",
                    childrenKey: "children",
                });
                this.typeList = response.data;
            }).finally(() => {
                this.loadingTreeFlag = false;
            })
        },

        // 左侧树：重新加载数据
        reLoadTreeData() {
            // 重置当前选择节点
            this.$refs.tSysDictionaryTypeTree.setCurrentKey();
            this.loadTreeData();
        },

        // 左侧树：点击事件
        nodeClickEvent(data, node, comp) {
            this.selectedType.fdTypeId = data.fdId;
            this.tableOpt.title = `数据字典 -【${data.fdName}】-【${data.fdCode}】`;
            this.selectedType.fdTypeName = data.fdName;
            this.selectedType.fdType = data.fdType;
            this.selectedType.fdCode = data.fdCode;
            this.tableOpt.columns[0].hide = data.fdType == 2 ? false : true;
            this.$refs.tSysDictionaryTableRef.refresh();
        },

        //重置表单数据
        resetDialogForm() {
            this.dialogForm = {
                fdId: '',
                fdName: '',
                fdCode: '',
                fdIsGroup: 0,
                fdType: 0,
                fdParentId: '',
                fdSort: 0
            };
        },

        // 获取树的节点信息
        getCurrentNode() {
            return this.$refs.tSysDictionaryTypeTree.getCurrentNode() || {}
        },

        // dialog：添加数据
        addDictionaryType() {
            console.log(this.dialogForm)
            let currentNodeFdId = this.getCurrentNode().fdId;
            this.resetDialogForm();
            this.dialogVisible = true;
            this.dialogTitle = '添加数据类别';
            this.isAddDialog = true;
            this.dialogForm.fdParentId = currentNodeFdId;
        },

        // dialog：编辑数据
        editDictionaryType() {
            let currentNodeFdId = this.getCurrentNode().fdId;
            if (!currentNodeFdId) {
                this.$message.error('请选择需要编辑的数据！');
                return
            }

            this.resetDialogForm();
            this.dialogVisible = true;
            this.dialogTitle = '编辑数据类别';
            this.isAddDialog = false;
            this.dialogForm.fdId = currentNodeFdId;

            this.$request({
                url: '/apm/sys/dictionaryType/getTSysDictionaryTypeByFdId',
                method: 'post',
                data: {
                    fdId: currentNodeFdId
                }
            }).then(response => {
                this.dialogForm.fdId = response.data.fdId
                this.dialogForm.fdName = response.data.fdName
                this.dialogForm.fdCode = response.data.fdCode
                this.dialogForm.fdSort = response.data.fdSort
                this.dialogForm.fdIsGroup = response.data.fdIsGroup
                this.dialogForm.fdType = response.data.fdType
                this.dialogForm.fdParentId = response.data.fdParentId
            })
        },

        // 删除类型数据
        deleteDictionaryType() {
            let currentNode = this.getCurrentNode();
            let currentNodeFdId = currentNode.fdId;
            if (!currentNodeFdId) {
                this.$message.error('请选择需要删除的数据！');
                return
            }

            this.$confirm(`确定要删除【${currentNode.fdName}】?`, '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                this.$request({
                    url: '/apm/sys/dictionaryType/updateTSysDictionaryTypeForDelete',
                    method: 'post',
                    data: {
                        fdId: currentNodeFdId
                    }
                }).then(response => {
                    this.$message.success(`删除成功！已删除${response.data}条数据！`);
                    this.loadTreeData();
                })
            })
        },
        saveDialog() {
            this.saveDialogLoadingFlag = true;
            this.$refs.dialogForm.validate((valid) => {
                if (!valid) {
                    this.$message.error(`数据校验失败，请重新填写信息！`);
                    return false;
                }

                if (this.isAddDialog) {
                    // 添加数据
                    this.$request({
                        url: '/apm/sys/dictionaryType/insertTSysDictionaryType',
                        method: 'post',
                        data: this.dialogForm
                    }).then(response => {
                        this.$message.success(`添加成功！已添加${response.data}条数据！`)
                        this.dialogVisible = false;
                        this.reLoadTreeData();
                    }).finally(() => {
                        this.saveDialogLoadingFlag = false;
                    })
                } else {
                    // 更新数据
                    this.$request({
                        url: '/apm/sys/dictionaryType/updateTSysDictionaryType',
                        method: 'post',
                        data: this.dialogForm
                    }).then(response => {
                        this.$message.success(`更新成功！已更新${response.data}条数据！`)
                        this.dialogVisible = false;
                        this.reLoadTreeData();
                    }).finally(() => {
                        this.saveDialogLoadingFlag = false;
                    })
                }
            });
        },
        // 修改排序
        doSortChange(type) {
            let currentNode = this.getCurrentNode();
            if (!currentNode.fdId) {
                this.$message.error(`请选择需要操作的节点！`);
                return;
            }
            let exchangeNode = getNodeByCurrent(this.$refs.tSysDictionaryTypeTree, type);
            if (exchangeNode == null) {
                this.$message.error(`无需排序！`);
                return;
            }

            let list = [];
            list.push({
                fdId:currentNode.fdId,
                fdSort:exchangeNode.fdSort,
            });
            list.push({
                fdId:exchangeNode.fdId,
                fdSort:currentNode.fdSort,
            });
            this.$request({
                url: '/apm/sys/dictionaryType/updateTSysDictionaryTypeSortList',
                method: 'post',
                data: {list: JSON.stringify(list)}
            }).then(response => {
                this.$message.success(`排序成功！`)
                this.$refs.popoverRef.doClose();
                this.loadTreeData();
            })
        },
        // 一键排序
        sortByIndex() {
            let list = getSortListByIndex(this.$refs.tSysDictionaryTypeTree.data);
            this.$request({
                url: '/apm/sys/dictionaryType/updateTSysDictionaryTypeSortList',
                method: 'post',
                data: {list: JSON.stringify(list)}
            }).then(response => {
                this.$message.success(`排序成功！`)
                this.$refs.popoverRef.doClose();
                this.loadTreeData();
            })
        },
        refreshCache() {
            this.$request({
                url: '/apm/sys/dictionary/refreshCache',
                method: 'post'
            }).then(response => {
                this.$message.success(`Redis缓存刷新成功！`)
            })
        }
    }
}
</script>

<style scoped>
.dev-tree-node-left {
    font-size: 15px;
    width: 60%;
    float: left;
}
</style>
