Просмотр исходного кода

update: layout style
support mobile style

Sendya 6 лет назад
Родитель
Сommit
36b3f2dec5

+ 76 - 72
src/components/chart/RankList.vue

@@ -1,73 +1,77 @@
-<template>
-  <div class="rank">
-    <h4 class="title">{{ title }}</h4>
-    <ul class="list">
-      <li :key="index" v-for="(item, index) in list">
-        <span :class="index < 3 ? 'active' : null">{{ index + 1 }}</span>
-        <span >{{ item.name }}</span>
-        <span >{{ item.total }}</span>
-      </li>
-    </ul>
-  </div>
-</template>
-
-<script>
-  export default {
-    name: "RankList",
-    // ['title', 'list']
-    props: {
-      title: {
-        type: String,
-        default: ''
-      },
-      list: {
-        type: Array,
-        default: null
-      }
-    }
-  }
-</script>
-
-<style lang="scss" scoped>
-
-    .rank {
-        padding: 0 32px 32px 72px;
-
-        .list {
-            margin: 25px 0 0;
-            padding: 0;
-            list-style: none;
-
-            li {
-                margin-top: 16px;
-
-                span {
-                    color: rgba(0, 0, 0, .65);
-                    font-size: 14px;
-                    line-height: 22px;
-
-                    &:first-child {
-                        background-color: #f5f5f5;
-                        border-radius: 20px;
-                        display: inline-block;
-                        font-size: 12px;
-                        font-weight: 600;
-                        margin-right: 24px;
-                        height: 20px;
-                        line-height: 20px;
-                        width: 20px;
-                        text-align: center;
-                    }
-                    &.active {
-                        background-color: #314659;
-                        color: #fff;
-                    }
-                    &:last-child {
-                        float: right;
-                    }
-                }
-            }
-        }
-    }
-
+<template>
+  <div class="rank">
+    <h4 class="title">{{ title }}</h4>
+    <ul class="list">
+      <li :key="index" v-for="(item, index) in list">
+        <span :class="index < 3 ? 'active' : null">{{ index + 1 }}</span>
+        <span>{{ item.name }}</span>
+        <span>{{ item.total }}</span>
+      </li>
+    </ul>
+  </div>
+</template>
+
+<script>
+  export default {
+    name: "RankList",
+    // ['title', 'list']
+    props: {
+      title: {
+        type: String,
+        default: ''
+      },
+      list: {
+        type: Array,
+        default: null
+      }
+    }
+  }
+</script>
+
+<style lang="scss" scoped>
+
+  .rank {
+    padding: 0 32px 32px 72px;
+
+    .list {
+      margin: 25px 0 0;
+      padding: 0;
+      list-style: none;
+
+      li {
+        margin-top: 16px;
+
+        span {
+          color: rgba(0, 0, 0, .65);
+          font-size: 14px;
+          line-height: 22px;
+
+          &:first-child {
+            background-color: #f5f5f5;
+            border-radius: 20px;
+            display: inline-block;
+            font-size: 12px;
+            font-weight: 600;
+            margin-right: 24px;
+            height: 20px;
+            line-height: 20px;
+            width: 20px;
+            text-align: center;
+          }
+          &.active {
+            background-color: #314659;
+            color: #fff;
+          }
+          &:last-child {
+            float: right;
+          }
+        }
+      }
+    }
+  }
+
+  .mobile .rank {
+    padding: 0 32px 32px 32px;
+  }
+
 </style>

+ 26 - 2
src/components/layout/LayoutMain.vue

@@ -1,9 +1,9 @@
 <template>
-  <a-layout class="layout">
+  <a-layout class="layout" :class="device">
 
     <a-drawer 
       v-if="device === 'mobile'"
-      wrapClassName="drawer-sider"
+      :wrapClassName="'drawer-sider ' + theme"
       placement="left"
       @close="() => this.collapsed = false"
       :closable="false"
@@ -93,6 +93,14 @@
     min-height: 100vh;
     overflow-x: hidden;
 
