<template>
  <div class="dc-page-header-container">
    <div class="dc-trademark">
      <div class="dc-logo">
        <div class="dc-logo-svg">
          <img v-if="setting.logoImg" :src="setting.logoImg" />
        </div>
        <!-- <div class="dc-logo-text" v-if="setting.logoSlogan">{{ setting.logoSlogan }}</div> -->
      </div>
      <!-- <div class="dc-company" :style="{ 'margin-left': setting.nameOffset + 'px' }">
        <div class="dc-company-zh-cn" v-if="setting.companyZnName">{{ setting.companyZnName }}</div>
        <div class="dc-company-en-us" v-if="setting.companyEnName">{{ setting.companyEnName }}</div>
      </div> -->
    </div>
    <div class="dc-nav" :style="{ maxWidth: 'calc(100vw - ' + (enableMsgNotice && expandSearch ? '825px' : '605px') + ')' }" v-if="isHideWhenOnlyOne ? sysFuiAppRels.length > 1 : sysFuiAppRels.length > 0">
      <t-radio-group class="dc-nav-group" v-model="activeAppId" variant="primary-filled">
        <t-radio-button v-for="item in fuiSysAppInfos" :key="item.appId" :value="item.appId">{{ item.appName }}</t-radio-button>
      </t-radio-group>
    </div>
    <div class="dc-opts">
      <div class="dc-search-box" v-if="enableSearch">
        <t-input class="dc-search-input" v-if="expandSearch" :data-source="searchResult" placeholder="请输入合同编号" />
        <t-button size="small" class="dc-search-btn" variant="text" @click="toggleSearchBox">
          <div class="dc-search-btn-text">搜索</div>
        </t-button>
      </div>
      <div class="dc-message-box" v-if="enableMsgNotice" @click="handleNoticeDrawer">
        <t-badge class="dc-badge" :count="newMsgNum">
          <div class="dc-message-svg-box">
            <img class="dc-message-svg" :src="messageSvg" />
          </div>
        </t-badge>
      </div>
      <div class="dc-role" :title="innerUserLabel" v-if="innerUserLabel && !hiddenUserLabel">{{ innerUserLabel }}</div>
      <div class="dc-user">
        <img class="dc-user-avatar" :src="setting.avatar" />
        <div class="dc-user-name">
          <t-dropdown
            class="dc-dropdown-link"
            :options="[
              {
                content: '我的应用',
                value: 1,
                disabled: !user,
                onClick: handleMyApp,
              },
              { content: '个人信息', disabled: !user, value: 2, onClick: handlePersonalInfo },
              { content: '修改密码', disabled: !user, value: 3, onClick: handleChangePassword },
              { content: '退出系统', value: 4, onClick: handleLogout },
            ]"
          >
            <div class="dc-dropdown-link-text">{{ user ? user.userName : "匿名" }}</div>
            <chevron-down-icon size="16" />
          </t-dropdown>
        </div>
      </div>
      <!-- 个人信息-->
      <dc-personal-info-modal v-if="!personalInfoVar.destroy" :visible.sync="personalInfoVar.visible" :personalHeaderExtendedInfo="personalHeaderExtendedInfo" @close="handleModalClose"></dc-personal-info-modal>
      <!-- 我的应用 -->
      <dc-my-app-modal v-if="!myAppVar.destroy" :visible.sync="myAppVar.visible" :sysAppInfos="allSysAppInfos" :sysFuiAppRels="sysFuiAppRels" @close="handleMyAppModalClose"></dc-my-app-modal>
      <!-- 消息提醒 -->
      <dc-notice-drawer v-if="!noticeVar.destroy" :visible.sync="noticeVar.visible" @close="handleModalClose" @change="loadNoticeNum"> </dc-notice-drawer>
      <!-- 密码修改 -->
      <dc-user-change-password-modal v-if="!changePasswordVar.destroy" :visible.sync="changePasswordVar.visible" :modalStatus="modalStatus" @close="handleModalClose"></dc-user-change-password-modal>
    </div>
  </div>
</template>

