feat(aihr): allow employees to complete onboarding tasks

This commit is contained in:
2026-07-15 02:49:40 +08:00
parent 2f21895597
commit 82d93a1af1
11 changed files with 112 additions and 5 deletions
+36 -2
View File
@@ -140,7 +140,17 @@
<text class="onboarding-meta">{{ item.status }}{{ item.projectCode ? ` · ${item.projectCode}` : '' }}</text>
<text v-if="item.dueTime" class="onboarding-meta">截止:{{ item.dueTime }}</text>
</view>
<text class="onboarding-status" :class="item.status === '已完成' ? 'done' : 'pending'">{{ item.status }}</text>
<view class="onboarding-actions">
<text class="onboarding-status" :class="item.status === '已完成' ? 'done' : 'pending'">{{ item.status }}</text>
<button
v-if="item.status !== '已完成'"
class="secondary-button compact-button"
:disabled="onboardingCompletingId === item.id"
@click="completeOnboarding(item)"
>
{{ onboardingCompletingId === item.id ? '提交中' : '确认完成' }}
</button>
</view>
</view>
</view>
<view v-else-if="!onboardingLoading" class="empty">暂无正式岗前/入职任务,等待 HR 或组织系统派发</view>
@@ -258,7 +268,7 @@ import type {
PracticePrepCard,
QualificationSummary
} from '@/types/api';
import { getOnboardTasks, getPracticeAssignments, getPracticeMistakes, getPracticePrepCard, getQualification } from '@/services/practice';
import { completeOnboardTask, getOnboardTasks, getPracticeAssignments, getPracticeMistakes, getPracticePrepCard, getQualification } from '@/services/practice';
import { getPositionSopSummary, searchKnowledge } from '@/services/knowledge';
import { getSelectedPositionProfile, isLoggedIn, rememberLoginRedirect } from '@/services/auth';
import { buildLearningTopics, selectLearningTopic } from '@/services/learning';
@@ -287,6 +297,7 @@ const positionProfile = ref(getSelectedPositionProfile());
const onboardTasks = ref<OnboardTask[]>([]);
const qualification = ref<QualificationSummary | null>(null);
const onboardingLoading = ref(false);
const onboardingCompletingId = ref<number | null>(null);
const qualificationLoading = ref(false);
const defaultTopic = computed(() => `${positionProfile.value.value} 岗前 SOP`);
@@ -418,6 +429,22 @@ const loadOnboarding = async () => {
}
};
const completeOnboarding = async (task: OnboardTask) => {
if (onboardingCompletingId.value !== null || task.status === '已完成') return;
onboardingCompletingId.value = task.id;
try {
await completeOnboardTask(task.id);
onboardTasks.value = onboardTasks.value.map((item) => item.id === task.id
? { ...item, status: '已完成', completedTime: new Date().toISOString() }
: item);
message.value = '任务已记录为完成,正式资格仍以 HR 复核为准';
} catch (error) {
handleRequestError(error, '任务完成记录失败');
} finally {
onboardingCompletingId.value = null;
}
};
const loadQualification = async () => {
if (!loggedIn.value) return;
qualificationLoading.value = true;
@@ -594,6 +621,13 @@ onShow(() => {
min-width: 0;
}
.onboarding-actions {
display: grid;
justify-items: end;
gap: 6px;
flex-shrink: 0;
}
.onboarding-title,
.qualification-cert {
color: #1f2d3d;
+8
View File
@@ -179,6 +179,14 @@ export const getOnboardTasks = () =>
timeout: 15000
});
export const completeOnboardTask = (id: number, evidenceRef?: string) =>
apiRequest<void>({
url: `/api/aihr/mobile/onboard/tasks/${id}/complete`,
method: 'POST',
data: evidenceRef ? { evidenceRef } : {},
timeout: 15000
});
export const getQualification = () =>
apiRequest<QualificationSummary>({
url: '/api/aihr/mobile/qualification',