feat: 完善移动端会员业务流程
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
<img :src="mobileAssets.claimMachine" alt="每日参与任务,赚取更多佣金" />
|
||||
<button
|
||||
type="button"
|
||||
:disabled="claiming || !halls.length || eligibility?.eligible === false"
|
||||
:disabled="claiming || !eligibleHalls.length"
|
||||
aria-label="自动领取任务"
|
||||
@click="claim"
|
||||
>
|
||||
@@ -22,7 +22,7 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div v-if="eligibility?.eligible === false" class="m-claim2-warning">
|
||||
<div v-if="halls.length && !eligibleHalls.length && eligibility?.eligible === false" class="m-claim2-warning">
|
||||
<n-icon :component="AlertCircleOutline" />
|
||||
<span>{{ eligibility.message || '暂不满足领取条件' }}</span>
|
||||
<button v-if="eligibility.pending_order_id" type="button" @click="openPendingOrder">查看任务</button>
|
||||
@@ -100,7 +100,7 @@
|
||||
import { useRouter } from 'vue-router';
|
||||
import { AlertCircleOutline, ImageOutline } from '@vicons/ionicons5';
|
||||
import AsyncState from '../components/AsyncState.vue';
|
||||
import { dateTime, errorText, money, request, safeImage } from '../api';
|
||||
import { MobileApiError, dateTime, errorText, money, request, safeImage } from '../api';
|
||||
import { mobileAssets } from '../assets';
|
||||
|
||||
type ResultState = 'matching' | 'success' | 'failed' | 'cancelled';
|
||||
@@ -112,6 +112,7 @@
|
||||
const halls = ref<any[]>([]);
|
||||
const stats = ref<any>();
|
||||
const eligibility = ref<any>();
|
||||
const eligibilityByHall = ref<Record<number, any>>({});
|
||||
const order = ref<any>();
|
||||
const showResult = ref(false);
|
||||
const resultState = ref<ResultState>('matching');
|
||||
@@ -128,6 +129,9 @@
|
||||
{ label: '今日佣金', value: money(stats.value?.today_commission_amount), icon: mobileAssets.claimToday },
|
||||
{ label: '今日领取数', value: stats.value?.today_claim_count ?? 0, icon: mobileAssets.claimCount },
|
||||
]);
|
||||
const eligibleHalls = computed(() =>
|
||||
halls.value.filter((hall) => eligibilityByHall.value[hall.id]?.eligible)
|
||||
);
|
||||
const businessHours = computed(() => {
|
||||
const start = String(eligibility.value?.business_start_at || '09:00').slice(0, 5);
|
||||
const end = String(eligibility.value?.business_end_at || '21:00').slice(0, 5);
|
||||
@@ -154,7 +158,7 @@
|
||||
]);
|
||||
halls.value = hallData || [];
|
||||
stats.value = statData;
|
||||
if (halls.value.length) await loadEligibility(halls.value[0].id);
|
||||
if (halls.value.length) await loadEligibilities();
|
||||
} catch (err) {
|
||||
error.value = errorText(err);
|
||||
} finally {
|
||||
@@ -162,8 +166,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
async function loadEligibility(hallID: number) {
|
||||
eligibility.value = await request({ url: '/v1/tasks/eligibility', params: { hall_id: hallID } });
|
||||
async function loadEligibilities() {
|
||||
const entries = await Promise.all(
|
||||
halls.value.map(async (hall) => [
|
||||
hall.id,
|
||||
await request<any>({ url: '/v1/tasks/eligibility', params: { hall_id: hall.id } }),
|
||||
] as const)
|
||||
);
|
||||
eligibilityByHall.value = Object.fromEntries(entries);
|
||||
eligibility.value = entries.find(([, value]) => value?.eligible)?.[1] || entries[0]?.[1];
|
||||
}
|
||||
|
||||
async function claim() {
|
||||
@@ -171,18 +182,33 @@
|
||||
claiming.value = true;
|
||||
pollFinished.value = false;
|
||||
try {
|
||||
await loadEligibility(halls.value[0].id);
|
||||
if (!eligibility.value?.eligible) {
|
||||
await loadEligibilities();
|
||||
const candidates = eligibleHalls.value;
|
||||
if (!candidates.length) {
|
||||
window.$message.warning(eligibility.value?.message || '暂不满足领取条件');
|
||||
return;
|
||||
}
|
||||
openMatching();
|
||||
order.value = await request<any>({
|
||||
url: '/v1/task-orders/claim',
|
||||
method: 'POST',
|
||||
data: { hall_id: halls.value[0].id },
|
||||
});
|
||||
handleOrder(order.value);
|
||||
let stockError: unknown;
|
||||
for (const hall of candidates) {
|
||||
eligibility.value = eligibilityByHall.value[hall.id];
|
||||
try {
|
||||
order.value = await request<any>({
|
||||
url: '/v1/task-orders/claim',
|
||||
method: 'POST',
|
||||
data: { hall_id: hall.id },
|
||||
});
|
||||
handleOrder(order.value);
|
||||
return;
|
||||
} catch (err) {
|
||||
if (err instanceof MobileApiError && err.reason === 'NO_TASK_AVAILABLE') {
|
||||
stockError = err;
|
||||
continue;
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
throw stockError || new Error('当前暂无可领取任务');
|
||||
} catch (err) {
|
||||
failureMessage.value = errorText(err);
|
||||
resultState.value = 'failed';
|
||||
|
||||
Reference in New Issue
Block a user