<script setup lang="ts" name="Menu">
import apis from "@a"
import message from "@@/utils/message"

const { sys_normal_disable, sys_show_hide } = useDict("sys_normal_disable", "sys_show_hide")

const tableRef = ref()
const modalRef = ref()
const iconShow = ref(false)
const opts = reactive({
	columns: [
		{ field: "menuId", name: "菜单ID", width: 100, isSort: true, visible: false },
		{ field: "menuName", name: "菜单名称", visible: true },
		{ field: "icon", name: "菜单图标", visible: true, width: 80 },
		{ field: "path", name: "路由地址/按钮", visible: true, width: 120 },
		//{ field: "query", name: "路由参数", visible: true, width: 120 },
		{ field: "component", name: "组件路径", visible: true },
		{ field: "isFrame", name: "是否为外链", visible: true, width: 90 },
		{ field: "isCache", name: "是否缓存", visible: true, width: 80 },
		{ field: "menuType", name: "菜单类型", visible: true, width: 80 },
		{ field: "visible", name: "菜单显示", visible: true, width: 80 },
		{ field: "status", name: "菜单状态", visible: true, width: 80 },
		{ field: "perms", name: "权限标识", visible: true },
		{ field: "actions", name: `操作`, width: 150 }
	] as any,
	queryParams: {
		menuName: undefined,
		visible: undefined,
		status: undefined
	},
	searchFormItems: [
		{
			field: "menuName",
			label: "菜单名称",
			class: "w-100",
			required: false,
			placeholder: "请输入菜单名称",
			listeners: {
				keyup: (e: KeyboardEvent) => {
					if (e.code == "Enter") {
						handleQuery()
					}
				}
			}
		},
		{
			field: "visible",
			label: "菜单显示",
			class: "w-100",
			required: false,
			component: "Dict",
			props: {
				placeholder: "请选择菜单显示",
				dictType: "sys_show_hide"
			}
		},
		{
			field: "status",
			label: "菜单状态",
			class: "w-100",
			required: false,
			component: "Dict",
			props: {
				placeholder: "请选择菜单状态",
				dictType: "sys_normal_disable"
			}
		}
	] as any,
	permission: "system:menu",
	handleBtns: [
		{
			key: "handleUpdate",
			show: false
		},
		{
			key: "handleDelete",
			show: false
		}
	],
	handleFuns: {
		handleCreate
	},
	customBtns: [],
	tableListFun: getTableData,
	getEntityFun: apis.system.menuApi.getMenu,
	deleteEntityFun: apis.system.menuApi.delMenu,
	modalTitle: "菜单",
	formRules: {
		menuName: [{ required: true, message: "菜单名称不能为空", trigger: "blur" }],
		orderNum: [{ required: true, message: "菜单顺序不能为空", trigger: "blur" }],
		path: [{ required: true, message: "路由地址不能为空", trigger: "blur" }]
	},
	labelWidth: "80px",
	emptyFormData: {
		parentId: 0,
		menuId: undefined,
		menuName: undefined,
		orderNum: undefined,
		path: undefined,
		component: undefined,
		query: undefined,
		isFrame: undefined,
		isCache: undefined,
		menuType: undefined,
		visible: "0",
		status: "0",
		perms: undefined,
		icon: undefined,
		btnClass: undefined,
		btnScript: undefined,
		remark: undefined
	}
})
const { queryParams, emptyFormData } = toRefs(opts)
const form = ref<any>(emptyFormData.value)

/** 搜索按钮操作 */
function handleQuery(query?: any) {
	query = query || tableRef.value?.getQueryParams() || queryParams.value
	tableRef.value?.query(query)
}
/** 重置按钮操作 */
function resetQuery() {
	//
}

const menuOptions = ref()
const defaultBtnStyle = ref()
function reset() {
	form.value = emptyFormData.value
	defaultBtnStyle.value = undefined
	getMenuTreeSelect()
}
/** 新增按钮操作 */
function handleCreate(row: any) {
	reset()
	if (row != null && row.menuId) {
		form.value.parentId = row.menuId
	} else {
		form.value.parentId = 0
	}
	modalRef.value.changePrefixTitle("添加")
	modalRef.value.show()
}

