refactor: 收口每日任务 ViewModel
This commit is contained in:
107
src/components/rpg-entry/rpgEntryProfileTaskViewModel.ts
Normal file
107
src/components/rpg-entry/rpgEntryProfileTaskViewModel.ts
Normal file
@@ -0,0 +1,107 @@
|
||||
import type {
|
||||
ProfileTaskCenterResponse,
|
||||
ProfileTaskItem,
|
||||
} from '../../../packages/shared/src/contracts/runtime';
|
||||
|
||||
const PROFILE_TASK_STATUS_PRIORITY_RANK: Record<
|
||||
ProfileTaskItem['status'],
|
||||
number
|
||||
> = {
|
||||
claimable: 2,
|
||||
incomplete: 1,
|
||||
disabled: 0,
|
||||
claimed: -1,
|
||||
};
|
||||
const PROFILE_TASK_CARD_FALLBACK_REWARD_POINTS = 10;
|
||||
const PROFILE_TASK_STATUS_LABELS: Record<ProfileTaskItem['status'], string> = {
|
||||
incomplete: '未完成',
|
||||
claimable: '可领取',
|
||||
claimed: '已领取',
|
||||
disabled: '已停用',
|
||||
};
|
||||
|
||||
export type ProfileTaskCardSummary = {
|
||||
actionLabel: string;
|
||||
progressCount: number;
|
||||
progressPercent: number;
|
||||
rewardPoints: number;
|
||||
threshold: number;
|
||||
};
|
||||
|
||||
export function selectProfileTaskCenterTasks(tasks: ProfileTaskItem[]) {
|
||||
return tasks
|
||||
.map((task, index) => ({ task, index }))
|
||||
.filter(
|
||||
({ task }) =>
|
||||
task.status === 'claimable' || task.status === 'incomplete',
|
||||
)
|
||||
.sort(
|
||||
(left, right) =>
|
||||
PROFILE_TASK_STATUS_PRIORITY_RANK[right.task.status] -
|
||||
PROFILE_TASK_STATUS_PRIORITY_RANK[left.task.status] ||
|
||||
left.index - right.index,
|
||||
)
|
||||
.slice(0, 1)
|
||||
.map(({ task }) => task);
|
||||
}
|
||||
|
||||
export function selectProfileTaskCardTask(tasks: ProfileTaskItem[]) {
|
||||
return (
|
||||
selectProfileTaskCenterTasks(tasks)[0] ??
|
||||
tasks.find((task) => task.status === 'claimed') ??
|
||||
tasks.find((task) => task.status !== 'disabled') ??
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
export function getProfileTaskStatusLabel(status: ProfileTaskItem['status']) {
|
||||
return PROFILE_TASK_STATUS_LABELS[status];
|
||||
}
|
||||
|
||||
export function buildProfileTaskProgressLabel(task: ProfileTaskItem) {
|
||||
const threshold = Math.max(1, task.threshold);
|
||||
const progressCount = Math.min(Math.max(0, task.progressCount), threshold);
|
||||
return `${progressCount}/${threshold}`;
|
||||
}
|
||||
|
||||
export function getProfileTaskClaimButtonLabel(
|
||||
task: ProfileTaskItem,
|
||||
isClaiming: boolean,
|
||||
) {
|
||||
if (isClaiming) {
|
||||
return '领取中';
|
||||
}
|
||||
|
||||
if (task.status === 'claimed') {
|
||||
return '已领取';
|
||||
}
|
||||
|
||||
return task.status === 'claimable' ? '领取' : '未完成';
|
||||
}
|
||||
|
||||
export function buildProfileTaskCardSummary(
|
||||
center: ProfileTaskCenterResponse | null,
|
||||
): ProfileTaskCardSummary {
|
||||
const task = selectProfileTaskCardTask(center?.tasks ?? []);
|
||||
const threshold = Math.max(1, task?.threshold ?? 1);
|
||||
const progressCount = Math.min(
|
||||
Math.max(0, task?.progressCount ?? 0),
|
||||
threshold,
|
||||
);
|
||||
const rewardPoints =
|
||||
task?.rewardPoints ?? PROFILE_TASK_CARD_FALLBACK_REWARD_POINTS;
|
||||
const actionLabel =
|
||||
task?.status === 'claimable'
|
||||
? '领取'
|
||||
: task?.status === 'claimed'
|
||||
? '已完成'
|
||||
: '去完成';
|
||||
|
||||
return {
|
||||
actionLabel,
|
||||
progressCount,
|
||||
progressPercent: Math.round((progressCount / threshold) * 100),
|
||||
rewardPoints,
|
||||
threshold,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user