vue-okr-tree 组件左右树结构

本文介绍了如何在Vue项目中实现组织架构树组件,展示了如何使用Vue-draggable-resizable进行布局,并详细讲解了VueOkrTree组件的用法,包括节点点击、展开与折叠、以及右侧详情弹窗的交互。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近公司需要做一个okr项目,okr项目里有一个对齐试图功能,在百度和GitHub上找了半天,最后终于找到了一位大神造的轮子,可能最终需求不是这个样子,但是也特别感谢大神的指导,希望大家多多支持大神,互相学习。

大神的博客:我开源了一个基于Vue的组织架构树组件_粉丝们务必加入微信粉丝群-CSDN博客_vue-okr-tree

大神的GitHub:GitHub - qq449245884/vue-okr-tree: http://www.longstudy.club/vue-okr-tree-doc/index.html

最终的展示效果如图:

 

子组件:

<template>
  <div class="map_container">
    <vue-draggable-resizable
      class="vue_draggable_resizable"
      w="auto"
      h="auto"
      :x="x"
      :y="y"
      :handles="[]"
      @dragging="onDrag"
      @resizing="onResize"
    >
      <div class="map_content_box">
        <div
          class="map_content"
          v-for="item in okrTreeData"
          :key="item.id"
          @click="handleDomClick"
        >
          <vue-okr-tree
            ref="okrTree"
            :data="item.data.right"
            :left-data="item.data.left"
            only-both-tree
            direction="horizontal"
            show-collapsable
            node-key="id"
            showNodeNum
            :render-content="renderContent"
            :node-btn-content="nodeBtnContent"
            @node-click="handleNodeClick"
            @node-expand="handleNodeExpand"
            @node-collapse="handleNodeCollapse"
          />
        </div>
      </div>
    </vue-draggable-resizable>
  </div>
</template>

<script>
import { VueOkrTree } from "vue-okr-tree";
import "vue-okr-tree/dist/vue-okr-tree.css";
import img from "@/assets/img/profile.jpg";
import img1 from "@/assets/img/tongjiduiqi.svg";
import VueDraggableResizable from "vue-draggable-resizable";
import "vue-draggable-resizable/dist/VueDraggableResizable.css";
import headerPhoto from "@/views/okrHome/components/headerPhoto";
import {
  getToken,
  setToken,
  getUsername,
  removeUsername,
  removeToken,
  removeExpiresIn,
  getAdminSex,
  getNickname,
} from "@/utils/auth";