<script lang="ts">
import Vue from "vue";
import Component from "vue-class-component";
import { MessagePlugin } from "tdesign-vue";
import MyAppModal from "./MyAppModal.vue";
import NoticeDrawer from "./NoticeDrawer.vue";
import PersonalInfoModal from "./PersonalInfoModal.vue";
import UserChangePasswordModal from "./UserChangePasswordModal.vue";
import { oauthService } from "../../services/oauth.service";
import { Prop, Watch } from "vue-property-decorator";
import { RestApi } from "../../model/RestApi";
import { RestfulResponse } from "../../model/RestfulResponse";
import { SysAppInfo } from "../../model/SysAppInfo";
import { Code } from "../../constants/enum/code.enum";
import { apiService } from "../../services/api.service";
import sysAppInfoApi from "../../constants/api/sys-app-info.api";
import { routerService } from "../../services/router.service";
import { MESSAGE_SVG_XML, SEARCH_SVG_XML } from "../../constants/encode-assets/svg";
import { SysFuiAppRel } from "../../model/SysFuiAppRel";
import sysFuiAppRelApi from "../../constants/api/sys-fui-app-rel.api";
import { AppLink } from "../../constants/enum/app-link.enum";
import { SysUserInfo } from "../../model/SysUserInfo";
import { userStore } from "../../stores/user.store";
import { PageHeaderSetting } from "../../model/PageHeaderSetting";
import sysMsgApi from "../../constants/api/sys-msg.api";
import { ModalVar } from "../../model/ModalVar";
import { ChevronDownIcon } from "tdesign-icons-vue";
import sysUserLoginApi from "../../constants/api/sys-user-login.api";
import { MessagePlugin as message } from "tdesign-vue/es/message/plugin";
import { ModalStatus } from "../../model/modalStatus";

@Component({
  name: "PageHeader",
  components: {
    "dc-my-app-modal": MyAppModal,
    "dc-notice-drawer": NoticeDrawer,
    "dc-personal-info-modal": PersonalInfoModal,
    "dc-user-change-password-modal": UserChangePasswordModal,
    ChevronDownIcon,
  },
})
export default class PageHeader extends Vue {
  searchSvg: any = SEARCH_SVG_XML; // 搜索图标
  messageSvg: any = MESSAGE_SVG_XML; // 消息图标

  @Prop({ default: () => new PageHeaderSetting() }) setting!: PageHeaderSetting; // 配置项
  @Prop({ default: false }) dynamic!: boolean; // 是否动态加载系统信息
  @Prop({ default: () => [] }) staticAllSysAppInfos!: SysAppInfo[]; // 静态-全部导航列表
  @Prop({ default: false }) enableSearch!: boolean; // 启用搜索
  @Prop({ default: false }) enableMsgNotice!: boolean; // 启用消息通知
  @Prop({ default: () => null }) userLabel!: string; // 自定义用户标签
  @Prop({ default: false }) hiddenUserLabel!: boolean; // 隐藏角色名称
  @Prop({ default: false }) isHideWhenOnlyOne!: boolean; // 只有一个时隐藏
  @Prop({ default: () => "" }) personalHeaderExtendedInfo!: string; // 个人信息头部扩展信息

  noticeVar: ModalVar = { visible: false, destroy: true }; // 消息通知模态框变量
  myAppVar: ModalVar = { visible: false, destroy: true }; // 我的应用弹窗模态框变量
  changePasswordVar: ModalVar = { visible: false, destroy: true }; // 修改密码弹窗模态框变量
  personalInfoVar: ModalVar = { visible: false, destroy: true }; // 个人信息框模态框变量
  modalStatus: ModalStatus = { cancel: "取消", close: true };
  tipDialog: any;

  newMsgNum = 0; // 消息数量
  static readonly NOTICE_INTERVAL: number = 3 * 1000 * 60; // 查询通知间隔
  noticeNumInterval: any = undefined; // 定时任务标记

  expandSearch = false; // 展示搜索
  searchResult: any[] = []; // 搜索结果

  activeAppId = ""; // 当前激活导航
  allSysAppInfos: SysAppInfo[] = []; // 全部导航列表
  sysFuiAppRels: SysFuiAppRel[] = []; // 常用导航关联列表
  observationRefreshMark: any = new Date().getTime(); // 观察刷新标志

  getPopupContainer = (triggerNode: any) => {
    return triggerNode;
  }; // 下拉面板位置

  // 常用导航列表
  get fuiSysAppInfos(): SysAppInfo[] {
    return this.sysFuiAppRels?.map((item) => this.allSysAppInfos.find((it) => it.appId === item.appId)!)?.filter((item) => item != null) || [];
  }

  // 用户信息
  get user(): SysUserInfo | undefined {
    this.observationRefreshMark = userStore.refreshMark;
    return userStore.user;
  }

  // 用户标签
  get innerUserLabel(): string {
    if (this.userLabel != null) {
      return this.userLabel;
    } else {
      const user = this.user;
      return user && user.sysRoleInfos && user.sysRoleInfos.length > 0 ? user.sysRoleInfos[0].roleName : "";
    }
  }

  mounted(): void {
    this.init();
  }

