<template>
  <div class="menu">
    <div class="menu-system">
      <span>{{ $t("TERMINAL") }}：</span>
      <a-select
        v-model="menuForm.clientType"
        class="d-inline-block"
        :placeholder="$t('PLACESELECT')"
        @change="moduleChange"
      >
        <a-select-option
          v-for="item in moduleList"
          :key="item.value"
          :value="item.value"
        >
          {{ $t(item.label) }}
        </a-select-option>
      </a-select>
    </div>
    <MomTable
      ref="MomTable"
      row-key="id"
      :row-selection="rowSelection"
      :init-call="false"
      :columns="columns"
      :data-source="menuList"
      :mega-extend="{
        rowIndex: false,
      }"
      :expand-icon-column-index="1"
      :action-buttons="tableAction"
      :pagination="false"
      :expanded-row-keys="expandedRowKeys"
      @expand="expandedOnClickIcon"
      @add="add"
      @edit="edit"
      @delete="del"
    >
      <template slot="toolbar">
        <a-button v-if="hasAuth('MENU_MANAGEMENT:ADD')" @click="addMenu">
          <a-icon type="plus" /> {{ $t("ADD") }}
        </a-button>
        <a-button
          :icon="isExpand ? 'up' : 'down'"
          class="btn__blue-4"
          @click="expandedAllRowsChange"
        >
          {{ isExpand ? $t("FOLD") : $t("UNFOLD") }}
        </a-button>
        <a-button
          v-if="hasAuth('MENU_MANAGEMENT:BATCH_DELETE')"
          type="danger"
          icon="delete"
          @click="handDelete"
        >
          {{ $t("BATCH_DELETE") }}
        </a-button>
      </template>
      <span slot="menuName" slot-scope="text">{{ $t(text) }}</span>
      <span slot="icon" slot-scope="text">
        <i v-if="text" class="mr-7" />
        <Icon v-if="text" :type="text" :size="18" />
      </span>
    </MomTable>
  </div>
</template>
<script>
import { reduce as _reduce, uniqBy } from "lodash";
import { deleteLeafArray, getLevelMark } from "@mega-apps/utils";
import { Icon } from "@mega-design/ui-vue";
import ApiConstant from "@/api/ApiConstant";
import { loadGlobalLoading } from "@/plugins/axios";
import { exportExcel } from "@/utils";

