<template>
  <el-dialog
    v-model="visible"
    :title="type === 'edit' ? '修改' : '新增'"
    :before-close="fnClose"
  >
    <el-form ref="formRef" :rules="rules" :model="form" label-width="110px">
      <el-form-item label="名称" prop="roleName">
        <el-input v-model="form.roleName" placeholder="请输入名称" />
      </el-form-item>
      <el-form-item label="备注" prop="remark">
        <el-input
          v-model="form.remark"
          type="textarea"
          :autosize="{ minRows: 1 }"
          placeholder="请输入备注"
        />
      </el-form-item>
      <el-form-item label="类型" prop="type">
        <el-select v-model="form.type" placeholder="请选择类型">
          <el-option
            v-for="item in options"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
      </el-form-item>
      <el-form-item
        v-show="form.type === 2 || form.type === 3"
        label="服务平台"
        prop="servicePlatformId"
      >
        <el-select
          v-model="form.servicePlatformId"
          placeholder="请选择服务平台"
          multiple
          @change="fnGetCompanyOptions"
        >
          <el-option
            v-for="item in servicePlatformOptions"
            :key="item.id"
            :label="item.serviceName"
            :value="item.id"
          />
        </el-select>
      </el-form-item>
      <el-form-item v-show="form.type === 3" label="企业" prop="companyId">
        <el-select v-model="form.companyId" multiple placeholder="请选择类型">
          <el-option
            v-for="item in companyOptions"
            :key="item.id"
            :label="`${item.companyName}（${item.servicePlatformName}）`"
            :value="item.id"
          />
        </el-select>
      </el-form-item>
      <el-form-item v-if="form.parentId !== '0'" label="菜单" prop="menuIdList">
        <el-tree
          ref="treeRef"
          node-key="menuId"
          :data="menusAll"
          :props="{
            label: 'name',
            children: 'list',
          }"
          show-checkbox
        />
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="fnClose">关闭</el-button>
      <el-button type="primary" @click="fnSubmit">确定</el-button>
    </template>
  </el-dialog>
</template>

<script setup>
import { debounce } from "throttle-debounce";
import useForm from "@/hooks/useForm.js";
import { ElMessage } from "element-plus";
import { nextTick, ref, watchEffect, watch } from "vue";
import {
  getRouteList,
  setRoleAdd,
  setRoleEdit,
  getBusServicePlatformListAllName,
  getBusCompanyInfoListAllName,
} from "@/request/system_management.js";

const props = defineProps({
  type: {
    type: String,
    required: true,
  },
});
const emits = defineEmits(["getData"]);
const visible = defineModel("visible", { type: Boolean, required: true });
const form = defineModel("form", { type: Object, required: true });
const { formRef, validate, reset } = useForm();
const treeRef = ref(null);
const menusAll = ref([]);
const rules = {
  roleName: [
    { required: true, message: "名称不能为空", trigger: "blur" },
    { min: 2, max: 30, message: "长度在2到30个字符", trigger: "blur" },
  ],
  type: [{ required: true, message: "类型不能为空", trigger: "change" }],
};
const options = [
  { label: "系统角色", value: 1 },
  { label: "服务平台角色", value: 2 },
  { label: "企业角色", value: 3 },
];
const servicePlatformOptions = ref([]);
const companyOptions = ref([]);
watch(
  () => form.value.type,
  async (val) => {
    if (val !== 1) await fnGetServicePlatformOptions();
    if (val === 3) await fnGetCompanyOptions();
  }
);
const fnGetServicePlatformOptions = async () => {
  if (servicePlatformOptions.value.length === 0) {
    const { data } = await getBusServicePlatformListAllName();
    servicePlatformOptions.value = data;
  }
};
const fnGetCompanyOptions = async () => {
  if (form.value.type !== 3 || form.value.servicePlatformId.length === 0)
    return;
  const { data } = await getBusCompanyInfoListAllName({
    servicePlatformIds: form.value.servicePlatformId.join(","),
  });
  companyOptions.value = data;
};
const fnGetData = async () => {
  const resData = await getRouteList({ parentId: 0 });
  menusAll.value = fnConversion(resData.menuList);
};
const fnConversion = (menuList) => {
  for (let i = 0; i < menuList.length; i++) {
    menuList[i].meta = JSON.parse(menuList[i].meta);
    if (menuList[i].type === 1) {
      menuList[i].name = (menuList[i].name || "首页") + "（页面）";
    }
    if (menuList[i].type === 2) {
      menuList[i].name = menuList[i].name + "（按钮）";
    }
    if (menuList[i].list.length > 0) {
      fnConversion(menuList[i].list);
    }
  }
  return menuList;
};
const fnClose = () => {
  reset();
  visible.value = false;
  treeRef.value?.setCheckedKeys([]);
};
watchEffect(async () => {
  if (visible.value) {
    await fnGetData();
    await nextTick();
    let checkedKeys = [];
    form.value.menuIdList.forEach((item) => {
      checkedKeys = fnGetChecked(item, menusAll.value, checkedKeys);
    });
    treeRef.value?.setCheckedKeys(checkedKeys);
  }
});
const fnGetChecked = (menuId, menusAll, checkedKeys) => {
  for (let i = 0; i < menusAll.length; i++) {
    if (menuId === menusAll[i].menuId) {
      if (menusAll[i].list.length === 0) {
        checkedKeys.push(menusAll[i].menuId);
        break;
      }
    } else {
      if (menusAll[i].list.length > 0) {
        fnGetChecked(menuId, menusAll[i].list, checkedKeys);
      }
    }
  }
  return checkedKeys;
};
const fnSubmit = debounce(
  1000,
  async () => {
    await validate();
    const checkedKeys = treeRef.value?.getCheckedKeys() || [];
    const halfCheckedKeys = treeRef.value?.getHalfCheckedKeys() || [];
    const servicePlatformId = form.value.servicePlatformId.join(",");
    const companyId = form.value.companyId.join(",");
    if (props.type === "add") {
      await setRoleAdd({
        ...form.value,
        menuIdList: [...checkedKeys, ...halfCheckedKeys],
        roleId: undefined,
        servicePlatformId,
        companyId,
      });
    }
    if (props.type === "edit")
      await setRoleEdit({
        ...form.value,
        menuIdList: [...checkedKeys, ...halfCheckedKeys],
      });
    ElMessage.success("操作成功");
    fnClose();
    emits("getData");
  },
  { atBegin: true }
);
</script>

<style lang="scss" scoped>
:deep(.el-tree) {
  width: 100%;
}
</style>
