feat(edit): 定价试算开发、SKU 样式功能修改

This commit is contained in:
R524809
2026-09-29 17:50:19 +08:00
parent 84b230e69a
commit 0a303414d8
52 changed files with 4278 additions and 1393 deletions
+126
View File
@@ -276,6 +276,7 @@ describe('商品编辑 M3.0–M3.3 HTTP 集成测试', () => {
assert.equal(editor.response.status, 200);
assert.equal(editor.body.data.product.id, first.productId);
assert.equal(editor.body.data.profile.id, first.profileId);
assert.equal(editor.body.data.profile.fulfillment, 'rfbs');
assert.equal(editor.body.data.variants.length, 1);
assert.equal(editor.body.data.variants[0].listing.status, 'not_listed');
});
@@ -2189,4 +2190,129 @@ describe('商品编辑 M3.0–M3.3 HTTP 集成测试', () => {
),
);
});
it('包装重量模式独立保存,并允许 SKU 已确认重量继承通用尺寸', async () => {
await database.workspaceTransaction(workspaceId, async (tx) => {
const store = await tx.query<{ id: string }>(
`SELECT id FROM atlas.stores
WHERE workspace_id = current_setting('app.workspace_id')::uuid
AND platform_id = $1 AND is_default = true LIMIT 1`,
[platformId],
);
if (!store.rows.length)
await tx.query(
`INSERT INTO atlas.stores
(workspace_id, platform_id, name, platform_client_id,
currency_code, is_default, status, credential_status)
VALUES (current_setting('app.workspace_id')::uuid, $1,
'包装规格模式测试店铺', $2, 'RUB', true, 'active', 'valid')`,
[platformId, `editor-package-${randomUUID()}`],
);
});
const created = await createCollectionItem('包装规格模式测试商品');
const entered = await request(
`/api/collection-items/${created.collectionItemId}/editor-contexts`,
{
method: 'POST',
headers: headers({
'X-Atlas-Platform-Id': platformId,
'Idempotency-Key': randomUUID(),
}),
},
);
assert.equal(entered.response.status, 201);
const before = await request(`/api/products/${created.productId}/editor`, {
headers: headers({ 'X-Atlas-Platform-Id': platformId }),
});
assert.equal(before.response.status, 200);
const snapshot = before.body.data;
const variant = snapshot.variants[0];
const payload = {
ai_source_material: snapshot.source_material,
ai_source_overridden_fields: snapshot.source_material_state.overridden_fields,
common: {
...snapshot.product.common,
default_physical_spec: snapshot.product.default_physical_spec,
default_package_spec: {
length_mm: '120',
width_mm: '60',
height_mm: '30',
shipping_weight_g: null,
status: 'missing',
},
package_weight_mode: 'variant',
package_dimensions_mode: 'common',
},
profile: {
target_store_id: snapshot.profile.target_store.id,
fulfillment: 'rfbs',
title: snapshot.profile.title,
description: snapshot.profile.description,
tags: snapshot.profile.tags,
platform_product_category_id: snapshot.profile.category.id,
category_source: snapshot.profile.category.source,
},
variants: [
{
id: variant.id,
client_key: null,
display_name: variant.display_name,
source_sku: variant.source_sku,
specification_values: variant.specification_values,
purchase_cost_cny: variant.purchase_cost_cny,
title: variant.title,
tags: variant.tags,
description: variant.description,
physical_spec: variant.physical_spec,
package_spec: {
length_mm: null,
width_mm: null,
height_mm: null,
shipping_weight_g: '400',
status: 'confirmed',
},
offer_id: variant.listing.offer_id,
media_asset_ids: variant.media.map((item: { asset_id: string }) => item.asset_id),
},
],
};
const saved = await request(`/api/products/${created.productId}/editor-draft`, {
method: 'PUT',
headers: headers({
'X-Atlas-Platform-Id': platformId,
'Idempotency-Key': randomUUID(),
'If-Match': `"${snapshot.product.revision}:${snapshot.profile.revision}"`,
}),
body: JSON.stringify(payload),
});
assert.equal(saved.response.status, 200, JSON.stringify(saved.body));
const after = await request(`/api/products/${created.productId}/editor`, {
headers: headers({ 'X-Atlas-Platform-Id': platformId }),
});
assert.equal(after.body.data.product.package_weight_mode, 'variant');
assert.equal(after.body.data.product.package_dimensions_mode, 'common');
assert.equal(after.body.data.product.default_package_spec.shipping_weight_g, null);
assert.equal(after.body.data.variants[0].package_spec.shipping_weight_g, '400.000');
assert.equal(after.body.data.variants[0].effective_package_spec.length_mm, '120.000');
assert.equal(after.body.data.variants[0].effective_package_spec.status, 'confirmed');
const {
package_weight_mode: _weightMode,
package_dimensions_mode: _dimensionsMode,
...legacyCommon
} = payload.common;
const legacySave = await request(`/api/products/${created.productId}/editor-draft`, {
method: 'PUT',
headers: headers({
'X-Atlas-Platform-Id': platformId,
'Idempotency-Key': randomUUID(),
'If-Match': `"${after.body.data.product.revision}:${after.body.data.profile.revision}"`,
}),
body: JSON.stringify({ ...payload, common: legacyCommon }),
});
assert.equal(legacySave.response.status, 200, JSON.stringify(legacySave.body));
const unchangedMode = await request(`/api/products/${created.productId}/editor`, {
headers: headers({ 'X-Atlas-Platform-Id': platformId }),
});
assert.equal(unchangedMode.body.data.product.package_weight_mode, 'variant');
});
});