  destroyed() {
    if (this.noticeNumInterval) {
      clearInterval(this.noticeNumInterval);
    }
  }

  @Watch("$route", { immediate: true })
  onRouteChange() {
    this.toggleActiveNavMenus();
  }
  /**
   * 监听是否需要修改密码
   */
  @Watch("setting", { immediate: true, deep: true })
  onSettingChange() {
    if (this.setting.passwordChangeDate) {
      this.getPasswordChangeDate();
    }
  }

  /**
   * @description: 静态数据变更处理
   * @author ChenRui
   * @date 2021/9/15 16:08
   */
  @Watch("staticAllSysAppInfos")
  onStaticAllSysAppInfosChange(val: SysAppInfo[]) {
    if (!this.dynamic) {
      this.allSysAppInfos = this.staticAllSysAppInfos || [];
      this.sysFuiAppRels = [];
      this.allSysAppInfos.forEach((item) => {
        this.sysFuiAppRels.push(
          new SysFuiAppRel({
            appId: item.appId,
          })
        );
      });
    }
  }

  private init(): void {
    if (this.dynamic) {
      this.loadSysInfo();
    } else {
      this.onStaticAllSysAppInfosChange(this.staticAllSysAppInfos);
    }
    if (this.enableMsgNotice) {
      this.initNoticeNumScheduled();
    }
  }

  /**
   * @Description: 定时调用通知总数查询
   * @author LiuBo
   * @date 2021/11/12
   * @time 11:46
   */
  private initNoticeNumScheduled(): void {
    this.loadNoticeNum();
    this.noticeNumInterval = setInterval(() => {
      this.loadNoticeNum();
    }, PageHeader.NOTICE_INTERVAL);
  }

  /**
   * @description: 加载常用系统及所有系统
   * @author ChenRui
   * @date 2021/3/31 17:13
   */
  loadSysInfo(): Promise<any> {
    return Promise.all([this.loadAllSysInfo(), this.loadFuiAppRels()]).then(([resAll, resCom]: any[]) => {
      if (resAll.code === Code.SUCCESS.code && resCom.code === Code.SUCCESS.code) {
        this.toggleActiveNavMenus();
      } else {
        MessagePlugin.error({ content: "系统错误，请联系管理员" });
      }
    });
  }

  /**
   * @description: 加载所有应用
   * @author ChenRui
   * @date 2021/8/10 15:49
   */
  loadAllSysInfo(): Promise<RestfulResponse> {
    const restApi: RestApi = new RestApi(sysAppInfoApi.queryAuthorizedApp);
    restApi.url = this.$dc.baseApi + sysAppInfoApi.queryAuthorizedApp.url;
    return apiService.general(restApi).then((res: RestfulResponse) => {
      if (res.code === Code.SUCCESS.code) {
        this.allSysAppInfos = res.data || [];
      }
      return res;
    });
  }

  /**
   * @description: 加载常用应用
   * @author ChenRui
   * @date 2021/8/10 15:56
   */
  loadFuiAppRels(): Promise<RestfulResponse> {
    const restApi: RestApi = new RestApi(sysFuiAppRelApi.queryByUserId);
    restApi.url = this.$dc.baseApi + sysFuiAppRelApi.queryByUserId.url;

    const query = {
      userId: this.$userStore.user?.userId,
    };
    return apiService.general(restApi, query).then((res: RestfulResponse) => {
      if (res.code === Code.SUCCESS.code) {
        this.sysFuiAppRels = res.data || [];
      }
      return res;
    });
  }

  /**
   * @Description: 调用查询任务总数接口
   * @author SunJQi
   * @date 2021/11/12
   * @time 11:46
   */
  loadNoticeNum(): void {
    const restApi: RestApi = new RestApi(sysMsgApi.querySysMsgCount);
    restApi.url = this.$dc.baseApi + sysMsgApi.querySysMsgCount.url;
    apiService.general(restApi, undefined).then((res: RestfulResponse) => {
      if (res.code === Code.SUCCESS.code) {
        this.newMsgNum = res.data;
      }
    });
  }

  /**
   * @description: 无权访问
   * @author ChenRui
   * @date 2021/4/20 11:30
   */
  noAccessHandler(event: any): void {
    this.$emit("no-access", event);
  }