+    &.mobile {
+      .ant-table-wrapper {
+        .ant-table-body {
+          overflow-y: auto;
+        }
+      }
+    }
+
     &.ant-layout-has-sider {
       flex-direction: row;
     }
@@ -156,6 +164,22 @@
 
   // drawer-sider 自定义
   .ant-drawer.drawer-sider {
+    .sider {
+      box-shadow: none;
+    }
+
+    &.dark {
+      .ant-drawer-content {
+        background-color: rgb(0, 21, 41);
+      }
+    }
+    &.light {
+      box-shadow: none;
+      .ant-drawer-content {
+        background-color: #fff;
+      }
+    }
+
     .ant-drawer-body {
       padding: 0
     }

+ 195 - 178
src/components/layout/PageHeader.vue

@@ -1,179 +1,196 @@
-<template>
-  <div class="page-header">
-
-    <a-breadcrumb class="breadcrumb">
-      <a-breadcrumb-item v-for="(item, index) in breadList" :key="index">
-        <router-link v-if="item.name != name" :to="{ path: item.path }">
-          {{ item.meta.title }}
-        </router-link>
-        <span v-else>{{ item.meta.title }}</span>
-      </a-breadcrumb-item>
-    </a-breadcrumb>
-
-    <div class="detail">
-      <div class="main" v-if="!$route.meta.hiddenPageHeader">
-        <div class="row">
-          <img v-if="logo" :src="logo" class="logo"/>
-          <h1 v-if="title" class="title">{{ title }}</h1>
-          <div class="action">
-            <slot name="action"></slot>
-          </div>
-        </div>
-        <div class="row">
-          <div v-if="avatar" class="avatar">
-            <a-avatar :src="avatar"/>
-          </div>
-          <div v-if="this.$slots.content" class="content">
-            <slot name="content"></slot>
-          </div>
-          <div v-if="this.$slots.extra" class="extra">
-            <slot name="extra"></slot>
-          </div>
-        </div>
-      </div>
-
-    </div>
-  </div>
-</template>
-
-<script>
-  import Breadcrumb from '@/components/tools/Breadcrumb'
-
-  export default {
-    name: "PageHeader",
-    components: {
-      "s-breadcrumb": Breadcrumb
-    },
-    props: {
-      title: {
-        type: String,
-        default: '',
-        required: false
-      },
-      breadcrumb: {
-        type: Array,
-        default: null,
-        required: false
-      },
-      logo: {
-        type: String,
-        default: '',
-        required: false
-      },
-      avatar: {
-        type: String,
-        default: '',
-        required: false
-      }
-    },
-    data() {
-      return {
-        name: '',
-        breadList: [],
-      }
-    },
-    created() {
-      this.getBreadcrumb()
-    },
-    methods: {
-      getBreadcrumb() {
-
-        this.breadList = []
-        this.breadList.push({name: 'index', path: '/dashboard/', meta: {title: '首页'}})
-
-        this.name = this.$route.name
-        this.$route.matched.forEach((item) => {
-          // item.meta.name === 'dashboard' ? item.path = '/dashboard' : this.$route.path === item.path
-          this.breadList.push(item)
-        })
-      }
-    },
-    watch: {
-      $route() {
-        this.getBreadcrumb()
-      }
-    }
-  }
-</script>
-
-<style lang="scss" scoped>
-  .page-header {
-    background: #fff;
-    padding: 16px 32px 0;
-    border-bottom: 1px solid #e8e8e8;
-
-    .breadcrumb {
-      margin-bottom: 16px;
-    }
-
-    .detail {
-      display: flex;
-      /*margin-bottom: 16px;*/
-
-      .avatar {
-        flex: 0 1 72px;
-        margin: 0 24px 8px 0;
-
-        & > span {
-          border-radius: 72px;
-          display: block;
-          width: 72px;
-          height: 72px;
-        }
-      }
-
-      .main {
-        width: 100%;
-        flex: 0 1 auto;
-
-        .row {
-          display: flex;
-          width: 100%;
-
-          .avatar {
-            margin-bottom: 16px;
-          }
-        }
-
-        .title {
-          font-size: 20px;
-          font-weight: 500;
-
-          font-size: 20px;
-          line-height: 28px;
-          font-weight: 500;
-          color: rgba(0,0,0,.85);
-          margin-bottom: 16px;
-          flex: auto;
-
-        }
-        .logo {
-          width: 28px;
-          height: 28px;
-          border-radius: 4px;
-          margin-right: 16px;
-        }
-        .content {
-          flex: auto;
-          color: rgba(0,0,0,.45);
-          line-height: 22px;
-        }
-        .extra {
-          flex: 0 1 auto;
-          margin-left: 88px;
-          min-width: 242px;
-          text-align: right;
-        }
-        .action {
-          margin-left: 56px;
-          min-width: 266px;
-          flex: 0 1 auto;
-          text-align: right;
-          &:empty {
-            display: none;
-          }
-        }
-      }
-    }
-  }
+<template>
+  <div class="page-header">
+
+    <a-breadcrumb class="breadcrumb">
+      <a-breadcrumb-item v-for="(item, index) in breadList" :key="index">
+        <router-link v-if="item.name != name" :to="{ path: item.path }">
+          {{ item.meta.title }}
+        </router-link>
+        <span v-else>{{ item.meta.title }}</span>
+      </a-breadcrumb-item>
+    </a-breadcrumb>
+
+    <div class="detail">
+      <div class="main" v-if="!$route.meta.hiddenPageHeader">
+        <div class="row">
+          <img v-if="logo" :src="logo" class="logo"/>
+          <h1 v-if="title" class="title">{{ title }}</h1>
+          <div class="action">
+            <slot name="action"></slot>
+          </div>
+        </div>
+        <div class="row">
+          <div v-if="avatar" class="avatar">
+            <a-avatar :src="avatar"/>
+          </div>
+          <div v-if="this.$slots.content" class="content">
+            <slot name="content"></slot>
+          </div>
+          <div v-if="this.$slots.extra" class="extra">
+            <slot name="extra"></slot>
+          </div>
+        </div>
+      </div>
+
+    </div>
+  </div>
+</template>
+
+<script>
+  import Breadcrumb from '@/components/tools/Breadcrumb'
+
+  export default {
+    name: "PageHeader",
+    components: {
+      "s-breadcrumb": Breadcrumb
+    },
+    props: {
+      title: {
+        type: String,
+        default: '',
+        required: false
+      },
+      breadcrumb: {
+        type: Array,
+        default: null,
+        required: false
+      },
+      logo: {
+        type: String,
+        default: '',
+        required: false
+      },
+      avatar: {
+        type: String,
+        default: '',
+        required: false
+      }
+    },
+    data() {
+      return {
+        name: '',
+        breadList: [],
+      }
+    },
+    created() {
+      this.getBreadcrumb()
+    },
+    methods: {
+      getBreadcrumb() {
+
+        this.breadList = []
+        this.breadList.push({name: 'index', path: '/dashboard/', meta: {title: '首页'}})
+
+        this.name = this.$route.name
+        this.$route.matched.forEach((item) => {
+          // item.meta.name === 'dashboard' ? item.path = '/dashboard' : this.$route.path === item.path
+          this.breadList.push(item)
+        })
+      }
+    },
+    watch: {
+      $route() {
+        this.getBreadcrumb()
+      }
+    }
+  }
+</script>
+
+<style lang="scss" scoped>
+  .page-header {
+    background: #fff;
+    padding: 16px 32px 0;
+    border-bottom: 1px solid #e8e8e8;
+
+    .breadcrumb {
+      margin-bottom: 16px;
+    }
+
+    .detail {
+      display: flex;
+      /*margin-bottom: 16px;*/
+
+      .avatar {
+        flex: 0 1 72px;
+        margin: 0 24px 8px 0;
+
+        & > span {
+          border-radius: 72px;
+          display: block;
+          width: 72px;
+          height: 72px;
+        }
+      }
+
+      .main {
+        width: 100%;
+        flex: 0 1 auto;
+
+        .row {
+          display: flex;
+          width: 100%;
+
+          .avatar {
+            margin-bottom: 16px;
+          }
+        }
+
+        .title {
+          font-size: 20px;
+          font-weight: 500;
+
+          font-size: 20px;
+          line-height: 28px;
+          font-weight: 500;
+          color: rgba(0,0,0,.85);
+          margin-bottom: 16px;
+          flex: auto;
+
+        }
+        .logo {
+          width: 28px;
+          height: 28px;
+          border-radius: 4px;
+          margin-right: 16px;
+        }
+        .content {
+          flex: auto;
+          color: rgba(0,0,0,.45);
+          line-height: 22px;
+        }
+        .extra {
+          flex: 0 1 auto;
+          margin-left: 88px;
+          min-width: 242px;
+          text-align: right;
+        }
+        .action {
+          margin-left: 56px;
+          min-width: 266px;
+          flex: 0 1 auto;
+          text-align: right;
+          &:empty {
+            display: none;
+          }
+        }
+      }
+    }
+  }
+
+  .mobile .page-header {
+
+    .main {
+
+      .row {
+        flex-wrap: wrap;
+      }
+
+      .extra {
+        flex: 1 1 auto;
+        margin-left: 0;
+        min-width: 0;
+        text-align: right;
+      }
+    }
+  }
 </style>

+ 342 - 328
src/views/dashboard/Workplace.vue

@@ -1,329 +1,343 @@
-<template>
-  <page-layout :avatar="avatar">
-    <div slot="headerContent">
-      <div class="title">{{ timeFix }},{{ user.name }},{{ welcome() }}</div>
-      <div>前端工程师 | 蚂蚁金服 - 某某某事业群 - VUE平台</div>
-    </div>
-    <div slot="extra">
-      <a-row>
-        <a-col :sm="8" :xs="24">
-          <head-info title="项目数" content="56" :bordered="true"/>
-        </a-col>
-        <a-col :sm="8" :xs="24">
-          <head-info title="团队排名" content="8/24" :bordered="true"/>
-        </a-col>
-        <a-col :sm="8" :xs="24">
-          <head-info title="项目访问" content="2,223"/>
-        </a-col>
-      </a-row>
-    </div>
-
-    <div>
-      <a-row :gutter="24">
-        <a-col :xl="16" :lg="24" :md="24" :sm="24" :xs="24">
-          <a-card 
-            class="project-list" 
-            :loading="loading" 
-            style="margin-bottom: 24px;" 
-            :bordered="false" 
-            title="进行中的项目"
-            :body-style="{ padding: 0 }">
-            <a slot="extra">全部项目</a>
-            <div>
-              <a-card-grid :key="i" v-for="(item, i) in projects">
-                <a-card :bordered="false" :body-style="{ padding: 0 }">
-                  <a-card-meta>
-                    <div slot="title" class="card-title">
-                      <a-avatar size="small" :src="item.cover"/>
-                      <a>{{ item.title }}</a>
-                    </div>
-                    <div slot="description" class="card-description">
-                      {{ item.description }}
-                    </div>
-                  </a-card-meta>
-                  <div class="project-item">
-                    <a href="/#/">科学搬砖组</a>
-                    <span class="datetime">9小时前</span>
-                  </div>
-                </a-card>
-              </a-card-grid>
-            </div>
-          </a-card>
-
-          <a-card :loading="loading" title="动态" :bordered="false">
-            <a-list>
-              <a-list-item :key="index" v-for="(item, index) in activities">
-                <a-list-item-meta>
-                  <a-avatar slot="avatar" :src="item.user.avatar" />
-                  <div slot="title">
-                    <span>{{ item.user.nickname }}</span>&nbsp;
-                    在&nbsp;<a href="#">{{ item.project.name }}</a>&nbsp;
-                    <span>{{ item.project.action }}</span>&nbsp;
-                    <a href="#">{{ item.project.event }}</a>
-                  </div>
-                  <div slot="description">{{ item.time }}</div>
-                </a-list-item-meta>
-              </a-list-item>
-            </a-list>
-          </a-card>
-        </a-col>
-        <a-col 
-          style="padding: 0 12px" 
-          :xl="8" 
-          :lg="24" 
-          :md="24" 
-          :sm="24" 
-          :xs="24">
-          <a-card title="快速开始 / 便捷导航" style="margin-bottom: 24px" :bordered="false" :body-style="{padding: 0}">
-            <div class="item-group">
-              <a>操作一</a>
-              <a>操作二</a>
-              <a>操作三</a>
-              <a>操作四</a>
-              <a>操作五</a>
-              <a>操作六</a>
-              <a-button size="small" type="primary" ghost icon="plus">添加</a-button>
-            </div>
-          </a-card>
-          <a-card title="XX 指数" style="margin-bottom: 24px" :loading="radarLoading" :bordered="false" :body-style="{ padding: 0 }">
-            <div style="min-height: 400px;">
-              <!-- :scale="scale" :axis1Opts="axis1Opts" :axis2Opts="axis2Opts"  -->
-              <radar :data="radarData" />
-            </div>
-          </a-card>
-          <a-card :loading="loading" title="团队" :bordered="false">
-            <div class="members">
-              <a-row>
-                <a-col :span="12" v-for="(item, index) in teams" :key="index">
-                  <a>
-                    <a-avatar size="small" :src="item.avatar" />
-                    <span class="member">{{ item.name }}</span>
-                  </a>
-                </a-col>
-              </a-row>
-            </div>
-          </a-card>
-        </a-col>
-      </a-row>
-    </div>
-  </page-layout>
-</template>
-
-<script>
-  import { timeFix } from "@/utils/util"
-  import {mapGetters} from "vuex"
-
-  import PageLayout from '@/components/layout/PageLayout'
-  import HeadInfo from '@/components/tools/HeadInfo'
-  import Radar from '@/components/chart/Radar'
-
-  const DataSet = require('@antv/data-set')
-
-  export default {
-    name: "Workplace",
-    components: {
-      PageLayout,
-      HeadInfo,
-      Radar
-    },
-    data() {
-      return {
-        timeFix: timeFix(),
-        avatar: '',
-        user: {},
-
-        projects: [],
-        loading: true,
-        radarLoading: true,
-        activities: [],
-        teams: [],
-
-        // data
-        axis1Opts: {
-          dataKey: 'item',
-          line: null,
-          tickLine: null,
-          grid: {
-            lineStyle: {
-              lineDash: null
-            },
-            hideFirstLine: false
-          }
-        },
-        axis2Opts: {
-          dataKey: 'score',
-          line: null,
-          tickLine: null,
-          grid: {
-            type: 'polygon',
-            lineStyle: {
-              lineDash: null
-            }
-          }
-        },
-        scale: [{
-          dataKey: 'score',
-          min: 0,
-          max: 80
-        }],
-        axisData: [
-          { item: '引用', a: 70, b: 30, c: 40 },
-          { item: '口碑', a: 60, b: 70, c: 40 },
-          { item: '产量', a: 50, b: 60, c: 40 },
-          { item: '贡献', a: 40, b: 50, c: 40 },
-          { item: '热度', a: 60, b: 70, c: 40 },
-          { item: '引用', a: 70, b: 50, c: 40 }
-        ],
-        radarData: []
-      }
-    },
-    computed: {
-      userInfo() {
-        return this.$store.getters.userInfo
-      }
-    },
-    created() {
-      this.user = this.userInfo
-      this.avatar = this.userInfo.avatar
-    },
-    mounted() {
-      this.getProjects()
-      this.getActivity()
-      this.getTeams()
-      this.initRadar()
-    },
-    methods: {
-      ...mapGetters(["nickname", "welcome"]),
-      getProjects() {
-        this.$http.get('/list/search/projects')
-          .then(res => {
-            this.projects = res.result && res.result.data
-            this.loading = false
-          })
-      },
-      getActivity() {
-        this.$http.get('/workplace/activity')
-          .then(res => {
-            this.activities = res.result
-          })
-      },
-      getTeams() {
-        this.$http.get('/workplace/teams')
-          .then(res => {
-            this.teams = res.result
-          })
-      },
-      initRadar() {
-        this.radarLoading = true
-
-        this.$http.get('/workplace/radar')
-          .then(res => {
-
-            const dv = new DataSet.View().source(res.result)
-            dv.transform({
-              type: 'fold',
-              fields: ['个人', '团队', '部门'],
-              key: 'user',
-              value: 'score'
-            })
-
-            this.radarData = dv.rows
-            this.radarLoading = false
-          })
-      }
-    }
-  }
-</script>
-
-<style lang="scss" scoped>
-  .project-list {
-
-    .card-title {
-      font-size: 0;
-
-      a {
-        color: rgba(0, 0, 0, 0.85);
-        margin-left: 12px;
-        line-height: 24px;
-        height: 24px;
-        display: inline-block;
-        vertical-align: top;
-        font-size: 14px;
-
-        &:hover {
-          color: #1890ff;
-        }
-      }
-    }
-    .card-description {
-      color: rgba(0, 0, 0, 0.45);
-      height: 44px;
-      line-height: 22px;
-      overflow: hidden;
-    }
-    .project-item {
-      display: flex;
-      margin-top: 8px;
-      overflow: hidden;
-      font-size: 12px;
-      height: 20px;
-      line-height: 20px;
-      a {
-        color: rgba(0, 0, 0, 0.45);
-        display: inline-block;
-        flex: 1 1 0;
-
-        &:hover {
-          color: #1890ff;
-        }
-      }
-      .datetime {
-        color: rgba(0, 0, 0, 0.25);
-        flex: 0 0 auto;
-        float: right;
-      }
-    }
-    .ant-card-meta-description {
-      color: rgba(0, 0, 0, 0.45);
-      height: 44px;
-      line-height: 22px;
-      overflow: hidden;
-    }
-  }
-
-  .item-group {
-    padding: 20px 0 8px 24px;
-    font-size: 0;
-    a {
-      color: rgba(0, 0, 0, 0.65);
-      display: inline-block;
-      font-size: 14px;
-      margin-bottom: 13px;
-      width: 25%;
-    }
-  }
-
-  .members {
-    a {
-      display: block;
-      margin: 12px 0;
-      line-height: 24px;
-      height: 24px;
-      .member {
-        font-size: 14px;
-        color: rgba(0, 0, 0, .65);
-        line-height: 24px;
-        max-width: 100px;
-        vertical-align: top;
-        margin-left: 12px;
-        transition: all 0.3s;
-        display: inline-block;
-      }
-      &:hover {
-        span {
-          color: #1890ff;
-        }
-      }
-    }
-  }
+<template>
+  <page-layout :avatar="avatar">
+    <div slot="headerContent">
+      <div class="title">{{ timeFix }},{{ user.name }}<span class="welcome-text">,{{ welcome() }}</span></div>
+      <div>前端工程师 | 蚂蚁金服 - 某某某事业群 - VUE平台</div>
+    </div>
+    <div slot="extra">
+      <a-row class="more-info">
+        <a-col :span="8">
+          <head-info title="项目数" content="56" :bordered="true"/>
+        </a-col>
+        <a-col :span="8">
+          <head-info title="团队排名" content="8/24" :bordered="true"/>
+        </a-col>
+        <a-col :span="8">
+          <head-info title="项目访问" content="2,223"/>
+        </a-col>
+      </a-row>
+    </div>
+
+    <div>
+      <a-row :gutter="24">
+        <a-col :xl="16" :lg="24" :md="24" :sm="24" :xs="24">
+          <a-card 
+            class="project-list" 
+            :loading="loading" 
+            style="margin-bottom: 24px;" 
+            :bordered="false" 
+            title="进行中的项目"
+            :body-style="{ padding: 0 }">
+            <a slot="extra">全部项目</a>
+            <div>
+              <a-card-grid :key="i" v-for="(item, i) in projects">
+                <a-card :bordered="false" :body-style="{ padding: 0 }">
+                  <a-card-meta>
+                    <div slot="title" class="card-title">
+                      <a-avatar size="small" :src="item.cover"/>
+                      <a>{{ item.title }}</a>
+                    </div>
+                    <div slot="description" class="card-description">
+                      {{ item.description }}
+                    </div>
+                  </a-card-meta>
+                  <div class="project-item">
+                    <a href="/#/">科学搬砖组</a>
+                    <span class="datetime">9小时前</span>
+                  </div>
+                </a-card>
+              </a-card-grid>
+            </div>
+          </a-card>
+
+          <a-card :loading="loading" title="动态" :bordered="false">
+            <a-list>
+              <a-list-item :key="index" v-for="(item, index) in activities">
+                <a-list-item-meta>
+                  <a-avatar slot="avatar" :src="item.user.avatar" />
+                  <div slot="title">
+                    <span>{{ item.user.nickname }}</span>&nbsp;
+                    在&nbsp;<a href="#">{{ item.project.name }}</a>&nbsp;
+                    <span>{{ item.project.action }}</span>&nbsp;
+                    <a href="#">{{ item.project.event }}</a>
+                  </div>
+                  <div slot="description">{{ item.time }}</div>
+                </a-list-item-meta>
+              </a-list-item>
+            </a-list>
+          </a-card>
+        </a-col>
+        <a-col 
+          style="padding: 0 12px" 
+          :xl="8" 
+          :lg="24" 
+          :md="24" 
+          :sm="24" 
+          :xs="24">
+          <a-card title="快速开始 / 便捷导航" style="margin-bottom: 24px" :bordered="false" :body-style="{padding: 0}">
+            <div class="item-group">
+              <a>操作一</a>
+              <a>操作二</a>
+              <a>操作三</a>
+              <a>操作四</a>
+              <a>操作五</a>
+              <a>操作六</a>
+              <a-button size="small" type="primary" ghost icon="plus">添加</a-button>
+            </div>
+          </a-card>
+          <a-card title="XX 指数" style="margin-bottom: 24px" :loading="radarLoading" :bordered="false" :body-style="{ padding: 0 }">
+            <div style="min-height: 400px;">
+              <!-- :scale="scale" :axis1Opts="axis1Opts" :axis2Opts="axis2Opts"  -->
+              <radar :data="radarData" />
+            </div>
+          </a-card>
+          <a-card :loading="loading" title="团队" :bordered="false">
+            <div class="members">
+              <a-row>
+                <a-col :span="12" v-for="(item, index) in teams" :key="index">
+                  <a>
+                    <a-avatar size="small" :src="item.avatar" />
+                    <span class="member">{{ item.name }}</span>
+                  </a>
+                </a-col>
+              </a-row>
+            </div>
+          </a-card>
+        </a-col>
+      </a-row>
+    </div>
+  </page-layout>
+</template>
+
+<script>
+  import { timeFix } from "@/utils/util"
+  import {mapGetters} from "vuex"
+
+  import PageLayout from '@/components/layout/PageLayout'
+  import HeadInfo from '@/components/tools/HeadInfo'
+  import Radar from '@/components/chart/Radar'
+
+  const DataSet = require('@antv/data-set')
+
+  export default {
+    name: "Workplace",
+    components: {
+      PageLayout,
+      HeadInfo,
+      Radar
+    },
+    data() {
+      return {
+        timeFix: timeFix(),
+        avatar: '',
+        user: {},
+
+        projects: [],
+        loading: true,
+        radarLoading: true,
+        activities: [],
+        teams: [],
+
+        // data
+        axis1Opts: {
+          dataKey: 'item',
+          line: null,
+          tickLine: null,
+          grid: {
+            lineStyle: {
+              lineDash: null
+            },
+            hideFirstLine: false
+          }
+        },
+        axis2Opts: {
+          dataKey: 'score',
+          line: null,
+          tickLine: null,
+          grid: {
+            type: 'polygon',
+            lineStyle: {
+              lineDash: null
+            }
+          }
+        },
+        scale: [{
+          dataKey: 'score',
+          min: 0,
+          max: 80
+        }],
+        axisData: [
+          { item: '引用', a: 70, b: 30, c: 40 },
+          { item: '口碑', a: 60, b: 70, c: 40 },
+          { item: '产量', a: 50, b: 60, c: 40 },
+          { item: '贡献', a: 40, b: 50, c: 40 },
+          { item: '热度', a: 60, b: 70, c: 40 },
+          { item: '引用', a: 70, b: 50, c: 40 }
+        ],
+        radarData: []
+      }
+    },
+    computed: {
+      userInfo() {
+        return this.$store.getters.userInfo
+      }
+    },
+    created() {
+      this.user = this.userInfo
+      this.avatar = this.userInfo.avatar
+    },
+    mounted() {
+      this.getProjects()
+      this.getActivity()
+      this.getTeams()
+      this.initRadar()
+    },
+    methods: {
+      ...mapGetters(["nickname", "welcome"]),
+      getProjects() {
+        this.$http.get('/list/search/projects')
+          .then(res => {
+            this.projects = res.result && res.result.data
+            this.loading = false
+          })
+      },
+      getActivity() {
+        this.$http.get('/workplace/activity')
+          .then(res => {
+            this.activities = res.result
+          })
+      },
+      getTeams() {
+        this.$http.get('/workplace/teams')
+          .then(res => {
+            this.teams = res.result
+          })
+      },
+      initRadar() {
+        this.radarLoading = true
+
+        this.$http.get('/workplace/radar')
+          .then(res => {
+
+            const dv = new DataSet.View().source(res.result)
+            dv.transform({
+              type: 'fold',
+              fields: ['个人', '团队', '部门'],
+              key: 'user',
+              value: 'score'
+            })
+
+            this.radarData = dv.rows
+            this.radarLoading = false
+          })
+      }
+    }
+  }
+</script>
+
+<style lang="scss" scoped>
+  .project-list {
+
+    .card-title {
+      font-size: 0;
+
+      a {
+        color: rgba(0, 0, 0, 0.85);
+        margin-left: 12px;
+        line-height: 24px;
+        height: 24px;
+        display: inline-block;
+        vertical-align: top;
+        font-size: 14px;
+
+        &:hover {
+          color: #1890ff;
+        }
+      }
+    }
+    .card-description {
+      color: rgba(0, 0, 0, 0.45);
+      height: 44px;
+      line-height: 22px;
+      overflow: hidden;
+    }
+    .project-item {
+      display: flex;
+      margin-top: 8px;
+      overflow: hidden;
+      font-size: 12px;
+      height: 20px;
+      line-height: 20px;
+      a {
+        color: rgba(0, 0, 0, 0.45);
+        display: inline-block;
+        flex: 1 1 0;
+
+        &:hover {
+          color: #1890ff;
+        }
+      }
+      .datetime {
+        color: rgba(0, 0, 0, 0.25);
+        flex: 0 0 auto;
+        float: right;
+      }
+    }
+    .ant-card-meta-description {
+      color: rgba(0, 0, 0, 0.45);
+      height: 44px;
+      line-height: 22px;
+      overflow: hidden;
+    }
+  }
+
+  .item-group {
+    padding: 20px 0 8px 24px;
+    font-size: 0;
+    a {
+      color: rgba(0, 0, 0, 0.65);
+      display: inline-block;
+      font-size: 14px;
+      margin-bottom: 13px;
+      width: 25%;
+    }
+  }
+
+  .members {
+    a {
+      display: block;
+      margin: 12px 0;
+      line-height: 24px;
+      height: 24px;
+      .member {
+        font-size: 14px;
+        color: rgba(0, 0, 0, .65);
+        line-height: 24px;
+        max-width: 100px;
+        vertical-align: top;
+        margin-left: 12px;
+        transition: all 0.3s;
+        display: inline-block;
+      }
+      &:hover {
+        span {
+          color: #1890ff;
+        }
+      }
+    }
+  }
+
+  .mobile {
+
+    .more-info {
+      border-top: 1px solid #e8e8e8;
+      padding-top: 16px;
+      margin: 16px 0 16px;
+    }
+
+    .content .title .welcome-text {
+      display: none;
+    }
+  }
+
 </style>