更新bug

This commit is contained in:
Your Name
2026-08-17 09:06:49 +08:00
parent 2fc8048844
commit c1eee2d28a
48 changed files with 3646 additions and 1016 deletions
@@ -98,7 +98,7 @@
</div>
</article>
<article class="metric-card">
<article v-if="dashboard.scope.kind !== 'assistant'" class="metric-card">
<div class="metric-label-row">
<span>本人本月业绩</span>
<el-tooltip :content="dashboard.meta.commission_note" placement="top">
@@ -151,11 +151,11 @@
<div class="panel-header">
<div>
<h2>{{ dashboard.rankings.appointments.title }}</h2>
<p>{{ appointmentRankingSubtitle }}</p>
<p v-if="appointmentRankingSubtitle">{{ appointmentRankingSubtitle }}</p>
</div>
<div class="panel-header-actions">
<el-tree-select
v-if="dashboard.rankings.appointments.kind !== 'doctor'"
v-if="showRankingDeptSelect"
v-model="rankingDeptId"
:data="dashboard.filters.ranking_departments"
:props="departmentTreeProps"
@@ -164,7 +164,7 @@
clearable
filterable
default-expand-all
placeholder="全部可见部门"
placeholder="全部部门"
class="ranking-dept-select"
@change="handleRankingDeptChange"
/>
@@ -176,12 +176,16 @@
v-for="(item, index) in dashboard.rankings.appointments.items"
:key="`appointment-${item.id}-${index}`"
class="ranking-row"
:class="{ 'is-self': item.is_self }"
>
<span class="ranking-index" :class="{ 'is-top': index < 2 }">{{ index + 1 }}</span>
<span class="ranking-index" :class="{ 'is-top': index < 2, 'is-self': item.is_self }">{{ index + 1 }}</span>
<div class="ranking-main">
<div class="ranking-copy">
<strong>{{ item.name || '未命名成员' }}</strong>
<span>{{ formatNumber(item.count) }} 挂号</span>
<strong>
{{ item.name || '未命名成员' }}
<i v-if="item.is_self" class="ranking-self-tag">我</i>
</strong>
<span>{{ formatNumber(item.count) }} {{ rankingCountUnit }}</span>
</div>
<div class="ranking-meter" aria-hidden="true">
<span :style="{ width: rankingWidth(item.count, appointmentRankingMax) }" />
@@ -190,14 +194,16 @@
<b class="ranking-value">{{ formatNumber(item.count) }}</b>
</div>
</div>
<el-empty v-else :image-size="72" description="当前数据范围内暂无挂号排行" />
<el-empty v-else :image-size="72" :description="`当前数据范围内暂无${rankingCountUnit}排行`" />
</article>
<article class="dashboard-panel ranking-panel">
<div class="panel-header">
<div>
<h2>{{ dashboard.rankings.performance.title }}</h2>
<p>{{ dashboard.rankings.performance.scope_label }}内今日计入业绩的业务订单</p>
<p>
{{ performanceRankingSubtitle }}
</p>
</div>
<span class="panel-meta">今日</span>
</div>
@@ -206,11 +212,15 @@
v-for="(item, index) in dashboard.rankings.performance.items"
:key="`performance-${item.id}-${index}`"
class="ranking-row"
:class="{ 'is-self': item.is_self }"
>
<span class="ranking-index" :class="{ 'is-top': index < 2 }">{{ index + 1 }}</span>
<span class="ranking-index" :class="{ 'is-top': index < 2, 'is-self': item.is_self }">{{ index + 1 }}</span>
<div class="ranking-main">
<div class="ranking-copy">
<strong>{{ item.name || '未命名部门' }}</strong>
<strong>
{{ item.name || (dashboard.rankings.performance.kind === 'person' ? '未命名成员' : '未命名部门') }}
<i v-if="item.is_self" class="ranking-self-tag">我</i>
</strong>
<span>{{ formatNumber(item.count) }} 个诊单</span>
</div>
<div class="ranking-meter" aria-hidden="true">
@@ -335,6 +345,7 @@ interface RankingItem {
name: string
count: number
amount: number
is_self?: boolean
}
type ComparisonDirection = 'up' | 'down' | 'flat'
@@ -355,10 +366,12 @@ const emptyComparison = (): MetricComparison => ({
const createInitialDashboard = () => ({
scope: {
key: '',
kind: '',
scope_value: 4,
label: '',
is_limited: true,
viewer_name: '',
viewer_id: 0,
role_ids: [] as number[],
role_names: [] as string[],
department_names: [] as string[],
@@ -401,11 +414,13 @@ const createInitialDashboard = () => ({
appointments: {
title: '实时挂号排行',
kind: 'assistant',
metric: 'registration',
scope_label: '',
items: [] as RankingItem[],
},
performance: {
title: '今日部门业绩排行',
kind: 'dept',
scope_label: '',
items: [] as RankingItem[],
},
@@ -413,6 +428,7 @@ const createInitialDashboard = () => ({
filters: {
ranking_departments: [] as any[],
ranking_dept_id: 0,
ranking_selectable: true,
},
trend: {
date_range: [] as string[],
@@ -533,9 +549,34 @@ const currentDate = computed(() => new Intl.DateTimeFormat('zh-CN', {
weekday: 'short',
}).format(now.value))
const showRankingDeptSelect = computed(() => (
dashboard.filters.ranking_selectable !== false
&& dashboard.scope.kind !== 'group_leader'
&& dashboard.rankings.appointments.kind !== 'doctor'
&& dashboard.filters.ranking_departments.length > 0
))
const rankingCountUnit = computed(() => (
dashboard.rankings.appointments.metric === 'appointment' ? '预约' : '挂号'
))
const appointmentRankingSubtitle = computed(() => {
if (dashboard.rankings.appointments.metric === 'appointment') {
return ''
}
const actor = dashboard.rankings.appointments.kind === 'doctor' ? '医生' : '成员'
return `${dashboard.rankings.appointments.scope_label}内${actor}已支付且实收低于 10 元的订单数`
const scopeLabel = dashboard.rankings.appointments.scope_label || '当前部门'
return `${scopeLabel}内${actor}已支付且实收低于 10 元的订单数`
})
const performanceRankingSubtitle = computed(() => {
const scopeLabel = dashboard.rankings.performance.scope_label || '当前部门'
if (dashboard.rankings.performance.kind === 'person') {
return dashboard.scope.kind === 'group_leader'
? '本小组内今日计入业绩的个人订单'
: `${scopeLabel}内今日计入业绩的个人订单`
}
return `${scopeLabel}内今日计入业绩的业务订单`
})
const appointmentRankingMax = computed(() => Math.max(
@@ -656,7 +697,7 @@ const loadDashboard = async () => {
errorMessage.value = ''
try {
const res: any = await performanceDashboardOverview({
ranking_dept_id: rankingDeptId.value,
ranking_dept_id: loaded.value ? (rankingDeptId.value || 0) : undefined,
// 驾驶舱是实时数据,避免浏览器或反向代理复用旧的 GET 响应。
_t: Date.now(),
})
@@ -998,6 +1039,11 @@ onBeforeUnmount(() => {
padding: 7px 9px;
border-radius: 11px;
background: var(--dash-surface-muted);
&.is-self {
background: color-mix(in srgb, var(--dash-accent) 16%, var(--dash-surface));
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dash-accent) 42%, transparent);
}
}
.ranking-index {
@@ -1017,6 +1063,24 @@ onBeforeUnmount(() => {
color: #fff;
background: var(--dash-accent);
}
&.is-self:not(.is-top) {
color: var(--dash-accent);
background: color-mix(in srgb, var(--dash-accent) 18%, var(--el-fill-color-light));
font-weight: 750;
}
}
.ranking-self-tag {
flex-shrink: 0;
padding: 0 5px;
border-radius: 6px;
color: #fff;
font-size: 10px;
font-style: normal;
font-weight: 700;
line-height: 18px;
background: var(--dash-accent);
}
.ranking-main {
@@ -1032,6 +1096,9 @@ onBeforeUnmount(() => {
margin-bottom: 5px;
strong {
display: inline-flex;
align-items: center;
gap: 6px;
overflow: hidden;
font-size: 12px;
text-overflow: ellipsis;