9.0 KiB
9.0 KiB
详情图集功能使用指南
🎯 功能概述
详情图集功能允许为工作流和课程添加多张详情展示图片,为用户提供更丰富的视觉内容介绍。
🔧 技术实现
数据库字段
-- 工作流表
ALTER TABLE workflow ADD COLUMN detail_gallery longtext DEFAULT NULL
COMMENT '详情图集(JSON格式存储多张图片URL)';
-- 课程表
ALTER TABLE course ADD COLUMN detail_gallery longtext DEFAULT NULL
COMMENT '详情图集(JSON格式存储多张图片URL)';
存储格式
// 详情图集字段存储格式
"detailGallery": "[\"https://oss.../image1.jpg\",\"https://oss.../image2.jpg\",\"https://oss.../image3.jpg\"]"
📱 前端集成
1. 图片上传流程
/**
* 上传详情图集
* @param {FileList} files - 选择的图片文件
* @param {string} userId - 用户ID
* @returns {Promise<string>} 详情图集JSON字符串
*/
async function uploadDetailGallery(files, userId) {
const uploadPromises = Array.from(files).map(async (file) => {
// 1. 获取OSS上传签名
const signResponse = await fetch('/user/oss/post-signature/json', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
fileName: file.name,
userId: userId
})
});
if (!signResponse.ok) {
throw new Error('获取上传签名失败');
}
const signResult = await signResponse.json();
const signData = signResult.data;
// 2. 构建上传表单
const formData = new FormData();
const objectKey = signData.dir + file.name;
formData.append('key', objectKey);
formData.append('policy', signData.policy);
formData.append('x-oss-credential', signData.x_oss_credential);
formData.append('x-oss-date', signData.x_oss_date);
formData.append('x-oss-signature-version', signData.version);
formData.append('x-oss-signature', signData.signature);
formData.append('success_action_status', '200');
formData.append('file', file);
// 3. 上传到OSS
const uploadResponse = await fetch(signData.url, {
method: 'POST',
body: formData
});
if (!uploadResponse.ok) {
throw new Error('文件上传失败');
}
// 4. 返回完整的文件URL
return `${signData.url}/${objectKey}`;
});
try {
const imageUrls = await Promise.all(uploadPromises);
return JSON.stringify(imageUrls);
} catch (error) {
console.error('上传详情图集失败:', error);
throw error;
}
}
2. 解析详情图集
/**
* 解析详情图集
* @param {string} detailGallery - 详情图集JSON字符串
* @returns {string[]} 图片URL数组
*/
function parseDetailGallery(detailGallery) {
if (!detailGallery || detailGallery.trim() === '') {
return [];
}
try {
const urls = JSON.parse(detailGallery);
return Array.isArray(urls) ? urls : [];
} catch (error) {
console.error('解析详情图集失败:', error);
return [];
}
}
/**
* 渲染详情图集
* @param {string} detailGallery - 详情图集JSON字符串
* @param {HTMLElement} container - 容器元素
*/
function renderDetailGallery(detailGallery, container) {
const imageUrls = parseDetailGallery(detailGallery);
container.innerHTML = '';
if (imageUrls.length === 0) {
container.innerHTML = '<p>暂无详情图片</p>';
return;
}
imageUrls.forEach((url, index) => {
const img = document.createElement('img');
img.src = url;
img.alt = `详情图片 ${index + 1}`;
img.className = 'detail-gallery-image';
img.style.cssText = `
width: 100%;
max-width: 400px;
height: auto;
margin: 10px;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
cursor: pointer;
`;
// 点击预览
img.addEventListener('click', () => {
showImagePreview(url);
});
container.appendChild(img);
});
}
3. 完整使用示例
<!-- HTML -->
<div class="upload-section">
<label for="detail-images">选择详情图片(可选择多张):</label>
<input type="file" id="detail-images" multiple accept="image/*">
<button onclick="handleUpload()">上传作品</button>
</div>
<div id="preview-container"></div>
<script>
async function handleUpload() {
const fileInput = document.getElementById('detail-images');
const files = fileInput.files;
let detailGallery = '';
// 如果选择了图片,则上传详情图集
if (files.length > 0) {
try {
detailGallery = await uploadDetailGallery(files, getCurrentUserId());
console.log('详情图集上传成功:', detailGallery);
} catch (error) {
alert('详情图集上传失败: ' + error.message);
return;
}
}
// 提交工作流
const workflowData = {
name: "我的工作流",
description: "工作流描述",
detailGallery: detailGallery, // 详情图集
vodVideoId: "a0776b0179bf71f0bea45017f1e90102",
data: JSON.stringify({nodes: [], edges: []}),
isFree: 1
};
try {
const response = await fetch('/user/workflow/submit', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + getToken()
},
body: JSON.stringify(workflowData)
});
if (response.ok) {
const result = await response.json();
alert('工作流上传成功!ID: ' + result.data);
} else {
alert('工作流上传失败');
}
} catch (error) {
alert('提交失败: ' + error.message);
}
}
// 获取当前用户ID
function getCurrentUserId() {
return '17543607206742139'; // 示例用户ID
}
// 获取认证token
function getToken() {
return localStorage.getItem('token');
}
</script>
🚀 后端接口支持
1. 工作流相关接口
上传工作流 - POST /user/workflow/submit
{
"name": "工作流名称",
"detailGallery": "[\"url1\",\"url2\"]",
"vodVideoId": "视频ID",
"data": "工作流JSON数据"
}
更新工作流 - PUT /user/content/workflows/{id}
{
"name": "更新的名称",
"detailGallery": "[\"new_url1\",\"new_url2\"]"
}
2. 课程相关接口
更新课程 - PUT /user/course/{id}
{
"title": "课程标题",
"detailGallery": "[\"url1\",\"url2\"]",
"price": 99.99
}
用户内容管理 - PUT /user/content/courses
{
"id": 1,
"title": "课程标题",
"detailGallery": "[\"url1\",\"url2\"]"
}
📋 响应示例
工作流详情API响应
{
"code": 200,
"message": "success",
"data": {
"workflow": {
"id": 1,
"name": "智能图像生成工作流",
"coverUrl": "https://oss.../cover.jpg",
"detailGallery": "[\"https://oss.../detail1.jpg\",\"https://oss.../detail2.jpg\",\"https://oss.../detail3.jpg\"]",
"vodVideoId": "a0776b0179bf71f0bea45017f1e90102",
"price": 29.99
}
}
}
课程详情API响应
{
"id": 1,
"title": "AI图像处理入门课程",
"coverUrl": "https://oss.../cover.jpg",
"detailGallery": "[\"https://oss.../detail1.jpg\",\"https://oss.../detail2.jpg\"]",
"price": 99.99,
"chapters": [...]
}
⚙️ 最佳实践
1. 图片要求
- 尺寸: 建议 1200x800px 或同等比例
- 格式: 推荐 JPG/PNG
- 大小: 单张图片不超过 5MB
- 数量: 建议 2-5 张图片
2. 用户体验
- 预览功能: 支持图片点击放大预览
- 加载优化: 使用懒加载和图片压缩
- 错误处理: 提供友好的错误提示
- 进度显示: 显示上传进度
3. 性能优化
// 图片压缩示例
function compressImage(file, maxWidth = 1200, quality = 0.8) {
return new Promise((resolve) => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const img = new Image();
img.onload = () => {
const ratio = Math.min(maxWidth / img.width, maxWidth / img.height);
canvas.width = img.width * ratio;
canvas.height = img.height * ratio;
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
canvas.toBlob(resolve, 'image/jpeg', quality);
};
img.src = URL.createObjectURL(file);
});
}
🔍 测试验证
1. 功能测试清单
- 单张图片上传
- 多张图片批量上传
- 图片格式验证
- 文件大小限制
- 详情图集解析
- 详情图集渲染
- 接口响应验证
2. 兼容性测试
- 现有工作流不受影响
- 现有课程不受影响
- API响应格式保持一致
- 数据库操作正常
🆘 常见问题
Q: 详情图集是必填字段吗? A: 不是,详情图集是可选字段,不影响现有功能。
Q: 如何清空详情图集?
A: 设置 detailGallery 为空字符串 "" 或 null。
Q: 支持的最大图片数量? A: 理论上无限制,但建议2-5张以获得最佳体验。
Q: 上传失败如何处理? A: 实现重试机制,并提供详细的错误信息。
更新时间: 2024-12-01
版本: v1.0