feat(fulfillment): 同城运费与路由修复,配送单展示商品用户地址
同城 MANUAL/ZZXFX 按小飞侠价规计费,路由查询回退仓配凭证;HQ 配送单补商品、用户和收货地址。门店核销回跳与小程序核销码一并带上。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -4,6 +4,8 @@ import { Prisma } from '@prisma/client';
|
||||
import { PrismaService } from '../../common/prisma/prisma.module';
|
||||
import { loadStorePrimaryBank } from '../../common/store/store-bank.util';
|
||||
import { serializeBigInt } from '../../common/decorators/current-user.decorator';
|
||||
import { FulfillmentProviderService } from '../fulfillment/fulfillment-provider.service';
|
||||
import { calcDeliveryFreightAmount } from '../fulfillment/delivery-freight.util';
|
||||
import type { AdminDeliveriesQueryDto, AdminRedeemRecordsQueryDto } from './dto/admin-query.dto';
|
||||
import type { UpdateDeliveryDto } from './dto/admin-mutate.dto';
|
||||
|
||||
@@ -334,18 +336,45 @@ export class AdminRedeemService {
|
||||
}
|
||||
}
|
||||
|
||||
const deliveryOrderSelect = {
|
||||
id: true,
|
||||
orderNo: true,
|
||||
status: true,
|
||||
deliveryType: true,
|
||||
productName: true,
|
||||
productSpec: true,
|
||||
barcode69: true,
|
||||
quantity: true,
|
||||
saleUnit: true,
|
||||
bottlesPerUnit: true,
|
||||
payAmount: true,
|
||||
receiverName: true,
|
||||
receiverPhone: true,
|
||||
receiverAddress: true,
|
||||
receiverProvince: true,
|
||||
receiverCity: true,
|
||||
receiverDistrict: true,
|
||||
user: { select: { id: true, userNo: true, phone: true, nickname: true } },
|
||||
imageResource: { select: { url: true } },
|
||||
} satisfies Prisma.OrderSelect;
|
||||
|
||||
@Injectable()
|
||||
export class AdminDeliveriesService {
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
constructor(
|
||||
private readonly prisma: PrismaService,
|
||||
private readonly fulfillmentProviderService: FulfillmentProviderService,
|
||||
) {}
|
||||
|
||||
async list(query: AdminDeliveriesQueryDto) {
|
||||
const page = query.page ?? 1;
|
||||
const pageSize = query.pageSize ?? 20;
|
||||
const where: Prisma.OrderDeliveryWhereInput = {};
|
||||
const where: Prisma.OrderDeliveryWhereInput = {
|
||||
order: { deliveryType: { not: 'ON_SITE_PICKUP' } },
|
||||
};
|
||||
if (query.provider) where.provider = query.provider as DeliveryProvider;
|
||||
if (query.trackingNo) where.trackingNo = { contains: query.trackingNo };
|
||||
if (query.orderNo) {
|
||||
where.order = { orderNo: { contains: query.orderNo } };
|
||||
where.order = { deliveryType: { not: 'ON_SITE_PICKUP' }, orderNo: { contains: query.orderNo } };
|
||||
}
|
||||
|
||||
const [items, total] = await Promise.all([
|
||||
@@ -355,39 +384,53 @@ export class AdminDeliveriesService {
|
||||
skip: (page - 1) * pageSize,
|
||||
take: pageSize,
|
||||
include: {
|
||||
order: {
|
||||
select: {
|
||||
id: true,
|
||||
orderNo: true,
|
||||
status: true,
|
||||
receiverName: true,
|
||||
receiverPhone: true,
|
||||
deliveryType: true,
|
||||
productName: true,
|
||||
quantity: true,
|
||||
},
|
||||
},
|
||||
order: { select: deliveryOrderSelect },
|
||||
fulfillmentProvider: { select: { code: true, pricingRulesJson: true } },
|
||||
},
|
||||
}),
|
||||
this.prisma.orderDelivery.count({ where }),
|
||||
]);
|
||||
return serializeBigInt({ items, total, page, pageSize });
|
||||
return serializeBigInt({
|
||||
items: items.map((row) => this.withLogisticsFee(row)),
|
||||
total,
|
||||
page,
|
||||
pageSize,
|
||||
});
|
||||
}
|
||||
|
||||
async detail(id: bigint) {
|
||||
const delivery = await this.prisma.orderDelivery.findUnique({
|
||||
where: { id },
|
||||
include: {
|
||||
order: {
|
||||
include: {
|
||||
user: { select: { id: true, userNo: true, phone: true } },
|
||||
imageResource: { select: { url: true } },
|
||||
},
|
||||
},
|
||||
order: { select: deliveryOrderSelect },
|
||||
fulfillmentProvider: { select: { code: true, pricingRulesJson: true } },
|
||||
},
|
||||
});
|
||||
if (!delivery) throw new NotFoundException('配送单不存在');
|
||||
return serializeBigInt(delivery);
|
||||
return serializeBigInt(this.withLogisticsFee(delivery));
|
||||
}
|
||||
|
||||
private withLogisticsFee<
|
||||
T extends {
|
||||
provider: string;
|
||||
order: { quantity: number; bottlesPerUnit: number; deliveryType: string };
|
||||
fulfillmentProvider?: { code: string; pricingRulesJson: string | null } | null;
|
||||
},
|
||||
>(row: T) {
|
||||
const { fulfillmentProvider, ...rest } = row;
|
||||
return {
|
||||
...rest,
|
||||
logisticsFee: calcDeliveryFreightAmount({
|
||||
quantity: row.order.quantity,
|
||||
bottlesPerUnit: row.order.bottlesPerUnit,
|
||||
deliveryType: row.order.deliveryType,
|
||||
provider: row.provider,
|
||||
providerCode: fulfillmentProvider?.code,
|
||||
pricing: this.fulfillmentProviderService.parsePricingRules(
|
||||
fulfillmentProvider?.pricingRulesJson ?? null,
|
||||
),
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
async update(id: bigint, dto: UpdateDeliveryDto) {
|
||||
|
||||
Reference in New Issue
Block a user