/** 修改按钮操作 */
function handleUpdate(row: any) {
	reset()
	if (row.menuId) {
		apis.system.menuApi.getMenu(row.menuId).then((res: any) => {
			form.value = res.data
			modalRef.value.changePrefixTitle("修改")
			modalRef.value.show()
		})
	}
}
function getMenuTreeSelect() {
	menuOptions.value = []
	apis.system.menuApi.listMenu({}).then((response) => {
		const menu: any = { menuId: 0, menuName: "主类目", children: [] }
		menu.children = handleTree(response.data, "menuId")
		menuOptions.value.push(menu)
	})
}

/** 提交按钮 */
function submitForm() {
	if (form.value.menuId != null) {
		apis.system.menuApi.updateMenu(form.value).then(() => {
			message.msgSuccess("修改成功")
			handleQuery()
		})
	} else {
		apis.system.menuApi.addMenu(form.value).then(() => {
			message.msgSuccess("新增成功")
			handleQuery()
		})
	}
}

/** 删除按钮操作 */
function handleDelete(row: any) {
	message
		.confirm('是否确认删除菜单为"' + row.menuName + '"的数据项？')
		.then(() => {
			return apis.system.menuApi.delMenu(row.menuId).then(() => {
				handleQuery()
			})
		})
		.catch(() => {
			//
		})
}

function defaultBtnChange(v: any) {
	switch (v) {
		case "A":
			form.value.btnClass = "btn btn-light-primary"
			form.value.btnScript = "handleCreate"
			break
		case "U":
			form.value.btnClass = "btn btn-light-success"
			form.value.btnScript = "handleUpdate@1"
			break
		case "D":
			form.value.btnClass = "btn btn-light-danger"
			form.value.btnScript = "handleDelete@0"
			break
		case "I":
			form.value.btnClass = "btn btn-light-warning"
			form.value.btnScript = "handleImport"
			break
		case "E":
			form.value.btnClass = "btn btn-light-info"
			form.value.btnScript = "handleExport"
			break
		case "H":
			form.value.btnClass = "btn btn-light"
			form.value.btnScript = "hide"
			break
	}
}

function getTableData(q: any) {
	return new Promise((resolve) => {
		apis.system.menuApi.listMenuByParentId(q).then((res) => {
			//res.data = handleTree(res.data, "menuId")
			resolve(res)
		})
	})
}

const showChooseIcon = ref(false)
const iconSelectRef = ref()

/** 展示下拉图标 */
function showSelectIcon() {
	iconSelectRef.value?.reset()
	showChooseIcon.value = true
}
/** 选择图标 */
function selected(name: string) {
	form.value.icon = name
	showChooseIcon.value = false
}

