Compare commits
1 Commits
bc83044afb
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 76ba61d5bb |
+31
-28
@@ -42,19 +42,19 @@ interface WeeklyMenu {
|
|||||||
|
|
||||||
// 餐食类型配置
|
// 餐食类型配置
|
||||||
const MEAL_TYPES = [
|
const MEAL_TYPES = [
|
||||||
{ code: MealTypeCode.BREAKFAST, label: "早餐" },
|
{code: MealTypeCode.BREAKFAST, label: "早餐"},
|
||||||
{ code: MealTypeCode.FRUIT, label: "早点/水果餐" },
|
{code: MealTypeCode.FRUIT, label: "早点/水果餐"},
|
||||||
{ code: MealTypeCode.LUNCH, label: "中餐" },
|
{code: MealTypeCode.LUNCH, label: "中餐"},
|
||||||
{ code: MealTypeCode.SPECIAL, label: "体弱儿餐" },
|
{code: MealTypeCode.SPECIAL, label: "体弱儿餐"},
|
||||||
{ code: MealTypeCode.SNACK, label: "午点" },
|
{code: MealTypeCode.SNACK, label: "午点"},
|
||||||
];
|
];
|
||||||
|
|
||||||
const WEEK_DAYS = [
|
const WEEK_DAYS = [
|
||||||
{ code: 1, label: "周一" },
|
{code: 1, label: "周一"},
|
||||||
{ code: 2, label: "周二" },
|
{code: 2, label: "周二"},
|
||||||
{ code: 3, label: "周三" },
|
{code: 3, label: "周三"},
|
||||||
{ code: 4, label: "周四" },
|
{code: 4, label: "周四"},
|
||||||
{ code: 5, label: "周五" },
|
{code: 5, label: "周五"},
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -128,11 +128,14 @@ function splitCellContent(content: string): string[] {
|
|||||||
* 确定餐食类型
|
* 确定餐食类型
|
||||||
*/
|
*/
|
||||||
function getMealType(mealName: string): MealTypeCode | null {
|
function getMealType(mealName: string): MealTypeCode | null {
|
||||||
if (mealName.includes("早") && !mealName.includes("早点")) return MealTypeCode.BREAKFAST;
|
const header = mealName.trim();
|
||||||
if (mealName.includes("水果") || mealName.includes("早点")) return MealTypeCode.FRUIT;
|
|
||||||
if (mealName.includes("中") || mealName.includes("午餐")) return MealTypeCode.LUNCH;
|
if (header.includes("早餐") || header.includes("早 餐")) return MealTypeCode.BREAKFAST;
|
||||||
if (mealName.includes("午点") || mealName.includes("点心")) return MealTypeCode.SNACK;
|
if (header.includes("早点") || header.includes("水果餐") || header.includes("早 点") || header.includes("早点/水果餐")) return MealTypeCode.FRUIT;
|
||||||
if (mealName.includes("体弱") || mealName.includes("晚")) return MealTypeCode.SPECIAL;
|
if (header.includes("中餐") || header.includes("中 餐")) return MealTypeCode.LUNCH;
|
||||||
|
if (header.includes("午点") || header.includes("午 点")) return MealTypeCode.SNACK;
|
||||||
|
if (header.includes("体弱儿餐") || header.includes("体弱儿")) return MealTypeCode.SPECIAL;
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,7 +181,7 @@ function transformTableToWeeklyMenu(tableData: string[][][]): WeeklyMenu {
|
|||||||
mealCode: mealType,
|
mealCode: mealType,
|
||||||
dishList: mealItems.map((item, idx) => ({
|
dishList: mealItems.map((item, idx) => ({
|
||||||
id: `${dayIndex + 1}-${mealType}-${idx + 1}`,
|
id: `${dayIndex + 1}-${mealType}-${idx + 1}`,
|
||||||
name: { zh: item },
|
name: {zh: item},
|
||||||
})),
|
})),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -191,7 +194,7 @@ function transformTableToWeeklyMenu(tableData: string[][][]): WeeklyMenu {
|
|||||||
(m) => m.dayCode === day.code && m.mealCode === meal.code
|
(m) => m.dayCode === day.code && m.mealCode === meal.code
|
||||||
);
|
);
|
||||||
if (!exists) {
|
if (!exists) {
|
||||||
meals.push({ dayCode: day.code, mealCode: meal.code, dishList: [] });
|
meals.push({dayCode: day.code, mealCode: meal.code, dishList: []});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -199,16 +202,16 @@ function transformTableToWeeklyMenu(tableData: string[][][]): WeeklyMenu {
|
|||||||
// 构建 days 数组,使用实际解析出的星期
|
// 构建 days 数组,使用实际解析出的星期
|
||||||
const days = weekdays
|
const days = weekdays
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.map((name, index) => ({ code: index + 1, name: { zh: name } }));
|
.map((name, index) => ({code: index + 1, name: {zh: name}}));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
menuId: `menu-${Date.now()}`,
|
menuId: `menu-${Date.now()}`,
|
||||||
weekNumber: "",
|
weekNumber: "",
|
||||||
title: { zh: "食谱", en: "Recipe" },
|
title: {zh: "食谱", en: "Recipe"},
|
||||||
days: days,
|
days: days,
|
||||||
mealCategories: MEAL_TYPES.map((m, i) => ({
|
mealCategories: MEAL_TYPES.map((m, i) => ({
|
||||||
code: m.code,
|
code: m.code,
|
||||||
name: { zh: m.label },
|
name: {zh: m.label},
|
||||||
sort: i + 1,
|
sort: i + 1,
|
||||||
})),
|
})),
|
||||||
meals: meals.sort((a, b) => {
|
meals: meals.sort((a, b) => {
|
||||||
@@ -229,11 +232,11 @@ function createEmptyMenu(): WeeklyMenu {
|
|||||||
return {
|
return {
|
||||||
menuId: `menu-${Date.now()}`,
|
menuId: `menu-${Date.now()}`,
|
||||||
weekNumber: "",
|
weekNumber: "",
|
||||||
title: { zh: "食谱", en: "Recipe" },
|
title: {zh: "食谱", en: "Recipe"},
|
||||||
days: WEEK_DAYS.map((d) => ({ code: d.code, name: { zh: d.label } })),
|
days: WEEK_DAYS.map((d) => ({code: d.code, name: {zh: d.label}})),
|
||||||
mealCategories: MEAL_TYPES.map((m, i) => ({
|
mealCategories: MEAL_TYPES.map((m, i) => ({
|
||||||
code: m.code,
|
code: m.code,
|
||||||
name: { zh: m.label },
|
name: {zh: m.label},
|
||||||
sort: i + 1,
|
sort: i + 1,
|
||||||
})),
|
})),
|
||||||
meals: [],
|
meals: [],
|
||||||
@@ -246,11 +249,11 @@ export async function POST(request: NextRequest) {
|
|||||||
const file = formData.get("file") as File | null;
|
const file = formData.get("file") as File | null;
|
||||||
|
|
||||||
if (!file) {
|
if (!file) {
|
||||||
return NextResponse.json({ error: "未上传文件" }, { status: 400 });
|
return NextResponse.json({error: "未上传文件"}, {status: 400});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!file.name.endsWith(".docx")) {
|
if (!file.name.endsWith(".docx")) {
|
||||||
return NextResponse.json({ error: "仅支持 .docx 格式" }, { status: 400 });
|
return NextResponse.json({error: "仅支持 .docx 格式"}, {status: 400});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 读取文件为 ArrayBuffer
|
// 读取文件为 ArrayBuffer
|
||||||
@@ -258,7 +261,7 @@ export async function POST(request: NextRequest) {
|
|||||||
const buffer = Buffer.from(arrayBuffer);
|
const buffer = Buffer.from(arrayBuffer);
|
||||||
|
|
||||||
// 使用 mammoth 转换为 HTML(保留表格结构)
|
// 使用 mammoth 转换为 HTML(保留表格结构)
|
||||||
const { value: htmlContent } = await mammoth.convertToHtml({ buffer });
|
const {value: htmlContent} = await mammoth.convertToHtml({buffer});
|
||||||
|
|
||||||
// 使用 cheerio 提取表格数据
|
// 使用 cheerio 提取表格数据
|
||||||
const tableData = extractRawDataFromHtml(htmlContent);
|
const tableData = extractRawDataFromHtml(htmlContent);
|
||||||
@@ -273,8 +276,8 @@ export async function POST(request: NextRequest) {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Parse error:", error);
|
console.error("Parse error:", error);
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{ error: "文件解析失败", details: String(error) },
|
{error: "文件解析失败", details: String(error)},
|
||||||
{ status: 500 }
|
{status: 500}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
allowBuilds:
|
||||||
|
msw: true
|
||||||
|
sharp: true
|
||||||
|
unrs-resolver: true
|
||||||
ignoredBuiltDependencies:
|
ignoredBuiltDependencies:
|
||||||
- sharp
|
- sharp
|
||||||
- unrs-resolver
|
- unrs-resolver
|
||||||
|
|||||||
Reference in New Issue
Block a user