export default {
  name: "VueOkrTreeComponent",
  props: {
    okrTreeData: {
      type: Array,
    },
  },
  components: {
    VueOkrTree,
    VueDraggableResizable,
    headerPhoto,
  },
  data() {
    return {
      width: 0,
      height: 0,
      x: 0,
      y: 0,
      testData: [],
      img: "require('../assets/profile.jpg')",
      positionFlag: false,
      customColors: [
        { color: "#D8423E", percentage: 50 },
        { color: "#EEAF00", percentage: 80 },
        { color: "#3DB373", percentage: 100 },
        { color: "#3F9EFF", percentage: 101 },
      ],
      childrenNum: 0,
      parentNum: 0,
      sex: sessionStorage.getItem("sex"),
      username: getUsername(),
      nickname: getNickname(),
      propStyle: {
        fontSize: "12px",
        width: "24px",
        height: "24px",
      },
      propScale: "0.7",
    };
  },
  mounted() {},
  methods: {
    handleDomClick(event) {
      // let currentDomNode = event.target;
      // console.log(currentDomNode);

      let card_wrap = document.getElementsByClassName("card_wrap");
      let card_wrap_arr = Array.from(card_wrap);
      card_wrap_arr.forEach((element) => {
        if (
          element.className.indexOf("current_select") !== -1 &&
          element.className.indexOf("current_empty_left_border") !== -1
        ) {
          // element.classList.remove("current_select");
          // element.classList.remove("current_empty_left_border");
        }
      });
    },
    onResize: function (x, y, width, height) {
      this.x = x;
      this.y = y;
      this.width = width;
      this.height = height;
    },
    onDrag: function (x, y) {
      this.x = x;
      this.y = y;
    },
    handleNodeClick(data, node, self) {
      this.$emit("showDetailDrawer");
    },
    handleNodeExpand(data, node, self) {},
    handleNodeCollapse(data, node, self) {},
    nodeBtnContent(h, node) {
      console.log(node, "node");
      return (
        <div class="org-chart-node-btn-text">{node.childNodes.length || 0}</div>
      );
    },
    renderContent(h, node) {
      const cls = ["card_wrap"];
      if (node.data.level === null) {
        cls.push("empty");
      }
      if (node.data.level === "公司级") {
        cls.push("company");
      }
      if (node.data.level === "部门级") {
        cls.push("dept");
      }
      if (node.data.level === "个人级") {
        cls.push("self");
      }
      if (node.isCurrent) {
        cls.push("current_select current_empty_left_border");
      }

      return (
        <div class={cls}>
          {node.data.level !== null ? (
            <div class="card_content">
              <div class="card_content_left">
                <headerPhoto
                  nickName={this.nickname}
                  sex={this.sex}
                  propStyle={this.propStyle}
                  propScale={0.7}
                ></headerPhoto>
              </div>
              <div class="card_content_right">
                <div class="card_content_right_top">
                  <span>{node.data.nickName}</span>
                  <span>已延期 250%</span>
                </div>
                <el-popover
                  placement="top-end"
                  width="300"
                  trigger="hover"
                  visible-arrow={false}
                >
                  <div class="popover_box">{node.data.objName}</div>
                  <div slot="reference" class="card_content_right_bottom">
                    {node.data.objName}
                  </div>
                </el-popover>
              </div>
            </div>
          ) : (
            <div class="info">
              <p class="zhedie">{node.data.objName}</p>
            </div>
          )}
        </div>
      );
    },
  },
};
</script>

<style  lang="scss" >
@import "@/assets/css/targetMap/targetMap.scss";
</style>

headerPhoto 组件:

<template>
  <div :style="{ backgroundColor: bgColor, ...size }" class="header-photo">
    <span :style="{'transform': `scale(${scale})`}">
      {{ name }}
    </span>
  </div>
</template>

<script>
export default {
  name: "headerPhoto",
  data() {
    return {
      name: "",
      smallLarge: {
        width: "20px",
        height: "20px",
        fontSize: "12px",
      },
      scale: 1,
    };
  },
  props: {
    sex: {
      default: -1,
    },
    nickName: {
      type: String,
      default: "",
    },
    color: {
      type: String,
    },
    propStyle: {
      type: Object,
      default() {
        return {
          width: "30px",
          height: "30px",
          fontSize: "12px",
        };
      },
    },
    propScale: {
      type: Number,
      default: 1,
    },
    small: {
      type: Boolean,
      default: false,
    },
  },
  watch: {
    nickName: {
      handler(val) {
        if (val.length) {
          this.name = val.substr(val.length - 2);
        }
      },
      immediate: true,
    },
    small: {
      handler(val) {
        if (val) {
          this.$nextTick(() => {
            this.scale = 0.6;
          });
        }
      },
      immediate: true,
    },
    propScale: {
      handler(val) {
        if (val) {
          this.scale = val;
        }
      },
      immediate: true,
    },
  },
  computed: {
    bgColor: function () {
      if (this.color) {
        return this.color;
      }
      if (this.sex == 0) {
        return "#4273f6";
      } else if (this.sex == 1) {
        return "#885BEF";
      } else {
        return "#59C2AB";
      }
    },
    size: function () {
      return this.small ? this.smallLarge : this.propStyle;
    },
  },
  methods: {}
};
</script>

