feat(store): 门店详情核销记录走马灯
新增 GET /stores/:id/recent-redeems,C 端在门店详情区上方循环展示脱敏核销动态。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -38,6 +38,15 @@ type TokenPayload = {
|
||||
allocations?: Array<{ couponId: string; amount: number }>;
|
||||
};
|
||||
|
||||
/** C 端公示:用户138****5678 / 用户*** */
|
||||
function maskRedeemUserLabel(phone?: string | null): string {
|
||||
const digits = String(phone || '').replace(/\D/g, '');
|
||||
if (digits.length >= 7) {
|
||||
return `用户${digits.slice(0, 3)}****${digits.slice(-4)}`;
|
||||
}
|
||||
return '用户***';
|
||||
}
|
||||
|
||||
type PendingSnapshot = TokenPayload & {
|
||||
redeemType: 'DIRECT' | 'COUPON';
|
||||
};
|
||||
@@ -1131,6 +1140,22 @@ export class RedeemService {
|
||||
};
|
||||
}
|
||||
|
||||
/** C 端门店详情走马灯:脱敏用户 + 时间 + 金额 */
|
||||
async listPublicStoreRecentRedeems(storeId: bigint, limit = 20) {
|
||||
const take = Math.min(Math.max(limit, 1), 50);
|
||||
const list = await this.prisma.redeemRecord.findMany({
|
||||
where: { storeId },
|
||||
orderBy: { createdAt: 'desc' },
|
||||
take,
|
||||
include: { user: { select: { phone: true } } },
|
||||
});
|
||||
return list.map((r) => ({
|
||||
userLabel: maskRedeemUserLabel(r.user?.phone),
|
||||
amount: Number(r.amount),
|
||||
createdAt: r.createdAt.toISOString(),
|
||||
}));
|
||||
}
|
||||
|
||||
async submitRating(userId: bigint, body: { redeemRecordId: string; serviceScore: number; envScore: number }) {
|
||||
const record = await this.prisma.redeemRecord.findFirst({
|
||||
where: { id: BigInt(body.redeemRecordId), userId },
|
||||
|
||||
Reference in New Issue
Block a user