Files
danyang-match/miniapp/pages/local-eligibility-supplement/local-eligibility-supplement.ts
T

157 lines
4.9 KiB
TypeScript

import api from '../../utils/api'
interface EligibilityEvidence {
fileId?: string
}
interface EligibilityStatusResponse {
eligibilityType?: string
evidences?: EligibilityEvidence[]
}
interface UploadedFile {
fileKey: string
}
const errorMessage = (error: unknown, fallback: string) =>
error instanceof Error ? error.message : (error as { message?: string })?.message || fallback
Page({
data: {
eligibilityType: '',
selectedType: '',
uploadedFileIds: [] as string[],
uploading: false,
submitting: false,
maxFiles: 5,
evidenceTypes: [
{ value: 'employment_proof', label: '工作证明', desc: '劳动合同、工牌或在职证明等' },
{ value: 'residence_proof', label: '居住证明', desc: '房产证、租赁合同或水电账单等' },
{ value: 'household_proof', label: '户籍证明', desc: '户口本或户籍页等' },
{ value: 'other', label: '其他材料', desc: '能够说明您在丹阳生活或工作的材料' },
],
},
onLoad(options: Record<string, string>) {
this.setData({ eligibilityType: options.type || '' })
},
onShow() {
this.loadStatus()
},
async loadStatus() {
try {
const result = await api.get<EligibilityStatusResponse>('/local-eligibility')
this.setData({
eligibilityType: this.data.eligibilityType || result.eligibilityType || '',
uploadedFileIds: (result.evidences || []).map((item) => item.fileId).filter(Boolean),
})
} catch {
// 页面仍允许用户重新选择并提交,错误会在具体操作时反馈。
}
},
onEvidenceTypeSelect(event: WechatMiniprogram.TouchEvent) {
this.setData({ selectedType: event.currentTarget.dataset.type as string })
},
onChooseImage() {
if (!this.data.selectedType) {
wx.showToast({ title: '请先选择佐证类型', icon: 'none' })
return
}
const remaining = this.data.maxFiles - this.data.uploadedFileIds.length
if (remaining <= 0) {
wx.showToast({ title: `最多上传${this.data.maxFiles}份材料`, icon: 'none' })
return
}
wx.chooseMedia({
count: remaining,
mediaType: ['image'],
sourceType: ['album', 'camera'],
success: ({ tempFiles }) => this.uploadFiles(tempFiles || []),
})
},
async uploadFiles(files: WechatMiniprogram.ChooseMediaSuccessCallbackResult['tempFiles']) {
this.setData({ uploading: true })
try {
for (const file of files) {
const uploaded = await this.uploadSingleFile(file.tempFilePath)
await api.post('/local-eligibility/evidences', {
evidenceType: this.data.selectedType,
fileId: uploaded.fileKey,
})
this.setData({ uploadedFileIds: [...this.data.uploadedFileIds, uploaded.fileKey] })
}
wx.showToast({ title: '材料已上传', icon: 'success' })
} catch (error) {
wx.showToast({ title: errorMessage(error, '上传失败,请重试'), icon: 'none' })
} finally {
this.setData({ uploading: false })
}
},
uploadSingleFile(filePath: string): Promise<UploadedFile> {
return new Promise((resolve, reject) => {
wx.uploadFile({
url: `${api.baseURL}/photos/upload`,
filePath,
name: 'file',
formData: { photoType: 'local_eligibility', sortOrder: '0' },
header: { Authorization: `Bearer ${api.getToken() || ''}` },
success(result) {
let body: { success?: boolean; message?: string; data?: UploadedFile }
try {
body = JSON.parse(result.data || '{}')
} catch {
reject(new Error('上传响应格式错误'))
return
}
if (result.statusCode === 200 && body.success && body.data?.fileKey) {
resolve(body.data)
} else {
reject(new Error(body.message || '上传失败'))
}
},
fail() {
reject(new Error('网络连接失败'))
},
})
})
},
onRemoveImage(event: WechatMiniprogram.TouchEvent) {
const index = Number(event.currentTarget.dataset.index)
this.setData({
uploadedFileIds: this.data.uploadedFileIds.filter((_, itemIndex) => itemIndex !== index),
})
},
async submitEligibility() {
await api.post('/local-eligibility/declaration', {
eligibilityType: this.data.eligibilityType,
regionCode: '321181',
})
return api.post('/local-eligibility/submit')
},
async onSubmit() {
if (!this.data.eligibilityType) {
wx.showToast({ title: '请选择本地资格类型', icon: 'none' })
return
}
this.setData({ submitting: true })
try {
await this.submitEligibility()
wx.showToast({ title: '已提交审核', icon: 'success' })
setTimeout(() => wx.navigateBack(), 800)
} catch (error) {
wx.showToast({ title: errorMessage(error, '提交失败,请重试'), icon: 'none' })
} finally {
this.setData({ submitting: false })
}
},
})