<style lang='scss' scoped>
.header-photo {
  border-radius: 50%;
  color: #ffffff;
  line-height: 1em;
  display: flex;
  align-items: center;
  justify-content: center;

  span {
    text-align: center;
    display: inline-block;
    width: 100%;
    margin-left: -1px;
  }
}
</style>

子组件样式:

.target-map-wrap {
  .relation-graph-wrap {
    padding-top: 56px;
    box-sizing: border-box;
    height: calc(100vh - 56px - 50px);

    .top-wrap {
      display: flex;
      justify-content: space-between;
      height: 42px;
      padding: 12px;

      .inpdiv {
        position: relative;

        /deep/ .el-input__inner {
          width: 236px;
          height: 30px;
          border-radius: 15px;
          font-size: 12px;
        }

        /deep/ .el-icon-search {
          position: absolute;
          right: 10px;
          top: 10px;
          width: 14px;
          height: 14px;
          color: rgba(0, 0, 0, 0.25);
        }
      }
    }

    .map_container {
      width: 100%;
      height: 100%;
      display: flex;
      justify-content: center;

      .vue_draggable_resizable {
        width: 100% !important;
        height: calc(100vh - 56px - 116px) !important;
        margin: 0 auto;
        cursor: pointer;
        max-width: 100%;
        // margin-bottom: 60px;
        display: flex;
        align-items: center;
        justify-content: center;

        .map_content_box {}
      }

      .vdr {
        border: none;
      }

      .org-chart-container {
        // margin-top: 20px !important;

        .horizontal .org-chart-node-label .org-chart-node-label-inner {
          box-shadow: 0 0 rgba(0, 0, 0, 0.4) !important;
          padding: 0 !important;
          margin: 6px 0;

          .card_wrap {
            position: relative;
            background: #fff;
            border-radius: 2px;

            .card_content {
              display: -ms-flexbox;
              display: flex;
              -ms-flex-direction: row;
              flex-direction: row;
              max-height: 100%;
              padding: 12px;
              border-radius: 2px;
              box-shadow: 0 1px 10px #cccccc;
              cursor: pointer;
              width: 310px !important;
              height: 62px !important;


              .card_content_left {
                -ms-flex: none;
                flex: none;
                width: 24px;
                margin-right: 8px;
              }

              .card_content_right {
                -ms-flex: 1 0 0px;
                flex: 1 0 0px;
                min-width: 0;

                .card_content_right_top {
                  display: -ms-flexbox;
                  display: flex;
                  -ms-flex-direction: row;
                  flex-direction: row;

                  span:nth-of-type(1) {
                    flex: 1;
                    min-width: 0;
                    font-size: 12px;
                    line-height: 18px;
                    color: #646a73;
                    overflow: hidden;
                    white-space: nowrap;
                    text-overflow: ellipsis;
                    text-align: left;
                  }

                  span:nth-of-type(2) {
                    padding-left: 4px;
                    margin-left: auto;
                    font-weight: 500;
                    font-size: 12px;
                    line-height: 18px;
                    color: #f54a45;
                  }
                }

                .card_content_right_bottom {
                  padding-top: 2px;
                  min-height: 22px;
                  max-height: 44px;
                  overflow: hidden;
                  font-size: 14px;
                  line-height: 22px;
                  font-weight: 400;
                  transition: min-height .35s ease-out;
                  overflow-y: auto;
                  color: #1f2329;
                  word-break: break-word;
                  text-align: left;
                  // 文本多行溢出样式start
                  text-overflow: -o-ellipsis-lastline;
                  overflow: hidden;
                  text-overflow: ellipsis;
                  display: -webkit-box;
                  -webkit-line-clamp: 2;
                  line-clamp: 2;
                  -webkit-box-orient: vertical;
                  // 文本多行溢出样式end

                  &:focus {
                    outline: none;
                  }

                  &:focus-within {
                    outline: none;
                  }
                }
              }
            }

          }

          .card_wrap::before {
            content: "";
            position: absolute;
            top: 0;
            bottom: 0;
            left: 0;
            width: 2px;
            border-radius: 2px 0 0 2px;
          }

          .card_wrap.company::before {
            background: #FFC46B;
          }

          .card_wrap.dept::before {
            background: #7BD5A4;
          }

          .card_wrap.self::before {
            background: #608DF3;
          }

          .card_wrap.current_select {
            border: 1px solid #3370ff;
          }

          .card_wrap.current_empty_left_border::before {
            background: none;
          }

        }

        .horizontal .org-chart-node-label .org-chart-node-btn:hover,
        .horizontal .org-chart-node-label .org-chart-node-left-btn:hover {
          transform: scale(1);
        }

        .horizontal .org-chart-node-label .org-chart-node-btn,
        .horizontal .org-chart-node-label .org-chart-node-left-btn {
          border: none;
        }

        .horizontal .org-chart-node-label .org-chart-node-btn.childrenNum:hover,
        .horizontal .org-chart-node-label .org-chart-node-left-btn.childrenNum:hover {
          background: #fff;
          color: #3370ff;
          box-shadow: 0 1px 14px #cccccc;
        }

        .horizontal .org-chart-node-label .org-chart-node-btn.childrenNum:before,
        .horizontal .org-chart-node-label .org-chart-node-left-btn.childrenNum:before {
          border-top: 0px;
        }

        .horizontal .org-chart-node-label .org-chart-node-btn.childrenNum:after,
        .horizontal .org-chart-node-label .org-chart-node-left-btn.childrenNum:after {
          border-left: 0px;
        }

      }

    }

  }
}

