推广码后端页面优化
This commit is contained in:
@@ -26,7 +26,12 @@ export class PromoController {
|
||||
touch(@CurrentUser() user: AuthUser | undefined, @Body() dto: PromoTouchDto) {
|
||||
const userId = user?.actorType === ActorType.USER ? user.actorId : undefined;
|
||||
return this.promoCodeService.touch(
|
||||
{ promoCode: dto.promoCode, qrcodeId: dto.qrcodeId, promoId: dto.promoId },
|
||||
{
|
||||
promoCode: dto.promoCode,
|
||||
qrcodeId: dto.qrcodeId,
|
||||
promoId: dto.promoId,
|
||||
countScan: dto.countScan,
|
||||
},
|
||||
userId,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { IsOptional, IsString } from 'class-validator';
|
||||
import { IsBoolean, IsOptional, IsString } from 'class-validator';
|
||||
import { Transform } from 'class-transformer';
|
||||
|
||||
export class PromoTouchDto {
|
||||
@IsOptional()
|
||||
@@ -13,4 +14,17 @@ export class PromoTouchDto {
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
promoId?: string;
|
||||
|
||||
/**
|
||||
* 是否累加扫码次数。扫码进入为 true;登录后归因可传 false,避免重复计数。
|
||||
* 默认 true。
|
||||
*/
|
||||
@IsOptional()
|
||||
@Transform(({ value }) => {
|
||||
if (value === false || value === 'false' || value === 0 || value === '0') return false;
|
||||
if (value === true || value === 'true' || value === 1 || value === '1') return true;
|
||||
return undefined;
|
||||
})
|
||||
@IsBoolean()
|
||||
countScan?: boolean;
|
||||
}
|
||||
|
||||
@@ -55,6 +55,12 @@ export class CreatePromoCodeDto {
|
||||
@IsString()
|
||||
@MaxLength(256)
|
||||
remark?: string;
|
||||
|
||||
/** 小程序码落地页路径,如 pages/home/index;留空用环境变量 WX_MINI_PROMO_PAGE */
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@MaxLength(128)
|
||||
page?: string;
|
||||
}
|
||||
|
||||
export class UpdatePromoCodeDto {
|
||||
|
||||
@@ -235,14 +235,19 @@ export class PromoCodeService {
|
||||
/**
|
||||
* 调用微信 getwxacodeunlimit,scene=推广活动 ID,PNG 上传 OSS uploads/qrcode/
|
||||
*/
|
||||
private async createQrcodeResource(promoId: bigint, code: string) {
|
||||
private async createQrcodeResource(promoId: bigint, code: string, pagePath?: string) {
|
||||
const scene = promoId.toString();
|
||||
if (scene.length > 32) {
|
||||
throw new BadRequestException('推广活动 ID 过长,无法写入小程序码 scene');
|
||||
}
|
||||
const page = (
|
||||
pagePath?.trim() ||
|
||||
process.env.WX_MINI_PROMO_PAGE ||
|
||||
'pages/home/index'
|
||||
).replace(/^\//, '');
|
||||
const pngBuffer = await this.wechat.getWxaCodeUnlimited({
|
||||
scene,
|
||||
page: process.env.WX_MINI_PROMO_PAGE || 'pages/home/index',
|
||||
page,
|
||||
width: 430,
|
||||
checkPath: false,
|
||||
});
|
||||
@@ -290,7 +295,7 @@ export class PromoCodeService {
|
||||
});
|
||||
|
||||
try {
|
||||
const resource = await this.createQrcodeResource(row.id, code);
|
||||
const resource = await this.createQrcodeResource(row.id, code, dto.page);
|
||||
const updated = await this.prisma.commonPromoCode.update({
|
||||
where: { id: row.id },
|
||||
data: { qrcodeResourceId: resource.id },
|
||||
@@ -380,7 +385,13 @@ export class PromoCodeService {
|
||||
|
||||
/** C 端扫码/带参进入:累加 scan_count、归因、标记用户来源 */
|
||||
async touch(
|
||||
input: { promoCode?: string; qrcodeId?: string; promoId?: string },
|
||||
input: {
|
||||
promoCode?: string;
|
||||
qrcodeId?: string;
|
||||
promoId?: string;
|
||||
/** 默认 true;登录后归因传 false 避免重复计扫码 */
|
||||
countScan?: boolean;
|
||||
},
|
||||
userId?: bigint,
|
||||
) {
|
||||
const promoCode = input.promoCode?.trim().toUpperCase();
|
||||
@@ -395,10 +406,13 @@ export class PromoCodeService {
|
||||
throw new NotFoundException('推广码无效或已停用');
|
||||
}
|
||||
|
||||
await this.prisma.commonPromoCode.update({
|
||||
where: { id: promo.id },
|
||||
data: { scanCount: { increment: 1 } },
|
||||
});
|
||||
const shouldCountScan = input.countScan !== false;
|
||||
if (shouldCountScan) {
|
||||
await this.prisma.commonPromoCode.update({
|
||||
where: { id: promo.id },
|
||||
data: { scanCount: { increment: 1 } },
|
||||
});
|
||||
}
|
||||
|
||||
let attributed = false;
|
||||
let sourceApplied = false;
|
||||
@@ -428,6 +442,7 @@ export class PromoCodeService {
|
||||
channelName: promo.name,
|
||||
attributed,
|
||||
sourceApplied,
|
||||
scanCounted: shouldCountScan,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -472,7 +487,14 @@ export class PromoCodeService {
|
||||
},
|
||||
}),
|
||||
]);
|
||||
return { scanCount, orderCount, conversionRate, attributionCount, sourceMarkedCount };
|
||||
return {
|
||||
scanCount,
|
||||
orderCount,
|
||||
conversionRate,
|
||||
attributionCount,
|
||||
sourceMarkedCount,
|
||||
registerCount: sourceMarkedCount,
|
||||
};
|
||||
}
|
||||
|
||||
/** 推广码关联用户:归因记录或用户来源指向本码 */
|
||||
|
||||
Reference in New Issue
Block a user