<template>
  <el-dialog
    v-model="dialogVisible"
    :title="isAdd ? '添加' : '编辑'"
    :width="800"
    center
    align-center
    :close-on-click-modal="false"
    @closed="hanldeBeforeClose"
  >
    <el-form :model="formData" ref="formRef" label-width="100px" :rules="formRules">
      <el-row :gutter="10">
        <el-col :span="12">
          <el-form-item label="上级目录" prop="parentId">
            <el-tree-select
              style="width: 100%"
              v-model="formData.parentId"
              :data="rootMenuOptions"
              :props="{ value: 'menuId', label: 'menuName', children: 'children' }"
              value-key="menuId"
              placeholder="选择上级菜单"
              default-expand-all
              check-strictly
              clearable
            />
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item label="菜单类型" prop="menuType">
            <el-radio-group v-model="formData.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 v-if="formData.menuType != 'F'" :span="24">
          <el-form-item label="菜单图标" prop="icon">
            <SelectIcon v-if="dialogVisible" v-model:icon-value="formData.icon" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="菜单名称" prop="menuName">
            <el-input v-model="formData.menuName" placeholder="请输入菜单名称" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="显示排序" prop="orderNum">
            <el-input-number style="width: 100%" v-model="formData.orderNum" controls-position="right" :min="0" />
          </el-form-item>
        </el-col>
        <el-col :span="12" v-if="formData.menuType != 'F'">
          <el-form-item>
            <template #label>
              <span>
                <el-tooltip content="选择是外链则路由地址需要以`http(s)://`开头" placement="top">
                  <el-icon><question-filled /></el-icon>
                </el-tooltip>
                是否外链
              </span>
            </template>
            <el-radio-group v-model="formData.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="formData.menuType != 'F'">
          <el-form-item prop="path">
            <template #label>
              <span>
                <el-tooltip content="访问的路由地址，如：`user`，如外网地址需内链访问则以`http(s)://`开头" placement="top">
                  <el-icon><question-filled /></el-icon>
                </el-tooltip>
                路由地址
              </span>
            </template>
            <el-input v-model="formData.path" placeholder="请输入路由地址" />
          </el-form-item>
        </el-col>
        <el-col :span="12" v-if="formData.menuType == 'C'">
          <el-form-item prop="component">
            <template #label>
              <span>
                <el-tooltip content="访问的组件路径，如：`system/user/index`，默认在`views`目录下" placement="top">
                  <el-icon><question-filled /></el-icon>
                </el-tooltip>
                组件路径
              </span>
            </template>
            <el-input v-model="formData.component" placeholder="请输入组件路径" />
          </el-form-item>
        </el-col>
        <el-col :span="12" v-if="formData.menuType != 'M'">
          <el-form-item>
            <el-input v-model="formData.perms" placeholder="请输入权限标识" maxlength="100" />
            <template #label>
              <span>
                <el-tooltip
                  content="控制器中定义的权限字符，如：@PreAuthorize(`@ss.hasPermi('system:user:list')`)"
                  placement="top"
                >
                  <el-icon><question-filled /></el-icon>
                </el-tooltip>
                权限字符
              </span>
            </template>
          </el-form-item>
        </el-col>
        <el-col :span="12" v-if="formData.menuType == 'C'">
          <el-form-item>
            <el-input v-model="formData.query" placeholder="请输入路由参数" maxlength="255" />
            <template #label>
              <span>
                <el-tooltip content='访问路由的默认传递参数，如：`{"id": 1, "name": "ry"}`' placement="top">
                  <el-icon><question-filled /></el-icon>
                </el-tooltip>
                路由参数
              </span>
            </template>
          </el-form-item>
        </el-col>
        <el-col :span="12" v-if="formData.menuType == 'C'">
          <el-form-item>
            <template #label>
              <span>
                <el-tooltip content="选择是则会被`keep-alive`缓存，需要匹配组件的`name`和地址保持一致" placement="top">
                  <el-icon><question-filled /></el-icon>
                </el-tooltip>
                是否缓存
              </span>
            </template>
            <el-radio-group v-model="formData.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="formData.menuType != 'F'">
          <el-form-item>
            <template #label>
              <span>
                <el-tooltip content="选择隐藏则路由将不会出现在侧边栏，但仍然可以访问" placement="top">
                  <el-icon><question-filled /></el-icon>
                </el-tooltip>
                显示状态
              </span>
            </template>
            <el-radio-group v-model="formData.visible">
              <el-radio label="0">显示</el-radio>
              <el-radio label="1">隐藏</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item>
            <template #label>
              <span>
                <el-tooltip content="选择停用则路由将不会出现在侧边栏，也不能被访问" placement="top">
                  <el-icon><question-filled /></el-icon>
                </el-tooltip>
                菜单状态
              </span>
            </template>
            <el-radio-group v-model="formData.status">
              <el-radio-group v-model="formData.status">
                <el-radio label="0">正常</el-radio>
                <el-radio label="1">停用</el-radio>
              </el-radio-group>
            </el-radio-group>
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="handleCancel">取消</el-button>
        <el-button type="primary" class="ml30" v-throttle="handleSubmit">确定</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script lang="ts" setup name="editTeamMember">
