feat(store): 门店套餐 v3.4.10 全端实现
新增 StorePackage 与变更审核流,覆盖总部直存、合伙/门店提审、C 端展示与套餐异议工单;同步 PRD/开发文档与 REQ 索引。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
import type { StorePackageItemDto } from '@dukang/shared-types';
|
||||
import { STORE_PACKAGE_MAX_COUNT } from '@dukang/shared-types';
|
||||
|
||||
export type PackageFormItem = StorePackageItemDto;
|
||||
|
||||
export function emptyPackage(index = 0): PackageFormItem {
|
||||
return {
|
||||
name: '',
|
||||
price: '',
|
||||
dishes: '',
|
||||
usableTime: '',
|
||||
otherNotes: '',
|
||||
sortOrder: index,
|
||||
};
|
||||
}
|
||||
|
||||
export function normalizePackageFormItems(raw: PackageFormItem[]): PackageFormItem[] {
|
||||
return raw
|
||||
.map((item, index) => ({
|
||||
name: item.name.trim(),
|
||||
price: item.price.trim(),
|
||||
dishes: item.dishes.trim(),
|
||||
usableTime: item.usableTime?.trim() || '',
|
||||
otherNotes: item.otherNotes?.trim() || '',
|
||||
sortOrder: index,
|
||||
}))
|
||||
.filter((item) => item.name || item.price || item.dishes || item.usableTime || item.otherNotes);
|
||||
}
|
||||
|
||||
export function validatePackageFormItems(items: PackageFormItem[]): string | null {
|
||||
const filled = normalizePackageFormItems(items);
|
||||
if (filled.length > STORE_PACKAGE_MAX_COUNT) {
|
||||
return `套餐最多 ${STORE_PACKAGE_MAX_COUNT} 条`;
|
||||
}
|
||||
for (let i = 0; i < filled.length; i++) {
|
||||
const item = filled[i];
|
||||
if (!item.name) return `第 ${i + 1} 条套餐名称不能为空`;
|
||||
const price = Number(item.price);
|
||||
if (!Number.isFinite(price) || price < 0) return `第 ${i + 1} 条套餐价格须为非负数字`;
|
||||
if (!item.dishes) return `第 ${i + 1} 条套餐菜品不能为空`;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
Reference in New Issue
Block a user