.empty {
  height: 20px;

  .info {
    height: 120px !important;
    background: #f4f4f4 !important;
    display: flex;
    justify-content: center;
    align-items: center;

    .zhedie {
      width: 100%;
      height: 20px;
      background: #fff;
      line-height: 20px;
      background: #e4e6f0;
      border-radius: 10px;
      color: rgba(0, 0, 0, 0.5);
      margin-top: 18px;
      font-size: 12px;
    }
  }
}

.popover_box {
  border: 1px solid #cccccc;
  padding: 5px;
  color: #1f2329;
  font-size: 14px;
  line-height: 22px;
  font-weight: 400;
  word-break: break-all;
  cursor: pointer;
  word-break: break-word;
}

/**按钮文 */
.org-chart-node-btn-text {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: #fff;
  border-radius: 50%;
  font-size: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #909090;
  z-index: 2;
  font-weight: 500;
}

.org-chart-node-left-btn:hover,
.org-chart-node-btn:hover {
  .org-chart-node-btn-text {
    background: #fff;
    color: #3370ff;
    box-shadow: 0 1px 14px #cccccc;
  }
}

// .horizontal .org-chart-node-label .org-chart-node-btn.expanded::before,
// .horizontal .org-chart-node-label .org-chart-node-left-btn.expanded::before {
//   background: #fff;
//   border-color: #3370ff;
//   box-shadow: 0 1px 14px #cccccc;
// }

.horizontal .org-chart-node-label .org-chart-node-btn.expanded:hover,
.horizontal .org-chart-node-label .org-chart-node-left-btn.expanded:hover {
  background: #fff;
  color: #3370ff;
  box-shadow: 0 1px 14px #cccccc;
}

父组件:

<template>
  <div class="target-map-wrap">
    <commonHeader class="commonHeader"></commonHeader>
    <!-- 右侧弹窗 -->
    <OkrTreeDetail
      :title="title"
      :visible="drawer"
      @closeDetailDrawer="closeDetailDrawer"
    ></OkrTreeDetail>
    <div class="relation-graph-wrap">
      <div class="top-wrap">
        <div class="inpdiv">
          <el-input
            placeholder="搜索员工姓名或目标关键字"
            v-model="searchValue"
            class="input-wrap"
            @keyup.enter.native="searchList"
          >
          </el-input>
          <i class="el-icon-search"></i>
        </div>
        <slideTab :list="tabList" @selectTab="changeTab"></slideTab>
      </div>
      <VueOkrTreeComponent
        :okrTreeData="okrTreeData"
        @showDetailDrawer="showDetailDrawer"
      ></VueOkrTreeComponent>
    </div>
  </div>