  /**
   * @description: 激活当前系统对应的选项卡
   * @author ChenRui
   * @date 2020/12/18 22:24
   */
  toggleActiveNavMenus(): void {
    const pathName: string = window.document.location.pathname;
    if (pathName && pathName.length > 0) {
      const projectName: string = pathName.substring(1, pathName.substr(1).indexOf("/") + 1);
      if (projectName && projectName.length > 0) {
        let systemNav: SysAppInfo | undefined = this.fuiSysAppInfos.find((item) => item.mountName === projectName);
        if (systemNav == null && this.allSysAppInfos != null && this.allSysAppInfos.length > 0) {
          systemNav = this.allSysAppInfos.find((item) => item.mountName === projectName);
          if (systemNav) {
            this.sysFuiAppRels.push(new SysFuiAppRel({ appId: systemNav.appId }));
          }
        }
        if (systemNav) {
          this.activeAppId = systemNav?.appId || "";
        }
      }
    }
  }

  /**
   * 获取密码修改时间
   */
  getPasswordChangeDate() {
    const restApi: RestApi = new RestApi(sysUserLoginApi.passwordForceChange);
    restApi.url = this.$dc.baseApi + sysUserLoginApi.passwordForceChange.url;

    apiService.general(restApi).then((response: RestfulResponse) => {
      if (response.code === Code.SUCCESS.code) {
        // 如果是null或大于设定的天数时，提示修改密码
        if (response.data === null || +this.setting.passwordChangeDate <= +response.data) {
          if (this.tipDialog) {
            this.tipDialog?.show();
            return;
          }
          this.tipDialog = this.$dialog({
            header: "密码修改提示",
            body: "您好！为保障您的账号安全，点击确定完成密码修改后才可正常使用系统功能。",
            closeBtn: false,
            cancelBtn: null,
            closeOnOverlayClick: false,
            onConfirm: ({ e }) => {
              this.modalStatus = { cancel: null, close: false };
              this.handleChangePassword();
              this.tipDialog.hide();
            },
          });
        }
      } else {
        message.error({ content: response.msg! });
      }
    });
  }

  /**
   * @description: 切换搜索框伸缩状态
   * @author ChenRui
   * @date 2021/8/10 20:41
   */
  toggleSearchBox() {
    this.expandSearch = !this.expandSearch;
  }

  /**
   * @description: 跨应用导航
   * @author ChenRui
   * @date 2021/8/10 16:00
   */
  nav(event: any): void {
    const sysAppInfo: SysAppInfo | undefined = this.allSysAppInfos.find((item) => item.appId === event);
    if (sysAppInfo && sysAppInfo.appUrl) {
      if (sysAppInfo.isLink === AppLink.OUT.code) {
        window.open(sysAppInfo.appUrl, "_blank");
      } else {
        const appUrl: string = sysAppInfo.appUrl.toLowerCase();
        const regex = /(http|https):\/\/([\w.]+\/?)\S*/;
        if (regex.test(appUrl)) {
          routerService.push(sysAppInfo.appUrl);
        } else {
          const url = window.location.protocol + "//" + location.host + sysAppInfo.appUrl;
          routerService.push(url);
        }
      }
    }
  }

  /**
   * @description: 我的应用
   * @author ChenRui
   * @date 2021/8/16 10:48
   */
  handleMyApp(): void {
    this.myAppVar.destroy = false;
    this.myAppVar.visible = true;
  }

  /**
   * @description: 个人信息
   * @author ChenRui
   * @date 2022/2/12 17:56
   */
  handlePersonalInfo(): void {
    this.personalInfoVar.destroy = false;
    this.personalInfoVar.visible = true;
  }

  /**
   * @description: 消息通知
   * @author ChenRui
   * @date 2022/2/12 17:57
   */
  handleNoticeDrawer(): void {
    this.noticeVar.destroy = false;
    this.noticeVar.visible = true;
  }

  /**
   * @description: 修改密码
   * @author ChenRui
   * @date 2021/10/11 17:42
   */
  handleChangePassword(): void {
    this.changePasswordVar.destroy = false;
    this.changePasswordVar.visible = true;
  }

  /**
   * @description: 关闭我的应用模态框
   * @author ChenRui
   * @date 2022/2/12 15:55
   */
  handleMyAppModalClose(response: RestfulResponse): void {
    setTimeout(() => {
      this.myAppVar.destroy = true;
    }, 500);
    if (response && response.code === Code.SUCCESS.code) {
      this.loadFuiAppRels().then();
    }
  }

  /**
   * @description: 模态框关闭
   * @author Zhang Qishan
   * @date 2021/8/28 2:36
   */
  handleModalClose(response: RestfulResponse): void {
    setTimeout(() => {
      this.noticeVar.destroy = true;
      this.changePasswordVar.destroy = true;
      this.personalInfoVar.destroy = true;
      this.modalStatus = { cancel: "取消", close: true };
    }, 300);
  }

