<template>
  <div class="es-main">
    <div class="es-simplicity-side">
      <img class="es-simplicity-logo" v-if="mainLogo" :src="mainLogo" />
      <div
        class="es-simplicity-org-name es-text-ellipsis-row4"
        :title="simpleUserInfo.orgShortName || simpleUserInfo.orgName"
      >
        {{ simpleUserInfo.orgShortName || simpleUserInfo.orgName }}
      </div>
      <el-dropdown
        v-if="
          jobExplicited && user.identityList && user.identityList.length > 1
        "
        trigger="click"
        placement="bottom-start"
        @command="handleDepSelect"
      >
        <div class="es-simplicity-dep-post">
          <span class="es-simplicity-dep-name"> {{ user.depName }}</span>
          <template v-if="user.postName">
            |
            <span class="es-simplicity-post-name">{{
              user.position || user.postName
            }}</span>
          </template>
          <i class="es-icon-qiehuangangwei"></i>
        </div>
        <el-dropdown-menu slot="dropdown">
          <el-dropdown-item
            v-for="item in user.identityList"
            :key="item.id"
            :command="item"
            :class="{ 'is-active': user.identityId == item.id }"
            >{{ item.name }}</el-dropdown-item
          >
        </el-dropdown-menu>
      </el-dropdown>
      <el-popover
        class="es-simplicity-user-popover"
        placement="right-start"
        width="360"
        trigger="click"
      >
        <!-- 用户信息 -->
        <user
          ref="user"
          :user="user"
          :notifyList="notifyList"
          :notify="notify"
          :contents="userInfoContents"
          @success="handleSuccess"
          @change="handleChangeConfig"
          @close="handlerClose"
        ></user>
        <div slot="reference" class="es-simplicity-pannel-user">
          <avatar
            v-show="showAvatar"
            :user="user"
            :size="56"
            :show-name="true"
          ></avatar>
          <div class="es-simplicity-greeting" v-show="!showAvatar">
            {{ greeting }}
          </div>
          <div class="es-simplicity-username">{{ user.username }}</div>
        </div>
        <!-- 用户信息 end -->
      </el-popover>
      <div class="es-simplicity-side-Application">
        <!-- 常用应用 -->
        <el-scrollbar>
          <div
            class="es-simplicity-side-app"
            v-for="item in userApps"
            :class="{ 'is-active': active == item.id }"
            :key="item.id"
            :title="item.text || item.name"
            @click="handlerClickApp(item)"
          >
            <el-badge
              class="es-simplicity-side-app-badge"
              v-bind="getBadge(item)"
            >
              <es-icon
                class="es-simplicity-side-app-icon"
                :contents="item.icons || item.icon || menuIcon"
              ></es-icon>
              <div class="es-simplicity-side-app-text">
                {{ item.text || item.name }}
              </div>
            </el-badge>
          </div>
          <div
            class="es-simplicity-side-app"
            @click="handlerClickApp()"
            v-show="applications.length"
          >
            <es-icon
              class="es-simplicity-side-app-icon"
              contents="es-icon-more"
            ></es-icon>
            <div class="es-simplicity-side-app-text">更多</div>
          </div>
          <div
            class="es-simplicity-side-app"
            v-for="(item, index) in newApps"
            :class="{ 'is-active': active == item.id }"
            :key="item.id"
            :title="item.text || item.name"
            @click.stop="handlerClickApp(item)"
          >
            <i
              class="el-icon-circle-close"
              @click.stop="handleDelete(index)"
            ></i>
            <el-badge v-bind="getBadge(item)">
              <es-icon
                class="es-simplicity-side-app-icon"
                :contents="item.icons || item.icon || menuIcon"
              ></es-icon>
              <div class="es-simplicity-side-app-text">
                {{ item.text || item.name }}
              </div>
            </el-badge>
          </div>
        </el-scrollbar>
        <!-- 常用应用 end -->
      </div>
      <div class="es-simplicity-side-app" v-if="_aiConfig && showAi">
        <img
          :src="_aiConfig.icon"
          class="es-simplicity-ai-icon"
          @click="handlerSetDrawer(_aiConfig, 'ai')"
        />
      </div>
    </div>
    <div class="es-simplicity-main">
      <!-- 应用 -->
      <apps
        :visible.sync="showApps"
        :menu-icon="menuIcon"
        :color="appColor"
        :backgroundColor="appBackgroundColor"
        :applications="applications"
        :business="business"
        :systems="systems"
        :user="user"
        @click="handlerClickApps"
      ></apps>
      <!-- 应用 end -->

      <!-- AI/IM -->
      <el-drawer
        class="es-simplicity-public-drawer"
        :direction="drawer.direction"
        modal-class="es-simplicity-apps-modal"
        size="100%"
        show-close
        :modal-append-to-body="false"
        :visible.sync="drawer.visible"
      >
        <div
          class="es-public-drawer-main"
          v-if="drawer.ai && drawer.ai.url"
          v-show="drawer.active == 'ai'"
        >
          <template v-if="isIE || drawer.ai.method !== 'wujie'">
            <iframe
              frameborder="0"
              width="100%"
              height="100%"
              :src="drawer.ai.url"
            ></iframe>
          </template>
          <template v-else>
            <es-wujie
              :host="host"
              :show="true"
              :props="wjProps"
              :attrs="wjAttrs"
              :name="drawer.ai.name"
              :url="drawer.ai.url"
            ></es-wujie>
          </template>
        </div>
        <div
          class="es-public-drawer-main"
          v-if="drawer.im && drawer.im.url"
          v-show="drawer.active == 'im'"
        >
          <template v-if="isIE || drawer.im.method !== 'wujie'">
            <iframe
              frameborder="0"
              width="100%"
              height="100%"
              :src="drawer.im.url"
            ></iframe>
          </template>
          <template v-else>
            <es-wujie
              :host="host"
              :show="true"
              :props="wjProps"
              :attrs="wjAttrs"
              :name="drawer.im.name"
              :url="drawer.im.url"
            ></es-wujie>
          </template>
        </div>
      </el-drawer>
      <!-- AI/IM end -->

      <!-- 路由、iframe -->
      <div class="es-simplicity-tabs-handler-mask" v-show="showTabsHandler">
        <el-card class="es-simplicity-tabs-handler" ref="tabsHandler">
          <div
            class="es-simplicity-tabs-handler-item"
            :class="{ 'is-disabled': isDisabled.refresh }"
            @click="isDisabled.refresh ? '' : handleTabsEvents(0)"
          >
            刷新
          </div>
          <div
            class="es-simplicity-tabs-handler-item"
            @click="handleTabsEvents(1)"
          >
            关闭标签
          </div>
          <div
            class="es-simplicity-tabs-handler-item"
            :class="{ 'is-disabled': isDisabled.other }"
            @click="isDisabled.other ? '' : handleTabsEvents(2)"
          >
            关闭其他
          </div>
          <div
            class="es-simplicity-tabs-handler-item"
            :class="{ 'is-disabled': isDisabled.left }"
            @click="isDisabled.left ? '' : handleTabsEvents(3)"
          >
            关闭左侧
          </div>
          <div
            class="es-simplicity-tabs-handler-item"
            :class="{ 'is-disabled': isDisabled.right }"
            @click="isDisabled.right ? '' : handleTabsEvents(4)"
          >
            关闭右侧
          </div>
        </el-card>
      </div>
      <el-tabs
        class="es-simplicity-iframe"
        :class="{ 'is-open': showMenu, 'is-fold': fold }"
        v-model="activeName"
        closable
        hide-bar
        opacity
        @tab-click="handleTabClick"
        @tab-remove="handleRemove"
        @tab-contextmenu="handleContextmenu"
      >
        <!-- 操作栏 -->
        <handler
          slot="append"
          v-bind="handleConfig"
          :show-title-type="showTitleType"
          :data="_handleDatas"
          :nums="handleNums"
          @click="handleClick"
        ></handler>
        <!-- 操作栏 end-->

        <!-- 菜单 -->
        <sub-menu
          v-if="subMenus"
          :collapse="isCollapse"
          :mode="mode"
          :visible.sync="showMenu"
          :closed.sync="fold"
          :size="menuWidth"
          :title="title"
          :color="menuColor"
          :backgroundColor="menuBackgroundColor"
          :menu-icon="menuIcon"
          :active="subActive"
          v-bind="subMenus"
          @command="handlerClickMenu"
        ></sub-menu>
        <!-- 菜单 end -->
        <el-tab-pane
          v-for="item in tabs"
          :key="item.id"
          :label="item.text || item.name"
          :name="item.id"
        >
          <router-page
            v-if="item.method === 'router'"
            v-bind="item"
            :query="$parent.params"
          ></router-page>
          <iframe
            v-else-if="isIE || item.method == 'iframe'"
            v-loading="item.loading"
            frameborder="0"
            width="100%"
            height="100%"
            :id="activeName == item.id ? iframeId : item.id || item.appCode"
            :name="activeName == item.id ? iframeId : item.id || item.appCode"
            :onload="handleLoadIframe(item)"
            :src="item.url"
          ></iframe>
          <es-wujie
            v-else-if="item.method === 'wujie' && item.url"
            :host="host"
            :show="true"
            :props="wjProps"
            :attrs="wjAttrs"
            :name="item.appCode"
            :url="item.url"
          ></es-wujie>
        </el-tab-pane>
      </el-tabs>
      <!-- 路由、iframe end -->

      <!-- 消息列表 -->
      <message
        v-if="showMsg"
        ref="message"
        :total.sync="handleNums.notice"
        :visible.sync="showMsg"
        :winopen="winopen"
        @ignore="handleChange"
        @handle="handleMenuTips"
      ></message>
      <!-- 消息列表 end-->

      <!-- 设置 -->
      <settings
        v-bind="$attrs"
        layout-type="simplicity"
        active="simplicity"
        :theme="themeColor"
        :predefine="themes"
        :visible.sync="showSet"
        @change="handleChange"
        @layout="handleLayout"
      ></settings>
      <!-- 设置 end-->

      <!-- 消息提醒 -->
      <notice :data="sysMsg" :winopen="winopen" @opened="handleOpened"></notice>
      <!-- 消息提醒 end -->

      <es-dialog
        class="es-public-search-dialog"
        :visible.sync="showSearch"
        size="lg"
      >
        <search
          :apps="applications"
          :menus="menus"
          :menuIcon="menuIcon"
          @select="handleSelect"
        ></search>
      </es-dialog>
      <!-- 公用弹窗 -->
      <es-dialog :title="dialog.title" :visible.sync="dialog.show" size="md">
        <template v-if="dialog.title == '查看在线人员' && !dialog.src">
          <online></online>
        </template>
        <iframe
          v-else-if="dialog.show"
          width="100%"
          height="100%"
          frameborder="0"
          :src="dialog.src"
        ></iframe>
      </es-dialog>
      <!-- 公用弹窗 end -->
    </div>
  </div>
