本API用于上传文件到阿里云OSS,并返回外部可访问的带签名URL。支持单文件和批量文件上传。
- 基础URL:
http://localhost:8098/api/generate/pod2post - 认证方式: Token认证(可选,不传时使用default用户)
- 请求格式: multipart/form-data
- 响应格式: JSON
POST /upload-and-return-url
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| file | File | 是 | 要上传的文件(最大50MB) |
| task_id | String | 是 | 任务ID,格式:pod2post_{timestamp}_{random} |
| folder | String | 否 | 文件夹路径,默认为空 |
| token | String | 否 | 用户认证令牌 |
- 图片: .jpg, .jpeg, .png, .gif, .webp, .svg
- 文本: .txt, .md, .json
- 文档: .pdf, .doc, .docx
// 使用 FormData
const formData = new FormData();
formData.append('file', fileInput.files[0]);
formData.append('task_id', 'pod2post_1736775600_abc123');
formData.append('folder', 'images');
formData.append('token', 'your-token-here');
fetch('http://localhost:8098/api/generate/pod2post/upload-and-return-url', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => console.log(data));# 使用 curl
curl -X POST http://localhost:8098/api/generate/pod2post/upload-and-return-url \
-F "file=@/path/to/file.jpg" \
-F "task_id=pod2post_1736775600_abc123" \
-F "folder=images" \
-F "token=your-token-here"{
"code": 200,
"success": true,
"message": "文件上传成功",
"data": {
"originalName": "example.jpg",
"ossPath": "pod2post/username/pod2post_1736775600_abc123/images/2025-01-13T10-30-00-000Z_example.jpg",
"ossUrl": "https://cms-mcp.oss-cn-hangzhou.aliyuncs.com/default/default/example.jpg",
"publicUrl": "https://cms-mcp.oss-cn-hangzhou.aliyuncs.com/pod2post/username/pod2post_1736775600_abc123/images/2025-01-13T10-30-00-000Z_example.jpg?OSSAccessKeyId=LTAI5tP7iEeXDKDgc8B1GWeW&Expires=2075706161&Signature=xxx",
"size": 1024000,
"mimetype": "image/jpeg",
"uploadedAt": "2025-01-13T10:30:00.000Z",
"taskId": "pod2post_1736775600_abc123",
"folder": "images",
"username": "default",
"etag": "\"138A6C20BB6E974E47E3E588CC92D37F\""
}
}| 字段名 | 类型 | 说明 |
|---|---|---|
| originalName | String | 原始文件名 |
| ossPath | String | OSS存储路径 |
| ossUrl | String | OSS返回的基础URL |
| publicUrl | String | 带签名的可访问URL(推荐使用) |
| size | Number | 文件大小(字节) |
| mimetype | String | 文件MIME类型 |
| uploadedAt | String | 上传时间(ISO 8601格式) |
| taskId | String | 任务ID |
| folder | String | 文件夹路径 |
| username | String | 用户名 |
| etag | String | 文件ETag |
POST /batch-upload-and-return-url
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| files | File[] | 是 | 要上传的文件列表(最多20个) |
| task_id | String | 是 | 任务ID,格式:pod2post_{timestamp}_{random} |
| folder | String | 否 | 文件夹路径,默认为空 |
| token | String | 否 | 用户认证令牌 |
const formData = new FormData();
// 添加多个文件
for (let file of fileInput.files) {
formData.append('files', file);
}
formData.append('task_id', 'pod2post_1736775600_batch');
formData.append('folder', 'documents');
formData.append('token', 'your-token-here');
fetch('http://localhost:8098/api/generate/pod2post/batch-upload-and-return-url', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => console.log(data));{
"code": 200,
"success": true,
"message": "批量上传完成: 2 成功, 0 失败",
"data": {
"taskId": "pod2post_1736775600_batch",
"folder": "documents",
"username": "default",
"uploaded": [
{
"originalName": "doc1.pdf",
"ossPath": "pod2post/username/pod2post_1736775600_batch/documents/2025-01-13T10-35-00-000Z_doc1.pdf",
"ossUrl": "https://cms-mcp.oss-cn-hangzhou.aliyuncs.com/default/default/doc1.pdf",
"publicUrl": "https://cms-mcp.oss-cn-hangzhou.aliyuncs.com/pod2post/username/pod2post_1736775600_batch/documents/2025-01-13T10-35-00-000Z_doc1.pdf?OSSAccessKeyId=xxx&Expires=xxx&Signature=xxx",
"size": 2048000,
"mimetype": "application/pdf",
"uploadedAt": "2025-01-13T10:35:00.000Z"
},
{
"originalName": "doc2.jpg",
"ossPath": "pod2post/username/pod2post_1736775600_batch/documents/2025-01-13T10-35-05-000Z_doc2.jpg",
"ossUrl": "https://cms-mcp.oss-cn-hangzhou.aliyuncs.com/default/default/doc2.jpg",
"publicUrl": "https://cms-mcp.oss-cn-hangzhou.aliyuncs.com/pod2post/username/pod2post_1736775600_batch/documents/2025-01-13T10-35-05-000Z_doc2.jpg?OSSAccessKeyId=xxx&Expires=xxx&Signature=xxx",
"size": 512000,
"mimetype": "image/jpeg",
"uploadedAt": "2025-01-13T10:35:05.000Z"
}
],
"failed": []
}
}{
"code": 400,
"success": false,
"message": "参数错误: task_id 格式不正确,应为 pod2post_{timestamp}_{random}"
}{
"code": 400,
"success": false,
"message": "参数错误: 未找到上传的文件"
}{
"code": 400,
"success": false,
"message": "参数错误: 不支持的文件类型: application/octet-stream"
}{
"code": 500,
"success": false,
"message": "OSS服务初始化失败"
}{
"code": 500,
"success": false,
"message": "文件上传到OSS失败",
"error": "详细错误信息(开发环境)"
}function generateTaskId() {
const timestamp = Date.now();
const random = Math.random().toString(36).substring(2, 9);
return `pod2post_${timestamp}_${random}`;
}
// 使用示例
const taskId = generateTaskId(); // pod2post_1736775600_abc123- 单个文件最大:50MB
- 批量上传最多:20个文件
- 使用
publicUrl:这是带签名的长期有效URL(10年有效期),可以直接用于前端展示 ossUrl:作为备份或内部使用- 文件名自动添加时间戳,避免重名冲突
try {
const response = await fetch(url, {
method: 'POST',
body: formData
});
const result = await response.json();
if (result.success) {
// 使用 result.data.publicUrl
console.log('上传成功:', result.data.publicUrl);
} else {
// 处理错误
console.error('上传失败:', result.message);
}
} catch (error) {
console.error('请求失败:', error);
}<!DOCTYPE html>
<html>
<head>
<title>Pod2Post 文件上传示例</title>
</head>
<body>
<h2>单文件上传</h2>
<form id="singleUpload">
<input type="file" id="singleFile" accept=".jpg,.png,.pdf,.txt,.json">
<input type="text" id="taskId" placeholder="任务ID(可选)">
<input type="text" id="folder" placeholder="文件夹路径(可选)">
<button type="submit">上传</button>
</form>
<h2>批量上传</h2>
<form id="batchUpload">
<input type="file" id="multipleFiles" multiple accept=".jpg,.png,.pdf,.txt,.json">
<input type="text" id="batchTaskId" placeholder="任务ID(可选)">
<input type="text" id="batchFolder" placeholder="文件夹路径(可选)">
<button type="submit">批量上传</button>
</form>
<div id="result"></div>
<script>
// 生成任务ID
function generateTaskId() {
const timestamp = Date.now();
const random = Math.random().toString(36).substring(2, 9);
return `pod2post_${timestamp}_${random}`;
}
// 单文件上传
document.getElementById('singleUpload').onsubmit = async (e) => {
e.preventDefault();
const formData = new FormData();
const file = document.getElementById('singleFile').files[0];
if (!file) {
alert('请选择文件');
return;
}
formData.append('file', file);
formData.append('task_id', document.getElementById('taskId').value || generateTaskId());
formData.append('folder', document.getElementById('folder').value || '');
formData.append('token', 'your-token-here'); // 可选
try {
const response = await fetch('http://localhost:8098/api/generate/pod2post/upload-and-return-url', {
method: 'POST',
body: formData
});
const result = await response.json();
if (result.success) {
document.getElementById('result').innerHTML = `
<h3>上传成功!</h3>
<p>文件名: ${result.data.originalName}</p>
<p>访问URL: <a href="${result.data.publicUrl}" target="_blank">${result.data.publicUrl}</a></p>
<p>文件大小: ${(result.data.size / 1024).toFixed(2)} KB</p>
`;
} else {
alert('上传失败: ' + result.message);
}
} catch (error) {
alert('请求失败: ' + error.message);
}
};
// 批量上传
document.getElementById('batchUpload').onsubmit = async (e) => {
e.preventDefault();
const formData = new FormData();
const files = document.getElementById('multipleFiles').files;
if (files.length === 0) {
alert('请选择文件');
return;
}
for (let file of files) {
formData.append('files', file);
}
formData.append('task_id', document.getElementById('batchTaskId').value || generateTaskId());
formData.append('folder', document.getElementById('batchFolder').value || '');
formData.append('token', 'your-token-here'); // 可选
try {
const response = await fetch('http://localhost:8098/api/generate/pod2post/batch-upload-and-return-url', {
method: 'POST',
body: formData
});
const result = await response.json();
if (result.success) {
let html = `<h3>批量上传完成!</h3>`;
html += `<p>成功: ${result.data.uploaded.length} 个</p>`;
html += `<p>失败: ${result.data.failed.length} 个</p>`;
result.data.uploaded.forEach(file => {
html += `<div style="margin: 10px 0; padding: 10px; border: 1px solid #ccc;">`;
html += `<p>${file.originalName} - ${(file.size / 1024).toFixed(2)} KB</p>`;
html += `<p><a href="${file.publicUrl}" target="_blank">查看文件</a></p>`;
html += `</div>`;
});
document.getElementById('result').innerHTML = html;
} else {
alert('批量上传失败: ' + result.message);
}
} catch (error) {
alert('请求失败: ' + error.message);
}
};
</script>
</body>
</html>- URL有效期:返回的
publicUrl有效期为10年,基本可以认为是永久链接 - 文件命名:系统会自动在文件名前添加时间戳,避免文件名冲突
- 用户隔离:不同用户的文件存储在不同的目录中
- 文件夹路径:支持多级目录,如
images/avatar、documents/2024 - 错误处理:请务必处理各种错误情况,特别是文件类型和大小限制
POST /write-text
写入文本文件到本地,并可选择上传到OSS生成下载链接。此接口在保持原有写入功能的基础上,增加了OSS上传功能。
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| task_id | String | 是 | - | 任务ID,格式:pod2post_{timestamp}_{random} |
| filename | String | 是 | - | 文件名(带后缀) |
| content | String | 是 | - | 文本内容(最大10MB) |
| token | String | 否 | - | 用户认证令牌 |
| upload_to_oss | Boolean | 否 | true | 是否上传到OSS |
| return_oss_url | Boolean | 否 | true | 是否返回OSS下载URL |
const response = await fetch('http://localhost:8098/api/generate/pod2post/write-text', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
task_id: 'pod2post_1736775600_abc123',
filename: 'content.json',
content: JSON.stringify({ title: '测试文档', content: '这是测试内容' }),
upload_to_oss: true,
return_oss_url: true,
token: 'your-token-here'
})
});
const result = await response.json();{
"code": 200,
"success": true,
"message": "文件写入成功并已生成下载链接",
"data": {
"filename": "content.json",
"path": "/app/data/users/default/workspace/card/pod2post_1736775600_abc123/content.json",
"size": 1024,
"isNew": true,
"taskId": "pod2post_1736775600_abc123",
"username": "default",
"createdAt": "2025-01-13T10:30:00.000Z",
"modifiedAt": "2025-01-13T10:30:00.000Z",
"ossPath": "pod2post/default/pod2post_1736775600_abc123/content.json",
"ossUrl": "https://cms-mcp.oss-cn-hangzhou.aliyuncs.com/default/default/content.json",
"downloadUrl": "https://cms-mcp.oss-cn-hangzhou.aliyuncs.com/pod2post/default/pod2post_1736775600_abc123/content.json?OSSAccessKeyId=LTAI5tP7iEeXDKDgc8B1GWeW&Expires=2075706161&Signature=xxx",
"oss": {
"ossPath": "pod2post/default/pod2post_1736775600_abc123/content.json",
"ossUrl": "https://cms-mcp.oss-cn-hangzhou.aliyuncs.com/default/default/content.json",
"downloadUrl": "https://cms-mcp.oss-cn-hangzhou.aliyuncs.com/pod2post/default/pod2post_1736775600_abc123/content.json?OSSAccessKeyId=xxx&Expires=xxx&Signature=xxx",
"uploadedAt": "2025-01-13T10:30:05.000Z"
}
}
}| 字段名 | 类型 | 说明 |
|---|---|---|
| filename | String | 文件名 |
| path | String | 本地文件路径 |
| size | Number | 文件大小(字节) |
| isNew | Boolean | 是否为新文件 |
| taskId | String | 任务ID |
| username | String | 用户名 |
| downloadUrl | String | OSS下载链接(如果上传到OSS) |
| ossPath | String | OSS存储路径 |
| ossUrl | String | OSS基础URL |
| oss | Object | OSS详细信息(可选) |
-
v1.1.0 (2025-01-13)
- 新增
write-text接口的OSS上传功能 - 支持写入文本文件后自动上传到OSS
- 返回可下载的OSS链接
- 添加可选参数控制OSS上传行为
- 新增
-
v1.0.0 (2025-01-13)
- 初始版本
- 支持单文件和批量上传
- 返回带签名的长期有效OSS URL
- 支持用户隔离和自定义文件夹