  /**
   * @description: 用户登出
   * @author ChenRui
   * @date 2021/8/10 15:54
   */
  handleLogout(): void {
    oauthService.logOut().then((res: RestfulResponse) => {
      this.$emit("logout", res);
    });
  }
}
</script>

<style scoped lang="scss">
.dc-page-header-container {
  display: flex;
  align-items: center;
  // background-color: rgba(42.16, 50.1, 62, 1);
  background-color: #fff;
  height: 60px;
  padding: 0;
  border-bottom: 1px solid #e7e7e7;
  .dc-trademark {
    display: flex;
    align-items: center;
    width: 232px;
    padding-top: 3px;
    justify-content: center;
    .dc-logo {
      display: flex;
      flex-direction: column;
      .dc-logo-svg {
        display: flex;
        justify-content: center;
        img {
          // width: 27px;
          height: 38px;
          display: block;
        }
      }
      .dc-logo-text {
        font-weight: 600;
        font-size: 12px;
        width: 100%;
        text-align: center;
        transform: scale(0.8);
        color: #ffffff;
      }
    }
    .dc-company {
      color: #ffffff;
      .dc-company-zh-cn {
        letter-spacing: 4px;
        text-align: center;
        font-size: 12px;
        font-weight: 600;
        margin-bottom: -3px;
        transform: scale(0.95);
        padding-left: 3px;
      }
      .dc-company-en-us {
        font-size: 12px;
        font-weight: 600;
        transform: scale(0.8);
      }
    }
  }
  .dc-nav {
    flex-grow: 1;
    height: 100%;
    .dc-nav-group {
      margin: 14px 0;
    }
    ::v-deep {
      > .ant-tabs {
        height: 60px;
        .ant-tabs-bar {
          height: 100%;
          margin-bottom: 0;
          border-bottom: 0;
          .ant-tabs-nav-container {
            height: 100%;
            margin-bottom: 0;
            .ant-tabs-nav-wrap {
              height: 100%;
              .ant-tabs-nav-scroll {
                height: 100%;
                .ant-tabs-nav {
                  height: 100%;
                  & > div {
                    height: 100%;
                    display: flex;
                    flex-direction: row;
                    .ant-tabs-tab {
                      border: 0;
                      margin: 0;
                      padding: 0 10px;
                      height: 100%;
                      border-radius: 0;
                      background-color: initial;
                      font-size: 15px;
                      display: flex;
                      align-items: center;
                      &.ant-tabs-tab-active {
                        background-color: #0052d9;
                        font-weight: 700;
                      }
                      &:hover {
                        font-weight: 700;
                      }
                    }
                  }
                }
              }
            }
            .ant-tabs-tab-arrow-show {
              transform: scale(1.2);
            }
          }
        }
        .ant-tabs-content {
          display: none;
        }
      }
    }
  }
  .dc-opts {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    margin-left: auto;
    padding: 0 15px;
    .dc-search-box {
      display: flex;
      justify-content: flex-end;
      align-items: center;
      .dc-search-input {
        margin-right: 10px;
        width: 250px;
      }
      .dc-search-btn {
        display: flex;
        align-items: center;
        .dc-search-btn-icon {
          display: block;
          margin-right: 5px;
        }
      }
    }
    .dc-message-box {
      margin: 0 30px 0 20px;
      .dc-badge {
        display: block;
        cursor: pointer;
        .dc-message-svg-box {
          width: 25px;
          height: 25px;
          border-radius: 12.5px;
          background-color: #0454da;
          display: flex;
          align-items: center;
          justify-content: center;
          .dc-message-svg {
            width: 22px;
            height: 22px;
          }
        }
        ::v-deep {
          .ant-badge-count {
            right: -1px;
            top: -3px;
            transform: scale(0.5);
          }
        }
      }
    }
    .dc-role {
      text-align: center;
      margin-right: 5px;
      max-width: 200px;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    .dc-user {
      display: flex;
      align-items: center;
      margin: 0 10px;
      .dc-user-avatar {
        margin-right: 12px;
        height: 24px;
        width: 24px;
      }
      .dc-user-name {
        font-family: "MicrosoftYaHei", "Microsoft YaHei";
        text-align: right;
        .dc-dropdown-link {
          display: flex;
          align-items: center;
          .dc-dropdown-link-text {
            max-width: 200px;
            white-space: nowrap;
            text-overflow: ellipsis;
            overflow: hidden;
            word-break: break-all;
          }
          ::v-deep {
            .anticon {
              display: block;
              margin-left: 5px;
              svg {
                transform: scale(1.2);
              }
            }
            .ant-dropdown {
              position: absolute !important;
              width: initial !important;
            }
          }
        }
      }
    }
  }
}
</style>