</template>

<script>
import { getNormalList, getStarMapList } from "@/api/common.js";
import { getCookie } from "@/utils/cookie.js";
import { getokrmap } from "@/api/okr.js";
import { getOkrMap } from "@/api/targetMap.js";

export default {
  name: "Index",
  components: {
    commonHeader: () => import("@/components/header.vue"),
    slideTab: () => import("@/components/slideTabs.vue"),
    VueOkrTreeComponent: () => import("@/components/VueOkrTreeComponent.vue"),
    OkrTreeDetail: () => import("./components/OkrTreeDetail.vue"),
  },
  data() {
    return {
      searchValue: "",
      tabList: [],
      okrTreeData: [],
      defaultId: "",
      title: "",
      drawer: false,
    };
  },
  watch: {
    okrTreeData: {
      handler(newVal) {
        this.okrTreeData = newVal;
      },
      immediate: true,
      deep: true,
    },
  },
  mounted() {
    this.getZhouqiList();
    setTimeout(() => {
      this.getList();
    }, 1000);
  },
  methods: {
    showDetailDrawer() {
      this.drawer = true;
    },
    closeDetailDrawer() {
      this.drawer = false;
    },
    getZhouqiList() {
      const obj = {
        periodStatus: "0",
        // userName: "Admin",
        userName: getCookie("username"),
      };
      getNormalList(obj).then((res) => {
        this.tabList = res.data;
        this.defaultId = this.tabList[0].id;
      });
    },
    async getList() {
      const params = {
        periodId: this.defaultId,
      };
      const { msg, code, data } = await getOkrMap(params);
      if (code === 200) {
        this.okrTreeData = data;
      } else {
        this.$message.error(msg);
      }
    },
    // tab 切换方法
    changeTab(id) {
      this.defaultId = id;
      this.okrTreeData = []; // 清空之前的数据
      this.getList();
    },
    //搜索框搜索数据
    async searchList() {
      const params = {
        periodId: this.defaultId,
        userName: "",
        nickName: "",
        objName: this.objName,
      };
      const { msg, code, data } = await getStarMapList(params);
      if (code === 200) {
        this.okrTreeData = data;
      } else {
        this.$message.error(msg);
      }
    },
    handlerKeyChange() {
      console.log("123");
    },
  },
};
</script>

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

点击卡片的时候会出现右侧详情弹窗页面,如下图:

弹窗组件:

<template>
  <el-drawer
    size="680px"
    :visible.sync="dialogVisible"
    :direction="direction"
    :show-close="false"
    @close="close"
  >
    <div slot="title" class="demo-drawer__header">
      <div class="drawer_header_wrap">
        <div class="drawer_header_wrap_left">
          <headerPhoto
            :nickName="nickname"
            :sex="sex"
            :propStyle="{ fontSize: '14px', width: '40px', height: '40px' }"
          ></headerPhoto>
          <div class="user_box">
            <p>uuu</p>
            <span>技术部</span>
          </div>
        </div>
        <div class="drawer_header_wrap_right">
          <span>查看详情</span>
          <i class="el-icon-close" @click="close"></i>
        </div>
      </div>
    </div>
    <div class="demo-drawer__content">
      <div class="drawer_content_wrap">
        <div class="drawer_content_wrap_container">
          <div class="ObjectiveItem_objective_content">
            <div class="ObjectiveItem_objective_icon"></div>
            <div class="ObjectiveItem_objective_content_center">
              <div class="ObjectiveItem_objective_content_center_top">
                <img src="@/assets/img/up.svg" alt="" class="up_svg" />
                <div class="ObjectiveItem_objective_content_center_top_user">
                  <span>www</span>,<span>eee</span>
                </div>
              </div>
              <div class="ObjectiveItem_objective_content_center_bottom">
                说我容光焕发杜尔股份很烦IE我回味回味很烦IE我划分为今日佛业务回家喔i氛围h9firwe回复惹我回家哦废物回家佛IE我就否无额很烦IE我fjo9iwe会发改委就分为法布尔司法发版后IE我很烦IE我
              </div>
            </div>
            <div class="ObjectiveItem_objective_content_right">
              <div class="ObjectiveItem_objective_content_right_progress">
                <div class="progress_top">进度</div>
                <div class="progress_center">
                  <el-progress
                    class="progress"
                    type="circle"
                    :percentage="getPercentage()"
                    :show-text="false"
                    :width="18"
                    :height="18"
                    :color="getProgressColor()"
                    :stroke-width="4"
                  ></el-progress>
                  <span>25%</span>
                </div>
              </div>
              <div class="ObjectiveItem_objective_content_right_weight">
                <div class="weight_top">权重</div>
                <div class="weight_center">100%</div>
              </div>
              <div class="ObjectiveItem_objective_content_right_score">
                <div class="score_top">总分</div>
                <div class="score_center">0.2</div>
              </div>
            </div>
          </div>
          <div class="ObjectiveItem_objective_bottom">
            <img src="@/assets/img/down.svg" alt="" class="down_svg" />
            <div class="ObjectiveItem_objective_bottom_content">
              <span>rrr</span>
            </div>
          </div>
        </div>
        <ul class="kr_list_wrap">
          <li>
            <div class="kr_result_content">
              <div class="kr_result_content_center">
                <p>kkkkkkkkkkkkkkkk​<span>@yyy</span><span>@iii</span></p>
              </div>
              <div class="kr_result_content_right">
                <div class="right_progress">
                  <div class="progress_center">
                    <el-progress
                      class="progress"
                      type="circle"
                      :percentage="getPercentage()"
                      :show-text="false"
                      :width="18"
                      :height="18"
                      :color="getProgressColor()"
                      :stroke-width="4"
                    ></el-progress>
                    <span>25%</span>
                  </div>
                </div>
                <div class="right_weight">
                  <div class="weight_center">100%</div>
                </div>
                <div class="right_score">
                  <div class="score_center">0.2</div>
                </div>
              </div>
            </div>
          </li>
          <li>
            <div class="kr_result_content">
              <div class="kr_result_content_center">
                <p>kkkkkkkkkkkkkkkk​<span>@ll</span><span>@ddd</span></p>
              </div>
              <div class="kr_result_content_right">
                <div class="right_progress">
                  <div class="progress_center">
                    <el-progress
                      class="progress"
                      type="circle"
                      :percentage="getPercentage()"
                      :show-text="false"
                      :width="18"
                      :height="18"
                      :color="getProgressColor()"
                      :stroke-width="4"
                    ></el-progress>
                    <span>25%</span>
                  </div>
                </div>
                <div class="right_weight">
                  <div class="weight_center">100%</div>
                </div>
                <div class="right_score">
                  <div class="score_center">0.2</div>
                </div>
              </div>
            </div>
          </li>
        </ul>
        <div class="drawer_content_wrap_progress">
          <div class="drawer_content_wrap_progress_left">
            <i class="el-icon-document"></i>
          </div>
          <div class="drawer_content_wrap_progress_center">
            <p>进度记录</p>
            <div>
              公共加入分为托管人考托管费热帖奇偶太过分我看见推广吗太浓酷热派克特科技破给她的听过课配开通怕热跨平台各欧特瑞不辜负日本国你让他废物你妇科你付款较为内容范围热热热呃呃呃呃呃呃呃呃呃
            </div>
          </div>
        </div>
      </div>
    </div>
  </el-drawer>
