hqweb端
This commit is contained in:
@@ -0,0 +1,233 @@
|
||||
import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common';
|
||||
import { Prisma } from '@prisma/client';
|
||||
import { PrismaService } from '../../common/prisma/prisma.module';
|
||||
import { serializeBigInt } from '../../common/decorators/current-user.decorator';
|
||||
import type { AdminStoreAccountsQueryDto, AdminStoreMediaQueryDto, AdminStoresQueryDto } from './dto/admin-query.dto';
|
||||
import type {
|
||||
CreateStoreAccountDto,
|
||||
CreateStoreDto,
|
||||
CreateStoreMediaDto,
|
||||
UpdateStoreAccountDto,
|
||||
UpdateStoreDto,
|
||||
UpdateStoreMediaDto,
|
||||
UpdateStoreStatusDto,
|
||||
} from './dto/admin-mutate.dto';
|
||||
|
||||
@Injectable()
|
||||
export class AdminStoresService {
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
|
||||
async listStores(query: AdminStoresQueryDto) {
|
||||
const page = query.page ?? 1;
|
||||
const pageSize = query.pageSize ?? 20;
|
||||
const where: Prisma.StoreWhereInput = {};
|
||||
if (query.name) where.name = { contains: query.name };
|
||||
if (query.status) where.status = query.status as Prisma.EnumStoreStatusFilter['equals'];
|
||||
if (query.cityId) where.cityId = BigInt(query.cityId);
|
||||
if (query.partnerId) where.partnerId = BigInt(query.partnerId);
|
||||
if (query.phone) where.phone = { contains: query.phone };
|
||||
|
||||
const [items, total] = await Promise.all([
|
||||
this.prisma.store.findMany({
|
||||
where,
|
||||
orderBy: { createdAt: 'desc' },
|
||||
skip: (page - 1) * pageSize,
|
||||
take: pageSize,
|
||||
include: {
|
||||
cityRef: { select: { id: true, name: true, code: true } },
|
||||
partner: { select: { id: true, companyName: true } },
|
||||
account: { select: { id: true, phone: true, name: true, status: true } },
|
||||
},
|
||||
}),
|
||||
this.prisma.store.count({ where }),
|
||||
]);
|
||||
return serializeBigInt({ items, total, page, pageSize });
|
||||
}
|
||||
|
||||
async detailStore(id: bigint) {
|
||||
const store = await this.prisma.store.findUnique({
|
||||
where: { id },
|
||||
include: {
|
||||
cityRef: true,
|
||||
partner: true,
|
||||
category: true,
|
||||
account: true,
|
||||
media: { orderBy: { sortOrder: 'asc' } },
|
||||
audits: { orderBy: { submittedAt: 'desc' }, take: 5 },
|
||||
_count: { select: { redeemRecords: true, ratings: true } },
|
||||
},
|
||||
});
|
||||
if (!store) throw new NotFoundException('门店不存在');
|
||||
return serializeBigInt({
|
||||
...store,
|
||||
redeemCount: store._count.redeemRecords,
|
||||
ratingCount: store._count.ratings,
|
||||
_count: undefined,
|
||||
});
|
||||
}
|
||||
|
||||
async updateStoreStatus(id: bigint, dto: UpdateStoreStatusDto) {
|
||||
const store = await this.prisma.store.update({
|
||||
where: { id },
|
||||
data: { status: dto.status as 'OPEN' | 'PAUSED' | 'CLOSED' },
|
||||
});
|
||||
return serializeBigInt(store);
|
||||
}
|
||||
|
||||
async updateStore(id: bigint, dto: UpdateStoreDto) {
|
||||
const store = await this.prisma.store.update({
|
||||
where: { id },
|
||||
data: {
|
||||
...(dto.name !== undefined ? { name: dto.name } : {}),
|
||||
...(dto.phone !== undefined ? { phone: dto.phone } : {}),
|
||||
...(dto.intro !== undefined ? { intro: dto.intro } : {}),
|
||||
...(dto.coverUrl !== undefined ? { coverUrl: dto.coverUrl } : {}),
|
||||
...(dto.address !== undefined ? { address: dto.address } : {}),
|
||||
...(dto.district !== undefined ? { district: dto.district } : {}),
|
||||
},
|
||||
});
|
||||
return serializeBigInt(store);
|
||||
}
|
||||
|
||||
async createStore(dto: CreateStoreDto) {
|
||||
const partner = await this.prisma.partner.findUnique({ where: { id: BigInt(dto.partnerId) } });
|
||||
if (!partner) throw new BadRequestException('开城合伙人不存在');
|
||||
const city = await this.prisma.city.findUnique({ where: { id: BigInt(dto.cityId) } });
|
||||
if (!city) throw new BadRequestException('开城城市不存在');
|
||||
|
||||
const store = await this.prisma.store.create({
|
||||
data: {
|
||||
cityId: city.id,
|
||||
partnerId: partner.id,
|
||||
categoryId: dto.categoryId ? BigInt(dto.categoryId) : null,
|
||||
name: dto.name,
|
||||
phone: dto.phone,
|
||||
province: dto.province ?? city.province,
|
||||
cityName: dto.city ?? city.name,
|
||||
district: dto.district ?? '',
|
||||
address: dto.address,
|
||||
intro: dto.intro ?? null,
|
||||
coverUrl: dto.coverUrl ?? null,
|
||||
status: 'OPEN',
|
||||
},
|
||||
});
|
||||
|
||||
await this.prisma.storeAccount.create({
|
||||
data: {
|
||||
storeId: store.id,
|
||||
phone: dto.accountPhone ?? dto.phone,
|
||||
name: dto.accountName ?? dto.name,
|
||||
},
|
||||
});
|
||||
|
||||
return serializeBigInt(store);
|
||||
}
|
||||
|
||||
async createStoreAccount(dto: CreateStoreAccountDto) {
|
||||
const store = await this.prisma.store.findUnique({
|
||||
where: { id: BigInt(dto.storeId) },
|
||||
include: { account: true },
|
||||
});
|
||||
if (!store) throw new BadRequestException('门店不存在');
|
||||
if (store.account) throw new BadRequestException('门店已有账户');
|
||||
const account = await this.prisma.storeAccount.create({
|
||||
data: { storeId: store.id, phone: dto.phone, name: dto.name },
|
||||
});
|
||||
return serializeBigInt(account);
|
||||
}
|
||||
|
||||
async listStoreMedia(query: AdminStoreMediaQueryDto) {
|
||||
const page = query.page ?? 1;
|
||||
const pageSize = query.pageSize ?? 20;
|
||||
const where: Prisma.StoreMediaWhereInput = {};
|
||||
if (query.storeId) where.storeId = BigInt(query.storeId);
|
||||
if (query.mediaType) where.mediaType = query.mediaType;
|
||||
|
||||
const [items, total] = await Promise.all([
|
||||
this.prisma.storeMedia.findMany({
|
||||
where,
|
||||
orderBy: [{ sortOrder: 'asc' }, { createdAt: 'desc' }],
|
||||
skip: (page - 1) * pageSize,
|
||||
take: pageSize,
|
||||
include: { store: { select: { id: true, name: true } } },
|
||||
}),
|
||||
this.prisma.storeMedia.count({ where }),
|
||||
]);
|
||||
return serializeBigInt({ items, total, page, pageSize });
|
||||
}
|
||||
|
||||
async createStoreMedia(dto: CreateStoreMediaDto) {
|
||||
const store = await this.prisma.store.findUnique({ where: { id: BigInt(dto.storeId) } });
|
||||
if (!store) throw new BadRequestException('门店不存在');
|
||||
const media = await this.prisma.storeMedia.create({
|
||||
data: {
|
||||
storeId: store.id,
|
||||
mediaType: dto.mediaType,
|
||||
url: dto.url,
|
||||
sortOrder: dto.sortOrder ?? 0,
|
||||
},
|
||||
});
|
||||
return serializeBigInt(media);
|
||||
}
|
||||
|
||||
async updateStoreMedia(id: bigint, dto: UpdateStoreMediaDto) {
|
||||
const media = await this.prisma.storeMedia.update({
|
||||
where: { id },
|
||||
data: {
|
||||
...(dto.url !== undefined ? { url: dto.url } : {}),
|
||||
...(dto.mediaType !== undefined ? { mediaType: dto.mediaType } : {}),
|
||||
...(dto.sortOrder !== undefined ? { sortOrder: dto.sortOrder } : {}),
|
||||
},
|
||||
});
|
||||
return serializeBigInt(media);
|
||||
}
|
||||
|
||||
async deleteStoreMedia(id: bigint) {
|
||||
await this.prisma.storeMedia.delete({ where: { id } });
|
||||
return { ok: true };
|
||||
}
|
||||
|
||||
async listStoreAccounts(query: AdminStoreAccountsQueryDto) {
|
||||
const page = query.page ?? 1;
|
||||
const pageSize = query.pageSize ?? 20;
|
||||
const where: Prisma.StoreAccountWhereInput = {};
|
||||
if (query.phone) where.phone = { contains: query.phone };
|
||||
if (query.storeId) where.storeId = BigInt(query.storeId);
|
||||
if (query.status) where.status = query.status as Prisma.EnumAccountStatusFilter['equals'];
|
||||
|
||||
const [items, total] = await Promise.all([
|
||||
this.prisma.storeAccount.findMany({
|
||||
where,
|
||||
orderBy: { createdAt: 'desc' },
|
||||
skip: (page - 1) * pageSize,
|
||||
take: pageSize,
|
||||
include: {
|
||||
store: { select: { id: true, name: true, status: true, cityName: true } },
|
||||
},
|
||||
}),
|
||||
this.prisma.storeAccount.count({ where }),
|
||||
]);
|
||||
return serializeBigInt({ items, total, page, pageSize });
|
||||
}
|
||||
|
||||
async detailStoreAccount(id: bigint) {
|
||||
const account = await this.prisma.storeAccount.findUnique({
|
||||
where: { id },
|
||||
include: { store: { include: { cityRef: true, partner: true } } },
|
||||
});
|
||||
if (!account) throw new NotFoundException('门店账号不存在');
|
||||
return serializeBigInt(account);
|
||||
}
|
||||
|
||||
async updateStoreAccount(id: bigint, dto: UpdateStoreAccountDto) {
|
||||
const account = await this.prisma.storeAccount.update({
|
||||
where: { id },
|
||||
data: {
|
||||
...(dto.name !== undefined ? { name: dto.name } : {}),
|
||||
...(dto.phone !== undefined ? { phone: dto.phone } : {}),
|
||||
...(dto.status !== undefined ? { status: dto.status as 'ACTIVE' | 'DISABLED' } : {}),
|
||||
},
|
||||
});
|
||||
return serializeBigInt(account);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user