Files
danyang-match/h5-demo/src/pages/matchmaker/ReferralConfirmationPage.vue
T
WorkBuddy 69ebf33e18
CI/CD Pipeline / Backend Build & Test (push) Waiting to run
CI/CD Pipeline / Admin Web Build (push) Waiting to run
CI/CD Pipeline / Mini Program Compile Check (push) Waiting to run
CI/CD Pipeline / Migration Validation (push) Blocked by required conditions
CI/CD Pipeline / Test Shell Guard (Phase 23 Gate) (push) Waiting to run
CI/CD Pipeline / UI Contracts (source-structure gates) (push) Waiting to run
CI/CD Pipeline / E2E (live stack) (push) Blocked by required conditions
release: freeze demo v1.1.0 2026-10-19
2026-10-19 20:36:22 +08:00

182 lines
5.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<PageLayout title="待确认的公益服务">
<div class="ref">
<div class="ref__hero">
<div class="ref__hero-title">待确认的公益服务</div>
<div class="ref__hero-desc">红娘提供的服务建议,需要由你本人确认后才会生效。</div>
</div>
<div class="ref__body">
<UiErrorState v-if="error" @retry="load" />
<UiLoading v-else-if="loading" />
<template v-else-if="referrals.length">
<div v-for="item in referrals" :key="item.id" class="ref__card">
<div class="ref__main">
<div class="ref__title">{{ item.title }}</div>
<div class="ref__detail">转介编号:{{ item.referralDisplayId || item.id }}</div>
<div v-if="item.detail" class="ref__detail">{{ item.detail }}</div>
<div class="ref__date">{{ formatDateTime(item.createdAt) }}</div>
</div>
<div class="ref__action">
<UiTag :type="item.confirmed ? 'success' : 'warning'">{{ item.statusText }}</UiTag>
<van-button
v-if="!item.confirmed"
size="mini"
type="primary"
:loading="confirmingId === item.id"
@click="onConfirm(item)"
>
确认转介
</van-button>
</div>
</div>
</template>
<UiEmpty v-else description="暂无待确认的转介" />
</div>
</div>
</PageLayout>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { useRoute } from 'vue-router'
import { referralService } from '@/api/services'
import { useAppStore } from '@/stores/app'
import { formatDateTime } from '@/utils/datetime'
import PageLayout from '@/layouts/PageLayout.vue'
import UiTag from '@/components/UiTag.vue'
import UiLoading from '@/components/UiLoading.vue'
import UiEmpty from '@/components/UiEmpty.vue'
import UiErrorState from '@/components/UiErrorState.vue'
const route = useRoute()
const appStore = useAppStore()
const STATUS_LABEL: Record<string, string> = {
submitted: '待您确认',
pending_confirmation: '待您确认',
confirmed: '已确认',
cancelled: '已取消',
completed: '已完成',
}
const referrals = ref<any[]>([])
const loading = ref(true)
const error = ref(false)
const confirmingId = ref('')
function normalize(item: any) {
const confirmed = !!item.userConfirmedAt || item.status === 'confirmed'
return {
id: item.id,
referralDisplayId: item.referralDisplayId,
targetType: item.type === 'activity' ? 'activity' : 'service_station',
title: item.type === 'activity' ? '公益活动转介' : '服务站转介',
detail: item.type === 'activity' ? item.activityDisplayId || '公益活动' : item.serviceType || '公益服务',
confirmed,
statusText: confirmed ? '已确认' : STATUS_LABEL[item.status] || '待您确认',
createdAt: item.createdAt || item.registeredAt || '',
}
}
async function load() {
loading.value = true
error.value = false
try {
const result: any = await referralService.getMyReferralHistory()
let list: any[] = result?.items || result?.records || (Array.isArray(result) ? result : [])
list = list.map(normalize)
const queryId = typeof route.query.id === 'string' ? route.query.id : ''
if (queryId) {
const matched = list.filter((x) => x.id === queryId)
if (matched.length) list = matched
}
referrals.value = list
} catch (err: any) {
error.value = true
appStore.toastError(err?.message || '加载失败,请稍后重试')
} finally {
loading.value = false
}
}
async function onConfirm(item: any) {
if (!item.id || confirmingId.value) return
confirmingId.value = item.id
try {
await referralService.confirmReferral(item.id, item.targetType)
appStore.toastSuccess('已确认')
await load()
} catch (err: any) {
appStore.toastError(err?.message || '确认失败,请重试')
} finally {
confirmingId.value = ''
}
}
onMounted(load)
</script>
<style scoped>
.ref {
min-height: 100vh;
background: var(--mini-bg);
}
.ref__hero {
background: var(--mini-brand-gradient);
color: #fff;
padding: 20px 16px 22px;
border-bottom-left-radius: 20px;
border-bottom-right-radius: 20px;
}
.ref__hero-title {
font-size: 18px;
font-weight: 600;
}
.ref__hero-desc {
font-size: 12px;
opacity: 0.85;
margin-top: 6px;
line-height: 1.6;
}
.ref__body {
padding: 12px 16px 24px;
}
.ref__card {
display: flex;
align-items: flex-start;
gap: 12px;
background: var(--mini-surface);
border-radius: var(--mini-radius);
padding: 14px;
margin-bottom: 10px;
box-shadow: var(--mini-shadow);
}
.ref__main {
flex: 1;
min-width: 0;
}
.ref__title {
font-size: 15px;
font-weight: 600;
color: var(--mini-text-strong);
}
.ref__detail {
font-size: 12px;
color: var(--mini-text-secondary);
margin-top: 4px;
}
.ref__date {
font-size: 11px;
color: var(--mini-text-muted);
margin-top: 6px;
}
.ref__action {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 10px;
flex: none;
}
</style>