fix(workbench): 工作台待关注优化+隔离补漏——类型标签/排序固化/标题措辞 + my_dashboard按entity_id过滤 (dashboard-optimize)
This commit is contained in:
@@ -476,13 +476,17 @@ def my_dashboard(
|
|||||||
from app.models import ActionPlan
|
from app.models import ActionPlan
|
||||||
if current_user.role == "ceo":
|
if current_user.role == "ceo":
|
||||||
# CEO/管理员查看全部行动方案(2026-08-26修复: 原逻辑只按assignee过滤导致工作台显示空)
|
# CEO/管理员查看全部行动方案(2026-08-26修复: 原逻辑只按assignee过滤导致工作台显示空)
|
||||||
my_plans = db.query(ActionPlan).order_by(ActionPlan.updated_at.desc()).all()
|
# 2026-08-31 隔离补漏: CEO 看全部也须按 entity_id 过滤,防跨账套待办串数据
|
||||||
|
my_plans = db.query(ActionPlan).filter(
|
||||||
|
ActionPlan.entity_id == entity_id,
|
||||||
|
).order_by(ActionPlan.updated_at.desc()).all()
|
||||||
else:
|
else:
|
||||||
my_plans = db.query(ActionPlan).filter(
|
my_plans = db.query(ActionPlan).filter(
|
||||||
or_(
|
or_(
|
||||||
ActionPlan.assignee == username,
|
ActionPlan.assignee == username,
|
||||||
ActionPlan.assignee == name,
|
ActionPlan.assignee == name,
|
||||||
)
|
),
|
||||||
|
ActionPlan.entity_id == entity_id,
|
||||||
).order_by(ActionPlan.updated_at.desc()).all()
|
).order_by(ActionPlan.updated_at.desc()).all()
|
||||||
|
|
||||||
plan_list = []
|
plan_list = []
|
||||||
|
|||||||
@@ -32,16 +32,17 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template v-if="!loading">
|
<template v-if="!loading">
|
||||||
<!-- 待办提醒 -->
|
<!-- 待关注提醒(行动逾期 + KPI预警) -->
|
||||||
<div v-if="reminders.length > 0" class="reminder-section">
|
<div v-if="reminders.length > 0" class="reminder-section">
|
||||||
<div class="section-header">
|
<div class="section-header">
|
||||||
<span class="section-icon">📌</span>
|
<span class="section-icon">📌</span>
|
||||||
<span class="section-title">待办提醒</span>
|
<span class="section-title">待关注</span>
|
||||||
<span class="section-badge">{{ reminders.length }}</span>
|
<span class="section-badge">{{ reminders.length }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-for="r in reminders" :key="r.type + r.related_id" class="reminder-card" :class="'sev-' + r.severity">
|
<div v-for="r in sortedReminders" :key="r.type + r.related_id" class="reminder-card" :class="'sev-' + r.severity">
|
||||||
<div class="reminder-left">
|
<div class="reminder-left">
|
||||||
<span class="reminder-icon">{{ r.severity === 'danger' ? '🔴' : '🟡' }}</span>
|
<span class="reminder-icon">{{ r.severity === 'danger' ? '🔴' : '🟡' }}</span>
|
||||||
|
<el-tag size="small" :type="r.related_type === 'action_plan' ? 'primary' : 'warning'" class="reminder-tag">{{ r.related_type === 'action_plan' ? '行动' : '指标' }}</el-tag>
|
||||||
</div>
|
</div>
|
||||||
<div class="reminder-body">
|
<div class="reminder-body">
|
||||||
<div class="reminder-msg">{{ r.message }}</div>
|
<div class="reminder-msg">{{ r.message }}</div>
|
||||||
@@ -115,10 +116,17 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted } from "vue"
|
import { ref, computed, onMounted } from "vue"
|
||||||
import { useRouter } from "vue-router"
|
import { useRouter } from "vue-router"
|
||||||
import api from "../api/index"
|
import api from "../api/index"
|
||||||
|
|
||||||
|
// 排序固化: danger(逾期行动/红色预警) 在前, warning(黄色预警) 在后;
|
||||||
|
// 同 severity 保持后端生成顺序 (overdue→red→yellow), 不改变现有展示次序
|
||||||
|
const severityOrder: Record<string, number> = { danger: 0, warning: 1 }
|
||||||
|
const sortedReminders = computed(() =>
|
||||||
|
[...reminders.value].sort((a: any, b: any) => (severityOrder[a.severity] ?? 2) - (severityOrder[b.severity] ?? 2))
|
||||||
|
)
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const userStr = localStorage.getItem('cma_user') || '{}'
|
const userStr = localStorage.getItem('cma_user') || '{}'
|
||||||
const user = JSON.parse(userStr)
|
const user = JSON.parse(userStr)
|
||||||
@@ -255,8 +263,9 @@ onMounted(async () => {
|
|||||||
}
|
}
|
||||||
.reminder-card.sev-danger { background: #fef0f0; border: 1px solid #fde2e2; }
|
.reminder-card.sev-danger { background: #fef0f0; border: 1px solid #fde2e2; }
|
||||||
.reminder-card.sev-warning { background: #fdf6ec; border: 1px solid #f5dab1; }
|
.reminder-card.sev-warning { background: #fdf6ec; border: 1px solid #f5dab1; }
|
||||||
.reminder-left { flex-shrink: 0; }
|
.reminder-left { flex-shrink: 0; display: flex; align-items: center; gap: 6px; }
|
||||||
.reminder-icon { font-size: 18px; }
|
.reminder-icon { font-size: 18px; }
|
||||||
|
.reminder-tag { font-size: 11px; }
|
||||||
.reminder-body { flex: 1; }
|
.reminder-body { flex: 1; }
|
||||||
.reminder-msg { font-size: 14px; }
|
.reminder-msg { font-size: 14px; }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user