Files
lehuo/apps/miniprogram/miniprogram/pages/volunteer-center/volunteer-center.ts
T
2026-08-12 14:35:12 +08:00

138 lines
4.5 KiB
TypeScript

import type {
ActivityRegistrationItem,
VolunteerProfile,
VolunteerSkillCode,
ServiceCategory,
} from '@lehuo/contracts';
import { MiniProgramApiError } from '../../services/api-client';
import {
fetchMyRegistrations,
fetchVolunteerProfile,
saveVolunteerProfile,
} from '../../services/participation';
import { createClientRequestId } from '../../utils/request-id';
Page({
data: {
loading: true,
busy: false,
message: '',
profile: null as VolunteerProfile | null,
registrations: [] as ActivityRegistrationItem[],
skillSelected: {},
interestSelected: {},
form: {
realName: '',
mobile: '',
regionCode: '',
availabilityNote: '',
skillCodes: [] as VolunteerSkillCode[],
interestCategories: [] as ServiceCategory[],
privacyConsent: false,
},
skills: [
{ code: 'ELDER_CARE', label: '老年关怀' },
{ code: 'CHILD_CARE', label: '儿童陪伴' },
{ code: 'DISABILITY_SUPPORT', label: '残障支持' },
{ code: 'EVENT_SUPPORT', label: '活动协助' },
{ code: 'FIRST_AID', label: '急救技能' },
{ code: 'PHOTOGRAPHY', label: '摄影记录' },
],
interests: [
{ code: 'OLD_AGE', label: '老年服务' },
{ code: 'WOMEN_CHILDREN', label: '妇女儿童' },
{ code: 'DISABILITY', label: '残障支持' },
{ code: 'DIFFICULT_FAMILY', label: '困难家庭' },
{ code: 'OTHER', label: '其他公益' },
],
},
onLoad() {
void this.load();
},
async load() {
this.setData({ loading: true, message: '' });
try {
const [profileResult, registrations] = await Promise.all([
fetchVolunteerProfile(),
fetchMyRegistrations(),
]);
const profile = profileResult.volunteer;
this.setData({
profile,
registrations: registrations.items,
skillSelected: Object.fromEntries((profile?.skillCodes ?? []).map((code) => [code, true])),
interestSelected: Object.fromEntries(
(profile?.interestCategories ?? []).map((code) => [code, true]),
),
...(profile
? {
form: {
realName: profile.realName,
mobile: profile.mobile,
regionCode: profile.regionCode,
availabilityNote: profile.availabilityNote,
skillCodes: profile.skillCodes,
interestCategories: profile.interestCategories,
privacyConsent: true,
},
}
: {}),
});
} catch (error) {
this.setData({
message: error instanceof MiniProgramApiError ? error.message : '志愿者中心加载失败',
});
} finally {
this.setData({ loading: false });
}
},
field(event: WechatMiniprogram.Input) {
const key = event.currentTarget.dataset['key'] as string;
this.setData({ [`form.${key}`]: event.detail.value });
},
skills(event: WechatMiniprogram.CheckboxGroupChange) {
this.setData({
'form.skillCodes': event.detail.value,
skillSelected: Object.fromEntries(event.detail.value.map((code) => [code, true])),
});
},
interests(event: WechatMiniprogram.CheckboxGroupChange) {
this.setData({
'form.interestCategories': event.detail.value,
interestSelected: Object.fromEntries(event.detail.value.map((code) => [code, true])),
});
},
consent(event: WechatMiniprogram.CheckboxGroupChange) {
this.setData({ 'form.privacyConsent': event.detail.value.includes('yes') });
},
async submit() {
const form = this.data.form;
if (!form.privacyConsent) {
this.setData({ message: '请先阅读并确认志愿者资料使用说明。' });
return;
}
this.setData({ busy: true, message: '' });
try {
await saveVolunteerProfile({
clientRequestId: createClientRequestId(),
...(this.data.profile ? { expectedRevision: this.data.profile.revision } : {}),
realName: form.realName,
mobile: form.mobile,
regionCode: form.regionCode,
availabilityNote: form.availabilityNote,
skillCodes: form.skillCodes,
interestCategories: form.interestCategories,
privacyConsent: true,
});
this.setData({ message: '志愿者资料已提交,请等待工作人员审核。' });
await this.load();
} catch (error) {
this.setData({
message: error instanceof MiniProgramApiError ? error.message : '提交失败,请稍后重试',
});
} finally {
this.setData({ busy: false });
}
},
});