108 lines
3.3 KiB
TypeScript
108 lines
3.3 KiB
TypeScript
import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common';
|
|
import { PrismaService } from '../../common/prisma/prisma.module';
|
|
import { BenefitService } from '../benefit/benefit.service';
|
|
import { TradeService } from '../trade/trade.service';
|
|
import { TicketService } from '../common/ticket.service';
|
|
import { serializeBigInt } from '../../common/decorators/current-user.decorator';
|
|
import type { TicketListQueryDto } from '../common/dto/common-query.dto';
|
|
|
|
@Injectable()
|
|
export class AdminTicketsService {
|
|
constructor(
|
|
private readonly prisma: PrismaService,
|
|
private readonly ticketService: TicketService,
|
|
private readonly tradeService: TradeService,
|
|
private readonly benefitService: BenefitService,
|
|
) {}
|
|
|
|
list(query: TicketListQueryDto) {
|
|
return this.ticketService.list(query);
|
|
}
|
|
|
|
detail(id: bigint) {
|
|
return this.ticketService.detail(id);
|
|
}
|
|
|
|
async approve(id: bigint, remark?: string) {
|
|
const ticket = await this.prisma.commonTicket.findUnique({ where: { id } });
|
|
if (!ticket) throw new NotFoundException('工单不存在');
|
|
if (ticket.status !== 'PENDING' && ticket.status !== 'OPEN') {
|
|
throw new BadRequestException('工单状态不可审批');
|
|
}
|
|
|
|
if (ticket.ticketType === 'REFUND' && ticket.refType === 'ORDER') {
|
|
const orderId = ticket.refId;
|
|
await this.prisma.order.update({
|
|
where: { id: orderId },
|
|
data: { status: 'REFUNDED', payStatus: 'REFUNDED' },
|
|
});
|
|
await this.benefitService.voidCouponsOnRefund(orderId);
|
|
await this.prisma.logThirdParty.create({
|
|
data: {
|
|
provider: 'WECHAT_REFUND',
|
|
scene: 'ORDER_REFUND',
|
|
refType: 'ORDER',
|
|
refId: orderId,
|
|
status: 'SUCCESS',
|
|
amount: 0,
|
|
},
|
|
});
|
|
await this.prisma.commonEvent.create({
|
|
data: {
|
|
eventType: 'ORDER_STATUS',
|
|
refType: 'ORDER',
|
|
refId: orderId,
|
|
actorType: 'HQ',
|
|
status: 'REFUNDED',
|
|
remark: remark ?? '退款工单审批通过',
|
|
},
|
|
});
|
|
}
|
|
|
|
if (ticket.ticketType === 'RESHIPMENT' && ticket.refType === 'ORDER') {
|
|
await this.tradeService.applyStatusTransition(
|
|
ticket.refId,
|
|
'PENDING_SHIP',
|
|
'PENDING_SHIP',
|
|
'HQ',
|
|
);
|
|
}
|
|
|
|
return this.ticketService.updateStatus(id, {
|
|
status: 'RESOLVED',
|
|
remark: remark ?? '审批通过',
|
|
});
|
|
}
|
|
|
|
reject(id: bigint, remark?: string) {
|
|
return this.ticketService.updateStatus(id, {
|
|
status: 'REJECTED',
|
|
remark: remark ?? '审批驳回',
|
|
});
|
|
}
|
|
|
|
async listPartnerReshipments(partnerAccountId: bigint) {
|
|
const account = await this.prisma.partnerAccount.findUniqueOrThrow({
|
|
where: { id: partnerAccountId },
|
|
});
|
|
const cities = await this.prisma.commonCity.findMany({
|
|
where: { partnerId: account.partnerId },
|
|
select: { id: true },
|
|
});
|
|
const orders = await this.prisma.order.findMany({
|
|
where: { cityId: { in: cities.map((c) => c.id) } },
|
|
select: { id: true },
|
|
});
|
|
const orderIds = orders.map((o) => o.id);
|
|
const tickets = await this.prisma.commonTicket.findMany({
|
|
where: {
|
|
ticketType: 'RESHIPMENT',
|
|
refType: 'ORDER',
|
|
refId: { in: orderIds },
|
|
},
|
|
orderBy: { createdAt: 'desc' },
|
|
});
|
|
return serializeBigInt(tickets);
|
|
}
|
|
}
|