138 lines
4.5 KiB
TypeScript
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 });
|
|
}
|
|
},
|
|
});
|