promptbackend / controllers /promptGroupController.js
samlax12's picture
Upload 18 files
8dee6fc verified
const asyncHandler = require('express-async-handler');
const PromptGroup = require('../models/PromptGroup');
const logger = require('../utils/logger');
// @desc 获取所有提示词组
// @route GET /api/prompt-groups
// @access Private
const getPromptGroups = asyncHandler(async (req, res) => {
const promptGroups = await PromptGroup.find({})
.populate('category', 'name color')
.sort({ updatedAt: -1 });
res.json(promptGroups);
});
// @desc 获取单个提示词组
// @route GET /api/prompt-groups/:id
// @access Private
const getPromptGroupById = asyncHandler(async (req, res) => {
const promptGroup = await PromptGroup.findById(req.params.id)
.populate('category', 'name color');
if (promptGroup) {
res.json(promptGroup);
} else {
res.status(404);
throw new Error('提示词组未找到');
}
});
// @desc 创建提示词组
// @route POST /api/prompt-groups
// @access Private
const createPromptGroup = asyncHandler(async (req, res) => {
const { name, description, category } = req.body;
const promptGroup = await PromptGroup.create({
name,
description,
category,
prompts: [],
workflows: [],
dslFiles: [],
createdBy: req.user._id,
});
if (promptGroup) {
res.status(201).json(promptGroup);
} else {
res.status(400);
throw new Error('无效的提示词组数据');
}
});
// @desc 更新提示词组
// @route PUT /api/prompt-groups/:id
// @access Private
const updatePromptGroup = asyncHandler(async (req, res) => {
const { name, description, category } = req.body;
const promptGroup = await PromptGroup.findById(req.params.id);
if (promptGroup) {
promptGroup.name = name || promptGroup.name;
promptGroup.description = description || promptGroup.description;
promptGroup.category = category || promptGroup.category;
const updatedPromptGroup = await promptGroup.save();
res.json(updatedPromptGroup);
} else {
res.status(404);
throw new Error('提示词组未找到');
}
});
// @desc 删除提示词组
// @route DELETE /api/prompt-groups/:id
// @access Private
const deletePromptGroup = asyncHandler(async (req, res) => {
const promptGroup = await PromptGroup.findById(req.params.id);
if (promptGroup) {
await promptGroup.deleteOne();
res.json({ message: '提示词组已删除' });
} else {
res.status(404);
throw new Error('提示词组未找到');
}
});
// @desc 添加提示词到提示词组
// @route POST /api/prompt-groups/:id/prompts
// @access Private
const addPromptToGroup = asyncHandler(async (req, res) => {
const { title, content, tags } = req.body;
const promptGroup = await PromptGroup.findById(req.params.id);
if (promptGroup) {
const newPrompt = {
title,
content,
tags: tags || [],
createdAt: new Date(),
updatedAt: new Date(),
};
promptGroup.prompts.push(newPrompt);
promptGroup.updatedAt = new Date();
const updatedPromptGroup = await promptGroup.save();
res.status(201).json(updatedPromptGroup.prompts[updatedPromptGroup.prompts.length - 1]);
} else {
res.status(404);
throw new Error('提示词组未找到');
}
});
// @desc 更新提示词
// @route PUT /api/prompt-groups/:id/prompts/:promptId
// @access Private
const updatePrompt = asyncHandler(async (req, res) => {
const { title, content, tags } = req.body;
const promptGroup = await PromptGroup.findById(req.params.id);
if (promptGroup) {
const promptIndex = promptGroup.prompts.findIndex(
(p) => p._id.toString() === req.params.promptId
);
if (promptIndex !== -1) {
promptGroup.prompts[promptIndex].title = title || promptGroup.prompts[promptIndex].title;
promptGroup.prompts[promptIndex].content = content || promptGroup.prompts[promptIndex].content;
promptGroup.prompts[promptIndex].tags = tags || promptGroup.prompts[promptIndex].tags;
promptGroup.prompts[promptIndex].updatedAt = new Date();
promptGroup.updatedAt = new Date();
const updatedPromptGroup = await promptGroup.save();
res.json(updatedPromptGroup.prompts[promptIndex]);
} else {
res.status(404);
throw new Error('提示词未找到');
}
} else {
res.status(404);
throw new Error('提示词组未找到');
}
});
// @desc 删除提示词
// @route DELETE /api/prompt-groups/:id/prompts/:promptId
// @access Private
const deletePrompt = asyncHandler(async (req, res) => {
const promptGroup = await PromptGroup.findById(req.params.id);
if (promptGroup) {
const promptExists = promptGroup.prompts.some(
(p) => p._id.toString() === req.params.promptId
);
if (promptExists) {
promptGroup.prompts = promptGroup.prompts.filter(
(p) => p._id.toString() !== req.params.promptId
);
promptGroup.updatedAt = new Date();
await promptGroup.save();
res.json({ message: '提示词已删除' });
} else {
res.status(404);
throw new Error('提示词未找到');
}
} else {
res.status(404);
throw new Error('提示词组未找到');
}
});
// @desc 添加DSL文件到提示词组 - 修改为支持文本内容
// @route POST /api/prompt-groups/:id/dsl-files
// @access Private
const addDslFileToGroup = asyncHandler(async (req, res) => {
try {
const { name, content, fileData, mimeType } = req.body;
logger.info(`正在添加DSL文件: ${name}`);
// 验证请求数据
if (!name) {
res.status(400);
throw new Error('文件名是必需的');
}
// 确保至少提供了文本内容或文件数据中的一个
if (!content && !fileData) {
res.status(400);
throw new Error('请提供YAML内容或上传文件');
}
const promptGroup = await PromptGroup.findById(req.params.id);
if (!promptGroup) {
res.status(404);
throw new Error('提示词组未找到');
}
// 确保文件名以 .yml 结尾
let fileName = name;
if (!fileName.toLowerCase().endsWith('.yml')) {
fileName = fileName.replace(/\.[^/.]+$/, '') + '.yml';
}
// 处理内容: 优先使用提供的内容,如果没有则尝试解码文件数据
let yamlContent = content;
// 如果提供了fileData但没有提供content,尝试将fileData转换为文本
if (!yamlContent && fileData) {
try {
// 尝试将Base64解码为文本
const buffer = Buffer.from(fileData, 'base64');
yamlContent = buffer.toString('utf-8');
logger.info(`成功从文件数据提取YAML内容`);
} catch (error) {
logger.error(`从文件数据提取内容失败: ${error.message}`);
res.status(400);
throw new Error('无法从上传的文件中提取内容');
}
}
const newDslFile = {
name: fileName,
content: yamlContent,
mimeType: mimeType || 'application/x-yaml',
uploadedAt: new Date(),
};
promptGroup.dslFiles.push(newDslFile);
promptGroup.updatedAt = new Date();
const updatedPromptGroup = await promptGroup.save();
logger.info(`DSL文件添加成功: ${fileName}`);
res.status(201).json(updatedPromptGroup.dslFiles[updatedPromptGroup.dslFiles.length - 1]);
} catch (error) {
logger.error(`添加DSL文件时出错: ${error.message}`);
if (!res.statusCode || res.statusCode === 200) {
res.status(500);
}
throw error;
}
});
// @desc 更新DSL文件
// @route PUT /api/prompt-groups/:id/dsl-files/:fileId
// @access Private
const updateDslFile = asyncHandler(async (req, res) => {
try {
const { name, content } = req.body;
if (!name && !content) {
res.status(400);
throw new Error('请提供要更新的文件名或内容');
}
const promptGroup = await PromptGroup.findById(req.params.id);
if (!promptGroup) {
res.status(404);
throw new Error('提示词组未找到');
}
const fileIndex = promptGroup.dslFiles.findIndex(
file => file._id.toString() === req.params.fileId
);
if (fileIndex === -1) {
res.status(404);
throw new Error('DSL文件未找到');
}
// 更新文件名 - 确保以.yml结尾
if (name) {
let updatedName = name;
if (!updatedName.toLowerCase().endsWith('.yml')) {
updatedName = updatedName.replace(/\.[^/.]+$/, '') + '.yml';
}
promptGroup.dslFiles[fileIndex].name = updatedName;
}
// 更新内容
if (content) {
promptGroup.dslFiles[fileIndex].content = content;
}
// 更新时间戳
promptGroup.dslFiles[fileIndex].uploadedAt = new Date();
promptGroup.updatedAt = new Date();
const updatedPromptGroup = await promptGroup.save();
logger.info(`DSL文件更新成功: ${promptGroup.dslFiles[fileIndex].name}`);
res.status(200).json(updatedPromptGroup.dslFiles[fileIndex]);
} catch (error) {
logger.error(`更新DSL文件时出错: ${error.message}`);
if (!res.statusCode || res.statusCode === 200) {
res.status(500);
}
throw error;
}
});
// @desc 删除DSL文件
// @route DELETE /api/prompt-groups/:id/dsl-files/:fileId
// @access Private
const deleteDslFile = asyncHandler(async (req, res) => {
const promptGroup = await PromptGroup.findById(req.params.id);
if (promptGroup) {
const fileExists = promptGroup.dslFiles.some(
(f) => f._id.toString() === req.params.fileId
);
if (fileExists) {
promptGroup.dslFiles = promptGroup.dslFiles.filter(
(f) => f._id.toString() !== req.params.fileId
);
promptGroup.updatedAt = new Date();
await promptGroup.save();
res.json({ message: 'DSL文件已删除' });
} else {
res.status(404);
throw new Error('DSL文件未找到');
}
} else {
res.status(404);
throw new Error('提示词组未找到');
}
});
module.exports = {
getPromptGroups,
getPromptGroupById,
createPromptGroup,
updatePromptGroup,
deletePromptGroup,
addPromptToGroup,
updatePrompt,
deletePrompt,
addDslFileToGroup,
updateDslFile,
deleteDslFile,
};