</template>

<script>
import avatar from './avatar.vue';
import handler from './handler.vue';
import subMenu from './sub-menu.vue';
import apps from './apps.vue';
import user from './user.vue';
import message from './message.vue';
import notice from './notice.vue';
import settings from '../public/settings.vue';
import routerPage from './router-page.vue';
import online from '../public/online.vue';
import search from '../public/search.vue';
import {
  wss,
  logout,
  topic,
  getUserAppWithTag,
  recordUserApp,
  getComplexApplications,
  getComplexApplicationsNew
} from 'eoss-ui/src/config/api.js';
import store from 'eoss-ui/src/utils/store';
import util from 'eoss-ui/src/utils/util';
const isIE = /MSIE|Trident/.test(navigator.userAgent);
const systemMode = util.getWinTopProperty('systemMode', 'default');
import WujieVue from 'wujie-vue2';
let events = [
  (tabs, index, that) => {
    let tab = tabs[index];
    if (tab.method == 'iframe') {
      tabs[index].url = util.handlerUrl(tab.url);
    }
    if (tab.method === 'wujie' && tab.appCode) {
      const url = tab.url;
      tab.url = '';
      that.$nextTick(() => {
        tab.url = url;
      });
    }
    if (tab.method === 'router') {
      that.$set(tabs[index], 'keys', util.uuid());
    }
    return tabs;
  },
  (tabs, index, that) => {
    let i = util.indexOfObj(tabs, that.activeName, 'id');
    if (tabs.length == 1) {
      that.activeName = '';
    } else if (i == index) {
      if (index < tabs.length - 1) {
        that.activeName = tabs[index + 1].id;
      } else {
        that.activeName = tabs[index - 1].id;
      }
    }
    tabs.splice(index, 1);
    return tabs;
  },
  (tabs, index, that) => {
    let tab = tabs.slice(index, index + 1);
    that.activeName = tab[0].id;
    return tab;
  },
  (tabs, index, that) => {
    let i = util.indexOfObj(tabs, that.activeName, 'id');
    if (i < index) {
      that.activeName = tabs[index].id;
    }
    tabs.splice(0, index);
    return tabs;
  },
  (tabs, index, that) => {
    let i = util.indexOfObj(tabs, that.activeName, 'id');
    if (i > index) {
      that.activeName = tabs[index].id;
    }
    tabs.splice(index + 1, tabs.length - index);
    return tabs;
  }
];
export default {
  name: 'Simplicity',
  provide() {
    return {
      esMain: this,
      refresh: this.handleRefresh,
      jumpMenu: this.jumpMenu
    };
  },
  components: {
    avatar,
    handler,
    subMenu,
    apps,
    user,
    message,
    notice,
    settings,
    routerPage,
    online,
    search
  },
  props: {
    //是否显示头像
    avatar: {
      type: Boolean,
      default: true
    },
    //im用例编码
    imUseCaseCode: String,
    //ai用例编码
    aiUseCaseCode: String,
    //模式
    mode: {
      type: String,
      default: systemMode
    },
    sysCode: String,
    appCode: String,
    //logo
    logo: String,
    //菜单、应用默认图标
    menuIcon: {
      type: String,
      default: 'es-icon-application'
    },
    //默认主题颜色
    theme: {
      type: String,
      default: '#409eff'
    },
    //主题颜色选择颜色集合
    themes: Array,
    //操作栏配置
    handleData: {
      type: Array,
      default: () => [
        {
          type: 'contact'
        },
        { type: 'dateTime' },
        { type: 'online' },
        {
          type: 'search',
          icon: 'es-icon-sousuo',
          title: '搜索'
        },
        {
          type: 'im',
          icon: 'es-icon-message',
          title: 'IM'
        },
        {
          type: 'index',
          icon: 'es-icon-zhuomian1',
          title: '门户'
        },
        {
          type: 'home',
          icon: 'es-icon-zhuye',
          title: '首页'
        },
        {
          type: 'notice',
          icon: 'es-icon-xiaoxi1',
          title: '消息'
        },
        {
          type: 'set',
          icon: 'es-icon-shezhi',
          title: '设置'
        },
        {
          type: 'quit',
          icon: 'es-icon-tuichu1',
          title: '退出'
        }
      ]
    },
    //操作栏单项配置
    handleConfig: Object,
    //需要隐藏的头部功能
    hides: Object,
    //菜单颜色
    menuColor: [String, Array],
    //菜单背景颜色
    menuBackgroundColor: [String, Array],
    //菜单是否折叠形式
    collapse: Boolean,
    //应用颜色
    appColor: [String, Array],
    //应用背景颜色
    appBackgroundColor: [String, Array],
    //默认头像
    userHead: String,
    //应用列表接口
    appsUrl: {
      type: String,
      default: getUserAppWithTag
    },
    //是否启用子应用菜单接口
    application: {
      type: Boolean,
      default: false
    },
    //菜单接口
    menuUrl: String,
    //远程请求菜单
    remote: {
      type: Boolean,
      default: true
    },
    //websocket
    socket: {
      type: Boolean,
      default: true
    },
    //iframeId
    iframeId: {
      type: String,
      default: 'stage'
    },
    //查看在线人数
    onlineView: {
      type: [String, Boolean],
      default: true
    },
    //消息办理是否采用window.open的方式打开
    winopen: {
      type: Boolean,
      default: true
    },
    //是否采用wujie微前端加载页面
    loadWujie: {
      type: Boolean,
      default: true
    },
    //无界微前端Props属性
    wjProps: Object,
    //无界微前端Attrs属性
    wjAttrs: Object,
    //菜单宽度
    menuWidth: {
      type: Number,
      default: 220
    },
    showTipNums: {
      type: Boolean,
      default: true
    },
    //路由方式
    routeType: String,
    host: {
      type: String,
      default() {
        return sessionStorage.getItem('host') || '';
      }
    },
    //切换旧版样式
    oldVersion: Boolean,
    //运维联系人
    contacts: Object,
    //展示系统操作按钮标题类型
    showHandlerTitleType: {
      type: String,
      default: 'tooltip',
      validator(val) {
        return ['tooltip', 'text'].includes(val);
      }
    },
    jobExplicit: Boolean
  },
  data() {
    return {
      //是否显示头像
      showAvatar: this.avatar,
      // 问候语
      greeting: util.timeCycle() + '好!',
      //用例权限编码
      useCaseCodes: util.getStorage('useCaseCodes'),
      //显示用户信息
      showUser: false,
      //主题色
      themeColor: this.theme,
      //是否ie浏览器
      isIE: isIE,
      //logo
      mainLogo: this.logo,
      //侧边用户应用
      userApps: [],
      //点击应用存侧边
      newApps: [],
      //所有菜单
      menus: [],
      //菜单名称
      title: '',
      //子菜单
      subMenus: null,
      //展示菜单导航
      showMenu: false,
      //子菜单选中
      subActive: '',
      //折叠菜单
      fold: false,
      //菜单样式是否折叠形式
      isCollapse: this.collapse,
      //人工智能配置
      aiConfig: null,
      //im配置
      imConfig: null,
      //公用窗口面板配置
      drawer: {
        visible: false,
        direction: 'ltr',
        ai: {},
        im: {},
        active: ''
      },
      //所有应用
      applications: [],
      //业务系统
      business: [],
      //系统管理
      systems: [],
      //气泡数
      menuTips: {},
      //展示所有应用
      showApps: false,
      //用户信息
      userModel: {},
      //通知类型列表
      notifyList: [],
      //用户样式
      userStyle: {},
      //通知类型
      notify: '',
      //用户信息表单结构
      userInfoContents: undefined,
      //窗口页签
      tabs: [],
      //页签选中name
      activeName: '',
      //初始应用菜单页
      initApps: null,
      //首页地址
      indexUrl: '',
      //首页名称
      indexTitle: '首页',
      //首页配置
      homePage: {},
      //门户跳转页地址
      doorIndex: '',
      //弹窗
      dialog: {},
      handleNums: {
        //消息数
        notice: 0,
        //在线人数
        online: 1
      },
      //消息列表展示状态
      showMsg: false,
      //搜索
      showSearch: false,
      //即时消息
      sysMsg: [],
      //定时关闭及时消息对象
      sysMsgOut: null,
      //额外信息数据
      extraData: '',
      //显示设置面板
      showSet: false,
      //窗口是否可选
      isDisabled: {},
      //显示页签操作
      showTabsHandler: false,
      //页签对象
      pane: null,
      //选中菜单
      active: '',
      //单位名称
      simpleUserInfo: {},
      handleDatas: this.handleData,
      //顶部右侧工具隐藏
      handleHides: '',
      // 显示旧设计
      showOld: this.oldVersion,
      //运维联系人
      contact: this.contacts,
      //单点退出地址
      singleLogout: null,
      //展示系统操作按钮标题类型
      showTitleType: this.showHandlerTitleType,
      jobExplicited: this.jobExplicit
    };
  },
  computed: {
    _handleDatas() {
      const handleDatas = this.handleDatas.filter((item, index) => {
        if (item.type === 'contact' && this.contact) {
          this.$set(this.handleDatas, index, { ...item, ...this.contact });
        }
        if (item.type === 'contact' && !this.contact) {
          return false;
        }
        return !item.hide && !this.hide[item.type];
      });
      return handleDatas;
    },
    //菜单接口
    _menuUrl() {
      if (this.menuUrl) {
        return this.menuUrl;
      }
      if (this.application) {
        return getComplexApplicationsNew;
      }
      return getComplexApplications;
    },
    //人工智能配置
    _aiConfig() {
      return this.aiConfig
        ? {
            ...this.aiConfig,
            icon: 'data:image/png;base64, '
          }
        : false;
    },
    showAi() {
      return this.aiUseCaseCode
        ? this.useCaseCodes.indexOf(this.aiUseCaseCode) > -1
        : true;
    },
    //用户信息
    user() {
      return this.userModel ? this.userModel : store.get('userModel');
    },
    //在线人数列表地址
    onlineUrl() {
      if (this.onlineView) {
        return typeof this.onlineView == 'string' ? this.onlineView : '';
      }
      return false;
    },
    //隐藏操作按键
    hide() {
      let handleHides = {};
      if (this.handleHides) {
        handleHides = JSON.parse(
          this.handleHides.replace(/(['"])?([a-zA-Z0-9_]+)(['"])?:/g, '"$2":')
        );
      }
      let hides = {
        contact: this.contact ? false : true,
        im: this.imConfig
          ? this.imUseCaseCode
            ? this.useCaseCodes.indexOf(this.imUseCaseCode) == -1
            : false
          : true,
        home: this.indexUrl ? false : true,
        index: this.doorIndex ? false : true,
        old: this.showOld ? false : true
      };

      if (this.layout === 'subsystem' || this.application) {
        hides.system = false;
      }
      if (this.layout === 'topside' || this.layout === 'side') {
        hides.user = true;
      }
      return { ...hides, ...this.hides, ...handleHides };
    }
  },
  watch: {
    menuTips: {
      deep: true,
      handler() {
        this.setTips(this.userApps);
        this.setTips(this.applications);
        this.setTips(this.business);
        this.setTips(this.systems);
        this.setTips(this.menus);
      }
    }
  },
  created() {
    this.doorIndex = sessionStorage.getItem('doorIndex');
  },
  mounted() {
    this.handleListener();
  },
  methods: {
    handleDepSelect(res) {
      this.$refs.user.handleSelect(res);
    },
    /**
     * @desc:匹配路由
     * @author huangbo
     * @date 2024年9月7日
     **/
    hasRouter(res, url, code) {
      if (!url) {
        return false;
      }
      if (Array.isArray(res)) {
        for (let i in res) {
          let path = this.hasRouter(res[i], url, code);
          if (path) {
            return path;
          }
        }
      } else {
        let path = res.path;
        if (path !== '/' && path !== '/404') {
          path = path.replace(path[1], path[1].toLowerCase());
        }
        let pathname = url.substring(url.indexOf('#/') + 1);
        pathname = pathname.split('?')[0];
        let appCode;
        if (res.path !== '/' && pathname == path) {
          if (res.components) {
            if (!res.components[code]) {
              console.error(
                '路由“命名视图”规范属性名称与菜单appCode不一致',
                res,
                code
              );
              appCode = Object.keys(res.components).filter((item) => {
                return item !== 'default';
              })[0];
            }
          } else {
            console.error(
              '请根据路由“命名视图”规范，正确添加components属性名称',
              res
            );
          }
          return appCode ? { path: pathname, appCode } : pathname;
        }
        if (res && Object.prototype.hasOwnProperty.call(res, 'children')) {
          let path = this.hasRouter(res.children, url, code);
          if (path) {
            return path;
          }
        }
      }
      return false;
    },
    /**
     * @desc:获取初始数据
     * @author huangbo
     * @date 2024年9月7日
     **/
    init(results, first) {
      this.setConfig(results);
      if (this.remote && first) {
        this.getApplications();
      }
    },
    /**
     * @desc:设置用户配置及信息
     * @author huangbo
     * @date 2024年9月7日
     **/
    setConfig(results) {
      localStorage.setItem('mainConfig', JSON.stringify(results));
      util.setStorage({
        type: this.storage,
        key: {
          depId: results.userModel.depId,
          orgId: results.userModel.orgId,
          userId: results.userModel.userId,
          userName: results.userModel.username || results.userModel.userName,
          useCaseCodes: results.resourceCodes || results.userModel.resourceCodes
        }
      });
      for (let i in results) {
        if (i === 'mainLogoUrl' && results[i]) {
          this.mainLogo = results[i];
        }
        if (
          i === 'mainBannerUrl' &&
          results[i] &&
          this.headerImage === undefined
        ) {
          this.headerImg = results[i];
        }
        if (i === 'initApplication' && results[i]) {
          this.initApps = results[i].split(',');
        }
        if (i === 'indexUrl' && results[i]) {
          this.indexUrl = results[i];
        }
        if (i === 'doorIndex' && results[i]) {
          util.win.open(results[i]);
          this.doorIndex = results[i];
        }
        if (i === 'subsystemName' && results[i]) {
          document.title = results[i];
        }
        if (i === 'loginPage' && results[i]) {
          util.setStorage({ key: 'loginPage', value: results[i] });
        }
        if (i === 'sysLogoIco' && results[i]) {
          localStorage.setItem('sysLogoIco', results[i]);
          util.setFavicon(results[i]);
        }
        if (i === 'userStyle' && results[i]) {
          if (results[i].color) {
            let color = unescape(results[i].color).toLowerCase();
            if (util.startWith(color, '#')) {
              this.themeColor = color;
            }
          }
          if (results[i].indexUrl) {
            this.indexUrl = results[i].indexUrl;
          }
          this.userStyle = results[i];
          this.notify = results[i].notify || '';
        }
        if (i === 'subsystemExtend' && results[i]) {
          if (results[i].indexTitle) {
            this.indexTitle = results[i].indexTitle;
          }
          if (Object.prototype.hasOwnProperty.call(results[i], 'showAvatar')) {
            this.showAvatar = JSON.parse(results[i].showAvatar);
          }
          if (results[i].themeColor) {
            let color = unescape(results[i].themeColor).toLowerCase();
            if (util.startWith(color, '#')) {
              this.themeColor = color;
            }
          }
          //三方单点登录退出地址
          if (results[i].singleLogout) {
            this.singleLogout = results[i].singleLogout.split(',');
          }
          if (results[i].userInfoContents) {
            this.userInfoContents = JSON.parse(results[i].userInfoContents);
          }
          //水印配置
          if (results[i].webPageWatermark) {
            try {
              util.win.webPageWatermark = results[i].webPageWatermark;
              util.watermark(results[i].webPageWatermark);
            } catch (error) {}
          }
          //登录页页面地址
          if (results[i].loginPage) {
            util.setStorage({ key: 'loginPage', value: results[i].loginPage });
          }
          //登录页页面地址
          if (results[i].openModel) {
            util.setStorage({ key: 'openModel', value: results[i].openModel });
          }
          //ai配置
          if (results[i].aiConfig) {
            if (typeof results[i].aiConfig == 'string') {
              try {
                this.aiConfig = JSON.parse(results[i].aiConfig);
              } catch (error) {
                this.aiConfig = { url: results[i].aiConfig };
              }
            } else {
              this.aiConfig = results[i].aiConfig;
            }
          }
          //im配置
          if (results[i].imConfig) {
            if (typeof results[i].imConfig == 'string') {
              try {
                this.imConfig = JSON.parse(results[i].imConfig);
              } catch (error) {
                this.imConfig = { url: results[i].imConfig };
              }
            } else {
              this.imConfig = results[i].imConfig;
            }
          }
          if (results[i].portalPage || results[i].portalpage) {
            this.doorIndex = results[i].portalPage || results[i].portalpage;
          }
          if (results[i].multipleVersion || results[i].oldVersion) {
            this.showOld = results[i].oldVersion
              ? JSON.parse(results[i].oldVersion)
              : true;
          }

          if (results[i].handleDatas) {
            this.handleDatas = JSON.parse(results[i].handleDatas);
          }
          if (results[i].topRightToolHide || results[i].handleHides) {
            this.handleHides = JSON.parse(
              results[i].topRightToolHide || results[i].handleHides
            );
          }
          if (results[i].contact) {
            let contact = JSON.parse(results[i].contact);
            let content = contact.content.split(',');
            this;
            this.contact = {
              ...contact,
              content
            };
          }
          //展示系统操作按钮标题类型
          if (results[i].showHandlerTitleType) {
            this.showTitleType = results[i].showHandlerTitleType;
          }
          //菜单样式是否折叠形式
          if (results[i].menuCollapse !== undefined) {
            this.isCollapse =
              results[i].menuCollapse !== false &&
              results[i].menuCollapse !== 'false';
          }
          //是否显示岗位
          if (results[i].jobExplicit !== undefined) {
            this.jobExplicited =
              results[i].jobExplicit !== false &&
              results[i].jobExplicit !== 'false';
          }
        }
        if (i === 'userModel' && results[i]) {
          if (results[i].userHeadUrl) {
            results[i].userHeadUrl = util.jointUrl({
              url: results[i].userHeadUrl,
              reg: '/main2'
            });
          } else {
            results[i].userHeadUrl = this.userHead;
          }
          this.userModel = results[i];
          if (results[i].openModel) {
            util.setStorage({ key: 'openModel', value: results[i].openModel });
          }
        }
        if (i === 'notifyList' && results[i]) {
          this.notifyList = results[i];
        }
        store.set(i, results[i]);
      }
    },
    /**
     * @desc:获取所有应用
     * @author huangbo
     * @date 2024年9月7日
     **/
    getApplications() {
      let loading = util.loading('', '加载中...');
      util
        .ajax({
          url: this.appsUrl,
          defaults: true
        })
        .then((res) => {
          if (this.socket) {
            this.initWebSocket();
          }
          if (res.rCode === 0) {
            if (res.results && Object.keys(res.results).length) {
              let { all, app_special_business_system, app_system, app_user } =
                res.results;
              this.userApps = app_user.filter((item) => {
                return item.permission !== false;
              });
              this.applications = all;
              this.business = app_special_business_system;
              this.systems = app_system;
              this.setTips(this.userApps);
              this.setTips(this.applications);
              this.setTips(this.business);
              this.setTips(this.systems);
            } else {
              this.$message.error('未分配应用菜单权限，请联系管理员！');
            }
            this.getMenus(loading);
          } else {
            loading.close();
            let msg = res.msg || '系统错误，请联系管理员！';
            this.$message.error(msg);
          }
        })
        .catch((err) => {
          loading.close();
          if (err.message && err.message !== 'canceled') {
            this.$message.error(err.message);
          }
        });
    },
    /**
     * @desc:获取菜单列表
     * @author huangbo
     * @date 2024年9月7日
     **/
    getMenus(loading) {
      const menuData = store.get('nav');
      if (menuData && menuData.length) {
        loading.close();
        this.renderMenus(menuData);
        return;
      }
      util
        .ajax({ url: this._menuUrl })
        .then((res) => {
          loading.close();
          if (res.rCode === 0) {
            if (res.results && res.results.length) {
              //this.$emit('update:menuData', res.results);
              store.set('nav', JSON.parse(JSON.stringify(res.results)));
              this.renderMenus(JSON.parse(JSON.stringify(res.results)));
            } else {
              this.$message.error('未分配菜单权限，请联系管理员！');
            }
          } else {
            let msg = res.msg || '系统错误，请联系管理员！';
            this.$message.error(msg);
          }
        })
        .catch((err) => {
          loading.close();
          if (err.message && err.message !== 'canceled') {
            this.$message.error(err.message);
          }
        });
    },
    /**
     * @desc:处理菜单列表
     * @author huangbo
     * @date 2024年9月7日
     **/
    renderMenus(res) {
      this.menus = res;
      this.setTips(this.menus);
      store.set('nav', this.menus);
      if (this.indexUrl) {
        let obj = this.getMenu(this.menus, this.indexUrl);
        obj = obj
          ? JSON.parse(JSON.stringify(obj))
          : {
              url: this.indexUrl,
              text: this.indexTitle,
              id: '0',
              appCode: 'indexUrl'
            };
        this.homePage = this.setIframeType(obj);
        if (!this.appCode) {
          this.tabs = [this.homePage];
          this.activeName = this.homePage.id;
        }
      }
      if (this.appCode) {
        let code = this.sysCode || this.appCode;
        let app = this.userApps.filter((item) => {
          return item.code === code;
        })[0];
        if (app) {
          this.active = app.id;
          if (app.url) {
            let obj = this.getMenu(this.menus, app.url);
            if (obj) {
              obj = JSON.parse(JSON.stringify(obj));
              let tab = this.setIframeType(obj);
              this.tabs = [tab];
              this.activeName = tab.id;
            } else {
              this.tabs = [app];
            }
          }
        }
        if (this.sysCode) {
          let subMenus = this.getMenu(this.menus, this.sysCode, 'appCode');
          if (subMenus) {
            let obj = this.getMenu(this.menus, this.appCode, 'appCode');
            if (obj) {
              if (obj.url) {
                obj = JSON.parse(JSON.stringify(obj));
              } else {
                obj = JSON.parse(JSON.stringify(this.getFirst(obj)));
              }
              this.subActive = obj.id;
              let tab = this.setIframeType(obj);
              this.tabs = [tab];
              this.activeName = tab.id;
            } else {
              this.subActive = '';
            }
            this.subMenus = subMenus;
            this.showMenu =
              (subMenus.children && subMenus.children.length > 0) ||
              (subMenus.fourthTabs && subMenus.fourthTabs.length > 0);
          } else {
            this.subMenus = null;
            this.showMenu = false;
            this.$message.error('未分配菜单权限，请联系管理员！');
          }
        } else {
          let subMenus = this.getMenu(this.menus, this.appCode, 'appCode');
          if (subMenus) {
            if (this.tabs.length == 0) {
              let obj = this.getFirst(subMenus);
              if (obj) {
                obj = JSON.parse(JSON.stringify(obj));
                this.subActive = obj.id;
                let tab = this.setIframeType(obj);
                this.tabs = [tab];
                this.activeName = tab.id;
              } else {
                this.subActive = '';
              }
            }
            this.subMenus = subMenus;
            this.showMenu =
              (subMenus.children && subMenus.children.length > 0) ||
              (subMenus.fourthTabs && subMenus.fourthTabs.length > 0);
          } else {
            this.subMenus = null;
            this.showMenu = false;
            this.$message.error('未分配菜单权限，请联系管理员！');
          }
        }
      } else if (this.initApps && this.initApps.length && !this.indexUrl) {
        let obj = this.getMenu(
          this.menus,
          this.initApps[this.initApps.length - 1]
        );
        if (obj) {
          let tab = this.setIframeType(JSON.parse(JSON.stringify(obj)));
          this.tabs.push(tab);
          this.activeName = tab.id;
        }
      }
    },
    /**
     * @desc:设置页面加载类型
     * @author huangbo
     * @date 2024年9月7日
     **/
    setIframeType(res) {
      let { url } = res;
      let urls = url.split('?');
      if (urls[0].indexOf('.js') > 1 && !isIE) {
        res.method = 'wujie';
        if (!res.appCode) {
          res.appCode = 'application_' + Date.now();
        }
      } else if (
        urls[0].indexOf('.dhtml') > 0 ||
        (urls[0].indexOf('.html') > 0 && urls[0].indexOf('.html#') === -1)
      ) {
        res.method = 'iframe';
      } else {
        if (urls[0].indexOf('.html') === -1 && urls[0].indexOf('#/') === -1) {
          res.method = 'iframe';
        } else {
          const routes = this.$router.options.routes;
          if (routes) {
            let path = this.hasRouter(routes, urls[0], res.appCode);
            if (path && this.routeType !== 'wujie') {
              res.method = 'router';
              if (typeof path === 'string') {
                res.path = path;
              } else {
                res.path = path.path;
                res.appCode = path.appCode;
              }
              res.keys = util.uuid();
            } else {
              let urlopenmode = util.getParams({
                url: url,
                name: 'urlopenmode'
              });
              if (
                this.loadWujie === false ||
                isIE ||
                res.urlopenmode == 3 ||
                urlopenmode == 3
              ) {
                res.method = 'iframe';
              } else {
                res.method = 'wujie';
                if (!res.appCode) {
                  res.appCode = 'application_' + Date.now();
                }
              }
            }
          } else if (
            (urls[0].indexOf('.html') > -1 && urls[0].indexOf('#/') > -1) ||
            urls[0].indexOf('/#/') > -1
          ) {
            res.method = 'wujie';
            if (!res.appCode) {
              res.appCode = 'application_' + Date.now();
            }
          } else {
            res.method = 'iframe';
          }
        }
      }
      return res;
    },
    /**
     * @desc:获取菜单
     * @author huangbo
     * @date 2024年9月7日
     **/
    getMenu(menus, res, key) {
      if (Array.isArray(menus)) {
        for (let i = 0; i < menus.length; i++) {
          let item = menus[i];
          if (key) {
            if (item[key] === res) {
              return item;
            }
          } else if (
            item.url === res ||
            item.id === res ||
            item.appCode === res
          ) {
            return item;
          }
          if (
            Object.prototype.hasOwnProperty.call(item, 'children') &&
            item.children.length
          ) {
            let obj = this.getMenu(item.children, res, key);
            if (obj) {
              return obj;
            }
          } else if (
            Object.prototype.hasOwnProperty.call(item, 'fourthTabs') &&
            item.fourthTabs.length
          ) {
            let obj = this.getMenu(item.fourthTabs, res, key);
            if (obj) {
              return obj;
            }
          }
        }
      }
      return false;
    },
    /**
     * @desc:获取菜单第一条数据
     * @author huangbo
     * @date 2024年9月7日
     **/
    getFirst(obj) {
      if (!obj) {
        return '';
      }
      let openIdex = 0;
      if (
        obj.extendData &&
        (obj.extendData.subDefOpenIndex || obj.extendData.subDefOpen)
      ) {
        openIdex = parseInt(
          obj.extendData.subDefOpenIndex || obj.extendData.subDefOpen,
          10
        );
      }
      if (obj.children && obj.children.length && obj.children[openIdex]) {
        return this.getFirst(obj.children[openIdex]);
      } else if (
        obj.fourthTabs &&
        obj.fourthTabs.length &&
        obj.fourthTabs[openIdex]
      ) {
        return this.getFirst(obj.fourthTabs[openIdex]);
      } else if (obj.url && obj.urlopenmode !== 1 && obj.urlopenmode !== 2) {
        return obj;
      }
    },
    /**
     * @desc:遍历设置菜单气泡提醒
     * @author huangbo
     * @date 2024年9月7日
     **/
    setTips(obj) {
      // 不显示菜单气泡提醒
      if (!this.showTipNums) return;
      if (!this.menuTips || !Object.keys(this.menuTips).length) {
        return false;
      }
      if (Array.isArray(obj)) {
        let num = 0;
        obj.forEach((item) => {
          let n = this.setTips(item);
          n = n ? parseInt(n) : 0;
          num += n;
          if (n) {
            this.$set(obj, 'tips', n);
            this.setDot(this.userApps, item.appCode, n);
            this.setDot(this.applications, item.appCode, n);
            this.setDot(this.business, item.appCode, n);
            this.setDot(this.systems, item.appCode, n);
          }
        });
        return num;
      } else {
        if (
          (obj.children && obj.children.length) ||
          (obj.fourthTabs && obj.fourthTabs.length)
        ) {
          let num = 0;
          if (obj.children && obj.children.length) {
            obj.children.forEach((item) => {
              let n = this.setTips(item);
              num += n ? parseInt(n) : 0;
            });
          }
          if (obj.fourthTabs && obj.fourthTabs.length) {
            obj.fourthTabs.forEach((item) => {
              let n = this.setTips(item);
              num += n ? parseInt(n) : 0;
            });
          }
          this.$set(obj, 'tips', num);
          this.setDot(this.userApps, obj.appCode, num);
          this.setDot(this.applications, obj.appCode, num);
          this.setDot(this.business, obj.appCode, num);
          this.setDot(this.systems, obj.appCode, num);
          return num;
        } else {
          let num =
            this.menuTips[obj.id] ||
            this.menuTips[obj.code] ||
            this.menuTips[obj.appCode];
          if (num && Number(num)) {
            this.$set(obj, 'tips', Number(num));
            return num;
          }
        }
      }
      return false;
    },
    setDot(obj, code, flag = true) {
      flag = flag ? true : false;
      if (Array.isArray(obj)) {
        obj.forEach((item) => {
          this.setDot(item, code, flag);
        });
      } else if (obj.code === code) {
        this.$set(obj, 'tips', flag);
      }
    },
    /**
     * @desc:获取气泡提醒
     * @author huangbo
     * @date 2024年9月7日
     **/
    getBadge(res) {
      let num = res.tips || 0;
      return num === true
        ? {
            isDot: true
            //hidden: item.tips
          }
        : {
            value: num,
            max: 99,
            hidden: !num
          };
    },
    /**
     * @desc:开启weosocket
     * @author huangbo
     * @date 2024年9月7日
     **/
    initWebSocket() {
      this.webSocket = util.socket({
        url: wss,
        take: topic,
        success: (res) => {
          let data = res.data || {};
          for (let i in data) {
            if (data[i] !== null && data[i] !== undefined) {
              if (i === 'onlineUserNums' && data[i] > 0) {
                this.$set(this.handleNums, 'online', data[i]);
              }
              if (i === 'sysMsgNums' && data[i] !== null) {
                this.$set(this.handleNums, 'notice', data[i]);
                if (this.showMsg) {
                  this.$refs.message.getMsg(true);
                }
              }
              if (i === 'menuTipsMap' && data[i] !== null) {
                this.menuTips = data[i];
              }
              if (i === 'sysMsgList' && data[i] !== null) {
                this.sysMsg = data[i];
                data[i] && data[i].length && this.$emit('bus-emit', 'waitdone');
              }
              if (i === 'extraData' && data[i] !== null) {
                this.extraData = data[i];
              }
            }
          }
          if (this.$store) {
            try {
              this.$store.commit('websocket', data);
            } catch (error) {}
          }
          const bus = this.bus || this.$eventBus || this.$root.Bus;
          if (bus) {
            bus.$emit('websocket', data);
          }
          if (util.win.eventBus) {
            util.win.eventBus.$emit('websocket', data);
          }
        }
      });
    },
    /**
     * @desc:显示用户信息
     * @author huangbo
     * @date 2024年9月7日
     **/
    showUserInfo() {
      if (this.showUser === false) {
        this.showUser = true;
      }
    },
    /**
     * @desc:删除更多应用菜单点击
     * @author huangbo
     * @date 2024年9月7日
     **/
    handleDelete(index) {
      this.newApps.splice(index, 1);
    },
    /**
     * @desc:储存更多应用菜单点击
     * @author huangbo
     * @date 2024年9月7日
     **/
    handlerClickApps(res) {
      if (res.permission === false) {
        return false;
      }
      let i = util.indexOfObj(this.newApps, res, 'id');
      if (i == -1) {
        this.newApps.push(res);
      }
      this.handlerClickApp(res);
    },
    /**
     * @desc:侧边应用菜单点击
     * @author huangbo
     * @date 2024年9月7日
     **/
    handlerClickApp(res) {
      this.showMsg = false;
      this.showSet = false;
      this.fold = false;
      this.showApps = false;
      this.drawer.visible = false;
      if (res) {
        if (res.permission === false) {
          return false;
        }
        if (
          (res.children && res.children.length) ||
          (res.fourthTabs && res.fourthTabs.length)
        ) {
          this.subMenus = res;
          this.showMenu = true;
        } else {
          this.subMenus = null;
          this.showMenu = false;
        }
        let set = true;
        if (res.url) {
          if (res.urlopenmode == 1 || res.openModel == 1) {
            set = false;
            util.win.open(res.url);
          } else if (res.urlopenmode == 2 || res.openModel == 2) {
            set = false;
            util.win.open(res.url, '_self');
          } else {
            let i = util.indexOfObj(this.tabs, res, 'id');
            this.activeName = res.id;
            if (i == -1) {
              let obj = res.code
                ? this.getMenu(this.menus, res.code, 'appCode')
                : null;
              if (obj) {
                obj = JSON.parse(JSON.stringify(obj));
                let n = util.indexOfObj(this.tabs, obj, 'id');
                if (n == -1) {
                  let tab = this.setIframeType(obj);
                  this.tabs.push(tab);
                  this.activeName = tab.id;
                } else {
                  if (obj.method == 'iframe') {
                    obj.url = util.handlerUrl(obj.url);
                  }
                }
              } else {
                let tab = this.setIframeType(res);
                this.tabs.push(tab);
                this.activeName = tab.id;
              }
            } else {
              if (res.method == 'iframe') {
                res.url = util.handlerUrl(res.url);
              }
            }
          }
        }
        if (set && res.code) {
          let subMenus = this.getMenu(this.menus, res.code, 'appCode');
          if (!subMenus && !res.url) {
            this.$alert('没有关联菜单，请联系管理员！', '提示', {
              confirmButtonText: '确定',
              type: 'warning'
            }).catch(() => {});
          } else {
            this.title = res.text || res.name;
            this.subMenus = subMenus ? subMenus : null;
            this.showMenu = subMenus
              ? (subMenus.children && subMenus.children.length > 0) ||
                (subMenus.fourthTabs && subMenus.fourthTabs.length > 0)
              : false;
            this.showApps = false;
            if (subMenus && subMenus.url) {
              subMenus = JSON.parse(JSON.stringify(subMenus));
              let i = util.indexOfObj(this.tabs, subMenus, 'id');
              this.activeName = subMenus.id;
              if (i == -1) {
                let tab = this.setIframeType(subMenus);
                this.tabs.push(tab);
              } else {
                if (subMenus.method == 'iframe') {
                  this.tabs[i].url = util.handlerUrl(subMenus.url);
                }
              }
            }
          }
        }
        this.active = res.id;
      } else {
        this.showApps = !this.showApps;
      }
    },
    /**
     * @desc:显示Drawer界面
     * @author huangbo
     * @date 2024年9月7日
     **/
    handlerSetDrawer(res, type, direction = 'ltr') {
      this.drawer.visible = true;
      this.drawer.active = type;
      this.drawer.direction = direction;
      if (res) {
        let { mounted, url } = res;
        this.drawer[type] = {
          mounted,
          url,
          name: res.name || util.uuid()
        };
      }
    },
    /**
     * @desc:关闭Drawer界面
     * @author huangbo
     * @date 2024年9月7日
     **/
    handleCloseDrawer() {
      this.drawer = { visible: false };
    },
    /**
     * @desc:菜单点击
     * @author huangbo
     * @date 2024年9月7日
     **/
    handlerClickMenu(res) {
      util
        .ajax({
          url: recordUserApp,
          params: {
            userId: this.user.userId,
            appId: res.id
          }
        })
        .then(() => {})
        .catch(() => {});
      this.showMsg = false;
      this.showSet = false;

      if (res.url) {
        if (res.urlopenmode == 1 || res.openModel == 1) {
          util.win.open(res.url);
          return;
        } else if (res.urlopenmode == 2 || res.openModel == 2) {
          util.win.open(res.url, '_self');
          return;
        }
      }
      let i = util.indexOfObj(this.tabs, res, 'id');
      if (i == -1) {
        let tab = this.setIframeType(res);
        this.tabs.push(tab);
        this.activeName = res.id;
      } else {
        this.tabs = events[0](this.tabs, i, this);
        // let tab = this.tabs[i];
        // if (tab.method === 'iframe') {
        //   this.activeName = res.id;
        //   this.$set(this.tabs[i], 'url', util.handlerUrl(tab.url));
        // } else {
        //   if (tab.method === 'wujie' && tab.appCode) {
        //     window.document
        //       .querySelector(`iframe[name=${tab.appCode}]`)
        //       .contentWindow.location.reload(true);
        //   }
        //   if (tab.method === 'router') {
        //     this.$set(this.tabs[i], 'keys', util.uuid());
        //   }
        //   this.activeName = res.id;
        // }
        this.activeName = res.id;
      }
    },

    /**
     * @desc:用户详情请求成功
     * @author huangbo
     * @date 2024年9月7日
     **/
    handleSuccess(res) {
      this.simpleUserInfo = res.simpleUserInfo;
    },
    /**
     * @desc:修改用户配置
     * @author huangbo
     * @date 2024年9月7日
     **/
    handleChangeConfig(name, res) {
      if (name == 'userHeadUrl') {
        this.$set(this.userModel, 'userHeadUrl', res);
        store.set('userModel', this.userModel);
        let mainConfig = JSON.parse(localStorage.getItem('mainConfig'));
        sessionStorage.setItem(
          'mainConfig',
          JSON.stringify({ ...mainConfig, userModel: this.userModel })
        );
      } else {
        this.$set(this.userStyle, 'notify', res);
        store.set('userStyle', this.userStyle);
        let mainConfig = JSON.parse(localStorage.getItem('mainConfig'));
        localStorage.setItem(
          'mainConfig',
          JSON.stringify({ ...mainConfig, userStyle: this.userStyle })
        );
      }
    },
    /**
     * @desc:关闭webSocket
     * @author huangbo
     * @date 2024年9月7日
     **/
    handlerClose() {
      if (this.webSocket) {
        this.webSocket.destroy();
      }
    },
    /**
     * @desc:刷新选中iframe页签
     * @author huangbo
     * @date 2024年9月7日
     **/
    handleRefresh(arg) {
      let i =
        arg &&
        arg != true &&
        arg !== 'pageData' &&
        !(typeof arg === 'object' && arg.path)
          ? util.indexOfObj(this.tabs, arg, 'appCode,code,id,url')
          : util.indexOfObj(this.tabs, this.activeName, 'id');
      let tab = this.tabs[i];
      if (isIE || tab.method === 'iframe') {
        if (arg && arg === 'pageData') {
          let iframe = document.getElementById(tab.id || tab.appCode);
          let source = tab.url;
          if (source && !util.startWith(source, ['http', 'https'], true)) {
            source = location.origin + source.replace('./', '/');
          }
          !iframe && (iframe = document.getElementById(this.iframeId));
          iframe &&
            iframe.contentWindow.postMessage(
              { method: 'pageData' },
              source || '*'
            );
        } else {
          this.$set(this.tabs[i], 'url', util.handlerUrl(tab.url));
        }
        return;
      }
      if (tab.method === 'wujie' && tab.appCode) {
        if (arg && arg === 'pageData') {
          WujieVue.$emit('pageData', tab);
        } else {
          // window.document
          //   .querySelector(`iframe[name=${tab.appCode}]`)
          //   .contentWindow.location.reload(true);
          let url = tab.url;
          // 如果传入了路由参数，需要更新 URL
          if (arg && typeof arg === 'object' && arg.path) {
            url = this.buildWujieUrl(tab.url, arg);
          }
          // 1. 获取带新时间戳的 URL
          const newUrl = util.handlerUrl(url);
          // 2. 关键：先置空，等待 Wujie 销毁实例
          tab.url = '';
          // 3. 使用 setTimeout 替代 $nextTick，给 Wujie 更多时间清理内存和 DOM
          setTimeout(() => {
            this.$set(this.tabs, i, { ...tab, url: newUrl });
          }, 50); // 50ms 的延迟通常足以让 Wujie 完成卸载
        }
        return;
      }
      if (tab.method === 'router') {
        if (arg && arg === 'pageData') {
          const bus = this.bus || this.$root.Bus;
          bus.$emit('pageData', tab);
        } else {
          this.$set(this.tabs[i], 'keys', util.uuid());
        }
      }
    },
    /**
     * @desc:构建 Wujie 子应用 URL（处理路由参数）
     * @param {String} baseUrl - 基础 URL
     * @param {Object} routeInfo - 路由信息 { path, params, query }
     * @returns {String} 拼接后的完整 URL
     **/
    buildWujieUrl(baseUrl, routeInfo) {
      const { path, params = {}, query = {} } = routeInfo;

      if (!path) {
        return baseUrl;
      }

      // 1. 处理 path + params（Vue Router 风格：params 作为路径参数）
      let fullPath = path;

      // 如果 params 中有值，将其拼接到 path 后面
      // 例如：path='/aa/bb', params={action:'action', id:'ddd', did:'33333'}
      // 结果：'/aa/bb/action/ddd/33333'
      const paramValues = Object.values(params).filter(
        (val) => val !== undefined && val !== null
      );
      if (paramValues.length > 0) {
        // 确保 path 不以 / 结尾
        const cleanPath = path.endsWith('/') ? path.slice(0, -1) : path;
        fullPath = cleanPath + '/' + paramValues.join('/');
      }

      // 2. 处理 query 参数
      const queryKeys = Object.keys(query);
      if (queryKeys.length > 0) {
        const queryString = queryKeys
          .map(
            (key) =>
              `${encodeURIComponent(key)}=${encodeURIComponent(query[key])}`
          )
          .join('&');
        fullPath += '?' + queryString;
      }

      // 3. 从 baseUrl 中提取基础部分（去掉 hash 路由部分）
      // 例如：baseUrl = 'http://example.com/app#/old/path'
      // 提取：'http://example.com/app#'
      let baseUrlPrefix = baseUrl;
      const hashIndex = baseUrl.indexOf('#');
      if (hashIndex > -1) {
        baseUrlPrefix = baseUrl.substring(0, hashIndex + 1); // 保留 #
      }

      // 4. 拼接最终 URL
      return baseUrlPrefix + fullPath;
    },
    /**
     * @desc:删除iframe
     * @author huangbo
     * @date 2024年9月7日
     **/
    handleRemove(name) {
      let len = this.tabs.length - 1;
      let i = util.indexOfObj(this.tabs, name, 'id,code,appCode');
      if (i > -1) {
        this.tabs.splice(i, 1);
        if (this.tabs.length == 0) {
          this.activeName = '';
        } else if (i == len) {
          this.activeName = this.tabs[len - 1].id;
        } else {
          this.activeName = this.tabs[i].id;
        }
      }
    },
    /**
     * @desc:tabs鼠标右键事件
     * @author huangbo
     * @date 2024年9月7日
     **/
    handleContextmenu(tabs, e) {
      let disabled = {};
      let index = parseInt(tabs.index, 10);
      if (index == 0) {
        disabled.left = true;
      }
      if (index == this.tabs.length - 1) {
        disabled.right = true;
      }
      if (this.tabs.length == 1) {
        disabled.other = true;
      }
      if (this.tabs[index].id != this.activeName) {
        disabled.refresh = true;
      }
      this.isDisabled = disabled;
      this.$refs.tabsHandler.$el.style.setProperty('left', `${e.x}px`);
      this.$refs.tabsHandler.$el.style.setProperty('top', `${e.y}px`);
      this.showTabsHandler = true;
      this.pane = index;
      window.addEventListener('click', this.closeTabsEvents);
    },
    /**
     * @desc:tabs页签事件
     * @author huangbo
     * @date 2024年9月7日
     **/
    handleTabsEvents(num) {
      if (this.pane !== null) {
        this.tabs = events[num](this.tabs, this.pane, this);
      }
      this.showTabsHandler = false;
      window.removeEventListener('click', this.closeTabsEvents);
    },

    /**
     * @desc:关闭页签事件面板
     * @author huangbo
     * @date 2024年9月7日
     **/
    closeTabsEvents(e) {
      if (
        e.target.parentNode != this.$refs.tabsHandler.$el &&
        e.target.parentNode.parentNode != this.$refs.tabsHandler.$el
      ) {
        this.showTabsHandler = false;
      }
      window.removeEventListener('click', this.closeTabsEvents);
    },

    /**
     * @desc:tabs页签点击事件
     * @author huangbo
     * @date 2024年9月7日
     **/
    handleTabClick() {
      this.active = '';
      this.subMenus = null;
      this.showMenu = false;
    },
    /**
     * @desc:handler工具栏点击事件
     * @author huangbo
     * @date 2024年9月7日
     **/
    handleClick(res) {
      const { type, event, open, link } = res;
      if (event) {
        event();
      } else if (open) {
        util.win.open(open);
      } else if (link) {
        util.win.open(link, '_self');
      } else {
        switch (type) {
          case 'quit':
            this.handleQuit();
            break;
          case 'online':
            this.showMsg = false;
            this.showSet = false;
            this.dialog = {
              title: '查看在线人员',
              show: true,
              src: this.onlineUrl
            };
            break;
          case 'notice':
            this.showMsg = !this.showMsg;
            this.showSet = false;
            break;
          case 'index':
            util.win.open(this.doorIndex, '_self');
            break;
          case 'set':
            this.showSet = !this.showSet;
            this.showMsg = false;
            break;
          case 'home':
            let i = util.indexOfObj(this.tabs, this.homePage.id, 'id');
            if (i == -1) {
              this.tabs.unshift(this.homePage);
            } else {
              let tab = this.tabs[i];
              if (tab.method === 'iframe') {
                this.$set(this.tabs[i], 'url', util.handlerUrl(tab.url));
              }
              if (tab.method === 'wujie' && tab.appCode) {
                window.document
                  .querySelector(`iframe[name=${tab.appCode}]`)
                  .contentWindow.location.reload(true);
              }
              if (tab.method === 'router') {
                this.$set(this.tabs[i], 'keys', util.uuid());
              }
            }
            this.activeName = this.homePage.id;
            this.showMsg = false;
            this.showSet = false;
            this.active = '';
            this.subMenus = null;
            this.showMenu = false;
            break;
          case 'search':
            this.showSearch = true;
            this.showMsg = false;
            this.showSet = false;
            break;
          case 'ai':
            this.handlerSetDrawer(this._aiConfig, 'ai', 'rtl');
            break;
          case 'im':
            this.handlerSetDrawer(this.imConfig, 'im', 'rtl');
            break;
          case 'goView':
            util.win.open(res.path, '_blank');
            break;
        }
      }
      this.$emit('handler-click', res);
    },
    /**
     * @desc:退出登录
     * @author huangbo
     * @date 2024年9月7日
     **/
    handleQuit() {
      this.$confirm('确定退出吗?', '退出系统', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          let iframes = document.getElementsByTagName('iframe');
          for (let i = 0; i < iframes.length; i++) {
            let src = iframes[i] ? iframes[i].src : null;
            let origin = util.win.location.origin;
            if (
              src &&
              util.startWith(src, 'http') &&
              src.indexOf(origin) === -1
            ) {
              iframes[i] && iframes[i].contentWindow.postMessage('logout', '*');
            }
            break;
          }
          if (this.singleLogout) {
            for (let i = 0; i < this.singleLogout.length; i++) {
              let iframe = document.createElement('iframe');
              iframe.style.display = 'none';
              iframe.src = this.singleLogout[i];
              document.body.appendChild(iframe);
            }
          }
          util
            .ajax({ method: 'post', url: logout })
            .then((res) => {
              if (res.rCode == 0) {
                util.removeStorage([
                  'Authorization',
                  'token',
                  'ssId',
                  'userId',
                  'userName',
                  'auth',
                  'deviceUnique',
                  'menus',
                  'useCaseCodes',
                  'mainConfig',
                  'jump'
                ]);
                if (this.onQuit && typeof this.onQuit === 'function') {
                  this.onQuit();
                } else {
                  try {
                    const loginPage =
                      util.getStorage('login') || util.getStorage('loginPage');
                    const topWin = util.getWinTop();
                    if (loginPage) {
                      let src;
                      if (!util.startWith(loginPage, ['http', '/'], true)) {
                        let pathname = topWin.location.pathname;
                        if (pathname !== '/') {
                          pathname = pathname.split('/');
                          pathname.splice(pathname.length - 1);
                          pathname = pathname.join('/');
                          src = pathname + '/' + loginPage.replace('./', '');
                        } else {
                          src = pathname + loginPage.replace('./', '');
                        }
                      } else {
                        src = loginPage;
                      }
                      topWin.location.href = src;
                    } else if (topWin.location.href.indexOf('main.html') > -1) {
                      topWin.location.href = './login.html';
                    } else {
                      const hash = topWin.location.hash;
                      if (hash) {
                        const len = topWin.location.href.indexOf(hash);
                        topWin.location.href =
                          util.win.location.href.slice(0, len) + '#/login';
                      } else {
                        topWin.location.href = '/login.html';
                      }
                    }
                  } catch (error) {
                    console.warn('Failed to handle login redirect:', error);
                    try {
                      util.getWinTop().postMessage({ type: 1 }, '*');
                    } catch (postMessageError) {
                      console.warn(
                        'Failed to send postMessage:',
                        postMessageError
                      );
                    }
                  }
                }
              }
            })
            .catch((err) => {
              if (err.message && err.message !== 'canceled') {
                this.$message.error(err.message);
              }
            });
        })
        .catch((e) => {});
    },
    /**
     * @desc:主题、消息回调
     * @author huangbo
     * @date 2024年9月7日
     **/
    handleChange(res) {
      const { type, value } = res;
      switch (type) {
        case 'theme':
          this.setTheme(value);
          break;
        case 'ignore':
          this.$set(this.handleNums, 'notice', 0);
          break;
      }
    },
    /**
     * @desc:菜单布局样式切换
     * @author huangbo
     * @date 2024年9月7日
     **/
    handleLayout(res, active) {
      if (active) {
        localStorage.setItem('layout', active);
        localStorage.setItem('layoutType', active);
      }
      this.$emit('chang-layout', res, active);
    },
    /**
     * @desc:消息修改总数
     * @author huangbo
     * @date 2024年9月7日
     **/
    handleMenuTips(id, num) {
      if (num) {
        this.$set(this.menuTips, id, num);
      } else {
        let n = parseInt(this.menuTips[id], 10) - 1;
        this.$set(this.menuTips, id, n);
      }
    },
    /**
     * @desc:处理即时消息
     * @author huangbo
     * @date 2024年9月7日
     **/
    handleOpened(res) {
      if (res === undefined) {
        this.sysMsg = [];
      } else if (res == false && this.sysMsg.length) {
        this.sysMsgOut = setTimeout(() => {
          this.sysMsg = [];
        }, 3000);
      } else if (this.sysMsgOut) {
        clearTimeout(this.sysMsgOut);
      }
    },
    jumpMenu(res, close, params = {}) {
      let apps = res;
      let param = params;
      let reload = true;
      if (typeof res === 'string') {
        apps = res.split(',');
      } else if (util.isObject(res)) {
        apps = Array.isArray(res.appCode)
          ? res.appCode
          : res.appCode.split(',');
        res.param && (param = { ...res.param, ...params });
        reload = Object.prototype.hasOwnProperty.call(res, 'reload')
          ? res.reload
          : true;
      }
      let obj = this.getMenu(this.menus, apps[apps.length - 1]);
      if (obj) {
        obj = JSON.parse(JSON.stringify(obj));
        let i = util.indexOfObj(this.tabs, obj, 'id,code,appCode');
        let n = util.indexOfObj(this.tabs, this.activeName, 'id');
        let old = this.activeName;
        this.activeName = obj.id;
        this.subActive = obj.id;
        if (i == -1) {
          let tab = this.setIframeType(obj);
          this.$set(tab, 'url', util.handlerUrl(tab.url, param));
          this.tabs.splice(n + 1, 0, tab);
        } else {
          let tab = this.tabs[i];
          if (tab.method === 'iframe') {
            this.$set(this.tabs[i], 'url', util.handlerUrl(tab.url, param));
          }
          if (tab.method === 'wujie' && tab.appCode) {
            const url = param ? util.handlerUrl(tab.url, param) : tab.url;
            if (reload || param) {
              tab.url = '';
              this.$nextTick(() => {
                tab.url = url;
              });
            }
            // if (param) {
            //   window.document.querySelector(
            //     `iframe[name=${tab.appCode}]`
            //   ).contentWindow.location.href = util.handlerUrl(tab.url, param);
            // } else {
            //   window.document
            //     .querySelector(`iframe[name=${tab.appCode}]`)
            //     .contentWindow.location.reload(true);
            // }
          }
          if (tab.method === 'router') {
            this.$set(this.tabs[i], 'url', util.handlerUrl(tab.url, param));
            this.$set(this.tabs[i], 'keys', util.uuid());
          }
        }
        if (close) {
          if (close === old) {
            this.tabs.splice(n, 1);
          } else {
            let d = util.indexOfObj(this.tabs, close, 'id,code,appCode');
            if (d > -1) {
              this.tabs.splice(d, 1);
            }
          }
        }
      } else {
        this.$message.error('没有此菜单！');
      }
    },
    //监听改变菜单
    handleListener() {
      util.win.addEventListener(
        'message',
        (e) => {
          var msg = e.data;
          if (msg.key == 'jump_Menu') {
            let res = msg.data1;
            this.jumpMenu(res);
          }
        },
        false
      );
    },
    handleSelect(res, parent) {
      this.showSearch = false;
      if (parent.name === '应用') {
        this.handlerClickApps(res);
      }
      if (parent.name === '菜单') {
        this.handlerClickApp(res);
      }
    },
    handleLoadIframe(item) {
      this.$set(item, 'loading', false);
    }
  },
  beforeDestroy() {
    clearTimeout(this.timer);
    this.timer = null;
    if (this.webSocket) {
      this.webSocket.destroy();
    }
  }
};
</script>

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