</template>

<script>
import {
  getToken,
  setToken,
  getUsername,
  removeUsername,
  removeToken,
  removeExpiresIn,
  getAdminSex,
  getNickname,
} from "@/utils/auth";
import { getList, doAdd, doEdit, doDelete } from "@/api/targetManage";
export default {
  name: "OkrTreeDetail",
  components: {
    headerPhoto: () => import("@/views/okrHome/components/headerPhoto"),
  },
  props: {
    title: String,
    periodTypeSelect: Array,
    data: Object,
    visible: {
      type: Boolean,
      default: false,
    },
  },
  watch: {
    visible(newVal) {
      this.dialogVisible = newVal;
    },
  },
  data() {
    return {
      dialogVisible: this.visible,
      loading: false,
      direction: "rtl",
      sex: sessionStorage.getItem("sex"),
      nickname: getNickname(),
    };
  },
  created() {},
  mounted() {},
  methods: {
    close() {
      this.$emit("closeDetailDrawer");
    },
    // 获取百分比
    getPercentage(okr) {
      // if (!okr.progress) {
      //   return 0;
      // } else {
      //   if (okr.progress >= 1) {
      //     return 100;
      //   } else {
      //     return +(okr.progress * 100).toFixed(0);
      //   }
      // }
    },
    // 获取状态颜色
    getProgressColor(okr, type) {
      // if (type === "objective") {
      //   if (okr.remark === "1") {
      //     //  取目标状态
      //     if (okr.status === "0") {
      //       return "#5272E5";
      //     } else if (okr.status === "1") {
      //       return "#E79144";
      //     } else if (okr.status === "2") {
      //       return "#D2655D";
      //     } else {
      //       return "#5272E5";
      //     }
      //   } else {
      //     //  默认
      //     const isHaveTwo = okr.okrProcessList.some((a) => a.status === "2");
      //     const isHaveOne = okr.okrProcessList.some((b) => b.status === "1");
      //     if (isHaveOne) {
      //       if (isHaveTwo) {
      //         return "#D2655D";
      //       } else {
      //         return "#E79144";
      //       }
      //     } else {
      //       if (isHaveTwo) {
      //         return "#D2655D";
      //       } else {
      //         return "#5272E5";
      //       }
      //     }
      //   }
      // } else if (type === "kr") {
      //   if (okr.status === "0") {
      //     return "#5272E5";
      //   } else if (okr.status === "1") {
      //     return "#E79144";
      //   } else if (okr.status === "2") {
      //     return "#D2655D";
      //   }
      // }
    },
  },
};
</script>

<style scoped lang="scss">
.demo-drawer__header {
  .drawer_header_wrap {
    padding: 16px 24px;
    border-bottom: 1px solid #dee0e3;
    display: -ms-flexbox;
    display: flex;
    -ms-flex-align: center;
    align-items: center;
    justify-content: space-between;

    .drawer_header_wrap_left {
      display: flex;

      .user_box {
        margin-left: 12px;
        p {
          font-size: 16px;
          // font-weight: 500;
          // line-height: 24px;
          color: #1f2329;
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
        }
        span {
          font-size: 14px;
          color: #8f959e;
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
        }
      }
    }

    .drawer_header_wrap_right {
      display: flex;
      align-items: center;
      span {
        font-size: 16px;
        color: #3370ff;
        line-height: 24px;
        margin-right: 24px;
        cursor: pointer;
      }

      .el-icon-close {
        font-size: 20px;
        color: #909399;
        cursor: pointer;
      }

      .el-icon-close:hover {
        color: #4273f6;
      }
    }
  }
}
/deep/.el-drawer__header {
  padding: 0px;
  margin-bottom: 0px;
}
/deep/.el-drawer:focus {
  outline: 0;
}
.demo-drawer__c