<template>
	<div class="system-dict-container layout-padding">
		<div class="layout-padding-auto layout-padding-view pd20">
			<splitpanes class="h100" Vertical>
				<pane min-size="16" max-size="25" size="16" class="orgTree">
					<el-input v-model="filterText" placeholder="类型名称" clearable />
					<el-scrollbar style="height: calc(100% - 55px)" class="mt10">
						<el-auto-resizer class="table" v-loading="state.tableLoading">
							<template #default="{ height, width }">
								<el-tree-v2
									:data="state.dicTypeList"
									highlight-current
									:expand-on-click-node="false"
									node-key="id"
									:props="{ children: 'children', label: 'dicTypeName' }"
									@node-click="handleNodeClick"
									:current-node-key="state.dicTypeList[0]?.id"
									:filter-method="filterNode"
									ref="treeRef"
									:height="height"
									:item-size="36"
									empty-text="暂无数据"
								>
									<template #default="{ node }">
										<span>{{ node.label }}</span>
									</template>
								</el-tree-v2>
							</template>
						</el-auto-resizer>
					</el-scrollbar>
				</pane>
				<pane class="rightContent">
					<div class="flex-column">
						<el-form :model="state.queryParams" ref="ruleFormRef" inline @submit.native.prevent>
							<el-form-item label="关键字" prop="keyword">
								<el-input
									v-model="state.queryParams.keyword"
									placeholder="字典值名称/字典值"
									clearable
									@keyup.enter="handleQuery"
									class="keyword-input"
								/>
							</el-form-item>
							<el-form-item>
								<el-button type="primary" @click="handleQuery" :loading="state.tableLoading" v-waves>
									<SvgIcon name="ele-Search" class="mr5" />查询
								</el-button>
								<el-button @click="resetQuery(ruleFormRef)" v-waves class="default-button" :loading="state.tableLoading">
									<SvgIcon name="ele-Refresh" class="mr5" />重置
								</el-button>
							</el-form-item>
						</el-form>
						<vxe-toolbar
							ref="toolbarRef"
							:loading="state.tableLoading"
							custom
							:refresh="{
								queryMethod: handleQuery,
							}"
						>
							<template #buttons>
								<el-button type="primary" @click="onOpenAddUser" v-auth="'system:dict:add'"> <SvgIcon name="ele-Plus" class="mr5" />新增 </el-button>
							</template>
						</vxe-toolbar>
						<div style="overflow: hidden; width: 100%; height: 100%; flex: 1">
							<vxe-table
								:loading="state.tableLoading"
								:data="list"
								:column-config="{ resizable: true, useKey: true }"
								:row-config="{ isCurrent: true, isHover: true, useKey: true, height: 36 }"
								ref="tableRef"
								height="auto"
								auto-resize
								show-overflow
								:scrollY="{ enabled: true, gt: 0 }"
								id="systemDict"
								:custom-config="{ storage: true }"
								showHeaderOverflow
								:tree-config="{
									childrenField: 'children',
									transform: true,
									rowField: 'id',
									parentField: 'parentId',
								}"
							>
								<vxe-column field="dicDataName" title="字典名称" min-width="350" treeNode>
									<template #default="{ row }">
										<p style="display: flex; align-items: center">
											<span class="pl5" v-html="row.dicDataName"></span>
										</p>
									</template>
								</vxe-column>
								<vxe-column field="dicDataValue" title="字典值" min-width="150">
									<template #default="{ row }">
										<p style="display: flex; align-items: center">
											<span class="pl5" v-html="row.dicDataValue"></span>
										</p>
									</template>
								</vxe-column>
								<vxe-column field="dicTypeCode" title="字典code" width="170"></vxe-column>
								<vxe-column field="sort" title="排序" width="120"></vxe-column>
								<vxe-column field="creationTime" title="更新时间" width="160" align="center">
									<template #default="{ row }">
										<span>{{ formatDate(row.creationTime, 'YYYY-mm-dd HH:MM:SS') }}</span>
									</template>
								</vxe-column>
								<vxe-column title="操作" fixed="right" width="80" align="center">
									<template #default="{ row }">
										<el-button link type="primary" @click="onOpenEditUser(row)" title="修改" v-auth="'system:dict:edit'"> 修改 </el-button>
									</template>
								</vxe-column>
							</vxe-table>
						</div>
					</div>
				</pane>
			</splitpanes>
		</div>
		<dict-add ref="dictAddRef" @updateList="handleQuery" :dicTypeList="state.dicTypeList" />
		<dict-edit ref="dickEditRef" @updateList="handleQuery" :dicTypeList="state.dicTypeList" />
	</div>
