fix(c3): record 坐标 Decimal 返回前转字符串,防泄漏 {s,e,d}
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
ab09210d28
commit
c00c4ee007
@ -647,6 +647,27 @@ describe('RecordService.detail / list / prepaidList', () => {
|
|||||||
expect(res).toMatchObject({ id: 'r1', items: [{ id: 'ri1' }], photos: [{ id: 'rp1' }], abnormals: [{ id: 'ra1' }] });
|
expect(res).toMatchObject({ id: 'r1', items: [{ id: 'ri1' }], photos: [{ id: 'rp1' }], abnormals: [{ id: 'ra1' }] });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('detail/list 将 Decimal 坐标序列化为字符串(null 保持 null)', async () => {
|
||||||
|
const recordFindUnique = vi.fn().mockResolvedValue({
|
||||||
|
id: 'r1',
|
||||||
|
recordStatus: 'submitted',
|
||||||
|
checkinLat: { toString: () => '25.010000' },
|
||||||
|
checkinLng: null,
|
||||||
|
});
|
||||||
|
const recordFindMany = vi.fn().mockResolvedValue([
|
||||||
|
{ id: 'r2', checkinLat: { toString: () => '26.500000' }, checkinLng: { toString: () => '103.100000' } },
|
||||||
|
]);
|
||||||
|
const { service } = makeService({ recordFindUnique, recordFindMany });
|
||||||
|
|
||||||
|
const detail = await runWithRequestContext(ctx, () => service.detail('r1'));
|
||||||
|
expect(detail.checkinLat).toBe('25.010000');
|
||||||
|
expect(detail.checkinLng).toBeNull();
|
||||||
|
|
||||||
|
const list = await runWithRequestContext(ctx, () => service.list({}));
|
||||||
|
expect(list[0].checkinLat).toBe('26.500000');
|
||||||
|
expect(list[0].checkinLng).toBe('103.100000');
|
||||||
|
});
|
||||||
|
|
||||||
it('list 按 elder/assignee/状态筛选', async () => {
|
it('list 按 elder/assignee/状态筛选', async () => {
|
||||||
const recordFindMany = vi.fn().mockResolvedValue([{ id: 'r1' }]);
|
const recordFindMany = vi.fn().mockResolvedValue([{ id: 'r1' }]);
|
||||||
const { service } = makeService({ recordFindMany });
|
const { service } = makeService({ recordFindMany });
|
||||||
|
|||||||
@ -267,11 +267,11 @@ export class RecordService {
|
|||||||
this.prisma.client.recordPhoto.findMany({ where: { recordId: id } }),
|
this.prisma.client.recordPhoto.findMany({ where: { recordId: id } }),
|
||||||
this.prisma.client.recordAbnormal.findMany({ where: { recordId: id } }),
|
this.prisma.client.recordAbnormal.findMany({ where: { recordId: id } }),
|
||||||
]);
|
]);
|
||||||
return { ...record, items, photos, abnormals };
|
return this.serializeRecord({ ...record, items, photos, abnormals });
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 列表:按老人/护理员/日期/状态筛选。 */
|
/** 列表:按老人/护理员/日期/状态筛选。 */
|
||||||
list(q: ListRecordQuery) {
|
async list(q: ListRecordQuery) {
|
||||||
const where: Record<string, any> = {};
|
const where: Record<string, any> = {};
|
||||||
if (q.elderId) where.elderId = q.elderId;
|
if (q.elderId) where.elderId = q.elderId;
|
||||||
if (q.assigneeId) where.assigneeId = q.assigneeId;
|
if (q.assigneeId) where.assigneeId = q.assigneeId;
|
||||||
@ -282,12 +282,14 @@ export class RecordService {
|
|||||||
lte: new Date(`${q.serviceDate}T23:59:59.999+08:00`),
|
lte: new Date(`${q.serviceDate}T23:59:59.999+08:00`),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return this.prisma.client.record.findMany({ where, orderBy: { checkinTime: 'desc' } });
|
const rows = await this.prisma.client.record.findMany({ where, orderBy: { checkinTime: 'desc' } });
|
||||||
|
return rows.map((r) => this.serializeRecord(r));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 垫付台账:按老人返回 is_prepaid=1 的记录。 */
|
/** 垫付台账:按老人返回 is_prepaid=1 的记录。 */
|
||||||
prepaidList(q: PrepaidListQuery) {
|
async prepaidList(q: PrepaidListQuery) {
|
||||||
return this.prisma.client.record.findMany({ where: { elderId: q.elderId, isPrepaid: true } });
|
const rows = await this.prisma.client.record.findMany({ where: { elderId: q.elderId, isPrepaid: true } });
|
||||||
|
return rows.map((r) => this.serializeRecord(r));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 结转:复制垫付 record → 正式 record(is_prepaid=0 + source_prepaid_of),原记录不改。 */
|
/** 结转:复制垫付 record → 正式 record(is_prepaid=0 + source_prepaid_of),原记录不改。 */
|
||||||
@ -387,6 +389,15 @@ export class RecordService {
|
|||||||
return record;
|
return record;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Prisma Decimal 经 TransformInterceptor 不会转,泄漏为 {s,e,d};返回前把坐标转字符串(null 保持 null)。 */
|
||||||
|
private serializeRecord(record: Record<string, any>): Record<string, any> {
|
||||||
|
return {
|
||||||
|
...record,
|
||||||
|
checkinLat: record.checkinLat != null ? record.checkinLat.toString() : null,
|
||||||
|
checkinLng: record.checkinLng != null ? record.checkinLng.toString() : null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/** 校验 exec_result 枚举 + svc_id 落本机构 L4,并解析快照;photo_required 从 order.item_list 推导。 */
|
/** 校验 exec_result 枚举 + svc_id 落本机构 L4,并解析快照;photo_required 从 order.item_list 推导。 */
|
||||||
private async resolveItems(items: RecordItemDto[], order?: Record<string, any> | null) {
|
private async resolveItems(items: RecordItemDto[], order?: Record<string, any> | null) {
|
||||||
return Promise.all(
|
return Promise.all(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user