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

feat(frontend): OKR 页面重构(TeamOkr/Alignment/Execution)+ 通知 workbench

wangkangyjy 1 неделя назад
Родитель
Сommit
2283361fe7

+ 1 - 1
frontend/src/views/notification/NotificationView.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="notification-page">
+  <div class="notification-page notification-workbench">
     <el-card>
       <template #header>
         <div class="card-header">

+ 5 - 4
frontend/src/views/okr/AlignmentView.vue

@@ -1,8 +1,9 @@
 <template>
-  <div class="alignment-page">
-    <div class="alignment-header">
-      <h3>OKR 对齐视图</h3>
-      <el-select v-model="selectedPeriodId" placeholder="选择周期" @change="loadTree" style="width:240px">
+  <div class="alignment-page alignment-workbench">
+    <div class="data-toolbar">
+      <span class="data-toolbar__title">OKR 对齐视图</span>
+      <span class="data-toolbar__spacer"></span>
+      <el-select v-model="selectedPeriodId" placeholder="选择周期" @change="loadTree" style="width:240px" size="small">
         <el-option v-for="p in periods" :key="p.id" :label="p.name" :value="p.id" />
       </el-select>
     </div>

+ 53 - 2
frontend/src/views/okr/OkrExecutionView.vue

@@ -1,6 +1,57 @@
 <template>
   <div class="okr-execution-view">
-    <h2>执行进度</h2>
-    <p>OKR 执行进度页面(将在任务12完善)</p>
+    <div class="data-toolbar">
+      <span class="data-toolbar__title">执行进度</span>
+    </div>
+    <div class="data-table" v-if="myOkr">
+      <div class="data-table__header" style="grid-template-columns:1fr 80px 80px 100px 80px">
+        <span>KR</span><span>进度</span><span>当前/目标</span><span>状态</span><span>操作</span>
+      </div>
+      <div v-for="kr in myOkr.keyResults" :key="kr.id" class="data-table__row"
+           style="grid-template-columns:1fr 80px 80px 100px 80px">
+        <span>{{ kr.title }}</span>
+        <span style="font-weight:600">{{ krPercent(kr) }}%</span>
+        <span style="color:var(--color-text-secondary)">{{ kr.currentValue }}/{{ kr.targetValue }}</span>
+        <StatusLabel :tone="krStatusTone(kr.status)" :label="krStatusLabel(kr.status)" />
+        <el-button size="small" @click="kr._showUpdate = !kr._showUpdate">更新</el-button>
+      </div>
+    </div>
+    <div v-else class="empty-state">加载中...</div>
   </div>
 </template>
+
+<script setup>
+import { ref, onMounted } from 'vue'
+import { useRoute } from 'vue-router'
+import * as okrApi from '@/api/okr'
+import StatusLabel from '@/components/common/StatusLabel.vue'
+
+const route = useRoute()
+const myOkr = ref(null)
+
+function krPercent(kr) {
+  if (kr.targetValue <= 0) return 0
+  return Math.round((kr.currentValue / kr.targetValue) * 100)
+}
+function krStatusLabel(s) {
+  const map = { NOT_STARTED: '未开始', IN_PROGRESS: '进行中', COMPLETED: '完成', BLOCKED: '阻塞' }
+  return map[s] || s
+}
+function krStatusTone(s) {
+  const map = { NOT_STARTED: 'info', IN_PROGRESS: 'active', COMPLETED: 'success', BLOCKED: 'danger' }
+  return map[s] || 'info'
+}
+
+onMounted(async () => {
+  const periodId = route.query.periodId
+  if (periodId) {
+    const res = await okrApi.getMyOkr(periodId)
+    myOkr.value = res.data
+  }
+})
+</script>
+
+<style scoped>
+.okr-execution-view { max-width: 960px; margin: 0 auto; }
+.empty-state { text-align: center; padding: 48px; color: var(--color-text-muted); }
+</style>

+ 4 - 5
frontend/src/views/okr/TeamOkrView.vue

@@ -1,10 +1,9 @@
 <template>
   <div class="app-page team-okr-workbench">
-    <div class="page-hero">
-      <div class="hero-info">
-        <h2>团队 OKR</h2>
-        <p>{{ subordinates.length }} 名直接下属 · 实时掌握团队运转</p>
-      </div>
+    <div class="data-toolbar">
+      <span class="data-toolbar__title">团队 OKR</span>
+      <span class="data-toolbar__sep">|</span>
+      <span class="data-toolbar__meta">{{ subordinates.length }} 名直接下属</span>
     </div>
 
     <PeriodBanner v-if="periods.length" :periods="periods" v-model="selectedPeriodId" />