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 { PartnerCityService } from '../city-scope/partner-city.service'; 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, private readonly partnerCityService: PartnerCityService, ) {} 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 orderWhere = await this.partnerCityService.buildPartnerOrderWhere(partnerAccountId); const orders = await this.prisma.order.findMany({ where: orderWhere, 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); } }