feat(mobile): unify page states with shared StateBlock component
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="message" class="status-message">{{ message }}</view>
|
||||
<view v-if="message && detail" class="status-message">{{ message }}</view>
|
||||
|
||||
<template v-if="detail">
|
||||
<view class="panel success-panel">
|
||||
@@ -75,10 +75,17 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<view v-else-if="!loading" class="panel empty-panel">
|
||||
<view class="empty">复盘结果暂不可用</view>
|
||||
<button class="secondary-button back-list-button" @click="goToReviews">返回待复盘</button>
|
||||
</view>
|
||||
<StateBlock v-else-if="loadFailed" type="error" action-text="重新加载" @action="loadPage" />
|
||||
|
||||
<StateBlock v-else-if="loading" type="loading" title="复盘结果加载中…" />
|
||||
|
||||
<StateBlock
|
||||
v-else
|
||||
type="empty"
|
||||
title="复盘结果暂不可用"
|
||||
action-text="返回待复盘"
|
||||
@action="goToReviews"
|
||||
/>
|
||||
<SupervisorTabBar active="review" />
|
||||
</view>
|
||||
</template>
|
||||
@@ -91,6 +98,7 @@ import { isLoggedIn, rememberLoginRedirect } from '@/services/auth';
|
||||
import { resetPageScroll } from '@/services/navigation';
|
||||
import { getPracticeAssignments, getPracticeReviewDetail, getPracticeTeamSnapshot } from '@/services/practice';
|
||||
import SupervisorTabBar from '@/components/SupervisorTabBar.vue';
|
||||
import StateBlock from '@/components/StateBlock.vue';
|
||||
|
||||
const basePath = '/pages/supervisor/review/done';
|
||||
const reviewId = ref(0);
|
||||
@@ -105,6 +113,8 @@ const weekNames = ['周日', '周一', '周二', '周三', '周四', '周五', '
|
||||
const now = new Date();
|
||||
const doneTimeLabel = `今天 ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')} · ${now.getMonth() + 1}月${now.getDate()}日 ${weekNames[now.getDay()]}`;
|
||||
|
||||
const loadFailed = computed(() => !loading.value && !!message.value && !detail.value);
|
||||
|
||||
const displayName = computed(() => {
|
||||
const identity = (detail.value?.extPartyId || '').trim();
|
||||
const mapped = identity ? memberNames.value[identity] : '';
|
||||
@@ -427,12 +437,4 @@ onShow(() => {
|
||||
background: #ffffff;
|
||||
color: #3a3d44;
|
||||
}
|
||||
|
||||
.empty-panel {
|
||||
padding-bottom: 18px;
|
||||
}
|
||||
|
||||
.back-list-button {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -11,16 +11,16 @@
|
||||
</button>
|
||||
</view>
|
||||
|
||||
<view v-if="message && !accessDenied" class="status-message">{{ message }}</view>
|
||||
<view v-if="message && !accessDenied && detail" class="status-message">{{ message }}</view>
|
||||
|
||||
<view v-if="accessDenied" class="panel supervisor-access-panel">
|
||||
<text class="panel-title">无主管权限</text>
|
||||
<text class="muted supervisor-access-copy">当前账号不是主管或项目经理,无法查看团队训练数据。</text>
|
||||
<view class="supervisor-access-actions">
|
||||
<button class="secondary-button" @click="goToEmployee">返回员工端</button>
|
||||
<button class="primary-button" @click="switchAccount">切换账号</button>
|
||||
</view>
|
||||
</view>
|
||||
<StateBlock
|
||||
v-if="accessDenied"
|
||||
type="access"
|
||||
action-text="切换账号"
|
||||
secondary-action-text="返回员工端"
|
||||
@action="switchAccount"
|
||||
@secondary-action="goToEmployee"
|
||||
/>
|
||||
|
||||
<view v-else-if="!loggedIn" class="panel login-panel">
|
||||
<view>
|
||||
@@ -30,6 +30,10 @@
|
||||
<button class="primary-button login-button" @click="goLogin">去登录</button>
|
||||
</view>
|
||||
|
||||
<StateBlock v-else-if="loadFailed" type="error" action-text="重新加载" @action="loadDetail" />
|
||||
|
||||
<StateBlock v-else-if="firstLoading" type="loading" title="复盘详情加载中…" />
|
||||
|
||||
<template v-else-if="detail">
|
||||
<view class="panel head-panel">
|
||||
<view class="head-main">
|
||||
@@ -206,10 +210,13 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<view v-else-if="loggedIn && !loading" class="panel empty-panel">
|
||||
<view class="empty">{{ reviewId ? '复盘详情暂不可用' : '缺少有效的复盘ID' }}</view>
|
||||
<button class="secondary-button back-list-button" @click="goToReviews">返回待复盘</button>
|
||||
</view>
|
||||
<StateBlock
|
||||
v-else-if="loggedIn && !loading"
|
||||
type="empty"
|
||||
:title="reviewId ? '复盘详情暂不可用' : '缺少有效的复盘ID'"
|
||||
action-text="返回待复盘"
|
||||
@action="goToReviews"
|
||||
/>
|
||||
<SupervisorTabBar v-if="loggedIn && !accessDenied" active="review" />
|
||||
</view>
|
||||
</template>
|
||||
@@ -223,6 +230,7 @@ import { clearAuth, isLoggedIn, rememberLoginRedirect } from '@/services/auth';
|
||||
import { resetPageScroll } from '@/services/navigation';
|
||||
import { getPracticeReviewDetail, getPracticeScenarios, getPracticeTeamSnapshot, markPracticeReviewed } from '@/services/practice';
|
||||
import SupervisorTabBar from '@/components/SupervisorTabBar.vue';
|
||||
import StateBlock from '@/components/StateBlock.vue';
|
||||
import {
|
||||
createAsyncGenerationGuard,
|
||||
isReviewEditable,
|
||||
@@ -251,6 +259,8 @@ const audioErrors = ref<Record<string, string>>({});
|
||||
const audioRequests = createAsyncGenerationGuard();
|
||||
const memberNames = ref<Record<string, string>>({});
|
||||
const editable = computed(() => isReviewEditable(detail.value?.status));
|
||||
const loadFailed = computed(() => !loading.value && !!message.value && !detail.value);
|
||||
const firstLoading = computed(() => loading.value && !detail.value && !message.value);
|
||||
|
||||
const displayName = computed(() => {
|
||||
const identity = (detail.value?.extPartyId || '').trim();
|
||||
@@ -588,19 +598,6 @@ onBeforeUnmount(() => {
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.supervisor-access-copy {
|
||||
display: block;
|
||||
margin-top: 8px;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.supervisor-access-actions {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
margin-top: 14px;
|
||||
}
|
||||
|
||||
.panel-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -1161,12 +1158,4 @@ onBeforeUnmount(() => {
|
||||
font-size: 13px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.empty-panel {
|
||||
padding-bottom: 18px;
|
||||
}
|
||||
|
||||
.back-list-button {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user