fix(mobile): polish candidate pages — clean text buttons, StateBlock empties, standard subpage header

This commit is contained in:
2026-07-21 01:30:39 +08:00
parent 2198a92bae
commit 6d2b5ec8b9
5 changed files with 45 additions and 68 deletions
@@ -78,7 +78,7 @@
<text class="activity-desc">{{ latestMaterial.time }} · {{ latestMaterial.status }}</text> <text class="activity-desc">{{ latestMaterial.time }} · {{ latestMaterial.status }}</text>
</view> </view>
</view> </view>
<view v-if="!latestRecord && !latestMaterial && !loading" class="empty compact-empty">暂无办理记录</view> <StateBlock v-if="!latestRecord && !latestMaterial && !loading" type="empty" :card="false" title="暂无办理记录" />
</view> </view>
</template> </template>
</view> </view>
@@ -92,6 +92,7 @@ import { isLoggedIn, rememberLoginRedirect } from '@/services/auth';
import { getCandidateInterviewRecords, getCandidateMaterials, getCandidateName } from '@/services/candidate'; import { getCandidateInterviewRecords, getCandidateMaterials, getCandidateName } from '@/services/candidate';
import { buildCandidateFlow } from '@/services/candidate-view'; import { buildCandidateFlow } from '@/services/candidate-view';
import { resetPageScroll } from '@/services/navigation'; import { resetPageScroll } from '@/services/navigation';
import StateBlock from '@/components/StateBlock.vue';
const currentPath = '/pages/candidate/index/index'; const currentPath = '/pages/candidate/index/index';
const records = ref<InterviewRecord[]>([]); const records = ref<InterviewRecord[]>([]);
@@ -359,12 +360,17 @@ onShow(() => {
.text-button { .text-button {
min-height: 36px; min-height: 36px;
padding: 0; padding: 0;
border: 0;
background: transparent; background: transparent;
color: #1d4ed8; color: var(--employee-primary);
font-size: 13px; font-size: 13px;
font-weight: 700; font-weight: 700;
} }
.text-button::after {
border: 0;
}
.activity-row { .activity-row {
justify-content: flex-start; justify-content: flex-start;
margin-top: 12px; margin-top: 12px;
@@ -128,7 +128,7 @@
<text class="record-score">{{ item.score }}</text> <text class="record-score">{{ item.score }}</text>
</view> </view>
</view> </view>
<view v-else-if="!recordsLoading" class="empty compact-empty">暂无面试记录</view> <StateBlock v-else-if="!recordsLoading" type="empty" :card="false" title="暂无面试记录" />
</view> </view>
</template> </template>
</view> </view>
@@ -153,6 +153,7 @@ import {
} from '@/services/candidate'; } from '@/services/candidate';
import { candidateRoutes } from '@/services/candidate-view'; import { candidateRoutes } from '@/services/candidate-view';
import { resetPageScroll } from '@/services/navigation'; import { resetPageScroll } from '@/services/navigation';
import StateBlock from '@/components/StateBlock.vue';
import { import {
chooseSpeechAudio, chooseSpeechAudio,
createSpeechPlaybackController, createSpeechPlaybackController,
@@ -735,11 +736,16 @@ onUnload(() => {
.text-button { .text-button {
min-height: 36px; min-height: 36px;
padding: 0; padding: 0;
border: 0;
background: transparent; background: transparent;
color: #1d4ed8; color: var(--employee-primary);
font-size: 13px; font-size: 13px;
} }
.text-button::after {
border: 0;
}
.compact-empty { .compact-empty {
padding-bottom: 4px; padding-bottom: 4px;
} }
@@ -47,7 +47,7 @@
</view> </view>
</view> </view>
</view> </view>
<view v-else-if="!loading" class="empty compact-empty">暂无已提交资料</view> <StateBlock v-else-if="!loading" type="empty" :card="false" title="暂无已提交资料" />
</view> </view>
<button class="secondary-button progress-button" @click="openProgress">查看审核进度</button> <button class="secondary-button progress-button" @click="openProgress">查看审核进度</button>
@@ -71,6 +71,7 @@ import {
materialStatusTone materialStatusTone
} from '@/services/candidate-view'; } from '@/services/candidate-view';
import { resetPageScroll } from '@/services/navigation'; import { resetPageScroll } from '@/services/navigation';
import StateBlock from '@/components/StateBlock.vue';
const currentPath = '/pages/candidate/materials/index'; const currentPath = '/pages/candidate/materials/index';
const materials = ref<CandidateMaterial[]>([]); const materials = ref<CandidateMaterial[]>([]);
@@ -224,11 +225,16 @@ onShow(() => {
.text-button { .text-button {
min-height: 36px; min-height: 36px;
padding: 0; padding: 0;
border: 0;
background: transparent; background: transparent;
color: #1d4ed8; color: var(--employee-primary);
font-size: 13px; font-size: 13px;
} }
.text-button::after {
border: 0;
}
.material-list { .material-list {
margin-top: 12px; margin-top: 12px;
border-top: 1px solid #e2e8f0; border-top: 1px solid #e2e8f0;
@@ -1,8 +1,8 @@
<template> <template>
<view class="page candidate-record-page"> <view class="page candidate-record-page">
<view class="record-header"> <view class="subpage-header">
<button class="back-button" aria-label="返回候选首页" @click="goBack"><uni-icons type="back" size="22" color="#111111" /></button> <button class="subpage-back-button" aria-label="返回候选首页" title="返回候选首页" @click="goBack"><uni-icons type="back" size="20" color="#25282d" /></button>
<view> <view class="subpage-heading">
<text class="page-title">面试记录</text> <text class="page-title">面试记录</text>
<text class="page-subtitle">{{ latestRecord ? `${latestRecord.time} · ${latestRecord.position}` : '面试与资料审核状态' }}</text> <text class="page-subtitle">{{ latestRecord ? `${latestRecord.time} · ${latestRecord.position}` : '面试与资料审核状态' }}</text>
</view> </view>
@@ -57,11 +57,14 @@
<button class="primary-button home-button" @click="goBack">返回候选人中心</button> <button class="primary-button home-button" @click="goBack">返回候选人中心</button>
</template> </template>
<view v-else class="panel empty-record-panel"> <StateBlock
<text class="panel-title">暂无面试记录</text> v-else
<text class="muted block">完成一次结构化面试后,这里会展示评分和问答明细。</text> type="empty"
<button class="primary-button home-button" @click="openInterview">开始面试</button> title="暂无面试记录"
</view> desc="完成一次结构化面试后,这里会展示评分和问答明细。"
action-text="开始面试"
@action="openInterview"
/>
</view> </view>
</template> </template>
@@ -73,6 +76,7 @@ import { isLoggedIn, rememberLoginRedirect } from '@/services/auth';
import { getCandidateInterviewRecords, getCandidateMaterials } from '@/services/candidate'; import { getCandidateInterviewRecords, getCandidateMaterials } from '@/services/candidate';
import { candidateRoutes } from '@/services/candidate-view'; import { candidateRoutes } from '@/services/candidate-view';
import { resetPageScroll } from '@/services/navigation'; import { resetPageScroll } from '@/services/navigation';
import StateBlock from '@/components/StateBlock.vue';
const currentPath = '/pages/candidate/progress/index'; const currentPath = '/pages/candidate/progress/index';
const records = ref<InterviewRecord[]>([]); const records = ref<InterviewRecord[]>([]);
@@ -147,34 +151,6 @@ onShow(() => {
background: #f9f9f9; background: #f9f9f9;
} }
.record-header {
display: flex;
align-items: flex-start;
gap: 12px;
padding: 10px 4px 16px;
}
.back-button {
display: flex;
width: 28px;
min-width: 28px;
height: 28px;
align-items: center;
justify-content: center;
padding: 0;
border: 0;
background: transparent;
color: #111;
line-height: 1;
}
.page-subtitle {
display: block;
margin-top: 5px;
color: #858991;
font-size: 13px;
}
.score-card, .score-card,
.question-card, .question-card,
.review-status-card { .review-status-card {
@@ -311,8 +287,7 @@ onShow(() => {
margin-top: 14px; margin-top: 14px;
} }
.login-panel, .login-panel {
.empty-record-panel {
border-radius: 18px; border-radius: 18px;
} }
+8 -24
View File
@@ -70,10 +70,13 @@
</view> </view>
</view> </view>
<view v-if="!answer && !loading" class="empty-state"> <StateBlock
<text class="empty-title">尚未生成预习</text> v-if="!answer && !loading"
<text class="empty-desc">选择主题后调用正式 SOP 知识库,不使用前端示例答案。</text> type="empty"
</view> :card="false"
title="尚未生成预习"
desc="选择主题后调用正式 SOP 知识库,不使用前端示例答案。"
/>
</template> </template>
</view> </view>
</template> </template>
@@ -85,6 +88,7 @@ import { isLoggedIn, rememberLoginRedirect } from '@/services/auth';
import { candidateRoutes } from '@/services/candidate-view'; import { candidateRoutes } from '@/services/candidate-view';
import { searchKnowledge } from '@/services/knowledge'; import { searchKnowledge } from '@/services/knowledge';
import { resetPageScroll } from '@/services/navigation'; import { resetPageScroll } from '@/services/navigation';
import StateBlock from '@/components/StateBlock.vue';
const currentPath = '/pages/candidate/study/index'; const currentPath = '/pages/candidate/study/index';
const topics = [ const topics = [
@@ -310,24 +314,4 @@ onShow(() => {
font-size: 13px; font-size: 13px;
line-height: 1.5; line-height: 1.5;
} }
.empty-state {
padding: 56px 24px;
text-align: center;
}
.empty-title {
display: block;
color: #172033;
font-size: 17px;
font-weight: 800;
}
.empty-desc {
display: block;
margin-top: 8px;
color: #64748b;
font-size: 13px;
line-height: 1.55;
}
</style> </style>