增加现场提货的配置

This commit is contained in:
2026-08-26 09:22:29 +08:00
parent c7cd0f6cf2
commit 632539e8dc
28 changed files with 393 additions and 105 deletions
+1
View File
@@ -191,6 +191,7 @@ CREATE TABLE common_city (
name VARCHAR(64) NOT NULL,
province VARCHAR(32) NOT NULL,
status VARCHAR(16) NOT NULL DEFAULT 'PENDING',
pickup_min_qty INT NOT NULL DEFAULT 2,
local_min_qty INT NOT NULL DEFAULT 2,
cross_min_qty INT NOT NULL DEFAULT 6,
max_partner_commission_rate DECIMAL(5,4) NOT NULL DEFAULT 0.0500 COMMENT '订单+核销佣金合计上限',
@@ -0,0 +1,3 @@
-- v3.5.11:城市履约起购 — 现场提货独立阈值(瓶当量)
ALTER TABLE `common_city`
ADD COLUMN `pickup_min_qty` INT NOT NULL DEFAULT 2 AFTER `status`;
+1
View File
@@ -1027,6 +1027,7 @@ model CommonCity {
name String @db.VarChar(64)
province String @db.VarChar(32)
status CityStatus @default(PENDING)
pickupMinQty Int @default(2) @map("pickup_min_qty")
localMinQty Int @default(2) @map("local_min_qty")
crossMinQty Int @default(6) @map("cross_min_qty")
maxPartnerCommissionRate Decimal @default(0.05) @map("max_partner_commission_rate") @db.Decimal(5, 4)
+2
View File
@@ -146,6 +146,8 @@ async function main() {
status: 'ACTIVE',
pickupMinQty: 2,
localMinQty: 2,
crossMinQty: 6,
@@ -143,6 +143,7 @@ export class AdminCitiesService {
...(dto.name !== undefined ? { name: dto.name } : {}),
...(dto.province !== undefined ? { province: dto.province } : {}),
...(dto.status !== undefined ? { status: dto.status as 'PENDING' | 'ACTIVE' | 'PAUSED' } : {}),
...(dto.pickupMinQty !== undefined ? { pickupMinQty: dto.pickupMinQty } : {}),
...(dto.localMinQty !== undefined ? { localMinQty: dto.localMinQty } : {}),
...(dto.crossMinQty !== undefined ? { crossMinQty: dto.crossMinQty } : {}),
...(dto.maxPartnerCommissionRate !== undefined
@@ -554,9 +554,18 @@ export class UpdateCityDto {
status?: string;
@IsOptional()
@IsNumber()
@Min(1)
pickupMinQty?: number;
@IsOptional()
@IsNumber()
@Min(1)
localMinQty?: number;
@IsOptional()
@IsNumber()
@Min(1)
crossMinQty?: number;
@IsOptional()
@@ -10,6 +10,7 @@ import type { FreightPayType } from '@prisma/client';
import {
calcBenefitAmount,
generateOrderNo,
minBottleQtyForDelivery,
orderTabToStatuses,
toMinSaleQuantity,
validateMinPurchase,
@@ -157,11 +158,15 @@ export class TradeService {
}
const bottlesPerUnit = sale.bottlesPerUnit > 0 ? sale.bottlesPerUnit : 1;
const mins = {
pickupMinQty: city.pickupMinQty,
localMinQty: city.localMinQty,
crossMinQty: city.crossMinQty,
};
const check = validateMinPurchase(
deliveryType,
body.quantity,
city.localMinQty,
city.crossMinQty,
mins,
{ bottlesPerUnit, saleUnit: sale.saleUnit },
);
@@ -173,12 +178,7 @@ export class TradeService {
});
const freightPayType: FreightPayType | null = deliveryType === 'CROSS_CITY' ? 'COD' : null;
const minBottleQty =
deliveryType === 'ON_SITE_PICKUP'
? city.localMinQty
: deliveryType === 'LOCAL'
? city.localMinQty
: city.crossMinQty;
const minBottleQty = minBottleQtyForDelivery(deliveryType, mins);
const minQty = toMinSaleQuantity(minBottleQty, bottlesPerUnit);
return {
@@ -1666,11 +1666,15 @@ export class TradeService {
}
const bottlesPerUnit = sale.bottlesPerUnit > 0 ? sale.bottlesPerUnit : 1;
const mins = {
pickupMinQty: city.pickupMinQty,
localMinQty: city.localMinQty,
crossMinQty: city.crossMinQty,
};
const check = validateMinPurchase(
deliveryType === 'CROSS_CITY' ? 'CROSS_CITY' : deliveryType === 'ON_SITE_PICKUP' ? 'ON_SITE_PICKUP' : 'LOCAL',
body.quantity,
city.localMinQty,
city.crossMinQty,
mins,
{ bottlesPerUnit, saleUnit: sale.saleUnit },
);
if (!check.ok) throw new BadRequestException(check.message);
@@ -1695,7 +1699,7 @@ export class TradeService {
bottlesPerUnit,
bottleQuantity: body.quantity * bottlesPerUnit,
minQuantity: toMinSaleQuantity(
deliveryType === 'CROSS_CITY' ? city.crossMinQty : city.localMinQty,
minBottleQtyForDelivery(deliveryType, mins),
bottlesPerUnit,
),
};