feat: complete V1 phases 0-7

This commit is contained in:
2026-08-12 14:35:12 +08:00
commit c3dd9be674
311 changed files with 38750 additions and 0 deletions
@@ -0,0 +1,128 @@
import {
SERVICE_RECORD_TYPES,
SERVICE_RECORD_TYPE_LABELS,
type ServiceCaseDetail,
} from '@lehuo/contracts';
import { MiniProgramApiError } from '../../services/api-client';
import {
createAssignedCaseRecord,
fetchAssignedCase,
fetchAssignedFileUrl,
} from '../../services/assigned-cases';
import { formatChinaDateTime } from '../../utils/date';
import { createClientRequestId } from '../../utils/request-id';
const recordTypes = SERVICE_RECORD_TYPES.map((value) => ({
value,
label: SERVICE_RECORD_TYPE_LABELS[value],
}));
Page({
data: {
publicId: '',
state: 'loading',
message: '',
serviceCase: null as ServiceCaseDetail | null,
records: [] as Array<Record<string, unknown>>,
recordTypes,
recordTypeIndex: 0,
content: '',
result: '',
followUpSuggestion: '',
submitting: false,
},
onLoad(options: Record<string, string | undefined>) {
this.setData({ publicId: options['id'] ?? '' });
void this.load();
},
async load() {
if (!this.data.publicId) {
this.setData({ state: 'error', message: '任务标识无效,请返回重试' });
return;
}
this.setData({ state: 'loading', message: '' });
try {
const result = await fetchAssignedCase(this.data.publicId);
this.setData({
state: 'success',
serviceCase: result.serviceCase,
records: result.serviceCase.records.map((record) => ({
...record,
serviceTimeLabel: formatChinaDateTime(record.serviceStartAt),
})),
});
} catch (error) {
this.setData({ state: 'error', message: this.errorMessage(error) });
}
},
errorMessage(error: unknown) {
return error instanceof MiniProgramApiError && error.requestId
? `${error.message}(编号:${error.requestId})`
: error instanceof Error
? error.message
: '操作失败,请稍后重试';
},
changeRecordType(event: WechatMiniprogram.PickerChange) {
this.setData({ recordTypeIndex: Number(event.detail.value) });
},
inputContent(event: WechatMiniprogram.Input) {
this.setData({ content: event.detail.value });
},
inputResult(event: WechatMiniprogram.Input) {
this.setData({ result: event.detail.value });
},
inputFollowUp(event: WechatMiniprogram.Input) {
this.setData({ followUpSuggestion: event.detail.value });
},
async submitRecord() {
const serviceCase = this.data.serviceCase;
if (!serviceCase || serviceCase.status !== 'IN_SERVICE') return;
if (this.data.content.trim().length < 2 || this.data.result.trim().length < 2) {
this.setData({ message: '请填写完整的服务内容和服务结果。' });
return;
}
this.setData({ submitting: true, message: '' });
try {
const selectedType = recordTypes[this.data.recordTypeIndex]?.value ?? 'OTHER';
await createAssignedCaseRecord(serviceCase.publicId, {
clientRequestId: createClientRequestId(),
serviceStartAt: new Date().toISOString(),
serviceType: selectedType,
content: this.data.content.trim(),
result: this.data.result.trim(),
...(this.data.followUpSuggestion.trim()
? { followUpSuggestion: this.data.followUpSuggestion.trim() }
: {}),
beneficiaryConfirmStatus: 'NOT_REQUESTED',
attachmentPublicIds: [],
});
this.setData({
content: '',
result: '',
followUpSuggestion: '',
message: '服务记录已安全保存。',
});
await this.load();
} catch (error) {
this.setData({ message: this.errorMessage(error) });
} finally {
this.setData({ submitting: false });
}
},
async previewFile(event: WechatMiniprogram.BaseEvent) {
const publicId = event.currentTarget.dataset['id'] as string;
try {
const result = await fetchAssignedFileUrl(publicId);
await wx.previewImage({ urls: [result.downloadUrl], current: result.downloadUrl });
} catch (error) {
this.setData({ message: this.errorMessage(error) });
}
},
});