export default {
  components: { Icon },
  data() {
    return {
      menuTypeList: [], // 菜单类型
      whetherCharList: [], // Y/N <==> 是否
      menuFrameList: [], // 菜单外链类型
      menuFrameOpenList: [], // 菜单外链打开类型
      menuTab: [], // 菜单tab
      clientType: "", // 菜单tab key
      tableAction: [
        this.hasAuth("MENU_MANAGEMENT:ADD") && "add",
        this.hasAuth("MENU_MANAGEMENT:EDIT") && "edit",
        this.hasAuth("MENU_MANAGEMENT:DELETE") && "delete",
      ],
      expandedRowKeys: [],
      activeModule: "", // 选中的菜单
      menuList: [], // 表格数据
      // 表格列数据
      columns: [
        {
          dataIndex: "menuName",
          sorter: false,
          title: () => this.$t("MENU_NAME"),
          width: 260,
          dynamic: false,
          scopedSlots: { customRender: "menuName" },
        },
        {
          dataIndex: "icon",
          sorter: false,
          title: () => this.$t("ICON"),
          width: 110,
          scopedSlots: { customRender: "icon" },
        },
        {
          dataIndex: "menuTypeText",
          sorter: false,
          title: () => this.$t("TYPE"),
          width: 82,
        },
        {
          dataIndex: "seq",
          sorter: false,
          title: () => this.$t("SORT"),
          width: 82,
        },
        {
          dataIndex: "perms",
          sorter: false,
          title: () => this.$t("PERMISSION_ID"),
          width: 380,
        },
        {
          dataIndex: "isFrameText",
          sorter: false,
          title: () => this.$t("OUTSIDE"),
          width: 82,
        },
        {
          dataIndex: "openTypeText",
          sorter: false,
          title: () => this.$t("OPEN_TYPE"),
          width: 110,
        },
        {
          dataIndex: "frameTypeText",
          sorter: false,
          title: () => this.$t("FRAME_TYPE"),
          width: 110,
        },
        {
          dataIndex: "menuPath",
          sorter: false,
          title: () => this.$t("MENU_PATH"),
          minWidth: 260,
          ellipsis: true,
        },
        {
          dataIndex: "visibleText",
          sorter: false,
          title: () => this.$t("VISIBLE"),
          width: 82,
        },
        {
          dataIndex: "updateBy",
          sorter: false,
          title: () => this.$t("UPDATE_BY"),
          width: 120,
        },
        {
          dataIndex: "updateTime",
          sorter: false,
          title: () => this.$t("UPDATE_TIME"),
          width: 168,
        },
      ],
      menuListCode: [], // 表格数据的所有code
      // 下拉数据菜单
      moduleList: [],
      // 是否展开
      isExpand: false,
      id: "",
      menuForm: {
        name: "",
        clientType: "",
        menuCode: "",
        parentMenuCode: "",
        parentId: "",
        parentName: "",
        menuType: "MODULE",
        mobileAppFlag: "0",
        appHomeUrl: "",
        backgroundColor: "",
        isFrame: "N",
        openType: "",
        frameType: "",
        reportServerCode: "",
        icon: "",
        treeLevel: 0,
        seq: "",
        menuName: "",
        isRelated: "N", // 是否关联路由
        menuPath: "",
        component: "",
        perms: "",
        keepAlive: "0",
        menuTag: "",
        visible: "Y",
        weight: "",
      },
      selectedRowKeys: [],
      selectedRows: [],
    };
  },
  computed: {
    rowSelection() {
      return {
        selectedRowKeys: this.selectedRowKeys,
        onChange: (selectedRowKeys, selectedRows) => {
          this.selectedRowKeys = selectedRowKeys;
          if (this.selectedRowKeys.length) {
            this.selectedRows = uniqBy(this.selectedRows.concat(selectedRows));
          } else {
            this.selectedRows = selectedRows;
          }
        },
      };
    },
    menuFormRules() {
      return {
        menuCode: [
          {
            required: true,
            message: this.$t("PLACEENTER"),
            trigger: "blur",
          },
        ],
        menuName: [
          {
            required: true,
            message: this.$t("PLACEENTER"),
            trigger: "blur",
          },
        ],
        menuPath: [
          {
            required: true,
            message: this.$t("PLACEENTER"),
            trigger: "blur",
          },
        ],
        component: [
          {
            required: true,
            message: this.$t("PLACEENTER"),
            trigger: "blur",
          },
        ],
        openType: [
          {
            required: true,
            message: this.$t("PLACESELECT"),
            trigger: "change",
          },
        ],
        frameType: [
          {
            required: true,
            message: this.$t("PLACESELECT"),
            trigger: "change",
          },
        ],
        reportServerCode: [
          {
            required: true,
            message: this.$t("PLACESELECT"),
            trigger: "change",
          },
        ],
        keepAlive: [
          {
            required: true,
            message: this.$t("PLACESELECT"),
            trigger: "change",
          },
        ],
        perms: [
          {
            max: 64,
            message: this.$t("PLACEENTER") + 64 + this.$t("LENGTH_TIP"),
            trigger: "blur",
          },
        ],
      };
    },
  },
  async created() {
    await this.tableBeforeSearch();
    // 处理选中 第一个终端类型
    if (this.moduleList.length) {
      if (this.$store.state.app.isMenuTerminal) {
        if (this.$store.state.app.isMenuTerminal) {
          this.menuForm.clientType = this.$store.state.app.isMenuTerminal;
          this.moduleChange(this.menuForm.clientType);
        }
      } else {
        const { value } = this.moduleList[0];
        this.menuForm.clientType = value;
        this.moduleChange(value);
      }
    }
  },
  async mounted() {
    if (this.$store.state.app.isMenuKeys) {
      if (this.menuForm.clientType) {
        await this.moduleChange(this.menuForm.clientType);
      }
    }
  },
  methods: {
    tableBeforeSearch() {
      return Promise.all([
        // 获取 菜单类型
        this.getDictByCode("DIC:CORE:SYS_MENU_TPYE"),
        // 获取 菜单外链类型
        this.getDictByCode("DIC:CORE:SYS_FRAME_TYPE"),
        // 获取 菜单外链打开类型
        this.getDictByCode("DIC:CORE:SYS_OUTER_LINK_OPEN_TYPE"),
        // 获取 Y/N <==> 是否
        this.getDictByCode("DIC:COMMON:WHETHER_CHAR"),
        // 终端
        this.getDictByCode("DIC:CORE:MENU_CLIENT"),
      ]).then(
        ([menuTypeRes, frameTypeRes, openTypeRes, whetherRes, clientRes]) => {
          this.menuTypeList = menuTypeRes.data?.data;
          this.menuFrameList = frameTypeRes.data?.data;
          this.menuFrameOpenList = openTypeRes.data?.data;
          this.whetherCharList = whetherRes.data?.data;
          this.moduleList = clientRes.data.data;
        }
      );
    },
    // 模块切换，获取菜单
    moduleChange(moduleCode) {
      this.$axios
        .get(
          `${ApiConstant.PREFIX_CORE}/api/sys/menu/list-system-menu/${moduleCode}`
        )
        .then((res) => {
          deleteLeafArray(res.data.data, "children");
          this.menuListCode = getLevelMark(res.data.data, "children", "code");
          const fn = (data, arr = []) => {
            data.forEach((item) => {
              arr.push({
                ...item,
                menuTypeText: this.getAttrValue(
                  this.menuTypeList,
                  item.menuType
                ),
                isFrameText: this.getAttrValue(
                  this.whetherCharList,
                  item.isFrame
                ),
                openTypeText: this.getAttrValue(
                  this.menuFrameOpenList,
                  item.openType
                ),
                frameTypeText: this.getAttrValue(
                  this.menuFrameList,
                  item.frameType
                ),
                visibleText: this.getAttrValue(
                  this.whetherCharList,
                  item.visible
                ),
              });
              if (item.children && item.children.length) {
                // eslint-disable-next-line no-param-reassign
                arr[arr.length - 1].children = [];
                fn(item.children, arr[arr.length - 1].children);
              }
            });
            return arr;
          };
          this.menuList = fn(res.data.data);
          if (this.expandedRowKeys.length === this.menuListCode.length) {
            this.isExpand = true;
          } else {
            this.isExpand = false;
          }
          // 配置从新增和编辑回到列表页做的展开
          const arrKeys = JSON.parse(
            JSON.stringify(this.$store.state.app.isMenuKeys)
          );
          let arr = [];
          if (arrKeys.length > 0) {
            arr = arrKeys.includes(",")
              ? arrKeys?.split(",")
              : arrKeys?.split();
            if (arr?.length > 0) {
              this.expandedRowKeys = arr;
            }
          }
        });
    },
    // 展开/收起所有行
    expandedAllRowsChange() {
      loadGlobalLoading(1, this.$i18n);
      // setTimeout 不能修改为 $nextTick 原因请有兴趣的同学研究
      setTimeout(() => {
        if (this.expandedRowKeys.length === this.menuListCode.length) {
          this.expandedRowKeys = [];
          this.isExpand = false;
        } else {
          this.expandedRowKeys = [...this.menuListCode];
          this.isExpand = true;
        }
        loadGlobalLoading(0);
      }, 200);
    },
    expandedOnClickIcon(expanded, record) {
      if (expanded) {
        this.expandedRowKeys.push(record.code);
      } else {
        const index = this.expandedRowKeys.findIndex((e) => e === record.code);
        index !== -1 && this.expandedRowKeys.splice(index, 1);
      }
    },
    // 添加菜单
    addMenu() {
      this.$router.push({
        path: "/upms/system/setting/menu/add",
        query: {
          clientType: this.menuForm.clientType,
        },
      });
      this.$store.commit(
        "app/SET_IS_MENU_KEYS",
        this.expandedRowKeys.toString()
      );
      this.$store.commit(
        "app/SET_IS_MENU_TERMINAL",
        this.menuForm.clientType.toString()
      );
    },

    add(row) {
      this.$router.push({
        path: "/upms/system/setting/menu/add",
        query: {
          parentId: row.id,
          clientType: this.menuForm.clientType,
        },
      });
      this.$store.commit(
        "app/SET_IS_MENU_KEYS",
        this.expandedRowKeys.toString()
      );
      this.$store.commit(
        "app/SET_IS_MENU_TERMINAL",
        this.menuForm.clientType.toString()
      );
    },
    // 编辑按钮点击事件
    edit(row) {
      this.$router.push({
        path: "/upms/system/setting/menu/edit",
        query: {
          id: row.id,
          clientType: this.menuForm.clientType,
        },
      });
      this.$store.commit(
        "app/SET_IS_MENU_KEYS",
        this.expandedRowKeys.toString()
      );
      this.$store.commit(
        "app/SET_IS_MENU_TERMINAL",
        this.menuForm.clientType.toString()
      );
    },
    del(row) {
      this.$confirm({
        title: this.$t("DELETE"),
        content: this.$t("DELETE_INFO"),
        okType: "warning",
        okText: this.$t("CONFIRM"),
        cancelText: this.$t("CANCEL"),
        centered: false,
        icon: "close-circle",
        onOk: () => {
          this.$axios
            .delete(`${ApiConstant.PREFIX_CORE}/api/sys/menu/${row.id}`)
            .then((res) => {
              this.$message.success(this.$t("SUBMITTED_FOR_DELETION"));
              this.moduleChange(row.clientType);
            });
        },
      });
    },
    handDelete() {
      if (this.selectedRowKeys.length > 0) {
        this.$confirm({
          title: this.$t("DELETE"),
          content: this.$t("DELETE_INFO"),
          okType: "warning",
          okText: this.$t("CONFIRM"),
          cancelText: this.$t("CANCEL"),
          centered: false,
          icon: "close-circle",
          onOk: () => {
            this.$axios
              .delete(`${ApiConstant.PREFIX_CORE}/api/sys/menu/batch-delete`, {
                params: {
                  ids: this.selectedRowKeys.join(","),
                },
              })
              .then((res) => {
                this.$message.success(this.$t("SUBMITTED_FOR_DELETION"));
                this.moduleChange(this.selectedRows[0]?.clientType);
              });
          },
        });
      } else {
        this.$message.error(this.$t("SELECT_ONE_DATA"));
      }
    },
    // 导出菜单功能
    handleExportExcel() {
      this.$axios({
        url: `${ApiConstant.PREFIX_CORE}/api/sys/menu/export?clientType=${this.menuForm.clientType}`,
        method: "get",
        responseType: "blob",
      }).then((res) => {
        exportExcel(res.data, `${this.$t("MENU_MANAGEMENT")}.xls`);
      });
    },
  },
};
</script>
<style lang="less" scoped>
.menu {
  .menu-system {
    padding: 10px 20px 0;
    border-bottom: 10px solid #f0f2f5;
    .ant-select {
      margin-bottom: 10px;
      width: 260px;
    }
  }
}
</style>
