feat: 商品详情大SKU改为单接口异步提交
All checks were successful
Build and Deploy TenantUI / build-and-deploy (push) Successful in 53s
All checks were successful
Build and Deploy TenantUI / build-and-deploy (push) Successful in 53s
This commit is contained in:
@@ -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,
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user