import { reactive, ref, defineExpose, inject, nextTick, computed, Ref } from "vue";
import { FormInstance, FormRules, ElMessage } from "element-plus";
import { editMenu, addMenu } from "@/api/modules/system/menu";
import { Menu } from "@/api/interface";
import { QuestionFilled } from "@element-plus/icons-vue";
import SelectIcon from "@/components/SelectIcon/index.vue";

//* 接收注入
const dialogVisible = ref(false);
//* data
//* ref
const formRef = ref<FormInstance>();
const openPromise = ref<any>({});
const menuOptions = inject<Ref>("menuOptions", ref([]));
const isAdd = ref(false);
interface FormData extends Partial<Menu.ResMenuList> {
  [key: string]: any;
}
const formData = reactive<FormData>(getFormDefaultValue());
//* 方法

// 校验规则
let formRules = reactive<FormRules>({
  menuName: [{ required: true, message: "菜单名称不能为空", trigger: "blur" }],
  orderNum: [{ required: true, message: "菜单顺序不能为空", trigger: "blur" }],
  path: [{ required: true, message: "路由地址不能为空", trigger: "blur" }]
});

// 添加主目录，过滤按钮
const rootMenuOptions = computed(() => {
  const filter = (tree: any) => {
    let filtered: any = [];

    for (let node of tree) {
      if (node.menuType !== "F") {
        // 保留节点
        let filteredNode = { ...node };

        // 过滤子节点
        if (node.children) {
          filteredNode.children = filter(node.children);
        }

        filtered.push(filteredNode);
      }
    }

    return filtered;
  };
  return [
    {
      menuId: 0,
      menuName: "主目录",
      children: filter(menuOptions.value)
    }
  ];
});

function getFormDefaultValue(): FormData {
  return {
    menuId: undefined,
    parentId: 0,
    menuName: undefined,
    component: undefined,
    path: undefined,
    icon: undefined,
    menuType: "M",
    orderNum: undefined,
    isFrame: "1",
    isCache: "0",
    visible: "0",
    status: "0"
  };
}

function hanldeBeforeClose() {
  dialogVisible.value = false;
  const defaultValue = getFormDefaultValue();
  for (const key of Object.keys(defaultValue)) {
    formData[key] = defaultValue[key];
  }
  nextTick(formRef.value?.clearValidate);
}
// 取消
function handleCancel() {
  dialogVisible.value = false;
}
//提交
function handleSubmit() {
  formRef.value?.validate(async valid => {
    if (!valid) return;
    const params = {
      ...formData,
      icon: formData.icon || "#"
    };
    if (isAdd.value) {
      await addMenu(params);
      ElMessage.success("新增成功");
    } else {
      await editMenu(params);
      ElMessage.success("编辑成功");
    }
    openPromise.value.resolve();
    dialogVisible.value = false;
  });
}

function open(params?: FormData) {
  isAdd.value = !params?.menuId;
  dialogVisible.value = true;
  if (params) {
    if (params.menuId) {
      for (const key of Object.keys(formData)) {
        formData[key] = params[key];
      }
    } else {
      formData.parentId = params.parentId;
    }
  }
  return new Promise(resolve => {
    openPromise.value.resolve = resolve;
  });
}
defineExpose({
  open
});
</script>

<style lang="scss"></style>
