fix(consignment): 寄卖改价上限按单价计算并补充单价/合计提示
This commit is contained in:
@@ -11,7 +11,8 @@
|
||||
* 「商品名下拉」(每个选项绑定一条模板的 ruleKey)。
|
||||
*
|
||||
* 取价(resolveTemplateSpecPriceFen):按选项的 ruleKey 实时回查启用的模板规则,
|
||||
* fixed 模式取 reward_amount;unit 模式取 unit_price_fen × 数量。
|
||||
* fixed 模式取 reward_amount;unit 模式取 unit_price_fen × 模板拼单份数(sharingTotalQuantity)。
|
||||
* 返回的是**每个寄卖单位**的价格:卖家寄卖数量只决定库存件数,不再参与取价/改价上限。
|
||||
* 模板停用/删除 → 返回 0 → 发布侧按 missingPricePolicy=block 拦截,提示运营补模板价。
|
||||
* 取价永远只看本分类(+子树)的模板,绝不跨分类借用(根治跨分类串价)。
|
||||
*/
|
||||
@@ -394,10 +395,8 @@ export function templateRulePriceFen(rule: ConsignmentTemplateRuleRow): number {
|
||||
export async function resolveTemplateSpecPriceFen(input: {
|
||||
specs: ConsignmentSpecField[]
|
||||
values: Record<string, unknown>
|
||||
quantity?: number
|
||||
}): Promise<{ priceFen: number; matchedRuleKeys: string[]; missingKeys: string[] }> {
|
||||
const specs = parseTemplateSpecs(input.specs)
|
||||
const quantity = Math.max(1, Math.round(Number(input.quantity || 1)))
|
||||
const matchedRuleKeys: string[] = []
|
||||
const missingKeys: string[] = []
|
||||
|
||||
@@ -424,12 +423,8 @@ export async function resolveTemplateSpecPriceFen(input: {
|
||||
// 同一组合的多个字段都指向同一条模板;取第一条命中的模板价
|
||||
const firstKey = matchedRuleKeys[0]!
|
||||
const rule = await getEnabledWorkProductRuleByKey(firstKey)
|
||||
const basePriceFen = rule ? templateRulePriceFen(rule) : 0
|
||||
// unit 计价的模板(如 X 许愿币按件价):寄卖数量是份数,按「模板 × 数量」放大
|
||||
const priceFen =
|
||||
rule && rule.pricingMode === 'unit' && rule.unitPriceFen > 0
|
||||
? Math.max(0, Math.round(rule.unitPriceFen * quantity))
|
||||
: basePriceFen
|
||||
// 模板价就是每个寄卖单位的单价;卖家寄卖数量只决定库存件数,不能放大改价上限
|
||||
const priceFen = rule ? templateRulePriceFen(rule) : 0
|
||||
return { priceFen, matchedRuleKeys, missingKeys }
|
||||
}
|
||||
|
||||
|
||||
@@ -232,3 +232,23 @@ test('寄售价不再强制最低1元,数量上限按当前分类统计', asyn
|
||||
'数量上限校验必须按当前寄卖配置统计',
|
||||
)
|
||||
})
|
||||
|
||||
test('模板建议价与改价上限按单价计算,不随寄卖数量放大', async () => {
|
||||
const [serviceSource, templateSource] = await Promise.all([
|
||||
readServiceSource(),
|
||||
readFile(new URL('./consignment-template-spec-service.ts', import.meta.url), 'utf8'),
|
||||
])
|
||||
// unit 计价模板:模板价 = 单价 × 拼单份数(templateRulePriceFen 内已算完);
|
||||
// 卖家寄卖数量只决定库存件数,取价时不能再乘一次
|
||||
assert.ok(
|
||||
templateSource.includes('const priceFen = rule ? templateRulePriceFen(rule) : 0'),
|
||||
'取价必须直接使用模板单价',
|
||||
)
|
||||
assert.ok(!templateSource.includes('quantity?: number'), '取价函数不再接收寄卖数量')
|
||||
const publishBlock = serviceSource.slice(
|
||||
serviceSource.indexOf('const priceSuggestion = await getWorkerConsignmentPriceSuggestion'),
|
||||
serviceSource.indexOf('const priceResolution = resolveWorkerConsignmentPrice'),
|
||||
)
|
||||
assert.ok(publishBlock.length > 0, '必须存在发布取价调用')
|
||||
assert.ok(!publishBlock.includes('quantity'), '发布取价不得传寄卖数量')
|
||||
})
|
||||
|
||||
@@ -407,12 +407,11 @@ export async function publishWorkerConsignment(workerId: number, payload: JsonOb
|
||||
const sellerNote = String(intakeValues.sellerNote ?? payload.sellerNote ?? '').trim()
|
||||
|
||||
// 寄售价:按配置算出系统建议价(模板折扣价 / 模板价固定下调),打手只能往下调。
|
||||
// 没有模板价时一律阻止发布。模板驱动规格按数量放大单价(unit 计价模板)。
|
||||
// 没有模板价时一律阻止发布。建议价与改价上限都是**单价**,不随寄卖数量放大。
|
||||
const priceSuggestion = await getWorkerConsignmentPriceSuggestion({
|
||||
profileId: profile?.profileId,
|
||||
specs,
|
||||
values: specValues,
|
||||
quantity,
|
||||
})
|
||||
const pricing = profile?.config.pricing ?? DEFAULT_CONSIGNMENT_PRICING
|
||||
const submittedPriceFen = Math.max(
|
||||
@@ -1072,8 +1071,6 @@ export async function getWorkerConsignmentPriceSuggestion(payload: {
|
||||
/** 保留旧参数,价格只依赖系统/系列/钻级/璀璨 */
|
||||
specs?: ConsignmentSpecField[]
|
||||
values?: ConsignmentSpecValues
|
||||
/** 模板驱动规格:unit 计价模板按数量放大单价 */
|
||||
quantity?: unknown
|
||||
/** 旧调用兼容:平铺参数 */
|
||||
system?: unknown
|
||||
series?: unknown
|
||||
@@ -1114,7 +1111,6 @@ export async function getWorkerConsignmentPriceSuggestion(payload: {
|
||||
const resolution = await resolveTemplateSpecPriceFen({
|
||||
specs,
|
||||
values,
|
||||
quantity: Number(payload.quantity || 1),
|
||||
})
|
||||
const templatePriceFen = Math.max(0, Math.round(Number(resolution.priceFen || 0)))
|
||||
const matchedRules: { ruleKey: string; productName: string; rewardAmountFen: number }[] = []
|
||||
|
||||
Reference in New Issue
Block a user