first-update
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import logger from '@/lib/util/logger';
|
||||
import cleanService from '@/lib/services/clean';
|
||||
|
||||
// 为指定文本块进行数据清洗
|
||||
export async function POST(request, { params }) {
|
||||
try {
|
||||
const { projectId, chunkId } = params;
|
||||
|
||||
// 验证项目ID和文本块ID
|
||||
if (!projectId || !chunkId) {
|
||||
return NextResponse.json({ error: 'Project ID or text block ID cannot be empty' }, { status: 400 });
|
||||
}
|
||||
|
||||
// 获取请求体
|
||||
const { model, language = '中文' } = await request.json();
|
||||
|
||||
if (!model) {
|
||||
return NextResponse.json({ error: 'Model cannot be empty' }, { status: 400 });
|
||||
}
|
||||
|
||||
// 使用数据清洗服务
|
||||
const result = await cleanService.cleanDataForChunk(projectId, chunkId, {
|
||||
model,
|
||||
language
|
||||
});
|
||||
|
||||
// 返回清洗结果
|
||||
return NextResponse.json({
|
||||
chunkId,
|
||||
originalLength: result.originalLength,
|
||||
cleanedLength: result.cleanedLength,
|
||||
success: result.success,
|
||||
message: '数据清洗完成'
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Error cleaning data:', error);
|
||||
return NextResponse.json({ error: error.message || 'Error cleaning data' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { generateEvalQuestionsForChunk } from '@/lib/services/eval';
|
||||
import logger from '@/lib/util/logger';
|
||||
|
||||
/**
|
||||
* 为指定文本块生成测评题目
|
||||
*/
|
||||
export async function POST(request, { params }) {
|
||||
try {
|
||||
const { projectId, chunkId } = params;
|
||||
|
||||
// 验证参数
|
||||
if (!projectId || !chunkId) {
|
||||
return NextResponse.json({ error: 'Project ID and Chunk ID are required' }, { status: 400 });
|
||||
}
|
||||
|
||||
// 获取请求体
|
||||
const { model, language = 'zh-CN' } = await request.json();
|
||||
|
||||
if (!model) {
|
||||
return NextResponse.json({ error: 'Model configuration is required' }, { status: 400 });
|
||||
}
|
||||
|
||||
// 调用服务层生成测评题目
|
||||
const result = await generateEvalQuestionsForChunk(projectId, chunkId, {
|
||||
model,
|
||||
language
|
||||
});
|
||||
|
||||
return NextResponse.json(result);
|
||||
} catch (error) {
|
||||
logger.error('Error generating eval questions:', error);
|
||||
return NextResponse.json({ error: error.message || 'Failed to generate eval questions' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { getQuestionsForChunk } from '@/lib/db/questions';
|
||||
import logger from '@/lib/util/logger';
|
||||
import questionService from '@/lib/services/questions';
|
||||
|
||||
// 为指定文本块生成问题
|
||||
export async function POST(request, { params }) {
|
||||
try {
|
||||
const { projectId, chunkId } = params;
|
||||
|
||||
// 验证项目ID和文本块ID
|
||||
if (!projectId || !chunkId) {
|
||||
return NextResponse.json({ error: 'Project ID or text block ID cannot be empty' }, { status: 400 });
|
||||
} // 获取请求体
|
||||
const { model, language = '中文', number, enableGaExpansion = false } = await request.json();
|
||||
|
||||
if (!model) {
|
||||
return NextResponse.json({ error: 'Model cannot be empty' }, { status: 400 });
|
||||
}
|
||||
|
||||
// 后续会根据是否有GA对来选择是否启用GA扩展选择服务函数
|
||||
const serviceFunc = questionService.generateQuestionsForChunkWithGA;
|
||||
|
||||
// 使用问题生成服务
|
||||
const result = await serviceFunc(projectId, chunkId, {
|
||||
model,
|
||||
language,
|
||||
number,
|
||||
enableGaExpansion
|
||||
});
|
||||
|
||||
// 统一返回格式,确保包含GA扩展信息
|
||||
const response = {
|
||||
chunkId,
|
||||
questions: result.questions || result.labelQuestions || [],
|
||||
total: result.total || (result.questions || result.labelQuestions || []).length,
|
||||
gaExpansionUsed: result.gaExpansionUsed || false,
|
||||
gaPairsCount: result.gaPairsCount || 0,
|
||||
expectedTotal: result.expectedTotal || result.total
|
||||
};
|
||||
|
||||
// 返回生成的问题
|
||||
return NextResponse.json(response);
|
||||
} catch (error) {
|
||||
logger.error('Error generating questions:', error);
|
||||
return NextResponse.json({ error: error.message || 'Error generating questions' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
// 获取指定文本块的问题
|
||||
export async function GET(request, { params }) {
|
||||
try {
|
||||
const { projectId, chunkId } = params;
|
||||
|
||||
// 验证项目ID和文本块ID
|
||||
if (!projectId || !chunkId) {
|
||||
return NextResponse.json({ error: 'The item ID or text block ID cannot be empty' }, { status: 400 });
|
||||
}
|
||||
|
||||
// 获取文本块的问题
|
||||
const questions = await getQuestionsForChunk(projectId, chunkId);
|
||||
|
||||
// 返回问题列表
|
||||
return NextResponse.json({
|
||||
chunkId,
|
||||
questions,
|
||||
total: questions.length
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error getting questions:', String(error));
|
||||
return NextResponse.json({ error: error.message || 'Error getting questions' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { deleteChunkById, getChunkById, updateChunkById } from '@/lib/db/chunks';
|
||||
|
||||
// 获取文本块内容
|
||||
export async function GET(request, { params }) {
|
||||
try {
|
||||
const { projectId, chunkId } = params;
|
||||
// 验证参数
|
||||
if (!projectId) {
|
||||
return NextResponse.json({ error: 'Project ID cannot be empty' }, { status: 400 });
|
||||
}
|
||||
if (!chunkId) {
|
||||
return NextResponse.json({ error: 'Text block ID cannot be empty' }, { status: 400 });
|
||||
}
|
||||
// 获取文本块内容
|
||||
const chunk = await getChunkById(chunkId);
|
||||
|
||||
return NextResponse.json(chunk);
|
||||
} catch (error) {
|
||||
console.error('Failed to get text block content:', String(error));
|
||||
return NextResponse.json({ error: error.message || 'Failed to get text block content' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
// 删除文本块
|
||||
export async function DELETE(request, { params }) {
|
||||
try {
|
||||
const { projectId, chunkId } = params;
|
||||
// 验证参数
|
||||
if (!projectId) {
|
||||
return NextResponse.json({ error: 'Project ID cannot be empty' }, { status: 400 });
|
||||
}
|
||||
if (!chunkId) {
|
||||
return NextResponse.json({ error: 'Text block ID cannot be empty' }, { status: 400 });
|
||||
}
|
||||
await deleteChunkById(chunkId);
|
||||
|
||||
return NextResponse.json({ message: 'Text block deleted successfully' });
|
||||
} catch (error) {
|
||||
console.error('Failed to delete text block:', String(error));
|
||||
return NextResponse.json({ error: error.message || 'Failed to delete text block' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
// 编辑文本块内容
|
||||
export async function PATCH(request, { params }) {
|
||||
try {
|
||||
const { projectId, chunkId } = params;
|
||||
|
||||
// 验证参数
|
||||
if (!projectId) {
|
||||
return NextResponse.json({ error: '项目ID不能为空' }, { status: 400 });
|
||||
}
|
||||
|
||||
if (!chunkId) {
|
||||
return NextResponse.json({ error: '文本块ID不能为空' }, { status: 400 });
|
||||
}
|
||||
|
||||
// 解析请求体获取新内容
|
||||
const requestData = await request.json();
|
||||
const { content } = requestData;
|
||||
|
||||
if (!content) {
|
||||
return NextResponse.json({ error: '内容不能为空' }, { status: 400 });
|
||||
}
|
||||
|
||||
let res = await updateChunkById(chunkId, { content });
|
||||
return NextResponse.json(res);
|
||||
} catch (error) {
|
||||
console.error('编辑文本块失败:', String(error));
|
||||
return NextResponse.json({ error: error.message || '编辑文本块失败' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { getChunkContentsByNames } from '@/lib/db/chunks';
|
||||
import { NextResponse } from 'next/server';
|
||||
|
||||
export async function POST(request, { params }) {
|
||||
try {
|
||||
const { projectId } = params;
|
||||
const { chunkNames } = await request.json();
|
||||
|
||||
if (!chunkNames || !Array.isArray(chunkNames)) {
|
||||
return NextResponse.json({ error: 'chunkNames 参数必须是数组' }, { status: 400 });
|
||||
}
|
||||
|
||||
const chunkContentMap = await getChunkContentsByNames(projectId, chunkNames);
|
||||
|
||||
return NextResponse.json(chunkContentMap);
|
||||
} catch (error) {
|
||||
console.error('批量获取文本块内容失败:', error);
|
||||
return NextResponse.json({ error: '批量获取文本块内容失败' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
/**
|
||||
* 批量编辑文本块内容
|
||||
* POST /api/projects/[projectId]/chunks/batch-edit
|
||||
*/
|
||||
export async function POST(request, { params }) {
|
||||
try {
|
||||
const { projectId } = params;
|
||||
const body = await request.json();
|
||||
const { position, content, chunkIds } = body;
|
||||
|
||||
// 验证参数
|
||||
if (!position || !content || !chunkIds || !Array.isArray(chunkIds) || chunkIds.length === 0) {
|
||||
return NextResponse.json({ error: 'Missing required parameters: position, content, chunkIds' }, { status: 400 });
|
||||
}
|
||||
|
||||
if (!['start', 'end'].includes(position)) {
|
||||
return NextResponse.json({ error: 'Position must be "start" or "end"' }, { status: 400 });
|
||||
}
|
||||
|
||||
// 验证项目权限(获取要编辑的文本块)
|
||||
const chunksToUpdate = await prisma.chunks.findMany({
|
||||
where: {
|
||||
id: { in: chunkIds },
|
||||
projectId: projectId
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
content: true,
|
||||
name: true
|
||||
}
|
||||
});
|
||||
|
||||
if (chunksToUpdate.length === 0) {
|
||||
return NextResponse.json({ error: 'Not found' }, { status: 404 });
|
||||
}
|
||||
|
||||
if (chunksToUpdate.length !== chunkIds.length) {
|
||||
return NextResponse.json({ error: 'Some chunks not found' }, { status: 400 });
|
||||
}
|
||||
|
||||
// 准备更新数据
|
||||
const updates = chunksToUpdate.map(chunk => {
|
||||
let newContent;
|
||||
|
||||
if (position === 'start') {
|
||||
// 在开头添加内容
|
||||
newContent = content + '\n\n' + chunk.content;
|
||||
} else {
|
||||
// 在结尾添加内容
|
||||
newContent = chunk.content + '\n\n' + content;
|
||||
}
|
||||
|
||||
return {
|
||||
where: { id: chunk.id },
|
||||
data: {
|
||||
content: newContent,
|
||||
size: newContent.length,
|
||||
updateAt: new Date()
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
async function processBatches(items, batchSize, processFn) {
|
||||
const results = [];
|
||||
for (let i = 0; i < items.length; i += batchSize) {
|
||||
const batch = items.slice(i, i + batchSize);
|
||||
const batchResults = await Promise.all(batch.map(processFn));
|
||||
results.push(...batchResults);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
const BATCH_SIZE = 50; // 每批处理 50 个
|
||||
await processBatches(updates, BATCH_SIZE, update => prisma.chunks.update(update));
|
||||
|
||||
// 记录操作日志(可选)
|
||||
console.log(`Successfully updated ${chunksToUpdate.length} chunks`);
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
updatedCount: chunksToUpdate.length,
|
||||
message: `Successfully updated ${chunksToUpdate.length} chunks`
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('批量编辑文本块失败:', error);
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: 'Batch edit chunks failed',
|
||||
details: error.message
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
} finally {
|
||||
await prisma.$disconnect();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { getChunkByName } from '@/lib/db/chunks';
|
||||
|
||||
/**
|
||||
* 根据文本块名称获取文本块
|
||||
* @param {Request} request 请求对象
|
||||
* @param {object} context 上下文,包含路径参数
|
||||
* @returns {Promise<NextResponse>} 响应对象
|
||||
*/
|
||||
export async function GET(request, { params }) {
|
||||
try {
|
||||
const { projectId } = params;
|
||||
|
||||
// 从查询参数中获取 chunkName
|
||||
const { searchParams } = new URL(request.url);
|
||||
const chunkName = searchParams.get('chunkName');
|
||||
|
||||
if (!chunkName) {
|
||||
return NextResponse.json({ error: '文本块名称不能为空' }, { status: 400 });
|
||||
}
|
||||
|
||||
// 根据名称和项目ID查询文本块
|
||||
const chunk = await getChunkByName(projectId, chunkName);
|
||||
|
||||
if (!chunk) {
|
||||
return NextResponse.json({ error: '未找到指定的文本块' }, { status: 404 });
|
||||
}
|
||||
|
||||
// 返回文本块信息
|
||||
return NextResponse.json(chunk);
|
||||
} catch (error) {
|
||||
console.error('根据名称获取文本块失败:', String(error));
|
||||
return NextResponse.json({ error: '获取文本块失败: ' + error.message }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { deleteChunkById, getChunkByFileIds, getChunkById, getChunksByFileIds, updateChunkById } from '@/lib/db/chunks';
|
||||
|
||||
// 获取文本块内容
|
||||
export async function POST(request, { params }) {
|
||||
try {
|
||||
const { projectId } = params;
|
||||
// 验证参数
|
||||
if (!projectId) {
|
||||
return NextResponse.json({ error: 'Project ID cannot be empty' }, { status: 400 });
|
||||
}
|
||||
const { array } = await request.json();
|
||||
// 获取文本块内容
|
||||
const chunk = await getChunksByFileIds(array);
|
||||
|
||||
return NextResponse.json(chunk);
|
||||
} catch (error) {
|
||||
console.error('Failed to get text block content:', String(error));
|
||||
return NextResponse.json({ error: String(error) || 'Failed to get text block content' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user