feat: 星域故事汇小游戏初始版本
This commit is contained in:
110
server/routes/story.js
Normal file
110
server/routes/story.js
Normal file
@@ -0,0 +1,110 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const StoryModel = require('../models/story');
|
||||
|
||||
// 获取故事列表
|
||||
router.get('/', async (req, res) => {
|
||||
try {
|
||||
const { category, featured, limit, offset } = req.query;
|
||||
const stories = await StoryModel.getList({
|
||||
category,
|
||||
featured: featured === 'true',
|
||||
limit: parseInt(limit) || 20,
|
||||
offset: parseInt(offset) || 0
|
||||
});
|
||||
res.json({ code: 0, data: stories });
|
||||
} catch (err) {
|
||||
console.error('获取故事列表失败:', err);
|
||||
res.status(500).json({ code: 500, message: '获取故事列表失败' });
|
||||
}
|
||||
});
|
||||
|
||||
// 获取热门故事
|
||||
router.get('/hot', async (req, res) => {
|
||||
try {
|
||||
const { limit } = req.query;
|
||||
const stories = await StoryModel.getHotStories(parseInt(limit) || 10);
|
||||
res.json({ code: 0, data: stories });
|
||||
} catch (err) {
|
||||
console.error('获取热门故事失败:', err);
|
||||
res.status(500).json({ code: 500, message: '获取热门故事失败' });
|
||||
}
|
||||
});
|
||||
|
||||
// 获取分类列表
|
||||
router.get('/categories', async (req, res) => {
|
||||
try {
|
||||
const categories = await StoryModel.getCategories();
|
||||
res.json({ code: 0, data: categories });
|
||||
} catch (err) {
|
||||
console.error('获取分类列表失败:', err);
|
||||
res.status(500).json({ code: 500, message: '获取分类列表失败' });
|
||||
}
|
||||
});
|
||||
|
||||
// 获取故事详情
|
||||
router.get('/:id', async (req, res) => {
|
||||
try {
|
||||
const storyId = parseInt(req.params.id);
|
||||
const story = await StoryModel.getDetail(storyId);
|
||||
if (!story) {
|
||||
return res.status(404).json({ code: 404, message: '故事不存在' });
|
||||
}
|
||||
res.json({ code: 0, data: story });
|
||||
} catch (err) {
|
||||
console.error('获取故事详情失败:', err);
|
||||
res.status(500).json({ code: 500, message: '获取故事详情失败' });
|
||||
}
|
||||
});
|
||||
|
||||
// 记录游玩
|
||||
router.post('/:id/play', async (req, res) => {
|
||||
try {
|
||||
const storyId = parseInt(req.params.id);
|
||||
await StoryModel.incrementPlayCount(storyId);
|
||||
res.json({ code: 0, message: '记录成功' });
|
||||
} catch (err) {
|
||||
console.error('记录游玩失败:', err);
|
||||
res.status(500).json({ code: 500, message: '记录游玩失败' });
|
||||
}
|
||||
});
|
||||
|
||||
// 点赞
|
||||
router.post('/:id/like', async (req, res) => {
|
||||
try {
|
||||
const storyId = parseInt(req.params.id);
|
||||
const { like } = req.body; // true: 点赞, false: 取消点赞
|
||||
await StoryModel.toggleLike(storyId, like);
|
||||
res.json({ code: 0, message: like ? '点赞成功' : '取消点赞成功' });
|
||||
} catch (err) {
|
||||
console.error('点赞操作失败:', err);
|
||||
res.status(500).json({ code: 500, message: '点赞操作失败' });
|
||||
}
|
||||
});
|
||||
|
||||
// AI改写结局
|
||||
router.post('/:id/rewrite', async (req, res) => {
|
||||
try {
|
||||
const storyId = parseInt(req.params.id);
|
||||
const { ending_name, ending_content, prompt } = req.body;
|
||||
|
||||
if (!prompt) {
|
||||
return res.status(400).json({ code: 400, message: '请输入改写指令' });
|
||||
}
|
||||
|
||||
// 调用AI服务生成新内容
|
||||
const result = await StoryModel.aiRewriteEnding({
|
||||
storyId,
|
||||
endingName: ending_name,
|
||||
endingContent: ending_content,
|
||||
prompt
|
||||
});
|
||||
|
||||
res.json({ code: 0, data: result });
|
||||
} catch (err) {
|
||||
console.error('AI改写失败:', err);
|
||||
res.status(500).json({ code: 500, message: 'AI改写失败' });
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
124
server/routes/user.js
Normal file
124
server/routes/user.js
Normal file
@@ -0,0 +1,124 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const UserModel = require('../models/user');
|
||||
|
||||
// 模拟微信登录(实际环境需要调用微信API)
|
||||
router.post('/login', async (req, res) => {
|
||||
try {
|
||||
const { code, userInfo } = req.body;
|
||||
|
||||
// 实际项目中需要用code换取openid
|
||||
// 这里为了开发测试,暂时用code作为openid
|
||||
const openid = code || `test_user_${Date.now()}`;
|
||||
|
||||
const user = await UserModel.findOrCreate(openid, userInfo);
|
||||
res.json({
|
||||
code: 0,
|
||||
data: {
|
||||
userId: user.id,
|
||||
openid: user.openid,
|
||||
nickname: user.nickname,
|
||||
avatarUrl: user.avatar_url
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('登录失败:', err);
|
||||
res.status(500).json({ code: 500, message: '登录失败' });
|
||||
}
|
||||
});
|
||||
|
||||
// 更新用户信息
|
||||
router.post('/profile', async (req, res) => {
|
||||
try {
|
||||
const { userId, nickname, avatarUrl, gender } = req.body;
|
||||
await UserModel.updateProfile(userId, { nickname, avatarUrl, gender });
|
||||
res.json({ code: 0, message: '更新成功' });
|
||||
} catch (err) {
|
||||
console.error('更新用户信息失败:', err);
|
||||
res.status(500).json({ code: 500, message: '更新用户信息失败' });
|
||||
}
|
||||
});
|
||||
|
||||
// 获取用户进度
|
||||
router.get('/progress', async (req, res) => {
|
||||
try {
|
||||
const { userId, storyId } = req.query;
|
||||
const progress = await UserModel.getProgress(
|
||||
parseInt(userId),
|
||||
storyId ? parseInt(storyId) : null
|
||||
);
|
||||
res.json({ code: 0, data: progress });
|
||||
} catch (err) {
|
||||
console.error('获取进度失败:', err);
|
||||
res.status(500).json({ code: 500, message: '获取进度失败' });
|
||||
}
|
||||
});
|
||||
|
||||
// 保存用户进度
|
||||
router.post('/progress', async (req, res) => {
|
||||
try {
|
||||
const { userId, storyId, currentNodeKey, isCompleted, endingReached } = req.body;
|
||||
await UserModel.saveProgress(parseInt(userId), parseInt(storyId), {
|
||||
currentNodeKey,
|
||||
isCompleted,
|
||||
endingReached
|
||||
});
|
||||
res.json({ code: 0, message: '保存成功' });
|
||||
} catch (err) {
|
||||
console.error('保存进度失败:', err);
|
||||
res.status(500).json({ code: 500, message: '保存进度失败' });
|
||||
}
|
||||
});
|
||||
|
||||
// 点赞操作
|
||||
router.post('/like', async (req, res) => {
|
||||
try {
|
||||
const { userId, storyId, isLiked } = req.body;
|
||||
await UserModel.toggleLike(parseInt(userId), parseInt(storyId), isLiked);
|
||||
res.json({ code: 0, message: isLiked ? '点赞成功' : '取消点赞' });
|
||||
} catch (err) {
|
||||
console.error('点赞操作失败:', err);
|
||||
res.status(500).json({ code: 500, message: '点赞操作失败' });
|
||||
}
|
||||
});
|
||||
|
||||
// 收藏操作
|
||||
router.post('/collect', async (req, res) => {
|
||||
try {
|
||||
const { userId, storyId, isCollected } = req.body;
|
||||
await UserModel.toggleCollect(parseInt(userId), parseInt(storyId), isCollected);
|
||||
res.json({ code: 0, message: isCollected ? '收藏成功' : '取消收藏' });
|
||||
} catch (err) {
|
||||
console.error('收藏操作失败:', err);
|
||||
res.status(500).json({ code: 500, message: '收藏操作失败' });
|
||||
}
|
||||
});
|
||||
|
||||
// 获取收藏列表
|
||||
router.get('/collections', async (req, res) => {
|
||||
try {
|
||||
const { userId } = req.query;
|
||||
const collections = await UserModel.getCollections(parseInt(userId));
|
||||
res.json({ code: 0, data: collections });
|
||||
} catch (err) {
|
||||
console.error('获取收藏列表失败:', err);
|
||||
res.status(500).json({ code: 500, message: '获取收藏列表失败' });
|
||||
}
|
||||
});
|
||||
|
||||
// 获取已解锁结局
|
||||
router.get('/endings', async (req, res) => {
|
||||
try {
|
||||
const { userId, storyId } = req.query;
|
||||
const endings = await UserModel.getUnlockedEndings(
|
||||
parseInt(userId),
|
||||
storyId ? parseInt(storyId) : null
|
||||
);
|
||||
res.json({ code: 0, data: endings });
|
||||
} catch (err) {
|
||||
console.error('获取结局列表失败:', err);
|
||||
res.status(500).json({ code: 500, message: '获取结局列表失败' });
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
Reference in New Issue
Block a user