Files
ai-scoring-application/app/api/criteria-templates/route.ts

127 lines
4.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { NextRequest, NextResponse } from 'next/server';
import { CriteriaTemplateService, CriteriaItemService } from '@/lib/services/database';
// GET - 獲取所有評分標準模板
export async function GET() {
try {
// 這裡暫時使用 user_id = 1實際應用中應該從 session 獲取
const templates = await CriteriaTemplateService.findByUserId(1);
// 獲取每個模板的評分項目
const templatesWithItems = await Promise.all(
templates.map(async (template) => {
const items = await CriteriaItemService.findByTemplateId(template.id);
return { ...template, items };
})
);
return NextResponse.json({
success: true,
data: templatesWithItems
});
} catch (error) {
console.error('獲取評分標準模板失敗:', error);
return NextResponse.json(
{ success: false, error: '獲取評分標準模板失敗' },
{ status: 500 }
);
}
}
// POST - 創建或更新評分標準模板(單一模板模式)
export async function POST(request: NextRequest) {
try {
const body = await request.json();
const { name, description, items } = body;
if (!name || !items || !Array.isArray(items)) {
return NextResponse.json(
{ success: false, error: '請提供模板名稱和評分項目' },
{ status: 400 }
);
}
// 驗證權重總和
const totalWeight = items.reduce((sum: number, item: any) => sum + (Number(item.weight) || 0), 0);
if (Math.abs(totalWeight - 100) > 0.01) {
return NextResponse.json(
{ success: false, error: '權重總和必須等於 100%' },
{ status: 400 }
);
}
// 驗證所有項目都有名稱
if (items.some((item: any) => !item.name?.trim())) {
return NextResponse.json(
{ success: false, error: '所有評分項目都必須有名稱' },
{ status: 400 }
);
}
// 使用事務創建或更新模板
const { transaction } = await import('@/lib/database');
const result = await transaction(async (connection) => {
// 檢查是否已存在模板
const [existingTemplates] = await connection.execute(
'SELECT id FROM criteria_templates WHERE user_id = ? LIMIT 1',
[1]
);
let templateId;
if (existingTemplates.length > 0) {
// 更新現有模板
templateId = existingTemplates[0].id;
await connection.execute(
'UPDATE criteria_templates SET name = ?, description = ?, total_weight = ?, updated_at = NOW() WHERE id = ?',
[name, description || '', totalWeight, templateId]
);
// 刪除舊的評分項目
await connection.execute(
'DELETE FROM criteria_items WHERE template_id = ?',
[templateId]
);
} else {
// 創建新模板
const [templateResult] = await connection.execute(
'INSERT INTO criteria_templates (user_id, name, description, is_default, is_public, total_weight) VALUES (?, ?, ?, ?, ?, ?)',
[1, name, description || '', 1, 1, totalWeight]
);
templateId = (templateResult as any).insertId;
}
// 創建評分項目
for (let i = 0; i < items.length; i++) {
const item = items[i];
await connection.execute(
'INSERT INTO criteria_items (template_id, name, description, weight, max_score, sort_order) VALUES (?, ?, ?, ?, ?, ?)',
[
templateId,
item.name,
item.description || '',
Number(item.weight) || 0,
Number(item.maxScore) || 10,
i + 1
]
);
}
return templateId;
});
return NextResponse.json({
success: true,
data: { id: result },
message: '評分標準模板儲存成功'
});
} catch (error) {
console.error('儲存評分標準模板失敗:', error);
return NextResponse.json(
{ success: false, error: '儲存評分標準模板失敗' },
{ status: 500 }
);
}
}