门店账户多账号
This commit is contained in:
@@ -116,17 +116,34 @@ export class StoreService {
|
||||
}
|
||||
const existingAccount = await this.prisma.storeAccount.findUnique({
|
||||
where: { phone: normalizedPhone },
|
||||
include: { _count: { select: { bindings: true } } },
|
||||
});
|
||||
if (existingAccount) {
|
||||
return { available: false, message: '该手机号已绑定门店' };
|
||||
if (!existingAccount) {
|
||||
return { available: true, existingStoreCount: 0, needConfirm: false };
|
||||
}
|
||||
return { available: true };
|
||||
if (existingAccount.isPrimary !== 1) {
|
||||
return { available: false, message: '该手机号已是门店子账号,不可作为负责人' };
|
||||
}
|
||||
if (existingAccount.status !== 'ACTIVE') {
|
||||
return { available: false, message: '该手机号对应门店账号已停用' };
|
||||
}
|
||||
const existingStoreCount = existingAccount._count.bindings;
|
||||
return {
|
||||
available: true,
|
||||
existingStoreCount,
|
||||
needConfirm: existingStoreCount > 0,
|
||||
message:
|
||||
existingStoreCount > 0
|
||||
? `该手机号已是门店主账号(已绑 ${existingStoreCount} 家店),确认后将追加绑定新店`
|
||||
: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
async createStore(partnerAccountId: bigint, body: Record<string, unknown>) {
|
||||
const { primaryId } = await this.resolvePartnerScope(partnerAccountId);
|
||||
const normalizedPhone = String(body.phone).trim();
|
||||
await this.assertStorePhoneAvailable(normalizedPhone);
|
||||
const confirmBindExisting = body.confirmBindExisting === true || body.confirmBindExisting === 'true';
|
||||
await this.assertStorePhoneAvailable(normalizedPhone, confirmBindExisting);
|
||||
|
||||
const city = await this.resolvePartnerCity(partnerAccountId, body.cityId);
|
||||
const coverUrl = body.coverUrl ? String(body.coverUrl).trim() : '';
|
||||
@@ -139,6 +156,10 @@ export class StoreService {
|
||||
if (envPhotoUrls.length < 3) throw new BadRequestException('请上传至少 3 张环境照片');
|
||||
if (!contractUrl) throw new BadRequestException('请上传签约合同');
|
||||
|
||||
const bankAccountName = body.bankAccountName ? String(body.bankAccountName) : null;
|
||||
const bankAccountNo = body.bankAccountNo ? String(body.bankAccountNo) : null;
|
||||
const bankBranch = body.bankBranch ? String(body.bankBranch) : null;
|
||||
|
||||
const store = await this.prisma.store.create({
|
||||
data: {
|
||||
cityId: city.id,
|
||||
@@ -151,9 +172,6 @@ export class StoreService {
|
||||
district: String(body.district ?? ''),
|
||||
address: String(body.address),
|
||||
intro: body.intro ? String(body.intro) : null,
|
||||
bankAccountName: body.bankAccountName ? String(body.bankAccountName) : null,
|
||||
bankAccountNo: body.bankAccountNo ? String(body.bankAccountNo) : null,
|
||||
bankBranch: body.bankBranch ? String(body.bankBranch) : null,
|
||||
openTime: body.openTime ? String(body.openTime) : '10:00',
|
||||
closeTime: body.closeTime ? String(body.closeTime) : '22:00',
|
||||
status: this.config.autoApproveStore ? 'OPEN' : 'PAUSED',
|
||||
@@ -219,14 +237,38 @@ export class StoreService {
|
||||
extraJson: body as never,
|
||||
},
|
||||
});
|
||||
void audit;
|
||||
|
||||
await this.prisma.storeAccount.create({
|
||||
data: {
|
||||
storeId: store.id,
|
||||
phone: normalizedPhone,
|
||||
name: String(body.name),
|
||||
},
|
||||
const existingPrimary = await this.prisma.storeAccount.findUnique({
|
||||
where: { phone: normalizedPhone },
|
||||
});
|
||||
if (existingPrimary && existingPrimary.isPrimary === 1) {
|
||||
await this.prisma.storeAccountStore.create({
|
||||
data: { storeAccountId: existingPrimary.id, storeId: store.id },
|
||||
});
|
||||
if (bankAccountName || bankAccountNo || bankBranch) {
|
||||
await this.prisma.storeAccount.update({
|
||||
where: { id: existingPrimary.id },
|
||||
data: {
|
||||
...(bankAccountName != null ? { bankAccountName } : {}),
|
||||
...(bankAccountNo != null ? { bankAccountNo } : {}),
|
||||
...(bankBranch != null ? { bankBranch } : {}),
|
||||
},
|
||||
});
|
||||
}
|
||||
} else {
|
||||
await this.prisma.storeAccount.create({
|
||||
data: {
|
||||
phone: normalizedPhone,
|
||||
name: String(body.name),
|
||||
isPrimary: 1,
|
||||
bankAccountName,
|
||||
bankAccountNo,
|
||||
bankBranch,
|
||||
bindings: { create: [{ storeId: store.id }] },
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
this.analyticsService.trackPartnerOneSafe(partnerAccountId, 'PARTNER_H5', {
|
||||
partnerAccountId: primaryId,
|
||||
@@ -321,26 +363,26 @@ export class StoreService {
|
||||
return this.partnerGetStore(partnerAccountId, storeId);
|
||||
}
|
||||
|
||||
async getShopStore(storeAccountId: bigint) {
|
||||
const account = await this.prisma.storeAccount.findUniqueOrThrow({
|
||||
where: { id: storeAccountId },
|
||||
async getShopStore(storeAccountId: bigint, storeId: bigint) {
|
||||
const binding = await this.prisma.storeAccountStore.findUniqueOrThrow({
|
||||
where: { storeAccountId_storeId: { storeAccountId, storeId } },
|
||||
include: { store: { include: { category: true, coverResource: true } } },
|
||||
});
|
||||
return serializeBigInt(mapStoreCompat(account.store));
|
||||
return serializeBigInt(mapStoreCompat(binding.store));
|
||||
}
|
||||
|
||||
async updateShopStatus(storeAccountId: bigint, status: 'OPEN' | 'PAUSED') {
|
||||
const account = await this.prisma.storeAccount.findUniqueOrThrow({
|
||||
where: { id: storeAccountId },
|
||||
async updateShopStatus(storeAccountId: bigint, storeId: bigint, status: 'OPEN' | 'PAUSED') {
|
||||
const binding = await this.prisma.storeAccountStore.findUniqueOrThrow({
|
||||
where: { storeAccountId_storeId: { storeAccountId, storeId } },
|
||||
include: { store: true },
|
||||
});
|
||||
const previousStatus = account.store.status;
|
||||
const previousStatus = binding.store.status;
|
||||
const store = await this.prisma.store.update({
|
||||
where: { id: account.storeId },
|
||||
where: { id: storeId },
|
||||
data: { status },
|
||||
});
|
||||
this.analyticsService.trackStoreOneSafe(storeAccountId, 'SHOP_H5', {
|
||||
storeId: account.storeId,
|
||||
storeId,
|
||||
eventName: 'store_status_change',
|
||||
extraJson: {
|
||||
status,
|
||||
@@ -721,10 +763,13 @@ export class StoreService {
|
||||
}
|
||||
}
|
||||
|
||||
private async assertStorePhoneAvailable(phone: string) {
|
||||
private async assertStorePhoneAvailable(phone: string, confirmBindExisting = false) {
|
||||
const result = await this.partnerCheckStorePhone(phone);
|
||||
if (!result.available) {
|
||||
throw new BadRequestException(result.message ?? '该手机号已绑定门店');
|
||||
throw new BadRequestException(result.message ?? '该手机号不可用');
|
||||
}
|
||||
if (result.needConfirm && !confirmBindExisting) {
|
||||
throw new BadRequestException(result.message ?? '该手机号已绑定门店,请确认后重试');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user