初始化
This commit is contained in:
@@ -0,0 +1,225 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const ArtistService = require('../services/artist');
|
||||
|
||||
/**
|
||||
* 获取作者信息
|
||||
* GET /api/artist/:id
|
||||
*/
|
||||
router.get('/:id', async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
if (!id || isNaN(parseInt(id))) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Invalid artist ID'
|
||||
});
|
||||
}
|
||||
|
||||
const artistService = new ArtistService(req.backend.getAuth());
|
||||
const result = await artistService.getArtistInfo(parseInt(id));
|
||||
|
||||
if (result.success) {
|
||||
res.json({
|
||||
success: true,
|
||||
data: result.data
|
||||
});
|
||||
} else {
|
||||
res.status(404).json({
|
||||
success: false,
|
||||
error: result.error
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 获取作者作品列表
|
||||
* GET /api/artist/:id/artworks
|
||||
*/
|
||||
router.get('/:id/artworks', async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const {
|
||||
type = 'art',
|
||||
filter = 'for_ios',
|
||||
offset = 0,
|
||||
limit = 30
|
||||
} = req.query;
|
||||
|
||||
if (!id || isNaN(parseInt(id))) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Invalid artist ID'
|
||||
});
|
||||
}
|
||||
|
||||
const artistService = new ArtistService(req.backend.getAuth());
|
||||
const result = await artistService.getArtistArtworks(parseInt(id), {
|
||||
type,
|
||||
filter,
|
||||
offset: parseInt(offset),
|
||||
limit: parseInt(limit)
|
||||
});
|
||||
|
||||
if (result.success) {
|
||||
res.json({
|
||||
success: true,
|
||||
data: result.data
|
||||
});
|
||||
} else {
|
||||
res.status(404).json({
|
||||
success: false,
|
||||
error: result.error
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 获取作者关注列表
|
||||
* GET /api/artist/:id/following
|
||||
*/
|
||||
router.get('/:id/following', async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const {
|
||||
restrict = 'public',
|
||||
offset = 0,
|
||||
limit = 30
|
||||
} = req.query;
|
||||
|
||||
if (!id || isNaN(parseInt(id))) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Invalid artist ID'
|
||||
});
|
||||
}
|
||||
|
||||
const artistService = new ArtistService(req.backend.getAuth());
|
||||
const result = await artistService.getArtistFollowing(parseInt(id), {
|
||||
restrict,
|
||||
offset: parseInt(offset),
|
||||
limit: parseInt(limit)
|
||||
});
|
||||
|
||||
if (result.success) {
|
||||
res.json({
|
||||
success: true,
|
||||
data: result.data
|
||||
});
|
||||
} else {
|
||||
res.status(404).json({
|
||||
success: false,
|
||||
error: result.error
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 获取作者粉丝列表
|
||||
* GET /api/artist/:id/followers
|
||||
*/
|
||||
router.get('/:id/followers', async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const {
|
||||
offset = 0,
|
||||
limit = 30
|
||||
} = req.query;
|
||||
|
||||
if (!id || isNaN(parseInt(id))) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Invalid artist ID'
|
||||
});
|
||||
}
|
||||
|
||||
const artistService = new ArtistService(req.backend.getAuth());
|
||||
const result = await artistService.getArtistFollowers(parseInt(id), {
|
||||
offset: parseInt(offset),
|
||||
limit: parseInt(limit)
|
||||
});
|
||||
|
||||
if (result.success) {
|
||||
res.json({
|
||||
success: true,
|
||||
data: result.data
|
||||
});
|
||||
} else {
|
||||
res.status(404).json({
|
||||
success: false,
|
||||
error: result.error
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 关注/取消关注作者
|
||||
* POST /api/artist/:id/follow
|
||||
*/
|
||||
router.post('/:id/follow', async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { action = 'follow' } = req.body;
|
||||
|
||||
if (!id || isNaN(parseInt(id))) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Invalid artist ID'
|
||||
});
|
||||
}
|
||||
|
||||
if (!['follow', 'unfollow'].includes(action)) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Invalid action. Must be "follow" or "unfollow"'
|
||||
});
|
||||
}
|
||||
|
||||
const artistService = new ArtistService(req.backend.getAuth());
|
||||
const result = await artistService.followArtist(parseInt(id), action);
|
||||
|
||||
if (result.success) {
|
||||
res.json({
|
||||
success: true,
|
||||
message: `Artist ${action === 'follow' ? 'followed' : 'unfollowed'} successfully`
|
||||
});
|
||||
} else {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
error: result.error
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
@@ -0,0 +1,172 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const ArtworkService = require('../services/artwork');
|
||||
|
||||
/**
|
||||
* 搜索作品
|
||||
* GET /api/artwork/search
|
||||
*/
|
||||
router.get('/search', async (req, res) => {
|
||||
try {
|
||||
const {
|
||||
keyword,
|
||||
type = 'all',
|
||||
sort = 'date_desc',
|
||||
duration = 'all',
|
||||
offset = 0,
|
||||
limit = 30
|
||||
} = req.query;
|
||||
|
||||
if (!keyword) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Search keyword is required'
|
||||
});
|
||||
}
|
||||
|
||||
const artworkService = new ArtworkService(req.backend.getAuth());
|
||||
const result = await artworkService.searchArtworks({
|
||||
keyword,
|
||||
type,
|
||||
sort,
|
||||
duration,
|
||||
offset: parseInt(offset),
|
||||
limit: parseInt(limit)
|
||||
});
|
||||
|
||||
if (result.success) {
|
||||
res.json({
|
||||
success: true,
|
||||
data: result.data
|
||||
});
|
||||
} else {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
error: result.error
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 获取作品详情
|
||||
* GET /api/artwork/:id
|
||||
*/
|
||||
router.get('/:id', async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { include_user = 'true', include_series = 'false' } = req.query;
|
||||
|
||||
if (!id || isNaN(parseInt(id))) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Invalid artwork ID'
|
||||
});
|
||||
}
|
||||
|
||||
const artworkService = new ArtworkService(req.backend.getAuth());
|
||||
const result = await artworkService.getArtworkDetail(parseInt(id), {
|
||||
include_user: include_user === 'true',
|
||||
include_series: include_series === 'true'
|
||||
});
|
||||
|
||||
if (result.success) {
|
||||
res.json({
|
||||
success: true,
|
||||
data: result.data
|
||||
});
|
||||
} else {
|
||||
res.status(404).json({
|
||||
success: false,
|
||||
error: result.error
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 获取作品预览信息
|
||||
* GET /api/artwork/:id/preview
|
||||
*/
|
||||
router.get('/:id/preview', async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
if (!id || isNaN(parseInt(id))) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Invalid artwork ID'
|
||||
});
|
||||
}
|
||||
|
||||
const artworkService = new ArtworkService(req.backend.getAuth());
|
||||
const result = await artworkService.getArtworkPreview(parseInt(id));
|
||||
|
||||
if (result.success) {
|
||||
res.json({
|
||||
success: true,
|
||||
data: result.data
|
||||
});
|
||||
} else {
|
||||
res.status(404).json({
|
||||
success: false,
|
||||
error: result.error
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 获取作品图片URL
|
||||
* GET /api/artwork/:id/images
|
||||
*/
|
||||
router.get('/:id/images', async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { size = 'medium' } = req.query;
|
||||
|
||||
if (!id || isNaN(parseInt(id))) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Invalid artwork ID'
|
||||
});
|
||||
}
|
||||
|
||||
const artworkService = new ArtworkService(req.backend.getAuth());
|
||||
const result = await artworkService.getArtworkImages(parseInt(id), size);
|
||||
|
||||
if (result.success) {
|
||||
res.json({
|
||||
success: true,
|
||||
data: result.data
|
||||
});
|
||||
} else {
|
||||
res.status(404).json({
|
||||
success: false,
|
||||
error: result.error
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
@@ -0,0 +1,124 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
|
||||
/**
|
||||
* 获取登录状态
|
||||
* GET /api/auth/status
|
||||
*/
|
||||
router.get('/status', (req, res) => {
|
||||
try {
|
||||
const status = req.backend.getLoginStatus();
|
||||
res.json({
|
||||
success: true,
|
||||
data: status
|
||||
});
|
||||
} catch (error) {
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 获取登录URL
|
||||
* GET /api/auth/login-url
|
||||
*/
|
||||
router.get('/login-url', (req, res) => {
|
||||
try {
|
||||
const loginData = req.backend.getLoginUrl();
|
||||
res.json({
|
||||
success: true,
|
||||
data: loginData
|
||||
});
|
||||
} catch (error) {
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 处理登录回调
|
||||
* POST /api/auth/callback
|
||||
*/
|
||||
router.post('/callback', async (req, res) => {
|
||||
try {
|
||||
const { code } = req.body;
|
||||
|
||||
if (!code) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Authorization code is required'
|
||||
});
|
||||
}
|
||||
|
||||
const result = await req.backend.handleLoginCallback(code);
|
||||
|
||||
if (result.success) {
|
||||
res.json({
|
||||
success: true,
|
||||
data: result
|
||||
});
|
||||
} else {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
error: result.error
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 重新登录
|
||||
* POST /api/auth/relogin
|
||||
*/
|
||||
router.post('/relogin', async (req, res) => {
|
||||
try {
|
||||
const result = await req.backend.relogin();
|
||||
|
||||
if (result.success) {
|
||||
res.json({
|
||||
success: true,
|
||||
message: 'Relogin successful'
|
||||
});
|
||||
} else {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
error: result.error
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 登出
|
||||
* POST /api/auth/logout
|
||||
*/
|
||||
router.post('/logout', (req, res) => {
|
||||
try {
|
||||
const result = req.backend.logout();
|
||||
res.json({
|
||||
success: true,
|
||||
message: 'Logout successful'
|
||||
});
|
||||
} catch (error) {
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
@@ -0,0 +1,270 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const DownloadService = require('../services/download');
|
||||
|
||||
/**
|
||||
* 下载单个作品
|
||||
* POST /api/download/artwork/:id
|
||||
*/
|
||||
router.post('/artwork/:id', async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const {
|
||||
size = 'original',
|
||||
quality = 'high',
|
||||
format = 'auto'
|
||||
} = req.body;
|
||||
|
||||
if (!id || isNaN(parseInt(id))) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Invalid artwork ID'
|
||||
});
|
||||
}
|
||||
|
||||
const downloadService = new DownloadService(req.backend.getAuth());
|
||||
const result = await downloadService.downloadArtwork(parseInt(id), {
|
||||
size,
|
||||
quality,
|
||||
format
|
||||
});
|
||||
|
||||
if (result.success) {
|
||||
res.json({
|
||||
success: true,
|
||||
data: result.data
|
||||
});
|
||||
} else {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
error: result.error
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 批量下载作品
|
||||
* POST /api/download/artworks
|
||||
*/
|
||||
router.post('/artworks', async (req, res) => {
|
||||
try {
|
||||
const {
|
||||
artworkIds,
|
||||
size = 'original',
|
||||
quality = 'high',
|
||||
format = 'auto',
|
||||
concurrent = 3
|
||||
} = req.body;
|
||||
|
||||
if (!artworkIds || !Array.isArray(artworkIds) || artworkIds.length === 0) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Artwork IDs array is required'
|
||||
});
|
||||
}
|
||||
|
||||
if (artworkIds.length > 50) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Maximum 50 artworks can be downloaded at once'
|
||||
});
|
||||
}
|
||||
|
||||
const downloadService = new DownloadService(req.backend.getAuth());
|
||||
const result = await downloadService.downloadMultipleArtworks(artworkIds, {
|
||||
size,
|
||||
quality,
|
||||
format,
|
||||
concurrent: parseInt(concurrent)
|
||||
});
|
||||
|
||||
if (result.success) {
|
||||
res.json({
|
||||
success: true,
|
||||
data: result.data
|
||||
});
|
||||
} else {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
error: result.error
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 下载作者作品
|
||||
* POST /api/download/artist/:id
|
||||
*/
|
||||
router.post('/artist/:id', async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const {
|
||||
type = 'art',
|
||||
filter = 'for_ios',
|
||||
size = 'original',
|
||||
quality = 'high',
|
||||
format = 'auto',
|
||||
limit = 50,
|
||||
concurrent = 3
|
||||
} = req.body;
|
||||
|
||||
if (!id || isNaN(parseInt(id))) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Invalid artist ID'
|
||||
});
|
||||
}
|
||||
|
||||
const downloadService = new DownloadService(req.backend.getAuth());
|
||||
const result = await downloadService.downloadArtistArtworks(parseInt(id), {
|
||||
type,
|
||||
filter,
|
||||
size,
|
||||
quality,
|
||||
format,
|
||||
limit: parseInt(limit),
|
||||
concurrent: parseInt(concurrent)
|
||||
});
|
||||
|
||||
if (result.success) {
|
||||
res.json({
|
||||
success: true,
|
||||
data: result.data
|
||||
});
|
||||
} else {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
error: result.error
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 获取下载进度
|
||||
* GET /api/download/progress/:taskId
|
||||
*/
|
||||
router.get('/progress/:taskId', async (req, res) => {
|
||||
try {
|
||||
const { taskId } = req.params;
|
||||
|
||||
if (!taskId) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Task ID is required'
|
||||
});
|
||||
}
|
||||
|
||||
const downloadService = new DownloadService(req.backend.getAuth());
|
||||
const result = await downloadService.getDownloadProgress(taskId);
|
||||
|
||||
if (result.success) {
|
||||
res.json({
|
||||
success: true,
|
||||
data: result.data
|
||||
});
|
||||
} else {
|
||||
res.status(404).json({
|
||||
success: false,
|
||||
error: result.error
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 取消下载任务
|
||||
* DELETE /api/download/cancel/:taskId
|
||||
*/
|
||||
router.delete('/cancel/:taskId', async (req, res) => {
|
||||
try {
|
||||
const { taskId } = req.params;
|
||||
|
||||
if (!taskId) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Task ID is required'
|
||||
});
|
||||
}
|
||||
|
||||
const downloadService = new DownloadService(req.backend.getAuth());
|
||||
const result = await downloadService.cancelDownload(taskId);
|
||||
|
||||
if (result.success) {
|
||||
res.json({
|
||||
success: true,
|
||||
message: 'Download task cancelled successfully'
|
||||
});
|
||||
} else {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
error: result.error
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 获取下载历史
|
||||
* GET /api/download/history
|
||||
*/
|
||||
router.get('/history', async (req, res) => {
|
||||
try {
|
||||
const {
|
||||
offset = 0,
|
||||
limit = 20
|
||||
} = req.query;
|
||||
|
||||
const downloadService = new DownloadService(req.backend.getAuth());
|
||||
const result = await downloadService.getDownloadHistory({
|
||||
offset: parseInt(offset),
|
||||
limit: parseInt(limit)
|
||||
});
|
||||
|
||||
if (result.success) {
|
||||
res.json({
|
||||
success: true,
|
||||
data: result.data
|
||||
});
|
||||
} else {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
error: result.error
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
Reference in New Issue
Block a user