feat: 星域故事汇小游戏初始版本

This commit is contained in:
2026-03-03 16:57:49 +08:00
commit cc0e39cccc
34 changed files with 6556 additions and 0 deletions

124
server/routes/user.js Normal file
View 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;