门店审核功能
This commit is contained in:
@@ -197,6 +197,9 @@ export class StoreService {
|
||||
openTime: body.openTime ? String(body.openTime) : '10:00',
|
||||
closeTime: body.closeTime ? String(body.closeTime) : '22:00',
|
||||
status: this.config.autoApproveStore ? 'OPEN' : 'PAUSED',
|
||||
auditStatus: this.config.autoApproveStore ? 'APPROVED' : 'PENDING',
|
||||
auditedAt: this.config.autoApproveStore ? new Date() : null,
|
||||
rejectReason: null,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -325,6 +328,18 @@ export class StoreService {
|
||||
if (!['OPEN', 'PAUSED', 'CLOSED'].includes(status)) {
|
||||
throw new BadRequestException('无效的门店状态');
|
||||
}
|
||||
if (status === 'OPEN') {
|
||||
if (store.auditStatus === 'PENDING') {
|
||||
throw new BadRequestException('门店尚在总部审核中,通过后方可开门');
|
||||
}
|
||||
if (store.auditStatus === 'REJECTED') {
|
||||
throw new BadRequestException(
|
||||
store.rejectReason
|
||||
? `门店审核未通过:${store.rejectReason}`
|
||||
: '门店审核未通过,请查看驳回原因并重新提交',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const updated = await this.prisma.store.update({
|
||||
where: { id: storeId },
|
||||
@@ -358,6 +373,9 @@ export class StoreService {
|
||||
if (store.status === 'CLOSED') {
|
||||
throw new BadRequestException('门店已关闭,不可编辑');
|
||||
}
|
||||
if (store.auditStatus === 'PENDING') {
|
||||
throw new BadRequestException('门店审核中,暂不可修改资料');
|
||||
}
|
||||
|
||||
const name = body.name !== undefined ? String(body.name).trim() : undefined;
|
||||
const phone = body.phone !== undefined ? String(body.phone).trim() : undefined;
|
||||
@@ -373,6 +391,7 @@ export class StoreService {
|
||||
throw new BadRequestException('门店简介须为 10~500 字');
|
||||
}
|
||||
|
||||
const resubmitAudit = store.auditStatus === 'REJECTED';
|
||||
await this.prisma.store.update({
|
||||
where: { id: storeId },
|
||||
data: {
|
||||
@@ -380,8 +399,33 @@ export class StoreService {
|
||||
...(phone !== undefined ? { phone } : {}),
|
||||
...(address !== undefined ? { address } : {}),
|
||||
...(introRaw !== undefined ? { intro: introRaw || null } : {}),
|
||||
...(resubmitAudit
|
||||
? {
|
||||
auditStatus: 'PENDING' as const,
|
||||
rejectReason: null,
|
||||
auditedAt: null,
|
||||
status: store.status === 'OPEN' ? ('PAUSED' as const) : store.status,
|
||||
}
|
||||
: {}),
|
||||
},
|
||||
});
|
||||
|
||||
if (resubmitAudit) {
|
||||
await this.prisma.commonEvent.create({
|
||||
data: {
|
||||
eventType: 'STORE_AUDIT',
|
||||
refType: 'STORE',
|
||||
refId: storeId,
|
||||
actorType: 'PARTNER',
|
||||
actorId: partnerAccountId,
|
||||
status: 'PENDING',
|
||||
param1: 'RESUBMIT',
|
||||
param1Desc: 'audit_type',
|
||||
remark: '合伙人修改资料后重新提交审核',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return this.partnerGetStore(partnerAccountId, storeId);
|
||||
}
|
||||
|
||||
@@ -398,6 +442,13 @@ export class StoreService {
|
||||
where: { storeAccountId_storeId: { storeAccountId, storeId } },
|
||||
include: { store: true },
|
||||
});
|
||||
if (status === 'OPEN' && binding.store.auditStatus !== 'APPROVED') {
|
||||
throw new BadRequestException(
|
||||
binding.store.auditStatus === 'REJECTED'
|
||||
? `门店审核未通过${binding.store.rejectReason ? `:${binding.store.rejectReason}` : ''}`
|
||||
: '门店尚在总部审核中,通过后方可营业',
|
||||
);
|
||||
}
|
||||
const previousStatus = binding.store.status;
|
||||
const store = await this.prisma.store.update({
|
||||
where: { id: storeId },
|
||||
@@ -423,34 +474,70 @@ export class StoreService {
|
||||
select: { id: true },
|
||||
});
|
||||
const storeIds = partnerStoreIds.map((s) => s.id);
|
||||
const [storeCount, orderCount, recentStores, pendingAuditCount] = await Promise.all([
|
||||
const [storeCount, orderCount, recentStores, pendingAuditCount, recentNotices] = await Promise.all([
|
||||
this.prisma.store.count({ where: { partnerAccountId: primaryId } }),
|
||||
this.prisma.order.count({
|
||||
where: await this.partnerCityService.buildPartnerOrderWhere(primaryId),
|
||||
}),
|
||||
this.prisma.store.findMany({
|
||||
where: { partnerAccountId: primaryId },
|
||||
select: { id: true, name: true, status: true, createdAt: true },
|
||||
select: { id: true, name: true, status: true, auditStatus: true, createdAt: true },
|
||||
orderBy: { createdAt: 'desc' },
|
||||
take: 10,
|
||||
}),
|
||||
this.prisma.store.count({
|
||||
where: { partnerAccountId: primaryId, auditStatus: 'PENDING' },
|
||||
}),
|
||||
storeIds.length === 0
|
||||
? Promise.resolve(0)
|
||||
: this.prisma.commonEvent.count({
|
||||
? Promise.resolve([])
|
||||
: this.prisma.commonEvent.findMany({
|
||||
where: {
|
||||
eventType: 'STORE_AUDIT',
|
||||
status: 'PENDING',
|
||||
refType: 'STORE',
|
||||
refId: { in: storeIds },
|
||||
status: { in: ['APPROVED', 'REJECTED'] },
|
||||
actorType: 'HQ',
|
||||
},
|
||||
orderBy: { createdAt: 'desc' },
|
||||
take: 20,
|
||||
}),
|
||||
]);
|
||||
|
||||
const storeNameMap = new Map(
|
||||
(
|
||||
await this.prisma.store.findMany({
|
||||
where: { id: { in: recentNotices.map((n) => n.refId) } },
|
||||
select: { id: true, name: true },
|
||||
})
|
||||
).map((s) => [s.id.toString(), s.name]),
|
||||
);
|
||||
|
||||
return {
|
||||
storeCount,
|
||||
orderCount,
|
||||
companyName: account.companyName ?? '',
|
||||
recentStores: serializeBigInt(recentStores),
|
||||
pendingAuditCount,
|
||||
notifications: serializeBigInt(
|
||||
recentNotices.map((n) => ({
|
||||
id: n.id,
|
||||
storeId: n.refId,
|
||||
storeName: storeNameMap.get(n.refId.toString()) ?? '门店',
|
||||
status: n.status,
|
||||
remark: n.remark,
|
||||
createdAt: n.createdAt,
|
||||
title:
|
||||
n.status === 'APPROVED'
|
||||
? '门店审核已通过'
|
||||
: n.status === 'REJECTED'
|
||||
? '门店审核已驳回'
|
||||
: '门店审核更新',
|
||||
content:
|
||||
n.status === 'APPROVED'
|
||||
? `${storeNameMap.get(n.refId.toString()) ?? '门店'} 已通过总部审核,可开门营业`
|
||||
: `${storeNameMap.get(n.refId.toString()) ?? '门店'} 未通过审核${n.remark ? `:${n.remark}` : ''}`,
|
||||
})),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user