feat: 第一次生成
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 214 KiB |
+117
@@ -0,0 +1,117 @@
|
||||
#### 1. 登录接口 (`POST /api/user/login`)
|
||||
|
||||
##### 接口描述:
|
||||
|
||||
- 用户登录接口,用于验证用户凭据并返回访问令牌(`token`)。
|
||||
|
||||
##### 请求路径:
|
||||
|
||||
- `POST http://192.168.1.99:8008/api/user/login`
|
||||
|
||||
##### 请求参数:
|
||||
|
||||
|字段|类型|必填|描述|
|
||||
|---|---|---|---|
|
||||
|`username`|`string`|是|用户名|
|
||||
|`password`|`string`|是|密码|
|
||||
|
||||
##### 示例请求体:
|
||||
|
||||
```json
|
||||
{ "username": "mzaxd", "password": "200712" }
|
||||
```
|
||||
|
||||
##### 返回值:
|
||||
|
||||
结构如以下示例,包含 token 用于后续请求的鉴权。
|
||||
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"code": 0,
|
||||
"data": {
|
||||
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI4YmJlZTIzYy1jZGY3LTQ5OTktOTU5NC0zNjZmNDljOTI3MjgiLCJyb2xlIjoxLCJpYXQiOjE3NDYzNDAxNTAsImV4cCI6MTc0NjM2MTc1MH0.a5sziK9-zkfw3WGhpi-j6zKhl3SgxRMf-bsdEf6xGqA"
|
||||
},
|
||||
"message": "操作成功"
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### 2. 搜索接口 (`GET /api/search`)
|
||||
|
||||
##### 接口描述:
|
||||
|
||||
- 搜索资源的接口,根据关键字 `keyword` 匹配数据并返回符合条件的列表。
|
||||
|
||||
##### 请求路径:
|
||||
|
||||
- `GET http://192.168.1.99:8008/api/search`
|
||||
|
||||
##### 查询参数:
|
||||
|
||||
|参数|类型|必填|描述|备注|
|
||||
|---|---|---|---|---|
|
||||
|`keyword`|`string`|是|搜索关键字|示例:"破地狱"|
|
||||
|`lastMessageId`|`string`|否|不重要,留空即可|-|
|
||||
|
||||
##### 示例请求:
|
||||
|
||||
`GET /api/search?keyword=破地狱&lastMessageId=`
|
||||
|
||||
##### 返回值:
|
||||
|
||||
结构如以下示例,包含多个 `channel` 下的资源条目。
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"code": 0,
|
||||
"data": [
|
||||
{
|
||||
"list": [
|
||||
{
|
||||
"messageId": "188367",
|
||||
"title": "名称:《破·地狱》(2024)[1080P][中文字幕][剧情/家庭][黄子华/许冠文/卫诗雅]",
|
||||
"pubDate": "2025-04-30T14:54:55+00:00",
|
||||
"content": "影片通过「破地狱」古老丧礼仪式探讨生死与家庭...",
|
||||
"image": "资源预览图URLO Caldera.jpg",
|
||||
"cloudLinks": [
|
||||
{
|
||||
"link": "网盘链接",
|
||||
"cloudType": "quark"
|
||||
}
|
||||
],
|
||||
"tags": ["#剧情", "#家庭", "#破地狱"],
|
||||
"channel": " kaynak藏(夸克)",
|
||||
"channelId": "yunpanshare"
|
||||
}
|
||||
],
|
||||
"channelInfo": {
|
||||
"id": "yunpanshare",
|
||||
"name": "原盘(夸克)",
|
||||
"index": 0,
|
||||
"channelLogo": "频道logoURL"
|
||||
}
|
||||
},
|
||||
{
|
||||
"list": [
|
||||
{
|
||||
"messageId": "5725",
|
||||
"title": "原盘版『破地狱』(2025) 1080P REMUX 国粤音轨",
|
||||
"pubDate": "2025-04-10T05:10:10+00:00",
|
||||
"content": "婚礼策划师道生(黄子华饰)债务危机..."
|
||||
}
|
||||
],
|
||||
"channelInfo": {
|
||||
"id": "alyp_1",
|
||||
"name": "Repo 高品质影视",
|
||||
"index": 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"message": "查询成功"
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,221 @@
|
||||
### 🤖 Assistant
|
||||
|
||||
# 百盘搜系统架构与详细设计文档
|
||||
## 目录结构
|
||||
```markdown
|
||||
/bps
|
||||
│
|
||||
├── frontend/ # 用户前端(Nuxt.js)
|
||||
│ ├── nuxt.config.ts
|
||||
│ ├── package.json
|
||||
│ ├── pages/
|
||||
│ ├── components/
|
||||
│ ├── composables/
|
||||
│ ├── assets/
|
||||
│ └── ...(其他Nuxt相关目录)
|
||||
│
|
||||
├── admin/ # 管理端后台(Nuxt.js 或 Vite+Vue3)
|
||||
│ ├── nuxt.config.ts
|
||||
│ ├── package.json
|
||||
│ ├── pages/
|
||||
│ ├── components/
|
||||
│ ├── composables/
|
||||
│ ├── assets/
|
||||
│ └── ...(其他前端相关目录)
|
||||
│
|
||||
├── backend/ # 后端服务(Express.js + TypeScript)
|
||||
│ ├── src/
|
||||
│ │ ├── controllers/ # 控制器层(接口处理逻辑)
|
||||
│ │ │ ├── searchController.ts
|
||||
│ │ │ ├── accountController.ts
|
||||
│ │ │ ├── transcodeController.ts
|
||||
│ │ │ └── statsController.ts
|
||||
│ │ ├── services/ # 服务层(业务逻辑处理)
|
||||
│ │ │ ├── adapters/ # 网盘适配器模块
|
||||
│ │ │ │ ├── BaiduDriveAdapter.ts
|
||||
│ │ │ │ ├── QuarkDriveAdapter.ts
|
||||
│ │ │ │ ├── UCDriveAdapter.ts
|
||||
│ │ │ │ └── XunleiDriveAdapter.ts
|
||||
│ │ │ └── DriveAdapter.ts # 抽象接口
|
||||
│ │ ├── models/ # 模型层(数据实体)
|
||||
│ │ │ ├── driveAccount.ts
|
||||
│ │ │ ├── transcodeRecord.ts
|
||||
│ │ │ └── ...
|
||||
│ │ ├── middlewares/ # 中间件(安全认证、日志等)
|
||||
│ │ │ ├── rateLimit.ts
|
||||
│ │ │ └── errorHandler.ts
|
||||
│ │ ├── utils/ # 工具层(加密、日志等)
|
||||
│ │ │ ├── crypto.ts
|
||||
│ │ │ └── logger.ts
|
||||
│ │ ├── prisma/ # Prisma 配置及迁移
|
||||
│ │ │ └── schema.prisma
|
||||
│ │ ├── app.ts
|
||||
│ │ └── server.ts
|
||||
│ ├── package.json
|
||||
│ ├── tsconfig.json
|
||||
│ └── ...
|
||||
│
|
||||
├── doc/ # 系统文档
|
||||
│ ├── 百盘搜详细设计文档.md
|
||||
│ ├── 搜索服务接口文档.md
|
||||
│ └── ...
|
||||
│
|
||||
├── .gitignore
|
||||
├── README.md
|
||||
└── ...
|
||||
```
|
||||
|
||||
## 模块具体设计
|
||||
### 1. 前端模块(Nuxt.js)
|
||||
#### 页面结构组件
|
||||
- **搜索页**(`/index.vue`):
|
||||
- 关键词输入、筛选器(网盘类型)、分页
|
||||
- 搜索结果展示(包含操作按钮)
|
||||
- **管理后台**(`/admin` 目录下 Nuxt/Vue 页面):
|
||||
- 统计看板(chart.js 展示)
|
||||
- 账号管理界面(增删改查表单)
|
||||
|
||||
#### 交互接口
|
||||
- **搜索请求**: `/api/search` (`GET`)
|
||||
- 参数: `keyword`, `types[]`, `page`
|
||||
-otechnically Redis 缓存(5分钟)
|
||||
- **获取资源链接**: `/api/generate-link` (`POST`)
|
||||
- 参数: `{ driveId, externalId, expiration: 10min }`
|
||||
- 调用对应适配器生成临时分享链接
|
||||
|
||||
### 2. 后端模块(Express.js + TypeScript)
|
||||
#### 核心接口声明
|
||||
```typescript
|
||||
// backend/src/controllers/searchController.ts
|
||||
export async function getSearchResults(req: Req, res: Res) {
|
||||
const { keyword, types, page = 1 } = req.query;
|
||||
try {
|
||||
const results = await SearchService.search(keyword, types, page);
|
||||
res.json(results);
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: 'SEARCH_FAILED' });
|
||||
}
|
||||
}
|
||||
|
||||
// backend/src/services/searchService.ts
|
||||
async function search(keyword: string, types?: string[], page: number) {
|
||||
// 1. Redis 缓存命中(5分钟有效期)
|
||||
const cacheKey = `search:${keyword}:${types?.join(',')}:${page}`;
|
||||
const cached = await redis.get(cacheKey);
|
||||
if (cached) return JSON.parse(cached);
|
||||
|
||||
// 2. 调用外部搜索服务聚合数据
|
||||
const aniSearchResults = await callAniSearchService(keyword);
|
||||
const baiduSearchResults = await callBaiduSearchService(keyword);
|
||||
|
||||
// ...聚合后端逻辑...
|
||||
|
||||
// 3. 缓存结果
|
||||
const finalResult = {
|
||||
total: ...,
|
||||
items: [...aniResults, ...baiduResults]
|
||||
};
|
||||
await redis.set(cacheKey, JSON.stringify(finalResult), 'EX', 300);
|
||||
return finalResult;
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 雷霄骄子(网盘适配器)
|
||||
#### 接口契约
|
||||
```typescript
|
||||
// backend/src/services/adapters/DriveAdapter.ts
|
||||
export interface DriveAdapter {
|
||||
getDisplayName(): string; // 展示名称(如"百度网盘")
|
||||
getServiceName(): string; // 唯一ID(如)baidu-cloud
|
||||
|
||||
transcodeAndShare(externalId: string): Promise<{ tempLink: string }>;
|
||||
// भविष्य会扩展删除等接口
|
||||
}
|
||||
```
|
||||
|
||||
#### 举例:百度网盘适配器
|
||||
```typescript
|
||||
import { DriveAdapter } from './DriveAdapter';
|
||||
|
||||
export class BaiduDriveAdapter implements DriveAdapter {
|
||||
getDisplayName() {
|
||||
return '百度网盘';
|
||||
}
|
||||
|
||||
getServiceName() {
|
||||
return 'baidu-cloud';
|
||||
}
|
||||
|
||||
async transcodeAndShare(externalId: string) {
|
||||
// 1. 检查网盘账号可用性(由 AccountService 确保)
|
||||
const account = await AccountService.findValidBaiduAccount();
|
||||
if (!account) {
|
||||
throw new Error('BAIDU_ACCOUNT_NOT_FOUND');
|
||||
}
|
||||
|
||||
// 2. 使用官方SDK获取真实 下载URL
|
||||
const baiduSdk = new BaiduSDK(account.appId, account.secret);
|
||||
const shareLink = await baiduSdk.createTempShare(externalId);
|
||||
|
||||
// 3. 缓存链接10分钟(redis 记录)
|
||||
await redis.set(`link:${externalId}`, shareLink, 'EX', 600);
|
||||
return { tempLink: shareLink };
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 高性能架构策略
|
||||
1. **负载分流**:
|
||||
- 复制搜索服务实例
|
||||
- 使用nginx作为负载均衡器
|
||||
2. **异步队列**:
|
||||
```typescript
|
||||
//фровoeysaTaskQueue
|
||||
const rabbitMq = new RabbitMQ();
|
||||
|
||||
// Generates a link in the background
|
||||
export async function createLinkWorker(externalId: string) {
|
||||
const adapter = getAdapterByExternalId(externalId);
|
||||
const { tempLink } = await adapter.transcodeAndShare(externalId);
|
||||
await rabbitMq.sendToUser('LINK_READY', tempLink);
|
||||
}
|
||||
```
|
||||
3. **提前缓存**:
|
||||
- 定期轮询热门搜索关键词
|
||||
- 保持10%用户行为采样结果缓存
|
||||
|
||||
### 5. 安全与监控
|
||||
- **日志监控**:
|
||||
```yaml
|
||||
# Extract logs into loki for DevOps
|
||||
loki-config:
|
||||
host: http://loki.internal:3100
|
||||
job: backend | labels: "app=bps, env=production"
|
||||
```
|
||||
- **防攻击策略**:
|
||||
- 限速(5次/秒)
|
||||
- CSRF令牌保护
|
||||
- 密码使用argon2加密
|
||||
|
||||
### 6. 完成功能里程碑
|
||||
| # | 特性 | 完成状态 | 备注 |
|
||||
|---|------------------------|---------|------|
|
||||
| 1 | 多网盘搜索聚合 | ✅ | |
|
||||
| 2 | 自动换adolink逻辑 | 🚧 | |
|
||||
| 3 | 支持未注册用户使用 | ✅ | |
|
||||
| 4 | 账号余额告警(可选) | ❌ | |
|
||||
|
||||
## 扩展接口设计 blueprint
|
||||
```typescript
|
||||
// 未来可能接口
|
||||
async deleteResource(externalId: string): Promise<void> {
|
||||
// 通过适配器调用网盘真实删除接口
|
||||
}
|
||||
```
|
||||
|
||||
> This is a hypothetical description. To summarize:
|
||||
> 1) I mapped your requirements into technical modules with code snippets.
|
||||
> 2) Extracted monolithic design into isolated components (front/Admin/Backend).
|
||||
> 3) Added suggestions for quick iteration.
|
||||
> 4) Balanced "now" vs "future" features with Mehndiroller labels.
|
||||
> Let me know if you'd like me to refine any sections further—like providing actual Prisma/S elems models for example!
|
||||
@@ -0,0 +1,172 @@
|
||||
## **项目概述**
|
||||
|
||||
### 目标
|
||||
|
||||
构建一个基于Nuxt.js的前端界面,通过后端服务对接多个网盘资源搜索接口,实现资源搜索、筛选、转存及临时分享功能。后端需支持网盘账号管理、资源转存逻辑扩展、Redis缓存及MySQL数据库存储。
|
||||
|
||||
### 约束条件
|
||||
|
||||
- **技术栈**:
|
||||
- 前端:Nuxt.js(TypeScript模式)
|
||||
- 后端:Express.js(TypeScript模式)
|
||||
- 数据库:MySQL 8.0(ORM使用Prisma)
|
||||
- 缓存:Redis
|
||||
- 接口协议:RESTful API
|
||||
- **核心原则**:
|
||||
- 所有网盘操作需通过后端中转,避免用户直接访问原始网盘接口
|
||||
- 转存资源需在10分钟后自动删除
|
||||
- 系统需支持未来扩展其他网盘服务
|
||||
|
||||
---
|
||||
|
||||
## **功能模块设计**
|
||||
|
||||
### **1. 前端界面**
|
||||
|
||||
#### **1.1 搜索页**
|
||||
|
||||
- **核心组件**:
|
||||
- 搜索框:支持输入关键词并提交搜索请求
|
||||
- 筛选条件:下拉选择(如“百度网盘”“阿里云盘”等)
|
||||
- 分页控件:支持跳转和动态加载
|
||||
- **数据展示**:
|
||||
- 列表项包含:文件名、大小、目录路径、来源网盘标识
|
||||
- 每项操作按钮:点击“获取链接”触发后端转存流程
|
||||
- **交互逻辑**:
|
||||
- 搜索请求发送至后端API `/api/search`
|
||||
- 结果分页响应需包含总页数、当前页数据
|
||||
- 筛选条件提交需触发完整搜索请求
|
||||
|
||||
#### **1.2 管理后台**
|
||||
|
||||
- **功能模块**:
|
||||
- **统计数据看板**:
|
||||
- 实时搜索量统计(按网盘类型)
|
||||
- 转存成功/失败次数
|
||||
- 用户行为分析(如热门搜索词)
|
||||
- **账号管理**:
|
||||
- 网盘账号列表(支持增删改)
|
||||
- 账号状态监控(如API调用配额)
|
||||
|
||||
---
|
||||
|
||||
### **2. 后端服务**
|
||||
|
||||
#### **2.1 核心接口设计**
|
||||
|
||||
|接口路径|方法|功能描述|
|
||||
|---|---|---|
|
||||
|`/api/search`|POST|接收关键词及筛选条件,调用搜索服务器接口并缓存结果到Redis|
|
||||
|`/api/generate-link`|POST|根据资源ID触发转存,返回临时分享链接,设置10分钟过期定时任务|
|
||||
|`/api/stats`|GET|返回统计信息(如总搜索次数、转存成功率)|
|
||||
|`/api/accounts`|CRUD|管理网盘账号凭证(加密存储)|
|
||||
|
||||
#### **2.2 转存逻辑模块**
|
||||
|
||||
- **流程**:
|
||||
1. 用户点击“获取链接” → 后端验证资源是否存在
|
||||
2. 调用对应网盘API(如BaiduAPI、AliyunAPI)进行转存
|
||||
3. 转存成功后,记录分享链接及过期时间到数据库
|
||||
4. 返回链接给前端,启动定时任务在10分钟后删除资源
|
||||
- **扩展性设计**:
|
||||
- 每个网盘的转存逻辑封装为独立模块(如 `src/services/BaiduDriveService.ts`)
|
||||
- 通过策略模式(Strategy Pattern)动态选择网盘适配器
|
||||
|
||||
#### **2.3 缓存策略**
|
||||
|
||||
- **Redis缓存规则**:
|
||||
- **搜索结果缓存**:
|
||||
- Key:`search:${keyword}:${filter}`
|
||||
- TTL:5分钟
|
||||
- **转存链接缓存**:
|
||||
- Key:`temp_link:${resourceId}`
|
||||
- TTL:10分钟(与自动删除逻辑同步)
|
||||
|
||||
---
|
||||
|
||||
## **4. 扩展性设计**
|
||||
|
||||
### **4.1 网盘适配器**
|
||||
|
||||
- **抽象接口**:
|
||||
|
||||
|
||||
|
||||
```typescript
|
||||
interface DriveAdapter {
|
||||
transcode(resourceId: string, account: Account): Promise<string | null>
|
||||
getShareLink(resourceId: string): Promise<string>
|
||||
}
|
||||
|
||||
|
||||
```
|
||||
|
||||
- **实现示例**:
|
||||
|
||||
<TYPESCRIPT>
|
||||
|
||||
```
|
||||
class BaiduDriveAdapter implements DriveAdapter { async transcode(...) { /* 百度网盘转存逻辑 */ } async getShareLink(...) { /* 生成百度网盘分享链接 */ }}
|
||||
```
|
||||
|
||||
|
||||
### **4.2 插件化架构**
|
||||
|
||||
- **账号管理**:
|
||||
- 新增网盘类型时,仅需注册对应适配器及账号凭证字段
|
||||
- 转存逻辑通过工厂模式动态选择适配器
|
||||
|
||||
---
|
||||
|
||||
## **5. 安全与可靠性**
|
||||
|
||||
### **5.1 安全措施**
|
||||
|
||||
- **敏感信息保护**:
|
||||
- 网盘账号凭证加密存储(如AES加密)
|
||||
- Redis缓存数据不存储敏感信息
|
||||
- **防滥用机制**:
|
||||
- 单用户请求频率限制(通过Nginx或Express Rate Limit中间件)
|
||||
- 转存失败重试次数限制
|
||||
|
||||
### **5.2 异常处理**
|
||||
|
||||
- **后端**:
|
||||
- 网盘API调用失败时记录日志并返回错误码
|
||||
- 转存超时资源自动清理(通过Cron任务扫描`TranscodeRecord`表)
|
||||
- **前端**:
|
||||
- 网络请求超时提示
|
||||
- 转存失败时显示错误原因(如“账号配额不足”)
|
||||
|
||||
---
|
||||
|
||||
## **6. 非功能性需求**
|
||||
|
||||
|
||||
### **6.1 可维护性**
|
||||
|
||||
- **日志监控**:
|
||||
- 使用 Winston 或 Log4js 记录关键操作日志
|
||||
- 日志内容对接loki
|
||||
|
||||
---
|
||||
|
||||
## **附录:技术选型说明**
|
||||
|
||||
### **前端(Nuxt.js)**
|
||||
|
||||
- **优势**:
|
||||
- 支持TypeScript和SSR,提升SEO友好度
|
||||
- 通过API Routes实现服务端渲染与数据预取
|
||||
|
||||
### **后端(Express.js)**
|
||||
|
||||
- **优势**:
|
||||
- 灵活配置中间件(如 Redis连接池、CORS)
|
||||
- 与TypeScript结合良好,支持接口强类型定义
|
||||
|
||||
### **数据库(MySQL + Prisma)**
|
||||
|
||||
- **优势**:
|
||||
- Prisma提供TypeScript类型安全的数据库操作
|
||||
- 支持复杂查询(如关联查询转存记录与账号)
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 136 KiB |
Reference in New Issue
Block a user