feat: 新增门户功能并重构资源展示组件
- 新增门户(Portal)数据模型与后端 API 端点 - 新增个人资料页面,支持用户更新昵称 - 重构前端资源卡片组件,支持显示 GitHub 版本信息与加速下载链接 - 在登录/注册页面添加 GitHub OAuth 支持 - 更新环境变量示例文件,添加前后端配置项 - 优化导航栏响应式设计,添加移动端菜单 - 添加页脚组件,包含备案信息 - 更新 Prisma 数据模型,适配 Better Auth 并添加种子数据 - 统一前后端 API URL 配置,支持环境变量覆盖
This commit is contained in:
@@ -7,6 +7,8 @@ export const auth = betterAuth({
|
||||
provider: 'postgresql',
|
||||
}),
|
||||
basePath: '/api/auth',
|
||||
baseURL: process.env.BETTER_AUTH_URL || 'http://localhost:3001',
|
||||
trustedOrigins: ['http://localhost:5173'],
|
||||
emailAndPassword: {
|
||||
enabled: true,
|
||||
},
|
||||
|
||||
@@ -4,6 +4,7 @@ import { auth } from './auth'
|
||||
import { prisma } from './prisma'
|
||||
import { resources } from './resources'
|
||||
import { posts } from './posts'
|
||||
import { portals } from './portals'
|
||||
|
||||
const app = new Elysia()
|
||||
.use(
|
||||
@@ -17,6 +18,7 @@ const app = new Elysia()
|
||||
.mount(auth.handler)
|
||||
.get('/health', () => 'OK')
|
||||
.use(resources)
|
||||
.use(portals)
|
||||
.use(posts)
|
||||
.get('/user/:id', async ({ params }) => {
|
||||
const user = await prisma.user.findUnique({
|
||||
|
||||
49
backend/src/portals.ts
Normal file
49
backend/src/portals.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { Elysia, t } from 'elysia'
|
||||
import { prisma } from './prisma'
|
||||
|
||||
export const portals = new Elysia({ prefix: '/portals' })
|
||||
.get('/', async () => {
|
||||
return await prisma.portal.findMany({
|
||||
orderBy: { order: 'asc' },
|
||||
})
|
||||
})
|
||||
.post(
|
||||
'/',
|
||||
async ({ body }) => {
|
||||
return await prisma.portal.create({
|
||||
data: body,
|
||||
})
|
||||
},
|
||||
{
|
||||
body: t.Object({
|
||||
title: t.String(),
|
||||
url: t.String(),
|
||||
description: t.Optional(t.String()),
|
||||
icon: t.Optional(t.String()),
|
||||
background: t.Optional(t.Boolean()),
|
||||
}),
|
||||
},
|
||||
)
|
||||
.put(
|
||||
'/:id',
|
||||
async ({ params: { id }, body }) => {
|
||||
return await prisma.portal.update({
|
||||
where: { id },
|
||||
data: body,
|
||||
})
|
||||
},
|
||||
{
|
||||
body: t.Object({
|
||||
title: t.Optional(t.String()),
|
||||
url: t.Optional(t.String()),
|
||||
description: t.Optional(t.String()),
|
||||
icon: t.Optional(t.String()),
|
||||
background: t.Optional(t.Boolean()),
|
||||
}),
|
||||
},
|
||||
)
|
||||
.delete('/:id', async ({ params: { id } }) => {
|
||||
return await prisma.portal.delete({
|
||||
where: { id },
|
||||
})
|
||||
})
|
||||
@@ -4,7 +4,7 @@ import { prisma } from './prisma'
|
||||
export const resources = new Elysia({ prefix: '/resources' })
|
||||
.get('/', async () => {
|
||||
return await prisma.resource.findMany({
|
||||
orderBy: { createdAt: 'desc' },
|
||||
orderBy: { order: 'asc' },
|
||||
})
|
||||
})
|
||||
.post(
|
||||
@@ -21,6 +21,12 @@ export const resources = new Elysia({ prefix: '/resources' })
|
||||
url: t.String(),
|
||||
icon: t.Optional(t.String()),
|
||||
category: t.Optional(t.String()),
|
||||
githubRepo: t.Optional(t.String()),
|
||||
downloadCdn: t.Optional(t.String()),
|
||||
downloadOriginal: t.Optional(t.String()),
|
||||
version: t.Optional(t.String()),
|
||||
background: t.Optional(t.Boolean()),
|
||||
image: t.Optional(t.String()),
|
||||
}),
|
||||
},
|
||||
)
|
||||
@@ -39,6 +45,12 @@ export const resources = new Elysia({ prefix: '/resources' })
|
||||
url: t.Optional(t.String()),
|
||||
icon: t.Optional(t.String()),
|
||||
category: t.Optional(t.String()),
|
||||
githubRepo: t.Optional(t.String()),
|
||||
downloadCdn: t.Optional(t.String()),
|
||||
downloadOriginal: t.Optional(t.String()),
|
||||
version: t.Optional(t.String()),
|
||||
background: t.Optional(t.Boolean()),
|
||||
image: t.Optional(t.String()),
|
||||
}),
|
||||
},
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user