feat: 商品详情大SKU改为单接口异步提交
All checks were successful
Build and Deploy TenantUI / build-and-deploy (push) Successful in 53s

This commit is contained in:
2026-02-25 10:51:30 +08:00
parent 5bdcf536a4
commit f8274173ac
2 changed files with 59 additions and 28 deletions

View File

@@ -24,6 +24,13 @@ export type ProductSkuSaveJobStatus =
| 'running' | 'running'
| 'succeeded'; | 'succeeded';
/** 商品异步保存中的 SKU 任务状态。 */
export type ProductSaveAsyncSkuJobStatus =
| 'failed'
| 'not_required'
| 'queued'
| 'running';
/** 分类展示渠道。 */ /** 分类展示渠道。 */
export type ProductCategoryChannel = 'dine_in' | 'pickup' | 'wm'; export type ProductCategoryChannel = 'dine_in' | 'pickup' | 'wm';
@@ -270,6 +277,15 @@ export interface SaveProductDto {
warningStock?: null | number; warningStock?: null | number;
} }
/** 商品异步保存响应。 */
export interface SaveProductAsyncDto {
message: null | string;
productId: string;
skuJobId: null | string;
skuJobStatus: ProductSaveAsyncSkuJobStatus;
storeId: string;
}
/** 创建 SKU 异步保存任务参数。 */ /** 创建 SKU 异步保存任务参数。 */
export interface CreateProductSkuSaveJobDto { export interface CreateProductSkuSaveJobDto {
productId: string; productId: string;
@@ -727,6 +743,11 @@ export async function saveProductApi(data: SaveProductDto) {
return requestClient.post<ProductDetailDto>('/product/save', data); return requestClient.post<ProductDetailDto>('/product/save', data);
} }
/** 异步保存商品(基础信息落库 + SKU 入队)。 */
export async function saveProductAsyncApi(data: SaveProductDto) {
return requestClient.post<SaveProductAsyncDto>('/product/save-async', data);
}
/** 创建 SKU 异步保存任务。 */ /** 创建 SKU 异步保存任务。 */
export async function createProductSkuSaveJobApi( export async function createProductSkuSaveJobApi(
data: CreateProductSkuSaveJobDto, data: CreateProductSkuSaveJobDto,

View File

@@ -18,7 +18,6 @@ import { message } from 'ant-design-vue';
import { uploadTenantFileApi } from '#/api/files'; import { uploadTenantFileApi } from '#/api/files';
import { import {
createProductSkuSaveJobApi,
deleteProductApi, deleteProductApi,
getProductAddonGroupListApi, getProductAddonGroupListApi,
getProductCategoryListApi, getProductCategoryListApi,
@@ -26,6 +25,7 @@ import {
getProductLabelListApi, getProductLabelListApi,
getProductSkuSaveJobApi, getProductSkuSaveJobApi,
getProductSpecListApi, getProductSpecListApi,
saveProductAsyncApi,
saveProductApi, saveProductApi,
} from '#/api/product'; } from '#/api/product';
@@ -514,7 +514,7 @@ export function createProductDetailDataActions(
: []; : [];
const shouldSaveSkuAsync = normalizedSkus.length > ASYNC_SKU_THRESHOLD; const shouldSaveSkuAsync = normalizedSkus.length > ASYNC_SKU_THRESHOLD;
const saved = await saveProductApi({ const payload = {
id: form.id, id: form.id,
storeId: storeId.value, storeId: storeId.value,
categoryId: form.categoryId, categoryId: form.categoryId,
@@ -548,38 +548,48 @@ export function createProductDetailDataActions(
specTemplateIds: [...form.specTemplateIds], specTemplateIds: [...form.specTemplateIds],
addonGroupIds: [...form.addonGroupIds], addonGroupIds: [...form.addonGroupIds],
labelIds: [...form.labelIds], labelIds: [...form.labelIds],
skus: shouldSaveSkuAsync ? undefined : normalizedSkus, skus: normalizedSkus,
comboGroups: normalizedComboGroups, comboGroups: normalizedComboGroups,
tags: [], tags: [],
}); };
if (shouldSaveSkuAsync) { if (shouldSaveSkuAsync) {
try { const asyncSaved = await saveProductAsyncApi(payload);
const createdJob = await createProductSkuSaveJobApi({ if (asyncSaved.productId) {
storeId: storeId.value, form.id = asyncSaved.productId;
productId: saved.id,
specTemplateIds: [...form.specTemplateIds],
skus: normalizedSkus,
});
message.success(
`商品基础信息已保存,${normalizedSkus.length} 条 SKU 正在后台处理`,
);
detail.value = saved;
void watchSkuSaveJobInBackground(
storeId.value,
saved.id,
createdJob.jobId,
);
} catch (error) {
console.error(error);
message.error('商品基础信息已保存,但 SKU 异步任务创建失败');
} }
} else {
message.success('商品详情已保存'); if (asyncSaved.skuJobStatus === 'queued' || asyncSaved.skuJobStatus === 'running') {
detail.value = saved; if (asyncSaved.skuJobId) {
patchForm(saved); message.success(
buildSkuRows(); asyncSaved.message ||
`商品基础信息已保存,${normalizedSkus.length} 条 SKU 正在后台处理`,
);
void watchSkuSaveJobInBackground(
storeId.value,
asyncSaved.productId || form.id,
asyncSaved.skuJobId,
);
} else {
message.warning(asyncSaved.message || 'SKU 任务已创建,请稍后刷新查看状态');
}
return;
}
if (asyncSaved.skuJobStatus === 'not_required') {
message.success(asyncSaved.message || '商品详情已保存');
return;
}
message.error(asyncSaved.message || '商品基础信息已保存,但 SKU 异步任务创建失败');
return;
} }
const saved = await saveProductApi(payload);
message.success('商品详情已保存');
detail.value = saved;
patchForm(saved);
buildSkuRows();
} catch (error) { } catch (error) {
console.error(error); console.error(error);
} finally { } finally {