[Claude Workbench] Initial commit - preserving existing code

This commit is contained in:
Claude Workbench
2025-11-14 17:41:15 +08:00
commit 0f7bc05697
587 changed files with 103215 additions and 0 deletions

684
广场功能实现方案.md Normal file
View File

@@ -0,0 +1,684 @@
# 广场功能完整实现方案
## 一、功能概述
用户可以将AI生成的作品发布到广场其他用户可以浏览、点赞、按类型筛选查询作品。
### 核心功能
1. **发布作品** - 用户将任务结果发布到广场
2. **浏览广场** - 按类型、热度、时间查询作品
3. **作品详情** - 查看单个作品详细信息
4. **点赞/取消点赞** - 用户可以对作品点赞
5. **统计数据** - 浏览量、点赞数、分享数统计
6. **个人作品** - 查看自己发布的作品
7. **删除作品** - 用户可以删除自己的作品
---
## 二、数据库设计
已在 `V10__add_plaza_feature.sql` 中定义了以下表:
### 1. plaza_work广场作品表
```sql
- id: 主键
- work_no: 作品编号(唯一)
- user_id: 发布者ID
- task_no: 关联任务编号
- task_type: 任务类型(text_to_image/image_to_video等
- model_name: 使用的模型
- prompt: 生成提示词
- result_url: 作品URL
- image_url: 参考图URL(可选)
- title: 作品标题
- description: 作品描述
- tags: 标签(JSON
- view_count, like_count, share_count: 统计数据
- is_public: 是否公开
- status: 状态(draft/published/hidden
- create_time, update_time, is_deleted
```
### 2. plaza_work_like点赞表
```sql
- id: 主键
- work_id: 作品ID
- user_id: 点赞用户ID
- create_time: 点赞时间
- 唯一索引:(work_id, user_id)
```
### 3. plaza_work_view浏览记录表
```sql
- id: 主键
- work_id: 作品ID
- user_id: 浏览用户ID(可空)
- ip_address: IP地址
- view_time: 浏览时间
```
---
## 三、API 接口设计
### 基础路径
所有接口以 `/user/plaza` 开头
### 1. 发布作品
```
POST /user/plaza/works/publish
```
**请求参数:**
```json
{
"taskNo": "TASK-20251026183750127-8554",
"title": "战场气氛短视频",
"description": "根据参考图生成的恢弘战场场景",
"tags": ["视频", "战争", "特效"],
"isPublic": true
}
```
**响应示例:**
```json
{
"code": 200,
"message": "success",
"data": {
"workNo": "WORK-20251026185630123-4567",
"taskNo": "TASK-20251026183750127-8554",
"taskType": "image_to_video",
"modelName": "sc_sora2_img_landscape_15s_small",
"prompt": "根据参考图展现出一个100秒左右的战场短视频...",
"resultUrl": "https://oss-1818ai-user-img.oss-cn-hangzhou.aliyuncs.com/result.mp4",
"imageUrl": "https://oss-1818ai-user-img.oss-cn-hangzhou.aliyuncs.com/ref.png",
"title": "战场气氛短视频",
"description": "根据参考图生成的恢弘战场场景",
"tags": ["视频", "战争", "特效"],
"viewCount": 0,
"likeCount": 0,
"isLiked": false,
"createTime": "2025-10-26T18:56:30"
}
}
```
---
### 2. 查询广场作品列表
```
GET /user/plaza/works/list
```
**请求参数:**
- `page`: 页码默认1
- `size`: 每页数量默认20
- `taskType`: 任务类型筛选可选text_to_image/image_to_video等
- `sortBy`: 排序方式可选latest-最新/hot-最热默认latest
**示例:**
```
GET /user/plaza/works/list?page=1&size=20&taskType=text_to_image&sortBy=hot
```
**响应示例:**
```json
{
"code": 200,
"message": "success",
"data": {
"total": 156,
"list": [
{
"workNo": "WORK-20251026185630123-4567",
"taskType": "text_to_image",
"modelName": "sc_soraimg_text_1x1",
"prompt": "一只可爱的橘猫在窗台晒太阳",
"resultUrl": "https://oss-.../cat.png",
"title": "窗台上的橘猫",
"tags": ["猫咪", "温馨", "治愈"],
"viewCount": 1245,
"likeCount": 89,
"isLiked": false,
"author": {
"userId": 17563793187762127,
"nickname": "AI创作者",
"avatarUrl": "https://oss-.../avatar.jpg"
},
"createTime": "2025-10-26T18:56:30"
}
// ... 更多作品
]
}
}
```
---
### 3. 查询作品详情
```
GET /user/plaza/works/{workNo}
```
**响应示例:**
```json
{
"code": 200,
"message": "success",
"data": {
"workNo": "WORK-20251026185630123-4567",
"taskType": "text_to_image",
"modelName": "sc_soraimg_text_1x1",
"prompt": "一只可爱的橘猫在窗台晒太阳,温馨的室内场景,柔和的光线",
"resultUrl": "https://oss-.../cat.png",
"imageUrl": null,
"aspectRatio": "1:1",
"title": "窗台上的橘猫",
"description": "这是一个温馨治愈的作品,展现了橘猫慵懒晒太阳的画面。",
"tags": ["猫咪", "温馨", "治愈"],
"viewCount": 1246,
"likeCount": 89,
"shareCount": 12,
"isLiked": false,
"author": {
"userId": 17563793187762127,
"nickname": "AI创作者",
"avatarUrl": "https://oss-.../avatar.jpg"
},
"createTime": "2025-10-26T18:56:30",
"updateTime": "2025-10-26T19:15:42"
}
}
```
---
### 4. 点赞/取消点赞
```
POST /user/plaza/works/{workNo}/like
DELETE /user/plaza/works/{workNo}/like
```
**响应示例:**
```json
{
"code": 200,
"message": "success",
"data": {
"isLiked": true,
"likeCount": 90
}
}
```
---
### 5. 查询我的作品
```
GET /user/plaza/my-works
```
**请求参数:**
- `page`: 页码
- `size`: 每页数量
- `status`: 状态筛选可选published/draft/hidden
**响应格式:** 同广场作品列表
---
### 6. 删除作品
```
DELETE /user/plaza/works/{workNo}
```
**响应示例:**
```json
{
"code": 200,
"message": "删除成功",
"data": null
}
```
---
### 7. 统计数据
```
GET /user/plaza/stats
```
**响应示例:**
```json
{
"code": 200,
"message": "success",
"data": {
"totalWorks": 5678,
"totalViews": 123456,
"totalLikes": 8901,
"worksByType": {
"text_to_image": 3456,
"image_to_video": 1234,
"text_to_video": 988
}
}
}
```
---
## 四、实现步骤
### 步骤1: 执行SQL脚本
```bash
mysql -u root -p 1818ai < V10__add_plaza_feature.sql
```
### 步骤2: 创建实体类
-`PlazaWork.java` - 已创建
-`PlazaWorkLike.java` - 已创建
### 步骤3: 创建DTO类
需要创建以下DTO
- `PlazaWorkDto.java` - 包含各种请求和响应DTO
- `PublishWorkRequest` - 发布作品请求
- `WorkQueryRequest` - 查询作品请求
- `WorkDetailResponse` - 作品详情响应
- `WorkListResponse` - 作品列表响应
- `WorkAuthorDto` - 作者信息DTO
### 步骤4: 创建Mapper接口
- `PlazaWorkMapper.java` - 作品数据访问
- `PlazaWorkLikeMapper.java` - 点赞数据访问
### 步骤5: 创建Service层
- `PlazaService.java` - 接口
- `PlazaServiceImpl.java` - 实现
### 步骤6: 创建Controller
- `PlazaController.java` - 用户端控制器
---
## 五、核心业务逻辑
### 1. 发布作品流程
```
1. 验证taskNo是否存在且属于当前用户
2. 验证任务状态是否为completed
3. 检查该任务是否已经发布过
4. 生成唯一的workNo
5. 从任务表复制数据到广场作品表
6. 设置标题、描述、标签等
7. 初始化统计数据浏览、点赞等为0
8. 返回作品信息
```
### 2. 查询列表流程
```
1. 构建查询条件(任务类型、公开性、状态)
2. 根据sortBy排序latest/hot
3. 分页查询
4. 关联查询用户信息(昵称、头像)
5. 判断当前用户是否点赞过(如果已登录)
6. 返回作品列表
```
### 3. 点赞流程
```
1. 检查作品是否存在
2. 检查是否已经点赞
3. 插入点赞记录
4. 更新作品点赞数(+1
5. 返回最新点赞状态
```
### 4. 浏览统计流程
```
1. 记录浏览日志(可选)
2. 更新作品浏览数(+1
3. 防止频繁刷新可加Redis缓存同一用户1分钟内只计数一次
```
---
## 六、前端调用示例
### 1. 发布作品到广场
```javascript
// 假设用户刚完成了一个任务,想发布到广场
async function publishToPlaza(taskNo) {
const response = await fetch('http://localhost:8081/user/plaza/works/publish', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${YOUR_TOKEN}`
},
body: JSON.stringify({
taskNo: taskNo,
title: '我的AI创作',
description: '这是我用AI生成的作品',
tags: ['AI艺术', '创意'],
isPublic: true
})
});
const result = await response.json();
console.log('发布成功:', result.data.workNo);
}
```
### 2. 浏览广场(按类型筛选)
```javascript
// 查询所有文生图作品
async function browsePlaza() {
const response = await fetch(
'http://localhost:8081/user/plaza/works/list?page=1&size=20&taskType=text_to_image&sortBy=hot',
{
headers: {
'Authorization': `Bearer ${YOUR_TOKEN}`
}
}
);
const result = await response.json();
console.log('广场作品:', result.data.list);
// 渲染作品网格
renderWorksGrid(result.data.list);
}
function renderWorksGrid(works) {
works.forEach(work => {
console.log(`
作品:${work.title}
作者:${work.author.nickname}
点赞:${work.likeCount}
浏览:${work.viewCount}
图片:${work.resultUrl}
`);
});
}
```
### 3. 查看作品详情
```javascript
async function viewWorkDetail(workNo) {
const response = await fetch(
`http://localhost:8081/user/plaza/works/${workNo}`,
{
headers: {
'Authorization': `Bearer ${YOUR_TOKEN}`
}
}
);
const result = await response.json();
console.log('作品详情:', result.data);
// 显示详情页
showDetailModal(result.data);
}
```
### 4. 点赞作品
```javascript
async function likeWork(workNo) {
const response = await fetch(
`http://localhost:8081/user/plaza/works/${workNo}/like`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${YOUR_TOKEN}`
}
}
);
const result = await response.json();
console.log('点赞成功,当前点赞数:', result.data.likeCount);
// 更新UI
updateLikeButton(workNo, result.data.isLiked, result.data.likeCount);
}
async function unlikeWork(workNo) {
const response = await fetch(
`http://localhost:8081/user/plaza/works/${workNo}/like`,
{
method: 'DELETE',
headers: {
'Authorization': `Bearer ${YOUR_TOKEN}`
}
}
);
const result = await response.json();
console.log('取消点赞');
}
```
### 5. 查看我的作品
```javascript
async function getMyWorks() {
const response = await fetch(
'http://localhost:8081/user/plaza/my-works?page=1&size=10',
{
headers: {
'Authorization': `Bearer ${YOUR_TOKEN}`
}
}
);
const result = await response.json();
console.log('我的作品:', result.data.list);
}
```
---
## 七、React 完整示例
```jsx
import React, { useState, useEffect } from 'react';
// 广场组件
function PlazaPage() {
const [works, setWorks] = useState([]);
const [taskType, setTaskType] = useState('');
const [sortBy, setSortBy] = useState('latest');
const [page, setPage] = useState(1);
useEffect(() => {
loadWorks();
}, [taskType, sortBy, page]);
async function loadWorks() {
const params = new URLSearchParams({
page,
size: 20,
sortBy,
...(taskType && { taskType })
});
const response = await fetch(
`http://localhost:8081/user/plaza/works/list?${params}`,
{
headers: {
'Authorization': `Bearer ${localStorage.getItem('token')}`
}
}
);
const result = await response.json();
setWorks(result.data.list);
}
async function handleLike(workNo, isLiked) {
const method = isLiked ? 'DELETE' : 'POST';
const response = await fetch(
`http://localhost:8081/user/plaza/works/${workNo}/like`,
{
method,
headers: {
'Authorization': `Bearer ${localStorage.getItem('token')}`
}
}
);
if (response.ok) {
// 刷新列表
loadWorks();
}
}
return (
<div className="plaza-page">
<h1>AI创作广场</h1>
{/* 筛选器 */}
<div className="filters">
<select value={taskType} onChange={(e) => setTaskType(e.target.value)}>
<option value="">全部类型</option>
<option value="text_to_image">文生图</option>
<option value="image_to_image">图生图</option>
<option value="text_to_video">文生视频</option>
<option value="image_to_video">图生视频</option>
</select>
<select value={sortBy} onChange={(e) => setSortBy(e.target.value)}>
<option value="latest">最新发布</option>
<option value="hot">最热门</option>
</select>
</div>
{/* 作品网格 */}
<div className="works-grid">
{works.map(work => (
<div key={work.workNo} className="work-card">
<img src={work.resultUrl} alt={work.title} />
<h3>{work.title}</h3>
<p className="author">{work.author.nickname}</p>
<div className="stats">
<span>👁️ {work.viewCount}</span>
<button onClick={() => handleLike(work.workNo, work.isLiked)}>
{work.isLiked ? '❤️' : '🤍'} {work.likeCount}
</button>
</div>
<div className="tags">
{work.tags.map(tag => (
<span key={tag} className="tag">{tag}</span>
))}
</div>
</div>
))}
</div>
{/* 分页 */}
<div className="pagination">
<button onClick={() => setPage(p => Math.max(1, p - 1))}>
上一页
</button>
<span> {page} </span>
<button onClick={() => setPage(p => p + 1)}>
下一页
</button>
</div>
</div>
);
}
export default PlazaPage;
```
---
## 八、后续完善功能(可选)
### 1. 评论功能
- 创建 `plaza_work_comment`
- 支持评论和回复
- 评论点赞
### 2. 标签系统
- 创建 `plaza_tag` 标签表
- 支持热门标签推荐
- 按标签筛选作品
### 3. 用户关注
- 创建 `user_follow` 关注关系表
- 查看关注用户的作品
- 关注动态推送
### 4. 举报系统
- 创建 `plaza_report` 举报表
- 用户可以举报违规作品
- 管理员审核机制
### 5. 作品收藏
- 创建 `plaza_work_collect` 收藏表
- 用户收藏喜欢的作品
- 查看收藏列表
### 6. 分享功能
- 生成分享链接
- 分享到社交媒体
- 统计分享数据
---
## 九、性能优化建议
### 1. 缓存策略
- Redis 缓存热门作品列表
- 缓存用户点赞状态
- 缓存作品统计数据
### 2. CDN 加速
- 作品图片/视频通过 CDN 分发
- 提升加载速度
### 3. 数据库优化
- 对热点字段建立索引
- 分表存储历史数据
- 读写分离
### 4. 异步处理
- 浏览统计异步入库
- 点赞数更新异步化
- 使用消息队列
---
## 十、安全考虑
1. **内容审核**
- 发布前自动审核(敏感词过滤)
- 人工审核机制
- 违规内容下架
2. **防刷机制**
- 限制发布频率
- 防止点赞刷数据
- IP 限流
3. **权限控制**
- 只能删除自己的作品
- 未登录用户只能浏览
- 隐私作品仅自己可见
---
## 总结
广场功能的核心是:
1. **数据模型** - 作品表、点赞表、浏览记录表
2. **API接口** - 发布、查询、点赞、删除等
3. **前端展示** - 瀑布流/网格布局、筛选排序、实时统计
按照本方案实施可以快速搭建一个功能完善的AI作品广场。
下一步我会为你生成完整的 Java 代码Mapper、Service、Controller