feat(ops): add global test whitelist and exclude test accounts from settlement
Unify product/store visibility on HQ whitelist, mark isTest snapshots, and fix SUPER_ADMIN access for the new module.
This commit is contained in:
@@ -25,6 +25,7 @@ import { AnalyticsService } from '../analytics/analytics.service';
|
||||
import { UserAddressService } from './user-address.service';
|
||||
import { ResourceService } from '../common/resource.service';
|
||||
import { HqPermissionsResolver } from '../../common/guards/hq-permission.guard';
|
||||
import { TestWhitelistService } from '../../common/test-whitelist/test-whitelist.service';
|
||||
|
||||
import type { User } from '@prisma/client';
|
||||
|
||||
@@ -67,8 +68,21 @@ export class AuthService {
|
||||
private readonly userAddressService: UserAddressService,
|
||||
@Inject(forwardRef(() => ResourceService)) private readonly resourceService: ResourceService,
|
||||
private readonly hqPermissions: HqPermissionsResolver,
|
||||
private readonly testWhitelist: TestWhitelistService,
|
||||
) {}
|
||||
|
||||
/** 登录/绑号后按全局白名单同步 isTest */
|
||||
private async syncTestFlagByPhone(phone: string) {
|
||||
const isTest = await this.testWhitelist.isPhoneInWhitelist(phone);
|
||||
await Promise.all([
|
||||
this.prisma.user.updateMany({ where: { phone }, data: { isTest } }),
|
||||
this.prisma.storeAccount.updateMany({ where: { phone }, data: { isTest } }),
|
||||
this.prisma.partnerAccount.updateMany({ where: { phone }, data: { isTest } }),
|
||||
this.prisma.store.updateMany({ where: { phone }, data: { isTest } }),
|
||||
]);
|
||||
return isTest;
|
||||
}
|
||||
|
||||
private assertMobilePhone(phone: string) {
|
||||
const trimmed = phone.trim();
|
||||
if (!/^1[3-9]\d{9}$/.test(trimmed)) {
|
||||
@@ -375,12 +389,14 @@ export class AuthService {
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
const isTest = await this.testWhitelist.isPhoneInWhitelist(normalizedPhone);
|
||||
user = await this.prisma.user.create({
|
||||
data: {
|
||||
phone: normalizedPhone,
|
||||
phoneVerifiedAt: new Date(),
|
||||
userNo: generateUserNo(),
|
||||
nickname: `用户${normalizedPhone.slice(-4)}`,
|
||||
isTest,
|
||||
sourceType: source?.sourceType ?? 'ORGANIC',
|
||||
sourceRefId: source?.sourceRefId,
|
||||
sourceLabel: source?.sourceLabel,
|
||||
@@ -401,6 +417,11 @@ export class AuthService {
|
||||
include: { avatar: true },
|
||||
});
|
||||
}
|
||||
await this.syncTestFlagByPhone(normalizedPhone);
|
||||
user = await this.prisma.user.findUniqueOrThrow({
|
||||
where: { id: user.id },
|
||||
include: { avatar: true },
|
||||
});
|
||||
await this.assertActiveUser(user.id);
|
||||
}
|
||||
|
||||
@@ -810,12 +831,14 @@ export class AuthService {
|
||||
}
|
||||
}
|
||||
if (!user) {
|
||||
const isTest = await this.testWhitelist.isPhoneInWhitelist(normalizedPhone);
|
||||
user = await this.prisma.user.create({
|
||||
data: {
|
||||
phone: normalizedPhone,
|
||||
phoneVerifiedAt: new Date(),
|
||||
userNo: generateUserNo(),
|
||||
nickname: `用户${normalizedPhone.slice(-4)}`,
|
||||
isTest,
|
||||
cityPreference: {
|
||||
create: {
|
||||
selectedCityCode: '410100',
|
||||
@@ -852,6 +875,12 @@ export class AuthService {
|
||||
|
||||
if (!user) throw new BadRequestException('登录失败');
|
||||
|
||||
await this.syncTestFlagByPhone(normalizedPhone);
|
||||
user = await this.prisma.user.findUniqueOrThrow({
|
||||
where: { id: user.id },
|
||||
include: { avatar: true },
|
||||
});
|
||||
|
||||
this.analyticsService.trackOneSafe(user.id, clientApp, {
|
||||
eventName: method === 'sms' ? 'sms_login' : 'wechat_phone_login',
|
||||
extraJson: { method },
|
||||
@@ -998,6 +1027,7 @@ export class AuthService {
|
||||
if (!account) throw new BadRequestException('该手机号未绑定门店');
|
||||
if (account.status !== 'ACTIVE') throw new BadRequestException('门店账号已停用');
|
||||
if (!account.bindings.length) throw new BadRequestException('该账号未绑定任何门店');
|
||||
await this.syncTestFlagByPhone(normalizedPhone);
|
||||
await this.prisma.storeAccount.update({
|
||||
where: { id: account.id },
|
||||
data: { lastLoginAt: new Date() },
|
||||
@@ -1032,6 +1062,7 @@ export class AuthService {
|
||||
});
|
||||
if (!account) throw new BadRequestException('未找到合伙人账号');
|
||||
if (account.status !== 'ACTIVE') throw new BadRequestException('合伙人账号已停用');
|
||||
await this.syncTestFlagByPhone(normalizedPhone);
|
||||
const primary = await this.resolvePrimaryAccount(account.id);
|
||||
await this.prisma.partnerAccount.update({
|
||||
where: { id: account.id },
|
||||
|
||||
Reference in New Issue
Block a user