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

最近公司需要做一个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__content {
  padding: 24px 24px 0;
  overflow-y: auto;
  position: relative;
  height: calc(100vh - 79px);

  .drawer_content_wrap {
    border: 1px solid #e4e5e7;
    margin-bottom: 20px;
    box-shadow: none;
    border-radius: 4px;
    padding-top: 12px;
  }
  .drawer_content_wrap_container {
    position: relative;
    border-bottom: 1px solid transparent;
    padding: 0 23px 12px 59px;
    .ObjectiveItem_objective_content {
      -ms-flex: 1;
      flex: 1;
      display: -ms-flexbox;
      display: flex;
      position: relative;

      .ObjectiveItem_objective_icon {
        position: absolute;
        left: -44px;
        top: 18px;
        width: 32px;
        height: 32px;
        margin-right: 12px;
        border-radius: 50%;
        background: url(data:image/png;base64,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);
        background-size: cover;
        z-index: 2;
      }

      .ObjectiveItem_objective_content_center {
        flex: 1;
        .ObjectiveItem_objective_content_center_top {
          position: relative;
          color: #8f959e;
          font-size: 12px;

          .up_svg {
            position: absolute;
            width: 24px;
            height: 24px;
            left: -28px;
            top: 9px;
          }

          .ObjectiveItem_objective_content_center_top_user {
            margin-right: 16px;
            white-space: pre-wrap;
            display: -ms-flexbox;
            display: flex;
            -ms-flex-flow: row wrap;
            flex-flow: row wrap;
            span {
              cursor: pointer;
              &:hover {
                color: #3370ff !important;
              }
            }
          }
        }
        .ObjectiveItem_objective_content_center_bottom {
          -ms-flex: 1;
          flex: 1;
          padding-top: 4px;
          padding-bottom: 4px;
          margin-right: 36px;
          color: #1f2329;
          font-size: 16px;
          line-height: 24px;
          margin-right: 23px;
          font-weight: 400;
          transition: min-height 0.35s ease-out;
          overflow-y: auto;
          color: #1f2329;
          word-break: break-word;
          -webkit-transform: none;
          transform: none;
          -webkit-user-select: none;
          -moz-user-select: none;
          -ms-user-select: none;
          user-select: none;
        }
      }

      .ObjectiveItem_objective_content_right {
        display: -ms-flexbox;
        display: flex;
        min-height: 32px;

        .ObjectiveItem_objective_content_right_progress {
          width: 77px;
          text-align: right;
          display: inline-block;
          line-height: 22px;
          color: #646a73;
          padding-top: 1px;

          .progress_top {
            line-height: 18px;
            font-size: 12px;
            color: #8f959e;
          }

          .progress_center {
            margin-top: 5px;
            color: #646a73;
            white-space: nowrap;
            display: flex;
            align-items: center;
            justify-content: flex-end;
            .progress {
            }
            span {
              display: inline-block;
              width: 43px;
            }
          }
        }

        .ObjectiveItem_objective_content_right_weight {
          margin-left: 16px;
          width: 56px;
          text-align: right;
          padding: 0 8px;
          .weight_top {
            line-height: 18px;
            font-size: 12px;
            color: #8f959e;
          }
          .weight_center {
            line-height: 22px;
            margin-top: 5px;
            color: #646a73;
          }
        }

        .ObjectiveItem_objective_content_right_score {
          margin-left: 6px;
          padding-right: 11px;
          min-height: 34px;
          line-height: 32px;
          border: 1px solid transparent;
          color: #646a73;
          background-color: inherit;
          width: 48px;
          text-align: right;

          .score_top {
            line-height: 18px;
            font-size: 12px;
            color: #8f959e;
          }

          .score_center {
            line-height: 22px;
            margin-top: 5px;
            color: #646a73;
            letter-spacing: 1px;
          }
        }
      }
      .ObjectiveItem_objective_content_right::after {
        content: "";
        display: block;
        position: absolute;
        bottom: 13px;
        left: -28px;
        border-left: 1px solid #e4e5e7;
        top: 18px;
      }
    }
    .ObjectiveItem_objective_bottom {
      position: relative;
      color: #8f959e;
      font-size: 12px;

      .down_svg {
        position: absolute;
        width: 24px;
        height: 24px;
        left: -28px;
        top: -14px;
        // transform: rotateX(180deg);
      }
    }
  }
  .drawer_content_wrap_container::after {
    content: "";
    display: block;
    position: absolute;
    left: 60px;
    bottom: 0;
    right: 24px;
    height: 1px;
    background: #dee0e3;
    z-index: 2;
  }
  .kr_list_wrap {
    li {
      padding: 0 22px 0 58px;
      .kr_result_content {
        position: relative;
        display: flex;
        padding: 12px 0;
        padding-left: 20px;
        border-bottom: 1px solid #dee0e3;
        .kr_result_content_center {
          flex: 1;
          color: #1f2329;
          span {
            color: #3370ff !important;
            cursor: pointer;
          }
        }
        .kr_result_content_right {
          display: flex;
          align-items: center;
          .right_progress {
            width: 77px;
            text-align: right;
            display: inline-block;
            color: #646a73;
            .progress_center {
              color: #646a73;
              white-space: nowrap;
              display: flex;
              align-items: center;
              justify-content: flex-end;

              span {
                display: inline-block;
                width: 43px;
              }
            }
          }
          .right_weight {
            color: #646a73;
            margin-left: 16px;
            width: 56px;
            text-align: right;
            padding: 0 8px;
          }
          .right_score {
            letter-spacing: 1px;
            margin-left: 6px;
            padding-right: 11px;
            color: #646a73;
            width: 48px;
            text-align: right;
          }
        }
      }
      .kr_result_content::before {
        content: " ";
        display: block;
        position: absolute;
        left: 2px;
        top: 19px;
        width: 6px;
        height: 6px;
        border-radius: 50%;
        background-color: #3370ff;
      }
      &:last-child .kr_result_content {
        border-bottom: 0px;
      }
    }
  }
  .drawer_content_wrap_progress {
    border-top: 1px solid #dee0e3;
    display: flex;
    .drawer_content_wrap_progress_left {
      width: 28px;
      height: 28px;
      line-height: 28px;
      margin: 12px 14px 12px 18px;
      background-color: #eff0f1;
      border-radius: 50%;
      color: #8f959e;
      text-align: center;
      font-size: 14px;
    }
    .drawer_content_wrap_progress_center {
      flex: 1;
      p {
        color: #1f2329;
        font-weight: 700;
        line-height: 26px;
        padding: 13px 0 4px;
      }
      div {
        line-height: 26px;
        padding-right: 15px;
        padding-bottom: 11px;
      }
    }
  }
}
</style>

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 24
    评论
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值