feat: 新增门户功能并重构资源展示组件

- 新增门户(Portal)数据模型与后端 API 端点
- 新增个人资料页面,支持用户更新昵称
- 重构前端资源卡片组件,支持显示 GitHub 版本信息与加速下载链接
- 在登录/注册页面添加 GitHub OAuth 支持
- 更新环境变量示例文件,添加前后端配置项
- 优化导航栏响应式设计,添加移动端菜单
- 添加页脚组件,包含备案信息
- 更新 Prisma 数据模型,适配 Better Auth 并添加种子数据
- 统一前后端 API URL 配置,支持环境变量覆盖
This commit is contained in:
2026-03-11 16:50:28 +08:00
parent 44b03672f0
commit 6adadce2d6
25 changed files with 1207 additions and 436 deletions

246
backend/prisma/seed.ts Normal file
View File

@@ -0,0 +1,246 @@
import { PrismaClient } from '@prisma/client'
import { PrismaPg } from "@prisma/adapter-pg";
import pg from "pg";
const connectionString = process.env.DATABASE_URL;
const pool = new pg.Pool({ connectionString });
const adapter = new PrismaPg(pool);
const prisma = new PrismaClient({ adapter });
const portalData = [
{
title: '中文论坛',
url: 'https://forum.hlae.site',
description: 'HLAE中文交流社区',
icon: 'pi pi-comments',
background: true,
},
{
title: '官方Wiki',
url: 'https://github.com/advancedfx/advancedfx/wiki',
description: '权威,但是英文 orz',
icon: 'pi pi-book',
background: true,
},
{
title: '新版文档',
url: 'https://doc.hlae.site',
description: '新版 advancedfx 文档,建设中',
icon: 'pi pi-bookmark',
background: true,
},
{
title: '官方Discord',
url: 'https://discord.gg/NGp8qhN',
description: '和开发者近距离交流',
icon: 'pi pi-discord',
background: true,
},
{
title: '问题与建议提交',
url: 'https://github.com/advancedfx/advancedfx/issues',
description: 'tnnd 为什么不更新',
icon: 'pi pi-question-circle',
background: true,
},
{
title: 'HUD生成器',
url: 'https://hud.hlae.site',
description: '击杀信息和准星生成工具',
icon: 'pi pi-wrench',
background: true,
},
{
title: '击杀信息生成',
url: '/hud/deathmsg',
description: 'CS2 · CS 击杀信息生成工具(测试)',
icon: 'pi pi-sliders-h',
background: true,
},
{
title: 'HLTV',
url: 'https://hltv.org/',
description: 'CSGO新闻、数据、录像',
icon: 'pi pi-video',
background: true,
},
]
const resourceData = [
{
title: 'HLAE',
githubRepo: 'advancedfx/advancedfx',
url: 'https://github.com/advancedfx/advancedfx',
description: '起源游戏影片制作工具',
background: false,
downloadCdn: 'https://api.upup.cool/get/hlae',
downloadOriginal: 'https://github.com/advancedfx/advancedfx/releases/latest',
image: '/icon/hlae.png',
},
{
title: 'FFmpeg',
githubRepo: 'GyanD/codexffmpeg',
url: 'https://ffmpeg.org',
description: '免费开源的全能媒体转码工具',
background: false,
downloadCdn: 'https://api.upup.cool/get/ffmpeg',
downloadOriginal: 'https://github.com/GyanD/codexffmpeg/releases/latest',
image: '/icon/ffmpeg.webp',
},
{
title: 'CFG预设 For CS2',
githubRepo: 'Purple-CSGO/CS2-Config-Presets',
url: 'https://cfg.upup.cool/v2',
description: '适用于CS2各场景的Config预设',
background: true,
downloadCdn: 'https://api.upup.cool/get/cs2-cfg',
downloadOriginal: 'https://github.com/Purple-CSGO/CS2-Config-Presets/releases/latest',
icon: 'pi pi-github',
},
{
title: 'CS Demo Manager',
githubRepo: 'akiver/CS-Demo-Manager',
url: 'https://cs-demo-manager.com',
description: 'CS录像分析观看工具',
background: true,
downloadCdn: 'https://api.upup.cool/get/csdm',
downloadOriginal: 'https://github.com/akiver/CS-Demo-Manager/releases/latest',
image: '/icon/csdm.svg',
},
{
title: 'CS工具箱',
githubRepo: 'plsgo/cstb',
url: 'https://cstb.upup.cool',
description: '一个为CS游戏各个方面带来便利的工具集合',
background: true,
downloadCdn: 'https://api.upup.cool/get/cstb',
downloadOriginal: 'https://github.com/plsgo/cstb/releases/latest',
image: '/icon/cstb.png',
},
{
title: 'HLAE Studio',
githubRepo: 'One-Studio/HLAE-Studio',
url: 'https://github.com/One-Studio/HLAE-Studio',
description: 'HLAE环境配置更新工具',
version: 'v1.1.0',
background: true,
downloadCdn: 'https://api.upup.cool/get/hlae-studio',
downloadOriginal: 'https://github.com/One-Studio/HLAE-Studio/releases/latest',
image: '/icon/hlae-studio.png',
},
{
title: 'CFG预设',
githubRepo: 'Purple-CSGO/CSGO-Config-Presets',
url: 'https://cfg.upup.cool',
description: '适用于CSGO各场景的Config预设',
background: true,
downloadCdn: 'https://api.upup.cool/get/csgo-cfg',
downloadOriginal: 'https://github.com/Purple-CSGO/CSGO-Config-Presets/releases/latest',
icon: 'pi pi-github',
},
{
title: 'nskinz',
githubRepo: 'advancedfx/nSkinz',
url: 'https://github.com/advancedfx/nskinz',
description: 'CSGO皮肤修改替换插件 advancedfx维护版本',
background: true,
downloadCdn: 'https://api.upup.cool/repo/advancedfx/nSkinz/&&&&.zip',
downloadOriginal: 'https://github.com/advancedfx/nSkinz/releases/latest',
icon: 'pi pi-github',
},
{
title: 'MIGI',
url: 'https://zoolsmith.github.io/MIGI3',
description: 'CSGO资源修改工具',
background: false,
downloadCdn: 'https://cdn.upup.cool/https://github.com/ZooLSmith/MIGI3/blob/main/migi.exe',
downloadOriginal: 'https://github.com/ZooLSmith/MIGI3/blob/main/migi.exe',
image: '/icon/migi.png',
},
{
title: 'Voukoder',
url: 'https://www.voukoder.org',
description: 'PR、AE、Vegas等软件的编码导出插件',
background: true,
downloadOriginal: 'https://www.voukoder.org/forum/thread/783-downloads-instructions/',
image: '/icon/voukoder.png',
},
{
title: 'ReShade AFX',
githubRepo: 'advancedfx/ReShade_advancedfx',
url: 'https://github.com/advancedfx/ReShade_advancedfx',
description: '连接HLAE录制的ReShade插件',
background: false,
downloadCdn: 'https://api.upup.cool/get/reshade-afx',
downloadOriginal: 'https://github.com/advancedfx/ReShade_advancedfx/releases/latest',
image: '/icon/reshade.png',
},
{
title: 'ReShade',
url: 'https://reshade.me',
description: '重塑你的游戏画面',
background: false,
downloadOriginal: 'https://reshade.me',
image: '/icon/reshade.png',
},
{
title: 'ShanaEncoder',
url: 'https://shana.pe.kr/shanaencoder_summary',
description: '方便好用的转码压制图形工具',
background: true,
downloadOriginal: 'https://shana.pe.kr/shanaencoder_download',
icon: 'pi pi-github',
},
{
title: 'SRadar',
githubRepo: 'zuoshipinSHEKL/SRadar',
url: 'https://sdr.hlae.cn',
description: 'Shekl制作的简易雷达',
background: true,
downloadCdn: 'https://api.upup.cool/get/sradar',
downloadOriginal: 'https://github.com/zuoshipinSHEKL/SRadar/releases/latest',
icon: 'pi pi-map',
},
]
async function main() {
console.log('Start seeding ...')
await prisma.portal.deleteMany()
await prisma.resource.deleteMany()
for (let i = 0; i < portalData.length; i++) {
const portal = portalData[i]
const p = await prisma.portal.create({
data: {
...portal,
order: i,
},
})
console.log(`Created portal with id: ${p.id}`)
}
for (let i = 0; i < resourceData.length; i++) {
const resource = resourceData[i]
const r = await prisma.resource.create({
data: {
...resource,
order: i,
},
})
console.log(`Created resource with id: ${r.id}`)
}
console.log('Seeding finished.')
}
main()
.then(async () => {
await prisma.$disconnect()
})
.catch(async (e) => {
console.error(e)
await prisma.$disconnect()
process.exit(1)
})