</template>
<script lang="tsx" setup name="systemDict">
import { defineAsyncComponent, nextTick, onMounted, reactive, ref, watch } from 'vue';
import type { FormInstance } from 'element-plus';
import { formatDate } from '@/utils/formatTime';
import { dicTypeList, getDataByTypeId } from '@/api/system/dict';
import { Splitpanes, Pane } from 'splitpanes';
import 'splitpanes/dist/splitpanes.css';
import XEUtils from 'xe-utils';

// 引入组件
const DictAdd = defineAsyncComponent(() => import('@/views/system/config/dict/components/Dict-add.vue')); // 新增组件
const DictEdit = defineAsyncComponent(() => import('@/views/system/config/dict/components/Dict-edit.vue')); // 编辑组件

// 定义变量内容
const state = reactive<any>({
	queryParams: {
		keyword: null, // 关键字
		typeid: null, // 字典类型
	},
	total: 0, // 总条数
	loading: false, // 加载状态
	tableLoading: false, // 表格加载状态
	dicTypeList: [], // 字典类型列表
});
const ruleFormRef = ref<RefType>(); // 表单组件
/** 搜索按钮操作 节流操作 */
const handleQuery = () => {
	queryList();
};
// 获取字典类型列表
const getDictTypeList = () => {
	state.loading = true;
	dicTypeList()
		.then((res: any) => {
			state.dicTypeList = res?.result ?? [];
			state.queryParams.typeid = res?.result[0].id ?? '';
			queryList();
			state.loading = false;
		})
		.catch(() => {
			state.loading = false;
		});
};
/* 获取字典列表 */
const tableRef = ref<RefType>();
const tableData = ref<EmptyArrayType>([]);
const list = ref<any[]>([]);
const queryList = () => {
	state.tableLoading = true;
	getDataByTypeId(state.queryParams)
		.then((res: any) => {
			tableData.value = res?.result ?? [];
			const filterVal = XEUtils.toValueString(state.queryParams.keyword)?.trim().toLowerCase();
			if (filterVal) {
				const filterRE = new RegExp(filterVal, 'gi');
				const options = { children: 'children' };
				const searchProps = ['dicDataName', 'dicDataValue'];
				// 搜索为克隆数据，不会污染源数据
				const rest = XEUtils.searchTree(
					tableData.value,
					(item) => searchProps.some((key) => String(item[key]).toLowerCase().indexOf(filterVal) > -1),
					options
				);
				XEUtils.eachTree(
					rest,
					(item) => {
						searchProps.forEach((key) => {
							item[key] = String(item[key]).replace(filterRE, (match) => `<span class="keyword-highlight">${match}</span>`);
						});
					},
					options
				);
				list.value = rest;
				list.value = XEUtils.toTreeArray(list.value);
				nextTick(() => {
					// 搜索之后默认展开所有子节点
					if (tableRef.value) {
						tableRef.value.setAllTreeExpand(true);
					}
				});
			} else {
				list.value = tableData.value;
				list.value = XEUtils.toTreeArray(list.value);
			}

			state.tableLoading = false;
		})
		.catch(() => {
			state.loading = false;
		});
};
// 点击节点
const handleNodeClick = (data: any) => {
	state.queryParams.typeid = data.id;
	state.isExpand = false;
	state.expandedRowKeys = [];
	queryList();
};
// 打开新增字典弹窗
const dictAddRef = ref<RefType>(); //新增字典
const onOpenAddUser = () => {
	dictAddRef.value.openDialog(state.queryParams.typeid);
};
// 打开修改字典弹窗
const dickEditRef = ref<RefType>(); //修改字典
const onOpenEditUser = (row: any) => {
	dickEditRef.value.openDialog(row, state.tableData);
};
/** 重置按钮操作 */
const resetQuery = (formEl: FormInstance | undefined) => {
	if (!formEl) return;
	formEl.resetFields();
	queryList();
};
const filterText = ref('');
const treeRef = ref<RefType>();
watch(filterText, (val) => {
	treeRef.value!.filter(val);
});
const filterNode = (value: string, data: any) => {
	if (!value) return true;
	return data.dicTypeName.includes(value);
};
const toolbarRef = ref<RefType>();
onMounted(() => {
	getDictTypeList();
	if (tableRef.value && toolbarRef.value) {
		tableRef.value.connect(toolbarRef.value);
	}
});
</script>
<style lang="scss" scoped>
.system-dict-container {
	.orgTree {
		height: 100%;
	}
	.rightContent {
		height: 100%;
		.flex-column {
			display: flex;
			flex-direction: column;
			height: 100%;
			.table {
				flex: 1;
			}
		}
	}

	:deep(.el-tree-node__content) {
		height: 40px;
	}
}
</style>