onMounted(() => {
	setTimeout(() => {
		iconShow.value = true
	}, 500)
})
</script>
<template>
	<div>
		<VbDataTable
			ref="tableRef"
			:is-tree="true"
			:is-lazy="true"
			keyField="menuId"
			iconField="menuName"
			parentField="parentId"
			root-id="0"
			childrenField="children"
			leaf-field="leaf"
			:check-multiple="false"
			:has-checkbox="false"
			:no-page="true"
			:expand-depth="1"
			:interval-left="10"
			:show-search-bar="false"
			:show-right-search-btn="false"
			:show-right-column-btn="false"
			:handle-perm="opts.permission"
			:handle-btns="opts.handleBtns"
			:handle-funs="opts.handleFuns"
			:search-form-items="opts.searchFormItems"
			:columns="opts.columns"
			:custom-btns="opts.customBtns"
			:remote-fun="opts.tableListFun"
			v-model:query-params="queryParams"
			:reset-search-form-fun="resetQuery"
			:custom-search-fun="handleQuery">
			<template #icon="{ row }">
				<i :class="`fs-4 text-primary bi bi-${row.icon}`"></i>
			</template>
			<template #path="{ row }">
				<template v-if="row.menuType == 'F'">
					<template v-if="row.btnScript">
						<template v-if="row.btnClass">
							<div
								class="d-flex justify-content-center align-items-center w-100"
								style="transform: scale(0.7)">
								<span :class="row.btnClass">{{ row.btnScript }}</span>
							</div>
						</template>
						<template v-else>{{ row.btnScript }}</template>
					</template>
					<template v-else>{{ row.btnClass }}</template>
				</template>
				<template v-else>{{ row.path }}</template>
			</template>
			<template #component="{ row }">
				<template v-if="row.component">
					<vb-tooltip :content="row.component" :auto-hide="true"></vb-tooltip>
				</template>
				<span v-else class="text-muted">-</span>
			</template>
			<template #query="{ row }">
				<template v-if="row.query">
					<vb-tooltip :content="row.query" :auto-hide="true"></vb-tooltip>
				</template>
				<span v-else class="text-muted">-</span>
			</template>

			<template #perms="{ row }">
				<template v-if="row.perms">
					<vb-tooltip :content="row.perms" :auto-hide="true"></vb-tooltip>
				</template>
				<span v-else class="text-muted">-</span>
			</template>
			<template #menuType="{ row }">
				<vb-tag
					:data="[
						{ label: '目录', value: 'M', type: 'primary' },
						{ label: '菜单', value: 'C', type: 'success' },
						{ label: '按钮', value: 'F', type: 'warning' }
					]"
					:value="row.menuType"></vb-tag>
			</template>
			<template #isCache="{ row }">
				<vb-tag
					:data="[
						{ label: '是', value: '0', type: 'primary' },
						{ label: '否', value: '1', type: 'danger' }
					]"
					:value="row.isCache"></vb-tag>
			</template>
			<template #isFrame="{ row }">
				<vb-tag
					:data="[
						{ label: '是', value: '0', type: 'primary' },
						{ label: '否', value: '1', type: 'danger' }
					]"
					:value="row.isFrame"></vb-tag>
			</template>
			<template #visible="{ row }">
				<DictTag type="sys_show_hide" :value="row.visible"></DictTag>
			</template>
			<template #status="{ row }">
				<DictTag type="sys_normal_disable" :value="row.status"></DictTag>
			</template>
			<template #actions="{ row }">
				<vb-tooltip content="新增" placement="top">
					<el-button
						link
						type="primary"
						@click="handleCreate(row)"
						v-hasPermission="'system:menu:add'">
						<template #icon>
							<VbIcon icon-name="plus-square" icon-type="duotone" class="fs-3"></VbIcon>
						</template>
					</el-button>
				</vb-tooltip>
				<vb-tooltip content="修改" placement="top">
					<el-button
						link
						type="primary"
						@click="handleUpdate(row)"
						v-hasPermission="'system:menu:edit'">
						<template #icon>
							<VbIcon icon-name="notepad-edit" icon-type="duotone" class="fs-3"></VbIcon>
						</template>
					</el-button>
				</vb-tooltip>
				<vb-tooltip content="删除" placement="top">
					<el-button
						link
						type="primary"
						@click="handleDelete(row)"
						v-hasPermission="'system:menu:remove'">
						<template #icon>
							<VbIcon icon-name="trash-square" icon-type="duotone" class="fs-3"></VbIcon>
						</template>
					</el-button>
				</vb-tooltip>
			</template>
		</VbDataTable>
		<VbModal
			v-model:modal="modalRef"
			:title="opts.modalTitle"
			:form-data="form"
			:form-rules="opts.formRules"
			:label-width="opts.labelWidth"
			:hide-event="() => (showChooseIcon = false)"
			@confirm="submitForm"
			append-to-body>
			<template #form>
				<el-row>
					<el-col :span="24">
						<el-form-item label="上级菜单" prop="parentId">
							<el-tree-select
								v-model="form.parentId"
								class="w-100"
								:data="menuOptions"
								:props="{ value: 'menuId', label: 'menuName', children: 'children' }"
								value-key="menuId"
								placeholder="选择上级菜单"
								check-strictly />
						</el-form-item>
					</el-col>

					<el-col :span="24">
						<el-form-item label="菜单类型" prop="menuType">
							<el-radio-group v-model="form.menuType">
								<el-radio label="M">目录</el-radio>
								<el-radio label="C">菜单</el-radio>
								<el-radio label="F">按钮</el-radio>
							</el-radio-group>
						</el-form-item>
					</el-col>
					<el-col :span="24" v-if="iconShow">
						<!-- <el-form-item label="菜单图标" prop="icon">
							<el-popover
								placement="bottom-start"
								:width="600"
								v-model:visible="showChooseIcon"
								trigger="focus"
								@show="showSelectIcon">
								<template #reference>
									<el-input
										v-model="form.icon"
										placeholder="点击选择图标"
										@blur="showChooseIcon = true"
										@focus="showChooseIcon = true"
										readonly>
										<template #prefix>
											<i v-if="form.icon" :class="`text-primary bi bi-${form.icon}`"></i>
											<i v-else class="text-muted bi bi-search"></i>
										</template>
									</el-input>
								</template>
								<icon-select ref="iconSelectRef" @selected="selected" :active-icon="form.icon" />
							</el-popover>
						</el-form-item> -->
						<el-form-item label="菜单图标" prop="icon">
							<el-input v-model="form.icon" placeholder="请输入菜单图标" class="w-100" />
						</el-form-item>
					</el-col>
					<el-col :span="12">
						<el-form-item label="菜单名称" prop="menuName">
							<el-input v-model="form.menuName" placeholder="请输入菜单名称" class="w-100" />
						</el-form-item>
					</el-col>
					<el-col :span="12">
						<el-form-item label="显示顺序" prop="orderNum">
							<el-input-number v-model="form.orderNum" placeholder="请输入显示顺序" class="w-100" />
						</el-form-item>
					</el-col>
					<el-col :span="12" v-if="form.menuType != 'M'">
						<el-form-item label="权限标识" prop="perms">
							<template #label>
								<span>
									<vb-tooltip
										:width="320"
										content="控制器中定义的权限字符，如：@PreAuthorize(`@ss.hasPermission('system:user:list')`)"
										placement="top">
										<span class="bi bi-question-circle-fill text-muted"></span>
									</vb-tooltip>
									权限字符
								</span>
							</template>
							<el-input v-model="form.perms" placeholder="请输入权限标识" class="w-100" />
						</el-form-item>
					</el-col>
					<el-col :span="24" v-if="form.menuType == 'F'">
						<el-form-item label="常用样式">
							<template #label>
								<span>
									<vb-tooltip
										:width="320"
										content="列举了几种常用样式脚本，方便快捷的设置按钮样式及按钮脚本"
										placement="top">
										<span class="bi bi-question-circle-fill text-muted"></span>
									</vb-tooltip>
									常用样式
								</span>
							</template>
							<el-radio-group v-model="defaultBtnStyle" @change="defaultBtnChange">
								<el-radio label="A">
									<span class="btn btn-light-primary" style="transform: scale(0.7)">新增</span>
								</el-radio>
								<el-radio label="U">
									<span class="btn btn-light-success" style="transform: scale(0.7)">编辑</span>
								</el-radio>
								<el-radio label="D">
									<span class="btn btn-light-danger" style="transform: scale(0.7)">删除</span>
								</el-radio>
								<el-radio label="I">
									<span class="btn btn-light-warning" style="transform: scale(0.7)">导入</span>
								</el-radio>
								<el-radio label="E">
									<span class="btn btn-light-info" style="transform: scale(0.7)">导出</span>
								</el-radio>
								<el-radio label="H">
									<span class="btn btn-light" style="transform: scale(0.7)">隐藏</span>
								</el-radio>
							</el-radio-group>
						</el-form-item>
					</el-col>
					<el-col :span="12" v-if="form.menuType == 'F'">
						<el-form-item label="按钮样式" prop="btnClass">
							<template #label>
								<span>
									<vb-tooltip content="按钮在toolbar中的显示样式 class" placement="top">
										<span class="bi bi-question-circle-fill text-muted"></span>
									</vb-tooltip>
									按钮样式
								</span>
							</template>
							<el-input v-model="form.btnClass" placeholder="请输入按钮样式" class="w-100" />
						</el-form-item>
					</el-col>
					<el-col :span="12" v-if="form.menuType == 'F'">
						<el-form-item label="按钮脚本" prop="btnScript">
							<template #label>
								<span>
									<vb-tooltip
										:width="320"
										content="点击按钮调用的方法名，前端需要向table组件内传此方法名为key的方法。[handleCreate]、[handleUpdate]、[handleDelete]、[handleExport]脚本在table组件内置了。注：设置为'hide'值会隐藏按钮。"
										placement="top">
										<span class="bi bi-question-circle-fill text-muted"></span>
									</vb-tooltip>
									按钮脚本
								</span>
							</template>
							<el-input v-model="form.btnScript" placeholder="请输入按钮脚本" class="w-100" />
						</el-form-item>
					</el-col>

					<el-col :span="12" v-if="form.menuType != 'F'">
						<el-form-item label="路由地址" prop="path">
							<el-input v-model="form.path" placeholder="请输入路由地址" class="w-100" />
						</el-form-item>
					</el-col>
					<el-col :span="12" v-if="form.menuType != 'F'">
						<el-form-item label="是否为外链" prop="isFrame">
							<template #label>
								<span>
									<vb-tooltip content="选择是外链则路由地址需要以`http(s)://`开头" placement="top">
										<span class="bi bi-question-circle-fill text-muted"></span>
									</vb-tooltip>
									是否外链
								</span>
							</template>
							<el-radio-group v-model="form.isFrame">
								<el-radio label="0">是</el-radio>
								<el-radio label="1">否</el-radio>
							</el-radio-group>
						</el-form-item>
					</el-col>
					<el-col :span="12" v-if="form.menuType == 'C'">
						<el-form-item label="组件路径" prop="component">
							<template #label>
								<span>
									<vb-tooltip
										:width="320"
										content="访问的组件路径，如：`system/user/index`，默认在`views`目录下"
										placement="top">
										<span class="bi bi-question-circle-fill text-muted"></span>
									</vb-tooltip>
									组件路径
								</span>
							</template>
							<el-input v-model="form.component" placeholder="请输入组件路径" class="w-100" />
						</el-form-item>
					</el-col>

					<el-col :span="12" v-if="form.menuType == 'C'">
						<el-form-item>
							<el-input v-model="form.query" placeholder="请输入路由参数" maxlength="255" />
							<template #label>
								<span>
									<vb-tooltip
										content='访问路由的默认传递参数，如：`{"id": 1, "name": "ry"}`'
										placement="top">
										<span class="bi bi-question-circle-fill text-muted"></span>
									</vb-tooltip>
									路由参数
								</span>
							</template>
						</el-form-item>
					</el-col>
					<el-col :span="12" v-if="form.menuType == 'C'">
						<el-form-item>
							<template #label>
								<span>
									<vb-tooltip
										content="选择是则会被`keep-alive`缓存，需要匹配组件的`name`和地址保持一致"
										placement="top">
										<span class="bi bi-question-circle-fill text-muted"></span>
									</vb-tooltip>
									是否缓存
								</span>
							</template>
							<el-radio-group v-model="form.isCache">
								<el-radio label="0">缓存</el-radio>
								<el-radio label="1">不缓存</el-radio>
							</el-radio-group>
						</el-form-item>
					</el-col>
					<el-col :span="12" v-if="form.menuType != 'F'">
						<el-form-item>
							<template #label>
								<span>
									<vb-tooltip
										content="选择隐藏则路由将不会出现在侧边栏，但仍然可以访问"
										placement="top">
										<span class="bi bi-question-circle-fill text-muted"></span>
									</vb-tooltip>
									显示状态
								</span>
							</template>
							<el-radio-group v-model="form.visible">
								<el-radio v-for="dict in sys_show_hide" :key="dict.value" :label="dict.value">
									{{ dict.label }}
								</el-radio>
							</el-radio-group>
						</el-form-item>
					</el-col>
					<el-col :span="12" v-if="form.menuType != 'F'">
						<el-form-item>
							<template #label>
								<span>
									<vb-tooltip
										content="选择停用则路由将不会出现在侧边栏，也不能被访问"
										placement="top">
										<span class="bi bi-question-circle-fill text-muted"></span>
									</vb-tooltip>
									菜单状态
								</span>
							</template>
							<el-radio-group v-model="form.status">
								<el-radio v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.value">
									{{ dict.label }}
								</el-radio>
							</el-radio-group>
						</el-form-item>
					</el-col>
					<el-col :span="24">
						<el-form-item label="备注" prop="remark">
							<el-input
								v-model="form.remark"
								type="textarea"
								placeholder="请输入内容"
								class="w-100" />
						</el-form-item>
					</el-col>
				</el-row>
			</template>
		</VbModal>
	</div>
</template>
